blob: 7520f13faec5c02e3f489ede213458bb9d2d379d [file] [log] [blame]
"""Fetch and Deploy Cuttlefish images to specified GCE instance.
"""
import os
from cmdexec import Target
class DeployAction(object):
"""This class manages deploying cuttlefish image to remote server.
"""
def __init__(self):
pass
@staticmethod
def configure(parser):
"""Set up command line argument parser."""
parser.add_argument('--system_build', type=str, required=False,
default='latest',
help='Build number to fetch from Android Build server.')
parser.add_argument('--system_branch', type=str, required=False,
default='git_oc-gce-dev',
help='Android Build branch providing system images.')
parser.add_argument('--system_target', type=str, required=False,
default='cf_x86_phone-userdebug',
help='Android Build target providing system images.')
parser.add_argument('--kernel_build', type=str, required=False,
default='latest',
help='Build number to fetch from Android Build server.')
parser.add_argument('--kernel_branch', type=str, required=False,
default='kernel-n-dev-android-gce-3.18-x86_64',
help='Android Build branch providing kernel images.')
parser.add_argument('--kernel_target', type=str, required=False,
default='kernel',
help='Android Build target providing kernel images.')
parser.add_argument('-i', '--instance', type=str, required=True,
help='IP address of GCE instance.')
parser.add_argument('--tmpdir', type=str, required=False,
default='/tmp',
help='Temporary folder location.')
parser.add_argument('--keep', action='store_true',
help='Keep downloaded archive file after completion '
'(=do not clean up).')
parser.add_argument('--instance_folder', type=str, required=False,
default='/srv/cf',
help='Folder on the remote machine where images should be deployed.')
parser.add_argument('--force_update', type=str, required=False,
help='Comma separated list of artifacts to force update.')
def _to_build_id(self, selector):
if selector == 'latest':
return '--latest'
return '--bid='+selector
def execute(self, args):
"""Deploy Cuttlefish image to GCE."""
# Do all work in temp folder.
# Allow system to fail here with an exception.
os.chdir(args.tmpdir)
target_dir = '%s/%s' % (args.instance_folder, args.system_build)
temp_image = '%s-%s.zip' % (args.system_target, args.system_build)
try:
loc_tgt = Target.for_localhost()
ssh_tgt = Target.for_remote_host(args.instance)
# Install UNZIP if not found.
ssh_tgt.execute('[ -x /usr/bin/unzip ] || sudo apt install unzip')
system_build = self._to_build_id(args.system_build)
kernel_build = self._to_build_id(args.kernel_build)
force_update = []
if args.force_update:
force_update = args.force_update.split(',')
if not os.path.exists(temp_image):
loc_tgt.execute(
'/google/data/ro/projects/android/fetch_artifact '
'%s --branch=%s --target=%s '
'\'cf_x86_phone-img-*\' \'%s\'' %
(system_build, args.system_branch, args.system_target, temp_image))
if not os.path.exists('ramdisk.img'):
loc_tgt.execute(
'/google/data/ro/projects/android/fetch_artifact '
'%s --branch=%s --target=%s ramdisk.img' %
(system_build, args.system_branch, args.system_target))
if not os.path.exists('kernel'):
loc_tgt.execute(
'/google/data/ro/projects/android/fetch_artifact '
'%s --branch=%s --target=%s '
'bzImage kernel' %
(kernel_build, args.kernel_branch, args.kernel_target))
# Give user and libvirt access rights to specified folder.
# Remote directory appears as 'no access rights' except for included
# users.
ssh_tgt.execute('sudo mkdir -p %s' % target_dir)
ssh_tgt.execute('sudo chmod ugo= %s' % target_dir)
ssh_tgt.execute('sudo setfacl -m g:libvirt:rwx %s' % target_dir)
ssh_tgt.execute('sudo setfacl -m u:libvirt-qemu:rwx %s' % target_dir)
# Copy files to remote server location.
upload_list = [
'kernel',
'ramdisk.img',
temp_image
]
for file_name in upload_list:
update = file_name in force_update
if not update:
out = ssh_tgt.execute('test -f %s/%s; echo $?' % (target_dir, file_name))
update = out[0] == '1'
if update:
ssh_tgt.copy(file_name, target_dir)
ssh_tgt.execute('unzip -p \'%s/%s\' system.img > %s/system.img' %
(target_dir, temp_image, target_dir))
ssh_tgt.execute('setfacl -m g:libvirt:rw %s/*' % target_dir)
ssh_tgt.execute('setfacl -m u:libvirt-qemu:rw %s/*' % target_dir)
finally:
if not args.keep:
os.unlink(temp_image)
os.unlink('ramdisk.img')
os.unlink('kernel')