summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
l---------config.hs2
-rw-r--r--debian/changelog3
-rw-r--r--doc/forum/Compatibility_between_different_software_versions.mdwn1
-rw-r--r--doc/forum/Compatibility_between_different_software_versions/comment_1_1bc12b78e09c7060f4b5c434004b4b7f._comment12
-rw-r--r--doc/forum/DiskImage_creation_does_not_work_on_my_system/comment_11_b1ad266b5c34b600d2d724bf5ffc40de._comment8
-rw-r--r--doc/forum/DiskImage_creation_does_not_work_on_my_system/comment_12_4baf7efcc6f9c50e3aebd663b7792279._comment23
-rw-r--r--doc/forum/DiskImage_creation_does_not_work_on_my_system/comment_13_2f8c7bb7f8ffb734a99ac3d7b28e2d62._comment15
-rw-r--r--doc/forum/How_to_create_a_property_with_info.mdwn65
-rw-r--r--doc/forum/How_to_create_a_property_with_info/comment_1_819902ee6b8e571f735dd2c9c93c49a9._comment29
-rw-r--r--doc/forum/How_to_create_a_property_with_info/comment_2_1c2b3cb54f27fb6b6bb5de9d159dd34f._comment15
-rw-r--r--doc/forum/How_to_create_a_property_with_info/comment_3_6cf0360b4922a131bca33d33acf078be._comment11
-rw-r--r--doc/forum/Sbuild_chroot_are_not_compatible_with_schroot/comment_3_6aeee8ba74b363d26a49d6773c5d5014._comment12
-rw-r--r--doc/forum/creating_Bind9_configuration/comment_3_6b4d73b17d87d00845fda26431ded422._comment10
-rw-r--r--doc/todo/LVM_logical_volume_creation__44___resize__44___format___38___removal.mdwn9
-rw-r--r--doc/todo/LVM_logical_volume_creation__44___resize__44___format___38___removal/comment_1_74c6576b25f74c6e620eb015af8b0f6a._comment26
-rw-r--r--doc/todo/LVM_logical_volume_creation__44___resize__44___format___38___removal/comment_2_d63d84b56ece233f795d1075aaba887a._comment18
-rw-r--r--doc/todo/LVM_logical_volume_creation__44___resize__44___format___38___removal/comment_3_1405e20c8f5dc6e9cca3732e3e368d03._comment25
-rw-r--r--doc/todo/LVM_logical_volume_creation__44___resize__44___format___38___removal/comment_4_20c6734d67fefeb1a8c07730d537e06b._comment8
-rw-r--r--doc/todo/LVM_logical_volume_creation__44___resize__44___format___38___removal/comment_5_aee8b3d2768fb7307a6cc2e3295fd1f6._comment12
-rw-r--r--doc/todo/unpropelling_a_host.mdwn9
-rw-r--r--privdata/relocate1
-rw-r--r--propellor.cabal1
-rw-r--r--src/Propellor/Engine.hs1
-rw-r--r--src/Propellor/Property/Lvm.hs171
-rw-r--r--src/Propellor/Property/Partition.hs14
25 files changed, 499 insertions, 2 deletions
diff --git a/config.hs b/config.hs
index 97d90636..ec313725 120000
--- a/config.hs
+++ b/config.hs
@@ -1 +1 @@
-joeyconfig.hs \ No newline at end of file
+config-simple.hs \ No newline at end of file
diff --git a/debian/changelog b/debian/changelog
index c7cfb81a..6aa2d8e5 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -10,6 +10,9 @@ propellor (4.8.0) UNRELEASED; urgency=medium
image.
* 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
-- Joey Hess <id@joeyh.name> Thu, 24 Aug 2017 11:00:19 -0400
diff --git a/doc/forum/Compatibility_between_different_software_versions.mdwn b/doc/forum/Compatibility_between_different_software_versions.mdwn
new file mode 100644
index 00000000..b2de3439
--- /dev/null
+++ b/doc/forum/Compatibility_between_different_software_versions.mdwn
@@ -0,0 +1 @@
+I'm just asking myself how (or if) we can guarantee compatibility between different versions of an application. Let's take "prosody" as an example. Even if we use the "DebianLike" property, there might be different versions of "prosody" in Debian Stable and Debian Unstable and therefore different configurations options available. Is there a way to catch those cases? Another example would be a "generic" property (which works for DebianLike and ArchLinux) for a specific software, but inside these distributions are different versions of the application. Even a "Prosody.installed" might be problematic, if the package has been renamed in a newer Debian release.
diff --git a/doc/forum/Compatibility_between_different_software_versions/comment_1_1bc12b78e09c7060f4b5c434004b4b7f._comment b/doc/forum/Compatibility_between_different_software_versions/comment_1_1bc12b78e09c7060f4b5c434004b4b7f._comment
new file mode 100644
index 00000000..97ab02e8
--- /dev/null
+++ b/doc/forum/Compatibility_between_different_software_versions/comment_1_1bc12b78e09c7060f4b5c434004b4b7f._comment
@@ -0,0 +1,12 @@
+[[!comment format=mdwn
+ username="joey"
+ subject="""comment 1"""
+ date="2017-08-31T22:26:42Z"
+ content="""
+`withOS` or `getOS` is often used to deal with such differences,
+varying behavior depending on the Host's defined OS. For example,
+Propellor.Property.Borg.installed does one thing on Debian jessie
+and another thing on other versions of Debian. And
+Propellor.Property.Apt.getMirror generates different urls for Debian and
+Ubuntu.
+"""]]
diff --git a/doc/forum/DiskImage_creation_does_not_work_on_my_system/comment_11_b1ad266b5c34b600d2d724bf5ffc40de._comment b/doc/forum/DiskImage_creation_does_not_work_on_my_system/comment_11_b1ad266b5c34b600d2d724bf5ffc40de._comment
new file mode 100644
index 00000000..79debc75
--- /dev/null
+++ b/doc/forum/DiskImage_creation_does_not_work_on_my_system/comment_11_b1ad266b5c34b600d2d724bf5ffc40de._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="picca"
+ avatar="http://cdn.libravatar.org/avatar/7e61c80d28018b10d31f6db7dddb864c"
+ subject="comment 11"
+ date="2017-08-24T18:36:12Z"
+ content="""
+Thanks a lot joey.
+"""]]
diff --git a/doc/forum/DiskImage_creation_does_not_work_on_my_system/comment_12_4baf7efcc6f9c50e3aebd663b7792279._comment b/doc/forum/DiskImage_creation_does_not_work_on_my_system/comment_12_4baf7efcc6f9c50e3aebd663b7792279._comment
new file mode 100644
index 00000000..b6de7d0a
--- /dev/null
+++ b/doc/forum/DiskImage_creation_does_not_work_on_my_system/comment_12_4baf7efcc6f9c50e3aebd663b7792279._comment
@@ -0,0 +1,23 @@
+[[!comment format=mdwn
+ username="picca"
+ avatar="http://cdn.libravatar.org/avatar/7e61c80d28018b10d31f6db7dddb864c"
+ subject="comment 12"
+ date="2017-08-24T19:11:24Z"
+ content="""
+If I understand correctly, the new typeclass need to provide a method which return the
+(RawDiskImage filename). In the process we have at least 2 cache level
+One for the chroot, and one for the RawImage.
+
+I was wondering if these cache (side effect) could not be regrouped
+under /var/cache/propellor instead of putting this randomly everywhere on the disk.
+
+This way It should be possible to \"reset\" propellor by removing the cache in order to force
+a cache rebuild.
+
+I think about this because I am not aware as a user of all these \"side effects\".
+
+propellor --purge-cache ;)
+
+cheers and thanks again
+
+"""]]
diff --git a/doc/forum/DiskImage_creation_does_not_work_on_my_system/comment_13_2f8c7bb7f8ffb734a99ac3d7b28e2d62._comment b/doc/forum/DiskImage_creation_does_not_work_on_my_system/comment_13_2f8c7bb7f8ffb734a99ac3d7b28e2d62._comment
new file mode 100644
index 00000000..74dc528e
--- /dev/null
+++ b/doc/forum/DiskImage_creation_does_not_work_on_my_system/comment_13_2f8c7bb7f8ffb734a99ac3d7b28e2d62._comment
@@ -0,0 +1,15 @@
+[[!comment format=mdwn
+ username="joey"
+ subject="""comment 13"""
+ date="2017-08-24T21:11:07Z"
+ content="""
+Yes, there are two levels of caches. This does make updating the images a
+whole lot faster!
+
+Some systems don't have a very large /var partition and so I think it's
+better to let the user pick where they go. The documentation could
+certainly (always) be improved.
+
+Note that reverting any of the properties in DiskImage will clean up
+all the cache files as well as the final disk image.
+"""]]
diff --git a/doc/forum/How_to_create_a_property_with_info.mdwn b/doc/forum/How_to_create_a_property_with_info.mdwn
new file mode 100644
index 00000000..ea8babe5
--- /dev/null
+++ b/doc/forum/How_to_create_a_property_with_info.mdwn
@@ -0,0 +1,65 @@
+Hello Joey,
+
+I try to setup a debomatic service on one of my computer.
+So I created a data which will store on which host it was installed
+
+ data DebOMaticHostMirror = DebOMaticHostMirror Url
+ deriving (Eq, Show, Typeable)
+
+So now I try to create a property which get the hostname and set the info,
+BUT I did not find the right way to do this. Here an attempt
+
+ debomaticHostMirror :: Property (HasInfo + UnixLike)
+ debomaticHostMirror = property' desc $ \w -> do
+ hostname <- asks hostName
+ ensureProperty $ pureInfoProperty desc (InfoVal (DebOMaticHostMirror hostname))
+ where
+ desc = "setup the Deb-O-Matic host name for other properties"
+
+but I get this error message
+
+ src/propellor-config.hs:935:3: error:
+ • Couldn't match expected type ‘Propellor Result’
+ with actual type ‘Property
+ (Propellor.Types.MetaTypes.MetaTypes inner0)
+ -> Propellor Result’
+ • In a stmt of a 'do' block:
+ ensureProperty
+ $ pureInfoProperty desc (InfoVal (DebOMaticHostMirror hostname))
+ In the expression:
+ do { hostname <- asks hostName;
+ ensureProperty
+ $ pureInfoProperty desc (InfoVal (DebOMaticHostMirror hostname)) }
+ In the second argument of ‘($)’, namely
+ ‘\ w
+ -> do { hostname <- asks hostName;
+ ensureProperty
+ $ pureInfoProperty desc (InfoVal (DebOMaticHostMirror hostname)) }’
+
+ src/propellor-config.hs:935:20: error:
+ • Couldn't match expected type ‘OuterMetaTypesWitness outer0’
+ with actual type ‘Property (HasInfo + UnixLike)’
+ • In the second argument of ‘($)’, namely
+ ‘pureInfoProperty desc (InfoVal (DebOMaticHostMirror hostname))’
+ In a stmt of a 'do' block:
+ ensureProperty
+ $ pureInfoProperty desc (InfoVal (DebOMaticHostMirror hostname))
+ In the expression:
+ do { hostname <- asks hostName;
+ ensureProperty
+ $ pureInfoProperty desc (InfoVal (DebOMaticHostMirror hostname)) }
+
+the Idea after is to create a property which will take the DeboMatic Info and generate the
+/etc/apt/sourses.list.d/debomatic.list on a bunch of hosts.
+
+Maybe we could have a
+
+ typeclass Mirror a where
+ toSourceListDLines :: a -> [Line]
+
+ instance Mirror DebOMaticHostMirror where
+ toSourceListDLines (DebOMaticHostMirror hostname) = ...
+
+then the stdSourceListD property should be change to use toSourceListDLines
+
+but this is another story :)
diff --git a/doc/forum/How_to_create_a_property_with_info/comment_1_819902ee6b8e571f735dd2c9c93c49a9._comment b/doc/forum/How_to_create_a_property_with_info/comment_1_819902ee6b8e571f735dd2c9c93c49a9._comment
new file mode 100644
index 00000000..853e6e86
--- /dev/null
+++ b/doc/forum/How_to_create_a_property_with_info/comment_1_819902ee6b8e571f735dd2c9c93c49a9._comment
@@ -0,0 +1,29 @@
+[[!comment format=mdwn
+ username="joey"
+ subject="""comment 1"""
+ date="2017-08-25T23:07:12Z"
+ content="""
+It's not allowed for the content of Info to come from an IO action.
+Info has to be static. This allows one Host to introspect the Info of
+another Host. The Dns properties rely on that.
+
+So, the type checker is right in preventing this. It's also not allowed
+to use ensureProperty with a property that HasInfo, as the info would
+not propigate to the outer property. The type checker is also preventing
+you making that mistake.
+
+(You also forgot to pass the `w` parameter to `ensureProperty`,
+which made the type checker unhappy as well and probably confused the error
+messages.)
+
+To accomplish your goal, you could use:
+
+ data DebOMaticHostMirror = DebOMaticHostMirror
+
+If a Host has this in its Info, you know that Host is the one with
+debomatic installed. You can then get its hostname using the `hostName`
+field accessor on the Host.
+
+The property that does that will need to be passed a `[Host]` which will
+typically be the `hosts` list defined in config.hs.
+"""]]
diff --git a/doc/forum/How_to_create_a_property_with_info/comment_2_1c2b3cb54f27fb6b6bb5de9d159dd34f._comment b/doc/forum/How_to_create_a_property_with_info/comment_2_1c2b3cb54f27fb6b6bb5de9d159dd34f._comment
new file mode 100644
index 00000000..6034e6e5
--- /dev/null
+++ b/doc/forum/How_to_create_a_property_with_info/comment_2_1c2b3cb54f27fb6b6bb5de9d159dd34f._comment
@@ -0,0 +1,15 @@
+[[!comment format=mdwn
+ username="picca"
+ avatar="http://cdn.libravatar.org/avatar/7e61c80d28018b10d31f6db7dddb864c"
+ subject="comment 2"
+ date="2017-08-26T06:29:44Z"
+ content="""
+I could have multiple host with debomatic install on it.
+I need to create a property which take a list of hosts (all with the Debomatic info) in order to generate the sources.list files.
+This way it is possible for me to select per host the sources of packages.
+
+what should be done in order to type check this ?
+I would like the compiler to says. Hey you ask for a source list from this host but it dos not contain a Debian mirror.
+
+Cheers
+"""]]
diff --git a/doc/forum/How_to_create_a_property_with_info/comment_3_6cf0360b4922a131bca33d33acf078be._comment b/doc/forum/How_to_create_a_property_with_info/comment_3_6cf0360b4922a131bca33d33acf078be._comment
new file mode 100644
index 00000000..ac4ca94b
--- /dev/null
+++ b/doc/forum/How_to_create_a_property_with_info/comment_3_6cf0360b4922a131bca33d33acf078be._comment
@@ -0,0 +1,11 @@
+[[!comment format=mdwn
+ username="joey"
+ subject="""comment 3"""
+ date="2017-08-28T22:38:55Z"
+ content="""
+Finding a way to type check that, I don't know. It would certianly be nice
+to be able to statically check such things. The way that Info is
+implemented as a monoid that contains many different types seems to
+preclude exposing enough information for the type checker to catch such a
+problem. So it would have to be changed somehow, I don't know how.
+"""]]
diff --git a/doc/forum/Sbuild_chroot_are_not_compatible_with_schroot/comment_3_6aeee8ba74b363d26a49d6773c5d5014._comment b/doc/forum/Sbuild_chroot_are_not_compatible_with_schroot/comment_3_6aeee8ba74b363d26a49d6773c5d5014._comment
new file mode 100644
index 00000000..12d59028
--- /dev/null
+++ b/doc/forum/Sbuild_chroot_are_not_compatible_with_schroot/comment_3_6aeee8ba74b363d26a49d6773c5d5014._comment
@@ -0,0 +1,12 @@
+[[!comment format=mdwn
+ username="spwhitton"
+ avatar="http://cdn.libravatar.org/avatar/9c3f08f80e67733fd506c353239569eb"
+ subject="comment 3"
+ date="2017-09-02T02:47:01Z"
+ content="""
+Thank you for the detailed report.
+
+I think the problem is the proxy propagation happens after the sbuild-createchroot command has run, but if the sbuild-createchroot command needs the proxy, it will fail in the way you describe.
+
+After speaking to Joey at DebConf I think I can rework the sbuild module to bypass sbuild-createchroot and run debootstrap itself, without thereby polluting the chroot that is created. That should make it much easier to fix this bug, so I'll do that first.
+"""]]
diff --git a/doc/forum/creating_Bind9_configuration/comment_3_6b4d73b17d87d00845fda26431ded422._comment b/doc/forum/creating_Bind9_configuration/comment_3_6b4d73b17d87d00845fda26431ded422._comment
new file mode 100644
index 00000000..c61feaab
--- /dev/null
+++ b/doc/forum/creating_Bind9_configuration/comment_3_6b4d73b17d87d00845fda26431ded422._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="Nicolas.Schodet"
+ avatar="http://cdn.libravatar.org/avatar/0d7ec808ec329d04ee9a93c0da3c0089"
+ subject="comment 3"
+ date="2017-08-28T14:03:35Z"
+ content="""
+It might be a configuration from my server provider, maybe I should do a clean install :)
+
+If not using a full clone, I also have problem because I cannot use things like Utility.Units.
+"""]]
diff --git a/doc/todo/LVM_logical_volume_creation__44___resize__44___format___38___removal.mdwn b/doc/todo/LVM_logical_volume_creation__44___resize__44___format___38___removal.mdwn
new file mode 100644
index 00000000..4b3198ee
--- /dev/null
+++ b/doc/todo/LVM_logical_volume_creation__44___resize__44___format___38___removal.mdwn
@@ -0,0 +1,9 @@
+I have made a new property to handle logical volume with propellor.
+
+I am not confident my haskell code is good looking as this is my first real life haskell code, can you please have a look?
+
+You can pull the lvm branch at http://git.ni.fr.eu.org/nicolas/propellor.git
+
+Thanks!
+
+> merge [[done]] --[[Joey]]
diff --git a/doc/todo/LVM_logical_volume_creation__44___resize__44___format___38___removal/comment_1_74c6576b25f74c6e620eb015af8b0f6a._comment b/doc/todo/LVM_logical_volume_creation__44___resize__44___format___38___removal/comment_1_74c6576b25f74c6e620eb015af8b0f6a._comment
new file mode 100644
index 00000000..5982361f
--- /dev/null
+++ b/doc/todo/LVM_logical_volume_creation__44___resize__44___format___38___removal/comment_1_74c6576b25f74c6e620eb015af8b0f6a._comment
@@ -0,0 +1,26 @@
+[[!comment format=mdwn
+ username="joey"
+ subject="""comment 1"""
+ date="2017-08-31T22:40:34Z"
+ content="""
+That's a pretty nice job for your first haskell code! And an impressive
+module.
+
+Most of my review comments have to do with improving types.. Which is
+always a nice way to improve already good code. :)
+
+* VolumeGroup and LogicalVolume seem like easy things to mix up.
+ Also, there's never a LogicalVolume without an associated VolumeGroup.
+ So, suggest `newtype VolumeGroup = VolumeGroup String` and
+ `data LogicalVolume = LogicalVolume String VolumeGroup` -- then
+ the user would write something like
+ `LogicalVolume "test" (VolumeGroup "vg0")`
+* Why not make `LvState` contain a `Maybe Partition.Fs` rather than
+ the string value. (This also would move the parsing of filesystem names
+ from `fsMatch` to `lvState` or perhaps to another function it uses.)
+* It seems a bit wrong for `parseSize` to include the rounding
+ to the next extent, which is not really related to parsing.
+ Would be better to split those two things into separate functions.
+
+I feel that this module is fairly close to mergeable.
+"""]]
diff --git a/doc/todo/LVM_logical_volume_creation__44___resize__44___format___38___removal/comment_2_d63d84b56ece233f795d1075aaba887a._comment b/doc/todo/LVM_logical_volume_creation__44___resize__44___format___38___removal/comment_2_d63d84b56ece233f795d1075aaba887a._comment
new file mode 100644
index 00000000..546fe436
--- /dev/null
+++ b/doc/todo/LVM_logical_volume_creation__44___resize__44___format___38___removal/comment_2_d63d84b56ece233f795d1075aaba887a._comment
@@ -0,0 +1,18 @@
+[[!comment format=mdwn
+ username="Nicolas.Schodet"
+ avatar="http://cdn.libravatar.org/avatar/0d7ec808ec329d04ee9a93c0da3c0089"
+ subject="comment 2"
+ date="2017-09-01T21:38:16Z"
+ content="""
+Thanks for your comments.
+
+I also have a problem when running vgs/lvs, they complain about leaked file descriptors. Is it something I can fix?
+
+ File descriptor 10 (/usr/local/propellor/.lock) leaked on vgs invocation. Parent PID 31216: ./dist/build/propellor-config/p
+ File descriptor 11 (pipe:[282601]) leaked on vgs invocation. Parent PID 31216: ./dist/build/propellor-config/p
+ File descriptor 12 (pipe:[282601]) leaked on vgs invocation. Parent PID 31216: ./dist/build/propellor-config/p
+ File descriptor 13 (pipe:[282602]) leaked on vgs invocation. Parent PID 31216: ./dist/build/propellor-config/p
+ File descriptor 14 (pipe:[282602]) leaked on vgs invocation. Parent PID 31216: ./dist/build/propellor-config/p
+
+I have pushed a new version with the suggested fixes.
+"""]]
diff --git a/doc/todo/LVM_logical_volume_creation__44___resize__44___format___38___removal/comment_3_1405e20c8f5dc6e9cca3732e3e368d03._comment b/doc/todo/LVM_logical_volume_creation__44___resize__44___format___38___removal/comment_3_1405e20c8f5dc6e9cca3732e3e368d03._comment
new file mode 100644
index 00000000..76c89ca6
--- /dev/null
+++ b/doc/todo/LVM_logical_volume_creation__44___resize__44___format___38___removal/comment_3_1405e20c8f5dc6e9cca3732e3e368d03._comment
@@ -0,0 +1,25 @@
+[[!comment format=mdwn
+ username="joey"
+ subject="""comment 3"""
+ date="2017-09-01T22:32:43Z"
+ content="""
+One way would be to use System.Process's `close_fds` when executing
+vgs/lvs. BTW, I've seen such complaints from lvm before, in some
+situations not involving propellor.
+
+I've made a commit that makes the propellor lock FD be close-on-exec,
+which is generally a good idea for lock FDs anyway. (To prevent some
+long-running daemon process that does not close such FDs keeping the lock
+held.)
+
+My guess is that the other 4 FDs, which are apparently pairs of FDs
+at both sides of a pipe, come from
+System.Console.Concurrent.Internal.bgProcess, which sets up just such a
+pipe. Quite possibly when vgs/lvs are run, it's via that function.
+
+Generally leaking non-lock-related FDs to child processes is not a big
+problem, as long as the child process doesn't write to random FDs (which
+would be pretty bad, but what would ever do that?) ... So I don't know if I
+want to try to chase down every FD used all through propellor to set them
+close-on-exec.
+"""]]
diff --git a/doc/todo/LVM_logical_volume_creation__44___resize__44___format___38___removal/comment_4_20c6734d67fefeb1a8c07730d537e06b._comment b/doc/todo/LVM_logical_volume_creation__44___resize__44___format___38___removal/comment_4_20c6734d67fefeb1a8c07730d537e06b._comment
new file mode 100644
index 00000000..74a8bbe1
--- /dev/null
+++ b/doc/todo/LVM_logical_volume_creation__44___resize__44___format___38___removal/comment_4_20c6734d67fefeb1a8c07730d537e06b._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="Nicolas.Schodet"
+ avatar="http://cdn.libravatar.org/avatar/0d7ec808ec329d04ee9a93c0da3c0089"
+ subject="comment 4"
+ date="2017-09-03T21:00:36Z"
+ content="""
+I can rebase/squash, do you see something else to improve?
+"""]]
diff --git a/doc/todo/LVM_logical_volume_creation__44___resize__44___format___38___removal/comment_5_aee8b3d2768fb7307a6cc2e3295fd1f6._comment b/doc/todo/LVM_logical_volume_creation__44___resize__44___format___38___removal/comment_5_aee8b3d2768fb7307a6cc2e3295fd1f6._comment
new file mode 100644
index 00000000..6850f3b9
--- /dev/null
+++ b/doc/todo/LVM_logical_volume_creation__44___resize__44___format___38___removal/comment_5_aee8b3d2768fb7307a6cc2e3295fd1f6._comment
@@ -0,0 +1,12 @@
+[[!comment format=mdwn
+ username="joey"
+ subject="""comment 5"""
+ date="2017-09-05T20:23:44Z"
+ content="""
+Looks good to me, merged. Thanks for your contribution!
+
+(I did make a simplification to it
+in [[!commit 0a6ad2b17419fd877789053c87b95866cfc39c46]],
+which seems ok by inspection to me, but I've not tested. Please
+let me know if I somehow got that wrong.)
+"""]]
diff --git a/doc/todo/unpropelling_a_host.mdwn b/doc/todo/unpropelling_a_host.mdwn
new file mode 100644
index 00000000..5c31bd90
--- /dev/null
+++ b/doc/todo/unpropelling_a_host.mdwn
@@ -0,0 +1,9 @@
+We discussed at DebConf the need for a property that removes propellor from a host. It would run itself at the end of the spin. It needs to nuke `/usr/local/propellor`. To what extent can it remove propellor's build dependencies? I can see two problems to be resolved before writing any code.
+
+1. There is no standard way to remove cabal and stack packages from `/root` without potentially nuking stuff the user wants to keep. So maybe the property should remove only OS packages? I.e. best used on `OSOnly` hosts/chroots.
+
+2. What if another property on the host installs some or all of those build dependencies? This property would be cancelled out by the unpropellor property. Maybe properties that install packages need to [[set info about the packages that are meant to remain installed|todo/metapackage]]?
+
+The unpropellor property could just nuke `/usr/local/propellor` and leave it at that. But then the sbuild module would need to maintain a list of propellor's build deps to remove from the newly created chroot, which is a third copy of the list..
+
+--spwhitton
diff --git a/privdata/relocate b/privdata/relocate
deleted file mode 100644
index 271692d8..00000000
--- a/privdata/relocate
+++ /dev/null
@@ -1 +0,0 @@
-.joeyconfig
diff --git a/propellor.cabal b/propellor.cabal
index 0fac1565..8089c107 100644
--- a/propellor.cabal
+++ b/propellor.cabal
@@ -127,6 +127,7 @@ Library
Propellor.Property.LightDM
Propellor.Property.Locale
Propellor.Property.Logcheck
+ Propellor.Property.Lvm
Propellor.Property.Mount
Propellor.Property.Network
Propellor.Property.Nginx
diff --git a/src/Propellor/Engine.hs b/src/Propellor/Engine.hs
index f54da929..b4dc66ce 100644
--- a/src/Propellor/Engine.hs
+++ b/src/Propellor/Engine.hs
@@ -97,6 +97,7 @@ onlyProcess lockfile a = bracket lock unlock (const a)
lock = do
createDirectoryIfMissing True (takeDirectory lockfile)
l <- createFile lockfile stdFileMode
+ setFdOption l CloseOnExec True
setLock l (WriteLock, AbsoluteSeek, 0, 0)
`catchIO` const alreadyrunning
return l
diff --git a/src/Propellor/Property/Lvm.hs b/src/Propellor/Property/Lvm.hs
new file mode 100644
index 00000000..d513c1be
--- /dev/null
+++ b/src/Propellor/Property/Lvm.hs
@@ -0,0 +1,171 @@
+-- | Maintainer: Nicolas Schodet <nico@ni.fr.eu.org>
+--
+-- Support for LVM logical volumes.
+
+module Propellor.Property.Lvm (
+ lvFormatted,
+ installed,
+ Eep(..),
+ VolumeGroup(..),
+ LogicalVolume(..),
+) where
+
+import Propellor
+import Propellor.Base
+import Utility.DataUnits
+import qualified Propellor.Property.Apt as Apt
+import qualified Propellor.Property.Mount as Mount
+import qualified Propellor.Property.Partition as Partition
+
+data Eep = YesReallyFormatLogicalVolume
+
+type DataSize = String
+
+newtype VolumeGroup = VolumeGroup String
+data LogicalVolume = LogicalVolume String VolumeGroup
+
+-- | Create or resize a logical volume, and make sure it is formatted. When
+-- reverted, remove the logical volume.
+--
+-- Example use:
+--
+-- > import qualified Propellor.Property.Lvm as Lvm
+-- > import qualified Propellor.Property.Partition as Partition
+-- > Lvm.lvFormatted Lvm.YesReallyFormatLogicalVolume
+-- > (Lvm.LogicalVolume "test" (Lvm.VolumeGroup "vg0")) "16m"
+-- > Partition.EXT4
+--
+-- If size and filesystem match, nothing is done.
+--
+-- Volume group must have been created already.
+lvFormatted
+ :: Eep
+ -> LogicalVolume
+ -> DataSize
+ -> Partition.Fs
+ -> RevertableProperty DebianLike UnixLike
+lvFormatted YesReallyFormatLogicalVolume lv sz fs =
+ setup <!> cleanup
+ where
+ setup :: Property DebianLike
+ setup = property' ("formatted logical volume " ++ (vglv lv)) $ \w -> do
+ es <- liftIO $ vgExtentSize vg
+ case es of
+ Nothing -> errorMessage $
+ "can not get extent size, does volume group "
+ ++ vgname ++ " exist?"
+ Just extentSize -> do
+ case parseSize of
+ Nothing -> errorMessage
+ "can not parse volume group size"
+ Just size -> do
+ state <- liftIO $ lvState lv
+ let rsize = roundSize extentSize size
+ ensureProperty w $
+ setupprop rsize state
+
+ cleanup :: Property UnixLike
+ cleanup = property' ("removed logical volume " ++ (vglv lv)) $ \w -> do
+ exists <- liftIO $ lvExists lv
+ ensureProperty w $ if exists
+ then removedprop
+ else doNothing
+
+ -- Parse size.
+ parseSize :: Maybe Integer
+ parseSize = readSize dataUnits sz
+
+ -- Round size to next extent size multiple.
+ roundSize :: Integer -> Integer -> Integer
+ roundSize extentSize s =
+ (s + extentSize - 1) `div` extentSize * extentSize
+
+ -- Dispatch to the right props.
+ setupprop :: Integer -> (Maybe LvState) -> Property DebianLike
+ setupprop size Nothing = createdprop size `before` formatprop
+ setupprop size (Just (LvState csize cfs))
+ | size == csize && fsMatch fs cfs = doNothing
+ | size == csize = formatprop
+ | fsMatch fs cfs = tightenTargets $ resizedprop size True
+ | otherwise = resizedprop size False `before` formatprop
+
+ createdprop :: Integer -> Property UnixLike
+ createdprop size =
+ cmdProperty "lvcreate"
+ (bytes size $ [ "-n", lvname, "--yes", vgname ])
+ `assume` MadeChange
+
+ resizedprop :: Integer -> Bool -> Property UnixLike
+ resizedprop size rfs =
+ cmdProperty "lvresize"
+ (resizeFs rfs $ bytes size $ [ vglv lv ])
+ `assume` MadeChange
+ where
+ resizeFs True l = "-r" : l
+ resizeFs False l = l
+
+ removedprop :: Property UnixLike
+ removedprop = cmdProperty "lvremove" [ "-f", vglv lv ]
+ `assume` MadeChange
+
+ formatprop :: Property DebianLike
+ formatprop = Partition.formatted Partition.YesReallyFormatPartition
+ fs (path lv)
+
+ fsMatch :: Partition.Fs -> Maybe Partition.Fs -> Bool
+ fsMatch a (Just b) = a == b
+ fsMatch _ _ = False
+
+ bytes size l = "-L" : ((show size) ++ "b") : l
+
+ (LogicalVolume lvname vg@(VolumeGroup vgname)) = lv
+
+-- | Make sure needed tools are installed.
+installed :: RevertableProperty DebianLike DebianLike
+installed = install <!> remove
+ where
+ install = Apt.installed ["lvm2"]
+ remove = Apt.removed ["lvm2"]
+
+data LvState = LvState Integer (Maybe Partition.Fs)
+
+-- Check for logical volume existance.
+lvExists :: LogicalVolume -> IO Bool
+lvExists lv = doesFileExist (path lv)
+
+-- Return Nothing if logical volume does not exists (or error), else return
+-- its size and maybe file system.
+lvState :: LogicalVolume -> IO (Maybe LvState)
+lvState lv = do
+ exists <- lvExists lv
+ if not exists
+ then return Nothing
+ else do
+ s <- readLvSize
+ fs <- maybe Nothing Partition.parseFs <$> readFs
+ return $ do
+ size <- s
+ return $ LvState size fs
+ where
+ readLvSize = catchDefaultIO Nothing $ readish
+ <$> readProcess "lvs" [ "-o", "size", "--noheadings",
+ "--nosuffix", "--units", "b", vglv lv ]
+ readFs = Mount.blkidTag "TYPE" (path lv)
+
+-- Read extent size (or Nothing on error).
+vgExtentSize :: VolumeGroup -> IO (Maybe Integer)
+vgExtentSize (VolumeGroup vgname) =
+ catchDefaultIO Nothing $ readish
+ <$> readProcess "vgs" [ "-o", "vg_extent_size",
+ "--noheadings", "--nosuffix", "--units", "b", vgname ]
+
+-- Give "vgname/lvname" for a LogicalVolume.
+vglv :: LogicalVolume -> String
+vglv lv =
+ vgname </> lvname
+ where
+ (LogicalVolume lvname (VolumeGroup vgname)) = lv
+
+-- Give device path.
+path :: LogicalVolume -> FilePath
+path lv = "/dev" </> (vglv lv)
diff --git a/src/Propellor/Property/Partition.hs b/src/Propellor/Property/Partition.hs
index 679675b7..27ae89ff 100644
--- a/src/Propellor/Property/Partition.hs
+++ b/src/Propellor/Property/Partition.hs
@@ -15,6 +15,20 @@ import Data.Char
data Fs = EXT2 | EXT3 | EXT4 | BTRFS | REISERFS | XFS | FAT | VFAT | NTFS | LinuxSwap
deriving (Show, Eq)
+-- | Parse commonly used names of filesystems.
+parseFs :: String -> Maybe Fs
+parseFs "ext2" = Just EXT2
+parseFs "ext3" = Just EXT3
+parseFs "ext4" = Just EXT4
+parseFs "btrfs" = Just BTRFS
+parseFs "reiserfs" = Just REISERFS
+parseFs "xfs" = Just XFS
+parseFs "fat" = Just FAT
+parseFs "vfat" = Just VFAT
+parseFs "ntfs" = Just NTFS
+parseFs "swap" = Just LinuxSwap
+parseFs _ = Nothing
+
data Eep = YesReallyFormatPartition
-- | Formats a partition.