From 92a6ea8dc7e09a64d946626ebd57c3a2cbe47dc5 Mon Sep 17 00:00:00 2001 From: Pete Vander Giessen Date: Thu, 25 Jul 2019 16:36:05 +0000 Subject: [PATCH] Broke configuration out into a manual step. Renamed the old and outdated "configure-openstack" script to "init.sh" Updated init.sh and folded most of the configure hook into it. Removed database installation step from install hook. We can now install microstack without a database dump, which helps immensely in updating. And we have a logical place to put additional configuraiton, including some of the manual steps in DEMO.md, which could be scripted if we gave users a chance to skip the system changes that they wanted to skip. Also updated README and DEMO file to match new flow. Updated test files. Future cleanup and features documented in Trello, but not included in this PR, which is big enough already :-) Change-Id: I8d926a8b463124494ddb7a4696adbe86f89db7d5 --- DEMO.md | 18 +- README.md | 8 +- snap-overlay/bin/configure-openstack | 172 ---------- snap-overlay/bin/init.sh | 317 +++++++++++++++++++ snap-overlay/bin/launch.sh | 6 + snap-wrappers/openstack/openstack-wrapper | 5 + snap/hooks/configure | 78 ----- snap/hooks/install | 5 +- snapcraft.yaml | 4 +- tests/basic-test.sh | 1 + tools/{install_and_build.sh => lxd_build.sh} | 0 tools/multipass_build.sh | 10 + tox.ini | 19 +- 13 files changed, 384 insertions(+), 259 deletions(-) delete mode 100755 snap-overlay/bin/configure-openstack create mode 100755 snap-overlay/bin/init.sh rename tools/{install_and_build.sh => lxd_build.sh} (100%) create mode 100755 tools/multipass_build.sh diff --git a/DEMO.md b/DEMO.md index f01f4f2..2dc6625 100644 --- a/DEMO.md +++ b/DEMO.md @@ -69,10 +69,26 @@ echo vm.swappiness=1 | sudo tee -a /etc/sysctl.conf sudo sysctl -p ``` +### Initialize MicroStack + +At this point, you have all the OpenStack bits on disk, and the +services are running. But they still have to be configured to talk to +each other. Plus, you need a root password and other niceties. Run the +init script to set all of that up: + +``` +microstack.init --auto +``` + +(Note that you may leave --auto out at present. The init script will +be interactive in the very near future, however, and if you are +scripting, you'll want to leave that auto in!) + ### Optional Microstack Config By default, microstack will use Cloudflare's 1.1.1.1 as a DNS. If -you're in a network restricted environment, or simply want to use a different DNS, you'll need to edit the config manually: +you're in a network restricted environment, or simply want to use a +different DNS, you'll need to edit the config manually: ``` sudo vim /var/snap/microstack/common/etc/neutron/dhcp_agent.ini diff --git a/README.md b/README.md index 3caf158..c634e4a 100644 --- a/README.md +++ b/README.md @@ -15,7 +15,13 @@ sudo snap install microstack --classic --candidate ``` ## Quickstart -To quickly configure networks and launch a vm, run `microstack.launch`. +To quickly configure networks and launch a vm, run + +`sudo microstack.init` + +This will configure various Openstack databases. Then run: + +`microstack.launch`. This will launch an instance for you, and make it available to manage via the command line, or via the Horizon Dashboard. diff --git a/snap-overlay/bin/configure-openstack b/snap-overlay/bin/configure-openstack deleted file mode 100755 index 4f1a0d9..0000000 --- a/snap-overlay/bin/configure-openstack +++ /dev/null @@ -1,172 +0,0 @@ -#!/bin/bash -e - -# Keystone -echo "Configuring Keystone" - -snap-openstack keystone-manage fernet_setup --keystone-user root --keystone-group root -snap-openstack keystone-manage db_sync - -systemctl restart snap.microstack.keystone-* - -openstack user show admin || { - snap-openstack keystone-manage bootstrap \ - --bootstrap-password $OS_PASSWORD \ - --bootstrap-admin-url http://10.20.20.1:5000/v3/ \ - --bootstrap-internal-url http://10.20.20.1:5000/v3/ \ - --bootstrap-public-url http://10.20.20.1:5000/v3/ \ - --bootstrap-region-id microstack -} - -openstack project show service || { - openstack project create --domain default --description "Service Project" service -} - -# Nova -echo "Configuring Nova" - -openstack user show nova || { - openstack user create --domain default --password nova nova - openstack role add --project service --user nova admin -} - -openstack user show placement || { - openstack user create --domain default --password placement placement - openstack role add --project service --user placement admin -} - -openstack service show compute || { - openstack service create --name nova \ - --description "OpenStack Compute" compute - - for endpoint in public internal admin; do - openstack endpoint create --region microstack \ - compute $endpoint http://10.20.20.1:8774/v2.1 || : - done -} - -openstack service show placement || { - openstack service create --name placement \ - --description "Placement API" placement - - for endpoint in public internal admin; do - openstack endpoint create --region microstack \ - placement $endpoint http://10.20.20.1:8778 || : - done -} - -snap-openstack nova-manage api_db sync -snap-openstack nova-manage cell_v2 list_cells | grep cell0 || { - snap-openstack nova-manage cell_v2 map_cell0 -} -snap-openstack nova-manage cell_v2 list_cells | grep cell1 || { - snap-openstack nova-manage cell_v2 create_cell --name=cell1 --verbose -} -snap-openstack nova-manage db sync - -systemctl restart snap.microstack.nova-* - -while ! nc -z 10.20.20.1 8774; do sleep 0.1; done; - -sleep 5 - -openstack flavor show m1.tiny || { - openstack flavor create --id 1 --ram 512 --disk 1 --vcpus 1 m1.tiny -} -openstack flavor show m1.small || { - openstack flavor create --id 2 --ram 2048 --disk 20 --vcpus 1 m1.small -} -openstack flavor show m1.medium || { - openstack flavor create --id 3 --ram 4096 --disk 20 --vcpus 2 m1.medium -} -openstack flavor show m1.large || { - openstack flavor create --id 4 --ram 8192 --disk 20 --vcpus 4 m1.large -} -openstack flavor show m1.xlarge || { - openstack flavor create --id 5 --ram 16384 --disk 20 --vcpus 8 m1.xlarge -} - -# Neutron -echo "Configuring Neutron" - -openstack user show neutron || { - openstack user create --domain default --password neutron neutron - openstack role add --project service --user neutron admin -} - -openstack service show network || { - openstack service create --name neutron \ - --description "OpenStack Network" network - - for endpoint in public internal admin; do - openstack endpoint create --region microstack \ - network $endpoint http://10.20.20.1:9696 || : - done -} - -snap-openstack neutron-db-manage upgrade head - -systemctl restart snap.microstack.neutron-* - -while ! nc -z 10.20.20.1 9696; do sleep 0.1; done; - -sleep 5 - -openstack network show test || { - openstack network create test -} - -openstack subnet show test-subnet || { - openstack subnet create --network test --subnet-range 192.168.222.0/24 test-subnet -} - -openstack network show external || { - openstack network create --external \ - --provider-physical-network=physnet1 \ - --provider-network-type=flat external -} - -openstack subnet show external-subnet || { - openstack subnet create --network external --subnet-range 10.20.20.0/24 \ - --no-dhcp external-subnet -} - -openstack router show test-router || { - openstack router create test-router - openstack router add subnet test-router test-subnet - openstack router set --external-gateway external test-router -} - -# Glance -echo "Configuring Glance" - -openstack user show glance || { - openstack user create --domain default --password glance glance - openstack role add --project service --user glance admin -} - -openstack service show image || { - openstack service create --name glance --description "OpenStack Image" image - for endpoint in internal admin public; do - openstack endpoint create --region microstack \ - image $endpoint http://10.20.20.1:9292 || : - done -} - -snap-openstack glance-manage db_sync - -systemctl restart snap.microstack.glance* - -while ! nc -z 10.20.20.1 9292; do sleep 0.1; done; - -sleep 5 - -openstack image show cirros || { - [ -f $HOME/images/cirros-0.3.5-x86_64-disk.img ] || { - mkdir -p $HOME/images - wget \ - http://download.cirros-cloud.net/0.3.5/cirros-0.3.5-x86_64-disk.img \ - -O ${HOME}/images/cirros-0.3.5-x86_64-disk.img - } - openstack image create --file ${HOME}/images/cirros-0.3.5-x86_64-disk.img \ - --public --container-format=bare --disk-format=qcow2 cirros -} diff --git a/snap-overlay/bin/init.sh b/snap-overlay/bin/init.sh new file mode 100755 index 0000000..e60398c --- /dev/null +++ b/snap-overlay/bin/init.sh @@ -0,0 +1,317 @@ +#!/bin/bash +set -e + +echo "Initializing Microstack." + +############################################################################## +# +# Config +# +# Setup env and templates. +# +############################################################################## +echo "Loading config and writing out templates ..." + +ospassword=$(snapctl get ospassword) +extgateway=$(snapctl get extgateway) +extcidr=$(snapctl get extcidr) +dns=$(snapctl get dns) + +# Check Config +if [ -z "$ospassword" -o -z "$extgateway" -o -z "$dns" -o -z "$extcidr"]; then + echo "Missing required config value." + exit 1 +fi + +# Write out templates and read off of our microstack.rc template +# TODO: any password change hooks would go here, updating the password +# in the db before writing it to the templates and restarting +# services. +snap-openstack setup # Write out templates + +# Load openstack .rc into this script's environment. Outside of the +# snap shell, this is handled by a wrapper. +source $SNAP_COMMON/etc/microstack.rc + + +############################################################################## +# +# System Optimization +# +# Perform some tasks that change the host system in ways to better +# support microstack. +# +############################################################################## + + +# Open up networking so that instances can route to the Internet (see +# bin/setup-br-ex for more networking setup, executed on microstack +# services start.) +echo "Setting up ipv4 forwarding." +sudo sysctl net.ipv4.ip_forward=1 + +# TODO: add vm swappiness and increased file handle limits here. +# TODO: make vm swappiness and file handle changes optional. + + +############################################################################## +# +# RabbitMQ Setup +# +# Configure database and wait for services to start. +# +############################################################################## +echo "Configuring RabbitMQ" + +echo "Waiting for rabbitmq to start" +while ! nc -z $extgateway 5672; do sleep 0.1; done; +while :; +do + grep "Starting broker..." ${SNAP_COMMON}/log/rabbitmq/startup_log && \ + grep "completed" ${SNAP_COMMON}/log/rabbitmq/startup_log && \ + break + sleep 1; +done +echo "Rabbitmq started." + +# Config! +HOME=$SNAP_COMMON/lib/rabbitmq rabbitmqctl add_user openstack rabbitmq || : +HOME=$SNAP_COMMON/lib/rabbitmq rabbitmqctl set_permissions openstack ".*" ".*" ".*" + + +############################################################################## +# +# Database setup +# +# Create databases and initialize keystone. +# +############################################################################## + +# Wait for MySQL to startup +echo "Waiting for MySQL server to start ..." +while ! nc -z $extgateway 3306; do sleep 0.1; done; +while :; +do + grep "mysqld: ready for connections." \ + ${SNAP_COMMON}/log/mysql/error.log && break; + sleep 1; +done +echo "Mysql server started." + +for db in neutron nova nova_api nova_cell0 cinder glance keystone; do + echo "CREATE DATABASE IF NOT EXISTS ${db}; GRANT ALL PRIVILEGES ON ${db}.* TO '${db}'@'$extgateway' IDENTIFIED BY '${db}';" \ + | mysql-start-client -u root +done + +# Configure Keystone Fernet Keys +echo "Configuring Keystone..." +snap-openstack launch keystone-manage fernet_setup \ + --keystone-user root \ + --keystone-group root +snap-openstack launch keystone-manage db_sync + +systemctl restart snap.microstack.keystone-* + +openstack user show admin || { + snap-openstack launch keystone-manage bootstrap \ + --bootstrap-password $ospassword \ + --bootstrap-admin-url http://$extgateway:5000/v3/ \ + --bootstrap-internal-url http://$extgateway:5000/v3/ \ + --bootstrap-public-url http://$extgateway:5000/v3/ \ + --bootstrap-region-id microstack +} + +openstack project show service || { + openstack project create --domain default --description "Service Project" service +} +echo "Keystone configured." + +############################################################################## +# +# Nova Setup +# +# Configure database and wait for services to start. +# +############################################################################## +echo "Configuring Nova..." + +openstack user show nova || { + openstack user create --domain default --password nova nova + openstack role add --project service --user nova admin +} + +openstack user show placement || { + openstack user create --domain default --password placement placement + openstack role add --project service --user placement admin +} + +openstack service show compute || { + openstack service create --name nova \ + --description "OpenStack Compute" compute + + for endpoint in public internal admin; do + openstack endpoint create --region microstack \ + compute $endpoint http://$extgateway:8774/v2.1 || : + done +} + +openstack service show placement || { + openstack service create --name placement \ + --description "Placement API" placement + + for endpoint in public internal admin; do + openstack endpoint create --region microstack \ + placement $endpoint http://$extgateway:8778 || : + done +} + +# Grant nova user access to cell0 +echo "GRANT ALL PRIVILEGES ON nova_cell0.* TO 'nova'@'$extgateway' IDENTIFIED BY 'nova';" \ + | mysql-start-client -u root + +snap-openstack launch nova-manage api_db sync +snap-openstack launch nova-manage cell_v2 list_cells | grep cell0 || { + snap-openstack launch nova-manage cell_v2 map_cell0 +} +snap-openstack launch nova-manage cell_v2 list_cells | grep cell1 || { + snap-openstack launch nova-manage cell_v2 create_cell --name=cell1 --verbose +} +snap-openstack launch nova-manage db sync + +systemctl restart snap.microstack.nova-* + +while ! nc -z $extgateway 8774; do sleep 0.1; done; + +sleep 5 + +openstack flavor show m1.tiny || { + openstack flavor create --id 1 --ram 512 --disk 1 --vcpus 1 m1.tiny +} +openstack flavor show m1.small || { + openstack flavor create --id 2 --ram 2048 --disk 20 --vcpus 1 m1.small +} +openstack flavor show m1.medium || { + openstack flavor create --id 3 --ram 4096 --disk 20 --vcpus 2 m1.medium +} +openstack flavor show m1.large || { + openstack flavor create --id 4 --ram 8192 --disk 20 --vcpus 4 m1.large +} +openstack flavor show m1.xlarge || { + openstack flavor create --id 5 --ram 16384 --disk 20 --vcpus 8 m1.xlarge +} + +############################################################################## +# +# Neutron Setup +# +# Configure database and wait for services to start. +# +############################################################################## +echo "Configuring Neutron" + +openstack user show neutron || { + openstack user create --domain default --password neutron neutron + openstack role add --project service --user neutron admin +} + +openstack service show network || { + openstack service create --name neutron \ + --description "OpenStack Network" network + + for endpoint in public internal admin; do + openstack endpoint create --region microstack \ + network $endpoint http://$extgateway:9696 || : + done +} + +snap-openstack launch neutron-db-manage upgrade head + +systemctl restart snap.microstack.neutron-* + +while ! nc -z $extgateway 9696; do sleep 0.1; done; + +sleep 5 + +openstack network show test || { + openstack network create test +} + +openstack subnet show test-subnet || { + openstack subnet create --network test --subnet-range 192.168.222.0/24 test-subnet +} + +openstack network show external || { + openstack network create --external \ + --provider-physical-network=physnet1 \ + --provider-network-type=flat external +} + +openstack subnet show external-subnet || { + openstack subnet create --network external --subnet-range 10.20.20.0/24 \ + --no-dhcp external-subnet +} + +openstack router show test-router || { + openstack router create test-router + openstack router add subnet test-router test-subnet + openstack router set --external-gateway external test-router +} + +############################################################################## +# +# Glance Setup +# +# Configure database and wait for services to start. +# +############################################################################## +echo "Configuring Glance" + +openstack user show glance || { + openstack user create --domain default --password glance glance + openstack role add --project service --user glance admin +} + +openstack service show image || { + openstack service create --name glance --description "OpenStack Image" image + for endpoint in internal admin public; do + openstack endpoint create --region microstack \ + image $endpoint http://$extgateway:9292 || : + done +} + +snap-openstack launch glance-manage db_sync + +systemctl restart snap.microstack.glance* + +while ! nc -z $extgateway 9292; do sleep 0.1; done; + +sleep 5 + +# Setup the cirros image, which is used by the launch app +echo "Grabbing cirros image." +openstack image show cirros || { + [ -f $SNAP_COMMON/images/cirros-0.4.0-x86_64-disk.img ] || { + mkdir -p $SNAP_COMMON/images + wget \ + http://download.cirros-cloud.net/0.4.0/cirros-0.4.0-x86_64-disk.img \ + -O ${SNAP_COMMON}/images/cirros-0.4.0-x86_64-disk.img + } + openstack image create \ + --file ${SNAP_COMMON}/images/cirros-0.4.0-x86_64-disk.img \ + --public --container-format=bare --disk-format=qcow2 cirros +} + +############################################################################## +# +# Post-setup tasks. +# +# Clean up hanging threads and wait for services to restart. +# +############################################################################## + +# Restart libvirt and virtlogd to get logging +# TODO: figure out why this doesn't Just Work initially +systemctl restart snap.microstack.*virt* + +echo "Complete. Marking microstack as initialized!" +snapctl set initialized=true diff --git a/snap-overlay/bin/launch.sh b/snap-overlay/bin/launch.sh index eafe5f9..5b5226b 100755 --- a/snap-overlay/bin/launch.sh +++ b/snap-overlay/bin/launch.sh @@ -2,6 +2,12 @@ set -e +# Check for microstack.init. TODO: just run microstack.init ... +if ! [ "$(snapctl get initialized)" == "true" ]; then + echo "Microstack is not initialized. Please run microstack.init!" + exit 1; +fi + source $SNAP_COMMON/etc/microstack.rc if [ -z "$1" ]; then diff --git a/snap-wrappers/openstack/openstack-wrapper b/snap-wrappers/openstack/openstack-wrapper index 8f4275b..d881c41 100755 --- a/snap-wrappers/openstack/openstack-wrapper +++ b/snap-wrappers/openstack/openstack-wrapper @@ -2,6 +2,11 @@ set -e +if ! [ "$(snapctl get initialized)" == "true" ]; then + echo "Microstack is not initialized. Please run microstack.init!" + exit 1; +fi + source $SNAP_COMMON/etc/microstack.rc exec $@ diff --git a/snap/hooks/configure b/snap/hooks/configure index 530f248..752fd0b 100755 --- a/snap/hooks/configure +++ b/snap/hooks/configure @@ -15,81 +15,3 @@ fi snap-openstack setup # Write out templates source $SNAP_COMMON/etc/microstack.rc - -# Open up networking so that instances can route to the Internet (see -# bin/setup-br-ex for more networking setup, executed on microstack -# services start.) -sudo sysctl net.ipv4.ip_forward=1 - -# Create all of the databases -echo "Creating OpenStack Databases" - -# Wait for MySQL to startup -while ! nc -z $extgateway 3306; do sleep 0.1; done; -sleep 5 - -# Wait for rabbitmq to start -while ! nc -z $extgateway 5672; do sleep 0.1; done; - -for db in neutron nova nova_api nova_cell0 cinder glance keystone; do - echo "CREATE DATABASE IF NOT EXISTS ${db}; GRANT ALL PRIVILEGES ON ${db}.* TO '${db}'@'$extgateway' IDENTIFIED BY '${db}';" \ - | mysql-start-client -u root -done - -# Grant nova user access to cell0 -echo "GRANT ALL PRIVILEGES ON nova_cell0.* TO 'nova'@'$extgateway' IDENTIFIED BY 'nova';" | mysql-start-client -u root - -# Endpoints from localhost -> $extgateway -# TODO Rebuild database so that these are already set to $extgateway, -# after lp:1824176 is addressed, and the process of building a new -# mysql.tar.xz is less fraught. -openstack endpoint list | grep localhost | while read line; do openstack endpoint set `echo $line | cut -d" " -f2` --url `echo $line | cut -d" " -f14 | sed "s/localhost/$extgateway/"`; done - -# RabbitMQ -echo "Configuring RabbitMQ" -# Rabbitmq isn't always started when we run this. Wait for it to start. -while :; -do - grep "Starting broker..." ${SNAP_COMMON}/log/rabbitmq/startup_log && \ - grep "completed" ${SNAP_COMMON}/log/rabbitmq/startup_log && \ - break - echo "waiting for rabbitmq to start" && sleep 1; -done - -HOME=$SNAP_COMMON/lib/rabbitmq rabbitmqctl add_user openstack rabbitmq || : -HOME=$SNAP_COMMON/lib/rabbitmq rabbitmqctl set_permissions openstack ".*" ".*" ".*" - -# Glance -echo "Waiting for glance to start." -while ! nc -z $extgateway 9292; do sleep 0.1; done; - -sleep 5 - -# Wait for identity service -while ! nc -z $extgateway 5000; do sleep 0.1; done; - -# Setup the cirros image, which is used by the launch app -openstack image show cirros || { - [ -f $SNAP_COMMON/images/cirros-0.4.0-x86_64-disk.img ] || { - mkdir -p $SNAP_COMMON/images - wget \ - http://download.cirros-cloud.net/0.4.0/cirros-0.4.0-x86_64-disk.img \ - -O ${SNAP_COMMON}/images/cirros-0.4.0-x86_64-disk.img - } - openstack image create \ - --file ${SNAP_COMMON}/images/cirros-0.4.0-x86_64-disk.img \ - --public --container-format=bare --disk-format=qcow2 cirros -} - -# Restart libvirt and virtlogd to get logging -# TODO: figure out why this doesn't Just Work initially -systemctl restart snap.microstack.*virt* - -# Wait for horizon -while ! nc -z $extgateway 80; do sleep 0.1; done; - -# Restart Placement API -# Workaround for issue w/ base:core18, where the Placement API throws -# http 500s until it has been restarted. -# TODO: root cause and fix the problem. -systemctl restart snap.microstack.nova-uwsgi.service diff --git a/snap/hooks/install b/snap/hooks/install index b26b32e..2d06aaa 100755 --- a/snap/hooks/install +++ b/snap/hooks/install @@ -11,7 +11,6 @@ snapctl set \ # snapshot is a mysql data dir with # rocky keystone,nova,glance,neutron dbs. mkdir -p ${SNAP_COMMON}/lib -tar -xJf ${SNAP}/data/mysql.tar.xz -C ${SNAP_COMMON}/lib # Install conf.d configuration from snap for db etc echo "Installing configuration for OpenStack Services" @@ -22,5 +21,5 @@ done snap-openstack setup # Sets up templates for the first time. -# Configure Keystone Fernet Keys -snap-openstack launch keystone-manage fernet_setup --keystone-user root --keystone-group root + + diff --git a/snapcraft.yaml b/snapcraft.yaml index 894d5d0..a118884 100644 --- a/snapcraft.yaml +++ b/snapcraft.yaml @@ -21,8 +21,8 @@ apps: # - network # OpenStack Service Configuration - configure: - command: configure-openstack + init: + command: init.sh # plugs: # - network diff --git a/tests/basic-test.sh b/tests/basic-test.sh index c4fbb0f..6d69c4a 100755 --- a/tests/basic-test.sh +++ b/tests/basic-test.sh @@ -81,6 +81,7 @@ fi # Install the snap under test $PREFIX sudo snap install --classic --dangerous microstack*.snap +$PREFIX sudo /snap/bin/microstack.init # Comment out the above and uncomment below to install the version of # the snap from the store. diff --git a/tools/install_and_build.sh b/tools/lxd_build.sh similarity index 100% rename from tools/install_and_build.sh rename to tools/lxd_build.sh diff --git a/tools/multipass_build.sh b/tools/multipass_build.sh new file mode 100755 index 0000000..fe393e5 --- /dev/null +++ b/tools/multipass_build.sh @@ -0,0 +1,10 @@ +#!/bin/bash + +set -ex + +export PATH=/snap/bin:$PATH + +sudo snap install --classic snapcraft +sudo snap install --classic --beta multipass + +snapcraft --debug diff --git a/tox.ini b/tox.ini index 5e5280a..aadb98e 100644 --- a/tox.ini +++ b/tox.ini @@ -1,5 +1,5 @@ [tox] -envlist = snap +envlist = multipass skipsdist = True [testenv] @@ -12,7 +12,22 @@ whitelist_externals = /snap/bin/snapcraft [testenv:snap] +# Testing environment for the gerrit gate. Named 'snap' to conform to +# the requirements of the snap friendly job that we inherit from in +# .zuul.yaml. deps = -r{toxinidir}/test-requirements.txt commands = - {toxinidir}/tools/install_and_build.sh + {toxinidir}/tools/lxd_build.sh {toxinidir}/tests/basic-test.sh + +[testenv:multipass] +# Default testing environment for a human operated machine. Builds the +# snap in a multipass instance, then runs tests in a separate multipass +# instance. This makes the fewest changes to your personal computer, +# but is heavier on system requirements. For a more lightweight test, +# use the "snap" environment above. Beware that you will wind up with +# a lot of things installed, including potentially the locally built +# version of MicroStack! +commands = + {toxinidir}/tools/multipass_build.sh + {toxinidir}/tests/basic-test.sh -m