diff --git a/config-joey.hs b/config-joey.hs index b6152f1..67986ff 100644 --- a/config-joey.hs +++ b/config-joey.hs @@ -366,9 +366,9 @@ standardSystemUnhardened hn suite arch motd = host hn & Apt.installed ["etckeeper"] & Apt.installed ["ssh"] & GitHome.installedFor "root" - & User.hasSomePassword "root" (Context hn) + & User.hasSomePassword "root" & User.accountFor "joey" - & User.hasSomePassword "joey" (Context hn) + & User.hasSomePassword "joey" & Sudo.enabledFor "joey" & GitHome.installedFor "joey" & Apt.installed ["vim", "screen", "less"] diff --git a/config-simple.hs b/config-simple.hs index fb02e27..c03149e 100644 --- a/config-simple.hs +++ b/config-simple.hs @@ -29,7 +29,7 @@ hosts = & Apt.unattendedUpgrades & Apt.installed ["etckeeper"] & Apt.installed ["ssh"] - & User.hasSomePassword "root" (Context "mybox.example.com") + & User.hasSomePassword "root" & Network.ipv6to4 & File.dirExists "/var/www" & Docker.docked webserverContainer diff --git a/debian/changelog b/debian/changelog index 6a1d60d..e70e6a9 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,4 +1,4 @@ -propellor (1.0.1) UNRELEASED; urgency=medium +propellor (1.1.0) UNRELEASED; urgency=medium * propellor --spin can now deploy propellor to hosts that do not have git, ghc, or apt-get. This is accomplished by uploading a fairly @@ -12,6 +12,9 @@ propellor (1.0.1) UNRELEASED; urgency=medium find the full hostname. * Added group-related properties. Thanks, Félix Sipma. * Added Git.barerepo. Thanks, Félix Sipma. + * hasSomePassword and hasPassword now default to using the name of the + host as the Context for the password. To specify a different context, + use hasSomePassword' and hasPassword' (API change) -- Joey Hess Sat, 22 Nov 2014 00:12:35 -0400 diff --git a/propellor.cabal b/propellor.cabal index cd34d4b..617a1fc 100644 --- a/propellor.cabal +++ b/propellor.cabal @@ -1,5 +1,5 @@ Name: propellor -Version: 1.0.0 +Version: 1.1.0 Cabal-Version: >= 1.6 License: BSD3 Maintainer: Joey Hess diff --git a/src/Propellor/Property/OS.hs b/src/Propellor/Property/OS.hs index 914fb9f..c96e20b 100644 --- a/src/Propellor/Property/OS.hs +++ b/src/Propellor/Property/OS.hs @@ -17,6 +17,10 @@ import qualified Propellor.Property.Debootstrap as Debootstrap -- This can replace one Linux distribution with different one. -- But, it can also fail and leave the system in an unbootable state. -- +-- To avoid this property being accidentially used, you have to provide +-- a Context containing the name of the host that you intend to apply the +-- property to. +-- -- This property only runs once. The cleanly installed system will have -- a file /etc/propellor-cleaninstall, which indicates it was cleanly -- installed. @@ -26,7 +30,7 @@ import qualified Propellor.Property.Debootstrap as Debootstrap -- working system. For example: -- -- > & os (System (Debian Unstable) "amd64") --- > & cleanInstall (confirm "com.example.foo") (BackupOldOS <> UseOldKernel) +-- > & cleanInstall (Context "foo.example.com") (BackupOldOS <> UseOldKernel) -- > `onChange` propertyList "fixing up after clean install" -- > [ fixupNetworkInterfaces -- > , fixupRootSsh @@ -34,38 +38,33 @@ import qualified Propellor.Property.Debootstrap as Debootstrap -- > -- , installGrub -- > ] -- > & Apt.installed ["ssh"] +-- > & User.hasSomePassword "root" +-- > & User.accountFor "joey" +-- > & User.hasSomePassword "joey" -- > -- rest of system properties here -cleanInstallOnce :: Confirmation -> Exceptions -> Property -cleanInstallOnce c = check (not <$> doesFileExist flagfile) $ +cleanInstallOnce :: Context -> Exceptions -> Property +cleanInstallOnce (Context c) = check (not <$> doesFileExist flagfile) $ Property "OS cleanly installed" $ do - confirm c + hostname <- asks hostName + when (hostname /= c) $ + error "Run with bad context, not matching hostname. Not running cleanInstalOnce!" error "TODO" - -- debootstrap /new-os chroot; avoid running - -- propellor inside the chroot yet + -- debootstrap /new-os chroot, but don't run propellor + -- inside the chroot. -- unmount all mounts -- move all directories to /old-os, -- except for /boot and /lib/modules -- move /new-os to / - -- touch /etc/propellor-cleaninstall + -- touch flagfile -- re-bootstrap propellor in /usr/local/propellor, -- (using git repo bundle, privdata file, and possibly -- git repo url, which all need to be arranged to -- be present in /old-os's /usr/local/propellor) + -- enable shadow passwords (to avoid foot-shooting) -- return MadeChange where flagfile = "/etc/propellor-cleaninstall" --- | To confirm you really intend to apply a dangerous Property to a --- system, and have not copied and pasted it in by accident, you must --- provide as confirmation, the hostname of the system you intend --- to apply the Property to, written in the form form "com.example.somehost" -newtype Confirmation = Confirmation String - -confirm :: String -> Confirmation -confirm (Confirmation c) h - | h ==(intercalate "." $ reverse $ split "." c) = return () - | otherwise = error "Bad confirmation of dangerous Property; see the documentation to fix this." - -- | Sometimes you want an almost clean install, but with some exceptions. data Exceptions = UseOldKernel -- ^ Leave /boot and /lib/modules from old OS, so the system can boot using them as before diff --git a/src/Propellor/Property/User.hs b/src/Propellor/Property/User.hs index 6a51703..434a92a 100644 --- a/src/Propellor/Property/User.hs +++ b/src/Propellor/Property/User.hs @@ -24,12 +24,27 @@ nuked user _ = check (isJust <$> catchMaybeIO (homedir user)) $ cmdProperty "use -- | Only ensures that the user has some password set. It may or may -- not be the password from the PrivData. -hasSomePassword :: UserName -> Context -> Property -hasSomePassword user context = check ((/= HasPassword) <$> getPasswordStatus user) $ - hasPassword user context +hasSomePassword :: UserName -> Property +hasSomePassword user = property (user ++ "has password") $ do + hostname <- asks hostName + ensureProperty $ hasSomePassword' user (Context hostname) -hasPassword :: UserName -> Context -> Property -hasPassword user context = withPrivData (Password user) context $ \getpassword -> +-- | While hasSomePassword uses the name of the host as context, +-- this allows specifying a different context. This is useful when +-- you want to use the same password on multiple hosts, for example. +hasSomePassword' :: UserName -> Context -> Property +hasSomePassword' user context = check ((/= HasPassword) <$> getPasswordStatus user) $ + hasPassword' user context + +-- | Ensures that a user's password is set to the password from the PrivData. +-- (Will change any existing password.) +hasPassword :: UserName -> Property +hasPassword user = property (user ++ "has password") $ do + hostname <- asks hostName + ensureProperty $ hasPassword' user (Context hostname) + +hasPassword' :: UserName -> Context -> Property +hasPassword' user context = withPrivData (Password user) context $ \getpassword -> property (user ++ " has password") $ getpassword $ \password -> makeChange $ withHandle StdinHandle createProcessSuccess