|
4 | 4 | [clojure.java.io :as io]
|
5 | 5 | [next.jdbc :as j]
|
6 | 6 | [next.jdbc.connection :as connection]
|
| 7 | + [jepsen.os.debian :as debian] |
| 8 | + [jepsen.control.util :as cu] |
7 | 9 | [jepsen [core :as jepsen]
|
8 | 10 | [control :as c]
|
9 |
| - [db :as db]] |
| 11 | + [db :as db] |
| 12 | + [util :as util :refer [parse-long]]] |
10 | 13 | [slingshot.slingshot :refer [try+ throw+]]))
|
11 | 14 |
|
12 | 15 | (def data-dir "/var/lib/tarantool/jepsen")
|
13 | 16 | (def logfile "/var/log/tarantool/jepsen.log")
|
14 | 17 | (def dir "/opt/tarantool")
|
| 18 | +(def tarantool-repo |
| 19 | + "Where can we clone tarantool from?" |
| 20 | + "https://github.com/tarantool/tarantool") |
15 | 21 |
|
16 | 22 | (def installer-name "installer.sh")
|
17 | 23 | (def installer-url (str "https://tarantool.io/" installer-name))
|
18 | 24 |
|
| 25 | +(def build-dir |
| 26 | + "A remote directory to clone project and compile." |
| 27 | + "/tmp/jepsen/build") |
| 28 | + |
| 29 | +(def build-file |
| 30 | + "A file we create to track the last built version; speeds up compilation." |
| 31 | + "jepsen-built-version") |
| 32 | + |
19 | 33 | (defn node-uri
|
20 | 34 | "An uri for connecting to a node on a particular port."
|
21 | 35 | [node port]
|
|
34 | 48 | (str "'" (peer-uri node) "'")))
|
35 | 49 | (str/join ",")))
|
36 | 50 |
|
37 |
| -(defn install! |
| 51 | +(defn install-build-prerequisites! |
| 52 | + "Installs prerequisite packages for building Tarantool." |
| 53 | + [] |
| 54 | + (info "Install prerequisites") |
| 55 | + (debian/install [:autoconf |
| 56 | + :automake |
| 57 | + :build-essential |
| 58 | + :cmake |
| 59 | + :coreutils |
| 60 | + :libtool |
| 61 | + :libreadline-dev |
| 62 | + :libncurses5-dev |
| 63 | + :libssl-dev |
| 64 | + :libunwind-dev |
| 65 | + :libicu-dev |
| 66 | + :make |
| 67 | + :sed |
| 68 | + :zlib1g-dev])) |
| 69 | + |
| 70 | +(defn checkout-repo! |
| 71 | + "Checks out a repo at the given version into a directory in build/ named |
| 72 | + `dir`. Returns the path to the build directory." |
| 73 | + [repo-url dir version] |
| 74 | + (let [full-dir (str build-dir "/" dir)] |
| 75 | + (when-not (cu/exists? full-dir) |
| 76 | + (c/cd build-dir |
| 77 | + (info "Cloning into" full-dir) |
| 78 | + (c/exec :mkdir :-p build-dir) |
| 79 | + (c/exec :git :clone repo-url dir))) |
| 80 | + |
| 81 | + (c/cd full-dir |
| 82 | + (try+ (c/exec :git :checkout version) |
| 83 | + (catch [:exit 1] e |
| 84 | + (if (re-find #"pathspec .+ did not match any file" (:err e)) |
| 85 | + (do ; Ah, we're out of date |
| 86 | + (c/exec :git :fetch) |
| 87 | + (c/exec :git :checkout version)) |
| 88 | + (throw+ e))))) |
| 89 | + |
| 90 | + (c/cd full-dir |
| 91 | + (c/exec :git :submodule :update :--init :--recursive)) |
| 92 | + |
| 93 | + full-dir)) |
| 94 | + |
| 95 | +(def build-locks |
| 96 | + "We use these locks to prevent concurrent builds." |
| 97 | + (util/named-locks)) |
| 98 | + |
| 99 | +(defmacro with-build-version |
| 100 | + "Takes a test, a repo name, a version, and a body. Builds the repo by |
| 101 | + evaluating body, only if it hasn't already been built. Takes out a lock on a |
| 102 | + per-repo basis to prevent concurrent builds. Remembers what version was last |
| 103 | + built by storing a file in the repo directory. Returns the result of body if |
| 104 | + evaluated, or the build directory." |
| 105 | + [node repo-name version & body] |
| 106 | + `(util/with-named-lock build-locks [~node ~repo-name] |
| 107 | + (let [build-file# (str build-dir "/" ~repo-name "/" build-file)] |
| 108 | + (if (try+ (= (str ~version) (c/exec :cat build-file#)) |
| 109 | + (catch [:exit 1] e# ; Not found |
| 110 | + false)) |
| 111 | + ; Already built |
| 112 | + (str build-dir "/" ~repo-name) |
| 113 | + ; Build |
| 114 | + (let [res# (do ~@body)] |
| 115 | + ; Log version |
| 116 | + (c/exec :echo ~version :> build-file#) |
| 117 | + res#))))) |
| 118 | + |
| 119 | +(defn build-tarantool! |
| 120 | + "Build Tarantool from scratch" |
| 121 | + [test node] |
| 122 | + (let [version (:version test)] |
| 123 | + (with-build-version node "tarantool" version |
| 124 | + (let [dir (checkout-repo! tarantool-repo "tarantool" version)] |
| 125 | + (install-build-prerequisites!) |
| 126 | + (info "Building Tarantool" (:version test)) |
| 127 | + (c/cd dir |
| 128 | + (c/exec :cmake :-DWITH_SYSTEMD:BOOL=ON |
| 129 | + :-DCMAKE_BUILD_TYPE=RelWithDebInfo |
| 130 | + :-DENABLE_DIST:BOOL=ON |
| 131 | + :-DENABLE_BACKTRACE:BOOL=ON |
| 132 | + "-DCMAKE_INSTALL_LOCALSTATEDIR:PATH=/var" |
| 133 | + "-DCMAKE_INSTALL_SYSCONFDIR:PATH=/etc" |
| 134 | + :.) |
| 135 | + (c/exec :make :-j2) |
| 136 | + (c/exec :make :install)) |
| 137 | + dir))) |
| 138 | + (c/su |
| 139 | + (c/exec :adduser |
| 140 | + :--system |
| 141 | + :--group |
| 142 | + :--quiet |
| 143 | + :--home "/var/spool/tarantool" |
| 144 | + :--no-create-home |
| 145 | + :--disabled-login |
| 146 | + :tarantool) |
| 147 | + (c/exec :install :-d :-otarantool :-gadm :-m2750 "/var/log/tarantool") |
| 148 | + (c/exec :install :-d :-otarantool :-gadm :-m2750 "/var/run/tarantool") |
| 149 | + (c/exec :install :-d :-otarantool :-gadm :-m2750 "/var/lib/tarantool"))) |
| 150 | + |
| 151 | +(defn install-package! |
38 | 152 | "Installation using installer.sh"
|
39 | 153 | [node version]
|
40 |
| - (info "Install Tarantool version" version) |
| 154 | + (info "Install Tarantool package version" version) |
41 | 155 | (c/su
|
42 | 156 | (c/exec :curl :-O :-L "https://tarantool.io/installer.sh")
|
43 | 157 | (c/exec :chmod :+x "./installer.sh")
|
44 | 158 | (c/exec (str "VER=" version) "./installer.sh")
|
45 |
| - (c/exec :usermod :-a :-G :tarantool :ubuntu) |
46 | 159 | (c/su (c/exec :systemctl :stop "tarantool@example"))))
|
47 | 160 |
|
| 161 | +(defn install! |
| 162 | + "Tarantool installation, accepts branch version (like 2.6) or commit hash" |
| 163 | + [node version] |
| 164 | + (if (re-matches #"\d+\.\d+" version) |
| 165 | + (install-package! node version) |
| 166 | + (build-tarantool! node version))) |
| 167 | + |
48 | 168 | (defn start!
|
49 | 169 | "Starts tarantool service"
|
50 | 170 | [test node]
|
|
81 | 201 | [test node]
|
82 | 202 | (let [read-only (not (is-primary? test node))]
|
83 | 203 | (info "Joining" node "as" (if (true? read-only) "replica" "leader"))
|
| 204 | + (c/exec :mkdir :-p "/etc/tarantool/instances.available") |
| 205 | + (c/exec :mkdir :-p "/etc/tarantool/instances.enabled") |
| 206 | + (c/exec :usermod :-a :-G :tarantool :ubuntu) |
84 | 207 | (c/exec :echo (-> "tarantool/jepsen.lua" io/resource slurp
|
85 | 208 | (str/replace #"%TARANTOOL_REPLICATION%" (replica-set test))
|
86 | 209 | (str/replace #"%TARANTOOL_IS_READ_ONLY%" (boolean-to-str read-only))
|
87 | 210 | (str/replace #"%TARANTOOL_SINGLE_MODE%" (boolean-to-str (:single-mode test)))
|
88 | 211 | (str/replace #"%TARANTOOL_DATA_ENGINE%" (:engine test)))
|
89 |
| - :> "/etc/tarantool/instances.enabled/jepsen.lua"))) |
| 212 | + :> "/etc/tarantool/instances.enabled/jepsen.lua") |
| 213 | + (c/exec :cp "/etc/tarantool/instances.enabled/jepsen.lua" "/etc/tarantool/instances.available"))) |
90 | 214 |
|
91 | 215 | (defn is-read-only
|
92 | 216 | [conn]
|
|
0 commit comments