propellor/src/Propellor/Property/OS.hs

125 lines
4.3 KiB
Haskell
Raw Normal View History

2014-11-23 19:42:22 +00:00
module Propellor.Property.OS (
cleanInstallOnce,
2014-11-24 04:40:53 +00:00
Confirmed(..),
fixupNetworkInterfaces,
2014-11-23 23:49:53 +00:00
rootSshAuthorized,
grubBoots,
2014-11-24 04:40:53 +00:00
GrubDev(..),
2014-11-23 23:49:53 +00:00
kernelInstalled,
2014-11-23 19:42:22 +00:00
oldOSRemoved,
) where
import Propellor
import qualified Propellor.Property.Chroot as Chroot
import qualified Propellor.Property.Debootstrap as Debootstrap
2014-11-24 04:40:53 +00:00
import qualified Propellor.Property.File as File
2014-11-24 04:51:36 +00:00
import qualified Propellor.Property.Ssh as Ssh
2014-11-24 04:40:53 +00:00
import Utility.FileMode
2014-11-23 19:42:22 +00:00
-- | Replaces whatever OS was installed before with a clean installation
-- of the OS that the Host is configured to have.
--
-- 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
2014-11-24 04:40:53 +00:00
-- a Confirmed containing the name of the host that you intend to apply the
-- property to.
--
2014-11-23 19:42:22 +00:00
-- This property only runs once. The cleanly installed system will have
-- a file /etc/propellor-cleaninstall, which indicates it was cleanly
-- installed.
--
-- You will typically want to run some more properties after the clean
-- install, to bootstrap from the cleanly installed system to a fully
-- working system. For example:
--
-- > & os (System (Debian Unstable) "amd64")
2014-11-24 04:40:53 +00:00
-- > & cleanInstall (Confirmed "foo.example.com") [BackupOldOS, UseOldKernel]
2014-11-23 19:42:22 +00:00
-- > `onChange` propertyList "fixing up after clean install"
-- > [ fixupNetworkInterfaces
2014-11-23 23:49:53 +00:00
-- > , rootSshAuthorized
-- > -- , kernelInstalled
-- > -- , grubBoots "hd0"
2014-11-23 19:42:22 +00:00
-- > ]
-- > & Apt.installed ["ssh"]
-- > & User.hasSomePassword "root"
-- > & User.accountFor "joey"
-- > & User.hasSomePassword "joey"
2014-11-23 19:42:22 +00:00
-- > -- rest of system properties here
2014-11-24 04:40:53 +00:00
cleanInstallOnce :: Confirmed -> [Tweak] -> Property
cleanInstallOnce confirmed tweaks = check (not <$> doesFileExist flagfile) $
property "OS cleanly installed" $ do
checkConfirmed confirmed
2014-11-23 19:42:22 +00:00
error "TODO"
-- debootstrap /new-os chroot, but don't run propellor
-- inside the chroot.
2014-11-23 19:42:22 +00:00
-- unmount all mounts
-- move all directories to /old-os,
2014-11-24 04:40:53 +00:00
-- except for /boot and /lib/modules when UseOldKernel
-- (or, delete when not BackupOldOS)
2014-11-23 19:42:22 +00:00
-- move /new-os to /
-- touch flagfile
2014-11-23 19:42:22 +00:00
-- 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)
2014-11-23 19:42:22 +00:00
-- return MadeChange
where
flagfile = "/etc/propellor-cleaninstall"
2014-11-24 04:40:53 +00:00
data Confirmed = Confirmed HostName
checkConfirmed :: Confirmed -> Propellor ()
checkConfirmed (Confirmed c) = do
hostname <- asks hostName
when (hostname /= c) $
errorMessage "Run with a bad confirmation, not matching hostname."
-- | Sometimes you want an almost clean install, but with some tweaks.
data Tweak
2014-11-23 19:42:22 +00:00
= UseOldKernel -- ^ Leave /boot and /lib/modules from old OS, so the system can boot using them as before
| BackupOldOS -- ^ Back up old OS to /old-os, to avoid losing any important files
-- /etc/network/interfaces is configured to bring up all interfaces that
-- are currently up, using the same IP addresses.
fixupNetworkInterfaces :: Property
fixupNetworkInterfaces = undefined
2014-11-24 04:40:53 +00:00
-- Root's .ssh/authorized_keys has added to it any ssh keys that
-- were authorized in the old OS. Any other contents of the file are
-- retained.
2014-11-23 23:49:53 +00:00
rootSshAuthorized :: Property
2014-11-24 04:40:53 +00:00
rootSshAuthorized = check (doesDirectoryExist oldloc) $
property (newloc ++ " copied from old OS") $ do
ks <- liftIO $ lines <$> readFile oldloc
2014-11-24 04:51:36 +00:00
ensureProperties (map (Ssh.authorizedKey "root") ks)
2014-11-24 04:40:53 +00:00
where
newloc = "/root/.ssh/authorized_keys"
oldloc = oldOsDir ++ newloc
2014-11-23 19:42:22 +00:00
2014-11-24 04:40:53 +00:00
-- Installs an appropriate kernel from the OS distribution.
2014-11-23 23:49:53 +00:00
kernelInstalled :: Property
kernelInstalled = undefined
2014-11-23 19:42:22 +00:00
2014-11-24 04:40:53 +00:00
-- Installs grub onto a device to boot the system.
--
-- You may want to install grub to multiple devices; eg for a system
-- that uses software RAID.
2014-11-23 23:49:53 +00:00
grubBoots :: GrubDev -> Property
grubBoots = undefined
2014-11-23 19:42:22 +00:00
2014-11-24 04:40:53 +00:00
type GrubDev = String
2014-11-23 19:42:22 +00:00
-- Removes the old OS's backup from /old-os
2014-11-24 04:40:53 +00:00
oldOSRemoved :: Confirmed -> Property
oldOSRemoved confirmed = check (doesDirectoryExist oldOsDir) $
property "old OS backup removed" $ do
checkConfirmed confirmed
liftIO $ removeDirectoryRecursive oldOsDir
2014-11-23 19:42:22 +00:00
return MadeChange
oldOsDir :: FilePath
oldOsDir = "/old-os"