def run(self, path_arg=None): if self.config.desktop: print_warning('Skipping install, running in desktop mode') return elif self.config.container_mode: print_warning('Skipping install, running in container mode') return cwd = '.' if path_arg: click = os.path.basename(path_arg) click_path = path_arg else: click = self.config.get_click_filename() click_path = os.path.join(self.config.build_dir, click) cwd = self.config.build_dir if self.config.ssh: command = 'scp {} phablet@{}:/home/phablet/'.format(click_path, self.config.ssh) run_subprocess_check_call(command, cwd=cwd, shell=True) else: self.device.check_any_attached() if self.config.device_serial_number: command = 'adb -s {} push {} /home/phablet/'.format(self.config.device_serial_number, click_path) else: self.device.check_multiple_attached() command = 'adb push {} /home/phablet/'.format(click_path) run_subprocess_check_call(command, cwd=cwd, shell=True) self.device.run_command('pkcon install-local --allow-untrusted /home/phablet/{}'.format(click), cwd=cwd)
def run(self, path_arg=""): if not self.config.lib_configs: print_warning('No libraries defined.') single_lib = path_arg found = False for lib in self.config.lib_configs: if not single_lib or single_lib == lib.name: print_info("Building {}".format(lib.name)) found = True lib.container_mode = self.config.container_mode lib.docker_image = self.config.docker_image lib.build_arch = self.config.build_arch lib.container = Container(lib, lib.name) lib.container.setup_dependencies() try: os.makedirs(lib.build_dir) except FileExistsError: pass except Exception: print_warning('Failed to create the build directory: {}'.format(str(sys.exc_info()[0]))) if lib.prebuild: run_subprocess_check_call(lib.prebuild, cwd=self.config.cwd, shell=True) self.build(lib) if lib.postbuild: run_subprocess_check_call(lib.postbuild, cwd=lib.build_dir, shell=True) if single_lib and not found: raise ValueError('Cannot build unknown library {}. You may add it to the clickable.json'.format(single_lib))
def __init__(self, config, name=None): self.config = config self.clickable_dir = '.clickable/{}'.format(self.config.build_arch) if name: self.clickable_dir = '{}/{}'.format(self.clickable_dir, name) self.docker_name_file = '{}/name.txt'.format(self.clickable_dir) self.docker_file = '{}/Dockerfile'.format(self.clickable_dir) if not self.config.container_mode: if self.config.lxd: print_warning( 'Use of lxd is deprecated and will be removed in a future version' ) check_command('usdk-target') else: check_command('docker') self.docker_image = self.config.docker_image self.base_docker_image = self.docker_image if self.docker_image in self.config.container_list: self.base_docker_image = self.docker_image if os.path.exists(self.docker_name_file): self.restore_cached_container()
def run(self, path_arg=""): single_lib = path_arg found = False for lib in self.config.lib_configs: if not single_lib or single_lib == lib.name: print_info("Cleaning {}".format(lib.name)) found = True if os.path.exists(lib.build_dir): try: shutil.rmtree(lib.build_dir) except Exception: cls, value, traceback = sys.exc_info() if cls == OSError and 'No such file or directory' in str( value ): # TODO see if there is a proper way to do this pass # Nothing to do here, the directory didn't exist else: print_warning( 'Failed to clean the build directory: {}: {}'. format(type, value)) else: print_info( 'Nothing to clean. Path does not exist: {}'.format( lib.build_dir)) if single_lib and not found: raise ValueError( 'Cannot clean unknown library {}. You may add it to the clickable.json' .format(single_lib))
def __init__(self, config): self.config = config self.clickableDir = '.clickable/{}'.format(self.config.build_arch) self.dockerNameFile = '{}/name.txt'.format(self.clickableDir) self.dockerFile = '{}/Dockerfile'.format(self.clickableDir) if not self.config.container_mode: if self.config.lxd: print_warning('Use of lxd is deprecated and will be removed in a future version') check_command('usdk-target') else: check_command('docker') self.docker_image = self.config.docker_image self.base_docker_image = self.docker_image if 'clickable/ubuntu-sdk' in self.docker_image: if self.config.use_nvidia: self.docker_image += '-nvidia' check_command('nvidia-docker') self.base_docker_image = self.docker_image if os.path.exists(self.dockerNameFile): with open(self.dockerNameFile, 'r') as f: self.docker_image = f.read().strip()
def load_config(self, file='clickable.json'): if os.path.isfile(os.path.join(self.cwd, file)): with open(os.path.join(self.cwd, file), 'r') as f: config_json = {} try: config_json = json.load(f) except ValueError: raise ValueError( 'Failed reading "{}", it is not valid json'.format( file)) for key in self.config: value = config_json.get(key, None) if value: self.config[key] = value else: if not self.skip_detection: print_warning( 'No clickable.json was found, using defaults and cli args') for key in self.required: if not getattr(self, key): raise ValueError( '"{}" is empty in the config file'.format(key)) self.dir = os.path.abspath(self.dir)
def run(self, path_arg=None): devices = self.device.detect_attached() if len(devices) == 0: print_warning('No attached devices') else: for device in devices: print_info(device)
def devices(self): devices = self.detect_devices() if len(devices) == 0: print_warning('No attached devices') else: for device in devices: print_info(device)
def __init__(self, config, device_serial_number=None, click_output=None): self.cwd = os.getcwd() self.config = config self.temp = os.path.join(self.config.dir, 'tmp') self.device_serial_number = device_serial_number if type(self.device_serial_number) == list and len( self.device_serial_number) > 0: self.device_serial_number = self.device_serial_number[0] self.build_arch = self.config.arch if self.config.template == self.config.PURE_QML_QMAKE or self.config.template == self.config.PURE_QML_CMAKE or self.config.template == self.config.PURE: self.build_arch = 'armhf' if self.config.desktop: self.build_arch = 'amd64' if self.config.arch == 'all': self.build_arch = 'armhf' if self.config.desktop: self.build_arch = 'amd64' if not self.config.container_mode: if self.config.ssh: self.check_command('ssh') self.check_command('scp') else: self.check_command('adb') if 'SNAP' in os.environ and os.environ['SNAP']: # If running as a snap, trick usdk-target into thinking its not in a snap del os.environ['SNAP'] if not self.config.container_mode: if self.config.chroot: print_warning( 'Use of chroots are deprecated and will be removed in a future version' ) self.check_command('click') elif self.config.lxd: print_warning( 'Use of lxd is deprecated and will be removed in a future version' ) self.check_command('usdk-target') else: self.check_command('docker') self.docker_image = 'clickable/ubuntu-sdk:{}-{}'.format( self.config.sdk.replace('ubuntu-sdk-', ''), self.build_arch) if self.config.use_nvidia: self.docker_image += '-nvidia' self.check_command('nvidia-docker') self.base_docker_image = self.docker_image if os.path.exists('.clickable/name.txt'): with open('.clickable/name.txt', 'r') as f: self.docker_image = f.read().strip()
def clean_dir(self, path): if os.path.exists(path) and os.path.isdir(path): shutil.rmtree(path) try: os.makedirs(path) except FileExistsError: pass except Exception: print_warning('Failed to create dir ({}): {}'.format(path, str(sys.exc_info()[0])))
def clean_dir(self, path): if os.path.exists(path) and os.path.isdir(path): shutil.rmtree(path) try: os.makedirs(path) except FileExistsError: pass except Exception: print_warning('Failed to create dir ({}): {}'.format( path, str(sys.exc_info()[0])))
def make_install(self): if os.path.exists(self.temp) and os.path.isdir(self.temp): shutil.rmtree(self.temp) try: os.makedirs(self.temp) except FileExistsError: print_warning('Failed to create temp dir, already exists') except Exception: print_warning('Failed to create temp dir ({}): {}'.format( self.temp, str(sys.exc_info()[0])))
def kill(self): if self.config.desktop: print_warning('Skipping kill, running in desktop mode') return elif self.config.container_mode: print_warning('Skipping kill, running in container mode') return if self.config.kill: try: self.run_device_command('pkill {}'.format(self.config.kill)) except Exception: pass # Nothing to do, the process probably wasn't running
def kill(self): if self.config.desktop: print_warning('Skipping kill, running in desktop mode') return elif self.config.container_mode: print_warning('Skipping kill, running in container mode') return if self.config.kill: try: # Enclose first character in square brackets to prevent # spurious error when running `pkill -f` over `adb` kill = '[' + self.config.kill[:1] + ']' + self.config.kill[1:] self.device.run_command('pkill -f \\"{}\\"'.format(kill)) except Exception: pass # Nothing to do, the process probably wasn't running
def logs(self): if self.config.desktop: print_warning('Skipping logs, running in desktop mode') return elif self.config.container_mode: print_warning('Skipping logs, running in container mode') return log = '~/.cache/upstart/application-click-{}_{}_{}.log'.format( self.find_package_name(), self.find_app_name(), self.find_version()) if self.config.log: log = self.config.log self.run_device_command('tail -f {}'.format(log))
def run(self, path_arg=None): try: os.makedirs(self.config.build_dir) except FileExistsError: pass except Exception: print_warning('Failed to create the build directory: {}'.format(str(sys.exc_info()[0]))) self.container.setup_dependencies() if self.config.prebuild: run_subprocess_check_call(self.config.prebuild, cwd=self.config.cwd, shell=True) self.build() if self.config.postbuild: run_subprocess_check_call(self.config.postbuild, cwd=self.config.build_dir, shell=True)
def _build(self): # Clear out prefix directory # IK this is against DRY, but I copied this code from MakeClickable.make_install if os.path.exists(self.config.dir) and os.path.isdir(self.temp): shutil.rmtree(self.config.dir) try: os.makedirs(self.config.dir) except FileExistsError: print_warning('Failed to create temp dir, already exists') except Exception: print_warning('Failed to create temp dir ({}): {}'.format(self.temp, str(sys.exc_info()[0]))) self.run_container_command('cmake {} -DCMAKE_INSTALL_PREFIX={}'.format(self._dirs['make'], self._dirs['build'])) super(CMakeClickable, self)._build()
def run(self, path_arg=None): if self.config.desktop: print_warning('Skipping logs, running in desktop mode') return elif self.config.container_mode: print_warning('Skipping logs, running in container mode') return log = '~/.cache/upstart/application-click-{}_{}_{}.log'.format( self.config.find_package_name(), self.config.find_app_name(), self.config.find_version() ) if self.config.log: log = self.config.log self.device.run_command('tail -f {}'.format(log))
def cleanup_config(self): self.make_args = merge_make_jobs_into_args(make_args=self.make_args, make_jobs=self.make_jobs) if self.config['dir']: self.config['build_dir'] = self.config['dir'] print_warning('The param "dir" in your clickable.json is deprecated and will be removed in a future version of Clickable. Use "build_dir" instead!') for key in self.flexible_lists: self.config[key] = flexible_string_to_list(self.config[key]) if self.config['docker_image']: self.custom_docker_image = True if self.config['dependencies']: if self.config['specificDependencies']: self.config['dependencies_build'] += self.config['dependencies'] else: self.config['dependencies_target'] += self.config['dependencies'] print_warning('The params "dependencies" (and possibly "specificDependencies") in your clickable.json are deprecated and will be removed in a future version of Clickable. Use "dependencies_build" and "dependencies_target" instead!')
def run(self, path_arg=None): if os.path.exists(self.config.build_dir): try: shutil.rmtree(self.config.build_dir) except Exception: cls, value, traceback = sys.exc_info() if cls == OSError and 'No such file or directory' in str(value): # TODO see if there is a proper way to do this pass # Nothing to do here, the directory didn't exist else: print_warning('Failed to clean the build directory: {}: {}'.format(type, value)) if os.path.exists(self.config.install_dir): try: shutil.rmtree(self.config.install_dir) except Exception: cls, value, traceback = sys.exc_info() if cls == OSError and 'No such file or directory' in str(value): # TODO see if there is a proper way to do this pass # Nothing to do here, the directory didn't exist else: print_warning('Failed to clean the temp directory: {}: {}'.format(type, value))
def build(self): try: os.makedirs(self.config.dir) except Exception: print_warning('Failed to create the build directory: {}'.format( str(sys.exc_info()[0]))) self.setup_dependencies() if self.config.prebuild: subprocess.check_call(self.config.prebuild, cwd=self.cwd, shell=True) self._build() if self.config.postbuild: subprocess.check_call(self.config.postbuild, cwd=self.config.dir, shell=True)
def run(self, path_arg=None): if os.path.exists(self.config.build_dir): try: shutil.rmtree(self.config.build_dir) except Exception: cls, value, traceback = sys.exc_info() if cls == OSError and 'No such file or directory' in str(value): # TODO see if there is a proper way to do this pass # Nothing to do here, the directory didn't exist else: print_warning('Failed to clean the build directory: {}: {}'.format(type, value)) if os.path.exists(self.config.temp): try: shutil.rmtree(self.config.temp) except Exception: cls, value, traceback = sys.exc_info() if cls == OSError and 'No such file or directory' in str(value): # TODO see if there is a proper way to do this pass # Nothing to do here, the directory didn't exist else: print_warning('Failed to clean the temp directory: {}: {}'.format(type, value))
def run(self, path_arg=None): if self.config.desktop: print_warning('Skipping install, running in desktop mode') return elif self.config.container_mode: print_warning('Skipping install, running in container mode') return cwd = '.' if path_arg: click = os.path.basename(path_arg) click_path = path_arg else: click = '{}_{}_{}.click'.format(self.config.find_package_name(), self.config.find_version(), self.config.arch) click_path = os.path.join(self.config.dir, click) cwd = self.config.dir if self.config.ssh: command = 'scp {} phablet@{}:/home/phablet/'.format( click_path, self.config.ssh) run_subprocess_check_call(command, cwd=cwd, shell=True) else: self.device.check_any_attached() if self.config.device_serial_number: command = 'adb -s {} push {} /home/phablet/'.format( self.config.device_serial_number, click_path) else: self.device.check_multiple_attached() command = 'adb push {} /home/phablet/'.format(click_path) run_subprocess_check_call(command, cwd=cwd, shell=True) self.device.run_command( 'pkcon install-local --allow-untrusted /home/phablet/{}'.format( click), cwd=cwd)
def run(self, path_arg=None): try: os.makedirs(self.config.dir) except FileExistsError: pass except Exception: print_warning('Failed to create the build directory: {}'.format( str(sys.exc_info()[0]))) self.container.setup_dependencies() if self.config.prebuild: subprocess.check_call(self.config.prebuild, cwd=self.config.cwd, shell=True) self.build() if self.config.postbuild: subprocess.check_call(self.config.postbuild, cwd=self.config.dir, shell=True)
def run_device_command(self, command, cwd=None): if self.config.container_mode: print_warning('Skipping device command, running in container mode') return if not cwd: cwd = self.config.dir wrapped_command = '' if self.config.ssh: wrapped_command = 'echo "{}" | ssh phablet@{}'.format( command, self.config.ssh) else: self.check_any_devices() if self.device_serial_number: wrapped_command = 'adb -s {} shell "{}"'.format( self.device_serial_number, command) else: self.check_multiple_devices() wrapped_command = 'adb shell "{}"'.format(command) subprocess.check_call(wrapped_command, cwd=cwd, shell=True)
def run(self, path_arg=""): if not self.config.lib_configs: print_warning('No libraries defined.') single_lib = path_arg found = False for lib in self.config.lib_configs: if not single_lib or single_lib == lib.name: print_info("Building {}".format(lib.name)) found = True lib.container_mode = self.config.container_mode lib.docker_image = self.config.docker_image lib.build_arch = self.config.build_arch try: os.makedirs(lib.build_dir) except FileExistsError: pass except Exception: print_warning('Failed to create the build directory: {}'.format(str(sys.exc_info()[0]))) container = Container(lib) container.setup_dependencies() if lib.prebuild: run_subprocess_check_call(lib.prebuild, cwd=self.config.cwd, shell=True) self.build(lib, container) if lib.postbuild: run_subprocess_check_call(lib.postbuild, cwd=lib.build_dir, shell=True) if single_lib and not found: raise ValueError('Cannot build unknown library {}. You may add it to the clickable.json'.format(single_lib))
def clean(self): if os.path.exists(self.config.dir): try: shutil.rmtree(self.config.dir) except Exception: type, value, traceback = sys.exc_info() if type == OSError and 'No such file or directory' in value: # TODO see if there is a proper way to do this pass # Nothing to do here, the directory didn't exist else: print_warning( 'Failed to clean the build directory: {}: {}'.format( type, value)) if os.path.exists(self.temp): try: shutil.rmtree(self.temp) except Exception: type, value, traceback = sys.exc_info() if type == OSError and 'No such file or directory' in value: # TODO see if there is a proper way to do this pass # Nothing to do here, the directory didn't exist else: print_warning( 'Failed to clean the temp directory: {}: {}'.format( type, value))
def run(self, path_arg=""): single_lib = path_arg found = False for lib in self.config.lib_configs: if not single_lib or single_lib == lib.name: print_info("Cleaning {}".format(lib.name)) found = True if os.path.exists(lib.build_dir): try: shutil.rmtree(lib.build_dir) except Exception: cls, value, traceback = sys.exc_info() if cls == OSError and 'No such file or directory' in str(value): # TODO see if there is a proper way to do this pass # Nothing to do here, the directory didn't exist else: print_warning('Failed to clean the build directory: {}: {}'.format(type, value)) else: print_info('Nothing to clean. Path does not exist: {}'.format(lib.build_dir)) if single_lib and not found: raise ValueError('Cannot clean unknown library {}. You may add it to the clickable.json'.format(single_lib))
def run(self, path_arg=None): if self.config.lxd: raise Exception('Using lxd for desktop mode is not supported') clean = CleanCommand(self.config) clean.run() build = BuildCommand(self.config) build.run() desktop_path = None hooks = self.config.get_manifest().get('hooks', {}) app = self.config.find_app_name() if app: if app in hooks and 'desktop' in hooks[app]: desktop_path = hooks[app]['desktop'] else: for key, value in hooks.items(): if 'desktop' in value: desktop_path = value['desktop'] break if not desktop_path: raise Exception( 'Could not find desktop file for app "{}"'.format(app)) desktop_path = os.path.join(self.config.temp, desktop_path) if not os.path.exists(desktop_path): raise Exception( 'Could not desktop file does not exist: "{}"'.format( desktop_path)) execute = None with open(desktop_path, 'r') as desktop_file: lines = desktop_file.readlines() for line in lines: if line.startswith('Exec='): execute = line.replace('Exec=', '') break if not execute: raise Exception('No "Exec" line found in the desktop file') else: execute = execute.strip() # Inspired by https://stackoverflow.com/a/1160227 xauth = '/tmp/.docker.xauth' with open(xauth, 'a'): os.utime(xauth, None) self.container.check_docker() share = '/tmp/clickable/share' if not os.path.isdir(share): os.makedirs(share) cache = '/tmp/clickable/cache' if not os.path.isdir(cache): os.makedirs(cache) config = '/tmp/clickable/config' if not os.path.isdir(config): os.makedirs(config) volumes = '-v {}:{} -v /tmp/.X11-unix:/tmp/.X11-unix -v {}:{} -v {}:/tmp/.local/share -v {}:/tmp/.cache -v {}:/tmp/.config'.format( self.config.cwd, self.config.cwd, xauth, xauth, share, cache, config, ) if self.config.use_nvidia: volumes += ' -v /dev/snd/pcmC2D0c:/dev/snd/pcmC2D0c -v /dev/snd/controlC2:/dev/snd/controlC2 --device /dev/snd' lib_path = ':'.join([ os.path.join(self.config.temp, 'lib/x86_64-linux-gnu'), os.path.join(self.config.temp, 'lib'), '/usr/local/nvidia/lib', '/usr/local/nvidia/lib64', ]) path = ':'.join([ '/usr/local/nvidia/bin', '/bin', '/usr/bin', os.path.join(self.config.temp, 'bin'), os.path.join(self.config.temp, 'lib/x86_64-linux-gnu/bin'), self.config.temp, ]) environment = '-e XAUTHORITY=/tmp/.docker.xauth -e DISPLAY={} -e QML2_IMPORT_PATH={} -e LD_LIBRARY_PATH={} -e PATH={} -e HOME=/tmp -e OXIDE_NO_SANDBOX=1'.format( os.environ['DISPLAY'], lib_path, lib_path, path, ) if execute.startswith('webapp-container'): # This is needed for the webapp-container, so only do it for this case volumes = '{} -v /etc/passwd:/etc/passwd'.format(volumes) environment = '{} -e APP_ID={}'.format( environment, self.config.find_package_name()) go_config = '' if self.config.gopath: go_config = '-v {}:/gopath -e GOPATH=/gopath'.format( self.config.gopath) run_xhost = False try: check_command('xhost') run_xhost = True except Exception: # TODO catch a specific Exception print_warning('xhost not installed, desktop mode may fail') run_xhost = False if run_xhost: subprocess.check_call(shlex.split('xhost +local:docker')) command = '{} run {} {} {} -w {} -u {} --rm -i {} bash -c "{}"'.format( 'nvidia-docker' if self.config.use_nvidia else 'docker', volumes, go_config, environment, self.config.temp, os.getuid(), self.container.docker_image, execute, ) subprocess.check_call(shlex.split(command), cwd=self.config.temp)
def print_instructions(self): instructions = self.query.get_user_instructions() if instructions is not None: print_warning(instructions)
def allow_docker_to_connect_to_xserver(self): if self.is_xhost_installed(): subprocess.check_call(shlex.split('xhost +local:docker')) else: print_warning('xhost not installed, desktop mode may fail')