diff options
author | Lars Wirzenius <liw@liw.fi> | 2020-04-09 15:23:27 +0300 |
---|---|---|
committer | Lars Wirzenius <liw@liw.fi> | 2020-04-09 15:23:27 +0300 |
commit | 9f3e1dd3dc0ada615789000f385c9e52fe9a9879 (patch) | |
tree | c0ae6a82c528fc45f1c9188ded5f01fb3d004dc1 /contractor | |
parent | 5fca00b7aadbd5d3f52dca3fdc7f0c084d9e3136 (diff) | |
download | ick-contractor-9f3e1dd3dc0ada615789000f385c9e52fe9a9879.tar.gz |
Change: upload workspace, sources to worker image, not via worker
Diffstat (limited to 'contractor')
-rwxr-xr-x | contractor | 151 |
1 files changed, 102 insertions, 49 deletions
@@ -14,6 +14,26 @@ import cliapp import yaml +# The device in the manager VM for the workspace disk. +WS_DEV = '/dev/vdb' + + +# The worker VM image file on manager VM. +WORKER_IMG = 'worker.img' + + +# The temporary worker VM image file, used while worker VM is running. +TEMP_IMG = 'temp.img' + + +# The UID of the worker account, on the worker VM. +WORKER_UID = 1000 + + +# The GID of the worker account, on the worker VM. +WORKER_GID = 1000 + + class ExecResult: @@ -87,6 +107,13 @@ class ContractorApplication(cliapp.Application): self.error('could not upload image to worker') sys.exit(1) + self.verbose('setting up workspace on worker') + ws = bs.workspace() + source = bs.source() + if m.setup_workspace(ws, source).failed(): + self.error('could not set up workspace') + sys.exit(1) + self.verbose('starting worker') w = m.start_worker() if not w: @@ -103,19 +130,6 @@ class ContractorApplication(cliapp.Application): else: self.verbose('no packages to install') - ws = bs.workspace() - if ws and os.path.exists(ws): - self.verbose('upload saved workspace from {}'.format(ws)) - if w.upload_workspace(ws).failed(): - self.error('failed to upload workspace') - sys.exit(1) - - self.verbose('upload source code from{}'.format(bs.source())) - if w.upload_source(bs.source()).failed(): - self.error('failed to upload source') - sys.exit(1) - - # self.verbose('Running build commands') # o = self.on_worker( # 'worker', ['sh', '-euxc', build['build']], @@ -162,19 +176,21 @@ class ContractorApplication(cliapp.Application): def cmd_worker_image(self, args): img = args[0] - self.verbose('Copying VM image {} to manager VM as worker.img'.format(img)) - tgt = '{}:worker.img'.format(self.ssh_target()) + self.verbose( + 'Copying VM image {} to manager VM as {}'.format( + img, WORKER_IMG)) + tgt = '{}:{}'.format(self.ssh_target(), WORKER_IMG) argv = ['rsync', '-aHSs', '--', img, tgt] cliapp.runcmd(argv) def cmd_worker_start(self, args): self.verbose('mkfs on workspace disk') - o = self.on_manager(['sudo', 'mkfs', '-t', 'ext4', '/dev/vdb']) + o = self.on_manager(['sudo', 'mkfs', '-t', 'ext4', WS_DEV]) if o is None: self.error('Failed to mkfs workspace') sys.exit(1) - img = 'worker.img' + img = WORKER_IMG self.verbose('Creating worker VM using {} on manager VM'.format(img)) o = self.on_manager(['./create-vm', img]) if o is None: @@ -405,7 +421,7 @@ class Manager: self.virsh(['undefine', 'worker']) def upload_worker_image(self, filename): - return rsync(filename, '{}:worker.img'.format(self._target)) + return rsync(filename, '{}:{}'.format(self._target, WORKER_IMG)) def start_worker(self): if self.copy_worker_image().failed(): @@ -431,8 +447,8 @@ class Manager: '--cpu=host', '--import', '--os-variant=debian9', - '--disk=path=temp.img,cache=none', - '--disk=path=/dev/vdb,cache=none', + '--disk=path={},cache=none'.format(TEMP_IMG), + '--disk=path={},cache=none'.format(WS_DEV), '--network=network=default', '--graphics=spice', '--noautoconsole', @@ -444,8 +460,8 @@ class Manager: return self.wait_for_worker() def copy_worker_image(self): - self.ssh(['rm', '-f', 'temp.img']) - return self.ssh(['cp', 'worker.img', 'temp.img']) + self.ssh(['rm', '-f', TEMP_IMG]) + return self.ssh(['cp', WORKER_IMG, TEMP_IMG]) def get_cpu_count(self): er = self.ssh(['lscpu'], quiet=True) @@ -486,6 +502,70 @@ class Manager: return w time.sleep(2) + def setup_workspace(self, saved_workspace, source): + er = self.setup_helper(saved_workspace, source) + if er.failed(): + logging.error('Could not set up workspace') + self.umount(WS_DEV) + self.kpartx('-dsv') + return er + + def setup_helper(self, saved_workspace, source): + er = self.kpartx('-asv') + if er.failed(): + return er + + er = self.mount(WS_DEV) + if er.failed(): + return er + + er = self.ssh( + ['sudo', 'chown', '{}:{}'.format(WORKER_UID, WORKER_GID), + '/mnt']) + if er.failed(): + return er + + er = self.ssh( + ['sudo', 'install', '-d', '--owner={}'.format(WORKER_UID), + '--group={}'.format(WORKER_GID), '/mnt/src']) + if er.failed(): + return er + + if os.path.exists(saved_workspace): + er = rsync( + '{}/.'.format(saved_workspace), + '{}:/mnt/.'.format(self._target)) + if er.failed(): + return er + + er = rsync( + '{}/.'.format(source), + '{}:/mnt/src/.'.format(self._target)) + if er.failed(): + return er + + return er + + def kpartx(self, options): + er = self.ssh(['sudo', 'kpartx', options, TEMP_IMG]) + if er.failed(): + logging.error('Could not add partitions for worker image') + return er + + def mount(self, device): + er = self.ssh(['sudo', 'mount', device, '/mnt']) + if er.failed(): + logging.error('Could not mount device') + return er + + def umount(self, device): + er = self.ssh(['sudo', 'umount', device]) + if er.failed(): + logging.error('Could not mount device') + return er + + + class Worker: @@ -503,32 +583,5 @@ class Worker: ['sudo', 'DEBIAN_FRONTEND=noninteractive', 'apt-get', '-y', 'install'] + pkgs) - def upload_workspace(self, dirname): - return rsync( - '{}/.'.format(dirname), - '{}/workspace/.'.format(self._target)) - - def upload_source(self, dirname): - er = self.ssh(['sudo', 'chown', 'worker:worker', '/workspace']) - if er.failed(): - logging.error('Could not set /workspace ownership') - return er - - er = self.ssh( - ['sudo', 'install', '-d', '--owner=worker', '--group=worker', - '/workspace/src']) - if er.failed(): - logging.error('Could not create /workspace/src on worker') - return er - - return rsync( - '{}/.'.format(dirname), - '{}:/workspace/src/.'.format(self._target)) - - def create_dir(self, dirname): - return self.ssh( - ['sudo', 'install', '-d', '--owner=worker', '--group=worker', - dirname]) - ContractorApplication().run() |