def __init__(self, dcos_url: str, masters: list, public_masters: list, slaves: list, public_slaves: list, default_os_user: str, auth_user: Optional[DcosUser]): """Proxy class for DC/OS clusters. Args: dcos_url: address for the DC/OS web UI. masters: list of Mesos master advertised IP addresses. public_masters: list of Mesos master IP addresses routable from the local host. slaves: list of 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.masters = sorted(masters) self.public_masters = sorted(public_masters) self.slaves = sorted(slaves) self.public_slaves = sorted(public_slaves) self.all_slaves = sorted(slaves + public_slaves) self.default_os_user = default_os_user self.auth_user = auth_user assert len(self.masters) == len(self.public_masters)
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 __init__(self, dcos_url: str, masters: list, public_masters: list, slaves: list, public_slaves: list, default_os_user: str, auth_user: Optional[DcosUser]): """Proxy class for DC/OS clusters. Args: dcos_url: address for the DC/OS web UI. masters: list of Mesos master advertised IP addresses. public_masters: list of Mesos master IP addresses routable from the local host. slaves: list of 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.masters = sorted(masters) self.public_masters = sorted(public_masters) self.slaves = sorted(slaves) self.public_slaves = sorted(public_slaves) self.all_slaves = sorted(slaves + public_slaves) self.zk_hostports = ','.join(':'.join([host, '2181']) for host in self.public_masters) self.default_os_user = default_os_user self.auth_user = auth_user assert len(self.masters) == len(self.public_masters)
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)
def api_session_from_host( cls, ssher: Ssher, 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: ssher: Ssher 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 """ ssher.command(host, ['sudo', 'usermod', '-aG', 'docker', ssher.user]) host_home = ssher.get_home_dir(host) installer_path = host_home + '/dcos_generate_config.sh' _download_dcos_installer(ssher, 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') ssher.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 wait(self): log.info('Waiting for bare cluster provisioning status..') self.get_bare_cluster_launcher().wait() cluster = self.get_onprem_cluster() self.bootstrap_host = cluster.bootstrap_host.public_ip log.info('Waiting for SSH connectivity to bootstrap host...') check_ssh(self.get_ssher(), self.bootstrap_host, self.config['ssh_port']) try: self.get_ssher().command(self.bootstrap_host, ['test', '-f', STATE_FILE]) last_complete = self.get_last_state() except subprocess.CalledProcessError: 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 = test_util.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 launch.util.LauncherError('InconsistentState', last_complete)