Esempio n. 1
0
def kraft_list_remove(ctx, origin=None):
    """
    """
    if isinstance(origin, list):
        for o in origin:
            kraft_list_remove(o)
        return

    existing_origins = ctx.obj.settings.get(KRAFTRC_LIST_ORIGINS)
    if existing_origins is None:
        existing_origins = list()

    new_uri = urlparse(origin)

    if os.path.exists(origin):
        origin = os.path.abspath(origin)

    for i, o in enumerate(existing_origins):
        cur_uri = urlparse(o)
        if (o == origin or (new_uri.netloc == cur_uri.netloc
                            and new_uri.path == cur_uri.path)):
            logger.info("Removed: %s" % origin)
            del existing_origins[i]
            break

    ctx.obj.settings.set(KRAFTRC_LIST_ORIGINS, existing_origins)
Esempio n. 2
0
def kraft_list_add(ctx, origin=None, update=False):
    """
    """
    if isinstance(origin, list):
        for o in origin:
            kraft_list_add(o, update=update)
        return

    existing_origins = ctx.obj.settings.get(KRAFTRC_LIST_ORIGINS)
    if existing_origins is None:
        existing_origins = list()

    new_uri = urlparse(origin)

    if os.path.exists(origin):
        origin = os.path.abspath(origin)

    for o in existing_origins:
        cur_uri = urlparse(o)
        if (o == origin
                or (new_uri.netloc == cur_uri.netloc
                    and new_uri.path == cur_uri.path)):
            logger.warning("Origin already saved: %s" % o)
            return

    existing_origins.append(origin)
    ctx.obj.settings.set(KRAFTRC_LIST_ORIGINS, existing_origins)
    logger.info("Saved: %s" % origin)

    if update:
        with ctx:
            kraft_update(origin)
Esempio n. 3
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
Esempio n. 4
0
    def remove_lib(ctx, self, lib=None, purge=False):
        if lib is None or str(lib) == "":
            logger.warn("No library to remove")
            return False

        elif isinstance(lib, six.string_types):
            _, name, _, _ = break_component_naming_format(lib)
            manifests = maniest_from_name(name)

            if len(manifests) == 0:
                logger.warn("Unknown library: %s" % lib)
                return False

            for manifest in manifests:
                if manifest.type != ComponentType.LIB:
                    continue

                self.config.libraries.remove(name, purge)
                break

            if purge and os.path.exists(manifest.localdir):
                logger.info("Purging lib/%s..." % name)
                shutil.rmtree(manifest.localdir)

        self.save_yaml()

        return True
Esempio n. 5
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'))
Esempio n. 6
0
    def add(self, component=None):
        if component is None:
            raise ValueError("expected component")

        if not isinstance(component, Component):
            raise TypeError("expected Component")

        logger.info("Adding %s@%s..." % (component.manifest, component.version))

        self._components.append(component)

        return True
Esempio n. 7
0
def kraft_update(ctx):
    origins = ctx.obj.settings.get(KRAFTRC_LIST_ORIGINS)
    if origins is None or len(origins) == 0:
        logger.error(
            "No source origins available.  Please see: kraft list add --help")
        sys.exit(1)

    try:
        for origin in origins:
            manifest = ctx.obj.cache.get(origin)

            if manifest is None:
                manifest = Manifest(manifest=origin)

            threads, items = kraft_update_from_source_threads(origin)

            for thread in threads:
                thread.join()

            # Check thread's return value
            while not items.empty():
                result = items.get()
                if result is not None:
                    manifest.add_item(result)
                    logger.info("Found %s/%s via %s..." %
                                (click.style(result.type.shortname, fg="blue"),
                                 click.style(result.name,
                                             fg="blue"), manifest.manifest))
                    ctx.obj.cache.save(origin, manifest)

    except RateLimitExceededException:
        logger.error("".join([
            "GitHub rate limit exceeded.  You can tell kraft to use a ",
            "personal access token by setting the UK_KRAFT_GITHUB_TOKEN ",
            "environmental variable."
        ]))

    except Exception as e:
        logger.critical(str(e))

        if ctx.obj.verbose:
            import traceback
            logger.critical(traceback.format_exc())

        sys.exit(1)
Esempio n. 8
0
def kraft_list_remove(ctx, origin=None):
    """
    """
    if isinstance(origin, list):
        for o in origin:
            kraft_list_remove(o)
        return

    new_uri = urlparse(origin)
    existing_origins = ctx.obj.settings.get(KRAFTRC_LIST_ORIGINS)
    for i, o in enumerate(existing_origins):
        cur_uri = urlparse(o)
        if new_uri.netloc == cur_uri.netloc and new_uri.path == cur_uri.path:
            logger.info("Removed: %s" % origin)
            del existing_origins[i]
            break

    ctx.obj.settings.set(KRAFTRC_LIST_ORIGINS, existing_origins)
Esempio n. 9
0
    def remove(self, component=None, purge=False):
        if component is None:
            raise ValueError("expected component")

        if isinstance(component, six.string_types):
            for i, c in enumerate(self._components):
                if c.name == component:
                    if purge and os.path.exists(c.localdir):
                        logger.info("Purging lib/%s..." % component)
                        shutil.rmtree(c.localdir)

                    else:
                        logger.info("Removing lib/%s..." % component)

                    del self._components[i]

                    return True

        return False
Esempio n. 10
0
def kraft_list_add(ctx, origin=None):
    """
    """
    if isinstance(origin, list):
        for o in origin:
            kraft_list_add(o)
        return

    new_uri = urlparse(origin)
    existing_origins = ctx.obj.settings.get(KRAFTRC_LIST_ORIGINS)
    if existing_origins is None:
        existing_origins = list()
    for o in existing_origins:
        cur_uri = urlparse(o)
        if new_uri.netloc == cur_uri.netloc and new_uri.path == cur_uri.path:
            logger.warning("Origin already saved: %s" % o)
            return

    existing_origins.append(origin)
    ctx.obj.settings.set(KRAFTRC_LIST_ORIGINS, existing_origins)
    logger.info("Saved: %s" % origin)
Esempio n. 11
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:
        popen = subprocess.Popen(
            cmd,
            shell=True,
            stdout=subprocess.PIPE,
            env=merge_dicts(os.environ, env)
        )

        for line in popen.stdout:
            logger.info(line.strip().decode('ascii'))

        popen.stdout.close()
        return_code = popen.wait()
        if return_code is not None and int(return_code) > 0:
            logger.error("Command '%s' returned %d" % (cmd, return_code))
            sys.exit(return_code)
Esempio n. 12
0
 def add_bridge(self, bridge=None):
     if bridge:
         logger.info("Using networking bridge '%s'" % bridge)
         self._cmd.extend(('-b', bridge))
Esempio n. 13
0
def kraft_app_init(ctx,
                   appdir=None,
                   name=None,
                   plat=None,
                   arch=None,
                   template_app=None,
                   force_init=False,
                   pull_dependencies=False,
                   dumps_local=False,
                   create_makefile=False):
    """

    """

    if appdir is None:
        raise ValueError("Cannot initialize application at unset directory")

    # If we are using a template application, we can simply copy from the source
    # repository
    if template_app is not None:
        app_manifest = None

        _, template_name, _, version = break_component_naming_format(
            template_app)

        for manifest_origin in ctx.obj.cache.all():
            manifest = ctx.obj.cache.get(manifest_origin)

            for _, item in manifest.items():
                if item.name == template_name and item.type == ComponentType.APP:
                    app_manifest = item

        if app_manifest is None:
            raise UnknownApplicationTemplateName(template_app)

        if version is not None:
            version = app_manifest.get_version(version)
            if version is None:
                raise UnknownVersionError(version, app_manifest)
        else:
            version = app_manifest.get_version(UNIKRAFT_RELEASE_STABLE)

        kraft_download_component(localdir=appdir,
                                 manifest=app_manifest,
                                 version=version.version)

        if pull_dependencies or dumps_local:
            workdir = None
            if dumps_local:
                workdir = os.path.join(appdir, UNIKRAFT_WORKDIR)

            kraft_list_pull(
                name=str(app_manifest),
                appdir=appdir,
                workdir=workdir,
                pull_dependencies=True,
                skip_app=True,
                force_pull=force_init,
            )

        app = Application.from_workdir(appdir)

    # If no application is provided, we can initialize a template by dumping
    # a YAML file
    else:
        unikraft = ctx.obj.cache.find_item_by_name(type="core",
                                                   name="unikraft")

        unikraft.download()

        app = Application(name=name,
                          unikraft=unikraft,
                          architectures=[arch],
                          platforms=[plat],
                          localdir=appdir,
                          ignore_version=force_init)

    app.name = name
    app.init(create_makefile=create_makefile)

    logger.info('Initialized new unikraft application: %s' % appdir)
Esempio n. 14
0
    def configure(ctx, self, target_arch=None, target_plat=None):
        """Configure a Unikraft application."""

        if not self.is_configured():
            self.init()

        self.checkout()

        # Generate a dynamic .config to populate defconfig with based on
        # configure's parameterization.
        dotconfig = []

        if 'kconfig' in self.config.unikraft:
            dotconfig.extend(self.config.unikraft['kconfig'])

        found_arch = False
        for arch in self.architectures.all():
            if target_arch == arch.name:
                found_arch = True
                logger.info("Using %s" % arch.repository)
                kconfig_enable = arch.repository.kconfig_enabled_flag()
                if kconfig_enable:
                    dotconfig.extend([kconfig_enable])
                if isinstance(arch.config,
                              (dict)) and 'kconfig' in arch.config:
                    dotconfig.extend(arch.config['kconfig'])
                dotconfig.extend(arch.repository.kconfig_extra)

        if not found_arch:
            raise MismatchTargetArchitecture(
                target_arch, [arch.name for arch in self.architectures.all()])

        found_plat = False
        for plat in self.platforms.all():
            if target_plat == plat.name:
                found_plat = True
                logger.info("Using %s" % plat.repository)
                kconfig_enable = plat.repository.kconfig_enabled_flag()
                if kconfig_enable:
                    dotconfig.extend([kconfig_enable])
                if isinstance(plat.config,
                              (dict)) and 'kconfig' in plat.config:
                    dotconfig.extend(plat.config['kconfig'])
                dotconfig.extend(plat.repository.kconfig_extra)

        if not found_plat:
            raise MismatchTargetPlatform(
                target_plat, [plat.name for plat in self.platforms.all()])

        for lib in self.libraries.all():
            logger.info("Using %s" % lib.repository)
            kconfig_enable = lib.repository.kconfig_enabled_flag()
            if kconfig_enable:
                dotconfig.extend([kconfig_enable])
            if isinstance(lib.config, (dict)) and 'kconfig' in lib.config:
                dotconfig.extend(lib.config['kconfig'])
            dotconfig.extend(lib.repository.kconfig_extra)

        # Create a temporary file with the kconfig written to it
        fd, path = tempfile.mkstemp()

        with os.fdopen(fd, 'w+') as tmp:
            logger.debug('Using the following defconfig:')
            for line in dotconfig:
                logger.debug(' > ' + line)
                tmp.write(line + '\n')

        try:
            self.make([('UK_DEFCONFIG=%s' % path), 'defconfig'])
        finally:
            os.remove(path)
Esempio n. 15
0
def cmd_list(ctx, show_installed=False, show_core=False, show_plats=False,
             show_libs=False, show_apps=False, show_local=False, paginate=False,
             this=False, this_set=None, return_json=False):
    """
    Retrieves lists of available architectures, platforms, libraries and
    applications supported by unikraft.  Use this command if you wish to
    determine (and then later select) the possible targets for your unikraft
    application.

    By default, this subcommand will list all possible targets.

    """
    if ctx.invoked_subcommand is None:
        kraft_list_preflight()

        show_archs = False

        # If no flags are set, show everything
        if (show_core is False
                and show_archs is False
                and show_plats is False
                and show_libs is False
                and show_apps is False):
            show_core = show_archs = show_plats = show_libs = show_apps = True

        # Populate a matrix with all relevant columns and rows for each
        # component.
        components = {}
        data = []
        data_json = {}

        if this or this_set is not None:
            workdir = os.getcwd()
            if this_set is not None:
                workdir = this_set

            try:
                app = Application.from_workdir(workdir)

                for manifest in app.manifests:
                    if manifest.type.shortname not in components:
                        components[manifest.type.shortname] = []
                    components[manifest.type.shortname].append(manifest)

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

        else:
            for manifest_origin in ctx.obj.cache.all():
                manifest = ctx.obj.cache.get(manifest_origin)

                for _, item in manifest.items():
                    if item.type.shortname not in components:
                        components[item.type.shortname] = []

                    components[item.type.shortname].append(item)

        for type, member in ComponentType.__members__.items():
            columns = [
                click.style(member.plural.upper(), fg='white'),
                click.style('VERSION ', fg='white'),
                click.style('RELEASED', fg='white'),
                click.style('LAST CHECKED', fg='white')
            ]

            if show_local:
                columns.append(click.style('LOCATION', fg='white'))

            rows = []
            components_showing = 0

            if member.shortname in components and (
                    (show_core and member is ComponentType.CORE) or
                    (show_archs and member is ComponentType.ARCH) or
                    (show_plats and member is ComponentType.PLAT) or
                    (show_libs and member is ComponentType.LIB) or
                    (show_apps and member is ComponentType.APP)):
                rows = components[member.shortname]

            # if len(rows) > 0:
            data.append(columns)

            for row in rows:
                installed = False
                install_error = False
                localdir = row.localdir

                if os.path.isdir(localdir):
                    installed = True
                    if len(os.listdir(localdir)) == 0:
                        install_error = True
                        logger.warn("%s directory is empty: %s " % (
                            row.name, localdir
                        ))

                latest_release = None
                if UNIKRAFT_RELEASE_STABLE in row.dists.keys():
                    latest_release = row.dists[UNIKRAFT_RELEASE_STABLE].latest
                elif UNIKRAFT_RELEASE_STAGING in row.dists.keys():
                    latest_release = row.dists[UNIKRAFT_RELEASE_STAGING].latest

                if return_json:
                    if member.plural not in data_json:
                        data_json[member.plural] = []

                    row_json = row.__getstate__()

                    if not show_installed or (installed and show_installed):
                        data_json[member.plural].append(row_json)
                        components_showing += 1

                else:
                    line = [
                        click.style(row.name, fg='yellow' if install_error else 'green' if installed else 'red'),  # noqa: E501
                        click.style(latest_release.version if latest_release is not None else "", fg='white'),  # noqa: E501
                        click.style(prettydate(latest_release.timestamp) if latest_release is not None else "", fg='white'),  # noqa: E501
                        click.style(prettydate(row.last_checked), fg='white'),
                    ]

                    if show_local:
                        line.append(click.style(localdir if installed else '', fg='white'))  # noqa: E501

                    if not show_installed or (installed and show_installed):
                        data.append(line)
                        components_showing += 1

            # Delete component headers with no rows
            if components_showing == 0 and len(data) > 0:
                del data[-1]

            # Line break
            elif len(rows) > 0:
                data.append([click.style("", fg='white')] * len(columns))

        if return_json:
            click.echo(json.dumps(data_json))

        else:
            output = pretty_columns(data)

            if len(data) == 0:
                logger.info("Nothing to show")
            elif paginate:
                click.echo_via_pager(output)
            else:
                click.echo(output[:-1])
Esempio n. 16
0
def kraft_run(ctx, plat, arch, initrd, background, paused, gdb, dbg,
              virtio_nic, bridge, interface, dry_run, args, memory,
              cpu_sockets, cpu_cores):
    """
    Starts the unikraft application once it has been successfully
    built.
    """

    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)

    target_platform = None

    for platform in project.platforms.all():
        if plat == platform.name:
            target_platform = platform

    if target_platform is None:
        logger.error('Application platform not configured or set')
        sys.exit(1)

    target_architecture = None

    for architecture in project.architectures.all():
        if arch == architecture.name:
            target_architecture = architecture

    if target_architecture is None:
        logger.error('Application architecture not configured or set')
        sys.exit(1)

    unikernel = UNIKERNEL_IMAGE_FORMAT % (ctx.workdir, project.name,
                                          target_platform.name,
                                          target_architecture.name)

    if not os.path.exists(unikernel):
        logger.error('Could not find unikernel: %s' % unikernel)
        logger.info('Have you tried running `kraft build`?')
        sys.exit(1)

    executor = target_platform.repository.executor
    executor.architecture = target_architecture.name
    executor.use_debug = dbg

    if initrd:
        executor.add_initrd(initrd)

    if virtio_nic:
        executor.add_virtio_nic(virtio_nic)

    if bridge:
        executor.add_bridge(bridge)

    if interface:
        executor.add_interface(interface)

    if gdb:
        executor.open_gdb(gdb)

    if memory:
        executor.set_memory(memory)

    if cpu_sockets:
        executor.set_cpu_sockets(cpu_sockets)

    if cpu_cores:
        executor.set_cpu_cores(cpu_cores)

    try:
        executor.unikernel = unikernel
        executor.execute(
            extra_args=args,
            background=background,
            paused=paused,
            dry_run=dry_run,
        )
    except ExecutorError as e:
        logger.error("Cannot execute: %s" % e)
        sys.exit(1)
Esempio n. 17
0
    def init(ctx,
             self,
             extra_values=dict(),
             force_create=False,
             no_input=False):
        """
        """

        context = generate_context(
            context_file=get_template_config(TEMPLATE_LIB),
            default_context=self._template_values)

        # prompt the user to manually configure at the command line.
        # except when 'no-input' flag is set
        context['cookiecutter'] = prompt_for_config(context, no_input)

        self._description = context['cookiecutter']['description']
        self._template_values = {
            **self._template_values,
            **dict(context['cookiecutter'])
        }

        # Set additional template values

        # Fix the starting "v" in the version string
        if context['cookiecutter']['version'].startswith('v'):
            context['cookiecutter']['version'] = context['cookiecutter'][
                'version'][1:]
            context['cookiecutter'][
                'source_archive'] = self.version_source_archive(
                    'v%s' % (UK_VERSION_VARNAME % self.kname))
        else:
            context['cookiecutter'][
                'source_archive'] = self.version_source_archive()

        # include automatically generated content
        context['cookiecutter'][
            'kconfig_dependencies'] = self.determine_kconfig_dependencies()
        context['cookiecutter']['source_files'] = self.determine_source_files()

        # include template dir or url in the context dict
        context['cookiecutter']['_template'] = get_templates_path(TEMPLATE_LIB)

        # add all vars that were never prompted
        for key in self._template_values:
            if key not in context['cookiecutter']:
                context['cookiecutter'][key] = self._template_values[key]

        output_dir = Path(self.localdir).parent
        # if self.source.startswith("file://"):
        #     output_dir = self.source[len("file://"):]

        logger.info("Generating files...")
        generate_files(
            repo_dir=get_templates_path(TEMPLATE_LIB),
            context=context,
            overwrite_if_exists=force_create,
            skip_if_file_exists=not force_create,
            output_dir=output_dir,
        )

        delete_template_resources_of_disabled_features(self.localdir)

        # Save initial commit
        repo = GitRepo.init(self.localdir)
        repo.config_writer().set_value(
            "user", "name", self.template_value['author_name']).release()
        repo.config_writer().set_value(
            "user", "email", self.template_value['author_email']).release()
        repo.index.commit('Initial commit (blank)')

        logger.info("Generated new library: %s" % self.localdir)
Esempio n. 18
0
    def bump(ctx, self, version=None, fast_forward=False, force_version=False):
        """
        Change the Unikraft library's source origin version.  Usually this
        involves updating the LIBNAME_VERSION variable in the Makefile.uk file.

        Args:
            version:  The version to set.  If None, the latest version will be
                set.
            fast_forward:  If True, choose the latest version.
            force_version:  Whatever the specified version is, use it.

        Raises:
            NonCompatibleUnikraftLibrary:  Provided path is not a Unikraft
                library.
            UnknownLibraryOriginVersion:  The provided version does not match
                known versions from the origin.
            BumpLibraryDowngrade:  Attempting to downgrade a library.
            NoRemoteVersionsAvailable:  No remote versions to select from.
            CannotDetermineRemoteVersion:  Unable to determine which version to
                upgrade to.
            UnknownLibraryProvider:  Undetermined origin provider.
            KraftError:  Miscellaneous error.
        """

        if self.origin_provider is None:
            raise UnknownLibraryProvider(self.name)

        # Retrieve known versions
        versions = self.origin_provider.probe_remote_versions()

        semversions = []

        if len(versions) == 0:
            raise NoRemoteVersionsAvailable(self.origin_provider.source)

        # filter out non-semver versions
        for known_version in list(versions.keys()):
            found = SEMVER_PATTERN.search(known_version)

            if found is not None:
                semversions.append(known_version)

        current_version = self.origin_version

        if version is None:

            # Pick the highest listed verson
            if ctx.obj.assume_yes:

                # There are no semversions
                if len(semversions) == 0:
                    raise CannotDetermineRemoteVersion(self.localdir)

                current_not_semver = False

                try:
                    semver.VersionInfo.parse(current_version)
                except ValueError as e:
                    logger.warn(e)
                    current_not_semver = True

                # Remove non-semvers
                latest_version = None
                _semversions = semversions
                semversions = list()
                for checkv in _semversions:
                    try:
                        semver.VersionInfo.parse(checkv)
                        semversions.append(checkv)
                    except ValueError:
                        continue

                latest_version = sorted(semversions, reverse=True)[0]

                # Pick the latest version
                if fast_forward or current_not_semver:
                    version = latest_version

                # Check if we're already at the latest version
                elif semver.compare(current_version, latest_version) == 0:
                    version = latest_version

                # Find the next version
                else:
                    semversions = sorted(semversions)

                    for i in range(len(semversions)):
                        try:
                            comparison = semver.compare(
                                semversions[i], current_version)
                        except ValueError as e:
                            logger.warn(e)
                            continue

                        if comparison == 0:
                            # We should have never made it this far, but because we
                            # did, we're at the latest version.
                            if i + 1 == len(semversions):
                                version = latest_version
                                break

                            # Select the next version
                            else:
                                version = semversions[i + 1]
                                break

            # Prompt user for a version
            else:
                version = read_user_choice(
                    'version', sorted(list(versions.keys()), reverse=True))

        if version not in versions.keys():
            if ctx.obj.assume_yes:
                logger.warn("Provided version '%s' not known in: {%s}" %
                            (version, ', '.join(versions.keys())))
            else:
                raise UnknownLibraryOriginVersion(version, versions.keys())

        if VSEMVER_PATTERN.search(version):
            version = version[1:]

        # Are we dealing with a semver pattern?
        try:
            if semver.compare(current_version, version) == 0:
                logger.info("Library already latest version: %s" % version)
                return version

            if semver.compare(current_version, version) > 0:
                if force_version:
                    logger.warn("Downgrading library from %s to %s..." %
                                (current_version, version))
                else:
                    raise BumpLibraryDowngrade(current_version, version)

        except ValueError:
            if current_version == version:
                logger.info("Library already at version: %s" % version)
                return version

        # Actually perform the bump
        makefile_uk = os.path.join(self.localdir, MAKEFILE_UK)
        logger.debug("Reading %s..." % makefile_uk)

        makefile_vars = make_list_vars(makefile_uk)['makefile']
        version_var = None

        for var in makefile_vars:
            if var.endswith(UNIKRAFT_LIB_MAKEFILE_VERSION_EXT):
                version_var = var
                break

        logger.info('Upgrading library from %s to %s...' %
                    (current_version, version))

        for line in fileinput.input(makefile_uk, inplace=1):
            if line.startswith(version_var) and current_version in line:
                print('%s = %s' % (version_var, version))
            else:
                print(line, end='')

        return version
Esempio n. 19
0
def kraft_init(ctx, name, target_plat, target_arch, template_app, version,
               force_create):
    if name is None:
        name = os.path.basename(os.getcwd())

    # Pre-flight check determines if we are trying to work with nothing
    if ctx.cache.is_stale() and click.confirm(
            'kraft caches are out-of-date.  Would you like to update?'):
        update()

    # Check if the directory is non-empty and prompt for validation
    if utils.is_dir_empty(ctx.workdir) is False and force_create is False:
        if click.confirm(
                '%s is a non-empty directory, would you like to continue?' %
                ctx.workdir):
            # It should be safe to set this now
            force_create = True
        else:
            logger.error('Cancelling!')
            sys.exit(1)

    # If we are using a template application, we can simply copy from the source
    # repository
    if template_app is not None:

        apps = {}

        for repo in ctx.cache.all():
            repo = ctx.cache.get(repo)

            if repo.type is RepositoryType.APP:
                apps[repo.name] = repo

        if template_app not in apps.keys():
            logger.error('Template application not found: %s' % template_app)
            logger.error('Supported templates: %s' % ', '.join(apps.keys()))
            sys.exit(1)

        app = apps[template_app]

        if version and version not in app.known_versions.keys():
            logger.error('Unknown version \'%s\' for app: %s' %
                         (version, template_app))
            sys.exit(1)

        app.checkout(version)

        utils.recursively_copy(
            app.localdir,
            ctx.workdir,
            overwrite=force_create,
            ignore=['.git', 'build', '.config', '.config.old', '.config.orig'])

        logger.info('Initialized new unikraft application \'%s\' in %s' %
                    (name, ctx.workdir))

    # If no application is provided, we can initialize a template by dumping
    # a YAML file
    else:
        # Determine the version of unikraft that we should be using
        if version is None:
            # This simply sets the "source" to the unikraft core repository which,
            # once parsed through the internal cache, should pop out the latest
            # version.
            unikraft_source = UNIKRAFT_CORE
            unikraft_version = None
        else:
            unikraft_source, unikraft_version = interpolate_source_version(
                source=version, repository_type=RepositoryType.CORE)

        try:
            core = Core.from_source_string(source=unikraft_source,
                                           version=unikraft_version)

            preferred_arch = ctx.settings.get(KRAFTCONF_PREFERRED_ARCHITECTURE)
            if target_arch is None:
                if preferred_arch:
                    target_arch = preferred_arch
                else:
                    logger.error("Please provide an architecture.")
                    sys.exit(1)

            arch_source, arch_version = interpolate_source_version(
                source=target_arch, repository_type=RepositoryType.ARCH)

            archs = Architectures([])
            archs.add(
                target_arch,
                Architecture.from_source_string(
                    name=target_arch,
                    source=arch_source,
                ), {})

            preferred_plat = ctx.settings.get(KRAFTCONF_PREFERRED_PLATFORM)
            if target_plat is None:
                if preferred_plat:
                    target_plat = preferred_plat
                else:
                    logger.error("Please provide a platform.")
                    sys.exit(1)

            plat_source, plat_version = interpolate_source_version(
                source=target_plat, repository_type=RepositoryType.PLAT)

            plats = Platforms([])
            plats.add(
                target_plat,
                Platform.from_source_string(
                    name=target_plat,
                    source=plat_source,
                ), {})

            logger.info("Using %s..." % core)

            project = Project(
                path=ctx.workdir,
                name=name,
                core=core,
                architectures=archs,
                platforms=plats,
            )

            project.init(force_create=force_create)
            logger.info('Initialized new unikraft application \'%s\' in %s' %
                        (name, ctx.workdir))
        except KraftError as e:
            logger.error(str(e))
            sys.exit(1)
Esempio n. 20
0
    def probe(ctx, self, origin=None, items=None, return_threads=False):
        # TODO: There should be a work around to fix this import loop cycle
        from kraft.manifest import Manifest

        if self.is_type(origin) is False:
            return []

        threads = list()
        if items is None:
            items = Queue()

        manifest = ctx.obj.cache.get(origin)

        if manifest is None:
            manifest = Manifest(manifest=origin)

        uri = urlparse(origin)

        # Is the origin from GitHub?
        if uri.netloc == GITHUB_ORIGIN:
            github_api = Github(ctx.obj.env.get('UK_KRAFT_GITHUB_TOKEN', None))
            github_org = uri.path.split('/')[1]
            github_repo = uri.path.split('/')[2]

            if "*" in github_org:
                logger.warn(
                    "Cannot use wildcard in GitHub organisation names!")
                return

            # Does the origin contain a wildcard in the repo name?
            if "*" in github_repo:
                logger.info("Populating via wildcard: %s" % origin)

                org = github_api.get_organization(github_org)
                repos = org.get_repos()

                for repo in repos:
                    if return_threads:
                        thread = ErrorPropagatingThread(
                            target=lambda *arg: items.put(
                                get_component_from_github(*arg)),
                            args=(
                                ctx,
                                origin,
                                github_org,
                                repo.name,
                            ))
                        threads.append(thread)
                        thread.start()
                    else:
                        items.put(
                            get_component_from_github(ctx, origin, github_org,
                                                      repo.name))
            else:
                logger.info("Using direct repository: %s" % origin)

                if return_threads:
                    thread = ErrorPropagatingThread(
                        target=lambda *arg: items.put(
                            get_component_from_github(*arg)),
                        args=(
                            ctx,
                            origin,
                            github_org,
                            github_repo,
                        ))
                    threads.append(thread)
                    thread.start()
                else:
                    items.put(
                        get_component_from_github(ctx, origin, github_org,
                                                  github_repo))

        return items, threads