run.sh 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259
  1. #!/bin/bash
  2. # Three nodes are initialized:
  3. # latest : created from the latest commit that triggered this CI job
  4. # tinc11 : from the latest tag in tinc 1.1 branch
  5. # tinc10 : from the latest commit in tinc 1.0 branch
  6. #
  7. # The latter two are configured by using import/export/exchange.
  8. # Since tinc 1.0 doesn't support that, host configs are copied to its hosts directory.
  9. # Then nodes are connected and some light testing is performed to make sure they work together.
  10. set -euo pipefail
  11. nodes='latest tinc11 tinc10'
  12. total_nodes=3
  13. declare -A refs=(
  14. [tinc10]='origin/master'
  15. [tinc11]="$(git describe --abbrev=0 --match='release-*')"
  16. [latest]='HEAD'
  17. )
  18. declare -A addr=(
  19. [tinc10]='192.168.1.1'
  20. [tinc11]='192.168.1.2'
  21. [latest]='192.168.1.3'
  22. )
  23. src=/usr/local/src
  24. etc=/usr/local/etc
  25. mkdir -p $src $etc
  26. archive() {
  27. tar -caf /tmp/tests.tar.gz /usr/local/etc || true
  28. }
  29. header() {
  30. echo >&2 '################################################################################'
  31. echo >&2 "# $*"
  32. echo >&2 '################################################################################'
  33. }
  34. build_meson() {
  35. meson setup "$1" -D prefix="/opt/$1"
  36. meson install -C "$1"
  37. }
  38. build_autotools() {
  39. autoreconf -fsi
  40. ./configure --prefix="/opt/$1"
  41. make -j"$(nproc)"
  42. make install
  43. }
  44. build() {
  45. local ref="$1"
  46. header "Building tinc (ref $ref)"
  47. git clone "$PWD" "$src/$ref" -b "compat-$ref"
  48. pushd "$src/$ref"
  49. if [[ -f meson.build ]]; then
  50. build_meson "$ref"
  51. else
  52. build_autotools "$ref"
  53. fi
  54. popd
  55. mkdir -p "/opt/$ref/var/run"
  56. }
  57. wait_network() {
  58. local from="$1"
  59. local to="$2"
  60. local total=0
  61. while ! ip netns exec "$from" ping -W1 -c1 "${addr[$to]}" >/dev/null; do
  62. total=$((total + 1))
  63. if [[ total -gt 60 ]]; then
  64. echo >&2 "Network connection between $from and $to is not working"
  65. exit 1
  66. fi
  67. echo >&2 "Network isn't ready yet..."
  68. sleep 1
  69. done
  70. }
  71. test_network() {
  72. local from="$1"
  73. local to="$2"
  74. wait_network "$from" "$to"
  75. header "Sending data between $from and $to"
  76. ip netns exec "$from" \
  77. iperf3 --time 1 --client "${addr[$to]}"
  78. }
  79. test_sign_verify() {
  80. local signer="$1"
  81. local verifier="$2"
  82. local output="$etc/$signer/signed"
  83. header "Test signature verification between $signer and $verifier"
  84. "$signer" sign >"$output" <<<"text message for node $signer to sign"
  85. for peer in "$signer" '*'; do
  86. "$verifier" verify "$peer" "$output"
  87. "$verifier" verify "$peer" <"$output"
  88. done
  89. }
  90. test_node_status() {
  91. local node="$1"
  92. header "Checking node status for $node"
  93. reachable="$("$node" dump reachable nodes | wc -l)"
  94. echo >&2 "Node $node can reach $reachable nodes"
  95. [[ $reachable == "$total_nodes" ]]
  96. for peer in $nodes; do
  97. echo >&2 -n "$node info $peer: "
  98. "$node" info "$peer" | tee /dev/stderr | grep -E -q '(can reach itself|directly)'
  99. done
  100. }
  101. latest() {
  102. /opt/latest/sbin/tinc -c $etc/latest "$@"
  103. }
  104. tinc11() {
  105. /opt/tinc11/sbin/tinc -c $etc/tinc11 "$@"
  106. }
  107. header 'Creating branches'
  108. for node in $nodes; do
  109. echo >&2 " $node: $(git rev-parse "compat-$node")"
  110. git branch "compat-$node" "${refs[$node]}"
  111. done
  112. build tinc10
  113. build tinc11
  114. build latest
  115. header 'Initializing node from the latest commit'
  116. latest <<EOF
  117. init latest
  118. set Address localhost
  119. set Port 30000
  120. set Interface latest
  121. set Subnet ${addr[latest]}
  122. set Compression 0
  123. set LogLevel 5
  124. EOF
  125. header 'Initializing node from the latest tag'
  126. tinc11 <<EOF
  127. init tinc11
  128. set Address localhost
  129. set Port 30001
  130. set Interface tinc11
  131. set Subnet ${addr[tinc11]}
  132. set Compression 3
  133. set LogLevel 5
  134. EOF
  135. header 'Initializing node for tinc 1.0'
  136. mkdir -p $etc/tinc10/hosts
  137. cat >$etc/tinc10/tinc.conf <<EOF
  138. Name = tinc10
  139. Interface = tinc10
  140. Compression = 10
  141. LogLevel = 5
  142. EOF
  143. cat >$etc/tinc10/hosts/tinc10 <<EOF
  144. Address = localhost
  145. Port = 30002
  146. Subnet = ${addr[tinc10]}
  147. EOF
  148. /opt/tinc10/sbin/tincd -c $etc/tinc10 --generate-keys
  149. trap archive EXIT INT TERM
  150. header 'Creating network namespaces'
  151. for ns in $nodes; do
  152. ip netns add "$ns"
  153. done
  154. header 'Creating network configuration scripts'
  155. for node in $nodes; do
  156. tinc_up="$etc/$node/tinc-up"
  157. cat >"$tinc_up" <<EOF
  158. #!/bin/bash
  159. set -eu
  160. ip link set dev $node netns $node
  161. ip netns exec $node ip addr add ${addr[$node]}/24 dev $node
  162. ip netns exec $node ip link set $node up
  163. ip netns exec $node ip link set lo up
  164. ip netns exec $node iperf3 --server --daemon
  165. EOF
  166. chmod 755 "$tinc_up"
  167. done
  168. header 'Exchanging host files'
  169. # Not all configs are copied to make sure 'peer exchange' is working
  170. # tinc10 <--> latest <--> tinc11
  171. latest export | tinc11 exchange | latest import
  172. cp $etc/tinc10/hosts/tinc10 $etc/latest/hosts/
  173. cp $etc/latest/hosts/latest $etc/tinc10/hosts/
  174. header "Starting nodes"
  175. for node in $nodes; do
  176. tincd="/opt/$node/sbin/tincd"
  177. echo >&2 "Starting node $node ($tincd)"
  178. "$tincd" --version
  179. "$tincd" \
  180. --config "$etc/$node" \
  181. --pidfile "$etc/$node/pid" \
  182. --logfile "$etc/$node/log" \
  183. --debug 5
  184. done
  185. header 'Running connectivity tests'
  186. for client in $nodes; do
  187. for server in $nodes; do
  188. if [[ $client != "$server" ]]; then
  189. test_network "$client" "$server"
  190. fi
  191. done
  192. done
  193. test_node_status latest
  194. test_node_status tinc11
  195. test_sign_verify latest tinc11
  196. test_sign_verify tinc11 latest