Exemplo n.º 1
0
    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)
Exemplo n.º 2
0
 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)
Exemplo n.º 3
0
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
    )