diff --git a/.do-not-sync-with-fedora b/.do-not-sync-with-fedora new file mode 100644 index 0000000..e69de29 diff --git a/.gitignore b/.gitignore index 0e7884d..8ef6948 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,101 @@ -SOURCES/LVM2.2.03.14.tgz +/LVM2.2.02.90.tgz +/LVM2.2.02.91.tgz +/LVM2.2.02.92.tgz +/LVM2.2.02.93.tgz +/LVM2.2.02.94.tgz +/LVM2.2.02.95.tgz +/LVM2.2.02.96.tgz +/LVM2.2.02.97.tgz +/LVM2.2.02.98.tgz +/LVM2.2.02.99.tgz +/LVM2.2.02.102.tgz +/LVM2.2.02.103.tgz +/LVM2.2.02.104.tgz +/LVM2.2.02.105.tgz +/LVM2.2.02.106.tgz +/LVM2.2.02.107.tgz +/LVM2.2.02.108.tgz +/LVM2.2.02.109.tgz +/LVM2.2.02.110.tgz +/LVM2.2.02.111.tgz +/LVM2.2.02.112.tgz +/LVM2.2.02.113.tgz +/LVM2.2.02.114.tgz +/LVM2.2.02.115.tgz +/LVM2.2.02.116.tgz +/LVM2.2.02.118.tgz +/LVM2.2.02.119.tgz +/LVM2.2.02.120.tgz +/LVM2.2.02.122.tgz +/LVM2.2.02.123.tgz +/LVM2.2.02.124.tgz +/LVM2.2.02.125.tgz +/LVM2.2.02.126.tgz +/LVM2.2.02.127.tgz +/LVM2.2.02.128.tgz +/LVM2.2.02.129.tgz +/LVM2.2.02.130.tgz +/LVM2.2.02.131.tgz +/LVM2.2.02.132.tgz +/LVM2.2.02.133.tgz +/LVM2.2.02.134.tgz +/LVM2.2.02.135.tgz +/LVM2.2.02.136.tgz +/LVM2.2.02.137.tgz +/LVM2.2.02.138.tgz +/LVM2.2.02.139.tgz +/LVM2.2.02.140.tgz +/LVM2.2.02.141.tgz +/LVM2.2.02.142.tgz +/LVM2.2.02.143.tgz +/LVM2.2.02.144.tgz +/LVM2.2.02.145.tgz +/LVM2.2.02.146.tgz +/LVM2.2.02.147.tgz +/LVM2.2.02.148.tgz +/LVM2.2.02.149.tgz +/LVM2.2.02.150.tgz +/LVM2.2.02.151.tgz +/LVM2.2.02.152.tgz +/LVM2.2.02.153.tgz +/LVM2.2.02.154.tgz +/LVM2.2.02.155.tgz +/LVM2.2.02.156.tgz +/LVM2.2.02.157.tgz +/LVM2.2.02.158.tgz +/LVM2.2.02.159.tgz +/LVM2.2.02.160.tgz +/LVM2.2.02.161.tgz +/LVM2.2.02.162.tgz +/LVM2.2.02.163.tgz +/LVM2.2.02.164.tgz +/LVM2.2.02.165.tgz +/LVM2.2.02.166.tgz +/LVM2.2.02.167.tgz +/LVM2.2.02.168.tgz +/LVM2.2.02.171.tgz +/LVM2.2.02.172.tgz +/LVM2.2.02.173.tgz +/LVM2.2.02.174.tgz +/LVM2.2.02.175.tgz +/LVM2.2.02.176.tgz +/LVM2.2.02.177.tgz +/LVM2.2.02.179.tgz +/LVM2.2.02.180.tgz +/LVM2.2.02.181.tgz +/LVM2.2.03.00.tgz +/LVM2.2.03.01.tgz +/LVM2.2.03.02.tgz +/LVM2.2.03.04.tgz +/LVM2.2.03.05.tgz +/LVM2.2.03.06.tgz +/LVM2.2.03.07.tgz +/LVM2.2.03.08.tgz +/LVM2.2.03.09.tgz +/lvm2-8801a86.tar.gz +/lvm2-9fe7aba.tar.gz +/lvm2-b84a992.tar.gz +/LVM2.2.03.11.tgz +/lvm2-4dc5d4a.tgz +/LVM2.2.03.12.tgz /LVM2.2.03.14.tgz diff --git a/0016-spec-Add-lvmautoactivation-man-page.patch b/0016-spec-Add-lvmautoactivation-man-page.patch new file mode 100644 index 0000000..e69de29 diff --git a/LVM2.2.03.14.tgz.asc b/LVM2.2.03.14.tgz.asc new file mode 100644 index 0000000..8cb8ceb --- /dev/null +++ b/LVM2.2.03.14.tgz.asc @@ -0,0 +1,17 @@ +-----BEGIN PGP SIGNATURE----- +Version: GnuPG v2.0.22 (GNU/Linux) + +iQIcBAABAgAGBQJhb+6rAAoJELkRJDHlCQOfBO4P/3d0ccQfFany0wbXfYRuS+1G +HYc0S5LPyhhhTIKRGpBOCEGnSwPlUxcP6mnxhwfrcDOYLl4z9Pj1NGnaYoQxpCHw +fQ4Lzzr6Fdt5TFIkGiVSbQynh/ybyOxfTuD5fMzWmEKrJ1ZNhTv0sDOqPoqLrS8o +W4C573IW9BEGN7CeHTcbcdpnUwt4GGsbsR2S5fGdKUo0Jw/PTY67wiCCTM0F92Qp +S3fkPQ+GWagXTTecrX5MeFjMrQIk3cOMBDvxccHMthzDEyjNtGoOJfmZV66eMzs2 +XDW0r6t/h5tX535QOWEjqazYavfUcTQn99+0X4dwbVxVa9h1baKo9bhOM4k7PyOx +XUXDiZYVvsCP/W+Sr69rxOSbzhClg3Y/8riw5Ttf2ygXdUgI7ce0Rnc8irslJCwJ +PyYKFMDxHDaor4LbRJL3ZpaWopoARkRKGJYMsU8VOHDPf0cIfN1JdbOiatqj5CQz +DfCKWzxqz88ZM8GyHxSHZ6bRtEOM6RtCiIONn66AgMHxObKxZ3604BFvv2jaJiVt +MvditBmlvjYaPjNjomSwxgdhs5gkbERJH7kkXgB8RNR2UIPNZhcTSd1xLrkeRpP2 +jt7kUR0NR4lab8qal8paIyQLSrcBTsngAI9EYxIgwN1gLcUWfxDJOOJt4tyrqy5v +qcvHOjD884RQSdTYXfe0 +=VTpu +-----END PGP SIGNATURE----- diff --git a/lvm2-make-generate.patch b/lvm2-make-generate.patch new file mode 100644 index 0000000..0b37216 --- /dev/null +++ b/lvm2-make-generate.patch @@ -0,0 +1,146 @@ + man/lvconvert.8_pregen | 2 +- + man/lvmdevices.8_pregen | 79 ++++++++++++++++++++++++++++++++++++++++--------- + 2 files changed, 66 insertions(+), 15 deletions(-) + +diff --git a/man/lvconvert.8_pregen b/man/lvconvert.8_pregen +index d733ab6..4fafe5d 100644 +--- a/man/lvconvert.8_pregen ++++ b/man/lvconvert.8_pregen +@@ -670,7 +670,7 @@ Convert LV to type thin-pool. + .RE + .P + .RS 4 +-LV1 types: linear striped cache raid error zero ++LV1 types: linear striped cache raid error zero writecache + .RE + .P + \(em +diff --git a/man/lvmdevices.8_pregen b/man/lvmdevices.8_pregen +index 267ce96..fa85362 100644 +--- a/man/lvmdevices.8_pregen ++++ b/man/lvmdevices.8_pregen +@@ -28,6 +28,8 @@ lvmdevices \(em Manage the devices file + .br + \fB--delpvid\fP \fIString\fP + .br ++ \fB--deviceidtype\fP \fIString\fP ++.br + \fB--devices\fP \fIPV\fP + .br + \fB--devicesfile\fP \fIString\fP +@@ -70,18 +72,18 @@ remove it from the devices file with lvmdevices --deldev. The + vgimportdevices(8) command adds all PVs from a VG to the devices file, + and updates the VG metadata to include device IDs of the PVs. + .P +-Commands adding new devices to the devices file necessarily look outside +-the existing devices file to find the devices to add. pvcreate, vgcreate, +-and vgextend also look outside the devices file to create new PVs and add +-them to the devices file. ++Commands that add new devices to the devices file necessarily look outside ++the existing devices file to find the devices being added. pvcreate, ++vgcreate, and vgextend also look outside the devices file to create new ++PVs and add those PVs to the devices file. + .P + LVM records devices in the devices file using hardware-specific IDs, such + as the WWID, and attempts to use subsystem-specific IDs for virtual device +-types (which also aim to be as unique and stable as possible.) +-These device IDs are also written in the VG metadata. When no hardware or ++types (which also aim to be as unique and stable as possible.) These ++device IDs are also written in the VG metadata. When no hardware or + virtual ID is available, lvm falls back using the unstable device name as +-the device ID. When devnames are used, lvm performs extra scanning to +-find devices if their devname changes, e.g. after reboot. ++the device ID. When devnames are used as IDs, lvm performs extra scanning ++to find devices if their devname changes, e.g. after reboot. + .P + When proper device IDs are used, an lvm command will not look at devices + outside the devices file, but when devnames are used as a fallback, lvm +@@ -95,12 +97,13 @@ overriding the devices file. The listed devices act as a sort of devices + file in terms of limiting which devices lvm will see and use. Devices + that are not listed will appear to be missing to the lvm command. + .P +-Multiple devices files can be kept in \fI#DEFAULT_SYS_DIR#/devices\fP, which allows lvm +-to be used with different sets of devices, e.g. system devices do not need +-to be exposed to a specific application, and the application can use lvm on +-its own devices that are not exposed to the system. The option +---devicesfile is used to select the devices file to use with the +-command. Without the option set, the default system devices file is used. ++Multiple devices files can be kept \fI#DEFAULT_SYS_DIR#/devices\fP, which ++allows lvm to be used with different sets of devices. For example, system ++devices do not need to be exposed to a specific application, and the ++application can use lvm on its own devices that are not exposed to the ++system. The option --devicesfile is used to select the devices ++file to use with the command. Without the option set, the default system ++devices file is used. + .P + Setting --devicesfile "" causes lvm to not use a devices file. + .P +@@ -120,6 +123,45 @@ if it does not yet exist. + .P + It is recommended to use lvm commands to make changes to the devices file to + ensure proper updates. ++.P ++The device ID and device ID type are included in the VG metadata and can ++be reported with pvs -o deviceid,deviceidtype. (Note that the lvmdevices ++command does not update VG metadata, but subsequent lvm commands modifying ++the metadata will include the device ID.) ++.P ++Possible device ID types are: ++.br ++.IP \[bu] 2 ++.B sys_wwid ++uses the wwid reported by sysfs. This is the first choice for non-virtual ++devices. ++.IP \[bu] 2 ++.B sys_serial ++uses the serial number reported by sysfs. This is the second choice for ++non-virtual devices. ++.IP \[bu] 2 ++.B mpath_uuid ++is used for dm multipath devices, reported by sysfs. ++.IP \[bu] 2 ++.B crypt_uuid ++is used for dm crypt devices, reported by sysfs. ++.IP \[bu] 2 ++.B md_uuid ++is used for md devices, reported by sysfs. ++.B lvmlv_uuid ++is used if a PV is placed on top of an lvm LV, reported by sysfs. ++.IP \[bu] 2 ++.B loop_file ++is used for loop devices, the backing file name repored by sysfs. ++.IP \[bu] 2 ++.B devname ++the device name is used if no other type applies. ++.P ++ ++The default choice for device ID type can be overriden using lvmdevices ++--addev --deviceidtype . If the specified type is available for the ++device it will be used, otherwise the device will be added using the type ++that would otherwise be chosen. + . + .SH USAGE + . +@@ -169,6 +211,8 @@ Add a device to the devices file. + .br + .RS 4 + .ad l ++[ \fB--deviceidtype\fP \fIString\fP ] ++.br + [ COMMON_OPTIONS ] + .ad b + .RE +@@ -308,6 +352,13 @@ Remove a device from the devices file. + Remove a device with the PVID from the devices file. + . + .HP ++\fB--deviceidtype\fP \fIString\fP ++.br ++The type of device ID to use for the device. ++If the specified type is available for the device, ++then it will override the default type that lvm would use. ++. ++.HP + \fB--devices\fP \fIPV\fP + .br + Devices that the command can use. This option can be repeated diff --git a/mirrors b/mirrors new file mode 100644 index 0000000..23553ce --- /dev/null +++ b/mirrors @@ -0,0 +1 @@ +ftp://sources.redhat.com/pub/lvm2/ diff --git a/tests/.fmf/version b/tests/.fmf/version new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/tests/.fmf/version @@ -0,0 +1 @@ +1 diff --git a/tests/collect_output.sh b/tests/collect_output.sh new file mode 100644 index 0000000..a9a2a67 --- /dev/null +++ b/tests/collect_output.sh @@ -0,0 +1,63 @@ +#!/bin/bash + +set -xv + +DIR="$1" +LIST="$2" + +[[ -n "$DIR" ]] || { + echo "ERROR: Missing DIR" >&2 + exit 1 +} + +cd "$DIR" + +# TODO: use find and xargs (?) + +passed_logs() { + grep '\(passed\|skipped\|warnings\)$' list | sed 's|/|_|' | sed 's| .*|.txt|' +} + +# Remove log file if the test succeeded (we are generating tons of logs) +echo "Removing output of passed tests..." +#passed_logs + +for f in $(passed_logs); do + #echo " $f" + rm -f "$f" +done + +# rm -f $(passed_logs) + +if [[ -n "$LIST" ]]; then + cat list >> "$LIST" +fi + +# Remove empty files and compress the rest: +for f in *.txt; do + if [[ -s "$f" ]]; then + echo "Compressing file '$f'..." + ls -l "$f" + gzip "$f" + ls -l "$f.gz" + else + echo "Removing empty file '$f'" + ls -l "$f" + rm -f "$f" + fi +done + +for f in *.gz; do +if [[ -f "$f" ]]; then + + # Use tar so we do not transfer dozens of small files: + tar cvf "logfiles.tar" *.gz + + # Clean up: + rm -f *.gz + +exit 1 + +fi +done + diff --git a/tests/get_lvm2_tarball.sh b/tests/get_lvm2_tarball.sh new file mode 100644 index 0000000..bcd14bc --- /dev/null +++ b/tests/get_lvm2_tarball.sh @@ -0,0 +1,30 @@ +#!/usr/bin/sh + +set -e + +PKG=$1 + +[[ "$PKG" == lvm2 ]] + +CHECK=false + +cat sources | \ + while read SHA512_HEADER TARBALL EQUAL HASH; do + if [[ "$SHA512_HEADER" == SHA512 ]]; then + TARBALL=$(echo $TARBALL |sed 's/.\(.*\)./\1/') + CHECK="sha512sum" + else + HASH="$SHA512_HEADER" + CHECK="md5sum" + fi + if [[ -f "$TARBALL" ]] && "$CHECK" -c sources; then + echo "File already downloaded and verified" + else + URL="https://sourceware.org/pub/$PKG/releases/$TARBALL" + echo "Fetching '$URL'..." + curl -k -o "$TARBALL" "$URL" + echo "Checking hash of '$TARBALL'..." + "$CHECK" -c sources + fi + done + diff --git a/tests/get_sources.sh b/tests/get_sources.sh new file mode 100644 index 0000000..95ce92b --- /dev/null +++ b/tests/get_sources.sh @@ -0,0 +1,15 @@ +#!/usr/bin/sh + +set -e + +PKG=$1 + +cat sources | \ + while read SHA512_HEADER TARBALL EQUAL HASH; do + if [[ "$SHA512_HEADER" == SHA512 ]]; then + TARBALL=$(echo $TARBALL |sed 's/.\(.*\)./\1/') + curl -k -o $TARBALL https://pkgs.devel.redhat.com/repo//rpms/$PKG/$TARBALL/sha512/$HASH/$TARBALL + else + exit 1 + fi + done diff --git a/tests/mock_build_and_test.sh b/tests/mock_build_and_test.sh new file mode 100644 index 0000000..30eb7ab --- /dev/null +++ b/tests/mock_build_and_test.sh @@ -0,0 +1,85 @@ +#!/bin/bash + +set -e +set -xv + +# TODO: Use the role! +dnf install -y mock + +# lsblk and blkid: +dnf install -y util-linux + +# rpmbuild and rpmdev-setuptree +dnf install -y rpmdevtools rpm-build + +# mock: +dnf install -y mock + +# gather info about the system and environment: +set + +pwd +ls -al + +uname -a + +rpm -qa | grep -F lvm2 | : +rpm -qa | grep -F device-mapper | : + +which lsblk | : +lsblk | : +which blkid | : +blkid | : + +find / -name lvm2.spec + +# NOTE: The following does not work - it will download src.rpm from default repo, not the one under test... +################################################################################# +## compile the test suite - using rpmbuild and mock +################################################################################# +#rpmdev-setuptree +# +#dnf download --source lvm2 +#rpm -ivh lvm2*.src.rpm +# +#find / -name '*.patch' +#exit 0 +##rpmbuild -bs + +################################################################################ +# compile the test suite - using mock +################################################################################ +if [[ -f lvm2.spec ]]; then + +mock_profile() { +( + ID= + VERSION_ID= + source /etc/os-release "" + [[ -n "$ID" && -n "$VERSION_ID" ]] || exit 1 + echo "${ID}-${VERSION_ID}-$(arch)" +) +} + +MOCK_PROFILE="$(mock_profile)" + +rm -rf "/var/lib/mock/$MOCK_PROFILE/result/" + +#mock -r "$MOCK_PROFILE" --init +#mock -r "$MOCK_PROFILE" --installdeps lvm2.spec +# FIXME: /var/str is controlled by tenv_workdir ansible variable - need an env.variable! +#mock -r "$MOCK_PROFILE" --buildsrpm --no-clean --spec lvm2.spec --sources "/var/str/source" --short-circuit=build +#ls -l + +find / -name 'lvm2*.src.rpm' +mock -r "$MOCK_PROFILE" --rebuild --no-clean ~/rpmbuild/SRPMS/lvm2*.src.rpm + +find / -name 'lvm2-2*.rpm' + +[[ -n $(find / -name 'lvm2-testsuite-2*.rpm') ]] + +ls -l +#dnf install -y ~/rpmbuild/RPMS/lvm2-testsuite-*.rpm +dnf install -y /var/lib/mock/"$MOCK_PROFILE"/result/lvm2-testsuite-2*.rpm +fi + diff --git a/tests/provision.fmf b/tests/provision.fmf new file mode 100644 index 0000000..c1b5de8 --- /dev/null +++ b/tests/provision.fmf @@ -0,0 +1,6 @@ +--- +# lvm2 testsuite requires at least 2G of RAM to run smoothly in /dev/shm +standard-inventory-qcow2: + qemu: + m: 3G + diff --git a/tests/refresh.sh b/tests/refresh.sh new file mode 100644 index 0000000..4358618 --- /dev/null +++ b/tests/refresh.sh @@ -0,0 +1,16 @@ +#!/bin/bash + +refresh_dirs() { + local dir= + while [[ -n "$*" ]]; do + if [[ -d "$1" ]]; then + rm -rf "$1" + fi + mkdir -p "$(dirname "$1")" + mkdir "$1" + shift + done +} + +refresh_dirs ~/rpmbuild/SRPMS ~/rpmbuild/RPMS +refresh_dirs /tmp/source diff --git a/tests/run_tests.yml b/tests/run_tests.yml new file mode 100644 index 0000000..c3af9b6 --- /dev/null +++ b/tests/run_tests.yml @@ -0,0 +1,77 @@ +--- +- name: Echo test header + shell: | + MSG="Running test case {{ test_case }}" + echo "*** $MSG ***" >/dev/console + logger -p user.notify "$MSG" + true + +- name: Create artifacts directory + file: + state: directory + path: "{{ remote_artifacts }}/{{ test_case }}" + +- name: Run the testsuite + # lvm2-testsuite --batch --flavours "{{ flavours.stdout_lines|join(',')}}" --only "{{ run_tests|default([])|join(',') }}" --skip "{{ skip_tests|default([])|join(',') }}" 2>&1 | tee "lvm2-testsuite.out" + shell: | + # Run testsuite in RAM disk: + mkdir -p /dev/shm/lvm2-slave + export LVM_TEST_DIR=/dev/shm/lvm2-slave + mount -o remount,dev /dev/shm + # Protection against some of our non-deterministic tests + # TODO: Add diff for each test run, so it is easier to tell whether test is broken, or there is an issue + RESULT=1 + ITERATION=0 + while [[ "$RESULT" -ne 0 && "$ITERATION" -lt {{ iterations|default(3) }} ]]; do + let ITERATION++ + mkdir "$ITERATION" + cd "$ITERATION" + echo "Running iteration $ITERATION..." + lvm2-testsuite --batch --flavours "{{ flavours.stdout_lines|join(',')}}" --only "{{ test_case }}" 2>&1 | tee "lvm2-testsuite.out" + RESULT="${PIPESTATUS[0]}" + cd ".." + done + cp -R "$ITERATION"/* "." + exit "$RESULT" + args: + chdir: "{{ remote_artifacts }}/{{ test_case }}" + register: lvm2_testsuite_run + ignore_errors: yes + +- name: Collect artifacts + shell: | + "{{ workdir }}/collect_output.sh" "{{ remote_artifacts }}/{{ test_case }}" "{{ remote_artifacts }}/list" + ignore_errors: yes + register: lvm2_testsuite_results + +#- name: Find artifacts +# find: +# path: "{{ remote_artifacts }}" +# patterns: "*.txt" +# register: artifacts_files + +- name: Fetch output + fetch: + dest: "{{ artifacts }}/{{ test_case }}/" + src: "{{ remote_artifacts }}/{{ test_case }}/{{ logfile }}" + flat: yes + with_items: + - lvm2-testsuite.out + - journal + - list + - logfiles.tar + loop_control: + loop_var: logfile + when: lvm2_testsuite_results.failed + +- name: Fetch list + fetch: + dest: "{{ artifacts }}/" + src: "{{ remote_artifacts }}/list" + flat: yes + +- name: Summary + shell: | + cut -d" " -f2 "{{ remote_artifacts }}/list" | sort | uniq -c + grep "failed$" "{{ remote_artifacts }}/list" || : + diff --git a/tests/tests.yml b/tests/tests.yml new file mode 100644 index 0000000..ea76c7f --- /dev/null +++ b/tests/tests.yml @@ -0,0 +1,343 @@ +- hosts: localhost + vars: + workdir: /tmp/testwd + remote_artifacts: /tmp/testwd/artifacts + srcdir: /tmp/source + package: lvm2 + fetch_all: true + #fetch_gzip: true + #fetch_tar: true + install_packages: true + #filter_flavours: '| grep -v "lockd\|polld"' # Ignore lockd and polld + filter_flavours: '| grep "vanilla"' # Run vanilla only + #run_tests: + # - vg + ignore_failures: + # tests need updating - remove after verified: + - lvconvert-thin.sh + - lvcreate-cache.sh + - lvcreate-thin-big.sh + # unstable results - should be warnings only + - lvconvert-cache-abort.sh + - lvconvert-mirror.sh + - dmeventd-restart.sh # TODO: could be an issue! + - nomda-restoremissing.sh # Unstable test, investigate + - api/dbus # New experimental VDO code not working yet + - open-file-limit.sh # Unstable test + # these are known issues with md not cleaning up after itself: + #- shell/duplicate-pvs-md0.sh + #- shell/duplicate-pvs-md1.sh + - shell/integrity # An unknown issue, likely in kernel + - writecache-blocksize # A new test not working properly + # New failures in 8.5 to investigate: + - shell/lvconvert-repair-thin.sh + - shell/snapshot-autoumount-dmeventd.sh + # New failures in 8.6 (2.03.14): + - lvconvert-repair-policy.sh + skip_tests: + - read-ahead.sh # tuned is interfering with tests + + # VDO is not supported yet: + - vdo # 8.4.0 kernel kmod-kvdo is broken + - lvconvert-cache-vdo.sh # TODO: likely an issue! + - lvcreate-vdo-cache.sh # TODO: likely an issue! + - lvconvert-cache-abort.sh # TODO: likely an issue! + + # TODO: Check and update list of known issues and unstable tests + - shell/000-basic.sh # this fails if there is different version of installed lvm2 and lvm2-testsuite (and we do not want this to fail gating) + - shell/fsadm-crypt.sh # broken on RHEL-8 - requires input on stdin + - lvconvert-raid-reshape.sh # blocking forever today, worked fine on Monday. kernel issue? + # these are known issues with md not cleaning up after itself: + #- shell/duplicate-pvs-md0.sh + #- shell/duplicate-pvs-md1.sh + + - shell/lvconvert-raid-takeover.sh # did this ever work? + - shell/lvm-on-md.sh # check the test! + - shell/thin-flags.sh # check the test! + + # these may take considerable amount of time and consume lot of RAM - we are running these on our infrastructure: + # vgchange-many does not work in CI - it is timing out writing large amounts of data + - shell/vgchange-many.sh + #- shell/vgcreate-many-pvs.sh + #- shell/thin-many-dmeventd.sh + + # NOTE: Uncomment the following to quickly check the test itself is working + #- vg + #- lv + #- pv + #- raid + #- mirror + #- python + #- poll + #- thin + #- scan + #- dbus + # + tags: + - classic + + tasks: + + - name: Set variables + set_fact: + artifacts: "{{ artifacts|default(lookup('env', 'TEST_ARTIFACTS') or './artifacts') }}" + + - name: str-common-init + include_role: + name: str-common-init + + - name: Install basic tools + dnf: + name: + - python3-libselinux + - sed + - tar + - util-linux + - psmisc # killall is required by testsuite + - nmap-ncat # nc required by lvmpolld tests (or socat) + - binutils # strings is required by some tests + - strace + - vim-common # xxd required by some tests + - mdadm + - vdo + - kmod-kvdo + state: present + + - name: See RAM and disks + shell: | + set -xv + free + mount + df + lsblk + true + + - name: Install rsync on localhost + dnf: + name: rsync + state: present + delegate_to: 127.0.0.1 + ignore_errors: yes + register: has_rsync + + - name: Install rsync on remote + dnf: + name: rsync + state: present + + - name: Create workdir + file: + state: directory + path: "{{ workdir }}" + mode: 0755 + + - name: Copy scripts to remote machine + copy: + src: "{{ playbook_dir }}/{{ item }}" + dest: "{{ workdir }}/" + mode: 0755 + with_items: + - get_lvm2_tarball.sh + - refresh.sh + - collect_output.sh + #- mock_build_and_test.sh + + - name: Check lvm2-testsuite is present + dnf: + name: lvm2-testsuite + state: present + ignore_errors: yes + register: lvm2_testsuite + + - name: Build and install lvm2-testsuite if not available + when: lvm2_testsuite.failed + block: + + - name: Make sure dependencies for retrieving the sources are installed + dnf: + name: + - curl + - wget + - rpm-build + - xz + #- mock + - rpmdevtools + - make + + - name: Copy spec file to remote machine + copy: + src: "{{ playbook_dir }}/../{{package}}.spec" + dest: "{{ workdir }}/" + +# - name: Display path to patches +# debug: +# msg: "{{ playbook_dir + '/../*.patch' }}" +# +# - name: Display patches +# debug: +# msg: "{{ lookup('fileglob', playbook_dir + '/../*.patch') }}" + + - name: Copy patches to remote machine + copy: + src: "{{ item }}" + dest: "{{ workdir }}/" + with_fileglob: "{{ playbook_dir }}/../*.patch" + + - name: Copy sources file to remote machine + copy: + src: "{{ playbook_dir }}/../sources" + dest: "{{ workdir }}/" + + - name: Enable testsuite in the spec file + shell: | + sed -i 's/enable_testsuite .*/enable_testsuite 1/' lvm2.spec + args: + chdir: "{{ workdir }}" + + # This would be handled by mock if available. And is not needed at all on Fedora + # TODO: Use conditional for the Fedora part! + - name: Enable buildroot repo + shell: dnf -y config-manager --set-enabled rhel-buildroot + ignore_errors: yes + + - name: Install build deps + shell: dnf -y build-dep {{ workdir }}/{{ package }}.spec + + - name: Run the refresh script + shell: | + ./refresh.sh + args: + chdir: "{{ workdir }}" + + - name: Run the source-retrieval script + shell: | + ./get_lvm2_tarball.sh {{ package }} + args: + chdir: "{{ workdir }}" + + - name: Build RPMs + shell: | + #rpmbuild -bp lvm2.spec --define "_sourcedir $PWD" --define "_specdir $PWD" --define "_builddir {{ srcdir }}" + #rpmbuild -bs lvm2.spec --define "_sourcedir $PWD" --define "_specdir $PWD" --define "_builddir {{ srcdir }}" + rpmbuild -ba lvm2.spec --define "_sourcedir $PWD" --define "_specdir $PWD" --define "_builddir {{ srcdir }}" + args: + chdir: "{{ workdir }}" + + - name: Install lvm2-testsuite + shell: | + dnf install -y /root/rpmbuild/RPMS/$(uname -m)/lvm2-testsuite-2.*.rpm + + args: + chdir: '{{ workdir }}' + +# - name: Build and install lvm2-testsuite +# shell: | +# ./mock_build_and_test.sh +# args: +# chdir: "{{ workdir }}" + + - name: Install lvm2 packages if requested + dnf: + state: present + name: + - lvm2 + - lvm2-lockd + - lvm2-dbusd + - device-mapper-event + when: install_packages|default(false) + + - name: Disable services interfering with tests + systemd: + name: "{{item}}" + masked: yes + enabled: no + state: stopped + ignore_errors: yes + with_items: + - lvm2-lvmpolld.service + - lvm2-lvmpolld.socket + - lvm2-monitor.service + - dm-event.socket + - dm-event.service + - lvm2-pvscan@.service + + # The above systemd module does not like templates... + - name: Disable pvscan service + shell: | + systemctl mask lvm2-pvscan@.service + ignore_errors: yes + + - name: Disable monitoring + shell: | + sed -i 's/monitoring *= *.*/monitoring = 0/' /etc/lvm/lvm.conf + + - name: Check environment + shell: | + lvmconfig --typeconfig diff + systemctl -a + + - name: Create artifacts directory + file: + state: directory + path: "{{ remote_artifacts }}" + + - name: Gather flavours + shell: | + ls -1 flavour-udev-* | grep -v "lvmlockd-dlm\|lvmlockd-sanlock" {{ filter_flavours|default('') }} | sed 's/^flavour-//' + args: + chdir: /usr/share/lvm2-testsuite/lib + register: flavours + +# - name: Find flavours +# find: +# contains: '^flavour-' +# paths: /usr/share/lvm2-testsuite/lib +# register: flavours +# # TODO: should use flavours.files when using find module, must drop flavour- prefix + +# - name: Debug flavours +# debug: +# var: flavours +# +# - name: Debug skip +# debug: +# msg: | +# '\({{ skip_tests|join("\|") }}\)' + + - name: Gather tests + shell: | + find . -name "*.sh" | sed 's/^\.\///' | grep -v '\({{ skip_tests|default(["qwqwasdf"])|join("\|") }}\)' | grep '\({{ run_tests|default(["."])|join("\|") }}\)' | sort + args: + chdir: /usr/share/lvm2-testsuite + register: lvm2_tests + +# - name: Debug lvm2_tests +# debug: +# var: lvm2_tests + + - name: Run tests + include_tasks: run_tests.yml + with_items: "{{ lvm2_tests.stdout_lines }}" + loop_control: + loop_var: test_case + + # NOTE: test.log is required by CI - shall we append to it? + - name: Fetch list with results as test.log + fetch: + dest: "{{ artifacts }}/test.log" + src: "{{ remote_artifacts }}/list" + flat: yes + +# - name: Check artifacts size on remote +# shell: | +# du -s "{{ remote_artifacts }}/" +# +# - name: Check artifacts size on local +# shell: | +# du -s "{{ artifacts }}/" +# delegate_to: 127.0.0.1 + + - name: Report failures + shell: | + ! grep -v '\(passed\|skipped\|warnings\)' "{{ remote_artifacts }}/list" | grep -v '\({{ ignore_failures|default(["qwqwasdf"])|join("\|") }}\)' + diff --git a/upstream b/upstream new file mode 100644 index 0000000..3e7c8f4 --- /dev/null +++ b/upstream @@ -0,0 +1 @@ +LVM2.2.03.14.tgz diff --git a/upstream-key.gpg b/upstream-key.gpg new file mode 100644 index 0000000..e7bf056 --- /dev/null +++ b/upstream-key.gpg @@ -0,0 +1,305 @@ +-----BEGIN PGP PUBLIC KEY BLOCK----- +Version: GnuPG v1.2.1 (GNU/Linux) + +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 +Y/JGhjIav89qy0Kqf7f3crt8RtU= +=0/xu +-----END PGP PUBLIC KEY BLOCK-----