diff --git a/test/case/infix_containers/Readme.adoc b/test/case/infix_containers/Readme.adoc index e67eb1b0..f17fe352 100644 --- a/test/case/infix_containers/Readme.adoc +++ b/test/case/infix_containers/Readme.adoc @@ -7,6 +7,7 @@ Verifies Infix Docker container support: - Common setup with a docker0 bridge, automatic VETH pairs to container(s) - Connecting a container with a VETH pair to a standard Linux bridge - Assigning a physical Ethernet interface to a container + - Upgrading a container with a volume, verifying volume data is intact - Basic firewall container running in host network mode and full privileges <<< @@ -19,4 +20,6 @@ include::container_phys/Readme.adoc[] include::container_veth/Readme.adoc[] +include::container_volume/Readme.adoc[] + include::container_firewall_basic/Readme.adoc[] diff --git a/test/case/infix_containers/container_volume/Readme.adoc b/test/case/infix_containers/container_volume/Readme.adoc new file mode 120000 index 00000000..9beaf0a3 --- /dev/null +++ b/test/case/infix_containers/container_volume/Readme.adoc @@ -0,0 +1 @@ +container_volume.adoc \ No newline at end of file diff --git a/test/case/infix_containers/container_volume/container_volume.adoc b/test/case/infix_containers/container_volume/container_volume.adoc new file mode 100644 index 00000000..20fbfc05 --- /dev/null +++ b/test/case/infix_containers/container_volume/container_volume.adoc @@ -0,0 +1,30 @@ +=== Container Volume Persistence +==== Description +Verify that a container created from a local OCI archive, with a volume +for persistent content, can be upgraded at runtime, without losing the +content in the volume on restart. + +==== Topology +ifdef::topdoc[] +image::{topdoc}../../test/case/infix_containers/container_volume/topology.svg[Container Volume Persistence topology] +endif::topdoc[] +ifndef::topdoc[] +ifdef::testgroup[] +image::container_volume/topology.svg[Container Volume Persistence topology] +endif::testgroup[] +ifndef::testgroup[] +image::topology.svg[Container Volume Persistence topology] +endif::testgroup[] +endif::topdoc[] +==== Test sequence +. Set up topology and attach to target DUT +. Create container with volume from bundled OCI image +. Verify container has started +. Modify container volume content +. Verify container volume content +. Upgrade container +. Verify container volume content survived upgrade + + +<<< + diff --git a/test/case/infix_containers/container_volume/test.py b/test/case/infix_containers/container_volume/test.py new file mode 100755 index 00000000..c8f5d1e0 --- /dev/null +++ b/test/case/infix_containers/container_volume/test.py @@ -0,0 +1,71 @@ +#!/usr/bin/env python3 +"""Container Volume Persistence + +Verify that a container created from a local OCI archive, with a volume +for persistent content, can be upgraded at runtime, without losing the +content in the volume on restart. + +""" +import infamy +from infamy.util import until + +with infamy.Test() as test: + NAME = "web-volume" + PORT = 8080 + MESG = "HEJ" + + with test.step("Set up topology and attach to target DUT"): + env = infamy.Env() + target = env.attach("target", "mgmt") + tgtssh = env.attach("target", "mgmt", "ssh") + addr = target.get_mgmt_ip() + url = infamy.Furl(f"http://[{addr}]:{PORT}/index.html") + + if not target.has_model("infix-containers"): + test.skip() + + with test.step("Create container with volume from bundled OCI image"): + target.put_config_dict("infix-containers", { + "containers": { + "container": [ + { + "name": f"{NAME}", + "image": f"oci-archive:{infamy.Container.HTTPD_IMAGE}", + "command": f"/usr/sbin/httpd -f -v -p {PORT}", + "network": { + "host": True + }, + "volume": [{ + "name": "www", + "target": "/var/www" + }] + } + ] + } + }) + + with test.step("Verify container has started"): + c = infamy.Container(target) + until(lambda: c.running(NAME), attempts=10) + + with test.step("Modify container volume content"): + cmd = f"sudo container shell {NAME} 'echo {MESG} >/var/www/index.html'" + tgtssh.runsh(cmd) + + with test.step("Verify container volume content"): + until(lambda: url.check(MESG), attempts=10) + + with test.step("Upgrade container"): + out = tgtssh.runsh(f"sudo container upgrade {NAME}") + if ">> Done." not in out.stdout: + msg = f"Failed upgrading container {NAME}:\n" \ + f"STDOUT:\n{out.stdout}\n" \ + f"STDERR:\n{out.stderr}" + test.fail(msg) + # else: + # print(f"Container {NAME} upgraded: {out.stdout}") + + with test.step("Verify container volume content survived upgrade"): + until(lambda: url.check(MESG), attempts=10) + + test.succeed() diff --git a/test/case/infix_containers/container_volume/topology.dot b/test/case/infix_containers/container_volume/topology.dot new file mode 120000 index 00000000..4f53d15a --- /dev/null +++ b/test/case/infix_containers/container_volume/topology.dot @@ -0,0 +1 @@ +../../../infamy/topologies/1x2.dot \ No newline at end of file diff --git a/test/case/infix_containers/container_volume/topology.svg b/test/case/infix_containers/container_volume/topology.svg new file mode 100644 index 00000000..ff3d246b --- /dev/null +++ b/test/case/infix_containers/container_volume/topology.svg @@ -0,0 +1,42 @@ + + + + + + +1x2 + + + +host + +host + +mgmt + +data + + + +target + +mgmt + +data + +target + + + +host:mgmt--target:mgmt + + + + +host:data--target:data + + + + diff --git a/test/case/infix_containers/infix_containers.yaml b/test/case/infix_containers/infix_containers.yaml index 3d364de7..40e51a31 100644 --- a/test/case/infix_containers/infix_containers.yaml +++ b/test/case/infix_containers/infix_containers.yaml @@ -12,6 +12,9 @@ - name: container_veth case: container_veth/test.py +- name: container_volume + case: container_volume/test.py + - name: container_firewall_basic case: container_firewall_basic/test.py