예제 #1
0
    def enableChannel(self, apturl):
        # ensure that no funny path tricks can be played
        # by e.g. passing "apt:foo?channel=../../"
        channel = os.path.basename(apturl.channel)

        channelpath = "%s/%s.list" % (channelsdir,channel)
        channelkey = "%s/%s.key" % (channelsdir,channel)
        channelhtml = "%s/%s.eula" % (channelsdir,channel)

        # check
        if not os.path.exists(channelpath):
            self.ui.error(_("Unknown channel '%s'") % channel,
                          _("The channel '%s' is not known") % channel)
            return RESULT_ERROR
        channel_info_html = ""
        if os.path.exists(channelhtml):
            channel_info_html = open(channelhtml).read()
        if not self.ui.askEnableChannel(apturl.channel, channel_info_html):
            return RESULT_CANCELT
        if not self.ui.doEnableChannel(channelpath, channelkey):
            self.ui.error(_("Enabling channel '%s' failed") % apturl.channel)
            return RESULT_ERROR
        self.ui.doUpdate()
        self.openCache()
        return RESULT_OK
예제 #2
0
def set_value(apt_url, s):
    " set a key,value pair from string s to AptUrl object "
    (key, value) = s.split("=")
    try:
        if ' ' in value:
            raise InvalidUrlException(apt_url, _("Whitespace in key=value"))
        if type(getattr(apt_url, key)) == type([]):
            getattr(apt_url, key).append(value)
        else:
            setattr(apt_url, key, value)
    except Exception, e:
        raise InvalidUrlException(apt_url, _("Exception '%s'") % e)
예제 #3
0
def parse(full_url, mapping=apturl_substitution_mapping):
    " parse an apt url and return a list of AptUrl objects "
    # apt:pkg1?k11=v11?k12=v12,pkg2?k21=v21?k22=v22,...
    res = []
    
    if len(full_url) > MAX_URL_LEN:
        url = "%s ..." % full_url[0:MAX_URL_LEN/10]
        raise InvalidUrlException(url, _("Url string '%s' too long") % url)

    # check against whitelist
    match_against_whitelist(full_url)
    for url in full_url.split(";"):
        if not ":" in url:
            raise InvalidUrlException(url, _("No ':' in the uri"))

        # now parse it

        (schema, packages) = url.split(":", 1)
        packages = packages.split(",")

        for package in packages:
            apt_url = AptUrl()
            apt_url.schema = schema
            # check for schemas of the form: apt+http://
            if schema.startswith("apt+"):
                apt_url.repo_url = schema[len("apt+"):] + ":" + package.split("?",1)[0]
            else:
                if "?" in package:
                    apt_url.package = package.split("?")[0].lstrip("/")
                else:
                    apt_url.package = package.lstrip("/")

            # now parse the ?... bits
            if "?" in package:
                key_value_pairs = package.split("?")[1:]
                for s in key_value_pairs:
                    if "&" in s:
                        and_key_value_pairs = s.split("&")
                        for s in and_key_value_pairs:
                            set_value(apt_url, s)
                    else:
                        set_value(apt_url, s)

            # do substitution (if needed) 
            do_apt_url_substitution(apt_url, mapping)
            
            # check if the package name is valid
            if not is_format_package_name(apt_url.package):
                raise InvalidUrlException(url, "Invalid package name '%s'" % apt_url.package)
            
            res.append(apt_url)
    return res    
예제 #4
0
    def enableSection(self, apturl):
        added = False

        # parse sources.list
        sourceslist = SourcesList()
        distro = aptsources.distro.get_distro()
        distro.get_sources(sourceslist)

        # check if we actually need to enable anything
        requested_components = []
        for component in apturl.section:
            if not component in distro.enabled_comps:
                requested_components.append(component)
        # if not, we are fine
        if not requested_components:
            return RESULT_OK
        # otherwise ask the user if the really wants to anble them
        if not self.ui.askEnableSections(apturl.section):
            return RESULT_CANCELT
        if not self.ui.doEnableSection(apturl.section):
            self.ui.error(_("Enabling '%s' failed") % ", ".join(apturl.section))
            return RESULT_ERROR
        self.ui.doUpdate()
        self.openCache()
        return RESULT_OK
예제 #5
0
 def openCache(self):
     try:
         self.cache = apt.Cache()
     except SystemError, strerr:
         if not '/etc/apt/sources.list' in str(strerr):
             raise
         self.ui.error(_("Invalid /etc/apt/sources.list file"), strerr)
         return False
예제 #6
0
 def askEnableSections(self, sections):
     " generic implementation, can be overridden "
     return self.yesNoQuestion(
         _("Enable additional components"),
         _n(
             "Do you want to enable the following " "component: '%s'?",
             "Do you want to enable the following " "components: '%s'?",
             len(sections),
         )
         % ", ".join(sections),
     )
예제 #7
0
    def parseArgs(self):
        parser = OptionParser()
        parser.add_option("-p", "--http-proxy", dest="http_proxy",
                          default=None, help="use http proxy")
        (options, args) = parser.parse_args()

        # eval and add proxy
        if options.http_proxy is not None:
            proxy = options.http_proxy
            if not ":" in proxy:
                proxy += ":3128"
            os.environ["http_proxy"] = "http://%s" % proxy

        # parse
        try:
            apturl_list = Parser.parse(args[0])
        except IndexError, e:
            self.ui.error(_("Need a url to continue, exiting"))
            return []
예제 #8
0
 def askEnableChannel(self, channel, channel_info_html):
     " generic implementation, can be overridden "
     return self.yesNoQuestion(
         _("Enable additional software channel"),
         _("Do you want to enable the following " "software channel: '%s'?") % channel,
     )
예제 #9
0
    def main(self):
        # global return code
        ret = RESULT_OK
        ui = self.ui
        
        # parse arguments
        apturl_list = self.parseArgs()
        if not apturl_list:
            return RESULT_BADARGS
        
        # open cache
        if not self.openCache():
            return RESULT_ERROR

        # now go over the url list
        for apturl in apturl_list:
            # FIXME: move this code block into a func like
            #        evalAptUrl()

            if not apturl.schema in ("apt", "apt+http"):
                self.ui.error(_("Can not deal with protocol '%s' ") % apturl.schema)
                continue

            if apturl.section:
                if self.enableSection(apturl) != RESULT_OK:
                    continue
            elif apturl.channel:
                if self.enableChannel(apturl) != RESULT_OK:
                    continue
            elif apturl.refresh is not None:
                ui.doUpdate()
                if not self.openCache():
                    return RESULT_ERROR
            
            # now check the package
            if not self.cache.has_key(apturl.package):
                try:
                    package_in_cache = bool(self.cache._cache[apturl.package])
                except KeyError:
                    package_in_cache = False
                if package_in_cache:
                    ui.error(_("Package '%s' is virtual.") % apturl.package)
                    continue
                else:
                    ui.error(_("Could not find package '%s'.") % apturl.package)
                    continue
            
            if self.cache[apturl.package].isInstalled and apturl.minver is None:
                ui.message(_("Package '%s' is already installed") % apturl.package)
                continue

            # ask the user
            pkg = self.cache[apturl.package]
            (sum, desc, homepage) = Helpers.parse_pkg(pkg)
            if not ui.askInstallPackage(apturl.package, sum, desc, homepage):
                ret = RESULT_CANCELT
                continue
            
            # try to install it
            try:
                self.cache[apturl.package].markInstall()
            except SystemError, e:
                ui.error(_("Can not install '%s' (%s) ") % (apturl.package, e))
                continue
            if apturl.minver is not None:
                verStr = self.cache[apturl.package].candidateVersion
                if apt_pkg.VersionCompare(verStr, apturl.minver) < 1:
                    ui.error(_("Package '%s' requests minimal version '%s', but "
                               "only '%s' is available") % (apturl.package,
                                                            apturl.minver,
                                                            verStr))
                    continue

            # install it
            ui.doInstall(apturl)

            if not self.verifyInstall(apturl):
                ret = RESULT_ERROR
예제 #10
0
        # eval and add proxy
        if options.http_proxy is not None:
            proxy = options.http_proxy
            if not ":" in proxy:
                proxy += ":3128"
            os.environ["http_proxy"] = "http://%s" % proxy

        # parse
        try:
            apturl_list = Parser.parse(args[0])
        except IndexError, e:
            self.ui.error(_("Need a url to continue, exiting"))
            return []
        except Parser.InvalidUrlException, e:
            self.ui.error(_("Invalid url: '%s' given, exiting") % e.url.decode('utf-8'),
                          unicode(e))
            return []
        return (apturl_list)
        
    def verifyInstall(self, apturl):
        " verify that the install package actually is installed "
        # check if the package got actually installed
        self.openCache()
        pkg = self.cache[apturl.package]
        if (not pkg.isInstalled or
            pkg._pkg.CurrentState != apt_pkg.CurStateInstalled or
            self.cache._depcache.BrokenCount > 0):
            return False
        return True
예제 #11
0
def match_against_whitelist(raw_url):
    " test if the url matches the internal whitelist "
    for char in raw_url:
        if not char in whitelist:
            raise InvalidUrlException(raw_url, _("Non whitelist char in the uri"))
    return True
예제 #12
0
        # eval and add proxy
        if options.http_proxy is not None:
            proxy = options.http_proxy
            if not ":" in proxy:
                proxy += ":3128"
            os.environ["http_proxy"] = "http://%s" % proxy

        # parse
        try:
            apturl_list = Parser.parse(args[0])
        except IndexError, e:
            self.ui.error(_("Need a url to continue, exiting"))
            return []
        except Parser.InvalidUrlException, e:
            self.ui.error(_("Invalid url: '%s' given, exiting") % e.url,
                          "%s" % str(e))
            return []
        return (apturl_list)
        
    def verifyInstall(self, apturl):
        " verify that the install package actually is installed "
        # check if the package got actually installed
        self.openCache()
        pkg = self.cache[apturl.package]
        if (not pkg.isInstalled or
            pkg._pkg.CurrentState != apt_pkg.CurStateInstalled or
            self.cache._depcache.BrokenCount > 0):
            return False
        return True