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:
parent
95c9cf6ec6
commit
ed7083ed88
@ -1,7 +1,8 @@
|
|||||||
Create Server
|
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)::
|
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 OS_REGION_NAME=DFW
|
||||||
export FLAVOR="8 GB Performance"
|
export FLAVOR="8 GB Performance"
|
||||||
export FQDN=servername01.opendev.org
|
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
|
--cloud=$OS_CLOUD --region=$OS_REGION_NAME
|
||||||
|
|
||||||
Manually add the hostname to DNS (the launch script does not do so
|
Manually add the hostname to DNS (the launch script does not do so
|
||||||
automatically, but it prints the commands to run). Note that for
|
automatically, but it prints the commands to run). Note that for
|
||||||
*.opendev.org hosts you'll only be able to add the reverse dns
|
*.opendev.org hosts you'll only be able to add the reverse dns
|
||||||
records via the printed commands. Forward A and AAAA records should
|
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
|
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 ansible runs see the new host. The launch script prints out
|
||||||
the appropriate lines to add to
|
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
|
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,
|
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
|
ssh root@$FQDN
|
||||||
|
|
||||||
@ -38,6 +39,6 @@ Add DNS Records
|
|||||||
|
|
||||||
The launch-node script will print the commands needed to be
|
The launch-node script will print the commands needed to be
|
||||||
run to configure DNS for a newly launched server. To see the commands
|
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
32
launch/pyproject.toml
Normal 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"]
|
0
launch/src/opendev_launch/__init__.py
Normal file
0
launch/src/opendev_launch/__init__.py
Normal file
@ -19,7 +19,7 @@
|
|||||||
# limitations under the License.
|
# limitations under the License.
|
||||||
|
|
||||||
import argparse
|
import argparse
|
||||||
from sshfp import sshfp_print_records
|
from .sshfp import sshfp_print_records
|
||||||
|
|
||||||
def get_href(server):
|
def get_href(server):
|
||||||
if not hasattr(server, 'links'):
|
if not hasattr(server, 'links'):
|
||||||
@ -131,6 +131,3 @@ def main():
|
|||||||
" openstacksdk >= 0.12 is required")
|
" openstacksdk >= 0.12 is required")
|
||||||
raise
|
raise
|
||||||
print_dns(cloud, server)
|
print_dns(cloud, server)
|
||||||
|
|
||||||
if __name__ == '__main__':
|
|
||||||
main()
|
|
@ -28,15 +28,15 @@ import tempfile
|
|||||||
import time
|
import time
|
||||||
import traceback
|
import traceback
|
||||||
|
|
||||||
import dns
|
from . import dns
|
||||||
import utils
|
from . import utils
|
||||||
|
|
||||||
import openstack
|
import openstack
|
||||||
import paramiko
|
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:
|
try:
|
||||||
# This unactionable warning does not need to be printed over and over.
|
# 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("When requesting an exception you can use the")
|
||||||
print("infra-root@openstack.org email address to verify the responsible")
|
print("infra-root@openstack.org email address to verify the responsible")
|
||||||
print("party.")
|
print("party.")
|
||||||
|
|
||||||
if __name__ == '__main__':
|
|
||||||
main()
|
|
@ -23,7 +23,7 @@ import socket
|
|||||||
|
|
||||||
import paramiko
|
import paramiko
|
||||||
|
|
||||||
from sshclient import SSHClient
|
from .sshclient import SSHClient
|
||||||
|
|
||||||
|
|
||||||
def iterate_timeout(max_seconds, purpose):
|
def iterate_timeout(max_seconds, purpose):
|
1
playbooks/roles/install-launch-node/README.rst
Normal file
1
playbooks/roles/install-launch-node/README.rst
Normal file
@ -0,0 +1 @@
|
|||||||
|
Install the launch node script to a venv
|
11
playbooks/roles/install-launch-node/tasks/main.yaml
Normal file
11
playbooks/roles/install-launch-node/tasks/main.yaml
Normal 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'
|
||||||
|
|
@ -62,3 +62,7 @@
|
|||||||
vars:
|
vars:
|
||||||
logrotate_file_name: /var/log/ansible/zuul_reboot.log
|
logrotate_file_name: /var/log/ansible/zuul_reboot.log
|
||||||
logrotate_frequency: weekly
|
logrotate_frequency: weekly
|
||||||
|
|
||||||
|
- name: Install node launcher
|
||||||
|
include_role:
|
||||||
|
name: install-launch-node
|
||||||
|
@ -23,14 +23,12 @@ def test_zuul_data(host, zuul_data):
|
|||||||
assert 'extra' in zuul_data
|
assert 'extra' in zuul_data
|
||||||
assert 'zuul' in zuul_data['extra']
|
assert 'zuul' in zuul_data['extra']
|
||||||
|
|
||||||
|
|
||||||
def test_clouds_yaml(host):
|
def test_clouds_yaml(host):
|
||||||
clouds_yaml = host.file('/etc/openstack/clouds.yaml')
|
clouds_yaml = host.file('/etc/openstack/clouds.yaml')
|
||||||
assert clouds_yaml.exists
|
assert clouds_yaml.exists
|
||||||
|
|
||||||
assert b'password' in clouds_yaml.content
|
assert b'password' in clouds_yaml.content
|
||||||
|
|
||||||
|
|
||||||
def test_openstacksdk_config(host):
|
def test_openstacksdk_config(host):
|
||||||
f = host.file('/etc/openstack')
|
f = host.file('/etc/openstack')
|
||||||
assert f.exists
|
assert f.exists
|
||||||
@ -47,7 +45,6 @@ def test_openstacksdk_config(host):
|
|||||||
assert f.group == 'root'
|
assert f.group == 'root'
|
||||||
assert f.mode == 0o640
|
assert f.mode == 0o640
|
||||||
|
|
||||||
|
|
||||||
def test_root_authorized_keys(host):
|
def test_root_authorized_keys(host):
|
||||||
authorized_keys = host.file('/root/.ssh/authorized_keys')
|
authorized_keys = host.file('/root/.ssh/authorized_keys')
|
||||||
assert authorized_keys.exists
|
assert authorized_keys.exists
|
||||||
@ -56,14 +53,12 @@ def test_root_authorized_keys(host):
|
|||||||
lines = content.split('\n')
|
lines = content.split('\n')
|
||||||
assert len(lines) >= 2
|
assert len(lines) >= 2
|
||||||
|
|
||||||
|
|
||||||
def test_ara(host):
|
def test_ara(host):
|
||||||
ara = host.run('/usr/ansible-venv/bin/ara-manage migrate')
|
ara = host.run('/usr/ansible-venv/bin/ara-manage migrate')
|
||||||
assert ara.rc == 0
|
assert ara.rc == 0
|
||||||
database = host.file('/root/.ara/server/ansible.sqlite')
|
database = host.file('/root/.ara/server/ansible.sqlite')
|
||||||
assert database.exists
|
assert database.exists
|
||||||
|
|
||||||
|
|
||||||
def test_kube_config(host):
|
def test_kube_config(host):
|
||||||
if platform.machine() != 'x86_64':
|
if platform.machine() != 'x86_64':
|
||||||
pytest.skip()
|
pytest.skip()
|
||||||
@ -72,14 +67,12 @@ def test_kube_config(host):
|
|||||||
|
|
||||||
assert b'Z2l0ZWFfazhzX2tleQ==' in kubeconfig.content
|
assert b'Z2l0ZWFfazhzX2tleQ==' in kubeconfig.content
|
||||||
|
|
||||||
|
|
||||||
def test_kubectl(host):
|
def test_kubectl(host):
|
||||||
if platform.machine() != 'x86_64':
|
if platform.machine() != 'x86_64':
|
||||||
pytest.skip()
|
pytest.skip()
|
||||||
kube = host.run('kubectl help')
|
kube = host.run('kubectl help')
|
||||||
assert kube.rc == 0
|
assert kube.rc == 0
|
||||||
|
|
||||||
|
|
||||||
def test_zuul_authorized_keys(host):
|
def test_zuul_authorized_keys(host):
|
||||||
authorized_keys = host.file('/home/zuul/.ssh/authorized_keys')
|
authorized_keys = host.file('/home/zuul/.ssh/authorized_keys')
|
||||||
assert authorized_keys.exists
|
assert authorized_keys.exists
|
||||||
@ -92,7 +85,6 @@ def test_zuul_authorized_keys(host):
|
|||||||
for key in keys:
|
for key in keys:
|
||||||
assert 'ssh-rsa' in key
|
assert 'ssh-rsa' in key
|
||||||
|
|
||||||
|
|
||||||
def test_rax_dns_backup(host):
|
def test_rax_dns_backup(host):
|
||||||
config_file = host.file('/etc/rax-dns-auth.conf')
|
config_file = host.file('/etc/rax-dns-auth.conf')
|
||||||
assert config_file.exists
|
assert config_file.exists
|
||||||
@ -103,7 +95,6 @@ def test_rax_dns_backup(host):
|
|||||||
output_dir = host.file('/var/lib/rax-dns-backup')
|
output_dir = host.file('/var/lib/rax-dns-backup')
|
||||||
assert output_dir.exists
|
assert output_dir.exists
|
||||||
|
|
||||||
|
|
||||||
def test_ssh_known_hosts(host):
|
def test_ssh_known_hosts(host):
|
||||||
f = host.file('/etc/ssh/ssh_known_hosts')
|
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
|
# Nothing special about this host, just testing it has an entry we
|
||||||
# expect.
|
# 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
|
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
|
||||||
|
Loading…
x
Reference in New Issue
Block a user