new page
This commit is contained in:
parent
e49af37fe8
commit
4020a3e707
|
@ -5,6 +5,7 @@ Other documentation:
|
|||
|
||||
* [[man page|usage]]
|
||||
* [[Haskell Newbie]]
|
||||
* [[Writing Properties]]
|
||||
* [[Centralized Git Repository]]
|
||||
* [[Components]]
|
||||
* [[Contributing]]
|
||||
|
|
|
@ -114,7 +114,8 @@ That's really all there is to configuring Propellor. Once you
|
|||
have a `config.hs` ready to try out, you can run `propellor --spin $host`
|
||||
on one of the hosts configured in it.
|
||||
|
||||
See the [[README]] for a further quick start.
|
||||
See the [[README]] for a further quick start and [[Writing Properties]]
|
||||
for guidance on extending propellor with your own custom properties.
|
||||
|
||||
(If you'd like to learn a little Haskell after all, check out
|
||||
[Learn You a Haskell for Great Good](http://learnyouahaskell.com/).)
|
||||
|
|
|
@ -0,0 +1,82 @@
|
|||
Propellor comes with a lot of properties you can use. But eventually,
|
||||
you'll want to write a property of your own.
|
||||
|
||||
This isn't hard. Often propellor has some properties you can use to build
|
||||
the property you want. Need to modify the content of a file? Use any of
|
||||
the properties in
|
||||
[Propellor.Property.File](http://hackage.haskell.org/package/propellor-2.2.1/docs/Propellor-Property-File.htm)
|
||||
Need to run some commands? Use [Propellor.Property.Cmd](http://hackage.haskell.org/package/propellor-2.2.1/docs/Propellor-Property-Cmd.html).
|
||||
|
||||
To combine properties, the easiest way is to use `requires`.
|
||||
|
||||
someproperty `requires` otherproperty
|
||||
|
||||
[Propellor.Property.List](http://hackage.haskell.org/package/propellor-2.2.1/docs/Propellor-Property-List.html)
|
||||
has a `propertyList` combinator that's also useful.
|
||||
|
||||
[Propellor.Property](http://hackage.haskell.org/package/propellor-2.2.1/docs/Propellor-Property.html)
|
||||
has some other functions to modify Properties in useful ways.
|
||||
For example, `check` makes a Property call an `IO Bool` to check if the
|
||||
Property needs be run.
|
||||
|
||||
## example: User.hasLoginShell
|
||||
|
||||
> As far as I can tell there is no easy way to set a user's
|
||||
> login shell. A Property User.hasLoginShell, which ensures
|
||||
> that a user has a specified login shell and that said shell
|
||||
> is in /etc/shells would be really helpful. Sadly, I lack the
|
||||
> skills to put this together myself :( -- weinzwang
|
||||
|
||||
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 user shell = shellSetTo user shell `requires` shellEnabled shell
|
||||
|
||||
The shellEnabled property can be easily written using propellor's file
|
||||
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 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 user shell = cmdProperty "chsh" ["--shell", shell, user]
|
||||
|
||||
The only remaining problem with this is that shellSetTo runs chsh every
|
||||
time, and propellor will always display that it's made a change each time
|
||||
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 that it's a trivial
|
||||
property, and then it will run chsh every time and not think it made any
|
||||
change:
|
||||
|
||||
shellSetTo :: UserName -> FilePath -> Property
|
||||
shellSetTo user shell = trivial $
|
||||
cmdProperty "chsh" ["--shell", shell, user]
|
||||
|
||||
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 user shell = check needchangeshell $
|
||||
cmdProperty "chsh" ["--shell", shell, user]
|
||||
where
|
||||
needchangeshell = do
|
||||
currshell <- userShell <$> getUserEntryForName user
|
||||
return (currshell /= shell)
|
||||
|
||||
And that will probably all work, although I've not tested it. You might
|
||||
want to throw in some uses of `describe` to give the new properties
|
||||
more useful descriptions.
|
||||
|
||||
I hope this has been helpful as an explanation of how to add properties to
|
||||
Propellor, and if you get these properties to work, a patch adding them
|
||||
to Propellor.User would be happily merged.
|
Loading…
Reference in New Issue