From a1655d24bbb1db9caccdf93eae8110d746389ae2 Mon Sep 17 00:00:00 2001 From: Joey Hess Date: Mon, 28 Mar 2016 05:53:38 -0400 Subject: type safe targets for properties * Property types have been improved to indicate what systems they target. This prevents using eg, Property FreeBSD on a Debian system. Transition guide for this sweeping API change: - Change "host name & foo & bar" to "host name $ props & foo & bar" - Similarly, `propertyList` and `combineProperties` need `props` to be used to combine together properties; they no longer accept lists of properties. (If you have such a list, use `toProps`.) - And similarly, Chroot, Docker, and Systemd container need `props` to be used to combine together the properies used inside them. - The `os` property is removed. Instead use `osDebian`, `osBuntish`, or `osFreeBSD`. These tell the type checker the target OS of a host. - Change "Property NoInfo" to "Property UnixLike" - Change "Property HasInfo" to "Property (HasInfo + UnixLike)" - Change "RevertableProperty NoInfo" to "RevertableProperty UnixLike UnixLike" - Change "RevertableProperty HasInfo" to "RevertableProperty (HasInfo + UnixLike) UnixLike" - GHC needs {-# LANGUAGE TypeOperators #-} to use these fancy types. This is enabled by default for all modules in propellor.cabal. But if you are using propellor as a library, you may need to enable it manually. - If you know a property only works on a particular OS, like Debian or FreeBSD, use that instead of "UnixLike". For example: "Property Debian" - It's also possible make a property support a set of OS's, for example: "Property (Debian + FreeBSD)" - Removed `infoProperty` and `simpleProperty` constructors, instead use `property` to construct a Property. - Due to the polymorphic type returned by `property`, additional type signatures tend to be needed when using it. For example, this will fail to type check, because the type checker cannot guess what type you intend the intermediate property "go" to have: foo :: Property UnixLike foo = go `requires` bar where go = property "foo" (return NoChange) To fix, specify the type of go: go :: Property UnixLike - `ensureProperty` now needs to be passed a witness to the type of the property it's used in. change this: foo = property desc $ ... ensureProperty bar to this: foo = property' desc $ \w -> ... ensureProperty w bar - General purpose properties like cmdProperty have type "Property UnixLike". When using that to run a command only available on Debian, you can tighten the type to only the OS that your more specific property works on. For example: upgraded :: Property Debian upgraded = tightenTargets (cmdProperty "apt-get" ["upgrade"]) - Several utility functions have been renamed: getInfo to fromInfo propertyInfo to getInfo propertyDesc to getDesc propertyChildren to getChildren * The new `pickOS` property combinator can be used to combine different properties, supporting different OS's, into one Property that chooses which to use based on the Host's OS. * Re-enabled -O0 in propellor.cabal to reign in ghc's memory use handling these complex new types. * Added dependency on concurrent-output; removed embedded copy. --- doc/FreeBSD.mdwn | 6 ++++-- doc/Linux.mdwn | 2 +- doc/haskell_newbie.mdwn | 6 +++--- doc/todo/depend_on_concurrent-output.mdwn | 3 +++ doc/todo/type_level_OS_requirements.mdwn | 7 +++---- doc/writing_properties.mdwn | 10 +++++----- 6 files changed, 19 insertions(+), 15 deletions(-) (limited to 'doc') diff --git a/doc/FreeBSD.mdwn b/doc/FreeBSD.mdwn index 2edff223..47b9c65b 100644 --- a/doc/FreeBSD.mdwn +++ b/doc/FreeBSD.mdwn @@ -1,8 +1,10 @@ Propellor is in the early stages of supporting FreeBSD. It should basically work, and there are some modules with FreeBSD-specific properties. -However, many other properties assume they're being run on a -Debian Linux system, and need additional porting to support FreeBSD. +However, many other properties only work on a Debian Linux system, and need +additional porting to support FreeBSD. Such properties have types like +`Property DebianLike`. The type checker will detect and reject attempts +to combine such properties with `Property FreeBSD`. [Sample config file](http://git.joeyh.name/?p=propellor.git;a=blob;f=config-freebsd.hs) which configures a FreeBSD system, as well as a Linux one. diff --git a/doc/Linux.mdwn b/doc/Linux.mdwn index 0434d69d..00276f69 100644 --- a/doc/Linux.mdwn +++ b/doc/Linux.mdwn @@ -6,4 +6,4 @@ Indeed, Propellor has been ported to [[FreeBSD]] now! See [[forum/Supported_OS]] for porting tips. Note that you can run Propellor on a OSX laptop and have it manage Linux -systems. +and other systems. diff --git a/doc/haskell_newbie.mdwn b/doc/haskell_newbie.mdwn index e92481f9..bd343cd6 100644 --- a/doc/haskell_newbie.mdwn +++ b/doc/haskell_newbie.mdwn @@ -48,12 +48,12 @@ Finally, you need to define the configuration for each host in the list: [[!format haskell """ mylaptop :: Host mylaptop = host "mylaptop.example.com" - & os (System (Debian Unstable) "amd64") + & osDebian Unstable "amd64" & Apt.stdSourcesList myserver :: Host myserver = host "server.example.com" - & os (System (Debian (Stable "jessie")) "amd64") + & osDebian (Stable "jessie") "amd64" & Apt.stdSourcesList & Apt.installed ["ssh"] """]] @@ -96,7 +96,7 @@ is.
 config.hs:30:19:
     Couldn't match expected type `RevertableProperty'
-                with actual type `Property NoInfo'
+                with actual type `Property DebianLike'
     In the return type of a call of `Apt.installed'
     In the second argument of `(!)', namely `Apt.installed ["ssh"]'
     In the first argument of `(&)', namely
diff --git a/doc/todo/depend_on_concurrent-output.mdwn b/doc/todo/depend_on_concurrent-output.mdwn
index fdc66b04..a104c82b 100644
--- a/doc/todo/depend_on_concurrent-output.mdwn
+++ b/doc/todo/depend_on_concurrent-output.mdwn
@@ -8,3 +8,6 @@ Once this is done, can switch GHC-Options back to -O0 from -O.
 -O0 is better because ghc takes less memory to build propellor.
 
 [[!tag user/joey]]
+
+> [[done]]. Didn't wait for it to hit stable; cabal will be used to install
+> it.
diff --git a/doc/todo/type_level_OS_requirements.mdwn b/doc/todo/type_level_OS_requirements.mdwn
index 7c2fb78f..f1c3e59f 100644
--- a/doc/todo/type_level_OS_requirements.mdwn
+++ b/doc/todo/type_level_OS_requirements.mdwn
@@ -21,13 +21,12 @@ withOS.
 
 The `os` property would need to yield a `Property (os:[])`, where the type
 level list contains a type-level eqivilant of the value passed to the
-property. Is that possible to do? reification or something?
-(See: )
-Or, alternatively, could have less polymorphic `debian` etc
+property. Is that possible to do?
+Or, alternatively, could have less polymorphic `osDebian` etc
 properties replace the `os` property.
 
 If a Host's list of properties, when all combined together,
-contains more than one element in its '[OS], that needs to be a type error,
+contains more than one element in its '[OS], that could be a type error,
 the OS of the Host is indeterminite. Which would be fixed by using the `os`
 property to specify.
 
diff --git a/doc/writing_properties.mdwn b/doc/writing_properties.mdwn
index 2209026f..1b7f046a 100644
--- a/doc/writing_properties.mdwn
+++ b/doc/writing_properties.mdwn
@@ -31,7 +31,7 @@ Propellor makes it very easy to put together a property like this.
 
 Let's start with a property that combines the two properties you mentioned:
 
-	hasLoginShell :: UserName -> FilePath -> Property
+	hasLoginShell :: UserName -> FilePath -> Property UnixLike
 	hasLoginShell user shell = shellSetTo user shell `requires` shellEnabled shell
 
 The shellEnabled property can be easily written using propellor's file
@@ -40,14 +40,14 @@ manipulation properties.
 	-- Need to add an import to the top of the source file.
 	import qualified Propellor.Property.File as File
 
-	shellEnabled :: FilePath -> Property
+	shellEnabled :: FilePath -> Property UnixLike
 	shellEnabled shell = "/etc/shells" `File.containsLine` shell
 
 And then, we want to actually change the user's shell. The `chsh(1)`
 program can do that, so we can simply tell propellor the command line to
 run:
 
-	shellSetTo :: UserName -> FilePath -> Property
+	shellSetTo :: UserName -> FilePath -> Property UnixLike
 	shellSetTo user shell = cmdProperty "chsh" ["--shell", shell, user]
 
 The only remaining problem with this is that shellSetTo runs chsh every
@@ -56,7 +56,7 @@ it runs, even when it didn't really do much. Now, there's an easy way to
 avoid that problem, we could just tell propellor to assume that chsh
 has not made a change:
 	
-	shellSetTo :: UserName -> FilePath -> Property
+	shellSetTo :: UserName -> FilePath -> Property UnixLike
 	shellSetTo user shell = cmdProperty "chsh" ["--shell", shell, user]
 		`assume` NoChange
 
@@ -64,7 +64,7 @@ But, it's not much harder to do this right. Let's make the property
 check if the user's shell is already set to the desired value and avoid
 doing anything in that case.
 
-	shellSetTo :: UserName -> FilePath -> Property
+	shellSetTo :: UserName -> FilePath -> Property UnixLike
 	shellSetTo user shell = check needchangeshell $
 		cmdProperty "chsh" ["--shell", shell, user]
 	  where
-- 
cgit v1.2.3