net-backup/app/repo.py

105 lines
3.7 KiB
Python

from git import Repo, InvalidGitRepositoryError, Git, rmtree
from config import cfg
import logging as log
from datetime import datetime
import os
import shutil
import stat
def check_remote_repo(repo: Repo):
log.info("check remote repo ")
if cfg.git.branch not in [r.name for r in repo.remotes]:
repo.create_remote(
name=cfg.git.branch,
url=f"{cfg.git.protocol}://{cfg.git.username}:"
f"{cfg.git.token}@{cfg.git.remote}",
)
log.info("set remote repo %r", cfg.git.branch)
remote = repo.remote(name=cfg.git.branch)
remote.fetch()
repo.git.merge(f"{cfg.git.branch}/{cfg.git.branch}")
log.info(
"merge from remote repo ",
)
else:
remote = repo.remote(name=cfg.git.branch)
remote.set_url(
f"{cfg.git.protocol}://{cfg.git.username}:"
f"{cfg.git.token}@{cfg.git.remote}"
)
log.info("update remote repo url %r", cfg.git.branch)
def check_bcp_repo(path: str = cfg.bcp.dir) -> None:
Git().config("--global", "--add", "safe.directory", path)
log.info("check local repo %r", path)
try:
repo = Repo(path)
log.info("local repo exists %r", path)
if cfg.git.push:
check_remote_repo(repo)
except InvalidGitRepositoryError:
repo = Repo.init(path=path, initial_branch=cfg.git.branch)
log.info("init repo in %r", path)
with repo.config_writer() as config:
config.set_value("user", "name", cfg.git.user)
config.set_value("user", "email", cfg.git.mail)
if cfg.git.push:
check_remote_repo(repo)
except Exception as e:
log.warning("Error: %r", e)
def add_file_and_commit(file_name: str, file_folder: str) -> None:
current_time = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
repo = Repo(cfg.bcp.dir)
if file_folder is not None:
file_name = file_folder + "/" + file_name
if file_name in repo.untracked_files:
repo.git.add(file_name)
repo.index.commit("add %s %s" % (file_name, current_time))
log.info("%r added in repo", file_name)
if bool(repo.git.diff(file_name)):
repo.index.add([file_name])
repo.index.commit("update %s %s" % (file_name, current_time))
log.info("change in %r commited", file_name)
else:
log.info("no changed in file %r", file_name)
def push_to_remote():
repo = Repo(cfg.bcp.dir)
remote = repo.remote(name=cfg.git.branch)
remote.push(refspec=f"{cfg.git.branch}:{cfg.git.branch}")
log.info("push to remote repo %r", cfg.git.branch)
def delete_all_files(path: str = cfg.bcp.dir) -> None:
if os.path.exists(path) and os.path.isdir(path):
for filename in os.listdir(path):
file_path = os.path.join(path, filename)
if filename == ".git":
log.info('start remove read only for .git')
for root, dirs, files in os.walk(file_path):
os.chmod(root, stat.S_IWRITE)
for file in files:
d_file_path = os.path.join(root, file)
os.chmod(d_file_path, stat.S_IWRITE)
log.info('end remove read only for .git')
try:
if os.path.isfile(file_path) or os.path.islink(file_path):
os.remove(file_path)
log.info("Successfully deleting: %s", file_path)
elif os.path.isdir(file_path):
shutil.rmtree(file_path)
log.info("Successfully deleting: %s", file_path)
except Exception as e:
log.warning("Error deleting %s: %s", file_path, e)