Add locking to git commands

Avoids conflicting attempts when multiple hosts check in at once.
This commit is contained in:
Joshua Boniface 2022-10-25 17:36:56 +00:00
parent fdae20c3c6
commit 00ac00ae2c
1 changed files with 53 additions and 42 deletions

View File

@ -22,6 +22,7 @@
import os.path import os.path
import git import git
import yaml import yaml
from filelock import FileLock
import pvcbootstrapd.lib.notifications as notifications import pvcbootstrapd.lib.notifications as notifications
@ -60,61 +61,71 @@ def pull_repository(config):
""" """
Pull (with rebase) the Ansible git repository Pull (with rebase) the Ansible git repository
""" """
logger.info(f"Updating local configuration repository {config['ansible_path']}") lockfile = "/tmp/pvcbootstrapd-git.lock"
try: lock = FileLock(lockfile)
git_ssh_cmd = f"ssh -i {config['ansible_keyfile']} -o StrictHostKeyChecking=no" with lock:
g = git.cmd.Git(f"{config['ansible_path']}") logger.info(f"Updating local configuration repository {config['ansible_path']}")
g.pull(rebase=True, env=dict(GIT_SSH_COMMAND=git_ssh_cmd)) try:
g.submodule("update", "--init", env=dict(GIT_SSH_COMMAND=git_ssh_cmd)) git_ssh_cmd = f"ssh -i {config['ansible_keyfile']} -o StrictHostKeyChecking=no"
except Exception as e: g = git.cmd.Git(f"{config['ansible_path']}")
logger.warn(e) logger.debug("Performing git pull")
notifications.send_webhook(config, "failure", "Failed to update Git repository") g.pull(rebase=True, env=dict(GIT_SSH_COMMAND=git_ssh_cmd))
logger.debug("Performing git submodule update")
g.submodule("update", "--init", env=dict(GIT_SSH_COMMAND=git_ssh_cmd))
except Exception as e:
logger.warn(e)
notifications.send_webhook(config, "failure", "Failed to update Git repository")
logger.info("Completed repository synchonization")
def commit_repository(config): def commit_repository(config):
""" """
Commit uncommitted changes to the Ansible git repository Commit uncommitted changes to the Ansible git repository
""" """
logger.info( lockfile = "/tmp/pvcbootstrapd-git.lock"
f"Committing changes to local configuration repository {config['ansible_path']}" lock = FileLock(lockfile)
) with lock:
logger.info(
try: f"Committing changes to local configuration repository {config['ansible_path']}"
g = git.cmd.Git(f"{config['ansible_path']}")
g.add("--all")
commit_env = {
"GIT_COMMITTER_NAME": "PVC Bootstrap",
"GIT_COMMITTER_EMAIL": "git@pvcbootstrapd",
}
g.commit(
"-m",
"Automated commit from PVC Bootstrap Ansible subsystem",
author="PVC Bootstrap <git@pvcbootstrapd>",
env=commit_env,
) )
notifications.send_webhook(config, "success", "Successfully committed to Git repository") try:
except Exception as e: g = git.cmd.Git(f"{config['ansible_path']}")
logger.warn(e) g.add("--all")
notifications.send_webhook(config, "failure", "Failed to commit to Git repository") commit_env = {
"GIT_COMMITTER_NAME": "PVC Bootstrap",
"GIT_COMMITTER_EMAIL": "git@pvcbootstrapd",
}
g.commit(
"-m",
"Automated commit from PVC Bootstrap Ansible subsystem",
author="PVC Bootstrap <git@pvcbootstrapd>",
env=commit_env,
)
notifications.send_webhook(config, "success", "Successfully committed to Git repository")
except Exception as e:
logger.warn(e)
notifications.send_webhook(config, "failure", "Failed to commit to Git repository")
def push_repository(config): def push_repository(config):
""" """
Push changes to the default remote Push changes to the default remote
""" """
logger.info( lockfile = "/tmp/pvcbootstrapd-git.lock"
f"Pushing changes from local configuration repository {config['ansible_path']}" lock = FileLock(lockfile)
) with lock:
logger.info(
try: f"Pushing changes from local configuration repository {config['ansible_path']}"
git_ssh_cmd = f"ssh -i {config['ansible_keyfile']} -o StrictHostKeyChecking=no" )
g = git.Repo(f"{config['ansible_path']}") try:
origin = g.remote(name="origin") git_ssh_cmd = f"ssh -i {config['ansible_keyfile']} -o StrictHostKeyChecking=no"
origin.push(env=dict(GIT_SSH_COMMAND=git_ssh_cmd)) g = git.Repo(f"{config['ansible_path']}")
notifications.send_webhook(config, "success", "Successfully pushed Git repository") origin = g.remote(name="origin")
except Exception as e: origin.push(env=dict(GIT_SSH_COMMAND=git_ssh_cmd))
logger.warn(e) notifications.send_webhook(config, "success", "Successfully pushed Git repository")
notifications.send_webhook(config, "failure", "Failed to push Git repository") except Exception as e:
logger.warn(e)
notifications.send_webhook(config, "failure", "Failed to push Git repository")
def load_cspec_yaml(config): def load_cspec_yaml(config):