propellor 5.12 → 5.13
raw patch · 12 files changed
+1015/−290 lines, 12 filesPVP ok
version bump matches the API change (PVP)
API changes (from Hackage documentation)
- Propellor: newtype Alt (f :: k -> Type) (a :: k) :: forall k. () => k -> Type -> k -> Type
- Propellor.Property.SiteSpecific.JoeySites: oldUseNetInstalled :: Package -> Property DebianLike
- Propellor.Property.SiteSpecific.JoeySites: oldUseNetServer :: [Host] -> Property (HasInfo + DebianLike)
- Propellor.Property.SiteSpecific.JoeySites: oldUseNetShellBox :: Property DebianLike
- Propellor.Types: instance forall a1 a2 (x :: [a2]) (y :: [a2]) (x' :: [a1]) (y' :: [a1]). (Propellor.Types.MetaTypes.CheckCombinable x y, Propellor.Types.MetaTypes.CheckCombinable x' y', Propellor.Types.Singletons.SingI (Propellor.Types.MetaTypes.Combine x y), Propellor.Types.Singletons.SingI (Propellor.Types.MetaTypes.Combine x' y')) => Propellor.Types.Combines (Propellor.Types.RevertableProperty (Propellor.Types.MetaTypes.MetaTypes x) (Propellor.Types.MetaTypes.MetaTypes x')) (Propellor.Types.RevertableProperty (Propellor.Types.MetaTypes.MetaTypes y) (Propellor.Types.MetaTypes.MetaTypes y'))
- Propellor.Types: instance forall k a (x :: [a]) (y :: [a]) (x' :: k). (Propellor.Types.MetaTypes.CheckCombinable x y, Propellor.Types.Singletons.SingI (Propellor.Types.MetaTypes.Combine x y)) => Propellor.Types.Combines (Propellor.Types.RevertableProperty (Propellor.Types.MetaTypes.MetaTypes x) (Propellor.Types.MetaTypes.MetaTypes x')) (Propellor.Types.Property (Propellor.Types.MetaTypes.MetaTypes y))
- Propellor.Types: instance forall k a (x :: [a]) (y :: [a]) (y' :: k). (Propellor.Types.MetaTypes.CheckCombinable x y, Propellor.Types.Singletons.SingI (Propellor.Types.MetaTypes.Combine x y)) => Propellor.Types.Combines (Propellor.Types.Property (Propellor.Types.MetaTypes.MetaTypes x)) (Propellor.Types.RevertableProperty (Propellor.Types.MetaTypes.MetaTypes y) (Propellor.Types.MetaTypes.MetaTypes y'))
- Propellor.Types: instance forall k1 k2 (setupmetatypes :: k2) (undometatypes :: k1). (GHC.Base.Monoid (Propellor.Types.Property (Propellor.Types.MetaTypes.MetaTypes setupmetatypes)), GHC.Base.Monoid (Propellor.Types.Property (Propellor.Types.MetaTypes.MetaTypes undometatypes)), Propellor.Types.Singletons.SingI setupmetatypes, Propellor.Types.Singletons.SingI undometatypes) => GHC.Base.Monoid (Propellor.Types.RevertableProperty (Propellor.Types.MetaTypes.MetaTypes setupmetatypes) (Propellor.Types.MetaTypes.MetaTypes undometatypes))
- Propellor.Types: instance forall k1 k2 (setupmetatypes :: k2) (undometatypes :: k1). (GHC.Base.Semigroup (Propellor.Types.Property (Propellor.Types.MetaTypes.MetaTypes setupmetatypes)), GHC.Base.Semigroup (Propellor.Types.Property (Propellor.Types.MetaTypes.MetaTypes undometatypes)), Propellor.Types.Singletons.SingI setupmetatypes, Propellor.Types.Singletons.SingI undometatypes) => GHC.Base.Semigroup (Propellor.Types.RevertableProperty (Propellor.Types.MetaTypes.MetaTypes setupmetatypes) (Propellor.Types.MetaTypes.MetaTypes undometatypes))
- Propellor.Types.MetaTypes: data DelayErrorFcf (a :: ErrorMessage) (b :: k) :: forall k. () => ErrorMessage -> k -> Type
- Propellor.Utilities: [SomeException] :: forall e. Exception e => e -> SomeException
+ Propellor: newtype Alt (f :: k -> Type) (a :: k)
+ Propellor: newtype Ap (f :: k -> Type) (a :: k)
+ Propellor.Property.Network: interfaceFileContains' :: FilePath -> [InterfaceStanza] -> Property DebianLike
+ Propellor.Property.Network: static'' :: Interface -> [(IPAddr, Maybe Gateway, InterfaceOptions)] -> Property DebianLike
+ Propellor.Property.Network: type InterfaceStanza = ([String], InterfaceOptions)
+ Propellor.Types: instance forall a k (x :: [a]) (y :: [a]) (x' :: k). (Propellor.Types.MetaTypes.CheckCombinable x y, Propellor.Types.Singletons.SingI (Propellor.Types.MetaTypes.Combine x y)) => Propellor.Types.Combines (Propellor.Types.RevertableProperty (Propellor.Types.MetaTypes.MetaTypes x) (Propellor.Types.MetaTypes.MetaTypes x')) (Propellor.Types.Property (Propellor.Types.MetaTypes.MetaTypes y))
+ Propellor.Types: instance forall a k (x :: [a]) (y :: [a]) (y' :: k). (Propellor.Types.MetaTypes.CheckCombinable x y, Propellor.Types.Singletons.SingI (Propellor.Types.MetaTypes.Combine x y)) => Propellor.Types.Combines (Propellor.Types.Property (Propellor.Types.MetaTypes.MetaTypes x)) (Propellor.Types.RevertableProperty (Propellor.Types.MetaTypes.MetaTypes y) (Propellor.Types.MetaTypes.MetaTypes y'))
+ Propellor.Types: instance forall a1 a2 (x :: [a1]) (y :: [a1]) (x' :: [a2]) (y' :: [a2]). (Propellor.Types.MetaTypes.CheckCombinable x y, Propellor.Types.MetaTypes.CheckCombinable x' y', Propellor.Types.Singletons.SingI (Propellor.Types.MetaTypes.Combine x y), Propellor.Types.Singletons.SingI (Propellor.Types.MetaTypes.Combine x' y')) => Propellor.Types.Combines (Propellor.Types.RevertableProperty (Propellor.Types.MetaTypes.MetaTypes x) (Propellor.Types.MetaTypes.MetaTypes x')) (Propellor.Types.RevertableProperty (Propellor.Types.MetaTypes.MetaTypes y) (Propellor.Types.MetaTypes.MetaTypes y'))
+ Propellor.Types: instance forall k1 k2 (setupmetatypes :: k1) (undometatypes :: k2). (GHC.Base.Monoid (Propellor.Types.Property (Propellor.Types.MetaTypes.MetaTypes setupmetatypes)), GHC.Base.Monoid (Propellor.Types.Property (Propellor.Types.MetaTypes.MetaTypes undometatypes)), Propellor.Types.Singletons.SingI setupmetatypes, Propellor.Types.Singletons.SingI undometatypes) => GHC.Base.Monoid (Propellor.Types.RevertableProperty (Propellor.Types.MetaTypes.MetaTypes setupmetatypes) (Propellor.Types.MetaTypes.MetaTypes undometatypes))
+ Propellor.Types: instance forall k1 k2 (setupmetatypes :: k1) (undometatypes :: k2). (GHC.Base.Semigroup (Propellor.Types.Property (Propellor.Types.MetaTypes.MetaTypes setupmetatypes)), GHC.Base.Semigroup (Propellor.Types.Property (Propellor.Types.MetaTypes.MetaTypes undometatypes)), Propellor.Types.Singletons.SingI setupmetatypes, Propellor.Types.Singletons.SingI undometatypes) => GHC.Base.Semigroup (Propellor.Types.RevertableProperty (Propellor.Types.MetaTypes.MetaTypes setupmetatypes) (Propellor.Types.MetaTypes.MetaTypes undometatypes))
+ Propellor.Types.MetaTypes: data DelayErrorFcf (a :: ErrorMessage) (b :: k)
+ Propellor.Utilities: SomeException :: e -> SomeException
- Propellor: (!) :: CheckCombinableNote x z (NoteFor ( 'Text "!")) => Props (MetaTypes x) -> RevertableProperty (MetaTypes y) (MetaTypes z) -> Props (MetaTypes (Combine x z))
+ Propellor: (!) :: CheckCombinableNote x z (NoteFor ('Text "!")) => Props (MetaTypes x) -> RevertableProperty (MetaTypes y) (MetaTypes z) -> Props (MetaTypes (Combine x z))
- Propellor: (&) :: (IsProp p, MetaTypes y ~ GetMetaTypes p, CheckCombinableNote x y (NoteFor ( 'Text "&"))) => Props (MetaTypes x) -> p -> Props (MetaTypes (Combine x y))
+ Propellor: (&) :: (IsProp p, MetaTypes y ~ GetMetaTypes p, CheckCombinableNote x y (NoteFor ('Text "&"))) => Props (MetaTypes x) -> p -> Props (MetaTypes (Combine x y))
- Propellor: Alt :: f a -> Alt
+ Propellor: Alt :: f a -> Alt (f :: k -> Type) (a :: k)
- Propellor: Ap :: f a -> Ap
+ Propellor: Ap :: f a -> Ap (f :: k -> Type) (a :: k)
- Propellor: [getAlt] :: Alt -> f a
+ Propellor: [getAlt] :: Alt (f :: k -> Type) (a :: k) -> f a
- Propellor: [getAp] :: Ap -> f a
+ Propellor: [getAp] :: Ap (f :: k -> Type) (a :: k) -> f a
- Propellor.Base: withCurrentDirectory :: () => FilePath -> IO a -> IO a
+ Propellor.Base: withCurrentDirectory :: FilePath -> IO a -> IO a
- Propellor.Container: propagateContainer :: (IncludesInfo metatypes ~ 'True, IsContainer c) => String -> c -> (PropagateInfo -> Bool) -> Property metatypes -> Property metatypes
+ Propellor.Container: propagateContainer :: (IncludesInfo metatypes ~ 'True, IsContainer c) => String -> c -> (PropagateInfo -> Bool) -> Property metatypes -> Property metatypes
- Propellor.Info: addInfoProperty :: IncludesInfo metatypes ~ 'True => Property metatypes -> Info -> Property metatypes
+ Propellor.Info: addInfoProperty :: IncludesInfo metatypes ~ 'True => Property metatypes -> Info -> Property metatypes
- Propellor.PrivData: withPrivData :: (IsContext c, IsPrivDataSource s, IncludesInfo metatypes ~ 'True) => s -> c -> (((PrivData -> Propellor Result) -> Propellor Result) -> Property metatypes) -> Property metatypes
+ Propellor.PrivData: withPrivData :: (IsContext c, IsPrivDataSource s, IncludesInfo metatypes ~ 'True) => s -> c -> (((PrivData -> Propellor Result) -> Propellor Result) -> Property metatypes) -> Property metatypes
- Propellor.PrivData: withSomePrivData :: (IsContext c, IsPrivDataSource s, IncludesInfo metatypes ~ 'True) => [s] -> c -> ((((PrivDataField, PrivData) -> Propellor Result) -> Propellor Result) -> Property metatypes) -> Property metatypes
+ Propellor.PrivData: withSomePrivData :: (IsContext c, IsPrivDataSource s, IncludesInfo metatypes ~ 'True) => [s] -> c -> ((((PrivDataField, PrivData) -> Propellor Result) -> Propellor Result) -> Property metatypes) -> Property metatypes
- Propellor.PropAccum: (!) :: CheckCombinableNote x z (NoteFor ( 'Text "!")) => Props (MetaTypes x) -> RevertableProperty (MetaTypes y) (MetaTypes z) -> Props (MetaTypes (Combine x z))
+ Propellor.PropAccum: (!) :: CheckCombinableNote x z (NoteFor ('Text "!")) => Props (MetaTypes x) -> RevertableProperty (MetaTypes y) (MetaTypes z) -> Props (MetaTypes (Combine x z))
- Propellor.PropAccum: (&) :: (IsProp p, MetaTypes y ~ GetMetaTypes p, CheckCombinableNote x y (NoteFor ( 'Text "&"))) => Props (MetaTypes x) -> p -> Props (MetaTypes (Combine x y))
+ Propellor.PropAccum: (&) :: (IsProp p, MetaTypes y ~ GetMetaTypes p, CheckCombinableNote x y (NoteFor ('Text "&"))) => Props (MetaTypes x) -> p -> Props (MetaTypes (Combine x y))
- Propellor.PropAccum: (&^) :: (IsProp p, MetaTypes y ~ GetMetaTypes p, CheckCombinableNote x y (NoteFor ( 'Text "&^"))) => Props (MetaTypes x) -> p -> Props (MetaTypes (Combine x y))
+ Propellor.PropAccum: (&^) :: (IsProp p, MetaTypes y ~ GetMetaTypes p, CheckCombinableNote x y (NoteFor ('Text "&^"))) => Props (MetaTypes x) -> p -> Props (MetaTypes (Combine x y))
- Propellor.Property: pickOS :: HasCallStack => (SingKind ( 'KProxy :: KProxy ka), SingKind ( 'KProxy :: KProxy kb), DemoteRep ( 'KProxy :: KProxy ka) ~ [MetaType], DemoteRep ( 'KProxy :: KProxy kb) ~ [MetaType], SingI c) => Property (MetaTypes (a :: ka)) -> Property (MetaTypes (b :: kb)) -> Property (MetaTypes c)
+ Propellor.Property: pickOS :: HasCallStack => (SingKind ('KProxy :: KProxy ka), SingKind ('KProxy :: KProxy kb), DemoteRep ('KProxy :: KProxy ka) ~ [MetaType], DemoteRep ('KProxy :: KProxy kb) ~ [MetaType], SingI c) => Property (MetaTypes (a :: ka)) -> Property (MetaTypes (b :: kb)) -> Property (MetaTypes c)
- Propellor.Types: type ArchLinux = MetaTypes '[ 'Targeting 'OSArchLinux]
+ Propellor.Types: type ArchLinux = MetaTypes '[ 'Targeting 'OSArchLinux]
- Propellor.Types: type Buntish = MetaTypes '[ 'Targeting 'OSBuntish]
+ Propellor.Types: type Buntish = MetaTypes '[ 'Targeting 'OSBuntish]
- Propellor.Types: type Debian = MetaTypes '[ 'Targeting 'OSDebian]
+ Propellor.Types: type Debian = MetaTypes '[ 'Targeting 'OSDebian]
- Propellor.Types: type DebianLike = MetaTypes '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish]
+ Propellor.Types: type DebianLike = MetaTypes '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish]
- Propellor.Types: type FreeBSD = MetaTypes '[ 'Targeting 'OSFreeBSD]
+ Propellor.Types: type FreeBSD = MetaTypes '[ 'Targeting 'OSFreeBSD]
- Propellor.Types: type Linux = MetaTypes '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish, 'Targeting 'OSArchLinux]
+ Propellor.Types: type Linux = MetaTypes '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish, 'Targeting 'OSArchLinux]
- Propellor.Types: type UnixLike = MetaTypes '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish, 'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD]
+ Propellor.Types: type UnixLike = MetaTypes '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish, 'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD]
- Propellor.Types.MetaTypes: type ArchLinux = MetaTypes '[ 'Targeting 'OSArchLinux]
+ Propellor.Types.MetaTypes: type ArchLinux = MetaTypes '[ 'Targeting 'OSArchLinux]
- Propellor.Types.MetaTypes: type Buntish = MetaTypes '[ 'Targeting 'OSBuntish]
+ Propellor.Types.MetaTypes: type Buntish = MetaTypes '[ 'Targeting 'OSBuntish]
- Propellor.Types.MetaTypes: type Debian = MetaTypes '[ 'Targeting 'OSDebian]
+ Propellor.Types.MetaTypes: type Debian = MetaTypes '[ 'Targeting 'OSDebian]
- Propellor.Types.MetaTypes: type DebianLike = MetaTypes '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish]
+ Propellor.Types.MetaTypes: type DebianLike = MetaTypes '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish]
- Propellor.Types.MetaTypes: type DelayError (err :: ErrorMessage) = Eval (DelayErrorFcf err :: k -> Type)
+ Propellor.Types.MetaTypes: type DelayError (err :: ErrorMessage) = Eval DelayErrorFcf err :: k -> Type
- Propellor.Types.MetaTypes: type FreeBSD = MetaTypes '[ 'Targeting 'OSFreeBSD]
+ Propellor.Types.MetaTypes: type FreeBSD = MetaTypes '[ 'Targeting 'OSFreeBSD]
- Propellor.Types.MetaTypes: type Linux = MetaTypes '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish, 'Targeting 'OSArchLinux]
+ Propellor.Types.MetaTypes: type Linux = MetaTypes '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish, 'Targeting 'OSArchLinux]
- Propellor.Types.MetaTypes: type UnixLike = MetaTypes '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish, 'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD]
+ Propellor.Types.MetaTypes: type UnixLike = MetaTypes '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish, 'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD]
- Propellor.Types.Singletons: class (kparam ~ 'KProxy) => SingKind (kparam :: KProxy k) where {
+ Propellor.Types.Singletons: class (kparam ~ 'KProxy) => SingKind (kparam :: KProxy k) where {
- Propellor.Utilities: withCreateProcess :: () => CreateProcess -> (Maybe Handle -> Maybe Handle -> Maybe Handle -> ProcessHandle -> IO a) -> IO a
+ Propellor.Utilities: withCreateProcess :: CreateProcess -> (Maybe Handle -> Maybe Handle -> Maybe Handle -> ProcessHandle -> IO a) -> IO a
- Propellor.Utilities: withCurrentDirectory :: () => FilePath -> IO a -> IO a
+ Propellor.Utilities: withCurrentDirectory :: FilePath -> IO a -> IO a
Files
- CHANGELOG +15/−0
- config.hs +458/−16
- debian/changelog +15/−0
- executables/propellor-config.hs +458/−16
- joeyconfig.hs +6/−151
- propellor.cabal +4/−4
- src/Propellor/Property/Apt.hs +2/−3
- src/Propellor/Property/Network.hs +23/−8
- src/Propellor/Property/SiteSpecific/Branchable.hs +0/−1
- src/Propellor/Property/SiteSpecific/JoeySites.hs +14/−86
- src/Propellor/Property/Sudo.hs +12/−1
- src/Utility/HumanNumber.hs +8/−4
CHANGELOG view
@@ -1,3 +1,18 @@+propellor (5.13) unstable; urgency=medium++ * Network: Added support for network interfaces with several address+ stanzas, eg ipv4 and ipv6.+ Thanks, Nicolas Schodet+ * Sudo.enabledFor: Deal with new @includedir syntax in sudoers file.+ * Apt.securityUpdates: Stop generating testing-security lines, as+ testing-security is unused per debian documentation.+ * Utility.HumanNumber: Fix rounding bug that could result in+ sometimes quite wrong values, eg "1.1 GB" when the input value was a+ few bytes less than 2 GB. Properties in Ccache and Journald that+ used it to generate config files were affected by this bug.++ -- Joey Hess <id@joeyh.name> Fri, 30 Jul 2021 10:02:19 -0400+ propellor (5.12) unstable; urgency=medium * Worked around a situation where ghc uses insane amounts of memory
config.hs view
@@ -1,29 +1,471 @@--- This is the main configuration file for Propellor, and is used to build--- the propellor program.+-- This is the live config file used by propellor's author.+-- https://propellor.branchable.com/+module Main where import Propellor+import Propellor.Property.Scheduled+import Propellor.Property.DiskImage+import Propellor.Property.Chroot+import Propellor.Property.Machine+import Propellor.Property.Bootstrap import qualified Propellor.Property.File as File import qualified Propellor.Property.Apt as Apt+import qualified Propellor.Property.Network as Network+import qualified Propellor.Property.Ssh as Ssh import qualified Propellor.Property.Cron as Cron+import qualified Propellor.Property.Sudo as Sudo import qualified Propellor.Property.User as User--main :: IO ()-main = defaultMain hosts+import qualified Propellor.Property.Hostname as Hostname+import qualified Propellor.Property.Tor as Tor+import qualified Propellor.Property.Dns as Dns+import qualified Propellor.Property.Git as Git+import qualified Propellor.Property.Postfix as Postfix+import qualified Propellor.Property.Apache as Apache+import qualified Propellor.Property.LetsEncrypt as LetsEncrypt+import qualified Propellor.Property.Locale as Locale+import qualified Propellor.Property.Grub as Grub+import qualified Propellor.Property.Borg as Borg+import qualified Propellor.Property.OpenId as OpenId+import qualified Propellor.Property.Systemd as Systemd+import qualified Propellor.Property.Journald as Journald+import qualified Propellor.Property.Fail2Ban as Fail2Ban+import qualified Propellor.Property.Laptop as Laptop+import qualified Propellor.Property.LightDM as LightDM+import qualified Propellor.Property.HostingProvider.Linode as Linode+import qualified Propellor.Property.SiteSpecific.GitHome as GitHome+import qualified Propellor.Property.SiteSpecific.GitAnnexBuilder as GitAnnexBuilder+import qualified Propellor.Property.SiteSpecific.Branchable as Branchable+import qualified Propellor.Property.SiteSpecific.JoeySites as JoeySites --- The hosts propellor knows about.-hosts :: [Host]-hosts =- [ mybox- ]+main :: IO () -- _ ______`| ,-.__+main = defaultMain hosts -- / \___-=O`/|O`/__| (____.'+ {- Propellor -- \ / | / ) _.-"-._+ Deployed -} -- `/-==__ _/__|/__=-| ( \_+hosts :: [Host] -- * \ | | '--------'+hosts = -- (o) `+ [ darkstar+ , dragon+ , oyster+ , orca+ , honeybee+ , kite+ , beaver+ , sow+ , mouse+ , peregrine+ , pell+ ] ++ monsters --- An example host.-mybox :: Host-mybox = host "mybox.example.com" $ props+darkstar :: Host+darkstar = host "darkstar.kitenet.net" $ props & osDebian Unstable X86_64- & Apt.stdSourcesList+ & ipv6 "2001:4830:1600:187::2"+ & Hostname.sane+ & Hostname.mailname+ & Apt.serviceInstalledRunning "swapspace"+ & Laptop.powertopAutoTuneOnBoot+ & Laptop.trimSSD+ & Grub.cmdline_Linux_default "i915.enable_psr=1"+ ! Grub.cmdline_Linux_default "quiet"+ & User.hasGroup (User "joey") (Group "dialout")++ & JoeySites.dkimMilter+ & JoeySites.postfixSaslPasswordClient+ -- & JoeySites.alarmClock "*-*-* 7:30" (User "joey")+ -- "/usr/bin/timeout 45m /home/joey/bin/goodmorning"+ & JoeySites.laptopSoftware+ & JoeySites.userDirHtml+ & Ssh.userKeys (User "joey") hostContext+ [ (SshEd25519, "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAICfFntnesZcYz2B2T41ay45igfckXRSh5uVffkuCQkLv joey@darkstar")+ ]+ & imageBuiltFor honeybee+ (RawDiskImage "/srv/honeybee.img")+ (Debootstrapped mempty)++dragon :: Host+dragon = host "dragon.kitenet.net" $ props+ & ipv6 "2001:4830:1600:187::2"+ & JoeySites.dkimMilter+ & JoeySites.postfixSaslPasswordClient++oyster :: Host+oyster = host "oyster.kitenet.net" $ props+ & standardSystem (Stable "buster") X86_64+ ["Unreliable server. Anything here may be lost at any time!" ]+ & ipv4 "45.138.157.89"++ & User.hasPassword (User "root") & Apt.unattendedUpgrades- & Apt.installed ["etckeeper"]++orca :: Host+orca = host "orca.kitenet.net" $ props+ & standardSystem Unstable X86_64 [ "Main git-annex build box." ]+ & ipv4 "138.38.108.179"++ & Apt.unattendedUpgrades+ & Postfix.satellite+ & Apt.serviceInstalledRunning "ntp"+ & Systemd.persistentJournal++ & Systemd.nspawned (GitAnnexBuilder.autoBuilderContainer+ GitAnnexBuilder.standardAutoBuilder+ Unstable X86_64 Nothing (Cron.Times "15 * * * *") "2h")+ & Systemd.nspawned (GitAnnexBuilder.autoBuilderContainer+ GitAnnexBuilder.standardAutoBuilder+ Unstable X86_32 Nothing (Cron.Times "30 * * * *") "2h")+ & Systemd.nspawned (GitAnnexBuilder.autoBuilderContainer+ GitAnnexBuilder.stackAutoBuilder+ (Stable "jessie") X86_32 (Just "ancient") (Cron.Times "45 * * * *") "2h")+ & Systemd.nspawned (GitAnnexBuilder.autoBuilderContainer+ GitAnnexBuilder.standardAutoBuilder+ Testing ARM64 Nothing (Cron.Times "1 * * * *") "4h")++honeybee :: Host+honeybee = host "honeybee.kitenet.net" $ props+ & standardSystem Testing ARMHF+ [ "Home router and arm git-annex build box." ]+ & Apt.removed ["rsyslog"]+ + & cubietech_Cubietruck+ & hasPartition+ ( partition EXT3+ `mountedAt` "/"+ `setSize` MegaBytes 16000+ )+ & JoeySites.cubieTruckOneWire+ & Systemd.persistentJournal+ & Apt.installed ["firmware-misc-nonfree"] -- wifi+ & Apt.serviceInstalledRunning "ntp" -- no hardware clock+ & bootstrappedFrom GitRepoOutsideChroot+ & Ssh.hostKeys hostContext+ [ (SshEd25519, "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIIS/hDYq1MAxfOBf49htym3BOYlx4Gk9SDpiHjv7u6IC")+ ]+ & Ssh.userKeys (User "joey") hostContext+ [ (SshEd25519, "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIAYgEgsDmN26goPBGPN0HIvtkZfxlc996nPfBPDWxGuh")+ ]++ & JoeySites.house+ (User "joey")+ hosts+ (Context "house.joeyh.name")+ (SshEd25519, "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIMAmVYddg/RgCbIj+cLcEiddeFXaYFnbEJ3uGj9G/EyV joey@honeybee")+ & JoeySites.homeRouter+ & JoeySites.homeNAS+ & Apt.installed ["mtr-tiny", "iftop", "screen"]+ & Postfix.satellite++ & check (not <$> hasContainerCapability Systemd.FilesystemContained) + (setupRevertableProperty autobuilder)+ -- In case compiler needs more than available ram+ & Apt.serviceInstalledRunning "swapspace"+ where+ autobuilder = Systemd.nspawned $ GitAnnexBuilder.autoBuilderContainer+ (GitAnnexBuilder.armAutoBuilder GitAnnexBuilder.standardAutoBuilder)+ Testing ARMEL Nothing (Cron.Times "15 15 * * *") "10h"++-- This is not a complete description of kite, since it's a+-- multiuser system with eg, user passwords that are not deployed+-- with propellor.+kite :: Host+kite = host "kite.kitenet.net" $ props+ & standardSystemUnhardened Testing X86_64 [ "Welcome to kite!" ]+ & ipv4 "66.228.36.95"+ & ipv6 "2600:3c03::f03c:91ff:fe73:b0d2"+ & alias "kitenet.net"+ & Ssh.hostKeys (Context "kitenet.net")+ [ (SshDsa, "ssh-dss AAAAB3NzaC1kc3MAAACBAO9tnPUT4p+9z7K6/OYuiBNHaij4Nzv5YVBih1vMl+ALz0gYAj8RWJzXmqp5buFAyfgOoLw+H9s1bBS01Sy3i07Dm6cx1fWG4RXL/E/3w1tavX99GD2bBxDBu890ebA5Tp+eFRJkS9+JwSvFiF6CP7NbVjifCagoUO56Ig048RwDAAAAFQDPY2xM3q6KwsVQliel23nrd0rV2QAAAIEAga3hj1hL00rYPNnAUzT8GAaSP62S4W68lusErH+KPbsMwFBFY/Ib1FVf8k6Zn6dZLh/HH/RtJi0JwdzPI1IFW+lwVbKfwBvhQ1lw9cH2rs1UIVgi7Wxdgfy8gEWxf+QIqn62wG+Ulf/HkWGvTrRpoJqlYRNS/gnOWj9Z/4s99koAAACBAM/uJIo2I0nK15wXiTYs/NYUZA7wcErugFn70TRbSgduIFH6U/CQa3rgHJw9DCPCQJLq7pwCnFH7too/qaK+czDk04PsgqV0+Jc7957gU5miPg50d60eJMctHV4eQ1FpwmGGfXxRBR9k2ZvikWYatYir3L6/x1ir7M0bA9IzNU45")+ , (SshRsa, "ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAIEA2QAJEuvbTmaN9ex9i9bjPhMGj+PHUYq2keIiaIImJ+8mo+yKSaGUxebG4tpuDPx6KZjdycyJt74IXfn1voGUrfzwaEY9NkqOP3v6OWTC3QeUGqDCeJ2ipslbEd9Ep9XBp+/ldDQm60D0XsIZdmDeN6MrHSbKF4fXv1bqpUoUILk=")+ , (SshEcdsa, "ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBLF+dzqBJZix+CWUkAd3Bd3cofFCKwHMNRIfwx1G7dL4XFe6fMKxmrNetQcodo2edyufwoPmCPr3NmnwON9vyh0=")+ , (SshEd25519, "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIFZftKMnH/zH29BHMKbcBO4QsgTrstYFVhbrzrlRzBO3")+ ]++ & Network.preserveStatic "eth0" `requires` Network.cleanInterfacesFile+ & Apt.installed ["linux-image-amd64"]+ & Apt.serviceInstalledRunning "swapspace"+ & Linode.serialGrub+ & Linode.mlocateEnabled+ & Apt.unattendedUpgrades+ & Systemd.installed+ & Systemd.persistentJournal+ & Journald.systemMaxUse "500MiB"+ & Ssh.passwordAuthentication True+ & Fail2Ban.installed -- since ssh password authentication is allowed+ -- Allow ssh -R to forward ports via kite+ & Ssh.setSshdConfig "GatewayPorts" "clientspecified"+ & Apt.serviceInstalledRunning "ntp"+ & "/etc/timezone" `File.hasContent` ["US/Eastern"]+ + & Borg.backup "/" (JoeySites.rsyncNetBorgRepo "kite.borg" []) Cron.Daily+ [ "--exclude=/proc/*"+ , "--exclude=/sys/*"+ , "--exclude=/run/*"+ , "--exclude=/mnt/*"+ , "--exclude=/tmp/*"+ , "--exclude=/var/tmp/*"+ , "--exclude=/var/cache/*"+ , "--exclude=/var/lib/swapspace/*"+ , "--exclude=/var/lib/container/*"+ , "--exclude=/home/joey/lib"+ -- These directories are backed up and restored separately.+ , "--exclude=/srv/git"+ ]+ [ Borg.KeepDays 7+ , Borg.KeepWeeks 4+ , Borg.KeepMonths 3+ ]+ `requires` Ssh.knownHost hosts "usw-s002.rsync.net" (User "root")+ `requires` Ssh.userKeys (User "root")+ (Context "kite.kitenet.net")+ [ (SshEd25519, "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIKyciu8E8qspcO8lnTSUBAxUdYfmk7FaFlvT5yxUaP+0 root@kite")+ ]++ & alias "smtp.kitenet.net"+ & alias "imap.kitenet.net"+ & alias "pop.kitenet.net"+ & alias "mail.kitenet.net"+ & JoeySites.kiteMailServer++ & JoeySites.legacyWebSites+ & File.ownerGroup "/srv/web" (User "joey") (Group "joey")+ & Apt.installed ["analog"]++ & alias "git.kitenet.net"+ & alias "git.joeyh.name"+ & JoeySites.gitServer hosts++ & JoeySites.downloads+ & JoeySites.gitAnnexDistributor+ & JoeySites.tmp++ & Apt.installed+ [ "git-annex", "myrepos"+ , "build-essential", "make"+ , "rss2email", "archivemail"+ , "devscripts"+ -- Some users have zsh as their login shell.+ , "zsh"+ ]++ & alias "znc.kitenet.net"+ & JoeySites.ircBouncer++ & alias "kgb.kitenet.net"+ & JoeySites.kgbServer+ + & Systemd.nspawned ancientKitenet+ ! Systemd.nspawned openidProvider+ + & alias "podcatcher.kitenet.net"+ & JoeySites.podcatcher++ & JoeySites.scrollBox+ & alias "scroll.joeyh.name"+ & alias "us.scroll.joeyh.name"++ & alias "ns4.kitenet.net"+ & myDnsPrimary "kitenet.net"+ [ (RelDomain "mouse-onion", CNAME $ AbsDomain "htieo6yu2qtcn2j3.onion")+ , (RelDomain "beaver-onion", CNAME $ AbsDomain "tl4xsvaxryjylgxs.onion")+ , (RelDomain "peregrine-onion", CNAME $ AbsDomain "rsdwvaabir6ty2kdzblq7wdda26ib4fuc6hzxzwum75jbn6thqbojvid.onion")+ , (RelDomain "sow-onion", CNAME $ AbsDomain "urt4g2tq32qktgtp.onion")+ ]+ & myDnsPrimary "joeyh.name" []+ & myDnsPrimary "ikiwiki.info" []+ & myDnsPrimary "olduse.net"+ [ (RelDomain "article", CNAME $ AbsDomain "virgil.koldfront.dk")+ ]+ ! myDnsPrimary "quarantimer.app" []+ & alias "ns4.branchable.com"+ & branchableSecondary+ & Dns.secondaryFor ["animx"] hosts "animx.eu.org"+ -- Use its own name server (amoung other things this avoids+ -- spamassassin URIBL_BLOCKED.+ & "/etc/resolv.conf" `File.hasContent`+ [ "nameserver 127.0.0.1"+ , "domain kitenet.net"+ , "search kitenet.net"+ ]+ + & alias "debug-me.joeyh.name"+ & Apt.installed ["debug-me", "debug-me-server"]+ & Systemd.enabled "debug-me"++ -- testing+ & Apache.httpsVirtualHost "letsencrypt.joeyh.name" "/var/www/html"+ (LetsEncrypt.AgreeTOS (Just "id@joeyh.name"))+ & alias "letsencrypt.joeyh.name"++beaver :: Host+beaver = host "beaver.kitenet.net" $ props & Apt.installed ["ssh"]+ & Ssh.hostPubKey SshDsa "ssh-dss AAAAB3NzaC1kc3MAAACBAIrLX260fY0Jjj/p0syNhX8OyR8hcr6feDPGOj87bMad0k/w/taDSOzpXe0Wet7rvUTbxUjH+Q5wPd4R9zkaSDiR/tCb45OdG6JsaIkmqncwe8yrU+pqSRCxttwbcFe+UU+4AAcinjVedZjVRDj2rRaFPc9BXkPt7ffk8GwEJ31/AAAAFQCG/gOjObsr86vvldUZHCteaJttNQAAAIB5nomvcqOk/TD07DLaWKyG7gAcW5WnfY3WtnvLRAFk09aq1EuiJ6Yba99Zkb+bsxXv89FWjWDg/Z3Psa22JMyi0HEDVsOevy/1sEQ96AGH5ijLzFInfXAM7gaJKXASD7hPbVdjySbgRCdwu0dzmQWHtH+8i1CMVmA2/a5Y/wtlJAAAAIAUZj2US2D378jBwyX1Py7e4sJfea3WSGYZjn4DLlsLGsB88POuh32aOChd1yzF6r6C2sdoPBHQcWBgNGXcx4gF0B5UmyVHg3lIX2NVSG1ZmfuLNJs9iKNu4cHXUmqBbwFYQJBvB69EEtrOw4jSbiTKwHFmqdA/mw1VsMB+khUaVw=="+ & Tor.installed+ & Tor.hiddenServiceAvailable "ssh" (Port 22)++sow :: Host+sow = host "sow.kitenet.net" $ props+ & Apt.installed ["ssh"]+ & Ssh.hostPubKey SshDsa "ssh-dss AAAAB3NzaC1kc3MAAACBAIrLX260fY0Jjj/p0syNhX8OyR8hcr6feDPGOj87bMad0k/w/taDSOzpXe0Wet7rvUTbxUjH+Q5wPd4R9zkaSDiR/tCb45OdG6JsaIkmqncwe8yrU+pqSRCxttwbcFe+UU+4AAcinjVedZjVRDj2rRaFPc9BXkPt7ffk8GwEJ31/AAAAFQCG/gOjObsr86vvldUZHCteaJttNQAAAIB5nomvcqOk/TD07DLaWKyG7gAcW5WnfY3WtnvLRAFk09aq1EuiJ6Yba99Zkb+bsxXv89FWjWDg/Z3Psa22JMyi0HEDVsOevy/1sEQ96AGH5ijLzFInfXAM7gaJKXASD7hPbVdjySbgRCdwu0dzmQWHtH+8i1CMVmA2/a5Y/wtlJAAAAIAUZj2US2D378jBwyX1Py7e4sJfea3WSGYZjn4DLlsLGsB88POuh32aOChd1yzF6r6C2sdoPBHQcWBgNGXcx4gF0B5UmyVHg3lIX2NVSG1ZmfuLNJs9iKNu4cHXUmqBbwFYQJBvB69EEtrOw4jSbiTKwHFmqdA/mw1VsMB+khUaVw=="+ & Tor.installed+ & Tor.hiddenServiceAvailable "ssh" (Port 22)++mouse :: Host+mouse = host "mouse.kitenet.net" $ props+ & ipv4 "67.223.19.96"+ & Apt.installed ["ssh"]+ & Tor.installed+ & Tor.hiddenServiceAvailable "ssh" (Port 22)++peregrine :: Host+peregrine = host "peregrine.kitenet.net" $ props+ & Apt.installed ["ssh", "screen", "variety", "git-annex"]+ & Tor.installed+ & Tor.hiddenServiceAvailable "ssh" (Port 22)+ & LightDM.autoLogin (User "desktop")++-- Branchable is not completely deployed with propellor yet.+pell :: Host+pell = host "pell.branchable.com" $ props+ & alias "branchable.com"+ & ipv4 "66.228.46.55"+ & ipv6 "2600:3c03::f03c:91ff:fedf:c0e5"++ -- All the websites I host at branchable that don't use+ -- branchable.com dns.+ & alias "olduse.net"+ & alias "www.olduse.net"+ & alias "www.kitenet.net"+ & alias "joeyh.name"+ & alias "www.joeyh.name"+ & alias "campaign.joeyh.name"+ & alias "ikiwiki.info"+ & alias "www.ikiwiki.info"+ & alias "git.ikiwiki.info"+ & alias "l10n.ikiwiki.info"+ & alias "dist-bugs.kitenet.net"+ & alias "family.kitenet.net"++ & osDebian (Stable "buster") X86_32+ & Apt.installed ["linux-image-686-pae"]+ & Apt.stdSourcesList `onChange` Apt.upgrade+ & Apt.unattendedUpgrades+ & Branchable.server hosts+ & Linode.serialGrub++++ --' __|II| ,.+ ---- __|II|II|__ ( \_,/\+--'-------'\o/-'-.-'-.-'-.- __|II|II|II|II|___/ __/ -'-.-'-.-'-.-'-.-'-.-'-+-------------------------- | [Containers] / --------------------------+-------------------------- : / ---------------------------+--------------------------- \____, o ,' ----------------------------+---------------------------- '--,___________,' -----------------------------++-- Exhibit: kite's 90's website on port 1994.+ancientKitenet :: Systemd.Container+ancientKitenet = Systemd.debContainer "ancient-kitenet" $ props+ & standardContainer (Stable "buster")+ & alias hn+ & Git.cloned (User "root") "git://kitenet-net.branchable.com/" "/var/www/html"+ (Just "remotes/origin/old-kitenet.net")+ & Apache.installed+ & Apache.listenPorts [p]+ & Apache.virtualHost hn p "/var/www/html"+ & Apache.siteDisabled "000-default"+ where+ p = Port 1994+ hn = "ancient.kitenet.net"++-- My own openid provider. Uses php, so containerized for security+-- and administrative sanity.+openidProvider :: Systemd.Container+openidProvider = Systemd.debContainer "openid-provider" $ props+ -- simpleid is not in buster+ & standardContainer (Stable "stretch")+ & alias hn+ & OpenId.providerFor [User "joey", User "liw"] hn (Just (Port 8086))+ where+ hn = "openid.kitenet.net"++type Motd = [String]++-- This is my standard system setup.+standardSystem :: DebianSuite -> Architecture -> Motd -> Property (HasInfo + Debian)+standardSystem suite arch motd =+ standardSystemUnhardened suite arch motd+ `before` Ssh.noPasswords++standardSystemUnhardened :: DebianSuite -> Architecture -> Motd -> Property (HasInfo + Debian)+standardSystemUnhardened suite arch motd = propertyList "standard system" $ props+ & osDebian suite arch+ & Hostname.sane+ & Hostname.mailname+ & Hostname.searchDomain+ & Locale.available "en_US.UTF-8"+ & File.hasContent "/etc/motd" ("":motd++[""])+ & Apt.stdSourcesList `onChange` Apt.upgrade+ & Apt.cacheCleaned+ & Apt.installed ["etckeeper"]+ & Apt.installed ["ssh", "mosh"]+ & GitHome.installedFor (User "root") & User.hasSomePassword (User "root")- & File.dirExists "/var/www"+ & User.accountFor (User "joey")+ & User.hasSomePassword (User "joey")+ & Sudo.enabledFor (User "joey")+ & GitHome.installedFor (User "joey")+ & Apt.installed ["vim", "screen", "less"] & Cron.runPropellor (Cron.Times "30 * * * *")+ -- I use postfix, or no MTA.+ & JoeySites.noExim++-- This is my standard container setup, Featuring automatic upgrades.+standardContainer :: DebianSuite -> Property (HasInfo + Debian)+standardContainer suite = propertyList "standard container" $ props+ & osDebian suite X86_64+ -- Do not want to run mail daemon inside a random container..+ & JoeySites.noExim+ & Apt.stdSourcesList `onChange` Apt.upgrade+ & Apt.unattendedUpgrades+ & Apt.cacheCleaned++branchableSecondary :: RevertableProperty (HasInfo + DebianLike) DebianLike+branchableSecondary = Dns.secondaryFor ["branchable.com"] hosts "branchable.com"++-- Currently using kite (ns4) as primary with gandi as secondary+-- kite handles all mail.+myDnsPrimary :: Domain -> [(BindDomain, Record)] -> RevertableProperty (HasInfo + DebianLike) DebianLike+myDnsPrimary domain extras = Dns.signedPrimary (Weekly Nothing) hosts domain+ (Dns.mkSOA "ns4.kitenet.net" 100) $+ [ (RootDomain, NS $ AbsDomain "ns4.kitenet.net")+ , (RootDomain, NS $ AbsDomain "ns6.gandi.net")+ , (RootDomain, MX 0 $ AbsDomain "kitenet.net")+ , (RootDomain, TXT "v=spf1 a a:kitenet.net ~all")+ , JoeySites.domainKey+ ] ++ extras++-- Systems I don't manage with propellor,+-- but do want to track their public keys etc.+monsters :: [Host]+monsters =+ [ host "usw-s002.rsync.net" $ props+ & Ssh.hostPubKey SshEd25519 "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIB7yTEBGfQYdwG/oeL+U9XPMIh/dW7XNs9T+M79YIOrd"+ , host "ns6.gandi.net" $ props+ & ipv4 "217.70.177.40"+ , host "animx" $ props+ & ipv4 "76.7.174.49"+ ]++++ -- o+ -- ___ o o+ {-----\ / o \ ___o o+ { \ __ \ / _ (X___>-- __o+ _____________________{ ______\___ \__/ | \__/ \____ |X__>+ < \___//|\\___/\ \____________ _+ \ ___/ | \___ # # \ (-)+ \ O O O # | \ # >=)+ \______________________________# # / #__________________/ (-}++
debian/changelog view
@@ -1,3 +1,18 @@+propellor (5.13) unstable; urgency=medium++ * Network: Added support for network interfaces with several address+ stanzas, eg ipv4 and ipv6.+ Thanks, Nicolas Schodet+ * Sudo.enabledFor: Deal with new @includedir syntax in sudoers file.+ * Apt.securityUpdates: Stop generating testing-security lines, as+ testing-security is unused per debian documentation.+ * Utility.HumanNumber: Fix rounding bug that could result in+ sometimes quite wrong values, eg "1.1 GB" when the input value was a+ few bytes less than 2 GB. Properties in Ccache and Journald that+ used it to generate config files were affected by this bug.++ -- Joey Hess <id@joeyh.name> Fri, 30 Jul 2021 10:02:19 -0400+ propellor (5.12) unstable; urgency=medium * Worked around a situation where ghc uses insane amounts of memory
executables/propellor-config.hs view
@@ -1,29 +1,471 @@--- This is the main configuration file for Propellor, and is used to build--- the propellor program.+-- This is the live config file used by propellor's author.+-- https://propellor.branchable.com/+module Main where import Propellor+import Propellor.Property.Scheduled+import Propellor.Property.DiskImage+import Propellor.Property.Chroot+import Propellor.Property.Machine+import Propellor.Property.Bootstrap import qualified Propellor.Property.File as File import qualified Propellor.Property.Apt as Apt+import qualified Propellor.Property.Network as Network+import qualified Propellor.Property.Ssh as Ssh import qualified Propellor.Property.Cron as Cron+import qualified Propellor.Property.Sudo as Sudo import qualified Propellor.Property.User as User--main :: IO ()-main = defaultMain hosts+import qualified Propellor.Property.Hostname as Hostname+import qualified Propellor.Property.Tor as Tor+import qualified Propellor.Property.Dns as Dns+import qualified Propellor.Property.Git as Git+import qualified Propellor.Property.Postfix as Postfix+import qualified Propellor.Property.Apache as Apache+import qualified Propellor.Property.LetsEncrypt as LetsEncrypt+import qualified Propellor.Property.Locale as Locale+import qualified Propellor.Property.Grub as Grub+import qualified Propellor.Property.Borg as Borg+import qualified Propellor.Property.OpenId as OpenId+import qualified Propellor.Property.Systemd as Systemd+import qualified Propellor.Property.Journald as Journald+import qualified Propellor.Property.Fail2Ban as Fail2Ban+import qualified Propellor.Property.Laptop as Laptop+import qualified Propellor.Property.LightDM as LightDM+import qualified Propellor.Property.HostingProvider.Linode as Linode+import qualified Propellor.Property.SiteSpecific.GitHome as GitHome+import qualified Propellor.Property.SiteSpecific.GitAnnexBuilder as GitAnnexBuilder+import qualified Propellor.Property.SiteSpecific.Branchable as Branchable+import qualified Propellor.Property.SiteSpecific.JoeySites as JoeySites --- The hosts propellor knows about.-hosts :: [Host]-hosts =- [ mybox- ]+main :: IO () -- _ ______`| ,-.__+main = defaultMain hosts -- / \___-=O`/|O`/__| (____.'+ {- Propellor -- \ / | / ) _.-"-._+ Deployed -} -- `/-==__ _/__|/__=-| ( \_+hosts :: [Host] -- * \ | | '--------'+hosts = -- (o) `+ [ darkstar+ , dragon+ , oyster+ , orca+ , honeybee+ , kite+ , beaver+ , sow+ , mouse+ , peregrine+ , pell+ ] ++ monsters --- An example host.-mybox :: Host-mybox = host "mybox.example.com" $ props+darkstar :: Host+darkstar = host "darkstar.kitenet.net" $ props & osDebian Unstable X86_64- & Apt.stdSourcesList+ & ipv6 "2001:4830:1600:187::2"+ & Hostname.sane+ & Hostname.mailname+ & Apt.serviceInstalledRunning "swapspace"+ & Laptop.powertopAutoTuneOnBoot+ & Laptop.trimSSD+ & Grub.cmdline_Linux_default "i915.enable_psr=1"+ ! Grub.cmdline_Linux_default "quiet"+ & User.hasGroup (User "joey") (Group "dialout")++ & JoeySites.dkimMilter+ & JoeySites.postfixSaslPasswordClient+ -- & JoeySites.alarmClock "*-*-* 7:30" (User "joey")+ -- "/usr/bin/timeout 45m /home/joey/bin/goodmorning"+ & JoeySites.laptopSoftware+ & JoeySites.userDirHtml+ & Ssh.userKeys (User "joey") hostContext+ [ (SshEd25519, "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAICfFntnesZcYz2B2T41ay45igfckXRSh5uVffkuCQkLv joey@darkstar")+ ]+ & imageBuiltFor honeybee+ (RawDiskImage "/srv/honeybee.img")+ (Debootstrapped mempty)++dragon :: Host+dragon = host "dragon.kitenet.net" $ props+ & ipv6 "2001:4830:1600:187::2"+ & JoeySites.dkimMilter+ & JoeySites.postfixSaslPasswordClient++oyster :: Host+oyster = host "oyster.kitenet.net" $ props+ & standardSystem (Stable "buster") X86_64+ ["Unreliable server. Anything here may be lost at any time!" ]+ & ipv4 "45.138.157.89"++ & User.hasPassword (User "root") & Apt.unattendedUpgrades- & Apt.installed ["etckeeper"]++orca :: Host+orca = host "orca.kitenet.net" $ props+ & standardSystem Unstable X86_64 [ "Main git-annex build box." ]+ & ipv4 "138.38.108.179"++ & Apt.unattendedUpgrades+ & Postfix.satellite+ & Apt.serviceInstalledRunning "ntp"+ & Systemd.persistentJournal++ & Systemd.nspawned (GitAnnexBuilder.autoBuilderContainer+ GitAnnexBuilder.standardAutoBuilder+ Unstable X86_64 Nothing (Cron.Times "15 * * * *") "2h")+ & Systemd.nspawned (GitAnnexBuilder.autoBuilderContainer+ GitAnnexBuilder.standardAutoBuilder+ Unstable X86_32 Nothing (Cron.Times "30 * * * *") "2h")+ & Systemd.nspawned (GitAnnexBuilder.autoBuilderContainer+ GitAnnexBuilder.stackAutoBuilder+ (Stable "jessie") X86_32 (Just "ancient") (Cron.Times "45 * * * *") "2h")+ & Systemd.nspawned (GitAnnexBuilder.autoBuilderContainer+ GitAnnexBuilder.standardAutoBuilder+ Testing ARM64 Nothing (Cron.Times "1 * * * *") "4h")++honeybee :: Host+honeybee = host "honeybee.kitenet.net" $ props+ & standardSystem Testing ARMHF+ [ "Home router and arm git-annex build box." ]+ & Apt.removed ["rsyslog"]+ + & cubietech_Cubietruck+ & hasPartition+ ( partition EXT3+ `mountedAt` "/"+ `setSize` MegaBytes 16000+ )+ & JoeySites.cubieTruckOneWire+ & Systemd.persistentJournal+ & Apt.installed ["firmware-misc-nonfree"] -- wifi+ & Apt.serviceInstalledRunning "ntp" -- no hardware clock+ & bootstrappedFrom GitRepoOutsideChroot+ & Ssh.hostKeys hostContext+ [ (SshEd25519, "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIIS/hDYq1MAxfOBf49htym3BOYlx4Gk9SDpiHjv7u6IC")+ ]+ & Ssh.userKeys (User "joey") hostContext+ [ (SshEd25519, "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIAYgEgsDmN26goPBGPN0HIvtkZfxlc996nPfBPDWxGuh")+ ]++ & JoeySites.house+ (User "joey")+ hosts+ (Context "house.joeyh.name")+ (SshEd25519, "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIMAmVYddg/RgCbIj+cLcEiddeFXaYFnbEJ3uGj9G/EyV joey@honeybee")+ & JoeySites.homeRouter+ & JoeySites.homeNAS+ & Apt.installed ["mtr-tiny", "iftop", "screen"]+ & Postfix.satellite++ & check (not <$> hasContainerCapability Systemd.FilesystemContained) + (setupRevertableProperty autobuilder)+ -- In case compiler needs more than available ram+ & Apt.serviceInstalledRunning "swapspace"+ where+ autobuilder = Systemd.nspawned $ GitAnnexBuilder.autoBuilderContainer+ (GitAnnexBuilder.armAutoBuilder GitAnnexBuilder.standardAutoBuilder)+ Testing ARMEL Nothing (Cron.Times "15 15 * * *") "10h"++-- This is not a complete description of kite, since it's a+-- multiuser system with eg, user passwords that are not deployed+-- with propellor.+kite :: Host+kite = host "kite.kitenet.net" $ props+ & standardSystemUnhardened Testing X86_64 [ "Welcome to kite!" ]+ & ipv4 "66.228.36.95"+ & ipv6 "2600:3c03::f03c:91ff:fe73:b0d2"+ & alias "kitenet.net"+ & Ssh.hostKeys (Context "kitenet.net")+ [ (SshDsa, "ssh-dss AAAAB3NzaC1kc3MAAACBAO9tnPUT4p+9z7K6/OYuiBNHaij4Nzv5YVBih1vMl+ALz0gYAj8RWJzXmqp5buFAyfgOoLw+H9s1bBS01Sy3i07Dm6cx1fWG4RXL/E/3w1tavX99GD2bBxDBu890ebA5Tp+eFRJkS9+JwSvFiF6CP7NbVjifCagoUO56Ig048RwDAAAAFQDPY2xM3q6KwsVQliel23nrd0rV2QAAAIEAga3hj1hL00rYPNnAUzT8GAaSP62S4W68lusErH+KPbsMwFBFY/Ib1FVf8k6Zn6dZLh/HH/RtJi0JwdzPI1IFW+lwVbKfwBvhQ1lw9cH2rs1UIVgi7Wxdgfy8gEWxf+QIqn62wG+Ulf/HkWGvTrRpoJqlYRNS/gnOWj9Z/4s99koAAACBAM/uJIo2I0nK15wXiTYs/NYUZA7wcErugFn70TRbSgduIFH6U/CQa3rgHJw9DCPCQJLq7pwCnFH7too/qaK+czDk04PsgqV0+Jc7957gU5miPg50d60eJMctHV4eQ1FpwmGGfXxRBR9k2ZvikWYatYir3L6/x1ir7M0bA9IzNU45")+ , (SshRsa, "ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAIEA2QAJEuvbTmaN9ex9i9bjPhMGj+PHUYq2keIiaIImJ+8mo+yKSaGUxebG4tpuDPx6KZjdycyJt74IXfn1voGUrfzwaEY9NkqOP3v6OWTC3QeUGqDCeJ2ipslbEd9Ep9XBp+/ldDQm60D0XsIZdmDeN6MrHSbKF4fXv1bqpUoUILk=")+ , (SshEcdsa, "ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBLF+dzqBJZix+CWUkAd3Bd3cofFCKwHMNRIfwx1G7dL4XFe6fMKxmrNetQcodo2edyufwoPmCPr3NmnwON9vyh0=")+ , (SshEd25519, "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIFZftKMnH/zH29BHMKbcBO4QsgTrstYFVhbrzrlRzBO3")+ ]++ & Network.preserveStatic "eth0" `requires` Network.cleanInterfacesFile+ & Apt.installed ["linux-image-amd64"]+ & Apt.serviceInstalledRunning "swapspace"+ & Linode.serialGrub+ & Linode.mlocateEnabled+ & Apt.unattendedUpgrades+ & Systemd.installed+ & Systemd.persistentJournal+ & Journald.systemMaxUse "500MiB"+ & Ssh.passwordAuthentication True+ & Fail2Ban.installed -- since ssh password authentication is allowed+ -- Allow ssh -R to forward ports via kite+ & Ssh.setSshdConfig "GatewayPorts" "clientspecified"+ & Apt.serviceInstalledRunning "ntp"+ & "/etc/timezone" `File.hasContent` ["US/Eastern"]+ + & Borg.backup "/" (JoeySites.rsyncNetBorgRepo "kite.borg" []) Cron.Daily+ [ "--exclude=/proc/*"+ , "--exclude=/sys/*"+ , "--exclude=/run/*"+ , "--exclude=/mnt/*"+ , "--exclude=/tmp/*"+ , "--exclude=/var/tmp/*"+ , "--exclude=/var/cache/*"+ , "--exclude=/var/lib/swapspace/*"+ , "--exclude=/var/lib/container/*"+ , "--exclude=/home/joey/lib"+ -- These directories are backed up and restored separately.+ , "--exclude=/srv/git"+ ]+ [ Borg.KeepDays 7+ , Borg.KeepWeeks 4+ , Borg.KeepMonths 3+ ]+ `requires` Ssh.knownHost hosts "usw-s002.rsync.net" (User "root")+ `requires` Ssh.userKeys (User "root")+ (Context "kite.kitenet.net")+ [ (SshEd25519, "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIKyciu8E8qspcO8lnTSUBAxUdYfmk7FaFlvT5yxUaP+0 root@kite")+ ]++ & alias "smtp.kitenet.net"+ & alias "imap.kitenet.net"+ & alias "pop.kitenet.net"+ & alias "mail.kitenet.net"+ & JoeySites.kiteMailServer++ & JoeySites.legacyWebSites+ & File.ownerGroup "/srv/web" (User "joey") (Group "joey")+ & Apt.installed ["analog"]++ & alias "git.kitenet.net"+ & alias "git.joeyh.name"+ & JoeySites.gitServer hosts++ & JoeySites.downloads+ & JoeySites.gitAnnexDistributor+ & JoeySites.tmp++ & Apt.installed+ [ "git-annex", "myrepos"+ , "build-essential", "make"+ , "rss2email", "archivemail"+ , "devscripts"+ -- Some users have zsh as their login shell.+ , "zsh"+ ]++ & alias "znc.kitenet.net"+ & JoeySites.ircBouncer++ & alias "kgb.kitenet.net"+ & JoeySites.kgbServer+ + & Systemd.nspawned ancientKitenet+ ! Systemd.nspawned openidProvider+ + & alias "podcatcher.kitenet.net"+ & JoeySites.podcatcher++ & JoeySites.scrollBox+ & alias "scroll.joeyh.name"+ & alias "us.scroll.joeyh.name"++ & alias "ns4.kitenet.net"+ & myDnsPrimary "kitenet.net"+ [ (RelDomain "mouse-onion", CNAME $ AbsDomain "htieo6yu2qtcn2j3.onion")+ , (RelDomain "beaver-onion", CNAME $ AbsDomain "tl4xsvaxryjylgxs.onion")+ , (RelDomain "peregrine-onion", CNAME $ AbsDomain "rsdwvaabir6ty2kdzblq7wdda26ib4fuc6hzxzwum75jbn6thqbojvid.onion")+ , (RelDomain "sow-onion", CNAME $ AbsDomain "urt4g2tq32qktgtp.onion")+ ]+ & myDnsPrimary "joeyh.name" []+ & myDnsPrimary "ikiwiki.info" []+ & myDnsPrimary "olduse.net"+ [ (RelDomain "article", CNAME $ AbsDomain "virgil.koldfront.dk")+ ]+ ! myDnsPrimary "quarantimer.app" []+ & alias "ns4.branchable.com"+ & branchableSecondary+ & Dns.secondaryFor ["animx"] hosts "animx.eu.org"+ -- Use its own name server (amoung other things this avoids+ -- spamassassin URIBL_BLOCKED.+ & "/etc/resolv.conf" `File.hasContent`+ [ "nameserver 127.0.0.1"+ , "domain kitenet.net"+ , "search kitenet.net"+ ]+ + & alias "debug-me.joeyh.name"+ & Apt.installed ["debug-me", "debug-me-server"]+ & Systemd.enabled "debug-me"++ -- testing+ & Apache.httpsVirtualHost "letsencrypt.joeyh.name" "/var/www/html"+ (LetsEncrypt.AgreeTOS (Just "id@joeyh.name"))+ & alias "letsencrypt.joeyh.name"++beaver :: Host+beaver = host "beaver.kitenet.net" $ props & Apt.installed ["ssh"]+ & Ssh.hostPubKey SshDsa "ssh-dss AAAAB3NzaC1kc3MAAACBAIrLX260fY0Jjj/p0syNhX8OyR8hcr6feDPGOj87bMad0k/w/taDSOzpXe0Wet7rvUTbxUjH+Q5wPd4R9zkaSDiR/tCb45OdG6JsaIkmqncwe8yrU+pqSRCxttwbcFe+UU+4AAcinjVedZjVRDj2rRaFPc9BXkPt7ffk8GwEJ31/AAAAFQCG/gOjObsr86vvldUZHCteaJttNQAAAIB5nomvcqOk/TD07DLaWKyG7gAcW5WnfY3WtnvLRAFk09aq1EuiJ6Yba99Zkb+bsxXv89FWjWDg/Z3Psa22JMyi0HEDVsOevy/1sEQ96AGH5ijLzFInfXAM7gaJKXASD7hPbVdjySbgRCdwu0dzmQWHtH+8i1CMVmA2/a5Y/wtlJAAAAIAUZj2US2D378jBwyX1Py7e4sJfea3WSGYZjn4DLlsLGsB88POuh32aOChd1yzF6r6C2sdoPBHQcWBgNGXcx4gF0B5UmyVHg3lIX2NVSG1ZmfuLNJs9iKNu4cHXUmqBbwFYQJBvB69EEtrOw4jSbiTKwHFmqdA/mw1VsMB+khUaVw=="+ & Tor.installed+ & Tor.hiddenServiceAvailable "ssh" (Port 22)++sow :: Host+sow = host "sow.kitenet.net" $ props+ & Apt.installed ["ssh"]+ & Ssh.hostPubKey SshDsa "ssh-dss AAAAB3NzaC1kc3MAAACBAIrLX260fY0Jjj/p0syNhX8OyR8hcr6feDPGOj87bMad0k/w/taDSOzpXe0Wet7rvUTbxUjH+Q5wPd4R9zkaSDiR/tCb45OdG6JsaIkmqncwe8yrU+pqSRCxttwbcFe+UU+4AAcinjVedZjVRDj2rRaFPc9BXkPt7ffk8GwEJ31/AAAAFQCG/gOjObsr86vvldUZHCteaJttNQAAAIB5nomvcqOk/TD07DLaWKyG7gAcW5WnfY3WtnvLRAFk09aq1EuiJ6Yba99Zkb+bsxXv89FWjWDg/Z3Psa22JMyi0HEDVsOevy/1sEQ96AGH5ijLzFInfXAM7gaJKXASD7hPbVdjySbgRCdwu0dzmQWHtH+8i1CMVmA2/a5Y/wtlJAAAAIAUZj2US2D378jBwyX1Py7e4sJfea3WSGYZjn4DLlsLGsB88POuh32aOChd1yzF6r6C2sdoPBHQcWBgNGXcx4gF0B5UmyVHg3lIX2NVSG1ZmfuLNJs9iKNu4cHXUmqBbwFYQJBvB69EEtrOw4jSbiTKwHFmqdA/mw1VsMB+khUaVw=="+ & Tor.installed+ & Tor.hiddenServiceAvailable "ssh" (Port 22)++mouse :: Host+mouse = host "mouse.kitenet.net" $ props+ & ipv4 "67.223.19.96"+ & Apt.installed ["ssh"]+ & Tor.installed+ & Tor.hiddenServiceAvailable "ssh" (Port 22)++peregrine :: Host+peregrine = host "peregrine.kitenet.net" $ props+ & Apt.installed ["ssh", "screen", "variety", "git-annex"]+ & Tor.installed+ & Tor.hiddenServiceAvailable "ssh" (Port 22)+ & LightDM.autoLogin (User "desktop")++-- Branchable is not completely deployed with propellor yet.+pell :: Host+pell = host "pell.branchable.com" $ props+ & alias "branchable.com"+ & ipv4 "66.228.46.55"+ & ipv6 "2600:3c03::f03c:91ff:fedf:c0e5"++ -- All the websites I host at branchable that don't use+ -- branchable.com dns.+ & alias "olduse.net"+ & alias "www.olduse.net"+ & alias "www.kitenet.net"+ & alias "joeyh.name"+ & alias "www.joeyh.name"+ & alias "campaign.joeyh.name"+ & alias "ikiwiki.info"+ & alias "www.ikiwiki.info"+ & alias "git.ikiwiki.info"+ & alias "l10n.ikiwiki.info"+ & alias "dist-bugs.kitenet.net"+ & alias "family.kitenet.net"++ & osDebian (Stable "buster") X86_32+ & Apt.installed ["linux-image-686-pae"]+ & Apt.stdSourcesList `onChange` Apt.upgrade+ & Apt.unattendedUpgrades+ & Branchable.server hosts+ & Linode.serialGrub++++ --' __|II| ,.+ ---- __|II|II|__ ( \_,/\+--'-------'\o/-'-.-'-.-'-.- __|II|II|II|II|___/ __/ -'-.-'-.-'-.-'-.-'-.-'-+-------------------------- | [Containers] / --------------------------+-------------------------- : / ---------------------------+--------------------------- \____, o ,' ----------------------------+---------------------------- '--,___________,' -----------------------------++-- Exhibit: kite's 90's website on port 1994.+ancientKitenet :: Systemd.Container+ancientKitenet = Systemd.debContainer "ancient-kitenet" $ props+ & standardContainer (Stable "buster")+ & alias hn+ & Git.cloned (User "root") "git://kitenet-net.branchable.com/" "/var/www/html"+ (Just "remotes/origin/old-kitenet.net")+ & Apache.installed+ & Apache.listenPorts [p]+ & Apache.virtualHost hn p "/var/www/html"+ & Apache.siteDisabled "000-default"+ where+ p = Port 1994+ hn = "ancient.kitenet.net"++-- My own openid provider. Uses php, so containerized for security+-- and administrative sanity.+openidProvider :: Systemd.Container+openidProvider = Systemd.debContainer "openid-provider" $ props+ -- simpleid is not in buster+ & standardContainer (Stable "stretch")+ & alias hn+ & OpenId.providerFor [User "joey", User "liw"] hn (Just (Port 8086))+ where+ hn = "openid.kitenet.net"++type Motd = [String]++-- This is my standard system setup.+standardSystem :: DebianSuite -> Architecture -> Motd -> Property (HasInfo + Debian)+standardSystem suite arch motd =+ standardSystemUnhardened suite arch motd+ `before` Ssh.noPasswords++standardSystemUnhardened :: DebianSuite -> Architecture -> Motd -> Property (HasInfo + Debian)+standardSystemUnhardened suite arch motd = propertyList "standard system" $ props+ & osDebian suite arch+ & Hostname.sane+ & Hostname.mailname+ & Hostname.searchDomain+ & Locale.available "en_US.UTF-8"+ & File.hasContent "/etc/motd" ("":motd++[""])+ & Apt.stdSourcesList `onChange` Apt.upgrade+ & Apt.cacheCleaned+ & Apt.installed ["etckeeper"]+ & Apt.installed ["ssh", "mosh"]+ & GitHome.installedFor (User "root") & User.hasSomePassword (User "root")- & File.dirExists "/var/www"+ & User.accountFor (User "joey")+ & User.hasSomePassword (User "joey")+ & Sudo.enabledFor (User "joey")+ & GitHome.installedFor (User "joey")+ & Apt.installed ["vim", "screen", "less"] & Cron.runPropellor (Cron.Times "30 * * * *")+ -- I use postfix, or no MTA.+ & JoeySites.noExim++-- This is my standard container setup, Featuring automatic upgrades.+standardContainer :: DebianSuite -> Property (HasInfo + Debian)+standardContainer suite = propertyList "standard container" $ props+ & osDebian suite X86_64+ -- Do not want to run mail daemon inside a random container..+ & JoeySites.noExim+ & Apt.stdSourcesList `onChange` Apt.upgrade+ & Apt.unattendedUpgrades+ & Apt.cacheCleaned++branchableSecondary :: RevertableProperty (HasInfo + DebianLike) DebianLike+branchableSecondary = Dns.secondaryFor ["branchable.com"] hosts "branchable.com"++-- Currently using kite (ns4) as primary with gandi as secondary+-- kite handles all mail.+myDnsPrimary :: Domain -> [(BindDomain, Record)] -> RevertableProperty (HasInfo + DebianLike) DebianLike+myDnsPrimary domain extras = Dns.signedPrimary (Weekly Nothing) hosts domain+ (Dns.mkSOA "ns4.kitenet.net" 100) $+ [ (RootDomain, NS $ AbsDomain "ns4.kitenet.net")+ , (RootDomain, NS $ AbsDomain "ns6.gandi.net")+ , (RootDomain, MX 0 $ AbsDomain "kitenet.net")+ , (RootDomain, TXT "v=spf1 a a:kitenet.net ~all")+ , JoeySites.domainKey+ ] ++ extras++-- Systems I don't manage with propellor,+-- but do want to track their public keys etc.+monsters :: [Host]+monsters =+ [ host "usw-s002.rsync.net" $ props+ & Ssh.hostPubKey SshEd25519 "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIB7yTEBGfQYdwG/oeL+U9XPMIh/dW7XNs9T+M79YIOrd"+ , host "ns6.gandi.net" $ props+ & ipv4 "217.70.177.40"+ , host "animx" $ props+ & ipv4 "76.7.174.49"+ ]++++ -- o+ -- ___ o o+ {-----\ / o \ ___o o+ { \ __ \ / _ (X___>-- __o+ _____________________{ ______\___ \__/ | \__/ \____ |X__>+ < \___//|\\___/\ \____________ _+ \ ___/ | \___ # # \ (-)+ \ O O O # | \ # >=)+ \______________________________# # / #__________________/ (-}++
joeyconfig.hs view
@@ -16,7 +16,6 @@ import qualified Propellor.Property.Sudo as Sudo import qualified Propellor.Property.User as User import qualified Propellor.Property.Hostname as Hostname-import qualified Propellor.Property.Fstab as Fstab import qualified Propellor.Property.Tor as Tor import qualified Propellor.Property.Dns as Dns import qualified Propellor.Property.Git as Git@@ -26,7 +25,6 @@ import qualified Propellor.Property.Locale as Locale import qualified Propellor.Property.Grub as Grub import qualified Propellor.Property.Borg as Borg-import qualified Propellor.Property.Gpg as Gpg import qualified Propellor.Property.OpenId as OpenId import qualified Propellor.Property.Systemd as Systemd import qualified Propellor.Property.Journald as Journald@@ -34,7 +32,6 @@ import qualified Propellor.Property.Laptop as Laptop import qualified Propellor.Property.LightDM as LightDM import qualified Propellor.Property.HostingProvider.Linode as Linode-import qualified Propellor.Property.HostingProvider.DigitalOcean as DigitalOcean import qualified Propellor.Property.SiteSpecific.GitHome as GitHome import qualified Propellor.Property.SiteSpecific.GitAnnexBuilder as GitAnnexBuilder import qualified Propellor.Property.SiteSpecific.Branchable as Branchable@@ -48,9 +45,8 @@ hosts = -- (o) ` [ darkstar , dragon- , clam+ , oyster , orca- , baleen , honeybee , kite , beaver@@ -58,8 +54,6 @@ , mouse , peregrine , pell- , keysafe- , quarantimer ] ++ monsters darkstar :: Host@@ -87,9 +81,6 @@ & imageBuiltFor honeybee (RawDiskImage "/srv/honeybee.img") (Debootstrapped mempty)- ! imageBuiltFor banana- (RawDiskImage "/srv/banana.img")- (Debootstrapped mempty) dragon :: Host dragon = host "dragon.kitenet.net" $ props@@ -97,46 +88,15 @@ & JoeySites.dkimMilter & JoeySites.postfixSaslPasswordClient -clam :: Host-clam = host "clam.kitenet.net" $ props+oyster :: Host+oyster = host "oyster.kitenet.net" $ props & standardSystem (Stable "buster") X86_64 ["Unreliable server. Anything here may be lost at any time!" ]- & ipv4 "46.36.36.189"+ & ipv4 "45.138.157.89" & User.hasPassword (User "root")- & Ssh.hostKeys hostContext- [ (SshEcdsa, "ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBPhfvcOuw0Yt+MnsFc4TI2gWkKi62Eajxz+TgbHMO/uRTYF8c5V8fOI3o+J/3m5+lT0S5o8j8a7xIC3COvi+AVw=")- ] & Apt.unattendedUpgrades - -- & Tor.isRelay- -- & Tor.named "kite1"- -- & Tor.bandwidthRate (Tor.PerMonth "400 GB")- - & "/etc/resolv.conf" `File.hasContent`- [ "nameserver 8.8.8.8"- , "nameserver 8.8.4.4"- , "nameserver 1.1.1.1"- , "domain kitenet.net"- , "search kitenet.net"- ]--baleen :: Host-baleen = host "baleen.kitenet.net" $ props- & standardSystem Unstable X86_64 [ "New git-annex build box." ]-- -- Not on public network; ssh access via bounce host.- & ipv4 "138.38.77.40"- - -- The root filesystem content may be lost if the VM is resized.- -- /dev/vdb contains persistent storage.- & Fstab.mounted "auto" "/dev/vdb" "/var/lib/container" mempty- - & Apt.unattendedUpgrades- & Postfix.satellite- & Apt.serviceInstalledRunning "ntp"- & Systemd.persistentJournal- orca :: Host orca = host "orca.kitenet.net" $ props & standardSystem Unstable X86_64 [ "Main git-annex build box." ]@@ -160,17 +120,6 @@ GitAnnexBuilder.standardAutoBuilder Testing ARM64 Nothing (Cron.Times "1 * * * *") "4h") -banana :: Host-banana = host "banana.kitenet.net" $ props- & lemaker_Banana_Pi- & hasPartition- ( partition EXT4- `mountedAt` "/"- `setSize` MegaBytes 950- )- & osDebian Testing ARMHF- & User.hasInsecurePassword (User "root") "root"- honeybee :: Host honeybee = host "honeybee.kitenet.net" $ props & standardSystem Testing ARMHF@@ -259,7 +208,6 @@ , "--exclude=/home/joey/lib" -- These directories are backed up and restored separately. , "--exclude=/srv/git"- , "--exclude=/var/spool/oldusenet" ] [ Borg.KeepDays 7 , Borg.KeepWeeks 4@@ -298,10 +246,6 @@ , "zsh" ] - & alias "nntp.olduse.net"- & JoeySites.oldUseNetServer hosts- & Systemd.nspawned oldusenetShellBox- & alias "znc.kitenet.net" & JoeySites.ircBouncer @@ -330,7 +274,7 @@ & myDnsPrimary "olduse.net" [ (RelDomain "article", CNAME $ AbsDomain "virgil.koldfront.dk") ]- & myDnsPrimary "quarantimer.app" []+ ! myDnsPrimary "quarantimer.app" [] & alias "ns4.branchable.com" & branchableSecondary & Dns.secondaryFor ["animx"] hosts "animx.eu.org"@@ -343,7 +287,7 @@ ] & alias "debug-me.joeyh.name"- & Apt.installed ["debug-me"]+ & Apt.installed ["debug-me", "debug-me-server"] & Systemd.enabled "debug-me" -- testing@@ -408,91 +352,8 @@ & Branchable.server hosts & Linode.serialGrub --- See https://joeyh.name/code/keysafe/servers/ for requirements.-keysafe :: Host-keysafe = host "keysafe.joeyh.name" $ props- & ipv4 "139.59.17.168"- & Hostname.sane- & Hostname.mailname- & osDebian (Stable "buster") X86_64- & Apt.stdSourcesList `onChange` Apt.upgrade- & Apt.unattendedUpgrades- & DigitalOcean.distroKernel- -- This is a 500 mb VM, so need more ram to build propellor.- & Apt.serviceInstalledRunning "swapspace"- & Cron.runPropellor (Cron.Times "30 * * * *")- & Apt.installed ["etckeeper", "sudo"]- & JoeySites.noExim- & Apt.removed ["nfs-common", "rsyslog", "acpid", "rpcbind", "at"] - & User.hasSomePassword (User "root")- & User.accountFor (User "joey")- & User.hasSomePassword (User "joey")- & Sudo.enabledFor (User "joey") - & Ssh.installed- & Ssh.randomHostKeys- & User "root" `Ssh.authorizedKeysFrom` (User "joey", darkstar)- & User "joey" `Ssh.authorizedKeysFrom` (User "joey", darkstar)- & Ssh.noPasswords-- & Tor.installed- & Tor.hiddenServiceAvailable "keysafe" (Port 4242)- `requires` Tor.hiddenServiceData "keysafe" hostContext- & Tor.bandwidthRate (Tor.PerMonth "750 GB")-- -- keysafe installed manually until package is available- & Systemd.enabled "keysafe"-- & Gpg.keyImported (Gpg.GpgKeyId "CECE11AE") (User "root")- & Ssh.knownHost hosts "usw-s002.rsync.net" (User "root")- & Ssh.userKeys (User "root")- (Context "keysafe.joeyh.name")- [ (SshEd25519, "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIEx8bK9ZbXVEgEvxQeXLjnr9cGa/QvoB459aglP529My root@keysafe")- ]- -- Note that this is not an incremental backup; it uploads the- -- whole content every time. So, only run weekly.- & Cron.niceJob "keysafe backup" Cron.Weekly (User "root") "/" backupcmd- `requires` Apt.installed ["rsync"]- where- datadir = "/var/lib/keysafe"- backupdir = "/var/backups/keysafe"- rsyncnetbackup = "2318@usw-s002.rsync.net:keysafe"- backupcmd = unwords- [ "keysafe --store-directory", datadir, "--backup-server", backupdir- , "&& rsync -a --delete --max-delete 3 ", backupdir , rsyncnetbackup- ]--quarantimer :: Host-quarantimer = host "quarantimer.app" $ props- & ipv4 "45.33.73.207"- & Hostname.sane- & Hostname.mailname- & osDebian (Stable "buster") X86_64- & Apt.stdSourcesList `onChange` Apt.upgrade- & Apt.unattendedUpgrades- & Cron.runPropellor (Cron.Times "30 * * * *")- & Apt.installed ["etckeeper", "sudo"]- & JoeySites.noExim-- & User.hasSomePassword (User "root")- & User.accountFor (User "joey")- & User.hasSomePassword (User "joey")- & Sudo.enabledFor (User "joey")- & Ssh.installed- & Ssh.randomHostKeys- & User "root" `Ssh.authorizedKeysFrom` (User "joey", darkstar)- & User "joey" `Ssh.authorizedKeysFrom` (User "joey", darkstar)- & Ssh.noPasswords-- & LetsEncrypt.letsEncrypt (LetsEncrypt.AgreeTOS (Just "id@joeyh.name"))- "quarantimer.app" "/home/joey/quarantimer/static"- & Apt.installed ["screen", "git", "ghc"]- & Apt.installed ["zlib1g-dev", "imagemagick"]- -- (Installing quarantimer not yet automated)--- --' __|II| ,. ---- __|II|II|__ ( \_,/\ --'-------'\o/-'-.-'-.-'-.- __|II|II|II|II|___/ __/ -'-.-'-.-'-.-'-.-'-.-'-@@ -515,12 +376,6 @@ where p = Port 1994 hn = "ancient.kitenet.net"--oldusenetShellBox :: Systemd.Container-oldusenetShellBox = Systemd.debContainer "oldusenet-shellbox" $ props- & standardContainer (Stable "buster")- & alias "shell.olduse.net"- & JoeySites.oldUseNetShellBox -- My own openid provider. Uses php, so containerized for security -- and administrative sanity.
propellor.cabal view
@@ -1,5 +1,5 @@ Name: propellor-Version: 5.12+Version: 5.13 Cabal-Version: 1.20 License: BSD2 Maintainer: Joey Hess <id@joeyh.name>@@ -39,7 +39,7 @@ Description: Build with type-errors library for better error messages and less memory use Library- Default-Language: Haskell98+ Default-Language: Haskell2010 GHC-Options: -Wall -fno-warn-tabs -O0 Default-Extensions: TypeOperators Hs-Source-Dirs: src@@ -239,7 +239,7 @@ Paths_propellor Executable propellor-config- Default-Language: Haskell98+ Default-Language: Haskell2010 Hs-Source-Dirs: executables Main-Is: propellor-config.hs GHC-Options: -threaded -Wall -fno-warn-tabs@@ -247,7 +247,7 @@ Build-Depends: propellor, base Executable propellor- Default-Language: Haskell98+ Default-Language: Haskell2010 Hs-Source-Dirs: executables Main-Is: wrapper.hs GHC-Options: -threaded -Wall -fno-warn-tabs
src/Propellor/Property/Apt.hs view
@@ -107,16 +107,15 @@ stdArchiveLines :: Propellor SourcesGenerator stdArchiveLines = return . binandsrc =<< getMirror --- | Only available for Stable and Testing+-- | Only available for Stable suites, not for Testing or Unstable. securityUpdates :: SourcesGenerator securityUpdates suite- | isStable suite || suite == Testing =+ | isStable suite = let l = "deb http://security.debian.org/debian-security " ++ securitysuite ++ " " ++ unwords stdSections in [l, srcLine l] | otherwise = [] where securitysuite- | suite == Testing = "testing-security" | suite `elem` map Stable releasesusingoldname = showSuite suite ++ "/updates" | otherwise = showSuite suite ++ "-security"
src/Propellor/Property/Network.hs view
@@ -10,6 +10,9 @@ -- | Options to put in a stanza of an ifupdown interfaces file. type InterfaceOptions = [(String, String)] +-- | Stanza of an ifupdown interfaces file, with header lines and options.+type InterfaceStanza = ([String], InterfaceOptions)+ ifUp :: Interface -> Property DebianLike ifUp iface = tightenTargets $ cmdProperty "ifup" [iface] `assume` MadeChange@@ -52,22 +55,29 @@ static' :: Interface -> IPAddr -> Maybe Gateway -> InterfaceOptions -> Property DebianLike static' iface addr gateway options =- interfaceFileContains (interfaceDFile iface) headerlines options'+ static'' iface [(addr, gateway, options)]++-- | Configures an interface with several stanzas (IPv4 and IPv6 for example).+static'' :: Interface -> [(IPAddr, Maybe Gateway, InterfaceOptions)] -> Property DebianLike+static'' iface confs =+ interfaceFileContains' (interfaceDFile iface) stanzas `describe` ("static IP address for " ++ iface) `requires` interfacesDEnabled where- headerlines =+ stanzas = map stanza confs+ stanza (addr, gateway, options) = (headerlines addr, options' addr gateway options)+ headerlines addr = [ "auto " ++ iface- , "iface " ++ iface ++ " " ++ inet ++ " static"+ , "iface " ++ iface ++ " " ++ (inet addr) ++ " static" ]- options' = catMaybes+ options' addr gateway options = catMaybes [ Just $ ("address", val addr) , case gateway of- Just (Gateway gaddr) -> + Just (Gateway gaddr) -> Just ("gateway", val gaddr) Nothing -> Nothing ] ++ options- inet = case addr of+ inet addr = case addr of IPv4 _ -> "inet" IPv6 _ -> "inet6" @@ -149,8 +159,13 @@ `describe` "interfaces.d directory enabled" interfaceFileContains :: FilePath -> [String] -> InterfaceOptions -> Property DebianLike-interfaceFileContains f headerlines options = tightenTargets $ hasContent f $- warning : headerlines ++ map fmt options+interfaceFileContains f headerlines options =+ interfaceFileContains' f [(headerlines, options)]++interfaceFileContains' :: FilePath -> [InterfaceStanza] -> Property DebianLike+interfaceFileContains' f stanzas = tightenTargets $ hasContent f $+ warning : concatMap stanza stanzas where+ stanza (headerlines, options) = headerlines ++ map fmt options fmt (k, v) = "\t" ++ k ++ " " ++ v warning = "# Deployed by propellor, do not edit."
src/Propellor/Property/SiteSpecific/Branchable.hs view
@@ -67,7 +67,6 @@ & Ssh.knownHost hosts "usw-s002.rsync.net" (User "root") & adminuser "joey"- & adminuser "liw" where adminuser u = propertyList ("admin user " ++ u) $ props & User.accountFor (User u)
src/Propellor/Property/SiteSpecific/JoeySites.hs view
@@ -97,86 +97,6 @@ s = d </> "login.sh" g = d </> "game.sh" -oldUseNetServer :: [Host] -> Property (HasInfo + DebianLike)-oldUseNetServer hosts = propertyList "olduse.net server" $ props- & Apt.installed ["leafnode"]- & oldUseNetInstalled "oldusenet-server"- & oldUseNetBackup- & spoolsymlink- & "/etc/news/leafnode/config" `File.hasContent`- [ "# olduse.net configuration (deployed by propellor)"- , "expire = 1000000" -- no expiry via texpire- , "server = " -- no upstream server- , "debugmode = 1"- , "allowSTRANGERS = 42" -- lets anyone connect- , "nopost = 1" -- no new posting (just gather them)- ]- & "/etc/hosts.deny" `File.lacksLine` "leafnode: ALL"- & Apt.serviceInstalledRunning "openbsd-inetd"- & File.notPresent "/etc/cron.daily/leafnode"- & File.notPresent "/etc/cron.d/leafnode"- & Cron.niceJob "oldusenet-expire" (Cron.Times "11 1 * * *") (User "news") newsspool expirecommand- & Cron.niceJob "oldusenet-uucp" (Cron.Times "*/5 * * * *") (User "news") "/" uucpcommand- & Apache.siteEnabled "nntp.olduse.net" nntpcfg- where- newsspool = "/var/spool/news"- datadir = "/var/spool/oldusenet"- expirecommand = intercalate ";"- [ "find \\( -path ./out.going -or -path ./interesting.groups -or -path './*/.overview' \\) -prune -or -type f -ctime +60 -print | xargs --no-run-if-empty rm"- , "find -type d -empty | xargs --no-run-if-empty rmdir"- ]- uucpcommand = "/usr/bin/uucp " ++ datadir- nntpcfg = apachecfg "nntp.olduse.net"- [ " DocumentRoot " ++ datadir ++ "/"- , " <Directory " ++ datadir ++ "/>"- , " Options Indexes FollowSymlinks"- , " AllowOverride None"- , Apache.allowAll- , " </Directory>"- ]-- spoolsymlink :: Property UnixLike- spoolsymlink = check (not . isSymbolicLink <$> getSymbolicLinkStatus newsspool)- (property "olduse.net spool in place" $ makeChange $ do- removeDirectoryRecursive newsspool- createSymbolicLink (datadir </> "news") newsspool- )-- oldUseNetBackup :: Property (HasInfo + DebianLike)- oldUseNetBackup = Borg.backup datadir borgrepo - (Cron.Times "33 4 * * *")- []- [Borg.KeepDays 30]- `requires` Ssh.userKeyAt (Just keyfile)- (User "root")- (Context "olduse.net")- (SshEd25519, "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIGtHhNuO/abNTrc5pyWkwXz/F8FAHw8VcET0Yh4mjgOk root@kite")- `requires` Ssh.knownHost hosts "usw-s002.rsync.net" (User "root")- borgrepo = rsyncNetBorgRepo "olduse.net.borg" [Borg.UseSshKey keyfile]- keyfile = "/root/.ssh/olduse.net.key"--oldUseNetShellBox :: Property DebianLike-oldUseNetShellBox = propertyList "olduse.net shellbox" $ props- & oldUseNetInstalled "oldusenet"- & Service.running "shellinabox"--oldUseNetInstalled :: Apt.Package -> Property DebianLike-oldUseNetInstalled pkg = check (not <$> Apt.isInstalled pkg) $- propertyList ("olduse.net " ++ pkg) $ props- & Apt.installed (words "build-essential devscripts debhelper git libncursesw5-dev libpcre3-dev pkg-config bison libicu-dev libidn11-dev libcanlock2-dev libuu-dev ghc libghc-ifelse-dev libghc-hxt-dev libghc-utf8-string-dev libghc-missingh-dev libghc-sha-dev haskell-stack")- `describe` "olduse.net build deps"- & scriptProperty- [ "rm -rf /root/tmp/oldusenet" -- idenpotency- , "git clone git://olduse.net/ /root/tmp/oldusenet/source"- , "cd /root/tmp/oldusenet/source/"- , "HOME=/root dpkg-buildpackage -us -uc"- , "dpkg -i ../" ++ pkg ++ "_*.deb || true"- , "apt-get -fy install" -- dependencies- , "rm -rf /root/tmp/oldusenet"- ]- `assume` MadeChange- `describe` "olduse.net built"- kgbServer :: Property (HasInfo + DebianLike) kgbServer = propertyList desc $ props & Apt.serviceInstalledRunning "kgb-bot"@@ -328,7 +248,7 @@ -- git-annex distribution signing key & Gpg.keyImported (Gpg.GpgKeyId "89C809CB") (User "joey") -- used for building rpms- & Apt.installed ["rpm", "createrepo"]+ & Apt.installed ["rpm", "createrepo-c"] where endpoint d = combineProperties ("endpoint " ++ d) $ props & File.dirExists d@@ -439,7 +359,7 @@ & Apt.serviceInstalledRunning "clamav-freshclam" -- Workaround https://bugs.debian.org/569150 & Cron.niceJob "amavis-expire" Cron.Daily (User "root") "/"- "find /var/lib/amavis/virusmails/ -type f -ctime +7 -delete"+ "find /var/lib/amavis/virusmails/ -type f -ctime +2 -delete" & dkimInstalled @@ -600,7 +520,10 @@ `onChange` (imapalpinescript `File.mode` combineModes (readModes ++ executeModes)) `describe` "imap script for pine"- & Apt.serviceInstalledRunning "mailman"+ -- XXX temporarily disabled installing as it's not available in+ -- debian unstable any longer. Need to upgrade to mailman3+ -- at some point. (nontrivial)+ -- & Apt.serviceInstalledRunning "mailman" -- Override the default http url. (Only affects new lists.) & "/etc/mailman/mm_cfg.py" `File.containsLine` "DEFAULT_URL_PATTERN = 'https://%s/cgi-bin/mailman/'"@@ -1145,7 +1068,7 @@ laptopSoftware :: Property DebianLike laptopSoftware = Apt.installed [ "intel-microcode", "acpi"- , "procmeter3", "xfce4", "procmeter3", "unclutter"+ , "procmeter3", "xfce4", "procmeter3", "unclutter-xfixes" , "mplayer", "fbreader", "firefox", "chromium" , "libdatetime-event-sunrise-perl", "libtime-duration-perl" , "network-manager", "network-manager-openvpn-gnome", "openvpn"@@ -1167,6 +1090,7 @@ , "vorbis-tools", "audacity" , "ekiga" , "bluez-firmware", "blueman", "pulseaudio-module-bluetooth"+ , "fwupd" , "xul-ext-ublock-origin", "xul-ext-pdf.js", "xul-ext-status4evar" , "vim-syntastic", "vim-fugitive" , "adb", "gthumb"@@ -1254,6 +1178,10 @@ (USBHubPort hubvendor 4) (USBDriveId wd "25a3") (Just "archive")+ & autoMountDrivePort "archive-14"+ (USBHubPort hubvendor 2)+ (USBDriveId wd "25a3")+ Nothing & autoMountDrive "passport" Nothing & Apt.installed ["git-annex", "borgbackup"] where@@ -1280,7 +1208,7 @@ autoMountDrivePort label hp drive malias = propertyList desc $ props & File.hasContent ("/etc/systemd/system/" ++ hub) [ "[Unit]"- , "Description=Startech usb hub port " ++ show (hubPort hp)+ , "Description=Startech usb hub port " ++ show (hubPort hp) ++ " vendor " ++ driveVendorId drive ++ " driveid " ++ driveProductId drive , "PartOf=" ++ mount , "[Service]" , "Type=oneshot"@@ -1307,7 +1235,7 @@ devfile = "/dev/disk/by-label/" ++ label mountpoint = "/media/joey/" ++ label desc = "auto mount with hub port power control " ++ mountpoint- hub = "startech-hub-port-" ++ show (hubPort hp) ++ ".service"+ hub = "startech-hub-port-" ++ show (hubPort hp) ++ "-vendor-" ++ driveVendorId drive ++ "-drivedid-" ++ driveProductId drive ++ ".service" mount = svcbase ++ ".mount" svcbase = Systemd.escapePath mountpoint selecthubport = unwords
src/Propellor/Property/Sudo.hs view
@@ -27,7 +27,7 @@ setup = property' desc $ \w -> do locked <- liftIO $ isLockedPassword user ensureProperty w $ combineProperties desc $ props- & containsLine sudoers "#includedir /etc/sudoers.d"+ & includessudoersd & fileProperty desc (modify locked . filter (wanted locked)) dfile@@ -43,8 +43,19 @@ desc = u ++ " is not sudoer" removeconflicting = fileProperty "remove conflicting" (filter notuserline)+ + -- Not reverted because this line is included by default.+ includessudoersd = fileProperty (sudoers ++ " includes " ++ sudoersd) addl sudoers+ where+ addl content = content ++ + if l `notElem` content && oldl `notElem` content+ then [l]+ else []+ l = "@includedir /etc/sudoers.d"+ oldl = "#includedir /etc/sudoers.d" sudoers = "/etc/sudoers"+ sudoersd = "/etc/sudoers.d" dfile = "/etc/sudoers.d/000users" sudobaseline = u ++ " ALL=(ALL:ALL)" notuserline l = not (sudobaseline `isPrefixOf` l)
src/Utility/HumanNumber.hs view
@@ -1,21 +1,25 @@ {- numbers for humans -- - Copyright 2012-2013 Joey Hess <id@joeyh.name>+ - Copyright 2012-2021 Joey Hess <id@joeyh.name> - - License: BSD-2-clause -} -module Utility.HumanNumber where+module Utility.HumanNumber (showImprecise) where {- Displays a fractional value as a string with a limited number - of decimal digits. -} showImprecise :: RealFrac a => Int -> a -> String showImprecise precision n- | precision == 0 || remainder == 0 = show (round n :: Integer)- | otherwise = show int ++ "." ++ striptrailing0s (pad0s $ show remainder)+ | precision == 0 || remainder' == 0 = show (round n :: Integer)+ | otherwise = show int' ++ "." ++ striptrailing0s (pad0s $ show remainder') where int :: Integer (int, frac) = properFraction n remainder = round (frac * 10 ^ precision) :: Integer+ (int', remainder')+ -- carry the 1+ | remainder == 10 ^ precision = (int + 1, 0)+ | otherwise = (int, remainder) pad0s s = replicate (precision - length s) '0' ++ s striptrailing0s = reverse . dropWhile (== '0') . reverse