Exemple #1
0
    def __init__(self, name):

        self.name = name
        if name[-7:] == '-native':
            self._basename = name[:-7]
            self._native = True
        else:
            self._basename = name
            self._native = False

        self.mk = self._get_mk()
        if not self.mk:
            Blog.fatal("unable to find mk for package: %s" % name)
        mk_full_path = os.path.join(Bos.topdir, self.mk)

        Blog.debug('start to parse .mk: %s' % self.mk)
        config = ConfigParser()
        meta = self._preprocess_mk()
        try:
            config.read(meta)
        except ParsingError as e:
            Blog.error(e.message)
            Blog.fatal("failed to parse .mk:  %s <%s>" % (name, self.mk))
        os.remove(meta)

        Blog.debug('parsing package .mk: %s' % self.mk)
        ## package description is required
        try:
            self._description = config.get('BOSMK', 'DESCRIPTION')
        except NoOptionError:
            Blog.fatal("package description missing: %s <%s>" % (name, self.mk))

        ## everything else if optional
        Blog.debug('parsing package .mk: %s optional fields.' % self.mk)
        self.require = []
        self._patch = []
        self._patched = None
        self._src = None
        self._files = {}
        for fld in dict(config.items('BOSMK')):
            if 'require' == fld:
                require = dict(config.items('BOSMK'))[
                    'require'].replace('\n', ' ').split(' ')

                for dep in require:
                    if self._native:
                        if dep[-7:] != '-native':
                            self.require.append(dep + '-native')
                            continue
                    self.require.append(dep)

            elif 'source' == fld:
                sources = dict(config.items('BOSMK'))[
                    'source'].replace('\n', ' ').split(' ')
                for s in sources:
                    if os.path.splitext(s)[1] == '.patch': self._patch.append(s)

                self._src = sources[0]

            elif fld[:5] == 'files':
                self._files.update({fld: dict(config.items('BOSMK'))[fld]})

        ## package misc
        if self._patch: self._patched = os.path.join(Bos.topdir, self._src, '.bos-patch-applied')
        self._mtime = os.path.getmtime(mk_full_path)
        self._gitdir = self._get_gitdir()

        ## installed contents directory:
        ## {package-name: [[mode ownership size path]]}
        self._contents = {}
        ## version info is available only after a successful install.
        self._version = None

        ## put it on shelf
        db = shelve.open(_get_shelf_name(name))
        db['obj'] = self
        db.close()
Exemple #2
0
    def _install(self):
        """
        install package from staging area to output area and populate DB

        examine contents in staging area to make sure that,
        - all package specified contents must exist, unless optional
        - all installed contents must associate with given package

        return: 0 if successful, error code otherwise
        """

        ## walk through package and sub-package definitions if any
        for kn in self._files:
            if kn == 'files':
                pn = self._basename
            else:
                pn = self._basename + kn[5:]

                Blog.debug('processing package: %s' % pn)

            ctx = BosInstallContext(pn, self)
            try:
                for itm in self._files[kn].split('\n'):
                    if '' == itm.strip(): continue

                    ownership, pattern, optional = _parse_install_item(itm)

                    Blog.debug('processing pattern: %s' % pattern)
                    flist = glob.glob(os.path.join(self._get_stagingdir(), pattern[1:]))
                    if (not flist) and (not optional):
                        Blog.fatal('<%s> unable to find: %s' % (self.name,  pattern))
                    for ff in flist: _install_files(ff, ownership, ctx)

                for ctnt in ctx.contents:
                    ff = ctnt[3]
                    path = os.path.join(ctx.indexdir, ff[1:])
                    if not os.path.exists(os.path.dirname(path)):
                        os.makedirs(os.path.dirname(path))
                    #with open(path, 'w') as f: f.write(ctx.name)
                    os.symlink(ctx.name, path)
            except:
                Blog.error("%s unable to install." % self.name)
                self._put_info({ctx.name:ctx.contents})
                self._uninstall()
                return -1

            Blog.debug('%s writing package info' % ctx.name)
            self._put_info({ctx.name:ctx.contents})

        ## post process: walk the stagingdir to make sure there's no files left
        try:
            for r, d, f in os.walk(self._get_stagingdir()):
                if f: Blog.fatal('installed but unpackaged contents found: %s\n%s'
                                 % (self.name, _list_dir(self._get_stagingdir())))
        except:
            Blog.error('%s unable to walk staging dir: %s'
                       % (self.name, self._get_stagingdir()))
            self._uninstall()
            return -2

        return 0