mirror of
https://github.com/kreuzwerker/terraform-provider-docker.git
synced 2025-12-24 00:29:46 -05:00
Feat/swarm 3 acc test infra (#39)
* Set up test infrastructure with local registry and custom images. * Updated travis docker version and usage of new test infra. * Made acc tests constantly output test results. * Tmp acc test files are ignored. * Fixed tests with new infra. * Allowing insecure registries for acc tests. Added fallback for v1 registries. * Added private image cleanup after tests. * Refined acc test structure to confirm tf provider standards with make testacc.
This commit is contained in:
parent
5a40076c95
commit
d7038e7560
14 changed files with 201 additions and 12 deletions
2
.gitignore
vendored
2
.gitignore
vendored
|
|
@ -29,3 +29,5 @@ website/vendor
|
||||||
# Test exclusions
|
# Test exclusions
|
||||||
!command/test-fixtures/**/*.tfstate
|
!command/test-fixtures/**/*.tfstate
|
||||||
!command/test-fixtures/**/.terraform/
|
!command/test-fixtures/**/.terraform/
|
||||||
|
scripts/testing/auth
|
||||||
|
scripts/testing/certs
|
||||||
|
|
|
||||||
18
.travis.yml
18
.travis.yml
|
|
@ -1,8 +1,18 @@
|
||||||
dist: trusty
|
dist: trusty
|
||||||
sudo: false
|
sudo: required
|
||||||
|
services:
|
||||||
|
- docker
|
||||||
language: go
|
language: go
|
||||||
go:
|
go:
|
||||||
- 1.8.1
|
- 1.9.1
|
||||||
|
|
||||||
|
before_install:
|
||||||
|
- curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
|
||||||
|
- sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable"
|
||||||
|
- sudo apt-get update
|
||||||
|
- sudo apt-get -y install docker-ce
|
||||||
|
- docker version
|
||||||
|
- export TRAVIS="true"
|
||||||
|
|
||||||
install:
|
install:
|
||||||
# This script is used by the Travis build to install a cookie for
|
# This script is used by the Travis build to install a cookie for
|
||||||
|
|
@ -11,9 +21,13 @@ install:
|
||||||
# See: https://github.com/golang/go/issues/12933
|
# See: https://github.com/golang/go/issues/12933
|
||||||
- bash scripts/gogetcookie.sh
|
- bash scripts/gogetcookie.sh
|
||||||
- go get github.com/kardianos/govendor
|
- go get github.com/kardianos/govendor
|
||||||
|
- sudo sed 's/DOCKER_OPTS="/DOCKER_OPTS="--insecure-registry=127.0.0.1:5000 /g' -i /etc/default/docker
|
||||||
|
- sudo cat /etc/default/docker
|
||||||
|
- sudo service docker restart
|
||||||
|
|
||||||
script:
|
script:
|
||||||
- make test
|
- make test
|
||||||
|
- make testacc
|
||||||
- make vendor-status
|
- make vendor-status
|
||||||
- make vet
|
- make vet
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -12,7 +12,7 @@ test: fmtcheck
|
||||||
xargs -t -n4 go test $(TESTARGS) -timeout=30s -parallel=4
|
xargs -t -n4 go test $(TESTARGS) -timeout=30s -parallel=4
|
||||||
|
|
||||||
testacc: fmtcheck
|
testacc: fmtcheck
|
||||||
TF_ACC=1 go test $(TEST) -v $(TESTARGS) -timeout 120m
|
@sh -c "'$(CURDIR)/scripts/runAccTests.sh'"
|
||||||
|
|
||||||
vet:
|
vet:
|
||||||
@echo "go vet ."
|
@echo "go vet ."
|
||||||
|
|
|
||||||
|
|
@ -1,11 +1,14 @@
|
||||||
package docker
|
package docker
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"crypto/tls"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"net/http"
|
"net/http"
|
||||||
"net/url"
|
"net/url"
|
||||||
|
"os"
|
||||||
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/hashicorp/terraform/helper/schema"
|
"github.com/hashicorp/terraform/helper/schema"
|
||||||
|
|
@ -60,10 +63,13 @@ func dataSourceDockerRegistryImageRead(d *schema.ResourceData, meta interface{})
|
||||||
password = auth.Password
|
password = auth.Password
|
||||||
}
|
}
|
||||||
|
|
||||||
digest, err := getImageDigest(pullOpts.Registry, pullOpts.Repository, pullOpts.Tag, username, password)
|
digest, err := getImageDigest(pullOpts.Registry, pullOpts.Repository, pullOpts.Tag, username, password, false)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("Got error when attempting to fetch image version from registry: %s", err)
|
digest, err = getImageDigest(pullOpts.Registry, pullOpts.Repository, pullOpts.Tag, username, password, true)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("Got error when attempting to fetch image version from registry: %s", err)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
d.SetId(digest)
|
d.SetId(digest)
|
||||||
|
|
@ -72,11 +78,23 @@ func dataSourceDockerRegistryImageRead(d *schema.ResourceData, meta interface{})
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func getImageDigest(registry, image, tag, username, password string) (string, error) {
|
func getImageDigest(registry, image, tag, username, password string, fallback bool) (string, error) {
|
||||||
client := http.DefaultClient
|
client := http.DefaultClient
|
||||||
|
|
||||||
req, err := http.NewRequest("GET", "https://"+registry+"/v2/"+image+"/manifests/"+tag, nil)
|
// Allow insecure registries only for ACC tests
|
||||||
|
// cuz we don't have a valid certs for this case
|
||||||
|
if env, okEnv := os.LookupEnv("TF_ACC"); okEnv {
|
||||||
|
if i, errConv := strconv.Atoi(env); errConv == nil && i >= 1 {
|
||||||
|
cfg := &tls.Config{
|
||||||
|
InsecureSkipVerify: true,
|
||||||
|
}
|
||||||
|
client.Transport = &http.Transport{
|
||||||
|
TLSClientConfig: cfg,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
req, err := http.NewRequest("GET", "https://"+registry+"/v2/"+image+"/manifests/"+tag, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", fmt.Errorf("Error creating registry request: %s", err)
|
return "", fmt.Errorf("Error creating registry request: %s", err)
|
||||||
}
|
}
|
||||||
|
|
@ -87,6 +105,10 @@ func getImageDigest(registry, image, tag, username, password string) (string, er
|
||||||
|
|
||||||
// Set this header so that we get the v2 manifest back from the registry.
|
// Set this header so that we get the v2 manifest back from the registry.
|
||||||
req.Header.Set("Accept", "application/vnd.docker.distribution.manifest.v2+json")
|
req.Header.Set("Accept", "application/vnd.docker.distribution.manifest.v2+json")
|
||||||
|
if fallback {
|
||||||
|
// Fallback to this header if the registry does not support the v2 manifest like gcr.io
|
||||||
|
req.Header.Set("Accept", "application/vnd.docker.distribution.manifest.v1+prettyjws")
|
||||||
|
}
|
||||||
|
|
||||||
resp, err := client.Do(req)
|
resp, err := client.Do(req)
|
||||||
|
|
||||||
|
|
@ -153,7 +175,7 @@ func getImageDigest(registry, image, tag, username, password string) (string, er
|
||||||
return "", fmt.Errorf("Bad credentials: " + resp.Status)
|
return "", fmt.Errorf("Bad credentials: " + resp.Status)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Some unexpected status was given, return an error
|
// Some unexpected status was given, return an error
|
||||||
default:
|
default:
|
||||||
return "", fmt.Errorf("Got bad response from registry: " + resp.Status)
|
return "", fmt.Errorf("Got bad response from registry: " + resp.Status)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -195,12 +195,12 @@ func TestAccDockerContainer_customized(t *testing.T) {
|
||||||
return fmt.Errorf("Container does not have correct number of extra host entries, got %d", len(c.HostConfig.ExtraHosts))
|
return fmt.Errorf("Container does not have correct number of extra host entries, got %d", len(c.HostConfig.ExtraHosts))
|
||||||
}
|
}
|
||||||
|
|
||||||
if c.HostConfig.ExtraHosts[0] != "testhost2:10.0.2.0" {
|
if c.HostConfig.ExtraHosts[0] != "testhost:10.0.1.0" {
|
||||||
return fmt.Errorf("Container has incorrect extra host string: %q", c.HostConfig.ExtraHosts[0])
|
return fmt.Errorf("Container has incorrect extra host string at 0: %q", c.HostConfig.ExtraHosts[0])
|
||||||
}
|
}
|
||||||
|
|
||||||
if c.HostConfig.ExtraHosts[1] != "testhost:10.0.1.0" {
|
if c.HostConfig.ExtraHosts[1] != "testhost2:10.0.2.0" {
|
||||||
return fmt.Errorf("Container has incorrect extra host string: %q", c.HostConfig.ExtraHosts[1])
|
return fmt.Errorf("Container has incorrect extra host string at 1: %q", c.HostConfig.ExtraHosts[1])
|
||||||
}
|
}
|
||||||
|
|
||||||
if _, ok := c.NetworkSettings.Networks["test"]; !ok {
|
if _, ok := c.NetworkSettings.Networks["test"]; !ok {
|
||||||
|
|
|
||||||
|
|
@ -195,6 +195,7 @@ data "docker_registry_image" "foo_private" {
|
||||||
resource "docker_image" "foo_private" {
|
resource "docker_image" "foo_private" {
|
||||||
provider = "docker.private"
|
provider = "docker.private"
|
||||||
name = "${data.docker_registry_image.foo_private.name}"
|
name = "${data.docker_registry_image.foo_private.name}"
|
||||||
|
keep_locally = true
|
||||||
pull_triggers = ["${data.docker_registry_image.foo_private.sha256_digest}"]
|
pull_triggers = ["${data.docker_registry_image.foo_private.sha256_digest}"]
|
||||||
}
|
}
|
||||||
`
|
`
|
||||||
|
|
|
||||||
57
scripts/runAccTests.sh
Executable file
57
scripts/runAccTests.sh
Executable file
|
|
@ -0,0 +1,57 @@
|
||||||
|
#!/bin/bash
|
||||||
|
set -e
|
||||||
|
|
||||||
|
log() {
|
||||||
|
echo ""
|
||||||
|
echo "##################################"
|
||||||
|
echo "-------> $1"
|
||||||
|
echo "##################################"
|
||||||
|
}
|
||||||
|
|
||||||
|
setup() {
|
||||||
|
export DOCKER_REGISTRY_ADDRESS="127.0.0.1:5000"
|
||||||
|
export DOCKER_REGISTRY_USER="testuser"
|
||||||
|
export DOCKER_REGISTRY_PASS="testpwd"
|
||||||
|
export DOCKER_PRIVATE_IMAGE="127.0.0.1:5000/my-private-service:v1"
|
||||||
|
sh scripts/testing/setup_private_registry.sh
|
||||||
|
}
|
||||||
|
|
||||||
|
run() {
|
||||||
|
# Run the acc test suite
|
||||||
|
TF_ACC=1 go test ./docker -v -timeout 120m
|
||||||
|
|
||||||
|
# for a single test
|
||||||
|
# TF_LOG=INFO TF_ACC=1 go test -v github.com/terraform-providers/terraform-provider-docker/docker -run ^TestAccDockerContainer_basic$ -timeout 360s
|
||||||
|
|
||||||
|
# keep the return for the scripts to fail and clean properly
|
||||||
|
return $?
|
||||||
|
}
|
||||||
|
|
||||||
|
cleanup() {
|
||||||
|
unset DOCKER_REGISTRY_ADDRESS DOCKER_REGISTRY_USER DOCKER_REGISTRY_PASS DOCKER_PRIVATE_IMAGE
|
||||||
|
echo "### unsetted env ###"
|
||||||
|
rm -f scripts/testing/auth/htpasswd
|
||||||
|
rm -f scripts/testing/certs/registry_auth.*
|
||||||
|
echo "### removed auth and certs ###"
|
||||||
|
docker stop private_registry
|
||||||
|
echo "### stopped private registry ###"
|
||||||
|
docker rmi -f $(docker images -aq 127.0.0.1:5000/my-private-service)
|
||||||
|
echo "### removed my-private-service images ###"
|
||||||
|
# consider running this manually to clean up the
|
||||||
|
# updateabe configs and secrets
|
||||||
|
#docker config rm $(docker config ls -q)
|
||||||
|
#docker secret rm $(docker secret ls -q)
|
||||||
|
}
|
||||||
|
|
||||||
|
## main
|
||||||
|
log "setup" && setup
|
||||||
|
log "run" && run && echo $?
|
||||||
|
if [ $? -ne 0 ]; then
|
||||||
|
log "cleanup" && cleanup
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
# we only clean on local envs. travis fails from time to time there
|
||||||
|
# cuz it cannot remove the images
|
||||||
|
if [ "$TRAVIS" != "true" ]; then
|
||||||
|
log "cleanup" && cleanup
|
||||||
|
fi
|
||||||
6
scripts/testing/Dockerfile_v1
Normal file
6
scripts/testing/Dockerfile_v1
Normal file
|
|
@ -0,0 +1,6 @@
|
||||||
|
FROM node:6.12.3-slim
|
||||||
|
EXPOSE 8080
|
||||||
|
COPY configs.json .
|
||||||
|
COPY secrets.json .
|
||||||
|
COPY server.js .
|
||||||
|
CMD node server.js
|
||||||
6
scripts/testing/Dockerfile_v2
Normal file
6
scripts/testing/Dockerfile_v2
Normal file
|
|
@ -0,0 +1,6 @@
|
||||||
|
FROM node:6.12.3-slim
|
||||||
|
EXPOSE 8080
|
||||||
|
COPY configs.json .
|
||||||
|
COPY secrets.json .
|
||||||
|
COPY server_v2.js .
|
||||||
|
CMD node server_v2.js
|
||||||
3
scripts/testing/configs.json
Normal file
3
scripts/testing/configs.json
Normal file
|
|
@ -0,0 +1,3 @@
|
||||||
|
{
|
||||||
|
"prefix": "123"
|
||||||
|
}
|
||||||
3
scripts/testing/secrets.json
Normal file
3
scripts/testing/secrets.json
Normal file
|
|
@ -0,0 +1,3 @@
|
||||||
|
{
|
||||||
|
"key": "QWERTY"
|
||||||
|
}
|
||||||
17
scripts/testing/server.js
Normal file
17
scripts/testing/server.js
Normal file
|
|
@ -0,0 +1,17 @@
|
||||||
|
var http = require('http');
|
||||||
|
var configs = require('./configs')
|
||||||
|
var secrets = require('./secrets')
|
||||||
|
|
||||||
|
var handleRequest = function(request, response) {
|
||||||
|
console.log('Received request for URL: ' + request.url);
|
||||||
|
|
||||||
|
if(request.url === '/health') {
|
||||||
|
response.writeHead(200);
|
||||||
|
response.end('ok');
|
||||||
|
} else {
|
||||||
|
response.writeHead(200);
|
||||||
|
response.end(configs.prefix + ' - Hello World!');
|
||||||
|
}
|
||||||
|
};
|
||||||
|
var www = http.createServer(handleRequest);
|
||||||
|
www.listen(8080);
|
||||||
20
scripts/testing/server_v2.js
Normal file
20
scripts/testing/server_v2.js
Normal file
|
|
@ -0,0 +1,20 @@
|
||||||
|
var http = require('http');
|
||||||
|
var configs = require('./configs')
|
||||||
|
var secrets = require('./secrets')
|
||||||
|
|
||||||
|
var handleRequest = function(request, response) {
|
||||||
|
console.log('Received request for URL: ' + request.url);
|
||||||
|
|
||||||
|
if(request.url === '/health') {
|
||||||
|
response.writeHead(200);
|
||||||
|
response.end('ok');
|
||||||
|
} else if(request.url === '/newroute') {
|
||||||
|
response.writeHead(200);
|
||||||
|
response.end('new Route!');
|
||||||
|
} else {
|
||||||
|
response.writeHead(200);
|
||||||
|
response.end(configs.prefix + ' - Hello World!');
|
||||||
|
}
|
||||||
|
};
|
||||||
|
var www = http.createServer(handleRequest);
|
||||||
|
www.listen(8080);
|
||||||
38
scripts/testing/setup_private_registry.sh
Executable file
38
scripts/testing/setup_private_registry.sh
Executable file
|
|
@ -0,0 +1,38 @@
|
||||||
|
set -e
|
||||||
|
|
||||||
|
# Create private registry
|
||||||
|
## Create self signed certs
|
||||||
|
mkdir -p scripts/testing/certs
|
||||||
|
openssl req \
|
||||||
|
-newkey rsa:2048 \
|
||||||
|
-nodes \
|
||||||
|
-x509 \
|
||||||
|
-days 365 \
|
||||||
|
-subj "/C=US/ST=Denial/L=Springfield/O=Dis/CN=127.0.0.1" \
|
||||||
|
-keyout scripts/testing/certs/registry_auth.key \
|
||||||
|
-out scripts/testing/certs/registry_auth.crt
|
||||||
|
## Create auth
|
||||||
|
mkdir -p scripts/testing/auth
|
||||||
|
# Start registry
|
||||||
|
docker run --entrypoint htpasswd registry:2 -Bbn testuser testpwd > scripts/testing/auth/htpasswd
|
||||||
|
docker run -d -p 5000:5000 --rm --name private_registry \
|
||||||
|
-v "$(pwd)"/scripts/testing/auth:/auth \
|
||||||
|
-e "REGISTRY_AUTH=htpasswd" \
|
||||||
|
-e "REGISTRY_AUTH_HTPASSWD_REALM=Registry Realm" \
|
||||||
|
-e "REGISTRY_AUTH_HTPASSWD_PATH=/auth/htpasswd" \
|
||||||
|
-v "$(pwd)"/scripts/testing/certs:/certs \
|
||||||
|
-e "REGISTRY_HTTP_TLS_CERTIFICATE=/certs/registry_auth.crt" \
|
||||||
|
-e "REGISTRY_HTTP_TLS_KEY=/certs/registry_auth.key" \
|
||||||
|
registry:2
|
||||||
|
# wait a bit for travis...
|
||||||
|
sleep 5
|
||||||
|
# Login to private registry
|
||||||
|
docker login -u testuser -p testpwd 127.0.0.1:5000
|
||||||
|
# Build private images
|
||||||
|
docker build -t my-private-service ./scripts/testing -f ./scripts/testing/Dockerfile_v1
|
||||||
|
docker tag my-private-service 127.0.0.1:5000/my-private-service:v1
|
||||||
|
docker build -t my-private-service ./scripts/testing -f ./scripts/testing/Dockerfile_v2
|
||||||
|
docker tag my-private-service 127.0.0.1:5000/my-private-service:v2
|
||||||
|
# Push private images into private registry
|
||||||
|
docker push 127.0.0.1:5000/my-private-service:v1
|
||||||
|
docker push 127.0.0.1:5000/my-private-service:v2
|
||||||
Loading…
Reference in a new issue