github.com/rstandt/terraform@v0.12.32-0.20230710220336-b1063613405c/builtin/provisioners/habitat/linux_provisioner_test.go (about) 1 package habitat 2 3 import ( 4 "github.com/hashicorp/terraform/communicator" 5 "github.com/hashicorp/terraform/helper/schema" 6 "github.com/hashicorp/terraform/terraform" 7 "testing" 8 ) 9 10 const linuxDefaultSystemdUnitFileContents = `[Unit] 11 Description=Habitat Supervisor 12 13 [Service] 14 ExecStart=/bin/hab sup run --peer host1 --peer 1.2.3.4 --auto-update 15 Restart=on-failure 16 [Install] 17 WantedBy=default.target` 18 19 const linuxCustomSystemdUnitFileContents = `[Unit] 20 Description=Habitat Supervisor 21 22 [Service] 23 ExecStart=/bin/hab sup run --listen-ctl 192.168.0.1:8443 --listen-gossip 192.168.10.1:9443 --listen-http 192.168.20.1:8080 --peer host1 --peer host2 --peer 1.2.3.4 --peer 5.6.7.8 --peer foo.example.com 24 Restart=on-failure 25 Environment="HAB_SUP_GATEWAY_AUTH_TOKEN=ea7-beef" 26 Environment="HAB_AUTH_TOKEN=dead-beef" 27 [Install] 28 WantedBy=default.target` 29 30 func TestLinuxProvisioner_linuxInstallHabitat(t *testing.T) { 31 cases := map[string]struct { 32 Config map[string]interface{} 33 Commands map[string]bool 34 }{ 35 "Installation with sudo": { 36 Config: map[string]interface{}{ 37 "version": "0.79.1", 38 "auto_update": true, 39 "use_sudo": true, 40 }, 41 42 Commands: map[string]bool{ 43 "env HAB_NONINTERACTIVE=true HAB_NOCOLORING=true sudo -E /bin/bash -c 'curl --silent -L0 https://raw.githubusercontent.com/habitat-sh/habitat/master/components/hab/install.sh > install.sh'": true, 44 "env HAB_NONINTERACTIVE=true HAB_NOCOLORING=true sudo -E /bin/bash -c 'bash ./install.sh -v 0.79.1'": true, 45 "env HAB_NONINTERACTIVE=true HAB_NOCOLORING=true sudo -E /bin/bash -c 'hab install core/busybox'": true, 46 "env HAB_NONINTERACTIVE=true HAB_NOCOLORING=true sudo -E /bin/bash -c 'hab pkg exec core/busybox adduser -D -g \"\" hab'": true, 47 "env HAB_NONINTERACTIVE=true HAB_NOCOLORING=true sudo -E /bin/bash -c 'rm -f install.sh'": true, 48 }, 49 }, 50 "Installation without sudo": { 51 Config: map[string]interface{}{ 52 "version": "0.79.1", 53 "auto_update": true, 54 "use_sudo": false, 55 }, 56 57 Commands: map[string]bool{ 58 "env HAB_NONINTERACTIVE=true HAB_NOCOLORING=true /bin/bash -c 'curl --silent -L0 https://raw.githubusercontent.com/habitat-sh/habitat/master/components/hab/install.sh > install.sh'": true, 59 "env HAB_NONINTERACTIVE=true HAB_NOCOLORING=true /bin/bash -c 'bash ./install.sh -v 0.79.1'": true, 60 "env HAB_NONINTERACTIVE=true HAB_NOCOLORING=true /bin/bash -c 'hab install core/busybox'": true, 61 "env HAB_NONINTERACTIVE=true HAB_NOCOLORING=true /bin/bash -c 'hab pkg exec core/busybox adduser -D -g \"\" hab'": true, 62 "env HAB_NONINTERACTIVE=true HAB_NOCOLORING=true /bin/bash -c 'rm -f install.sh'": true, 63 }, 64 }, 65 "Installation with Habitat license acceptance": { 66 Config: map[string]interface{}{ 67 "version": "0.81.0", 68 "accept_license": true, 69 "auto_update": true, 70 "use_sudo": true, 71 }, 72 73 Commands: map[string]bool{ 74 "env HAB_NONINTERACTIVE=true HAB_NOCOLORING=true sudo -E /bin/bash -c 'curl --silent -L0 https://raw.githubusercontent.com/habitat-sh/habitat/master/components/hab/install.sh > install.sh'": true, 75 "env HAB_NONINTERACTIVE=true HAB_NOCOLORING=true sudo -E /bin/bash -c 'bash ./install.sh -v 0.81.0'": true, 76 "env HAB_NONINTERACTIVE=true HAB_NOCOLORING=true sudo -E /bin/bash -c 'hab install core/busybox'": true, 77 "env HAB_NONINTERACTIVE=true HAB_NOCOLORING=true sudo -E /bin/bash -c 'hab pkg exec core/busybox adduser -D -g \"\" hab'": true, 78 "env HAB_LICENSE=accept sudo -E /bin/bash -c 'hab -V'": true, 79 "env HAB_NONINTERACTIVE=true HAB_NOCOLORING=true sudo -E /bin/bash -c 'rm -f install.sh'": true, 80 }, 81 }, 82 } 83 84 o := new(terraform.MockUIOutput) 85 c := new(communicator.MockCommunicator) 86 87 for k, tc := range cases { 88 c.Commands = tc.Commands 89 90 p, err := decodeConfig( 91 schema.TestResourceDataRaw(t, Provisioner().(*schema.Provisioner).Schema, tc.Config), 92 ) 93 if err != nil { 94 t.Fatalf("Error: %v", err) 95 } 96 97 err = p.linuxInstallHabitat(o, c) 98 if err != nil { 99 t.Fatalf("Test %q failed: %v", k, err) 100 } 101 } 102 } 103 104 func TestLinuxProvisioner_linuxStartHabitat(t *testing.T) { 105 cases := map[string]struct { 106 Config map[string]interface{} 107 Commands map[string]bool 108 Uploads map[string]string 109 }{ 110 "Start systemd Habitat with sudo": { 111 Config: map[string]interface{}{ 112 "version": "0.79.1", 113 "auto_update": true, 114 "use_sudo": true, 115 "service_name": "hab-sup", 116 "peer": "--peer host1", 117 "peers": []interface{}{"1.2.3.4"}, 118 }, 119 120 Commands: map[string]bool{ 121 "env HAB_NONINTERACTIVE=true HAB_NOCOLORING=true sudo -E /bin/bash -c 'hab install core/hab-sup/0.79.1'": true, 122 "env HAB_NONINTERACTIVE=true HAB_NOCOLORING=true sudo -E /bin/bash -c 'systemctl enable hab-sup && systemctl start hab-sup'": true, 123 "env HAB_NONINTERACTIVE=true HAB_NOCOLORING=true sudo -E /bin/bash -c 'mv /tmp/hab-sup.service /etc/systemd/system/hab-sup.service'": true, 124 }, 125 126 Uploads: map[string]string{ 127 "/tmp/hab-sup.service": linuxDefaultSystemdUnitFileContents, 128 }, 129 }, 130 "Start systemd Habitat without sudo": { 131 Config: map[string]interface{}{ 132 "version": "0.79.1", 133 "auto_update": true, 134 "use_sudo": false, 135 "service_name": "hab-sup", 136 "peer": "--peer host1", 137 "peers": []interface{}{"1.2.3.4"}, 138 }, 139 140 Commands: map[string]bool{ 141 "env HAB_NONINTERACTIVE=true HAB_NOCOLORING=true /bin/bash -c 'hab install core/hab-sup/0.79.1'": true, 142 "env HAB_NONINTERACTIVE=true HAB_NOCOLORING=true /bin/bash -c 'systemctl enable hab-sup && systemctl start hab-sup'": true, 143 }, 144 145 Uploads: map[string]string{ 146 "/etc/systemd/system/hab-sup.service": linuxDefaultSystemdUnitFileContents, 147 }, 148 }, 149 "Start unmanaged Habitat with sudo": { 150 Config: map[string]interface{}{ 151 "version": "0.81.0", 152 "license": "accept-no-persist", 153 "auto_update": true, 154 "use_sudo": true, 155 "service_type": "unmanaged", 156 "peer": "--peer host1", 157 "peers": []interface{}{"1.2.3.4"}, 158 }, 159 160 Commands: map[string]bool{ 161 "env HAB_NONINTERACTIVE=true HAB_NOCOLORING=true sudo -E /bin/bash -c 'hab install core/hab-sup/0.81.0'": true, 162 "env HAB_NONINTERACTIVE=true HAB_NOCOLORING=true sudo -E /bin/bash -c 'mkdir -p /hab/sup/default && chmod o+w /hab/sup/default'": true, 163 "env HAB_NONINTERACTIVE=true HAB_NOCOLORING=true sudo -E /bin/bash -c '(setsid hab sup run --peer host1 --peer 1.2.3.4 --auto-update > /hab/sup/default/sup.log 2>&1 <&1 &) ; sleep 1'": true, 164 }, 165 166 Uploads: map[string]string{ 167 "/etc/systemd/system/hab-sup.service": linuxDefaultSystemdUnitFileContents, 168 }, 169 }, 170 "Start Habitat with custom config": { 171 Config: map[string]interface{}{ 172 "version": "0.79.1", 173 "auto_update": false, 174 "use_sudo": true, 175 "service_name": "hab-sup", 176 "peer": "--peer host1 --peer host2", 177 "peers": []interface{}{"1.2.3.4", "5.6.7.8", "foo.example.com"}, 178 "listen_ctl": "192.168.0.1:8443", 179 "listen_gossip": "192.168.10.1:9443", 180 "listen_http": "192.168.20.1:8080", 181 "builder_auth_token": "dead-beef", 182 "gateway_auth_token": "ea7-beef", 183 "ctl_secret": "bad-beef", 184 }, 185 186 Commands: map[string]bool{ 187 "env HAB_NONINTERACTIVE=true HAB_NOCOLORING=true HAB_AUTH_TOKEN=dead-beef sudo -E /bin/bash -c 'hab install core/hab-sup/0.79.1'": true, 188 "env HAB_NONINTERACTIVE=true HAB_NOCOLORING=true HAB_AUTH_TOKEN=dead-beef sudo -E /bin/bash -c 'systemctl enable hab-sup && systemctl start hab-sup'": true, 189 "env HAB_NONINTERACTIVE=true HAB_NOCOLORING=true HAB_AUTH_TOKEN=dead-beef sudo -E /bin/bash -c 'mv /tmp/hab-sup.service /etc/systemd/system/hab-sup.service'": true, 190 }, 191 192 Uploads: map[string]string{ 193 "/tmp/hab-sup.service": linuxCustomSystemdUnitFileContents, 194 }, 195 }, 196 } 197 198 o := new(terraform.MockUIOutput) 199 c := new(communicator.MockCommunicator) 200 201 for k, tc := range cases { 202 c.Commands = tc.Commands 203 c.Uploads = tc.Uploads 204 205 p, err := decodeConfig( 206 schema.TestResourceDataRaw(t, Provisioner().(*schema.Provisioner).Schema, tc.Config), 207 ) 208 if err != nil { 209 t.Fatalf("Error: %v", err) 210 } 211 212 err = p.linuxStartHabitat(o, c) 213 if err != nil { 214 t.Fatalf("Test %q failed: %v", k, err) 215 } 216 } 217 } 218 219 func TestLinuxProvisioner_linuxUploadRingKey(t *testing.T) { 220 cases := map[string]struct { 221 Config map[string]interface{} 222 Commands map[string]bool 223 }{ 224 "Upload ring key": { 225 Config: map[string]interface{}{ 226 "version": "0.79.1", 227 "auto_update": true, 228 "use_sudo": true, 229 "service_name": "hab-sup", 230 "peers": []interface{}{"1.2.3.4"}, 231 "ring_key": "test-ring", 232 "ring_key_content": "dead-beef", 233 }, 234 235 Commands: map[string]bool{ 236 "env HAB_NONINTERACTIVE=true HAB_NOCOLORING=true sudo -E /bin/bash -c 'echo -e \"dead-beef\" | hab ring key import'": true, 237 }, 238 }, 239 } 240 241 o := new(terraform.MockUIOutput) 242 c := new(communicator.MockCommunicator) 243 244 for k, tc := range cases { 245 c.Commands = tc.Commands 246 247 p, err := decodeConfig( 248 schema.TestResourceDataRaw(t, Provisioner().(*schema.Provisioner).Schema, tc.Config), 249 ) 250 if err != nil { 251 t.Fatalf("Error: %v", err) 252 } 253 254 err = p.linuxUploadRingKey(o, c) 255 if err != nil { 256 t.Fatalf("Test %q failed: %v", k, err) 257 } 258 } 259 } 260 261 func TestLinuxProvisioner_linuxStartHabitatService(t *testing.T) { 262 cases := map[string]struct { 263 Config map[string]interface{} 264 Commands map[string]bool 265 Uploads map[string]string 266 }{ 267 "Start Habitat service with sudo": { 268 Config: map[string]interface{}{ 269 "version": "0.79.1", 270 "auto_update": false, 271 "use_sudo": true, 272 "service_name": "hab-sup", 273 "peers": []interface{}{"1.2.3.4"}, 274 "ring_key": "test-ring", 275 "ring_key_content": "dead-beef", 276 "service": []interface{}{ 277 map[string]interface{}{ 278 "name": "core/foo", 279 "topology": "standalone", 280 "strategy": "none", 281 "channel": "stable", 282 "user_toml": "[config]\nlisten = 0.0.0.0:8080", 283 "bind": []interface{}{ 284 map[string]interface{}{ 285 "alias": "backend", 286 "service": "bar", 287 "group": "default", 288 }, 289 }, 290 }, 291 map[string]interface{}{ 292 "name": "core/bar", 293 "topology": "standalone", 294 "strategy": "rolling", 295 "channel": "staging", 296 "user_toml": "[config]\nlisten = 0.0.0.0:443", 297 }, 298 }, 299 }, 300 301 Commands: map[string]bool{ 302 "env HAB_NONINTERACTIVE=true HAB_NOCOLORING=true sudo -E /bin/bash -c 'hab pkg install core/foo --channel stable'": true, 303 "env HAB_NONINTERACTIVE=true HAB_NOCOLORING=true sudo -E /bin/bash -c 'mkdir -p /hab/user/foo/config'": true, 304 "env HAB_NONINTERACTIVE=true HAB_NOCOLORING=true sudo -E /bin/bash -c 'mv /tmp/user-a5b83ec1b302d109f41852ae17379f75c36dff9bc598aae76b6f7c9cd425fd76.toml /hab/user/foo/config/user.toml'": true, 305 "env HAB_NONINTERACTIVE=true HAB_NOCOLORING=true sudo -E /bin/bash -c 'hab svc load core/foo --topology standalone --strategy none --channel stable --bind backend:bar.default'": true, 306 "env HAB_NONINTERACTIVE=true HAB_NOCOLORING=true sudo -E /bin/bash -c 'hab pkg install core/bar --channel staging'": true, 307 "env HAB_NONINTERACTIVE=true HAB_NOCOLORING=true sudo -E /bin/bash -c 'mkdir -p /hab/user/bar/config'": true, 308 "env HAB_NONINTERACTIVE=true HAB_NOCOLORING=true sudo -E /bin/bash -c 'mv /tmp/user-6466ae3283ae1bd4737b00367bc676c6465b25682169ea5f7da222f3f078a5bf.toml /hab/user/bar/config/user.toml'": true, 309 "env HAB_NONINTERACTIVE=true HAB_NOCOLORING=true sudo -E /bin/bash -c 'hab svc load core/bar --topology standalone --strategy rolling --channel staging'": true, 310 }, 311 312 Uploads: map[string]string{ 313 "/tmp/user-a5b83ec1b302d109f41852ae17379f75c36dff9bc598aae76b6f7c9cd425fd76.toml": "[config]\nlisten = 0.0.0.0:8080", 314 "/tmp/user-6466ae3283ae1bd4737b00367bc676c6465b25682169ea5f7da222f3f078a5bf.toml": "[config]\nlisten = 0.0.0.0:443", 315 }, 316 }, 317 } 318 319 o := new(terraform.MockUIOutput) 320 c := new(communicator.MockCommunicator) 321 322 for k, tc := range cases { 323 c.Commands = tc.Commands 324 c.Uploads = tc.Uploads 325 326 p, err := decodeConfig( 327 schema.TestResourceDataRaw(t, Provisioner().(*schema.Provisioner).Schema, tc.Config), 328 ) 329 if err != nil { 330 t.Fatalf("Error: %v", err) 331 } 332 333 var errs []error 334 for _, s := range p.Services { 335 err = p.linuxStartHabitatService(o, c, s) 336 if err != nil { 337 errs = append(errs, err) 338 } 339 } 340 341 if len(errs) > 0 { 342 for _, e := range errs { 343 t.Logf("Test %q failed: %v", k, e) 344 t.Fail() 345 } 346 } 347 } 348 }