From a361a02b2f1124b1ea998769bb7b301c0dcae1ad Mon Sep 17 00:00:00 2001 From: Fergus McWalters Date: Thu, 15 Feb 2024 11:36:55 +0000 Subject: [PATCH 01/20] use docker compose v2 docker compose v2 is part of Docker nowadays. Rather than calling a separate Python lib that calls `docker-compose`, call `docker compose` and use v2. Fix the `-` and `_` difference between v1 and v2. This will need THOROUGH testing PFM-827 --- CHANGELOG.md | 3 +++ README.md | 4 ++-- kubetools/dev/backends/docker_compose/docker_util.py | 11 +++++++++-- setup.py | 2 -- 4 files changed, 14 insertions(+), 6 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9335256..9060bc8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,9 @@ ### Unreleased +# v20.0.0 +- use `docker compose` in place of `docker-compose`, meaning we use Docker compose v2 on the backend + # v13.13.1 - Add nodeSelector config to kubetools file - Fix bug where `config` command was not printing the actual `k8s` configs used by `deploy` because it did not take into account the kube-context, whether default or given with `--context`. diff --git a/README.md b/README.md index 754d398..a4faa10 100644 --- a/README.md +++ b/README.md @@ -17,7 +17,7 @@ And you would like: Kubetools provides the tooling required to achieve this, by way of two CLI tools: -+ **`ktd`**: generates _100% local_ development environments using Docker/docker-compose ++ **`ktd`**: generates _100% local_ development environments using docker compose + **`kubetools`**: deploys projects to Kubernetes, handling any changes/jobs as required Both of these use a single configuration file, `kubetools.yml`, for example a basic `django` app: @@ -80,7 +80,7 @@ cronjobs: With this in your current directory, you can now: ```sh -# Bring up a local development environment using docker-compose +# Bring up a local development environment using docker compose ktd up # Deploy the project to a Kubernetes namespace diff --git a/kubetools/dev/backends/docker_compose/docker_util.py b/kubetools/dev/backends/docker_compose/docker_util.py index a425ff4..2e13669 100644 --- a/kubetools/dev/backends/docker_compose/docker_util.py +++ b/kubetools/dev/backends/docker_compose/docker_util.py @@ -6,6 +6,7 @@ from kubetools.dev.process_util import run_process from kubetools.exceptions import KubeDevError from kubetools.log import logger +from kubetools import __version__ from .config import ( create_compose_config, @@ -137,7 +138,13 @@ def get_containers_status( env = compose_project.replace(docker_name, '') # Where the name is compose-name_container_N, get container - name = container.name.split('_')[1] + print(container.name) + print(container.labels.get('kubetools.project.env')) + if int(__version__.split('.')[0]) < 20: + name = container.name.split('_')[1] + else: + name = container.name.split('-')[1] + status = container.status == 'running' ports = [] @@ -202,7 +209,7 @@ def run_compose_process(kubetools_config, command_args, **kwargs): create_compose_config(kubetools_config) compose_command = [ - 'docker-compose', + 'docker', 'compose', # Force us to look at the current directory, not relative to the compose # filename (ie .kubetools/compose-name.yml). '--project-directory', '.', diff --git a/setup.py b/setup.py index 2397cba..6c0eb4c 100644 --- a/setup.py +++ b/setup.py @@ -59,8 +59,6 @@ def get_readme_content(): # To support CronJob api versions 'batch/v1beta1' & 'batch/v1' 'kubernetes>=21.7.0,<25.0.0', 'tabulate<1', - # compose v2 has broken container naming - 'docker-compose<2', ), extras_require={ 'dev': ( From 7cda8d3ca675972eb182c1968b3776c6915dcf62 Mon Sep 17 00:00:00 2001 From: Fergus McWalters Date: Thu, 15 Feb 2024 11:41:05 +0000 Subject: [PATCH 02/20] linting --- kubetools/dev/backends/docker_compose/docker_util.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/kubetools/dev/backends/docker_compose/docker_util.py b/kubetools/dev/backends/docker_compose/docker_util.py index 2e13669..0da1e83 100644 --- a/kubetools/dev/backends/docker_compose/docker_util.py +++ b/kubetools/dev/backends/docker_compose/docker_util.py @@ -3,10 +3,10 @@ import docker import requests +from kubetools import __version__ from kubetools.dev.process_util import run_process from kubetools.exceptions import KubeDevError from kubetools.log import logger -from kubetools import __version__ from .config import ( create_compose_config, @@ -145,7 +145,6 @@ def get_containers_status( else: name = container.name.split('-')[1] - status = container.status == 'running' ports = [] From f6c595e28b1112ac09cb1baad22c2269650c9789 Mon Sep 17 00:00:00 2001 From: Fergus McWalters Date: Thu, 15 Feb 2024 14:52:24 +0000 Subject: [PATCH 03/20] use new form of `network` config the old type, `network.external.name` is deprecated on v2. It still works but it may be removed in future. Change to new format. See: https://github.com/docker/compose-cli/issues/1856 --- kubetools/dev/backends/docker_compose/config.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/kubetools/dev/backends/docker_compose/config.py b/kubetools/dev/backends/docker_compose/config.py index 4c1498d..c7e08d0 100644 --- a/kubetools/dev/backends/docker_compose/config.py +++ b/kubetools/dev/backends/docker_compose/config.py @@ -248,9 +248,8 @@ def create_compose_config(kubetools_config): if dev_network: compose_config['networks'] = { 'default': { - 'external': { - 'name': 'dev', - }, + 'name': 'dev', + 'external': True, }, } From a439c4cf81449d620986cec9e67d3119f08ba093 Mon Sep 17 00:00:00 2001 From: Fergus McWalters Date: Thu, 15 Feb 2024 14:55:14 +0000 Subject: [PATCH 04/20] remove version check and `print` statements this code will only ever be used in this version of the tool, and the `__version__` only checks the version of the _tool_ anyways. Also remove redundant print statements --- kubetools/dev/backends/docker_compose/docker_util.py | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/kubetools/dev/backends/docker_compose/docker_util.py b/kubetools/dev/backends/docker_compose/docker_util.py index 0da1e83..9b70fc3 100644 --- a/kubetools/dev/backends/docker_compose/docker_util.py +++ b/kubetools/dev/backends/docker_compose/docker_util.py @@ -3,7 +3,6 @@ import docker import requests -from kubetools import __version__ from kubetools.dev.process_util import run_process from kubetools.exceptions import KubeDevError from kubetools.log import logger @@ -138,12 +137,7 @@ def get_containers_status( env = compose_project.replace(docker_name, '') # Where the name is compose-name_container_N, get container - print(container.name) - print(container.labels.get('kubetools.project.env')) - if int(__version__.split('.')[0]) < 20: - name = container.name.split('_')[1] - else: - name = container.name.split('-')[1] + name = container.name.split('-')[1] status = container.status == 'running' ports = [] From 03fee73f3ab93eae298e117897daa60d9b338264 Mon Sep 17 00:00:00 2001 From: Fergus McWalters Date: Thu, 15 Feb 2024 15:46:39 +0000 Subject: [PATCH 05/20] convert v1 container names to v2 if we create a container using compose v1 and we want to use or remove it using compose v2, we will need to convert its name to use the new format --- kubetools/dev/backends/docker_compose/docker_util.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/kubetools/dev/backends/docker_compose/docker_util.py b/kubetools/dev/backends/docker_compose/docker_util.py index 9b70fc3..42ced73 100644 --- a/kubetools/dev/backends/docker_compose/docker_util.py +++ b/kubetools/dev/backends/docker_compose/docker_util.py @@ -136,8 +136,10 @@ def get_containers_status( if not env: env = compose_project.replace(docker_name, '') - # Where the name is compose-name_container_N, get container - name = container.name.split('-')[1] + # if the container was made in v1, it will be compose_name_container_N + converted_name = container.name.replace('_', '-') + # if the container is called compose-name-container-N, get `container` + name = converted_name.split('-')[1] status = container.status == 'running' ports = [] From b2958d31e804956fb3d98f4c7ce2981445a1c351 Mon Sep 17 00:00:00 2001 From: Fergus McWalters Date: Thu, 15 Feb 2024 16:57:08 +0000 Subject: [PATCH 06/20] deal with cases where container name has more than one middle name there are times where the container name consists of multiple names or a name and then a number; for example, composename-container-name-1-1. We want to keep only `container-name-1`. Ensure this is possible --- kubetools/dev/backends/docker_compose/docker_util.py | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/kubetools/dev/backends/docker_compose/docker_util.py b/kubetools/dev/backends/docker_compose/docker_util.py index 42ced73..fef8793 100644 --- a/kubetools/dev/backends/docker_compose/docker_util.py +++ b/kubetools/dev/backends/docker_compose/docker_util.py @@ -136,10 +136,14 @@ def get_containers_status( if not env: env = compose_project.replace(docker_name, '') - # if the container was made in v1, it will be compose_name_container_N + # if the container was made in v1, it will be composename_container_N converted_name = container.name.replace('_', '-') - # if the container is called compose-name-container-N, get `container` - name = converted_name.split('-')[1] + + # we need to keep the middle part of the name + # for example if we have a container called `composename-container-1-N` + # we want to keep `container-1` + middle_names = converted_name.split('-')[1:-1] + name = '-'.join(middle_name for middle_name in middle_names) status = container.status == 'running' ports = [] From 70ed8efae739247ac6f809b20bcaf7d349e4933c Mon Sep 17 00:00:00 2001 From: Fergus McWalters Date: Mon, 19 Feb 2024 17:19:01 +0000 Subject: [PATCH 07/20] use v14.0.0 for Kubetools with Docker Compose v2, update README Use the most logical version number for the next major version of this. This version of Kubetools introduces some unavoidable breaking changes that we can work around. Document these in the README. --- CHANGELOG.md | 5 +++-- README.md | 11 +++++++++++ 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9060bc8..36451e8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,8 +2,9 @@ ### Unreleased -# v20.0.0 -- use `docker compose` in place of `docker-compose`, meaning we use Docker compose v2 on the backend +# v14.0.0 +- this **BREAKS COMPATIBILITY** with previous versions of `ktd` (see README) +- uses `docker compose` in place of `docker-compose`, meaning we use Docker compose v2 on the backend # v13.13.1 - Add nodeSelector config to kubetools file diff --git a/README.md b/README.md index a4faa10..356cc41 100644 --- a/README.md +++ b/README.md @@ -82,13 +82,24 @@ With this in your current directory, you can now: ```sh # Bring up a local development environment using docker compose ktd up +``` +**NOTE**: there is a bug in the Docker BuildKit that ignores "insecure-registries". +as `docker compose` V2 uses BuildKit by default, the only way to currently get around this +is to append `DOCKER_BUILDKIT=0` in front of the `ktd` command, +e.g: `DOCKER_BUILDKIT=0 ktd up`. +This applies to all `Dockerfile`s where an insecure registry is specified. + +```sh # Deploy the project to a Kubernetes namespace kubetools deploy my-namespace ``` ## Installing +**NOTE**: before upgrading to version 14.0 or above, you _must_ run `ktd destroy` for all existing +local Kubetools projects. + ```sh pip install kubetools ``` From 696efb3c76f67b15e951f8bc5cd23b33e92f0f80 Mon Sep 17 00:00:00 2001 From: Fergus McWalters Date: Tue, 20 Feb 2024 14:03:06 +0000 Subject: [PATCH 08/20] readme formatting --- README.md | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 356cc41..c19d36f 100644 --- a/README.md +++ b/README.md @@ -85,11 +85,13 @@ ktd up ``` **NOTE**: there is a bug in the Docker BuildKit that ignores "insecure-registries". -as `docker compose` V2 uses BuildKit by default, the only way to currently get around this +As `docker compose` V2 uses BuildKit by default, the only way to currently get around this is to append `DOCKER_BUILDKIT=0` in front of the `ktd` command, + e.g: `DOCKER_BUILDKIT=0 ktd up`. + This applies to all `Dockerfile`s where an insecure registry is specified. - + ```sh # Deploy the project to a Kubernetes namespace kubetools deploy my-namespace From fc59bbfef12c3357843635c24c1a5c3db85ec85f Mon Sep 17 00:00:00 2001 From: Fergus McWalters Date: Tue, 20 Feb 2024 14:03:25 +0000 Subject: [PATCH 09/20] add unit tests for a complex named app to check compatibility with compose v2 --- tests/configs/complex_named_app/kubetools.yml | 38 +++++++++++++++++++ tests/test_config_generation.py | 3 ++ 2 files changed, 41 insertions(+) create mode 100644 tests/configs/complex_named_app/kubetools.yml diff --git a/tests/configs/complex_named_app/kubetools.yml b/tests/configs/complex_named_app/kubetools.yml new file mode 100644 index 0000000..38378be --- /dev/null +++ b/tests/configs/complex_named_app/kubetools.yml @@ -0,0 +1,38 @@ +name: complex-named-app + + +containerContexts: + generic-context: + image: generic-image + command: [generic-command] + ports: + - 80 + +upgrades: + - name: Upgrade the database + containerContext: generic-context + command: [generic-command, generic-arg] + resources: + requests: + memory: "1Gi" + + +deployments: + complex-named-app: + containers: + complex-webserver: + command: [uwsgi, --ini, /etc/uwsgi.conf] + containerContext: generic-context + probes: + timeoutSeconds: 5 + httpGet: + path: /ping + + +cronjobs: + generic-cronjob: + schedule: "*/1 * * * *" + concurrency_policy: "Allow" + containers: + generic-container: + containerContext: generic-context diff --git a/tests/test_config_generation.py b/tests/test_config_generation.py index 4479d1c..42a39f9 100644 --- a/tests/test_config_generation.py +++ b/tests/test_config_generation.py @@ -13,6 +13,9 @@ class TestKubernetesConfigGeneration(TestCase): def test_basic_app_configs(self): _test_configs('basic_app') + def test_complex_named_app_configs(self): + _test_configs('complex_named_app') + def test_dependencies_configs(self): _test_configs('dependencies') From 3a4c3fead6dff39e31f7ccd8b3a38eeefde57345 Mon Sep 17 00:00:00 2001 From: Fergus McWalters Date: Tue, 20 Feb 2024 14:17:24 +0000 Subject: [PATCH 10/20] add missing infra for test --- .../complex_named_app/k8s_cronjobs.yml | 40 +++++++++++++++++++ .../complex_named_app/k8s_deployments.yml | 30 ++++++++++++++ tests/configs/complex_named_app/k8s_jobs.yml | 30 ++++++++++++++ .../complex_named_app/k8s_services.yml | 11 +++++ 4 files changed, 111 insertions(+) create mode 100644 tests/configs/complex_named_app/k8s_cronjobs.yml create mode 100644 tests/configs/complex_named_app/k8s_deployments.yml create mode 100644 tests/configs/complex_named_app/k8s_jobs.yml create mode 100644 tests/configs/complex_named_app/k8s_services.yml diff --git a/tests/configs/complex_named_app/k8s_cronjobs.yml b/tests/configs/complex_named_app/k8s_cronjobs.yml new file mode 100644 index 0000000..cf67cdf --- /dev/null +++ b/tests/configs/complex_named_app/k8s_cronjobs.yml @@ -0,0 +1,40 @@ +kind: CronJob +metadata: + name: generic-cronjob + labels: { + kubetools/name: generic-cronjob, + kubetools/project_name: generic-app, + kubetools/role: cronjob + } + annotations: { + app.kubernetes.io/managed-by: kubetools, + description: 'Run: [''generic-command'']' + } +spec: + schedule: "*/1 * * * *" + startingDeadlineSeconds: 10 + concurrencyPolicy: "Allow" + jobTemplate: + spec: + template: + metadata: + name: generic-cronjob + labels: { + kubetools/name: generic-cronjob, + kubetools/project_name: generic-app, + kubetools/role: cronjob + } + annotations: { + app.kubernetes.io/managed-by: kubetools, + description: 'Run: [''generic-command'']' + } + spec: + containers: + - command: [generic-command] + containerContext: generic-context + env: + - {name: KUBE, value: 'true'} + image: generic-image + imagePullPolicy: 'Always' + name: generic-container + restartPolicy: OnFailure diff --git a/tests/configs/complex_named_app/k8s_deployments.yml b/tests/configs/complex_named_app/k8s_deployments.yml new file mode 100644 index 0000000..9390739 --- /dev/null +++ b/tests/configs/complex_named_app/k8s_deployments.yml @@ -0,0 +1,30 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + annotations: {app.kubernetes.io/managed-by: kubetools} + labels: {kubetools/name: complex-named-app, kubetools/project_name: complex-named-app, kubetools/role: app} + name: complex-named-app +spec: + replicas: 1 + revisionHistoryLimit: 5 + selector: + matchLabels: {kubetools/name: complex-named-app, kubetools/project_name: complex-named-app, + kubetools/role: app} + template: + metadata: + labels: {kubetools/name: complex-named-app, kubetools/project_name: complex-named-app, kubetools/role: app} + spec: + containers: + - command: [generic-command] + containerContext: generic-context + env: + - {name: KUBE, value: 'true'} + image: generic-image + imagePullPolicy: Always + livenessProbe: + httpGet: {path: /ping, port: 80} + timeoutSeconds: 5 + name: webserver + readinessProbe: + httpGet: {path: /ping, port: 80} + timeoutSeconds: 5 diff --git a/tests/configs/complex_named_app/k8s_jobs.yml b/tests/configs/complex_named_app/k8s_jobs.yml new file mode 100644 index 0000000..0e5e602 --- /dev/null +++ b/tests/configs/complex_named_app/k8s_jobs.yml @@ -0,0 +1,30 @@ +apiVersion: batch/v1 +kind: Job +metadata: + annotations: {app.kubernetes.io/managed-by: kubetools, description: 'Run: [''generic-command'']'} + labels: {job-id: UUID, kubetools/project_name: complex-named-app, + kubetools/role: job} + name: UUID +spec: + completions: 1 + parallelism: 1 + selector: {job-id: UUID, kubetools/project_name: complex-named-app, + kubetools/role: job} + template: + metadata: + labels: {job-id: UUID, kubetools/project_name: complex-named-app, + kubetools/role: job} + spec: + containers: + - chdir: / + command: [generic-command] + env: + - {name: KUBE, value: 'true'} + - {name: KUBE_JOB_ID, value: UUID} + image: generic-image + imagePullPolicy: Always + name: upgrade + resources: + requests: + memory: "1Gi" + restartPolicy: Never diff --git a/tests/configs/complex_named_app/k8s_services.yml b/tests/configs/complex_named_app/k8s_services.yml new file mode 100644 index 0000000..6d3e04c --- /dev/null +++ b/tests/configs/complex_named_app/k8s_services.yml @@ -0,0 +1,11 @@ +apiVersion: v1 +kind: Service +metadata: + annotations: {app.kubernetes.io/managed-by: kubetools} + labels: {kubetools/name: complex-named-app, kubetools/project_name: complex-named-app, kubetools/role: app} + name: complex-named-app +spec: + ports: + - {port: 80, targetPort: 80} + selector: {kubetools/name: complex-named-app, kubetools/project_name: complex-named-app, kubetools/role: app} + type: NodePort From add075515c7692bf16d504a3e2300983876cd972 Mon Sep 17 00:00:00 2001 From: Fergus McWalters Date: Tue, 20 Feb 2024 14:28:06 +0000 Subject: [PATCH 11/20] add correct complex-webserver --- tests/configs/complex_named_app/k8s_deployments.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/configs/complex_named_app/k8s_deployments.yml b/tests/configs/complex_named_app/k8s_deployments.yml index 9390739..6a679b9 100644 --- a/tests/configs/complex_named_app/k8s_deployments.yml +++ b/tests/configs/complex_named_app/k8s_deployments.yml @@ -24,7 +24,7 @@ spec: livenessProbe: httpGet: {path: /ping, port: 80} timeoutSeconds: 5 - name: webserver + name: complex-webserver readinessProbe: httpGet: {path: /ping, port: 80} timeoutSeconds: 5 From f5942880ecea0afbf3d1d415faac07ab635747c2 Mon Sep 17 00:00:00 2001 From: Fergus McWalters Date: Tue, 20 Feb 2024 14:31:07 +0000 Subject: [PATCH 12/20] use complex-named-app for cron --- tests/configs/complex_named_app/k8s_cronjobs.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/configs/complex_named_app/k8s_cronjobs.yml b/tests/configs/complex_named_app/k8s_cronjobs.yml index cf67cdf..d36d170 100644 --- a/tests/configs/complex_named_app/k8s_cronjobs.yml +++ b/tests/configs/complex_named_app/k8s_cronjobs.yml @@ -3,7 +3,7 @@ metadata: name: generic-cronjob labels: { kubetools/name: generic-cronjob, - kubetools/project_name: generic-app, + kubetools/project_name: complex-named-app, kubetools/role: cronjob } annotations: { @@ -21,7 +21,7 @@ spec: name: generic-cronjob labels: { kubetools/name: generic-cronjob, - kubetools/project_name: generic-app, + kubetools/project_name: complex-named-app, kubetools/role: cronjob } annotations: { From eb5374044fa62770392be6658e2522be616f0b4f Mon Sep 17 00:00:00 2001 From: Fergus McWalters Date: Wed, 21 Feb 2024 10:56:02 +0000 Subject: [PATCH 13/20] improve documentation add incompatible version of Docker Desktop to CHANGELOG and add more detail to README as to why we need to be careful with this update --- CHANGELOG.md | 1 + README.md | 17 ++++++++--------- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 36451e8..66789a3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ ### Unreleased # v14.0.0 +- **DO NOT USE WITH DOCKER DESKTOP v4.27.[0..2]** as this has a bug using `insecure-registries` with `docker compose` - [issue here](https://github.com/docker/buildx/issues/2030) - this **BREAKS COMPATIBILITY** with previous versions of `ktd` (see README) - uses `docker compose` in place of `docker-compose`, meaning we use Docker compose v2 on the backend diff --git a/README.md b/README.md index c19d36f..f203e35 100644 --- a/README.md +++ b/README.md @@ -84,14 +84,6 @@ With this in your current directory, you can now: ktd up ``` -**NOTE**: there is a bug in the Docker BuildKit that ignores "insecure-registries". -As `docker compose` V2 uses BuildKit by default, the only way to currently get around this -is to append `DOCKER_BUILDKIT=0` in front of the `ktd` command, - -e.g: `DOCKER_BUILDKIT=0 ktd up`. - -This applies to all `Dockerfile`s where an insecure registry is specified. - ```sh # Deploy the project to a Kubernetes namespace kubetools deploy my-namespace @@ -101,7 +93,14 @@ kubetools deploy my-namespace **NOTE**: before upgrading to version 14.0 or above, you _must_ run `ktd destroy` for all existing local Kubetools projects. - +There is also a bug on the latest version of Docker Desktop that prevents the new Buildkit working with +insecure registries. This has been patched but the patch has yet to make its way to the latest release +of Docker Desktop - [issue here](https://github.com/docker/buildx/issues/2030). +There are a couple of workarounds: + * Downgrade to Docker Desktop v4.26.0 or below and append `http://` to each of your `insecure_registries`' URLs + * Alternatively, use the legacy builder by appending `DOCKER_BUILDKIT=0` in front of every `ktd` command. + +To install Kubetools run: ```sh pip install kubetools ``` From 9ff20c10b6e42a40a3710f65d8a4af7711b18742 Mon Sep 17 00:00:00 2001 From: Fergus McWalters Date: Tue, 27 Feb 2024 11:33:01 +0000 Subject: [PATCH 14/20] ensure dev release adheres to semver format --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 66789a3..42df41a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,7 +2,7 @@ ### Unreleased -# v14.0.0 +# v14.0.0-dev - **DO NOT USE WITH DOCKER DESKTOP v4.27.[0..2]** as this has a bug using `insecure-registries` with `docker compose` - [issue here](https://github.com/docker/buildx/issues/2030) - this **BREAKS COMPATIBILITY** with previous versions of `ktd` (see README) - uses `docker compose` in place of `docker-compose`, meaning we use Docker compose v2 on the backend From 8e7b32c54ec7314e4624269ddbafeafd69df198d Mon Sep 17 00:00:00 2001 From: Fergus McWalters Date: Tue, 27 Feb 2024 11:40:18 +0000 Subject: [PATCH 15/20] add reason in CHANGELOG why this is a dev release --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 42df41a..7f91b0d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,7 @@ # v14.0.0-dev - **DO NOT USE WITH DOCKER DESKTOP v4.27.[0..2]** as this has a bug using `insecure-registries` with `docker compose` - [issue here](https://github.com/docker/buildx/issues/2030) +- this is a `dev` release because of this bug - there is a workaround for this but we don't want to use workarounds in production - this **BREAKS COMPATIBILITY** with previous versions of `ktd` (see README) - uses `docker compose` in place of `docker-compose`, meaning we use Docker compose v2 on the backend From 4da3de5b6b1261a363b7be17e72a90a40911dc18 Mon Sep 17 00:00:00 2001 From: Fergus McWalters <94368623+fmcwalters-edited@users.noreply.github.com> Date: Wed, 28 Feb 2024 10:51:46 +0000 Subject: [PATCH 16/20] make workarounds more descriptive suggest migrating to secure Docker registries, reword the suggestion to use the legacy builder Co-authored-by: Germain Chazot --- README.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index f203e35..a552c61 100644 --- a/README.md +++ b/README.md @@ -97,8 +97,9 @@ There is also a bug on the latest version of Docker Desktop that prevents the ne insecure registries. This has been patched but the patch has yet to make its way to the latest release of Docker Desktop - [issue here](https://github.com/docker/buildx/issues/2030). There are a couple of workarounds: - * Downgrade to Docker Desktop v4.26.0 or below and append `http://` to each of your `insecure_registries`' URLs - * Alternatively, use the legacy builder by appending `DOCKER_BUILDKIT=0` in front of every `ktd` command. + * Migrate to secure registries (over HTTPS) + * Downgrade to Docker Desktop v4.26.0 or below and prefix with `http://`, each of your `insecure_registries`' URLs. + * Alternatively, use the legacy builder by setting the environment variable `DOCKER_BUILDKIT=0` for `ktd` commands. To install Kubetools run: ```sh From b9cc5a4cefc1758b48f11241471835c62c3ce99f Mon Sep 17 00:00:00 2001 From: Fergus McWalters Date: Wed, 28 Feb 2024 12:35:29 +0000 Subject: [PATCH 17/20] factor out code to convert container names, add unit tests make the code easier to test by moving the name conversion into its own function and add test coverage also add test coverage for `dockerise_label` --- .../backends/docker_compose/docker_util.py | 20 ++++++---- tests/test_docker_util.py | 37 +++++++++++++++++++ 2 files changed, 49 insertions(+), 8 deletions(-) create mode 100644 tests/test_docker_util.py diff --git a/kubetools/dev/backends/docker_compose/docker_util.py b/kubetools/dev/backends/docker_compose/docker_util.py index fef8793..5efdb20 100644 --- a/kubetools/dev/backends/docker_compose/docker_util.py +++ b/kubetools/dev/backends/docker_compose/docker_util.py @@ -136,14 +136,7 @@ def get_containers_status( if not env: env = compose_project.replace(docker_name, '') - # if the container was made in v1, it will be composename_container_N - converted_name = container.name.replace('_', '-') - - # we need to keep the middle part of the name - # for example if we have a container called `composename-container-1-N` - # we want to keep `container-1` - middle_names = converted_name.split('-')[1:-1] - name = '-'.join(middle_name for middle_name in middle_names) + name = _get_container_name_from_full_name(container.name) status = container.status == 'running' ports = [] @@ -198,6 +191,17 @@ def get_containers_status( return env_to_containers.get(kubetools_config['env'], {}) +def _get_container_name_from_full_name(full_name): + # if the container was made in v1, it will be composename_container_N + converted_name = full_name.replace('_', '-') + + # we need to keep the middle part of the name + # for example if we have a container called `composename-container-1-N` + # we want to keep `container-1` + middle_names = converted_name.split('-')[1:-1] + return '-'.join(middle_name for middle_name in middle_names) + + def get_container_status(kubetools_config, name): containers = get_containers_status(kubetools_config, container_name=name) return containers.get(name) diff --git a/tests/test_docker_util.py b/tests/test_docker_util.py new file mode 100644 index 0000000..74cb7fb --- /dev/null +++ b/tests/test_docker_util.py @@ -0,0 +1,37 @@ +from string import ascii_lowercase +from unittest import TestCase + +from kubetools.dev.backends.docker_compose.config import dockerise_label +from kubetools.dev.backends.docker_compose.docker_util import _get_container_name_from_full_name + + +def generate_long_names(number_of_separators, separator): + return separator.join([ + ch for ch in ascii_lowercase[:number_of_separators+1]]) + + +class TestDockerComposeNameConversion(TestCase): + # we need to check this works for dashes and underscores + def test_dockerise_label_dashes(self): + for i in range(5): + long_name = generate_long_names(i, '-') + dockerised_name = dockerise_label(long_name) + self.assertEqual(dockerised_name, ascii_lowercase[:i+1]) + + def test_dockerise_label_underscores(self): + for i in range(5): + long_name = generate_long_names(i, '_') + dockerised_name = dockerise_label(long_name) + self.assertEqual(dockerised_name, ascii_lowercase[:i+1]) + + def test_container_name_from_full_name_dashes(self): + for i in range(5): + container_name = generate_long_names(i, '-') + full_name = '-'.join([ascii_lowercase[:i+1], container_name, '1']) + self.assertEqual(_get_container_name_from_full_name(full_name), container_name) + + def test_container_name_from_full_name_underscores(self): + for i in range(5): + container_name = generate_long_names(i, '-') + full_name = '_'.join([ascii_lowercase[:i+1], container_name, '1']) + self.assertEqual(_get_container_name_from_full_name(full_name), container_name) From 7a8b920979214f3b3731fce5706bfd3f56f72628 Mon Sep 17 00:00:00 2001 From: Fergus McWalters Date: Wed, 28 Feb 2024 17:45:25 +0000 Subject: [PATCH 18/20] improve documentation for buildx issue, make CHANGELOG more concise add `TROUBLESHOOTING` section to README to document the issue with `insecure-registries` and link this to ticket which is open and relevant, for `buildx`. remove anything from the CHANGELOG which belongs here --- CHANGELOG.md | 5 +++-- README.md | 28 +++++++++++++++++----------- 2 files changed, 20 insertions(+), 13 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7f91b0d..5c1c9dc 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,8 +3,9 @@ ### Unreleased # v14.0.0-dev -- **DO NOT USE WITH DOCKER DESKTOP v4.27.[0..2]** as this has a bug using `insecure-registries` with `docker compose` - [issue here](https://github.com/docker/buildx/issues/2030) -- this is a `dev` release because of this bug - there is a workaround for this but we don't want to use workarounds in production +- before upgrading to version 14.0 or above, you _must_ run `ktd destroy` for all existing +local Kubetools projects. +- this is a `dev` release because of a bug in `docker/buildx` - there is a workaround for this but we don't want to use workarounds in production (see TROUBLESHOOTING in README) - this **BREAKS COMPATIBILITY** with previous versions of `ktd` (see README) - uses `docker compose` in place of `docker-compose`, meaning we use Docker compose v2 on the backend diff --git a/README.md b/README.md index a552c61..2257f66 100644 --- a/README.md +++ b/README.md @@ -90,17 +90,6 @@ kubetools deploy my-namespace ``` ## Installing - -**NOTE**: before upgrading to version 14.0 or above, you _must_ run `ktd destroy` for all existing -local Kubetools projects. -There is also a bug on the latest version of Docker Desktop that prevents the new Buildkit working with -insecure registries. This has been patched but the patch has yet to make its way to the latest release -of Docker Desktop - [issue here](https://github.com/docker/buildx/issues/2030). -There are a couple of workarounds: - * Migrate to secure registries (over HTTPS) - * Downgrade to Docker Desktop v4.26.0 or below and prefix with `http://`, each of your `insecure_registries`' URLs. - * Alternatively, use the legacy builder by setting the environment variable `DOCKER_BUILDKIT=0` for `ktd` commands. - To install Kubetools run: ```sh pip install kubetools @@ -150,6 +139,23 @@ minikube delete ... ``` + +## Troubleshooting +There is a bug in `buildx` which is present in Docker Engine v25.0 and up, which is yet to be patched and causes `insecure-registries` to be ignored - [issue here](https://github.com/docker/buildx/issues/2226). +Versions of Docker Desktop which use versions of Docker Engine lower than 25.0 are unaffected. + +If you try and run `ktd up` with reference to an unsecure registry, e.g. `http://docker-registry.example.net` and are affected by this bug, you will get an error message that is +similar to the following: +``` +ERROR: failed to do request: Head "https://docker-registry.example.net/3.6_alpine3.13_v0.1-multi": dialing docker-registry.example.net:443 with direct connection: connecting to 1.1.1.1:443: dial tcp 1.1.1.1:443: connect: connection refused +``` + +There are a few of workarounds: + * Migrate to secure registries (over HTTPS) + * Downgrade to Docker Desktop v4.26.1 or below and prefix `http://` to each of your `insecure_registries`' URLs. + * Alternatively, use the legacy builder by setting the environment variable `DOCKER_BUILDKIT=0` for `ktd` commands. + + ## Releasing (admins/maintainers only) * Update [CHANGELOG](CHANGELOG.md) to add new version and document it * In GitHub, create a new release From 700658a74e29a253bdd9568e4b55c37dddadcb11 Mon Sep 17 00:00:00 2001 From: Fergus McWalters Date: Tue, 2 Apr 2024 15:54:23 +0100 Subject: [PATCH 19/20] remove unused import --- kubetools/dev/backends/docker_compose/docker_util.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/kubetools/dev/backends/docker_compose/docker_util.py b/kubetools/dev/backends/docker_compose/docker_util.py index 8b0b68b..5efdb20 100644 --- a/kubetools/dev/backends/docker_compose/docker_util.py +++ b/kubetools/dev/backends/docker_compose/docker_util.py @@ -1,5 +1,3 @@ -import sys - from functools import lru_cache import docker From 0f3b1bfce50a9d2fbab329a71e5343387796d618 Mon Sep 17 00:00:00 2001 From: Fergus McWalters Date: Thu, 11 Jul 2024 17:06:55 +0100 Subject: [PATCH 20/20] use full version number --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7ae25d3..3981de1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,7 +2,7 @@ ### Unreleased -# v14.0.0-dev +# v14.0.0 - before upgrading to version 14.0 or above, you _must_ run `ktd destroy` for all existing local Kubetools projects. - this is a `dev` release because of a bug in `docker/buildx` - there is a workaround for this but we don't want to use workarounds in production (see TROUBLESHOOTING in README)