merge to 1.3.0
This commit is contained in:
@@ -33,6 +33,10 @@ ENV SHUFFLE_BASE_IMAGE_REGISTRY=docker.io
|
||||
ENV SHUFFLE_BASE_IMAGE_NAME=frikky/shuffle
|
||||
ENV SHUFFLE_BASE_IMAGE_TAG_SUFFIX=0.8.70
|
||||
|
||||
#for k8s
|
||||
ENV SHUFFLE_OPENSEARCH_URL=https://opensearch:9200
|
||||
ENV SHUFFLE_OPENSEARCH_SKIPSSL_VERIFY=true
|
||||
|
||||
RUN apk add --no-cache bash tzdata
|
||||
COPY --from=builder /app/ /
|
||||
|
||||
|
||||
Executable → Regular
+6
-6
@@ -7,7 +7,7 @@ go 1.19
|
||||
require (
|
||||
cloud.google.com/go/datastore v1.10.0
|
||||
cloud.google.com/go/storage v1.29.0
|
||||
github.com/docker/docker v23.0.0+incompatible
|
||||
github.com/docker/docker v23.0.3+incompatible
|
||||
github.com/gorilla/mux v1.8.0
|
||||
github.com/patrickmn/go-cache v2.1.0+incompatible
|
||||
github.com/satori/go.uuid v1.2.0
|
||||
@@ -25,7 +25,7 @@ require (
|
||||
github.com/algolia/algoliasearch-client-go/v3 v3.18.1 // indirect
|
||||
github.com/bradfitz/gomemcache v0.0.0-20221031212613-62deef7fc822 // indirect
|
||||
github.com/bradfitz/slice v0.0.0-20180809154707-2b758aa73013 // indirect
|
||||
github.com/docker/distribution v2.8.1+incompatible // indirect
|
||||
github.com/docker/distribution v2.8.2+incompatible // indirect
|
||||
github.com/docker/go-connections v0.4.0 // indirect
|
||||
github.com/docker/go-units v0.5.0 // indirect
|
||||
github.com/frikky/go-elasticsearch/v8 v8.13.1 // indirect
|
||||
@@ -51,12 +51,12 @@ require (
|
||||
github.com/skip2/go-qrcode v0.0.0-20200617195104-da1b6568686e // indirect
|
||||
go.opencensus.io v0.24.0 // indirect
|
||||
go4.org v0.0.0-20201209231011-d4a079459e60 // indirect
|
||||
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519 // indirect
|
||||
golang.org/x/crypto v0.1.0 // indirect
|
||||
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4 // indirect
|
||||
golang.org/x/net v0.0.0-20221014081412-f15817d10f9b // indirect
|
||||
golang.org/x/net v0.7.0 // indirect
|
||||
golang.org/x/oauth2 v0.0.0-20221014153046-6fdb5e3db783 // indirect
|
||||
golang.org/x/sys v0.1.0 // indirect
|
||||
golang.org/x/text v0.5.0 // indirect
|
||||
golang.org/x/sys v0.5.0 // indirect
|
||||
golang.org/x/text v0.7.0 // indirect
|
||||
golang.org/x/tools v0.1.12 // indirect
|
||||
golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 // indirect
|
||||
google.golang.org/api v0.106.0 // indirect
|
||||
|
||||
Executable → Regular
+12
-20
@@ -74,10 +74,10 @@ github.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnht
|
||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/docker/distribution v2.8.1+incompatible h1:Q50tZOPR6T/hjNsyc9g8/syEs6bk8XXApsHjKukMl68=
|
||||
github.com/docker/distribution v2.8.1+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w=
|
||||
github.com/docker/docker v23.0.0+incompatible h1:L6c28tNyqZ4/ub9AZC9d5QUuunoHHfEH4/Ue+h/E5nE=
|
||||
github.com/docker/docker v23.0.0+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
|
||||
github.com/docker/distribution v2.8.2+incompatible h1:T3de5rq0dB1j30rp0sA2rER+m322EBzniBPB6ZIzuh8=
|
||||
github.com/docker/distribution v2.8.2+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w=
|
||||
github.com/docker/docker v23.0.3+incompatible h1:9GhVsShNWz1hO//9BNg/dpMnZW25KydO4wtVxWAIbho=
|
||||
github.com/docker/docker v23.0.3+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
|
||||
github.com/docker/go-connections v0.4.0 h1:El9xVISelRB7BuFusrZozjnkIM5YnzCViNKohAFqRJQ=
|
||||
github.com/docker/go-connections v0.4.0/go.mod h1:Gbd7IOopHjR8Iph03tsViu4nIes5XhDvyHbTtUxmeec=
|
||||
github.com/docker/go-units v0.5.0 h1:69rxXcBk27SvSaaxTtLh/8llcHD8vYHT7WSdRZ/jvr4=
|
||||
@@ -212,14 +212,6 @@ github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFR
|
||||
github.com/rwcarlsen/goexif v0.0.0-20190401172101-9e8deecbddbd/go.mod h1:hPqNNc0+uJM6H+SuU8sEs5K5IQeKccPqeSjfgcKGgPk=
|
||||
github.com/satori/go.uuid v1.2.0 h1:0uYX9dsZ2yD7q2RtLRtPSdGDWzjeM3TbMJP9utgA0ww=
|
||||
github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0=
|
||||
github.com/shuffle/shuffle-shared v0.3.51 h1:+JPEGw6R4a320who+SrGP/VqBxZdKPdcLw/07cO7d6c=
|
||||
github.com/shuffle/shuffle-shared v0.3.51/go.mod h1:jQrYySmvp/0De5ftrAaY6xwwr7TMfqBmBxQ2AX9yrjQ=
|
||||
github.com/shuffle/shuffle-shared v0.3.74 h1:i7M1Gug9j2Wa02WuSxKDbXoLvBWKW5Pxf/EpFy6v38Y=
|
||||
github.com/shuffle/shuffle-shared v0.3.74/go.mod h1:jQrYySmvp/0De5ftrAaY6xwwr7TMfqBmBxQ2AX9yrjQ=
|
||||
github.com/shuffle/shuffle-shared v0.4.2 h1:GzDAOHN4YMMLzRmmToyO/KSYDziRuEuxLheawlAY3Rk=
|
||||
github.com/shuffle/shuffle-shared v0.4.2/go.mod h1:jQrYySmvp/0De5ftrAaY6xwwr7TMfqBmBxQ2AX9yrjQ=
|
||||
github.com/shuffle/shuffle-shared v0.4.9 h1:mGCaLcSbrsQCy26pJXPlZAtitEzEEwqotGNjnsvOM/U=
|
||||
github.com/shuffle/shuffle-shared v0.4.9/go.mod h1:jQrYySmvp/0De5ftrAaY6xwwr7TMfqBmBxQ2AX9yrjQ=
|
||||
github.com/shuffle/shuffle-shared v0.4.17 h1:56ll366bdmIJu/7GFqNC2XTjjl0SGBf430PSq+EB6Ro=
|
||||
github.com/shuffle/shuffle-shared v0.4.17/go.mod h1:jQrYySmvp/0De5ftrAaY6xwwr7TMfqBmBxQ2AX9yrjQ=
|
||||
github.com/skip2/go-qrcode v0.0.0-20200617195104-da1b6568686e h1:MRM5ITcdelLK2j1vwZ3Je0FKVCfqOLp5zO6trqMLYs0=
|
||||
@@ -254,8 +246,8 @@ golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8U
|
||||
golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519 h1:7I4JAnoQBe7ZtJcBaYHi5UtiO8tQHbUSXxL+pnGRANg=
|
||||
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
||||
golang.org/x/crypto v0.1.0 h1:MDRAIl0xIo9Io2xV565hzXHw3zVseKrJKodhohM5CjU=
|
||||
golang.org/x/crypto v0.1.0/go.mod h1:RecgLatLF4+eUMCP1PoPZQb+cVrJcOPbHkTkbkB9sbw=
|
||||
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||
golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||
golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=
|
||||
@@ -322,8 +314,8 @@ golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwY
|
||||
golang.org/x/net v0.0.0-20201031054903-ff519b6c9102/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
|
||||
golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
|
||||
golang.org/x/net v0.0.0-20201224014010-6772e930b67b/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
||||
golang.org/x/net v0.0.0-20221014081412-f15817d10f9b h1:tvrvnPFcdzp294diPnrdZZZ8XUt2Tyj7svb7X52iDuU=
|
||||
golang.org/x/net v0.0.0-20221014081412-f15817d10f9b/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk=
|
||||
golang.org/x/net v0.7.0 h1:rJrUqqhjsgNp7KqAIc25s9pZnjU7TUcSY7HcVZjdn1g=
|
||||
golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
|
||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||
@@ -375,8 +367,8 @@ golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7w
|
||||
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20201201145000-ef89a241ccb3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.1.0 h1:kunALQeHf1/185U1i0GOB/fy1IPRDDpuoOOqRReG57U=
|
||||
golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.5.0 h1:MUK/U/4lj1t1oPg0HfuXDN/Z1wv31ZJ/YcPiGccS4DU=
|
||||
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
@@ -384,8 +376,8 @@ golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3
|
||||
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
|
||||
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.5.0 h1:OLmvp0KP+FVG99Ct/qFiL/Fhk4zp4QQnZ7b2U+5piUM=
|
||||
golang.org/x/text v0.5.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
|
||||
golang.org/x/text v0.7.0 h1:4BRB4x83lYWy72KwLD/qYDuTu7q9PjSagHvijDw7cLo=
|
||||
golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
|
||||
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/time v0.0.0-20191024005414-555d28b269f0 h1:/5xXl8Y5W96D+TtHSlonuFqGHIWVuyCkGJLwGh9JJFs=
|
||||
|
||||
@@ -36,6 +36,16 @@ import (
|
||||
// No necessary outside shared
|
||||
"cloud.google.com/go/datastore"
|
||||
"cloud.google.com/go/storage"
|
||||
|
||||
//k8s deps
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/client-go/kubernetes"
|
||||
"k8s.io/client-go/rest"
|
||||
"k8s.io/client-go/tools/clientcmd"
|
||||
"k8s.io/client-go/util/homedir"
|
||||
"path/filepath"
|
||||
// "k8s.io/client-go/util/retry"
|
||||
)
|
||||
|
||||
// This is getting out of hand :)
|
||||
@@ -171,111 +181,266 @@ func shutdown(workflowExecution shuffle.WorkflowExecution, nodeId string, reason
|
||||
os.Exit(3)
|
||||
}
|
||||
|
||||
// }
|
||||
|
||||
func isRunningInCluster() bool {
|
||||
_, existsHost := os.LookupEnv("KUBERNETES_SERVICE_HOST")
|
||||
_, existsPort := os.LookupEnv("KUBERNETES_SERVICE_PORT")
|
||||
return existsHost && existsPort
|
||||
}
|
||||
|
||||
func buildEnvVars(envMap map[string]string) []corev1.EnvVar {
|
||||
var envVars []corev1.EnvVar
|
||||
for key, value := range envMap {
|
||||
envVars = append(envVars, corev1.EnvVar{Name: key, Value: value})
|
||||
}
|
||||
return envVars
|
||||
}
|
||||
|
||||
func getKubernetesClient() (*kubernetes.Clientset, error) {
|
||||
if isRunningInCluster() {
|
||||
config, err := rest.InClusterConfig()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
clientset, err := kubernetes.NewForConfig(config)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return clientset, nil
|
||||
} else {
|
||||
home := homedir.HomeDir()
|
||||
kubeconfigPath := filepath.Join(home, ".kube", "config")
|
||||
config, err := clientcmd.BuildConfigFromFlags("", kubeconfigPath)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
clientset, err := kubernetes.NewForConfig(config)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return clientset, nil
|
||||
}
|
||||
}
|
||||
|
||||
// Deploys the internal worker whenever something happens
|
||||
func deployApp(cli *dockerclient.Client, image string, identifier string, env []string, workflowExecution shuffle.WorkflowExecution, action shuffle.Action) error {
|
||||
// form basic hostConfig
|
||||
ctx := context.Background()
|
||||
log.Printf("################################### new call to deployApp ###################################")
|
||||
log.Printf("image: %s", image)
|
||||
log.Printf("identifier: %s", identifier)
|
||||
// log.Printf("execution: %+v", workflowExecution)
|
||||
|
||||
if action.AppName == "shuffle-subflow" {
|
||||
// Automatic replacement of URL
|
||||
for paramIndex, param := range action.Parameters {
|
||||
if param.Name != "backend_url" {
|
||||
continue
|
||||
}
|
||||
if os.Getenv("IS_KUBERNETES") == "true" {
|
||||
|
||||
if strings.Contains(param.Value, "shuffle-backend") {
|
||||
// Automatic replacement as this is default
|
||||
action.Parameters[paramIndex].Value = os.Getenv("BASE_URL")
|
||||
log.Printf("[DEBUG][%s] Replaced backend_url with %s", workflowExecution.ExecutionId, os.Getenv("BASE_URL"))
|
||||
namespace := "shuffle"
|
||||
localRegistry := os.Getenv("REGISTRY_URL")
|
||||
|
||||
envMap := make(map[string]string)
|
||||
for _, envStr := range env {
|
||||
parts := strings.SplitN(envStr, "=", 2)
|
||||
if len(parts) == 2 {
|
||||
envMap[parts[0]] = parts[1]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Max 10% CPU every second
|
||||
//CPUShares: 128,
|
||||
//CPUQuota: 10000,
|
||||
//CPUPeriod: 100000,
|
||||
hostConfig := &container.HostConfig{
|
||||
LogConfig: container.LogConfig{
|
||||
Type: "json-file",
|
||||
Config: map[string]string{
|
||||
"max-size": "10m",
|
||||
clientset, err := getKubernetesClient()
|
||||
if err != nil {
|
||||
fmt.Println("[ERROR]Error getting kubernetes client:", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
log.Printf("[DEBUG] Got kubernetes client")
|
||||
str := strings.ToLower(identifier)
|
||||
strSplit := strings.Split(str, "_")
|
||||
value := strSplit[0]
|
||||
value = strings.ReplaceAll(value, "_", "-")
|
||||
|
||||
// checking if app is generated or not
|
||||
appDetails := strings.Split(image, ":")[1]
|
||||
appDetailsSplit := strings.Split(appDetails, "_")
|
||||
appName := strings.Join(appDetailsSplit[:len(appDetailsSplit)-1], "_")
|
||||
appVersion := appDetailsSplit[len(appDetailsSplit)-1]
|
||||
|
||||
log.Printf("APP VERSION IS: %s", appVersion)
|
||||
|
||||
for _, app := range workflowExecution.Workflow.Actions {
|
||||
log.Printf("[DEBUG] App: %s, Version: %s", appName, appVersion)
|
||||
log.Printf("[DEBUG] Checking app %s with version %s", app.AppName, app.AppVersion)
|
||||
if app.AppName == appName && app.AppVersion == appVersion {
|
||||
if app.Generated == true {
|
||||
log.Printf("[DEBUG] Generated app, setting local registry")
|
||||
image = fmt.Sprintf("%s/%s", localRegistry, image)
|
||||
break
|
||||
} else {
|
||||
log.Printf("[DEBUG] Not generated app, setting shuffle registry")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//fix naming convention
|
||||
podUuid := uuid.NewV4().String()
|
||||
podName := fmt.Sprintf("%s-%s", value, podUuid)
|
||||
|
||||
pod := &corev1.Pod{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: podName,
|
||||
Labels: map[string]string{
|
||||
"app": "shuffle-app",
|
||||
"executionId": workflowExecution.ExecutionId,
|
||||
},
|
||||
},
|
||||
Spec: corev1.PodSpec{
|
||||
NodeName: "worker1", // change this in prod
|
||||
RestartPolicy: "Never",
|
||||
Containers: []corev1.Container{
|
||||
{
|
||||
Name: value,
|
||||
Image: image,
|
||||
Env: buildEnvVars(envMap),
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
Resources: container.Resources{},
|
||||
}
|
||||
|
||||
hostConfig.NetworkMode = container.NetworkMode(fmt.Sprintf("container:worker-%s", workflowExecution.ExecutionId))
|
||||
|
||||
// Removing because log extraction should happen first
|
||||
if cleanupEnv == "true" {
|
||||
hostConfig.AutoRemove = true
|
||||
}
|
||||
|
||||
// FIXME: Add proper foldermounts here
|
||||
//log.Printf("\n\nPRE FOLDERMOUNT\n\n")
|
||||
//volumeBinds := []string{"/tmp/shuffle-mount:/rules"}
|
||||
//volumeBinds := []string{"/tmp/shuffle-mount:/rules"}
|
||||
volumeBinds := []string{}
|
||||
if len(volumeBinds) > 0 {
|
||||
log.Printf("[DEBUG] Setting up binds for container!")
|
||||
hostConfig.Binds = volumeBinds
|
||||
hostConfig.Mounts = []mount.Mount{}
|
||||
for _, bind := range volumeBinds {
|
||||
if !strings.Contains(bind, ":") || strings.Contains(bind, "..") || strings.HasPrefix(bind, "~") {
|
||||
log.Printf("[WARNING] Bind %s is invalid.", bind)
|
||||
continue
|
||||
}
|
||||
|
||||
log.Printf("[DEBUG] Appending bind %s", bind)
|
||||
bindSplit := strings.Split(bind, ":")
|
||||
sourceFolder := bindSplit[0]
|
||||
destinationFolder := bindSplit[0]
|
||||
hostConfig.Mounts = append(hostConfig.Mounts, mount.Mount{
|
||||
Type: mount.TypeBind,
|
||||
Source: sourceFolder,
|
||||
Target: destinationFolder,
|
||||
})
|
||||
}
|
||||
|
||||
createdPod, err := clientset.CoreV1().Pods(namespace).Create(context.Background(), pod, metav1.CreateOptions{})
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "Error creating pod: %v\n", err)
|
||||
// os.Exit(1)
|
||||
}
|
||||
fmt.Printf("[DEBUG] Created pod %q in namespace %q\n", createdPod.Name, createdPod.Namespace)
|
||||
} else {
|
||||
//log.Printf("[WARNING] Not mounting folders")
|
||||
}
|
||||
// form basic hostConfig
|
||||
ctx := context.Background()
|
||||
|
||||
config := &container.Config{
|
||||
Image: image,
|
||||
Env: env,
|
||||
}
|
||||
if action.AppName == "shuffle-subflow" {
|
||||
// Automatic replacement of URL
|
||||
for paramIndex, param := range action.Parameters {
|
||||
if param.Name != "backend_url" {
|
||||
continue
|
||||
}
|
||||
|
||||
// Checking as late as possible, just in case.
|
||||
newExecId := fmt.Sprintf("%s_%s", workflowExecution.ExecutionId, action.ID)
|
||||
_, err := shuffle.GetCache(ctx, newExecId)
|
||||
if err == nil {
|
||||
log.Printf("\n\n[DEBUG] Result for %s already found - returning\n\n", newExecId)
|
||||
if strings.Contains(param.Value, "shuffle-backend") {
|
||||
// Automatic replacement as this is default
|
||||
action.Parameters[paramIndex].Value = os.Getenv("BASE_URL")
|
||||
log.Printf("[DEBUG][%s] Replaced backend_url with %s", workflowExecution.ExecutionId, os.Getenv("BASE_URL"))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Max 10% CPU every second
|
||||
//CPUShares: 128,
|
||||
//CPUQuota: 10000,
|
||||
//CPUPeriod: 100000,
|
||||
hostConfig := &container.HostConfig{
|
||||
LogConfig: container.LogConfig{
|
||||
Type: "json-file",
|
||||
Config: map[string]string{
|
||||
"max-size": "10m",
|
||||
},
|
||||
},
|
||||
Resources: container.Resources{},
|
||||
}
|
||||
|
||||
hostConfig.NetworkMode = container.NetworkMode(fmt.Sprintf("container:worker-%s", workflowExecution.ExecutionId))
|
||||
|
||||
// Removing because log extraction should happen first
|
||||
if cleanupEnv == "true" {
|
||||
hostConfig.AutoRemove = true
|
||||
}
|
||||
|
||||
// FIXME: Add proper foldermounts here
|
||||
//log.Printf("\n\nPRE FOLDERMOUNT\n\n")
|
||||
//volumeBinds := []string{"/tmp/shuffle-mount:/rules"}
|
||||
//volumeBinds := []string{"/tmp/shuffle-mount:/rules"}
|
||||
volumeBinds := []string{}
|
||||
if len(volumeBinds) > 0 {
|
||||
log.Printf("[DEBUG] Setting up binds for container!")
|
||||
hostConfig.Binds = volumeBinds
|
||||
hostConfig.Mounts = []mount.Mount{}
|
||||
for _, bind := range volumeBinds {
|
||||
if !strings.Contains(bind, ":") || strings.Contains(bind, "..") || strings.HasPrefix(bind, "~") {
|
||||
log.Printf("[WARNING] Bind %s is invalid.", bind)
|
||||
continue
|
||||
}
|
||||
|
||||
log.Printf("[DEBUG] Appending bind %s", bind)
|
||||
bindSplit := strings.Split(bind, ":")
|
||||
sourceFolder := bindSplit[0]
|
||||
destinationFolder := bindSplit[0]
|
||||
hostConfig.Mounts = append(hostConfig.Mounts, mount.Mount{
|
||||
Type: mount.TypeBind,
|
||||
Source: sourceFolder,
|
||||
Target: destinationFolder,
|
||||
})
|
||||
}
|
||||
} else {
|
||||
//log.Printf("[WARNING] Not mounting folders")
|
||||
}
|
||||
|
||||
config := &container.Config{
|
||||
Image: image,
|
||||
Env: env,
|
||||
}
|
||||
|
||||
// Checking as late as possible, just in case.
|
||||
newExecId := fmt.Sprintf("%s_%s", workflowExecution.ExecutionId, action.ID)
|
||||
_, err := shuffle.GetCache(ctx, newExecId)
|
||||
if err == nil {
|
||||
log.Printf("\n\n[DEBUG] Result for %s already found - returning\n\n", newExecId)
|
||||
return nil
|
||||
}
|
||||
|
||||
cacheData := []byte("1")
|
||||
err = shuffle.SetCache(ctx, newExecId, cacheData, 30)
|
||||
if err != nil {
|
||||
log.Printf("[WARNING] Failed setting cache for action %s: %s", newExecId, err)
|
||||
} else {
|
||||
log.Printf("[DEBUG] Adding %s to cache. Name: %s", newExecId, action.Name)
|
||||
}
|
||||
|
||||
if action.ExecutionDelay > 0 {
|
||||
log.Printf("[DEBUG] Running app %s in docker with delay of %d", action.Name, action.ExecutionDelay)
|
||||
waitTime := time.Duration(action.ExecutionDelay) * time.Second
|
||||
|
||||
time.AfterFunc(waitTime, func() {
|
||||
DeployContainer(ctx, cli, config, hostConfig, identifier, workflowExecution, newExecId)
|
||||
})
|
||||
} else {
|
||||
log.Printf("[DEBUG] Running app %s in docker NORMALLY as there is no delay set with identifier %s", action.Name, identifier)
|
||||
returnvalue := DeployContainer(ctx, cli, config, hostConfig, identifier, workflowExecution, newExecId)
|
||||
log.Printf("[DEBUG] Normal deploy ret: %s", returnvalue)
|
||||
return returnvalue
|
||||
}
|
||||
return nil
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
cacheData := []byte("1")
|
||||
err = shuffle.SetCache(ctx, newExecId, cacheData, 30)
|
||||
func cleanupExecution(clientset *kubernetes.Clientset, workflowExecution shuffle.WorkflowExecution, namespace string) error {
|
||||
|
||||
workerName := fmt.Sprintf("worker-%s", workflowExecution.ExecutionId)
|
||||
labelSelector := fmt.Sprintf("app=shuffle-app,executionId=%s", workflowExecution.ExecutionId)
|
||||
|
||||
podList, err := clientset.CoreV1().Pods(namespace).List(context.TODO(), metav1.ListOptions{
|
||||
LabelSelector: labelSelector,
|
||||
})
|
||||
if err != nil {
|
||||
log.Printf("[WARNING] Failed setting cache for action %s: %s", newExecId, err)
|
||||
} else {
|
||||
log.Printf("[DEBUG] Adding %s to cache. Name: %s", newExecId, action.Name)
|
||||
return fmt.Errorf("[ERROR]failed to list apps with label selector %s: %v", labelSelector, err)
|
||||
}
|
||||
|
||||
if action.ExecutionDelay > 0 {
|
||||
log.Printf("[DEBUG] Running app %s in docker with delay of %d", action.Name, action.ExecutionDelay)
|
||||
waitTime := time.Duration(action.ExecutionDelay) * time.Second
|
||||
|
||||
time.AfterFunc(waitTime, func() {
|
||||
DeployContainer(ctx, cli, config, hostConfig, identifier, workflowExecution, newExecId)
|
||||
})
|
||||
} else {
|
||||
log.Printf("[DEBUG] Running app %s in docker NORMALLY as there is no delay set with identifier %s", action.Name, identifier)
|
||||
returnvalue := DeployContainer(ctx, cli, config, hostConfig, identifier, workflowExecution, newExecId)
|
||||
log.Printf("[DEBUG] Normal deploy ret: %s", returnvalue)
|
||||
return returnvalue
|
||||
for _, pod := range podList.Items {
|
||||
err := clientset.CoreV1().Pods(namespace).Delete(context.TODO(), pod.Name, metav1.DeleteOptions{})
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to delete app %s: %v", pod.Name, err)
|
||||
}
|
||||
fmt.Printf("App %s in namespace %s deleted.\n", pod.Name, namespace)
|
||||
}
|
||||
|
||||
podErr := clientset.CoreV1().Pods(namespace).Delete(context.TODO(), workerName, metav1.DeleteOptions{})
|
||||
if podErr != nil {
|
||||
return fmt.Errorf("[ERROR] failed to delete the worker %s in namespace %s: %v", workerName, namespace, podErr)
|
||||
}
|
||||
fmt.Printf("[DEBUG] %s in namespace %s deleted.\n", workerName, namespace)
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -869,7 +1034,17 @@ func handleExecutionResult(workflowExecution shuffle.WorkflowExecution) {
|
||||
log.Printf("[INFO][%s] BREAKING BECAUSE RESULTS IS SAME LENGTH AS ACTIONS. SHOULD CHECK ALL RESULTS FOR WHETHER THEY'RE DONE", workflowExecution.ExecutionId)
|
||||
validateFinished(workflowExecution)
|
||||
log.Printf("[DEBUG][%s] Shutting down (17)", workflowExecution.ExecutionId)
|
||||
shutdown(workflowExecution, "", "", true)
|
||||
if os.Getenv("IS_KUBERNETES") == "true" {
|
||||
// log.Printf("workflow execution: %#v", workflowExecution)
|
||||
clientset, err := getKubernetesClient()
|
||||
if err != nil {
|
||||
fmt.Println("[ERROR]Error getting kubernetes client:", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
cleanupExecution(clientset, workflowExecution, "shuffle")
|
||||
} else {
|
||||
shutdown(workflowExecution, "", "", true)
|
||||
}
|
||||
return
|
||||
}
|
||||
}
|
||||
@@ -1086,14 +1261,35 @@ func handleDefaultExecution(client *http.Client, req *http.Request, workflowExec
|
||||
if workflowExecution.Status == "FINISHED" || workflowExecution.Status == "SUCCESS" {
|
||||
log.Printf("[INFO][%s] Workflow execution is finished. Exiting worker.", workflowExecution.ExecutionId)
|
||||
log.Printf("[DEBUG] Shutting down (20)")
|
||||
shutdown(workflowExecution, "", "", true)
|
||||
//handle workerssssssssss
|
||||
if os.Getenv("IS_KUBERNETES") == "true" {
|
||||
// log.Printf("workflow execution: %#v", workflowExecution)
|
||||
clientset, err := getKubernetesClient()
|
||||
if err != nil {
|
||||
fmt.Println("[ERROR]Error getting kubernetes client:", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
cleanupExecution(clientset, workflowExecution, "shuffle")
|
||||
} else {
|
||||
shutdown(workflowExecution, "", "", true)
|
||||
}
|
||||
}
|
||||
|
||||
log.Printf("[INFO][%s] Status: %s, Results: %d, actions: %d", workflowExecution.ExecutionId, workflowExecution.Status, len(workflowExecution.Results), len(workflowExecution.Workflow.Actions)+extra)
|
||||
if workflowExecution.Status != "EXECUTING" {
|
||||
log.Printf("[WARNING][%s] Exiting as worker execution has status %s!", workflowExecution.ExecutionId, workflowExecution.Status)
|
||||
log.Printf("[DEBUG] Shutting down (21)")
|
||||
shutdown(workflowExecution, "", "", true)
|
||||
if os.Getenv("IS_KUBERNETES") == "true" {
|
||||
// log.Printf("workflow execution: %#v", workflowExecution)
|
||||
clientset, err := getKubernetesClient()
|
||||
if err != nil {
|
||||
fmt.Println("[ERROR]Error getting kubernetes client:", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
cleanupExecution(clientset, workflowExecution, "shuffle")
|
||||
} else {
|
||||
shutdown(workflowExecution, "", "", true)
|
||||
}
|
||||
}
|
||||
|
||||
setWorkflowExecution(ctx, workflowExecution, false)
|
||||
|
||||
Reference in New Issue
Block a user