def _decode(self, data, output): def move(n): """Move ``n`` bytes from ``data`` to ``output``.""" nonlocal data ASSERT.greater_or_equal(self._chunk_remaining, n) output.append(data[:n]) data = data[n:] self._chunk_remaining -= n def expect(pattern): """Drop ``pattern`` prefix from ``data``.""" nonlocal data n = min(len(pattern), len(data)) ASSERT.equal(pattern[:n], data[:n]) data = data[n:] return n while data: if self._chunk_remaining > 0: move(min(self._chunk_remaining, len(data))) continue if self._chunk_remaining == 0: self._chunk_remaining -= expect(b'\r\n') continue if self._chunk_remaining == -1: self._chunk_remaining -= expect(b'\n') continue match = self._CRLF_PATTERN.search(data) if not match: self._append(data) match = self._CRLF_PATTERN.search(self._buffer[:self._pos]) if not match: break data = self._reset() chunk_size = data[:match.start()] if self._pos > 0: self._append(chunk_size) chunk_size = self._reset() # TODO: Handle parameters (stuff after ';'). chunk_size = int( bytes(chunk_size).split(b';', maxsplit=1)[0], base=16, ) if chunk_size == 0: # TODO: Handle trailers. self.eof = True else: ASSERT.false(self.eof) data = data[match.end():] self._chunk_remaining = chunk_size if self.eof: ASSERT.empty(data)
def __post_init__(self): validate_app_name(self.name) if self.service_section is None: ASSERT.not_empty(self.exec) ASSERT.in_(self.type, _SERVICE_TYPES) ASSERT.in_(self.kill_mode, _KILL_MODES) else: ASSERT.empty(self.exec) ASSERT.none(self.type) ASSERT.none(self.kill_mode)
def cmd_setup_base_rootfs(image_rootfs_path, prune_stash_path): """Set up base rootfs. Changes from 18.04 to 20.04. * /lib is now a symlink to /usr/lib. * system.slice has been removed: https://github.com/systemd/systemd/commit/d8e5a9338278d6602a0c552f01f298771a384798 """ ASSERT.predicate(image_rootfs_path, Path.is_dir) oses.assert_root_privilege() # Remove unneeded files. for dir_relpath in ( 'usr/share/doc', 'usr/share/info', 'usr/share/man', 'var/cache', 'var/lib/apt', 'var/lib/dpkg', ): dir_path = image_rootfs_path / dir_relpath if dir_path.is_dir(): if prune_stash_path: dst_path = ASSERT.not_predicate( prune_stash_path / dir_relpath, g1.files.lexists ) dst_path.mkdir(mode=0o755, parents=True, exist_ok=True) _move_dir_content(dir_path, dst_path) else: _clear_dir_content(dir_path) # Remove certain config files. for path in ( # Remove this so that systemd-nspawn may set the hostname. image_rootfs_path / 'etc/hostname', # systemd-nspawn uses machine-id to link journal. image_rootfs_path / 'etc/machine-id', image_rootfs_path / 'var/lib/dbus/machine-id', # debootstrap seems to copy this file from the build machine, # which is not the host machine that runs this image; so let's # replace this with a generic stub. image_rootfs_path / 'etc/resolv.conf', image_rootfs_path / 'run/systemd/resolve/stub-resolv.conf', ): LOG.info('remove: %s', path) g1.files.remove(path) # Replace certain config files. for path, content in ( (image_rootfs_path / 'etc/default/locale', _LOCALE), (image_rootfs_path / 'etc/resolv.conf', _RESOLV_CONF), (image_rootfs_path / 'etc/systemd/journald.conf', _JOURNALD_CONF), ): LOG.info('replace: %s', path) path.write_text(content) # Remove unneeded unit files. base_units = set(_BASE_UNITS) for unit_dir_path in ( image_rootfs_path / 'etc/systemd/system', image_rootfs_path / 'usr/lib/systemd/system', ): if not unit_dir_path.exists(): continue LOG.info('clean up unit files in: %s', unit_dir_path) for unit_path in unit_dir_path.iterdir(): if unit_path.name in base_units: base_units.remove(unit_path.name) continue # There should have no duplicated units, right? ASSERT.not_in(unit_path.name, _BASE_UNITS) LOG.info('remove: %s', unit_path) g1.files.remove(unit_path) ASSERT.empty(base_units) # Create unit files. for unit_dir_path, unit_files in ( (image_rootfs_path / 'etc/systemd/system', _ETC_UNIT_FILES), (image_rootfs_path / 'usr/lib/systemd/system', _LIB_UNIT_FILES), ): for unit_file in unit_files: ASSERT.predicate(unit_dir_path, Path.is_dir) path = unit_dir_path / unit_file.relpath LOG.info('create: %s', path) if unit_file.kind is _UnitFile.Kinds.DIRECTORY: path.mkdir(mode=0o755) elif unit_file.kind is _UnitFile.Kinds.FILE: path.write_text(unit_file.content) path.chmod(0o644) else: ASSERT.is_(unit_file.kind, _UnitFile.Kinds.SYMLINK) path.symlink_to(unit_file.content) bases.chown_root(path) # Create ``pod-exit`` script and exit status directory. pod_exit_path = image_rootfs_path / 'usr/sbin/pod-exit' LOG.info('create: %s', pod_exit_path) pod_exit_path.write_text(_POD_EXIT) bases.setup_file(pod_exit_path, 0o755, bases.chown_root) bases.make_dir(image_rootfs_path / 'var/lib/pod', 0o755, bases.chown_root) bases.make_dir( image_rootfs_path / 'var/lib/pod/exit-status', 0o755, bases.chown_root )