devspace icon indicating copy to clipboard operation
devspace copied to clipboard

`exec_container` does not respect `devImage`

Open joshuamanns opened this issue 2 years ago • 6 comments

What happened? When adding an exec_container command to a pipeline, the resulting deployment overrides the dev.<service_name>.devImage property of the service and instead causes the runtime.images.<service_name> value to be referenced.

This results in an ImagePullBackOff error when no image has been pushed to the registry.

It appears to happen irrespective of matching image/label selections and which pipeline it is is run from.

What did you expect to happen instead? The exec_container command would not modify which image is referenced in the deployment, using devImage when one is specified, and image otherwise.

How can we reproduce the bug? (as minimally and precisely as possible)

My devspace.yaml:

version: v2beta1
name: exec_container_bug

vars:
  REGISTRY_HOST:
    name: REGISTRY_HOST
    source: env
    default: registry-push:5000
  REGISTRY_NAME:
    name: REGISTRY_NAME
    source: env
    default: frontend

pipelines:
  dev:
    run: |-
      run_dependencies --all
      create_deployments --all
      # comment this command out to observe how `devImage` is respected
      exec_container --label-selector "app.kubernetes.io/component=web-server,app.kubernetes.io/name=frontend" -- \
                      sh -c 'echo hi'
      start_dev --all
  
images:
  next-server:
    image: ${REGISTRY_HOST}/${REGISTRY_NAME}/frontend
    tags:
      - 'devspace-${devspace.git.commit}-####'
    dockerfile: ./frontend/Dockerfile
    context: frontend/
    target: app
    appendDockerfileInstructions:
      - USER root
      - RUN apt update -y
      - RUN apt install curl vim -y
    rebuildStrategy: default

deployments:
  next-server:
    helm:
      releaseName: frontend
      chart:
        path: ./helm

dev:
  web-server:
    labelSelector:
      app.kubernetes.io/component: web-server
      app.kubernetes.io/name: frontend
    devImage: ghcr.io/loft-sh/devspace-containers/typescript:17-alpine
    sync:
      - path: .:.
        disableDownload: true
        initialSync: preferLocal
        waitInitialSync: true
        excludeFile: .gitignore
        excludePaths:
          - ".git/"
        uploadExcludePaths:
          - Dockerfile
          - .dockerignore
        onUpload:
          restartContainer: true
          exec:
          - command: |-
              npm install
            name: 'Install node modules'
            onChange: ["./package.json"]
    restartHelper:
      inject: true
    command: ["node", "server.js"]

Local Environment:

  • DevSpace Version: [use devspace --version] devspace version 6.0.1
  • Operating System: debian linux bullseye
  • ARCH of the OS: ARM64 Kubernetes Cluster:
  • Cloud Provider: aws
  • Kubernetes Version: [use kubectl version] v1.25.0

/kind bug

joshuamanns avatar Sep 07 '22 22:09 joshuamanns

@joshuamanns thanks for reporting this issue! The problem seems to be that you first exec into the container and then it will be replaced by the dev configuration. Would reordering it be an option for you like this:

pipelines:
  dev:
    run: |-
      run_dependencies --all
      create_deployments --all
      # comment this command out to observe how `devImage` is respected
      start_dev --all
      exec_container --label-selector "app.kubernetes.io/component=web-server,app.kubernetes.io/name=frontend" -- \
                      sh -c 'echo hi'

FabianKramm avatar Sep 08 '22 11:09 FabianKramm

Thanks @FabianKramm. So my use case is that I would like to take a devImage, install some build tools inside of it, and build some dependencies from source in the devImage container itself when I sync files (if you're truly curious I can explain "why" later 😄 ), then start the process using the compiled build output. exec_container seemed like the way I should approach that, but perhaps it is not?

joshuamanns avatar Sep 09 '22 01:09 joshuamanns

Hey @joshuamanns ! I see, with DevSpace v6.1.0 you can do that via:

dev:
  web-server:
    labelSelector:
      app.kubernetes.io/component: web-server
      app.kubernetes.io/name: frontend
    devImage: ghcr.io/loft-sh/devspace-containers/typescript:17-alpine
    sync:
      - path: .:.
        disableDownload: true
        excludeFile: .gitignore
        excludePaths:
          - ".git/"
          - Dockerfile
          - .dockerignore
        onUpload:
          restartContainer: true
          exec:
          - command: |-
              # Your init commands
              apt install ...  
            once: true # <- Only execute this one time during the pod's lifecycle
          - command: |-
              npm install
            name: 'Install node modules'
            onChange: ["./package.json"]
    command: ["node", "server.js"]

FabianKramm avatar Sep 09 '22 16:09 FabianKramm

Ah, interesting @FabianKramm - I've just tested and it does not seem to play well if the file in the dev.*.command is not available until after onUpload.exec.command is run. So in my case, server.js isn't built until the init commands finish, which results in the the container spinning.

joshuamanns avatar Sep 09 '22 20:09 joshuamanns

@joshuamanns but isn't that what you want? Or do you want to start the container first and then run the init script?

FabianKramm avatar Sep 12 '22 11:09 FabianKramm

Hello, @joshuamanns!

Seems that we might have misunderstood the flow you are trying to achieve. We would be happy to further support you in this matter if you could provide us with more details about your desired outcome.

Please let us know if there is anything else we could help with! Thank you for your contribution!

alexandradragodan avatar Oct 21 '22 10:10 alexandradragodan