# Question
Title: Copy multiple files using * wildcard from kubernetes container
I have several files named out1, out2, ... in my Kubernetes container. I want to copy them to my local computer. I am using:

```
$ kubectl cp pod:/path/out* .

```

But I am getting an error:

> tar: Removing leading \`/' from member names
> tar: /path/out\*: Cannot stat: No such file or directory tar: Exiting with failure status due to previous errors
> error: path/out\* no such file or directory

How can I use `kubectl cp` with wildcards?

# Answer
> 13 votes
Wildcard support was added to `kubectl cp` in the #72641 pull request.

It is merged but **only available in Kubernetes v1.14.0**. Take a look at the ChangeLog:

> Notable Features:
> \[...\]
> • kubectl supports copying files with wild card (#72641, @dixudx)

However, as stated on the issue #78854 the PR was made without proper tests and **the feature is actually broken**. The PR to fix the problem (#78928) is open since June, and it's not merged yet.

Although the PR to fix the feature exists, they are also considering removing the support to wildcard copy.

# Answer
> 14 votes
You can do that using this command:

```
kubectl cp -n [NAMESPACE] [POD_NAME]:/[POD_DIRECTORY]/. .

```

# Answer
> 3 votes
As there is no wildcard support, a workaround is to do a 2-step process to achieve the same:

* `kubectl exec ...` to do make a new tmp directory and wildcard copy/move your desired transfer files into that dir on the container
* use the cmd from @cookiedough above to copy all files from that dir on the container to your local

Example:

```
export TARGET_POD="myapp-mypod1234" && \
kubectl exec "$TARGET_POD" -n MYNAMESPACE "$TARGET_POD" \
-- sh -c "mkdir -p /tmp/outfiles && cp /path/out* /tmp/outfiles/" && \
kubectl cp "sites/$TARGET_POD:/tmp/outfiles/." .

```

# Answer
> 3 votes
I had a similar requirement and finally settled on:

```
mkdir /my/dest/dir
kubectl  exec $TARGET_POD -n MYNAMESPACE -- tar -zcvf - -C /my/src/directory . | tar -zxvf - -C /my/dest/dir

```

This depends on 'tar' being available inside the container. Similar can be done with any archive command (zip/unzip or cpio) that can deal with stdin/stdout as long as the command is in both the container and the host.

Also note that '\*' is not native to tar, but depends on shell expansion (in my experience...), so if you want to match only certain files in a directory on the container I include 'bash' in the call and cd to the directory first:

```
kubectl  exec $TARGET_POD -n MYNAMESPACE -- bash -c "cd /my/src/directory;tar -zcvf - *.log" | tar -zxvf - -C /my/dest/dir

```

Again, bash or some other shell supporting * expansion must be present in the container.

Finally, this works in the other direction as well sending multiple files to a container:

```
cd /my/src/dir
tar -zcvf - *.log | kubectl exec $TARGET_POD -n MYNAMESPACE --stdin -- tar -zxvf - -C /my/dest/dir

```

And "bash" is your friend if the target directory does not exist:

```
tar -zcvf - *.log | kubectl exec $TARGET_POD -n MYNAMESPACE --stdin -- bash -c "mkdir -p /my/dest/dir;tar -zxvf - -C /my/dest/dir"

```

# Answer
> 0 votes
For everyone's benefit, I am pasting working code as suggested by **heyjared** user on https://github.com/kubernetes/kubernetes/issues/78854

```
Use find with xargs as a workaround:

find . | xargs -i{} kubectl cp {} namespace/pod:path

```

It worked for me. I replaced "." with my needed source path.

Example:

```
find <source_path> | xargs -i{} kubectl cp {} namespace/pod:<path_inside_pod>

```

Like:

```
find /var/tmp/data/ | xargs -i{} kubectl cp {} namespace/pod:/tmp/

```

This will copy all contents inside local /var/tmp/data/ directory and store it under /tmp/ inside pod.

---
Tags: kubernetes, kubectl
---


# Question
Title: Unable to create a project with MANUAL as source in AWX
I have followed the instructions to install AWX from this site.

https://computingforgeeks.com/install-and-configure-ansible-awx-on-centos/

But I'm unable to create manual SCM project on new project on ansible AWX. I get the below error message.

> There are no available playbook directories in /var/lib/awx/projects. Either that directory is empty, or all of the contents are already assigned to other projects. Create a new directory there and make sure the playbook files can be read by the “awx” system user, or have AWX directly retrieve your playbooks from source control using the Source Control Type option above.

# Answer
1. awx system account needs having read permission on the directory and all files/playbooks in it.
2. I tried and it needs to reboot the AWX server once in order for AWX to index that manual project directory so that it will be available in the drop down list.

Good luck.
> 0 votes

---
Tags: ansible, centos, awx
---


# Question
Title: How can I check for an installed packaged version on multiple linux hosts?
i need to check more than 100 servers for the snapd package, but I don't like the output at all. I searched all day for different options without luck. Attached is the output of ansible-playbook. Any hints guys?

```
---
 - hosts: centos
   become: true
   tasks:
    - name: Check Hostname
      command: /usr/bin/hostname

    - name: Check for package if is installed
      yum:
        list: snapd
      register: result

```

For checking the package version I tried with the following playbook but Ansible doesn't like the syntax:

```
---
 - hosts: test2
   become: true
   tasks:
    - name: Check Hostname
      command: /usr/bin/hostname

    - name: Check for package if is installed
      yum:
        list: snapd
      register: package_name_version

    - name: set package version
      set_fact:
        package_name_version: "{{ package_name_version.results|selectattr('yumstate','equalto','installed')|map(attribute='version')|list|first }}"

```

Thanks, Juls

# Answer
**Ansible approach.** Due to the possibility of multiple versions of the same package being installed, the package dictionary value is a list. To resolve this, simply take the first element of the list.

```
  tasks:
    - name: Gather the package facts
      ansible.builtin.package_facts:
        manager: auto

    - name: Check whether a package is installed
      ansible.builtin.debug:
        msg: "{{ ansible_facts.packages['google-chrome-stable'][0].version }}"
      when: "'google-chrome-stable' in ansible_facts.packages"

```
> 0 votes

# Answer
A simple way would be to do:

```
ansible -i <inventory> <target group, lets' say some CentOS systems> -m shell -a "rpm -qa | grep <package name>"

```

That would display a list consisting of server name and package version.
> 0 votes

# Answer
The "Ansible approach" would look like this:

```
- name: Check whether a package called snapd is installed
  ansible.builtin.debug:
    msg: "{{ ansible_facts.packages['snapd'].version }} version of snapd is installed!"
  when: "'snapd' in ansible_facts.packages"

```
> 0 votes

---
Tags: ansible
---


title: How can I use S3 as a filesystem

text:
# Question
Title: How can I use S3 as a filesystem
I'm not sure if it's something I'm doing wrong, or if the S3 web interface is just trash. There are a ton of basic capabilities that work in pretty much any other file storage product (Windows Explorer, Google Drive, OneDrive etc.), which don't work in S3:

1. The search string must be 100% exact--case-sensitive (if I search "myfile" and the file happens to be "MyFile", it won't find it), no wildcards or searching multiple words (if my file is something like "puppy-picture-2340987254309874345.jpg", I can't just search for "puppy picture" or even "puppy-picture-\*.jpg", I have to already know the exact filename I'm looking for), etc.
2. I can only download 1 item at a time?? If I select 1 object, the Download button is available but if I select a second object it's not. I don't think I've ever seen any file store site/product that won't allow you to download multiple files, it's one of the most basic capabilities.
3. Can't rename directories.

Again, I'm not sure if there's something I'm doing wrong but I've never been able to get the above issues to work. It just blows my mind because these all seem like very simple, basic functions.

# Answer
This was going to be a comment, but I'll add it as an answer and take the consequences.

Yes, you are doing it wrong. S3 is an **object store**. The things you are looking for (search, directories, etc) are for **filesystems**. You are asking a fish to climb a tree

You can mount S3 onto a filesystem, but it is not a filesystem.

If you want an object storage to do filesystem things, then mount it into a filesystem. See:

https://github.com/awslabs/mountpoint-s3/

However if you actually want a filesystem, why not use a filesystem:

https://aws.amazon.com/efs/
> 3 votes

# Answer
* A lot of people interface with AWS not over the web, but via the command line.
* There are already external programs for accessing S3 via a friendly interface, like Cyberduck.
* A lot of people who use AWS are very technical and do not need friendly user interfaces.
* People use AWS for work, and thus have more time to deal with user interfaces. Contrast that with a casual app or website, where if the user doesn't figure out what they want in 3 seconds they might just leave and never come back.
> 0 votes

---
Tags: amazon-s3, s3
---


# Question
Title: What is the URL I provide to docker or podman to pull down a GitLab registry image?
When I am at a repo's container registry, I can see this,

However it's not clear ohw that URL works, the URL provided is

> `gitlab-org/gitlab-runner/alpine-no-root`

But I can't run

```
podman pull gitlab-org/gitlab-runner/alpine-no-root

```

It asks me to choose between the docker.io or quay.io registry, GitLab isn't an option. Moreover, if I try, to add `gitlab.org/`, I get an error

```
$ podman pull "gitlab.org/gitlab-org/gitlab-runner/alpine-no-root"
Trying to pull gitlab.org/gitlab-org/gitlab-runner/alpine-no-root:latest...
Error: initializing image from source docker://gitlab.org/gitlab-org/gitlab-runner/alpine-no-root:latest: invalid character '<' looking for beginning of value

```

And, if I try to specify `registry.gitlab.org` I get another -- different error -- and it can't find the repository,

```
$ podman pull "registry.gitlab.org/gitlab-org/gitlab-runner/alpine-no-root"
Trying to pull registry.gitlab.org/gitlab-org/gitlab-runner/alpine-no-root:latest...
Error: initializing source docker://registry.gitlab.org/gitlab-org/gitlab-runner/alpine-no-root:latest: pinging container registry registry.gitlab.org: Get "https://registry.gitlab.org/v2/": dial tcp: lookup registry.gitlab.org on 127.0.0.1:53: no such host

```

How do I pull this image?

# Answer
You must use

```
registry.gitlab.com/gitlab-org/gitlab-runner/alpine-no-root

```
* The project is `gitlab-org`
* The domain is `gitlab.com`
* The registry is at `registry.gitlab.com`

The naming convention on the GitLab registry is,

```
<registry URL>/<namespace>/<project>/<image>

```

So you want,

```
registry.gitlab.com/gitlab-org/gitlab-runner/alpine-no-root

```

---

# Easy way

Click the clipboard icon to copy the url,

You may think that copies the name, but it copies the full registry URL you want.
> 1 votes

---
Tags: gitlab, docker-registry
---


# Question
Title: What happens when you are running a "too old" version of k8s in eks?
I'm desperately trying to resolve all of our dockershim uses so we can migrate to EKS 1.24+, but I'm not optimistic I'll get it done before the "deadline".

I'm stuck on EKS 1.23 until I can replace DooD. I wonder what will happen when it's no longer supported in October?

# Answer
> 2 votes
Check out the eks versions faq at the bottom of this page:

> Q: What happens on the end of support date?
>
> A: On the end of support date, \[...\]. Existing control planes are automatically updated by Amazon EKS to the earliest supported version through a gradual deployment process after the end of support date. \[...\]

End of support date for 1.23 is October 11, 2023

Also about timing:

> Q: When exactly is my control plane automatically updated after the end of support date?
>
> A: Amazon EKS can't provide specific time frames. Automatic updates can happen at any time after the end of support date.

so you should do it yourself to keep control. Otherwise it could happen any time after the EOL date.

They also state why they do it like that:

> Q: Can I leave my control plane on a Kubernetes version indefinitely?
>
> A: No. Cloud security at AWS is the highest priority. \[...\]

But the worker nodes are under your domain

> Q: Are Amazon EKS managed node groups automatically updated along with the cluster control plane version?
>
> A: No. A managed node group creates Amazon EC2 instances in your account. \[...\] The Kubernetes version that's on your managed node group might be more than one version earlier than your control plane. \[...\]

so your dockershim use-cases should be save.

---
Tags: kubernetes, amazon-web-services, eks
---


# Question
Title: Docker on Ubuntu, getting ERROR: BuildKit is enabled but the buildx component is missing or broken. Install the buildx component
I ran the command `sudo rm -rf ~/.local/share/containers/` and now I'm getting,

```
ERROR: BuildKit is enabled but the buildx component is missing or broken.
       Install the buildx component to build images with BuildKit:
       https://docs.docker.com/go/buildx/

```

When I try to run `docker build` how can I resolve this error?

# Answer
> 0 votes
In my case, the solution was to remove the distro provided docker (which I didn't have -- this is just for safety),

```
$ for pkg in docker.io docker-doc docker-compose podman-docker containerd runc; do sudo apt-get remove $pkg; done

```

Which should do nothing, and didn't for me but that's fine. Then you need to reinstall `docker-ce`,

```
apt-get --reinstall install docker-ce

```

In my case, that didn't work either, because the distro upgrade from one version of Ubuntu to another disabled the `docker-ce` repo, so I had to re-add that, I just re-ran the commands Docker provides,

```
# Add Docker's official GPG key:
sudo apt-get update
sudo apt-get install ca-certificates curl gnupg
sudo install -m 0755 -d /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
sudo chmod a+r /etc/apt/keyrings/docker.gpg

# Add the repository to Apt sources:
echo \
  "deb [arch="$(dpkg --print-architecture)" signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu \
  "$(. /etc/os-release && echo "$VERSION_CODENAME")" stable" | \
  sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
sudo apt-get update

```

Then I ran,

```
apt-get --reinstall install docker-ce

```

And it worked!

---
Tags: docker, ubuntu
---


# Question
Title: Mac M1 Docker Desktop no longer launches
I’ve been using Docker Desktop on my Mac M1 for over a year without trouble and just today it seems to have stopped working. It may have coincided with an update.

When trying to open Docker Desktop by double clicking the Docker App icon, it just doesn’t open (and no error message is displayed - it seems to fail silently). When I try to start it up via docker-compose on the cli, the below exceptions are thrown. Could anyone please advise next course of action?

Many thanks.

```
manachi@macmone lamp % docker-compose up -d
Traceback (most recent call last):
  File "urllib3/connectionpool.py", line 670, in urlopen
  File "urllib3/connectionpool.py", line 392, in _make_request
  File "http/client.py", line 1255, in request
  File "http/client.py", line 1301, in _send_request
  File "http/client.py", line 1250, in endheaders
  File "http/client.py", line 1010, in _send_output
  File "http/client.py", line 950, in send
  File "docker/transport/unixconn.py", line 43, in connect
FileNotFoundError: [Errno 2] No such file or directory

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "requests/adapters.py", line 439, in send
  File "urllib3/connectionpool.py", line 726, in urlopen
  File "urllib3/util/retry.py", line 410, in increment
  File "urllib3/packages/six.py", line 734, in reraise
  File "urllib3/connectionpool.py", line 670, in urlopen
  File "urllib3/connectionpool.py", line 392, in _make_request
  File "http/client.py", line 1255, in request
  File "http/client.py", line 1301, in _send_request
  File "http/client.py", line 1250, in endheaders
  File "http/client.py", line 1010, in _send_output
  File "http/client.py", line 950, in send
  File "docker/transport/unixconn.py", line 43, in connect
urllib3.exceptions.ProtocolError: ('Connection aborted.', FileNotFoundError(2, 'No such file or directory'))

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "docker/api/client.py", line 214, in _retrieve_server_version
  File "docker/api/daemon.py", line 181, in version
  File "docker/utils/decorators.py", line 46, in inner
  File "docker/api/client.py", line 237, in _get
  File "requests/sessions.py", line 543, in get
  File "requests/sessions.py", line 530, in request
  File "requests/sessions.py", line 643, in send
  File "requests/adapters.py", line 498, in send
requests.exceptions.ConnectionError: ('Connection aborted.', FileNotFoundError(2, 'No such file or directory'))

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "docker-compose", line 3, in <module>
  File "compose/cli/main.py", line 81, in main
  File "compose/cli/main.py", line 200, in perform_command
  File "compose/cli/command.py", line 60, in project_from_options
  File "compose/cli/command.py", line 152, in get_project
  File "compose/cli/docker_client.py", line 41, in get_client
  File "compose/cli/docker_client.py", line 170, in docker_client
  File "docker/api/client.py", line 197, in __init__
  File "docker/api/client.py", line 221, in _retrieve_server_version
docker.errors.DockerException: Error while fetching server API version: ('Connection aborted.', FileNotFoundError(2, 'No such file or directory'))
[767] Failed to execute script docker-compose

```

# Answer
> 0 votes
It turns out after restarting my computer again, there was a prompt requesting escalated admin privileges and then agreeing to new license terms. I didn't seem to see this the last 2 reboots. After both those steps, it's now working again as expected.

# Answer
> 0 votes
If you are on mac, you probably need to check the `Allow the default Docker socket to be used` checkbox.

---
Tags: docker, docker-compose, macos
---


# Question
Title: Setup keycloak with mysql via docker compose
I've been trying to get keycloak running for a bit now. I had it going using the legacy tag but it seems like bad practice to get started with a legacy version. So I wanted to get the most recent version running. This is my docker compose config, but somehow It wont work. It has something todo with the database connection but I cant figure out what's going wrong.

```
version: '3'
volumes:
  mysql_data2:
      driver: local
services:
  mysql:
      container_name: keycloak_mysql
      image: mysql:5.7
      volumes:
        - mysql_data2:/var/lib/mysql
      environment:
        MYSQL_ROOT_PASSWORD: MyRootPassword
        MYSQL_DATABASE: keycloak
        MYSQL_USER: keycloak
        MYSQL_PASSWORD: MyKeycloakMySQLPassword
  keycloak:
      container_name: keycloak_keycloak
      image: quay.io/keycloak/keycloak:22.0.3
      environment:
        KC_DB: MYSQL
        KC_DB_URL_HOST: mysql
        KC_DB_SCHEMA: keycloak
        KC_DB_USERNAME: keycloak
        KC_DB_PASSWORD: MyKeycloakMySQLPassword
        KEYCLOAK_ADMIN: admin
        KEYCLOAK_ADMIN_PASSWORD: MyKeycloakAdminPassword
        KC_HOSTNAME_STRICT: "false"
        KC_HTTP_RELATIVE_PATH: "/keycloak"
        KC_PROXY: "edge"
      ports:
        - 8080:8080
        - 8443:8443
      depends_on:
        - mysql
      command:
        - "start"

```

# Answer
> 1 votes
I think the `KC_DB_` environment variables are supposed to be just `DB_`. If I rewrite your `compose.yaml` like this...

```
  keycloak:
      container_name: keycloak_keycloak
      image: quay.io/keycloak/keycloak:22.0.3
      environment:
        DB: MYSQL
        DB_URL_HOST: mysql
        DB_SCHEMA: keycloak
        DB_USERNAME: keycloak
        DB_PASSWORD: MyKeycloakMySQLPassword

```

...then it starts up without errors and I can connect to the console at http://localhost:8080/keycloak/.

---

A couple of comments unrelated to your question:

Your `depends_on` is effectively a no-op, because it just waits for successful container startup; it doesn't know whether or not mysql is ready to accept connections. To make it useful you need to (a) implement a health check on the mysql container and then (b) use the extended form of `depends_on`. Something like:

```
volumes:
  mysql_data2:
    driver: local

services:

  mysql:
    image: mysql:5.7
    volumes:
      - mysql_data2:/var/lib/mysql
    environment:
      MYSQL_ROOT_PASSWORD: MyRootPassword
      MYSQL_DATABASE: keycloak
      MYSQL_USER: keycloak
      MYSQL_PASSWORD: MyKeycloakMySQLPassword

      # This provides the password to the healthcheck command
      MYSQL_PWD: MyRootPassword
    healthcheck:
      test:
        - CMD
        - mysql
        - -e
        - select 1
      interval: 10s
      start_period: 20s
      timeout: 5s

  keycloak:
    depends_on:
      mysql:
        condition: service_healthy
    image: quay.io/keycloak/keycloak:22.0.3
    environment:
      DB: MYSQL
      DB_URL_HOST: mysql
      DB_SCHEMA: keycloak
      DB_USERNAME: keycloak
      DB_PASSWORD: MyKeycloakMySQLPassword
      KEYCLOAK_ADMIN: admin
      KEYCLOAK_ADMIN_PASSWORD: MyKeycloakAdminPassword
      KC_HOSTNAME_STRICT: 'false'
      KC_HTTP_RELATIVE_PATH: /keycloak
      KC_PROXY: edge
    ports:
      - 8080:8080
      - 8443:8443
    command:
      - start

```

Lastly, on my system I was experiencing very long startup times for the mysql container. I was able to resolve this by constraining the number of open files:

```
  mysql:
    ulimits:
      nofile:
        soft: 1024
        hard: 1024

```

This is probably not appropriate for a production configuration, but it reduced the startup time from at least a minute to just a few seconds.

---
Tags: docker-compose, mysql, keycloak
---


title: Azure DevOps Clean after pipeline run

text:
# Question
Title: Azure DevOps Clean after pipeline run
I have self-hosted build agents using Azure DevOps. We have the clean flag in the checkout step, however we run out of space sometimes.

**What is the preferred way of cleaning the agents' work directories?**

The problem is, that the clean process is in the beginning of a pipeline, and leaves everything behind. This is even worse if we have two parallel builds. (First clean then clones the repo, then the second cleans and clones the repo, then first build, then there is no space for the second build). Unless the first build is scheduled again, the build outputs stays on the agent.

We tried to schedule a deletion task every day, but it doesn't solve our problems.

We tried to add a script at the end of our `yaml` file that cleans the working dir. Is it recommended?

```
    - powershell: Remove-Item $(Pipeline.Workspace)/** -Force
      displayName: Clean after publish

```

Also it would be great if we could clean up even if the build fails, or someone cancels it midway.

# Answer
There is a `clean` option within the job properties. See the job definition.

> ```
> jobs:
> - job:
> ...
>  workspace:  # Workspace options on the agent.
>    clean: string # Which parts of the workspace should be scorched before fetching.  (outputs, resources, all)
>
> ```

As it would be called before fetching, there will be always space for the new build.
> 1 votes

# Answer
```
- task: DeleteFiles@1
  displayName: 'clean *'
  inputs:
    SourceFolder: '$(Pipeline.Workspace)'
    Contents: '**/*'
    RemoveDotFiles: true
  condition: always()

```

will clean everything in '$(Pipeline.Workspace)/notClean/**allClean**'.
> 2 votes

# Answer
I tried to use `DeleteFiles@1`, like @lionclub. But the implementation is very slow for large repositories.

So, I decided to use PowerShell:

```
- task: PowerShell@2
  displayName: 'Cleanup source folder'
  inputs:
    targetType: 'inline'
    script: 'Get-ChildItem -Recurse | foreach { Write-Host $_.FullName ; Remove-Item $_.FullName -Force -Recurse }'
    failOnStderr: true
    pwsh: true
    workingDirectory: '$(Build.SourcesDirectory)'

```

There are variations:

1. Using `failOnStderr` or not
2. Using PowerShell or PowerShell Core (`pwsh: true`)
3. Add separate tasks for `$(Build.ArtifactStagingDirectory)` and `$(Build.BinariesDirectory)`
4. Clear complete working folder e.g. by using variable `$(Agent.BuildDirectory)`
5. Adding `condition: always()` to always clear folder, incl. failed runs
> 2 votes

---
Tags: azure-pipelines
---


title: Rules to avoid parents of same WIT type

text:
# Question
Title: Rules to avoid parents of same WIT type
I noticed that it sometimes happens that users select parents from the same type like story-story, epic-epic, ... According to this post: https://developercommunity.visualstudio.com/t/same-category-hierarchy-error-but-the-specified-wo/761057 It's highly recommended to avoid this, due to obvious reasons.

Is it possible to prevent this by default? Like a rule: if WIT is changed & parent type equals WIT type --\> error

# Answer
> 0 votes
No there is no built-in way to setup rules over work item relationships.

The options that are supported can be found here.

---
Tags: azure-devops
---


# Question
Title: How to declaratively configure self hosted build agents for CI?
We assemble android application using GH Actions on self-hosted agents. Right now we upgraded a couple of libraries and now we need to use another JDK version. Issue is that right now we need to manually go through each agent and set up new JDK version there.

I am wondering, maybe is there a tool that can configure build agents (or any machine, actually) (I am talking about installing tools, choosing their versions, etc.) in a declarative way. Like having yaml or any other type of file which has all required information and the tool will do anything required to meet requirements defined in a config file.

Docker is already doing something like that, but it's not really declarative and it creates overhead, which is something we can not allow.

# Answer
If you have Docker on the machines which are hosting the github runners, and you have already registered them with the repos containing the pipelines which will execute them, you have a few options available:

1. The easiest, but most invasive way of doing this is to use the machines as bare-metal provisioned. I would write an ansible role and playbook (this provides your declarative configuration) to turn a vanilla machine into a provisioned runner.
2. If you create Github Actions, you can package them into containers (using the same Ansible role and playbook as above), and update your `workflow.yml` to use these actions or containers on the host. You will have to build the container that the workflow or action needs before. If you want to have a declarative configuration for these containers too, you can write a Packer template.
3. Finally, customise the the containers that are used by the runner: See https://docs.github.com/en/actions/hosting-your-own-runners/managing-self-hosted-runners/customizing-the-containers-used-by-jobs. You can use that to define mount points (for special licensed software, e.g.)

So, to recap and respond directly to the question:

> is there a tool that can configure build agents

My choice would be Ansible. Create a repo for the role and playbook. The actions in that repo will provision your hosts every time you merge to main. E.g. a new version of java is approved -\> you merge the PR -\> Github Actions run Ansible playbook -\> runners are now updated.

Alternatively, you use that same Ansible role and playbook to provision containers which are referenced in the application's pipeline; put a Packer template in the same repo as the Ansible role and playbook.
> 0 votes

---
Tags: continuous-integration
---


# Question
Title: Version agnostic code in a branch-versioned monorepo?
Our repo at work has branch versions, branch names are like,

* 1.0
* 1.2
* 1.4

We also have version-agnostic code we're creating now for a plugin system.

Currently there is a proposal to put this version agnostic code in the latest branch on the repo. Are there any cons this approach we should be considering? Is it problematic to say "plugins are found in the latest branch and work with all branches of the repo"? Are there any open source precidents for this?

# Answer
It's likely that you'll eventually find that it will be impossible to keep the plugins truly version agnostic.

Somewhere along the line one version of the regular code will make an assumption about the plugins that happens to be correct in one version, but changes in a later version. Even if you fix all of your branches to work with newer versions of the plugins, historical commits in those branches won't work with the newest plugins. This can make it difficult to some kinds of debugging (eg: anything with `git bisect`).

Instead of having the plugins only in the latest branch, it might be better to have them in all of the branches, and have a policy that changes to the plugins happen only in the latest version branch, and are then "backported" to the older versions' branches by cherry-picking the plugin update commits.

However, the best is probably to move the plugins into a separate repo and either use a package manager or git submodules. Then each version branch can be explicit about which version of the plugins it works with.
> 0 votes

---
Tags: versioning, monorepo
---


# Question
Title: Does Jenkins essentially function like a package manager for your software product?
I'm a relatively new IT Ops guy in a software (web) development company. Recently I deployed a virtual machine on OpenStack, because some developer needs it, and then I installed their application (written by our developers, not third party application) on that newly deployed server using Jenkins.

So basically, what I did was to install an application automatically on a server using Jenkins. This feels like installing a software on a Linux PC using a package manager like APT in Ubuntu, where everything is handled automatically by the package manager.

So, is the purpose of Jenkins to function like some automatic software installer? Is Jenkins essentially a package manager?

# Answer
Sorta, but the additional process it does is compilation of the source code (or linking to a jenkins agent that compiles the code). Then it can deploy the finished build to wherever you tell it. This could be just outputting the build to a network share, or it could be sending it to a virtual machine or docker container to run and test for bugs :D
> 0 votes

# Answer
No. A package manager is more than something that can just install software, otherwise a Makefile would also be a package manager. Package managers keep track of what software is currently installed on a system, what software is available to install on that system (usually from a remote repository of pre-compiled software), dependencies and other relationships between packages (e.g. deprecations, merges/splits, metapackages, etc.), which files are owned/provided by which packages, and so on.
> 0 votes

# Answer
You are really close, but there is so much more to Jenkins; my definition here...

Jenkins is a lot like a kind of web-based version of Make (but has nothing to do with the Gnu Make Project). Extremely versatile in its capabilities, Jenkins acts like a programmable robot that can perform a huge variety of tasks. A Jenkins *job* defines a set of steps to be automated. When you run a Jenkins *job*, each run is known as a *build*. Most users create a Continuous Integration/Continuous Delivery "pipeline" (a special kind of Jenkins *job*) that builds, packages, and/or deploys software. This automates what a human would do at the command line, doing steps such as checking out source code, compiling the code, running a script to package the code, and moving the code to a destination (such as a web server) to deploy the finished product. But you can use Jenkins to automate lots of other kinds of tasks, such as the scheduled tasks that run batch processes, for example. It can also act as a notification system that sends reports or results of Jenkins jobs. In a way, Jenkins also comprises a framework that, along with a huge community-driven selection of plugins, you can build automation for just about "anything" with.
> 0 votes

---
Tags: jenkins, continuous-integration, continuous-deployment, continuous-delivery
---


# Question
Title: GitLab file variable with a dot or period `.` in its name?
I have a file called `.auto.tfvars` that I want to use to set some Terraform variables in an CI run, however when I try to add it, I get a popup called,

> Variables key can contain only letters, digits and '\_'.

Looking at the documentation for GitLab CI/CD variables, I don't see this restriction mentioned nor a workaround.

# Answer
> 0 votes
The GitLab file variable name isn't the path to the file. **It's the name of an environmental variable that stores the path to the file**. Either way you'll have to move the key to where you want the file stored.

Let's say you set this in the GitLab UI,

```
MYGITLAB_FILE_VARIABLE=contents

```

When that gets run `MYGITLAB_FILE_VARIABLE` will be some long and random path name on the runner. You'll have to run this in a CI job to get that file where you want.

```
mv $MYGITLAB_FILE_VARIABLE /my/desired/path

```

# Answer
> 0 votes
I used double \__ and renamed them to dots during the pipeline process. Its not ideal but works

`env |sed 's/__/./g' > application.properties`

---
Tags: gitlab
---


# Question
Title: When a Google Cloud Function fails to deploy, code and settings used for the deployment get lost. Can I revive the last deployment state?
I always have to save code at least in clipboard and sometimes make a screenshot or some other backup of the settings before I deploy a Google Cloud Function, which seems strange to me, perhaps there is a temporary Google backup of it somewhere? If a deployment fails, the Cloud Function is rolled back to the version before deployment (here: version 85) and recent changes that I tried to deploy got lost.

That means, in a Python Cloud Function, I have lost my most recent code in the "main.py", any changes in the "requirements.txt" and even any changes in the environment variables.

Is there a way to go back to the version of my tried deployment and work further from there again?

# Answer
# Code easily recoverable

Source code is still in the cloud function's source bucket. Check the build log for \`Step #0 - "fetch": Fetching archive ..."

The archive path will match:

* gs://`bucket-id`/`function-folder`/`version`/function-source.zip

Navigate to https://console.cloud.google.com/storage/browser/\`bucket-id\`/\`function-folder\`/

There you'll find two versions. One is the most recent build source. The other is the most recent *sucessful* build.
> 1 votes

# Answer
**(This later turns out wrong, there *is* a way to recover the last run code, see the other answers)**

There is no way to recover that failed deployment code.

Yet, there is an easy workaround to never lose your code of the deployment time again: just deploy with `gcloud` function from the shell instead of using the online deployment! Then, you can just change the code as you like, save, and deploy, so that you will not lose it even if the deployment fails.

If you really want to roll back to the last running deployment, you can find that online.

This is best practice. Even if you may think setting up gcloud with the local environment variables and code costs some time at first, you will not need to save the code that you deploy before clicking the `Test the function` button since you will not use that button anymore.
> 1 votes

# Answer
You **can** recover lost code when a Cloud Function deployment fails. But it is a bit cumbersome to do so.

In case anyone needs it, you can recover it by finding the image that was built, deploy it on a VM on GCE, Then extract the source code and download it using ssh.

1. Find your image. Container images for GCF are stored in your container registry. Depending on your project and region it can for example be in: `gcr.io -> PROJECT -> gcf -> REGION`. Then find the folder holding your CF code. I found this path using the build log in case you have trouble finding the correct folder.
2. Deploy your image. When you find your image you can simple select deploy in the navbar and deploy it to a new VM in GCE.
3. Access the VM. When deployed simply SSH into the VM.

Since the deployment of the CF function failed, the image will also fail and be in restart mode all the time when you have accessed the VM. But you can still copy the source code and download it:

1. Create a new image: `docker create --name="my_tmp_image" your_image:tag`
2. Then copy the code to a .tar file: `docker export my_tmp_image > img.tar`
3. Download the file using the download button in the open SSH window.

Once downloaded, you will find your source code in the workspace folder.

And don't forget to kill the VM so you don't waste money on it.
> 1 votes

# Answer
Took my longer than I would have liked to realize, but function source code is stored in a GCS bucket, even for failed deployments, so it can be retrieved from there.
> 1 votes

---
Tags: deployment, google-cloud-platform
---


# Question
Title: How to reload the Firewalld service using Ansible?
I have added some rules to firewalld on CentOS via Ansible. But I need to reload the firewalld daemon for the service to work properly and permanently. Is there a way to do this in Ansible?

Here is my Ansible code:

```
- name: Add port to firewalld
  firewalld:
    port: "{{ item }}"
    permanent: yes
    state: enabled
  when: ansible_distribution == 'CentOS' or ansible_distribution == 'Red Hat Enterprise Linux'
  loop:
    - 8080/tcp
    - 8000/tcp
    - 8090/tcp
    - 8040/tcp

```

# Answer
As per the documentation the firewalld module can only be used to add / remove / update rules from the firewalld ruleset. To reload the service use the `service` module like this (as per documentation):

```
- name: Always reload firewalld
  ansible.builtin.service:
    name: firewalld
    state: reloaded

```
> 4 votes

---
Tags: ansible
---


# Question
Title: vmware/photon with vagrant and virtualbox provider
Im trying to get a vagrant virtualbox vmware/photon up and running but the most basic Vagrantfile emits an error.

```
    Vagrant.configure("2") do |config|
      config.vm.box = "vmware/photon"
      config.vm.box_version = "4.0.2"
    end

```

```
Path: <provider config: virtualbox>
Line number: 19
Message: NameError: undefined local variable or method `override' for main:Object

        override.vbguest.no_install = true

```

One thing I tried was to set the override variable

`Vagrant.configure("2") do |override, config|`

But then a full callstack is thrown:

```
D:/HashiCorp/Vagrant/embedded/gems/gems/vagrant-2.3.7/lib/vagrant/config/v2/loader.rb:37:in `load': can't convert Vagrant::Config::V2::Root to Array (Vagrant::Config::V2::Root#to_ary gives Vagrant::Config::V2::DummyConfig) (TypeError)
        from D:/HashiCorp/Vagrant/embedded/gems/gems/vagrant-2.3.7/lib/vagrant/config/loader.rb:126:in `block (2 levels) in load'
        from D:/HashiCorp/Vagrant/embedded/gems/gems/vagrant-2.3.7/lib/vagrant/config/loader.rb:119:in `each'
        from D:/HashiCorp/Vagrant/embedded/gems/gems/vagrant-2.3.7/lib/vagrant/config/loader.rb:119:in `block in load'
        from D:/HashiCorp/Vagrant/embedded/gems/gems/vagrant-2.3.7/lib/vagrant/config/loader.rb:116:in `each'
        from D:/HashiCorp/Vagrant/embedded/gems/gems/vagrant-2.3.7/lib/vagrant/config/loader.rb:116:in `load'
        from D:/HashiCorp/Vagrant/embedded/gems/gems/vagrant-2.3.7/lib/vagrant/vagrantfile.rb:31:in `initialize'
        from D:/HashiCorp/Vagrant/embedded/gems/gems/vagrant-2.3.7/lib/vagrant/environment.rb:817:in `new'
        from D:/HashiCorp/Vagrant/embedded/gems/gems/vagrant-2.3.7/lib/vagrant/environment.rb:817:in `vagrantfile'
        from D:/HashiCorp/Vagrant/embedded/gems/gems/vagrant-2.3.7/lib/vagrant/environment.rb:998:in `process_configured_plugins'
        from D:/HashiCorp/Vagrant/embedded/gems/gems/vagrant-2.3.7/lib/vagrant/environment.rb:189:in `initialize'
        from D:/HashiCorp/Vagrant/embedded/gems/gems/vagrant-2.3.7/bin/vagrant:211:in `new'
        from D:/HashiCorp/Vagrant/embedded/gems/gems/vagrant-2.3.7/bin/vagrant:211:in `<main>'

```

How do we get photonos up and running with vagrant and virtualbox?

# Answer
Day later I figured it out

The Vagrantfile from the photon box itself has a syntax error if you have vbguest additions already installed.

`~/.vagrant.d/boxes/vmware-VAGRANTSLASH-photon/4.0.2/virtualbox/Vagrantfile`

```
  config.vm.provider "virtualbox" do |v|
    if Vagrant.has_plugin?("vagrant-vbguest")
        override.vbguest.no_install = true
    end

```

The error is emitted when override is used on no\_install = true.

`undefined local variable or method `override' for main:Object`

changing the provider to

```
config.vm.provider "virtualbox" do |v, override|

```

fixed it
> 0 votes

---
Tags: kubernetes, vagrant, virtualization, virtualbox
---


# Question
Title: Enforce https on portainer with cert-manager and letsencrypt after initial setup
I have a running k3s cluster with portainer and helm, and I just got cert-manager with letsencrypt set up as a `ClusterIssuer`

Now I would like to enforce https and use the certificate I created for portainer:

```
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
  name: portainer-tls-secret
  namespace: portainer
spec:
  secretName: portainer-tls-secret
  duration: 2160h # 90d
  renewBefore: 360h # 15d
  subject:
    organizations:
      - <redacted>
  commonName: portainer.k8s.mydomain.tld
  isCA: false
  privateKey:
    algorithm: RSA
    encoding: PKCS1
    size: 4096
  usages:
    - server auth
    - client auth
  dnsNames:
    - portainer.k8s.mydomain.tld
  issuerRef:
    name: letsencrypt-prod
    kind: ClusterIssuer
    group: cert-manager.io

```

This works beautifully:
`kubectl get Certificate --all-namespaces`

> ```
> NAMESPACE      NAME                                  READY   SECRET                                    AGE
> portainer      portainer-tls-secret                  True    portainer-tls-secret                      11m
>
> ```

But according to the documentation I have to supply it with a parameter:

`helm install -n portainer portainer portainer/portainer --set tls.existingSecret=portainer-tls-secret`

(OR upload a single file using the settings, which I doubt very much will autorenew using cert-manager)

As I understand it, the `--set <variablename>=<value>` is for setting environment variables - can I just "deploy" it by running the helm chart? - even though it is not installed via helm:

> ```
> $ helm upgrade -n portainer portainer portainer/portainer --set tls.existingSecret=portainer-tls-secret
> Error: UPGRADE FAILED: "portainer" has no deployed releases
>
> ```

# Answer
> 0 votes
My not-very-elegant solution was to uninstall portainer

```
kubectl delete namespace portainer
kubectl delete ClusterRoleBinding portainer

```

and reinstall it using helm:

```
helm upgrade --install --create-namespace -n portainer portainer portainer/portainer \
    --set tls.force=true \
    --set tls.existingSecret=portainer-tls-secret

```

---
Tags: kubernetes, cert-manager
---


title: Parametrize gitlab ci pipeline

text:
# Question
Title: Parametrize gitlab ci pipeline
There is the following simple pipeline:
`build``test``deploy`
that uses specified `python` version for all stages, for example `3.8`.

How can I scale (parametrize) it for `python` with versions: `3.7`, `3.8` and `3.9`?
Simplest solution that comes to mind is to create 3 different pipelines with hardcoded `python` versions:
`build_37``test_37``deploy_37`
`build_38``test_38``deploy_38`
`build_39``test_39``deploy_39`.

I know this is a very bad solution.
What is the right way?

# Answer
I would suggest to use the parallel matrix feature of GitLab CI (see also here). As Bruce Becker suggested utilizing `tox` is also a valid option and exactly designed for your use case.

```
build:
  image: python:${PY_VERSION}
  parallel:
    matrix:
      - PY_VERSION: ["3.7", "3.8", "3.9"]
  script: poetry build

```
> 3 votes

# Answer
One could use Gitlab templates in conjunction with an environment variable that sets the python version.
> 1 votes

# Answer
You can parametrize GitLab pipeline using `variables` keyword in `gitlab-ci.yaml`:

```
variables:
  PYTHON_VERSION:
    value: "3.7"
    options:
      - "3.7"
      - "3.8"
      - "3.9"
    description: "Python version"

```

You can see a sample GitLab `gitlab-ci.yaml` using `variables` keyword at my GitLab or read an article about GitLab Parameterized Pipelines.

Disclaimer: I wrote the above article.
> 0 votes

---
Tags: continuous-integration, gitlab, python
---


# Question
Title: Why Elasticsearch is terminated if I bind mount a volume?
In my docker-compose I setup an elasticsearch container:

```
version: "3.3"
services:

  elasticsearch:
   build:
      context: .
      dockerfile: ./dockerfiles/DockerfileElasticSearch
   networks:
      private:
      public:
        ipv4_address: ${IP_BASE}.4
   env_file: env/elasticsearch.env
   volumes:
      - "./volumes/elasticsearch:/usr/share/elasticsearch/data:rw"
   environment:
     - "discovery.type=single-node"
     ## Avoid test failures due to small disks
     ## More info at https://github.com/markshust/docker-magento/issues/488
     - "cluster.routing.allocation.disk.threshold_enabled=false"
     - "index.blocks.read_only_allow_delete"

networks:
  private:
  public:
    ipam:
      config:
        - subnet: ${IP_BASE}.0/24
          gateway: ${IP_BASE}.1

```

But the elasticsearch container upon `docker-compose up -d` is terminated:

```
{"type": "server", "timestamp": "2023-09-25T07:45:25,470Z", "level": "ERROR", "component": "o.e.b.ElasticsearchUncaughtExceptionHandler", "cluster.name": "docker-cluster", "node.name": "d87be4eb6a30", "message": "uncaught exception in thread [main]",
"stacktrace": ["org.elasticsearch.bootstrap.StartupException: ElasticsearchException[failed to bind service]; nested: AccessDeniedException[/usr/share/elasticsearch/data/nodes];",
"at org.elasticsearch.bootstrap.Elasticsearch.init(Elasticsearch.java:174) ~[elasticsearch-7.7.0.jar:7.7.0]",
"at org.elasticsearch.bootstrap.Elasticsearch.execute(Elasticsearch.java:161) ~[elasticsearch-7.7.0.jar:7.7.0]",
"at org.elasticsearch.cli.EnvironmentAwareCommand.execute(EnvironmentAwareCommand.java:86) ~[elasticsearch-7.7.0.jar:7.7.0]",
"at org.elasticsearch.cli.Command.mainWithoutErrorHandling(Command.java:127) ~[elasticsearch-cli-7.7.0.jar:7.7.0]",
"at org.elasticsearch.cli.Command.main(Command.java:90) ~[elasticsearch-cli-7.7.0.jar:7.7.0]",
"at org.elasticsearch.bootstrap.Elasticsearch.main(Elasticsearch.java:126) ~[elasticsearch-7.7.0.jar:7.7.0]",
"at org.elasticsearch.bootstrap.Elasticsearch.main(Elasticsearch.java:92) ~[elasticsearch-7.7.0.jar:7.7.0]",
"Caused by: org.elasticsearch.ElasticsearchException: failed to bind service",
"at org.elasticsearch.node.Node.<init>(Node.java:638) ~[elasticsearch-7.7.0.jar:7.7.0]",
"at org.elasticsearch.node.Node.<init>(Node.java:264) ~[elasticsearch-7.7.0.jar:7.7.0]",
"at org.elasticsearch.bootstrap.Bootstrap$5.<init>(Bootstrap.java:227) ~[elasticsearch-7.7.0.jar:7.7.0]",
"at org.elasticsearch.bootstrap.Bootstrap.setup(Bootstrap.java:227) ~[elasticsearch-7.7.0.jar:7.7.0]",
"at org.elasticsearch.bootstrap.Bootstrap.init(Bootstrap.java:393) ~[elasticsearch-7.7.0.jar:7.7.0]",
"at org.elasticsearch.bootstrap.Elasticsearch.init(Elasticsearch.java:170) ~[elasticsearch-7.7.0.jar:7.7.0]",
"... 6 more",
"Caused by: java.nio.file.AccessDeniedException: /usr/share/elasticsearch/data/nodes",
"at sun.nio.fs.UnixException.translateToIOException(UnixException.java:90) ~[?:?]",
"at sun.nio.fs.UnixException.rethrowAsIOException(UnixException.java:111) ~[?:?]",
"at sun.nio.fs.UnixException.rethrowAsIOException(UnixException.java:116) ~[?:?]",
"at sun.nio.fs.UnixFileSystemProvider.createDirectory(UnixFileSystemProvider.java:389) ~[?:?]",
"at java.nio.file.Files.createDirectory(Files.java:694) ~[?:?]",
"at java.nio.file.Files.createAndCheckIsDirectory(Files.java:801) ~[?:?]",
"at java.nio.file.Files.createDirectories(Files.java:787) ~[?:?]",
"at org.elasticsearch.env.NodeEnvironment.lambda$new$0(NodeEnvironment.java:274) ~[elasticsearch-7.7.0.jar:7.7.0]",
"at org.elasticsearch.env.NodeEnvironment$NodeLock.<init>(NodeEnvironment.java:211) ~[elasticsearch-7.7.0.jar:7.7.0]",
"at org.elasticsearch.env.NodeEnvironment.<init>(NodeEnvironment.java:271) ~[elasticsearch-7.7.0.jar:7.7.0]",
"at org.elasticsearch.node.Node.<init>(Node.java:284) ~[elasticsearch-7.7.0.jar:7.7.0]",
"at org.elasticsearch.node.Node.<init>(Node.java:264) ~[elasticsearch-7.7.0.jar:7.7.0]",
"at org.elasticsearch.bootstrap.Bootstrap$5.<init>(Bootstrap.java:227) ~[elasticsearch-7.7.0.jar:7.7.0]",
"at org.elasticsearch.bootstrap.Bootstrap.setup(Bootstrap.java:227) ~[elasticsearch-7.7.0.jar:7.7.0]",
"at org.elasticsearch.bootstrap.Bootstrap.init(Bootstrap.java:393) ~[elasticsearch-7.7.0.jar:7.7.0]",
"at org.elasticsearch.bootstrap.Elasticsearch.init(Elasticsearch.java:170) ~[elasticsearch-7.7.0.jar:7.7.0]",
"... 6 more"] }
uncaught exception in thread [main]
ElasticsearchException[failed to bind service]; nested: AccessDeniedException[/usr/share/elasticsearch/data/nodes];
Likely root cause: java.nio.file.AccessDeniedException: /usr/share/elasticsearch/data/nodes
    at java.base/sun.nio.fs.UnixException.translateToIOException(UnixException.java:90)
    at java.base/sun.nio.fs.UnixException.rethrowAsIOException(UnixException.java:111)
    at java.base/sun.nio.fs.UnixException.rethrowAsIOException(UnixException.java:116)
    at java.base/sun.nio.fs.UnixFileSystemProvider.createDirectory(UnixFileSystemProvider.java:389)
    at java.base/java.nio.file.Files.createDirectory(Files.java:694)
    at java.base/java.nio.file.Files.createAndCheckIsDirectory(Files.java:801)
    at java.base/java.nio.file.Files.createDirectories(Files.java:787)
    at org.elasticsearch.env.NodeEnvironment.lambda$new$0(NodeEnvironment.java:274)
    at org.elasticsearch.env.NodeEnvironment$NodeLock.<init>(NodeEnvironment.java:211)
    at org.elasticsearch.env.NodeEnvironment.<init>(NodeEnvironment.java:271)
    at org.elasticsearch.node.Node.<init>(Node.java:284)
    at org.elasticsearch.node.Node.<init>(Node.java:264)
    at org.elasticsearch.bootstrap.Bootstrap$5.<init>(Bootstrap.java:227)
    at org.elasticsearch.bootstrap.Bootstrap.setup(Bootstrap.java:227)
    at org.elasticsearch.bootstrap.Bootstrap.init(Bootstrap.java:393)
    at org.elasticsearch.bootstrap.Elasticsearch.init(Elasticsearch.java:170)
    at org.elasticsearch.bootstrap.Elasticsearch.execute(Elasticsearch.java:161)
    at org.elasticsearch.cli.EnvironmentAwareCommand.execute(EnvironmentAwareCommand.java:86)
    at org.elasticsearch.cli.Command.mainWithoutErrorHandling(Command.java:127)
    at org.elasticsearch.cli.Command.main(Command.java:90)
    at org.elasticsearch.bootstrap.Elasticsearch.main(Elasticsearch.java:126)
    at org.elasticsearch.bootstrap.Elasticsearch.main(Elasticsearch.java:92)
For complete error details, refer to the log at /usr/share/elasticsearch/logs/docker-cluster.log

```

Instead if I remove the volumes section runs fine:

```
version: "3.3"
services:

  elasticsearch:
   build:
      context: .
      dockerfile: ./dockerfiles/DockerfileElasticSearch
   networks:
      private:
      public:
        ipv4_address: ${IP_BASE}.4
   env_file: env/elasticsearch.env
   environment:
     - "discovery.type=single-node"
     ## Avoid test failures due to small disks
     ## More info at https://github.com/markshust/docker-magento/issues/488
     - "cluster.routing.allocation.disk.threshold_enabled=false"
     - "index.blocks.read_only_allow_delete"

networks:
  private:
  public:
    ipam:
      config:
        - subnet: ${IP_BASE}.0/24
          gateway: ${IP_BASE}.1

```

Any idea why? How I can retain the elasticsearch data?

# Answer
> 0 votes
I do not know why but a working version of mine is to use `volumes` like this:

```

version: "3.3"
services:

  elasticsearch:
   build:
      context: .
      dockerfile: ./dockerfiles/DockerfileElasticSearch
   networks:
      private:
      public:
        ipv4_address: ${IP_BASE}.4
   env_file: env/elasticsearch.env
   volumes:
      - "elasticsearch:/usr/share/elasticsearch/data:rw"
   environment:
     - "discovery.type=single-node"
     ## Avoid test failures due to small disks
     ## More info at https://github.com/markshust/docker-magento/issues/488
     - "cluster.routing.allocation.disk.threshold_enabled=false"
     - "index.blocks.read_only_allow_delete"

volumes:
  elasticsearch:
    driver: local
    driver_opts:
      type: none
      o: bind
      device: './volumes/elasticsearch'

networks:
  private:
  public:
    ipam:
      config:
        - subnet: ${IP_BASE}.0/24
          gateway: ${IP_BASE}.1

```

But you must make the folder `./volumes/elasticsearch` first.

---
Tags: docker-compose, elasticsearch
---


# Question
Title: Deploy multiple instances of the same application Kubernetes
I'm developing a web application in NodeJS and I want to create multiple instances of the same application to deploy it in multiple subdomains of my main domain. I want each instance to have the same application but a different database for each. But I don't know how to do it.

I looked into it and it turns out that if I use Docker, Kubernetes and deploy to a cloud provider, that can solve my problem. The problem is that I know very little about Kubernetes and I have a question I can't answer!

Since each subdomain must point to the IP address of an instance of my application. How can I solve this problem? Do I have to create a cluster for each subdomain or is there a way to put them all in one? What do you think about this solution?

If you have a resource or another completely different solution, I'm open to anything. Thank you.

# Answer
You can create multiple instances of your application and in your application you can configure database details to use different databases.

For routing part, you can setup a proxy server using Apache2/Nginx/HA Proxy.

Your domain and sub-domains point to proxy server ip and Proxy server route the traffic to desired upstream application instance based on routing rules.

This can be done without kubernetes and docker on any virtual machine from any cloud provider.
> 0 votes

# Answer
1. Deploy your application in different namespaces.
2. Use configmaps in each namespace to specify a DB endpoint(This way you can specify different DB endpoints for each instance of the application).
3. It is your choice to deploy multiple ingress according to your domains, which ideally you should or to use an nginx, or any equivalent tool to forward your request to a particular application.

I hope this helps.
> 0 votes

---
Tags: docker, kubernetes, azure-devops, microservices, cloud
---


# Question
Title: How to scrape only some targets of EC2 based on tag
I have a requirement, where I have enabled NGINX metrics and I am trying to plot metrics with Prometheus. I am trying to plot metrics for NGINX EC2 server which has a tag named `test=nginx` or by running on specific port 9113. I am trying to use the below config, but after adding this config I am unable to see the targets in Prometheus

```
- job_name: "prometheus_nginx"
  ec2_sd_configs:
    - region: us-east-1
      access_key: XXXXXXXXXX
      secret_key: XXXXXXXXXX/
      port: 9113
  relabel_configs:
    - source_labels: [__meta_ec2_tag_test]
      regex: nginx
      action: keep
    - source_labels: []
      regex: .*
      action: drop

```

So can someone please help in what modifications are needed. NGINX is running on EC2 and Prometheus is running as a pod. Already enabled the traffic between NGINX and Prometheus pod and I am able to plot metrics.

But I am looking at more feasible option which should automatically get the dynamic targets based on the tag of the EC2 server

# Answer
> 1 votes
I have figured out the way and using the below code snippet, we should be able to filter the ec2 instances based on the tags

```
    additionalScrapeConfigs: |
  - job_name: "prometheus_nginx"
    ec2_sd_configs:
      - region: us-east-1
        access_key: XXXXXX
        secret_key: XXXXXX
        port: 9113
        filters:
          - name: tag:test
            values:
              - nginx

```

Thanks to chatgpt

---
Tags: amazon-ec2, nginx, prometheus
---


# Question
Title: Provisioning times for Redis in cloud taking too long, how can we shorten it?
Provisioning a 1 GB Redis cache service on AWS takes around 8 minutes. Doing the same on Azure takes around 16 minutes. Ours Terraform scripts need the call back from the Redis systems. Why is this taking so long and **how can we make this process faster** for immutable infrastructure?

* ideally, we would like to create related infra less than 4 minutes
* some tests even take longer 8 and 16 minutes are the averages
* we are using a managed Redis service by cloud providers.
* Doing manually also takes that much time to complete it. Infrastructure gets set up but the Redis is not usable for Terraform or X.
* This happens in any random account in cloud providers with or without Terraform

# Answer
> 0 votes
The amount of time it takes a cloud to create a specific cloud resource is an implementation detail of that cloud. And so you will not be in a position to change the amount of time it takes Azure to create a Redis cache unless you are also in a position to change the underlying implementation of how Azure creates that Redis cache.

If a cloud implementation takes an unacceptably long time to create a specific resource, you have two options as a user: create a different kind of resource, or create it in advance of when you need it so that you don't have to spend the creation time during your low-latency deploy process.

---
Tags: amazon-web-services, terraform, azure, redis
---


# Question
Title: Increase NGINX Client_Max_Body_Size via YAML (AKS)
TLDR: Can I utilize my existing deployment YAML (see **dev-deployment.yaml** snippet below) to specify a client\_max\_body\_size to a server or servers in my **nginx ingress**?

Some background:

* I recently added some functionality to an API for uploading images
* Receive this error when attempting uploads in our DEV environment: 413 Request Entity Too Large
    + issue not occurring when running locally
* Preliminary research suggested increasing the **nginx** 'client\_max\_body\_size' greater than the attempted upload size
* Additionally found that setting an annotation like 'nginx.ingress.kubernetes.io/proxy-body-size' in my YAML might achieve the same goal
* This all runs in Azure Kubernetes Service (AKS)

I don't know if it's even possible to configure this setting via this method with the desired outcome at this point. Just seeing if anyone may have a similar configuration and if they were able to resolve it from a YAML perspective, versus going in and editing **nginx** .conf file(s) in the node agents in AKS.

**dev-deployment.yaml (ingress rules section only)**

```
#ingress rules
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: someApp-ingress-dev
  namespace: default
  annotations:
    kubernetes.io/ingress.class: nginx
    nginx.ingress.kubernetes.io/rewrite-target: /
    nginx.ingress.kubernetes.io/proxy-body-size: 50m
spec:
  tls:
  - hosts:
    - ui-dev.example.com
    - api1-dev.example.com
    - api2-dev.example.com
    - api3-dev.example.com
    - api4-dev.example.com
    secretName: someApp-secret
  rules:
  - host: ui-dev.example.com
    http:
      paths:
        - path: /
          pathType: Prefix
          backend:
            service:
              name: someApp-ui-dev
              port:
                number: 80
  - host: structures-dev.example.com
    http:
      paths:
        - path: /
          pathType: Prefix
          backend:
            service:
              name: someApp-api1-api-dev
              port:
                number: 80

// limited to (2) rules for brevity

```

# Answer
> 0 votes
I found a way to do this and side-stepped all that I posed above.

I added the following entry in the **ConfigMap** in **AKS** for my **nginx-ingress** controllers:

```
data:
  client-max-body-size: 40m

```

My pods inherited this (after delete) and applied it to all the server entries in my **default.conf**. I'll circle back at some point and figure out how to target a specific server entry.

---
Tags: kubernetes, azure-devops, nginx, yaml
---


# Question
Title: How should I update a single input to a Nix flake?
I have a Nix flake with several inputs whose URLs are remote git repositories. I want to update one input in `flake.lock`, but not the others; in particular, I want to avoid repinning `nixpkgs`.

When I run `nix flake update`, all inputs are updated. This is probably desirable for correctness. However, I can subsequently roll back part of the changes to `flake.lock`, performing minor surgery, so that only one input is updated.

Is there a blessed or safe way to update only one input? I would accept a way to update a given input and all of its transitive dependencies, if that is the only safe way.

# Answer
> 4 votes
Unintuitively enough, you use a different command for that. `nix flake update` updates all inputs as you noticed, while you use

```
nix flake lock --update-input <name_of_input>

```

to update only a single input. You can also chain several of these in a single command:

```
nix flake lock --update-input nixpkgs --update-input nix

```

---
Tags: nixos
---


# Question
Title: Can Mimir read secrets from Volume mounts?
We have kyverno on our work k8 cluster with a policy that says Secrets must not come from envFrom statements.

So I am trying to setup mimir-distributed chart (version 5.1.0) to use secrets from Volume Mounts.

I can get the volumes mounted and I can see the correct contents of each secret in there files.

My Values file looks like this:

```
alertmanager:
  extraVolumes:
    - name: secret-grafana-mimir
      secret:
        secretName: secret-grafana-mimir
  # Extra volume mounts that will be added to the alertmanager container
  extraVolumeMounts:
    - name: secret-grafana-mimir
      mountPath: "/etc/secret"
      readOnly: true

mimir:
  structuredConfig:

    alertmanager_storage:
      backend: azure
      azure:
        ## Recplaced the ${} var with the file path
        account_name: /etc/secret/MIMIR_STORAGE_ACCOUNT_NAME
        account_key: /etc/secret/MIMIR_STORAGE_ACCOUNT_KEY
        container_name: mimir-alaertmanager
    compactor:
      data_dir: "/data"
...

```

But each service in the Mimir stack then gives pretty much the same error:

This error is from Mimir Alert manager:

```
ts=2023-09-28T06:03:38.93765098Z caller=main.go:225 level=info msg="Starting application" version="(version=2.10.0, branch=HEAD, revision=77906f7)"
ts=2023-09-28T06:03:39.337442912Z caller=server.go:335 level=info msg="server listening on addresses" http=[::]:8080 grpc=[::]:9095
ts=2023-09-28T06:03:39.537634469Z caller=multitenant.go:156 level=warn msg="The configured Alertmanager HTTP prefix '/alertmanager' is different than the path specified in the external URL 'http://prometheus-alertmanager.observability:9093': the Alertmanager UI and API may not work as expected unless you have a reverse proxy exposing the Alertmanager endpoints under '/alertmanager' prefix"
ts=2023-09-28T06:03:39.538016272Z caller=log.go:87 level=error msg="error running application" err="decode account key: illegal base64 data at input byte 17\nerror initialising module: alertmanager\ngithub.com/grafana/dskit/modules.(*Manager).initModule\n\t/__w/mimir/mimir/vendor/github.com/grafana/dskit/modules/modules.go:138\ngithub.com/grafana/dskit/modules.(*Manager).InitModuleServices\n\t/__w/mimir/mimir/vendor/github.com/grafana/dskit/modules/modules.go:108\ngithub.com/grafana/mimir/pkg/mimir.(*Mimir).Run\n\t/__w/mimir/mimir/pkg/mimir/mimir.go:800\nmain.main\n\t/__w/mimir/mimir/cmd/mimir/main.go:227\nruntime.main\n\t/usr/local/go/src/runtime/proc.go:267\nruntime.goexit\n\t/usr/local/go/src/runtime/asm_amd64.s:1650"

```

# Answer
Just had word from the Grafana team that this is not supported, will raise a feature request
> 0 votes

---
Tags: kubernetes, helm, grafana
---


# Question
Title: get node_exporter metrics for a single system user
I have installed the node\_exporter within the userspace of a linux system user. Everything works and I get the metrics in my grafana. But what I get is apperently the metrics for the whole host system (interesting, that I can get so much data about the host system as a simple user). But what I want is to see the CPU usage or RAM usage etc. just for my user, is that possible?

# Answer
> 0 votes
What datasource are you using? How do you transfer data from your collector (node\_exporter) to grafana?

You could use a combination of telegraf agents and influxdb to create tags (eg users) and then filter your metrics based on those tags.

---
Tags: prometheus, grafana
---


# Question
Title: EKS cluster upgrade from 1.23 to 1.24 ServiceUnavailableException: Updates in the cell are disabled
I've tried upgrading my EKS cluster to 1.24 and I keep getting this error: `ServiceUnavailableException: Updates in the cell are disabled`

I get this using the AWS console webpage here https://us-east-1.console.aws.amazon.com/eks/home?region=us-east-1#/clusters

I get it using `aws eks` and I get it using `eksctl`

Does this mean some AWS server is down? How do I report this on Basic support plan?

# Answer
EKS Upgrades were deliberately disabled by AWS due to an EC2 related issue. From the AWS status incident:

```
[11:56 AM PDT] We can confirm that customers are experiencing elevated error rates for cluster upgrade operations in the US-EAST-1 Region.
This is a result of actions we took to prevent additional customer impact following the EC2 network propagation event yesterday in a single Availability Zone (use1-az2).
For EKS customers, we have purposely disabled cluster upgrade operations to prevent any impact to existing clusters and running applications.
We have identified the root cause for the underlying issue and are working towards mitigating the current impact.
We will enable cluster upgrade operations once the issue is resolved.
We will provide an update within the next 60 minutes, or sooner if we have additional information to share.

```
> 0 votes

---
Tags: amazon-web-services, eks, upgrade
---


title: What is the meaning of start-dev?

text:
# Question
Title: What is the meaning of start-dev?
I have command

```
docker run --name vy-keycloak -p 8085:8080 -e KEYCLOAK_ADMIN=admin -e KEYCLOAK_ADMIN_PASSWORD=admin quay.io/keycloak/keycloak:22.0.3 start-dev

```

It runs success. What is the meaning of `start-dev`?

Related https://www.keycloak.org/server/all-config

https://www.keycloak.org/getting-started/getting-started-docker#\_start\_keycloak

# Answer
`start-dev` is the command which is starting when the container is running.

In the documentation (https://docs.docker.com/engine/reference/commandline/run/) you see that the `docker run` command is defined like this:

```
docker run [OPTIONS] IMAGE [COMMAND] [ARG...]

```

After the image name (in your case it's `quay.io/keycloak/keycloak:22.0.3`) you can call a command. In your case it's `start-dev`.
> 3 votes

---
Tags: docker
---


# Question
Title: What is the syntax error in my docker compose file?
I copied authoritative content at https://github.com/Kong/docker-kong/blob/master/compose/docker-compose.yml

```
version: '3.9'

x-kong-config: &kong-env
  KONG_DATABASE: ${KONG_DATABASE:-off}
  KONG_PG_DATABASE: ${KONG_PG_DATABASE:-kong}
  KONG_PG_HOST: db
  KONG_PG_USER: ${KONG_PG_USER:-kong}
  KONG_PG_PASSWORD_FILE: /run/secrets/kong_postgres_password

volumes:
  kong_data: {}
  kong_prefix_vol:
    driver_opts:
     type: tmpfs
     device: tmpfs
  kong_tmp_vol:
    driver_opts:
     type: tmpfs
     device: tmpfs

networks:
  kong-net:
    external: false

services:
  kong-migrations:
    image: "${KONG_DOCKER_TAG:-kong:latest}"
    command: kong migrations bootstrap
    profiles: ["database"]
    depends_on:
      - db
    environment:
      <<: *kong-env
    secrets:
      - kong_postgres_password
    networks:
      - kong-net
    restart: on-failure

  kong-migrations-up:
    image: "${KONG_DOCKER_TAG:-kong:latest}"
    command: kong migrations up && kong migrations finish
    profiles: ["database"]
    depends_on:
      - db
    environment:
      <<: *kong-env
    secrets:
      - kong_postgres_password
    networks:
      - kong-net
    restart: on-failure

  kong:
    image: "${KONG_DOCKER_TAG:-kong:latest}"
    user: "${KONG_USER:-kong}"
    environment:
      <<: *kong-env
      KONG_ADMIN_ACCESS_LOG: /dev/stdout
      KONG_ADMIN_ERROR_LOG: /dev/stderr
      KONG_PROXY_LISTEN: "${KONG_PROXY_LISTEN:-0.0.0.0:8000}"
      KONG_ADMIN_LISTEN: "${KONG_ADMIN_LISTEN:-0.0.0.0:8001}"
      KONG_ADMIN_GUI_LISTEN: "${KONG_ADMIN_GUI_LISTEN:-0.0.0.0:8002}"
      KONG_PROXY_ACCESS_LOG: /dev/stdout
      KONG_PROXY_ERROR_LOG: /dev/stderr
      KONG_PREFIX: ${KONG_PREFIX:-/var/run/kong}
      KONG_DECLARATIVE_CONFIG: "/opt/kong/kong.yaml"
    secrets:
      - kong_postgres_password
    networks:
      - kong-net
    ports:
      # The following two environment variables default to an insecure value (0.0.0.0)
      # according to the CIS Security test.
      - "${KONG_INBOUND_PROXY_LISTEN:-0.0.0.0}:8000:8000/tcp"
      - "${KONG_INBOUND_SSL_PROXY_LISTEN:-0.0.0.0}:8443:8443/tcp"
      # Making them mandatory but undefined, like so would be backwards-breaking:
      # - "${KONG_INBOUND_PROXY_LISTEN?Missing inbound proxy host}:8000:8000/tcp"
      # - "${KONG_INBOUND_SSL_PROXY_LISTEN?Missing inbound proxy ssl host}:8443:8443/tcp"
      # Alternative is deactivating check 5.13 in the security bench, if we consider Kong's own config to be enough security here

      - "127.0.0.1:8001:8001/tcp"
      - "127.0.0.1:8444:8444/tcp"
      - "127.0.0.1:8002:8002/tcp"
    healthcheck:
      test: ["CMD", "kong", "health"]
      interval: 10s
      timeout: 10s
      retries: 10
    restart: on-failure:5
    read_only: true
    volumes:
      - kong_prefix_vol:${KONG_PREFIX:-/var/run/kong}
      - kong_tmp_vol:/tmp
      - ./config:/opt/kong
    security_opt:
      - no-new-privileges

  db:
    image: postgres:9.5
    profiles: ["database"]
    environment:
      POSTGRES_DB: ${KONG_PG_DATABASE:-kong}
      POSTGRES_USER: ${KONG_PG_USER:-kong}
      POSTGRES_PASSWORD_FILE: /run/secrets/kong_postgres_password
    secrets:
      - kong_postgres_password
    healthcheck:
      test: ["CMD", "pg_isready", "-U", "${KONG_PG_USER:-kong}"]
      interval: 30s
      timeout: 30s
      retries: 3
    restart: on-failure
    stdin_open: true
    tty: true
    networks:
      - kong-net
    volumes:
      - kong_data:/var/lib/postgresql/data

secrets:
  kong_postgres_password:
    file: ./POSTGRES_PASSWORD

```

But I get a syntax error in my IDE (which is IntelliJ IDEA 2023.x, latest stable version). What is my syntax error in my docker-compose file?

# Answer
By default, some IDEs, such as Visual Code, will look for a standard Schema of the file type "docker-compose.yaml" or "docker-compose.yml".

Example

For example, I have the most up-to-date versions of the linter plugins, and I haven't had any problems with the file. I would recommend that you update your plugins or IDE.
> 1 votes

---
Tags: docker, docker-compose
---


# Question
Title: How to prune all but two most recent docker images?
I'm building images on a small server and spinning them up with docker-compose.

When it's disk gets full I run `docker prune -a` so all the stopped containers, dangling image are cleaned out.

But I'd like to keep one or two recent **images** in case I need to roll back quickly.

The docker prune documentation says `--filter until=<timestamp>`. But the timestamps from the previous images could be days, weeks or months old.

Then suggested method for pruning by date is:

a) find the timestamp by listing the images with this format

`docker images --format 'table {{.Repository}}\t{{.Tag}}\t{{.ID}}\t{{.CreatedAt}}\t{{.Size}}'`

**which produces**

```
REPOSITORY          TAG                 IMAGE ID            CREATED AT                      SIZE
foo                 latest              2f287ac753da        2017-01-04 13:42:23 -0800 PST   3.98 MB
alpine              latest              88e169ea8f46        2016-12-27 10:17:25 -0800 PST   3.98 MB
busybox             latest              e02e811dd08f        2016-10-07 14:03:58 -0700 PDT   1.09 MB

```

How can I automatically select the second `created at` timestamp in the list it produces?

...to then pass it as a variable into

b) `docker image prune -a --force --filter "until=<2rd timestamp from list>"`

Is there an way to use awk ? Is there another way to leave an extra image ?

# Answer
> 4 votes
The problem is that the date format isn't ideal.

> Supported formats for date formatted time stamps include RFC3339Nano, RFC3339, 2006-01-02T15:04:05, 2006-01-02T15:04:05.999999999, 2006-01-02Z07:00, and 2006-01-02

Reference: https://docs.docker.com/engine/reference/commandline/system\_prune/#filtering

So this is really just a *half* answer, since it will use the date and the local timestamp.

> The local timezone on the daemon will be used if you do not provide either a Z or a +-00:00 timezone offset at the end of the timestamp.

Thankfully, this comes sorted.

```
~: docker images --format '{{.CreatedAt}}'
2020-06-09 12:44:57 -0700 PDT
2020-05-29 14:19:46 -0700 PDT
2020-05-05 13:40:47 -0700 PDT
2020-04-28 11:55:11 -0700 PDT
2020-03-09 10:35:34 -0700 PDT
2020-03-09 10:14:43 -0700 PDT
2020-03-09 10:14:43 -0700 PDT
2020-03-09 10:14:43 -0700 PDT
2020-02-26 07:10:58 -0800 PST

```

I don't know how to transform timestamps in bash off the top of my head, so let's just do this the quick and messy way... the whole date!

```
 ~: docker images --format '{{.CreatedAt}}' | sed -n '2p' | awk '{print $1;}'
2020-05-29

```

Now we can do command substitution.

```
~: docker image prune --force --filter "until=`docker images --format '{{.CreatedAt}}' | sed -n '2p' | awk '{print $1;}'`"
Total reclaimed space: 1.344GB

```

I didn't put a heck of a lot of thought in to this answer, so there may be some edges cases I didn't consider. Also, if someone with better bash-fu can transform that timestamp, that would be awesome.

# Answer
> 1 votes
It is also possible to use `before` filter.

E.g., if the question would be about removing "all but 1(one) most recent image", the answer could be:

```
docker images -q --filter before=$nameTag $nameOnly | xargs --no-run-if-empty docker rmi --force || true

```

And Jenkins method could look like:

```
def previousImagesCleanup(String nameTag) {
  String nameOnly=nameTag.split(':')[0]
  log.info("Clean up if build succeeded - delete images prior to the current one ($nameTag). Preserving last one for cache purposes.")
  sh("docker images -q --filter before=$nameTag $nameOnly | xargs --no-run-if-empty docker rmi --force || true")
}

```

---
Tags: docker, docker-compose
---


# Question
Title: Ubuntu Server 22.04 Autoinstall and Cloud-Init Not Executing Commands
I am trying to set up an Ubuntu Server 22.04 installation using autoinstall and cloud-init. I have two USB keys (I followed this tutorial https://www.jimangel.io/posts/automate-ubuntu-22-04-lts-bare-metal/):

* One with an ISO image of Ubuntu Server 22.04 with autoinstall enabled.
* The second one contains two YAML files: `meta-data` (empty file) and `user-data`.

When I try to install the new setup on a machine, ubuntu gets installed, the user is created **but** when the computer reboots, none of the packages (see user-data) seem to be installed. Even simple tests like creating a directory using runcmd do not persist.

**Debugging Attempts**

Checked cloud-init logs at /var/log/cloud-init.log and /var/log/cloud-init-output.log but did not find any relevant errors or warnings. Tried simplifying the user-data file to just create a directory, but it did not work.

I'd appreciate any pointers to debug and resolve this issue.

Here is my user-data file:

```
#cloud-config
package_update: true
package_upgrade: true

autoinstall:
  version: 1
  locale: en_US
  keyboard:
    layout: fr
  identity:
    hostname: user
    username: user
    password: "$6$xyz$waX2p...."
  ssh:
    install-server: true
  packages:
    - openssh-server
  package_upgrade: true
  late-commands:
    - shutdown -h now
runcmd:
  - apt install -y curl autossh unzip
  - apt install -y docker.io
  - systemctl start docker
  - systemctl enable docker
  - mkdir /home/bob

```

# Answer
The answer was to include the `runcmd` within the autoinstall, like that:

```
package_update: true
package_upgrade: true

autoinstall:
  version: 1
  locale: en_US
  keyboard:
    layout: fr
  identity:
    hostname: user
    username: user
    password: "$6$xyz$waX2p...."
  ssh:
    install-server: true
  packages:
    - openssh-server
  package_upgrade: true
  late-commands:
    - shutdown -h now
  runcmd:
    - apt install -y curl

```
> 0 votes

---
Tags: ubuntu, cloud-init
---


title: Add prometheus config for all jobs

text:
# Question
Title: Add prometheus config for all jobs
In my prometheus.yml I have several jobs defined like:

```
  - job_name: alpha
    scheme: 'https'
    metrics_path: '/metrics'
    static_configs:
      - targets:
        - one.example
        - two.example
    relabel_configs:
      - source_labels: [__address__]
        regex: '(.*).example.*'
        replacement: '${1}'
        target_label: 'slug'

  - job_name: beta
    scheme: 'https'
    metrics_path: '/metrics'
    static_configs:
      - targets:
        - three.example
        - four.example
    relabel_configs:
      - source_labels: [__address__]
        regex: '(.*).example.*'
        replacement: '${1}'
        target_label: 'slug'

```

as you can see, only the targets differ per job, all the other configs like `relabel_configs` and `scheme` etc. are the same. Because its not only two jobs but around 20 for now, I don't want to repeat the same settings for each job. Is there no way to create a default config for all jobs?

# Answer
> Is there no way to create a default config for all jobs?

No, there is no such way. `relabel_configs` are specified on the job level.

On the other hand, if all 20 of your jobs have exactly the same relabeling config, you might consider using a single job and additional labels for distinction (I assume you distinct right now by `job` label):

```
  - job_name: unitedjod
    scheme: 'https'
    metrics_path: '/metrics'
    static_configs:
      - targets:
        - one.example
        - two.example
        labels:
          target_type: alpha
      - targets:
        - three.example
        - four.example
        labels:
          target_type: beta
    relabel_configs:
      - source_labels: [__address__]
        regex: '(.*).example.*'
        replacement: '${1}'
        target_label: 'slug'

```

Here first group of targets will contain label `target_type` with value `alpha`, and second group - with value `beta`.
> 1 votes

---
Tags: prometheus
---


# Question
Title: Azure DevOps Release Pipeline Fails on Partially Offline Deployment Group
I'm currently using Azure DevOps for CI/CD and have set up a deployment group with multiple target machines. Some of these machines are scheduled to go offline during the night . However, I've noticed that when even one of these machines is offline, my release pipeline fails to deploy to the entire group, including the online machines. The error message I receive is: "Deployment Group deployment configuration settings are not met."

My goal is to have the release pipeline deploy successfully to the online machines, even if some machines in the deployment group are offline.

Is there a configuration setting or workaround in Azure DevOps to handle this scenario? How can I ensure that the pipeline continues to deploy to online machines without being halted by offline ones? Any insights or solutions would be greatly appreciated. Thank you!

# Answer
You could apply tags to the targets (e.g. Active) and use that as a filter in the stage tasks.
> 0 votes

---
Tags: azure-devops
---


# Question
Title: Azure pipeline is publishing an empty zip file
I have an Azure pipeline for a Blazor project and I'm trying to publish the results of the build to an Azure app service.

The build completes fine but the deploy task throws an error. At first I thought it was a problem with one of the paths in the pipeline. be

Eventually I checked the Azure logs and found this. This error is what led me to look at the zip file and its empty.

The pipeline artifact is fine. When its first created in the build, its also fine. But moving from the build to deploy the zip is 0KB. My yaml file is below. If you look at the 2nd Stage which is "Dev", I'm doing an `ls` just before that. I see what I expect

I do another list in the middle of deployment to Azure and its empty.

I haven't been able to find another issue like this anywhere but maybe I'm searching on the wrong keywords. Any help is greatly appreciated.

```
trigger:
- master

pool:
  vmImage: 'windows-latest'

variables:
  solution: '**/*.sln'
  buildPlatform: 'Any CPU'
  buildConfiguration: 'Release'
  name: $(TeamProject)_$(SourceBranchName)_$(Date:yyyyMMdd)$(Rev:r)

stages:
- stage: 'Build'

  jobs:
  - job:
    displayName: 'Build the application'

    steps:
      - task: NuGetToolInstaller@1

      - task: NuGetCommand@2
        displayName: 'Restore NuGet packages'
        inputs:
          restoreSolution: '$(solution)'
          feedsToUse: config

      - task: VSBuild@1
        displayName: 'Build'
        inputs:
          solution: '$(solution)'
          msbuildArgs: '/p:DeployOnBuild=true /p:WebPublishMethod=Package /p:PackageAsSingleFile=true /p:SkipInvalidConfigurations=true /p:DesktopBuildPackageLocation="$(build.artifactStagingDirectory)\WebApp.zip"
          platform: '$(buildPlatform)'
          configuration: '$(buildConfiguration)'

      - task: PublishPipelineArtifact@1
        displayName: 'Publish to $(Pipeline.Workspace)'
        inputs:
          targetPath: '$(Pipeline.Workspace)'
          artifactName:  'WebApp.zip'

      - task: DownloadBuildArtifacts@1
        displayName: 'Download Build Artifacts'
        inputs:
          buildType: current
          project: 'HR3D Engineering'
          pipeline: 'HR Taxonomy'
          artifactName: 'WebApp.zip'
          downloadPath: '$(System.ArtifactsDirectory)' #download to this folder.

      - task: CmdLine@2
        inputs:
            script: 'ls -la $(System.ArtifactsDirectory)'

- stage: 'Dev'
  displayName: 'Deploy to the dev environment'
  dependsOn: Build
  condition:  succeeded()
  jobs:
  - deployment: Deploy
    pool:
      vmImage: 'windows-latest'
    environment: ChangeManagement-Dev
    variables:
    - group: Release
    strategy:
      runOnce:
        deploy:
          steps:
          - download: current
            artifact: 'WebApp.zip'

          - task: CmdLine@2
            inputs:
                script: 'ls -la D:\a\1\'

          - task: AzureWebApp@1
            displayName: 'Azure App Service Deploy: $(System.ArtifactsStagingDirectory)'
            inputs:
              azureSubscription: 'HR Data Governance(2442165c-339d-4e83-a443-a6583c372938)'  #service connection name
              appType: 'webAppLinux'
              appName: 'HRChangeManagement-Dev' #app service name
              package: 'D:\a\1\WebApp.zip'

```

# Answer
> 0 votes
Chris, 1.Enable diagnostics to get more information 2.Have you tried the Default value: $(System.DefaultWorkingDirectory)/\**/\*.zip.?

Per https://learn.microsoft.com/en-us/azure/devops/pipelines/tasks/reference/azure-web-app-v1?view=azure-pipelines#inputs

---
Tags: azure-devops, azure-pipelines, yaml, azure-artifacts
---


# Question
Title: Docker on Centos 7 - "unkown flag: --ip-forward"
I've installed docker on Centos 7 from the official docker-ce repository (followed instructions here). I'm seeing the following error when trying to start the docker service with `systemctl start docker`

```
Starting Docker Application Container Engine...
docker[24207]: unknown flag: --ip-forward
docker[24207]: See 'docker --help'.
docker[24207]: Usage:  docker [OPTIONS] COMMAND

```

Here is the docker version:

```
[root@js03 englab]# docker --version
Docker version 24.0.6, build ed223bc

```

# Answer
> 0 votes
It turns out there was a leftover file from a previous version of docker at `/etc/systemd/system/docker.service.d/service-overrides.conf` that was injecting environment variables into the docker.service ExecStart command.

```
# cat /etc/systemd/system/docker.service.d/service-overrides.conf
[Service]
EnvironmentFile=-/etc/sysconfig/docker
EnvironmentFile=-/etc/sysconfig/docker-storage
EnvironmentFile=-/etc/sysconfig/docker-network
ExecStart=
ExecStart=/usr/bin/docker daemon $OPTIONS \
      $DOCKER_STORAGE_OPTIONS \
      $DOCKER_NETWORK_OPTIONS \
      $BLOCK_REGISTRY \
      $INSECURE_REGISTRY

```

I removed this file and rebooted, then docker started successfully.

---
Tags: docker, containerd
---


# Question
Title: How to run a script or a command on EC2 instance via AWS CLI?
According to New EC2 Run Command news article, AWS CLI should support a new sub-command to execute scripts on remote EC2 instances.

However I've checked in `aws ec2 help`, but I can't find the relevant command.

I've installed `aws` via `apt-get`:

```
$ aws --version
aws-cli/1.14.32 Python/3.5.4 Linux/4.12.7-64 botocore/1.8.36

```

Which sub-command I should look for and what's the syntax to run, let say `ipconfig` in *PowerShell* on the remote EC2 instance?

# Answer
To run ipconfig from the AWS Systems Manager Run Command:

```
$ aws ssm send-command --document-name "AWS-RunPowerShellScript" --instance-ids "<your instance id>" --parameters commands=ipconfig

```

Note: If you've got the error, consider specifying the right `--region`.

This assumes you have your AWS credentials and CLI configured properly. See Systems Manager Run Command Walkthrough Using the AWS CLI for more information.

---

Here is the practical shell command example of sending and getting the command output:

```
cmdid=$(aws ssm send-command --instance-ids "i-ch3ng3th1s" --document-name "AWS-RunPowerShellScript" --parameters commands=ipconfig --query "Command.CommandId" --output text)
aws ssm list-command-invocations --command-id "$cmdid" --details --query "CommandInvocations[*].CommandPlugins[*].Output[]" --output text

```
> 15 votes

# Answer
Here is a helper Bash script which uses `aws ssm send-command` to run the commands:

```
#/usr/bin/env bash -x
# Script to run PowerShell script on the Windows instance.
instanceId="$1"
cmdId=$(aws ssm send-command --instance-ids "$instanceId" --document-name "AWS-RunPowerShellScript" --query "Command.CommandId" --output text --parameters commands="'${@:2}'")
[ $? -ne 0 ] && { echo "Usage: $0 instance_id command"; exit 1; }
while [ "$(aws ssm list-command-invocations --command-id "$cmdId" --query "CommandInvocations[].Status" --output text)" == "InProgress" ]; do sleep 1; done
aws ssm list-command-invocations --command-id "$cmdId" --details --query "CommandInvocations[*].CommandPlugins[*].Output[]" --output text

```

Usage:

```
 ./run_ec2_ps_cmd.sh instance-id command

```

Example:

```
$ ./run_ec2_ps_cmd.sh i-xyz hostname
ip-xyz

```

To execute larger outputs, see: How to avoid output being truncated when running AWS SSM command?
> 7 votes

# Answer
Yes, you can do this with AWS Systems manager. AWS Systems Manager Run Command allows you to remotely and securely run set of commands on EC2 as well on-premise server. Below are high-level steps to achieve this.

Attach Instance IAM role: The ec2 instance must have IAM role with policy AmazonSSMFullAccess. This role enables the instance to communicate with the Systems Manager API.

Install SSM Agent: The EC2 instance must have SSM agent installed on it. The SSM Agent process the run command requests & configure the instance as per command.

Execute command : Example usage via AWS CLI:

Execute the following command to retrieve the services running on the instance. Replace Instance-ID with ec2 instance id.

```
aws ssm send-command --document-name "AWS-RunShellScript" --comment "listing services" --instance-ids "Instance-ID" --parameters commands="service --status-all" --region us-west-2 --output text

```

More detailed information: here
> 3 votes

# Answer
Here is something super cool I do with AWS SSM Send-Command!

Using Apache Airflow I create a brand new EC2-Instance using a Cloud Formation Template (or CFT for short) that's just a JSON file with all the configuration values for my EC2-Instance that I want; also note that in this CFT I also have a bootstrap command that copies a Python script from an S3 location to the new EC2-Instance so that I can execute it later on using an SSM Send-Command! I do this using Python3 and the AWS SDK for Python3 called the Boto3 library. Here's part of the command for creating the new CFT Stack that in turn creates my new EC2-Instance:

```
import boto3

cft = boto3.client("cloudformation", "us-east-1")

response = cft.create_stack(
    StackName='foobarStackName',
    TemplateBody=json.dumps(json_data))

```

Then I can get the Instance-ID of the new EC2-Instance (required to use SSM Send-Command) using something like this:

```
response = cft.describe_stacks(
    StackName='foobarStackName',
)

```

Then I can get the Instance-ID of the current Airflow Worker's server's EC2-Instance by running this command `wget -q -O - http://169.254.169.254/latest/meta-data/instance-id` through Python:

```
output = subprocess.Popen(['wget', '-q', '-O', '-', 'http://169.254.169.254/latest/meta-data/instance-id'],
                          stdout=subprocess.PIPE)

# Do some weird stuff to get the value (I'm a Java developer so excuse my bad Python skilz)
instanceId = output.communicate()
instanceId = str(instanceId).split("'")[1]

```

**NOW!!!! FOR THE GRAND FINALE**

I can then execute a script on the new EC2-Instance I created and send that script whatever parameters/arguments I want... including the Instance-ID of the server that sent the SSM Send-Command so that way when my script is done running on the new EC2-Instance it can send another SSM Send-Command back to my Airflow server to tell it that the script is finished. This is at a very high level without details but it's just to demonstrate an idea :)

```
subprocess.run(shlex.split('sudo aws ssm send-command --document-name "AWS-RunShellScript" --parameters commands=["sudo python3 /home/ec2-user/ec2_file_sensor.py ' + filepath + ' ' + batchIdValue + ' ' + source + ' ' + fileType + ' ' + airflowWorkerInstanceId + '"] --instance-ids ' + ec2ResourceInstanceId + ' --region us-east-1'))

```

*Not sure if this helped anyone but it's a cool and FUN example of doing something with the AWS SSM Send-Command! Albeit, probably a code smell xD*
> 3 votes

# Answer
If you need to execute more than just one command, because let's say you are investigating an issue, you can start a session:

```
aws ssm start-session --target i-0123456789abcdef0

```

You will need to install Session Manager Plugin for that.
> 0 votes

# Answer
I've slightly improved the script by @kenorb as it wasn't working for me in 2023. It now accepts the region name as a parameter and properly extracts the CommandID:

```
#!/usr/bin/env bash

# Script to run a shell script on a Linux instance

while getopts "r:i:" opt; do
  case $opt in
    r) regionId="$OPTARG" ;;
    i) instanceId="$OPTARG" ;;
    *) echo "Usage: $0 -r region_id -i instance_id command"
       exit 1
       ;;
  esac
done

# Remove the flags from the positional parameters
shift $((OPTIND -1))

# Check if regionId and instanceId are provided
if [[ -z "$regionId" || -z "$instanceId" ]]; then
  echo "Usage: $0 -r region_id -i instance_id command"
  exit 1
fi

cmdId=$(aws ssm send-command --document-name "AWS-RunShellScript" --targets "Key=instanceids,Values=$instanceId" --region "$regionId" --output text --parameters commands="'$*'" | grep -Eo '([a-z0-9])+-([a-z0-9])+-([a-z0-9])+-([a-z0-9])+-([a-z0-9])+')
[ $? -ne 0 ] && { echo "Failed to send command"; exit 1; }

while [ "$(aws ssm list-command-invocations --region "$regionId" --command-id "$cmdId" --query "CommandInvocations[].Status" --output text)" == "InProgress" ]; do
  sleep 0.5
done

aws ssm list-command-invocations --region "$regionId" --command-id "$cmdId" --details --query "CommandInvocations[*].CommandPlugins[*].Output[]" --output text

```

Results in:

```
./run_ec2_ps_cmd.sh -i i-INSERTINSTANCEIDHERE -r us-east-1 'echo "Hello World!"'
Hello World!

```

Don't forget to escape quotes and parameters (dollar signs) in the input, i.e.:

```
./run_ec2_ps_cmd.sh -i i-INSERTINSTANCEIDHERE -r us-east-1 "netstat -tuln | awk \'{print \$4}\'"

```
> 0 votes

---
Tags: amazon-ec2, aws-cli
---


title: Mapping error in Docker Compose

text:
# Question
Title: Mapping error in Docker Compose
I'm still a newbie in the Docker area. I'm just getting confused about this from this Docker-run command:

```
docker run -d --name fritzbox_smarthome_exporter -p 9103:9103 \
  -v $(pwd)/boxcert.cer:/fritzbox.pem:ro \
  -e PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin \
  -e PASSWORD=ChefsPassWord \
  -e USERNAME=chef \
  jaymedh/fritzbox_smarthome_exporter '-noverify=false' '-url=http://fritz.box' '-cert=/fritzbox.pem'

```

to create a corresponding `docker-compose.yml` file.

Can someone enlighten a blind person? Thanks.

This is my design:

```
version: '3.8'
services:
  fritzbox_smarthome_exporter:
    image: 'jaymedh/fritzbox_smarthome_exporter:latest'
    restart: unless-stopped
    ports:
      - '9103:9103'
environment:
      USERNAME=Chef
      PASSWORD=cHefsPw
      PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
volumes:
      - $(pwd)/boxcert.cer:/fritzbox.pem:ro
command: noverify=false url=http://192.168.0.2 cert=/fritzbox.pem

```

But Portainer throws the following error message:

```
failed to deploy a stack: validating /data/compose/25/docker-compose.yml: services.fritzbox_smarthome_exporter1.environment must be a mapping

```

Even if I replace the variable with the regular path on the system ( `- /opt/fritz_smarthome_exporter/boxcert.cer:/fritzbox.pem:ro` ), I get an error.

```
version: '3.8'
services:
  fritzbox_smarthome_exporter:
    image: 'jaymedh/fritzbox_smarthome_exporter:latest'
    restart: unless-stopped
    ports:
      - '9103:9103'
environment:
      USERNAME=Chef
      PASSWORD=cHefsPw
      PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
volumes:
      - /opt/fritbox_smarthome_exporter/boxcert.cer /fritzbox.pem:ro
command: noverify=false url=http://192.168.0.2 cert=/fritzbox.pem

the Error: failed to deploy a stack: validating /data/compose/38/docker-compose.yml: volumes must be a mapping

```

can anyone help me ?

# Answer
> 0 votes
Indentation looks incorrect...Docker Composerize can help you: https://www.composerize.com

```
version: '3.3'
services:
    fritzbox_smarthome_exporter:
        container_name: fritzbox_smarthome_exporter
        ports:
            - '9103:9103'
        volumes:
            - ${PWD}/boxcert.cer:/fritzbox.pem:ro
        environment:
            PATH: /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
            PASSWORD: ChefsPassWord
            USERNAME: chef
        labels:
            - 'http://fritz.box'
        image: jaymedh/fritzbox_smarthome_exporter
        restart: unless-stopped

```

# Answer
> 0 votes
The format of your environment variables is incorrect. Additionally, using bash expansion for the volume path won't work, but you can use a relative path:

```
version: '3.8'
services:
  fritzbox_smarthome_exporter:
    image: 'jaymedh/fritzbox_smarthome_exporter:latest'
    restart: unless-stopped
    ports:
      - '9103:9103'
    environment:
      USERNAME: Chef
      PASSWORD: cHefsPw
      PATH: "/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
    volumes:
      - ./boxcert.cer:/fritzbox.pem:ro
    command: "noverify=false url=http://192.168.0.2 cert=/fritzbox.pem"

```

You can read more about the docker compose file syntax in the official docs

---
Tags: docker, docker-compose
---


# Question
Title: Github Actions: How to export a variable from within Docker and reuse across steps?
We’re developing embedded software which needs to be compiled inside an SDK container. I’m setting up a CI/CD pipeline so that we can compile, ssh-copy and ssh install it on the remote device. To make things more “thread-safe” (so that concurrent actions don’t interfere) I want to export the name of the compiled package so that I can install and clean up specifically that file on the remote device. I’ve tried normal export and an action that saves it to the “global store”, without success.

This is what I tried (all inside one job):

```
# Container step
         EAP=$(echo *.eap)

# Next step
      - name: Save .eap name to env
        uses: UnlyEd/github-action-store-variable@v3
        with:
          variables: |
            EAP=${{ env.EAP }}

# SSH step
        test -f $EAP

```

# Answer
Solution explained in https://docs.github.com/en/github-ae@latest/actions/learn-github-actions/variables

We can use GITHUB\_ENV for variables within the job, or GITHUB\_OUTPUT for variables explicitly across steps and jobs. No need for separate action

Like so `echo "EAP=$(echo *.eap)" >> $GITHUB_ENV`
> 0 votes

---
Tags: docker, github, github-actions
---