def wait_for_registration(self):
        cmd = "maas maas node-groups list"

        def get_uuid(odict):
            ostr = odict['output']
            ngs = json.loads(ostr)
            return ngs[0]['uuid']

        def uuid_not_master(odict):
            return get_uuid(odict) != 'master'

        succeeded = utils.poll_until_true(cmd, uuid_not_master, 5)
        if not succeeded:
            msg = "timed out waiting for cluster registration"
            log.debug(msg)
            raise MaasInstallError(msg)

        out = utils.get_command_output(cmd)
        if out['status'] != 0:
            log.debug("failed to get cluster UUID. out={}".format(out))
            raise MaasInstallError("Error in cluster registration")

        return get_uuid(out)
    def wait_for_registration(self):
        cmd = "maas maas node-groups list"

        def get_uuid(odict):
            ostr = odict['output']
            ngs = json.loads(ostr)
            return ngs[0]['uuid']

        def uuid_not_master(odict):
            return get_uuid(odict) != 'master'

        succeeded = utils.poll_until_true(cmd, uuid_not_master, 5)
        if not succeeded:
            msg = "timed out waiting for cluster registration"
            log.debug(msg)
            raise MaasInstallError(msg)

        out = utils.get_command_output(cmd)
        if out['status'] != 0:
            log.debug("failed to get cluster UUID. out={}".format(out))
            raise MaasInstallError("Error in cluster registration")

        return get_uuid(out)
    def continue_with_interface(self):
        self.display_controller.ui.hide_widget_on_top()
        self.start_task("Installing MAAS")

        check_output('mkdir -p /etc/openstack', shell=True)
        check_output(['cp', '/etc/network/interfaces',
                      '/etc/openstack/interfaces.cloud.bak'])
        check_output(['cp', '-r', '/etc/network/interfaces.d',
                      '/etc/openstack/interfaces.cloud.d.bak'])

        utils.spew('/etc/openstack/interface', self.target_iface)

        utils.apt_install('openstack-multi')

        self.start_task("Configuring MAAS")
        self.create_superuser()
        self.apikey = self.get_apikey()

        self.login_to_maas(self.apikey)

        try:
            utils.chown(os.path.join(utils.install_home(), '.maascli.db'),
                        utils.install_user(),
                        utils.install_user())
        except:
            raise MaasInstallError("Unable to set permissions on {}".format(
                os.path.join(utils.install_home(), '.maascli.db')))

        self.start_task("Waiting for MAAS cluster registration")
        cluster_uuid = self.wait_for_registration()
        self.create_maas_bridge(self.target_iface)

        self.prompt_for_bridge()

        self.start_task("Configuring MAAS networks")
        self.configure_maas_networking(cluster_uuid,
                                       'br0',
                                       self.gateway,
                                       self.dhcp_range,
                                       self.static_range)

        self.configure_dns()

        self.config.save_maas_creds(self.gateway,
                                    self.apikey)

        if "MAAS_HTTP_PROXY" in os.environ:
            pv = os.environ['MAAS_HTTP_PROXY']
            out = utils.get_command_output('maas maas maas set-config '
                                           'name=http_proxy '
                                           'value={}'.format(pv))
            if out['status'] != 0:
                log.debug("Error setting maas proxy config: {}".format(out))
                raise MaasInstallError("Error setting proxy config")

        self.display_controller.info_message("Importing MAAS boot images")
        self.start_task("Importing MAAS boot images")
        out = utils.get_command_output('maas maas boot-resources import')
        if out['status'] != 0:
            log.debug("Error starting boot images import: {}".format(out))
            raise MaasInstallError("Error setting proxy config")

        def pred(out):
            return out['output'] != '[]'

        ok = utils.poll_until_true('maas maas boot-images read '
                                   ' {}'.format(cluster_uuid),
                                   pred, 15, timeout=7200)
        if not ok:
            log.debug("poll timed out for getting boot images")
            raise MaasInstallError("Downloading boot images timed out")

        self.display_controller.info_message("Done importing boot images")

        self.stop_current_task()
        msg = "Waiting for sufficient resources in MAAS"
        self.display_controller.info_message(msg)
        self.display_controller.current_installer = self
        self.display_controller.current_state = InstallState.NODE_WAIT
    def create_bootstrap_kvm(self):
        self.display_controller.info_message(
            "Initializing environment for Juju ...")
        out = utils.get_command_output('usermod -a -G libvirtd maas')
        if out['status'] != 0:
            log.debug("error adding maas user to libvirtd: {}".format(out))
            raise MaasInstallError("error in creating bootstrap kvm")

        out = utils.get_command_output('service maas-clusterd restart')
        if out['status'] != 0:
            log.debug("error restarting maas-clusterd: {}".format(out))
            raise MaasInstallError("error in creating bootstrap kvm")

        if self.config.is_landscape:
            vcpus = 2
            ram = 4096
            disk = 40
        else:
            # only juju state server
            vcpus = 1
            ram = 2048
            disk = 20
        # TODO investigate if this breaks with someone attempting nested
        # kvm installations. REF http://git.io/8z4xBw
        cmd = ("virt-install --name juju-bootstrap "
               "--ram={ram} --vcpus={vcpus} "
               "--hvm --virt-type=kvm --pxe --boot network,hd "
               "--os-variant=ubuntutrusty --graphics vnc --noautoconsole "
               "--os-type=linux --accelerate "
               "--disk=/var/lib/libvirt/images/juju-bootstrap.qcow2,"
               # no space here...
               "bus=virtio,format=qcow2,cache=none,sparse=true,"
               # no space here...
               "size={disk} "
               "--network=bridge=br0,model=virtio".format(ram=ram,
                                                          vcpus=vcpus,
                                                          disk=disk))

        out = utils.get_command_output(cmd)
        if out['status'] != 0:
            log.debug("error creating kvm: {}".format(out))
            raise MaasInstallError("Could not create KVM with {}MB RAM, "
                                   "{}G disk and {} vcpus.".format(ram,
                                                                   disk,
                                                                   vcpus))

        out = utils.get_command_output("virsh dumpxml juju-bootstrap "
                                       " | grep 'mac address' | cut -d\\' -f2")
        if out['status'] != 0:
            log.debug("error creating kvm: {}".format(out))
            raise MaasInstallError("error in creating bootstrap kvm")

        kvm_mac = out['output'].strip()

        cmd = ("maas maas nodes new architecture=amd64/generic "
               "mac_addresses={} "
               "hostname=juju-bootstrap nodegroup=$cluster_uuid "
               "power_type=virsh "
               "power_parameters_power_address=qemu:///system "
               "power_parameters_power_id=juju-bootstrap".format(kvm_mac))

        out = utils.get_command_output(cmd)
        if out['status'] != 0:
            log.debug("error creating bootstrap node: {}"
                      "command was:\n{}".format(out, cmd))
            raise MaasInstallError("error in creating bootstrap kvm")

        out = utils.get_command_output('maas maas nodes list '
                                       'mac_address={}'.format(kvm_mac))
        if out['status'] != 0:
            log.debug("error getting system id of kvm: {}".format(out))
            raise MaasInstallError("error in creating bootstrap kvm")

        system_id = json.loads(out['output'])[0]['system_id']

        # out = utils.get_command_output('juju --show-log sync-tools',
        #                                user_sudo=True)
        # if out['status'] != 0:
        #     log.debug("error in sync-tools: {}".format(out))
        #     raise MaasInstallError("error in creating bootstrap kvm")

        def get_node_status(output):
            return json.loads(output)[0]['status']

        # wait until status is 4
        ok = utils.poll_until_true('maas maas nodes list '
                                   'id={}'.format(system_id),
                                   lambda o: get_node_status(o['output']) == 4,
                                   5)
        if not ok:
            log.debug("waiting for status == 4 timed out.")
            raise MaasInstallError("error in bootstrap node creation")
    def continue_with_interface(self):
        self.display_controller.hide_widget_on_top()
        self.tasker.start_task("Installing MAAS")

        check_output('mkdir -p /etc/openstack', shell=True)
        check_output([
            'cp', '/etc/network/interfaces',
            '/etc/openstack/interfaces.cloud.bak'
        ])
        check_output([
            'cp', '-r', '/etc/network/interfaces.d',
            '/etc/openstack/interfaces.cloud.d.bak'
        ])

        utils.spew('/etc/openstack/interface', self.target_iface)

        utils.apt_install('openstack-multi')

        self.tasker.start_task("Configuring MAAS")
        self.create_superuser()
        self.apikey = self.get_apikey()

        self.login_to_maas(self.apikey)

        try:
            utils.chown(os.path.join(utils.install_home(), '.maascli.db'),
                        utils.install_user(), utils.install_user())
        except:
            raise MaasInstallError("Unable to set permissions on {}".format(
                os.path.join(utils.install_home(), '.maascli.db')))

        self.tasker.start_task("Waiting for MAAS cluster registration")
        cluster_uuid = self.wait_for_registration()
        self.create_maas_bridge(self.target_iface)

        self.prompt_for_bridge()

        self.tasker.start_task("Configuring MAAS networks")
        self.configure_maas_networking(cluster_uuid, 'br0', self.gateway,
                                       self.dhcp_range, self.static_range)

        self.configure_dns()

        self.config.setopt('maascreds',
                           dict(api_host=self.gateway, api_key=self.apikey))

        if "MAAS_HTTP_PROXY" in os.environ:
            pv = os.environ['MAAS_HTTP_PROXY']
            out = utils.get_command_output('maas maas maas set-config '
                                           'name=http_proxy '
                                           'value={}'.format(pv))
            if out['status'] != 0:
                log.debug("Error setting maas proxy config: {}".format(out))
                raise MaasInstallError("Error setting proxy config")

        self.display_controller.status_info_message(
            "Importing MAAS boot images")
        self.tasker.start_task("Importing MAAS boot images")
        out = utils.get_command_output('maas maas boot-resources import')
        if out['status'] != 0:
            log.debug("Error starting boot images import: {}".format(out))
            raise MaasInstallError("Error setting proxy config")

        def pred(out):
            return out['output'] != '[]'

        ok = utils.poll_until_true('maas maas boot-images read '
                                   ' {}'.format(cluster_uuid),
                                   pred,
                                   15,
                                   timeout=7200)
        if not ok:
            log.debug("poll timed out for getting boot images")
            raise MaasInstallError("Downloading boot images timed out")

        self.display_controller.status_info_message(
            "Done importing boot images")

        self.tasker.stop_current_task()
        msg = "Waiting for sufficient resources in MAAS"
        self.display_controller.status_info_message(msg)
        self.display_controller.current_installer = self
        self.display_controller.current_state = InstallState.NODE_WAIT