1
0
mirror of https://github.com/gryf/boxpy.git synced 2026-02-02 14:15:49 +01:00

19 Commits
1.0 ... 1.3.1

Author SHA1 Message Date
0093e32b74 Fix for rebuild command and calling vmdestroy function. 2021-11-04 09:26:38 +01:00
353d848072 Pass more than one machine to destroy command.
From now on, there is a possibility to pass more than one machine to be
destroyed.
2021-11-04 08:41:13 +01:00
4581ab0ed0 Specify from which Python version boxpy is supported. 2021-10-19 19:33:15 +02:00
deba0aa621 Narrow down proposed VMs to running only for ssh command. 2021-10-19 19:32:30 +02:00
6528813d6a Update examples for multinode setup 2021-10-19 19:31:18 +02:00
9699e61b35 Exit, if image checksum is wrong. 2021-10-03 19:08:15 +02:00
f46432546e Added ability to add url for write_files section. 2021-10-01 19:15:25 +02:00
fe422576cd Fixed long param for listing VMs. 2021-10-01 19:09:14 +02:00
a7b0984f77 Handle nonexisted VMs for commands. 2021-09-30 21:11:18 +02:00
085785af46 Added sudo to cloud init status command.
Some systems have to have a strict control, even in system state
information. Prefixed with "sudo" to command to gather information how
cloud init is doing.
2021-09-30 21:00:18 +02:00
9288179474 Added support for Centos Stream.
Currently default and only version supported is 8, since 9 behaves
differently with similar config drive.
2021-09-29 17:16:09 +02:00
a5702254ca Removed owner field on examples, since it's in a way. 2021-09-29 17:13:35 +02:00
74053995c8 Refactored Image classes.
There were very similar methods for downloading/proceeding with
checksum for both Ubuntu and Fedora classes. Extracted those two into
methods in base class.
2021-09-29 14:47:03 +02:00
1999f1dc7e Fixed checking existence of func in args. 2021-09-26 18:53:08 +02:00
7f99f91933 Fail on yaml parse errors 2021-09-02 18:36:57 +02:00
db8a42518e Rephrase help for VM type option. 2021-09-02 09:27:34 +02:00
c19f4f1a61 Update devstack deployment examples. 2021-08-20 08:24:50 +02:00
d7544f52f6 Added run type option to create and rebuild subcommand.
For now, the only mode VirtualBox VM has launched was headless. For
debugging purposes, there were other types allowed using --type switch
for command create and rebuild, while headless will remain the default
one.
2021-08-19 21:09:06 +02:00
3c43263bb9 Fix clashing version from boxpy and subcommands.
Currently, you could pass long version of '--version' option to either
boxpy itself and subcommands create and rebuild. With this patch proper
context is now detected.
2021-08-19 21:08:34 +02:00
7 changed files with 297 additions and 133 deletions

View File

@@ -2,8 +2,8 @@
box.py
======
Box.py is a simple automation tool meant to run Ubuntu or Fedora cloud images
on top of VirtualBox.
Box.py is a simple automation tool meant to run Ubuntu, Fedora or Centos Stream
cloud images on top of VirtualBox.
What it does is simply download official cloud image, set up VM, tweak it up
and do the initial pre-configuration using generated config drive.
@@ -16,12 +16,13 @@ weird named options for ``vboxmanage`` ;P)
Requirements
------------
- Python 3.x
- Python >=3.7
- `pyyaml`_
- `requests`_
- Virtualbox (obviously)
- ``mkisofs`` or ``genisoimage`` command for generating iso image
- ``mkisofs`` or ``genisoimage`` command for generating ISO image
- ``wget`` command for fetching images
- ``sha256sum`` command for checksum check
- ``qemu-img`` from *qemu-utils* package command for converting between images
@@ -140,11 +141,20 @@ pass filenames to the custom config, instead of filling up
permissions: '0644'
filename: /path/to/local/file.txt
during processing this file, boxpy will look for ``filename`` key in the yaml
file for the ``write_files`` sections, and it will remove that key, read the
file and put its contents under ``content`` key. What is more important, that
will be done after template processing, so there will be no interference for
possible ``$`` characters.
or
.. code:: yaml
write_files:
- path: /opt/somefile.txt
permissions: '0644'
url: https://some.url/content
during processing this file, boxpy will look for ``filename`` or ``url`` keys
in the yaml file for the ``write_files`` sections, and it will remove that key,
read the file and put its contents under ``content`` key. What is more
important, that will be done after template processing, so there will be no
interference for possible ``$`` characters.
What is more interesting is the fact, that you could use whatever cloud-init
accepts, and a special section, for keeping configuration, so that you don't
@@ -202,3 +212,4 @@ This work is licensed under GPL-3.
.. _pyyaml: https://github.com/yaml/pyyaml
.. _cloud-init: https://cloudinit.readthedocs.io
.. _requests: https://docs.python-requests.org

272
box.py
View File

@@ -4,6 +4,7 @@ import argparse
import collections.abc
import os
import random
import re
import shutil
import string
import subprocess
@@ -13,16 +14,18 @@ import time
import uuid
import xml.dom.minidom
import requests
import yaml
__version__ = "1.0"
__version__ = "1.3"
CACHE_DIR = os.environ.get('XDG_CACHE_HOME', os.path.expanduser('~/.cache'))
CLOUD_IMAGE = "ci.iso"
FEDORA_RELEASE_MAP = {'32': '1.6', '33': '1.2', '34': '1.2'}
TYPE_MAP = {'HardDisk': 'disk', 'DVD': 'dvd', 'Floppy': 'floppy'}
DISTRO_MAP = {'ubuntu': 'Ubuntu', 'fedora': 'Fedora'}
DISTRO_MAP = {'ubuntu': 'Ubuntu', 'fedora': 'Fedora',
'centos': 'Centos Stream'}
META_DATA_TPL = string.Template('''\
instance-id: $instance_id
local-hostname: $vmhostname
@@ -136,7 +139,7 @@ _boxpy() {
;;
create|rebuild)
items=(--cpus --disable-nested --disk-size --distro --forwarding
--key --memory --hostname --port --config --version)
--key --memory --hostname --port --config --version --type)
if [[ ${prev} == ${cmd} ]]; then
if [[ ${cmd} = "rebuild" ]]; then
_vms_comp vms
@@ -156,7 +159,12 @@ _boxpy() {
_ssh_identityfile
;;
--distro)
COMPREPLY=( $(compgen -W "ubuntu fedora" -- ${cur}) )
COMPREPLY=( $(compgen -W "ubuntu fedora centos" \
-- ${cur}) )
;;
--type)
COMPREPLY=( $(compgen -W "gui headless sdl separate" \
-- ${cur}) )
;;
--*)
COMPREPLY=( )
@@ -165,11 +173,16 @@ _boxpy() {
fi
;;
destroy|info)
info)
if [[ ${prev} == ${cmd} ]]; then
_vms_comp vms
fi
;;
destroy)
_vms_comp vms
_get_excluded_items "${COMPREPLY[@]}"
COMPREPLY=( $(compgen -W "$result" -- ${cur}) )
;;
list)
items=(--long --running --run-by-boxpy)
_get_excluded_items "${items[@]}"
@@ -177,7 +190,7 @@ _boxpy() {
;;
ssh)
if [[ ${prev} == ${cmd} ]]; then
_vms_comp vms
_vms_comp runningvms
fi
;;
esac
@@ -416,27 +429,52 @@ class Config:
if conf.get('write_files'):
new_list = []
for file_data in conf['write_files']:
content = None
fname = file_data.get('filename')
if not fname:
url = file_data.get('url')
if not any((fname, url)):
new_list.append(file_data)
continue
fname = os.path.expanduser(os.path.expandvars(fname))
if not os.path.exists(fname):
LOG.warning("File '%s' doesn't exists",
file_data['filename'])
continue
if fname:
key = 'filename'
content = self._read_filename(fname)
if content is None:
LOG.warning("File '%s' doesn't exists", fname)
continue
with open(fname) as fobj:
file_data['content'] = fobj.read()
del file_data['filename']
new_list.append(file_data)
if url:
key = 'url'
code, content = self._get_url(url)
if content is None:
LOG.warning("Getting url '%s' returns %s code",
url, code)
continue
if content:
file_data['content'] = content
del file_data[key]
new_list.append(file_data)
conf['write_files'] = new_list
# 3. finally dump it again.
return "#cloud-config\n" + yaml.safe_dump(conf)
def _get_url(self, url):
response = requests.get(url)
if response.status_code != 200:
return response.status_code, None
return response.status_code, response.text
def _read_filename(self, fname):
fullpath = os.path.expanduser(os.path.expandvars(fname))
if not os.path.exists(fullpath):
return
with open(fname) as fobj:
return fobj.read()
def _set_ssh_key_path(self):
self.ssh_key_path = self.key
@@ -630,7 +668,7 @@ class VBoxManage:
continue
if long_list:
info = "\n".join(Run(['vboxmanage', 'showvminfo',
info]).stdout.split('\n'))
name]).stdout.split('\n'))
machines[name] = info
return machines
@@ -751,9 +789,9 @@ class VBoxManage:
return False
return True
def poweron(self):
def poweron(self, type_='headless'):
if Run(['vboxmanage', 'startvm', self.name_or_uuid, '--type',
'headless']).returncode != 0:
type_]).returncode != 0:
LOG.fatal('Failed to start: %s', self.name_or_uuid)
raise BoxVBoxFailure()
@@ -861,21 +899,6 @@ class Image:
return False
return True
def _download_image(self):
raise NotImplementedError()
class Ubuntu(Image):
URL = "https://cloud-images.ubuntu.com/releases/%s/release/%s"
IMG = "ubuntu-%s-server-cloudimg-%s.img"
def __init__(self, vbox, version, arch, release):
super().__init__(vbox, version, arch, release)
self._img_fname = self.IMG % (version, arch)
self._img_url = self.URL % (version, self._img_fname)
self._checksum_file = 'SHA256SUMS'
self._checksum_url = self.URL % (version, self._checksum_file)
def _checksum(self):
"""
Get and check checkusm for downloaded image. Return True if the
@@ -886,15 +909,8 @@ class Ubuntu(Image):
return False
LOG.info('Calculating checksum for "%s"', self._img_fname)
expected_sum = None
fname = os.path.join(self._tmp, self._checksum_file)
Run(['wget', self._checksum_url, '-q', '-O', fname])
with open(fname) as fobj:
for line in fobj.readlines():
if self._img_fname in line:
expected_sum = line.split(' ')[0]
break
expected_sum = self._get_checksum(fname)
if not expected_sum:
LOG.fatal('Cannot find checksum for provided cloud image')
@@ -926,6 +942,32 @@ class Ubuntu(Image):
LOG.header('Downloaded image %s', self._img_fname)
return True
def _get_checksum(self, fname):
raise NotImplementedError()
class Ubuntu(Image):
URL = "https://cloud-images.ubuntu.com/releases/%s/release/%s"
IMG = "ubuntu-%s-server-cloudimg-%s.img"
def __init__(self, vbox, version, arch, release):
super().__init__(vbox, version, arch, release)
self._img_fname = self.IMG % (version, arch)
self._img_url = self.URL % (version, self._img_fname)
self._checksum_file = 'SHA256SUMS'
self._checksum_url = self.URL % (version, self._checksum_file)
def _get_checksum(self, fname):
expected_sum = None
Run(['wget', self._checksum_url, '-q', '-O', fname])
with open(fname) as fobj:
for line in fobj.readlines():
if self._img_fname in line:
expected_sum = line.split(' ')[0]
break
return expected_sum
class Fedora(Image):
URL = ("https://download.fedoraproject.org/pub/fedora/linux/releases/%s/"
@@ -940,18 +982,8 @@ class Fedora(Image):
self._checksum_file = self.CHKS % (version, release, arch)
self._checksum_url = self.URL % (version, arch, self._checksum_file)
def _checksum(self):
"""
Get and check checkusm for downloaded image. Return True if the
checksum is correct, False otherwise.
"""
if not os.path.exists(os.path.join(CACHE_DIR, self._img_fname)):
LOG.debug('Image %s not downloaded yet', self._img_fname)
return False
LOG.info('Calculating checksum for "%s"', self._img_fname)
def _get_checksum(self, fname):
expected_sum = None
fname = os.path.join(self._tmp, self._checksum_file)
Run(['wget', self._checksum_url, '-q', '-O', fname])
with open(fname) as fobj:
@@ -961,35 +993,55 @@ class Fedora(Image):
if self._img_fname in line:
expected_sum = line.split('=')[1].strip()
break
return expected_sum
if not expected_sum:
LOG.fatal('Cannot find checksum for provided cloud image')
return False
if os.path.exists(os.path.join(CACHE_DIR, self._img_fname)):
cmd = ['sha256sum', os.path.join(CACHE_DIR, self._img_fname)]
calulated_sum = Run(cmd).stdout.split(' ')[0]
LOG.details('Checksum for image: %s, expected: %s', calulated_sum,
expected_sum)
return calulated_sum == expected_sum
class CentosStream(Image):
URL = "https://cloud.centos.org/centos/%s-stream/%s/images/%s"
IMG = '.*(CentOS-Stream-GenericCloud-%s-[0-9]+\.[0-9].%s.qcow2).*'
CHKS = "CHECKSUM"
return False
def __init__(self, vbox, version, arch, release):
super().__init__(vbox, version, arch, release)
self._checksum_file = '%s-centos-stream-%s-%s' % (self.CHKS, version,
arch)
self._checksum_url = self.URL % (version, arch, self.CHKS)
# there is assumption, that we always need latest relese for specific
# version and architecture.
self._img_fname = self._get_image_name(version, arch)
self._img_url = self.URL % (version, arch, self._img_fname)
def _download_image(self):
if self._checksum():
LOG.details('Image already downloaded: %s', self._img_fname)
return True
def _get_image_name(self, version, arch):
Run(['wget', self._checksum_url, '-q', '-O', self._checksum_file])
fname = os.path.join(CACHE_DIR, self._img_fname)
Run(['wget', '-q', self._img_url, '-O', fname])
pat = re.compile(self.IMG % (version, arch))
if not self._checksum():
# TODO: make some retry mechanism?
LOG.fatal('Checksum for downloaded image differ from expected')
return False
images = []
with open(self._checksum_file) as fobj:
for line in fobj.read().strip().split('\n'):
line = line.strip()
if line.startswith('#'):
continue
match = pat.match(line)
if match and match.groups():
images.append(match.groups()[0])
LOG.header('Downloaded image %s', self._img_fname)
return True
images.reverse()
if images:
return images[0]
def _get_checksum(self, fname):
expected_sum = None
Run(['wget', self._checksum_url, '-q', '-O', fname])
with open(fname) as fobj:
for line in fobj.readlines():
if line.startswith('#'):
continue
if self._img_fname in line:
expected_sum = line.split('=')[1].strip()
break
return expected_sum
DISTROS = {'ubuntu': {'username': 'ubuntu',
@@ -1001,7 +1053,12 @@ DISTROS = {'ubuntu': {'username': 'ubuntu',
'realname': 'fedora',
'img_class': Fedora,
'amd64': 'x86_64',
'default_version': '34'}}
'default_version': '34'},
'centos': {'username': 'centos',
'realname': 'centos',
'img_class': CentosStream,
'amd64': 'x86_64',
'default_version': '8'}}
def get_image_object(vbox, version, image='ubuntu', arch='amd64'):
@@ -1062,6 +1119,10 @@ def vmcreate(args, conf=None):
conf = Config(args)
except BoxNotFound:
return 7
except yaml.YAMLError:
LOG.fatal(f'Cannot read or parse file `{args.config}` as YAML '
f'file')
return 14
LOG.header('Creating VM: %s', conf.name)
vbox = VBoxManage(conf.name)
@@ -1094,6 +1155,9 @@ def vmcreate(args, conf=None):
image = get_image_object(vbox, conf.version, image=conf.distro)
path_to_disk = image.convert_to_vdi(conf.name + '.vdi', conf.disk_size)
if not path_to_disk:
return 21
iso = IsoImage(conf)
path_to_iso = iso.get_generated_image()
if not path_to_iso:
@@ -1109,7 +1173,7 @@ def vmcreate(args, conf=None):
vbox.add_nic(key, val)
# start the VM and wait for cloud-init to finish
vbox.poweron()
vbox.poweron(args.type)
# give VBox some time to actually change the state of the VM before query
time.sleep(3)
@@ -1120,7 +1184,7 @@ def vmcreate(args, conf=None):
'-o', 'ConnectTimeout=2',
'-i', conf.ssh_key_path[:-4],
f'ssh://{DISTROS[conf.distro]["username"]}'
f'@localhost:{vbox.vm_info["port"]}', 'cloud-init status']
f'@localhost:{vbox.vm_info["port"]}', 'sudo cloud-init status']
try:
while True:
out = Run(cmd).stdout
@@ -1163,8 +1227,21 @@ def vmcreate(args, conf=None):
def vmdestroy(args):
LOG.header('Removing VM: %s', args.name)
return VBoxManage(args.name).destroy()
if isinstance(args.name, list):
vm_names = args.name
else:
vm_names = [args.name]
for name in vm_names:
vbox = VBoxManage(name)
if not vbox.get_vm_info():
LOG.fatal(f'Cannot remove VM "{name}" - it doesn\'t exists.')
return 18
LOG.header('Removing VM: %s', name)
res = VBoxManage(name).destroy()
if res:
return res
return 0
def vmlist(args):
@@ -1182,6 +1259,8 @@ def vmlist(args):
LOG.header('All VMs:')
for key in sorted(vms):
if args.long:
LOG.header(f"\n{key}")
LOG.info(vms[key])
return 0
@@ -1190,6 +1269,10 @@ def vmlist(args):
def vminfo(args):
vbox = VBoxManage(args.name)
info = vbox.get_vm_info()
if not info:
LOG.fatal(f'Cannot show details of VM "{args.name}" - '
f'it doesn\'t exists.')
return 19
LOG.header('Details for VM: %s', args.name)
LOG.info('Creator:\t\t%s', info.get('creator', 'unknown/manual'))
@@ -1245,12 +1328,21 @@ def vminfo(args):
def vmrebuild(args):
LOG.header('Rebuilding VM: %s', args.name)
vbox = VBoxManage(args.name)
if not vbox.get_vm_info():
LOG.fatal(f'Cannot rebuild VM "{args.name}" - it doesn\'t exists.')
return 20
else:
LOG.header('Rebuilding VM: %s', args.name)
try:
conf = Config(args, vbox)
except BoxNotFound:
return 8
except yaml.YAMLError:
LOG.fatal(f'Cannot read or parse file `{args.config}` as YAML '
f'file')
return 15
vbox.poweroff()
@@ -1280,10 +1372,18 @@ def shell_completion(args):
def connect(args):
vbox = VBoxManage(args.name)
if not vbox.get_vm_info():
LOG.fatal(f'No machine has been found with a name `{args.name}`.')
return 17
try:
conf = Config(args, vbox)
except BoxNotFound:
return 11
except yaml.YAMLError:
LOG.fatal(f'Cannot read or parse file `{args.config}` as YAML '
f'file.')
return 16
return Run(['ssh', '-o', 'StrictHostKeyChecking=no',
'-o', 'UserKnownHostsFile=/dev/null',
@@ -1335,13 +1435,16 @@ def main():
help="disable nested virtualization")
create.add_argument('-s', '--disk-size', help="disk size to be expanded "
"to. By default to 10GB")
create.add_argument('-t', '--type', default='headless',
help="VM run type, headless by default.",
choices=['gui', 'headless', 'sdl', 'separate'])
create.add_argument('-u', '--cpus', type=int, help="amount of CPUs to be "
"configured. Default 1.")
create.add_argument('-v', '--version', help=f"distribution version. "
f"Default {DISTROS['ubuntu']['default_version']}")
destroy = subparsers.add_parser('destroy', help='destroy VM')
destroy.add_argument('name', help='name or UUID of the VM')
destroy.add_argument('name', nargs='+', help='name or UUID of the VM')
destroy.set_defaults(func=vmdestroy)
list_vms = subparsers.add_parser('list', help='list VMs')
@@ -1375,6 +1478,9 @@ def main():
help="disable nested virtualization")
rebuild.add_argument('-s', '--disk-size',
help='disk size to be expanded to')
rebuild.add_argument('-t', '--type', default='headless',
help="VM run type, headless by default.",
choices=['gui', 'headless', 'sdl', 'separate'])
rebuild.add_argument('-u', '--cpus', type=int,
help='amount of CPUs to be configured')
rebuild.add_argument('-v', '--version', help='distribution version')
@@ -1398,7 +1504,7 @@ def main():
LOG.set_verbose(args.verbose, args.quiet)
if args.version:
if 'func' not in args and args.version:
LOG.info(f'boxpy {__version__}')
parser.exit()

View File

@@ -1,3 +1,5 @@
# Note, that cloud init will fail, due to old cloudinit package, which module
# cc_keys_to_console doesn't recognize skipping option. Just ignore this error.
package_update: true
packages:
- bash-completion
@@ -12,7 +14,6 @@ packages:
write_files:
- path: /tmp/local.conf
permissions: '0644'
owner: fedora:fedora
content: |
[[local|localrc]]
ADMIN_PASSWORD=pass
@@ -33,4 +34,4 @@ boxpy_data:
memory: 4GB
disk_size: 10GB
distro: fedora
version: 32
version: 34

View File

@@ -19,7 +19,6 @@ packages:
write_files:
- path: /tmp/local.conf
permissions: '0644'
owner: ubuntu:ubuntu
content: |
[[local|localrc]]
ADMIN_PASSWORD=pass
@@ -27,6 +26,8 @@ write_files:
RABBIT_PASSWORD=$$ADMIN_PASSWORD
SERVICE_PASSWORD=$$ADMIN_PASSWORD
runcmd:
- [apt, purge, '-y', python3-pyasn1-modules]
- [apt, purge, '-y', python3-simplejson]
- [su, -, ubuntu, -c, "git clone https://github.com/gryf/vmstrap"]
- [su, -, ubuntu, -c, "vmstrap/bootstrap.sh"]
- [rm, -fr, /home/ubuntu/vmstrap]

View File

@@ -31,13 +31,10 @@ write_files:
- 192.168.10.10/24
- path: /tmp/local.conf
permissions: '0644'
owner: ubuntu:ubuntu
content: |
[[local|localrc]]
disable_all_services
disable_service tls-proxy
# Cinder
disable_service c-api
disable_service c-bak
@@ -81,15 +78,20 @@ write_files:
enable_service n-cond
enable_service n-cpu
enable_service n-sch
# Neutron
enable_service neutron
enable_service neutron-tag-ports-during-bulk-creation
# Octavia
enable_service o-api
enable_service o-cw
enable_service o-da
enable_service o-hk
enable_service o-hm
enable_service octavia
# OVN
# Neutron ovn services
enable_service ovn-controller
enable_service ovn-northd
enable_service ovs-vswitchd
@@ -100,60 +102,83 @@ write_files:
enable_service placement-client
# Neutron services
enable_service q-agt
enable_service q-dhcp
enable_service q-l3
enable_service q-meta
enable_service q-ovn-metadata-agent
enable_service q-qos
enable_service q-svc
enable_service q-trunk
enable_service rabbit
# Swift
disable_service s-account
disable_service s-container
disable_service s-object
disable_service s-proxy
# Tempest
enable_service tempest
enable_service tls-proxy
# TLS
disable_service tls-proxy
# Vars
ADMIN_PASSWORD="secretadmin"
DATABASE_PASSWORD="secretdatabase"
ETCD_USE_RAMDISK="True"
KURYR_ENABLED_HANDLERS="vif,endpoints,service,namespace,pod_label,policy,kuryrnetworkpolicy,kuryrnetwork,kuryrport,kuryrloadbalancer"
KURYR_EP_DRIVER_OCTAVIA_PROVIDER="amphora"
KURYR_K8S_API_PORT="6443"
KURYR_K8S_CLOUD_PROVIDER="False"
KURYR_K8S_CONTAINERIZED_DEPLOYMENT="True"
KURYR_ENFORCE_SG_RULES="False"
KURYR_EP_DRIVER_OCTAVIA_PROVIDER="ovn"
KURYR_K8S_MULTI_WORKER_TESTS="True"
KURYR_K8S_OCTAVIA_MEMBER_MODE="L2"
KURYR_LB_ALGORITHM="SOURCE_IP_PORT"
KURYR_NEUTRON_DEFAULT_ROUTER="router1"
KURYR_SG_DRIVER="policy"
KURYR_SUBNET_DRIVER="namespace"
LOGFILE="/opt/stack/logs/devstacklog.txt"
LOG_COLOR="False"
ML2_L3_PLUGIN="router"
ML2_L3_PLUGIN="ovn-router,trunk,qos"
OCTAVIA_AMP_IMAGE_FILE="/tmp/test-only-amphora-x64-haproxy-ubuntu-bionic.qcow2"
OCTAVIA_AMP_IMAGE_NAME="test-only-amphora-x64-haproxy-ubuntu-bionic"
OCTAVIA_AMP_IMAGE_SIZE="3"
Q_AGENT="openvswitch"
Q_ML2_TENANT_NETWORK_TYPE="vxlan"
Q_ML2_PLUGIN_MECHANISM_DRIVERS="openvswitch,linuxbridge"
OVN_BRANCH="v20.06.2"
OVN_BUILD_FROM_SOURCE="True"
OVN_DBS_LOG_LEVEL="dbg"
OVN_L3_CREATE_PUBLIC_NETWORK="True"
VAR_RUN_PATH="/usr/local/var/run"
RABBIT_PASSWORD="secretrabbit"
RECLONE="no"
SERVICE_PASSWORD="secretservice"
SERVICE_TOKEN="password"
TEMPEST_PLUGINS="/opt/stack/kuryr-tempest-plugin"
USE_PYTHON3="True"
LIBS_FROM_GIT=cinder,devstack,devstack-gate,devstack-plugin-container,glance,keystone,kuryr-kubernetes,kuryr-tempest-plugin,neutron,nova,octavia,placement,python-octaviaclient,requirements,swift,tempest
LIBS_FROM_GIT=cinder,devstack,devstack-gate,devstack-plugin-container,glance,keystone,kuryr-kubernetes,kuryr-tempest-plugin,neutron,nova,octavia,octavia-tempest-plugin,ovn-octavia-provider,placement,python-octaviaclient,requirements,swift,tempest
TEMPEST_PLUGINS="/opt/stack/kuryr-tempest-plugin /opt/stack/octavia-tempest-plugin"
# enabled plugins
enable_plugin devstack-plugin-container https://opendev.org/openstack/devstack-plugin-container
enable_plugin kuryr-kubernetes https://github.com/gryf/kuryr-kubernetes
enable_plugin kuryr-kubernetes https://opendev.org/openstack/kuryr-kubernetes
enable_plugin kuryr-tempest-plugin https://opendev.org/openstack/kuryr-tempest-plugin
enable_plugin neutron https://opendev.org/openstack/neutron
enable_plugin octavia https://opendev.org/openstack/octavia
enable_plugin octavia-tempest-plugin https://opendev.org/openstack/octavia-tempest-plugin
enable_plugin ovn-octavia-provider https://opendev.org/openstack/ovn-octavia-provider
[[post-config|$OCTAVIA_CONF]]
[api_settings]
enabled_provider_drivers = amphora:'Octavia Amphora driver',ovn:'Octavia OVN driver'
runcmd:
- [apt, purge, '-y', python3-pyasn1-modules]
- [apt, purge, '-y', python3-simplejson]
- [su, -, ubuntu, -c, "git clone https://github.com/gryf/vmstrap"]
- [su, -, ubuntu, -c, "vmstrap/bootstrap.sh"]
- [rm, -fr, /home/ubuntu/vmstrap]
- [su, -, ubuntu, -c, "echo 'export HOST_IP=192.168.10.10' >> .bashrc"]
- [su, -, ubuntu, -c, "cp /tmp/local.conf /home/ubuntu/devstack/"]
- [systemctl, restart, systemd-networkd]
boxpy_data:
key: vm
cpus: 4

View File

@@ -31,12 +31,9 @@ write_files:
- 192.168.10.11/24
- path: /tmp/local.conf
permissions: '0644'
owner: ubuntu:ubuntu
content: |
[[local|localrc]]
disable_all_services
disable_service tls-proxy
# Cinder
disable_service c-bak
@@ -56,46 +53,66 @@ write_files:
enable_service kuryr-daemon
disable_service kuryr-kubernetes
# Nova
enable_service n-cpu
# OVN
# Neutron
enable_service neutron
enable_service ovn-controller
disable_service ovn-northd
enable_service ovn-octavia-provider
enable_service ovs-vswitchd
enable_service ovsdb-server
# Placement API
enable_service placement-client
# Neutron services
# Neutron services cd
enable_service q-ovn-metadata-agent
disable_service q-svc
# tempest
disable_service tempest
# tls
disable_service tls-proxy
# Vars
ADMIN_PASSWORD="secretadmin"
DATABASE_HOST="192.168.10.10"
DATABASE_PASSWORD="secretdatabase"
ENABLE_CHASSIS_AS_GW="False"
GLANCE_HOSTPORT="192.168.10.10:9292"
ML2_L3_PLUGIN="router"
# turn on ovn-provider
KURYR_ENFORCE_SG_RULES="False"
KURYR_EP_DRIVER_OCTAVIA_PROVIDER="ovn"
KURYR_K8S_OCTAVIA_MEMBER_MODE="L2"
KURYR_LB_ALGORITHM="SOURCE_IP_PORT"
KURYR_NEUTRON_DEFAULT_ROUTER="router1"
VAR_RUN_PATH="/usr/local/var/run"
KURYR_ENABLED_HANDLERS="vif,endpoints,service,namespace,pod_label,policy,kuryrnetworkpolicy,kuryrnetwork,kuryrport,kuryrloadbalancer"
KURYR_FORCE_IMAGE_BUILD="True"
KURYR_EP_DRIVER_OCTAVIA_PROVIDER="amphora"
KURYR_K8S_API_PORT="6443"
KURYR_K8S_CLOUD_PROVIDER="False"
KURYR_K8S_CONTAINERIZED_DEPLOYMENT="True"
KURYR_SG_DRIVER="policy"
KURYR_SUBNET_DRIVER="namespace"
OVN_BRANCH="v20.06.2"
OVN_BUILD_FROM_SOURCE="True"
OVN_DBS_LOG_LEVEL="dbg"
OVN_L3_CREATE_PUBLIC_NETWORK="True"
LIBVIRT_TYPE="qemu"
LOGFILE="/opt/stack/logs/devstacklog.txt"
LOG_COLOR="False"
Q_AGENT="openvswitch"
Q_ML2_TENANT_NETWORK_TYPE="vxlan"
Q_ML2_PLUGIN_MECHANISM_DRIVERS="openvswitch,linuxbridge"
Q_HOST="192.168.10.10"
RABBIT_HOST="192.168.10.10"
RABBIT_PASSWORD="secretrabbit"
RECLONE="no"
SERVICE_HOST="192.168.10.10"
SERVICE_PASSWORD="secretservice"
SERVICE_TOKEN="password"
TEMPEST_PLUGINS="/opt/stack/kuryr-tempest-plugin"
USE_PYTHON3="True"
LIBS_FROM_GIT=cinder,devstack,devstack-gate,devstack-plugin-container,glance,keystone,kuryr-kubernetes,kuryr-tempest-plugin,neutron,nova,octavia,placement,python-octaviaclient,requirements,swift,tempest
@@ -103,11 +120,14 @@ write_files:
enable_plugin devstack-plugin-container https://opendev.org/openstack/devstack-plugin-container
enable_plugin kuryr-kubernetes https://opendev.org/openstack/kuryr
runcmd:
- [apt, purge, '-y', python3-pyasn1-modules]
- [apt, purge, '-y', python3-simplejson]
- [su, -, ubuntu, -c, "git clone https://github.com/gryf/vmstrap"]
- [su, -, ubuntu, -c, "vmstrap/bootstrap.sh"]
- [rm, -fr, /home/ubuntu/vmstrap]
- [su, -, ubuntu, -c, "echo 'export HOST_IP=192.168.10.11' >> .bashrc"]
- [su, -, ubuntu, -c, "cp /tmp/local.conf /home/ubuntu/devstack/"]
- [systemctl, restart, systemd-networkd]
boxpy_data:
key: vm
cpus: 4
@@ -115,4 +135,3 @@ boxpy_data:
disk_size: 50GB
advanced:
nic2: intnet
port: 2223

View File

@@ -1 +1,2 @@
pyyaml>=5.4.1
requests>=2.26.0