#!/usr/bin/env python3 import logging import os import shutil import subprocess import sys import urllib.parse MAX_CLONE_TIME = 1 MAX_REMOVE_TIME = 60 MAX_PUSH_TIME = 60 GITLAB_DOMAIN = 'wmf-gitlab3.vm.liw.fi' GITLAB_PROJECT = 'liw' def runcmd(argv, timeout): logging.info('Running command: %r', argv) try: p = subprocess.run( argv, timeout=timeout, stdout=subprocess.PIPE, stderr=subprocess.PIPE) except subprocess.TimeoutExpired: logging.error('Command took too long (timeout %r)', timeout) return False except Exception as e: logging.error('Error during git clone: %s', str(e)) return False if p.returncode != 0: logging.error('Command failed: %r', argv) logging.error('exit code: %d', p.returncode) logging.error('stdout: %r', p.stdout) logging.error('stderr: %r', p.stderr) return False logging.info('Command succeeded') return True def clone(url, ref, dirname): if os.path.exists(dirname): logging.debug('Removing %s', dirname) shutil.rmtree(dirname) argv = ['git', 'clone', '-q', '-b', ref, url, dirname] return runcmd(argv, MAX_CLONE_TIME) def remove(token, gitlab_domain, gitlab_project, name): snippet = urllib.parse.quote('%s/%s.git' % (gitlab_project, name), safe='') url = 'https://%s/api/v4/projects/%s' % (gitlab_domain, snippet) argv = ['curl', '-HPRIVATE-TOKEN: %s' % token, '-X', 'DELETE', url] return runcmd(argv, MAX_REMOVE_TIME) def push(dirname, gitlab_domain, gitlab_project, name): logging.info('Pushing %s to %s as %s', dirname, gitlab_domain, name) url = 'ssh://git@%s/%s/%s.git' % (gitlab_domain, gitlab_project, name) logging.debug('Pushing to repo URL: %s', url) argv = ['git', 'push', url, 'master'] return runcmd(argv, MAX_PUSH_TIME) def main(): token = sys.argv[1] logging.basicConfig( filename='vcsworker.log', level=logging.DEBUG, format='%(levelname)s %(message)s') logging.info('VCS worker starts') spec = { 'git': 'git://git.liw.fi/heippa', 'ref': 'master', 'gitlab': 'hithere2', } tmpdir = 'vcstmp' logging.info('Workspace: %s', tmpdir) if not os.path.exists(tmpdir): os.makedirs(tmpdir) url = spec['git'] ref = spec['ref'] name = spec['gitlab'] dirname = os.path.join(tmpdir, name) if clone(url, ref, dirname): if remove(token, GITLAB_DOMAIN, GITLAB_PROJECT, name): if push(dirname, GITLAB_DOMAIN, GITLAB_PROJECT, name): logging.info('Repository copied successfully') return logging.error('Something went wrong when copying repository') main()