Skip to content

Commit

Permalink
support process specification (#193)
Browse files Browse the repository at this point in the history
* introduce multi-process example app
* use v0.0.2 images
* changelog
* wip: introduce failing test
* add optional timeout for cli wrapper
* refactor test setup
* implement feature, test passing
* collided with a stale ns, reduce likelihood
* gen docs
* make docs in build
  • Loading branch information
mitchdraft authored and soloio-bulldozer[bot] committed May 3, 2019
1 parent a6f675f commit e71cb61
Show file tree
Hide file tree
Showing 32 changed files with 466 additions and 30 deletions.
2 changes: 1 addition & 1 deletion Gopkg.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,8 @@ clean:
generatecode: must
mkdir -p $(OUTPUT_DIR)
go run cmd/generate-code/main.go
rm docs/cli/squashctl*
go run cmd/generate-docs/main.go
gofmt -w ci cmd pkg test
goimports -w ci cmd pkg test

Expand Down
4 changes: 4 additions & 0 deletions changelog/v0.5.13/multi-process.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
description:
- type: NEW_FEATURE
description: Option to pass a process selector, rather than default to PID 1
issueLink: https://github.com/solo-io/squash/issues/173
1 change: 1 addition & 0 deletions contrib/condition/multi_process/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
_out/
32 changes: 32 additions & 0 deletions contrib/condition/multi_process/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
IMAGE_TAG ?= dev
CONTAINER_REPO_ORG ?= docker.io/soloio

## These are the images created by this makefile
MULTI_SPEC := $(CONTAINER_REPO_ORG)/multi_process:$(IMAGE_TAG)
SINGLE_SPEC := $(CONTAINER_REPO_ORG)/multi_process_base:$(IMAGE_TAG)

ROOTDIR := $(shell pwd)
OUTPUT_DIR := $(ROOTDIR)/_output

.PHONY: all
all: push-single push-multi

.PHONY: compile
compile:
GOOS=linux go build -gcflags "-N -l" -o $(OUTPUT_DIR)/sample_app main.go

.PHONY: build-multi
build-multi: compile
docker build -t $(MULTI_SPEC) -f multi.dockerfile .

.PHONY: push-multi
push-multi: build-multi
docker push $(MULTI_SPEC)

.PHONY: build-single
build-single: compile
docker build -t $(SINGLE_SPEC) -f single.dockerfile .

.PHONY: push-single
push-single: build-single
docker push $(SINGLE_SPEC)
69 changes: 69 additions & 0 deletions contrib/condition/multi_process/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
# Debug arbitrary container PIDs with Squash

At one point, Squash assumed that a user's debug target was completely described by the selection of: namespace, pod name, container. Squash assumed that the user wanted to debug the first process in the container. This is a reasonable assumption, since a popular container usage pattern is to specify one process per container. However it may be useful to run multiple processes in a single container. In order for squash to debug an arbitrary process, it needs to be told how to choose among the available processes.

# Demonstration of the properties of multi-process containers

This directory includes files needed to build and deploy a sample app as the first process in one container and the second process in a separate container.

## Build and push the containers

*This step is not needed, as the container images are already available with the values shown below. If you change these values you will need to update the manifests similarly.*

```bash
export CONTAINER_REPO_ORG = docker.io/soloio
IMAGE_TAG=v0.0.2 make all
```

## Deploy the containers

We will deploy our sample containers in their own pods:

```bash
kubectl apply -f single.yaml
kubectl apply -f multi.yaml
```

## Inspect the images

Note that the container with a single process features our app in PID 1

```bash
k exec -it squash-demo-multiprocess-base-6c746c8595-kpsvt -- /bin/s
h
/app # ls
sample_app
/app # ps
PID USER TIME COMMAND
1 root 0:00 ./sample_app
19 root 0:00 /bin/sh
26 root 0:00 ps
```

However, for our multi-process container, our app is not PID 1

```bash
k exec -it squash-demo-multiprocess-5fbdcd96cf-k9bzw -- /bin/sh
/app # ls
call_app.sh sample_app
/app # ps
PID USER TIME COMMAND
1 root 0:00 {call_app.sh} /bin/sh ./call_app.sh
7 root 0:00 ./sample_app
20 root 0:00 /bin/sh
27 root 0:00 ps
```

## Debug the processes with squash

You can debug the single process container without passing any flags. Squash will use the first PID by default. This works fine with our single process example.

```bash
squashctl # follow interactive prompt to choose target debug container
```

To debug a multi-process container, you need to specify a process-identifier string. Squash will look for processes whos invocation comand matches the string provided.

```bash
squashctl --process sample_app # matches with case-insensitive regex
```
5 changes: 5 additions & 0 deletions contrib/condition/multi_process/call_app.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
#!/bin/sh

echo running the app from a bash script

./sample_app
32 changes: 32 additions & 0 deletions contrib/condition/multi_process/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package main

import (
"fmt"
"log"
"net/http"
"os"
)

var ServiceToCall = "example-service2"

func main() {

fmt.Println("starting app")
potentialservice2 := os.Getenv("SERVICE2_URL")
if potentialservice2 != "" {
ServiceToCall = potentialservice2
}

http.HandleFunc("/calc", handler)
http.HandleFunc("/", view)

log.Fatal(http.ListenAndServe(":8080", nil))
}

func view(w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w, "hello")
}

func handler(w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w, "hello again")
}
6 changes: 6 additions & 0 deletions contrib/condition/multi_process/multi.dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
# calls a go process from a shell script, making it the second PID
FROM alpine
WORKDIR /app
ADD _output/sample_app /app
ADD call_app.sh /app
ENTRYPOINT ./call_app.sh
20 changes: 20 additions & 0 deletions contrib/condition/multi_process/multi.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
apiVersion: apps/v1beta1
kind: Deployment
metadata:
name: squash-demo-multiprocess
spec:
replicas: 1
selector:
matchLabels:
app: squash-demo-multiprocess
template:
metadata:
labels:
app: squash-demo-multiprocess
spec:
containers:
- name: squash-demo-multiprocess
image: soloio/multi_process:v0.0.2
ports:
- containerPort: 8080
protocol: TCP
5 changes: 5 additions & 0 deletions contrib/condition/multi_process/single.dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# calls the go process only, making it the first PID
FROM alpine
WORKDIR /app
ADD _output/sample_app /app
ENTRYPOINT ./sample_app
20 changes: 20 additions & 0 deletions contrib/condition/multi_process/single.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
apiVersion: apps/v1beta1
kind: Deployment
metadata:
name: squash-demo-multiprocess-base
spec:
replicas: 1
selector:
matchLabels:
app: squash-demo-multiprocess-base
template:
metadata:
labels:
app: squash-demo-multiprocess-base
spec:
containers:
- name: squash-demo-multiprocess-base
image: soloio/multi_process_base:v0.0.2
ports:
- containerPort: 8080
protocol: TCP
2 changes: 2 additions & 0 deletions docs/cli/squashctl.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ squashctl [flags]
### Options

```
--config string optional, path to squash config (defaults to ~/.squash/config.yaml)
--container string Container to debug
--container-repo string debug container repo to use (default "soloio")
--container-version string debug container version to use (default "mkdev")
Expand All @@ -36,6 +37,7 @@ squashctl [flags]
--no-guess-debugger don't auto detect debugger to use
--no-guess-pod don't auto detect pod to use
--pod string Pod to debug
--process-match string optional, if passed, Squash will try to find a process in the target container that matches (regex, case-insensitive) this string. Otherwise Squash chooses the first process.
--squash-namespace string the namespace where squash resources will be deployed (default: squash-debugger) (default "squash-debugger")
--timeout int timeout in seconds to wait for debug pod to be ready (default 300)
```
Expand Down
2 changes: 2 additions & 0 deletions docs/cli/squashctl_completion.md
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ squashctl completion SHELL [flags]
### Options inherited from parent commands

```
--config string optional, path to squash config (defaults to ~/.squash/config.yaml)
--container string Container to debug
--container-repo string debug container repo to use (default "soloio")
--container-version string debug container version to use (default "mkdev")
Expand All @@ -68,6 +69,7 @@ squashctl completion SHELL [flags]
--no-guess-debugger don't auto detect debugger to use
--no-guess-pod don't auto detect pod to use
--pod string Pod to debug
--process-match string optional, if passed, Squash will try to find a process in the target container that matches (regex, case-insensitive) this string. Otherwise Squash chooses the first process.
--squash-namespace string the namespace where squash resources will be deployed (default: squash-debugger) (default "squash-debugger")
--timeout int timeout in seconds to wait for debug pod to be ready (default 300)
```
Expand Down
2 changes: 2 additions & 0 deletions docs/cli/squashctl_deploy.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ deploy squash or a demo microservice
### Options inherited from parent commands

```
--config string optional, path to squash config (defaults to ~/.squash/config.yaml)
--container string Container to debug
--container-repo string debug container repo to use (default "soloio")
--container-version string debug container version to use (default "mkdev")
Expand All @@ -32,6 +33,7 @@ deploy squash or a demo microservice
--no-guess-debugger don't auto detect debugger to use
--no-guess-pod don't auto detect pod to use
--pod string Pod to debug
--process-match string optional, if passed, Squash will try to find a process in the target container that matches (regex, case-insensitive) this string. Otherwise Squash chooses the first process.
--squash-namespace string the namespace where squash resources will be deployed (default: squash-debugger) (default "squash-debugger")
--timeout int timeout in seconds to wait for debug pod to be ready (default 300)
```
Expand Down
2 changes: 2 additions & 0 deletions docs/cli/squashctl_deploy_demo.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ squashctl deploy demo [flags]
### Options inherited from parent commands

```
--config string optional, path to squash config (defaults to ~/.squash/config.yaml)
--container string Container to debug
--container-repo string debug container repo to use (default "soloio")
--container-version string debug container version to use (default "mkdev")
Expand All @@ -39,6 +40,7 @@ squashctl deploy demo [flags]
--no-guess-debugger don't auto detect debugger to use
--no-guess-pod don't auto detect pod to use
--pod string Pod to debug
--process-match string optional, if passed, Squash will try to find a process in the target container that matches (regex, case-insensitive) this string. Otherwise Squash chooses the first process.
--squash-namespace string the namespace where squash resources will be deployed (default: squash-debugger) (default "squash-debugger")
--timeout int timeout in seconds to wait for debug pod to be ready (default 300)
```
Expand Down
2 changes: 2 additions & 0 deletions docs/cli/squashctl_deploy_squash.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ squashctl deploy squash [flags]
### Options inherited from parent commands

```
--config string optional, path to squash config (defaults to ~/.squash/config.yaml)
--container string Container to debug
--container-repo string debug container repo to use (default "soloio")
--container-version string debug container version to use (default "mkdev")
Expand All @@ -37,6 +38,7 @@ squashctl deploy squash [flags]
--no-guess-debugger don't auto detect debugger to use
--no-guess-pod don't auto detect pod to use
--pod string Pod to debug
--process-match string optional, if passed, Squash will try to find a process in the target container that matches (regex, case-insensitive) this string. Otherwise Squash chooses the first process.
--squash-namespace string the namespace where squash resources will be deployed (default: squash-debugger) (default "squash-debugger")
--timeout int timeout in seconds to wait for debug pod to be ready (default 300)
```
Expand Down
2 changes: 2 additions & 0 deletions docs/cli/squashctl_squash.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ squashctl squash [flags]
### Options inherited from parent commands

```
--config string optional, path to squash config (defaults to ~/.squash/config.yaml)
--container string Container to debug
--container-repo string debug container repo to use (default "soloio")
--container-version string debug container version to use (default "mkdev")
Expand All @@ -44,6 +45,7 @@ squashctl squash [flags]
--no-guess-debugger don't auto detect debugger to use
--no-guess-pod don't auto detect pod to use
--pod string Pod to debug
--process-match string optional, if passed, Squash will try to find a process in the target container that matches (regex, case-insensitive) this string. Otherwise Squash chooses the first process.
--squash-namespace string the namespace where squash resources will be deployed (default: squash-debugger) (default "squash-debugger")
--timeout int timeout in seconds to wait for debug pod to be ready (default 300)
```
Expand Down
2 changes: 2 additions & 0 deletions docs/cli/squashctl_squash_delete.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ squashctl squash delete [flags]
### Options inherited from parent commands

```
--config string optional, path to squash config (defaults to ~/.squash/config.yaml)
--container string Container to debug
--container-repo string debug container repo to use (default "soloio")
--container-version string debug container version to use (default "mkdev")
Expand All @@ -36,6 +37,7 @@ squashctl squash delete [flags]
--no-guess-debugger don't auto detect debugger to use
--no-guess-pod don't auto detect pod to use
--pod string Pod to debug
--process-match string optional, if passed, Squash will try to find a process in the target container that matches (regex, case-insensitive) this string. Otherwise Squash chooses the first process.
--squash-namespace string the namespace where squash resources will be deployed (default: squash-debugger) (default "squash-debugger")
--timeout int timeout in seconds to wait for debug pod to be ready (default 300)
```
Expand Down
2 changes: 2 additions & 0 deletions docs/cli/squashctl_squash_status.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ squashctl squash status [flags]
### Options inherited from parent commands

```
--config string optional, path to squash config (defaults to ~/.squash/config.yaml)
--container string Container to debug
--container-repo string debug container repo to use (default "soloio")
--container-version string debug container version to use (default "mkdev")
Expand All @@ -36,6 +37,7 @@ squashctl squash status [flags]
--no-guess-debugger don't auto detect debugger to use
--no-guess-pod don't auto detect pod to use
--pod string Pod to debug
--process-match string optional, if passed, Squash will try to find a process in the target container that matches (regex, case-insensitive) this string. Otherwise Squash chooses the first process.
--squash-namespace string the namespace where squash resources will be deployed (default: squash-debugger) (default "squash-debugger")
--timeout int timeout in seconds to wait for debug pod to be ready (default 300)
```
Expand Down
3 changes: 3 additions & 0 deletions docs/cli/squashctl_utils.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ squash utils list-attachments
### Options inherited from parent commands

```
--config string optional, path to squash config (defaults to ~/.squash/config.yaml)
--container string Container to debug
--container-repo string debug container repo to use (default "soloio")
--container-version string debug container version to use (default "mkdev")
Expand All @@ -42,6 +43,7 @@ squash utils list-attachments
--no-guess-debugger don't auto detect debugger to use
--no-guess-pod don't auto detect pod to use
--pod string Pod to debug
--process-match string optional, if passed, Squash will try to find a process in the target container that matches (regex, case-insensitive) this string. Otherwise Squash chooses the first process.
--squash-namespace string the namespace where squash resources will be deployed (default: squash-debugger) (default "squash-debugger")
--timeout int timeout in seconds to wait for debug pod to be ready (default 300)
```
Expand All @@ -53,4 +55,5 @@ squash utils list-attachments
* [squashctl utils delete-permissions](../squashctl_utils_delete-permissions) - remove all service accounts, roles, and role bindings created by Squash.
* [squashctl utils delete-planks](../squashctl_utils_delete-planks) - remove all plank debugger pods created by Squash.
* [squashctl utils list-attachments](../squashctl_utils_list-attachments) - list all existing debug attachments
* [squashctl utils register-resources](../squashctl_utils_register-resources) - register the custom resource definitions (CRDs) needed by squash

2 changes: 2 additions & 0 deletions docs/cli/squashctl_utils_delete-attachments.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ squashctl utils delete-attachments [flags]
### Options inherited from parent commands

```
--config string optional, path to squash config (defaults to ~/.squash/config.yaml)
--container string Container to debug
--container-repo string debug container repo to use (default "soloio")
--container-version string debug container version to use (default "mkdev")
Expand All @@ -36,6 +37,7 @@ squashctl utils delete-attachments [flags]
--no-guess-debugger don't auto detect debugger to use
--no-guess-pod don't auto detect pod to use
--pod string Pod to debug
--process-match string optional, if passed, Squash will try to find a process in the target container that matches (regex, case-insensitive) this string. Otherwise Squash chooses the first process.
--squash-namespace string the namespace where squash resources will be deployed (default: squash-debugger) (default "squash-debugger")
--timeout int timeout in seconds to wait for debug pod to be ready (default 300)
```
Expand Down
Loading

0 comments on commit e71cb61

Please sign in to comment.