diff --git a/test/integration/docker-compose.yml b/test/integration/docker-compose.yml index 01b5152f..da67f164 100644 --- a/test/integration/docker-compose.yml +++ b/test/integration/docker-compose.yml @@ -50,8 +50,19 @@ services: volumes: - shared:/shared + vm3: + privileged: true + build: + context: docker/vm + volumes: + - shared:/shared + load_balancer: build: context: docker/load_balancer ports: - "12345:80" + depends_on: + - vm1 + - vm2 + - vm3 diff --git a/test/integration/docker/deployer/Dockerfile b/test/integration/docker/deployer/Dockerfile index 2b49fcb0..bb6b462a 100644 --- a/test/integration/docker/deployer/Dockerfile +++ b/test/integration/docker/deployer/Dockerfile @@ -1,6 +1,6 @@ FROM ruby:3.2 -WORKDIR /app +WORKDIR / ENV VERBOSE=true @@ -17,7 +17,8 @@ RUN echo \ RUN apt-get update --fix-missing && apt-get install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin COPY *.sh . -COPY app/ . +COPY app/ app/ +COPY app_with_roles/ app_with_roles/ RUN rm -rf /root/.ssh RUN ln -s /shared/ssh /root/.ssh @@ -25,7 +26,8 @@ RUN mkdir -p /etc/docker/certs.d/registry:4443 && ln -s /shared/certs/domain.crt RUN git config --global user.email "deployer@example.com" RUN git config --global user.name "Deployer" -RUN git init && echo ".env" >> .gitignore && git add . && git commit -am "Initial version" +RUN cd app && git init && echo ".env" >> .gitignore && git add . && git commit -am "Initial version" +RUN cd app_with_roles && git init && echo ".env" >> .gitignore && git add . && git commit -am "Initial version" HEALTHCHECK --interval=1s CMD pgrep sleep diff --git a/test/integration/docker/deployer/app_with_roles/.env.erb b/test/integration/docker/deployer/app_with_roles/.env.erb new file mode 100644 index 00000000..dcd2fcf5 --- /dev/null +++ b/test/integration/docker/deployer/app_with_roles/.env.erb @@ -0,0 +1 @@ +SECRET_TOKEN=1234 diff --git a/test/integration/docker/deployer/app_with_roles/.kamal/hooks/docker-setup b/test/integration/docker/deployer/app_with_roles/.kamal/hooks/docker-setup new file mode 100755 index 00000000..2c218dc5 --- /dev/null +++ b/test/integration/docker/deployer/app_with_roles/.kamal/hooks/docker-setup @@ -0,0 +1,3 @@ +#!/bin/sh +echo "Docker set up!" +mkdir -p /tmp/${TEST_ID} && touch /tmp/${TEST_ID}/docker-setup diff --git a/test/integration/docker/deployer/app_with_roles/.kamal/hooks/post-deploy b/test/integration/docker/deployer/app_with_roles/.kamal/hooks/post-deploy new file mode 100755 index 00000000..0fcc6920 --- /dev/null +++ b/test/integration/docker/deployer/app_with_roles/.kamal/hooks/post-deploy @@ -0,0 +1,3 @@ +#!/bin/sh +echo "Deployed!" +mkdir -p /tmp/${TEST_ID} && touch /tmp/${TEST_ID}/post-deploy diff --git a/test/integration/docker/deployer/app_with_roles/.kamal/hooks/post-traefik-reboot b/test/integration/docker/deployer/app_with_roles/.kamal/hooks/post-traefik-reboot new file mode 100755 index 00000000..598ddb63 --- /dev/null +++ b/test/integration/docker/deployer/app_with_roles/.kamal/hooks/post-traefik-reboot @@ -0,0 +1,3 @@ +#!/bin/sh +echo "Rebooted Traefik on ${KAMAL_HOSTS}" +mkdir -p /tmp/${TEST_ID} && touch /tmp/${TEST_ID}/post-traefik-reboot diff --git a/test/integration/docker/deployer/app_with_roles/.kamal/hooks/pre-build b/test/integration/docker/deployer/app_with_roles/.kamal/hooks/pre-build new file mode 100755 index 00000000..0cf78d88 --- /dev/null +++ b/test/integration/docker/deployer/app_with_roles/.kamal/hooks/pre-build @@ -0,0 +1,3 @@ +#!/bin/sh +echo "About to build and push..." +mkdir -p /tmp/${TEST_ID} && touch /tmp/${TEST_ID}/pre-build diff --git a/test/integration/docker/deployer/app_with_roles/.kamal/hooks/pre-connect b/test/integration/docker/deployer/app_with_roles/.kamal/hooks/pre-connect new file mode 100755 index 00000000..10095286 --- /dev/null +++ b/test/integration/docker/deployer/app_with_roles/.kamal/hooks/pre-connect @@ -0,0 +1,8 @@ +#!/bin/sh + +echo "About to lock..." +if [ "$KAMAL_HOSTS" != "vm1,vm2,vm3" ]; then + echo "Expected hosts to be 'vm1,vm2,vm3', got $KAMAL_HOSTS" + exit 1 +fi +mkdir -p /tmp/${TEST_ID} && touch /tmp/${TEST_ID}/pre-connect diff --git a/test/integration/docker/deployer/app_with_roles/.kamal/hooks/pre-deploy b/test/integration/docker/deployer/app_with_roles/.kamal/hooks/pre-deploy new file mode 100755 index 00000000..32fa04c6 --- /dev/null +++ b/test/integration/docker/deployer/app_with_roles/.kamal/hooks/pre-deploy @@ -0,0 +1,3 @@ +#!/bin/sh +echo "Deployed!" +mkdir -p /tmp/${TEST_ID} && touch /tmp/${TEST_ID}/pre-deploy diff --git a/test/integration/docker/deployer/app_with_roles/.kamal/hooks/pre-traefik-reboot b/test/integration/docker/deployer/app_with_roles/.kamal/hooks/pre-traefik-reboot new file mode 100755 index 00000000..81269d24 --- /dev/null +++ b/test/integration/docker/deployer/app_with_roles/.kamal/hooks/pre-traefik-reboot @@ -0,0 +1,3 @@ +#!/bin/sh +echo "Rebooting Traefik on ${KAMAL_HOSTS}..." +mkdir -p /tmp/${TEST_ID} && touch /tmp/${TEST_ID}/pre-traefik-reboot diff --git a/test/integration/docker/deployer/app_with_roles/Dockerfile b/test/integration/docker/deployer/app_with_roles/Dockerfile new file mode 100644 index 00000000..dc270aa9 --- /dev/null +++ b/test/integration/docker/deployer/app_with_roles/Dockerfile @@ -0,0 +1,9 @@ +FROM registry:4443/nginx:1-alpine-slim + +COPY default.conf /etc/nginx/conf.d/default.conf + +ARG COMMIT_SHA +RUN echo $COMMIT_SHA > /usr/share/nginx/html/version +RUN mkdir -p /usr/share/nginx/html/versions && echo "version" > /usr/share/nginx/html/versions/$COMMIT_SHA +RUN mkdir -p /usr/share/nginx/html/versions && echo "hidden" > /usr/share/nginx/html/versions/.hidden + diff --git a/test/integration/docker/deployer/app_with_roles/config/deploy.yml b/test/integration/docker/deployer/app_with_roles/config/deploy.yml new file mode 100644 index 00000000..004ffb25 --- /dev/null +++ b/test/integration/docker/deployer/app_with_roles/config/deploy.yml @@ -0,0 +1,37 @@ +service: app +image: app +servers: + web: + hosts: + - vm1 + - vm2 + workers: + hosts: + - vm3 + cmd: sleep infinity + +asset_path: /usr/share/nginx/html/versions + +registry: + server: registry:4443 + username: root + password: root +builder: + multiarch: false + args: + COMMIT_SHA: <%= `git rev-parse HEAD` %> +healthcheck: + cmd: wget -qO- http://localhost > /dev/null || exit 1 +traefik: + args: + accesslog: true + accesslog.format: json + image: registry:4443/traefik:v2.10 +accessories: + busybox: + service: custom-busybox + image: registry:4443/busybox:1.36.0 + cmd: sh -c 'echo "Starting busybox..."; trap exit term; while true; do sleep 1; done' + roles: + - web +stop_wait_time: 1 diff --git a/test/integration/docker/deployer/app_with_roles/default.conf b/test/integration/docker/deployer/app_with_roles/default.conf new file mode 100644 index 00000000..e37a9bc1 --- /dev/null +++ b/test/integration/docker/deployer/app_with_roles/default.conf @@ -0,0 +1,17 @@ +server { + listen 80; + listen [::]:80; + server_name localhost; + + location / { + root /usr/share/nginx/html; + index index.html index.htm; + } + + # redirect server error pages to the static page /50x.html + # + error_page 500 502 503 504 /50x.html; + location = /50x.html { + root /usr/share/nginx/html; + } +} diff --git a/test/integration/docker/deployer/update_app_rev.sh b/test/integration/docker/deployer/update_app_rev.sh index db7fd220..4214ffb2 100755 --- a/test/integration/docker/deployer/update_app_rev.sh +++ b/test/integration/docker/deployer/update_app_rev.sh @@ -1,3 +1,3 @@ #!/bin/bash -git commit -am 'Update rev' --amend +cd $1 && git commit -am 'Update rev' --amend diff --git a/test/integration/integration_test.rb b/test/integration/integration_test.rb index 251e9641..bd62c474 100644 --- a/test/integration/integration_test.rb +++ b/test/integration/integration_test.rb @@ -7,6 +7,7 @@ class IntegrationTest < ActiveSupport::TestCase docker_compose "up --build -d" wait_for_healthy setup_deployer + @app = "app" end teardown do @@ -34,8 +35,9 @@ class IntegrationTest < ActiveSupport::TestCase result end - def deployer_exec(*commands, **options) - docker_compose("exec deployer #{commands.join(" ")}", **options) + def deployer_exec(*commands, workdir: nil, **options) + workdir ||= "/#{@app}" + docker_compose("exec --workdir #{workdir} deployer #{commands.join(" ")}", **options) end def kamal(*commands, **options) @@ -72,7 +74,7 @@ class IntegrationTest < ActiveSupport::TestCase end def update_app_rev - deployer_exec "./update_app_rev.sh" + deployer_exec "./update_app_rev.sh #{@app}", workdir: "/" latest_app_version end @@ -115,7 +117,7 @@ class IntegrationTest < ActiveSupport::TestCase end def setup_deployer - deployer_exec("./setup.sh") unless $DEPLOYER_SETUP + deployer_exec("./setup.sh", workdir: "/") unless $DEPLOYER_SETUP $DEPLOYER_SETUP = true end diff --git a/test/integration/main_test.rb b/test/integration/main_test.rb index 22f60860..7c858a17 100644 --- a/test/integration/main_test.rb +++ b/test/integration/main_test.rb @@ -42,6 +42,22 @@ class MainTest < IntegrationTest assert_no_remote_env_file end + test "app with roles" do + @app = "app_with_roles" + + kamal :envify + + version = latest_app_version + + assert_app_is_down + + kamal :deploy + + assert_app_is_up version: version + assert_hooks_ran "pre-connect", "pre-build", "pre-deploy", "post-deploy" + assert_container_running host: :vm3, name: "app-workers-#{version}" + end + test "config" do config = YAML.load(kamal(:config, capture: true)) version = latest_app_version @@ -115,4 +131,8 @@ class MainTest < IntegrationTest assert vm1_image_ids.any? assert vm1_container_ids.any? end + + def assert_container_running(host:, name:) + assert docker_compose("exec #{host} docker ps --filter=name=#{name} -q", capture: true).strip.present? + end end