def _inject_snap(self, name): session = requests_unixsocket.Session() # Cf. https://github.com/snapcore/snapd/wiki/REST-API#get-v2snapsname # TODO use get_local_snap info from the snaps module. slug = 'snaps/{}'.format(parse.quote(name, safe='')) api = snaps.get_snapd_socket_path_template().format(slug) try: json = session.request('GET', api).json() except requests.exceptions.ConnectionError as e: raise SnapdError( 'Error connecting to {}'.format(api)) from e if json['type'] == 'error': raise SnapdError( 'Error querying {!r} snap: {}'.format( name, json['result']['message'])) id = json['result']['id'] # Lookup confinement to know if we need to --classic when installing is_classic = json['result']['confinement'] == 'classic' # Revisions are unique, so we don't need to know the channel rev = json['result']['revision'] if not rev.startswith('x'): self._inject_assertions('{}_{}.assert'.format(name, rev), [ ['account-key', 'public-key-sha3-384={}'.format(_STORE_KEY)], ['snap-declaration', 'snap-name={}'.format(name)], ['snap-revision', 'snap-revision={}'.format(rev), 'snap-id={}'.format(id)], ]) # https://github.com/snapcore/snapd/blob/master/snap/info.go # MountFile filename = '{}_{}.snap'.format(name, rev) # https://github.com/snapcore/snapd/blob/master/dirs/dirs.go # CoreLibExecDir installed = os.path.join(os.path.sep, 'var', 'lib', 'snapd', 'snaps', filename) filepath = os.path.join(self.tmp_dir, filename) if rev.startswith('x'): logger.info('Making {} user-accessible'.format(filename)) check_call(['sudo', 'cp', installed, filepath]) check_call(['sudo', 'chown', str(os.getuid()), filepath]) else: shutil.copyfile(installed, filepath) container_filename = os.path.join(os.sep, 'run', filename) self._push_file(filepath, container_filename) logger.info('Installing {}'.format(container_filename)) cmd = ['snap', 'install', container_filename] if rev.startswith('x'): cmd.append('--dangerous') if is_classic: cmd.append('--classic') self._container_run(cmd)
def _inject_snap(self, name: str, tmp_dir: str): session = requests_unixsocket.Session() # Cf. https://github.com/snapcore/snapd/wiki/REST-API#get-v2snapsname # TODO use get_local_snap info from the snaps module. slug = 'snaps/{}'.format(parse.quote(name, safe='')) api = snaps.get_snapd_socket_path_template().format(slug) try: json = session.request('GET', api).json() except requests.exceptions.ConnectionError as e: raise SnapdError('Error connecting to {}'.format(api)) from e if json['type'] == 'error': raise SnapdError('Error querying {!r} snap: {}'.format( name, json['result']['message'])) id = json['result']['id'] # Lookup confinement to know if we need to --classic when installing is_classic = json['result']['confinement'] == 'classic' # If the server has a different arch we can't inject local snaps target_arch = self._project_options.target_arch if (target_arch and target_arch != self._get_container_arch()): channel = json['result']['channel'] return self._install_snap(name, channel, is_classic=is_classic) # Revisions are unique, so we don't need to know the channel rev = json['result']['revision'] # https://github.com/snapcore/snapd/blob/master/snap/info.go # MountFile filename = '{}_{}.snap'.format(name, rev) # https://github.com/snapcore/snapd/blob/master/dirs/dirs.go # CoreLibExecDir installed = os.path.join(os.path.sep, 'var', 'lib', 'snapd', 'snaps', filename) filepath = os.path.join(tmp_dir, filename) if rev.startswith('x'): logger.info('Making {} user-accessible'.format(filename)) subprocess.check_call(['sudo', 'cp', installed, filepath]) subprocess.check_call( ['sudo', 'chown', str(os.getuid()), filepath]) else: shutil.copyfile(installed, filepath) if self._is_same_snap(filepath, name): logger.debug('Not re-injecting same version of {!r}'.format(name)) return if not rev.startswith('x'): self._inject_assertions('{}_{}.assert'.format(name, rev), [ ['account-key', 'public-key-sha3-384={}'.format(_STORE_KEY)], ['snap-declaration', 'snap-name={}'.format(name)], [ 'snap-revision', 'snap-revision={}'.format(rev), 'snap-id={}'.format(id) ], ], tmp_dir) container_filename = os.path.join(os.sep, 'run', filename) self._push_file(filepath, container_filename) self._install_snap(container_filename, is_dangerous=rev.startswith('x'), is_classic=is_classic)