コード例 #1
0
ファイル: group.py プロジェクト: fdumpling/python-kollaclient
 def take_action(self, parsed_args):
     try:
         groupname = parsed_args.groupname.strip()
         groupname = utils.convert_to_unicode(groupname)
         inventory = Inventory.load()
         inventory.remove_group(groupname)
         Inventory.save(inventory)
     except CommandError as e:
         raise e
     except Exception as e:
         raise Exception(traceback.format_exc())
コード例 #2
0
ファイル: deploy.py プロジェクト: meganeshkadam/kolla-cli
    def test_json_generator(self):
        self.run_cli_cmd('setdeploy local')

        host1 = 'host_test1'
        self.run_cli_cmd('host add %s' % host1)

        inventory = Inventory.load()

        path = inventory.create_json_gen_file()
        (retval, msg) = self.run_command(path)
        os.remove(path)
        self.assertEqual(0, retval, 'json generator command failed: %s' % msg)

        self.assertNotEqual('', msg,
                            'json generator returned no data: %s' % msg)

        self.assertIn(host1, msg,
                      '%s not in json_gen output: %s' % (host1, msg))

        for service, subservices in SERVICES.items():
            self.assertIn(service, msg,
                          '%s not in json_gen output: %s' % (service, msg))
            for subservice in subservices:
                self.assertIn(
                    subservice, msg,
                    '%s not in json_gen output: %s' % (subservice, msg))

        # verify that json output is valid. This will throw if invalid json
        try:
            json.loads(msg)
        except Exception:
            self.assertTrue(False, 'invalid json: %s' % msg)
        remote_msg = '"ansible_ssh_user": "******"'
        local_msg = '"ansible_connection": "local"'

        # verify that setdeploy local worked:
        self.assertIn(local_msg, msg,
                      '%s not in local json_gen output: %s' % (local_msg, msg))
        self.assertNotIn(remote_msg, msg,
                         '%s in local json_gen output: %s' % (remote_msg, msg))

        # verify that setdeploy remote worked:
        self.run_cli_cmd('setdeploy remote')
        inventory = Inventory.load()
        path = inventory.create_json_gen_file()
        (retval, msg) = self.run_command(path)
        os.remove(path)
        self.assertEqual(0, retval, 'json generator command failed: %s' % msg)

        self.assertIn(
            remote_msg, msg,
            '%s not in remote json_gen output: %s' % (remote_msg, msg))
        self.assertNotIn(local_msg, msg,
                         '%s in remote json_gen output: %s' % (local_msg, msg))
コード例 #3
0
ファイル: group.py プロジェクト: meganeshkadam/kolla-cli
 def take_action(self, parsed_args):
     try:
         groupname = parsed_args.groupname.strip()
         groupname = utils.convert_to_unicode(groupname)
         inventory = Inventory.load()
         inventory.remove_group(groupname)
         Inventory.save(inventory)
     except CommandError as e:
         raise e
     except Exception as e:
         raise Exception(traceback.format_exc())
コード例 #4
0
ファイル: host.py プロジェクト: meganeshkadam/kolla-cli
    def take_action(self, parsed_args):
        try:
            hostname = parsed_args.hostname.strip()
            hostname = utils.convert_to_unicode(hostname)

            inventory = Inventory.load()
            inventory.add_host(hostname)
            Inventory.save(inventory)
        except CommandError as e:
            raise e
        except Exception as e:
            raise Exception(traceback.format_exc())
コード例 #5
0
def run_ansible_cmd(cmd, host):
    # sudo -u kolla ansible ol7-c4 -i inv_path -a "cmd"
    out = None
    user = get_admin_user()
    inventory = Inventory.load()
    inv_path = inventory.create_json_gen_file()

    acmd = ('/usr/bin/sudo -u %s ansible %s -i %s -a "%s"'
            % (user, host, inv_path, cmd))

    try:
        (out, err) = subprocess.Popen(acmd, shell=True,
                                      stdout=subprocess.PIPE,
                                      stderr=subprocess.PIPE).communicate()
    except Exception as e:
        print('%s\nCannot communicate with host: %s, skipping' % (e, host))
    finally:
        os.remove(inv_path)

    if not out:
        print('Host %s is not accessible: %s, skipping' % (host, err))
    elif '>>' not in out:
        print('Ansible command: %s' % acmd)
        print('Host: %s. \nInvalid ansible return data: [%s]. skipping'
              % (host, out))
        out = None
    return out
コード例 #6
0
ファイル: host.py プロジェクト: meganeshkadam/kolla-cli
    def take_action(self, parsed_args):
        try:
            hostname = None
            if parsed_args.hostname:
                hostname = parsed_args.hostname.strip()
                hostname = utils.convert_to_unicode(hostname)

            inventory = Inventory.load()

            if hostname:
                host = inventory.get_host(hostname)
                if not host:
                    _host_not_found(self.log, hostname)

            data = []
            host_groups = inventory.get_host_groups()
            if host_groups:
                if hostname:
                    data.append((hostname, host_groups[hostname]))
                else:
                    for (hostname, groupnames) in host_groups.items():
                        data.append((hostname, groupnames))
            else:
                data.append(('', ''))
            return (('Host', 'Groups'), sorted(data))
        except CommandError as e:
            raise e
        except Exception as e:
            raise Exception(traceback.format_exc())
コード例 #7
0
 def take_action(self, parsed_args):
     try:
         mode = parsed_args.mode.strip()
         remote_flag = False
         if mode == 'remote':
             remote_flag = True
         elif mode != 'local':
             raise CommandError('Invalid deploy mode. Mode must be ' +
                                'either "local" or "remote"')
         inventory = Inventory.load()
         inventory.set_deploy_mode(remote_flag)
         Inventory.save(inventory)
     except CommandError as e:
         raise e
     except Exception:
         raise Exception(traceback.format_exc())
コード例 #8
0
    def test_json_generator(self):
        self.run_cli_cmd("setdeploy local")

        host1 = "host_test1"
        self.run_cli_cmd("host add %s" % host1)

        inventory = Inventory.load()

        path = inventory.create_json_gen_file()
        (retval, msg) = self.run_command(path)
        os.remove(path)
        self.assertEqual(0, retval, "json generator command failed: %s" % msg)

        self.assertNotEqual("", msg, "json generator returned no data: %s" % msg)

        self.assertIn(host1, msg, "%s not in json_gen output: %s" % (host1, msg))

        for service, subservices in SERVICES.items():
            self.assertIn(service, msg, "%s not in json_gen output: %s" % (service, msg))
            for subservice in subservices:
                self.assertIn(subservice, msg, "%s not in json_gen output: %s" % (subservice, msg))

        # verify that json output is valid. This will throw if invalid json
        try:
            json.loads(msg)
        except Exception:
            self.assertTrue(False, "invalid json: %s" % msg)
        remote_msg = '"ansible_ssh_user": "******"'
        local_msg = '"ansible_connection": "local"'

        # verify that setdeploy local worked:
        self.assertIn(local_msg, msg, "%s not in local json_gen output: %s" % (local_msg, msg))
        self.assertNotIn(remote_msg, msg, "%s in local json_gen output: %s" % (remote_msg, msg))

        # verify that setdeploy remote worked:
        self.run_cli_cmd("setdeploy remote")
        inventory = Inventory.load()
        path = inventory.create_json_gen_file()
        (retval, msg) = self.run_command(path)
        os.remove(path)
        self.assertEqual(0, retval, "json generator command failed: %s" % msg)

        self.assertIn(remote_msg, msg, "%s not in remote json_gen output: %s" % (remote_msg, msg))
        self.assertNotIn(local_msg, msg, "%s in remote json_gen output: %s" % (local_msg, msg))
コード例 #9
0
def main():
    """collect docker logs from servers

    $ command is $ log_collector.py <all | host1[,host2,host3...]>
    """
    global tar_file_descr

    help_msg = 'Usage: log_collector.py <all | host1[,host2,host3...]>'
    hosts = []
    if len(sys.argv) == 2:
        if '-h' == sys.argv[1] or '--help' == sys.argv[1]:
            print(help_msg)
            sys.exit(0)
        elif 'all' == sys.argv[1]:
            # get logs from all hosts
            inventory = Inventory.load()
            hosts = inventory.get_hostnames()
        else:
            # get logs from specified hosts
            hostnames = sys.argv[1].split(',')
            for host in hostnames:
                if host not in hosts:
                    hosts.append(host)
    else:
        print(help_msg)
        sys.exit(1)

    # open tar file for storing logs
    fd, tar_path = tempfile.mkstemp(prefix='kolla_support_logs_',
                                    suffix='.tgz')
    os.close(fd)  # avoid fd leak

    with tarfile.open(tar_path, 'w:gz') as tar_file_descr:
        # gather dump output from kollacli
        print('Getting kollacli logs')
        # cliff prints log output to stderr
        (_, err) = subprocess.Popen('kollacli dump'.split(),
                                    stdout=subprocess.PIPE,
                                    stderr=subprocess.PIPE).communicate()
        if '/' in err:
            dump_path = '/' + err.strip().split('/', 1)[1]
            if os.path.isfile(dump_path):
                tar_file_descr.add(dump_path)
                os.remove(dump_path)
            else:
                print('ERROR: No kolla dump output file at %s' % dump_path)
        else:
            print('ERROR: No path found in dump command output: %s' % err)

        # gather logs from selected hosts
        for host in hosts:
            print('Getting docker logs from host: %s' % host)
            add_logs_from_host(host)
    print('Log collection complete. Logs are at %s' % tar_path)
コード例 #10
0
ファイル: host.py プロジェクト: meganeshkadam/kolla-cli
    def take_action(self, parsed_args):
        try:
            hostname = parsed_args.hostname.strip()
            hostname = utils.convert_to_unicode(hostname)
            inventory = Inventory.load()
            if not inventory.get_host(hostname):
                _host_not_found(self.log, hostname)

            inventory.check_host(hostname)
        except CommandError as e:
            raise e
        except Exception as e:
            raise Exception(traceback.format_exc())
コード例 #11
0
ファイル: deploy.py プロジェクト: meganeshkadam/kolla-cli
    def test_json_filtering(self):

        hosts = ['host_test1', 'host_test2', 'host_test3']
        groups = ['control', 'network', 'storage']

        for host in hosts:
            self.run_cli_cmd('host add %s' % host)
            for group in groups:
                self.run_cli_cmd('group addhost %s %s' % (group, host))

        inventory = Inventory.load()

        # filter by host- include all hosts
        inv_filter = {'deploy_hosts': hosts}
        path = inventory.create_json_gen_file(inv_filter)
        self.log.info('run command: %s' % path)
        (retval, msg) = self.run_command(path)
        os.remove(path)
        self.assertEqual(0, retval, 'json generator command failed: %s' % msg)

        self.check_json(msg, groups, hosts, groups, hosts)

        # filter by host- to first host
        included_host = hosts[0]
        inv_filter = {'deploy_hosts': [included_host]}
        path = inventory.create_json_gen_file(inv_filter)
        self.log.info('run command: %s' % path)
        (retval, msg) = self.run_command(path)
        os.remove(path)
        self.assertEqual(0, retval, 'json generator command failed: %s' % msg)
        self.check_json(msg, groups, hosts, groups, [included_host])

        # filter by group- include all groups
        inv_filter = {'deploy_groups': groups}
        path = inventory.create_json_gen_file(inv_filter)
        self.log.info('run command: %s' % path)
        (retval, msg) = self.run_command(path)
        os.remove(path)
        self.assertEqual(0, retval, 'json generator command failed: %s' % msg)
        self.check_json(msg, groups, hosts, groups, hosts)

        # filter by group- to first group
        included_group = groups[0]
        inv_filter = {'deploy_groups': [included_group]}
        path = inventory.create_json_gen_file(inv_filter)
        self.log.info('run command: %s' % path)
        (retval, msg) = self.run_command(path)
        os.remove(path)
        self.assertEqual(0, retval, 'json generator command failed: %s' % msg)
        self.check_json(msg, groups, hosts, [included_group], hosts)
コード例 #12
0
    def test_json_filtering(self):

        hosts = ["host_test1", "host_test2", "host_test3"]
        groups = ["control", "network", "storage"]

        for host in hosts:
            self.run_cli_cmd("host add %s" % host)
            for group in groups:
                self.run_cli_cmd("group addhost %s %s" % (group, host))

        inventory = Inventory.load()

        # filter by host- include all hosts
        inv_filter = {"deploy_hosts": hosts}
        path = inventory.create_json_gen_file(inv_filter)
        self.log.info("run command: %s" % path)
        (retval, msg) = self.run_command(path)
        os.remove(path)
        self.assertEqual(0, retval, "json generator command failed: %s" % msg)

        self.check_json(msg, groups, hosts, groups, hosts)

        # filter by host- to first host
        included_host = hosts[0]
        inv_filter = {"deploy_hosts": [included_host]}
        path = inventory.create_json_gen_file(inv_filter)
        self.log.info("run command: %s" % path)
        (retval, msg) = self.run_command(path)
        os.remove(path)
        self.assertEqual(0, retval, "json generator command failed: %s" % msg)
        self.check_json(msg, groups, hosts, groups, [included_host])

        # filter by group- include all groups
        inv_filter = {"deploy_groups": groups}
        path = inventory.create_json_gen_file(inv_filter)
        self.log.info("run command: %s" % path)
        (retval, msg) = self.run_command(path)
        os.remove(path)
        self.assertEqual(0, retval, "json generator command failed: %s" % msg)
        self.check_json(msg, groups, hosts, groups, hosts)

        # filter by group- to first group
        included_group = groups[0]
        inv_filter = {"deploy_groups": [included_group]}
        path = inventory.create_json_gen_file(inv_filter)
        self.log.info("run command: %s" % path)
        (retval, msg) = self.run_command(path)
        os.remove(path)
        self.assertEqual(0, retval, "json generator command failed: %s" % msg)
        self.check_json(msg, groups, hosts, [included_group], hosts)
コード例 #13
0
ファイル: group.py プロジェクト: fdumpling/python-kollaclient
    def take_action(self, parsed_args):
        try:
            inventory = Inventory.load()

            data = []
            group_services = inventory.get_group_services()
            if group_services:
                for (groupname, servicenames) in group_services.items():
                    data.append((groupname, sorted(servicenames)))
            else:
                data.append(('', ''))
            return (('Group', 'Services'), sorted(data))
        except CommandError as e:
            raise e
        except Exception as e:
            raise Exception(traceback.format_exc())
コード例 #14
0
ファイル: service.py プロジェクト: meganeshkadam/kolla-cli
    def take_action(self, parsed_args):
        try:
            inventory = Inventory.load()

            data = []
            service_subsvcs = inventory.get_service_sub_services()
            if service_subsvcs:
                for (servicename, sub_svcname) in service_subsvcs.items():
                    data.append((servicename, sub_svcname))
            else:
                data.append(('', ''))
            return (('Service', 'Sub-Services'), sorted(data))
        except CommandError as e:
            raise e
        except Exception as e:
            raise Exception(traceback.format_exc())
コード例 #15
0
ファイル: group.py プロジェクト: meganeshkadam/kolla-cli
    def take_action(self, parsed_args):
        try:
            inventory = Inventory.load()

            data = []
            group_services = inventory.get_group_services()
            if group_services:
                for (groupname, servicenames) in group_services.items():
                    data.append((groupname, sorted(servicenames)))
            else:
                data.append(('', ''))
            return (('Group', 'Services'), sorted(data))
        except CommandError as e:
            raise e
        except Exception as e:
            raise Exception(traceback.format_exc())
コード例 #16
0
ファイル: host.py プロジェクト: meganeshkadam/kolla-cli
    def take_action(self, parsed_args):
        try:
            if not parsed_args.hostname and not parsed_args.file:
                raise CommandError('Hostname or hosts info file path ' +
                                   'is required')
            if parsed_args.hostname and parsed_args.file:
                raise CommandError('Hostname and hosts info file path ' +
                                   'cannot both be present')
            inventory = Inventory.load()

            if parsed_args.file:
                # multi-host setup via xml file
                hosts_data = self.get_yml_data(parsed_args.file.strip())
                inventory.setup_hosts(hosts_data)
            else:
                # single host setup
                hostname = parsed_args.hostname.strip()
                hostname = utils.convert_to_unicode(hostname)
                if not inventory.get_host(hostname):
                    _host_not_found(self.log, hostname)

                check_ok = inventory.check_host(hostname, True)
                if check_ok:
                    self.log.info(
                        'Skipping setup of host (%s) as check is ok' %
                        hostname)
                    return True

                if parsed_args.insecure:
                    password = parsed_args.insecure.strip()
                else:
                    setup_user = get_setup_user()
                    password = getpass.getpass('%s password for %s: ' %
                                               (setup_user, hostname))
                password = utils.convert_to_unicode(password)
                inventory.setup_host(hostname, password)

        except CommandError as e:
            raise e
        except Exception as e:
            raise Exception(traceback.format_exc())
コード例 #17
0
ファイル: service.py プロジェクト: meganeshkadam/kolla-cli
    def take_action(self, parsed_args):
        try:
            inventory = Inventory.load()

            data = []
            service_groups = inventory.get_service_groups()
            if service_groups:
                for (servicename, (groupnames, inherit)) \
                        in service_groups.items():
                    inh_str = 'yes'
                    if inherit is None:
                        inh_str = '-'
                    elif inherit is False:
                        inh_str = 'no'
                    data.append((servicename, groupnames, inh_str))
            else:
                data.append(('', ''))
            return (('Service', 'Groups', 'Inherited'), sorted(data))
        except CommandError as e:
            raise e
        except Exception as e:
            raise Exception(traceback.format_exc())
コード例 #18
0
ファイル: host.py プロジェクト: meganeshkadam/kolla-cli
    def take_action(self, parsed_args):
        try:
            hostname = ''
            hostname = parsed_args.hostname.strip()
            hostname = convert_to_unicode(hostname)

            if hostname != 'all':
                inventory = Inventory.load()
                host = inventory.get_host(hostname)
                if not host:
                    _host_not_found(self.log, hostname)

            destroy_type = 'kill'
            if parsed_args.stop:
                destroy_type = 'stop'

            self.log.info('please be patient as this may take a while.')
            ansible_properties = properties.AnsibleProperties()
            base_distro = \
                ansible_properties.get_property('kolla_base_distro')
            install_type = \
                ansible_properties.get_property('kolla_install_type')
            container_prefix = base_distro + '-' + install_type
            kollacli_home = get_kollacli_home()
            playbook = AnsiblePlaybook()
            playbook.playbook_path = os.path.join(kollacli_home,
                                                  'ansible/host_destroy.yml')
            playbook.extra_vars = 'hosts=' + hostname + \
                                  ' prefix=' + container_prefix + \
                                  ' destroy_type=' + destroy_type
            playbook.print_output = False
            playbook.verbose_level = self.app.options.verbose_level
            playbook.run()
        except CommandError as e:
            raise e
        except Exception as e:
            raise Exception(traceback.format_exc())
コード例 #19
0
    def _add_cmd_info(self, tar):
        # run all the kollacli list commands
        cmds = ['kollacli service listgroups',
                'kollacli service list',
                'kollacli group listservices',
                'kollacli group listhosts',
                'kollacli host list',
                'kollacli property list',
                'kollacli password list']

        # collect the json inventory output
        inventory = Inventory.load()
        inv_path = inventory.create_json_gen_file()
        cmds.append(inv_path)

        try:
            fd, path = tempfile.mkstemp(suffix='.tmp')
            os.close(fd)
            with open(path, 'w') as tmp_file:
                for cmd in cmds:
                    err_msg, output = run_cmd(cmd, False)
                    tmp_file.write('\n\n$ %s\n' % cmd)
                    if err_msg:
                        tmp_file.write('Error message: %s\n' % err_msg)
                    lines = output.split('\n')
                    for line in lines:
                        tmp_file.write(line + '\n')
            tar.add(path, arcname=os.path.join('kolla', 'cmds_output'))

        except Exception as e:
            raise e
        finally:
            if path:
                os.remove(path)
            if inv_path:
                os.remove(inv_path)
        return
コード例 #20
0
    def run(self):
        globals_string = None
        password_string = None
        inventory_path = None
        cmd = ''
        try:
            flag = ''
            # verbose levels: 1=not verbose, 2=more verbose
            if self.verbose_level > 1:
                flag = '-vvv'

            admin_user = get_admin_user()
            command_string = ('/usr/bin/sudo -u %s ansible-playbook %s'
                              % (admin_user, flag))
            inventory = Inventory.load()
            inventory_filter = {}
            if self.hosts:
                for hostname in self.hosts:
                    host = inventory.get_host(hostname)
                    if not host:
                        raise CommandError(
                            'Host (%s) not found. ' % hostname)
                inventory_filter['deploy_hosts'] = self.hosts
            elif self.groups:
                for groupname in self.groups:
                    group = inventory.get_group(groupname)
                    if not group:
                        raise CommandError(
                            'Group (%s) not found. ' % groupname)
                inventory_filter['deploy_groups'] = self.groups

            inventory_path = inventory.create_json_gen_file(inventory_filter)
            inventory_string = '-i ' + inventory_path
            cmd = (command_string + ' ' + inventory_string)

            if self.include_globals:
                globals_string = self._get_globals_path()
                cmd = (cmd + ' ' + globals_string)

            if self.include_passwords:
                password_string = self._get_password_path()
                cmd = (cmd + ' ' + password_string)

            cmd = (cmd + ' ' + self.playbook_path)

            if self.extra_vars or self.serial:
                extra_vars = ''
                if self.extra_vars:
                    extra_vars = self.extra_vars
                    if self.serial:
                        extra_vars += ' '
                if self.serial:
                    extra_vars += 'serial_var=1'

                cmd = (cmd + ' --extra-vars \"' +
                       extra_vars + '\"')

            if self.services:
                service_string = ''
                first = True
                for service in self.services:
                    valid_service = inventory.get_service(service)
                    if not valid_service:
                        raise CommandError(
                            'Service (%s) not found. ' % service)
                    if not first:
                        service_string = service_string + ','
                    else:
                        first = False
                    service_string = service_string + service
                cmd = (cmd + ' --tags ' + service_string)

            if self.flush_cache:
                cmd = (cmd + ' --flush-cache')

            if self.verbose_level > 1:
                # log the ansible command
                self.log.debug('cmd:' + cmd)

                if self.verbose_level > 2:
                    # log the inventory
                    dbg_gen = inventory_path
                    (inv, _) = \
                        subprocess.Popen(dbg_gen.split(' '),
                                         stdout=subprocess.PIPE,
                                         stderr=subprocess.PIPE).communicate()
                    self.log.debug(inv)

            err_msg, output = run_cmd(cmd, self.print_output)
            if err_msg:
                if not self.print_output:
                    # since the user didn't see the output, include it in
                    # the error message
                    err_msg = '%s %s' % (err_msg, output)
                raise CommandError(err_msg)

            self.log.info('Success')
        except CommandError as e:
            raise e
        except Exception:
            raise Exception(traceback.format_exc())
        finally:
            if inventory_path:
                os.remove(inventory_path)
コード例 #21
0
ファイル: playbook.py プロジェクト: meganeshkadam/kolla-cli
    def run(self):
        globals_string = None
        password_string = None
        inventory_path = None
        cmd = ''
        try:
            flag = ''
            # verbose levels: 1=not verbose, 2=more verbose
            if self.verbose_level > 1:
                flag = '-vvv'

            admin_user = get_admin_user()
            command_string = ('/usr/bin/sudo -u %s ansible-playbook %s' %
                              (admin_user, flag))
            inventory = Inventory.load()
            inventory_filter = {}
            if self.hosts:
                for hostname in self.hosts:
                    host = inventory.get_host(hostname)
                    if not host:
                        raise CommandError('Host (%s) not found. ' % hostname)
                inventory_filter['deploy_hosts'] = self.hosts
            elif self.groups:
                for groupname in self.groups:
                    group = inventory.get_group(groupname)
                    if not group:
                        raise CommandError('Group (%s) not found. ' %
                                           groupname)
                inventory_filter['deploy_groups'] = self.groups

            inventory_path = inventory.create_json_gen_file(inventory_filter)
            inventory_string = '-i ' + inventory_path
            cmd = (command_string + ' ' + inventory_string)

            if self.include_globals:
                globals_string = self._get_globals_path()
                cmd = (cmd + ' ' + globals_string)

            if self.include_passwords:
                password_string = self._get_password_path()
                cmd = (cmd + ' ' + password_string)

            cmd = (cmd + ' ' + self.playbook_path)

            if self.extra_vars or self.serial:
                extra_vars = ''
                if self.extra_vars:
                    extra_vars = self.extra_vars
                    if self.serial:
                        extra_vars += ' '
                if self.serial:
                    extra_vars += 'serial_var=1'

                cmd = (cmd + ' --extra-vars \"' + extra_vars + '\"')

            if self.services:
                service_string = ''
                first = True
                for service in self.services:
                    valid_service = inventory.get_service(service)
                    if not valid_service:
                        raise CommandError('Service (%s) not found. ' %
                                           service)
                    if not first:
                        service_string = service_string + ','
                    else:
                        first = False
                    service_string = service_string + service
                cmd = (cmd + ' --tags ' + service_string)

            if self.flush_cache:
                cmd = (cmd + ' --flush-cache')

            if self.verbose_level > 1:
                # log the ansible command
                self.log.debug('cmd:' + cmd)

                if self.verbose_level > 2:
                    # log the inventory
                    dbg_gen = inventory_path
                    (inv, _) = \
                        subprocess.Popen(dbg_gen.split(' '),
                                         stdout=subprocess.PIPE,
                                         stderr=subprocess.PIPE).communicate()
                    self.log.debug(inv)

            err_msg, output = run_cmd(cmd, self.print_output)
            if err_msg:
                if not self.print_output:
                    # since the user didn't see the output, include it in
                    # the error message
                    err_msg = '%s %s' % (err_msg, output)
                raise CommandError(err_msg)

            self.log.info('Success')
        except CommandError as e:
            raise e
        except Exception:
            raise Exception(traceback.format_exc())
        finally:
            if inventory_path:
                os.remove(inventory_path)