Package: git-syncer
Git syncerAllows cron job control and command execution on a remote machine using git
infrastructure.👷🏻Please note, this project is still a work-in-progress🏗️Quick startOn your computer, set up the basic repository
(checkout theexample_projectin this repository to see how this should generally look):CreateaprivateGitHub repository and clone it.Create arequirements.txtfile, and add thegit-syncerdependency.Create amain.pyfile:fromgit_syncerimportrunfromgit_syncer.runnablesimportregisterregister()# Add boot jobs, cron jobs, and remote commands here 🏋🏻‍♂️if__name__=="__main__":run()Add a.gitignorefile (tip: usegitignore.io).
It must containout/directory.Commit and push your changes.On your remote machine (SSH to it):Set up GitHub credentials to clone your new repository.Highly recommended: instead of providing your own personal GitHub credentials on the remote machine,add an SSH deploy key to your repository. If you choose to do so, check theAllow write accesscheckbox.Clone your new repository to the remote machine.Set up avirtual environmentfor this project and activate it
(usingsource <venv_dir>/bin/activate).cdto your repository directory.Install dependencies usingpip install -r requirements.txt(git-syncershould be installed).⚠️THIS STEP WILL OVERRIDE YOUR EXISTING CRONTAB SETTINGS!⚠️Activate the syncer using the CLI commandinit-syncer.From now on, you can add newcron jobsand executeremote commandson the
remote machine using this git repository. For more details, see theusage section.UsageNote: this tool writes logs to~/logs/git-syncer/.RunnablesARunnableis the basic class that the package uses.
To define your own custom commands, create your own class, inheritRunnable,
and implement the mandatory abstract methods:# File: my_runnables.pyfromgit_syncer.modelsimportRunnableclassHelloWorld(Runnable):@propertydefverbose_name(self)->str:return"Hello World"defrun(self)->str:return"This runnable was called!"...and register your runnable inmain.py:# File: main.pyfromgit_syncer.runnablesimportregisterfrommy_runnablesimportHelloWorldregister(HelloWorld())Boot jobsBoot jobs will execute once the remote machine turns on.
In order to make aRunnableinto a boot job, set therun_on_bootproperty toTrue:classHelloWorld(Runnable):@propertydefrun_on_boot(self)->bool:returnTrue...Cron jobsTo create a cron job, inherit theCronJobclass, and fill theexpressionproperty:fromgit_syncer.modelsimportCronJobclassMyCronJob(CronJob):@propertydefverbose_name(self)->str:return"Ping"@propertydefexpression(self)->str:# Every 5 minutesreturn"*/5 * * * *"defrun(self)->str:return"This job runs every 5 minutes"Execute jobs on commandIn order to make a non-cron runnable execute on the remote machine:On your local machine, commit an empty file matching yourRunnablename underexecutefolder (for example,
if the runnable class name isGetIP, commit a file namedexecute/get-ip).Push your changes.On the next round minute:The runnable will execute on the remote device,The execution result will be written in a file matching your runnable name (for example, if the runnable
class name isGetIP, the result file will be namedexecute/get-ip-result.txt, and theexecute/get-ipfile will be removed).The changes will be committed and pushed back to the repository.Wait a few seconds and pull your repository. You will see the execution result in the expected result file.Expert mode: every minute, in order the check if a non-cronRunnableshould be executed, itsshould_executemethod
is called (matching file names to the runnable class name). In order to execute your runnable based on different logic,
override theshould_executemethod:fromtypingimportSetfromgit_syncer.modelsimportRunnableimportrandomclassHelloWorld(Runnable):@propertydefverbose_name(self)->str:return"Hello World"defrun(self)->str:return"This runnable was called!"defshould_execute(self,inputs:Set[str])->bool:# Take a look at the base method and implement your own logic.returnrandom.randint(1,100)%5==0Error handling👷🏻 TODO