diff --git a/.fmf/version b/.fmf/version new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/.fmf/version @@ -0,0 +1 @@ +1 diff --git a/.packit.yaml b/.packit.yaml index c110485..72b5dd1 100644 --- a/.packit.yaml +++ b/.packit.yaml @@ -28,13 +28,33 @@ jobs: - "copr://rhcontainerbot/podman-next" enable_net: true - # Run on commit to main branch - - job: copr_build - trigger: commit - notifications: - failure_comment: - message: "podman-next COPR build failed. @containers/packit-build please check." - branch: main - owner: rhcontainerbot - project: podman-next + # - job: copr_build + # trigger: commit + # notifications: + # failure_comment: + # message: "podman-next COPR build failed. @containers/packit-build please check." + # branch: main + # owner: rhcontainerbot + # project: podman-next + # enable_net: true + + - &tests + job: tests + trigger: pull_request + skip_build: true enable_net: true + targets: + # - fedora-all-x86_64 + # - fedora-all-aarch64 + - fedora-40-x86_64 + - fedora-40-aarch64 + identifier: docker + tmt_plan: /tests/docker + + # - <<: *tests + # identifier: podman + # tmt_plan: /tests/podman + + # - <<: *tests + # identifier: rootful-podman + # tmt_plan: /tests/rootful-podman diff --git a/Cargo.lock b/Cargo.lock index 3a47161..b94b837 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4,36 +4,36 @@ version = 3 [[package]] name = "aho-corasick" -version = "1.1.2" +version = "1.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b2969dcb958b36655471fc61f7e416fa76033bdd4bfed0678d8fee1e2d07a1f0" +checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916" dependencies = [ "memchr", ] [[package]] name = "anstyle" -version = "1.0.5" +version = "1.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2faccea4cc4ab4a667ce676a30e8ec13922a692c99bb8f5b11f1502c72e04220" +checksum = "8901269c6307e8d93993578286ac0edf7f195079ffff5ebdeea6a59ffb7e36bc" [[package]] name = "anyhow" -version = "1.0.79" +version = "1.0.82" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "080e9890a082662b09c1ad45f567faeeb47f22b5fb23895fbe1e651e718e25ca" +checksum = "f538837af36e6f6a9be0faa67f9a314f8119e4e4b5867c6ab40ed60360142519" [[package]] name = "autocfg" -version = "1.1.0" +version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" +checksum = "f1fdabc7756949593fe60f30ec81974b613357de856987752631dea1e3394c80" [[package]] name = "bitflags" -version = "2.4.2" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed570934406eb16438a4e976b1b4500774099c13b8cb96eec99f620f05090ddf" +checksum = "cf4b9d6a944f767f8e5e0db018570623c85f3d925ac718db4e06d0187adb21c1" [[package]] name = "block-buffer" @@ -46,9 +46,9 @@ dependencies = [ [[package]] name = "bytes" -version = "1.5.0" +version = "1.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a2bd12c1caf447e69cd4528f47f94d203fd2582878ecb9e9465484c4148a8223" +checksum = "514de17de45fdb8dc022b1a7975556c53c86f9f0aa5f534b98977b171857c2c9" [[package]] name = "camino" @@ -62,11 +62,17 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" +[[package]] +name = "cfg_aliases" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fd16c4719339c4530435d38e511904438d07cce7950afa3718a84ac36c10e89e" + [[package]] name = "clap" -version = "4.4.18" +version = "4.5.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e578d6ec4194633722ccf9544794b71b1385c3c027efe0c55db226fc880865c" +checksum = "90bc066a67923782aa8515dbaea16946c5bcc5addbd668bb80af688e53e548a0" dependencies = [ "clap_builder", "clap_derive", @@ -74,32 +80,32 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.4.18" +version = "4.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4df4df40ec50c46000231c914968278b1eb05098cf8f1b3a518a95030e71d1c7" +checksum = "ae129e2e766ae0ec03484e609954119f123cc1fe650337e155d03b022f24f7b4" dependencies = [ "anstyle", "clap_lex", - "strsim", + "strsim 0.11.1", ] [[package]] name = "clap_derive" -version = "4.4.7" +version = "4.5.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf9804afaaf59a91e75b022a30fb7229a7901f60c755489cc61c9b423b836442" +checksum = "528131438037fd55894f62d6e9f068b8f45ac57ffa77517819645d10aed04f64" dependencies = [ "heck", "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.60", ] [[package]] name = "clap_lex" -version = "0.6.0" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "702fc72eb24e5a1e48ce58027a675bc24edd52096d5397d4aea7c6dd9eca0bd1" +checksum = "98cc8fbded0c607b7ba9dd60cd98df59af97e84d24e49c8557331cfc26d301ce" [[package]] name = "cpufeatures" @@ -129,9 +135,7 @@ dependencies = [ "serde", "serde_json", "serde_yaml", - "test-case", "urlencoding", - "uuid", "xml-rs", ] @@ -147,9 +151,9 @@ dependencies = [ [[package]] name = "darling" -version = "0.14.4" +version = "0.20.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b750cb3417fd1b327431a470f388520309479ab0bf5e323505daf0290cd3850" +checksum = "54e36fcd13ed84ffdfda6f5be89b31287cbb80c439841fe69e04841435464391" dependencies = [ "darling_core", "darling_macro", @@ -157,58 +161,58 @@ dependencies = [ [[package]] name = "darling_core" -version = "0.14.4" +version = "0.20.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "109c1ca6e6b7f82cc233a97004ea8ed7ca123a9af07a8230878fcfda9b158bf0" +checksum = "9c2cf1c23a687a1feeb728783b993c4e1ad83d99f351801977dd809b48d0a70f" dependencies = [ "fnv", "ident_case", "proc-macro2", "quote", - "strsim", - "syn 1.0.109", + "strsim 0.10.0", + "syn 2.0.60", ] [[package]] name = "darling_macro" -version = "0.14.4" +version = "0.20.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4aab4dbc9f7611d8b55048a3a16d2d010c2c8334e46304b40ac1cc14bf3b48e" +checksum = "a668eda54683121533a393014d8692171709ff57a7d61f187b6e782719f8933f" dependencies = [ "darling_core", "quote", - "syn 1.0.109", + "syn 2.0.60", ] [[package]] name = "derive_builder" -version = "0.12.0" +version = "0.20.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8d67778784b508018359cbc8696edb3db78160bab2c2a28ba7f56ef6932997f8" +checksum = "0350b5cb0331628a5916d6c5c0b72e97393b8b6b03b47a9284f4e7f5a405ffd7" dependencies = [ "derive_builder_macro", ] [[package]] name = "derive_builder_core" -version = "0.12.0" +version = "0.20.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c11bdc11a0c47bc7d37d582b5285da6849c96681023680b906673c5707af7b0f" +checksum = "d48cda787f839151732d396ac69e3473923d54312c070ee21e9effcaa8ca0b1d" dependencies = [ "darling", "proc-macro2", "quote", - "syn 1.0.109", + "syn 2.0.60", ] [[package]] name = "derive_builder_macro" -version = "0.12.0" +version = "0.20.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ebcda35c7a396850a55ffeac740804b40ffec779b98fffbb1738f4033f0ee79e" +checksum = "206868b8242f27cecce124c19fd88157fbd0dd334df2587f36417bafbc85097b" dependencies = [ "derive_builder_core", - "syn 1.0.109", + "syn 2.0.60", ] [[package]] @@ -243,17 +247,6 @@ dependencies = [ "version_check", ] -[[package]] -name = "getrandom" -version = "0.2.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "190092ea657667030ac6a35e305e62fc4dd69fd98ac98631e5d3a2b1575a12b5" -dependencies = [ - "cfg-if", - "libc", - "wasi", -] - [[package]] name = "getset" version = "0.1.2" @@ -274,15 +267,15 @@ checksum = "290f1a1d9242c78d09ce40a5e87e7554ee637af1351968159f4952f028f75604" [[package]] name = "heck" -version = "0.4.1" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" +checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" [[package]] name = "hermit-abi" -version = "0.3.4" +version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5d3d0e0f38255e7fa3cf31335b3a56f05febd18025f4db5ef7a0cfb4f8da651f" +checksum = "d231dfb89cfffdbc30e7fc41579ed6066ad03abda9e567ccafae602b97ec5024" [[package]] name = "home" @@ -301,9 +294,9 @@ checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" [[package]] name = "indexmap" -version = "2.2.2" +version = "2.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "824b2ae422412366ba479e8111fd301f7b5faece8149317bb81925979a53f520" +checksum = "168fb715dda47215e360912c096649d23d58bf392ac62f73919e831745e40f26" dependencies = [ "equivalent", "hashbrown", @@ -311,9 +304,9 @@ dependencies = [ [[package]] name = "itoa" -version = "1.0.10" +version = "1.0.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1a46d1a171d865aa5f83f92695765caa047a9b4cbae2cbf37dbd613a793fd4c" +checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b" [[package]] name = "lazy_static" @@ -338,9 +331,9 @@ dependencies = [ [[package]] name = "memchr" -version = "2.7.1" +version = "2.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "523dc4f511e55ab87b694dc30d0f820d60906ef06413f93d4d7a1385599cc149" +checksum = "6c8640c5d730cb13ebd907d8d04b52f55ac9a2eec55b440c8892f40d56c76c1d" [[package]] name = "minidom" @@ -353,12 +346,13 @@ dependencies = [ [[package]] name = "nix" -version = "0.27.1" +version = "0.28.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2eb04e9c688eff1c89d72b407f168cf79bb9e867a9d3323ed6c01519eb9cc053" +checksum = "ab2156c4fce2f8df6c499cc1c763e4394b7482525bf2a9701c9d79d215f519e4" dependencies = [ "bitflags", "cfg-if", + "cfg_aliases", "libc", ] @@ -374,9 +368,9 @@ dependencies = [ [[package]] name = "oci-spec" -version = "0.6.4" +version = "0.6.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8384f8eff13954bafafba991f1910779020456f9694de25e81a13da5b7de6309" +checksum = "e423c4f827362c0d8d8da4b1f571270f389ebde73bcd3240a3d23c6d6f61d0f0" dependencies = [ "derive_builder", "getset", @@ -411,27 +405,27 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.78" +version = "1.0.81" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2422ad645d89c99f8f3e6b88a9fdeca7fabeac836b1002371c4367c8f984aae" +checksum = "3d1597b0c024618f09a9c3b8655b7e430397a36d23fdafec26d6965e9eec3eba" dependencies = [ "unicode-ident", ] [[package]] name = "quote" -version = "1.0.35" +version = "1.0.36" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef" +checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7" dependencies = [ "proc-macro2", ] [[package]] name = "regex" -version = "1.10.3" +version = "1.10.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b62dbe01f0b06f9d8dc7d49e05a0785f153b00b2c227856282f671e0318c9b15" +checksum = "c117dbdfde9c8308975b6a18d71f3f385c89461f7b3fb054288ecf2a2058ba4c" dependencies = [ "aho-corasick", "memchr", @@ -441,9 +435,9 @@ dependencies = [ [[package]] name = "regex-automata" -version = "0.4.5" +version = "0.4.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5bb987efffd3c6d0d8f5f89510bb458559eab11e4f869acb20bf845e016259cd" +checksum = "86b83b8b9847f9bf95ef68afb0b8e6cdb80f498442f5179a29fad448fcc1eaea" dependencies = [ "aho-corasick", "memchr", @@ -452,15 +446,15 @@ dependencies = [ [[package]] name = "regex-syntax" -version = "0.8.2" +version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c08c74e62047bb2de4ff487b251e4a92e24f48745648451635cec7d591162d9f" +checksum = "adad44e29e4c806119491a7f06f03de4d1af22c3a680dd47f1e6e179439d1f56" [[package]] name = "rust-embed" -version = "6.8.1" +version = "8.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a36224c3276f8c4ebc8c20f158eca7ca4359c8db89991c4925132aaaf6702661" +checksum = "fb78f46d0066053d16d4ca7b898e9343bc3530f71c61d5ad84cd404ada068745" dependencies = [ "rust-embed-impl", "rust-embed-utils", @@ -469,22 +463,22 @@ dependencies = [ [[package]] name = "rust-embed-impl" -version = "6.8.1" +version = "8.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49b94b81e5b2c284684141a2fb9e2a31be90638caf040bf9afbc5a0416afe1ac" +checksum = "b91ac2a3c6c0520a3fb3dd89321177c3c692937c4eb21893378219da10c44fc8" dependencies = [ "proc-macro2", "quote", "rust-embed-utils", - "syn 2.0.48", + "syn 2.0.60", "walkdir", ] [[package]] name = "rust-embed-utils" -version = "7.8.1" +version = "8.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d38ff6bf570dc3bb7100fce9f7b60c33fa71d80e88da3f2580df4ff2bdded74" +checksum = "86f69089032567ffff4eada41c573fc43ff466c7db7c5688b2e7969584345581" dependencies = [ "sha2", "walkdir", @@ -509,9 +503,9 @@ checksum = "22a197350ece202f19a166d1ad6d9d6de145e1d2a8ef47db299abe164dbd7530" [[package]] name = "ryu" -version = "1.0.16" +version = "1.0.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f98d2aa92eebf49b69786be48e4477826b256916e84a57ff2a4f21923b48eb4c" +checksum = "e86697c916019a8588c99b5fac3cead74ec0b4b819707a682fd4d23fa0ce1ba1" [[package]] name = "same-file" @@ -524,29 +518,29 @@ dependencies = [ [[package]] name = "serde" -version = "1.0.196" +version = "1.0.198" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "870026e60fa08c69f064aa766c10f10b1d62db9ccd4d0abb206472bee0ce3b32" +checksum = "9846a40c979031340571da2545a4e5b7c4163bdae79b301d5f86d03979451fcc" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.196" +version = "1.0.198" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "33c85360c95e7d137454dc81d9a4ed2b8efd8fbe19cee57357b32b9771fccb67" +checksum = "e88edab869b01783ba905e7d0153f9fc1a6505a96e4ad3018011eedb838566d9" dependencies = [ "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.60", ] [[package]] name = "serde_json" -version = "1.0.113" +version = "1.0.116" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "69801b70b1c3dac963ecb03a364ba0ceda9cf60c71cfe475e99864759c8b8a79" +checksum = "3e17db7126d17feb94eb3fad46bf1a96b034e8aacbc2e775fe81505f8b0b2813" dependencies = [ "itoa", "ryu", @@ -555,9 +549,9 @@ dependencies = [ [[package]] name = "serde_yaml" -version = "0.9.31" +version = "0.9.34+deprecated" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "adf8a49373e98a4c5f0ceb5d05aa7c648d75f63774981ed95b7c7443bbd50c6e" +checksum = "6a8b1a1a2ebf674015cc02edccce75287f1a0130d394307b36743c2f5d504b47" dependencies = [ "indexmap", "itoa", @@ -600,6 +594,12 @@ version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" +[[package]] +name = "strsim" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" + [[package]] name = "syn" version = "1.0.109" @@ -613,66 +613,33 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.48" +version = "2.0.60" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f3531638e407dfc0814761abb7c00a5b54992b849452a0646b7f65c9f770f3f" +checksum = "909518bc7b1c9b779f1bbf07f2929d35af9f0f37e47c6e9ef7f9dddc1e1821f3" dependencies = [ "proc-macro2", "quote", "unicode-ident", ] -[[package]] -name = "test-case" -version = "3.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eb2550dd13afcd286853192af8601920d959b14c401fcece38071d53bf0768a8" -dependencies = [ - "test-case-macros", -] - -[[package]] -name = "test-case-core" -version = "3.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "adcb7fd841cd518e279be3d5a3eb0636409487998a4aff22f3de87b81e88384f" -dependencies = [ - "cfg-if", - "proc-macro2", - "quote", - "syn 2.0.48", -] - -[[package]] -name = "test-case-macros" -version = "3.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c89e72a01ed4c579669add59014b9a524d609c0c88c6a585ce37485879f6ffb" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.48", - "test-case-core", -] - [[package]] name = "thiserror" -version = "1.0.56" +version = "1.0.59" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d54378c645627613241d077a3a79db965db602882668f9136ac42af9ecb730ad" +checksum = "f0126ad08bff79f29fc3ae6a55cc72352056dfff61e3ff8bb7129476d44b23aa" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.56" +version = "1.0.59" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa0faa943b50f3db30a20aa7e265dbc66076993efed8463e8de414e5d06d3471" +checksum = "d1cd413b5d558b4c5bf3680e324a6fa5014e7b7c067a51e69dbdf47eb7148b66" dependencies = [ "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.60", ] [[package]] @@ -689,9 +656,9 @@ checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" [[package]] name = "unsafe-libyaml" -version = "0.2.10" +version = "0.2.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ab4c90930b95a82d00dc9e9ac071b4991924390d46cbd0dfe566148667605e4b" +checksum = "673aac59facbab8a9007c7f6108d11f63b603f7cabff99fabf650fea5c32b861" [[package]] name = "urlencoding" @@ -699,15 +666,6 @@ version = "2.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "daf8dba3b7eb870caf1ddeed7bc9d2a049f3cfdfae7cb521b087cc33ae4c49da" -[[package]] -name = "uuid" -version = "1.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f00cc9702ca12d3c81455259621e676d0f7251cec66a21e98fe2e9a37db93b2a" -dependencies = [ - "getrandom", -] - [[package]] name = "version_check" version = "0.9.4" @@ -716,51 +674,23 @@ checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" [[package]] name = "walkdir" -version = "2.4.0" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d71d857dc86794ca4c280d616f7da00d2dbfd8cd788846559a6813e6aa4b54ee" +checksum = "29790946404f91d9c5d06f9874efddea1dc06c5efe94541a7d6863108e3a5e4b" dependencies = [ "same-file", "winapi-util", ] -[[package]] -name = "wasi" -version = "0.11.0+wasi-snapshot-preview1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" - -[[package]] -name = "winapi" -version = "0.3.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" -dependencies = [ - "winapi-i686-pc-windows-gnu", - "winapi-x86_64-pc-windows-gnu", -] - -[[package]] -name = "winapi-i686-pc-windows-gnu" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" - [[package]] name = "winapi-util" -version = "0.1.6" +version = "0.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f29e6f9198ba0d26b4c9f07dbe6f9ed633e1f3d5b8b414090084349e46a52596" +checksum = "134306a13c5647ad6453e8deaec55d3a44d6021970129e6188735e74bf546697" dependencies = [ - "winapi", + "windows-sys", ] -[[package]] -name = "winapi-x86_64-pc-windows-gnu" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" - [[package]] name = "windows-sys" version = "0.52.0" @@ -772,13 +702,14 @@ dependencies = [ [[package]] name = "windows-targets" -version = "0.52.0" +version = "0.52.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a18201040b24831fbb9e4eb208f8892e1f50a37feb53cc7ff887feb8f50e7cd" +checksum = "6f0713a46559409d202e70e28227288446bf7841d3211583a4b53e3f6d96e7eb" dependencies = [ "windows_aarch64_gnullvm", "windows_aarch64_msvc", "windows_i686_gnu", + "windows_i686_gnullvm", "windows_i686_msvc", "windows_x86_64_gnu", "windows_x86_64_gnullvm", @@ -787,48 +718,54 @@ dependencies = [ [[package]] name = "windows_aarch64_gnullvm" -version = "0.52.0" +version = "0.52.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cb7764e35d4db8a7921e09562a0304bf2f93e0a51bfccee0bd0bb0b666b015ea" +checksum = "7088eed71e8b8dda258ecc8bac5fb1153c5cffaf2578fc8ff5d61e23578d3263" [[package]] name = "windows_aarch64_msvc" -version = "0.52.0" +version = "0.52.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bbaa0368d4f1d2aaefc55b6fcfee13f41544ddf36801e793edbbfd7d7df075ef" +checksum = "9985fd1504e250c615ca5f281c3f7a6da76213ebd5ccc9561496568a2752afb6" [[package]] name = "windows_i686_gnu" -version = "0.52.0" +version = "0.52.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "88ba073cf16d5372720ec942a8ccbf61626074c6d4dd2e745299726ce8b89670" + +[[package]] +name = "windows_i686_gnullvm" +version = "0.52.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a28637cb1fa3560a16915793afb20081aba2c92ee8af57b4d5f28e4b3e7df313" +checksum = "87f4261229030a858f36b459e748ae97545d6f1ec60e5e0d6a3d32e0dc232ee9" [[package]] name = "windows_i686_msvc" -version = "0.52.0" +version = "0.52.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ffe5e8e31046ce6230cc7215707b816e339ff4d4d67c65dffa206fd0f7aa7b9a" +checksum = "db3c2bf3d13d5b658be73463284eaf12830ac9a26a90c717b7f771dfe97487bf" [[package]] name = "windows_x86_64_gnu" -version = "0.52.0" +version = "0.52.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d6fa32db2bc4a2f5abeacf2b69f7992cd09dca97498da74a151a3132c26befd" +checksum = "4e4246f76bdeff09eb48875a0fd3e2af6aada79d409d33011886d3e1581517d9" [[package]] name = "windows_x86_64_gnullvm" -version = "0.52.0" +version = "0.52.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a657e1e9d3f514745a572a6846d3c7aa7dbe1658c056ed9c3344c4109a6949e" +checksum = "852298e482cd67c356ddd9570386e2862b5673c85bd5f88df9ab6802b334c596" [[package]] name = "windows_x86_64_msvc" -version = "0.52.0" +version = "0.52.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dff9641d1cd4be8d1a070daf9e3773c5f67e78b4d9d42263020c057706765c04" +checksum = "bec47e5bfd1bff0eeaf6d8b485cc1074891a197ab4225d504cb7a1ab88b02bf0" [[package]] name = "xml-rs" -version = "0.8.19" +version = "0.8.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0fcb9cbac069e033553e8bb871be2fbdffcab578eb25bd0f7c508cedc6dcd75a" +checksum = "791978798f0597cfc70478424c2b4fdc2b7a8024aaff78497ef00f24ef674193" diff --git a/Cargo.toml b/Cargo.toml index 8289325..8595b88 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -31,7 +31,7 @@ default-features = false version = "0.15.2" [dependencies.nix] -version = "0.27.0" +version = "0.28.0" default-features = false features = ["fs", "mount"] @@ -50,7 +50,7 @@ default-features = false features = ["std"] [dependencies.rust-embed] -version = "6.0" +version = "8.0" default-features = false features = ["debug-embed"] @@ -69,12 +69,3 @@ version = "2.0" [dependencies.xml-rs] version = "0.8.0" default-features = false - -[dev-dependencies.test-case] -version = "3.0" -default-features = false - -[dev-dependencies.uuid] -version = "1.0" -default-features = false -features = ["std", "v4"] diff --git a/docs/2-podman-docker.md b/docs/2-podman-docker.md index 33edc6f..6092743 100644 --- a/docs/2-podman-docker.md +++ b/docs/2-podman-docker.md @@ -12,7 +12,7 @@ First, obtain a QEMU-compatible VM image and place it in a directory by itself: ```console $ mkdir my-vm-image -$ curl -LO --output-dir my-vm-image https://download.fedoraproject.org/pub/fedora/linux/releases/39/Cloud/x86_64/images/Fedora-Cloud-Base-39-1.5.x86_64.qcow2 +$ curl -LO --output-dir my-vm-image https://download.fedoraproject.org/pub/fedora/linux/releases/40/Cloud/x86_64/images/Fedora-Cloud-Base-Generic.x86_64-40-1.14.qcow2 ``` Then run: @@ -86,8 +86,7 @@ convention, so you can use those here: $ podman run \ --runtime crun-vm \ -it --rm \ - quay.io/containerdisks/fedora:39 \ - "" # unused, but must specify command because container image does not + quay.io/containerdisks/fedora:40 ``` You can also use `util/package-vm-image.sh` to easily package a VM image into a @@ -113,7 +112,7 @@ meta-data user-data vendor-data $ podman run \ --runtime crun-vm \ -it --rm \ - quay.io/containerdisks/fedora:39 \ + quay.io/containerdisks/fedora:40 \ --cloud-init ~/examples/cloud-init/config # path must be absolute ``` @@ -127,7 +126,7 @@ option: $ podman run \ --runtime crun-vm \ -it --rm \ - quay.io/containerdisks/fedora:39 \ + quay.io/containerdisks/fedora:40 \ --password pass ``` @@ -140,7 +139,7 @@ the `--ignition` option: $ podman run \ --runtime crun-vm \ -it --rm \ - quay.io/crun-vm/example-fedora-coreos:39 \ + quay.io/crun-vm/example-fedora-coreos:40 \ --ignition ~/examples/ignition/config.ign # path must be absolute ``` @@ -162,8 +161,7 @@ port 22, you can `ssh` into it as root using podman-exec: $ podman run \ --runtime crun-vm \ --detach --rm \ - quay.io/containerdisks/fedora:39 \ - "" + quay.io/containerdisks/fedora:40 8068a2c180e0f4bf494f5e0baa37d9f13a9810f76b361c0771b73666e47ec383 $ podman exec --latest whoami @@ -214,8 +212,7 @@ $ podman run \ --runtime crun-vm \ --detach --rm \ -p 8000:80 \ - quay.io/crun-vm/example-http-server:latest \ - "" + quay.io/crun-vm/example-http-server:latest 36c8705482589cfc4336a03d3802e7699f5fb228123d18e693488ac7b80116d1 $ curl localhost:8000 @@ -251,7 +248,7 @@ $ podman run \ --runtime crun-vm \ -it --rm \ -v ./util:/home/fedora/util:z \ - quay.io/containerdisks/fedora:39 \ + quay.io/containerdisks/fedora:40 \ --password pass ``` @@ -277,7 +274,7 @@ $ podman run \ --runtime crun-vm \ -it --rm \ -v ./README.md:/home/fedora/README.md:z \ - quay.io/containerdisks/fedora:39 \ + quay.io/containerdisks/fedora:40 \ --password pass ``` @@ -296,7 +293,7 @@ $ podman run \ --runtime crun-vm \ -it --rm \ --device /dev/ram0:/home/fedora/my-disk \ - quay.io/containerdisks/fedora:39 \ + quay.io/containerdisks/fedora:40 \ --password pass ``` @@ -310,7 +307,7 @@ raw format is assumed): $ podman run \ --runtime crun-vm \ -it --rm \ - quay.io/containerdisks/fedora:39 \ + quay.io/containerdisks/fedora:40 \ --password pass \ --blockdev source=~/my-disk.qcow2,target=/home/fedora/my-disk,format=qcow2 # paths must be absolute ``` diff --git a/docs/3-kubernetes.md b/docs/3-kubernetes.md index 83439d7..7c17b57 100644 --- a/docs/3-kubernetes.md +++ b/docs/3-kubernetes.md @@ -49,8 +49,6 @@ spec: containers: - name: my-vm image: quay.io/crun-vm/example-http-server:latest - args: - - "" # unused, but must specify command because container image does not ports: - containerPort: 80 runtimeClassName: crun-vm @@ -133,7 +131,7 @@ metadata: spec: containers: - name: my-other-vm - image: quay.io/containerdisks/fedora:39 + image: quay.io/containerdisks/fedora:40 args: - --cloud-init=/etc/cloud-init volumeMounts: diff --git a/examples/quadlet/README.md b/examples/quadlet/README.md index c01bc81..fb2798a 100644 --- a/examples/quadlet/README.md +++ b/examples/quadlet/README.md @@ -16,7 +16,7 @@ launch and manage your VMs through systemd. Here's an example of how to do so: [Container] PodmanArgs=--runtime crun-vm # make Podman use crun-vm as the runtime - Image=quay.io/containerdisks/fedora:39 # the container image containing our VM image + Image=quay.io/containerdisks/fedora:40 # the container image containing our VM image Exec=--password pass # optional crun-vm arguments [Install] @@ -27,7 +27,7 @@ launch and manage your VMs through systemd. Here's an example of how to do so: into the following podman invocation: ```console - $ podman run --runtime crun-vm quay.io/containerdisks/fedora:39 --password pass + $ podman run --runtime crun-vm quay.io/containerdisks/fedora:40 --password pass ``` 2. Inform systemd of the new unit file: diff --git a/plans/tests.fmf b/plans/tests.fmf new file mode 100644 index 0000000..2035594 --- /dev/null +++ b/plans/tests.fmf @@ -0,0 +1,58 @@ +provision: + hardware: + virtualization: + is-supported: true + +prepare: + - name: Install dependencies + how: install + package: + - bash + - cargo + - coreutils + - crun + - crun-krun + - docker + - genisoimage + - grep + - guestfs-tools + - libselinux-devel + - libvirt-client + - libvirt-daemon-driver-qemu + - openssh + - openssh-clients + - passt + - podman + - qemu-img + - qemu-system-aarch64-core + - qemu-system-x86-core + - sed + - util-linux + - virtiofsd + +execute: + how: tmt + script: | + set -ex + export PATH=$PATH:/root/.cargo/bin + export LIBGUESTFS_BACKEND=direct + tag=$( awk -F= '/^VERSION_ID=/ {print tolower($2)}' /etc/os-release ) + export CRUN_VM_TEST_ENV_BASE_IMAGE=quay.io/containerdisks/fedora:$tag + tests/env.sh build + tests/env.sh start + tests/env.sh run "$ENGINE" all + +/docker: + summary: Run all tests under Docker + environment: + ENGINE: docker + +/podman: + summary: Run all tests under Podman + environment: + ENGINE: podman + +/rootful-podman: + summary: Run all tests under Rootful Podman + environment: + ENGINE: rootful-podman diff --git a/scripts/entrypoint.sh b/scripts/entrypoint.sh index f134295..9060b4e 100644 --- a/scripts/entrypoint.sh +++ b/scripts/entrypoint.sh @@ -50,9 +50,6 @@ virsh --connect "qemu+unix:///session?socket=$socket" "\$@" EOF chmod +x /crun-vm/virsh -# remove if present from previous boot -rm -f /crun-vm/ssh-successful - # launch VM function __bg_ensure_tty() { diff --git a/src/commands/create/custom_opts.rs b/src/commands/create/custom_opts.rs index 65f2c4f..8ca121a 100644 --- a/src/commands/create/custom_opts.rs +++ b/src/commands/create/custom_opts.rs @@ -52,6 +52,9 @@ pub struct CustomOptions { #[clap(long)] pub random_ssh_key_pair: bool, + #[clap(long, help = "Use software emulation rather than KVM")] + pub emulated: bool, + #[clap(long)] pub cloud_init: Option, diff --git a/src/commands/create/domain.rs b/src/commands/create/domain.rs index 06d9bf8..6e81263 100644 --- a/src/commands/create/domain.rs +++ b/src/commands/create/domain.rs @@ -1,5 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-or-later +use std::env; use std::fs::File; use std::io::{BufReader, Write}; @@ -19,7 +20,7 @@ pub fn set_up_libvirt_domain_xml( ) -> Result<()> { let path = spec.root_path()?.join("crun-vm/domain.xml"); - generate(&path, spec, vm_image_info, mounts)?; + generate(&path, spec, vm_image_info, mounts, custom_options)?; merge_overlays(&path, &custom_options.merge_libvirt_xml)?; Ok(()) @@ -30,21 +31,23 @@ fn generate( spec: &oci_spec::runtime::Spec, vm_image_info: &VmImageInfo, mounts: &Mounts, + custom_options: &CustomOptions, ) -> Result<()> { let mut w = xml::EmitterConfig::new() .perform_indent(true) .create_writer(File::create(path.as_ref())?); - let has_kvm = Utf8Path::new("/dev/kvm").exists(); - let domain_type = if has_kvm { "kvm" } else { "qemu" }; + let domain_type = match custom_options.emulated { + true => "qemu", + false => "kvm", + }; s(&mut w, "domain", &[("type", domain_type)], |w| { st(w, "name", &[], "domain")?; - let cpu_mode = if has_kvm { - "host-passthrough" - } else { - "host-model" + let cpu_mode = match custom_options.emulated { + true => "host-model", + false => "host-passthrough", }; se(w, "cpu", &[("mode", cpu_mode)])?; @@ -58,8 +61,18 @@ fn generate( let memory = get_memory_size(spec).to_string(); st(w, "memory", &[("unit", "b")], memory.as_str())?; - s(w, "os", &[], |w| { - st(w, "type", &[("machine", "q35")], "hvm") + s(w, "os", &[("firmware", "efi")], |w| { + let attrs = match ["x86", "x86_64"].contains(&env::consts::ARCH) { + true => [("machine", "q35")].as_slice(), + false => [].as_slice(), // use libvirt's default + }; + st(w, "type", attrs, "hvm")?; + + s(w, "firmware", &[], |w| { + se(w, "feature", &[("enabled", "no"), ("name", "secure-boot")]) + })?; + + Ok(()) })?; // fw_cfg requires ACPI diff --git a/src/commands/create/mod.rs b/src/commands/create/mod.rs index 0a1bb31..dcc557d 100644 --- a/src/commands/create/mod.rs +++ b/src/commands/create/mod.rs @@ -81,13 +81,18 @@ pub fn create(args: &liboci_cli::Create, raw_args: &[impl AsRef]) -> Resu set_up_devices(&mut spec, &mut mounts)?; set_up_blockdevs(&mut spec, &mut mounts, &custom_options)?; - set_up_extra_container_mounts_and_devices(&mut spec)?; + set_up_extra_container_mounts_and_devices(&mut spec, &custom_options)?; set_up_security(&mut spec); - if is_first_create { - let ssh_pub_key = - set_up_ssh_key_pair(&mut spec, &custom_options, runtime_env, &priv_dir_path)?; + let ssh_pub_key = set_up_ssh_key_pair( + &mut spec, + &custom_options, + runtime_env, + &priv_dir_path, + is_first_create, + )?; + if is_first_create { set_up_first_boot_config(&spec, &mounts, &custom_options, &ssh_pub_key)?; set_up_libvirt_domain_xml(&spec, &base_vm_image_info, &mounts, &custom_options)?; } @@ -127,6 +132,11 @@ fn set_up_container_root( let new_root_path = priv_dir_path.join("root"); fs::create_dir_all(&new_root_path)?; + match fs::remove_file(new_root_path.join("crun-vm/ssh-successful")) { + Err(e) if e.kind() == ErrorKind::NotFound => {} + r => r?, + }; + // create root directory spec.set_root(Some( @@ -199,7 +209,7 @@ fn set_up_vm_image( let image_dir_path = priv_dir_path.join("image"); fs::create_dir_all(&image_dir_path)?; - if !image_dir_path.join("image").exists() { + if !image_dir_path.join("image").try_exists()? { fs::hard_link(vm_image_path_in_host, image_dir_path.join("image"))?; } @@ -475,7 +485,10 @@ fn set_up_blockdevs( Ok(()) } -fn set_up_extra_container_mounts_and_devices(spec: &mut oci_spec::runtime::Spec) -> Result<()> { +fn set_up_extra_container_mounts_and_devices( + spec: &mut oci_spec::runtime::Spec, + custom_options: &CustomOptions, +) -> Result<()> { fn add_bind_mount(spec: &mut oci_spec::runtime::Spec, path: impl AsRef) { spec.mounts_push( oci_spec::runtime::MountBuilder::default() @@ -526,7 +539,12 @@ fn set_up_extra_container_mounts_and_devices(spec: &mut oci_spec::runtime::Spec) .unwrap(), ); - if Utf8Path::new("/dev/kvm").exists() { + if !custom_options.emulated { + ensure!( + Path::new("/dev/kvm").try_exists()?, + "/dev/kvm not found; is host KVM support enabled?" + ); + add_bind_mount(spec, "/dev/kvm"); add_char_dev(spec, "/dev/kvm")?; } @@ -607,6 +625,7 @@ fn set_up_ssh_key_pair( custom_options: &CustomOptions, env: RuntimeEnv, priv_dir_path: &Utf8Path, + is_first_create: bool, ) -> Result { let user_home: Utf8PathBuf = home::home_dir() .ok_or_else(|| anyhow!("could not determine user home"))? @@ -636,7 +655,7 @@ fn set_up_ssh_key_pair( spec.mount_label(), true, )?; - } else { + } else if is_first_create { // use new key pair fs::create_dir_all(&container_ssh_dir)?; diff --git a/tests/env.sh b/tests/env.sh index 7200a71..a49ff6f 100755 --- a/tests/env.sh +++ b/tests/env.sh @@ -5,14 +5,14 @@ set -o errexit -o pipefail -o nounset start_time="$( date +%s%N )" -env_image_base=quay.io/containerdisks/fedora:39 +env_image_base=${CRUN_VM_TEST_ENV_BASE_IMAGE:-"quay.io/containerdisks/fedora:40"} env_image=quay.io/crun-vm/test-env:latest container_name=crun-vm-test-env declare -A TEST_IMAGES TEST_IMAGES=( - [fedora]=quay.io/containerdisks/fedora:39 # uses cloud-init - [coreos]=quay.io/crun-vm/example-fedora-coreos:39 # uses Ignition + [fedora]=quay.io/containerdisks/fedora:40 # uses cloud-init + [coreos]=quay.io/crun-vm/example-fedora-coreos:40 # uses Ignition ) declare -A TEST_IMAGES_DEFAULT_USER @@ -122,6 +122,15 @@ trap '__extra_cleanup; rm -fr "$temp_dir"' EXIT export RUST_BACKTRACE=1 RUST_LIB_BACKTRACE=1 +arch=$( uname -m ) +case "$arch" in +x86_64|aarch64) + ;; +*) + >&2 echo "Unsupported arch \"$arch\"" + ;; +esac + case "${1:-}" in build) if (( $# != 1 )); then @@ -140,10 +149,25 @@ build) # expand base image + case "$arch" in + x86_64) + root_part=/dev/sda4 + ;; + aarch64) + root_part=/dev/sda3 + + # enable nested virt + virt-customize \ + --add "$temp_dir/image" \ + --append-line '/etc/default/grub:GRUB_CMDLINE_LINUX_DEFAULT="kvm-arm.mode=nested"' \ + --run-command 'grub2-mkconfig -o /boot/grub2/grub.cfg' + ;; + esac + __log_and_run qemu-img create -f qcow2 "$temp_dir/resized-image.qcow2" 20G __log_and_run virt-resize \ --quiet \ - --expand /dev/sda5 \ + --expand "$root_part" \ "$temp_dir/image" \ "$temp_dir/resized-image.qcow2" @@ -155,9 +179,14 @@ build) --name "$container_name-build" \ --runtime "$runtime" \ --memory 8g \ - --rm -dit \ + --rm -it \ --rootfs "$temp_dir" \ - --persistent + --persistent & + + sleep 120 + kill %1 + wait + exit 42 # shellcheck disable=SC2317 __extra_cleanup() { @@ -174,6 +203,15 @@ build) # get a predictable keypair __exec 'ssh-keygen -q -f .ssh/id_rsa -N "" && sudo cp -r .ssh /root/' + case "$arch" in + x86_64) + qemu_pkg=qemu-system-x86-core + ;; + aarch64) + qemu_pkg=qemu-system-aarch64-core + ;; + esac + __exec sudo dnf update -y __exec sudo dnf install -y \ bash \ @@ -191,7 +229,7 @@ build) openssh-clients \ podman \ qemu-img \ - qemu-system-x86-core \ + "$qemu_pkg" \ shadow-utils \ util-linux \ virtiofsd @@ -411,7 +449,11 @@ run) xargs --no-run-if-empty ${engine_cmd[*]} stop --time 0 \ >/dev/null 2>&1 ${engine_cmd[*]} ps --filter label=$label --format '{{.Names}}' --all | - xargs --no-run-if-empty ${engine_cmd[*]} rm --force + xargs --no-run-if-empty ${engine_cmd[*]} rm --force \ + >/dev/null 2>&1 \ + || true # avoid 'removal already in progress' docker errors + ${engine_cmd[*]} ps --filter label=$label --format '{{.Names}}' --all | + xargs --no-run-if-empty false # fail if containers still exist sudo rm -fr $label.temp $label.util " diff --git a/tests/t/cloud-init.sh b/tests/t/cloud-init.sh index 6ea51dd..17b0e1c 100644 --- a/tests/t/cloud-init.sh +++ b/tests/t/cloud-init.sh @@ -15,11 +15,7 @@ EOF cat >"$TEMP_DIR/meta-data" <"$TEMP_DIR/config.ign" < "$TEMP_DIR/file" __engine run \ - --rm --detach \ + --detach \ --name "mount-$os" \ --volume "$TEMP_DIR/file:$home/file:z" \ --volume "$TEMP_DIR:$home/dir:z" \ --mount "type=tmpfs,dst=$home/tmp" \ - "$image" \ - "" + "$image" __test() { __engine exec "mount-$os" --as "$user" @@ -43,5 +42,6 @@ for os in fedora coreos; do __test __engine stop --time 0 "mount-$os" + __engine rm "mount-$os" done diff --git a/tests/t/publish.sh b/tests/t/publish.sh index 34f04c6..a2748dc 100644 --- a/tests/t/publish.sh +++ b/tests/t/publish.sh @@ -7,8 +7,7 @@ __engine run \ --rm --detach \ --name publish \ --publish 127.0.0.1::8000 \ - "$image" \ - "" + "$image" endpoint=$( __engine port publish | tee /dev/stderr | cut -d' ' -f3 ) diff --git a/tests/t/stop-start.sh b/tests/t/stop-start.sh index b4787b1..bdce535 100644 --- a/tests/t/stop-start.sh +++ b/tests/t/stop-start.sh @@ -1,6 +1,6 @@ # SPDX-License-Identifier: GPL-2.0-or-later -__engine run --detach --name stop-start "${TEST_IMAGES[fedora]}" "" +__engine run --detach --name stop-start "${TEST_IMAGES[fedora]}" __engine exec stop-start --as fedora '[[ ! -e i-was-here ]] && touch i-was-here'