diff options
89 files changed, 1800 insertions, 1331 deletions
@@ -1 +1 @@ -config-joey.hs
\ No newline at end of file +config-simple.hs
\ No newline at end of file diff --git a/debian/rules b/debian/rules index c88cc004..a71212db 100755 --- a/debian/rules +++ b/debian/rules @@ -1,4 +1,4 @@ -#!/bin/false +#!/usr/bin/make -f # Avoid using cabal, as it writes to $HOME export CABAL=./Setup diff --git a/doc/documentation.mdwn b/doc/documentation.mdwn index 340eb09f..99f61c04 100644 --- a/doc/documentation.mdwn +++ b/doc/documentation.mdwn @@ -1,14 +1,15 @@ The [API documentation](http://hackage.haskell.org/package/propellor) of -Propellor's modules is the most important docuemntation of propellor. +Propellor's modules is the most important documentation of propellor. Other documentation: * [[man page|usage]] * [[Haskell Newbie]] +* [[Writing Properties]] * [[Centralized Git Repository]] * [[Components]] * [[Contributing]] * [[Interface Stability]] -* [[Coding Stye]] +* [[Coding Style]] * [[Security]] * [[Debugging]] diff --git a/doc/forum/Apache.siteEnabled_doesn_not_update_the_apache_config_file.mdwn b/doc/forum/Apache.siteEnabled_doesn_not_update_the_apache_config_file.mdwn new file mode 100644 index 00000000..b678d8d0 --- /dev/null +++ b/doc/forum/Apache.siteEnabled_doesn_not_update_the_apache_config_file.mdwn @@ -0,0 +1,34 @@ +Hello, + +Still working on the reprepro property :) + +Here A property that I am using to publish a repository via apache (this is a prototype) + + website :: String -> Property + website hn = toProp $ Apache.siteEnabled hn apachecfg + where + apachecfg = [ "<VirtualHost *>" + , "DocumentRoot " ++ basePath + , "<Directory " ++ basePath ++ ">" + , " Options Indexes FollowSymLinks Multiviews" + , " Order allow,deny" + , Apache.allowAll + , "</Directory>" + ] ++ concatMap deny ["db", "conf", "incoming"] + ++ ["</VirtualHost>"] + + deny dir = [ "<Directory \"" ++ basePath ++ "apt/*/" ++ dir ++ "\">" + , " Order deny,allow" + , " Deny from all" + , "</Directory>" + ] + +during my test I am runing the config.hs with +runhaskell config.hs (it work the first time, the apache config files are ok) + +but when I do a modification on the apachecfg and rerun the runhaskell, +the config files are not updated. I need to remove them to have an updated version. + +cheers + +Fred diff --git a/doc/forum/Apache.siteEnabled_doesn_not_update_the_apache_config_file/comment_1_932ba6f4e444c99d8d561149d17c8fe7._comment b/doc/forum/Apache.siteEnabled_doesn_not_update_the_apache_config_file/comment_1_932ba6f4e444c99d8d561149d17c8fe7._comment new file mode 100644 index 00000000..0101ccb2 --- /dev/null +++ b/doc/forum/Apache.siteEnabled_doesn_not_update_the_apache_config_file/comment_1_932ba6f4e444c99d8d561149d17c8fe7._comment @@ -0,0 +1,30 @@ +[[!comment format=mdwn + username="picca" + subject="first run" + date="2014-12-08T09:31:46Z" + content=""" +root@mordor:~/propellor/src# PROPELLOR_DEBUG=1 runhaskell config.hs +[2014-12-08 10:27:10 CET] read: hostname [\"-f\"] +[2014-12-08 10:27:10 CET] command line: Run \"mordor\" +[2014-12-08 10:27:10 CET] read: git [\"remote\"] +[2014-12-08 10:27:10 CET] read: git [\"symbolic-ref\",\"--short\",\"HEAD\"] +[2014-12-08 10:27:10 CET] call: git [\"fetch\"] +Pull from central git repository ... done +[2014-12-08 10:27:12 CET] read: git [\"show-ref\",\"--hash\",\"master\"] +[2014-12-08 10:27:12 CET] read: git [\"show-ref\",\"--hash\",\"master\"] +mordor has Operating System (Debian Unstable) \"i386\" ... ok +[2014-12-08 10:27:12 CET] read: apt-cache [\"policy\",\"etckeeper\"] +mordor apt installed etckeeper ... ok +[2014-12-08 10:27:13 CET] read: apt-cache [\"policy\",\"ssh\"] +mordor apt installed ssh ... ok +[2014-12-08 10:27:13 CET] read: passwd [\"-S\",\"root\"] +mordor root has password ... ok +[2014-12-08 10:27:13 CET] call: a2query [\"-q\",\"-s\",\"reprepro\"] +[2014-12-08 10:27:14 CET] read: apt-cache [\"policy\",\"apache2\"] +[2014-12-08 10:27:14 CET] call: a2ensite [\"--quiet\",\"reprepro\"] +Enabling site reprepro. +[2014-12-08 10:27:15 CET] call: sh [\"-c\",\"set -e ; service 'apache2' reload >/dev/null 2>&1 || true\"] +mordor create reprepro ... done +mordor overall ... done + +"""]] diff --git a/doc/forum/Apache.siteEnabled_doesn_not_update_the_apache_config_file/comment_2_5323336b92d9aef5a9021b924029f3af._comment b/doc/forum/Apache.siteEnabled_doesn_not_update_the_apache_config_file/comment_2_5323336b92d9aef5a9021b924029f3af._comment new file mode 100644 index 00000000..85a57383 --- /dev/null +++ b/doc/forum/Apache.siteEnabled_doesn_not_update_the_apache_config_file/comment_2_5323336b92d9aef5a9021b924029f3af._comment @@ -0,0 +1,38 @@ +[[!comment format=mdwn + username="picca" + subject="second run with content modified" + date="2014-12-08T09:37:43Z" + content=""" +Second run after adding a space here + + - , \" Options Indexes FollowSymLinks Multiviews\" + + , \" Options Indexes FollowSymLinks Multiviews\" + + + root@mordor:~/propellor/src# PROPELLOR_DEBUG=1 runhaskell config.hs + [2014-12-08 10:34:19 CET] read: hostname [\"-f\"] + [2014-12-08 10:34:19 CET] command line: Run \"mordor\" + [2014-12-08 10:34:19 CET] read: git [\"remote\"] + [2014-12-08 10:34:19 CET] read: git [\"symbolic-ref\",\"--short\",\"HEAD\"] + [2014-12-08 10:34:19 CET] call: git [\"fetch\"] + remote: Counting objects: 32, done. + remote: Compressing objects: 100% (6/6), done. + remote: Total 6 (delta 3), reused 0 (delta 0) + Dépaquetage des objets: 100% (6/6), fait. + Depuis git://git.kitenet.net/propellor + c5a8cae..9ac0dfb master -> origin/master + Pull from central git repository ... done + [2014-12-08 10:34:20 CET] read: git [\"show-ref\",\"--hash\",\"master\"] + [2014-12-08 10:34:20 CET] read: git [\"show-ref\",\"--hash\",\"master\"] + mordor has Operating System (Debian Unstable) \"i386\" ... ok + [2014-12-08 10:34:20 CET] read: apt-cache [\"policy\",\"etckeeper\"] + mordor apt installed etckeeper ... ok + [2014-12-08 10:34:21 CET] read: apt-cache [\"policy\",\"ssh\"] + mordor apt installed ssh ... ok + [2014-12-08 10:34:21 CET] read: passwd [\"-S\",\"root\"] + mordor root has password ... ok + [2014-12-08 10:34:21 CET] call: a2query [\"-q\",\"-s\",\"reprepro\"] + mordor create reprepro ... ok + mordor overall ... ok + +"""]] diff --git a/doc/forum/Apache.siteEnabled_doesn_not_update_the_apache_config_file/comment_3_531c2c5e78fb5c62e54d84231b129dc8._comment b/doc/forum/Apache.siteEnabled_doesn_not_update_the_apache_config_file/comment_3_531c2c5e78fb5c62e54d84231b129dc8._comment new file mode 100644 index 00000000..5dc67fb0 --- /dev/null +++ b/doc/forum/Apache.siteEnabled_doesn_not_update_the_apache_config_file/comment_3_531c2c5e78fb5c62e54d84231b129dc8._comment @@ -0,0 +1,11 @@ +[[!comment format=mdwn + username="picca" + subject="comment 3" + date="2014-12-08T10:47:59Z" + content=""" +I forgot to say that the content of + +/etc/apache2/site-xxx/reprepro[.conf] + +is unmodifed after this second run +"""]] diff --git a/doc/forum/Apache.siteEnabled_doesn_not_update_the_apache_config_file/comment_4_54281604c588a7229f9d987e8cdee802._comment b/doc/forum/Apache.siteEnabled_doesn_not_update_the_apache_config_file/comment_4_54281604c588a7229f9d987e8cdee802._comment new file mode 100644 index 00000000..a9201541 --- /dev/null +++ b/doc/forum/Apache.siteEnabled_doesn_not_update_the_apache_config_file/comment_4_54281604c588a7229f9d987e8cdee802._comment @@ -0,0 +1,16 @@ +[[!comment format=mdwn + username="joey" + subject="""comment 4""" + date="2014-12-09T04:35:12Z" + content=""" +Pretty obvious why if you look at the code: + + enable = check (not <$> isenabled) $ + cmdProperty "a2ensite" ["--quiet", hn] + `describe` ("apache site enabled " ++ hn) + `requires` siteAvailable hn cf + +So that property was skipped entirely if the site was already enabled and never looked at the config file. + +I've put in a fix. +"""]] diff --git a/doc/forum/Propellor_without_superuser_privileges.mdwn b/doc/forum/Propellor_without_superuser_privileges.mdwn new file mode 100644 index 00000000..d7288a72 --- /dev/null +++ b/doc/forum/Propellor_without_superuser_privileges.mdwn @@ -0,0 +1,3 @@ +Joey uses propellor to popular his /home/joey on hosts he controls. I'd like to use it to populate my home directory on hosts where I don't have root. If someone gives me a shell account on a Debian box, it would be great to just run `propellor --spin` to have apply properties such as having certain stuff downloaded and compiled in `~/local/bin`, putting cronjobs in place, and checking stuff out with `myrepos`. + +Does propellor assume root access at a deep enough level that writing properties to do this stuff would be impractical? diff --git a/doc/forum/Propellor_without_superuser_privileges/comment_1_021ecbb1b8bd7e26776b49ec75e90d0c._comment b/doc/forum/Propellor_without_superuser_privileges/comment_1_021ecbb1b8bd7e26776b49ec75e90d0c._comment new file mode 100644 index 00000000..1a38ef94 --- /dev/null +++ b/doc/forum/Propellor_without_superuser_privileges/comment_1_021ecbb1b8bd7e26776b49ec75e90d0c._comment @@ -0,0 +1,26 @@ +[[!comment format=mdwn + username="joey" + subject="""comment 1""" + date="2014-12-26T19:26:00Z" + content=""" +I think that the root assumptions are in basically 3 places: + +* Many Properties assume they're run as root, and will fail if they're not. + Probably not a problem in practice for most of them. It might be nice + to make a few, such as `User.hasSomePassword` work when run as a normal + user. + +* Propellor's self-deployment involves running apt-get to instal ghc, + etc. This could be modified to check if it's not root and do a local + user of ghc if necessary. + +* `localdir = "/usr/local" and this is used in various places by eg, + `--spin`. It is, however, entirely possible to run "./propellor" in + some other directory, which causes it to run in that directory + and ensure the properties of localhost. `--spin` could certianly be + taught to run in a user mode where it uses "~/.propellor/" instead of + `localdir`. + +I think that's all! I don't plan to try to add this feature myself, but +will be happy to support anyone who wants to work on it. +"""]] diff --git a/doc/forum/Supported_OS.mdwn b/doc/forum/Supported_OS.mdwn new file mode 100644 index 00000000..f17b9054 --- /dev/null +++ b/doc/forum/Supported_OS.mdwn @@ -0,0 +1,5 @@ +What are the requirements for the configured OS ? Does it need to be Debian ? + +Would Propellor work for Arch linux, RHEL, Windows, AIX or linux on pSeries) ? + +Cheers diff --git a/doc/forum/Supported_OS/comment_1_f324bed708305e2667bd00f80544dd90._comment b/doc/forum/Supported_OS/comment_1_f324bed708305e2667bd00f80544dd90._comment new file mode 100644 index 00000000..3a2055ea --- /dev/null +++ b/doc/forum/Supported_OS/comment_1_f324bed708305e2667bd00f80544dd90._comment @@ -0,0 +1,23 @@ +[[!comment format=mdwn + username="joey" + subject="""comment 1""" + date="2014-12-07T15:58:03Z" + content=""" +I have heard of propellor being used on OSX. Probably that user wrote their +own code for OSX specific stuff. + +Propellor properites can be parameterized by OS. Currently it has support +for Debian and some untested support for Ubuntu. A property can be parameterized +like this: + + foo :: Property + foo = property "foo" withOS desc $ \o -> case o of + (Just (System (Debian _) _)) -> ensureProperty fooDebian + (Just (System (Ubuntu _) _)) -> ensureProperty fooUbuntu + +The first step for adding a new OS will be to modify <http://hackage.haskell.org/package/propellor-1.0.0/docs/Propellor-Types-OS.html>. +Compilation will then warn about all OS parameterized properties that +need to be updated to support your added OS, and it can be taken from there. + +I'll accept reasonable patches to support other OS's. +"""]] diff --git a/doc/forum/how_to_set_the_proxy_using_an_automatix_proxy.pac.mdwn b/doc/forum/how_to_set_the_proxy_using_an_automatix_proxy.pac.mdwn new file mode 100644 index 00000000..c88defcf --- /dev/null +++ b/doc/forum/how_to_set_the_proxy_using_an_automatix_proxy.pac.mdwn @@ -0,0 +1,12 @@ +Hello, + +I am trying propellor on Debian Jessie (haskell is fantastic for this sort or things) to setup one of my computer. + +On my network, the system administrator set proxies for http and https. +These information are available via a http://proxy/proxy.pac URL. + +So I would like to know what should be done to extract this information and set it for all users on the system ? + +Cheers + +Frederic diff --git a/doc/forum/how_to_set_the_proxy_using_an_automatix_proxy.pac/comment_1_69d7c8fb1d62300456575bb10e935d69._comment b/doc/forum/how_to_set_the_proxy_using_an_automatix_proxy.pac/comment_1_69d7c8fb1d62300456575bb10e935d69._comment new file mode 100644 index 00000000..6bf8844d --- /dev/null +++ b/doc/forum/how_to_set_the_proxy_using_an_automatix_proxy.pac/comment_1_69d7c8fb1d62300456575bb10e935d69._comment @@ -0,0 +1,10 @@ +[[!comment format=mdwn + username="joey" + subject="""comment 1""" + date="2014-11-25T15:44:13Z" + content=""" +You could, for example, use Propellor.Propety.Cmd.cmdProperty +to run a command that sets up the proxying. If there's not a single command +that does it, you could cause propellor to fetch the url and deploy the +info itself. +"""]] diff --git a/doc/forum/how_to_set_the_proxy_using_an_automatix_proxy.pac/comment_2_da30b2621493e48ceabcfa5732dbcdf8._comment b/doc/forum/how_to_set_the_proxy_using_an_automatix_proxy.pac/comment_2_da30b2621493e48ceabcfa5732dbcdf8._comment new file mode 100644 index 00000000..8458ee49 --- /dev/null +++ b/doc/forum/how_to_set_the_proxy_using_an_automatix_proxy.pac/comment_2_da30b2621493e48ceabcfa5732dbcdf8._comment @@ -0,0 +1,19 @@ +[[!comment format=mdwn + username="picca" + subject="comment 2" + date="2014-11-25T17:55:25Z" + content=""" +In my case I need to wget the proxy.pac file and parse it to find the right proxy. + +what worried me is that these proxy.pac things are dynamical depending on the ip of the sender AND the receive. +It work nicely with web browser, but not with the unix http_proxy and HTTPS_PROXY env. + +nevertheless, I can create something to parse my local setup and extract the right http_proxy. + +Is there something available in Propellor to set a global environment variable in /etc/environment (the right place for this ?) + +cheers + +Frederic + +"""]] diff --git a/doc/forum/how_to_set_the_proxy_using_an_automatix_proxy.pac/comment_3_bd76d169af2ef2f154ad1f0f64506661._comment b/doc/forum/how_to_set_the_proxy_using_an_automatix_proxy.pac/comment_3_bd76d169af2ef2f154ad1f0f64506661._comment new file mode 100644 index 00000000..9bdcb4df --- /dev/null +++ b/doc/forum/how_to_set_the_proxy_using_an_automatix_proxy.pac/comment_3_bd76d169af2ef2f154ad1f0f64506661._comment @@ -0,0 +1,11 @@ +[[!comment format=mdwn + username="joey" + subject="""comment 1""" + date="2014-11-25T19:37:46Z" + content=""" +There's no Property that handles setting global environment currently, but +it's a reasonable one to add. + +I think that /etc/environment is read by `pam_env` logins, but maybe not +other things, so dunno. +"""]] diff --git a/doc/forum/how_to_set_the_proxy_using_an_automatix_proxy.pac/comment_4_a6a49d35ee8a05abc982049b55d0397c._comment b/doc/forum/how_to_set_the_proxy_using_an_automatix_proxy.pac/comment_4_a6a49d35ee8a05abc982049b55d0397c._comment new file mode 100644 index 00000000..d2a0b45e --- /dev/null +++ b/doc/forum/how_to_set_the_proxy_using_an_automatix_proxy.pac/comment_4_a6a49d35ee8a05abc982049b55d0397c._comment @@ -0,0 +1,11 @@ +[[!comment format=mdwn + username="picca" + subject="comment 4" + date="2014-11-25T20:01:12Z" + content=""" +I saw that there is an haskell binding for augeas. + +Maybe this could be a nice uniform interface to deal with all the system configuration files. +then no need to deal with the config file formats. + +"""]] diff --git a/doc/forum/how_to_set_the_proxy_using_an_automatix_proxy.pac/comment_5_7783b8a96c8032a39ff3b5b446a976ed._comment b/doc/forum/how_to_set_the_proxy_using_an_automatix_proxy.pac/comment_5_7783b8a96c8032a39ff3b5b446a976ed._comment new file mode 100644 index 00000000..d670fa3b --- /dev/null +++ b/doc/forum/how_to_set_the_proxy_using_an_automatix_proxy.pac/comment_5_7783b8a96c8032a39ff3b5b446a976ed._comment @@ -0,0 +1,7 @@ +[[!comment format=mdwn + username="gueux" + subject="comment 5" + date="2014-11-27T08:17:36Z" + content=""" +Just looked at augeas, and add it to propellor would be great. Much more robust than Propellor.Property.File.{containsLine,containsLines,lacksLine}, at least. +"""]] diff --git a/doc/forum/modify_managed_host_propellor__39__s_.git__47__config.mdwn b/doc/forum/modify_managed_host_propellor__39__s_.git__47__config.mdwn new file mode 100644 index 00000000..0815b4b3 --- /dev/null +++ b/doc/forum/modify_managed_host_propellor__39__s_.git__47__config.mdwn @@ -0,0 +1 @@ +How can I modify the configuration of a managed host (which seems to be stored in /usr/local/propellor/.git/config) from the host on which I run propellor? diff --git a/doc/forum/modify_managed_host_propellor__39__s_.git__47__config/comment_1_da3ebb4736a1f1012b6d27bcd33ff44f._comment b/doc/forum/modify_managed_host_propellor__39__s_.git__47__config/comment_1_da3ebb4736a1f1012b6d27bcd33ff44f._comment new file mode 100644 index 00000000..f034a377 --- /dev/null +++ b/doc/forum/modify_managed_host_propellor__39__s_.git__47__config/comment_1_da3ebb4736a1f1012b6d27bcd33ff44f._comment @@ -0,0 +1,10 @@ +[[!comment format=mdwn + username="joey" + subject="""comment 1""" + date="2014-10-31T14:40:33Z" + content=""" +I'm curious what you need to configure there.. + +But, there seems to be a simple solution: Add a Property that configures +the .git/config however you need to! :) +"""]] diff --git a/doc/forum/my_experience_with_propellor:_how_to_run_a_single_task_on_a_host__63__.mdwn b/doc/forum/my_experience_with_propellor:_how_to_run_a_single_task_on_a_host__63__.mdwn new file mode 100644 index 00000000..0a50fc91 --- /dev/null +++ b/doc/forum/my_experience_with_propellor:_how_to_run_a_single_task_on_a_host__63__.mdwn @@ -0,0 +1,177 @@ +Having taken the inital hurdle of getting propellor running +(cf. my last post in this forum), I am beginning to like propellor +quite a lot. - This comes not too much as a surprise, as I am +a Haskeller really. - I would love to use it for all my configuration +needs, and to that end ditch ansible. + +Propellor's biggest show stopper for me is this (maybe I am misunderstanding +propellor?): + +I can run + +``` + propellor --spin myhost +``` + +from the command line, and all the tasks/properties that I have +defined myhost to have beforehand will be executed/realized/configured. + +Say eg. I haved defined (sorry for the bad formatting, +seems I have to do it line by line to get the markdown look nice) + +``` +myhost :: Host +``` + +``` +myhost = host "myhost" + & os (System (Debian Testing) "amd64") + & emacs + & apt +``` + +``` +emacs :: Property HasInfo +``` + +``` +emacs = propertyList "install & configure emacs" $ props + & Apt.installed ["emacs" + , "auto-complete-el"] +``` + +``` + apt :: Property HasInfo +``` + +``` +apt = propertyList "apt update + upgrade" $ props + & Apt.update + & Apt.upgrade +``` + + +Then running + +``` + propellor --spin myhost +``` + +will make sure, that emacs is installed, and all my +packages on myhost are up to date. + +It does so every time I run propellor, but normally I install +emacs only once (and I know it's installed), whereas +the apt update+upgrade combo I would want to run every other day. + +So what I would like is this: have just a minimal config for +myhost, like this: + +``` +myhost :: Host +``` + +``` +myhost = host "myhost" + & os (System (Debian Testing) "amd64") +``` + +and then run a task (require a property ?) on myhost, somehow +from the command line, like this + +``` + propellor --spin myhost --task apt +``` + +Many other properties / installation steps I could run in this +manner, like installing emacs initially + +``` + propellor --spin myhost --task emacs +``` + +In ansible I can do this with playbooks: + +``` + ansible-playbook -l myhost apt.yml +``` + +with some preconfigured playbook apt.yml that does just +the apt update + upgrade task and nothing else. But I would +have other tasks in other playbooks of course: I can install & configure +emacs on myhost + +``` + ansible-playbook -l myhost emacs.yml +``` + +etc. + +Related to that (but maybe not strictly the same question): + +I wouldn't mind writing my own haskell script that does +the command line parsing (with optparse applicative eg): +I could have options for + +``` + --host (myhost/...) +``` + +and + +``` + --task (emacs/apt/...) +``` + +and then just call into propellor. Unfortunately propellor's +defaultMain does more than I want: gets the command line +from processCmdLine. + +So I tried to create my own otherMain (similar to defaultMain, +but would let me do my own command line parsing): + +``` + otherMain :: [Host] -> CmdLine -> IO () +``` + +but then at some point just gave up: for one thing: things +were getting complicated, because of all the indirection: +the propellor command line tool recompiles itself (?), +does all this git stuff etc. + +And then: maybe I am approaching things in the wrong direction: +maybe it's just not meant to be used that way +(but ansible works fine for me in this regard)? + +And I thought: I don't really want to start a major programming +task just to get this thing working, the way that seems +reasonable to me. Or maybe it's possible already, and I just +don't know how to use it? (So I am stuck with ansible for the time +being). + +Still more or less related: + +Say this otherMain function existed, that allowed me to +to do my own command line parsing and just +call propellor on some host with the one or the other task, +I am not 100% what's the right +way to ensure/require/execute such a task on a host: + +above I am just using + +``` + host & property +``` + +(from PropAccum), but maybe ensureProperty is better suited +for that? + +Also for the wish list: some CONFIG_FILE env variable that +would allow me to keep my config.hs somewhere other than +in ~/.propellor/config.hs + + +Anyway, thanks so far +I would certainly want to switch to propellor completely. + + Andreas diff --git a/doc/forum/my_experience_with_propellor:_how_to_run_a_single_task_on_a_host__63__/comment_1_8959a79735aa3fa13ee37e57eb5a92e1._comment b/doc/forum/my_experience_with_propellor:_how_to_run_a_single_task_on_a_host__63__/comment_1_8959a79735aa3fa13ee37e57eb5a92e1._comment new file mode 100644 index 00000000..273dc758 --- /dev/null +++ b/doc/forum/my_experience_with_propellor:_how_to_run_a_single_task_on_a_host__63__/comment_1_8959a79735aa3fa13ee37e57eb5a92e1._comment @@ -0,0 +1,14 @@ +[[!comment format=mdwn + username="joey" + subject="""comment 1""" + date="2015-04-14T18:48:23Z" + content=""" +By composing these things at the command-line, you're using the +command-line, rather than haskell, for describing your system. I don't +think that's a win. + +As far as properties that you don't want to have run every time, see +`Propellor.Property.Scheduled.period`. For example: + + & Apt.update `period` Daily +"""]] diff --git a/doc/forum/my_experience_with_propellor:_how_to_run_a_single_task_on_a_host__63__/comment_2_f07c33b4a14cdc0b78695de49875c9b5._comment b/doc/forum/my_experience_with_propellor:_how_to_run_a_single_task_on_a_host__63__/comment_2_f07c33b4a14cdc0b78695de49875c9b5._comment new file mode 100644 index 00000000..3eca3457 --- /dev/null +++ b/doc/forum/my_experience_with_propellor:_how_to_run_a_single_task_on_a_host__63__/comment_2_f07c33b4a14cdc0b78695de49875c9b5._comment @@ -0,0 +1,52 @@ +[[!comment format=mdwn + username="https://www.google.com/accounts/o8/id?id=AItOawm-czsfuWENKQ0GI8l0gnGTeF1JEli1mA0" + nickname="Andreas" + subject="comment 2" + date="2015-04-14T19:24:46Z" + content=""" +using the command line: well yes, that's right. +Still: I can configure a lot of details in haskell (ansible playbooks): + +my emacs task eg. is not only ensuring that emacs is installed +(as in the example above), but I also set some links to my +elisp config files, ensure that cask installed etc. + +another task for me is installing X windows: +again lots of details: not only the xorg packages, +but some links to .xsession files, window manager config +files etc. + +and yes: I am happy, that I can spell out the details +of these tasks in propellor/haskell. + +I just don't see the point of ensuring them again and again +with every spin of propellor, and I would want +to be able to run just this one task on the command line. + + +concerning +``` + Apt.update `period` Daily +``` +thanks, will have a look. +but I guess this is cron job (will see), +in general I think I will want to stick to my habit, that I want +to see what's going on (what is upgraded), thus prefer +to not run any cron jobs for apt upgrades + +My overall message / concern is: I don't want to completly change my +habits, just because I am using propellor + +I had the habit of installing my computers task by task + +I had the habit of logging in to one of my systems, and +doing apt-get update && apt-get upgrade + +I want my config tool to help me achieve things in my +way that I am used to. + + + + + +"""]] diff --git a/doc/forum/my_experience_with_propellor:_how_to_run_a_single_task_on_a_host__63__/comment_3_06c63446531f56e4c93f64f6bcfba2b1._comment b/doc/forum/my_experience_with_propellor:_how_to_run_a_single_task_on_a_host__63__/comment_3_06c63446531f56e4c93f64f6bcfba2b1._comment new file mode 100644 index 00000000..144915df --- /dev/null +++ b/doc/forum/my_experience_with_propellor:_how_to_run_a_single_task_on_a_host__63__/comment_3_06c63446531f56e4c93f64f6bcfba2b1._comment @@ -0,0 +1,25 @@ +[[!comment format=mdwn + username="joey" + subject="""comment 3""" + date="2015-04-14T19:42:22Z" + content=""" +[period](http://hackage.haskell.org/package/propellor-2.2.1/docs/Propellor-Property-Scheduled.html) +is not a cron job, it just modifies the Property to only do anything +every so often. + +It's also possible to modify a Property so it only runs once. +[flagFile](http://hackage.haskell.org/package/propellor-2.2.1/docs/Propellor-Property.html#v:flagFile) +can be used to do that. + +But there are good reasons for propellor to default to checking all +Properties of a system each time: + +* It means that most Properties are idempotent, which has many good + features, like being able to recover from a crash. +* If a system no longer has a configured Property, to fix it back to having + the property it's supposed to have. +* Or, if it can't be fixed, to tell you with an error message in red. +* It keeps propellor mostly stateless; rather than having to record state + about how it thinks a system is, which could diverge from reality, + it just looks at how it actually is. +"""]] diff --git a/doc/forum/my_experience_with_propellor:_how_to_run_a_single_task_on_a_host__63__/comment_4_f52f30380b4fe58292fcf0ef368efbb1._comment b/doc/forum/my_experience_with_propellor:_how_to_run_a_single_task_on_a_host__63__/comment_4_f52f30380b4fe58292fcf0ef368efbb1._comment new file mode 100644 index 00000000..ecd20630 --- /dev/null +++ b/doc/forum/my_experience_with_propellor:_how_to_run_a_single_task_on_a_host__63__/comment_4_f52f30380b4fe58292fcf0ef368efbb1._comment @@ -0,0 +1,44 @@ +[[!comment format=mdwn + username="https://www.google.com/accounts/o8/id?id=AItOawm-czsfuWENKQ0GI8l0gnGTeF1JEli1mA0" + nickname="Andreas" + subject="comment 4" + date="2015-04-15T10:15:17Z" + content=""" +Well thanks a lot, and yes I am learning: propellor has a lot +of powerful features under the hood already. + +I still remain sceptical for the time being: + +Propellor's overall approach seems: one spin of propellor does ensure +that a complete systems is properly installed (and then one can +declare exceptions: don't check this every time...). I can even see +how this is useful: if I where a sys admin with a huge farm of +systems, I wouldn't want to deal with half installed systems, but just +have propellor do a complete job. + +As far as I am only concerned with a few personal computers of mine, I +prefer to stick to my task by task approach, though, and for tasks +that come up reapeatedly (like keeping my apt cache + installed +packages up to date) that seems reasonable to me as well. - having +only a minimal required configuration for a host, and then building +upon that (I think/hope, you got the idea by now). The fact, that +this model is nicely supported by ansible, seems to suggest at least, +that this kind of reasoning/approach is not completely flawed. + +What is not 100% clear to me: if propellor could be bent to support my +kind of workflow: I would think that it's possible? (even though I +might not have the time to bend it that way myself). Or are there any +fundamental issues with it? + +What I am suggesting is: that propellor be at my disposal, +more as a library, and would not also impose a certain +command line interface / workflow on me. + +Anyway, you would certainly win me as a user (don't know +how much that counts, and cannot speak for other people's +needs). + +Thanks anyway. + Andreas + +"""]] diff --git a/doc/forum/propellor_with_no_central_repository__63__.mdwn b/doc/forum/propellor_with_no_central_repository__63__.mdwn new file mode 100644 index 00000000..5f322878 --- /dev/null +++ b/doc/forum/propellor_with_no_central_repository__63__.mdwn @@ -0,0 +1 @@ +Is there a way to use propellor with no central repository? diff --git a/doc/forum/propellor_with_no_central_repository__63__/comment_1_6a2a5068962b17dac08609cd65887f48._comment b/doc/forum/propellor_with_no_central_repository__63__/comment_1_6a2a5068962b17dac08609cd65887f48._comment new file mode 100644 index 00000000..1f1456c5 --- /dev/null +++ b/doc/forum/propellor_with_no_central_repository__63__/comment_1_6a2a5068962b17dac08609cd65887f48._comment @@ -0,0 +1,7 @@ +[[!comment format=mdwn + username="joey" + subject="""comment 1""" + date="2014-10-31T14:39:48Z" + content=""" +Not yet, but see [[todo/git_push_over_propellor_ssh_channel]] +"""]] diff --git a/doc/forum/propellor_with_no_central_repository__63__/comment_2_0f035bb4bb5cc13574394505f28abe5e._comment b/doc/forum/propellor_with_no_central_repository__63__/comment_2_0f035bb4bb5cc13574394505f28abe5e._comment new file mode 100644 index 00000000..6a6aa946 --- /dev/null +++ b/doc/forum/propellor_with_no_central_repository__63__/comment_2_0f035bb4bb5cc13574394505f28abe5e._comment @@ -0,0 +1,9 @@ +[[!comment format=mdwn + username="joey" + subject="""yay!""" + date="2014-11-19T01:31:14Z" + content=""" +propellor now supports this mode by default, just use `propellor --spin +hostname` and the changes in the local repo will be pushed and deployed to +the host, w/o needing a centralized git repo. +"""]] diff --git a/doc/forum/property_combinator_ordering.mdwn b/doc/forum/property_combinator_ordering.mdwn new file mode 100644 index 00000000..25549bb4 --- /dev/null +++ b/doc/forum/property_combinator_ordering.mdwn @@ -0,0 +1,8 @@ +when I write + + setDistribution cfg = f `File.hasContent` cfg + `onChange` update + `requires` File.dirExists confDir + +is update called before ensuring the confiDir Exist ? +It seems to me but who knows ? diff --git a/doc/forum/property_combinator_ordering/comment_1_0ea2186b5cfa7eadaf38ac2e97fc4a2c._comment b/doc/forum/property_combinator_ordering/comment_1_0ea2186b5cfa7eadaf38ac2e97fc4a2c._comment new file mode 100644 index 00000000..c41abd90 --- /dev/null +++ b/doc/forum/property_combinator_ordering/comment_1_0ea2186b5cfa7eadaf38ac2e97fc4a2c._comment @@ -0,0 +1,31 @@ +[[!comment format=mdwn + username="joey" + subject="""comment 1""" + date="2014-12-01T15:53:11Z" + content=""" +I think that should behave intuitively, but of course if you're unsure +of this kind of thing, adding parens is a good way to disambiguate the +code. + + (f `File.hasContent` cfg `onChange` update) + `requires` File.dirExists confDir + +Written that way, it's explicit that the parenthesized part runs +together as one action. + +Or, we can do a quick test in ghci: + + joey@darkstar:~/src/propellor/src#joeyconfig>ghci Propellor.hs Propellor/Property.hs + *Propellor> let f1 = property "hasContent" (liftIO (print "f1") >> return MadeChange) + *Propellor> let f2 = property "update" (liftIO (print "f2") >> return MadeChange) + *Propellor> let f3 = property "dirExists" (liftIO (print "f3") >> return MadeChange) + *Propellor> runPropellor (Host "foo" [] mempty) $ ensureProperty $ f1 `onChange` f2 `requires` f3 + "dirExists" + "hasContent" + "update" + MadeChange + +So, yes, it's behaving as it should, first ensuring that the `requires` +property is met, and then running the main property, and since it made a +change, following up by running the `onChange` property. +"""]] diff --git a/doc/forum/trying_to_--spin_to_a_sid+experimental_machine.mdwn b/doc/forum/trying_to_--spin_to_a_sid+experimental_machine.mdwn new file mode 100644 index 00000000..1fde595c --- /dev/null +++ b/doc/forum/trying_to_--spin_to_a_sid+experimental_machine.mdwn @@ -0,0 +1,290 @@ +I'm trying to get propellor running, and for now, I'd prefer +to not use a central git repo, according to what I have read + +``` + propellor --spin host +``` + +should do just that: not use git. + +So I have cabal installed propellor locally, and +in addition cloned + +``` + git clone git://propellor.branchable.com/ .propellor +``` + +in my $HOME + +My local machine (from where I run propellor) runs debian testing, the +machine I want to spin to: softland, debian unstable+experimental, +ie. unstable in general + all things ghc from experimental, to get ghc +7.8.4 (but not any more than that from experimental). + +was not sure, what the right propellor config would be in that case: + +``` +& os (System (Debian Experimental) "amd64") +``` +which I have used, or + +``` + & os (System (Debian Unstable) "amd64") +``` +because in general I want Unstable + + +First thing I notice, when running + + +``` +$ propellor --spin softland +``` + +propellor nevertheless tries to git push (but fails, obviously, +somewhere down in propellors output): + +``` +... +Building propellor-2.2.1... +Preprocessing library propellor-2.2.1... +In-place registering propellor-2.2.1... +Preprocessing executable 'propellor' for propellor-2.2.1... +Preprocessing executable 'propellor-config' for propellor-2.2.1... +Propellor build ... done +[master 8ca2715] propellor spin +Git commit ... done +Counting objects: 10, done. +Delta compression using up to 2 threads. +Compressing objects: 100% (8/8), done. +Writing objects: 100% (10/10), 913 bytes | 0 bytes/s, done. +Total 10 (delta 6), reused 0 (delta 0) +remote: you are not allowed to change config.hs +To git://propellor.branchable.com/ + ! [remote rejected] master -> master (pre-receive hook declined) +error: failed to push some refs to 'git://propellor.branchable.com/' +Push to central git repository ... failed +Stop listening request sent. +Hit http://ftp.uk.debian.org sid InRelease +Hit http://ftp.uk.debian.org experimental InRelease +Get:1 http://ftp.uk.debian.org sid/main amd64 Packages/DiffIndex [7,876 B] +... +``` + +Note in particular the lines: + +``` + To git://propellor.branchable.com/ + ! [remote rejected] master -> master (pre-receive hook declined) + error: failed to push some refs to 'git://propellor.branchable.com/' + Push to central git repository ... failed +``` + +Shouldn't propellor be completely quiet about git / +not try to push at all? + +OK, never mind, let's see what's next: some long +output, propellor finally fails, I assume it's because +of my sid+experimental configuration? + + +``` +Stop listening request sent. +Hit http://ftp.uk.debian.org sid InRelease +Hit http://ftp.uk.debian.org experimental InRelease +Get:1 http://ftp.uk.debian.org sid/main amd64 Packages/DiffIndex [7,876 B] +Get:2 http://ftp.uk.debian.org sid/contrib amd64 Packages/DiffIndex [7,819 B] +Get:3 http://ftp.uk.debian.org sid/non-free amd64 Packages/DiffIndex [7,819 B] +Get:4 http://ftp.uk.debian.org sid/contrib Translation-en/DiffIndex [7,819 B] +Get:5 http://ftp.uk.debian.org sid/main Translation-en/DiffIndex [7,876 B] +Get:6 http://ftp.uk.debian.org sid/non-free Translation-en/DiffIndex [7,819 B] +Get:7 http://ftp.uk.debian.org sid/main Sources [7,633 kB] +Get:8 http://ftp.uk.debian.org sid/contrib Sources [57.1 kB] +Get:9 http://ftp.uk.debian.org sid/non-free Sources [105 kB] +Get:10 http://ftp.uk.debian.org experimental/main Sources/DiffIndex [7,819 B] +Get:11 http://ftp.uk.debian.org experimental/contrib Sources/DiffIndex [7,819 B] +Get:12 http://ftp.uk.debian.org experimental/non-free Sources/DiffIndex [7,819 B] +Get:13 http://ftp.uk.debian.org experimental/main amd64 Packages/DiffIndex [7,819 B] +Get:14 http://ftp.uk.debian.org experimental/contrib amd64 Packages/DiffIndex [7,819 B] +Get:15 http://ftp.uk.debian.org experimental/contrib Translation-en/DiffIndex [7,819 B] +Get:16 http://ftp.uk.debian.org experimental/main Translation-en/DiffIndex [7,819 B] +Fetched 7,897 kB in 6s (1,169 kB/s) +Reading package lists... +Reading package lists... +Building dependency tree... +Reading state information... +Skipping gnupg, it is already installed and upgrade is not set. +0 upgraded, 0 newly installed, 0 to remove and 0 not upgraded. +Reading package lists... +Building dependency tree... +Reading state information... +Skipping ghc, it is already installed and upgrade is not set. +0 upgraded, 0 newly installed, 0 to remove and 0 not upgraded. +Reading package lists... +Building dependency tree... +Reading state information... +Skipping cabal-install, it is already installed and upgrade is not set. +0 upgraded, 0 newly installed, 0 to remove and 0 not upgraded. +Reading package lists... +Building dependency tree... +Reading state information... +Skipping libghc-async-dev, it is already installed and upgrade is not set. +0 upgraded, 0 newly installed, 0 to remove and 0 not upgraded. +Reading package lists... +Building dependency tree... +Reading state information... +Some packages could not be installed. This may mean that you have +requested an impossible situation or if you are using the unstable +distribution that some required packages have not yet been created +or been moved out of Incoming. +The following information may help to resolve the situation: +The following packages have unmet dependencies: + libghc-missingh-dev : Depends: libghc-hunit-dev-1.2.5.2-6e02e + Depends: libghc-array-dev-0.4.0.1-3b784 + Depends: libghc-base-dev-4.6.0.1-8aa5d + Depends: libghc-containers-dev-0.5.0.0-ab1da + Depends: libghc-directory-dev-1.2.0.1-91a78 + Depends: libghc-filepath-dev-1.3.0.1-b12cb + Depends: libghc-hslogger-dev-1.2.1-028cc + Depends: libghc-mtl-dev-2.1.2-94c72 + Depends: libghc-network-dev-2.4.1.2-040ce + Depends: libghc-old-locale-dev-1.0.0.5-6729c + Depends: libghc-old-time-dev-1.1.0.1-2f8ea + Depends: libghc-parsec-dev-3.1.3-6c6e2 + Depends: libghc-process-dev-1.1.0.2-76e05 + Depends: libghc-random-dev-1.0.1.1-43fdc + Depends: libghc-regex-compat-dev-0.95.1-121c7 + Depends: libghc-time-dev-1.4.0.1-10dc4 + Depends: libghc-unix-dev-2.6.0.1-4f219 +E: Unable to correct problems, you have held broken packages. +Reading package lists... +Building dependency tree... +Reading state information... +Some packages could not be installed. This may mean that you have +requested an impossible situation or if you are using the unstable +distribution that some required packages have not yet been created +or been moved out of Incoming. +The following information may help to resolve the situation: +The following packages have unmet dependencies: + libghc-hslogger-dev : Depends: libghc-base-dev-4.6.0.1-8aa5d + Depends: libghc-containers-dev-0.5.0.0-ab1da + Depends: libghc-directory-dev-1.2.0.1-91a78 + Depends: libghc-mtl-dev-2.1.2-94c72 + Depends: libghc-network-dev-2.4.1.2-040ce + Depends: libghc-old-locale-dev-1.0.0.5-6729c + Depends: libghc-process-dev-1.1.0.2-76e05 + Depends: libghc-time-dev-1.4.0.1-10dc4 + Depends: libghc-unix-dev-2.6.0.1-4f219 +E: Unable to correct problems, you have held broken packages. +Reading package lists... +Building dependency tree... +Reading state information... +Some packages could not be installed. This may mean that you have +requested an impossible situation or if you are using the unstable +distribution that some required packages have not yet been created +or been moved out of Incoming. +The following information may help to resolve the situation: +The following packages have unmet dependencies: + libghc-unix-compat-dev : Depends: libghc-base-dev-4.6.0.1-8aa5d + Depends: libghc-unix-dev-2.6.0.1-4f219 +E: Unable to correct problems, you have held broken packages. +Reading package lists... +Building dependency tree... +Reading state information... +Skipping libghc-ansi-terminal-dev, it is already installed and upgrade is not set. +0 upgraded, 0 newly installed, 0 to remove and 0 not upgraded. +Reading package lists... +Building dependency tree... +Reading state information... +Some packages could not be installed. This may mean that you have +requested an impossible situation or if you are using the unstable +distribution that some required packages have not yet been created +or been moved out of Incoming. +The following information may help to resolve the situation: +The following packages have unmet dependencies: + libghc-ifelse-dev : Depends: libghc-base-dev-4.6.0.1-8aa5d +E: Unable to correct problems, you have held broken packages. +Reading package lists... +Building dependency tree... +Reading state information... +Skipping libghc-network-dev, it is already installed and upgrade is not set. +0 upgraded, 0 newly installed, 0 to remove and 0 not upgraded. +Reading package lists... +Building dependency tree... +Reading state information... +Skipping libghc-quickcheck2-dev, it is already installed and upgrade is not set. +0 upgraded, 0 newly installed, 0 to remove and 0 not upgraded. +Reading package lists... +Building dependency tree... +Reading state information... +Skipping libghc-mtl-dev, it is already installed and upgrade is not set. +0 upgraded, 0 newly installed, 0 to remove and 0 not upgraded. +Reading package lists... +Building dependency tree... +Reading state information... +Some packages could not be installed. This may mean that you have +requested an impossible situation or if you are using the unstable +distribution that some required packages have not yet been created +or been moved out of Incoming. +The following information may help to resolve the situation: +The following packages have unmet dependencies: + libghc-monadcatchio-transformers-dev : Depends: libghc-base-dev-4.6.0.1-8aa5d + Depends: libghc-extensible-exceptions-dev-0.1.1.4-255a3 + Depends: libghc-monads-tf-dev-0.1.0.2-731f0 + Depends: libghc-transformers-dev-0.3.0.0-ff2bb +E: Unable to correct problems, you have held broken packages. +Downloading the latest package list from hackage.haskell.org +Skipping download: Local and remote files match. +Resolving dependencies... +All the requested packages are already installed: +Use --reinstall if you want to reinstall anyway. +Resolving dependencies... +Configuring propellor-2.2.1... +Building propellor-2.2.1... +Preprocessing library propellor-2.2.1... +In-place registering propellor-2.2.1... +Preprocessing executable 'propellor' for propellor-2.2.1... +Preprocessing excaecutable 'propellor-bal: can't find source for configconf in src +ig' for propellor-2.2.1... +propellor: user error (ssh ["-o","ControlPath=/home/rx/.ssh/propellor/softland.sock","-o","ControlMaster=auto","-o","ControlPersist=yes","root@softland","sh -c 'if [ ! -d /usr/local/propellor/.git ] ; then (if ! git --version >/dev/null; then apt-get update && apt-get --no-install-recommends --no-upgrade -y install git; fi && echo STATUSNeedGitClone) || echo STATUSNeedPrecompiled ; else cd /usr/local/propellor && if ! test -x ./propellor; then ( apt-get update ; apt-get --no-upgrade --no-install-recommends -y install gnupg ; apt-get --no-upgrade --no-install-recommends -y install ghc ; apt-get --no-upgrade --no-install-recommends -y install cabal-install ; apt-get --no-upgrade --no-install-recommends -y install libghc-async-dev ; apt-get --no-upgrade --no-install-recommends -y install libghc-missingh-dev ; apt-get --no-upgrade --no-install-recommends -y install libghc-hslogger-dev ; apt-get --no-upgrade --no-install-recommends -y install libghc-unix-compat-dev ; apt-get --no-upgrade --no-install-recommends -y install libghc-ansi-terminal-dev ; apt-get --no-upgrade --no-install-recommends -y install libghc-ifelse-dev ; apt-get --no-upgrade --no-install-recommends -y install libghc-network-dev ; apt-get --no-upgrade --no-install-recommends -y install libghc-quickcheck2-dev ; apt-get --no-upgrade --no-install-recommends -y install libghc-mtl-dev ; apt-get --no-upgrade --no-install-recommends -y install libghc-monadcatchio-transformers-dev ; cabal update ; cabal install --only-dependencies ) || true && cabal configure && cabal build && ln -sf dist/build/propellor-config/propellor-config propellor; fi && ./propellor --boot softland ; fi'"] exited 1) +rx@varenne ~/work/propellor $ +``` + +I should add, that I have tried to --spin to another +machine, and ... finally got that working: + + +``` + , host "laptop" + & os (System (Debian Testing) "amd64") +``` + +Not sure, if I need more than that, want to keep it to the +minimum first, anyway: + + +``` + propellor --spin laptop +``` + +this works, yeah - sorry for the noise, above - but still I get + + +``` +Git commit ... done +To git://propellor.branchable.com/ + ! [rejected] master -> master (fetch first) +error: failed to push some refs to 'git://propellor.branchable.com/' +hint: Updates were rejected because the remote contains work that you do +hint: not have locally. This is usually caused by another repository pushing +hint: to the same ref. You may want to first integrate the remote changes +hint: (e.g., 'git pull ...') before pushing again. +hint: See the 'Note about fast-forwards' in 'git push --help' for details. +Push to central git repository ... failed +``` + +Possible to turn off these git push attempts? + + +Thanks, + Andreas diff --git a/doc/forum/trying_to_--spin_to_a_sid+experimental_machine/comment_1_df7ac45d7e576e8d73a8665521dbd6e0._comment b/doc/forum/trying_to_--spin_to_a_sid+experimental_machine/comment_1_df7ac45d7e576e8d73a8665521dbd6e0._comment new file mode 100644 index 00000000..cfe1750a --- /dev/null +++ b/doc/forum/trying_to_--spin_to_a_sid+experimental_machine/comment_1_df7ac45d7e576e8d73a8665521dbd6e0._comment @@ -0,0 +1,29 @@ +[[!comment format=mdwn + username="https://www.google.com/accounts/o8/id?id=AItOawm-czsfuWENKQ0GI8l0gnGTeF1JEli1mA0" + nickname="Andreas" + subject="finally got it working" + date="2015-03-27T05:15:26Z" + content=""" +can spin to softland, my sid+experimental host now. + +with recent git://propellor.branchable.com/ updates +and have used: + +``` + & os (System (Debian Experimental) \"amd64\") +``` + +so sorry for the noise, still not sure about: + +* how to express my installation properly: + mostly unstable, ghc stuff from experimental + +* how to turn off the git push to branchable attempts + when just spinning to one of my mashines: + have set now: + ``` + git branch --unset-upstream + ``` + which shortcuts these attempts at least. + +"""]] diff --git a/doc/forum/trying_to_--spin_to_a_sid+experimental_machine/comment_2_8600d257d92f786f2fcf0d4934f727d5._comment b/doc/forum/trying_to_--spin_to_a_sid+experimental_machine/comment_2_8600d257d92f786f2fcf0d4934f727d5._comment new file mode 100644 index 00000000..51c3fc53 --- /dev/null +++ b/doc/forum/trying_to_--spin_to_a_sid+experimental_machine/comment_2_8600d257d92f786f2fcf0d4934f727d5._comment @@ -0,0 +1,17 @@ +[[!comment format=mdwn + username="joey" + subject="""comment 2""" + date="2015-03-30T23:22:17Z" + content=""" +Pushing to origin is needed when using propellor in the central git +repository deployment mode. So it makes sense for --spin to try to push. +If that push fails for some reason, it's not a fatal error, since propellor +--spin also does peer-to-peer pushes. + +I don't think I want to get into trying to determine if a particular origin +repo url is read-only or read-write. It can be hard to tell with eg +a https url. + +Why don't you just `git remote rename origin upstream`? If the remote +is not called origin, propellor will ignore it. +"""]] diff --git a/doc/forum/trying_to_--spin_to_a_sid+experimental_machine/comment_3_f1ca62944fe0303db6f1dc0916e8c967._comment b/doc/forum/trying_to_--spin_to_a_sid+experimental_machine/comment_3_f1ca62944fe0303db6f1dc0916e8c967._comment new file mode 100644 index 00000000..ed34d6a7 --- /dev/null +++ b/doc/forum/trying_to_--spin_to_a_sid+experimental_machine/comment_3_f1ca62944fe0303db6f1dc0916e8c967._comment @@ -0,0 +1,13 @@ +[[!comment format=mdwn + username="joey" + subject="""comment 3""" + date="2015-03-30T23:26:38Z" + content=""" +As to a mixed unstable/experimental machine, such a machine has a Property +of having somepackage installed from experimental. One way to represent +that is by defining a property: + +installedFromExperimental :: [Package] -> Property NoInfo +installedFromExperimental = Apt.installed' ["-y", "-texperimental"] + +"""]] diff --git a/doc/forum/trying_to_--spin_to_a_sid+experimental_machine/comment_4_d0d946df7455d079af9bc331da6fac55._comment b/doc/forum/trying_to_--spin_to_a_sid+experimental_machine/comment_4_d0d946df7455d079af9bc331da6fac55._comment new file mode 100644 index 00000000..72b21450 --- /dev/null +++ b/doc/forum/trying_to_--spin_to_a_sid+experimental_machine/comment_4_d0d946df7455d079af9bc331da6fac55._comment @@ -0,0 +1,16 @@ +[[!comment format=mdwn + username="https://www.google.com/accounts/o8/id?id=AItOawm-czsfuWENKQ0GI8l0gnGTeF1JEli1mA0" + nickname="Andreas" + subject="thanks a lot" + date="2015-04-06T21:11:46Z" + content=""" +thanks for your your commments (both of them), +and fair enough: have just renamed my origin remote to upstream, +will try your installedFromExperimental suggestion next. + + +I will have more questions about propellor, +but aske them in a different thread +(as they are not really about installation) + +"""]] diff --git a/doc/haskell_newbie.mdwn b/doc/haskell_newbie.mdwn index 24839b12..ec42629c 100644 --- a/doc/haskell_newbie.mdwn +++ b/doc/haskell_newbie.mdwn @@ -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/).) diff --git a/doc/news/propellor_demo.mdwn b/doc/news/propellor_demo.mdwn new file mode 100644 index 00000000..362f56e6 --- /dev/null +++ b/doc/news/propellor_demo.mdwn @@ -0,0 +1,8 @@ +A quick demo of propellor. + +<video controls src="http://downloads.kitenet.net/talks/propellor_demo/propellor_demo.webm"></video> + +[video](http://downloads.kitenet.net/talks/propellor_demo/propellor_demo.webm) + +(Audio quality is clipped/fast in places, unfortunately this was a problem +with the source recording.) diff --git a/doc/news/version_1.2.2.mdwn b/doc/news/version_1.2.2.mdwn new file mode 100644 index 00000000..c10940fd --- /dev/null +++ b/doc/news/version_1.2.2.mdwn @@ -0,0 +1,4 @@ +propellor 1.2.2 released with [[!toggle text="these changes"]] +[[!toggleable text=""" + * Revert ensureProperty warning message, too many false positives in places + where Info is correctly propigated. Better approach needed."""]]
\ No newline at end of file diff --git a/doc/news/version_1.3.0.mdwn b/doc/news/version_1.3.0.mdwn new file mode 100644 index 00000000..87abb2f7 --- /dev/null +++ b/doc/news/version_1.3.0.mdwn @@ -0,0 +1,17 @@ +propellor 1.3.0 released with [[!toggle text="these changes"]] +[[!toggleable text=""" + * --spin checks if the DNS matches any configured IP address property + of the host, and if not, sshes to the host by IP address. + * Detect #774376 and refuse to use docker if the system is so broken + that docker exec doesn't enter a chroot. + * Update intermediary propellor in --spin --via + * Added support for DNSSEC. + * Ssh.hostKey and Ssh.hostKeys no longer install public keys from + the privdata. Instead, the public keys are included in the + configuration. (API change) + * Ssh.hostKeys now removes any host keys of types that the host is not + configured to have. + * sshPubKey is renamed to Ssh.pubKey, and has an added SshKeyType + parameter. (API change) + * CloudAtCost.deCruft no longer forces randomHostKeys. + * Fix build with process 1.2.1.0."""]]
\ No newline at end of file diff --git a/doc/news/version_1.3.1.mdwn b/doc/news/version_1.3.1.mdwn new file mode 100644 index 00000000..74a39ac4 --- /dev/null +++ b/doc/news/version_1.3.1.mdwn @@ -0,0 +1,6 @@ +propellor 1.3.1 released with [[!toggle text="these changes"]] +[[!toggleable text=""" + * Fix bug that prevented deploying ssh host keys when the file for the + key didn't already exist. + * DNS records for hosts with known ssh public keys now automatically + include SSHFP records."""]]
\ No newline at end of file diff --git a/doc/news/version_1.3.2.mdwn b/doc/news/version_1.3.2.mdwn new file mode 100644 index 00000000..77902008 --- /dev/null +++ b/doc/news/version_1.3.2.mdwn @@ -0,0 +1,5 @@ +propellor 1.3.2 released with [[!toggle text="these changes"]] +[[!toggleable text=""" + * SSHFP records are also generated for CNAMES of hosts. + * Merge Utiity modules from git-annex. + * Ignore bogus DNS when spinning the local host."""]]
\ No newline at end of file diff --git a/doc/news/version_2.3.0.mdwn b/doc/news/version_2.3.0.mdwn new file mode 100644 index 00000000..232ab49c --- /dev/null +++ b/doc/news/version_2.3.0.mdwn @@ -0,0 +1,13 @@ +propellor 2.3.0 released with [[!toggle text="these changes"]] +[[!toggleable text=""" + * Make propellor resistent to changes to shared libraries, such as libffi, + which might render the propellor binary unable to run. This is dealt with + by checking the binary both when running propellor on a remote host, + and by Cron.runPropellor. If the binary doesn't work, it will be rebuilt. + * Note that since a new switch had to be added to allow testing the binary, + upgrading to this version will cause a rebuild from scratch of propellor. + * Added hasLoginShell and shellEnabled. + * debCdn changed to new httpredir.debian.org official replacement for + http.debian.net. + * API change: Added User and Group newtypes, and Properties that + used to use the type UserName = String were changed to use them."""]]
\ No newline at end of file diff --git a/doc/security.mdwn b/doc/security.mdwn index 12ae18de..831b2b41 100644 --- a/doc/security.mdwn +++ b/doc/security.mdwn @@ -29,7 +29,7 @@ in cleartext private data such as passwords, ssh private keys, etc. Instead, `propellor --spin $host` looks for a `~/.propellor/privdata/privdata.gpg` file and if found decrypts it, -extracts the private that that the $host needs, and sends it to to the +extracts the private data that the $host needs, and sends it to to the $host using ssh. This lets a host know its own private data, without seeing all the rest. diff --git a/doc/security/comment_1_6b4d8f45fc60f12b2b8c41046390cf43._comment b/doc/security/comment_1_6b4d8f45fc60f12b2b8c41046390cf43._comment new file mode 100644 index 00000000..4ed9ecdb --- /dev/null +++ b/doc/security/comment_1_6b4d8f45fc60f12b2b8c41046390cf43._comment @@ -0,0 +1,10 @@ +[[!comment format=mdwn + username="https://www.google.com/accounts/o8/id?id=AItOawmtnXa0F3OsNh8H7yf5EEbtuufPZG-3StI" + nickname="Arnaud" + subject="Is it ok to publish to a public repository?" + date="2014-08-29T21:13:19Z" + content=""" +It is not clear to me whether or not it is safe to publish my own propellor repository to a publicly hosted service. It seems to me that when I do ./propellor --add-key MYKEYID, the private key data is stored in the repository as a commit, so pushing it exposes this data to the public. Am I wrong? + +Thanks +"""]] diff --git a/doc/security/comment_2_7cd009d097b01bb3197210b5ea77c7d5._comment b/doc/security/comment_2_7cd009d097b01bb3197210b5ea77c7d5._comment new file mode 100644 index 00000000..4d209b03 --- /dev/null +++ b/doc/security/comment_2_7cd009d097b01bb3197210b5ea77c7d5._comment @@ -0,0 +1,8 @@ +[[!comment format=mdwn + username="http://joeyh.name/" + ip="131.252.200.111" + subject="comment 2" + date="2014-08-29T21:52:02Z" + content=""" +--add-key puts your **public** key in the repository, not the private key. +"""]] diff --git a/doc/security/comment_3_91876d995c40a24858bce61a749a3c16._comment b/doc/security/comment_3_91876d995c40a24858bce61a749a3c16._comment new file mode 100644 index 00000000..4d75842d --- /dev/null +++ b/doc/security/comment_3_91876d995c40a24858bce61a749a3c16._comment @@ -0,0 +1,17 @@ +[[!comment format=mdwn + username="https://www.google.com/accounts/o8/id?id=AItOawmtnXa0F3OsNh8H7yf5EEbtuufPZG-3StI" + nickname="Arnaud" + subject="Remote host fails to connect" + date="2014-08-30T06:40:33Z" + content=""" +Makes sense of course, but the message one gets when doing that is a bit misleading. + +I ran into another issue: propellor deploys itself to remote host, but then the propellor instance run on remote host cannot read the remote git repo, because: + +1. the host key is not initially present in root's known_hosts, then +2. the user's (root) public key is unknown to the remote git repo, in my case bitbucket.org, and the URL used is git@bitbucket.org:abailly/capital-match-infra.git which implies connection goes through SSH + +I am puzzled: Does this mean I should add some for use by the remote host deployed to? This does not make sense so there should be another way... If I change the origin url to use https, then I cannot push locally anymore. + +Thanks for your help +"""]] diff --git a/doc/security/comment_4_347ce6a229a2347c5fd945eef72fd7f7._comment b/doc/security/comment_4_347ce6a229a2347c5fd945eef72fd7f7._comment new file mode 100644 index 00000000..b2ac4d57 --- /dev/null +++ b/doc/security/comment_4_347ce6a229a2347c5fd945eef72fd7f7._comment @@ -0,0 +1,22 @@ +[[!comment format=mdwn + username="https://www.google.com/accounts/o8/id?id=AItOawmtnXa0F3OsNh8H7yf5EEbtuufPZG-3StI" + nickname="Arnaud" + subject="Output from propellor --spin $host" + date="2014-08-30T07:17:52Z" + content=""" +Here is the output (truncated): + + + Permission denied (publickey). + fatal: Could not read from remote repository. + + Please make sure you have the correct access rights + and the repository exists. + Git fetch ... failed + fatal: ambiguous argument 'origin/master': unknown revision or path not in the working tree. + Use '--' to separate paths from revisions, like this: + 'git <command> [<revision>...] -- [<file>...]' + propellor: user error (git [\"log\",\"-n\",\"1\",\"--format=%G?\",\"origin/master\"] exited 128) + + +"""]] diff --git a/doc/security/comment_5_0c682e12a21d1477628ff0b80e6505d4._comment b/doc/security/comment_5_0c682e12a21d1477628ff0b80e6505d4._comment new file mode 100644 index 00000000..cc26f42d --- /dev/null +++ b/doc/security/comment_5_0c682e12a21d1477628ff0b80e6505d4._comment @@ -0,0 +1,13 @@ +[[!comment format=mdwn + username="https://www.google.com/accounts/o8/id?id=AItOawmtnXa0F3OsNh8H7yf5EEbtuufPZG-3StI" + nickname="Arnaud" + subject="Got it working..." + date="2014-08-31T12:50:17Z" + content=""" +OK, I manage to get my first propellor config run fine by setting different branch.master.url and branch.master.pushUrl configurations: + +* Use a https:// based url for the first +* Use a git:// based url for the second + +I had to nuke the remote /usr/local/propellor directory because it still had wrong configuration with a single remote url. +"""]] diff --git a/doc/security/comment_6_e5f2fdced08fb823efed35684110a840._comment b/doc/security/comment_6_e5f2fdced08fb823efed35684110a840._comment new file mode 100644 index 00000000..be8ac7f9 --- /dev/null +++ b/doc/security/comment_6_e5f2fdced08fb823efed35684110a840._comment @@ -0,0 +1,11 @@ +[[!comment format=mdwn + username="joey" + subject="""comment 6""" + date="2014-11-19T01:35:59Z" + content=""" +@Arnaud, see [[centralized_repository]], including its documentation of a +"deploy" remote, which can be used to configure the url that remote hosts +should pull from. + +Also, propellor can be used now without any centralized repository. +"""]] diff --git a/doc/security/comment_7_ebbb6f3617c879715a35900a07ea1909._comment b/doc/security/comment_7_ebbb6f3617c879715a35900a07ea1909._comment new file mode 100644 index 00000000..e9d20642 --- /dev/null +++ b/doc/security/comment_7_ebbb6f3617c879715a35900a07ea1909._comment @@ -0,0 +1,8 @@ +[[!comment format=mdwn + username="https://www.google.com/accounts/o8/id?id=AItOawkgUir7k_amh9RFp4D3QutX1fGh_nd7ko4" + nickname="Philipp" + subject="Passwords in PrivData" + date="2014-12-13T18:25:23Z" + content=""" +I wonder if there could be a shortcut in PrivData handling that hashes the input with crypt() instead of passing it raw to a machine. For instance passwords are stored in plain on the target machines, while this is not required to set the password in shadow: the hash would suffice. I think this page should at least spell out that fact. +"""]] diff --git a/doc/todo/Bug_in_Property.Ssh.authorizedKey.mdwn b/doc/todo/Bug_in_Property.Ssh.authorizedKey.mdwn new file mode 100644 index 00000000..7a59fc20 --- /dev/null +++ b/doc/todo/Bug_in_Property.Ssh.authorizedKey.mdwn @@ -0,0 +1,8 @@ +If Ssh.authorizedKey in propellor 2.0.0 is used to create .ssh/authorized_keys for +a user other than root, it will be owned by root:root and won't +work for the user. Adding a key to an existing authorized_keys +file doesn't change its ownership and therefore works fine. + +-- weinzwang + +> Thanks, [[fixed|done]] this and will make a release. diff --git a/doc/todo/Wishlist:_User.hasLoginShell.mdwn b/doc/todo/Wishlist:_User.hasLoginShell.mdwn new file mode 100644 index 00000000..cf8aa73c --- /dev/null +++ b/doc/todo/Wishlist:_User.hasLoginShell.mdwn @@ -0,0 +1,9 @@ +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 + +> patched in and so [[done]] --[[Joey]] diff --git a/doc/todo/Wishlist:_User.hasLoginShell/comment_1_c02e8783b91c3c0326bf1b317be4694f._comment b/doc/todo/Wishlist:_User.hasLoginShell/comment_1_c02e8783b91c3c0326bf1b317be4694f._comment new file mode 100644 index 00000000..52043406 --- /dev/null +++ b/doc/todo/Wishlist:_User.hasLoginShell/comment_1_c02e8783b91c3c0326bf1b317be4694f._comment @@ -0,0 +1,59 @@ +[[!comment format=mdwn + username="joey" + subject="""comment 1""" + date="2015-04-19T16:07:24Z" + content=""" +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. +"""]] diff --git a/doc/todo/bytes_in_privData__63__.mdwn b/doc/todo/bytes_in_privData__63__.mdwn new file mode 100644 index 00000000..27297fd5 --- /dev/null +++ b/doc/todo/bytes_in_privData__63__.mdwn @@ -0,0 +1,17 @@ +It seems like I can't set the content of a PrivFile to arbitrary bytes. + + $ propellor --set 'PrivFile "mysecret.key"' 'mycontext' < ~/mysecret.key + find . | grep -v /.git/ | grep -v /tmp/ | grep -v /dist/ | grep -v /doc/ | egrep '\.hs$' | xargs hothasktags | perl -ne 'print; s/Propellor\.Property\.//; print' | sort > tags 2>/dev/null || true + cabal build + Building propellor-2.2.1... + Preprocessing library propellor-2.2.1... + In-place registering propellor-2.2.1... + Preprocessing executable 'propellor' for propellor-2.2.1... + Preprocessing executable 'propellor-config' for propellor-2.2.1... + [70 of 70] Compiling Main ( src/config.hs, dist/build/propellor-config/propellor-config-tmp/Main.o ) + Linking dist/build/propellor-config/propellor-config ... + ln -sf dist/build/propellor-config/propellor-config propellor + + + Enter private data on stdin; ctrl-D when done: + propellor: <stdin>: hGetContents: invalid argument (invalid byte sequence) diff --git a/doc/todo/bytes_in_privData__63__/comment_1_42c107179b091f74ef55aff1fc240c5e._comment b/doc/todo/bytes_in_privData__63__/comment_1_42c107179b091f74ef55aff1fc240c5e._comment new file mode 100644 index 00000000..5c1508fd --- /dev/null +++ b/doc/todo/bytes_in_privData__63__/comment_1_42c107179b091f74ef55aff1fc240c5e._comment @@ -0,0 +1,19 @@ +[[!comment format=mdwn + username="joey" + subject="""comment 1""" + date="2015-04-20T01:04:26Z" + content=""" +I imagine that adding `fileEncoding stdin` to setPrivData will fix +this crash, but I'd expect there are also other problems with encodings +for privdata that haskell doesn't like. Similar fixes would probably +be needed in several other places. + +Probably cleaner and better to convert +`PrivData` from a String to a ByteString, and so avoid encodings +being applied to it. I think this could be done without changing the +file format; the privdata file uses Read/Show for serialization, +and happily ByteString uses the same Read/Show format as String does. + +So, changing the type and following the compile errors should get you +there, I think! +"""]] diff --git a/doc/todo/bytes_in_privData__63__/comment_2_60f577b476adc6ee1e4f18e11843df90._comment b/doc/todo/bytes_in_privData__63__/comment_2_60f577b476adc6ee1e4f18e11843df90._comment new file mode 100644 index 00000000..10ff956a --- /dev/null +++ b/doc/todo/bytes_in_privData__63__/comment_2_60f577b476adc6ee1e4f18e11843df90._comment @@ -0,0 +1,7 @@ +[[!comment format=mdwn + username="gueux" + subject="comment 2" + date="2015-04-21T12:59:42Z" + content=""" +Would you accept a patch converting PrivData from String to ByteString? +"""]] diff --git a/doc/todo/bytes_in_privData__63__/comment_3_55f34128de77b7947d32fac71071e033._comment b/doc/todo/bytes_in_privData__63__/comment_3_55f34128de77b7947d32fac71071e033._comment new file mode 100644 index 00000000..a1c7f62f --- /dev/null +++ b/doc/todo/bytes_in_privData__63__/comment_3_55f34128de77b7947d32fac71071e033._comment @@ -0,0 +1,7 @@ +[[!comment format=mdwn + username="joey" + subject="""comment 3""" + date="2015-04-21T16:52:06Z" + content=""" +Absolutely. Thought that went w/o saying. ;) +"""]] diff --git a/doc/todo/bytes_in_privData__63__/comment_4_f34a8f82c7bce7224e4edc59410c741f._comment b/doc/todo/bytes_in_privData__63__/comment_4_f34a8f82c7bce7224e4edc59410c741f._comment new file mode 100644 index 00000000..bd7a0618 --- /dev/null +++ b/doc/todo/bytes_in_privData__63__/comment_4_f34a8f82c7bce7224e4edc59410c741f._comment @@ -0,0 +1,19 @@ +[[!comment format=mdwn + username="gueux" + subject="comment 4" + date="2015-04-23T09:21:07Z" + content=""" +I tried to do the conversion, but then it started a kind of chain reaction... (PrivData=ByteString to writeFileProtected to Line=ByteString to ... to readProcess to ...) Should I use FilePath=String? ... To be honest, the patch became a lot bigger that what I am comfortable with. :-) + +I guess you should have a look at it... + +At least, I think there is a type bug in Propellor.Property.File: + + hasPrivContent' :: (IsContext c, IsPrivDataSource s) => (String -> FilePath -> IO ()) -> s -> FilePath -> c -> Property HasInfo + +but it should be + + hasPrivContent' :: (IsContext c, IsPrivDataSource s) => (FilePath -> String -> IO ()) -> s -> FilePath -> c -> Property HasInfo + +(it is hidden by FilePath = String) +"""]] diff --git a/doc/todo/bytes_in_privData__63__/comment_5_f4db6ffad054feb7eb299708fcd7d05c._comment b/doc/todo/bytes_in_privData__63__/comment_5_f4db6ffad054feb7eb299708fcd7d05c._comment new file mode 100644 index 00000000..45c97b97 --- /dev/null +++ b/doc/todo/bytes_in_privData__63__/comment_5_f4db6ffad054feb7eb299708fcd7d05c._comment @@ -0,0 +1,15 @@ +[[!comment format=mdwn + username="joey" + subject="""comment 5""" + date="2015-04-23T13:25:50Z" + content=""" +Can you put the patch up somewhere? I'll take a look. Might see a way to +short-curcuit the bytestring before everything becomes one.. + +One way might be: + + writeFileProtected :: FileContent content => FilePath -> content -> IO () + +Which would also at least partly avoid foot-shooting over which parameter is which. +(Fixed that type signature.) +"""]] diff --git a/doc/todo/bytes_in_privData__63__/comment_6_545e1c26a042b9f8347496a1bfb61548._comment b/doc/todo/bytes_in_privData__63__/comment_6_545e1c26a042b9f8347496a1bfb61548._comment new file mode 100644 index 00000000..29b07e5c --- /dev/null +++ b/doc/todo/bytes_in_privData__63__/comment_6_545e1c26a042b9f8347496a1bfb61548._comment @@ -0,0 +1,48 @@ +[[!comment format=mdwn + username="joey" + subject="""comment 6""" + date="2015-04-28T19:24:12Z" + content=""" +I've followed the same path in the wip-bytestring-privdata branch. + +It needs to round trip through String anyway to handle Read/Show +serialization the same as before. I think this is doable without falling +over on invalid encodings, but it's certianly ugly. + +And yeah, changing Line to ByteString and all the other follow-on changes +just don't seem right. Everything that uses withPrivData would need to deal +with it being a ByteString, and would need to worry about encoding problems +when it needed to convert to a String, or Text, or whatever. + +So this feels like kicking the can down the road in the wrong direction... + +---- + +Maybe it would be better to handle this by adding a type to wrap up an +encoded ByteString in the PrivData. Could use base64 or something like +that for the encoding. Then only consumers of these ByteStrings would be a +little complicated by needing to unwrap it. + +Then it would be handly to give --set, --dump and --edit some +special handling of fields encoded like that. They could operate on raw +ByteStrings when handling such fields, and take care of the encoding +details. + +Add a new constructor to PrivDataField for binary files: + + | PrivBinaryFile FilePath + +And a function to get the encoder and decoder: + + type Encoder = ByteString -> PrivData + type Decoder = PrivData -> ByteString + + privDataEncoding :: PrivDataField -> Maybe (Encoder, Decoder) + +Then --set, --dump, and --edit could use that to encode and decode the +data. + +And finally, a `withBinaryPrivData` that uses ByteString. + +(Maybe this could be made more type safe though..) +"""]] diff --git a/doc/todo/docker_todo_list.mdwn b/doc/todo/docker_todo_list.mdwn index 72ded426..1321445d 100644 --- a/doc/todo/docker_todo_list.mdwn +++ b/doc/todo/docker_todo_list.mdwn @@ -1,5 +1,3 @@ * There is no way for a property of a docker container to require some property be met outside the container. For example, some servers need ntp installed for a good date source. -* The SimpleSh was added before `docker exec` existed, and could probably - be eliminated by using that. diff --git a/doc/todo/editor_for_privdata__63__.mdwn b/doc/todo/editor_for_privdata__63__.mdwn new file mode 100644 index 00000000..8b91338c --- /dev/null +++ b/doc/todo/editor_for_privdata__63__.mdwn @@ -0,0 +1,4 @@ +Would adding a way to call $EDITOR to edit privdata be possible? +It would make sense for editing data like logcheck files. + +> [[done]] diff --git a/doc/todo/editor_for_privdata__63__/comment_2_4fcbdf36f32ca7cf82593a8992167aff._comment b/doc/todo/editor_for_privdata__63__/comment_2_4fcbdf36f32ca7cf82593a8992167aff._comment new file mode 100644 index 00000000..bbe93fe3 --- /dev/null +++ b/doc/todo/editor_for_privdata__63__/comment_2_4fcbdf36f32ca7cf82593a8992167aff._comment @@ -0,0 +1,9 @@ +[[!comment format=mdwn + username="http://joeyh.name/" + subject="comment 2" + date="2014-11-11T21:16:09Z" + content=""" +Already exists in `propellor --edit` + +Documentation patches accepted! :) +"""]] diff --git a/doc/todo/etckeeper.mdwn b/doc/todo/etckeeper.mdwn new file mode 100644 index 00000000..7dc80cef --- /dev/null +++ b/doc/todo/etckeeper.mdwn @@ -0,0 +1 @@ +It would be cool to have an etckeeper module :-). diff --git a/doc/todo/etckeeper/comment_1_8766da27c69bbae357d497e0e557fad2._comment b/doc/todo/etckeeper/comment_1_8766da27c69bbae357d497e0e557fad2._comment new file mode 100644 index 00000000..f080f70e --- /dev/null +++ b/doc/todo/etckeeper/comment_1_8766da27c69bbae357d497e0e557fad2._comment @@ -0,0 +1,9 @@ +[[!comment format=mdwn + username="joey" + subject="""comment 1""" + date="2014-11-06T15:46:56Z" + content=""" +All I've needed for this is `& Apt.installed ["etckeeper"]` + +Patches welcome, I suppose. +"""]] diff --git a/doc/todo/fail_if_modification_not_commited_when_using_--spin.mdwn b/doc/todo/fail_if_modification_not_commited_when_using_--spin.mdwn new file mode 100644 index 00000000..046f4a6f --- /dev/null +++ b/doc/todo/fail_if_modification_not_commited_when_using_--spin.mdwn @@ -0,0 +1,3 @@ +Sometimes I forget to commit a modification, and running "propellor --spin" automatically commits this stuff. It would be better if "propellor --spin" failed (or, even better, warned the user) that there are uncommited changes, and "propellor --spin" would just always add an empty commit. + +> --merge added; [[done]] --[[Joey]] diff --git a/doc/todo/fail_if_modification_not_commited_when_using_--spin/comment_1_7267d62ccc8db44bccb935836536e8a1._comment b/doc/todo/fail_if_modification_not_commited_when_using_--spin/comment_1_7267d62ccc8db44bccb935836536e8a1._comment new file mode 100644 index 00000000..19b2fab6 --- /dev/null +++ b/doc/todo/fail_if_modification_not_commited_when_using_--spin/comment_1_7267d62ccc8db44bccb935836536e8a1._comment @@ -0,0 +1,30 @@ +[[!comment format=mdwn + username="joey" + subject="""comment 1""" + date="2014-11-23T18:41:40Z" + content=""" +Letting --spin commit is part of my workflow. It's great when you're just +changing config.hs to quickly blast out the changes. + +Granted, it is not so nice when doing Property development, as changes get +fragmented across the spins used to test them. I'd be happy to find some +way to improve that. Perhaps a way could be found to get this structure of +git commits: + + manual commit------------------------->manual commit--merge + \--spin--spin--spin--spin--spin------------/ + +Where the second manual commit has an identical tree committed as does the +spin just underneath it, and so the following merge doesn't change any files, +just grafts the two branches back together. + +I guess that could be handled by haing a checkpoint command, that squashes +all the previous spins since the last checkpoint together into one commit, +lets the user edit the commit message of that, and the juggles the branches +into place and creates the merge commit -- which then becomes the new last +checkpoint. + +I'll take patches for such a thing, or more simply a way to configure --spin's +auto-committing behavior. However, I don't want to change the default +behavior to not commit. +"""]] diff --git a/doc/todo/fail_if_modification_not_commited_when_using_--spin/comment_2_e4d170a14d689bef5d9174b251a4fe6f._comment b/doc/todo/fail_if_modification_not_commited_when_using_--spin/comment_2_e4d170a14d689bef5d9174b251a4fe6f._comment new file mode 100644 index 00000000..3e8e5f62 --- /dev/null +++ b/doc/todo/fail_if_modification_not_commited_when_using_--spin/comment_2_e4d170a14d689bef5d9174b251a4fe6f._comment @@ -0,0 +1,7 @@ +[[!comment format=mdwn + username="gueux" + subject="comment 2" + date="2014-11-23T20:23:24Z" + content=""" +Your solution seems a lot better :-). +"""]] diff --git a/doc/todo/fail_if_modification_not_commited_when_using_--spin/comment_3_c69eaa9c6ae5b07b5c2dd2591de965a3._comment b/doc/todo/fail_if_modification_not_commited_when_using_--spin/comment_3_c69eaa9c6ae5b07b5c2dd2591de965a3._comment new file mode 100644 index 00000000..8ad6ab49 --- /dev/null +++ b/doc/todo/fail_if_modification_not_commited_when_using_--spin/comment_3_c69eaa9c6ae5b07b5c2dd2591de965a3._comment @@ -0,0 +1,19 @@ +[[!comment format=mdwn + username="joey" + subject="""comment 3""" + date="2014-11-23T21:12:19Z" + content=""" +Here's a almost-script to do it, which worked when it did it by hand: + +<pre> +get old-head (git show-ref HEAD -s) +get curr-branch (refs/heads/master eg) +find old-commit (look back through git log for the first commit that was not "propellor spin") +git reset old-commit +git commit -a # user gets to edit commit message for all the spins and any staged changes here +git merge -S -s ours old-head +get current-commit (result of merge) +git update-ref curr-branch current-commit +git checkout curr-branch +</pre> +"""]] diff --git a/doc/todo/git_push_over_propellor_ssh_channel.mdwn b/doc/todo/git_push_over_propellor_ssh_channel.mdwn new file mode 100644 index 00000000..c6d42fcf --- /dev/null +++ b/doc/todo/git_push_over_propellor_ssh_channel.mdwn @@ -0,0 +1,13 @@ +Propellor currently needs a central git server. And it has a special-cased +protocol during bootstrap that transfers the git repo over to a new host, +using the ssh connection that will be used to run propellor. + +This could be improved by making a git push be done whenever +`propellor spin $host` runs. The remote propellor runs `git receive-pack`; +the local one runs `git send-pack`. + +Then there would be no need for a central git repo. Although still very +useful if you have multiple propellor driven hosts and you want to just git +commit and let cron sort them out. + +> [[done]]! --[[Joey]] diff --git a/doc/todo/info_propigation_out_of_nested_properties.mdwn b/doc/todo/info_propigation_out_of_nested_properties.mdwn index e6427069..536d6719 100644 --- a/doc/todo/info_propigation_out_of_nested_properties.mdwn +++ b/doc/todo/info_propigation_out_of_nested_properties.mdwn @@ -1,36 +1,97 @@ > Now [[fixed|done]]!! --[[Joey]] -Currently, Info about a Host's Properties is manually gathered and -propigated. propertyList combines the Info of the Properties in the list. -Docker.docked extracts relevant Info from the Properties of the container -(but not al of it, intentionally!). +Currently, Info about a Host's Properties is propigated to the host by +examining the tree of Properties. -This works, but it's error-prone. Consider this example: +This works, but there's one problem. Consider this example: withOS desc $ \o -> case o of (Just (System (Debian Unstable) _)) -> ensureProperty foo _ -> ensureProperty bar Here, the Info of `foo` is not propigated out. Nor is `bar`'s Info. -Of course, only one of them will be run, and only its info should be propigated -out.. +It's not really clear if just one Info, or both should be propigated out. -This commonly afflicts eg, privData. For example, `User.hasPassword'` -has this problem, and this prevents --list-fields from listing privdata -that's not set from that property. +---- One approach might be to make the Propellor monad be able to be run in two -modes. In one mode, it actually perform IO, etc. In the other mode, all -liftIO is a no-op, but all Info encountered is accumulated using a Reader -monad. This might need two separate monad definitions. +modes. In run mode, it actually performs IO, etc. In introspection mode, all +liftIO is a no-op, but all Info encountered is accumulated using a Reader. +This might need two separate monad definitions. -That is surely doable, but the withOS example above shows a problem with it -- -the OS is itself part of a Host's info, so won't be known until all its -properties have been examined for info! +That is surely doable, but consider this example: -Perhaps that can be finessed. We don't really need to propigate out OS info. -Just DNS and PrivDataField Info. So info could be collected in 2 passes, -first as it's done now by static propertyInfo values. Then take that -and use it as the Info when running the Properties in the Reader monad. -Combine what the Reader accumulates with the static info to get the full -info. + property "demo" = do + needfoo <- liftIO checkFoo + if needfoo + then ensureProperty foo + else ensureProperty . bar =<< liftIO (getBarParam) + +In introspection mode, the liftIO is a no-op, but needs to return a Bool. +That seems unlikely (how to pick which?), but even if some defaulting is +used, only one of foo or bar's info will be seen. + +Worse, the bar property is not fully known until IO can be performed to get +its parameter. + +---- + +Another approach could be something like this: + + withInfoFrom foo $ \callfoo -> + withInfoFrom bar $ \callbar -> + property "demo" = do + needfoo <- liftIO checkFoo + if needfoo + then callfoo + else callbar + +Here withInfoFrom adds foo and bar as child properties of the demo property +that (may) call them. + +This approach is not fully type safe; it would be possible to call +withInfoFrom in a way that didn't let it propigate the info. + +And again this doesn't solve the problem that IO can be needed to get +a parameter of a child property. + +---- + +Another approach would be to add a new SimpleProperty, which is a property +that has no Info. Only allow calling ensureProperty on this new type. + +(Or, remove propertyInfo from Property, and add a new InfoProperty that +has the info.) + +But, propertyList can only contain one type at a time, +not a mixed list of Property and SimpleProperty. + +Could a GADT be used instead? + + {-# LANGUAGE GADTs #-} + {-# LANGUAGE EmptyDataDecls #-} + + data HasInfo + data NoInfo + + data Property = IProperty (GProperty HasInfo) | SProperty (GProperty NoInfo) + + data GProperty i where + GIProperty :: Desc -> Propellor Result -> Info -> GProperty HasInfo + GSProperty :: Desc -> Propellor Result -> GProperty NoInfo + + ensureProperty :: GProperty NoInfo -> Propellor Result + ensureProperty (GSProperty d r) = r + +That works. I made a `gadtwip` git branch that elaborated on that, +to the point that Property.File compiles, but is otherwise +unfinished. Most definitions of `Property` need to be changed to +`GProperty NoInfo`, so that ensureProperty can call them. It's a big, +intrusive change, and it may complicate propellor too much. + +I've tried to make this change a couple times now, and not been completely +successful so far. + +(I may need to make instances of Prop for `GProperty NoInfo` and `GProperty +HasInfo`, if that's possible, and make more Property combinators work on +Prop.) diff --git a/doc/todo/issue_after_upgrading_shared_library.mdwn b/doc/todo/issue_after_upgrading_shared_library.mdwn new file mode 100644 index 00000000..52e72d4a --- /dev/null +++ b/doc/todo/issue_after_upgrading_shared_library.mdwn @@ -0,0 +1,25 @@ +After upgrading my server to jessie, I noticed that propellor does not work anymore. The issue seems to be that, libffi was upgraded from libffi5:amd64 to libffi6:amd64 + + $ ./propellor --spin myserver + Building propellor-2.2.1... + Preprocessing library propellor-2.2.1... + In-place registering propellor-2.2.1... + Preprocessing executable 'propellor' for propellor-2.2.1... + Preprocessing executable 'propellor-config' for propellor-2.2.1... + Propellor build ... done + + You need a passphrase to unlock the secret key for + user: bla + + [master 2aabb40] propellor spin + Git commit ... done + Counting objects: 1, done. + Writing objects: 100% (1/1), 852 bytes | 0 bytes/s, done. + Total 1 (delta 0), reused 0 (delta 0) + To root@myserver:/var/lib/git/private/propellor.git + b16f1a6..2aabb40 master -> master + Push to central git repository ... done + ./propellor: error while loading shared libraries: libffi.so.5: cannot open shared object file: No such file or directory + propellor: user error (ssh ["-o","ControlPath=/home/myuser/.ssh/propellor/myserver.sock","-o","ControlMaster=auto","-o","ControlPersist=yes","root@myserver","sh -c 'if [ ! -d /usr/local/propellor/.git ] ; then (if ! git --version >/dev/null; then apt-get update && apt-get --no-install-recommends --no-upgrade -y install git; fi && echo STATUSNeedGitClone) || echo STATUSNeedPrecompiled ; else cd /usr/local/propellor && if ! test -x ./propellor; then ( apt-get update ; apt-get --no-upgrade --no-install-recommends -y install gnupg ; apt-get --no-upgrade --no-install-recommends -y install ghc ; apt-get --no-upgrade --no-install-recommends -y install cabal-install ; apt-get --no-upgrade --no-install-recommends -y install libghc-async-dev ; apt-get --no-upgrade --no-install-recommends -y install libghc-missingh-dev ; apt-get --no-upgrade --no-install-recommends -y install libghc-hslogger-dev ; apt-get --no-upgrade --no-install-recommends -y install libghc-unix-compat-dev ; apt-get --no-upgrade --no-install-recommends -y install libghc-ansi-terminal-dev ; apt-get --no-upgrade --no-install-recommends -y install libghc-ifelse-dev ; apt-get --no-upgrade --no-install-recommends -y install libghc-network-dev ; apt-get --no-upgrade --no-install-recommends -y install libghc-quickcheck2-dev ; apt-get --no-upgrade --no-install-recommends -y install libghc-mtl-dev ; apt-get --no-upgrade --no-install-recommends -y install libghc-monadcatchio-transformers-dev ; cabal update ; cabal install --only-dependencies ) || true && cabal configure && cabal build && ln -sf dist/build/propellor-config/propellor-config propellor; fi && ./propellor --boot myserver ; fi'"] exited 127) + +> [[fixed|done]] --[[Joey]] diff --git a/doc/todo/issue_after_upgrading_shared_library/comment_1_8d9144d57871cb5d234710d1ab1b7183._comment b/doc/todo/issue_after_upgrading_shared_library/comment_1_8d9144d57871cb5d234710d1ab1b7183._comment new file mode 100644 index 00000000..77c7df83 --- /dev/null +++ b/doc/todo/issue_after_upgrading_shared_library/comment_1_8d9144d57871cb5d234710d1ab1b7183._comment @@ -0,0 +1,20 @@ +[[!comment format=mdwn + username="joey" + subject="""comment 1""" + date="2015-04-02T01:14:06Z" + content=""" +I think I saw this once myself (have no servers older than jessie left +now). + +I believe the problem can be worked around by running make clean +in /usr/local/propellor on the server. + +I'm not clear yet on a good way for --spin to detect that propellor +has failed due to this, rather than some other problem, and try +a clean and rebuild. + +Hmm, xmonad should have a similar problem, since it builds a haskell +program locally. I wonder how the debian package deals with it there. + +Note there's a libffi6, so this will presumably happen again.. +"""]] diff --git a/doc/todo/issue_after_upgrading_shared_library/comment_2_01a3d5e006158302e12862cacee3327e._comment b/doc/todo/issue_after_upgrading_shared_library/comment_2_01a3d5e006158302e12862cacee3327e._comment new file mode 100644 index 00000000..3f7a7bbc --- /dev/null +++ b/doc/todo/issue_after_upgrading_shared_library/comment_2_01a3d5e006158302e12862cacee3327e._comment @@ -0,0 +1,7 @@ +[[!comment format=mdwn + username="gueux" + subject="comment 2" + date="2015-04-02T09:24:07Z" + content=""" +Indeed, \"make clean\" on the server worked. I don't know it could be made more robust to this kind of upgrade... +"""]] diff --git a/doc/todo/issue_after_upgrading_shared_library/comment_2_6025ec35330fbac220f2888e60be1e78._comment b/doc/todo/issue_after_upgrading_shared_library/comment_2_6025ec35330fbac220f2888e60be1e78._comment new file mode 100644 index 00000000..bc89ad7f --- /dev/null +++ b/doc/todo/issue_after_upgrading_shared_library/comment_2_6025ec35330fbac220f2888e60be1e78._comment @@ -0,0 +1,17 @@ +[[!comment format=mdwn + username="joey" + subject="""comment 2""" + date="2015-04-02T14:27:26Z" + content=""" +So I thought of two approaches. + +1. Propellor could copy in all the shared libraries. It already contains + code to do this. But, this would add overhead to every build. And it + might not guard against all snafus. + +2. Make propellor --check that should exit 0. Make --spin check that + propellor works and rebuild if not. Also make the runPropellor cron job + do that. + +I've gone with option #2. +"""]] diff --git a/doc/todo/lxc_containers_support.mdwn b/doc/todo/lxc_containers_support.mdwn new file mode 100644 index 00000000..5e9da306 --- /dev/null +++ b/doc/todo/lxc_containers_support.mdwn @@ -0,0 +1 @@ +Adding lxc containers support would be great, as an alternative to docker, chroot, or systemd containers. diff --git a/doc/todo/port_info_for_properties_for_firewall.mdwn b/doc/todo/port_info_for_properties_for_firewall.mdwn new file mode 100644 index 00000000..efaaba05 --- /dev/null +++ b/doc/todo/port_info_for_properties_for_firewall.mdwn @@ -0,0 +1,24 @@ +The firewall module could be improved if properties that set up a service +on a port included info (see Propellor.Info and Propellor.Types.Info) +about the port(s) used. + +While currently the ports have to be explicitly listed: + + & Apache.installed + & Firewall.installed + & Firewall.addRule (Rule INPUT ACCEPT (Proto TCP :- Port 80)) + & Firewall.addRule (Rule INPUT ACCEPT (Proto TCP :- Port 443)) + +Instead the ports would be derived from the installed services. + + & Apache.installed + & Firewall.installed + +There could also be some combinators to adjust the exposed +ports of a property. + + & localOnly Apache.installed + & exposedPorts [443,80] (Apt.serviceInstalledRunning "apache2") + +Such port enformation is also going to be needed as a basis of +[[type_level_port_conflict_detection]]. --[[Joey]] diff --git a/doc/todo/publish_propellor_as_library_to_hackage.mdwn b/doc/todo/publish_propellor_as_library_to_hackage.mdwn new file mode 100644 index 00000000..709ee35b --- /dev/null +++ b/doc/todo/publish_propellor_as_library_to_hackage.mdwn @@ -0,0 +1,4 @@ +Currently, AFAIK, one needs to fork propellor repo, add its own configuration and compile propellor binary from all the source tree. +It would be handy and more modular to allow one to have a propellor configuration linked to propellor as a library, hosted on hackage. + +> [[done]] --[[Joey]] diff --git a/doc/todo/publish_propellor_as_library_to_hackage/comment_1_00a865bf7977c0e49f54a365f4b60ce8._comment b/doc/todo/publish_propellor_as_library_to_hackage/comment_1_00a865bf7977c0e49f54a365f4b60ce8._comment new file mode 100644 index 00000000..8d56f0f1 --- /dev/null +++ b/doc/todo/publish_propellor_as_library_to_hackage/comment_1_00a865bf7977c0e49f54a365f4b60ce8._comment @@ -0,0 +1,27 @@ +[[!comment format=mdwn + username="joey" + subject="""comment 1""" + date="2015-02-28T15:01:24Z" + content=""" +Unusual as it is for propellor's configuration git repo to include the full +source code to propellor, I like this approach. It lets users change any +existing property that is not generic enough, or makes assumptions they +don't like, or needs porting to their OS of choice. + +But still, propellor is +[on hackage](http://hackage.haskell.org/package/propellor), as +a library. It can be used that way if you want to. + +I don't think that any of propellor's code cares how it's distributed, +except for src/wrapper.hs (which cabal will install as +~/.cabal/bin/propellor), which sets up the ~/.propellor/ repository. You +can bypass using that wrapper if you like, and cabal install propellor and +create your own ~/.propellor/ repository containing only your own +config.hs, and build and use propellor that way. + +Where that approach becomes a problem is that propellor --spin currently +relies on propellor's Makefile being in the repository, when bootstrapping +propellor on a remote host. So you'll need to include a copy of that in +your repo for --spin to work. I'd like to get rid of the need for the +Makefile. (Only the build and deps targets are used by --spin.) +"""]] diff --git a/doc/todo/publish_propellor_as_library_to_hackage/comment_2_29cc276929020e68eae8ae04110a3f5f._comment b/doc/todo/publish_propellor_as_library_to_hackage/comment_2_29cc276929020e68eae8ae04110a3f5f._comment new file mode 100644 index 00000000..af61b1db --- /dev/null +++ b/doc/todo/publish_propellor_as_library_to_hackage/comment_2_29cc276929020e68eae8ae04110a3f5f._comment @@ -0,0 +1,17 @@ +[[!comment format=mdwn + username="joey" + subject="""comment 2""" + date="2015-02-28T17:08:28Z" + content=""" +Ok, I got --spin to not use the Makefile any more. So with the 2.2.0 +release, if you want to make ~/.propellor contain only a config.hs +file and a foo.cabal file, that will work. The cabal file would contain +something like: + +<pre> +Executable propellor-config + Main-Is: config.hs + GHC-Options: -Wall -threaded -O0 + Build-Depends: propellor, base >= 4.5, base < 5 +</pre> +"""]] diff --git a/doc/todo/publish_propellor_as_library_to_hackage/comment_3_efbe0ef77be957c37e745ec64452ae99._comment b/doc/todo/publish_propellor_as_library_to_hackage/comment_3_efbe0ef77be957c37e745ec64452ae99._comment new file mode 100644 index 00000000..09628e53 --- /dev/null +++ b/doc/todo/publish_propellor_as_library_to_hackage/comment_3_efbe0ef77be957c37e745ec64452ae99._comment @@ -0,0 +1,10 @@ +[[!comment format=mdwn + username="https://www.google.com/accounts/o8/id?id=AItOawmtnXa0F3OsNh8H7yf5EEbtuufPZG-3StI" + nickname="Arnaud" + subject="You rocks!" + date="2015-03-05T15:24:49Z" + content=""" +Apologies for wrong information, I did not check if propellor was on hackage. Anyway, thanks a lot for caring to \"fix\" that, will give it a try this week and keep you posted. + +Thanks a lot +"""]] diff --git a/doc/todo/publish_propellor_as_library_to_hackage/comment_4_6ebf2e30596ddf6eba91717576837019._comment b/doc/todo/publish_propellor_as_library_to_hackage/comment_4_6ebf2e30596ddf6eba91717576837019._comment new file mode 100644 index 00000000..737e7066 --- /dev/null +++ b/doc/todo/publish_propellor_as_library_to_hackage/comment_4_6ebf2e30596ddf6eba91717576837019._comment @@ -0,0 +1,8 @@ +[[!comment format=mdwn + username="https://www.google.com/accounts/o8/id?id=AItOawmtnXa0F3OsNh8H7yf5EEbtuufPZG-3StI" + nickname="Arnaud" + subject="Propellor 2.2.0 not on hackage" + date="2015-03-08T20:21:42Z" + content=""" +So I cannot depend on it right now. Do you know when it will be available there? +"""]] diff --git a/doc/todo/publish_propellor_as_library_to_hackage/comment_5_4a4e94c637e0380adc1a43ec3d0633e1._comment b/doc/todo/publish_propellor_as_library_to_hackage/comment_5_4a4e94c637e0380adc1a43ec3d0633e1._comment new file mode 100644 index 00000000..85f95c17 --- /dev/null +++ b/doc/todo/publish_propellor_as_library_to_hackage/comment_5_4a4e94c637e0380adc1a43ec3d0633e1._comment @@ -0,0 +1,8 @@ +[[!comment format=mdwn + username="joey" + subject="""comment 5""" + date="2015-03-09T17:00:35Z" + content=""" +SImply because 2.2.0 had not been released yet. (UNRELEASED in +changelog..) +"""]] diff --git a/doc/todo/publish_propellor_as_library_to_hackage/comment_6_19470170c3ef461f446b0af1d8501640._comment b/doc/todo/publish_propellor_as_library_to_hackage/comment_6_19470170c3ef461f446b0af1d8501640._comment new file mode 100644 index 00000000..143f1dea --- /dev/null +++ b/doc/todo/publish_propellor_as_library_to_hackage/comment_6_19470170c3ef461f446b0af1d8501640._comment @@ -0,0 +1,8 @@ +[[!comment format=mdwn + username="https://www.google.com/accounts/o8/id?id=AItOawmtnXa0F3OsNh8H7yf5EEbtuufPZG-3StI" + nickname="Arnaud" + subject="comment 6" + date="2015-03-10T06:28:52Z" + content=""" +Sorry, I did not read the changelog. Thanks for all the hard work on propellor. +"""]] diff --git a/doc/todo/type_level_port_conflict_detection.mdwn b/doc/todo/type_level_port_conflict_detection.mdwn new file mode 100644 index 00000000..5aec5775 --- /dev/null +++ b/doc/todo/type_level_port_conflict_detection.mdwn @@ -0,0 +1,5 @@ +See <http://stackoverflow.com/questions/26027765/using-types-to-prevent-conflicting-port-numbers-in-a-list> --[[Joey]] + +Needs ghc newer than 7.6.3. It may be possible to port Data.Type.Equality +and Data.Type.Bool to older versions; I got them to compile but they didn't +work right. --[[Joey]] diff --git a/doc/writing_properties.mdwn b/doc/writing_properties.mdwn new file mode 100644 index 00000000..c7183e09 --- /dev/null +++ b/doc/writing_properties.mdwn @@ -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. diff --git a/privdata.joey/keyring.gpg b/privdata.joey/keyring.gpg Binary files differdeleted file mode 100644 index 01dd24e7..00000000 --- a/privdata.joey/keyring.gpg +++ /dev/null diff --git a/privdata.joey/privdata.gpg b/privdata.joey/privdata.gpg deleted file mode 100644 index 548354a1..00000000 --- a/privdata.joey/privdata.gpg +++ /dev/null @@ -1,1300 +0,0 @@ ------BEGIN PGP MESSAGE----- -Version: GnuPG v1 - -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 -X2t75jMcmpFuYSmp6vl8HuxJiXc= -=Mvv1 ------END PGP MESSAGE----- diff --git a/src/Propellor/PrivData/Paths.hs b/src/Propellor/PrivData/Paths.hs index 9f791b76..3d0d8a58 100644 --- a/src/Propellor/PrivData/Paths.hs +++ b/src/Propellor/PrivData/Paths.hs @@ -3,7 +3,7 @@ module Propellor.PrivData.Paths where import System.FilePath privDataDir :: FilePath -privDataDir = "privdata.joey" +privDataDir = "privdata" privDataFile :: FilePath privDataFile = privDataDir </> "privdata.gpg" |
