diff --git a/deployment/virtualbox/pybox/Parser.py b/deployment/virtualbox/pybox/Parser.py index f9dd5fef..73ed60c6 100644 --- a/deployment/virtualbox/pybox/Parser.py +++ b/deployment/virtualbox/pybox/Parser.py @@ -100,7 +100,7 @@ def handle_args(): Directory with config files, scripts, images (i.e. lab_setup.sh, lab_setup.conf, ...) that are needed for the install. All files at this location are - transfered to controller-0 in /home/wrsroot. You + transfered to controller-0 in /home/sysadmin. You can add you own scripts that you need to be present on the controller. Caution: rsync will follow links and will fail if links are broken! @@ -117,13 +117,19 @@ def handle_args(): parser.add_argument("--config-controller-ini", help= """ Path to the local config_controller .ini. This - file is transfered to the controller. NOTE: OAM + file is transferred to the controller. NOTE: OAM configuration in this ini is updated dynamically based on networking related args. (e.g. stx_config.ini_centos, ~/stx_config.ini_centos, /home/myousaf ...). """, type=str) + parser.add_argument("--ansible-controller-config", help= + """ + Path to a local YAML file to be copied as localhost.yml + to the home directory of the controller-0. + """, + type=str) parser.add_argument("--vbox-home-dir", help= """ This is the folder where vbox disks will be @@ -367,7 +373,7 @@ def handle_args(): type=str, choices=['serial', 'graphical'], default='serial') parser.add_argument("--username", help= """ - Username. default is 'wrsroot' + Username. default is 'sysadmin' """, type=str) parser.add_argument("--password", help= diff --git a/deployment/virtualbox/pybox/README.txt b/deployment/virtualbox/pybox/README.md similarity index 53% rename from deployment/virtualbox/pybox/README.txt rename to deployment/virtualbox/pybox/README.md index 9b3ae7a8..8131cefd 100644 --- a/deployment/virtualbox/pybox/README.txt +++ b/deployment/virtualbox/pybox/README.md @@ -1,11 +1,29 @@ -Pybox -===== +# Pybox -The automated installer provides you with an easy tool to install -StarlingX AIO-SX, AIO-DX, Standard, and Storage setups on Linux hosts on -Virtualbox 5.1.x. +This automated installer provides you with an easy way to install +StarlingX in many different configuration options. The following +acronyms are important to understand: -The main concepts of the autoinstaller is the stage and the chain. A stage +- `AIO` stands for All-In-One, and it means that a single host might +be responsible for more than one role. +- `SX` stands for Simplex, and it means there's only one controller node +that the whole installation depends on. +- `DX` stands for Duplex, and it means that 2 or more controllers will +be arranged in a high-availability setup. + +The configurations available from this script, via the `--setup-type` +parameter, are: + +- `AIO-SX` or "All-In-One Simplex" will set up one single VM that will be both +a controller and a worker nodes. +- `AIO-DX` or "All-In-One Duplex" will set up two controller VMs with one of +them also being a worker. +- `Standard` and `Storage` setups are currently under review. + +Overall Design of the Code +-------------------------- + +The main concepts of the autoinstaller are stages and chains. A stage is an atomic set of actions taken by the autoinstaller. A chain is a set of stages executed in a specific order. Stages can be executed independently and repeated as many times the user needs. Chains can be @@ -19,7 +37,7 @@ Example stages: - config-controller # Run config controller using the - config-controller-ini updated based on --ini-* options. - rsync-config # Rsync all files from --config-files-dir and - --config-files-dir* to /home/wrsroot. + --config-files-dir* to /home/sysadmin. - lab-setup1 # Run lab_setup with one or more --lab-setup-conf files from controller-0. - unlock-controller-0 # Unlock controller-0 and wait for it to reboot. @@ -47,8 +65,7 @@ the user does not need to reinstall from scratch. The user can restore the snapshot of the previous stage, whether to retry or fix the issue manually, then continue the process. -List of Features ----------------- +## List of Features Basic: - Multi-user, and multiple lab installs can run at the same time. @@ -93,23 +110,66 @@ Other features chain) - Support to install lowlatency and securityprofile -Installation ------------- +## Installation and Usage -Prerequisites: +This section covers a basic functioning example of the **All-In-One Simplex +(AIO-SX) installation**, which creates one VM that will work as both a +Controller and a Worker. A NAT Network between the host and the Virtual Machine +will be configured and used. -- Install Virtualbox. It is recommend v5.1.x. Use v5.2 at your own risk -- Configure at least a vbox hostonly adapter network. If you want to - use NAT, you must also configue a NAT Network. -- Make sure you have rsync, ssh-keygen, and sshpass commands installed. -- Install python3 and pip3 if not already done. +>_NOTE_: the following steps assume you're on a Debian-based Linux box. -Sample Usage ------------- +1. Install dependencies: -./install_vbox.py --setup-type AIO-SX --iso-location -"/home/myousaf/bootimage.iso" --labname test --install-mode serial ---config-files-dir /home/myousaf/pybox/configs/aio-sx/ ---config-controller-ini -/home/myousaf/pybox/configs/aio-sx/stx_config.ini_centos --vboxnet-name -vboxnet0 --controller0-ip 10.10.10.8 --ini-oam-cidr '10.10.10.0/24' + ```shell + sudo apt install virtualbox socat git rsync sshpass openssh-client python3-pip python3-venv + ``` + +2. Create a NAT Network with the `VBoxManage` CLI that is installed with VirtualBox: + + ```shell + VBoxManage natnetwork add --netname NatNetwork --network 10.10.10.0/24 --dhcp off --ipv6 on + VBoxManage natnetwork modify --netname NatNetwork --port-forward-4 http-8080:tcp:[]:8080:[10.10.10.3]:8080 + ``` + +3. Checkout the repository, and set up Python's Virtual Environment with: + + ```shell + git clone https://opendev.org/starlingx/tools.git + cd tools/deployment/virtualbox/pybox + python3 -m venv venv + source ./venv/bin/activate + pip install --upgrade pip + pip install -r requirements.txt + ``` + +4. Grab the latest ISO (this script was last tested with version 8.0.0): + + ```shell + wget https://mirror.starlingx.cengn.ca/mirror/starlingx/release/latest_release/debian/monolithic/outputs/iso/starlingx-intel-x86-64-cd.iso \ + -O $HOME/Downloads/stx-8.iso + ``` + +5. Now you're ready to run the script. From the `/deployment/virtualbox/pybox` +folder, do: + + ```shell + python3 ./install_vbox.py --setup-type AIO-SX \ + --iso-location "$HOME/Downloads/stx-8.iso" \ + --labname StarlingX --install-mode serial \ + --config-files-dir ./configs/aio-sx/ \ + --config-controller-ini ./configs/aio-sx/stx_config.ini_centos \ + --ansible-controller-config ./configs/aio-sx/localhost.yml \ + --vboxnet-type nat \ + --vboxnet-name NatNetwork \ + --nat-controller0-local-ssh-port 3122 \ + --controller0-ip 10.10.10.3 \ + --ini-oam-cidr '10.10.10.0/24' \ + --snapshot + ``` + +The script takes a while to do all the things (from creating a VM and +installing an OS in it to configuring StarlingX). Several restarts might +occur, and you might see a VirtualBox with a prompt. You don't need to type +anything. While the installation script is running it will take care of +everything for you. diff --git a/deployment/virtualbox/pybox/configs/aio-sx/lab_setup.sh b/deployment/virtualbox/pybox/configs/aio-sx/lab_setup.sh index 2f94e638..c137f04e 100755 --- a/deployment/virtualbox/pybox/configs/aio-sx/lab_setup.sh +++ b/deployment/virtualbox/pybox/configs/aio-sx/lab_setup.sh @@ -628,19 +628,19 @@ MGMTQOSWEIGHT=8 ## ## local_lvm - nova-local volume group is created and physical volumes are ## added. The instances logical volume is created and -## mounted at /etc/nova/instances. The instances logical +## mounted at /etc/platform/instances. The instances logical ## volume uses a subset of the available space within the ## volume group. Instance disks are logical volumes created ## out of the available space in the nova-local volume group ## local_image - nova-local volume group is created and physical volumes ## are added. The instances logical volume is created and -## mounted at /etc/nova/instances. The instances logical is +## mounted at /etc/platform/instances. The instances logical is ## sized to use 100% of the volume group. Instance disks are ## file based CoW images contained within -## /etc/nova/instances. +## /etc/platform/instances. ## remote - nova-local volume group is created and physical volumes are ## added. The instances logical volume is created and -## mounted at /etc/nova/instances. The instances logical is +## mounted at /etc/platform/instances. The instances logical is ## sized to use 100% of the volume group. Instance disks are ## RBD based from the ceph ephemeral pool. ## diff --git a/deployment/virtualbox/pybox/configs/aio-sx/lab_setup1.sh b/deployment/virtualbox/pybox/configs/aio-sx/lab_setup1.sh new file mode 100644 index 00000000..e8a42fc5 --- /dev/null +++ b/deployment/virtualbox/pybox/configs/aio-sx/lab_setup1.sh @@ -0,0 +1,65 @@ +#!/bin/bash + +## This file makes the necessary configuration for the unlock of the Controller-0 + +GROUPNO=0 +DATE_FORMAT="%Y-%m-%d %T" +LOG_FILE=${LOG_FILE:-"${HOME}/lab_setup_1.group${GROUPNO}.log"} +VERBOSE_LEVEL=0 + +OPENRC=/etc/platform/openrc +source ${OPENRC} + + +function info { + local MSG="$1" + + echo ${MSG} + echo $(date +"${DATE_FORMAT}") ${MSG} >> ${LOG_FILE} +} + + +function log_command { + local CMD=$1 + local MSG="[${OS_USERNAME}@${OS_PROJECT_NAME}]> RUNNING: ${CMD}" + + set +e + if [ ${VERBOSE_LEVEL} -gt 0 ]; then + echo ${MSG} + fi + echo $(date +"${DATE_FORMAT}") ${MSG} >> ${LOG_FILE} + + if [ ${VERBOSE_LEVEL} -gt 1 ]; then + eval ${CMD} 2>&1 | tee -a ${LOG_FILE} + RET=${PIPESTATUS[0]} + else + eval ${CMD} &>> ${LOG_FILE} + RET=$? + fi + + if [ ${RET} -ne 0 ]; then + info "COMMAND FAILED (rc=${RET}): ${CMD}" + info "===========================" + info "Check \"${LOG_FILE}\" for more details, fix the issues and" + info "re-run the failed command manually." + exit 1 + fi + set -e + + return ${RET} +} + + +## Set OAM interface +function configure_OAM_interface { + #Set OAM_IF variable + log_command "OAM_IF=enp0s3" + #Associate OAM_IF with Controller-0 + log_command "system host-if-modify controller-0 $OAM_IF -c platform" + log_command "system interface-network-assign controller-0 $OAM_IF oam" + + return 0 +} + + +configure_OAM_interface diff --git a/deployment/virtualbox/pybox/configs/aio-sx/localhost.yml b/deployment/virtualbox/pybox/configs/aio-sx/localhost.yml new file mode 100644 index 00000000..1b2b6278 --- /dev/null +++ b/deployment/virtualbox/pybox/configs/aio-sx/localhost.yml @@ -0,0 +1,13 @@ +system_mode: simplex + +dns_servers: +- 1.1.1.1 +- 8.8.8.8 + +external_oam_subnet: 10.10.10.0/24 +external_oam_gateway_address: 10.10.10.1 +external_oam_floating_address: 10.10.10.3 + +admin_username: admin +admin_password: Li69nux* +ansible_become_pass: Li69nux* \ No newline at end of file diff --git a/deployment/virtualbox/pybox/consts/config.ini b/deployment/virtualbox/pybox/consts/config.ini index b5e9177f..80e66ab8 100644 --- a/deployment/virtualbox/pybox/consts/config.ini +++ b/deployment/virtualbox/pybox/consts/config.ini @@ -61,7 +61,7 @@ name=vbox floating_ip=10.10.10.7 controller-0_ip=10.10.10.8 controller-1_ip=10.10.10.9 -username=wrsroot +username=sysadmin password=Li69nux* [Serial] diff --git a/deployment/virtualbox/pybox/consts/env.py b/deployment/virtualbox/pybox/consts/env.py index c946e547..4c894016 100644 --- a/deployment/virtualbox/pybox/consts/env.py +++ b/deployment/virtualbox/pybox/consts/env.py @@ -22,6 +22,6 @@ class Lab: 'floating_ip': '10.10.10.7', 'controller-0_ip': '10.10.10.8', 'controller-1_ip': '10.10.10.9', - 'username': 'wrsroot', + 'username': 'sysadmin', 'password': 'Li69nux*', } diff --git a/deployment/virtualbox/pybox/helper/host_helper.py b/deployment/virtualbox/pybox/helper/host_helper.py index ae4540e7..67184550 100644 --- a/deployment/virtualbox/pybox/helper/host_helper.py +++ b/deployment/virtualbox/pybox/helper/host_helper.py @@ -103,7 +103,7 @@ def disable_logout(stream): serial.send_bytes(stream, "export TMOUT=0") -def change_password(stream, username="wrsroot", password="Li69nux*"): +def change_password(stream, username="sysadmin", password="Li69nux*"): """ changes the default password on initial login. Args: @@ -114,15 +114,15 @@ def change_password(stream, username="wrsroot", password="Li69nux*"): serial.send_bytes(stream, username, expect_prompt=False) serial.expect_bytes(stream, "Password:") serial.send_bytes(stream, username, expect_prompt=False) - serial.expect_bytes(stream, "UNIX password:") + serial.expect_bytes(stream, "Current password:") serial.send_bytes(stream, username, expect_prompt=False) serial.expect_bytes(stream, "New password:") serial.send_bytes(stream, password, expect_prompt=False) - serial.expect_bytes(stream, "Retype new") + serial.expect_bytes(stream, "Retype new password") serial.send_bytes(stream, password) -def login(stream, timeout=600, username="wrsroot", password="Li69nux*"): +def login(stream, timeout=600, username="sysadmin", password="Li69nux*"): """ Logs into controller-0. Args: diff --git a/deployment/virtualbox/pybox/helper/install_lab.py b/deployment/virtualbox/pybox/helper/install_lab.py index 9c1786bf..f1c9d74a 100644 --- a/deployment/virtualbox/pybox/helper/install_lab.py +++ b/deployment/virtualbox/pybox/helper/install_lab.py @@ -30,7 +30,7 @@ def set_dns(stream, dns_ip): """ LOG.info("Configuring DNS to %s.", dns_ip) - serial.send_bytes(stream, "source /etc/nova/openrc; system dns-modify " + serial.send_bytes(stream, "source /etc/platform/openrc; system dns-modify " "nameservers={}".format(dns_ip), prompt='keystone') @@ -43,9 +43,10 @@ def config_controller(stream, config_file=None, password='Li69nux*'): if config_file: args += '--config-file ' + config_file + ' ' - serial.send_bytes(stream, "sudo config_controller {}".format(args), expect_prompt=False) + # serial.send_bytes(stream, f'sudo config_controller {args}', expect_prompt=False) + serial.send_bytes(stream, 'ansible-playbook /usr/share/ansible/stx-ansible/playbooks/bootstrap.yml', expect_prompt=False) host_helper.check_password(stream, password=password) - ret = serial.expect_bytes(stream, "unlock controller to proceed.", + ret = serial.expect_bytes(stream, "~$", timeout=HostTimeout.LAB_CONFIG) if ret != 0: LOG.info("Configuration failed. Exiting installer.") diff --git a/deployment/virtualbox/pybox/install_vbox.py b/deployment/virtualbox/pybox/install_vbox.py index 8f69dff2..7cec686e 100755 --- a/deployment/virtualbox/pybox/install_vbox.py +++ b/deployment/virtualbox/pybox/install_vbox.py @@ -48,15 +48,19 @@ def menu_selector(stream, setup_type, # Wait for menu to load (add sleep so we can see what is picked) serial.expect_bytes(stream, "Press") + # Pick install type if setup_type in [AIO_SX, AIO_DX]: - LOG.info("Selecting AIO controller") - serial.send_bytes(stream, "\033[B", expect_prompt=False, send=False) - if lowlatency is True: - LOG.info("Selecting low latency controller") + LOG.info("Selecting All-in-one Install") serial.send_bytes(stream, "\033[B", expect_prompt=False, send=False) + if lowlatency is True: + LOG.info("Selecting All-in-one (lowlatency) Install") + serial.send_bytes(stream, "\033[B", expect_prompt=False, send=False) + else: + LOG.info("Selecting Controller Install") serial.send_bytes(stream, "\n", expect_prompt=False, send=False) time.sleep(4) + # Serial or Graphical menu (picking Serial by default) if install_mode == "graphical": LOG.info("Selecting Graphical menu") @@ -65,6 +69,7 @@ def menu_selector(stream, setup_type, LOG.info("Selecting Serial menu") serial.send_bytes(stream, "\n", expect_prompt=False, send=False) time.sleep(6) + # Security profile menu if securityprofile == "extended": LOG.info("Selecting extended security profile") @@ -531,7 +536,7 @@ def wait_for_hosts(ssh_client, hostnames, status, raise Exception("VMs failed to go %s!", status) # Get host list host_statuses, _, _ = run_ssh_cmd( - ssh_client, 'source /etc/nova/openrc; system host-list', timeout=30) + ssh_client, 'source /etc/platform/openrc; system host-list', timeout=30) host_statuses = host_statuses[1:-1] for host_status in host_statuses: for host in hostnames: @@ -610,7 +615,7 @@ def set_serial_prompt_mode(stream, mode): if serial.send_bytes(stream, vboxoptions.password, prompt="~$", fail_ok=True, timeout=30): raise Exception("Login failure, invalid password?") if mode == CONSOLE_USER_MODE: - serial.send_bytes(stream, "source /etc/nova/openrc\n", + serial.send_bytes(stream, "source /etc/platform/openrc\n", timeout=30, prompt='keystone') serial_console_mode = CONSOLE_USER_MODE if mode == 'root' and serial_console_mode != 'root': @@ -621,7 +626,7 @@ def set_serial_prompt_mode(stream, mode): "cd /home/wrsroot", prompt="/home/wrsroot# ", timeout=30) - serial.send_bytes(stream, "source /etc/nova/openrc\n", + serial.send_bytes(stream, "source /etc/platform/openrc\n", timeout=30, prompt='keystone') serial_console_mode = CONSOLE_ROOT_MODE serial.send_bytes(stream, "export TMOUT=0", timeout=10, prompt='keystone') @@ -742,57 +747,56 @@ def stage_install_controller0(): def stage_config_controller(stream): ip, port = get_ssh_ip_and_port( 'controller-0') # Floating ip is not yet configured - if True: - # Updated config file - LOG.info("#### Updating config_controller ini file networking" \ - "settings and uploading it to controller.") - destination = "/home/" + \ - vboxoptions.username + "/stx_config.ini_centos" - configini = configparser.ConfigParser() - configini.optionxform = str - configini.read(vboxoptions.config_controller_ini) - old_cidr = configini['OAM_NETWORK']['CIDR'] - new_cidr = vboxoptions.ini_oam_cidr - LOG.info("Replacing OAM_NETWORK/CIDR from %s to %s", old_cidr, new_cidr) - configini['OAM_NETWORK']['CIDR'] = new_cidr - old_gateway = configini['OAM_NETWORK']['GATEWAY'] - new_gateway = vboxoptions.vboxnet_ip - LOG.info("Replacing OAM_NETWORK/GATEWAY from %s to %s", old_gateway, new_gateway) - configini['OAM_NETWORK']['GATEWAY'] = new_gateway - if vboxoptions.setup_type == AIO_SX: - old_ip_address = configini['OAM_NETWORK']['IP_ADDRESS'] - new_ip_address = vboxoptions.controller0_ip - LOG.info("Replacing OAM_NETWORK/IP_ADDRESS from %s to %s", - old_ip_address, new_ip_address) - configini['OAM_NETWORK']['IP_ADDRESS'] = new_ip_address - else: - old_start_addr = configini['OAM_NETWORK']['IP_START_ADDRESS'] - new_start_addr = vboxoptions.ini_oam_ip_start_address - LOG.info("Replacing OAM_NETWORK/IP_START_ADDRESS from %s to %s", - old_start_addr, new_start_addr) - configini['OAM_NETWORK']['IP_START_ADDRESS'] = new_start_addr - old_end_addr = configini['OAM_NETWORK']['IP_END_ADDRESS'] - new_end_addr = vboxoptions.ini_oam_ip_end_address - LOG.info("Replacing OAM_NETWORK/IP_END_ADDRESS from %s to %s", - old_end_addr, new_end_addr) - configini['OAM_NETWORK']['IP_END_ADDRESS'] = new_end_addr - # Take updated config file and copy it to controller - with tempfile.NamedTemporaryFile(mode='w') as fp: - configini.write(fp, space_around_delimiters=False) - fp.flush() - - sftp_send( - fp.name, remote_host=ip, remote_port=port, destination=destination, - username=vboxoptions.username, password=vboxoptions.password) + # Updated config file + LOG.info("#### Updating config_controller ini file networking" \ + "settings and uploading it to controller.") + destination = "/home/" + \ + vboxoptions.username + "/stx_config.ini_centos" + configini = configparser.ConfigParser() + configini.optionxform = str + configini.read(vboxoptions.config_controller_ini) + old_cidr = configini['OAM_NETWORK']['CIDR'] + new_cidr = vboxoptions.ini_oam_cidr + LOG.info("Replacing OAM_NETWORK/CIDR from %s to %s", old_cidr, new_cidr) + configini['OAM_NETWORK']['CIDR'] = new_cidr + old_gateway = configini['OAM_NETWORK']['GATEWAY'] + new_gateway = vboxoptions.vboxnet_ip + LOG.info("Replacing OAM_NETWORK/GATEWAY from %s to %s", old_gateway, new_gateway) + configini['OAM_NETWORK']['GATEWAY'] = new_gateway + if vboxoptions.setup_type == AIO_SX: + old_ip_address = configini['OAM_NETWORK']['IP_ADDRESS'] + new_ip_address = vboxoptions.controller0_ip + LOG.info("Replacing OAM_NETWORK/IP_ADDRESS from %s to %s", + old_ip_address, new_ip_address) + configini['OAM_NETWORK']['IP_ADDRESS'] = new_ip_address else: - destination = "/home/" + \ - vboxoptions.username + "/stx_config.ini_centos" + old_start_addr = configini['OAM_NETWORK']['IP_START_ADDRESS'] + new_start_addr = vboxoptions.ini_oam_ip_start_address + LOG.info("Replacing OAM_NETWORK/IP_START_ADDRESS from %s to %s", + old_start_addr, new_start_addr) + configini['OAM_NETWORK']['IP_START_ADDRESS'] = new_start_addr + old_end_addr = configini['OAM_NETWORK']['IP_END_ADDRESS'] + new_end_addr = vboxoptions.ini_oam_ip_end_address + LOG.info("Replacing OAM_NETWORK/IP_END_ADDRESS from %s to %s", + old_end_addr, new_end_addr) + configini['OAM_NETWORK']['IP_END_ADDRESS'] = new_end_addr + + # Take updated config file and copy it to controller + with tempfile.NamedTemporaryFile(mode='w') as fp: + configini.write(fp, space_around_delimiters=False) + fp.flush() + sftp_send( - vboxoptions.config_controller_ini, remote_host=ip, remote_port=port, - destination=destination, + fp.name, remote_host=ip, remote_port=port, destination=destination, username=vboxoptions.username, password=vboxoptions.password) + LOG.info("Copying Ansible configuration file") + destination_ansible = f'/home/{vboxoptions.username}/localhost.yml' + sftp_send( + vboxoptions.ansible_controller_config, remote_host=ip, remote_port=port, destination=destination_ansible, + username=vboxoptions.username, password=vboxoptions.password) + # Run config_controller LOG.info("#### Running config_controller") install_lab.config_controller(stream, config_file=destination, @@ -840,22 +844,30 @@ def get_ssh_ip_and_port(node='floating'): def stage_rsync_config(): + if not vboxoptions.config_files_dir and not vboxoptions.config_files_dir_dont_follow_links: + LOG.info("No rsync done! Please set config-files-dir " + "and/or config-files-dir-dont-follow-links") + return + # Get ip and port for ssh on floating ip ip, port = get_ssh_ip_and_port() + # Copy config files to controller if vboxoptions.config_files_dir: local_path = vboxoptions.config_files_dir + follow_links = True send_dir(source=local_path, remote_host=ip, remote_port=port, destination='/home/' + vboxoptions.username + '/', - username=vboxoptions.username, password=vboxoptions.password) + username=vboxoptions.username, password=vboxoptions.password, + follow_links=follow_links) + if vboxoptions.config_files_dir_dont_follow_links: local_path = vboxoptions.config_files_dir_dont_follow_links + follow_links = False send_dir(source=local_path, remote_host=ip, remote_port=port, destination='/home/' + vboxoptions.username + '/', - username=vboxoptions.username, password=vboxoptions.password) - if not vboxoptions.config_files_dir and not vboxoptions.config_files_dir_dont_follow_links: - LOG.info("No rsync done! Please set config-files-dir" \ - "and/or config-files-dir-dont-follow-links") + username=vboxoptions.username, password=vboxoptions.password, + follow_links=follow_links) @connect_to_serial @@ -873,19 +885,18 @@ def _run_lab_setup_serial(stream): @connect_to_ssh -def _run_lab_setup(ssh_client): +def _run_lab_setup(stage, ssh_client): conf_str = "" for cfg_file in vboxoptions.lab_setup_conf: conf_str = conf_str + " -f {}".format(cfg_file) - _, _, exitcode = run_ssh_cmd(ssh_client, - 'source /etc/platform/openrc; ' - 'export PATH="$PATH:/usr/local/bin; ' - 'export PATH="$PATH:/usr/bin; ' - 'export PATH="$PATH:/usr/local/sbin; ' - 'export PATH="$PATH:/usr/sbin"; ' - 'sh lab_setup.sh {}'.format(conf_str), - timeout=HostTimeout.LAB_INSTALL) + command = f'source /etc/platform/openrc; export ' \ + f'PATH="$PATH:/usr/local/bin"; export PATH="$PATH:/usr/bin"; ' \ + f'export PATH="$PATH:/usr/local/sbin"; export ' \ + f'PATH="$PATH:/usr/sbin"; sh lab_setup{stage}.sh' + + _, _, exitcode = run_ssh_cmd(ssh_client, command, timeout=HostTimeout.LAB_INSTALL) + if exitcode != 0: msg = "Lab setup failed, expecting exit code of 0 but got {}.".format( exitcode) @@ -894,23 +905,23 @@ def _run_lab_setup(ssh_client): def stage_lab_setup1(): - _run_lab_setup() + _run_lab_setup(1) def stage_lab_setup2(): - _run_lab_setup() + _run_lab_setup(2) def stage_lab_setup3(): - _run_lab_setup() + _run_lab_setup(3) def stage_lab_setup4(): - _run_lab_setup() + _run_lab_setup(4) def stage_lab_setup5(): - _run_lab_setup() + _run_lab_setup(5) @connect_to_ssh @@ -918,7 +929,7 @@ def stage_lab_setup5(): def stage_unlock_controller0(stream, ssh_client): LOG.info("#### Unlocking controller-0") _, _, _ = run_ssh_cmd(ssh_client, - 'source /etc/nova/openrc; system host-unlock controller-0', + 'source /etc/platform/openrc; system host-unlock controller-0', timeout=HostTimeout.CONTROLLER_UNLOCK) LOG.info("#### Waiting for controller-0 to reboot") @@ -978,7 +989,7 @@ def stage_install_nodes(ssh_client): username=vboxoptions.username, password=vboxoptions.password) # Apply host-bulk-add _, _, exitcode = run_ssh_cmd(ssh_client, - 'source /etc/nova/openrc; ', + 'source /etc/platform/openrc; ', 'system host-bulk-add {}'.format(destination), timeout=60) if exitcode != 0: @@ -1015,7 +1026,7 @@ def stage_unlock_controller1(ssh_client): LOG.info("#### Unlocking controller-1") run_ssh_cmd(ssh_client, - 'source /etc/nova/openrc; system host-unlock controller-1', + 'source /etc/platform/openrc; system host-unlock controller-1', timeout=60) LOG.info("#### waiting for controller-1 to be available.") @@ -1029,7 +1040,7 @@ def stage_unlock_storages(ssh_client): for storage in storages: run_ssh_cmd(ssh_client, - 'source /etc/nova/openrc; system host-unlock {}'.format(storage), + 'source /etc/platform/openrc; system host-unlock {}'.format(storage), timeout=60) LOG.info("Waiting 15s before next unlock") time.sleep(15) @@ -1047,7 +1058,7 @@ def stage_unlock_workers(ssh_client): for worker in workers: run_ssh_cmd( ssh_client, - 'source /etc/nova/openrc; system host-unlock {}'.format(worker), + 'source /etc/platform/openrc; system host-unlock {}'.format(worker), timeout=60) LOG.info("Waiting 15s before next unlock") time.sleep(15) @@ -1316,7 +1327,6 @@ AIO_SX_STAGES = [ STG_RSYNC_CONFIG, STG_LAB_SETUP1, STG_UNLOCK_CONTROLLER0, - STG_LAB_SETUP2, ] AIO_DX_STAGES = [ diff --git a/deployment/virtualbox/pybox/requirements.txt b/deployment/virtualbox/pybox/requirements.txt index dd488e2d..089f7795 100644 --- a/deployment/virtualbox/pybox/requirements.txt +++ b/deployment/virtualbox/pybox/requirements.txt @@ -1,6 +1,6 @@ -# Install rsync, sshpass -# configparser paramiko pytest -streamexpect +git+https://github.com/digidotcom/python-streamexpect#egg=streamexpect +pexpect + diff --git a/deployment/virtualbox/pybox/utils/sftp.py b/deployment/virtualbox/pybox/utils/sftp.py index f99084ca..1fd0388a 100644 --- a/deployment/virtualbox/pybox/utils/sftp.py +++ b/deployment/virtualbox/pybox/utils/sftp.py @@ -41,38 +41,31 @@ def sftp_send(source, remote_host, remote_port, destination, username, password) sftp_client.close() ssh_client.close() + def send_dir(source, remote_host, remote_port, destination, username, password, follow_links=True, clear_known_hosts=True): # Only works from linux for now if not source.endswith('/') or not source.endswith('\\'): source = source + '/' - params = { - 'source': source, - 'remote_host': remote_host, - 'destination': destination, - 'port': remote_port, - 'username': username, - 'password': password, - 'follow_links': "L" if follow_links else "", - } + + follow_links = "L" if follow_links else "" if clear_known_hosts: if remote_host == '127.0.0.1': keygen_arg = "[127.0.0.1]:{}".format(remote_port) else: keygen_arg = remote_host - cmd = 'ssh-keygen -f "/home/%s/.ssh/known_hosts" -R' \ - ' %s', getpass.getuser(), keygen_arg + cmd = f'ssh-keygen -f "/home/{getpass.getuser()}/.ssh/known_hosts" -R {keygen_arg}' LOG.info("CMD: %s", cmd) process = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE) for line in iter(process.stdout.readline, b''): LOG.info("%s", line.decode("utf-8").strip()) process.wait() - LOG.info("Running rsync of dir: {source} ->" \ - "{username}@{remote_host}:{destination}".format(**params)) - cmd = ("rsync -av{follow_links} " - "--rsh=\"/usr/bin/sshpass -p {password} ssh -p {port} -o StrictHostKeyChecking=no -l {username}\" " - "{source}* {username}@{remote_host}:{destination}".format(**params)) + LOG.info(f'Running rsync of dir: {source} -> {username}@{remote_host}' + f':{destination}') + cmd = (f'rsync -av{follow_links} --rsh="/usr/bin/sshpass -p {password} ' + f'ssh -p {remote_port} -o StrictHostKeyChecking=no -l {username}" ' + f'{source}* {username}@{remote_host}:{destination}') LOG.info("CMD: %s", cmd) process = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE) @@ -80,7 +73,7 @@ def send_dir(source, remote_host, remote_port, destination, username, LOG.info("%s", line.decode("utf-8").strip()) process.wait() if process.returncode: - raise Exception("Error in rsync, return code:{}".format(process.returncode)) + raise Exception(f'Error in rsync, return code: {process.returncode}') def send_dir_fallback(source, remote_host, destination, username, password): diff --git a/deployment/virtualbox/setup_vm.sh b/deployment/virtualbox/setup_vm.sh index 5600851d..3c53f88d 100755 --- a/deployment/virtualbox/setup_vm.sh +++ b/deployment/virtualbox/setup_vm.sh @@ -130,7 +130,7 @@ init_hostonly_net rm -f "$HOSTADD_SCRIPT" cat < "$HOSTADD_SCRIPT" #!/usr/bin/env bash -source /etc/nova/openrc +source /etc/platform/openrc EOF chmod +x "$HOSTADD_SCRIPT"