1861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li#!/usr/bin/python
2861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li"""
3861b2d54aec24228cdb3895dbc40062cb40cb2adEric LiSoftware package management library.
4861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li
5861b2d54aec24228cdb3895dbc40062cb40cb2adEric LiThis is an abstraction layer on top of the existing distributions high level
6861b2d54aec24228cdb3895dbc40062cb40cb2adEric Lipackage managers. It supports package operations useful for testing purposes,
7861b2d54aec24228cdb3895dbc40062cb40cb2adEric Liand multiple high level package managers (here called backends). If you want
8861b2d54aec24228cdb3895dbc40062cb40cb2adEric Lito make this lib to support your particular package manager/distro, please
9861b2d54aec24228cdb3895dbc40062cb40cb2adEric Liimplement the given backend class.
10861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li
11861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li@author: Higor Vieira Alves (halves@br.ibm.com)
12861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li@author: Lucas Meneghel Rodrigues (lmr@redhat.com)
13861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li@author: Ramon de Carvalho Valle (rcvalle@br.ibm.com)
14861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li
15861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li@copyright: IBM 2008-2009
16861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li@copyright: Red Hat 2009-2010
17861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li"""
18861b2d54aec24228cdb3895dbc40062cb40cb2adEric Liimport os, re, logging, ConfigParser, optparse, random, string
19861b2d54aec24228cdb3895dbc40062cb40cb2adEric Litry:
20861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li    import yum
21861b2d54aec24228cdb3895dbc40062cb40cb2adEric Liexcept:
22861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li    pass
23861b2d54aec24228cdb3895dbc40062cb40cb2adEric Liimport common
24861b2d54aec24228cdb3895dbc40062cb40cb2adEric Lifrom autotest_lib.client.bin import os_dep, utils
25861b2d54aec24228cdb3895dbc40062cb40cb2adEric Lifrom autotest_lib.client.common_lib import error
26861b2d54aec24228cdb3895dbc40062cb40cb2adEric Lifrom autotest_lib.client.common_lib import logging_config, logging_manager
27861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li
28861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li
29861b2d54aec24228cdb3895dbc40062cb40cb2adEric Lidef generate_random_string(length):
30861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li    """
31861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li    Return a random string using alphanumeric characters.
32861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li
33861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li    @length: Length of the string that will be generated.
34861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li    """
35861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li    r = random.SystemRandom()
36861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li    str = ""
37861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li    chars = string.letters + string.digits
38861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li    while length > 0:
39861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li        str += r.choice(chars)
40861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li        length -= 1
41861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li    return str
42861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li
43861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li
44861b2d54aec24228cdb3895dbc40062cb40cb2adEric Liclass SoftwareManagerLoggingConfig(logging_config.LoggingConfig):
45861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li    """
46861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li    Used with the sole purpose of providing convenient logging setup
47861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li    for the KVM test auxiliary programs.
48861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li    """
49861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li    def configure_logging(self, results_dir=None, verbose=False):
50861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li        super(SoftwareManagerLoggingConfig, self).configure_logging(
51861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li                                                            use_console=True,
52861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li                                                            verbose=verbose)
53861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li
54861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li
55861b2d54aec24228cdb3895dbc40062cb40cb2adEric Liclass SystemInspector(object):
56861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li    """
57861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li    System inspector class.
58861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li
59861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li    This may grow up to include more complete reports of operating system and
60861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li    machine properties.
61861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li    """
62861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li    def __init__(self):
63861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li        """
64861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li        Probe system, and save information for future reference.
65861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li        """
66861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li        self.distro = utils.get_os_vendor()
67861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li        self.high_level_pms = ['apt-get', 'yum', 'zypper']
68861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li
69861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li
70861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li    def get_package_management(self):
71861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li        """
72861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li        Determine the supported package management systems present on the
73861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li        system. If more than one package management system installed, try
74861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li        to find the best supported system.
75861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li        """
76861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li        list_supported = []
77861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li        for high_level_pm in self.high_level_pms:
78861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li            try:
79861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li                os_dep.command(high_level_pm)
80861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li                list_supported.append(high_level_pm)
81861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li            except:
82861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li                pass
83861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li
84861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li        pm_supported = None
85861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li        if len(list_supported) == 0:
86861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li            pm_supported = None
87861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li        if len(list_supported) == 1:
88861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li            pm_supported = list_supported[0]
89861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li        elif len(list_supported) > 1:
90861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li            if 'apt-get' in list_supported and self.distro in ['Debian', 'Ubuntu']:
91861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li                pm_supported = 'apt-get'
92861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li            elif 'yum' in list_supported and self.distro == 'Fedora':
93861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li                pm_supported = 'yum'
94861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li            else:
95861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li                pm_supported = list_supported[0]
96861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li
97861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li        logging.debug('Package Manager backend: %s' % pm_supported)
98861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li        return pm_supported
99861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li
100861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li
101861b2d54aec24228cdb3895dbc40062cb40cb2adEric Liclass SoftwareManager(object):
102861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li    """
103861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li    Package management abstraction layer.
104861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li
105861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li    It supports a set of common package operations for testing purposes, and it
106861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li    uses the concept of a backend, a helper class that implements the set of
107861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li    operations of a given package management tool.
108861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li    """
109861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li    def __init__(self):
110861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li        """
111861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li        Class constructor.
112861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li
113861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li        Determines the best supported package management system for the given
114861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li        operating system running and initializes the appropriate backend.
115861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li        """
116861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li        inspector = SystemInspector()
117861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li        backend_type = inspector.get_package_management()
118861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li        if backend_type == 'yum':
119861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li            self.backend = YumBackend()
120861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li        elif backend_type == 'zypper':
121861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li            self.backend = ZypperBackend()
122861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li        elif backend_type == 'apt-get':
123861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li            self.backend = AptBackend()
124861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li        else:
125861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li            raise NotImplementedError('Unimplemented package management '
126861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li                                      'system: %s.' % backend_type)
127861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li
128861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li
129861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li    def check_installed(self, name, version=None, arch=None):
130861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li        """
131861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li        Check whether a package is installed on this system.
132861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li
133861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li        @param name: Package name.
134861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li        @param version: Package version.
135861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li        @param arch: Package architecture.
136861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li        """
137861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li        return self.backend.check_installed(name, version, arch)
138861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li
139861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li
140861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li    def list_all(self):
141861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li        """
142861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li        List all installed packages.
143861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li        """
144861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li        return self.backend.list_all()
145861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li
146861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li
147861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li    def list_files(self, name):
148861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li        """
149861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li        Get a list of all files installed by package [name].
150861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li
151861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li        @param name: Package name.
152861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li        """
153861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li        return self.backend.list_files(name)
154861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li
155861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li
156861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li    def install(self, name):
157861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li        """
158861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li        Install package [name].
159861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li
160861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li        @param name: Package name.
161861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li        """
162861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li        return self.backend.install(name)
163861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li
164861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li
165861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li    def remove(self, name):
166861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li        """
167861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li        Remove package [name].
168861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li
169861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li        @param name: Package name.
170861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li        """
171861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li        return self.backend.remove(name)
172861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li
173861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li
174861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li    def add_repo(self, url):
175861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li        """
176861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li        Add package repo described by [url].
177861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li
178861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li        @param name: URL of the package repo.
179861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li        """
180861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li        return self.backend.add_repo(url)
181861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li
182861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li
183861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li    def remove_repo(self, url):
184861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li        """
185861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li        Remove package repo described by [url].
186861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li
187861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li        @param url: URL of the package repo.
188861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li        """
189861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li        return self.backend.remove_repo(url)
190861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li
191861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li
192861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li    def upgrade(self):
193861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li        """
194861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li        Upgrade all packages available.
195861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li        """
196861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li        return self.backend.upgrade()
197861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li
198861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li
199861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li    def provides(self, file):
200861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li        """
201861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li        Returns a list of packages that provides a given capability to the
202861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li        system (be it a binary, a library).
203861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li
204861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li        @param file: Path to the file.
205861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li        """
206861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li        return self.backend.provides(file)
207861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li
208861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li
209861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li    def install_what_provides(self, file):
210861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li        """
211861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li        Installs package that provides [file].
212861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li
213861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li        @param file: Path to file.
214861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li        """
215861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li        provides = self.provides(file)
216861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li        if provides is not None:
217861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li            self.install(provides)
218861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li        else:
219861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li            logging.warning('No package seems to provide %s', file)
220861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li
221861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li
222861b2d54aec24228cdb3895dbc40062cb40cb2adEric Liclass RpmBackend(object):
223861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li    """
224861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li    This class implements operations executed with the rpm package manager.
225861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li
226861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li    rpm is a lower level package manager, used by higher level managers such
227861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li    as yum and zypper.
228861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li    """
229861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li    def __init__(self):
230861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li        self.lowlevel_base_cmd = os_dep.command('rpm')
231861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li
232861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li
233861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li    def _check_installed_version(self, name, version):
234861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li        """
235861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li        Helper for the check_installed public method.
236861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li
237861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li        @param name: Package name.
238861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li        @param version: Package version.
239861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li        """
240861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li        cmd = (self.lowlevel_base_cmd + ' -q --qf %{VERSION} ' + name +
241861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li               ' 2> /dev/null')
242861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li        inst_version = utils.system_output(cmd)
243861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li
244861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li        if inst_version >= version:
245861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li            return True
246861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li        else:
247861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li            return False
248861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li
249861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li
250861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li    def check_installed(self, name, version=None, arch=None):
251861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li        """
252861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li        Check if package [name] is installed.
253861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li
254861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li        @param name: Package name.
255861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li        @param version: Package version.
256861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li        @param arch: Package architecture.
257861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li        """
258861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li        if arch:
259861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li            cmd = (self.lowlevel_base_cmd + ' -q --qf %{ARCH} ' + name +
260861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li                   ' 2> /dev/null')
261861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li            inst_archs = utils.system_output(cmd)
262861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li            inst_archs = inst_archs.split('\n')
263861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li
264861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li            for inst_arch in inst_archs:
265861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li                if inst_arch == arch:
266861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li                    return self._check_installed_version(name, version)
267861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li            return False
268861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li
269861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li        elif version:
270861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li            return self._check_installed_version(name, version)
271861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li        else:
272861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li            cmd = 'rpm -q ' + name + ' 2> /dev/null'
273861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li            return (os.system(cmd) == 0)
274861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li
275861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li
276861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li    def list_all(self):
277861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li        """
278861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li        List all installed packages.
279861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li        """
280861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li        installed_packages = utils.system_output('rpm -qa').splitlines()
281861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li        return installed_packages
282861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li
283861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li
284861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li    def list_files(self, name):
285861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li        """
286861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li        List files installed on the system by package [name].
287861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li
288861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li        @param name: Package name.
289861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li        """
290861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li        path = os.path.abspath(name)
291861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li        if os.path.isfile(path):
292861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li            option = '-qlp'
293861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li            name = path
294861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li        else:
295861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li            option = '-ql'
296861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li
297861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li        l_cmd = 'rpm' + ' ' + option + ' ' + name + ' 2> /dev/null'
298861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li
299861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li        try:
300861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li            result = utils.system_output(l_cmd)
301861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li            list_files = result.split('\n')
302861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li            return list_files
303861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li        except error.CmdError:
304861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li            return []
305861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li
306861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li
307861b2d54aec24228cdb3895dbc40062cb40cb2adEric Liclass DpkgBackend(object):
308861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li    """
309861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li    This class implements operations executed with the dpkg package manager.
310861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li
311861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li    dpkg is a lower level package manager, used by higher level managers such
312861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li    as apt and aptitude.
313861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li    """
314861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li    def __init__(self):
315861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li        self.lowlevel_base_cmd = os_dep.command('dpkg')
316861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li
317861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li
318861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li    def check_installed(self, name):
319861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li        if os.path.isfile(name):
320861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li            n_cmd = (self.lowlevel_base_cmd + ' -f ' + name +
321861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li                     ' Package 2>/dev/null')
322861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li            name = utils.system_output(n_cmd)
323861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li        i_cmd = self.lowlevel_base_cmd + ' -s ' + name + ' 2>/dev/null'
324861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li        # Checking if package is installed
325861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li        package_status = utils.system_output(i_cmd, ignore_status=True)
326861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li        not_inst_pattern = re.compile('not-installed', re.IGNORECASE)
327861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li        dpkg_not_installed = re.search(not_inst_pattern, package_status)
328861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li        if dpkg_not_installed:
329861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li            return False
330861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li        return True
331861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li
332861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li
333861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li    def list_all(self):
334861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li        """
335861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li        List all packages available in the system.
336861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li        """
337861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li        installed_packages = []
338861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li        raw_list = utils.system_output('dpkg -l').splitlines()[5:]
339861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li        for line in raw_list:
340861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li            parts = line.split()
341861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li            if parts[0] == "ii":  # only grab "installed" packages
342861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li                installed_packages.append("%s-%s" % (parts[1], parts[2]))
343861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li
344861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li
345861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li    def list_files(self, package):
346861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li        """
347861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li        List files installed by package [package].
348861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li
349861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li        @param package: Package name.
350861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li        @return: List of paths installed by package.
351861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li        """
352861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li        if os.path.isfile(package):
353861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li            l_cmd = self.lowlevel_base_cmd + ' -c ' + package
354861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li        else:
355861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li            l_cmd = self.lowlevel_base_cmd + ' -l ' + package
356861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li        return utils.system_output(l_cmd).split('\n')
357861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li
358861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li
359861b2d54aec24228cdb3895dbc40062cb40cb2adEric Liclass YumBackend(RpmBackend):
360861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li    """
361861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li    Implements the yum backend for software manager.
362861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li
363861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li    Set of operations for the yum package manager, commonly found on Yellow Dog
364861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li    Linux and Red Hat based distributions, such as Fedora and Red Hat
365861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li    Enterprise Linux.
366861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li    """
367861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li    def __init__(self):
368861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li        """
369861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li        Initializes the base command and the yum package repository.
370861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li        """
371861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li        super(YumBackend, self).__init__()
372861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li        executable = os_dep.command('yum')
373861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li        base_arguments = '-y'
374861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li        self.base_command = executable + ' ' + base_arguments
375861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li        self.repo_file_path = '/etc/yum.repos.d/autotest.repo'
376861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li        self.cfgparser = ConfigParser.ConfigParser()
377861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li        self.cfgparser.read(self.repo_file_path)
378861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li        y_cmd = executable + ' --version | head -1'
379861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li        self.yum_version = utils.system_output(y_cmd, ignore_status=True)
380861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li        logging.debug('Yum backend initialized')
381861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li        logging.debug('Yum version: %s' % self.yum_version)
382861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li        self.yum_base = yum.YumBase()
383861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li
384861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li
385861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li    def _cleanup(self):
386861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li        """
387861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li        Clean up the yum cache so new package information can be downloaded.
388861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li        """
389861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li        utils.system("yum clean all")
390861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li
391861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li
392861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li    def install(self, name):
393861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li        """
394861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li        Installs package [name]. Handles local installs.
395861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li        """
396861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li        if os.path.isfile(name):
397861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li            name = os.path.abspath(name)
398861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li            command = 'localinstall'
399861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li        else:
400861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li            command = 'install'
401861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li
402861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li        i_cmd = self.base_command + ' ' + command + ' ' + name
403861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li
404861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li        try:
405861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li            utils.system(i_cmd)
406861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li            return True
407861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li        except:
408861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li            return False
409861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li
410861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li
411861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li    def remove(self, name):
412861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li        """
413861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li        Removes package [name].
414861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li
415861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li        @param name: Package name (eg. 'ipython').
416861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li        """
417861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li        r_cmd = self.base_command + ' ' + 'erase' + ' ' + name
418861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li        try:
419861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li            utils.system(r_cmd)
420861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li            return True
421861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li        except:
422861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li            return False
423861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li
424861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li
425861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li    def add_repo(self, url):
426861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li        """
427861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li        Adds package repository located on [url].
428861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li
429861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li        @param url: Universal Resource Locator of the repository.
430861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li        """
431861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li        # Check if we URL is already set
432861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li        for section in self.cfgparser.sections():
433861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li            for option, value in self.cfgparser.items(section):
434861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li                if option == 'url' and value == url:
435861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li                    return True
436861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li
437861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li        # Didn't find it, let's set it up
438861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li        while True:
439861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li            section_name = 'software_manager' + '_' + generate_random_string(4)
440861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li            if not self.cfgparser.has_section(section_name):
441861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li                break
442861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li        self.cfgparser.add_section(section_name)
443861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li        self.cfgparser.set(section_name, 'name',
444861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li                           'Repository added by the autotest software manager.')
445861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li        self.cfgparser.set(section_name, 'url', url)
446861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li        self.cfgparser.set(section_name, 'enabled', 1)
447861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li        self.cfgparser.set(section_name, 'gpgcheck', 0)
448861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li        self.cfgparser.write(self.repo_file_path)
449861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li
450861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li
451861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li    def remove_repo(self, url):
452861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li        """
453861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li        Removes package repository located on [url].
454861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li
455861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li        @param url: Universal Resource Locator of the repository.
456861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li        """
457861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li        for section in self.cfgparser.sections():
458861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li            for option, value in self.cfgparser.items(section):
459861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li                if option == 'url' and value == url:
460861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li                    self.cfgparser.remove_section(section)
461861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li                    self.cfgparser.write(self.repo_file_path)
462861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li
463861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li
464861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li    def upgrade(self):
465861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li        """
466861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li        Upgrade all available packages.
467861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li        """
468861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li        r_cmd = self.base_command + ' ' + 'update'
469861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li        try:
470861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li            utils.system(r_cmd)
471861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li            return True
472861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li        except:
473861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li            return False
474861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li
475861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li
476861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li    def provides(self, name):
477861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li        """
478861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li        Returns a list of packages that provides a given capability.
479861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li
480861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li        @param name: Capability name (eg, 'foo').
481861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li        """
482861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li        d_provides = self.yum_base.searchPackageProvides(args=[name])
483861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li        provides_list = [key for key in d_provides]
484861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li        if provides_list:
485861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li            logging.info("Package %s provides %s", provides_list[0], name)
486861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li            return str(provides_list[0])
487861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li        else:
488861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li            return None
489861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li
490861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li
491861b2d54aec24228cdb3895dbc40062cb40cb2adEric Liclass ZypperBackend(RpmBackend):
492861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li    """
493861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li    Implements the zypper backend for software manager.
494861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li
495861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li    Set of operations for the zypper package manager, found on SUSE Linux.
496861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li    """
497861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li    def __init__(self):
498861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li        """
499861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li        Initializes the base command and the yum package repository.
500861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li        """
501861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li        super(ZypperBackend, self).__init__()
502861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li        self.base_command = os_dep.command('zypper') + ' -n'
503861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li        z_cmd = self.base_command + ' --version'
504861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li        self.zypper_version = utils.system_output(z_cmd, ignore_status=True)
505861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li        logging.debug('Zypper backend initialized')
506861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li        logging.debug('Zypper version: %s' % self.zypper_version)
507861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li
508861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li
509861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li    def install(self, name):
510861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li        """
511861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li        Installs package [name]. Handles local installs.
512861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li
513861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li        @param name: Package Name.
514861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li        """
515861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li        path = os.path.abspath(name)
516861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li        i_cmd = self.base_command + ' install -l ' + name
517861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li        try:
518861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li            utils.system(i_cmd)
519861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li            return True
520861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li        except:
521861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li            return False
522861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li
523861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li
524861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li    def add_repo(self, url):
525861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li        """
526861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li        Adds repository [url].
527861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li
528861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li        @param url: URL for the package repository.
529861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li        """
530861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li        ar_cmd = self.base_command + ' addrepo ' + url
531861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li        try:
532861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li            utils.system(ar_cmd)
533861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li            return True
534861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li        except:
535861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li            return False
536861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li
537861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li
538861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li    def remove_repo(self, url):
539861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li        """
540861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li        Removes repository [url].
541861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li
542861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li        @param url: URL for the package repository.
543861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li        """
544861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li        rr_cmd = self.base_command + ' removerepo ' + url
545861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li        try:
546861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li            utils.system(rr_cmd)
547861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li            return True
548861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li        except:
549861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li            return False
550861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li
551861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li
552861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li    def remove(self, name):
553861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li        """
554861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li        Removes package [name].
555861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li        """
556861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li        r_cmd = self.base_command + ' ' + 'erase' + ' ' + name
557861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li
558861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li        try:
559861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li            utils.system(r_cmd)
560861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li            return True
561861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li        except:
562861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li            return False
563861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li
564861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li
565861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li    def upgrade(self):
566861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li        """
567861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li        Upgrades all packages of the system.
568861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li        """
569861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li        u_cmd = self.base_command + ' update -l'
570861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li
571861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li        try:
572861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li            utils.system(u_cmd)
573861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li            return True
574861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li        except:
575861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li            return False
576861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li
577861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li
578861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li    def provides(self, name):
579861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li        """
580861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li        Searches for what provides a given file.
581861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li
582861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li        @param name: File path.
583861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li        """
584861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li        p_cmd = self.base_command + ' what-provides ' + name
585861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li        list_provides = []
586861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li        try:
587861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li            p_output = utils.system_output(p_cmd).split('\n')[4:]
588861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li            for line in p_output:
589861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li                line = [a.strip() for a in line.split('|')]
590861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li                try:
591861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li                    state, pname, type, version, arch, repository = line
592861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li                    if pname not in list_provides:
593861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li                        list_provides.append(pname)
594861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li                except IndexError:
595861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li                    pass
596861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li            if len(list_provides) > 1:
597861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li                logging.warning('More than one package found, '
598861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li                                'opting by the first queue result')
599861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li            if list_provides:
600861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li                logging.info("Package %s provides %s", list_provides[0], name)
601861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li                return list_provides[0]
602861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li            return None
603861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li        except:
604861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li            return None
605861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li
606861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li
607861b2d54aec24228cdb3895dbc40062cb40cb2adEric Liclass AptBackend(DpkgBackend):
608861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li    """
609861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li    Implements the apt backend for software manager.
610861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li
611861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li    Set of operations for the apt package manager, commonly found on Debian and
612861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li    Debian based distributions, such as Ubuntu Linux.
613861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li    """
614861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li    def __init__(self):
615861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li        """
616861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li        Initializes the base command and the debian package repository.
617861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li        """
618861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li        super(AptBackend, self).__init__()
619861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li        executable = os_dep.command('apt-get')
620861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li        self.base_command = executable + ' -y'
621861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li        self.repo_file_path = '/etc/apt/sources.list.d/autotest'
622861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li        self.apt_version = utils.system_output('apt-get -v | head -1',
623861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li                                               ignore_status=True)
624861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li        logging.debug('Apt backend initialized')
625861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li        logging.debug('apt version: %s' % self.apt_version)
626861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li
627861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li
628861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li    def install(self, name):
629861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li        """
630861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li        Installs package [name].
631861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li
632861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li        @param name: Package name.
633861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li        """
634861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li        command = 'install'
635861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li        i_cmd = self.base_command + ' ' + command + ' ' + name
636861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li
637861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li        try:
638861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li            utils.system(i_cmd)
639861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li            return True
640861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li        except:
641861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li            return False
642861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li
643861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li
644861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li    def remove(self, name):
645861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li        """
646861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li        Remove package [name].
647861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li
648861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li        @param name: Package name.
649861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li        """
650861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li        command = 'remove'
651861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li        flag = '--purge'
652861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li        r_cmd = self.base_command + ' ' + command + ' ' + flag + ' ' + name
653861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li
654861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li        try:
655861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li            utils.system(r_cmd)
656861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li            return True
657861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li        except:
658861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li            return False
659861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li
660861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li
661861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li    def add_repo(self, repo):
662861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li        """
663861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li        Add an apt repository.
664861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li
665861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li        @param repo: Repository string. Example:
666861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li                'deb http://archive.ubuntu.com/ubuntu/ maverick universe'
667861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li        """
668861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li        repo_file = open(self.repo_file_path, 'a')
669861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li        repo_file_contents = repo_file.read()
670861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li        if repo not in repo_file_contents:
671861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li            repo_file.write(repo)
672861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li
673861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li
674861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li    def remove_repo(self, repo):
675861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li        """
676861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li        Remove an apt repository.
677861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li
678861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li        @param repo: Repository string. Example:
679861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li                'deb http://archive.ubuntu.com/ubuntu/ maverick universe'
680861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li        """
681861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li        repo_file = open(self.repo_file_path, 'r')
682861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li        new_file_contents = []
683861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li        for line in repo_file.readlines:
684861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li            if not line == repo:
685861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li                new_file_contents.append(line)
686861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li        repo_file.close()
687861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li        new_file_contents = "\n".join(new_file_contents)
688861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li        repo_file.open(self.repo_file_path, 'w')
689861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li        repo_file.write(new_file_contents)
690861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li        repo_file.close()
691861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li
692861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li
693861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li    def upgrade(self):
694861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li        """
695861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li        Upgrade all packages of the system with eventual new versions.
696861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li        """
697861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li        ud_command = 'update'
698861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li        ud_cmd = self.base_command + ' ' + ud_command
699861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li        try:
700861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li            utils.system(ud_cmd)
701861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li        except:
702861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li            logging.error("Apt package update failed")
703861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li        up_command = 'upgrade'
704861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li        up_cmd = self.base_command + ' ' + up_command
705861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li        try:
706861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li            utils.system(up_cmd)
707861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li            return True
708861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li        except:
709861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li            return False
710861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li
711861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li
712861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li    def provides(self, file):
713861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li        """
714861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li        Return a list of packages that provide [file].
715861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li
716861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li        @param file: File path.
717861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li        """
718861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li        if not self.check_installed('apt-file'):
719861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li            self.install('apt-file')
720861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li        command = os_dep.command('apt-file')
721861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li        cache_update_cmd = command + ' update'
722861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li        try:
723861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li            utils.system(cache_update_cmd, ignore_status=True)
724861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li        except:
725861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li            logging.error("Apt file cache update failed")
726861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li        fu_cmd = command + ' search ' + file
727861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li        try:
728861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li            provides = utils.system_output(fu_cmd).split('\n')
729861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li            list_provides = []
730861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li            for line in provides:
731861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li                if line:
732861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li                    try:
733861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li                        line = line.split(':')
734861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li                        package = line[0].strip()
735861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li                        path = line[1].strip()
736861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li                        if path == file and package not in list_provides:
737861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li                            list_provides.append(package)
738861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li                    except IndexError:
739861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li                        pass
740861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li            if len(list_provides) > 1:
741861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li                logging.warning('More than one package found, '
742861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li                                'opting by the first queue result')
743861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li            if list_provides:
744861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li                logging.info("Package %s provides %s", list_provides[0], file)
745861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li                return list_provides[0]
746861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li            return None
747861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li        except:
748861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li            return None
749861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li
750861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li
751861b2d54aec24228cdb3895dbc40062cb40cb2adEric Liif __name__ == '__main__':
752861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li    parser = optparse.OptionParser(
753861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li    "usage: %prog [install|remove|list-all|list-files|add-repo|remove-repo|"
754861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li    "upgrade|what-provides|install-what-provides] arguments")
755861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li    parser.add_option('--verbose', dest="debug", action='store_true',
756861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li                      help='include debug messages in console output')
757861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li
758861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li    options, args = parser.parse_args()
759861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li    debug = options.debug
760861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li    logging_manager.configure_logging(SoftwareManagerLoggingConfig(),
761861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li                                      verbose=debug)
762861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li    software_manager = SoftwareManager()
763861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li    if args:
764861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li        action = args[0]
765861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li        args = " ".join(args[1:])
766861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li    else:
767861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li        action = 'show-help'
768861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li
769861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li    if action == 'install':
770861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li        software_manager.install(args)
771861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li    elif action == 'remove':
772861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li        software_manager.remove(args)
773861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li    if action == 'list-all':
774861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li        software_manager.list_all()
775861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li    elif action == 'list-files':
776861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li        software_manager.list_files(args)
777861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li    elif action == 'add-repo':
778861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li        software_manager.add_repo(args)
779861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li    elif action == 'remove-repo':
780861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li        software_manager.remove_repo(args)
781861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li    elif action == 'upgrade':
782861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li        software_manager.upgrade()
783861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li    elif action == 'what-provides':
784861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li        software_manager.provides(args)
785861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li    elif action == 'install-what-provides':
786861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li        software_manager.install_what_provides(args)
787861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li    elif action == 'show-help':
788861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li        parser.print_help()
789