diff --git a/.github/actions/setup-microceph/action.yml b/.github/actions/setup-microceph/action.yml index 62366a6987a3..f572afb25ab0 100644 --- a/.github/actions/setup-microceph/action.yml +++ b/.github/actions/setup-microceph/action.yml @@ -81,8 +81,7 @@ runs: # MicroCeph does not accept partitions directly. # See: https://github.com/canonical/microceph/issues/251 - disk="$(losetup -f)" - sudo losetup --direct-io=on "${disk}" "${ephemeral_disk}${i}" + disk="$(sudo losetup --find --nooverlap --direct-io=on --show "${ephemeral_disk}${i}")" sudo microceph disk add "${disk}" done else diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml index 3e8f54361865..13fdecbbe440 100644 --- a/.github/workflows/codeql.yml +++ b/.github/workflows/codeql.yml @@ -51,7 +51,7 @@ jobs: strategy: fail-fast: false matrix: - language: ['go'] + language: ['go', 'python'] # CodeQL supports [ 'c-cpp', 'csharp', 'go', 'java-kotlin', 'javascript-typescript', 'python', 'ruby', 'swift' ] # Use only 'java-kotlin' to analyze code written in Java, Kotlin or both # Use only 'javascript-typescript' to analyze code written in JavaScript, TypeScript or both diff --git a/Makefile b/Makefile index e81761c12f23..453d595fc5af 100644 --- a/Makefile +++ b/Makefile @@ -143,6 +143,9 @@ update-protobuf: .PHONY: update-schema update-schema: +ifeq ($(shell command -v goimports),) + (cd / ; go install golang.org/x/tools/cmd/goimports@latest) +endif cd lxd/db/generate && go build -v -trimpath -o $(GOPATH)/bin/lxd-generate -tags "$(TAG_SQLITE3)" $(DEBUG) && cd - go generate ./... gofmt -s -w ./lxd/db/ diff --git a/lxd/db/cluster/config.mapper.go b/lxd/db/cluster/config.mapper.go index 530ac1532009..d4e32a0eb4f8 100644 --- a/lxd/db/cluster/config.mapper.go +++ b/lxd/db/cluster/config.mapper.go @@ -89,8 +89,9 @@ func GetConfig(ctx context.Context, tx *sql.Tx, parent string, filters ...Config configObjectsLocal := strings.Replace(configObjects, "%s_id", fmt.Sprintf("%s_id", parent), -1) fillParent := make([]any, strings.Count(configObjectsLocal, "%s")) + mangledParent := strings.Replace(parent, "_", "s_", -1) + "s" for i := range fillParent { - fillParent[i] = strings.Replace(parent, "_", "s_", -1) + "s" + fillParent[i] = mangledParent } queryStr := fmt.Sprintf(configObjectsLocal, fillParent...) diff --git a/lxd/db/cluster/devices.mapper.go b/lxd/db/cluster/devices.mapper.go index d4be71c76884..487575d6ea85 100644 --- a/lxd/db/cluster/devices.mapper.go +++ b/lxd/db/cluster/devices.mapper.go @@ -89,8 +89,9 @@ func GetDevices(ctx context.Context, tx *sql.Tx, parent string, filters ...Devic deviceObjectsLocal := strings.Replace(deviceObjects, "%s_id", fmt.Sprintf("%s_id", parent), -1) fillParent := make([]any, strings.Count(deviceObjectsLocal, "%s")) + mangledParent := strings.Replace(parent, "_", "s_", -1) + "s" for i := range fillParent { - fillParent[i] = strings.Replace(parent, "_", "s_", -1) + "s" + fillParent[i] = mangledParent } queryStr := fmt.Sprintf(deviceObjectsLocal, fillParent...) diff --git a/lxd/db/generate/db/method.go b/lxd/db/generate/db/method.go index 16b92d5facb1..9a4b477b8f19 100644 --- a/lxd/db/generate/db/method.go +++ b/lxd/db/generate/db/method.go @@ -178,8 +178,9 @@ func (m *Method) getMany(buf *file.Buffer) error { stmtLocal := stmtVar + "Local" buf.L("%s := strings.Replace(%s, \"%%s_id\", fmt.Sprintf(\"%%s_id\", parent), -1)", stmtLocal, stmtVar) buf.L("fillParent := make([]any, strings.Count(%s, \"%%s\"))", stmtLocal) + buf.L("mangledParent := strings.Replace(parent, \"_\", \"s_\", -1) + \"s\"") buf.L("for i := range fillParent {") - buf.L("fillParent[i] = strings.Replace(parent, \"_\", \"s_\", -1) + \"s\"") + buf.L("fillParent[i] = mangledParent") buf.L("}") buf.N() buf.L("queryStr := fmt.Sprintf(%s, fillParent...)", stmtLocal) diff --git a/lxd/resources/cpu.go b/lxd/resources/cpu.go index 26ae39271735..5b5536915f3a 100644 --- a/lxd/resources/cpu.go +++ b/lxd/resources/cpu.go @@ -51,17 +51,17 @@ func parseRangedListToInt64Slice(input string) ([]int64, error) { for _, chunk := range chunks { if strings.Contains(chunk, "-") { // Range - fields := strings.SplitN(chunk, "-", 2) - if len(fields) != 2 { + before, after, _ := strings.Cut(chunk, "-") + if after == "" { return nil, fmt.Errorf("Invalid CPU/NUMA set value: %q", input) } - low, err := strconv.ParseInt(fields[0], 10, 64) + low, err := strconv.ParseInt(before, 10, 64) if err != nil { return nil, fmt.Errorf("Invalid CPU/NUMA set value: %w", err) } - high, err := strconv.ParseInt(fields[1], 10, 64) + high, err := strconv.ParseInt(after, 10, 64) if err != nil { return nil, fmt.Errorf("Invalid CPU/NUMA set value: %w", err) } @@ -243,8 +243,12 @@ func GetCPU() (*api.ResourcesCPU, error) { } // Extract cpu index - fields := strings.SplitN(line, ":", 2) - value := strings.TrimSpace(fields[1]) + _, value, found := strings.Cut(line, ":") + if !found { + return nil, fmt.Errorf("Failed to parse /proc/cpuinfo: Missing separator") + } + + value = strings.TrimSpace(value) cpuSocket, err := strconv.ParseInt(value, 10, 64) if err != nil { return nil, fmt.Errorf("Failed to parse cpu index %q in /proc/cpuinfo: %w", value, err) @@ -272,9 +276,13 @@ func GetCPU() (*api.ResourcesCPU, error) { } // Get key/value - fields := strings.SplitN(line, ":", 2) - key := strings.TrimSpace(fields[0]) - value := strings.TrimSpace(fields[1]) + key, value, found := strings.Cut(line, ":") + if !found { + return nil, fmt.Errorf("Failed to parse /proc/cpuinfo: Missing separator") + } + + key = strings.TrimSpace(key) + value = strings.TrimSpace(value) if key == "vendor_id" { cpuInfo.Vendor = value diff --git a/test/lint/test-tests.sh b/test/lint/test-tests.sh index b3496cf72763..d02135237cce 100755 --- a/test/lint/test-tests.sh +++ b/test/lint/test-tests.sh @@ -58,3 +58,7 @@ if grep -rlE '\!.* \|\| true$' test/; then echo "Some tests commands are ignoring expected failures (! cmd_should_fail || true)" >&2 exit 1 fi +if grep -rlE '^\s*[^\!]+ \|\| false$' test/; then + echo "Some tests commands use unneeded construct to fail (cmd_should_succeed || false)" >&2 + exit 1 +fi diff --git a/test/suites/backup.sh b/test/suites/backup.sh index 772b17c53682..62a29c7807bf 100644 --- a/test/suites/backup.sh +++ b/test/suites/backup.sh @@ -266,7 +266,7 @@ EOF echo "After:" echo "${poolConfigAfter}" - [ "${poolConfigBefore}" = "${poolConfigAfter}" ] || false + [ "${poolConfigBefore}" = "${poolConfigAfter}" ] lxc storage show "${poolName}" lxc info c1 | grep snap0 diff --git a/test/suites/basic.sh b/test/suites/basic.sh index fd5ca9bf4367..d238a8b83821 100644 --- a/test/suites/basic.sh +++ b/test/suites/basic.sh @@ -421,13 +421,13 @@ test_basic_usage() { # Test user, group and cwd lxc exec foo -- mkdir /blah - [ "$(lxc exec foo --user 1000 -- id -u)" = "1000" ] || false - [ "$(lxc exec foo --group 1000 -- id -g)" = "1000" ] || false - [ "$(lxc exec foo --cwd /blah -- pwd)" = "/blah" ] || false + [ "$(lxc exec foo --user 1000 -- id -u)" = "1000" ] + [ "$(lxc exec foo --group 1000 -- id -g)" = "1000" ] + [ "$(lxc exec foo --cwd /blah -- pwd)" = "/blah" ] - [ "$(lxc exec foo --user 1234 --group 5678 --cwd /blah -- id -u)" = "1234" ] || false - [ "$(lxc exec foo --user 1234 --group 5678 --cwd /blah -- id -g)" = "5678" ] || false - [ "$(lxc exec foo --user 1234 --group 5678 --cwd /blah -- pwd)" = "/blah" ] || false + [ "$(lxc exec foo --user 1234 --group 5678 --cwd /blah -- id -u)" = "1234" ] + [ "$(lxc exec foo --user 1234 --group 5678 --cwd /blah -- id -g)" = "5678" ] + [ "$(lxc exec foo --user 1234 --group 5678 --cwd /blah -- pwd)" = "/blah" ] # check that we can set the environment lxc exec foo -- pwd | grep /root diff --git a/test/suites/clustering.sh b/test/suites/clustering.sh index 5a5879e3af52..986c3588ad99 100644 --- a/test/suites/clustering.sh +++ b/test/suites/clustering.sh @@ -492,14 +492,14 @@ test_clustering_containers() { LXD_DIR="${LXD_TWO_DIR}" lxc move bar egg --target node2 LXD_DIR="${LXD_ONE_DIR}" lxc info egg | grep -q "Location: node2" apply_template2=$(LXD_DIR="${LXD_TWO_DIR}" lxc config get egg volatile.apply_template) - [ "${apply_template1}" = "${apply_template2}" ] || false + [ "${apply_template1}" = "${apply_template2}" ] # Move back to node3 the container on node1, keeping the same name. apply_template1=$(LXD_DIR="${LXD_TWO_DIR}" lxc config get egg volatile.apply_template) LXD_DIR="${LXD_TWO_DIR}" lxc move egg --target node3 LXD_DIR="${LXD_ONE_DIR}" lxc info egg | grep -q "Location: node3" apply_template2=$(LXD_DIR="${LXD_TWO_DIR}" lxc config get egg volatile.apply_template) - [ "${apply_template1}" = "${apply_template2}" ] || false + [ "${apply_template1}" = "${apply_template2}" ] if command -v criu >/dev/null 2>&1; then # If CRIU supported, then try doing a live move using same name, @@ -1580,11 +1580,11 @@ test_clustering_update_cert() { # Send update request LXD_DIR="${LXD_ONE_DIR}" lxc cluster update-cert "${cert_path}" "${key_path}" -q - cmp -s "${LXD_ONE_DIR}/cluster.crt" "${cert_path}" || false - cmp -s "${LXD_TWO_DIR}/cluster.crt" "${cert_path}" || false + cmp -s "${LXD_ONE_DIR}/cluster.crt" "${cert_path}" + cmp -s "${LXD_TWO_DIR}/cluster.crt" "${cert_path}" - cmp -s "${LXD_ONE_DIR}/cluster.key" "${key_path}" || false - cmp -s "${LXD_TWO_DIR}/cluster.key" "${key_path}" || false + cmp -s "${LXD_ONE_DIR}/cluster.key" "${key_path}" + cmp -s "${LXD_TWO_DIR}/cluster.key" "${key_path}" LXD_DIR="${LXD_ONE_DIR}" lxc info --target node2 | grep -q "server_name: node2" LXD_DIR="${LXD_TWO_DIR}" lxc info --target node1 | grep -q "server_name: node1" @@ -1754,11 +1754,11 @@ test_clustering_update_cert_token() { # Change the cluster cert LXD_DIR="${LXD_ONE_DIR}" lxc cluster update-cert "${cert_path}" "${key_path}" -q - cmp -s "${LXD_ONE_DIR}/cluster.crt" "${cert_path}" || false - cmp -s "${LXD_TWO_DIR}/cluster.crt" "${cert_path}" || false + cmp -s "${LXD_ONE_DIR}/cluster.crt" "${cert_path}" + cmp -s "${LXD_TWO_DIR}/cluster.crt" "${cert_path}" - cmp -s "${LXD_ONE_DIR}/cluster.key" "${key_path}" || false - cmp -s "${LXD_TWO_DIR}/cluster.key" "${key_path}" || false + cmp -s "${LXD_ONE_DIR}/cluster.key" "${key_path}" + cmp -s "${LXD_TWO_DIR}/cluster.key" "${key_path}" # Verify the token with the wrong cert fingerprint is not usable due to the fingerprint mismatch url="https://10.1.1.101:8443" @@ -2160,8 +2160,8 @@ test_clustering_image_replication() { # Image replication will be performed across all nodes in the cluster by default images_minimal_replica1=$(LXD_DIR="${LXD_ONE_DIR}" lxc config get cluster.images_minimal_replica) images_minimal_replica2=$(LXD_DIR="${LXD_TWO_DIR}" lxc config get cluster.images_minimal_replica) - [ "$images_minimal_replica1" = "" ] || false - [ "$images_minimal_replica2" = "" ] || false + [ "$images_minimal_replica1" = "" ] + [ "$images_minimal_replica2" = "" ] # Import the test image on node1 LXD_DIR="${LXD_ONE_DIR}" ensure_import_testimage @@ -2172,8 +2172,8 @@ test_clustering_image_replication() { # The image tarball is available on both nodes fingerprint=$(LXD_DIR="${LXD_ONE_DIR}" lxc image info testimage | awk '/^Fingerprint/ {print $2}') - [ -f "${LXD_ONE_DIR}/images/${fingerprint}" ] || false - [ -f "${LXD_TWO_DIR}/images/${fingerprint}" ] || false + [ -f "${LXD_ONE_DIR}/images/${fingerprint}" ] + [ -f "${LXD_TWO_DIR}/images/${fingerprint}" ] # Spawn a third node setup_clustering_netns 3 @@ -2214,15 +2214,15 @@ test_clustering_image_replication() { # The image tarball is available on all three nodes fingerprint=$(LXD_DIR="${LXD_ONE_DIR}" lxc image info testimage | awk '/^Fingerprint/ {print $2}') - [ -f "${LXD_ONE_DIR}/images/${fingerprint}" ] || false - [ -f "${LXD_TWO_DIR}/images/${fingerprint}" ] || false - [ -f "${LXD_THREE_DIR}/images/${fingerprint}" ] || false + [ -f "${LXD_ONE_DIR}/images/${fingerprint}" ] + [ -f "${LXD_TWO_DIR}/images/${fingerprint}" ] + [ -f "${LXD_THREE_DIR}/images/${fingerprint}" ] # Delete the imported image LXD_DIR="${LXD_ONE_DIR}" lxc image delete testimage - [ ! -f "${LXD_ONE_DIR}/images/${fingerprint}" ] || false - [ ! -f "${LXD_TWO_DIR}/images/${fingerprint}" ] || false - [ ! -f "${LXD_THREE_DIR}/images/${fingerprint}" ] || false + [ ! -f "${LXD_ONE_DIR}/images/${fingerprint}" ] + [ ! -f "${LXD_TWO_DIR}/images/${fingerprint}" ] + [ ! -f "${LXD_THREE_DIR}/images/${fingerprint}" ] # Import the image from the container LXD_DIR="${LXD_ONE_DIR}" ensure_import_testimage @@ -2234,9 +2234,9 @@ test_clustering_image_replication() { lxc publish c1 --alias new-image fingerprint=$(LXD_DIR="${LXD_ONE_DIR}" lxc image info new-image | awk '/^Fingerprint/ {print $2}') - [ -f "${LXD_ONE_DIR}/images/${fingerprint}" ] || false - [ -f "${LXD_TWO_DIR}/images/${fingerprint}" ] || false - [ -f "${LXD_THREE_DIR}/images/${fingerprint}" ] || false + [ -f "${LXD_ONE_DIR}/images/${fingerprint}" ] + [ -f "${LXD_TWO_DIR}/images/${fingerprint}" ] + [ -f "${LXD_THREE_DIR}/images/${fingerprint}" ] # Delete the imported image LXD_DIR="${LXD_TWO_DIR}" lxc image delete new-image @@ -2270,7 +2270,7 @@ test_clustering_image_replication() { # The image tarball is only available on node2 fingerprint=$(LXD_DIR="${LXD_TWO_DIR}" lxc image info testimage | awk '/^Fingerprint/ {print $2}') - [ -f "${LXD_TWO_DIR}/images/${fingerprint}" ] || false + [ -f "${LXD_TWO_DIR}/images/${fingerprint}" ] [ ! -f "${LXD_ONE_DIR}/images/${fingerprint}" ] || false [ ! -f "${LXD_THREE_DIR}/images/${fingerprint}" ] || false diff --git a/test/suites/container_devices_disk.sh b/test/suites/container_devices_disk.sh index ab1b89f629de..34479d796350 100644 --- a/test/suites/container_devices_disk.sh +++ b/test/suites/container_devices_disk.sh @@ -44,15 +44,15 @@ _container_devices_disk_shift() { lxc start foo lxc config device add foo idmapped_mount disk source="${TEST_DIR}/shift-source" path=/mnt - [ "$(lxc exec foo -- stat /mnt/a -c '%u:%g')" = "65534:65534" ] || false + [ "$(lxc exec foo -- stat /mnt/a -c '%u:%g')" = "65534:65534" ] lxc config device remove foo idmapped_mount lxc config device add foo idmapped_mount disk source="${TEST_DIR}/shift-source" path=/mnt shift=true - [ "$(lxc exec foo -- stat /mnt/a -c '%u:%g')" = "123:456" ] || false + [ "$(lxc exec foo -- stat /mnt/a -c '%u:%g')" = "123:456" ] lxc stop foo -f lxc start foo - [ "$(lxc exec foo -- stat /mnt/a -c '%u:%g')" = "123:456" ] || false + [ "$(lxc exec foo -- stat /mnt/a -c '%u:%g')" = "123:456" ] lxc config device remove foo idmapped_mount lxc stop foo -f @@ -80,10 +80,10 @@ _container_devices_disk_shift() { lxc exec foo -- touch /mnt/a lxc exec foo -- chown 123:456 /mnt/a - [ "$(lxc exec foo -- stat /mnt/a -c '%u:%g')" = "123:456" ] || false - [ "$(lxc exec foo-priv -- stat /mnt/a -c '%u:%g')" = "123:456" ] || false - [ "$(lxc exec foo-isol1 -- stat /mnt/a -c '%u:%g')" = "123:456" ] || false - [ "$(lxc exec foo-isol2 -- stat /mnt/a -c '%u:%g')" = "123:456" ] || false + [ "$(lxc exec foo -- stat /mnt/a -c '%u:%g')" = "123:456" ] + [ "$(lxc exec foo-priv -- stat /mnt/a -c '%u:%g')" = "123:456" ] + [ "$(lxc exec foo-isol1 -- stat /mnt/a -c '%u:%g')" = "123:456" ] + [ "$(lxc exec foo-isol2 -- stat /mnt/a -c '%u:%g')" = "123:456" ] lxc delete -f foo-priv foo-isol1 foo-isol2 lxc config device remove foo shifted @@ -99,19 +99,19 @@ _container_devices_raw_mount_options() { lxc launch testimage foo-priv -c security.privileged=true lxc config device add foo-priv loop_raw_mount_options disk source="${loop_device_1}" path=/mnt - [ "$(lxc exec foo-priv -- stat /mnt -c '%u:%g')" = "0:0" ] || false + [ "$(lxc exec foo-priv -- stat /mnt -c '%u:%g')" = "0:0" ] lxc exec foo-priv -- touch /mnt/foo lxc config device remove foo-priv loop_raw_mount_options lxc config device add foo-priv loop_raw_mount_options disk source="${loop_device_1}" path=/mnt raw.mount.options=uid=123,gid=456,ro - [ "$(lxc exec foo-priv -- stat /mnt -c '%u:%g')" = "123:456" ] || false + [ "$(lxc exec foo-priv -- stat /mnt -c '%u:%g')" = "123:456" ] ! lxc exec foo-priv -- touch /mnt/foo || false lxc config device remove foo-priv loop_raw_mount_options lxc stop foo-priv -f lxc config device add foo-priv loop_raw_mount_options disk source="${loop_device_1}" path=/mnt raw.mount.options=uid=123,gid=456,ro lxc start foo-priv - [ "$(lxc exec foo-priv -- stat /mnt -c '%u:%g')" = "123:456" ] || false + [ "$(lxc exec foo-priv -- stat /mnt -c '%u:%g')" = "123:456" ] ! lxc exec foo-priv -- touch /mnt/foo || false lxc config device remove foo-priv loop_raw_mount_options @@ -163,9 +163,9 @@ _container_devices_disk_cephfs() { _container_devices_disk_socket() { lxc start foo lxc config device add foo unix-socket disk source="${LXD_DIR}/unix.socket" path=/root/lxd.sock - [ "$(lxc exec foo -- stat /root/lxd.sock -c '%F')" = "socket" ] || false + [ "$(lxc exec foo -- stat /root/lxd.sock -c '%F')" = "socket" ] lxc restart -f foo - [ "$(lxc exec foo -- stat /root/lxd.sock -c '%F')" = "socket" ] || false + [ "$(lxc exec foo -- stat /root/lxd.sock -c '%F')" = "socket" ] lxc config device remove foo unix-socket lxc stop foo -f } @@ -173,9 +173,9 @@ _container_devices_disk_socket() { _container_devices_disk_char() { lxc start foo lxc config device add foo char disk source=/dev/zero path=/root/zero - [ "$(lxc exec foo -- stat /root/zero -c '%F')" = "character special file" ] || false + [ "$(lxc exec foo -- stat /root/zero -c '%F')" = "character special file" ] lxc restart -f foo - [ "$(lxc exec foo -- stat /root/zero -c '%F')" = "character special file" ] || false + [ "$(lxc exec foo -- stat /root/zero -c '%F')" = "character special file" ] lxc config device remove foo char lxc stop foo -f } diff --git a/test/suites/container_devices_disk_restricted.sh b/test/suites/container_devices_disk_restricted.sh index 305e6cac7375..e447d4771509 100644 --- a/test/suites/container_devices_disk_restricted.sh +++ b/test/suites/container_devices_disk_restricted.sh @@ -63,7 +63,7 @@ test_container_devices_disk_restricted() { lxc stop -f c1 lxc config device set c1 d1 source="${testRoot}/allowed1/foolink" path=/mnt/foolink lxc start c1 - [ "$(lxc exec c1 --project restricted -- stat /mnt/foolink -c '%u:%g')" = "65534:65534" ] || false + [ "$(lxc exec c1 --project restricted -- stat /mnt/foolink -c '%u:%g')" = "65534:65534" ] lxc stop -f c1 # Check usage of raw.idmap is restricted. @@ -86,12 +86,12 @@ test_container_devices_disk_restricted() { # Check single entry raw.idmap has taken effect on disk share. lxc config device set c1 d1 source="${testRoot}/allowed1" path=/mnt lxc start c1 || (lxc info --show-log c1 ; false) - [ "$(lxc exec c1 --project restricted -- stat /mnt/foo1 -c '%u:%g')" = "1000:1000" ] || false - [ "$(lxc exec c1 --project restricted -- stat /mnt/foo2 -c '%u:%g')" = "65534:65534" ] || false + [ "$(lxc exec c1 --project restricted -- stat /mnt/foo1 -c '%u:%g')" = "1000:1000" ] + [ "$(lxc exec c1 --project restricted -- stat /mnt/foo2 -c '%u:%g')" = "65534:65534" ] # Check adding unix socket is allowed. lxc config device add c1 unix-socket disk source="${testRoot}/allowed1/lxd.sock" path=/root/lxd.sock - [ "$(lxc exec c1 --project restricted -- stat /root/lxd.sock -c '%F')" = "socket" ] || false + [ "$(lxc exec c1 --project restricted -- stat /root/lxd.sock -c '%F')" = "socket" ] lxc delete -f c1 lxc project switch default diff --git a/test/suites/container_devices_nic_routed.sh b/test/suites/container_devices_nic_routed.sh index 1899c7c240c9..d73b4c73f98f 100644 --- a/test/suites/container_devices_nic_routed.sh +++ b/test/suites/container_devices_nic_routed.sh @@ -59,17 +59,10 @@ test_container_devices_nic_routed() { lxc init testimage "${ctName}" # Check vlan option not allowed without parent option. - ! lxc config device add "${ctName}" eth0 nic \ - name=eth0 \ - nictype=routed \ - vlan=1234 || false + ! lxc config device add "${ctName}" eth0 nic name=eth0 nictype=routed vlan=1234 || false # Check VLAN parent interface creation and teardown. - lxc config device add "${ctName}" eth0 nic \ - name=eth0 \ - nictype=routed \ - parent=${ctName} \ - vlan=1235 + lxc config device add "${ctName}" eth0 nic name=eth0 nictype=routed parent=${ctName} vlan=1235 lxc start "${ctName}" stat "/sys/class/net/${ctName}.1235" lxc stop -f "${ctName}" @@ -77,10 +70,7 @@ test_container_devices_nic_routed() { lxc config device remove "${ctName}" eth0 # Add routed NIC to instance. - lxc config device add "${ctName}" eth0 nic \ - name=eth0 \ - nictype=routed \ - parent=${ctName} + lxc config device add "${ctName}" eth0 nic name=eth0 nictype=routed parent=${ctName} # Check starting routed NIC with IPs in use on parent network is prevented. lxc config device set "${ctName}" eth0 ipv4.address="192.0.2.254" @@ -99,21 +89,16 @@ test_container_devices_nic_routed() { lxc config device unset "${ctName}" eth0 ipv6.neighbor_probe # Check starting routed NIC with unused IPs. - lxc config device set "${ctName}" eth0 \ - ipv4.address="192.0.2.1${ipRand}" \ - ipv6.address="2001:db8::1${ipRand}" \ - ipv4.routes="192.0.3.0/24" \ - ipv6.routes="2001:db7::/64" \ - mtu=1600 + lxc config device set "${ctName}" eth0 ipv4.address="192.0.2.1${ipRand}" ipv6.address="2001:db8::1${ipRand}" ipv4.routes="192.0.3.0/24" ipv6.routes="2001:db7::/64" mtu=1600 lxc start "${ctName}" ctHost=$(lxc config get "${ctName}" volatile.eth0.host_name) # Check profile routes are applied - if ! ip -4 r list dev "${ctHost}"| grep "192.0.3.0/24" ; then + if ! ip -4 r list dev "${ctHost}"| grep -F "192.0.3.0/24" ; then echo "ipv4.routes invalid" false fi - if ! ip -6 r list dev "${ctHost}" | grep "2001:db7::/64" ; then + if ! ip -6 r list dev "${ctHost}" | grep -F "2001:db7::/64" ; then echo "ipv6.routes invalid" false fi @@ -122,8 +107,8 @@ test_container_devices_nic_routed() { lxc exec "${ctName}" -- ip a | grep "inet 192.0.2.1${ipRand}/32 scope global eth0" # Check neighbour proxy entries added to parent interface. - ip neigh show proxy dev "${ctName}" | grep "192.0.2.1${ipRand}" - ip neigh show proxy dev "${ctName}" | grep "2001:db8::1${ipRand}" + ip neigh show proxy dev "${ctName}" | grep -F "192.0.2.1${ipRand}" + ip neigh show proxy dev "${ctName}" | grep -F "2001:db8::1${ipRand}" # Check custom MTU is applied. if ! lxc exec "${ctName}" -- ip link show eth0 | grep "mtu 1600" ; then @@ -141,8 +126,8 @@ test_container_devices_nic_routed() { lxc stop "${ctName}" --force # Check neighbour proxy entries removed from parent interface. - ! ip neigh show proxy dev "${ctName}" | grep "192.0.2.1${ipRand}" || false - ! ip neigh show proxy dev "${ctName}" | grep "2001:db8::1${ipRand}" || false + ! ip neigh show proxy dev "${ctName}" | grep -F "192.0.2.1${ipRand}" || false + ! ip neigh show proxy dev "${ctName}" | grep -F "2001:db8::1${ipRand}" || false # Check that MTU is inherited from parent device when not specified on device. ip link set "${ctName}" mtu 1605 @@ -162,16 +147,16 @@ test_container_devices_nic_routed() { parent=${ctName} \ ipv4.address="192.0.2.2${ipRand}, 192.0.2.3${ipRand}" lxc start "${ctName}2" - lxc exec "${ctName}2" -- ip -4 r | grep "169.254.0.1" - ! lxc exec "${ctName}2" -- ip -6 r | grep "fe80::1" || false + lxc exec "${ctName}2" -- ip -4 r | grep -F "169.254.0.1" + ! lxc exec "${ctName}2" -- ip -6 r | grep -F "fe80::1" || false lxc stop -f "${ctName}2" # Check single IPv6 family auto default gateway works. lxc config device unset "${ctName}2" eth0 ipv4.address lxc config device set "${ctName}2" eth0 ipv6.address="2001:db8::2${ipRand}, 2001:db8::3${ipRand}" lxc start "${ctName}2" - ! lxc exec "${ctName}2" -- ip r | grep "169.254.0.1" || false - lxc exec "${ctName}2" -- ip -6 r | grep "fe80::1" + ! lxc exec "${ctName}2" -- ip r | grep -F "169.254.0.1" || false + lxc exec "${ctName}2" -- ip -6 r | grep -F "fe80::1" lxc stop -f "${ctName}2" # Enable both IP families. @@ -214,18 +199,18 @@ test_container_devices_nic_routed() { fi # Check static routes added to custom routing table - ip -4 route show table 100 | grep "192.0.2.1${ipRand}" - ip -6 route show table 101 | grep "2001:db8::1${ipRand}" + ip -4 route show table 100 | grep -F "192.0.2.1${ipRand}" + ip -6 route show table 101 | grep -F "2001:db8::1${ipRand}" # Check volatile cleanup on stop. lxc stop -f "${ctName}" - if lxc config show "${ctName}" | grep volatile.eth0 | grep -v volatile.eth0.hwaddr | grep -v volatile.eth0.name ; then + if [ "$(lxc config show "${ctName}" | grep -F volatile.eth0 | grep -vF volatile.eth0.hwaddr | grep -vF volatile.eth0.name)" != "" ]; then echo "unexpected volatile key remains" false fi # Check parent device is still up. - if ! grep "1" "/sys/class/net/${ctName}/carrier" ; then + if [ "$(cat /sys/class/net/${ctName}/carrier)" != "1" ]; then echo "parent is down" false fi diff --git a/test/suites/devlxd.sh b/test/suites/devlxd.sh index 4d90c0a41a3a..b4fe1b248a48 100644 --- a/test/suites/devlxd.sh +++ b/test/suites/devlxd.sh @@ -154,5 +154,5 @@ EOF lxc delete devlxd --force kill -9 ${monitorDevlxdPID} || true - [ "${MATCH}" = "1" ] || false + [ "${MATCH}" = "1" ] } diff --git a/test/suites/filtering.sh b/test/suites/filtering.sh index d011d1993fe5..9579d495b719 100644 --- a/test/suites/filtering.sh +++ b/test/suites/filtering.sh @@ -16,20 +16,15 @@ test_filtering() { lxc init testimage c1 lxc init testimage c2 - count=$(curl -G --unix-socket "$LXD_DIR/unix.socket" "lxd/1.0/instances" --data-urlencode "recursion=0" --data-urlencode "filter=name eq c1" | jq ".metadata | length") - [ "${count}" = "1" ] || false + [ "$(curl -G --unix-socket "$LXD_DIR/unix.socket" "lxd/1.0/instances" --data-urlencode "recursion=0" --data-urlencode "filter=name eq c1" | jq ".metadata | length")" = "1" ] - count=$(curl -G --unix-socket "$LXD_DIR/unix.socket" "lxd/1.0/instances" --data-urlencode "recursion=1" --data-urlencode "filter=name eq c1" | jq ".metadata | length") - [ "${count}" = "1" ] || false + [ "$(curl -G --unix-socket "$LXD_DIR/unix.socket" "lxd/1.0/instances" --data-urlencode "recursion=1" --data-urlencode "filter=name eq c1" | jq ".metadata | length")" = "1" ] - count=$(curl -G --unix-socket "$LXD_DIR/unix.socket" "lxd/1.0/instances" --data-urlencode "recursion=2" --data-urlencode "filter=name eq c1" | jq ".metadata | length") - [ "${count}" = "1" ] || false + [ "$(curl -G --unix-socket "$LXD_DIR/unix.socket" "lxd/1.0/instances" --data-urlencode "recursion=2" --data-urlencode "filter=name eq c1" | jq ".metadata | length")" = "1" ] - count=$(curl -G --unix-socket "$LXD_DIR/unix.socket" "lxd/1.0/images" --data-urlencode "recursion=0" --data-urlencode "filter=properties.os eq BusyBox" | jq ".metadata | length") - [ "${count}" = "1" ] || false + [ "$(curl -G --unix-socket "$LXD_DIR/unix.socket" "lxd/1.0/images" --data-urlencode "recursion=0" --data-urlencode "filter=properties.os eq BusyBox" | jq ".metadata | length")" = "1" ] - count=$(curl -G --unix-socket "$LXD_DIR/unix.socket" "lxd/1.0/images" --data-urlencode "recursion=1" --data-urlencode "filter=properties.os eq Ubuntu" | jq ".metadata | length") - [ "${count}" = "0" ] || false + [ "$(curl -G --unix-socket "$LXD_DIR/unix.socket" "lxd/1.0/images" --data-urlencode "recursion=1" --data-urlencode "filter=properties.os eq Ubuntu" | jq ".metadata | length")" = "0" ] lxc delete c1 lxc delete c2 diff --git a/test/suites/image_profiles.sh b/test/suites/image_profiles.sh index a86dc18f2f81..e914291d5a61 100644 --- a/test/suites/image_profiles.sh +++ b/test/suites/image_profiles.sh @@ -2,7 +2,7 @@ _image_nil_profile_list() { # Launch container with default profile list and check its profiles ensure_import_testimage lxc launch testimage c1 - lxc list -f json c1 | jq -r '.[0].profiles | join(" ")' | grep -q "default" || false + [ "$(lxc list -f json c1 | jq -r '.[0].profiles | join(" ")')" = "default" ] # Cleanup lxc delete c1 -f @@ -15,13 +15,13 @@ _image_empty_profile_list() { lxc image show testimage | sed "s/profiles.*/profiles: []/; s/- default//" | lxc image edit testimage # Check that the profile list is correct - lxc image show testimage | grep -q 'profiles: \[\]' || false + lxc image show testimage | grep -qF 'profiles: []' ! lxc image show testimage | grep -q -- '- default' || false # Launch the container and check its profiles storage=$(lxc storage list | grep "^| " | tail -n 1 | cut -d' ' -f2) lxc launch testimage c1 -s "$storage" - lxc list -f json c1 | jq -r '.[0].profiles | join(" ")' | grep -q "^$" || false + [ "$(lxc list -f json c1 | jq -r '.[0].profiles | join(" ")')" = "" ] # Cleanup lxc delete c1 -f @@ -37,16 +37,16 @@ _image_alternate_profile_list() { lxc image show testimage | sed "s/profiles.*/profiles: ['p1','p2','p3']/; s/- default//" | lxc image edit testimage # Check that the profile list is correct - lxc image show testimage | grep -q -- '- p1' || false - lxc image show testimage | grep -q -- '- p2' || false - lxc image show testimage | grep -q -- '- p3' || false + lxc image show testimage | grep -q -- '- p1' + lxc image show testimage | grep -q -- '- p2' + lxc image show testimage | grep -q -- '- p3' ! lxc image show testimage | grep -q -- '- default' || false # Launch the container and check its profiles storage=$(lxc storage list | grep "^| " | tail -n 1 | cut -d' ' -f2) lxc profile device add p1 root disk path=/ pool="$storage" lxc launch testimage c1 - lxc list -f json c1 | jq -r '.[0].profiles | join(" ")' | grep -q "p1 p2 p3" || false + [ "$(lxc list -f json c1 | jq -r '.[0].profiles | join(" ")')" = "p1 p2 p3" ] # Cleanup lxc delete c1 -f diff --git a/test/suites/projects.sh b/test/suites/projects.sh index 99f5f3bff7a5..5212e379261a 100644 --- a/test/suites/projects.sh +++ b/test/suites/projects.sh @@ -1045,7 +1045,7 @@ test_projects_restrictions() { # Setting restricted.containers.lowlevel to 'allow' makes it possible to set # low-level options. lxc project set p1 restricted.containers.lowlevel=allow - lxc init testimage c1 -c "raw.idmap=both 0 0" || false + lxc init testimage c1 -c "raw.idmap=both 0 0" # It's not possible to set restricted.containers.lowlevel back to 'block', # because there's an instance with raw.idmap set. diff --git a/test/suites/snapshots.sh b/test/suites/snapshots.sh index c41449eb7a16..956ca3451ad1 100644 --- a/test/suites/snapshots.sh +++ b/test/suites/snapshots.sh @@ -360,16 +360,20 @@ test_snap_expiry() { lxc launch testimage c1 lxc snapshot c1 lxc config show c1/snap0 | grep -q 'expires_at: 0001-01-01T00:00:00Z' + [ "$(lxc config get --property c1/snap0 expires_at)" = "0001-01-01 00:00:00 +0000 UTC" ] lxc config set c1 snapshots.expiry '1d' lxc snapshot c1 ! lxc config show c1/snap1 | grep -q 'expires_at: 0001-01-01T00:00:00Z' || false + [ "$(lxc config get --property c1/snap1 expires_at)" != "0001-01-01 00:00:00 +0000 UTC" ] lxc copy c1 c2 ! lxc config show c2/snap1 | grep -q 'expires_at: 0001-01-01T00:00:00Z' || false + [ "$(lxc config get --property c2/snap1 expires_at)" != "0001-01-01 00:00:00 +0000 UTC" ] lxc snapshot c1 --no-expiry - lxc config show c1/snap2 | grep -q 'expires_at: 0001-01-01T00:00:00Z' || false + lxc config show c1/snap2 | grep -q 'expires_at: 0001-01-01T00:00:00Z' + [ "$(lxc config get --property c1/snap2 expires_at)" = "0001-01-01 00:00:00 +0000 UTC" ] lxc rm -f c1 lxc rm -f c2 diff --git a/test/suites/sql.sh b/test/suites/sql.sh index e8efc76ecd7f..12fce267c17b 100644 --- a/test/suites/sql.sh +++ b/test/suites/sql.sh @@ -35,8 +35,8 @@ test_sql() { # Local database schema dump SQLITE_DUMP="${TEST_DIR}/dump.db" lxd sql local .schema | sqlite3 "${SQLITE_DUMP}" - [ "$(sqlite3 "${SQLITE_DUMP}" 'SELECT * FROM schema' | wc -l)" = "0" ] - [ "$(sqlite3 "${SQLITE_DUMP}" 'SELECT * FROM patches' | wc -l)" = "0" ] + [ "$(sqlite3 "${SQLITE_DUMP}" 'SELECT * FROM schema')" = "" ] + [ "$(sqlite3 "${SQLITE_DUMP}" 'SELECT * FROM patches')" = "" ] rm -f "${SQLITE_DUMP}" # Global database dump @@ -52,8 +52,8 @@ test_sql() { # Global database schema dump SQLITE_DUMP="${TEST_DIR}/dump.db" lxd sql global .schema | sqlite3 "${SQLITE_DUMP}" - [ "$(sqlite3 "${SQLITE_DUMP}" 'SELECT * FROM schema' | wc -l)" = "0" ] - [ "$(sqlite3 "${SQLITE_DUMP}" 'SELECT * FROM profiles' | wc -l)" = "0" ] + [ "$(sqlite3 "${SQLITE_DUMP}" 'SELECT * FROM schema')" = "" ] + [ "$(sqlite3 "${SQLITE_DUMP}" 'SELECT * FROM profiles')" = "" ] rm -f "${SQLITE_DUMP}" # Sync the global database to disk diff --git a/test/suites/storage_snapshots.sh b/test/suites/storage_snapshots.sh index 28a19b4adccc..528af0df32d2 100644 --- a/test/suites/storage_snapshots.sh +++ b/test/suites/storage_snapshots.sh @@ -41,7 +41,16 @@ expires_at: ${expiry_date_in_one_minute} EOF # Check that the expiry date is set correctly lxc storage volume show "${storage_pool}" "${storage_volume}/yaml_volume_snapshot" | grep "expires_at: ${expiry_date_in_one_minute}" - lxc storage volume show "${storage_pool}" "${storage_volume}/yaml_volume_snapshot" | grep "description: foodesc" + + # Dates are formatted differently between `show` and `get --property` + property_expiry_date_in_one_minute="$(date -u -d "${expiry_date_in_one_minute}" '+%Y-%m-%d %H:%M:%S %z %Z')" + [ "$(lxc storage volume get --property "${storage_pool}" "${storage_volume}/yaml_volume_snapshot" expires_at)" = "${property_expiry_date_in_one_minute}" ] + + # Check that the description property can be set/get correctly + [ "$(lxc storage volume get --property "${storage_pool}" "${storage_volume}/yaml_volume_snapshot" description)" = "foodesc" ] + lxc storage volume set --property "${storage_pool}" "${storage_volume}/yaml_volume_snapshot" description="bardesc" + [ "$(lxc storage volume get --property "${storage_pool}" "${storage_volume}/yaml_volume_snapshot" description)" = "bardesc" ] + # Delete the snapshot lxc storage volume delete "${storage_pool}" "${storage_volume}/yaml_volume_snapshot" @@ -83,7 +92,7 @@ EOF ! lxc storage volume show "${storage_pool}" "${storage_volume}/snap1" | grep -q 'expires_at: 0001-01-01T00:00:00Z' || false lxc storage volume snapshot "${storage_pool}" "${storage_volume}" --no-expiry - lxc storage volume show "${storage_pool}" "${storage_volume}/snap2" | grep -q 'expires_at: 0001-01-01T00:00:00Z' || false + lxc storage volume show "${storage_pool}" "${storage_volume}/snap2" | grep -q 'expires_at: 0001-01-01T00:00:00Z' lxc storage volume rm "${storage_pool}" "${storage_volume}/snap2" lxc storage volume rm "${storage_pool}" "${storage_volume}/snap1" diff --git a/test/suites/warnings.sh b/test/suites/warnings.sh index 210e116fc9fd..2b090dd87995 100644 --- a/test/suites/warnings.sh +++ b/test/suites/warnings.sh @@ -12,11 +12,9 @@ test_warnings() { lxc query --wait -X POST -d '{\"type_code\": 0, \"message\": \"global warning 2\", \"project\": \"default\"}' /internal/testing/warnings # There should be two warnings now. - count=$(lxc query --wait /1.0/warnings | jq 'length') - [ "${count}" -eq 2 ] || false + [ "$(lxc query --wait /1.0/warnings | jq 'length')" = "2" ] - count=$(lxc query --wait /1.0/warnings\?recursion=1 | jq 'length') - [ "${count}" -eq 2 ] || false + [ "$(lxc query --wait /1.0/warnings\?recursion=1 | jq 'length')" = "2" ] # Invalid query (unknown project) ! lxc query --wait -X POST -d '{\"type_code\": 0, \"message\": \"global warning\", \"project\": \"foo\"}' /internal/testing/warnings || false @@ -36,27 +34,22 @@ test_warnings() { lxc query --wait -X POST -d "{\\\"type_code\\\": 0, \\\"message\\\": \\\"global warning\\\", \\\"entity_type\\\": \\\"image\\\", \\\"entity_id\\\": ${image_id}}" /internal/testing/warnings # There should be three warnings now. - count=$(lxc warning list --format json | jq 'length') - [ "${count}" -eq 3 ] || false + [ "$(lxc warning list --format json | jq 'length')" = "3" ] # Test filtering - count=$(curl -G --unix-socket "$LXD_DIR/unix.socket" "lxd/1.0/warnings" --data-urlencode "recursion=0" --data-urlencode "filter=status eq new" | jq ".metadata | length") - [ "${count}" -eq 3 ] || false + [ "$(curl -G --unix-socket "$LXD_DIR/unix.socket" "lxd/1.0/warnings" --data-urlencode "recursion=0" --data-urlencode "filter=status eq new" | jq ".metadata | length")" = "3" ] - count=$(curl -G --unix-socket "$LXD_DIR/unix.socket" "lxd/1.0/warnings" --data-urlencode "recursion=0" --data-urlencode "filter=status eq resolved" | jq ".metadata | length") - [ "${count}" -eq 0 ] || false + [ "$(curl -G --unix-socket "$LXD_DIR/unix.socket" "lxd/1.0/warnings" --data-urlencode "recursion=0" --data-urlencode "filter=status eq resolved" | jq ".metadata | length")" = "0" ] # Acknowledge a warning uuid=$(lxc warning list --format json | jq -r '.[] | select(.last_message=="global warning 2") | .uuid') lxc warning ack "${uuid}" # This should hide the acknowledged - count=$(lxc warning list --format json | jq 'length') - [ "${count}" -eq 2 ] || false + [ "$(lxc warning list --format json | jq 'length')" = "2" ] # ... unless one uses --all. - count=$(lxc warning list --all --format json | jq 'length') - [ "${count}" -eq 3 ] || false + [ "$(lxc warning list --all --format json | jq 'length')" = "3" ] lxc warning show "${uuid}" | grep "global warning 2"