summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSean Whitton <spwhitton@spwhitton.name>2018-02-18 14:33:50 -0700
committerSean Whitton <spwhitton@spwhitton.name>2018-02-18 14:33:50 -0700
commit3768bbc7abf7543ffd82223b2d8ca63a887c4306 (patch)
tree1ed1520dd776917cba4752fab0afbe40efb6000c
parentc8b2396f140a1eaa6c54d6060901fbefd5d6a763 (diff)
parentb0599c446cbcc5eb5f46687699115ea27b62ef3e (diff)
Merge tag '5.3.2' into debian
tagging package propellor version 5.3.2 # gpg: Signature made Sun 18 Feb 2018 11:31:47 AM MST # gpg: using RSA key 28A500C35207EAB72F6C0F25DB12DB0FF05F8F38 # gpg: Good signature from "Joey Hess <joeyh@joeyh.name>" [full] # Primary key fingerprint: E85A 5F63 B31D 24C1 EBF0 D81C C910 D922 2512 E3C7 # Subkey fingerprint: 28A5 00C3 5207 EAB7 2F6C 0F25 DB12 DB0F F05F 8F38
-rw-r--r--debian/changelog13
-rw-r--r--doc/README.mdwn9
-rw-r--r--doc/forum/Simple_quickstart_without_git__44___SSH__44___GPG.mdwn35
-rw-r--r--doc/forum/Simple_quickstart_without_git__44___SSH__44___GPG/comment_1_031851f4a01a8a4d9fb4bd1f9ac077c8._comment22
-rw-r--r--doc/forum/dm-crypt__47__LUKS_encryption_and_key_management.mdwn1
-rw-r--r--doc/forum/dm-crypt__47__LUKS_encryption_and_key_management/comment_1_62fc297972ab5be50b9cb8cd3aa269c0._comment17
-rw-r--r--doc/news/version_4.7.6.mdwn6
-rw-r--r--doc/news/version_4.7.7.mdwn11
-rw-r--r--doc/news/version_4.8.0.mdwn21
-rw-r--r--doc/news/version_4.8.1.mdwn4
-rw-r--r--doc/news/version_4.9.0.mdwn23
-rw-r--r--doc/news/version_5.3.0.mdwn16
-rw-r--r--doc/news/version_5.3.1.mdwn5
-rw-r--r--joeyconfig.hs5
-rw-r--r--propellor.cabal3
-rw-r--r--src/Propellor/EnsureProperty.hs1
-rw-r--r--src/Propellor/Property/Atomic.hs161
-rw-r--r--src/Propellor/Property/Git.hs18
-rw-r--r--src/Propellor/Property/SiteSpecific/JoeySites.hs42
-rw-r--r--src/Propellor/Property/Systemd.hs4
20 files changed, 321 insertions, 96 deletions
diff --git a/debian/changelog b/debian/changelog
index cf27030d..1f32e38d 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,3 +1,16 @@
+propellor (5.3.2) unstable; urgency=medium
+
+ * Added Propellor.Property.Atomic, which can make a non-atomic property
+ that operates on a directory into an atomic property.
+ (Inspired by Vaibhav Sagar's talk on Functional Devops in a
+ Dysfunctional World at LCA 2018.)
+ * Added Git.pulled.
+ * Systemd.machined: Install systemd-container on Debian
+ stretch.
+ Thanks, Sean Whitton
+
+ -- Joey Hess <id@joeyh.name> Sun, 18 Feb 2018 14:31:39 -0400
+
propellor (5.3.1-1) unstable; urgency=medium
* New upstream release.
diff --git a/doc/README.mdwn b/doc/README.mdwn
index a4a38c5f..8bdb6c83 100644
--- a/doc/README.mdwn
+++ b/doc/README.mdwn
@@ -18,12 +18,10 @@ There is fairly complete
which includes many built-in Properties for dealing with
[Apt](http://hackage.haskell.org/package/propellor/docs/Propellor-Property-Apt.html)
and
-[Apache](http://hackage.haskell.org/package/propellor/docs/Propellor-Property-Apache.html)
-,
+[Apache](http://hackage.haskell.org/package/propellor/docs/Propellor-Property-Apache.html),
[Cron](http://hackage.haskell.org/package/propellor/docs/Propellor-Property-Cron.html)
and
-[Commands](http://hackage.haskell.org/package/propellor/docs/Propellor-Property-Cmd.html)
-,
+[Commands](http://hackage.haskell.org/package/propellor/docs/Propellor-Property-Cmd.html),
[Dns](http://hackage.haskell.org/package/propellor/docs/Propellor-Property-Dns.html)
and
[Docker](http://hackage.haskell.org/package/propellor/docs/Propellor-Property-Docker.html), etc.
@@ -56,3 +54,6 @@ see [configuration for the Haskell newbie](https://propellor.branchable.com/hask
each host becomes tiresome, you can
[automate that](http://propellor.branchable.com/automated_spins/).
7. Write some neat new properties and send patches!
+
+(Want to get your feet wet with propellor before plunging in?
+[[try this|forum/Simple_quickstart_without_git__44___SSH__44___GPG]])
diff --git a/doc/forum/Simple_quickstart_without_git__44___SSH__44___GPG.mdwn b/doc/forum/Simple_quickstart_without_git__44___SSH__44___GPG.mdwn
new file mode 100644
index 00000000..d0920424
--- /dev/null
+++ b/doc/forum/Simple_quickstart_without_git__44___SSH__44___GPG.mdwn
@@ -0,0 +1,35 @@
+I wanted to start using propellor in the most simple way and the requirement to have a GPG key, signed commits, propellor updating itself, and so on was way too much to start with.
+
+So I wrote this Haskell file:
+
+
+ module Main where
+
+ import Propellor
+ import Propellor.Engine
+ import qualified Propellor.Property.Apt as Apt
+
+ main :: IO ()
+ main = mainProperties myHost
+
+ myHost :: Host
+ myHost = host "local" $ props
+ & Apt.installed [
+ "etckeeper"
+ , "git"
+ , "rsync"
+ , "tmux"
+ , "tree"
+ , "unattended-upgrades"
+ , "zsh"
+ ]
+
+And then used the Debian package *entr* to scp the executable to a test server and have it executed there:
+
+ echo mytest-exe | entr scp /_ mytesthost:
+
+and on the test host:
+
+ echo mytest-exe | entr sudo ./mytest-exe
+
+Maybe somebody finds this useful as a starting point to learn propellor.
diff --git a/doc/forum/Simple_quickstart_without_git__44___SSH__44___GPG/comment_1_031851f4a01a8a4d9fb4bd1f9ac077c8._comment b/doc/forum/Simple_quickstart_without_git__44___SSH__44___GPG/comment_1_031851f4a01a8a4d9fb4bd1f9ac077c8._comment
new file mode 100644
index 00000000..a99e83e2
--- /dev/null
+++ b/doc/forum/Simple_quickstart_without_git__44___SSH__44___GPG/comment_1_031851f4a01a8a4d9fb4bd1f9ac077c8._comment
@@ -0,0 +1,22 @@
+[[!comment format=mdwn
+ username="joey"
+ subject="""comment 1"""
+ date="2018-02-04T16:09:17Z"
+ content="""
+Thank you for this excellent idea and post! I've added a link to it under
+the quick start on the front page.
+
+Propellor's deployment system
+is just what happened to meet my needs, but certianly not ideal for anyone,
+and what I really like about this is it shows how the core of propellor is
+not locked into that one system.
+
+I see that `entr` automatically re-transfers the file when it has changed,
+so am I right that you could use this in combination with eg
+`stack build --file-watch` to immediately test each change to config.hs?
+
+Do note that your method doesn't transfer over any private data that
+propellor might use on the host. And, some container properties need
+the propellor binary in /usr/local/propellor/ in order to work.
+But until you need such properties, it's a nice way to get your feet wet.
+"""]]
diff --git a/doc/forum/dm-crypt__47__LUKS_encryption_and_key_management.mdwn b/doc/forum/dm-crypt__47__LUKS_encryption_and_key_management.mdwn
new file mode 100644
index 00000000..12a2bea5
--- /dev/null
+++ b/doc/forum/dm-crypt__47__LUKS_encryption_and_key_management.mdwn
@@ -0,0 +1 @@
+Hi. Searching for *luks* in the git repository and the forum doesn’t bring up any hits. Am I right to assume, that encrypting the disk with dm-crypt/LUKS and managing keys/passwords is currently not easily doable?
diff --git a/doc/forum/dm-crypt__47__LUKS_encryption_and_key_management/comment_1_62fc297972ab5be50b9cb8cd3aa269c0._comment b/doc/forum/dm-crypt__47__LUKS_encryption_and_key_management/comment_1_62fc297972ab5be50b9cb8cd3aa269c0._comment
new file mode 100644
index 00000000..0962459f
--- /dev/null
+++ b/doc/forum/dm-crypt__47__LUKS_encryption_and_key_management/comment_1_62fc297972ab5be50b9cb8cd3aa269c0._comment
@@ -0,0 +1,17 @@
+[[!comment format=mdwn
+ username="joey"
+ subject="""comment 1"""
+ date="2018-02-06T15:37:45Z"
+ content="""
+Not aware of anyone using propellor for that yet.
+
+Propellor's LVM module would probably be a decent starting point for
+implementing dm-crypt support.
+
+Key/passwords could certianly be managed with propellor's privdata
+interface. Whether it makes sense to do so for security is probably up to
+the individual user, since privdata can be decrypted with your gpg private
+key, which you might not want to equate to access to your encrypted volume.
+Also, privdata is stored on the host that uses it in unencrypted form
+protected only by file permissions.
+"""]]
diff --git a/doc/news/version_4.7.6.mdwn b/doc/news/version_4.7.6.mdwn
deleted file mode 100644
index 4c8abd97..00000000
--- a/doc/news/version_4.7.6.mdwn
+++ /dev/null
@@ -1,6 +0,0 @@
-propellor 4.7.6 released with [[!toggle text="these changes"]]
-[[!toggleable text="""
- * Sbuild: Add Sbuild.userConfig property.
- Thanks, Sean Whitton
- * Locale: Make sure that the locales package is installed when enabling
- locales."""]] \ No newline at end of file
diff --git a/doc/news/version_4.7.7.mdwn b/doc/news/version_4.7.7.mdwn
deleted file mode 100644
index 258f0f23..00000000
--- a/doc/news/version_4.7.7.mdwn
+++ /dev/null
@@ -1,11 +0,0 @@
-propellor 4.7.7 released with [[!toggle text="these changes"]]
-[[!toggleable text="""
- * Locale: Display an error message when /etc/locale.gen does not contain
- the requested locale.
- * Attic module is deprecated and will warn when used.
- Attic is no longer available in Debian and appears to have been
- mostly supersceded by Borg.
- * Obnam module is deprecated and will warn when used.
- Obnam has been retired by its author.
- * Add Typeable instance to Bootstrapper, fixing build with old versions
- of ghc. (Previous attempt was incomplete.)"""]] \ No newline at end of file
diff --git a/doc/news/version_4.8.0.mdwn b/doc/news/version_4.8.0.mdwn
deleted file mode 100644
index 217c3154..00000000
--- a/doc/news/version_4.8.0.mdwn
+++ /dev/null
@@ -1,21 +0,0 @@
-propellor 4.8.0 released with [[!toggle text="these changes"]]
-[[!toggleable text="""
- * DiskImage: Made a DiskImage type class, so that different disk image
- formats can be implemented. The properties in this module can generate
- any type that is a member of DiskImage. (API change)
- (To convert existing configs, convert the filename of the disk image
- to RawDiskImage filename.)
- * Removed DiskImage.vmdkBuiltFor property. (API change)
- Instead, use VirtualBoxPointer in the property that creates the disk
- image.
- * Apt.isInstalled: Fix handling of packages that are not known at all
- to apt.
- * Borg: Converted BorgRepo from a String alias to a data type.
- (API change)
- * Borg: Allow specifying ssh private key to use when accessing a borg
- repo by using the BorgRepoUsing constructor with UseSshKey.
- * Borg: Fix broken shell escaping in borg cron job.
- * Attic: Fix broken shell escaping in attic cron job.
- * Make lock file descriptors close-on-exec.
- * Lvm: New module for setting up LVM volumes.
- Thanks, Nicolas Schodet"""]] \ No newline at end of file
diff --git a/doc/news/version_4.8.1.mdwn b/doc/news/version_4.8.1.mdwn
deleted file mode 100644
index fbd293cd..00000000
--- a/doc/news/version_4.8.1.mdwn
+++ /dev/null
@@ -1,4 +0,0 @@
-propellor 4.8.1 released with [[!toggle text="these changes"]]
-[[!toggleable text="""
- * Borg: Fix propigation of exit status of borg backup.
- * Borg: Fix handling of UseSshKey."""]] \ No newline at end of file
diff --git a/doc/news/version_4.9.0.mdwn b/doc/news/version_4.9.0.mdwn
deleted file mode 100644
index c625e0c7..00000000
--- a/doc/news/version_4.9.0.mdwn
+++ /dev/null
@@ -1,23 +0,0 @@
-propellor 4.9.0 released with [[!toggle text="these changes"]]
-[[!toggleable text="""
- * When the ipv4 and ipv6 properties are used with a container, avoid
- propagating the address out to the host.
- * DnsInfo has been replaced with DnsInfoPropagated and
- DnsInfoUnpropagated. (API change)
- * Code that used fromDnsInfo . fromInfo changes to use getDnsInfo.
- * addDNS takes an additional Bool parameter to control whether
- the DNS info should propagate out of containers. (API change)
- * Made the PropellorRepo.hasOriginUrl property override the repository
- url that --spin passes to a host.
- * PropellorRepo.hasOriginUrl type changed to include HasInfo. (API change)
- * Fstab.mounted: Create mount point if necessary, and mount it
- if it's not already mounted.
- Thanks, Nicolas Schodet
- * Properties that check for an empty directory now treat a directory
- containing only "lost+found" as effectively empty, to support
- situations where the directory is a mount point of an EXT* filesystem.
- Thanks, Nicolas Schodet
- * Make addInfo accumulate Info in order properties appear, not
- reverse order.
- This fixes a bug involving reverting Systemd.resolvConfed or
- Systemd.linkJournal."""]] \ No newline at end of file
diff --git a/doc/news/version_5.3.0.mdwn b/doc/news/version_5.3.0.mdwn
deleted file mode 100644
index 07900e0b..00000000
--- a/doc/news/version_5.3.0.mdwn
+++ /dev/null
@@ -1,16 +0,0 @@
-propellor 5.3.0 released with [[!toggle text="these changes"]]
-[[!toggleable text="""
- * Avoid bogus warning about new upstream version when /usr/bin/propellor
- is run on a Debian system, but ~/.propellor was not cloned from the
- Debian git bundle.
- * Parted: Allow partitions to have no filesystem, for eg, GPT BIOS boot
- partitions. (API change)
- * Added rawPartition to PartSpec, for specifying partitions with no
- filesystem.
- * Added BiosGrubFlag to PartFlag.
- * Add HasCallStack constraint to pickOS and unsupportedOS, so the
- call stack includes the caller.
- * Run su with --login, to avoid inheriting some problematic environment
- variables, such as TMP, from the caller.
- * Grub: Added properties to configure /etc/default/grub.
- * Laptop: New module, starting with powertopAutoTuneOnBoot."""]] \ No newline at end of file
diff --git a/doc/news/version_5.3.1.mdwn b/doc/news/version_5.3.1.mdwn
new file mode 100644
index 00000000..4f660270
--- /dev/null
+++ b/doc/news/version_5.3.1.mdwn
@@ -0,0 +1,5 @@
+propellor 5.3.1 released with [[!toggle text="these changes"]]
+[[!toggleable text="""
+ * Last release mistakenly contained my personal branch not master.
+ * contrib/post-merge-hook documentation updated to recommend also using
+ it as a post-checkout hook, to avoid such problems."""]] \ No newline at end of file
diff --git a/joeyconfig.hs b/joeyconfig.hs
index 1d019498..23da8bb4 100644
--- a/joeyconfig.hs
+++ b/joeyconfig.hs
@@ -27,7 +27,6 @@ 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.FlashKernel as FlashKernel
import qualified Propellor.Property.Borg as Borg
import qualified Propellor.Property.Gpg as Gpg
import qualified Propellor.Property.Systemd as Systemd
@@ -193,9 +192,7 @@ honeybee = host "honeybee.kitenet.net" $ props
`mountedAt` "/"
`setSize` MegaBytes 8000
)
- & File.hasPrivContentExposed "/etc/flash-kernel/dtbs/sun7i-a20-cubietruck.dtb"
- (Context "cubietruck gpio")
- `onChange` FlashKernel.flashKernel
+ & JoeySites.cubieTruckOneWire
& Apt.installed ["firmware-brcm80211"]
-- Workaround for https://bugs.debian.org/844056
diff --git a/propellor.cabal b/propellor.cabal
index 4f90c49c..d9157eb1 100644
--- a/propellor.cabal
+++ b/propellor.cabal
@@ -1,5 +1,5 @@
Name: propellor
-Version: 5.3.1
+Version: 5.3.2
Cabal-Version: >= 1.20
License: BSD2
Maintainer: Joey Hess <id@joeyh.name>
@@ -89,6 +89,7 @@ Library
Propellor.Property.Apache
Propellor.Property.Apt
Propellor.Property.Apt.PPA
+ Propellor.Property.Atomic
Propellor.Property.Attic
Propellor.Property.Bootstrap
Propellor.Property.Borg
diff --git a/src/Propellor/EnsureProperty.hs b/src/Propellor/EnsureProperty.hs
index ad74bfa8..5a07107c 100644
--- a/src/Propellor/EnsureProperty.hs
+++ b/src/Propellor/EnsureProperty.hs
@@ -8,6 +8,7 @@ module Propellor.EnsureProperty
( ensureProperty
, property'
, OuterMetaTypesWitness(..)
+ , Cannot_ensureProperty_WithInfo
) where
import Propellor.Types
diff --git a/src/Propellor/Property/Atomic.hs b/src/Propellor/Property/Atomic.hs
new file mode 100644
index 00000000..8519048b
--- /dev/null
+++ b/src/Propellor/Property/Atomic.hs
@@ -0,0 +1,161 @@
+{-# LANGUAGE DataKinds #-}
+{-# LANGUAGE TypeFamilies #-}
+
+module Propellor.Property.Atomic (
+ atomicDirUpdate,
+ atomicDirSync,
+ atomicUpdate,
+ AtomicResourcePair(..),
+ flipAtomicResourcePair,
+ SwapAtomicResourcePair,
+ CheckAtomicResourcePair,
+) where
+
+import Propellor.Base
+import Propellor.Types.Core
+import Propellor.Types.MetaTypes
+import Propellor.EnsureProperty
+import Propellor.Property.File
+import Propellor.Property.Rsync (syncDir)
+
+import System.Posix.Files
+
+-- | A pair of resources, one active and one inactive, which can swap
+-- positions atomically.
+data AtomicResourcePair a = AtomicResourcePair
+ { activeAtomicResource :: a
+ , inactiveAtomicResource :: a
+ }
+
+flipAtomicResourcePair :: AtomicResourcePair a -> AtomicResourcePair a
+flipAtomicResourcePair a = AtomicResourcePair
+ { activeAtomicResource = inactiveAtomicResource a
+ , inactiveAtomicResource = activeAtomicResource a
+ }
+
+-- | Action that activates the inactiveAtomicResource, and deactivates
+-- the activeAtomicResource. This action must be fully atomic.
+type SwapAtomicResourcePair a = AtomicResourcePair a -> Propellor Bool
+
+-- | Checks which of the pair of resources is currently active and
+-- which is inactive, and puts them in the correct poisition in
+-- the AtomicResourcePair.
+type CheckAtomicResourcePair a = AtomicResourcePair a -> Propellor (AtomicResourcePair a)
+
+-- | Makes a non-atomic Property be atomic, by applying it to the
+-- inactiveAtomicResource, and if it was successful,
+-- atomically activating that resource.
+atomicUpdate
+ -- Constriaints inherited from ensureProperty.
+ :: ( Cannot_ensureProperty_WithInfo t ~ 'True
+ , (Targets t `NotSuperset` Targets t) ~ 'CanCombine
+ )
+ => SingI t
+ => AtomicResourcePair a
+ -> CheckAtomicResourcePair a
+ -> SwapAtomicResourcePair a
+ -> (a -> Property (MetaTypes t))
+ -> Property (MetaTypes t)
+atomicUpdate rbase rcheck rswap mkp = property' d $ \w -> do
+ r <- rcheck rbase
+ res <- ensureProperty w $ mkp $ inactiveAtomicResource r
+ case res of
+ FailedChange -> return FailedChange
+ NoChange -> return NoChange
+ MadeChange -> do
+ ok <- rswap r
+ if ok
+ then return res
+ else return FailedChange
+ where
+ d = getDesc $ mkp $ activeAtomicResource rbase
+
+-- | Applies a Property to a directory such that the directory is updated
+-- fully atomically; there is no point in time in which the directory will
+-- be in an inconsistent state.
+--
+-- For example, git repositories are not usually updated atomically,
+-- and so while the repository is being updated, the files in it can be a
+-- mixture of two different versions, which could cause unexpected
+-- behavior to consumers. To avoid such problems:
+--
+-- > & atomicDirUpdate "/srv/web/example.com"
+-- > (\d -> Git.pulled "joey" "http://.." d Nothing)
+--
+-- This operates by making a second copy of the directory, and passing it
+-- to the Property, which can make whatever changes it needs to that copy,
+-- non-atomically. After the Property successfully makes a change, the
+-- copy is swapped into place, fully atomically.
+--
+-- This necessarily uses double the disk space, since there are two copies
+-- of the directory. The parent directory will actually contain three
+-- children: a symlink with the name of the directory itself, and two copies
+-- of the directory, with names suffixed with ".1" and ".2"
+atomicDirUpdate
+ -- Constriaints inherited from ensureProperty.
+ :: ( Cannot_ensureProperty_WithInfo t ~ 'True
+ , (Targets t `NotSuperset` Targets t) ~ 'CanCombine
+ )
+ => SingI t
+ => FilePath
+ -> (FilePath -> Property (MetaTypes t))
+ -> Property (MetaTypes t)
+atomicDirUpdate d = atomicUpdate (mkDirLink d) (checkDirLink d) (swapDirLink d)
+
+mkDirLink :: FilePath -> AtomicResourcePair FilePath
+mkDirLink d = AtomicResourcePair
+ { activeAtomicResource = addext ".1"
+ , inactiveAtomicResource = addext ".2"
+ }
+ where
+ addext = addExtension (dropTrailingPathSeparator d)
+
+inactiveLinkTarget :: AtomicResourcePair FilePath -> FilePath
+inactiveLinkTarget = takeFileName . inactiveAtomicResource
+
+swapDirLink :: FilePath -> SwapAtomicResourcePair FilePath
+swapDirLink d rp = liftIO $ do
+ v <- tryIO $ createSymbolicLink (inactiveLinkTarget rp)
+ `viaStableTmp` d
+ case v of
+ Right () -> return True
+ Left e -> do
+ warningMessage $ "Unable to update symlink at " ++ d ++ " (" ++ show e ++ ")"
+ return False
+
+checkDirLink :: FilePath -> CheckAtomicResourcePair FilePath
+checkDirLink d rp = liftIO $ do
+ v <- tryIO $ readSymbolicLink d
+ return $ case v of
+ Right t | t == inactiveLinkTarget rp ->
+ flipAtomicResourcePair rp
+ _ -> rp
+
+-- | This can optionally be used after atomicDirUpdate to rsync the changes
+-- that were made over to the other copy of the directory. It's not
+-- necessary to use this, but it can improve efficiency.
+--
+-- For example:
+--
+-- > & atomicDirUpdate "/srv/web/example.com"
+-- > (\d -> Git.pulled "joey" "http://.." d Nothing)
+-- > `onChange` atomicDirSync "/srv/web/example.com"
+--
+-- Using atomicDirSync in the above example lets git only download
+-- the changes once, rather than the same changes being downloaded a second
+-- time to update the other copy of the directory the next time propellor
+-- runs.
+--
+-- Suppose that a web server program is run from the git repository,
+-- and needs to be restarted after the pull. That restart should be done
+-- after the atomicDirUpdate, but before the atomicDirSync. That way,
+-- the old web server process will not have its files changed out from
+-- under it.
+--
+-- > & atomicDirUpdate "/srv/web/example.com"
+-- > (\d -> Git.pulled "joey" "http://.." d Nothing)
+-- > `onChange` (webServerRestart `before` atomicDirSync "/srv/web/example.com")
+atomicDirSync :: FilePath -> Property (DebianLike + ArchLinux)
+atomicDirSync d = syncDir (activeAtomicResource rp) (inactiveAtomicResource rp)
+ where
+ rp = mkDirLink d
diff --git a/src/Propellor/Property/Git.hs b/src/Propellor/Property/Git.hs
index 5d7c8b4d..e7dcb80c 100644
--- a/src/Propellor/Property/Git.hs
+++ b/src/Propellor/Property/Git.hs
@@ -61,6 +61,9 @@ type Branch = String
-- it will be recursively deleted first.
--
-- A branch can be specified, to check out.
+--
+-- Does not make subsequent changes be pulled into the repository after
+-- it's cloned.
cloned :: User -> RepoUrl -> FilePath -> Maybe Branch -> Property DebianLike
cloned owner url dir mbranch = check originurl go
`requires` installed
@@ -95,11 +98,26 @@ cloned owner url dir mbranch = check originurl go
, Just "git update-server-info"
]
+-- | Specified git repository is cloned to the specified directory,
+-- and any new commits are pulled into it each time this property runs.
+pulled :: User -> RepoUrl -> FilePath -> Maybe Branch -> Property DebianLike
+pulled owner url dir mbranch = go
+ `requires` cloned owner url dir mbranch
+ `describe` desc
+ where
+ desc = "git pulled " ++ url ++ " to " ++ dir
+ go = userScriptProperty owner
+ [ "cd " ++ shellEscape dir
+ , "git pull"
+ ]
+ `changesFile` (dir </> ".git" </> "FETCH_HEAD")
+
isGitDir :: FilePath -> IO Bool
isGitDir dir = isNothing <$> catchMaybeIO (readProcess "git" ["rev-parse", "--resolve-git-dir", dir])
data GitShared = Shared Group | SharedAll | NotShared
+-- | Sets up a new, empty bare git repository.
bareRepo :: FilePath -> User -> GitShared -> Property UnixLike
bareRepo repo user gitshared = check (isRepo repo) $ propertyList ("git repo: " ++ repo) $ toProps $
dirExists repo : case gitshared of
diff --git a/src/Propellor/Property/SiteSpecific/JoeySites.hs b/src/Propellor/Property/SiteSpecific/JoeySites.hs
index 0a1982c1..8f0c6f62 100644
--- a/src/Propellor/Property/SiteSpecific/JoeySites.hs
+++ b/src/Propellor/Property/SiteSpecific/JoeySites.hs
@@ -541,7 +541,7 @@ kiteMailServer = propertyList "kitenet.net mail server" $ props
, "smtpd_sasl_security_options = noanonymous"
, "smtpd_sasl_local_domain = kitenet.net"
- , "# Enable postgrey."
+ , "# Enable postgrey and sasl auth and client certs."
, "smtpd_recipient_restrictions = permit_tls_clientcerts,permit_sasl_authenticated,,permit_mynetworks,reject_unauth_destination,check_policy_service inet:127.0.0.1:10023"
, "# Enable spamass-milter, amavis-milter (opendkim is not enabled because it causes mails forwarded from eg gmail to be rejected)"
@@ -668,7 +668,6 @@ domainKey = (RelDomain "mail._domainkey", TXT "v=DKIM1; k=rsa; p=MIGfMA0GCSqGSIb
postfixSaslPasswordClient :: Property (HasInfo + DebianLike)
postfixSaslPasswordClient = combineProperties "postfix uses SASL password to authenticate with smarthost" $ props
- & Postfix.satellite
& Postfix.mappedFile "/etc/postfix/sasl_passwd"
(`File.hasPrivContent` (Context "kitenet.net"))
& Postfix.mainCfFile `File.containsLines`
@@ -680,6 +679,9 @@ postfixSaslPasswordClient = combineProperties "postfix uses SASL password to aut
, "smtp_sasl_password_maps = hash:/etc/postfix/sasl_passwd"
]
`onChange` Postfix.reloaded
+ -- Comes after so it does not set relayhost but uses the setting
+ -- above.
+ & Postfix.satellite
hasPostfixCert :: Context -> Property (HasInfo + UnixLike)
hasPostfixCert ctx = combineProperties "postfix tls cert installed" $ props
@@ -1048,7 +1050,7 @@ laptopSoftware = Apt.installed
, "ttf-bitstream-vera"
, "mairix", "offlineimap", "mutt"
, "nmap", "whois", "wireshark", "tcpdump", "iftop"
- , "udevil", "pmount", "tree"
+ , "udevil", "pmount", "tree", "pv"
, "arbtt", "hledger", "bc"
, "apache2", "ikiwiki", "libhighlight-perl"
, "pal"
@@ -1059,7 +1061,7 @@ laptopSoftware = Apt.installed
, "vim-syntastic", "vim-fugitive"
, "adb", "gthumb"
, "w3m", "sm", "weechat"
- , "borgbackup", "wipe"
+ , "borgbackup", "wipe", "smartmontools", "libgfshare-bin"
, "units"
]
`requires` baseSoftware
@@ -1079,3 +1081,35 @@ devSoftware = Apt.installed
, "gdb", "dpkg-repack", "lintian"
, "pristine-tar", "github-backup"
]
+
+cubieTruckOneWire :: Property DebianLike
+cubieTruckOneWire =
+ File.hasContent "/etc/easy-peasy-devicetree-squeezy/my.dts" mydts
+ `onChange` utilitysetup
+ `requires` utilityinstalled
+ where
+ utilityinstalled = Git.cloned (User "root") "https://git.joeyh.name/git/easy-peasy-devicetree-squeezy.git" "/usr/local/easy-peasy-devicetree-squeezy" Nothing
+ `onChange` File.isSymlinkedTo "/usr/local/bin/easy-peasy-devicetree-squeezy" (File.LinkTarget "/usr/local/easy-peasy-devicetree-squeezy/easy-peasy-devicetree-squeezy")
+ utilitysetup = cmdProperty "easy-peasy-devicetree-squeezy"
+ ["--debian", "sun7i-a20-cubietruck"]
+ `assume` MadeChange
+ mydts =
+ [ "/* Device tree addition enabling onewire sensors on CubieTruck GPIO pin PG8 */"
+ , "#include <dt-bindings/gpio/gpio.h>"
+ , ""
+ , "/ {"
+ , "\tonewire_device {"
+ , "\t\tcompatible = \"w1-gpio\";"
+ , "\t\tgpios = <&pio 6 8 GPIO_ACTIVE_HIGH>; /* PG8 */"
+ , "\t\tpinctrl-names = \"default\";"
+ , "\t\tpinctrl-0 = <&my_w1_pin>;"
+ , "\t};"
+ , "};"
+ , ""
+ , "&pio {"
+ , "\tmy_w1_pin: my_w1_pin@0 {"
+ , "\t\tallwinner,pins = \"PG8\";"
+ , "\t\tallwinner,function = \"gpio_in\";"
+ , "\t};"
+ , "};"
+ ]
diff --git a/src/Propellor/Property/Systemd.hs b/src/Propellor/Property/Systemd.hs
index 51d1313c..8fa236d2 100644
--- a/src/Propellor/Property/Systemd.hs
+++ b/src/Propellor/Property/Systemd.hs
@@ -205,8 +205,8 @@ machined = withOS "machined installed" $ \w o ->
case o of
-- Split into separate debian package since systemd 225.
(Just (System (Debian _ suite) _))
- | not (isStable suite) -> ensureProperty w $
- Apt.installed ["systemd-container"]
+ | not (isStable suite) || suite == (Stable "stretch") ->
+ ensureProperty w $ Apt.installed ["systemd-container"]
_ -> noChange
-- | Defines a container with a given machine name,