Git syncer
Allows cron job control and command execution on a remote machine using git infrastructure.
👷🏻 Please note, this project is still a work-in-progress 🏗️
Quick start
On your computer, set up the basic repository
(checkout the example_project in this repository to see how this should generally look):
- Create a private GitHub repository and clone it.
- Create a
requirements.txtfile, and add thegit-syncerdependency. - Create a
main.pyfile:
from git_syncer import run
from git_syncer.runnables import register
register() # Add boot jobs, cron jobs, and remote commands here 🏋🏻♂️
if __name__ == "__main__":
run()
- Add a
.gitignorefile (tip: use gitignore.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 a virtual environment for this project and activate it
(using
source <venv_dir>/bin/activate). cdto your repository directory.- Install dependencies using
pip 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 new cron jobs and execute remote commands on the remote machine using this git repository. For more details, see the usage section.
Usage
Note: this tool writes logs to ~/logs/git-syncer/.
Runnables
A Runnable is the basic class that the package uses.
To define your own custom commands, create your own class, inherit Runnable,
and implement the mandatory abstract methods:
# File: my_runnables.py
from git_syncer.models import Runnable
class HelloWorld(Runnable):
@property
def verbose_name(self) -> str:
return "Hello World"
def run(self) -> str:
return "This runnable was called!"
...and register your runnable in main.py:
# File: main.py
from git_syncer.runnables import register
from my_runnables import HelloWorld
register(HelloWorld())
Boot jobs
Boot jobs will execute once the remote machine turns on.
In order to make a Runnable into a boot job, set the run_on_boot property to True:
class HelloWorld(Runnable):
@property
def run_on_boot(self) -> bool:
return True
...
Cron jobs
To create a cron job, inherit the CronJob class, and fill the expression property:
from git_syncer.models import CronJob
class MyCronJob(CronJob):
@property
def verbose_name(self) -> str:
return "Ping"
@property
def expression(self) -> str:
# Every 5 minutes
return "*/5 * * * *"
def run(self) -> str:
return "This job runs every 5 minutes"
Execute jobs on command
In order to make a non-cron runnable execute on the remote machine:
- On your local machine, commit an empty file matching your
Runnablename 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 is
GetIP, 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-cron Runnable should be executed, its should_execute method
is called (matching file names to the runnable class name). In order to execute your runnable based on different logic,
override the should_execute method:
from typing import Set
from git_syncer.models import Runnable
import random
class HelloWorld(Runnable):
@property
def verbose_name(self) -> str:
return "Hello World"
def run(self) -> str:
return "This runnable was called!"
def should_execute(self, inputs: Set[str]) -> bool:
# Take a look at the base method and implement your own logic.
return random.randint(1, 100) % 5 == 0
Error handling
👷🏻 TODO
Release files for git-syncer 1.1.1
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| git-syncer-1.1.1.tar.gz | 15.5 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| git_syncer-1.1.1-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 33.7 kB
Release files / git-syncer-1.1.1.tar.gz
| Download URL | git-syncer-1.1.1.tar.gz |
|---|---|
| Size | 15.5 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
cc45d955f05a8a132cde3c390d31a961a7d68eed928d10e4bb3f7975ca6e3c68
|
|
BLAKE2b-256 checksum How to use checksums |
cafc3fb3c25ad0c7ab2933e260fbbd0bb46f6ef354f9ab477cf0285ac73a60b6
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/4.0.1 CPython/3.8.10
|
Release files / git_syncer-1.1.1-py3-none-any.whl
| Download URL | git_syncer-1.1.1-py3-none-any.whl |
|---|---|
| Size | 18.1 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
8b85470edfe3eb776af85212f493bbbd850593224a260f268cd97ed4f9b90e92
|
|
BLAKE2b-256 checksum How to use checksums |
f0ad1c4f19121c5e7a1a2b746038b4017858787fa4b6c7c8e50f07a4b2f2fe7a
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/4.0.1 CPython/3.8.10
|