Skip to content

Commit

Permalink
Merge pull request #276 from kiwigrid/allow-executable-files
Browse files Browse the repository at this point in the history
feat: run executable files without `sh`

increments #minor
  • Loading branch information
jekkel authored May 8, 2023
2 parents b16667c + 233219d commit e8fd62a
Show file tree
Hide file tree
Showing 5 changed files with 64 additions and 15 deletions.
11 changes: 7 additions & 4 deletions .github/workflows/build_and_test.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v3
uses: actions/checkout@v3
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v2
- name: Build sidecar
Expand Down Expand Up @@ -91,6 +91,7 @@ jobs:
wait_for_pod_ready "sidecar"
wait_for_pod_ready "sidecar-5xx"
wait_for_pod_ready "sidecar-pythonscript"
wait_for_pod_ready "dummy-server-pod"
- name: Install Configmaps and Secrets
Expand All @@ -103,7 +104,7 @@ jobs:
sleep 20
echo "Installing resources..."
kubectl apply -f "test/resources/resources.yaml"
pods=("sidecar" "sidecar-5xx")
pods=("sidecar" "sidecar-5xx" "sidecar-pythonscript")
resources=("sample-configmap" "sample-secret-binary" "absolute-configmap" "relative-configmap" "change-dir-configmap" "url-configmap-500" "url-configmap-basic-auth" "sample-configmap")
for p in ${pods[*]}; do
for r in ${resources[*]}; do
Expand All @@ -116,11 +117,12 @@ jobs:
run: |
kubectl logs sidecar > /tmp/sidecar.log
kubectl logs sidecar-5xx > /tmp/sidecar-5xx.log
kubectl logs sidecar-pythonscript > /tmp/sidecar-pythonscript.log
kubectl logs dummy-server-pod > /tmp/dummy-server.log
- name: Upload artifacts
uses: actions/upload-artifact@v3
with:
name: pod-logs_${{ matrix.k8s }}
name: pod-logs_${{ matrix.k8s.maj_min }}
path: /tmp/*.log
- name: Download expected files from cluster
run: |
Expand Down Expand Up @@ -199,4 +201,5 @@ jobs:
kubectl exec sidecar -- sh -c "! test -e /tmp/secret-kubelogo.png" && kubectl exec sidecar -- sh -c "test -e /tmp/change-secret-kubelogo.png" &&
kubectl exec sidecar -- sh -c "! test -e /tmp/absolute/absolute.txt" && kubectl exec sidecar -- sh -c "test -e /tmp/absolute/change-absolute.txt" &&
kubectl exec sidecar -- sh -c "! test -e /tmp/relative/relative.txt" && kubectl exec sidecar -- sh -c "test -e /tmp/relative/change-relative.txt" &&
kubectl exec sidecar -- sh -c "! test -e /tmp/orig-dir/change-dir.txt" && kubectl exec sidecar -- sh -c "test -e /tmp/new-dir/change-dir.txt"
kubectl exec sidecar -- sh -c "! test -e /tmp/orig-dir/change-dir.txt" && kubectl exec sidecar -- sh -c "test -e /tmp/new-dir/change-dir.txt" &&
test $(cat /tmp/sidecar-pythonscript.log | grep "Hello from python script!" | wc -l) = "7"
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -78,10 +78,10 @@ If the filename ends with `.url` suffix, the content will be processed as a URL
| `REQ_USERNAME` | Username to use for basic authentication for requests to `REQ_URL` and for `*.url` triggered requests | false | - | string |
| `REQ_PASSWORD` | Password to use for basic authentication for requests to `REQ_URL` and for `*.url` triggered requests | false | - | string |
| `REQ_BASIC_AUTH_ENCODING` | Which encoding to use for username and password as [by default it's undefined](https://datatracker.ietf.org/doc/html/rfc7617) (e.g. `utf-8`). | false | `latin1` | string |
| `SCRIPT` | Absolute path to shell script to execute after a configmap got reloaded. It runs before calls to `REQ_URI` | false | - | string |
| `SCRIPT` | Absolute path to a script to execute after a configmap got reloaded. It runs before calls to `REQ_URI`. If the file is not executable it will be passed to `sh`. Otherwise it's executed as is. [Shebangs](https://en.wikipedia.org/wiki/Shebang_(Unix)) known to work are `#!/bin/sh` and `#!/usr/bin/env python` | false | - | string |
| `ERROR_THROTTLE_SLEEP` | How many seconds to wait before watching resources again when an error occurs | false | `5` | integer |
| `SKIP_TLS_VERIFY` | Set to `true` to skip tls verification for kube api calls | false | - | boolean |
| `REQ_SKIP_TLS_VERIFY` | Set to `true` to skip tls verification for all HTTP requests (except the Kube API server, which are controlled by `SKIP_TLS_VERIFY`). Note that the latest 'requests' library no longer offer a way to disable this via env vars; however a custom truststore can be set via REQUESTS_CA_BUNDLE. | false | - | boolean |
| `REQ_SKIP_TLS_VERIFY` | Set to `true` to skip tls verification for all HTTP requests (except the Kube API server, which are controlled by `SKIP_TLS_VERIFY`). Note that the latest 'requests' library no longer offer a way to disable this via env vars; however a custom truststore can be set via REQUESTS_CA_BUNDLE. | false | - | boolean |
| `UNIQUE_FILENAMES` | Set to true to produce unique filenames where duplicate data keys exist between ConfigMaps and/or Secrets within the same or multiple Namespaces. | false | `false` | boolean |
| `DEFAULT_FILE_MODE` | The default file system permission for every file. Use three digits (e.g. '500', '440', ...) | false | - | string |
| `KUBECONFIG` | if this is given and points to a file or `~/.kube/config` is mounted k8s config will be loaded from this file, otherwise "incluster" k8s configuration is tried. | false | - | string |
Expand Down
15 changes: 11 additions & 4 deletions src/helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import errno
import hashlib
import os
import stat
import subprocess
from datetime import datetime

Expand Down Expand Up @@ -169,11 +170,17 @@ def unique_filename(filename, namespace, resource, resource_name):
def execute(script_path):
logger.debug(f"Executing script from {script_path}")
try:
result = subprocess.run(["sh", script_path],
capture_output=True,
check=True)
file_stat = os.stat(script_path)
if file_stat.st_mode & stat.S_IXOTH:
result = subprocess.run([script_path],
capture_output=True,
check=True)
else:
result = subprocess.run(["sh", script_path],
capture_output=True,
check=True)
logger.debug(f"Script stdout: {result.stdout}")
logger.debug(f"Script stderr: {result.stderr}")
logger.debug(f"Script exit code: {result.returncode}")
except subprocess.CalledProcessError as e:
logger.error(f"Script failed with error: {e}")
logger.error(f"Script failed with error: {e}")
8 changes: 4 additions & 4 deletions src/resources.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
#!/usr/bin/env python

import base64
import copy
import os
import signal
import sys
import copy
import traceback
from collections import defaultdict
from multiprocessing import Process
Expand All @@ -14,10 +14,10 @@
from kubernetes.client.rest import ApiException
from urllib3.exceptions import MaxRetryError
from urllib3.exceptions import ProtocolError
from logger import get_logger

from helpers import request, write_data_to_file, remove_file, unique_filename, CONTENT_TYPE_TEXT, \
CONTENT_TYPE_BASE64_BINARY, execute, WATCH_SERVER_TIMEOUT, WATCH_CLIENT_TIMEOUT
from logger import get_logger

RESOURCE_SECRET = "secret"
RESOURCE_CONFIGMAP = "configmap"
Expand Down Expand Up @@ -277,8 +277,8 @@ def _update_file(data_key, data_content, dest_folder, metadata, resource,
else:
logger.debug(f"Deleting {filename}")
return remove_file(dest_folder, filename)
except Exception as e:
logger.error(f"Error when updating from ${data_key} into ${dest_folder}: ${e}")
except Exception:
logger.exception(f"Error when updating from '%s' into '%s'", data_key, dest_folder)
return False


Expand Down
41 changes: 40 additions & 1 deletion test/resources/sidecar.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,10 @@ data:
script.sh: |-
#!/bin/sh
touch /tmp/script_result
script.py: |-
#!/usr/bin/env python
print("Hello from python script!")
---
apiVersion: v1
kind: Pod
Expand Down Expand Up @@ -80,6 +84,41 @@ spec:
---
apiVersion: v1
kind: Pod
metadata:
name: sidecar-pythonscript
namespace: default
spec:
serviceAccountName: sample-acc
containers:
- name: sidecar
image: kiwigrid/k8s-sidecar:testing
volumeMounts:
- name: shared-volume
mountPath: /tmp/
- name: script-volume
mountPath: /opt/script.py
subPath: script.py
env:
- name: LABEL
value: "findme"
- name: FOLDER
value: /tmp/
- name: RESOURCE
value: both
- name: SCRIPT
value: "/opt/script.py"
- name: LOG_LEVEL
value: "DEBUG"
volumes:
- name: shared-volume
emptyDir: { }
- name: script-volume
configMap:
name: script-configmap
defaultMode: 0777
---
apiVersion: v1
kind: Pod
metadata:
name: sidecar-5xx
namespace: default
Expand Down Expand Up @@ -140,4 +179,4 @@ spec:
ports:
- port: 80
targetPort: 80
name: http
name: http

0 comments on commit e8fd62a

Please sign in to comment.