From a84a358b3b90dac9a66f6034434843a612aa888f Mon Sep 17 00:00:00 2001 From: Ievgen Popovych Date: Wed, 15 Mar 2023 16:08:24 +0100 Subject: [PATCH] pkg/utils, test/system: Offer built-in support for Ubuntu This allows using the --distro and --release options to create and enter Ubuntu containers. Note that Ubuntu 4.10 was the first ever Ubuntu release [1]. Hence, values older than that are not permitted for the --release option. Some changes by Debarshi Ray. [1] https://wiki.ubuntu.com/Releases https://github.com/containers/toolbox/pull/483 https://github.com/containers/toolbox/pull/1284 Signed-off-by: Ievgen Popovych --- src/pkg/utils/utils.go | 55 ++++++++ src/pkg/utils/utils_test.go | 115 +++++++++++++++++ test/system/000-setup.bats | 3 + test/system/101-create.bats | 235 ++++++++++++++++++++++++++++++++++ test/system/102-list.bats | 90 +++++++++++++ test/system/104-run.bats | 30 +++++ test/system/libs/helpers.bash | 3 +- 7 files changed, 530 insertions(+), 1 deletion(-) diff --git a/src/pkg/utils/utils.go b/src/pkg/utils/utils.go index 48da8726b..7a6b29a7e 100644 --- a/src/pkg/utils/utils.go +++ b/src/pkg/utils/utils.go @@ -28,6 +28,7 @@ import ( "strings" "syscall" "time" + "unicode/utf8" "github.com/acobaugh/osrelease" "github.com/containers/toolbox/pkg/shell" @@ -108,6 +109,12 @@ var ( getFullyQualifiedImageRHEL, parseReleaseRHEL, }, + "ubuntu": { + "ubuntu-toolbox", + "ubuntu-toolbox", + getFullyQualifiedImageUbuntu, + parseReleaseUbuntu, + }, } ) @@ -343,6 +350,11 @@ func getFullyQualifiedImageRHEL(image, release string) string { return imageFull } +func getFullyQualifiedImageUbuntu(image, release string) string { + imageFull := "quay.io/toolbx-images/" + image + return imageFull +} + // GetGroupForSudo returns the name of the sudoers group. // // Some distros call it 'sudo' (eg. Ubuntu) and some call it 'wheel' (eg. Fedora). @@ -672,6 +684,49 @@ func parseReleaseRHEL(release string) (string, error) { return release, nil } +func parseReleaseUbuntu(release string) (string, error) { + releaseParts := strings.Split(release, ".") + if len(releaseParts) != 2 { + return "", &ParseReleaseError{"The release must be in the 'YY.MM' format."} + } + + releaseYear, err := strconv.Atoi(releaseParts[0]) + if err != nil { + logrus.Debugf("Parsing release year %s as an integer failed: %s", releaseParts[0], err) + return "", &ParseReleaseError{"The release must be in the 'YY.MM' format."} + } + + if releaseYear < 4 { + return "", &ParseReleaseError{"The release year must be 4 or more."} + } + + releaseYearLen := utf8.RuneCountInString(releaseParts[0]) + if releaseYearLen > 2 { + return "", &ParseReleaseError{"The release year cannot have more than two digits."} + } else if releaseYear < 10 && releaseYearLen == 2 { + return "", &ParseReleaseError{"The release year cannot have a leading zero."} + } + + releaseMonth, err := strconv.Atoi(releaseParts[1]) + if err != nil { + logrus.Debugf("Parsing release month %s as an integer failed: %s", releaseParts[1], err) + return "", &ParseReleaseError{"The release must be in the 'YY.MM' format."} + } + + if releaseMonth < 1 { + return "", &ParseReleaseError{"The release month must be between 01 and 12."} + } else if releaseMonth > 12 { + return "", &ParseReleaseError{"The release month must be between 01 and 12."} + } + + releaseMonthLen := utf8.RuneCountInString(releaseParts[1]) + if releaseMonthLen != 2 { + return "", &ParseReleaseError{"The release month must have two digits."} + } + + return release, nil +} + // PathExists wraps around os.Stat providing a nice interface for checking an existence of a path. func PathExists(path string) bool { if _, err := os.Stat(path); !os.IsNotExist(err) { diff --git a/src/pkg/utils/utils_test.go b/src/pkg/utils/utils_test.go index a34562b52..425a7a11a 100644 --- a/src/pkg/utils/utils_test.go +++ b/src/pkg/utils/utils_test.go @@ -205,6 +205,121 @@ func TestParseRelease(t *testing.T) { inputRelease: "2.-1", errMsg: "The release must be in the '.' format.", }, + { + inputDistro: "ubuntu", + inputRelease: "4.10", + output: "4.10", + }, + { + inputDistro: "ubuntu", + inputRelease: "5.04", + output: "5.04", + }, + { + inputDistro: "ubuntu", + inputRelease: "20.04", + output: "20.04", + }, + { + inputDistro: "ubuntu", + inputRelease: "20.10", + output: "20.10", + }, + { + inputDistro: "ubuntu", + inputRelease: "20", + errMsg: "The release must be in the 'YY.MM' format.", + }, + { + inputDistro: "ubuntu", + inputRelease: "20.04.0", + errMsg: "The release must be in the 'YY.MM' format.", + }, + { + inputDistro: "ubuntu", + inputRelease: "20.04.1", + errMsg: "The release must be in the 'YY.MM' format.", + }, + { + inputDistro: "ubuntu", + inputRelease: "foo", + errMsg: "The release must be in the 'YY.MM' format.", + }, + { + inputDistro: "ubuntu", + inputRelease: "20foo", + errMsg: "The release must be in the 'YY.MM' format.", + }, + { + inputDistro: "ubuntu", + inputRelease: "foo.bar", + errMsg: "The release must be in the 'YY.MM' format.", + }, + { + inputDistro: "ubuntu", + inputRelease: "foo.bar.baz", + errMsg: "The release must be in the 'YY.MM' format.", + }, + { + inputDistro: "ubuntu", + inputRelease: "3.10", + errMsg: "The release year must be 4 or more.", + }, + { + inputDistro: "ubuntu", + inputRelease: "202.4", + errMsg: "The release year cannot have more than two digits.", + }, + { + inputDistro: "ubuntu", + inputRelease: "202.04", + errMsg: "The release year cannot have more than two digits.", + }, + { + inputDistro: "ubuntu", + inputRelease: "2020.4", + errMsg: "The release year cannot have more than two digits.", + }, + { + inputDistro: "ubuntu", + inputRelease: "2020.04", + errMsg: "The release year cannot have more than two digits.", + }, + { + inputDistro: "ubuntu", + inputRelease: "04.10", + errMsg: "The release year cannot have a leading zero.", + }, + { + inputDistro: "ubuntu", + inputRelease: "4.bar", + errMsg: "The release must be in the 'YY.MM' format.", + }, + { + inputDistro: "ubuntu", + inputRelease: "4.bar.baz", + errMsg: "The release must be in the 'YY.MM' format.", + }, + { + inputDistro: "ubuntu", + inputRelease: "4.0", + errMsg: "The release month must be between 01 and 12.", + }, + { + inputDistro: "ubuntu", + inputRelease: "4.00", + errMsg: "The release month must be between 01 and 12.", + }, + { + inputDistro: "ubuntu", + inputRelease: "4.13", + errMsg: "The release month must be between 01 and 12.", + }, + { + inputDistro: "ubuntu", + inputRelease: "20.4", + errMsg: "The release month must have two digits.", + }, } for _, tc := range testCases { diff --git a/test/system/000-setup.bats b/test/system/000-setup.bats index a55d9e52f..795dc60ea 100644 --- a/test/system/000-setup.bats +++ b/test/system/000-setup.bats @@ -28,6 +28,9 @@ load 'libs/helpers' # Cache all images that will be needed during the tests _pull_and_cache_distro_image fedora 34 || false _pull_and_cache_distro_image rhel 8.7 || false + _pull_and_cache_distro_image ubuntu 16.04 || false + _pull_and_cache_distro_image ubuntu 18.04 || false + _pull_and_cache_distro_image ubuntu 20.04 || false _pull_and_cache_distro_image busybox || false # If run on Fedora Rawhide, cache 2 extra images (previous Fedora versions) local rawhide_res="$(awk '/rawhide/' $os_release)" diff --git a/test/system/101-create.bats b/test/system/101-create.bats index 824dd5a4b..df806f56e 100644 --- a/test/system/101-create.bats +++ b/test/system/101-create.bats @@ -112,6 +112,51 @@ teardown() { assert_output --regexp "Created[[:blank:]]+rhel-toolbox-8.7" } +@test "create: Ubuntu 16.04" { + pull_distro_image ubuntu 16.04 + + run $TOOLBOX --assumeyes create --distro ubuntu --release 16.04 + + assert_success + assert_output --partial "Created container: ubuntu-toolbox-16.04" + assert_output --partial "Enter with: toolbox enter ubuntu-toolbox-16.04" + + run $PODMAN ps --all + + assert_success + assert_output --regexp "Created[[:blank:]]+ubuntu-toolbox-16.04" +} + +@test "create: Ubuntu 18.04" { + pull_distro_image ubuntu 18.04 + + run $TOOLBOX --assumeyes create --distro ubuntu --release 18.04 + + assert_success + assert_output --partial "Created container: ubuntu-toolbox-18.04" + assert_output --partial "Enter with: toolbox enter ubuntu-toolbox-18.04" + + run $PODMAN ps --all + + assert_success + assert_output --regexp "Created[[:blank:]]+ubuntu-toolbox-18.04" +} + +@test "create: Ubuntu 20.04" { + pull_distro_image ubuntu 20.04 + + run $TOOLBOX --assumeyes create --distro ubuntu --release 20.04 + + assert_success + assert_output --partial "Created container: ubuntu-toolbox-20.04" + assert_output --partial "Enter with: toolbox enter ubuntu-toolbox-20.04" + + run $PODMAN ps --all + + assert_success + assert_output --regexp "Created[[:blank:]]+ubuntu-toolbox-20.04" +} + @test "create: Try an unsupported distribution" { local distro="foo" @@ -333,6 +378,196 @@ teardown() { assert [ ${#lines[@]} -eq 3 ] } +@test "create: Try Ubuntu with an invalid release ('--release 20')" { + run $TOOLBOX --assumeyes create --distro ubuntu --release 20 + + assert_failure + assert_line --index 0 "Error: invalid argument for '--release'" + assert_line --index 1 "The release must be in the 'YY.MM' format." + assert_line --index 2 "Run 'toolbox --help' for usage." + assert [ ${#lines[@]} -eq 3 ] +} + +@test "create: Try Ubuntu with an invalid release ('--release 20.04.0')" { + run $TOOLBOX --assumeyes create --distro ubuntu --release 20.04.0 + + assert_failure + assert_line --index 0 "Error: invalid argument for '--release'" + assert_line --index 1 "The release must be in the 'YY.MM' format." + assert_line --index 2 "Run 'toolbox --help' for usage." + assert [ ${#lines[@]} -eq 3 ] +} + +@test "create: Try Ubuntu with an invalid release ('--release 20.04.1')" { + run $TOOLBOX --assumeyes create --distro ubuntu --release 20.04.1 + + assert_failure + assert_line --index 0 "Error: invalid argument for '--release'" + assert_line --index 1 "The release must be in the 'YY.MM' format." + assert_line --index 2 "Run 'toolbox --help' for usage." + assert [ ${#lines[@]} -eq 3 ] +} + +@test "create: Try Ubuntu with an invalid release ('--release foo')" { + run $TOOLBOX --assumeyes create --distro ubuntu --release foo + + assert_failure + assert_line --index 0 "Error: invalid argument for '--release'" + assert_line --index 1 "The release must be in the 'YY.MM' format." + assert_line --index 2 "Run 'toolbox --help' for usage." + assert [ ${#lines[@]} -eq 3 ] +} + +@test "create: Try Ubuntu with an invalid release ('--release 20foo')" { + run $TOOLBOX --assumeyes create --distro ubuntu --release 20foo + + assert_failure + assert_line --index 0 "Error: invalid argument for '--release'" + assert_line --index 1 "The release must be in the 'YY.MM' format." + assert_line --index 2 "Run 'toolbox --help' for usage." + assert [ ${#lines[@]} -eq 3 ] +} + +@test "create: Try Ubuntu with an invalid release ('--release foo.bar')" { + run $TOOLBOX --assumeyes create --distro ubuntu --release foo.bar + + assert_failure + assert_line --index 0 "Error: invalid argument for '--release'" + assert_line --index 1 "The release must be in the 'YY.MM' format." + assert_line --index 2 "Run 'toolbox --help' for usage." + assert [ ${#lines[@]} -eq 3 ] +} + +@test "create: Try Ubuntu with an invalid release ('--release foo.bar.baz')" { + run $TOOLBOX --assumeyes create --distro ubuntu --release foo.bar.baz + + assert_failure + assert_line --index 0 "Error: invalid argument for '--release'" + assert_line --index 1 "The release must be in the 'YY.MM' format." + assert_line --index 2 "Run 'toolbox --help' for usage." + assert [ ${#lines[@]} -eq 3 ] +} + +@test "create: Try Ubuntu with an invalid release ('--release 3.10')" { + run $TOOLBOX --assumeyes create --distro ubuntu --release 3.10 + + assert_failure + assert_line --index 0 "Error: invalid argument for '--release'" + assert_line --index 1 "The release year must be 4 or more." + assert_line --index 2 "Run 'toolbox --help' for usage." + assert [ ${#lines[@]} -eq 3 ] +} + +@test "create: Try Ubuntu with an invalid release ('--release 202.4')" { + run $TOOLBOX --assumeyes create --distro ubuntu --release 202.4 + + assert_failure + assert_line --index 0 "Error: invalid argument for '--release'" + assert_line --index 1 "The release year cannot have more than two digits." + assert_line --index 2 "Run 'toolbox --help' for usage." + assert [ ${#lines[@]} -eq 3 ] +} + +@test "create: Try Ubuntu with an invalid release ('--release 202.04')" { + run $TOOLBOX --assumeyes create --distro ubuntu --release 202.04 + + assert_failure + assert_line --index 0 "Error: invalid argument for '--release'" + assert_line --index 1 "The release year cannot have more than two digits." + assert_line --index 2 "Run 'toolbox --help' for usage." + assert [ ${#lines[@]} -eq 3 ] +} + +@test "create: Try Ubuntu with an invalid release ('--release 2020.4')" { + run $TOOLBOX --assumeyes create --distro ubuntu --release 2020.4 + + assert_failure + assert_line --index 0 "Error: invalid argument for '--release'" + assert_line --index 1 "The release year cannot have more than two digits." + assert_line --index 2 "Run 'toolbox --help' for usage." + assert [ ${#lines[@]} -eq 3 ] +} + +@test "create: Try Ubuntu with an invalid release ('--release 2020.04')" { + run $TOOLBOX --assumeyes create --distro ubuntu --release 2020.04 + + assert_failure + assert_line --index 0 "Error: invalid argument for '--release'" + assert_line --index 1 "The release year cannot have more than two digits." + assert_line --index 2 "Run 'toolbox --help' for usage." + assert [ ${#lines[@]} -eq 3 ] +} + +@test "create: Try Ubuntu with an invalid release ('--release 04.10')" { + run $TOOLBOX --assumeyes create --distro ubuntu --release 04.10 + + assert_failure + assert_line --index 0 "Error: invalid argument for '--release'" + assert_line --index 1 "The release year cannot have a leading zero." + assert_line --index 2 "Run 'toolbox --help' for usage." + assert [ ${#lines[@]} -eq 3 ] +} + +@test "create: Try Ubuntu with an invalid release ('--release 4.bar')" { + run $TOOLBOX --assumeyes create --distro ubuntu --release 4.bar + + assert_failure + assert_line --index 0 "Error: invalid argument for '--release'" + assert_line --index 1 "The release must be in the 'YY.MM' format." + assert_line --index 2 "Run 'toolbox --help' for usage." + assert [ ${#lines[@]} -eq 3 ] +} + +@test "create: Try Ubuntu with an invalid release ('--release 4.bar.baz')" { + run $TOOLBOX --assumeyes create --distro ubuntu --release 4.bar.baz + + assert_failure + assert_line --index 0 "Error: invalid argument for '--release'" + assert_line --index 1 "The release must be in the 'YY.MM' format." + assert_line --index 2 "Run 'toolbox --help' for usage." + assert [ ${#lines[@]} -eq 3 ] +} + +@test "create: Try Ubuntu with an invalid release ('--release 4.0')" { + run $TOOLBOX --assumeyes create --distro ubuntu --release 4.0 + + assert_failure + assert_line --index 0 "Error: invalid argument for '--release'" + assert_line --index 1 "The release month must be between 01 and 12." + assert_line --index 2 "Run 'toolbox --help' for usage." + assert [ ${#lines[@]} -eq 3 ] +} + +@test "create: Try Ubuntu with an invalid release ('--release 4.00')" { + run $TOOLBOX --assumeyes create --distro ubuntu --release 4.00 + + assert_failure + assert_line --index 0 "Error: invalid argument for '--release'" + assert_line --index 1 "The release month must be between 01 and 12." + assert_line --index 2 "Run 'toolbox --help' for usage." + assert [ ${#lines[@]} -eq 3 ] +} + +@test "create: Try Ubuntu with an invalid release ('--release 4.13')" { + run $TOOLBOX --assumeyes create --distro ubuntu --release 4.13 + + assert_failure + assert_line --index 0 "Error: invalid argument for '--release'" + assert_line --index 1 "The release month must be between 01 and 12." + assert_line --index 2 "Run 'toolbox --help' for usage." + assert [ ${#lines[@]} -eq 3 ] +} + +@test "create: Try Ubuntu with an invalid release ('--release 20.4')" { + run $TOOLBOX --assumeyes create --distro ubuntu --release 20.4 + + assert_failure + assert_line --index 0 "Error: invalid argument for '--release'" + assert_line --index 1 "The release month must have two digits." + assert_line --index 2 "Run 'toolbox --help' for usage." + assert [ ${#lines[@]} -eq 3 ] +} + @test "create: Try a non-default distro without a release" { local distro="fedora" local system_id="$(get_system_id)" diff --git a/test/system/102-list.bats b/test/system/102-list.bats index 22e0c444d..15c40701d 100644 --- a/test/system/102-list.bats +++ b/test/system/102-list.bats @@ -178,6 +178,96 @@ teardown() { assert [ ${#stderr_lines[@]} -eq 0 ] } +@test "list: Ubuntu 16.04 image" { + pull_distro_image ubuntu 16.04 + + local num_of_images + num_of_images="$(list_images)" + assert_equal "$num_of_images" 1 + + run --keep-empty-lines --separate-stderr "$TOOLBOX" list + + assert_success + assert_line --index 1 --partial "quay.io/toolbx-images/ubuntu-toolbox:16.04" + assert [ ${#lines[@]} -eq 3 ] + assert [ ${#stderr_lines[@]} -eq 0 ] +} + +@test "list: Ubuntu 16.04 image (using --images)" { + pull_distro_image ubuntu 16.04 + + local num_of_images + num_of_images="$(list_images)" + assert_equal "$num_of_images" 1 + + run --keep-empty-lines --separate-stderr "$TOOLBOX" list --images + + assert_success + assert_line --index 1 --partial "quay.io/toolbx-images/ubuntu-toolbox:16.04" + assert [ ${#lines[@]} -eq 3 ] + assert [ ${#stderr_lines[@]} -eq 0 ] +} + +@test "list: Ubuntu 18.04 image" { + pull_distro_image ubuntu 18.04 + + local num_of_images + num_of_images="$(list_images)" + assert_equal "$num_of_images" 1 + + run --keep-empty-lines --separate-stderr "$TOOLBOX" list + + assert_success + assert_line --index 1 --partial "quay.io/toolbx-images/ubuntu-toolbox:18.04" + assert [ ${#lines[@]} -eq 3 ] + assert [ ${#stderr_lines[@]} -eq 0 ] +} + +@test "list: Ubuntu 18.04 image (using --images)" { + pull_distro_image ubuntu 18.04 + + local num_of_images + num_of_images="$(list_images)" + assert_equal "$num_of_images" 1 + + run --keep-empty-lines --separate-stderr "$TOOLBOX" list --images + + assert_success + assert_line --index 1 --partial "quay.io/toolbx-images/ubuntu-toolbox:18.04" + assert [ ${#lines[@]} -eq 3 ] + assert [ ${#stderr_lines[@]} -eq 0 ] +} + +@test "list: Ubuntu 20.04 image" { + pull_distro_image ubuntu 20.04 + + local num_of_images + num_of_images="$(list_images)" + assert_equal "$num_of_images" 1 + + run --keep-empty-lines --separate-stderr "$TOOLBOX" list + + assert_success + assert_line --index 1 --partial "quay.io/toolbx-images/ubuntu-toolbox:20.04" + assert [ ${#lines[@]} -eq 3 ] + assert [ ${#stderr_lines[@]} -eq 0 ] +} + +@test "list: Ubuntu 20.04 image (using --images)" { + pull_distro_image ubuntu 20.04 + + local num_of_images + num_of_images="$(list_images)" + assert_equal "$num_of_images" 1 + + run --keep-empty-lines --separate-stderr "$TOOLBOX" list --images + + assert_success + assert_line --index 1 --partial "quay.io/toolbx-images/ubuntu-toolbox:20.04" + assert [ ${#lines[@]} -eq 3 ] + assert [ ${#stderr_lines[@]} -eq 0 ] +} + @test "list: An image without a name" { build_image_without_name >/dev/null diff --git a/test/system/104-run.bats b/test/system/104-run.bats index 0cd3ba566..484fb9fe7 100644 --- a/test/system/104-run.bats +++ b/test/system/104-run.bats @@ -66,6 +66,36 @@ teardown() { assert [ ${#stderr_lines[@]} -eq 0 ] } +@test "run: Smoke test with Ubuntu 16.04" { + create_distro_container ubuntu 16.04 ubuntu-toolbox-16.04 + + run --separate-stderr $TOOLBOX run --distro ubuntu --release 16.04 true + + assert_success + assert [ ${#lines[@]} -eq 0 ] + assert [ ${#stderr_lines[@]} -eq 0 ] +} + +@test "run: Smoke test with Ubuntu 18.04" { + create_distro_container ubuntu 18.04 ubuntu-toolbox-18.04 + + run --separate-stderr $TOOLBOX run --distro ubuntu --release 18.04 true + + assert_success + assert [ ${#lines[@]} -eq 0 ] + assert [ ${#stderr_lines[@]} -eq 0 ] +} + +@test "run: Smoke test with Ubuntu 20.04" { + create_distro_container ubuntu 20.04 ubuntu-toolbox-20.04 + + run --separate-stderr $TOOLBOX run --distro ubuntu --release 20.04 true + + assert_success + assert [ ${#lines[@]} -eq 0 ] + assert [ ${#stderr_lines[@]} -eq 0 ] +} + @test "run: Ensure that a login shell is used to invoke the command" { create_default_container diff --git a/test/system/libs/helpers.bash b/test/system/libs/helpers.bash index 5f56e4f9a..b264d7216 100644 --- a/test/system/libs/helpers.bash +++ b/test/system/libs/helpers.bash @@ -26,7 +26,8 @@ readonly SKOPEO=${SKOPEO:-$(command -v skopeo)} declare -Ag IMAGES=([busybox]="quay.io/toolbox_tests/busybox" \ [docker-reg]="quay.io/toolbox_tests/registry" \ [fedora]="registry.fedoraproject.org/fedora-toolbox" \ - [rhel]="registry.access.redhat.com/ubi8/toolbox") + [rhel]="registry.access.redhat.com/ubi8/toolbox" \ + [ubuntu]="quay.io/toolbx-images/ubuntu-toolbox") function cleanup_all() {