launch-node : make into a small package

This turns launch-node into an installable package.  This is not meant
for distribution, we just encapsulate the installation in a virtualenv
on the bastion host.  Small updates to documentation and simple
testing are added (also remove some spaces to make test_bridge.py
consistent).

Change-Id: Ibcb4774114d73600753ca155ed277d775964bc79
This commit is contained in:
Ian Wienand 2022-11-21 16:28:57 +11:00
parent 95c9cf6ec6
commit ed7083ed88
No known key found for this signature in database
14 changed files with 68 additions and 29 deletions

View File

@ -1,7 +1,8 @@
Create Server
=============
The commands in this section should be run as root.
The commands in this section should be run as root on the bastion
host.
To launch a node in the OpenStack CI account (production servers)::
@ -9,24 +10,24 @@ To launch a node in the OpenStack CI account (production servers)::
export OS_REGION_NAME=DFW
export FLAVOR="8 GB Performance"
export FQDN=servername01.opendev.org
cd /opt/system-config/launch/
./launch-node.py $FQDN --flavor "$FLAVOR" \
/usr/launcher-venv/bin/launch-node $FQDN --flavor "$FLAVOR" \
--cloud=$OS_CLOUD --region=$OS_REGION_NAME
Manually add the hostname to DNS (the launch script does not do so
automatically, but it prints the commands to run). Note that for
*.opendev.org hosts you'll only be able to add the reverse dns
records via the printed commands. Forward A and AAAA records should
be added to opendev/zone-opendev.org/zones/opendev.org/zone.db.
be added to ``opendev/zone-opendev.org/zones/opendev.org/zone.db``.
We need to add the host to our static inventory file so that
the ansible runs see the new host. The launch script prints out
the appropriate lines to add to
opendev/system-config:inventory/openstack.yaml.
``opendev/system-config:inventory/openstack.yaml``.
In order for Ansible to work, you also need to accept the root SSH
key for the new server. Once the new DNS entries have propagated,
as root on bridge.openstack.org:
as ``root`` on the bastion server::
ssh root@$FQDN
@ -38,6 +39,6 @@ Add DNS Records
The launch-node script will print the commands needed to be
run to configure DNS for a newly launched server. To see the commands
for an existing server, run:
for an existing server, run::
./dns.py $FQDN
/usr/launcher-venv/bin/show-dns $FQDN

32
launch/pyproject.toml Normal file
View File

@ -0,0 +1,32 @@
[build-system]
requires = ["setuptools>=61.0"]
build-backend = "setuptools.build_meta"
[project]
name = "opendev_launch"
version = "1.0.0"
description = "launch nodes"
requires-python = ">=3.6"
classifiers = [
"Programming Language :: Python :: 3",
"License :: OSI Approved :: Apache2 License",
"Operating System :: OS Independent",
]
dependencies = [
"paramiko>=2.9.1",
# This is a very specific list which is known to work
# with RAX storage...
"python-openstackclient==4.0.2",
"python-cinderclient==9.1.0",
"openstacksdk==0.102.0"
]
[project.urls]
"Homepage" = "https://opendev.org/"
[project.scripts]
launch-node = "opendev_launch:launch_node.main"
show-dns = "opendev_launch:dns.main"
[tool.setuptools.package-data]
opendev_launch = ["*.sh"]

View File

View File

@ -19,7 +19,7 @@
# limitations under the License.
import argparse
from sshfp import sshfp_print_records
from .sshfp import sshfp_print_records
def get_href(server):
if not hasattr(server, 'links'):
@ -131,6 +131,3 @@ def main():
" openstacksdk >= 0.12 is required")
raise
print_dns(cloud, server)
if __name__ == '__main__':
main()

View File

@ -28,15 +28,15 @@ import tempfile
import time
import traceback
import dns
import utils
from . import dns
from . import utils
import openstack
import paramiko
from sshclient import SSHException
from .sshclient import SSHException
SCRIPT_DIR = os.path.dirname(sys.argv[0])
SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__))
try:
# This unactionable warning does not need to be printed over and over.
@ -419,6 +419,3 @@ def main():
print("When requesting an exception you can use the")
print("infra-root@openstack.org email address to verify the responsible")
print("party.")
if __name__ == '__main__':
main()

View File

@ -23,7 +23,7 @@ import socket
import paramiko
from sshclient import SSHClient
from .sshclient import SSHClient
def iterate_timeout(max_seconds, purpose):

View File

@ -0,0 +1 @@
Install the launch node script to a venv

View File

@ -0,0 +1,11 @@
- name: Create launcher venv
include_role:
name: create-venv
vars:
create_venv_path: '/usr/launcher-venv'
- name: Install node launcher
pip:
name: 'file:///home/zuul/src/opendev.org/opendev/system-config/launch'
virtualenv: '/usr/launcher-venv'

View File

@ -62,3 +62,7 @@
vars:
logrotate_file_name: /var/log/ansible/zuul_reboot.log
logrotate_frequency: weekly
- name: Install node launcher
include_role:
name: install-launch-node

View File

@ -23,14 +23,12 @@ def test_zuul_data(host, zuul_data):
assert 'extra' in zuul_data
assert 'zuul' in zuul_data['extra']
def test_clouds_yaml(host):
clouds_yaml = host.file('/etc/openstack/clouds.yaml')
assert clouds_yaml.exists
assert b'password' in clouds_yaml.content
def test_openstacksdk_config(host):
f = host.file('/etc/openstack')
assert f.exists
@ -47,7 +45,6 @@ def test_openstacksdk_config(host):
assert f.group == 'root'
assert f.mode == 0o640
def test_root_authorized_keys(host):
authorized_keys = host.file('/root/.ssh/authorized_keys')
assert authorized_keys.exists
@ -56,14 +53,12 @@ def test_root_authorized_keys(host):
lines = content.split('\n')
assert len(lines) >= 2
def test_ara(host):
ara = host.run('/usr/ansible-venv/bin/ara-manage migrate')
assert ara.rc == 0
database = host.file('/root/.ara/server/ansible.sqlite')
assert database.exists
def test_kube_config(host):
if platform.machine() != 'x86_64':
pytest.skip()
@ -72,14 +67,12 @@ def test_kube_config(host):
assert b'Z2l0ZWFfazhzX2tleQ==' in kubeconfig.content
def test_kubectl(host):
if platform.machine() != 'x86_64':
pytest.skip()
kube = host.run('kubectl help')
assert kube.rc == 0
def test_zuul_authorized_keys(host):
authorized_keys = host.file('/home/zuul/.ssh/authorized_keys')
assert authorized_keys.exists
@ -92,7 +85,6 @@ def test_zuul_authorized_keys(host):
for key in keys:
assert 'ssh-rsa' in key
def test_rax_dns_backup(host):
config_file = host.file('/etc/rax-dns-auth.conf')
assert config_file.exists
@ -103,7 +95,6 @@ def test_rax_dns_backup(host):
output_dir = host.file('/var/lib/rax-dns-backup')
assert output_dir.exists
def test_ssh_known_hosts(host):
f = host.file('/etc/ssh/ssh_known_hosts')
@ -116,3 +107,8 @@ def test_ssh_known_hosts(host):
# Nothing special about this host, just testing it has an entry we
# expect.
assert b'bridge01.opendev.org,104.130.253.34,2001:4800:7818:103:be76:4eff:fe04:48c1 ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIGG6WTR3dkhn766C69IRcLNN1Oxx7WMrcNsN03r+uZbU' in f.content
def test_launch_node_venv(host):
launch = host.run('/usr/launcher-venv/bin/launch-node --help')
assert 'usage: launch-node' in launch.stdout
assert launch.rc == 0