Beispiel #1
0
    def execute(self, options_dict, non_option_args):
        if len(non_option_args) < 1:
            self.usage()
            return False

        plist = []
        yum = self.yum()

        for dep in non_option_args:
            if yum.returnInstalledPackagesByDep (dep):
                continue

            try:
                pkg = yum.returnPackageByDep(dep)
                plist.append(pkg.name)
            except:
                rucktalk.error("Unable to satisfy requirement '%s'" % dep)
                return False

        installs, updates = self.find_available_packages(plist)
        if not installs and not updates:
            rucktalk.message("Requirements are already met on the system.");
            return True

        for i in installs:
            yum.install(i)

        for u in updates:
            exactmatches, matches, unmatched = self.find_packages([u.name], installed=True)
            yum.tsInfo.addUpdate(u, exactmatches[0])

        self.start_transaction(dryrun=options_dict.has_key('dry-run'))
Beispiel #2
0
def usage_full():
    rucktalk.message("Usage: ruck <command> <options> ...")
    rucktalk.message("")

    rucktalk.message("The following options are understood by all commands:")
    ruckformat.opt_table(default_opt_table)

    keys = command_dict.keys()

    if keys:
        command_list = []
        for k in keys:
            description, constructor, aliases, hidden, basic, category  = command_dict[k]
            if not hidden:
                command_list.append([k, aliases, description, category])

        print_command_list(command_list, with_categories=1)

        rucktalk.message("")
        rucktalk.message("For more detailed information about a specific command,")
        rucktalk.message("run 'ruck <command name> --help'.")
        rucktalk.message("")

    else:
        rucktalk.error("<< No commands found --- something is wrong! >>")
Beispiel #3
0
    def execute(self, options_dict, non_option_args):
        size = len(non_option_args)
        if size < 1:
            self.usage()
            return False

        table_rows = []
        yum = self.yum()

        for file in non_option_args:
            if not os.access (file, os.F_OK):
                rucktalk.error("File %s does not exist" % file)
                continue

            matches = yum.rpmdb.searchFiles (file);
            if not matches:
                rucktalk.message("No package owns file %s" % file)
                continue

            for pkg in matches:
                row = ruckformat.package_to_row(yum, pkg, False, ["name", "version"])
                if size > 1:
                    row.insert (0, file)
                table_rows.append (row)

        if len(table_rows):
            if size == 1:
                ruckformat.tabular(["Name", "Version"], table_rows)
            else:
                ruckformat.tabular(["File", "Name", "Version"], table_rows)
Beispiel #4
0
    def execute(self, options_dict, non_option_args):
        if len(non_option_args) != 1:
            self.usage()
            return False

        locks = rucklocks.get_locks()
        i = int(non_option_args[0]) - 1

        if i >= len(locks):
            rucktalk.error("Invalid lock %s" % str(i + 1))
            return False

        rucklocks.remove_lock(i)
        rucktalk.message("--- Lock successfully removed ---")
Beispiel #5
0
    def execute(self, options_dict, non_option_args):
        if len(non_option_args) != 2:
            self.usage()
            return False

        repoid = non_option_args[0]
        url = non_option_args[1]

        if not self.check_url(url):
            rucktalk.error("Invalid url '%s'" % url)
            return False

        if self.find_repo_file(repoid) != None:
            rucktalk.error("Repository '%s' already exists" % repoid)
            return False

        yum = self.yum(repos=False)

        repopath = os.path.join(yum.conf.reposdir[0], repoid + ".repo")
        if not os.path.exists(os.path.dirname(repopath)):
            os.makedirs(os.path.dirname(repopath))

        parser = ConfigParser()
        parser.add_section(repoid)

        name = repoid
        if options_dict.has_key('name'):
            name = options_dict['name']

        parser.set(repoid, "name", name)

        if options_dict.has_key('mirrorlist'):
            parser.set(repoid, "mirrorlist", url)
        else:
            parser.set(repoid, "baseurl", url)

        parser.set(repoid, "enabled", "1")

        gpgval = "0"
        if options_dict.has_key('check-signatures'):
            gpgval = "1"

        parser.set(repoid, "gpgcheck", gpgval)



        parser.write(file(repopath, "w+"))

        rucktalk.message("--- Successfully added '%s' ---" % repoid)
Beispiel #6
0
    def gpgsigcheck(self, pkgs):
        yum = self.yum()

        for p in pkgs:
            result, errmsg = yum.sigCheckPkg(p)
            if result == 0:
                # woo!
                pass
            elif result == 1:
                # FIXME: need to download gpg
                rucktalk.error("Ignoring missing gpg key.")
                pass
            else:
                yumtalk.error(errmsg)
                return False

        return True
Beispiel #7
0
    def execute(self, options_dict, non_option_args):
        if len(non_option_args) < 1 or (options_dict.has_key('uninstalled-only') and options_dict.has_key('installed-only')):
            self.usage()
            return False

        table_rows = []
        yum = self.yum()
        dtype = self.dep_type();

        plist = []
        unmatched1 = None
        unmatched2 = None

        if not options_dict.has_key('uninstalled-only'):
            exactmatches, matches, unmatched1 = self.find_packages (non_option_args, installed=True)
            plist = exactmatches + matches

        if not options_dict.has_key('installed-only'):
            exactmatches, matches, unmatched2 = self.find_packages (non_option_args, installed=False)
            plist += exactmatches
            plist += matches

        if (unmatched1 is None or len(unmatched1) > 0) and (unmatched2 is None or len(unmatched2)) > 0:
            if unmatched1 != None:
                arg = unmatched1[0]
            else:
                arg = unmatched2[0]

            rucktalk.error("Could not find package '%s'" % arg)
            return False

        for p in plist:
            rucktalk.message("--- %s ---" % ruckformat.package_to_str(p))
            deps = p.returnPrco(dtype)

            if len(deps) == 0:
                rucktalk.message("\nNo %s found\n" % dtype)
            else:
                for dep in deps:
                    #FIXME: piece of crap prcoPrintable sometimes chokes
                    try:
                        rucktalk.message(p.prcoPrintable(dep))
                    except:
                        pass
                rucktalk.message('')
Beispiel #8
0
    def execute(self, options_dict, non_option_args):
        if len(non_option_args) < 1:
            self.usage()
            return 1

        yum = self.yum()

        exactmatches, matches, unmatched = self.find_packages(non_option_args, installed=1)
        if len(unmatched) > 0:
            rucktalk.error("Could not find package '%s'" % unmatched[0])
            return False

        plist = exactmatches + matches

        for p in plist:
            yum.remove(p)

        self.start_transaction(dryrun=options_dict.has_key('dry-run'))
Beispiel #9
0
    def execute(self, options_dict, non_option_args):
        if len(non_option_args) != 1:
            self.usage()
            return False

        repoid = non_option_args[0]
        repopath = self.find_repo_file(repoid)
        if repopath == None:
            rucktalk.error("Repository '%s' does not exist" % repoid)
            return False

        parser = ConfigParser()
        parser.read(repopath)
        parser.remove_section(repoid)
        if len(parser.sections()) == 0:
            os.unlink(repopath)
        else:
            parser.write(file(repopath, 'w+'))

        rucktalk.message("--- Successfully removed '%s' ---" % repoid)
Beispiel #10
0
    def execute(self, options_dict, non_option_args):
        if len(non_option_args) < 1:
            self.usage()
            return 1

        pk = self.pkcon()

        for arg in non_option_args:
            if os.path.exists(arg):
                rucktalk.error("This hasn't been implemented yet") # FIXME
            else:
                installs, removals = self.separate_args(non_option_args)

                pkids = pk.resolve(installs)
                if len(pkids) > 0:
                    pk.install_packages(pkids)
                else:
                    rucktalk.error("No packages found")
                    return 1

                if len(removals) > 0:
                    pk.remove_packages(removals)
Beispiel #11
0
def usage_basic():
    rucktalk.message("Usage: ruck <command> <options> ...")
    rucktalk.message("")

    keys = command_dict.keys()

    if keys:
        keys.sort()
        command_list = []
        for k in keys:
            description, constructor, aliases, hidden, basic, category  = command_dict[k]
            if not hidden and basic:
                command_list.append([k, aliases, description, category])

        rucktalk.message("Some basic commands are:")
        print_command_list(command_list)

        rucktalk.message("")
        rucktalk.message("For a more complete list of commands and important options,")
        rucktalk.message("run \"ruck help\".")
        rucktalk.message("")

    else:
        rucktalk.error("<< No commands found --- something is wrong! >>")
Beispiel #12
0
def show_exception(e):
    if rucktalk.show_verbose:
        trace = ""
        exception = ""
        exc_list = traceback.format_exception_only(sys.exc_type, sys.exc_value)
        for entry in exc_list:
            exception += entry
            tb_list = traceback.format_tb(sys.exc_info()[2])
            for entry in tb_list:
                trace += entry

        rucktalk.error(str(e))
        rucktalk.error(trace)
    else:
        rucktalk.error(str(e))
Beispiel #13
0
def register(constructor):
    obj = constructor()
    name = obj.name()
    aliases = obj.aliases()
    hidden = obj.is_hidden()
    basic = obj.is_basic()
    description = obj.description_short() or "<No Description Available>"
    category = obj.category()

    if command_dict.has_key(name):
        rucktalk.error("Command name collision: '"+name+"'")
    else:
        command_dict[name] = (description, constructor, aliases, hidden, basic, category)

    for a in aliases:
        al = string.lower(a)
        if command_dict.has_key(al):
            rucktalk.error("Command/alias collision: '"+a+"'")
        elif alias_dict.has_key(al):
            rucktalk.error("Alias collision: '"+a+"'")
        else:
            alias_dict[al] = name
Beispiel #14
0
    def start_transaction(self, dryrun=False, download_only=False):
        yum = self.yum()

        if not download_only:
            (rescode, resmsgs) = self.resolve_deps()
            if rescode != 2:
                for resmsg in resmsgs:
                    rucktalk.error(resmsg)

                return False

        self.show_ts_packages()

        if self.tsInfo_is_empty(yum.tsInfo):
            rucktalk.warning("Nothing to do.")
            return False

        downloadpkgs = self.get_pkgs_to_download()

        if len(downloadpkgs) > 0:
            total_size = 0

            for p in downloadpkgs:
                try:
                    size = int(p.size())
                    total_size += size
                except:
                    pass

            if total_size > 0:
                rucktalk.message("\nTotal download size: %s\n" % (ruckformat.bytes_to_str(total_size)))

        if self.need_prompt():
            answer = raw_input('\nProceed with transaction? (y/N) ')
            if len(answer) != 1 or answer[0] != 'y':
                rucktalk.message('Transaction Canceled')
                return False

        problems = yum.downloadPkgs(downloadpkgs)
        if len(problems.keys()) > 0:
            rucktalk.error("Error downloading packages:")
            for key in problems.keys():
                for error in unique(problems[key]):
                    rucktalk.message("  %s: %s" % (key, error))
            return False

        if download_only:
            for pkg in downloadpkgs:
                dest = ruckformat.package_to_str(pkg, repo=False) + ".rpm"
                shutil.move(pkg.localpath, dest)
                rucktalk.message ("Downloaded '%s'" % dest)

            return True

        # Check GPG signatures
        if not self.gpgsigcheck(downloadpkgs):
            return False

        tsConf = {}
        for feature in ['diskspacecheck']: # more to come, I'm sure
                tsConf[feature] = getattr(yum.conf, feature)

        if dryrun:
            testcb = ruckyum.RPMInstallCallback(output=1)
            testcb.tsInfo = yum.tsInfo
            # clean out the ts b/c we have to give it new paths to the rpms
            del yum.ts

            yum.initActionTs()
            yum.populateTs(keepold=0) # sigh
            tserrors = yum.ts.test(testcb, conf=tsConf)
            del testcb

            if len(tserrors) > 0:
                errstring = ''
                for descr in tserrors:
                    errstring += '  %s\n' % descr

                rucktalk.error(errstring)
                return False

        else:
            rucktalk.message('Running Transaction Test')

            testcb = ruckyum.RPMInstallCallback(output=0)
            testcb.tsInfo = yum.tsInfo
            # clean out the ts b/c we have to give it new paths to the rpms
            del yum.ts

            yum.initActionTs()
            # save our dsCallback out
            dscb = yum.dsCallback
            yum.dsCallback = None # dumb, dumb dumb dumb!
            yum.populateTs(keepold=0) # sigh
            tserrors = yum.ts.test(testcb, conf=tsConf)
            del testcb

            if len(tserrors) > 0:
                errstring = 'Transaction Check Error: '
                for descr in tserrors:
                    errstring += '  %s\n' % descr

                rucktalk.error(errstring)
                return False

            rucktalk.message('Transaction Test Succeeded\n')
            del yum.ts

            yum.initActionTs() # make a new, blank ts to populate
            yum.populateTs(keepold=0) # populate the ts
            yum.ts.check() #required for ordering
            yum.ts.order() # order

            # put back our depcheck callback
            yum.dsCallback = dscb

            cb = ruckyum.RPMInstallCallback(output=1)
            cb.tsInfo = yum.tsInfo

            yum.runTransaction(cb=cb)

        rucktalk.message('\nTransaction Finished')
        return True
Beispiel #15
0
def expand_synthetic_args(argv):

    ###
    ### First, walk across our argument list and find any --read-from-file
    ### options.  For each, read the arguments from the file and insert
    ### them directly after the --read-from-file option.
    ###

    i = 0
    is_file_to_read_from = 0
    while i < len(argv):
        arg = argv[i]
        file_to_read = None
        if is_file_to_read_from:
            file_to_read = arg
            is_file_to_read_from = 0
        if arg == "--read-from-file":
            is_file_to_read_from = 1
        elif string.find(arg, "--read-from-file=") == 0:
            file_to_read = arg[len("--read-from-file="):]
            is_file_to_read_from = 0

        if file_to_read:
            lines = []
            try:
                f = open(file_to_read, "r")
                lines = map(string.strip, f.readlines())
            except IOError:
                rucktalk.error("Couldn't open file '%s' to read arguments" % file_to_read)
                sys.exit(1)
            argv = argv[:i] + lines + argv[i+1:]
            i = i + len(lines)

        i = i + 1

    ###
    ### Next, look for --read-from-stdin options.  If there is more than
    ### one on the command line, we split our list of options on blank
    ### lines.
    ###

    rfs_count = argv.count("--read-from-stdin")
    if rfs_count > 0:
        lines = map(string.strip, sys.stdin.readlines())

        i = 0  # position in argv
        j = 0  # position in lines
        while i < len(argv):

            if argv[i] == "--read-from-stdin":

                if j < len(lines):
                    if rfs_count > 1 and "" in lines[j:]:
                        j1 = j + lines[j:].index("")
                        argv = argv[:i+1] + lines[j:j1] + argv[i+1:]
                        j = j1+1
                    else:
                        argv = argv[:i+1] + \
                               filter(lambda x:x!="", lines[j:]) + \
                               argv[i+1:]
                        j = len(lines)


                rfs_count = rfs_count - 1

            i = i + 1

    ###
    ### Finally, we filter our all of those --read-from-* arguments
    ### that we left lying around in argv.
    ###

    argv = filter(lambda x: \
                  string.find(x,"--read-from-file") != 0 \
                  and x != "--read-from-stdin",
                  argv)

    return argv
Beispiel #16
0
 def errorlog(self, level, message):
     rucktalk.error(message)
Beispiel #17
0
 def execute(self, server, options_dict, non_option_args):
     rucktalk.error("Execute not implemented!")
     sys.exit(1)
Beispiel #18
0
def main(ver, ruck_dir):

    global local
    global ruck_version

    ruck_version = ver

    if os.environ.has_key("RUCK_DEBUG"):
        rucktalk.show_debug = 1

    import rucklocks

    rucklocks.init()

    import_commands(ruck_dir)

    ###
    ### Grab the option list and extract the first non-option argument that
    ### looks like a command.  This could get weird if someone passes the name
    ### of a command as the argument to an option.
    ###

    argv = sys.argv[1:]

    argv = ruckcommand.expand_synthetic_args(argv)

    if "--version" in argv:
        print
        print ruck_name + " " + ruck_version
        print ruck_copyright
        print
        sys.exit(0)

    command = ruckcommand.extract_command_from_argv(argv)

    if "-?" in argv or "--help" in argv:
        command.usage()
        sys.exit(0)

    # A hack to suppress extra whitespace when dumping.
    if command.name() == "dump":
        rucktalk.be_terse = 1

    argv = ruckcommand.get_user_default_args(argv, command)

    opt_dict, args = command.process_argv(argv)

    ###
    ### Control verbosity
    ###

    if opt_dict.has_key("terse"):
        rucktalk.be_terse = 1

    if opt_dict.has_key("quiet"):
        rucktalk.show_messages = 0
        rucktalk.show_warnings = 0

    if opt_dict.has_key("verbose"):
        rucktalk.show_verbose = 1

    ### Whitespace is nice, so we always print a blank line before
    ### executing the command

    if not rucktalk.be_terse:
        rucktalk.message("")

    if opt_dict.has_key("cache-only") or os.getuid() != 0:
        command.cache_only = True
    elif opt_dict.has_key("no-plugins"):
        command.no_plugins = True

    try:
        command.execute(opt_dict, args)
    except IOError, e:
        if e.errno == 13:
            rucktalk.error("You must be root to execute this command")
        else:
            show_exception(e)

        sys.exit(1)
Beispiel #19
0
    def process_argv(self, argv):
        ###
        ### Expand our synthetic args.
        ### Then compile our list of arguments into something that getopt can
        ### understand.  Finally, call getopt on argv and massage the results
        ### in something easy-to-use.
        ###

        argv = get_user_default_args(argv, self.name())

        opt_table = self.opt_table()

        short_opt_getopt = ""
        long_opt_getopt  = []

        short2long_dict = {}

        for o in opt_table:

            short_opt = o[0]
            long_opt  = o[1]
            opt_desc  = o[2]

            if short_opt:

                if short2long_dict.has_key(short_opt):
                    rucktalk.error("Short option collision!")
                    rucktalk.error("-" + short_opt + ", --" + long_opt)
                    rucktalk.error("  vs.")
                    rucktalk.error("-" + short_opt + ", --" + short2long_dict[short_opt])
                    sys.exit(1)

                short2long_dict[short_opt] = long_opt
                short_opt_getopt = short_opt_getopt + short_opt
                if opt_desc:
                    short_opt_getopt = short_opt_getopt + ":"

            if opt_desc:
                long_opt_getopt.append(long_opt + "=")
            else:
                long_opt_getopt.append(long_opt)

        try:
            optlist, args = getopt.getopt(argv, short_opt_getopt, long_opt_getopt)
        except getopt.error:
            did_something = 0
            for a in argv:
                if string.find(a,"--") == 0:
                    if not a[2:] in map(lambda x:x[1], opt_table):
                        rucktalk.error("Invalid argument " + a)
                        did_something = 1
                elif string.find(a, "-") == 0:
                    if not a[1:] in map(lambda x:x[0], opt_table):
                        rucktalk.error("Invalid argument " + a)
                        did_something = 1

            # Just in case something strange went wrong and we weren't
            # able to describe quite why the options parsing failed,
            # we print a catch-all error message.
            if not did_something:
                rucktalk.error("Invalid arguments")

            self.usage()

            sys.exit(1)

        ###
        ### Walk through our list of options and replace short options with the
        ### corresponding long option.
        ###

        i = 0
        while i < len(optlist):
            key = optlist[i][0]
            if key[0:2] != "--":
                optlist[i] = ("--" + short2long_dict[key[1:]], optlist[i][1])
            i = i + 1


        ###
        ### Get the list of "orthogonal" options for this command and, if our
        ### list of options contains orthogonal elements, remove all but the
        ### last such option.
        ### (i.e. if we are handed --quiet --verbose, we drop the --quiet)
        ###

        optlist.reverse()
        for oo_list in self.orthogonal_opts():
            i = 0
            seen_oo = 0
            while i < len(optlist):
                key = optlist[i][0]
                if key[2:] in oo_list:
                    if seen_oo:
                        del optlist[i]
                        i = i - 1
                    seen_oo = 1
                i = i + 1
        optlist.reverse()

        ###
        ### Store our options in a dictionary
        ###

        opt_dict = {}

        for key, value in optlist:
            opt_dict[key[2:]] = value


        return opt_dict, args