From 7fb04e409c4d0d045b3caa4f61caaf42b74d37c7 Mon Sep 17 00:00:00 2001 From: Ben Jackson Date: Thu, 16 Jun 2022 17:15:13 +1000 Subject: [PATCH] feat: add support for ignoring missing env_files in docker-compose --- cmd/helpers_values.go | 2 +- cmd/root.go | 2 + cmd/template_autogen_ingress_test.go | 20 ++++ cmd/validate_compose.go | 7 +- cmd/validate_compose_test.go | 30 ++++- internal/lagoon/compose.go | 4 +- internal/lagoon/compose_test.go | 31 ++++- .../docker-compose/test10/docker-compose.yml | 111 ++++++++++++++++++ .../docker-compose/test9/docker-compose.yml | 111 ++++++++++++++++++ .../test21-results/nginx.yaml | 45 +++++++ .../test21/docker-compose.yml | 111 ++++++++++++++++++ .../template-autogenerated/test21/lagoon.yml | 34 ++++++ 12 files changed, 491 insertions(+), 17 deletions(-) create mode 100644 test-resources/docker-compose/test10/docker-compose.yml create mode 100644 test-resources/docker-compose/test9/docker-compose.yml create mode 100644 test-resources/template-autogenerated/test21-results/nginx.yaml create mode 100644 test-resources/template-autogenerated/test21/docker-compose.yml create mode 100644 test-resources/template-autogenerated/test21/lagoon.yml diff --git a/cmd/helpers_values.go b/cmd/helpers_values.go index 8f6909e4..8a8a1953 100644 --- a/cmd/helpers_values.go +++ b/cmd/helpers_values.go @@ -135,7 +135,7 @@ func collectBuildValues(debug bool, activeEnv, standbyEnv *bool, // lCompose := composetypes.Project{} // unmarshal the docker-compose.yml file - lCompose, err := lagoon.UnmarshaDockerComposeYAML(lYAML.DockerComposeYAML, ignoreNonStringKeyErrors, composeVars) + lCompose, err := lagoon.UnmarshaDockerComposeYAML(lYAML.DockerComposeYAML, ignoreNonStringKeyErrors, ignoreMissingEnvFiles, composeVars) if err != nil { return err } diff --git a/cmd/root.go b/cmd/root.go index e16dbc19..106d6efc 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -118,6 +118,8 @@ func init() { "The fastly secret prefix to use") rootCmd.PersistentFlags().BoolVarP(&ignoreNonStringKeyErrors, "ignore-non-string-key-errors", "", true, "Ignore non-string-key docker-compose errors (true by default, subject to change).") + rootCmd.PersistentFlags().BoolVarP(&ignoreMissingEnvFiles, "ignore-missing-env-files", "", true, + "Ignore missing env_file files (true by default, subject to change).") } // initConfig reads in config file and ENV variables if set. diff --git a/cmd/template_autogen_ingress_test.go b/cmd/template_autogen_ingress_test.go index c7054491..8a3885c3 100644 --- a/cmd/template_autogen_ingress_test.go +++ b/cmd/template_autogen_ingress_test.go @@ -454,6 +454,26 @@ func TestAutogeneratedIngressGeneration(t *testing.T) { emptyDir: false, want: "../test-resources/template-autogenerated/test20-results", }, + { + name: "test21 autogenerated routes where docker-compose env_file has missing file references", + args: args{ + alertContact: "alertcontact", + statusPageID: "statuspageid", + projectName: "test21-example-com", + environmentName: "feature", + environmentType: "development", + buildType: "branch", + lagoonVersion: "v2.7.x", + branch: "feature", + projectVars: `[{"name":"LAGOON_SYSTEM_ROUTER_PATTERN","value":"${environment}.${project}.example.com","scope":"internal_system"}]`, + envVars: `[]`, + secretPrefix: "fastly-api-", + lagoonYAML: "../test-resources/template-autogenerated/test21/lagoon.yml", + templatePath: "../test-resources/template-autogenerated/output", + }, + emptyDir: false, + want: "../test-resources/template-autogenerated/test21-results", + }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { diff --git a/cmd/validate_compose.go b/cmd/validate_compose.go index 12e4ab8b..d7cbd4ae 100644 --- a/cmd/validate_compose.go +++ b/cmd/validate_compose.go @@ -11,6 +11,7 @@ import ( var ( dockerComposeFile string ignoreNonStringKeyErrors bool + ignoreMissingEnvFiles bool ) var validateDockerCompose = &cobra.Command{ @@ -20,7 +21,7 @@ var validateDockerCompose = &cobra.Command{ Run: func(cmd *cobra.Command, args []string) { // @TODO: ignoreNonStringKeyErrors is `true` by default because Lagoon doesn't enforce // docker-compose compliance yet - err := ValidateDockerCompose(dockerComposeFile, ignoreNonStringKeyErrors) + err := ValidateDockerCompose(dockerComposeFile, ignoreNonStringKeyErrors, ignoreMissingEnvFiles) if err != nil { fmt.Println(err.Error()) os.Exit(1) @@ -29,8 +30,8 @@ var validateDockerCompose = &cobra.Command{ } // ValidateDockerCompose validate a docker-compose file -func ValidateDockerCompose(file string, ignoreErrors bool) error { - _, err := lagoon.UnmarshaDockerComposeYAML(file, ignoreNonStringKeyErrors, map[string]string{}) +func ValidateDockerCompose(file string, ignoreErrors, ignoreMisEnvFiles bool) error { + _, err := lagoon.UnmarshaDockerComposeYAML(file, ignoreErrors, ignoreMisEnvFiles, map[string]string{}) if err != nil { return err } diff --git a/cmd/validate_compose_test.go b/cmd/validate_compose_test.go index fb590d1d..2f5a8688 100644 --- a/cmd/validate_compose_test.go +++ b/cmd/validate_compose_test.go @@ -1,13 +1,15 @@ package cmd import ( + "strings" "testing" ) func TestValidateDockerCompose(t *testing.T) { type args struct { - file string - ignoreErrors bool + file string + ignoreNonStringKeyErrors bool + ignoreMissingEnvFiles bool } tests := []struct { name string @@ -50,16 +52,32 @@ func TestValidateDockerCompose(t *testing.T) { { name: "test6 check an invalid docker-compose (same as test5 but ignoring the errors)", args: args{ - file: "../test-resources/docker-compose/test8/docker-compose.yml", - ignoreErrors: true, + file: "../test-resources/docker-compose/test8/docker-compose.yml", + ignoreNonStringKeyErrors: true, + }, + }, + { + name: "test7 check an valid docker-compose with missing env_files ", + args: args{ + file: "../test-resources/docker-compose/test10/docker-compose.yml", + }, + wantErr: true, + wantErrMsg: "no such file or directory", + }, + { + name: "test8 check an valid docker-compose with missing env_files (same as test7 but ignoring the missing file errors)", + args: args{ + file: "../test-resources/docker-compose/test9/docker-compose.yml", + ignoreNonStringKeyErrors: true, + ignoreMissingEnvFiles: true, }, }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - if err := ValidateDockerCompose(tt.args.file, tt.args.ignoreErrors); err != nil { + if err := ValidateDockerCompose(tt.args.file, tt.args.ignoreNonStringKeyErrors, tt.args.ignoreMissingEnvFiles); err != nil { if tt.wantErr { - if err.Error() != tt.wantErrMsg { + if !strings.Contains(err.Error(), tt.wantErrMsg) { t.Errorf("ValidateDockerCompose() error = %v, wantErr %v", err, tt.wantErr) } } else { diff --git a/internal/lagoon/compose.go b/internal/lagoon/compose.go index 802e950d..ec15584c 100644 --- a/internal/lagoon/compose.go +++ b/internal/lagoon/compose.go @@ -7,13 +7,15 @@ import ( ) // UnmarshaDockerComposeYAML unmarshal the lagoon.yml file into a YAML and map for consumption. -func UnmarshaDockerComposeYAML(file string, ignoreErrors bool, envvars map[string]string) (*composetypes.Project, error) { +func UnmarshaDockerComposeYAML(file string, ignoreErrors, ignoreMissingEnvFiles bool, envvars map[string]string) (*composetypes.Project, error) { options, err := cli.NewProjectOptions([]string{file}, cli.WithResolvedPaths(false), cli.WithLoadOptions( loader.WithSkipValidation, + loader.WithDiscardEnvFiles, func(o *loader.Options) { o.IgnoreNonStringKeyErrors = ignoreErrors + o.IgnoreMissingEnvFileCheck = ignoreMissingEnvFiles }, ), ) diff --git a/internal/lagoon/compose_test.go b/internal/lagoon/compose_test.go index fb1a3252..e64e64a8 100644 --- a/internal/lagoon/compose_test.go +++ b/internal/lagoon/compose_test.go @@ -2,6 +2,7 @@ package lagoon import ( "encoding/json" + "strings" "testing" "github.com/google/go-cmp/cmp" @@ -9,8 +10,9 @@ import ( func TestUnmarshaDockerComposeYAML(t *testing.T) { type args struct { - file string - ignoreErrors bool + file string + ignoreNonStringKeyErrors bool + ignoreMissingEnvFiles bool } tests := []struct { name string @@ -64,8 +66,8 @@ func TestUnmarshaDockerComposeYAML(t *testing.T) { { name: "test7 check an invalid docker-compose with ignoring non-string key errors", args: args{ - file: "../../test-resources/docker-compose/test7/docker-compose.yml", - ignoreErrors: true, + file: "../../test-resources/docker-compose/test7/docker-compose.yml", + ignoreNonStringKeyErrors: true, }, want: `{"name":"test7","services":{"cli":{"build":{"context":".","dockerfile":".lagoon/cli.dockerfile","args":{"DOCKER_CLI_IMAGE_URI":"","ENVIRONMENT_TYPE_ID":""}},"container_name":"_cli","environment":{"ENVIRONMENT_TYPE_ID":"","LAGOON_ENVIRONMENT_TYPE":"","LAGOON_PROJECT":"","LAGOON_ROUTE":"http://","PHP_MEMORY_LIMIT":"768M","XDEBUG_ENABLE":""},"labels":{"lagoon.persistent":"/app/docroot/sites/default/files/","lagoon.persistent.name":"nginx","lagoon.type":"cli-persistent"},"networks":{"default":null},"user":"root","volumes":[{"type":"bind","source":"./.lagoon/scripts/bash_prompts.rc","target":"/home/.bashrc","bind":{"create_host_path":true}},{"type":"bind","source":"./.lagoon/scripts/color_grid.sh","target":"/home/color_grid.sh","bind":{"create_host_path":true}}],"volumes_from":["container:amazeeio-ssh-agent"]},"mariadb":{"container_name":"_db","environment":{"ENVIRONMENT_TYPE_ID":"","LAGOON_ENVIRONMENT_TYPE":"","LAGOON_PROJECT":"","LAGOON_ROUTE":"http://","PHP_MEMORY_LIMIT":"768M","XDEBUG_ENABLE":""},"image":"amazeeio/mariadb-drupal","labels":{"lagoon.type":"mariadb"},"networks":{"default":null},"ports":[{"mode":"ingress","target":3306,"protocol":"tcp"}],"volumes":[{"type":"volume","source":"mysql","target":"/var/lib/mysql","volume":{}}]},"nginx":{"build":{"context":".","dockerfile":".lagoon/nginx.dockerfile","args":{"CLI_IMAGE":"","DOCKER_NGINX_IMAGE_URI":"","LAGOON_GIT_BRANCH":null}},"container_name":"_nginx","depends_on":{"cli":{"condition":"service_started"}},"environment":{"ENVIRONMENT_TYPE_ID":"","LAGOON_ENVIRONMENT_TYPE":"","LAGOON_LOCALDEV_URL":"http://","LAGOON_PROJECT":"","LAGOON_ROUTE":"http://","PHP_MEMORY_LIMIT":"768M","XDEBUG_ENABLE":""},"labels":{"lagoon.name":"nginx","lagoon.persistent":"/app/docroot/sites/default/files/","lagoon.type":"nginx-php-persistent"},"networks":{"amazeeio-network":null,"default":null},"volumes":[{"type":"bind","source":"./.lagoon/nginx/nginx-http.conf","target":"/etc/nginx/conf.d/000-nginx-http.conf","bind":{"create_host_path":true}},{"type":"bind","source":"./.lagoon/nginx/app.conf","target":"/etc/nginx/conf.d/app.conf","bind":{"create_host_path":true}}]},"php":{"build":{"context":".","dockerfile":".lagoon/php.dockerfile","args":{"CLI_IMAGE":"","DOCKER_PHP_IMAGE_URI":""}},"container_name":"_php","depends_on":{"cli":{"condition":"service_started"}},"environment":{"ENVIRONMENT_TYPE_ID":"","LAGOON_ENVIRONMENT_TYPE":"","LAGOON_PROJECT":"","LAGOON_ROUTE":"http://","PHP_MEMORY_LIMIT":"768M","XDEBUG_ENABLE":""},"labels":{"lagoon.deployment.servicetype":"php","lagoon.name":"nginx","lagoon.persistent":"/app/docroot/sites/default/files","lagoon.type":"nginx-php-persistent"},"networks":{"default":null}}},"networks":{"amazeeio-network":{"name":"amazeeio-network","ipam":{},"external":true},"default":{"name":"test7_default","ipam":{},"external":false}},"volumes":{"app":{"name":"test7_app","external":false},"mysql":{"name":"test7_mysql","external":false},"solr7":{"name":"test7_solr7","external":false}}}`, }, @@ -77,15 +79,32 @@ func TestUnmarshaDockerComposeYAML(t *testing.T) { wantErr: true, wantErrMsg: "Non-string key in x-site-branch: ", }, + { + name: "test9 check an valid docker-compose with missing env_files", + args: args{ + file: "../../test-resources/docker-compose/test9/docker-compose.yml", + ignoreNonStringKeyErrors: true, + ignoreMissingEnvFiles: true, + }, + want: `{"name":"test9","services":{"cli":{"build":{"context":".","dockerfile":"lagoon/cli.dockerfile"},"container_name":"-cli","environment":{"DRUSH_OPTIONS_URI":"https://","LAGOON_PROJECT":"","LAGOON_ROUTE":"https://","SIMPLETEST_BASE_URL":"http://nginx:8080","SIMPLETEST_DB":"mysql://drupal:drupal@mariadb:3306/drupal","SSMTP_MAILHUB":"host.docker.internal:1025"},"labels":{"lagoon.persistent":"/app/public/sites/default/files/","lagoon.persistent.name":"nginx","lagoon.type":"cli-persistent"},"networks":{"default":null},"volumes":[{"type":"bind","source":".","target":"/app","bind":{"create_host_path":true}},{"type":"volume","source":"ssh","target":"/tmp/amazeeio_ssh-agent","volume":{}}]},"mariadb":{"container_name":"-db","environment":{"LAGOON_PROJECT":"","LAGOON_ROUTE":"https://","SSMTP_MAILHUB":"host.docker.internal:1025"},"image":"uselagoon/mariadb-drupal:latest","labels":{"lagoon.type":"mariadb"},"networks":{"default":null},"ports":[{"mode":"ingress","target":3306,"protocol":"tcp"}]},"nginx":{"build":{"context":".","dockerfile":"lagoon/nginx.dockerfile","args":{"CLI_IMAGE":""}},"container_name":"-nginx","depends_on":{"cli":{"condition":"service_started"}},"environment":{"LAGOON_LOCALDEV_URL":"","LAGOON_PROJECT":"","LAGOON_ROUTE":"https://","SSMTP_MAILHUB":"host.docker.internal:1025"},"labels":{"lagoon.persistent":"/app/public/sites/default/files/","lagoon.type":"nginx-php-persistent"},"networks":{"default":null,"stonehenge-network":null},"volumes":[{"type":"bind","source":".","target":"/app","bind":{"create_host_path":true}}]},"php":{"build":{"context":".","dockerfile":"lagoon/php.dockerfile","args":{"CLI_IMAGE":""}},"container_name":"-php","depends_on":{"cli":{"condition":"service_started"}},"environment":{"LAGOON_PROJECT":"","LAGOON_ROUTE":"https://","SSMTP_MAILHUB":"host.docker.internal:1025"},"labels":{"lagoon.name":"nginx","lagoon.persistent":"/app/public/sites/default/files/","lagoon.type":"nginx-php-persistent"},"networks":{"default":null},"volumes":[{"type":"bind","source":".","target":"/app","bind":{"create_host_path":true}}]},"pma":{"container_name":"-pma","environment":{"PMA_HOST":"mariadb","PMA_PASSWORD":"drupal","PMA_USER":"drupal","UPLOAD_LIMIT":"1G"},"image":"phpmyadmin/phpmyadmin","labels":{"lagoon.type":"none"},"networks":{"default":null,"stonehenge-network":null}}},"networks":{"default":{"name":"test9_default","ipam":{},"external":false},"stonehenge-network":{"name":"stonehenge-network","ipam":{},"external":true}},"volumes":{"es_data":{"name":"test9_es_data","external":false},"ssh":{"name":"stonehenge-ssh","external":true}}}`, + }, + { + name: "test10 check an valid docker-compose with missing env_files (same as test9 but not ignoring the errors)", + args: args{ + file: "../../test-resources/docker-compose/test10/docker-compose.yml", + }, + wantErr: true, + wantErrMsg: "no such file or directory", + }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - l, err := UnmarshaDockerComposeYAML(tt.args.file, tt.args.ignoreErrors, map[string]string{}) + l, err := UnmarshaDockerComposeYAML(tt.args.file, tt.args.ignoreNonStringKeyErrors, tt.args.ignoreMissingEnvFiles, map[string]string{}) if err != nil && !tt.wantErr { t.Errorf("UnmarshaDockerComposeYAML() error = %v, wantErr %v", err, tt.wantErr) } if tt.wantErr { - if err.Error() != tt.wantErrMsg { + if !strings.Contains(err.Error(), tt.wantErrMsg) { t.Errorf("UnmarshaDockerComposeYAML() error = %v, wantErrMsg %v", err.Error(), tt.wantErrMsg) } } else { diff --git a/test-resources/docker-compose/test10/docker-compose.yml b/test-resources/docker-compose/test10/docker-compose.yml new file mode 100644 index 00000000..c58a678e --- /dev/null +++ b/test-resources/docker-compose/test10/docker-compose.yml @@ -0,0 +1,111 @@ +version: '2.3' + +x-lagoon-project: + # Lagoon project name (leave `&lagoon-project` when you edit this) + &lagoon-project "${COMPOSE_PROJECT_NAME}" + +x-environment: + &default-environment + LAGOON_PROJECT: *lagoon-project + # Route that should be used locally + LAGOON_ROUTE: "https://${DRUPAL_HOSTNAME}" + SSMTP_MAILHUB: "host.docker.internal:1025" + +services: + + cli: # cli container, will be used for executing composer and any local commands (drush, drupal, etc.) + container_name: "${COMPOSE_PROJECT_NAME}-cli" + build: + context: . + dockerfile: lagoon/cli.dockerfile + image: *lagoon-project # this image will be reused as `CLI_IMAGE` in subsequent Docker builds + labels: + # Lagoon Labels + lagoon.type: cli-persistent + lagoon.persistent.name: nginx # mount the persistent storage of nginx into this container + lagoon.persistent: "/app/public/sites/default/files/" # location where the persistent storage should be mounted + volumes: + - .:/app:delegated + - ssh:/tmp/amazeeio_ssh-agent + environment: + << : *default-environment # loads the defined environment variables from the top + SIMPLETEST_BASE_URL: "http://nginx:8080" + SIMPLETEST_DB: "mysql://drupal:drupal@mariadb:3306/drupal" + DRUSH_OPTIONS_URI: "https://${DRUPAL_HOSTNAME}" + env_file: + - .env.local + + nginx: + container_name: "${COMPOSE_PROJECT_NAME}-nginx" + build: + context: . + dockerfile: lagoon/nginx.dockerfile + args: + CLI_IMAGE: *lagoon-project # Inject the name of the cli image + labels: + lagoon.type: nginx-php-persistent + lagoon.persistent: "/app/public/sites/default/files/" # define where the persistent file storage should be mounted too + volumes: + - .:/app:delegated + depends_on: + - cli # basically just tells docker-compose to build the cli first + environment: + << : *default-environment # loads the defined environment variables from the top + LAGOON_LOCALDEV_URL: "${DRUPAL_HOSTNAME}" # generate another route for nginx, by default we go to varnish + networks: + - stonehenge-network + - default + + php: + container_name: "${COMPOSE_PROJECT_NAME}-php" + build: + context: . + dockerfile: lagoon/php.dockerfile + args: + CLI_IMAGE: *lagoon-project + labels: + lagoon.type: nginx-php-persistent + lagoon.name: nginx # we want this service be part of the nginx pod in Lagoon + lagoon.persistent: /app/public/sites/default/files/ # define where the persistent storage should be mounted too + volumes: + - .:/app:delegated + depends_on: + - cli # basically just tells docker-compose to build the cli first + environment: + << : *default-environment # loads the defined environment variables from the top + env_file: + - .env.local + + mariadb: + container_name: "${COMPOSE_PROJECT_NAME}-db" + image: uselagoon/mariadb-drupal:latest + labels: + lagoon.type: mariadb + ports: + - "3306" # exposes the port 3306 with a random local port, find it with `docker-compose port mariadb 3306` + environment: + << : *default-environment + + pma: + image: phpmyadmin/phpmyadmin + container_name: "${COMPOSE_PROJECT_NAME}-pma" + environment: + PMA_HOST: mariadb + PMA_USER: drupal + PMA_PASSWORD: drupal + UPLOAD_LIMIT: 1G + labels: + lagoon.type: none + networks: + - default + - stonehenge-network + +networks: + stonehenge-network: + external: true + +volumes: + es_data: + ssh: + name: stonehenge-ssh + external: true \ No newline at end of file diff --git a/test-resources/docker-compose/test9/docker-compose.yml b/test-resources/docker-compose/test9/docker-compose.yml new file mode 100644 index 00000000..c58a678e --- /dev/null +++ b/test-resources/docker-compose/test9/docker-compose.yml @@ -0,0 +1,111 @@ +version: '2.3' + +x-lagoon-project: + # Lagoon project name (leave `&lagoon-project` when you edit this) + &lagoon-project "${COMPOSE_PROJECT_NAME}" + +x-environment: + &default-environment + LAGOON_PROJECT: *lagoon-project + # Route that should be used locally + LAGOON_ROUTE: "https://${DRUPAL_HOSTNAME}" + SSMTP_MAILHUB: "host.docker.internal:1025" + +services: + + cli: # cli container, will be used for executing composer and any local commands (drush, drupal, etc.) + container_name: "${COMPOSE_PROJECT_NAME}-cli" + build: + context: . + dockerfile: lagoon/cli.dockerfile + image: *lagoon-project # this image will be reused as `CLI_IMAGE` in subsequent Docker builds + labels: + # Lagoon Labels + lagoon.type: cli-persistent + lagoon.persistent.name: nginx # mount the persistent storage of nginx into this container + lagoon.persistent: "/app/public/sites/default/files/" # location where the persistent storage should be mounted + volumes: + - .:/app:delegated + - ssh:/tmp/amazeeio_ssh-agent + environment: + << : *default-environment # loads the defined environment variables from the top + SIMPLETEST_BASE_URL: "http://nginx:8080" + SIMPLETEST_DB: "mysql://drupal:drupal@mariadb:3306/drupal" + DRUSH_OPTIONS_URI: "https://${DRUPAL_HOSTNAME}" + env_file: + - .env.local + + nginx: + container_name: "${COMPOSE_PROJECT_NAME}-nginx" + build: + context: . + dockerfile: lagoon/nginx.dockerfile + args: + CLI_IMAGE: *lagoon-project # Inject the name of the cli image + labels: + lagoon.type: nginx-php-persistent + lagoon.persistent: "/app/public/sites/default/files/" # define where the persistent file storage should be mounted too + volumes: + - .:/app:delegated + depends_on: + - cli # basically just tells docker-compose to build the cli first + environment: + << : *default-environment # loads the defined environment variables from the top + LAGOON_LOCALDEV_URL: "${DRUPAL_HOSTNAME}" # generate another route for nginx, by default we go to varnish + networks: + - stonehenge-network + - default + + php: + container_name: "${COMPOSE_PROJECT_NAME}-php" + build: + context: . + dockerfile: lagoon/php.dockerfile + args: + CLI_IMAGE: *lagoon-project + labels: + lagoon.type: nginx-php-persistent + lagoon.name: nginx # we want this service be part of the nginx pod in Lagoon + lagoon.persistent: /app/public/sites/default/files/ # define where the persistent storage should be mounted too + volumes: + - .:/app:delegated + depends_on: + - cli # basically just tells docker-compose to build the cli first + environment: + << : *default-environment # loads the defined environment variables from the top + env_file: + - .env.local + + mariadb: + container_name: "${COMPOSE_PROJECT_NAME}-db" + image: uselagoon/mariadb-drupal:latest + labels: + lagoon.type: mariadb + ports: + - "3306" # exposes the port 3306 with a random local port, find it with `docker-compose port mariadb 3306` + environment: + << : *default-environment + + pma: + image: phpmyadmin/phpmyadmin + container_name: "${COMPOSE_PROJECT_NAME}-pma" + environment: + PMA_HOST: mariadb + PMA_USER: drupal + PMA_PASSWORD: drupal + UPLOAD_LIMIT: 1G + labels: + lagoon.type: none + networks: + - default + - stonehenge-network + +networks: + stonehenge-network: + external: true + +volumes: + es_data: + ssh: + name: stonehenge-ssh + external: true \ No newline at end of file diff --git a/test-resources/template-autogenerated/test21-results/nginx.yaml b/test-resources/template-autogenerated/test21-results/nginx.yaml new file mode 100644 index 00000000..6bbf61f3 --- /dev/null +++ b/test-resources/template-autogenerated/test21-results/nginx.yaml @@ -0,0 +1,45 @@ +--- +apiVersion: networking.k8s.io/v1 +kind: Ingress +metadata: + annotations: + fastly.amazee.io/watch: "false" + ingress.kubernetes.io/ssl-redirect: "false" + kubernetes.io/tls-acme: "true" + lagoon.sh/branch: feature + lagoon.sh/version: v2.7.x + nginx.ingress.kubernetes.io/server-snippet: | + add_header X-Robots-Tag "noindex, nofollow"; + nginx.ingress.kubernetes.io/ssl-redirect: "false" + creationTimestamp: null + labels: + app.kubernetes.io/instance: nginx + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: autogenerated-ingress + helm.sh/chart: autogenerated-ingress-0.1.0 + lagoon.sh/autogenerated: "true" + lagoon.sh/buildType: branch + lagoon.sh/environment: feature + lagoon.sh/environmentType: development + lagoon.sh/project: test21-example-com + lagoon.sh/service: nginx + lagoon.sh/service-type: nginx-php-persistent + name: nginx +spec: + rules: + - host: nginx.feature.test21-example-com.example.com + http: + paths: + - backend: + service: + name: nginx + port: + name: http + path: / + pathType: Prefix + tls: + - hosts: + - nginx.feature.test21-example-com.example.com + secretName: nginx-tls +status: + loadBalancer: {} diff --git a/test-resources/template-autogenerated/test21/docker-compose.yml b/test-resources/template-autogenerated/test21/docker-compose.yml new file mode 100644 index 00000000..c58a678e --- /dev/null +++ b/test-resources/template-autogenerated/test21/docker-compose.yml @@ -0,0 +1,111 @@ +version: '2.3' + +x-lagoon-project: + # Lagoon project name (leave `&lagoon-project` when you edit this) + &lagoon-project "${COMPOSE_PROJECT_NAME}" + +x-environment: + &default-environment + LAGOON_PROJECT: *lagoon-project + # Route that should be used locally + LAGOON_ROUTE: "https://${DRUPAL_HOSTNAME}" + SSMTP_MAILHUB: "host.docker.internal:1025" + +services: + + cli: # cli container, will be used for executing composer and any local commands (drush, drupal, etc.) + container_name: "${COMPOSE_PROJECT_NAME}-cli" + build: + context: . + dockerfile: lagoon/cli.dockerfile + image: *lagoon-project # this image will be reused as `CLI_IMAGE` in subsequent Docker builds + labels: + # Lagoon Labels + lagoon.type: cli-persistent + lagoon.persistent.name: nginx # mount the persistent storage of nginx into this container + lagoon.persistent: "/app/public/sites/default/files/" # location where the persistent storage should be mounted + volumes: + - .:/app:delegated + - ssh:/tmp/amazeeio_ssh-agent + environment: + << : *default-environment # loads the defined environment variables from the top + SIMPLETEST_BASE_URL: "http://nginx:8080" + SIMPLETEST_DB: "mysql://drupal:drupal@mariadb:3306/drupal" + DRUSH_OPTIONS_URI: "https://${DRUPAL_HOSTNAME}" + env_file: + - .env.local + + nginx: + container_name: "${COMPOSE_PROJECT_NAME}-nginx" + build: + context: . + dockerfile: lagoon/nginx.dockerfile + args: + CLI_IMAGE: *lagoon-project # Inject the name of the cli image + labels: + lagoon.type: nginx-php-persistent + lagoon.persistent: "/app/public/sites/default/files/" # define where the persistent file storage should be mounted too + volumes: + - .:/app:delegated + depends_on: + - cli # basically just tells docker-compose to build the cli first + environment: + << : *default-environment # loads the defined environment variables from the top + LAGOON_LOCALDEV_URL: "${DRUPAL_HOSTNAME}" # generate another route for nginx, by default we go to varnish + networks: + - stonehenge-network + - default + + php: + container_name: "${COMPOSE_PROJECT_NAME}-php" + build: + context: . + dockerfile: lagoon/php.dockerfile + args: + CLI_IMAGE: *lagoon-project + labels: + lagoon.type: nginx-php-persistent + lagoon.name: nginx # we want this service be part of the nginx pod in Lagoon + lagoon.persistent: /app/public/sites/default/files/ # define where the persistent storage should be mounted too + volumes: + - .:/app:delegated + depends_on: + - cli # basically just tells docker-compose to build the cli first + environment: + << : *default-environment # loads the defined environment variables from the top + env_file: + - .env.local + + mariadb: + container_name: "${COMPOSE_PROJECT_NAME}-db" + image: uselagoon/mariadb-drupal:latest + labels: + lagoon.type: mariadb + ports: + - "3306" # exposes the port 3306 with a random local port, find it with `docker-compose port mariadb 3306` + environment: + << : *default-environment + + pma: + image: phpmyadmin/phpmyadmin + container_name: "${COMPOSE_PROJECT_NAME}-pma" + environment: + PMA_HOST: mariadb + PMA_USER: drupal + PMA_PASSWORD: drupal + UPLOAD_LIMIT: 1G + labels: + lagoon.type: none + networks: + - default + - stonehenge-network + +networks: + stonehenge-network: + external: true + +volumes: + es_data: + ssh: + name: stonehenge-ssh + external: true \ No newline at end of file diff --git a/test-resources/template-autogenerated/test21/lagoon.yml b/test-resources/template-autogenerated/test21/lagoon.yml new file mode 100644 index 00000000..0e1c70d5 --- /dev/null +++ b/test-resources/template-autogenerated/test21/lagoon.yml @@ -0,0 +1,34 @@ +docker-compose-yaml: ../test-resources/template-autogenerated/test21/docker-compose.yml + +tasks: + + post-rollout: + - run: + name: Drush deploy + command: drush deploy + service: cli + +routes: + insecure: Redirect + +environments: + + dev: + routes: + - nginx: + - test.example.com + cronjobs: + - name: drush cron + schedule: '0 0 * * *' # UTC == 2AM (or in the summer 3AM) EET + command: drush cron + service: cli + + main: + routes: + - nginx: + - ex.example.com + cronjobs: + - name: drush cron + schedule: '0 0 * * *' # UTC == 2AM (or in the summer 3AM) EET + command: drush cron + service: cli \ No newline at end of file