From 6abbd065d3e2bf56300ba5fa9a47f0c8e4dfea2a Mon Sep 17 00:00:00 2001 From: Morgan Rhodes Date: Thu, 2 May 2019 13:25:07 -0700 Subject: [PATCH 1/2] Refactor puppetserver container tests This updates the puppetserver tests to use `docker-compose` instead of `docker-run`. This also updates the tests to use the shared testing gem from github.com/puppetlabs/pupperware. This also includes a move from the puppet-agent-alpine to puppet-agent-ubuntu for testing. We were seeing a lot of intermittent network failures with the alpine container on windows (LCOW). See https://github.com/docker/libnetwork/issues/2371 and https://github.com/Microsoft/opengcs/issues/303 have more information on this issue. This should hopefully clear up the intermittent name resolution failures we were seeing. --- .travis.yml | 22 +++++- docker/Gemfile | 4 + docker/Makefile | 12 ++- docker/docker-compose.yml | 32 ++++++++ docker/puppetserver-standalone/.rspec | 1 - docker/puppetserver/.rspec | 1 - docker/spec/puppetserver_spec.rb | 103 ++++++-------------------- docker/spec/spec_helper.rb | 22 ------ 8 files changed, 87 insertions(+), 110 deletions(-) create mode 100644 docker/docker-compose.yml delete mode 100644 docker/spec/spec_helper.rb diff --git a/.travis.yml b/.travis.yml index 9056bfa384..0ee716d96f 100644 --- a/.travis.yml +++ b/.travis.yml @@ -3,6 +3,10 @@ lein: 2.8.1 dist: trusty # see https://www.deps.co/guides/travis-ci-latest-java/ certificate issues sudo: required + +services: + - docker + script: - ./ext/travisci/test.sh - $TRAVIS_BUILD_DIR/ext/travisci/secscan.sh "$TRAVIS_BUILD_DIR/src/clj" "clj" @@ -13,9 +17,23 @@ matrix: - stage: puppetserver tests jdk: openjdk8 - stage: puppetserver container tests - language: generic + language: ruby + rvm: 2.5.5 + env: + - DOCKER_COMPOSE_VERSION=1.24.0 script: - - cd docker && make lint && make build && make test + - | + set -ex + sudo rm /usr/local/bin/docker-compose + curl --location https://github.com/docker/compose/releases/download/${DOCKER_COMPOSE_VERSION}/docker-compose-`uname --kernel-name`-`uname --machine` > docker-compose + chmod +x docker-compose + sudo mv docker-compose /usr/local/bin + cd docker + make lint + make build + make test + set +x + notifications: email: false hipchat: diff --git a/docker/Gemfile b/docker/Gemfile index a8b8d52efa..ca4fc64e6e 100644 --- a/docker/Gemfile +++ b/docker/Gemfile @@ -12,3 +12,7 @@ end gem 'rspec' gem 'rspec_junit_formatter' +gem 'pupperware', + :git => 'https://github.com/puppetlabs/pupperware.git', + :ref => 'master', + :glob => 'gem/*.gemspec' diff --git a/docker/Makefile b/docker/Makefile index 45f962628e..4da5cb705d 100644 --- a/docker/Makefile +++ b/docker/Makefile @@ -5,6 +5,10 @@ build_date := $(shell date -u +%FT%T) hadolint_available := $(shell hadolint --help > /dev/null 2>&1; echo $$?) hadolint_command := hadolint --ignore DL3008 --ignore DL3018 --ignore DL4000 --ignore DL4001 hadolint_container := hadolint/hadolint:latest +pwd := $(shell pwd) +export BUNDLE_PATH = $(pwd)/.bundle/gems +export BUNDLE_BIN = $(pwd)/.bundle/bin +export GEMFILE = $(pwd)/Gemfile version = $(shell echo $(git_describe) | sed 's/-.*//') dockerfile := Dockerfile @@ -53,11 +57,13 @@ ifeq ($(IS_LATEST),true) endif test: prep - @bundle install --path .bundle/gems + @bundle install --path $$BUNDLE_PATH --gemfile $$GEMFILE @PUPPET_TEST_DOCKER_IMAGE=$(NAMESPACE)/puppetserver-standalone:$(version) \ - bundle exec rspec --options puppetserver-standalone/.rspec spec + bundle exec --gemfile $$GEMFILE \ + rspec --options puppetserver-standalone/.rspec spec @PUPPET_TEST_DOCKER_IMAGE=$(NAMESPACE)/puppetserver:$(version) \ - bundle exec rspec --options puppetserver/.rspec spec + bundle exec --gemfile $$GEMFILE \ + rspec --options puppetserver/.rspec spec push-image: prep @docker push puppet/puppetserver-standalone:$(version) diff --git a/docker/docker-compose.yml b/docker/docker-compose.yml new file mode 100644 index 0000000000..ac29761552 --- /dev/null +++ b/docker/docker-compose.yml @@ -0,0 +1,32 @@ +version: '3.5' + +services: + puppet: + hostname: puppet.test + image: ${PUPPET_TEST_DOCKER_IMAGE:-puppet/puppetserver-standalone} + environment: + - PUPPETSERVER_HOSTNAME=puppet.test + - PUPPERWARE_ANALYTICS_ENABLED=${PUPPERWARE_ANALYTICS_ENABLED:-false} + - DNS_ALT_NAMES=puppet,puppet.test,${DNS_ALT_NAMES:-} + dns_search: '.test' + networks: + puppetserver_test: + aliases: + - puppet.test + + compiler: + hostname: compiler.test + image: ${PUPPET_TEST_DOCKER_IMAGE:-puppet/puppetserver-standalone} + environment: + - PUPPERWARE_ANALYTICS_ENABLED=${PUPPERWARE_ANALYTICS_ENABLED:-false} + - CA_ENABLED=false + - CA_HOSTNAME=puppet.test + dns_search: '.test' + networks: + puppetserver_test: + aliases: + - compiler.test + +networks: + puppetserver_test: + name: puppetserver_test diff --git a/docker/puppetserver-standalone/.rspec b/docker/puppetserver-standalone/.rspec index 76e31a667f..409f24e240 100644 --- a/docker/puppetserver-standalone/.rspec +++ b/docker/puppetserver-standalone/.rspec @@ -1,4 +1,3 @@ ---require spec_helper --format RspecJunitFormatter --out puppetserver-standalone/TEST-rspec.xml --format documentation diff --git a/docker/puppetserver/.rspec b/docker/puppetserver/.rspec index 5f7ad7b5ac..16164127c6 100644 --- a/docker/puppetserver/.rspec +++ b/docker/puppetserver/.rspec @@ -1,4 +1,3 @@ ---require spec_helper --format RspecJunitFormatter --out puppetserver/TEST-rspec.xml --format documentation diff --git a/docker/spec/puppetserver_spec.rb b/docker/spec/puppetserver_spec.rb index d58feff8db..f648dc781b 100644 --- a/docker/spec/puppetserver_spec.rb +++ b/docker/spec/puppetserver_spec.rb @@ -2,115 +2,56 @@ require 'rspec/core' require 'open3' +require 'pupperware/spec_helper' describe 'puppetserver container' do - include Helpers - - def puppetserver_health_check(container) - empty_response_counter = 0 - status = '' - - # We intermittently get an empty response from the `docker inspect` - # but we don't want this to run forever if the container failed, so - # assume that 5 empty responses in a row is a failure case - while status.empty? && empty_response_counter < 5 - result = run_command("docker inspect \"#{container}\" --format '{{.State.Health.Status}}'") - status = result[:stdout].chomp - if status.empty? - empty_response_counter += 1 - sleep 1 - end - STDOUT.puts "queried health status of #{container}: #{status}" - end - - return status - end + include Pupperware::SpecHelpers before(:all) do - run_command('docker pull puppet/puppet-agent-alpine:latest') - @image = ENV['PUPPET_TEST_DOCKER_IMAGE'] - if @image.nil? + run_command('docker pull puppet/puppet-agent-ubuntu:latest') + if ENV['PUPPET_TEST_DOCKER_IMAGE'].nil? + fail <<-MSG error_message = <<-MSG -* * * * * + * * * * * PUPPET_TEST_DOCKER_IMAGE environment variable must be set so we know which image to test against! -* * * * * + * * * * * MSG - fail error_message - end + end - # Windows doesn't have the default 'bridge' network driver - network_opt = File::ALT_SEPARATOR.nil? ? '' : '--driver=nat' - - result = run_command("docker network create #{network_opt} puppetserver_test_network") - fail 'Failed to create network' unless result[:status].exitstatus == 0 - @network = result[:stdout].chomp + status = run_command('docker-compose --no-ansi version')[:status] + if status.exitstatus != 0 + fail "`docker-compose` must be installed and available in your PATH" + end - result = run_command("docker run --rm --detach \ - --env DNS_ALT_NAMES=puppet \ - --env PUPPERWARE_ANALYTICS_ENABLED=false \ - --name puppet.test \ - --network #{@network} \ - --hostname puppet.test \ - #{@image}") - fail 'Failed to create puppet.test' unless result[:status].exitstatus == 0 - @container = result[:stdout].chomp + teardown_cluster() - result = run_command("docker run --rm --detach \ - --env DNS_ALT_NAMES=puppet \ - --env PUPPERWARE_ANALYTICS_ENABLED=false \ - --env CA_ENABLED=false \ - --env CA_HOSTNAME=puppet.test \ - --network #{@network} \ - --name puppet-compiler.test \ - --hostname puppet-compiler.test \ - #{@image}") - fail 'Failed to create compiler' unless result[:status].exitstatus == 0 - @compiler = result[:stdout].chomp + run_command('docker-compose --no-ansi up --detach') end after(:all) do - run_command("docker container kill #{@container}") unless @container.nil? - run_command("docker container kill #{@compiler}") unless @compiler.nil? - run_command("docker network rm #{@network}") unless @network.nil? + emit_logs() + teardown_cluster() end it 'should start puppetserver successfully' do - status = puppetserver_health_check(@container) - while (status == 'starting' || status == "'starting'") - sleep(1) - status = puppetserver_health_check(@container) - end - if status !~ /\'?healthy\'?/ - run_command("docker logs #{@container}") - end - expect(status).to match(/\'?healthy\'?/) + expect(wait_on_puppetserver_status()).to eq ('healthy') end it 'should be able to run a puppet agent against the puppetserver' do - result = run_command("docker run --rm --name puppet-agent.test --hostname puppet-agent.test --network #{@network} puppet/puppet-agent-alpine:latest agent --test --server puppet.test") - expect(result[:status].exitstatus).to eq(0) + expect(run_agent('puppet-agent.test', 'puppetserver_test')).to eq(0) end it 'should be able to start a compile master' do - status = puppetserver_health_check(@compiler) - while (status == 'starting' || status == "'starting'") - sleep(1) - status = puppetserver_health_check(@compiler) - end - if status !~ /\'?healthy\'?/ - run_command("docker logs #{@compiler}") - end - expect(status).to match(/\'?healthy\'?/) -end + expect(wait_on_puppetserver_status(180, 'compiler')).to eq ('healthy') + end it 'should be able to run an agent against the compile master' do - result = run_command("docker run --rm --name puppet-agent-compiler.test --hostname puppet-agent-compiler.test --network #{@network} puppet/puppet-agent-alpine:latest agent --test --server puppet-compiler.test --ca_server puppet.test") - expect(result[:status].exitstatus).to eq(0) + expect(run_agent('compiler-agent.test', 'puppetserver_test', get_container_hostname(get_service_container('compiler')), get_container_hostname(get_service_container('puppet')))).to eq(0) end it 'should have r10k available' do - result = run_command('docker exec puppet.test r10k --help') + result = run_command('docker-compose exec -T puppet r10k --help') expect(result[:status].exitstatus).to eq(0) end end diff --git a/docker/spec/spec_helper.rb b/docker/spec/spec_helper.rb deleted file mode 100644 index 097cfdb63a..0000000000 --- a/docker/spec/spec_helper.rb +++ /dev/null @@ -1,22 +0,0 @@ -require 'open3' - -module Helpers - def run_command(command) - stdout_string = '' - status = nil - - Open3.popen3(command) do |stdin, stdout, stderr, wait_thread| - Thread.new do - stdout.each { |l| stdout_string << l; STDOUT.puts l } - end - Thread.new do - stderr.each { |l| STDOUT.puts l } - end - - stdin.close - status = wait_thread.value - end - - { status: status, stdout: stdout_string } - end -end From aad85a07869b48eaf9dc89eedb71b6f6c926967f Mon Sep 17 00:00:00 2001 From: Morgan Rhodes Date: Fri, 3 May 2019 11:41:17 -0700 Subject: [PATCH 2/2] (maint) Make puppetdb more configurable This adds `PUPPET_STORECONFIGS_BACKEND`, `PUPPET_STORECONFIGS`, and `PUPPET_REPORTS` environment variables for configuring `storeconfigs_backend`, `storeconfigs`, and `reports` settings in puppet.conf. --- docker/docker-compose.yml | 4 ++++ .../docker-entrypoint.d/85-setup-storeconfigs.sh | 13 +++++++++++++ docker/puppetserver/Dockerfile | 3 +++ docker/puppetserver/README.md | 12 ++++++++++++ 4 files changed, 32 insertions(+) create mode 100644 docker/puppetserver-standalone/docker-entrypoint.d/85-setup-storeconfigs.sh diff --git a/docker/docker-compose.yml b/docker/docker-compose.yml index ac29761552..b7b896a37c 100644 --- a/docker/docker-compose.yml +++ b/docker/docker-compose.yml @@ -8,6 +8,8 @@ services: - PUPPETSERVER_HOSTNAME=puppet.test - PUPPERWARE_ANALYTICS_ENABLED=${PUPPERWARE_ANALYTICS_ENABLED:-false} - DNS_ALT_NAMES=puppet,puppet.test,${DNS_ALT_NAMES:-} + - PUPPET_STORECONFIGS=false + - PUPPET_REPORTS=log dns_search: '.test' networks: puppetserver_test: @@ -21,6 +23,8 @@ services: - PUPPERWARE_ANALYTICS_ENABLED=${PUPPERWARE_ANALYTICS_ENABLED:-false} - CA_ENABLED=false - CA_HOSTNAME=puppet.test + - PUPPET_STORECONFIGS=false + - PUPPET_REPORTS=log dns_search: '.test' networks: puppetserver_test: diff --git a/docker/puppetserver-standalone/docker-entrypoint.d/85-setup-storeconfigs.sh b/docker/puppetserver-standalone/docker-entrypoint.d/85-setup-storeconfigs.sh new file mode 100644 index 0000000000..65151fafa7 --- /dev/null +++ b/docker/puppetserver-standalone/docker-entrypoint.d/85-setup-storeconfigs.sh @@ -0,0 +1,13 @@ +#!/bin/sh + +if [ -n "$PUPPET_STORECONFIGS_BACKEND" ]; then + puppet config set storeconfigs_backend $PUPPET_STORECONFIGS_BACKEND --section master +fi + +if [ -n "$PUPPET_STORECONFIGS" ]; then + puppet config set storeconfigs $PUPPET_STORECONFIGS --section master +fi + +if [ -n "$PUPPET_REPORTS" ]; then + puppet config set reports $PUPPET_REPORTS --section master +fi diff --git a/docker/puppetserver/Dockerfile b/docker/puppetserver/Dockerfile index 645760dd8e..d3efb4d0ef 100644 --- a/docker/puppetserver/Dockerfile +++ b/docker/puppetserver/Dockerfile @@ -12,6 +12,9 @@ ENV PUPPERWARE_ANALYTICS_STREAM="$pupperware_analytics_stream" ENV PUPPERWARE_ANALYTICS_TRACKING_ID="UA-132486246-3" ENV PUPPERWARE_ANALYTICS_APP_NAME="puppetserver" ENV PUPPERWARE_ANALYTICS_ENABLED=false +ENV PUPPET_STORECONFIGS_BACKEND="puppetdb" +ENV PUPPET_STORECONFIGS=true +ENV PUPPET_REPORTS="puppetdb" LABEL org.label-schema.maintainer="Puppet Release Team " \ org.label-schema.vendor="Puppet" \ diff --git a/docker/puppetserver/README.md b/docker/puppetserver/README.md index 6a94e26f77..693a3d1e81 100644 --- a/docker/puppetserver/README.md +++ b/docker/puppetserver/README.md @@ -69,6 +69,18 @@ The following environment variables are supported: If consul is enabled, the port to access consul at. Defaults to '8500'. +- `PUPPET_REPORTS` + + Sets `reports` in puppet.conf. Defaults to 'puppetdb'. + +- `PUPPET_STORECONFIGS` + + Sets `storeconfigs` in puppet.conf. Defaults to true. + +- `PUPPET_STORECONFIGS_BACKEND` + + Sets `storeconfigs_backend` in puppet.conf. Defaults to 'puppetdb'. + - `PUPPETDB_SERVER_URLS` The `server_urls` to set in /etc/puppetlabs/puppet/puppetdb.conf. Defaults to 'https://puppetdb:8081'.