Currently, I visualise it something like this:
Generates a state from a set of plaintext files, checks for deviations from the state, and fixes them as required. Kind of like Make, but more specialised.
Syncs the state files across computers. The best method would see to be to use Git over SSH – the advantage over immix is that I can have multiple branches.
Runs the syncer and applicator every few hours/minutes/seconds. This could be as simple as a script hooked up to a systemd/launchd/init service file, or a cron job.
The most complex part is the applicator. Generating the state from a set of plaintext files would be challenging, so would checking for deviations and applying them.
The state would probably be defined in a set of plaintext files, with the target state declared within.
For instance, to make sure some packages were installed, the file would include:
installed_packages = lynx,vim,fbpdf,other
Or something like that. Add in if statements, include statements, variables, and some commands, and the resulting basic declarative language should be able to define the target state, including understanding the host OS and changing accordingly (launchd vs. systemd service files, for instance), the current architecture, the specifics of the host system, and the hostname (in essence, the computer ID). I will look to see whether my chosen language has a library that could handle this part for me, but otherwise I think it should be within my grasp to create something that worked.
One additional challenge would be some sanity checking – checking that a package was not both required and forbidden, for instance. I’m not sure where that would fit, but it would probably be the most challenging task.
Checking for deviations would be hard, but not insurmountable. For instance, depending on the package manager, the command for checking for a program being installed would vary. On Mac OSX, the simplest method would be to try to find the program binary, since there is not native package manager, and resort to macports or homebrew as required for installing. Being able to define behaviour – like how to check that a package is installed – in the declarative language would be a must. Actually checking the state should be reasonably easy – run through each of the proposed state variables and check with the method defined for that particular system/architecture/OS whether they are satisfied. After creating a list of unsatisfied substates, the checker could pass the list on to the applicator.
Applying the unsatisfied substates would be reasonably easy. Like checking for deviations, provided the way to resolve the issue was defined somewhere – how to change the relevant config file, how to install packages, how to add a user – SSS mk.2 would just have to apply that method, doing something if it failed (printing an error, logging, messaging the user, or similar).
Some expected challenges include:
- Local vs global changes. On computers that only I use, I’d want the changes to be global. However, on shared computers – such as the Mac I occasionally have to use – the changes would have to be local only, and because I don’t have super user rights, I’d have to install software locally, as well as changing the configuration locally.
- Depending on how much my chosen language handles low level details, writing a powerful declarative language for the configuration could be challenging. So much so, that I might need to consider an alternative method. I hope not… in Python it would be reasonably easy!
- Working on computers with different directory structures. My computers all run Arch Linux, so they are easy. However, sometimes the directory structures can be radically different. I’d have to be careful to make sure all locations were not hard coded and instead referenced back to an OS-specific config file. Especially if I ever do manage to make a specialised distro for the Toshiba.