Is it possible to wrap a docker image, and do works before and after it's origin operations?

1/25/2021

I'm trying to use sonarsource/sonar-scanner-cli as a kubernetes container, so I do this in a yaml:

- name: "sonarqube-scan-{{ .Values.git.commitID }}"
  image: "{{ .Values.harbor.host }}/{{ .Values.harbor.cache }}/sonarsource/sonar-scanner-cli"
  env:
    # Sonarqube's URL
    - name: SONAR_HOST_URL
      valueFrom:
        secretKeyRef:
          name: sonarqube
          key: sonar-url
    # Auth token of sonarqube's bot
    - name: SONAR_LOGIN
      valueFrom:
        secretKeyRef:
          name: sonar-bot
          key: sonar-token
  volumeMounts:
    - mountPath: /usr/src
      name: initrepo

Now, I want to do some pre-setup before the sonarsource/sonar-scanner-cl regular run and parse the docker container's run output for some other works. If this is a shell script, I do like:

$before.sh
$sonar-scanner-cl.sh | after.sh

I guess I can build a new docker image which is FROM sonarsource/sonar-scanner-cl, and put processes in before.sh and after.sh in its run script, but I don't know how to call the original sonarsource/sonar-scanner-cl run commands. What are the actual commands?

Or, alternatively, does kubernetes have a way to do this?

-- Romulus Urakagi Ts'ai
docker
kubernetes

1 Answer

1/25/2021

Here's how one can modify container commands without building another image.

  1. Pull the image
docker pull sonarsource/sonar-scanner-cli
  1. Inspect it
docker inspect sonarsource/sonar-scanner-cli

You should get something like this:

            "Cmd": [
                "/bin/sh",
                "-c",
                "#(nop) ",
                "CMD [\"sonar-scanner\"]" <- arguments
            ],
            "WorkingDir": "/usr/src",
            "Entrypoint": [ <- executable
                "/usr/bin/entrypoint.sh"
            ],

Entrypoint is what will be executed and CMD [...] (not Cmd) are the arguments for the executable. In a human-friendly format that equals to:

#      entrypoint          args
/usr/bin/entrypoint.sh sonar-scanner

Now in this case we have a script that is being executed so there are two options.

Option 1: Modify the entrypoint script and mount it at launch

  1. Run this to save the script on your machine:
docker run --rm --entrypoint="" sonarsource/sonar-scanner-cli /bin/cat /usr/bin/entrypoint.sh > entrypoint.sh
  1. Modify entrypoint.sh as you like, then put its contents into a configMap.
  2. Mount the file from the configMap instead of /usr/bin/entrypoint.sh (don't forget to set mode to 0755)

Option 2: Change entrypoint and arguments in resource definition

Note that this may not work with some images (ones with no shell inside).

- name: "sonarqube-scan-{{ .Values.git.commitID }}"
  image: "{{ .Values.harbor.host }}/{{ .Values.harbor.cache }}/sonarsource/sonar-scanner-cli"
  command: # this is entrypoint in k8s API
    - /bin/sh
    - -c
  args:  # this goes instead of CMD
    - "before.sh && /usr/bin/entrypoint.sh sonar-scanner && after.sh"
                 # | original command and args          | 
-- anemyte
Source: StackOverflow