summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMaxim Biro <nurupo.contributions@gmail.com>2020-03-04 23:11:38 -0500
committerMaxim Biro <nurupo.contributions@gmail.com>2020-03-10 06:16:00 -0400
commit26fd89437bc0351df01766a69b2b475467f85ac0 (patch)
treee2560b283fdb7371e50b31ddc4af4298e28b4aee
parentbd7b7fadbacbb84144ed2160109befa106623d5d (diff)
Update and fix FreeBSD setup on Travis-CI
- Bump FreeBSD to 12.1. - Simplify stage1 logic. - Re-try downloading the image from a different mirror if one fails. - Use the `expect` utility instead of dealing with screen's log file. - Re-run failed toxcore test one more time and in sequence.
-rw-r--r--.travis/cmake-freebsd-env.sh38
-rwxr-xr-x.travis/cmake-freebsd-install.sh89
-rwxr-xr-x.travis/cmake-freebsd-stage1168
-rwxr-xr-x.travis/cmake-freebsd-stage1.expect41
-rwxr-xr-x.travis/cmake-freebsd-stage214
5 files changed, 129 insertions, 221 deletions
diff --git a/.travis/cmake-freebsd-env.sh b/.travis/cmake-freebsd-env.sh
index 8ae7e738..7d698940 100644
--- a/.travis/cmake-freebsd-env.sh
+++ b/.travis/cmake-freebsd-env.sh
@@ -1,10 +1,44 @@
1#!/bin/sh 1#!/bin/sh
2 2
3NPROC=`nproc` 3# Common variables and functions
4
5NPROC=$(nproc)
4 6
5SCREEN_SESSION=freebsd 7SCREEN_SESSION=freebsd
6SSH_PORT=10022 8SSH_PORT=10022
7 9
10FREEBSD_VERSION="12.1"
11IMAGE_NAME=FreeBSD-${FREEBSD_VERSION}-RELEASE-amd64.raw
12# https://download.freebsd.org/ftp/releases/VM-IMAGES/12.1-RELEASE/amd64/Latest/
13IMAGE_SHA512="a65da6260f5f894fc86fbe1f27dad7800906da7cffaa5077f82682ab74b6dd46c4ce87158c14b726d74ca3c6d611bea3bb336164da3f1cb990550310b110da22"
14
8RUN() { 15RUN() {
9 ssh -t -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no root@localhost -p $SSH_PORT "$@" 16 ssh -t -o ConnectionAttempts=120 -o ConnectTimeout=2 -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no root@localhost -p $SSH_PORT "$@"
17}
18
19start_vm() {
20 screen -d -m qemu-system-x86_64 -curses -m 2048 -smp $NPROC -net user,hostfwd=tcp::${SSH_PORT}-:22 -net nic "$IMAGE_NAME"
21
22 # Wait for ssh to start listening on the port
23 while ! echo "exit" | nc localhost ${SSH_PORT} | grep 'OpenSSH'; do
24 sleep 5
25 done
26
27 # Test that ssh works
28 RUN uname -a
29 RUN last
30}
31
32stop_vm()
33{
34 # Turn it off
35 # We use this contraption because for some reason `shutdown -h now` and
36 # `poweroff` result in FreeBSD not shutting down on Travis (they work on my
37 # machine though)
38 RUN "shutdown -p +5sec && sleep 30" || true
39
40 # Wait for the qemu process to terminate
41 while pgrep qemu; do
42 sleep 5
43 done
10} 44}
diff --git a/.travis/cmake-freebsd-install.sh b/.travis/cmake-freebsd-install.sh
deleted file mode 100755
index 59a78965..00000000
--- a/.travis/cmake-freebsd-install.sh
+++ /dev/null
@@ -1,89 +0,0 @@
1#!/bin/sh
2
3# Travis doesn't provide FreeBSD machines, so we just take a Linux one and run
4# FreeBSD in qemu virtual machine. qemu is being ran in curses mode inside a
5# screen session, because screen allows to easily send input and read output.
6# The input is sent using `screen -S session-name -X stuff ...` and the output
7# is read from the screen's log file. Note that for some reason you can't send
8# long input lines on Travis (it works just fine when I do it on my machine...),
9# but that limitation is not an issue, as we don't really need to send long
10# lines of input anyway. Also, note that since we run qemu in curses mode, the
11# output contains control characters intended for a terminal emulator telling
12# how to position and color the text, so it might be a little tricky to read it
13# sometimes. The only time when this script has to send input to and read the
14# output from the screen session is during the initial setup when we setup the
15# network, install and configure the ssh server, and update the system. After
16# this initial setup, ssh is used to communicate with the FreeBSD running in the
17# VM, which is a lot friendlier way of communication. Please note that Travis
18# doesn't seem to allow KVM passthrough, so qemu has to emulate all the
19# hardware, which makes it quite slow compared to the host machine. We cache
20# the qemu image since it takes a long time to run the initial system and
21# package updates, and we do incremental system and package updates on every
22# change to the list of git tags (i.e. on every toxcore release, presumably).
23
24sudo apt-get update
25sudo apt-get install -y qemu
26
27OLD_PWD="$PWD"
28
29mkdir -p /opt/freebsd/cache
30cd /opt/freebsd/cache
31
32# Make sure to update DL_SHA512 when bumping the version
33FREEBSD_VERSION="11.2"
34IMAGE_NAME=FreeBSD-${FREEBSD_VERSION}-RELEASE-amd64.raw
35
36# Sends keys to the VM as they are
37send_keys()
38{
39 screen -S $SCREEN_SESSION -X stuff "$1"
40}
41
42# Blocks until a specific text appears on VM's screen
43wait_for()
44{
45 while ! grep -q "$1" screenlog.0
46 do
47 sleep 1
48 done
49}
50
51# Starts VM and waits until it's fully running (until a login prompt is shown)
52start_vm()
53{
54 rm -f screenlog.0
55
56 # Start emulator. 2000mb RAM should be enough, right? The build machine has over 7gb.
57 screen -L -S $SCREEN_SESSION -d -m \
58 qemu-system-x86_64 -curses -m 2000 -smp $NPROC \
59 -net user,hostfwd=tcp::${SSH_PORT}-:22 -net nic "$IMAGE_NAME"
60
61 # Wait for the boot screen options
62 wait_for "Autoboot in"
63
64 # Select the 1st option
65 send_keys '
66'
67
68 # Wait for the system to boot and present the login prompt
69 wait_for "FreeBSD/amd64 ("
70}
71
72# Shuts VM down and waits until its process finishes
73stop_vm()
74{
75 # Turn it off
76 send_keys 'poweroff
77'
78
79 # Wait for qemu process to terminate
80 while ps aux | grep qemu | grep -vq grep
81 do
82 sleep 1
83 done
84}
85
86# Let's see what's in the cache directory
87ls -lh
88
89cd "$OLD_PWD"
diff --git a/.travis/cmake-freebsd-stage1 b/.travis/cmake-freebsd-stage1
index a9d4c10e..6a88ed44 100755
--- a/.travis/cmake-freebsd-stage1
+++ b/.travis/cmake-freebsd-stage1
@@ -1,5 +1,7 @@
1#!/bin/sh 1#!/bin/sh
2 2
3# Download and initial setup of the FreeBSD VM
4
3ACTION="$1" 5ACTION="$1"
4 6
5set -eux 7set -eux
@@ -7,8 +9,6 @@ set -eux
7. .travis/cmake-freebsd-env.sh 9. .travis/cmake-freebsd-env.sh
8 10
9travis_install() { 11travis_install() {
10 . .travis/cmake-freebsd-install.sh
11
12 git tag -l --sort=version:refname > GIT_TAGS 12 git tag -l --sort=version:refname > GIT_TAGS
13 13
14 OLD_PWD="$PWD" 14 OLD_PWD="$PWD"
@@ -18,83 +18,55 @@ travis_install() {
18 18
19 # === Get the VM image, set it up and cache === 19 # === Get the VM image, set it up and cache ===
20 20
21 # Create image if it's not cached or if this build script has changed 21 # Create image if it's not cached, or if this build script has changed, or a new toxcore tag was pushed
22 sha256sum "$OLD_PWD/.travis/cmake-freebsd-env.sh" > /tmp/sha 22 sha256sum "$OLD_PWD/.travis/cmake-freebsd-env.sh" > /tmp/sha
23 sha256sum "$OLD_PWD/.travis/cmake-freebsd-install.sh" >> /tmp/sha 23 sha256sum "$OLD_PWD/.travis/cmake-freebsd-stage1" >> /tmp/sha
24 sha256sum "$OLD_PWD/.travis/cmake-freebsd-stage1" >> /tmp/sha 24 sha256sum "$OLD_PWD/.travis/cmake-freebsd-stage1.expect" >> /tmp/sha
25 if [ ! -f "./$IMAGE_NAME.tgz" ] || [ ! -f ./cmake-freebsd-stage1-all.sha256 ] || [ "`cat cmake-freebsd-stage1-all.sha256`" != "`cat /tmp/sha`" ]; then 25 if [ ! -f "./$IMAGE_NAME.tgz" ] || [ ! -f ./cmake-freebsd-stage1-all.sha256 ] || [ "$(cat cmake-freebsd-stage1-all.sha256)" != "$(cat /tmp/sha)" ] || ! diff -u ./GIT_TAGS "$OLD_PWD/GIT_TAGS"; then
26
27 rm -rf ./* 26 rm -rf ./*
28 27
29 # https://download.freebsd.org/ftp/releases/VM-IMAGES/11.2-RELEASE/amd64/Latest/ 28 while true; do
30 DL_SHA512="0c3c232c7023c5036daeb5fbf68c2ddecf9703c74e317afcf19da91e83d0afcc526785571e2868894ce15cdb56b74fafa1ce9fd216469db91e021ac2ef8911e5" 29 # Selecting random mirror from https://www.freebsd.org/doc/handbook/mirrors-ftp.html
31 # Selecting random mirror from https://www.freebsd.org/doc/handbook/mirrors-ftp.html 30 # Note that not all mirrors listed on that page are working, so we have removed them
32 # Note that not all mirrors listed on that page are working, so we have removed them 31 # There are no arrays in sh so we get a bit clever
33 # I'm so sorry, there are no arrays in sh and we are not using bash... 32 DL_MIRROR_1=1
34 DL_MIRROR_1=1 33 DL_MIRROR_2=2
35 DL_MIRROR_2=4 34 DL_MIRROR_3=3
36 # There are 2 mirrors 35 DL_MIRROR_4=4
37 DL_MIRROR_RANDOM=`expr $(date +%s) % 2 + 1` 36 DL_MIRROR_5=5
38 DL_URL="ftp://ftp$(eval echo \$DL_MIRROR_$DL_MIRROR_RANDOM).us.freebsd.org/pub/FreeBSD/releases/VM-IMAGES/${FREEBSD_VERSION}-RELEASE/amd64/Latest/${IMAGE_NAME}.xz" 37 DL_MIRROR_6=6
39 38 DL_MIRROR_7=7
40 wget "$DL_URL" 39 DL_MIRROR_8=10
41 40 DL_MIRROR_9=11
42 if ! ( echo "$DL_SHA512 $IMAGE_NAME.xz" | sha512sum -c --status - ) ; then 41 DL_MIRROR_10=13
43 echo "Error: sha512 of $IMAGE_NAME.xz doesn't match the known one" 42 DL_MIRROR_11=14
44 exit 1 43
44 # There are 11 mirrors
45 DL_MIRROR_RANDOM=`expr $(date +%s) % 11 + 1`
46 DL_URL="ftp://ftp$(eval echo \$DL_MIRROR_$DL_MIRROR_RANDOM).us.freebsd.org/pub/FreeBSD/releases/VM-IMAGES/${FREEBSD_VERSION}-RELEASE/amd64/Latest/${IMAGE_NAME}.xz"
47
48 # Make sure there are no partial downloads from the previous loop iterations
49 rm -rf ./*
50
51 wget --tries 1 "$DL_URL" && break
52 done
53
54 if ! ( echo "$IMAGE_SHA512 $IMAGE_NAME.xz" | sha512sum -c --status - ) ; then
55 echo "Error: sha512 of $IMAGE_NAME.xz doesn't match the known one"
56 exit 1
45 fi 57 fi
46 58
47 unxz "$IMAGE_NAME.xz" 59 unxz "$IMAGE_NAME.xz"
48 60
49 # With this we don't have to guess how long a command will run for and sleeping 61 sudo apt-get update
50 # for that amount of time, risking either under sleeping or over sleeping, instead 62 sudo apt-get install -y qemu screen expect
51 # we will sleep exactly until the command is finished by printing out a unique
52 # string after the command is executed and then checking if it was printed.
53 execute_shell_and_wait()
54 {
55 # $RANDOM is a bash built-in, so we try to avoid name collision here by using ugly RANDOM_STR name
56 RANDOM_STR=$(< /dev/urandom tr -dc _A-Za-z0-9 | head -c16)
57 send_keys "$1;echo $RANDOM_STR
58
59"
60 # \[1B is a control escape sequence for a new line in the terminal.
61 # We want to wait for <new-line>$RANDOM_STR instead of just $RANDOM_STR because
62 # $RANDOM_STR we have inputted with send_keys above would appear in the screenlog.0
63 # file and we don't want to match our input, we want to match the echo's output.
64 # The .\? optionally matches any character. Sometimes it happens that there is some
65 # random character inserved between the new line control escape sequence and $RANDOM_STR.
66 wait_for "\[1B.\?$RANDOM_STR"
67 }
68
69 start_vm
70
71 # Login as root user
72 send_keys 'root
73
74'
75
76 # Wait for the prompt
77 wait_for "root@.*:~"
78 63
79 # Configure network, ssh and start changing password 64 # The downloaded image has little free disk space
80 execute_shell_and_wait 'echo "ifconfig_em0=DHCP" >> /etc/rc.conf' 65 qemu-img resize -f raw "$IMAGE_NAME" +5G
81 execute_shell_and_wait 'echo "Port 22" >> /etc/ssh/sshd_config'
82 execute_shell_and_wait 'echo "PermitRootLogin yes" >> /etc/ssh/sshd_config'
83 execute_shell_and_wait 'echo "PasswordAuthentication yes" >> /etc/ssh/sshd_config'
84 execute_shell_and_wait 'echo "PermitEmptyPasswords yes" >> /etc/ssh/sshd_config'
85 execute_shell_and_wait 'echo "sshd_enable=YES" >> /etc/rc.conf'
86 send_keys 'sh /etc/rc.d/netif restart && sh /etc/rc.d/sshd start && passwd
87'
88 66
89 # Wait for the password prompt 67 NPROC=$NPROC SSH_PORT=$SSH_PORT IMAGE_NAME="$IMAGE_NAME" screen "$OLD_PWD/.travis/cmake-freebsd-stage1.expect"
90 wait_for "Changing local password for root"
91 68
92 # Reset password to empty for the passwordless ssh to work 69 start_vm
93 send_keys '
94'
95 wait_for "New Password"
96 send_keys '
97'
98 70
99 # Update system 71 # Update system
100 RUN env PAGER=cat env ASSUME_ALWAYS_YES=YES freebsd-update --not-running-from-cron fetch 72 RUN env PAGER=cat env ASSUME_ALWAYS_YES=YES freebsd-update --not-running-from-cron fetch
@@ -117,7 +89,6 @@ travis_install() {
117 gmake \ 89 gmake \
118 cmake \ 90 cmake \
119 pkgconf \ 91 pkgconf \
120 opencv \
121 portaudio \ 92 portaudio \
122 libsndfile \ 93 libsndfile \
123 texinfo \ 94 texinfo \
@@ -130,60 +101,11 @@ travis_install() {
130 # Create cache 101 # Create cache
131 tar -Sczvf "$IMAGE_NAME.tgz" "$IMAGE_NAME" 102 tar -Sczvf "$IMAGE_NAME.tgz" "$IMAGE_NAME"
132 rm "$IMAGE_NAME" 103 rm "$IMAGE_NAME"
133 rm screenlog.0
134
135 cp "$OLD_PWD/GIT_TAGS" .
136 sha256sum "$OLD_PWD/.travis/cmake-freebsd-env.sh" > cmake-freebsd-stage1-all.sha256
137 sha256sum "$OLD_PWD/.travis/cmake-freebsd-install.sh" >> cmake-freebsd-stage1-all.sha256
138 sha256sum "$OLD_PWD/.travis/cmake-freebsd-stage1" >> cmake-freebsd-stage1-all.sha256
139
140 ls -lh
141 fi
142
143 # === Update the image on new version (tag) of toxcore ===
144
145 if ! diff -u ./GIT_TAGS "$OLD_PWD/GIT_TAGS" ; then
146 # Extract the cached image
147 tar -Sxzvf "$IMAGE_NAME.tgz"
148
149 start_vm
150
151 # Log in.
152 # Although qemu prints "login:" and "Password:" lines, they are not written into the screen's log
153 # file for some reason (perhaps not enough text to flush the buffer to a file?), so we can't use
154 # wait_for on them, we just use sleep to add hopefully enough delay.
155 sleep 5
156 # "login:"
157 send_keys 'root
158
159'
160 sleep 5
161 # "Password:"
162 send_keys '
163
164'
165 # Wait for the prompt
166 wait_for "root@.* ~"
167
168 # Update system
169 RUN PAGER=cat ASSUME_ALWAYS_YES=YES freebsd-update --not-running-from-cron fetch
170 RUN PAGER=cat ASSUME_ALWAYS_YES=YES freebsd-update --not-running-from-cron install || true
171
172 # Update packages
173 RUN PAGER=cat ASSUME_ALWAYS_YES=YES pkg upgrade
174
175 # === Cache the updated VM image ===
176
177 stop_vm
178
179 # Create/Update cache
180 rm "$IMAGE_NAME.tgz"
181 tar -Sczvf "$IMAGE_NAME.tgz" "$IMAGE_NAME"
182 rm "$IMAGE_NAME"
183 rm screenlog.0
184 104
185 cp "$OLD_PWD/GIT_TAGS" . 105 cp "$OLD_PWD/GIT_TAGS" .
186 106 sha256sum "$OLD_PWD/.travis/cmake-freebsd-env.sh" > cmake-freebsd-stage1-all.sha256
107 sha256sum "$OLD_PWD/.travis/cmake-freebsd-stage1" >> cmake-freebsd-stage1-all.sha256
108 sha256sum "$OLD_PWD/.travis/cmake-freebsd-stage1.expect" >> cmake-freebsd-stage1-all.sha256
187 ls -lh 109 ls -lh
188 fi 110 fi
189 111
diff --git a/.travis/cmake-freebsd-stage1.expect b/.travis/cmake-freebsd-stage1.expect
new file mode 100755
index 00000000..3269e742
--- /dev/null
+++ b/.travis/cmake-freebsd-stage1.expect
@@ -0,0 +1,41 @@
1#!/usr/bin/expect -f
2
3set timeout -1
4
5# Note: doesn't work if -nographic is used instead of -curses
6spawn qemu-system-x86_64 -curses -m 2048 -smp $env(NPROC) -net user,hostfwd=tcp::$env(SSH_PORT)-:22 -net nic "$env(IMAGE_NAME)"
7
8# Skip the boot menu
9expect "to boot or any other key to stop"
10send -- "\r"
11
12expect "login: "
13send -- "root\r"
14
15# Setup DHCP networking and paswordless ssh
16expect "root@freebsd:~ # "
17send -- "echo \"ifconfig_em0=DHCP\" >> /etc/rc.conf\r"
18expect "root@freebsd:~ # "
19send -- "echo \"Port 22\" >> /etc/ssh/sshd_config\r"
20expect "root@freebsd:~ # "
21send -- "echo \"PermitRootLogin yes\" >> /etc/ssh/sshd_config\r"
22expect "root@freebsd:~ # "
23send -- "echo \"PasswordAuthentication yes\" >> /etc/ssh/sshd_config\r"
24expect "root@freebsd:~ # "
25send -- "echo \"PermitEmptyPasswords yes\" >> /etc/ssh/sshd_config\r"
26expect "root@freebsd:~ # "
27send -- "echo \"sshd_enable=YES\" >> /etc/rc.conf\r"
28expect "root@freebsd:~ # "
29
30# Set the empty password
31send -- "passwd\r"
32expect "New Password:"
33send -- "\r"
34expect "Retype New Password:"
35send -- "\r"
36expect "root@freebsd:~ # "
37
38# Done
39send -- "poweroff\r"
40wait
41exit 0
diff --git a/.travis/cmake-freebsd-stage2 b/.travis/cmake-freebsd-stage2
index 9750531e..609cd618 100755
--- a/.travis/cmake-freebsd-stage2
+++ b/.travis/cmake-freebsd-stage2
@@ -1,5 +1,7 @@
1#!/bin/sh 1#!/bin/sh
2 2
3# Toxcore building
4
3ACTION="$1" 5ACTION="$1"
4 6
5set -eux 7set -eux
@@ -7,7 +9,8 @@ set -eux
7. .travis/cmake-freebsd-env.sh 9. .travis/cmake-freebsd-env.sh
8 10
9travis_install() { 11travis_install() {
10 . .travis/cmake-freebsd-install.sh 12 sudo apt-get update
13 sudo apt-get install -y qemu screen
11 14
12 OLD_PWD="$PWD" 15 OLD_PWD="$PWD"
13 16
@@ -29,10 +32,6 @@ travis_install() {
29 32
30 start_vm 33 start_vm
31 34
32 # Display FreeBSD kernel info and last login
33 RUN uname -a
34 RUN last
35
36 cd "$OLD_PWD" 35 cd "$OLD_PWD"
37 36
38 # Copy over toxcore code from Travis to qemu 37 # Copy over toxcore code from Travis to qemu
@@ -59,14 +58,15 @@ travis_script() {
59 -DMIN_LOGGER_LEVEL=TRACE \ 58 -DMIN_LOGGER_LEVEL=TRACE \
60 -DMUST_BUILD_TOXAV=ON \ 59 -DMUST_BUILD_TOXAV=ON \
61 -DSTRICT_ABI=ON \ 60 -DSTRICT_ABI=ON \
62 -DTEST_TIMEOUT_SECONDS=120 \ 61 -DTEST_TIMEOUT_SECONDS=300 \
63 -DUSE_IPV6=OFF \ 62 -DUSE_IPV6=OFF \
64 -DAUTOTEST=ON' 63 -DAUTOTEST=ON'
65 64
66 # We created the VM with the same number of cores as the host, so the host-ran `nproc` here is fine 65 # We created the VM with the same number of cores as the host, so the host-ran `nproc` here is fine
67 RUN 'gmake "-j$NPROC" -k install -C_build' 66 RUN 'gmake "-j$NPROC" -k install -C_build'
68 RUN 'gmake "-j$NPROC" test ARGS="-j50" -C_build || \ 67 RUN 'gmake "-j$NPROC" test ARGS="-j50" -C_build || \
69 gmake "-j$NPROC" -C_build test ARGS="-j50 --rerun-failed" CTEST_OUTPUT_ON_FAILURE=1 || \ 68 gmake "-j1" -C_build test ARGS="-j1 --rerun-failed" || \
69 gmake "-j1" -C_build test ARGS="-j1 --rerun-failed" CTEST_OUTPUT_ON_FAILURE=1 || \
70 true' 70 true'
71} 71}
72 72