示例#1
0
    def add_bootstrap_to_no_proxy(self):
        """Finds bootstrap node IP and adds it to the current setting of
        no-proxy in the juju env.
        """
        out = utils.get_command_output(
            "{0} juju status".format(
                self.config.juju_home()),
            timeout=None,
            user_sudo=True)
        if out['status'] != 0:
            log.debug("error from status: {}".format(out))
            raise Exception("Problem with juju status.")
        try:
            status = yaml.load(out['output'])
            bootstrap_dns_name = status['machines']['0']['dns-name']
        except:
            utils.pollinate(self.session_id, 'EJ')
            log.exception("Error parsing yaml from juju status")
            raise Exception("Problem getting bootstrap machine DNS name")

        # first attempt to get directly, then use juju run:
        try:
            bootstrap_ip = socket.gethostbyname(bootstrap_dns_name)

        except socket.gaierror as e:
            log.error("Failed to get ip directly: {}".format(e))

            out = utils.get_command_output(
                "{} juju run --machine 0 "
                "'ip -o -4 address show dev juju-br0'".format(
                    self.config.juju_home()))
            if out['status'] != 0:
                log.error("Failed to get ip: {}".format(out))
                raise Exception("Failed to get IP of bootstrap node")
            regex = re.compile("inet\s+(\d+\.\d+\.\d+\.\d+)\/")
            match = re.search(regex, out['output'].rstrip())
            if match:
                bootstrap_ip = match.group(1)
                bootstrap_ip = get_ip_set("{}/24".format(bootstrap_ip))
            else:
                log.error("Failed to get ip: {}".format(out))
                raise Exception("Failed to get IP of bootstrap node")

        out = utils.get_command_output(
            "{} juju get-env no-proxy".format(self.config.juju_home()),
            timeout=None, user_sudo=True)
        if out['status'] != 0:
            log.debug("error from get-env: {}".format(out))
            raise Exception("Problem getting existing no-proxy setting")

        no_proxy = "{},{}".format(
            out['output'].rstrip(), bootstrap_ip)

        out = utils.get_command_output(
            "{} juju set-env no-proxy={}".format(self.config.juju_home(),
                                                 no_proxy),
            timeout=None, user_sudo=True)
        if out['status'] != 0:
            log.debug("error from set-env: {}".format(out))
            raise Exception("Problem setting no-proxy environment")
示例#2
0
    def add_bootstrap_to_no_proxy(self):
        """Finds bootstrap node IP and adds it to the current setting of
        no-proxy in the juju env.
        """
        out = utils.get_command_output(
            "{0} juju status".format(
                self.config.juju_home()),
            timeout=None,
            user_sudo=True)
        if out['status'] != 0:
            log.debug("error from status: {}".format(out))
            raise Exception("Problem with juju status.")
        try:
            status = yaml.load(out['output'])
            bootstrap_dns_name = status['machines']['0']['dns-name']
        except:
            utils.pollinate(self.session_id, 'EJ')
            log.exception("Error parsing yaml from juju status")
            raise Exception("Problem getting bootstrap machine DNS name")

        # first attempt to get directly, then use juju run:
        try:
            bootstrap_ip = socket.gethostbyname(bootstrap_dns_name)

        except socket.gaierror as e:
            log.error("Failed to get ip directly: {}".format(e))

            out = utils.get_command_output(
                "{} juju run --machine 0 "
                "'ip -o -4 address show dev juju-br0'".format(
                    self.config.juju_home()))
            if out['status'] != 0:
                log.error("Failed to get ip: {}".format(out))
                raise Exception("Failed to get IP of bootstrap node")
            regex = re.compile("inet\s+(\d+\.\d+\.\d+\.\d+)\/")
            match = re.search(regex, out['output'].rstrip())
            if match:
                bootstrap_ip = match.group(1)
                bootstrap_ip = get_ip_set("{}/24".format(bootstrap_ip))
            else:
                log.error("Failed to get ip: {}".format(out))
                raise Exception("Failed to get IP of bootstrap node")

        out = utils.get_command_output(
            "{} juju get-env no-proxy".format(self.config.juju_home()),
            timeout=None, user_sudo=True)
        if out['status'] != 0:
            log.debug("error from get-env: {}".format(out))
            raise Exception("Problem getting existing no-proxy setting")

        no_proxy = "{},{}".format(
            out['output'].rstrip(), bootstrap_ip)

        out = utils.get_command_output(
            "{} juju set-env no-proxy={}".format(self.config.juju_home(),
                                                 no_proxy),
            timeout=None, user_sudo=True)
        if out['status'] != 0:
            log.debug("error from set-env: {}".format(out))
            raise Exception("Problem setting no-proxy environment")
 def test_get_command_output_timeout(self, mock_Popen, mock_env):
     mock_env.copy.return_value = {'FOO': 'bazbot'}
     mock_Popen.return_value.communicate.return_value = (bytes(), bytes())
     get_command_output("fake", timeout=20)
     mock_Popen.assert_called_with("timeout 20s fake", shell=True,
                                   stdout=PIPE, stderr=PIPE,
                                   bufsize=-1,
                                   env={'LC_ALL': 'C',
                                        'FOO': 'bazbot'},
                                   close_fds=True)
示例#4
0
    def test_get_command_output_raises(self, mock_Popen, mock_env):
        err = OSError()
        err.errno = errno.ENOENT
        mock_Popen.side_effect = err
        rv = get_command_output('foo')
        self.assertEqual(rv, dict(ret=127, output="", err=""))

        mock_Popen.side_effect = OSError()
        with self.assertRaises(OSError):
            get_command_output('foo')
示例#5
0
 def test_get_command_output_timeout(self, mock_Popen, mock_env):
     mock_env.copy.return_value = {'FOO': 'bazbot'}
     mock_Popen.return_value.communicate.return_value = (bytes(), bytes())
     get_command_output("fake", timeout=20)
     mock_Popen.assert_called_with("timeout 20s fake", shell=True,
                                   stdout=PIPE, stderr=PIPE,
                                   bufsize=-1,
                                   env={'LC_ALL': 'C',
                                        'FOO': 'bazbot'},
                                   close_fds=True)
示例#6
0
    def test_get_command_output_raises(self, mock_Popen, mock_env):
        err = OSError()
        err.errno = errno.ENOENT
        mock_Popen.side_effect = err
        rv = get_command_output('foo')
        self.assertEqual(rv, dict(ret=127, output="", err=""))

        mock_Popen.side_effect = OSError()
        with self.assertRaises(OSError):
            get_command_output('foo')
    def login_to_maas(self, apikey):
        cmd = ("maas login maas {} {}".format(self.LOCAL_MAAS_URL, apikey))

        out = utils.get_command_output(cmd)
        if out['status'] != 0:
            log.debug("failed to login to maas: {}".format(out))

            # Remove maascli.db that gets created regardless of
            # status of login
            utils.get_command_output('rm -f {}'.format(
                os.path.join(utils.install_home(), '.maascli.db')))
            raise MaasInstallError("Couldn't log in")
示例#8
0
 def set_perms(self):
     """ sets permissions
     """
     try:
         log.info("Setting permissions for user {}".format(utils.install_user()))
         utils.chown(self.config.cfg_path, utils.install_user(), utils.install_user(), recursive=True)
         utils.get_command_output("sudo chmod 777 {}".format(self.config.cfg_path))
         utils.get_command_output("sudo chmod 777 -R {}/*".format(self.config.cfg_path))
     except:
         msg = "Error setting ownership for " "{}".format(self.config.cfg_path)
         log.exception(msg)
         raise Exception(msg)
    def login_to_maas(self, apikey):
        cmd = ("maas login maas {} {}".format(self.LOCAL_MAAS_URL,
                                              apikey))

        out = utils.get_command_output(cmd)
        if out['status'] != 0:
            log.debug("failed to login to maas: {}".format(out))

            # Remove maascli.db that gets created regardless of
            # status of login
            utils.get_command_output('rm -f {}'.format(
                os.path.join(utils.install_home(), '.maascli.db')))
            raise MaasInstallError("Couldn't log in")
示例#10
0
    def create_maas_bridge(self, target_iface):
        """Creates br0 bridge using existing config for 'target_iface'.
        Bridge is defined in
        /etc/network/interfaces.d/openstack.cfg.  Existing config
        for either an existing br0 bridge or the specified target_iface
        will be commented out.
        """
        utils.get_command_output('ifdown {} br0'.format(target_iface))

        cfgfilenames = ['/etc/network/interfaces']
        cfgfilenames += glob.glob('/etc/network/interfaces.d/*.cfg')
        new_bridgefilename = os.path.join(self.tempdir.name, 'bridge.cfg')

        num_bridges = 0
        for cfn in [c for c in cfgfilenames if os.path.exists(c)]:
            created = self.create_bridge_if_exists(target_iface,
                                                   new_bridgefilename,
                                                   cfn)
            num_bridges += (1 if created else 0)

        if num_bridges > 1:
            log.warning("found multiple instances of {}, "
                        "network configuration may "
                        "be wrong".format(target_iface))

        with open('/etc/network/interfaces', 'r+') as e_n_i_file:
            contents = "".join(e_n_i_file.readlines())
            if not re.match('\s*source /etc/network/interfaces.d/\*.cfg',
                            contents):
                e_n_i_file.write("\nsource /etc/network/interfaces.d/*.cfg")

        cloudinst_cfgfilename = "/etc/network/interfaces.d/openstack.cfg"
        with open(new_bridgefilename, 'r') as new_bridge:
            with open(cloudinst_cfgfilename, 'w') as cloudinstall_cfgfile:
                bridge_config = "".join(new_bridge.readlines())
                cloudinstall_cfgfile.write("auto {}\n"
                                           "iface {} inet manual\n\n"
                                           "auto br0\n"
                                           "{}\n"
                                           "bridge_ports "
                                           "{}".format(target_iface,
                                                       target_iface,
                                                       bridge_config,
                                                       target_iface))

        res = utils.get_command_output('ifup {} br0'.format(target_iface))
        if res['status'] != 0:
            log.debug("'ifup {} br0' failed. out={}".format(target_iface, res))
            raise MaasInstallError("Failure in bridge creation")
 def set_perms(self):
     """ sets permissions
     """
     try:
         utils.chown(self.config.cfg_path,
                     utils.install_user(),
                     utils.install_user(),
                     recursive=True)
         utils.get_command_output("sudo chmod 700 {}".format(
             self.config.cfg_path))
         utils.get_command_output("sudo chmod 600 -R {}/*".format(
             self.config.cfg_path))
     except:
         raise SingleInstallException(
             "Unable to set ownership for {}".format(self.config.cfg_path))
    def create_maas_bridge(self, target_iface):
        """Creates br0 bridge using existing config for 'target_iface'.
        Bridge is defined in
        /etc/network/interfaces.d/openstack.cfg.  Existing config
        for either an existing br0 bridge or the specified target_iface
        will be commented out.
        """
        utils.get_command_output('ifdown {} br0'.format(target_iface))

        cfgfilenames = ['/etc/network/interfaces']
        cfgfilenames += glob.glob('/etc/network/interfaces.d/*.cfg')
        new_bridgefilename = os.path.join(self.tempdir.name, 'bridge.cfg')

        num_bridges = 0
        for cfn in [c for c in cfgfilenames if os.path.exists(c)]:
            created = self.create_bridge_if_exists(target_iface,
                                                   new_bridgefilename, cfn)
            num_bridges += (1 if created else 0)

        if num_bridges > 1:
            log.warning("found multiple instances of {}, "
                        "network configuration may "
                        "be wrong".format(target_iface))

        with open('/etc/network/interfaces', 'r+') as e_n_i_file:
            contents = "".join(e_n_i_file.readlines())
            if not re.match('\s*source /etc/network/interfaces.d/\*.cfg',
                            contents):
                e_n_i_file.write("\nsource /etc/network/interfaces.d/*.cfg")

        cloudinst_cfgfilename = "/etc/network/interfaces.d/openstack.cfg"
        with open(new_bridgefilename, 'r') as new_bridge:
            with open(cloudinst_cfgfilename, 'w') as cloudinstall_cfgfile:
                bridge_config = "".join(new_bridge.readlines())
                cloudinstall_cfgfile.write("auto {}\n"
                                           "iface {} inet manual\n\n"
                                           "auto br0\n"
                                           "{}\n"
                                           "bridge_ports "
                                           "{}".format(target_iface,
                                                       target_iface,
                                                       bridge_config,
                                                       target_iface))

        res = utils.get_command_output('ifup {} br0'.format(target_iface))
        if res['status'] != 0:
            log.debug("'ifup {} br0' failed. out={}".format(target_iface, res))
            raise MaasInstallError("Failure in bridge creation")
    def post_proc(self):
        """ post processing for nova-cloud-controller """
        super(CharmNovaCloudController, self).post_proc()
        svc = self.juju_state.service(self.charm_name)
        unit = svc.unit(self.charm_name)
        k_svc = self.juju_state.service('keystone')
        keystone = k_svc.unit('keystone')
        openstack_password = self.config.getopt('openstack_password')
        public_address = keystone.public_address
        if is_ipv6(public_address):
            public_address = "[%s]".format(public_address)
            log.debug("Found ipv6 address, {}".format(public_address))

        if unit.machine_id == '-1':
            return True

        for u in ['admin', 'ubuntu']:
            env = self._openstack_env(u,
                                      openstack_password,
                                      u, public_address)
            self._openstack_env_save(u, env)

        setup_script_path = self.render_setup_script()
        cmds = ("bash {script} "
                "\"{password}\" \"{install_type}\" "
                "> {cfg_home}/script.log 2>&1".format(
                    script=setup_script_path,
                    password=openstack_password,
                    cfg_home=self.config.cfg_path,
                    install_type=self.config.getopt('install_type')
                ))
        err = utils.get_command_output(cmds)
        if err['status'] != 0:
            raise CharmPostProcessException(err)
 def test_bootstrap_succeeded(self):
     """ Verifies a local bootstrap happened
     """
     cmd = ("openstack-juju stat --format yaml")
     out = utils.get_command_output(cmd)
     out = out['output']
     assert ('environment: local' in out)
示例#15
0
    def run_configure_script(self):
        "runs configure-landscape, returns output (LDS hostname)"

        ldscreds = self.config.getopt('landscapecreds')
        args = {
            "bin": self.lscape_configure_bin,
            "admin_email": shlex.quote(ldscreds['admin_email']),
            "admin_name": shlex.quote(ldscreds['admin_name']),
            "sys_email": shlex.quote(ldscreds['system_email']),
            "maas_host":
            shlex.quote(self.config.getopt('maascreds')['api_host'])
        }

        cmd = ("{bin} --admin-email {admin_email} "
               "--admin-name {admin_name} "
               "--system-email {sys_email} "
               "--maas-host {maas_host}".format(**args))

        log.debug("Running landscape configure: {}".format(cmd))

        out = utils.get_command_output(cmd, timeout=None)

        if out['status']:
            utils.pollinate(self.session_id, 'ET')
            log.error("Problem with configuring Landscape: {}.".format(out))
            raise Exception("Error configuring Landscape.")

        utils.pollinate(self.session_id, 'DL')

        return out['output'].strip()
 def detect_existing_dhcp(self, interface):
     """return True if an existing DHCP server is running on interface."""
     cmd = "nmap --script broadcast-dhcp-discover -e {}".format(interface)
     out = utils.get_command_output(cmd)
     if "DHCPOFFER" in out['output']:
         return True
     return False
示例#17
0
 def add_config_entries(cls, name, configlines):
     raw_lxc_config = "\n".join(configlines)
     out = utils.get_command_output('lxc config set {} raw.lxc '
                                    '"{}"'.format(name, raw_lxc_config),
                                    user_sudo=True)
     if out['status'] > 0:
         raise Exception("couldn't set container config")
    def deploy(self, charm, settings):
        """ Deploy a charm to an instance

        :param str charm: charm to deploy
        :param str machine_id: (optional) machine id
        :param str instances: (optional) number of instances to deploy
        :param dict constraints: (optional) machine constraints
        """
        cmd = "juju deploy"
        if 'machine_id' in settings and settings['machine_id']:
            cmd += " --to {mid}".format(mid=settings['machine_id'])

        if 'instances' in settings:
            cmd += " -n {instances}".format(instances=settings['instances'])

        if 'configfile' in settings:
            cmd += " --config {file}".format(file=settings['configfile'])

        if 'constraints' in settings:
            opts = []
            for k, v in settings['constraints'].items():
                opts.append("{k}={v}".format(k=k, v=v))
            if opts:
                cmd += " --constraints \"{opts}\"".format(opts=" ".join(opts))

        cmd += " {charm}".format(charm=charm)
        log.debug("Deploying {charm} -> {cmd}".format(charm=charm, cmd=cmd))

        cmd_ = get_command_output(cmd)
        log.debug("Deploy result: {out}".format(out=cmd_['stdout']))
        if cmd_['ret']:
            log.warning("Deploy error ({cmd}): "
                        "{out}".format(cmd=cmd, out=cmd_['stdout']))
 def test_bootstrap_succeeded(self):
     """ Verifies a local bootstrap happened
     """
     cmd = ("openstack-juju stat --format yaml")
     out = utils.get_command_output(cmd)
     out = out['output']
     assert('environment: local' in out)
示例#20
0
 def detect_existing_dhcp(self, interface):
     """return True if an existing DHCP server is running on interface."""
     cmd = "nmap --script broadcast-dhcp-discover -e {}".format(interface)
     out = utils.get_command_output(cmd)
     if "DHCPOFFER" in out['output']:
         return True
     return False
示例#21
0
    def post_proc(self):
        """ post processing for nova-cloud-controller """
        super(CharmNovaCloudController, self).post_proc()
        svc = self.juju_state.service(self.charm_name)
        unit = svc.unit(self.charm_name)
        k_svc = self.juju_state.service('keystone')
        keystone = k_svc.unit('keystone')
        openstack_password = self.config.getopt('openstack_password')
        public_address = keystone.public_address
        if is_ipv6(public_address):
            public_address = "[%s]".format(public_address)
            log.debug("Found ipv6 address, {}".format(public_address))

        if unit.machine_id == '-1':
            return True

        for u in ['admin', 'ubuntu']:
            env = self._openstack_env(u, openstack_password, u, public_address)
            self._openstack_env_save(u, env)

        setup_script_path = self.render_setup_script()
        cmds = ("bash {script} "
                "\"{password}\" \"{install_type}\" "
                "> {cfg_home}/script.log 2>&1".format(
                    script=setup_script_path,
                    password=openstack_password,
                    cfg_home=self.config.cfg_path,
                    install_type=self.config.getopt('install_type')))
        err = utils.get_command_output(cmds)
        if err['status'] != 0:
            raise CharmPostProcessException(err)
示例#22
0
    def run_configure_script(self):
        "runs configure-landscape, returns output (LDS hostname)"

        ldscreds = self.config.getopt('landscapecreds')
        args = {"bin": self.lscape_configure_bin,
                "admin_email": shlex.quote(ldscreds['admin_email']),
                "admin_name": shlex.quote(ldscreds['admin_name']),
                "sys_email": shlex.quote(ldscreds['system_email']),
                "maas_host": shlex.quote(
                    self.config.getopt('maascreds')['api_host'])}

        cmd = ("{bin} --admin-email {admin_email} "
               "--admin-name {admin_name} "
               "--system-email {sys_email} "
               "--maas-host {maas_host}".format(**args))

        log.debug("Running landscape configure: {}".format(cmd))

        out = utils.get_command_output(cmd, timeout=None)

        if out['status']:
            log.error("Problem with configuring Landscape: {}.".format(out))
            raise Exception("Error configuring Landscape.")

        return out['output'].strip()
def poll_state():
    """ Polls current state of Juju and MAAS

    :returns: list of Machine() and the Juju state
    :rtype: tuple (JujuState(), MaasState())
    """
    # Capture Juju state
    cmd = utils.get_command_output('juju status',
                                   combine_output=False)
    if cmd['ret']:
        raise SystemExit("Error connecting to juju: stderr: {e}".format(
            e=cmd['stderr']))
    juju = JujuState(cmd['stdout'])

    maas = None
    if MULTI_SYSTEM:
        # Login to MAAS
        auth = MaasAuth()
        auth.get_api_key('root')
        # auth.login()

        # Load Client routines
        c = MaasClient(auth)

        # Capture Maas state
        maas = MaasState(c.nodes)
        c.tag_fpi(maas)
        c.nodes_accept_all()
        c.tag_name(maas)

    update_machine_info(juju, maas)
    return (juju, maas)
 def add_config_entries(cls, name, configlines):
     raw_lxc_config = "\n".join(configlines)
     out = utils.get_command_output('lxc config set {} raw.lxc '
                                    '"{}"'.format(name, raw_lxc_config),
                                    user_sudo=True)
     if out['status'] > 0:
         raise Exception("couldn't set container config")
    def create(cls, name, userdata):
        """ creates a container from an image with the alias 'ubuntu'
        """

        imgname = os.getenv("LXD_IMAGE_NAME", "ubuntu")
        out = utils.get_command_output('lxc image list | '
                                       'grep {}'.format(imgname),
                                       user_sudo=True)
        if len(out['output']) == 0:
            m = ("LXD: No image named '{}' found. "
                 "Please import an image or set an alias.".format(imgname))
            raise Exception(m)

        out = utils.get_command_output('lxc init {} {}'.format(imgname,
                                                               name),
                                       user_sudo=True)
        if out['status'] > 0:
            raise Exception("Unable to create container: " +
                            out['output'] + "\nERR:\n" +
                            out['err'])

        out = utils.get_command_output('lxc config show ' + name,
                                       user_sudo=True)
        if out['status'] > 0:
            raise Exception("Unable to get container config: " +
                            out['output'] + "\nERR:\n" +
                            out['err'])

        cfgyaml = yaml.load(out['output'])
        with open(userdata, 'r') as uf:
            if 'user.user_data' in cfgyaml['config']:
                raise Exception("Container config already has userdata")

            cfgyaml['config']['user.user-data'] = "".join(uf.readlines())
            cfgyaml['config']['security.privileged'] = True

        with tempfile.NamedTemporaryFile(delete=False) as cfgtmp:
            cfgtmp.write(yaml.dump(cfgyaml).encode())
            cfgtmp.flush()
            os.chmod(cfgtmp.name, stat.S_IROTH | stat.S_IRWXU)
            cmd = 'cat {} | lxc config edit {}'.format(cfgtmp.name, name)
            out = utils.get_command_output(cmd, user_sudo=True)
            if out['status'] > 0:
                raise Exception("Unable to set userdata config: " +
                                out['output'] + "ERR" + out['err'])

        return 0
示例#26
0
    def wait(cls, name):
        """ waits for the container to be in a RUNNING state

        :param str name: name of container
        """
        out = utils.get_command_output(
            'sudo lxc-wait -n {0} -s RUNNING'.format(name))
        return out['status']
 def get_apikey(self):
     credcmd = ("maas-region-admin apikey " "--username root")
     out = utils.get_command_output(credcmd)
     if out['status'] != 0:
         log.debug("failed to get apikey: {}".format(out))
         raise MaasInstallError("Couldn't get apikey")
     apikey = out['output'].strip()
     return apikey
示例#28
0
    def wait(cls, name):
        """ waits for the container to be in a RUNNING state

        :param str name: name of container
        """
        out = utils.get_command_output(
            'sudo lxc-wait -n {0} -s RUNNING'.format(name))
        return out['status']
    def login_to_maas(self, apikey):
        cmd = ("maas login maas {} {}".format(self.LOCAL_MAAS_URL,
                                              apikey))

        out = utils.get_command_output(cmd)
        if out['status'] != 0:
            log.debug("failed to login to maas: {}".format(out))
            raise MaasInstallError("Couldn't log in")
示例#30
0
 def add_relation(self, endpoint_a, endpoint_b):
     """ Add relation between services """
     cmd = "juju add-relation {a} {b}".format(a=endpoint_a,
                                              b=endpoint_b)
     log.debug("Adding relation {a} <-> {b}".format(a=endpoint_a,
                                                    b=endpoint_b))
     ret, out, _, _ = get_command_output(cmd)
     return out
示例#31
0
 def add_devices(cls, name, devices):
     for dname, dtype, keyvalstr in devices:
         cmd = 'lxc config device add {} {} {} {}'.format(
             name, dname, dtype, keyvalstr)
         out = utils.get_command_output(cmd, user_sudo=True)
         if out['status'] > 0:
             raise Exception("couldn't add device:"
                             "out:{}\nerr{}".format(out['output'],
                                                    out['err']))
示例#32
0
 def get_apikey(self):
     credcmd = ("maas-region-admin apikey "
                "--username root")
     out = utils.get_command_output(credcmd)
     if out['status'] != 0:
         log.debug("failed to get apikey: {}".format(out))
         raise MaasInstallError("Couldn't get apikey")
     apikey = out['output'].strip()
     return apikey
示例#33
0
 def get_log_text(self, unit_name):
     name = "-".join(unit_name.split("/"))
     cmd = "sudo grep {unit} /var/log/juju-ubuntu-local/all-machines.log " " | tail -n 2"
     cmd = cmd.format(unit=name)
     out = utils.get_command_output(cmd)
     if out["status"] == 0 and len(out["output"]) > 0:
         return out["output"]
     else:
         return "No log matches for {}".format(name)
 def cloud_init_finished(self):
     """ checks the log to see if cloud-init finished
     """
     log_file = os.path.join(self.container_abspath,
                             'rootfs/var/log/cloud-init-output.log')
     out = utils.get_command_output('sudo tail -n1 {0}'.format(log_file))
     if 'finished at' in out['output']:
         return True
     return False
 def add_devices(cls, name, devices):
     for dname, dtype, keyvalstr in devices:
         cmd = 'lxc config device add {} {} {} {}'.format(name, dname,
                                                          dtype, keyvalstr)
         out = utils.get_command_output(cmd, user_sudo=True)
         if out['status'] > 0:
             raise Exception("couldn't add device:"
                             "out:{}\nerr{}".format(out['output'],
                                                    out['err']))
示例#36
0
    def create(cls, name, userdata):
        """ creates a container from an image with the alias 'ubuntu'
        """

        imgname = os.getenv("LXD_IMAGE_NAME", "ubuntu")
        out = utils.get_command_output('lxc image list | '
                                       'grep {}'.format(imgname),
                                       user_sudo=True)
        if len(out['output']) == 0:
            m = ("LXD: No image named '{}' found. "
                 "Please import an image or set an alias.".format(imgname))
            raise Exception(m)

        out = utils.get_command_output('lxc init {} {}'.format(imgname, name),
                                       user_sudo=True)
        if out['status'] > 0:
            raise Exception("Unable to create container: " + out['output'] +
                            "\nERR:\n" + out['err'])

        out = utils.get_command_output('lxc config show ' + name,
                                       user_sudo=True)
        if out['status'] > 0:
            raise Exception("Unable to get container config: " +
                            out['output'] + "\nERR:\n" + out['err'])

        cfgyaml = yaml.load(out['output'])
        with open(userdata, 'r') as uf:
            if 'user.user_data' in cfgyaml['config']:
                raise Exception("Container config already has userdata")

            cfgyaml['config']['user.user-data'] = "".join(uf.readlines())
            cfgyaml['config']['security.privileged'] = True

        with tempfile.NamedTemporaryFile(delete=False) as cfgtmp:
            cfgtmp.write(yaml.dump(cfgyaml).encode())
            cfgtmp.flush()
            os.chmod(cfgtmp.name, stat.S_IROTH | stat.S_IRWXU)
            cmd = 'cat {} | lxc config edit {}'.format(cfgtmp.name, name)
            out = utils.get_command_output(cmd, user_sudo=True)
            if out['status'] > 0:
                raise Exception("Unable to set userdata config: " +
                                out['output'] + "ERR" + out['err'])

        return 0
示例#37
0
    def configure_maas_networking(self, cluster_uuid, interface,
                                  gateway, dhcp_range, static_range):
        """ set up or update the node-group-interface.

        dhcp_range is a tuple of ip addresses as strings: (low, high)
        """
        maas_query_cmd = ('maas maas node-group-interfaces'
                          ' list {}'.format(cluster_uuid))
        out = utils.get_command_output(maas_query_cmd)
        interfaces = json.loads(out['output'])
        nmatching = len([i for i in interfaces
                         if i['interface'] == interface])
        interface_exists = nmatching == 1

        paramstr = ('ip={address} interface={interface} '
                    'management=2 subnet_mask={netmask} '
                    'broadcast_ip={bcast} router_ip={gateway} '
                    'ip_range_low={ip_range_low} '
                    'ip_range_high={ip_range_high} '
                    'static_ip_range_low={static_ip_range_low} '
                    'static_ip_range_high={static_ip_range_high}')
        args = dict(uuid=cluster_uuid,
                    interface=interface,
                    address=get_ip_addr(interface),
                    netmask=get_netmask(interface),
                    bcast=get_bcast_addr(interface),
                    gateway=gateway,
                    ip_range_low=dhcp_range[0],
                    ip_range_high=dhcp_range[1],
                    static_ip_range_low=static_range[0],
                    static_ip_range_high=static_range[1])

        if interface_exists:
            cmd = ('maas maas node-group-interface update {uuid} {interface} '
                   + paramstr).format(**args)
        else:
            cmd = ('maas maas node-group-interfaces new {uuid} '
                   + paramstr).format(**args)

        out = utils.get_command_output(cmd)
        if out['status'] != 0:
            log.debug("cmd failed: {}\n - output"
                      "={}".format(cmd, out))
            raise MaasInstallError("unable to create or update network")
示例#38
0
 def get_log_text(self, unit_name):
     name = '-'.join(unit_name.split('/'))
     cmd = ("sudo grep {unit} /var/log/juju-ubuntu-local/all-machines.log "
            " | tail -n 2")
     cmd = cmd.format(unit=name)
     out = utils.get_command_output(cmd)
     if out['status'] == 0 and len(out['output']) > 0:
         return out['output']
     else:
         return "No log matches for {}".format(name)
    def create_superuser(self):
        pw = shlex.quote(self.config.getopt('openstack_password'))
        cmd = ("maas-region-admin createadmin "
               "--username root --password {} "
               "--email [email protected]".format(pw))
        out = utils.get_command_output(cmd)
        if out['status'] != 0:
            log.debug("failed to create maas admin. output" "={}".format(out))

            raise MaasInstallError("Couldn't create admin")
示例#40
0
 def get_log_text(self, unit_name):
     name = '-'.join(unit_name.split('/'))
     cmd = ("sudo grep {unit} /var/log/juju-ubuntu-local/all-machines.log "
            " | tail -n 2")
     cmd = cmd.format(unit=name)
     out = utils.get_command_output(cmd)
     if out['status'] == 0 and len(out['output']) > 0:
         return out['output']
     else:
         return "No log matches for {}".format(name)
示例#41
0
 def set_perms(self):
     """ sets permissions
     """
     try:
         log.info("Setting permissions for user {}".format(
             utils.install_user()))
         utils.chown(self.config.cfg_path,
                     utils.install_user(),
                     utils.install_user(),
                     recursive=True)
         utils.get_command_output("sudo chmod 777 {}".format(
             self.config.cfg_path))
         utils.get_command_output("sudo chmod 777 -R {}/*".format(
             self.config.cfg_path))
     except:
         msg = ("Error setting ownership for "
                "{}".format(self.config.cfg_path))
         log.exception(msg)
         raise Exception(msg)
    def configure_maas_networking(self, cluster_uuid, interface, gateway,
                                  dhcp_range, static_range):
        """ set up or update the node-group-interface.

        dhcp_range is a tuple of ip addresses as strings: (low, high)
        """
        maas_query_cmd = ('maas maas node-group-interfaces'
                          ' list {}'.format(cluster_uuid))
        out = utils.get_command_output(maas_query_cmd)
        interfaces = json.loads(out['output'])
        nmatching = len([i for i in interfaces if i['interface'] == interface])
        interface_exists = nmatching == 1

        paramstr = ('ip={address} interface={interface} '
                    'management=2 subnet_mask={netmask} '
                    'broadcast_ip={bcast} router_ip={gateway} '
                    'ip_range_low={ip_range_low} '
                    'ip_range_high={ip_range_high} '
                    'static_ip_range_low={static_ip_range_low} '
                    'static_ip_range_high={static_ip_range_high}')
        args = dict(uuid=cluster_uuid,
                    interface=interface,
                    address=get_ip_addr(interface),
                    netmask=get_netmask(interface),
                    bcast=get_bcast_addr(interface),
                    gateway=gateway,
                    ip_range_low=dhcp_range[0],
                    ip_range_high=dhcp_range[1],
                    static_ip_range_low=static_range[0],
                    static_ip_range_high=static_range[1])

        if interface_exists:
            cmd = ('maas maas node-group-interface update '
                   '{uuid} {interface} paramstr').format(**args)
        else:
            cmd = ('maas maas node-group-interfaces new {uuid} ' +
                   paramstr).format(**args)

        out = utils.get_command_output(cmd)
        if out['status'] != 0:
            log.debug("cmd failed: {}\n - output" "={}".format(cmd, out))
            raise MaasInstallError("unable to create or update network")
示例#43
0
    def configure_nat(self, network):
        cmd = ('iptables -t nat -a POSTROUTING '
               '-s {} ! -d {} -j MASQUERADE'.format(network, network))
        utils.get_command_output(cmd)

        utils.spew('/etc/network/iptables.rules',
                   "*nat\n"
                   ":PREROUTING ACCEPT [0:0]\n"
                   ":INPUT ACCEPT [0:0]\n"
                   ":OUTPUT ACCEPT [0:0]\n"
                   ":POSTROUTING ACCEPT [0:0]\n"
                   "-A POSTROUTING -s {} ! -d {} -j MASQUERADE\n"
                   "COMMIT\n".format(network, network))
        utils.get_command_output('chmod 0600 /etc/network/iptables.rules')
        cmd = ("sed -e '/^iface lo inet loopback$/a\ "
               "pre-up iptables-restore < /etc/network/iptables.rules' "
               "-i /etc/network/interfaces")
        res = utils.get_command_output(cmd)
        if res['status'] != 0:
            log.debug("error editing /etc/network/interfaces: {}".format(res))
示例#44
0
    def start(cls, name, lxc_logfile):
        """ starts lxc container

        :param str name: name of container
        """
        out = utils.get_command_output('lxc start ' + name, user_sudo=True)

        if out['status'] > 0:
            raise Exception("Unable to start container: "
                            "out:{}\nerr{}".format(out['output'], out['err']))
        return out['status']
示例#45
0
    def create_superuser(self):
        pw = self.config.openstack_password
        cmd = ("maas-region-admin createadmin "
               "--username root --password {} "
               "--email [email protected]".format(pw))
        out = utils.get_command_output(cmd)
        if out['status'] != 0:
            log.debug("failed to create maas admin. output"
                      "={}".format(out))

            raise MaasInstallError("Couldn't create admin")
 def add_relation(self, endpoint_a, endpoint_b):
     """ Add relation between services """
     cmd = "juju add-relation {a} {b}".format(a=endpoint_a,
                                              b=endpoint_b)
     cmd_ = get_command_output(cmd, combine_output=True)
     log.debug("Adding relation ({a},{b}) ".format(a=endpoint_a,
                                                   b=endpoint_b))
     if cmd_['ret']:
         log.error("Result: {r}".format(r=cmd_['stdout']))
         return True
     return False
    def configure_nat(self, network):
        cmd = ('iptables -t nat -a POSTROUTING '
               '-s {} ! -d {} -j MASQUERADE'.format(network, network))
        utils.get_command_output(cmd)

        utils.spew(
            '/etc/network/iptables.rules', "*nat\n"
            ":PREROUTING ACCEPT [0:0]\n"
            ":INPUT ACCEPT [0:0]\n"
            ":OUTPUT ACCEPT [0:0]\n"
            ":POSTROUTING ACCEPT [0:0]\n"
            "-A POSTROUTING -s {} ! -d {} -j MASQUERADE\n"
            "COMMIT\n".format(network, network))
        utils.get_command_output('chmod 0600 /etc/network/iptables.rules')
        cmd = ("sed -e '/^iface lo inet loopback$/a\ "
               "pre-up iptables-restore < /etc/network/iptables.rules' "
               "-i /etc/network/interfaces")
        res = utils.get_command_output(cmd)
        if res['status'] != 0:
            log.debug("error editing /etc/network/interfaces: {}".format(res))
示例#48
0
    def destroy(cls, name):
        """ destroys lxc container

        :param str name: name of container
        """
        out = utils.get_command_output('lxc delete ' + name, user_sudo=True)

        if out['status'] > 0:
            raise Exception("Unable to delete container: "
                            "{0}".format(out['output']))

        return out['status']
    def stop(cls, name):
        """ stops lxc container

        :param str name: name of container
        """
        out = utils.get_command_output('lxc stop ' + name, user_sudo=True)

        if out['status'] > 0:
            raise Exception("Unable to stop container: "
                            "{}".format(out['output']))

        return out['status']
    def destroy(cls, name):
        """ destroys lxc container

        :param str name: name of container
        """
        out = utils.get_command_output('lxc delete ' + name, user_sudo=True)

        if out['status'] > 0:
            raise Exception("Unable to delete container: "
                            "{0}".format(out['output']))

        return out['status']
示例#51
0
    def start(cls, name, lxc_logfile):
        """ starts lxc container

        :param str name: name of container
        """
        out = utils.get_command_output(
            'sudo lxc-start -n {0} -d -o {1}'.format(name, lxc_logfile))

        if out['status'] > 0:
            raise Exception("Unable to start container: "
                            "{0}".format(out['output']))
        return out['status']
示例#52
0
    def destroy(cls, name):
        """ destroys lxc container

        :param str name: name of container
        """
        out = utils.get_command_output('sudo lxc-destroy -n {0}'.format(name))

        if out['status'] > 0:
            raise Exception("Unable to destroy container: "
                            "{0}".format(out['output']))

        return out['status']
示例#53
0
    def stop(cls, name):
        """ stops lxc container

        :param str name: name of container
        """
        out = utils.get_command_output('lxc stop ' + name, user_sudo=True)

        if out['status'] > 0:
            raise Exception("Unable to stop container: "
                            "{}".format(out['output']))

        return out['status']
示例#54
0
    def add_static_route(self, lxc_net):
        """ Adds static route to host system
        """
        # Store container IP in config
        ip = Container.ip(self.container_name)
        self.config.setopt("container_ip", ip)

        log.info("Adding static route for {} via {}".format(lxc_net, ip))

        out = utils.get_command_output("ip route add {} via {} dev lxcbr0".format(lxc_net, ip))
        if out["status"] != 0:
            raise Exception("Could not add static route for {}" " network: {}".format(lxc_net, out["output"]))
示例#55
0
    def wait_checked(cls, name, check_logfile, interval=20):
        """waits for container to be in RUNNING state, checking
        'check_logfile' every 'interval' seconds for error messages.

        Intended to be used with container_start, which uses 'lxc-start
        -d', which returns 0 immediately and does not detect errors.

        returns when the container 'name' is in RUNNING state.
        raises an exception if errors are detected.
        """
        while True:
            out = utils.get_command_output('sudo lxc-wait -n {} -s RUNNING '
                                           '-t {}'.format(name, interval))
            if out['status'] == 0:
                return
            log.debug("{} not RUNNING after {} seconds, "
                      "checking '{}' for errors".format(
                          name, interval, check_logfile))
            grepout = utils.get_command_output(
                'grep -q ERROR {}'.format(check_logfile))
            if grepout['status'] == 0:
                raise Exception("Error detected starting container. See {} "
                                "for details.".format(check_logfile))
示例#56
0
    def add_static_route(self, lxc_net):
        """ Adds static route to host system
        """
        # Store container IP in config
        ip = Container.ip(self.container_name)
        self.config.setopt('container_ip', ip)

        log.info("Adding static route for {} via {}".format(lxc_net, ip))

        out = utils.get_command_output(
            'ip route add {} via {} dev lxcbr0'.format(lxc_net, ip))
        if out['status'] != 0:
            raise Exception("Could not add static route for {}"
                            " network: {}".format(lxc_net, out['output']))
 def configure_dns(self):
     with open('/etc/bind/named.conf.options', 'w') as nco_file:
         with open('/etc/resolv.conf', 'r') as resolv_conf_file:
             forwarders = "".join([
                 "\t\t{};\n".format(l.split()[1])
                 for l in resolv_conf_file.readlines()
                 if l.startswith('nameserver')
             ])
         nco_file.write(DNS_CONF_TEMPLATE.format(forwarders))
     utils.get_command_output('service bind9 restart')
     utils.get_command_output("sed -e '/^iface lo inet loopback$/a"
                              "\\n#added by openstack-install\\n"
                              "dns-nameservers 127.0.0.1' "
                              " -i /etc/network/interfaces")
     utils.get_command_output('ifdown lo')
     utils.get_command_output('ifup lo')
示例#58
0
    def cp(cls, name, src, dst):
        """ copy file to container

        :param str name: name of container
        :param str src: file to copy to container
        :param str dst: destination full path
        """

        cmd = ("lxc file push {src} {name}/{dst} ".format(dst=dst,
                                                          name=name,
                                                          src=src))
        ret = utils.get_command_output(cmd)
        if ret['status'] > 0:
            raise Exception("There was a problem copying ({0}) to the "
                            "container ({1}): out:'{2}'\nerr:{3}"
                            "\ncmd:{4}".format(src, name, ret['output'],
                                               ret['err'], cmd))
示例#59
0
    def wait_checked(cls, name, check_logfile, interval=20):
        """waits for container to be in RUNNING state.

        Ignores check_logfile.

        returns when the container 'name' is in RUNNING state.
        raises an exception if errors are detected.
        """
        while True:
            cmd = 'lxc info {} | grep Status'.format(name)
            out = utils.get_command_output(cmd, user_sudo=True)
            if out['status'] != 0:
                raise Exception("Error getting container info {}".format(out))
            outstr = out['output'].strip()
            if outstr == "Status: Running":
                return
            time.sleep(4)
    def test_get_command_output_user_sudo(self, mock_Popen, mock_env):
        mock_env.copy.return_value = {'FOO': 'bazbot'}
        outb, errb = bytes('out', 'utf-8'), bytes('err', 'utf-8')
        mock_Popen.return_value.communicate.return_value = (outb, errb)
        mock_Popen.return_value.returncode = 4747
        with patch('cloudinstall.utils.install_user') as mock_install_user:
            mock_install_user.return_value = 'fakeuser'
            rv = get_command_output("fake", user_sudo=True)
            self.assertEqual(rv, dict(output='out', err='err',
                                      status=4747))

        mock_Popen.assert_called_with("sudo -E -H -u fakeuser fake",
                                      shell=True,
                                      stdout=PIPE, stderr=PIPE,
                                      bufsize=-1,
                                      env={'LC_ALL': 'C',
                                           'FOO': 'bazbot'},
                                      close_fds=True)