Example #1
0
    def download(cls,
                 manifest=None,
                 localdir=None,
                 version=None,
                 override_existing=False,
                 **kwargs):

        try:
            repo = GitRepo(localdir)

        except (InvalidGitRepositoryError, NoSuchPathError):
            repo = GitRepo.init(localdir)

        if manifest.git is not None:
            try:
                repo.create_remote('origin', manifest.git)
            except GitCommandError as e:
                pass

        try:
            if sys.stdout.isatty():
                repo.remotes.origin.fetch(progress=GitProgressBar(
                    label="%s@%s" % (str(manifest), version.version)))
            else:
                for fetch_info in repo.remotes.origin.fetch():
                    logger.debug(
                        "Updated %s %s to %s" %
                        (manifest.git, fetch_info.ref, fetch_info.commit))

            # self.last_checked = datetime.now()
        except (GitCommandError, AttributeError) as e:
            logger.error("Could not fetch %s: %s" % (manifest.git, str(e)))

        if version.git_sha is not None:
            repo.git.checkout(version.git_sha)
Example #2
0
    def init_env(self):  # noqa: C901
        """
        Determines whether the integrity of the kraft application, namely
        determining whether the kraft application can run under the given
        runtime environment.
        """

        if 'UK_CACHEDIR' not in os.environ:
            os.environ['UK_CACHEDIR'] = os.path.join(os.environ['HOME'],
                                                     UNIKRAFT_CACHEDIR)
        if 'UK_WORKDIR' not in os.environ:
            os.environ['UK_WORKDIR'] = os.path.join(os.environ['HOME'],
                                                    UNIKRAFT_WORKDIR)
        if os.path.isdir(os.environ['UK_WORKDIR']) is False:
            os.mkdir(os.environ['UK_WORKDIR'])
        if 'UK_ROOT' not in os.environ:
            os.environ['UK_ROOT'] = os.path.join(os.environ['UK_WORKDIR'],
                                                 UNIKRAFT_COREDIR)
        if os.path.isdir(os.environ['UK_ROOT']) is False:
            os.mkdir(os.environ['UK_ROOT'])
        if 'UK_ARCHS' not in os.environ:
            os.environ['UK_ARCHS'] = os.path.join(os.environ['UK_WORKDIR'],
                                                  UNIKRAFT_ARCHSDIR)
        if os.path.isdir(os.environ['UK_ARCHS']) is False:
            os.mkdir(os.environ['UK_ARCHS'])
        if 'UK_PLATS' not in os.environ:
            os.environ['UK_PLATS'] = os.path.join(os.environ['UK_WORKDIR'],
                                                  UNIKRAFT_PLATSDIR)
        if os.path.isdir(os.environ['UK_PLATS']) is False:
            os.mkdir(os.environ['UK_PLATS'])
        if 'UK_LIBS' not in os.environ:
            os.environ['UK_LIBS'] = os.path.join(os.environ['UK_WORKDIR'],
                                                 UNIKRAFT_LIBSDIR)
        if os.path.isdir(os.environ['UK_LIBS']) is False:
            os.mkdir(os.environ['UK_LIBS'])
        if 'UK_APPS' not in os.environ:
            os.environ['UK_APPS'] = os.path.join(os.environ['UK_WORKDIR'],
                                                 UNIKRAFT_APPSDIR)
        if os.path.isdir(os.environ['UK_APPS']) is False:
            os.mkdir(os.environ['UK_APPS'])

        # Check if we have a build-time engine set
        if 'UK_BUILD_ENGINE' not in os.environ:
            os.environ['UK_BUILD_ENGINE'] = 'gcc'

        if 'KRAFTRC' not in os.environ:
            os.environ['KRAFTRC'] = os.path.join(os.environ['HOME'], KRAFTRC)
        if os.path.exists(os.environ['KRAFTRC']) is False:
            default_kraftrc = pkgutil.get_data(__name__, KRAFTRC)
            logger.debug("Creating %s..." % os.environ['KRAFTRC'])
            if not default_kraftrc:
                Path(os.environ['KRAFTRC']).touch()
            else:
                kraftrc = open(os.environ['KRAFTRC'], "wb")
                kraftrc.write(default_kraftrc)
                kraftrc.close()

        self._env = Environment.from_env_file(self._workdir, None)
        self._cache = Cache(self.env)
        self._settings = Settings(os.environ['KRAFTRC'])
Example #3
0
    def is_stale(self):
        """Determine if the list of remote repositories is stale.  Return a
        boolean value if at least one repository is marked as stale."""

        logger.debug("Checking cache for staleness...")

        if len(self.all()) == 0:
            return True

        # biggest_timeout = 0
        # repos = self.repos()

        # # If there is nothing cached, this is also stale
        # if len(repos) == 0:
        #     return True

        # for repo in repos:
        #     # If we have never checked, this is stale
        #     if repos[repo].last_checked is None:
        #         return True

        #     diff = (datetime.now() - repos[repo].last_checked).total_seconds()
        #     if diff > biggest_timeout:
        #         biggest_timeout = diff

        # if biggest_timeout > STALE_TIMEOUT:
        #     return True

        return False
Example #4
0
    def download(ctx, self, manifest=None, localdir=None, version=None,
            override_existing=False):

        if version.tarball is None:
            logger.warn("Cannot download tarball, not in manifest")
            return

        remote = manifest.get_version(version.version).tarball

        if remote.endswith(".tar.gz"):
            ext = ".tar.gz"
        else:
            _, ext = os.path.splitext(remote)

        local = os.path.join(
            ctx.obj.env.get('UK_CACHEDIR', os.path.join(
                ctx.obj.workdir,
                UNIKRAFT_CACHEDIR)
            ),
            "%s-%s%s" % (manifest.name, version.version, ext)
        )

        logger.debug("Downloading %s..." % remote)

        t = TarballProgressBar(label="%s/%s@%s"
            % (manifest.type.shortname, manifest.name, version.version)
        )
        urllib.request.urlretrieve(
            remote,
            filename=local,
            reporthook=t.update_to,
            data=None
        )
Example #5
0
def execute(cmd="", env={}, dry_run=False, use_logger=False):
    if type(cmd) is list:
        cmd = " ".join(cmd)

    logger.debug("Running: %s" % cmd)

    if not dry_run:
        popen = subprocess.Popen(cmd,
                                 shell=True,
                                 stdout=subprocess.PIPE,
                                 env=merge_dicts(os.environ, env))

        for line in popen.stdout:
            line = line.strip().decode('ascii')
            if use_logger:
                logger.info(line)
            else:
                print(line)

        popen.stdout.close()
        return_code = popen.wait()
        if return_code is not None and int(return_code) > 0:
            return return_code

    return 0
Example #6
0
def kraft_build(ctx, fast):
    logger.debug("Building %s..." % ctx.workdir)

    try:
        project = Project.from_config(
            ctx.workdir,
            config.load(
                config.find(ctx.workdir, None, ctx.env)
            )
        )

    except KraftError as e:
        logger.error(str(e))
        sys.exit(1)
    
    if not project.is_configured():
        if click.confirm('It appears you have not configured your application.  Would you like to do this now?', default=True):
            project.configure()

    n_proc = None
    if fast:
        # This simply set the `-j` flag which signals to make to use all cores.
        n_proc = ""
        
    project.build(n_proc=n_proc)
Example #7
0
 def open_menuconfig(self):
     """
     Run the make menuconfig target.
     """
     cmd = self.make_raw('menuconfig')
     logger.debug("Running:\n%s" % ' '.join(cmd))
     subprocess.run(cmd)
Example #8
0
def kraft_clean(ctx,
                workdir=None,
                proper=False,
                dist=False,
                progress=True,
                libs=None):
    """
    Cleans the build artifacts of a Unikraft unikernel.
    """

    if workdir is None or os.path.exists(workdir) is False:
        raise ValueError("working directory is empty: %s" % workdir)

    logger.debug("Cleaning %s..." % workdir)

    app = Application.from_workdir(workdir)

    if progress:
        if proper:
            make_progressbar(app.make_raw(extra="properclean"))

        elif dist:
            make_progressbar(app.make_raw(extra="distclean"))

        else:
            if len(libs) is not None and len(libs) > 0:
                for lib in list(libs):
                    make_progressbar(app.make_raw(extra="clean-lib%s" % lib))

            else:
                make_progressbar(app.make_raw(extra="clean"))

    else:
        app.clean(proper=proper, dist=dist)
Example #9
0
    def automount(self, dry_run=False):
        for vol in self.volumes.all():
            if vol.driver is VolumeDriver.VOL_INITRD:
                self.add_initrd(vol.source)

            if vol.driver is VolumeDriver.VOL_9PFS:
                source = vol.source

                # Extract tarball file systems
                if not dry_run and vol.source.lower().endswith(
                    ('.tgz', '.tar.gz', '.tar')):
                    source = tempfile.mkdtemp()
                    logger.debug('Extracting %s to %s...' %
                                 (vol.source, source))
                    tarball = tarfile.open(vol.source)
                    tarball.extractall(source)
                    tarball.close()

                self.add_virtio_9pfs(source)

            if vol.driver is VolumeDriver.VOL_RAW:
                self.add_virtio_raw(vol.source)

            if vol.driver is VolumeDriver.VOL_QCOW2:
                self.add_virtio_qcow2(vol.source)
Example #10
0
def kraft_build(ctx,
                workdir=None,
                fetch=True,
                prepare=True,
                target=None,
                fast=False,
                force_build=False):
    """
    """
    if workdir is None or os.path.exists(workdir) is False:
        raise ValueError("working directory is empty: %s" % workdir)

    logger.debug("Building %s..." % workdir)

    app = Application.from_workdir(workdir, force_build)

    if not app.is_configured():
        if click.confirm(
                'It appears you have not configured your application.  Would you like to do this now?',
                default=True):  # noqa: E501
            app.configure()

    n_proc = None
    if fast:
        # This simply set the `-j` flag which signals to make to use all cores.
        n_proc = 0

    app.build(fetch=fetch, prepare=prepare, target=target, n_proc=n_proc)
Example #11
0
    def get(self, origin=None):
        ret = None
        if isinstance(origin, six.string_types) and origin in self._cache:
            logger.debug("Retrieving %s from cache..." % origin)
            with self._cache_lock:
                ret = self._cache[origin]

        return ret
Example #12
0
    def is_stale(self):
        """
        Determine if the list of remote repositories is stale.  Return a boolean
        value if at least one repository is marked as stale.
        """

        logger.debug("Checking cache for staleness...")
        return True if len(self.all()) == 0 else False
Example #13
0
    def intrusively_determine_kconfig(self):
        if self.is_downloaded:
            config_uk = os.path.join(self.localdir, CONFIG_UK)
            if os.path.exists(config_uk):
                logger.debug("Reading: %s..." % config_uk)
                return kconfiglib.Kconfig(filename=config_uk)

        return None
Example #14
0
    def intrusively_determine_kconfig(self):
        kconfig = None
        config_uk = UK_CONFIG_FILE % self._localdir
        if os.path.exists(config_uk):
            logger.debug("Reading: %s..." % config_uk)
            kconfig = kconfiglib.Kconfig(filename=config_uk)

        return kconfig
Example #15
0
    def get(self, prop, default=None):
        try:
            result = dpath.util.get(self._settings, prop)
        except KeyError:
            logger.debug('Missed setting lookup: %s', prop)
            result = None

        return result
Example #16
0
def delete_resource(resource):
    if os.path.isfile(resource):
        logger.debug("Removing file: %s" % resource)
        os.remove(resource)

    elif os.path.isdir(resource):
        logger.debug("Removing directory: %s" % resource)
        shutil.rmtree(resource)
Example #17
0
    def execute(
            self,  # noqa: C901
            extra_args=None,
            background=False,
            paused=False,
            dry_run=False):
        logger.debug("Executing on KVM...")

        self._cmd.extend(('-k', self.unikernel))

        if background:
            self._cmd.append('-x')
        if paused:
            self._cmd.append('-P')
        if dry_run:
            self._cmd.append('-D')
        if extra_args:
            self._cmd.extend(('-a', ' '.join(extra_args)))

        self.automount(dry_run)
        self.autoconnect(dry_run)

        if self.architecture == "x86_64":
            self._cmd.extend(('-t', 'x86pc'))
        elif self.architecture == "arm64":
            self._cmd.extend(('-t', 'arm64v'))

        # if platform.machine() != self.architecture:
        #     self._cmd.append('-W')

        if self.arguments:
            self._cmd.extend(('-a', self.arguments))

        cmd = [QEMU_GUEST]

        cmd.extend(self._cmd)

        for pre_up_cmd in self._pre_up:
            util.execute(pre_up_cmd, dry_run=dry_run)

        cmd = list(map(str, cmd))
        logger.debug('Running: %s' % ' '.join(cmd))

        if not dry_run:
            process = subprocess.Popen(cmd)

            try:
                process.wait()

            except KeyboardInterrupt:
                try:
                    process.terminate()
                except OSError:
                    pass
                process.wait()

        for post_down_cmd in self._post_down:
            util.execute(post_down_cmd, dry_run=dry_run)
Example #18
0
    def save(self, origin, manifest):
        if not isinstance(origin, six.string_types):
            raise TypeError("origin is not string")
        if not isinstance(manifest, Manifest):
            raise TypeError("Invalid manifest")

        with self._cache_lock:
            logger.debug("Saving %s into cache..." % manifest)
            self._cache[origin] = manifest
Example #19
0
def kraft_build(ctx,
                verbose=False,
                workdir=None,
                fetch=True,
                prepare=True,
                progress=True,
                target=None,
                fast=False,
                force_build=False):
    """
    """
    if workdir is None or os.path.exists(workdir) is False:
        raise ValueError("working directory is empty: %s" % workdir)

    logger.debug("Building %s..." % workdir)

    app = Application.from_workdir(workdir, force_build)

    if not app.is_configured():
        if click.confirm(
                'It appears you have not configured your application.  Would you like to do this now?',
                default=True):  # noqa: E501
            app.configure()

    n_proc = None
    if fast:
        # This simply set the `-j` flag which signals to make to use all cores.
        n_proc = 0

    if fetch:
        app.fetch()

    if prepare:
        app.prepare()

    if progress:
        return_code = make_progressbar(app.make_raw(verbose=verbose))

    else:
        return_code = app.build(target=target, n_proc=n_proc)

    if return_code > 0:
        sys.exit(return_code)

    print("\nSuccessfully built unikernels:\n")

    for target in app.binaries:
        if not os.path.exists(target.binary):
            continue

        print("  => %s/%s" %
              (UNIKRAFT_BUILDDIR, os.path.basename(target.binary)))
        print("  => %s/%s (with symbols)" %
              (UNIKRAFT_BUILDDIR, os.path.basename(target.binary_debug)))

    print("\nTo instantiate, use: kraft run\n")
Example #20
0
    def save_yaml(self, file=None):
        if file is None:
            file = os.path.join(self.localdir, SUPPORTED_FILENAMES[0])

        yaml = serialize_config(self.repr(), original=file)

        logger.debug("Saving: %s" % file)

        with open(file, 'w+') as f:
            f.write(yaml)
Example #21
0
def execute(cmd="", env={}, dry_run=False):
    if type(cmd) is list:
        cmd = " ".join(cmd)

    logger.debug("Running: %s" % cmd)
    
    if not dry_run:
        cmd = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, env={**os.environ, **env})

        for line in cmd.stdout:
            logger.info(line.strip().decode('ascii'))
Example #22
0
def kraft_clean(ctx, workdir=None, proper=False):
    """
    Cleans the build artifacts of a Unikraft unikernel.
    """

    if workdir is None or os.path.exists(workdir) is False:
        raise ValueError("working directory is empty: %s" % workdir)

    logger.debug("Cleaning %s..." % workdir)

    app = Application.from_workdir(workdir)
    app.clean(proper=proper)
Example #23
0
    def run(self, target=None, initrd=None, background=False,  # noqa: C901
            paused=False, gdb=4123, dbg=False, virtio_nic=None, bridge=None,
            interface=None, dry_run=False, args=None, memory=64, cpu_sockets=1,
            cpu_cores=1):

        if target is None:
            raise KraftError('Target not set')

        elif target.binary is None:
            raise KraftError('Target has not been compiled')

        elif not os.path.exists(target.binary):
            raise KraftError('Could not find unikernel: %s' % target.binary)

        logger.debug("Running binary: %s" % target.binary)

        runner = target.platform.runner
        runner.use_debug = dbg
        runner.architecture = target.architecture.name

        if initrd:
            runner.add_initrd(initrd)

        if virtio_nic:
            runner.add_virtio_nic(virtio_nic)

        if bridge:
            runner.add_bridge(bridge)

        if interface:
            runner.add_interface(interface)

        if gdb:
            runner.open_gdb(gdb)

        if memory:
            runner.set_memory(memory)

        if cpu_sockets:
            runner.set_cpu_sockets(cpu_sockets)

        if cpu_cores:
            runner.set_cpu_cores(cpu_cores)

        runner.unikernel = target.binary
        runner.execute(
            extra_args=args,
            background=background,
            paused=paused,
            dry_run=dry_run,
        )
Example #24
0
def find_config(base_dir, filenames, environment, override_dir=None):
    if filenames == ['-']:
        return ConfigDetails(
            os.path.abspath(override_dir) if override_dir else os.getcwd(),
            [KraftFile(None, yaml.safe_load(sys.stdin))], environment)

    if filenames:
        filenames = [os.path.join(base_dir, f) for f in filenames]
    else:
        filenames = get_default_config_files(base_dir)

    logger.debug("Using configuration files: %s" % (",".join(filenames)))
    return ConfigDetails(
        override_dir if override_dir else os.path.dirname(filenames[0]),
        [KraftFile.from_filename(f) for f in filenames], environment)
Example #25
0
    def execute(self,
                extra_args=None,
                background=False,
                paused=False,
                dry_run=False):
        logger.debug("Executing on Xen...")

        self._cmd.extend(('-k', self.unikernel))

        if background:
            self._cmd.append('-X')
        if paused:
            self._cmd.append('-P')
        if dry_run:
            self._cmd.append('-D')
        if extra_args:
            self._cmd.extend(('-a', ' '.join(extra_args)))

        self.automount(dry_run)
        self.autoconnect(dry_run)

        if self.arguments:
            self._cmd.extend(('-a', self.arguments))

        cmd = [XEN_GUEST]
        cmd.extend(self._cmd)

        for pre_up_cmd in self._pre_up:
            utils.execute(pre_up_cmd, dry_run=dry_run)

        cmd = list(map(str, cmd))
        logger.debug('Running: %s' % ' '.join(cmd))

        if not dry_run:
            process = subprocess.Popen(cmd)

            try:
                process.wait()

            except KeyboardInterrupt:
                try:
                    process.terminate()
                except OSError:
                    pass
                process.wait()

        for post_down_cmd in self._post_down:
            utils.execute(post_down_cmd, dry_run=dry_run)
Example #26
0
def clean(ctx, proper):
    """
    Cleans build files.
    """

    logger.debug("Cleaning %s..." % ctx.workdir)

    try:
        project = Project.from_config(
            ctx.workdir, config.load(config.find(ctx.workdir, None, ctx.env)))

    except KraftError as e:
        logger.error(str(e))
        sys.exit(1)

    project.clean(proper=proper)
Example #27
0
 def list_possible_mirrors(self):
     extra = []
     for lib in self.config.libraries.all():
         if not lib.is_fetched:
             for mirror in lib.origin_mirrors:
                 response = requests.head(mirror)
                 if response.status_code == 200:
                     extra.append(
                         lib.kname +
                         UNIKRAFT_LIB_MAKEFILE_URL_EXT +
                         "=" +
                         mirror
                     )
                 else:
                     logger.debug("Mirror down: %s" % mirror)
                     break
     return extra
Example #28
0
def kraft_prepare(ctx, workdir=None):
    """
    """
    if workdir is None or os.path.exists(workdir) is False:
        raise ValueError("working directory is empty: %s" % workdir)

    logger.debug("Preparing %s..." % workdir)

    app = Application.from_workdir(workdir)

    if not app.is_configured():
        if click.confirm(
                'It appears you have not configured your application.  Would you like to do this now?',
                default=True):  # noqa: E501
            app.configure()

    app.prepare()
Example #29
0
def recursively_copy(src, dest, overwrite=False, ignore=None):
    if os.path.basename(src) in ignore:
        pass
    elif os.path.isdir(src):
        if not os.path.isdir(dest):
            os.makedirs(dest)

        files = os.listdir(src)

        for f in files:
            recursively_copy(os.path.join(src, f), os.path.join(dest, f),
                             overwrite, ignore)
    elif (os.path.exists(dest) and overwrite) or os.path.exists(dest) is False:
        logger.debug('Copying %s => %s' % (src, dest))
        try:
            copyfile(src, dest)
        except SameFileError:
            pass
Example #30
0
def make_progressbar(make=""):
    if make is None or len(make) == 0:
        return None

    make_n = make[:]
    make_n.append("-n")

    logger.debug("Calculating how many files to build...")
    logger.debug(" ".join(make_n))

    all_make_commands = subprocess.check_output(make_n)
    all_make_commands = all_make_commands.decode('utf-8').split('\n')
    actual_make_commands = []

    for i, command in enumerate(all_make_commands):
        command = command.strip()
        if command.startswith('make') \
                or command == "" \
                or command == ":" \
                or "fixdep" in command:
            pass

        else:
            actual_make_commands.append(command)

    with std_out_err_redirect_tqdm() as orig_stdout:
        logger.debug("Starting build...")
        logger.debug(" ".join(make))

        popen = subprocess.Popen(make, stdout=subprocess.PIPE, env=os.environ)

        with tqdm(
                total=len(actual_make_commands),
                file=orig_stdout,
                unit="file",
                leave=False,
                bar_format=
                "{desc:<3}{percentage:3.0f}% {bar} {n_fmt}/{total_fmt} [{rate_fmt}{postfix}]",
                dynamic_ncols=True) as t:  # noqa: E125

            for line in popen.stdout:
                t.update()
                line = line.strip().decode('ascii')
                if line.startswith("make: Leaving directory") is False and \
                        line.startswith("make: Entering directory") is False:
                    print(line)

            t.close()

        popen.stdout.close()
        return popen.wait()

    return 0