I think we can do cron management a little bit better, and as a result of changes here, better support the program in other locations as well.
Global settings file
To begin, I propose creating a ~/settings/.brewpisettings file to hold common variables we already repeatedly ask for in the install and upgrade process (and other places as well). By placing this file in a standard location, the multiple brewpi scripts could reference (from any repo) without having to import an entire module from a differenet repo, or hack-ily parse through other code. It would hold:
- webPath - path to brewpi web install location
- scriptPath - path to brewpi-script install location
- Hexfile version - current version of the hex file loaded on Arduino
- board version - model of Arduino board being used
- modules present to be loaded - in this case, brewpi.py, wifichecker.sh, and maybe bubblecounter.whatever
- stdout logging path - path to stdout log file
- stderr logging path - path to stderr log file
... and anything else that we reuse I haven't though of yet.
At first, I thought about pushing the entire brewpi settings file currently being used to /etc/brewpi, but I think this will cause significant issues with configuration management as updates are made to the config file, or the user changes it. Instead, I suggest creating a sym-link in /etc/brewpi/settings to wherever the settings file is installed. This way, any script can universally reference /etc/brewpi/settings to get its important data, no matter where the user has installed brewpi. This additionally allows us to make changes to the config file locally via the git repo without needing to update a file outside the repo.
Module requirements
A module will take one of four arguments from stdin when run:
- null: Run the module
- install: install the module
- cron: return the cron line that should be used in cron.d
- remove: optional, but good to have it in the plan
Installing a module
For cronUpdate.sh , I strongly disagree with putting the install code for each module into cronUpdate.sh .
The goal of modularity is pushing as much code specific to a module, out to the module itself. Think of how aptitude updates run, or installing a python module- the install code for each new package is not contained within the main program- you merely pass an install argument to the code it has downloaded, and the package takes care of the rest. For wifichecker, its only a few lines, but as modules become more advanced, so too may become the install code. You don't want to carry around that amount of code for modules some users may never use (and especially if the modules eventually get pushed to their own repo).
Instead, when called by cronUpdate.sh with the 'install' argument (and root privs), the module will take care of adding itself to cron.d, updating its entry in the .settings file as 'true', and moving files anywhere they may need to be. There will also need to be an install path variable for each entry
Tracking/Updating modules
To update modules, updateCron cycles through the list of installed modules in .settings, checks which vars are true, and compares (version number? md5 hash? cron line?) of a module and, if different, prompts to update.
-OR-
cycle through each installed module and just overwrite the cron file with each new entry (starting with brewpi)
I don't want to be prompted to install old modules I already said no to!
updateCron has a 'master' list of all potential modules within it. (This is the only module-specific code located in updateCron) When it scans .settings to update, any entries that exist within the master list but not the .settings file will cause the user to be prompted to install that module. If they choose 'yes', the module is installed, and an entry is made to the .settings file with moduleName = True. If the user choose not to install, an entry is made to .settings with moduleName = False, and that module is not prompted to the user for install again on future updates.
updateCron psuedocode
read in all modules listed in .settings file
retrieve current cron lines from each installed module
compare to installed cron.d lines, replace if necessary (or straight overwrite everytime)
prompt user to install any newly-added modules not seen before
restart cron
Profit!
Bottom line
I think this framework for modules / cron
- gives us a format that future modules should adhere to
- pushes as much unique/module-specific code out to the module as possible
- promotes code re-use by brewpi
- prevents extensive changes to 'core' code (updateCron.sh) as each module is added (only adding a variable name to check for, nothing extensive or bulky)
- enables commonly-used variables to be used from a static location
- don't need to create backward-compatibility checks for the 'new' cron file version
Lets discuss!