def install_dcos(cluster: onprem.OnpremCluster, node_client: ssh_client.SshClient, prereqs_script_path: str, install_prereqs: bool, bootstrap_script_url: str, parallelism: int, enable_selinux: Union[bool, None]): """ Args: cluster: cluster abstraction for handling network addresses node_client: SshClient that can access all non-bootstrap nodes in `cluster` prereqs_script_path: if given, this will be run before preflight on any nodes bootstrap_script_url: where the installation script will be pulled from (see do_genconf) parallelism: how many concurrent SSH tunnels to run enable_selinux: attempt to enable selinux on every node """ # Check to make sure we can talk to the cluster for host in cluster.cluster_hosts: node_client.wait_for_ssh_connection(host.public_ip) # do genconf and configure bootstrap if necessary all_client = get_client(cluster, 'cluster_hosts', node_client, parallelism=parallelism) # enable or disable selinux depending on the config if enable_selinux is not None: setenforce = '1' if enable_selinux else '0' check_results( all_client.run_command('run', ['sudo setenforce ' + setenforce]), node_client, 'Set SELinux mode') # install prereqs if enabled if install_prereqs: log.info('Copying prereqs installation script on cluster hosts') check_results( all_client.run_command('copy', prereqs_script_path, '~/install_prereqs.sh', False), node_client, 'copy install_prereqs script') log.info('Installing prerequisites on cluster hosts') check_results( all_client.run_command('run', [ 'chmod +x ~/install_prereqs.sh', '&&', '~/install_prereqs.sh' ]), node_client, 'install DC/OS prerequisites') log.info('Prerequisites installed.') # download install script from boostrap host and run it remote_script_path = '/tmp/install_dcos.sh' log.info('Starting preflight') check_results( do_preflight(all_client, remote_script_path, bootstrap_script_url), node_client, 'preflight') log.info('Preflight check succeeded; moving onto deploy') check_results( do_deploy(cluster, node_client, parallelism, remote_script_path), node_client, 'deploy') log.info('Deploy succeeded; moving onto postflight') check_results(do_postflight(all_client), node_client, 'postflight') log.info('Postflight succeeded')
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 test_ssh_client(tunnel_args, tmpdir): """ Copies data to 'remote' (localhost) and then commands to cat that data back """ src_text = str(uuid.uuid4()) src_file = tmpdir.join('src') src_file.write(src_text) dst_file = tmpdir.join('dst') read_cmd = ['cat', str(dst_file)] with open_tunnel(**tunnel_args) as t: t.copy_file(str(src_file), str(dst_file)) dst_text = t.command(read_cmd).decode().strip() assert dst_text == src_text, 'retrieved destination file did not match source!' ssh_client = SshClient(tunnel_args['user'], tunnel_args['key']) ssh_client_out = ssh_client.command( tunnel_args['host'], read_cmd, port=tunnel_args['port']).decode().strip() assert ssh_client_out == src_text, 'SshClient did not produce the expected result!'
def install_dcos(cluster: onprem.OnpremCluster, node_client: ssh_client.SshClient, prereqs_script_path: str, install_prereqs: bool, bootstrap_script_url: str, parallelism: int): """ Args: cluster: cluster abstraction for handling network addresses node_client: SshClient that can access all non-bootstrap nodes in `cluster` prereqs_script_path: if given, this will be run before preflight on any nodes bootstrap_script_url: where the installation script will be pulled from (see do_genconf) parallelism: how many concurrent SSH tunnels to run """ # Check to make sure we can talk to the cluster for host in cluster.cluster_hosts: node_client.wait_for_ssh_connection(host.public_ip) # do genconf and configure bootstrap if necessary all_client = get_client(cluster, 'cluster_hosts', node_client, parallelism=parallelism) # install prereqs if enabled if install_prereqs: log.info('Installing prerequisites on cluster hosts') with open(prereqs_script_path, 'r') as p: commands = p.readlines() check_results(all_client.run_command('run', commands), node_client, 'install_prereqs') log.info('Prerequisites installed.') # download install script from boostrap host and run it remote_script_path = '/tmp/install_dcos.sh' log.info('Starting preflight') check_results( do_preflight(all_client, remote_script_path, bootstrap_script_url), node_client, 'preflight') log.info('Preflight check succeeded; moving onto deploy') check_results( do_deploy(cluster, node_client, parallelism, remote_script_path), node_client, 'deploy') log.info('Deploy succeeded; moving onto postflight') check_results(do_postflight(all_client), node_client, 'postflight') log.info('Postflight succeeded')
def reset_bootstrap_host(ssh: ssh_client.SshClient, bootstrap_host: str): with ssh.tunnel(bootstrap_host) as t: log.info('Checking for previous installer before starting upgrade') home_dir = t.command(['pwd']).decode().strip() previous_installer = t.command( ['docker', 'ps', '--quiet', '--filter', 'name=dcos-genconf']).decode().strip() if previous_installer: log.info('Previous installer found, killing...') t.command(['docker', 'rm', '--force', previous_installer]) t.command([ 'sudo', 'rm', '-rf', os.path.join(home_dir, 'genconf*'), os.path.join(home_dir, 'dcos*') ])