def __init__(self,
                 dcos_url: str,
                 masters: Optional[List[str]],
                 slaves: Optional[List[str]],
                 public_slaves: Optional[List[str]],
                 default_os_user: str,
                 auth_user: Optional[DcosUser],
                 exhibitor_admin_password: Optional[str] = None):
        """Proxy class for DC/OS clusters. If any of the host lists (masters,
        slaves, public_slaves) are provided, the wait_for_dcos function of this
        class will wait until provisioning is complete. If these lists are not
        provided, then there is no ground truth and the cluster will be assumed
        the be in a completed state.

        Args:
            dcos_url: address for the DC/OS web UI.
            masters: list of Mesos master advertised IP addresses.
            slaves: list of Mesos slave/agent advertised IP addresses.
            public_slaves: list of public Mesos slave/agent advertised IP addresses.
            default_os_user: default user that marathon/metronome will launch tasks under
            auth_user: use this user's auth for all requests
                Note: user must be authenticated explicitly or call self.wait_for_dcos()
        """
        super().__init__(Url.from_string(dcos_url))
        self.master_list = masters
        self.slave_list = slaves
        self.public_slave_list = public_slaves
        self.default_os_user = default_os_user
        self.auth_user = auth_user
        self.exhibitor_admin_password = exhibitor_admin_password
    def exhibitor(self):
        if self.exhibitor_admin_password is None:
            # No basic HTTP auth. Access Exhibitor via the adminrouter.
            default_url = self.default_url.copy(path='exhibitor')
        else:
            # Exhibitor is protected with HTTP basic auth, which conflicts with adminrouter's auth. We must bypass
            # the adminrouter and access Exhibitor directly.
            default_url = Url.from_string('http://{}:8181'.format(
                self.masters[0]))

        return Exhibitor(
            default_url=default_url,
            session=self.copy().session,
            exhibitor_admin_password=self.exhibitor_admin_password)
Beispiel #3
0
    def wait(self):
        log.info('Waiting for bare cluster provisioning status..')
        self.get_bare_cluster_launcher().wait()
        cluster = self.get_onprem_cluster()
        log.info('Waiting for SSH connectivity to cluster host...')
        for host in cluster.hosts:
            cluster.ssh_client.wait_for_ssh_connection(host.public_ip,
                                                       self.config['ssh_port'])

        self.bootstrap_host = cluster.bootstrap_host.public_ip
        try:
            self.get_ssh_client().command(self.bootstrap_host,
                                          ['test', '-f', STATE_FILE])
            last_complete = self.get_last_state()
            log.info('Detected previous launch state, continuing '
                     'from last complete stage ({})'.format(last_complete))
        except subprocess.CalledProcessError:
            log.info(
                'No installation state file detected; beginning fresh install...'
            )
            last_complete = None

        if last_complete is None:
            cluster.setup_installer_server(self.config['installer_url'], False)
            last_complete = 'SETUP'
            self.post_state(last_complete)

        installer = dcos_test_utils.onprem.DcosInstallerApiSession(
            Url('http', self.bootstrap_host, '', '', '',
                self.config['installer_port']))
        if last_complete == 'SETUP':
            last_complete = 'GENCONF'
            installer.genconf(self.get_completed_onprem_config(cluster))
            self.post_state(last_complete)
        if last_complete == 'GENCONF':
            installer.preflight()
            last_complete = 'PREFLIGHT'
            self.post_state(last_complete)
        if last_complete == 'PREFLIGHT':
            installer.deploy()
            last_complete = 'DEPLOY'
            self.post_state(last_complete)
        if last_complete == 'DEPLOY':
            installer.postflight()
            last_complete = 'POSTFLIGHT'
            self.post_state(last_complete)
        if last_complete != 'POSTFLIGHT':
            raise dcos_launch.util.LauncherError(
                'InconsistentState',
                'State on bootstrap host is: ' + last_complete)
Beispiel #4
0
    def api_session_from_host(cls,
                              ssh_client: SshClient,
                              host: str,
                              installer_url: str,
                              offline_mode: bool,
                              port: int = 9000):
        """ Will download and start a DC/OS onprem installer and return a
        DcosInstallerApiSession to interact with it

        Args:
            ssh_client: SshClient object to access the server hosting the installer
            host: IP address of the target host server
            installer_url: URL to pull the installer from relative to the host
            offline_mode: if True, installer will start with the --offline-mode
                option which disables installing pre-requisites from the internet
            port: the installer can run on an arbitrary port but defaults to 9000
        """
        ssh_client.add_ssh_user_to_docker_users(host)

        host_home = ssh_client.get_home_dir(host)
        installer_path = host_home + '/dcos_generate_config.sh'

        download_dcos_installer(ssh_client, host, installer_path,
                                installer_url)

        log.info('Starting installer server at: {}:{}'.format(host, port))
        cmd = [
            'DCOS_INSTALLER_DAEMONIZE=true', 'bash', installer_path, '--web',
            '-p',
            str(port)
        ]
        if offline_mode:
            cmd.append('--offline')
        ssh_client.command(host, cmd)

        api = cls(Url('http', host, '', '', '', port))

        @retry(wait_fixed=1000, stop_max_delay=60000)
        def wait_for_up():
            log.debug('Waiting for installer server...')
            api.get('/').raise_for_status()

        wait_for_up()
        log.info('Installer server is up and running!')
        return api
def mock_url():
    """A URL that is accepted by DcosApiSession."""
    return Url('https', 'localhost', 'service/metronome', '', '', port=443)