From d4a82713dbf0f273d84f423d708bad89000fe5c5 Mon Sep 17 00:00:00 2001 From: Harduino Date: Sat, 1 Aug 2020 21:42:40 +0300 Subject: [PATCH] siemonster :: implementation of parent's network --- functions/onprem/orborus/Dockerfile | 1 + functions/onprem/orborus/orborus.go | 91 +++++++++++------------------ functions/onprem/worker/Dockerfile | 34 +++++------ functions/onprem/worker/worker.go | 40 ++++++------- 4 files changed, 69 insertions(+), 97 deletions(-) diff --git a/functions/onprem/orborus/Dockerfile b/functions/onprem/orborus/Dockerfile index 30859959..e5bc379e 100644 --- a/functions/onprem/orborus/Dockerfile +++ b/functions/onprem/orborus/Dockerfile @@ -9,6 +9,7 @@ COPY orborus.go /app/orborus.go RUN CGO_ENABLED=0 GOOS=linux go build -a -installsuffix cgo -o orborus . FROM alpine:3.12 +RUN apk add --no-cache bash COPY --from=builder /app/ / CMD ["./orborus"] diff --git a/functions/onprem/orborus/orborus.go b/functions/onprem/orborus/orborus.go index fbee4052..983b45bd 100644 --- a/functions/onprem/orborus/orborus.go +++ b/functions/onprem/orborus/orborus.go @@ -14,12 +14,12 @@ import ( "log" "net/http" "os" + "os/exec" "strings" "time" "github.com/docker/docker/api/types" "github.com/docker/docker/api/types/container" - network "github.com/docker/docker/api/types/network" dockerclient "github.com/docker/docker/client" //network "github.com/docker/docker/api/types/network" //natting "github.com/docker/go-connections/nat" @@ -27,11 +27,11 @@ import ( var baseUrl = os.Getenv("BASE_URL") var baseimagename = "frikky/shuffle" -var shuffleNetwork = "" // Filled in init if found var dockerApiVersion = os.Getenv("DOCKER_API_VERSION") var environment = os.Getenv("ENVIRONMENT_NAME") var orgId = os.Getenv("ORG_ID") +var runningMode = os.Getenv("RUNNING_MODE") // Starts jobs in bulk, so this could be increased var sleepTime = 3 @@ -62,56 +62,50 @@ func init() { if err != nil { panic(fmt.Sprintf("Unable to create docker client: %s", err)) } +} - // FIXME: Move this to global variables? - containerIdentifier := "orborus" - networkIdentifier := "shuffle" +// form id of current running container +func getThisContainerId() string { + containerId := "" + fCol := "" - ctx := context.Background() - containers, err := dockercli.ContainerList(ctx, types.ContainerListOptions{ - All: true, - }) - if err != nil { - log.Printf("Failed getting containers during init - running without network check: %s", err) + // some adjusting based on current running mode + switch runningMode { + case "Kubernetes": + // cgroup will be like: + // 11:net_cls,net_prio:/kubepods/besteffort/podf132b44d-cfcf-43f7-9906-79f58e268333/851466f8b5ed5aa0f265b1c95c6d2bafbc51a38dd5c5a1621b6e586572150009 + fCol = "5" + + case "Docker": + // cgroup will be like: + // 12:perf_event:/docker/0f06810364f52a2cd6e80bfba27419cb8a29758a204cd676388f4913bb366f2b + fCol = "3" + + default: + fCol = "3" // for backward-compatibility with production + log.Printf("[WARNING] Running not containerized, so I can't figure out current container id!") } - // Skip random containers. Only handle things related to Shuffle. - for _, container := range containers { - found := false - - // Bad states - it might just be created sometimes, leading to now netowkr - //if container.State == "restarting" || container.State == "paused" || container.State == "exited" || container.State == "dead" { - // continue - //} - - for _, name := range container.Names { - if !strings.Contains(strings.ToLower(name), containerIdentifier) { - found = true - continue - } - } - - if found { - for key, _ := range container.NetworkSettings.Networks { - if strings.Contains(strings.ToLower(key), networkIdentifier) { - shuffleNetwork = key - break - } - } + if fCol != "" { + cmd := fmt.Sprintf("head -1 /proc/self/cgroup | cut -d/ -f%s", fCol) + out, err := exec.Command("bash","-c",cmd).Output() + if err == nil { + containerId = strings.TrimSpace(string(out)) } } - if len(shuffleNetwork) > 0 { - log.Printf("Found shuffle network \"%s\" for container %s", shuffleNetwork, containerIdentifier) - } else { - log.Printf("Running Shuffle without a docker network") - } + return containerId } // Deploys the internal worker whenever something happens func deployWorker(image string, identifier string, env []string) { + // figure out current container id + containerId := getThisContainerId() + // Binds is the actual "-v" volume. hostConfig := &container.HostConfig{ + NetworkMode: container.NetworkMode(fmt.Sprintf("container:%s", containerId)), + IpcMode: container.IpcMode(fmt.Sprintf("container:%s", containerId)), LogConfig: container.LogConfig{ Type: "json-file", Config: map[string]string{}, @@ -121,23 +115,6 @@ func deployWorker(image string, identifier string, env []string) { }, } - // Look for Shuffle network and set it - networkConfig := &network.NetworkingConfig{} - if len(shuffleNetwork) > 0 { - log.Printf("Starting worker with network %s", shuffleNetwork) - networkConfig = &network.NetworkingConfig{ - EndpointsConfig: map[string]*network.EndpointSettings{ - shuffleNetwork: { - NetworkID: shuffleNetwork, - }, - }, - } - - env = append(env, fmt.Sprintf("DOCKER_NETWORK=%s", shuffleNetwork)) - } else { - log.Printf("Starting worker WITHOUT any specified network: %s", shuffleNetwork) - } - // ROFL: https://docker-py.readthedocs.io/en/1.4.0/volumes/ config := &container.Config{ Image: image, @@ -154,7 +131,7 @@ func deployWorker(image string, identifier string, env []string) { context.Background(), config, hostConfig, - networkConfig, + nil, nil, identifier, ) diff --git a/functions/onprem/worker/Dockerfile b/functions/onprem/worker/Dockerfile index 2f8971f8..7f253e1b 100644 --- a/functions/onprem/worker/Dockerfile +++ b/functions/onprem/worker/Dockerfile @@ -1,21 +1,17 @@ -#from golang as builder -# -#RUN mkdir /app -#WORKDIR /app -#COPY worker.go /app/worker.go -# -#RUN go get github.com/docker/docker/api/types -#RUN go get github.com/docker/docker/api/types/container -#RUN go get -u github.com/docker/docker/client -# -#RUN CGO_ENABLED=0 GOOS=linux go build -a -installsuffix cgo -o worker . -# +from golang as builder -# THis is a workaround until I get docker/docker to build in a dockerfile -# PS: This is tricky to google. -# Might not work on some machines. -from scratch -#COPY --from=builder /app/ / -COPY worker.bin /worker.bin +WORKDIR /app -CMD ["./worker.bin"] +RUN go get github.com/docker/docker/api/types && \ + go get github.com/docker/docker/api/types/container && \ + go get -u github.com/docker/docker/client + +COPY worker.go /app/worker.go +RUN CGO_ENABLED=0 GOOS=linux go build -a -installsuffix cgo -o worker . + + +FROM alpine:3.12 +RUN apk add --no-cache bash +COPY --from=builder /app/ / + +CMD ["./worker"] diff --git a/functions/onprem/worker/worker.go b/functions/onprem/worker/worker.go index 48b11ebc..dce95db1 100644 --- a/functions/onprem/worker/worker.go +++ b/functions/onprem/worker/worker.go @@ -11,12 +11,12 @@ import ( "log" "net/http" "os" + "os/exec" "strings" "time" "github.com/docker/docker/api/types" "github.com/docker/docker/api/types/container" - network "github.com/docker/docker/api/types/network" dockerclient "github.com/docker/docker/client" ) @@ -412,9 +412,26 @@ func shutdown(executionId, workflowId string) { os.Exit(3) } +// form container id of current running container +func getThisContainerId() string { + containerId := "" + cmd := fmt.Sprintf("head -1 /proc/self/cgroup | cut -d/ -f3") + out, err := exec.Command("bash","-c",cmd).Output() + if err == nil { + containerId = strings.TrimSpace(string(out)) + } + + return containerId +} + // Deploys the internal worker whenever something happens func deployApp(cli *dockerclient.Client, image string, identifier string, env []string) error { + // figure out current container id + containerId := getThisContainerId() + hostConfig := &container.HostConfig{ + NetworkMode: container.NetworkMode(fmt.Sprintf("container:%s", containerId)), + IpcMode: container.IpcMode(fmt.Sprintf("container:%s", containerId)), LogConfig: container.LogConfig{ Type: "json-file", Config: map[string]string{}, @@ -426,23 +443,11 @@ func deployApp(cli *dockerclient.Client, image string, identifier string, env [] Env: env, } - networkConfig := &network.NetworkingConfig{} - shuffleNetwork := os.Getenv("DOCKER_NETWORK") - if len(shuffleNetwork) > 0 { - networkConfig = &network.NetworkingConfig{ - EndpointsConfig: map[string]*network.EndpointSettings{ - shuffleNetwork: { - NetworkID: shuffleNetwork, - }, - }, - } - } - cont, err := cli.ContainerCreate( context.Background(), config, hostConfig, - networkConfig, + nil, nil, identifier, ) @@ -1107,13 +1112,6 @@ func main() { } } - shuffleNetwork := os.Getenv("DOCKER_NETWORK") - if len(shuffleNetwork) > 0 { - log.Printf("Running with Docker network %s", shuffleNetwork) - } else { - log.Printf("No docker network specified for Worker.") - } - // WORKER_TESTING_WORKFLOW should be a workflow ID authorization := "" executionId := ""