Worker fix

This commit is contained in:
Frikky
2024-08-20 23:37:21 +02:00
parent fe2e3105eb
commit af14b76ac5
4 changed files with 689 additions and 383 deletions
+2
View File
@@ -465,6 +465,8 @@ github.com/shuffle/shuffle-shared v0.6.61 h1:+9CCLeZLiAVDgNRTkZxnIgz+FZ7UrEHez2B
github.com/shuffle/shuffle-shared v0.6.61/go.mod h1:RAJiSFjmuKmijKTbbEf9A6Ojb+3/te7g71lED7JjPus= github.com/shuffle/shuffle-shared v0.6.61/go.mod h1:RAJiSFjmuKmijKTbbEf9A6Ojb+3/te7g71lED7JjPus=
github.com/shuffle/shuffle-shared v0.6.62 h1:NWVjVbnNpm6osDHQS2NGqwAgWk1Fk3s5RKUO3P5n4js= github.com/shuffle/shuffle-shared v0.6.62 h1:NWVjVbnNpm6osDHQS2NGqwAgWk1Fk3s5RKUO3P5n4js=
github.com/shuffle/shuffle-shared v0.6.62/go.mod h1:RAJiSFjmuKmijKTbbEf9A6Ojb+3/te7g71lED7JjPus= github.com/shuffle/shuffle-shared v0.6.62/go.mod h1:RAJiSFjmuKmijKTbbEf9A6Ojb+3/te7g71lED7JjPus=
github.com/shuffle/shuffle-shared v0.6.63 h1:eNQMpVhe/mAMxl61W9Wj6/Z4PrtPeEnbjvMtDdT1mqw=
github.com/shuffle/shuffle-shared v0.6.63/go.mod h1:RAJiSFjmuKmijKTbbEf9A6Ojb+3/te7g71lED7JjPus=
github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0=
github.com/sirupsen/logrus v1.9.0/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= github.com/sirupsen/logrus v1.9.0/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=
github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ= github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ=
+7 -5
View File
@@ -7,9 +7,9 @@ require (
github.com/gorilla/mux v1.8.1 github.com/gorilla/mux v1.8.1
github.com/satori/go.uuid v1.2.0 github.com/satori/go.uuid v1.2.0
github.com/shuffle/shuffle-shared v0.6.63 github.com/shuffle/shuffle-shared v0.6.63
k8s.io/api v0.30.0 k8s.io/api v0.30.2
k8s.io/apimachinery v0.30.0 k8s.io/apimachinery v0.30.2
k8s.io/client-go v0.30.0 k8s.io/client-go v0.30.2
) )
require ( require (
@@ -27,7 +27,7 @@ require (
github.com/algolia/algoliasearch-client-go/v3 v3.18.1 // indirect github.com/algolia/algoliasearch-client-go/v3 v3.18.1 // indirect
github.com/bradfitz/gomemcache v0.0.0-20230905024940-24af94b03874 // indirect github.com/bradfitz/gomemcache v0.0.0-20230905024940-24af94b03874 // indirect
github.com/bradfitz/slice v0.0.0-20180809154707-2b758aa73013 // indirect github.com/bradfitz/slice v0.0.0-20180809154707-2b758aa73013 // indirect
github.com/cloudflare/circl v1.3.3 // indirect github.com/cloudflare/circl v1.3.7 // indirect
github.com/containerd/log v0.1.0 // indirect github.com/containerd/log v0.1.0 // indirect
github.com/cyphar/filepath-securejoin v0.2.4 // indirect github.com/cyphar/filepath-securejoin v0.2.4 // indirect
github.com/davecgh/go-spew v1.1.1 // indirect github.com/davecgh/go-spew v1.1.1 // indirect
@@ -38,7 +38,7 @@ require (
github.com/emirpasic/gods v1.18.1 // indirect github.com/emirpasic/gods v1.18.1 // indirect
github.com/felixge/httpsnoop v1.0.4 // indirect github.com/felixge/httpsnoop v1.0.4 // indirect
github.com/frikky/kin-openapi v0.41.0 // indirect github.com/frikky/kin-openapi v0.41.0 // indirect
github.com/frikky/schemaless v0.0.11 // indirect github.com/frikky/schemaless v0.0.13 // indirect
github.com/ghodss/yaml v1.0.0 // indirect github.com/ghodss/yaml v1.0.0 // indirect
github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376 // indirect github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376 // indirect
github.com/go-git/go-billy/v5 v5.5.0 // indirect github.com/go-git/go-billy/v5 v5.5.0 // indirect
@@ -79,6 +79,8 @@ require (
github.com/pjbgf/sha1cd v0.3.0 // indirect github.com/pjbgf/sha1cd v0.3.0 // indirect
github.com/pkg/errors v0.9.1 // indirect github.com/pkg/errors v0.9.1 // indirect
github.com/sashabaranov/go-openai v1.19.2 // indirect github.com/sashabaranov/go-openai v1.19.2 // indirect
github.com/sendgrid/rest v2.6.9+incompatible // indirect
github.com/sendgrid/sendgrid-go v3.14.0+incompatible // indirect
github.com/sergi/go-diff v1.1.0 // indirect github.com/sergi/go-diff v1.1.0 // indirect
github.com/skeema/knownhosts v1.2.1 // indirect github.com/skeema/knownhosts v1.2.1 // indirect
github.com/skip2/go-qrcode v0.0.0-20200617195104-da1b6568686e // indirect github.com/skip2/go-qrcode v0.0.0-20200617195104-da1b6568686e // indirect
+16
View File
@@ -97,6 +97,8 @@ github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMn
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
github.com/cloudflare/circl v1.3.3 h1:fE/Qz0QdIGqeWfnwq0RE0R7MI51s0M2E4Ga9kq5AEMs= github.com/cloudflare/circl v1.3.3 h1:fE/Qz0QdIGqeWfnwq0RE0R7MI51s0M2E4Ga9kq5AEMs=
github.com/cloudflare/circl v1.3.3/go.mod h1:5XYMA4rFBvNIrhs50XuiBJ15vF2pZn4nnUKZrLbUZFA= github.com/cloudflare/circl v1.3.3/go.mod h1:5XYMA4rFBvNIrhs50XuiBJ15vF2pZn4nnUKZrLbUZFA=
github.com/cloudflare/circl v1.3.7 h1:qlCDlTPz2n9fu58M0Nh1J/JzcFpfgkFHHX3O35r5vcU=
github.com/cloudflare/circl v1.3.7/go.mod h1:sRTcRWXGLrKw6yIGJ+l7amYJFfAXbZG0kBSc8r4zxgA=
github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=
github.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= github.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk=
github.com/cncf/xds/go v0.0.0-20231128003011-0fa0005c9caa h1:jQCWAUqqlij9Pgj2i/PB79y4KOPYVyFYdROxgaCwdTQ= github.com/cncf/xds/go v0.0.0-20231128003011-0fa0005c9caa h1:jQCWAUqqlij9Pgj2i/PB79y4KOPYVyFYdROxgaCwdTQ=
@@ -139,6 +141,8 @@ github.com/frikky/schemaless v0.0.9 h1:RzNLPkJq5c4nlm5iLiTndFcbeQxdMGJIj266wSGt2
github.com/frikky/schemaless v0.0.9/go.mod h1:mooDxY+D6weHjhKvjy3+IE9S7P4g4cpNnidkdRv/cHQ= github.com/frikky/schemaless v0.0.9/go.mod h1:mooDxY+D6weHjhKvjy3+IE9S7P4g4cpNnidkdRv/cHQ=
github.com/frikky/schemaless v0.0.11 h1:c4r6CJX30XI+SoJdT9RlUd9qYSQlx6hvwGRtsypu+uM= github.com/frikky/schemaless v0.0.11 h1:c4r6CJX30XI+SoJdT9RlUd9qYSQlx6hvwGRtsypu+uM=
github.com/frikky/schemaless v0.0.11/go.mod h1:mooDxY+D6weHjhKvjy3+IE9S7P4g4cpNnidkdRv/cHQ= github.com/frikky/schemaless v0.0.11/go.mod h1:mooDxY+D6weHjhKvjy3+IE9S7P4g4cpNnidkdRv/cHQ=
github.com/frikky/schemaless v0.0.13 h1:ARiN9V7wr2VZXAr9JK5wvTbyPgpGrgeiL1VhR5MlgaQ=
github.com/frikky/schemaless v0.0.13/go.mod h1:mooDxY+D6weHjhKvjy3+IE9S7P4g4cpNnidkdRv/cHQ=
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ=
github.com/ghodss/yaml v1.0.0 h1:wQHKEahhL6wmXdzwWG11gIVCkOv05bNOh+Rxn0yngAk= github.com/ghodss/yaml v1.0.0 h1:wQHKEahhL6wmXdzwWG11gIVCkOv05bNOh+Rxn0yngAk=
@@ -387,12 +391,18 @@ github.com/sashabaranov/go-openai v1.19.2 h1:+dkuCADSnwXV02YVJkdphY8XD9AyHLUWwk6
github.com/sashabaranov/go-openai v1.19.2/go.mod h1:lj5b/K+zjTSFxVLijLSTDZuP7adOgerWeFyZLUhAKRg= github.com/sashabaranov/go-openai v1.19.2/go.mod h1:lj5b/K+zjTSFxVLijLSTDZuP7adOgerWeFyZLUhAKRg=
github.com/satori/go.uuid v1.2.0 h1:0uYX9dsZ2yD7q2RtLRtPSdGDWzjeM3TbMJP9utgA0ww= github.com/satori/go.uuid v1.2.0 h1:0uYX9dsZ2yD7q2RtLRtPSdGDWzjeM3TbMJP9utgA0ww=
github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0= github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0=
github.com/sendgrid/rest v2.6.9+incompatible h1:1EyIcsNdn9KIisLW50MKwmSRSK+ekueiEMJ7NEoxJo0=
github.com/sendgrid/rest v2.6.9+incompatible/go.mod h1:kXX7q3jZtJXK5c5qK83bSGMdV6tsOE70KbHoqJls4lE=
github.com/sendgrid/sendgrid-go v3.14.0+incompatible h1:KDSasSTktAqMJCYClHVE94Fcif2i7P7wzISv1sU6DUA=
github.com/sendgrid/sendgrid-go v3.14.0+incompatible/go.mod h1:QRQt+LX/NmgVEvmdRw0VT/QgUn499+iza2FnDca9fg8=
github.com/sergi/go-diff v1.1.0 h1:we8PVUC3FE2uYfodKH/nBHMSetSfHDR6scGdBi+erh0= github.com/sergi/go-diff v1.1.0 h1:we8PVUC3FE2uYfodKH/nBHMSetSfHDR6scGdBi+erh0=
github.com/sergi/go-diff v1.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM= github.com/sergi/go-diff v1.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM=
github.com/shuffle/shuffle-shared v0.6.16 h1:dQBDRmb2Wgl3pEuewqjDvN6v6nUKr+1EvGSEja9zG6s= github.com/shuffle/shuffle-shared v0.6.16 h1:dQBDRmb2Wgl3pEuewqjDvN6v6nUKr+1EvGSEja9zG6s=
github.com/shuffle/shuffle-shared v0.6.16/go.mod h1:HhQTn7xZZ69ZTc4EptO9OeNmgbKDyGlWAhFkUFUAHSA= github.com/shuffle/shuffle-shared v0.6.16/go.mod h1:HhQTn7xZZ69ZTc4EptO9OeNmgbKDyGlWAhFkUFUAHSA=
github.com/shuffle/shuffle-shared v0.6.27 h1:q4qZD6bGZFIvZ5Y10unGr3N3rZ7OryWyvvaGgANZJZU= github.com/shuffle/shuffle-shared v0.6.27 h1:q4qZD6bGZFIvZ5Y10unGr3N3rZ7OryWyvvaGgANZJZU=
github.com/shuffle/shuffle-shared v0.6.27/go.mod h1:rWkh1eWdIx7OqQzJ1+JzF3Hck1X/Ty1WkUtjLrp+CU4= github.com/shuffle/shuffle-shared v0.6.27/go.mod h1:rWkh1eWdIx7OqQzJ1+JzF3Hck1X/Ty1WkUtjLrp+CU4=
github.com/shuffle/shuffle-shared v0.6.63 h1:eNQMpVhe/mAMxl61W9Wj6/Z4PrtPeEnbjvMtDdT1mqw=
github.com/shuffle/shuffle-shared v0.6.63/go.mod h1:RAJiSFjmuKmijKTbbEf9A6Ojb+3/te7g71lED7JjPus=
github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0=
github.com/sirupsen/logrus v1.9.0/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= github.com/sirupsen/logrus v1.9.0/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=
github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ= github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ=
@@ -906,10 +916,16 @@ honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9
honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
k8s.io/api v0.30.0 h1:siWhRq7cNjy2iHssOB9SCGNCl2spiF1dO3dABqZ8niA= k8s.io/api v0.30.0 h1:siWhRq7cNjy2iHssOB9SCGNCl2spiF1dO3dABqZ8niA=
k8s.io/api v0.30.0/go.mod h1:OPlaYhoHs8EQ1ql0R/TsUgaRPhpKNxIMrKQfWUp8QSE= k8s.io/api v0.30.0/go.mod h1:OPlaYhoHs8EQ1ql0R/TsUgaRPhpKNxIMrKQfWUp8QSE=
k8s.io/api v0.30.2 h1:+ZhRj+28QT4UOH+BKznu4CBgPWgkXO7XAvMcMl0qKvI=
k8s.io/api v0.30.2/go.mod h1:ULg5g9JvOev2dG0u2hig4Z7tQ2hHIuS+m8MNZ+X6EmI=
k8s.io/apimachinery v0.30.0 h1:qxVPsyDM5XS96NIh9Oj6LavoVFYff/Pon9cZeDIkHHA= k8s.io/apimachinery v0.30.0 h1:qxVPsyDM5XS96NIh9Oj6LavoVFYff/Pon9cZeDIkHHA=
k8s.io/apimachinery v0.30.0/go.mod h1:iexa2somDaxdnj7bha06bhb43Zpa6eWH8N8dbqVjTUc= k8s.io/apimachinery v0.30.0/go.mod h1:iexa2somDaxdnj7bha06bhb43Zpa6eWH8N8dbqVjTUc=
k8s.io/apimachinery v0.30.2 h1:fEMcnBj6qkzzPGSVsAZtQThU62SmQ4ZymlXRC5yFSCg=
k8s.io/apimachinery v0.30.2/go.mod h1:iexa2somDaxdnj7bha06bhb43Zpa6eWH8N8dbqVjTUc=
k8s.io/client-go v0.30.0 h1:sB1AGGlhY/o7KCyCEQ0bPWzYDL0pwOZO4vAtTSh/gJQ= k8s.io/client-go v0.30.0 h1:sB1AGGlhY/o7KCyCEQ0bPWzYDL0pwOZO4vAtTSh/gJQ=
k8s.io/client-go v0.30.0/go.mod h1:g7li5O5256qe6TYdAMyX/otJqMhIiGgTapdLchhmOaY= k8s.io/client-go v0.30.0/go.mod h1:g7li5O5256qe6TYdAMyX/otJqMhIiGgTapdLchhmOaY=
k8s.io/client-go v0.30.2 h1:sBIVJdojUNPDU/jObC+18tXWcTJVcwyqS9diGdWHk50=
k8s.io/client-go v0.30.2/go.mod h1:JglKSWULm9xlJLx4KCkfLLQ7XwtlbflV6uFFSHTMgVs=
k8s.io/klog/v2 v2.120.1 h1:QXU6cPEOIslTGvZaXvFWiP9VKyeet3sawzTOvdXb4Vw= k8s.io/klog/v2 v2.120.1 h1:QXU6cPEOIslTGvZaXvFWiP9VKyeet3sawzTOvdXb4Vw=
k8s.io/klog/v2 v2.120.1/go.mod h1:3Jpz1GvMt720eyJH1ckRHK1EDfpxISzJ7I9OYgaDtPE= k8s.io/klog/v2 v2.120.1/go.mod h1:3Jpz1GvMt720eyJH1ckRHK1EDfpxISzJ7I9OYgaDtPE=
k8s.io/kube-openapi v0.0.0-20240228011516-70dd3763d340 h1:BZqlfIlq5YbRMFko6/PM7FjZpUb45WallggurYhKGag= k8s.io/kube-openapi v0.0.0-20240228011516-70dd3763d340 h1:BZqlfIlq5YbRMFko6/PM7FjZpUb45WallggurYhKGag=
+346 -60
View File
@@ -3,7 +3,6 @@ package main
import ( import (
"github.com/shuffle/shuffle-shared" "github.com/shuffle/shuffle-shared"
"bytes" "bytes"
"context" "context"
"encoding/json" "encoding/json"
@@ -22,18 +21,21 @@ import (
"time" "time"
"github.com/docker/docker/api/types" "github.com/docker/docker/api/types"
"github.com/docker/docker/api/types/filters"
"github.com/docker/docker/api/types/container" "github.com/docker/docker/api/types/container"
"github.com/docker/docker/api/types/filters"
"github.com/docker/docker/api/types/mount" "github.com/docker/docker/api/types/mount"
dockerclient "github.com/docker/docker/client" dockerclient "github.com/docker/docker/client"
// This is for automatic removal of certain code :) // This is for automatic removal of certain code :)
"github.com/gorilla/mux" "github.com/gorilla/mux"
"github.com/satori/go.uuid" uuid "github.com/satori/go.uuid"
//k8s deps //k8s deps
corev1 "k8s.io/api/core/v1" corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
appsv1 "k8s.io/api/apps/v1"
"k8s.io/apimachinery/pkg/util/intstr"
"k8s.io/client-go/kubernetes" "k8s.io/client-go/kubernetes"
) )
@@ -77,6 +79,7 @@ var startAction string
//var allLogs map[string]string //var allLogs map[string]string
//var containerIds []string //var containerIds []string
var downloadedImages []string var downloadedImages []string
type ImageDownloadBody struct { type ImageDownloadBody struct {
Image string `json:"image"` Image string `json:"image"`
} }
@@ -87,7 +90,7 @@ type ImageRequest struct {
var finishedExecutions []string var finishedExecutions []string
var imagesDistributed []string var imagesDistributed []string
var imagedownloadTimeout = time.Second * 300
// Images to be autodeployed in the latest version of Shuffle. // Images to be autodeployed in the latest version of Shuffle.
var autoDeploy = map[string]string{ var autoDeploy = map[string]string{
@@ -188,14 +191,12 @@ func setWorkflowExecution(ctx context.Context, workflowExecution shuffle.Workflo
} }
} }
for _, trigger := range workflowExecution.Workflow.Triggers { for _, trigger := range workflowExecution.Workflow.Triggers {
//log.Printf("[DEBUG] Found trigger %s", trigger.AppName) //log.Printf("[DEBUG] Found trigger %s", trigger.AppName)
if trigger.AppName != "User Input" && trigger.AppName != "Shuffle Workflow" && trigger.AppName != "shuffle-subflow" { if trigger.AppName != "User Input" && trigger.AppName != "Shuffle Workflow" && trigger.AppName != "shuffle-subflow" {
continue continue
} }
// check if it has wait for results in params // check if it has wait for results in params
wait := false wait := false
for _, param := range trigger.Parameters { for _, param := range trigger.Parameters {
@@ -249,7 +250,6 @@ func setWorkflowExecution(ctx context.Context, workflowExecution shuffle.Workflo
os.Exit(0) os.Exit(0)
} }
break break
} }
@@ -271,7 +271,6 @@ func setWorkflowExecution(ctx context.Context, workflowExecution shuffle.Workflo
return nil return nil
} }
// removes every container except itself (worker) // removes every container except itself (worker)
func shutdown(workflowExecution shuffle.WorkflowExecution, nodeId string, reason string, handleResultSend bool) { func shutdown(workflowExecution shuffle.WorkflowExecution, nodeId string, reason string, handleResultSend bool) {
log.Printf("[DEBUG][%s] Shutdown (%s) started with reason %#v. Result amount: %d. ResultsSent: %d, Send result: %#v, Parent: %#v", workflowExecution.ExecutionId, workflowExecution.Status, reason, len(workflowExecution.Results), requestsSent, handleResultSend, workflowExecution.ExecutionParent) log.Printf("[DEBUG][%s] Shutdown (%s) started with reason %#v. Result amount: %d. ResultsSent: %d, Send result: %#v, Parent: %#v", workflowExecution.ExecutionId, workflowExecution.Status, reason, len(workflowExecution.Results), requestsSent, handleResultSend, workflowExecution.ExecutionParent)
@@ -369,7 +368,7 @@ func shutdown(workflowExecution shuffle.WorkflowExecution, nodeId string, reason
//Finished shutdown (after %d seconds). ", sleepDuration) //Finished shutdown (after %d seconds). ", sleepDuration)
// Allows everything to finish in subprocesses (apps) // Allows everything to finish in subprocesses (apps)
if os.Getenv("SHUFFLE_SWARM_CONFIG") != "run" && os.Getenv("SHUFFLE_SWARM_CONFIG") != "swarm" { if os.Getenv("SHUFFLE_SWARM_CONFIG") != "run" && os.Getenv("SHUFFLE_SWARM_CONFIG") != "swarm" && isKubernetes != "true" {
time.Sleep(time.Duration(sleepDuration) * time.Second) time.Sleep(time.Duration(sleepDuration) * time.Second)
os.Exit(3) os.Exit(3)
} else { } else {
@@ -377,9 +376,10 @@ func shutdown(workflowExecution shuffle.WorkflowExecution, nodeId string, reason
} }
} }
// Deploys the internal worker whenever something happens func int32Ptr(i int32) *int32 { return &i }
func deployApp(cli *dockerclient.Client, image string, identifier string, env []string, workflowExecution shuffle.WorkflowExecution, action shuffle.Action) error {
if isKubernetes == "true" { // ** STARTREMOVE ***/
func deployk8sApp(image string, identifier string, env []string) error {
if len(os.Getenv("KUBERNETES_NAMESPACE")) > 0 { if len(os.Getenv("KUBERNETES_NAMESPACE")) > 0 {
kubernetesNamespace = os.Getenv("KUBERNETES_NAMESPACE") kubernetesNamespace = os.Getenv("KUBERNETES_NAMESPACE")
} else { } else {
@@ -394,16 +394,24 @@ func deployApp(cli *dockerclient.Client, image string, identifier string, env []
} }
} }
// add to env
// fmt.Sprintf("SHUFFLE_APP_EXPOSED_PORT=%d", deployport),
// fmt.Sprintf("SHUFFLE_SWARM_CONFIG=%s", os.Getenv("SHUFFLE_SWARM_CONFIG")),
envMap["SHUFFLE_APP_EXPOSED_PORT"] = "80"
envMap["SHUFFLE_SWARM_CONFIG"] = os.Getenv("SHUFFLE_SWARM_CONFIG")
envMap["BASE_URL"] = "http://shuffle-workers:33333"
clientset, _, err := shuffle.GetKubernetesClient() clientset, _, err := shuffle.GetKubernetesClient()
if err != nil { if err != nil {
log.Printf("[ERROR] Failed getting kubernetes: %s", err) log.Printf("[ERROR] Failed getting kubernetes: %s", err)
return err return err
} }
str := strings.ToLower(identifier) // str := strings.ToLower(identifier)
strSplit := strings.Split(str, "_") // strSplit := strings.Split(str, "_")
value := strSplit[0] // value := strSplit[0]
value = strings.ReplaceAll(value, "_", "-") // value = strings.ReplaceAll(value, "_", "-")
value := identifier
// Checking if app is generated or not // Checking if app is generated or not
localRegistry := os.Getenv("REGISTRY_URL") localRegistry := os.Getenv("REGISTRY_URL")
@@ -443,45 +451,260 @@ func deployApp(cli *dockerclient.Client, image string, identifier string, env []
log.Printf("[DEBUG] Got kubernetes with namespace %#v to run image '%s'", kubernetesNamespace, image) log.Printf("[DEBUG] Got kubernetes with namespace %#v to run image '%s'", kubernetesNamespace, image)
//fix naming convention //fix naming convention
podUuid := uuid.NewV4().String() // podUuid := uuid.NewV4().String()
podName := fmt.Sprintf("%s-%s", value, podUuid) // podName := fmt.Sprintf("%s-%s", value, podUuid)
// replace identifier "_" with "-"
podName := strings.ReplaceAll(identifier, "_", "-")
pod := &corev1.Pod{ // pod := &corev1.Pod{
// ObjectMeta: metav1.ObjectMeta{
// Name: podName,
// Labels: map[string]string{
// "app": podName,
// // "executionId": workflowExecution.ExecutionId,
// },
// },
// Spec: corev1.PodSpec{
// RestartPolicy: "Never", // As a crash is not useful in this context
// // DNSPolicy: "Default",
// DNSPolicy: corev1.DNSClusterFirst,
// // NodeName: "worker1"
// Containers: []corev1.Container{
// {
// Name: value,
// Image: image,
// Env: buildEnvVars(envMap),
// // Pull if not available
// ImagePullPolicy: corev1.PullIfNotPresent,
// },
// },
// },
// }
// createdPod, err := clientset.CoreV1().Pods(kubernetesNamespace).Create(context.Background(), pod, metav1.CreateOptions{})
// if err != nil {
// log.Printf("[ERROR] Failed creating pod: %v", err)
// // os.Exit(1)
// } else {
// log.Printf("[DEBUG] Created pod %#v in namespace %#v", createdPod.Name, kubernetesNamespace)
// }
// service := &corev1.Service{
// ObjectMeta: metav1.ObjectMeta{
// Name: identifier,
// },
// Spec: corev1.ServiceSpec{
// Selector: map[string]string{
// "app": podName,
// },
// Ports: []corev1.ServicePort{
// {
// Protocol: "TCP",
// Port: 80,
// TargetPort: intstr.FromInt(80),
// },
// },
// Type: corev1.ServiceTypeNodePort,
// },
// }
// _, err = clientset.CoreV1().Services(kubernetesNamespace).Create(context.TODO(), service, metav1.CreateOptions{})
// if err != nil {
// log.Printf("[ERROR] Failed creating service: %v", err)
// return err
// }
// use deployment instead of pod
// then expose a service similarly.
// number of replicas can be set to os.Getenv("SHUFFLE_SCALE_REPLICAS")
replicaNumberStr := os.Getenv("SHUFFLE_SCALE_REPLICAS")
replicaNumber := 1
if len(replicaNumberStr) > 0 {
tmpInt, err := strconv.Atoi(replicaNumberStr)
if err != nil {
log.Printf("[ERROR] %s is not a valid number for replication", replicaNumberStr)
} else {
replicaNumber = tmpInt
}
}
replicaNumberInt32 := int32(replicaNumber)
deployment := &appsv1.Deployment{
ObjectMeta: metav1.ObjectMeta{ ObjectMeta: metav1.ObjectMeta{
Name: podName, Name: podName,
},
Spec: appsv1.DeploymentSpec{
Replicas: int32Ptr(replicaNumberInt32),
Selector: &metav1.LabelSelector{
MatchLabels: map[string]string{
"app": podName,
},
},
Template: corev1.PodTemplateSpec{
ObjectMeta: metav1.ObjectMeta{
Labels: map[string]string{ Labels: map[string]string{
"app": "shuffle-app", "app": podName,
"executionId": workflowExecution.ExecutionId,
}, },
}, },
Spec: corev1.PodSpec{ Spec: corev1.PodSpec{
RestartPolicy: "Never", // As a crash is not useful in this context
DNSPolicy: "Default",
// NodeName: "worker1"
Containers: []corev1.Container{ Containers: []corev1.Container{
{ {
Name: value, Name: value,
Image: image, Image: image,
Env: buildEnvVars(envMap), Env: buildEnvVars(envMap),
},
// Pull if not available },
ImagePullPolicy: corev1.PullIfNotPresent,
}, },
}, },
}, },
} }
createdPod, err := clientset.CoreV1().Pods(kubernetesNamespace).Create(context.Background(), pod, metav1.CreateOptions{}) _, err = clientset.AppsV1().Deployments(kubernetesNamespace).Create(context.Background(), deployment, metav1.CreateOptions{})
if err != nil { if err != nil {
log.Printf("[ERROR] Failed creating pod: %v", err) log.Printf("[ERROR] Failed creating deployment: %v", err)
// os.Exit(1) return err
} else { }
log.Printf("[DEBUG] Created pod %#v in namespace %#v", createdPod.Name, kubernetesNamespace)
// kubectl expose deployment {podName} --type=NodePort --port=80 --target-port=80
service := &corev1.Service{
ObjectMeta: metav1.ObjectMeta{
Name: podName,
},
Spec: corev1.ServiceSpec{
Selector: map[string]string{
"app": podName,
},
Ports: []corev1.ServicePort{
{
Protocol: "TCP",
Port: 80,
TargetPort: intstr.FromInt(80),
},
},
Type: corev1.ServiceTypeNodePort,
},
}
_, err = clientset.CoreV1().Services(kubernetesNamespace).Create(context.TODO(), service, metav1.CreateOptions{})
if err != nil {
log.Printf("[ERROR] Failed creating service: %v", err)
return err
} }
return nil return nil
} }
//** ENDREMOVE ***/
// 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 {
// if isKubernetes == "true" {
// if len(os.Getenv("KUBERNETES_NAMESPACE")) > 0 {
// kubernetesNamespace = os.Getenv("KUBERNETES_NAMESPACE")
// } else {
// kubernetesNamespace = "default"
// }
// envMap := make(map[string]string)
// for _, envStr := range env {
// parts := strings.SplitN(envStr, "=", 2)
// if len(parts) == 2 {
// envMap[parts[0]] = parts[1]
// }
// }
// clientset, _, err := shuffle.GetKubernetesClient()
// if err != nil {
// log.Printf("[ERROR] Failed getting kubernetes: %s", err)
// return err
// }
// str := strings.ToLower(identifier)
// strSplit := strings.Split(str, "_")
// value := strSplit[0]
// value = strings.ReplaceAll(value, "_", "-")
// // Checking if app is generated or not
// localRegistry := os.Getenv("REGISTRY_URL")
// /*
// appDetails := strings.Split(image, ":")[1]
// appDetailsSplit := strings.Split(appDetails, "_")
// appName := strings.Join(appDetailsSplit[:len(appDetailsSplit)-1], "_")
// appVersion := appDetailsSplit[len(appDetailsSplit)-1]
// 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")
// }
// }
// }
// */
// if len(localRegistry) == 0 && len(os.Getenv("SHUFFLE_BASE_IMAGE_REGISTRY")) > 0 {
// localRegistry = os.Getenv("SHUFFLE_BASE_IMAGE_REGISTRY")
// }
// if len(localRegistry) > 0 && strings.Count(image, "/") <= 2 {
// log.Printf("[DEBUG] Using REGISTRY_URL %s", localRegistry)
// image = fmt.Sprintf("%s/%s", localRegistry, image)
// } else {
// if strings.Count(image, "/") <= 2 {
// image = fmt.Sprintf("frikky/shuffle:%s", image)
// }
// }
// log.Printf("[DEBUG] Got kubernetes with namespace %#v to run image '%s'", kubernetesNamespace, image)
// //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{
// RestartPolicy: "Never", // As a crash is not useful in this context
// // DNSPolicy: "Default",
// DNSPolicy: corev1.DNSClusterFirst,
// // NodeName: "worker1"
// Containers: []corev1.Container{
// {
// Name: value,
// Image: image,
// Env: buildEnvVars(envMap),
// // Pull if not available
// ImagePullPolicy: corev1.PullIfNotPresent,
// },
// },
// },
// }
// createdPod, err := clientset.CoreV1().Pods(kubernetesNamespace).Create(context.Background(), pod, metav1.CreateOptions{})
// if err != nil {
// log.Printf("[ERROR] Failed creating pod: %v", err)
// // os.Exit(1)
// } else {
// log.Printf("[DEBUG] Created pod %#v in namespace %#v", createdPod.Name, kubernetesNamespace)
// }
// return nil
// }
// form basic hostConfig // form basic hostConfig
ctx := context.Background() ctx := context.Background()
@@ -583,7 +806,6 @@ func deployApp(cli *dockerclient.Client, image string, identifier string, env []
Env: env, Env: env,
} }
// Checking as late as possible, just in case. // Checking as late as possible, just in case.
newExecId := fmt.Sprintf("%s_%s", workflowExecution.ExecutionId, action.ID) newExecId := fmt.Sprintf("%s_%s", workflowExecution.ExecutionId, action.ID)
_, err := shuffle.GetCache(ctx, newExecId) _, err := shuffle.GetCache(ctx, newExecId)
@@ -618,8 +840,7 @@ func deployApp(cli *dockerclient.Client, image string, identifier string, env []
} }
func cleanupKubernetesExecution(clientset *kubernetes.Clientset, workflowExecution shuffle.WorkflowExecution, namespace string) error { func cleanupKubernetesExecution(clientset *kubernetes.Clientset, workflowExecution shuffle.WorkflowExecution, namespace string) error {
// workerName := fmt.Sprintf("worker-%s", workflowExecution.ExecutionId)
workerName := fmt.Sprintf("worker-%s", workflowExecution.ExecutionId)
labelSelector := fmt.Sprintf("app=shuffle-app,executionId=%s", workflowExecution.ExecutionId) labelSelector := fmt.Sprintf("app=shuffle-app,executionId=%s", workflowExecution.ExecutionId)
podList, err := clientset.CoreV1().Pods(namespace).List(context.TODO(), metav1.ListOptions{ podList, err := clientset.CoreV1().Pods(namespace).List(context.TODO(), metav1.ListOptions{
@@ -637,11 +858,11 @@ func cleanupKubernetesExecution(clientset *kubernetes.Clientset, workflowExecuti
log.Printf("App %s in namespace %s deleted.", pod.Name, namespace) log.Printf("App %s in namespace %s deleted.", pod.Name, namespace)
} }
podErr := clientset.CoreV1().Pods(namespace).Delete(context.TODO(), workerName, metav1.DeleteOptions{}) // podErr := clientset.CoreV1().Pods(namespace).Delete(context.TODO(), workerName, metav1.DeleteOptions{})
if podErr != nil { // if podErr != nil {
return fmt.Errorf("[ERROR] failed to delete the worker %s in namespace %s: %v", workerName, namespace, podErr) // return fmt.Errorf("[ERROR] failed to delete the worker %s in namespace %s: %v", workerName, namespace, podErr)
} // }
log.Printf("[DEBUG] %s in namespace %s deleted.", workerName, namespace) // log.Printf("[DEBUG] %s in namespace %s deleted.", workerName, namespace)
return nil return nil
} }
@@ -824,6 +1045,48 @@ func removeIndex(s []string, i int) []string {
func getWorkerURLs() ([]string, error) { func getWorkerURLs() ([]string, error) {
workerUrls := []string{} workerUrls := []string{}
if isKubernetes == "true" {
workerUrls = append(workerUrls, "http://shuffle-workers:33333")
// workerUrls = append(workerUrls, "http://192.168.29.16:33333")
// get service "shuffle-workers" "Endpoints"
// serviceName := "shuffle-workers"
// clientset, _, err := shuffle.GetKubernetesClient()
// if err != nil {
// log.Println("[ERROR] Failed to get Kubernetes client:", err)
// return workerUrls, err
// }
// services, err := clientset.CoreV1().Services("default").List(context.Background(), metav1.ListOptions{})
// if err != nil {
// log.Println("[ERROR] Failed to list services:", err)
// return workerUrls, err
// }
// for _, service := range services.Items {
// if service.Name == serviceName {
// endpoints, err := clientset.CoreV1().Endpoints("default").Get(context.Background(), serviceName, metav1.GetOptions{})
// if err != nil {
// log.Println("[ERROR] Failed to get endpoints for service:", err)
// return workerUrls, err
// }
// for _, subset := range endpoints.Subsets {
// for _, address := range subset.Addresses {
// for _, port := range subset.Ports {
// url := fmt.Sprintf("http://%s:%d", address.IP, port.Port)
// workerUrls = append(workerUrls, url)
// }
// }
// }
// }
// }
log.Printf("[DEBUG] Worker URLs for k8s: %#v", workerUrls)
return workerUrls, nil
}
// Create a new Docker client // Create a new Docker client
cli, err := dockerclient.NewEnvClient() cli, err := dockerclient.NewEnvClient()
if err != nil { if err != nil {
@@ -880,7 +1143,6 @@ func askOtherWorkersToDownloadImage(image string) {
return return
} }
httpClient := &http.Client{} httpClient := &http.Client{}
distributed := false distributed := false
for _, url := range urls { for _, url := range urls {
@@ -936,16 +1198,22 @@ func handleExecutionResult(workflowExecution shuffle.WorkflowExecution) {
return return
} }
startAction, extra, children, parents, visited, executed, nextActions, environments := shuffle.GetExecutionVariables(ctx, workflowExecution.ExecutionId) startAction, extra, children, parents, visited, executed, nextActions, environments := shuffle.GetExecutionVariables(ctx, workflowExecution.ExecutionId)
dockercli, err := dockerclient.NewEnvClient() var dockercli *dockerclient.Client
var err error
if isKubernetes != "true" {
dockercli, err = dockerclient.NewEnvClient()
if err != nil { if err != nil {
log.Printf("[ERROR] Unable to create docker client (3): %s", err) log.Printf("[ERROR] Unable to create docker client (3): %s", err)
return return
} }
}
if isKubernetes == "true" {
defer dockercli.Close() defer dockercli.Close()
}
for _, action := range relevantActions { for _, action := range relevantActions {
appname := action.AppName appname := action.AppName
@@ -976,7 +1244,8 @@ func handleExecutionResult(workflowExecution shuffle.WorkflowExecution) {
//executed = append(executed, action.ID) //executed = append(executed, action.ID)
// FIXME - check whether it's running locally yet too // FIXME - check whether it's running locally yet too
// take care of auto clean up later on for k8s
if isKubernetes != "true" {
stats, err := dockercli.ContainerInspect(context.Background(), identifier) stats, err := dockercli.ContainerInspect(context.Background(), identifier)
if err != nil || stats.ContainerJSONBase.State.Status != "running" { if err != nil || stats.ContainerJSONBase.State.Status != "running" {
// REMOVE // REMOVE
@@ -984,7 +1253,7 @@ func handleExecutionResult(workflowExecution shuffle.WorkflowExecution) {
log.Printf("[DEBUG][%s] Docker Container Status: %s, should kill: %s", workflowExecution.ExecutionId, stats.ContainerJSONBase.State.Status, identifier) log.Printf("[DEBUG][%s] Docker Container Status: %s, should kill: %s", workflowExecution.ExecutionId, stats.ContainerJSONBase.State.Status, identifier)
err = removeContainer(identifier) err = removeContainer(identifier)
if err != nil { if err != nil {
log.Printf("Error killing container: %s", err) log.Printf("[ERROR] Error killing container: %s", err)
} }
} else { } else {
//log.Printf("WHAT TO DO HERE?: %s", err) //log.Printf("WHAT TO DO HERE?: %s", err)
@@ -993,6 +1262,7 @@ func handleExecutionResult(workflowExecution shuffle.WorkflowExecution) {
//log.Printf(" //log.Printf("
continue continue
} }
}
if len(action.Parameters) == 0 { if len(action.Parameters) == 0 {
action.Parameters = []shuffle.WorkflowAppActionParameter{} action.Parameters = []shuffle.WorkflowAppActionParameter{}
@@ -1093,7 +1363,6 @@ func handleExecutionResult(workflowExecution shuffle.WorkflowExecution) {
env = append(env, fmt.Sprintf("SHUFFLE_APP_SDK_TIMEOUT=%s", os.Getenv("SHUFFLE_APP_SDK_TIMEOUT"))) env = append(env, fmt.Sprintf("SHUFFLE_APP_SDK_TIMEOUT=%s", os.Getenv("SHUFFLE_APP_SDK_TIMEOUT")))
} }
// Fixes issue: // Fixes issue:
// standard_go init_linux.go:185: exec user process caused "argument list too long" // standard_go init_linux.go:185: exec user process caused "argument list too long"
// https://devblogs.microsoft.com/oldnewthing/20100203-00/?p=15083 // https://devblogs.microsoft.com/oldnewthing/20100203-00/?p=15083
@@ -1121,8 +1390,6 @@ func handleExecutionResult(workflowExecution shuffle.WorkflowExecution) {
fmt.Sprintf("%s:%s_%s", baseimagename, parsedAppname, action.AppVersion), fmt.Sprintf("%s:%s_%s", baseimagename, parsedAppname, action.AppVersion),
} }
// If cleanup is set, it should run for efficiency // If cleanup is set, it should run for efficiency
pullOptions := types.ImagePullOptions{} pullOptions := types.ImagePullOptions{}
if cleanupEnv == "true" { if cleanupEnv == "true" {
@@ -1134,7 +1401,7 @@ func handleExecutionResult(workflowExecution shuffle.WorkflowExecution) {
return return
} }
err := downloadDockerImageBackend(&http.Client{Timeout: 60 * time.Second}, image) err := downloadDockerImageBackend(&http.Client{Timeout: imagedownloadTimeout}, image)
executed := false executed := false
if err == nil { if err == nil {
log.Printf("[DEBUG] Downloaded image %s from backend (CLEANUP)", image) log.Printf("[DEBUG] Downloaded image %s from backend (CLEANUP)", image)
@@ -1247,13 +1514,15 @@ func handleExecutionResult(workflowExecution shuffle.WorkflowExecution) {
} }
log.Printf("[DEBUG][%s] Failed deploy. Downloading image %s: %s", workflowExecution.ExecutionId, image, err) log.Printf("[DEBUG][%s] Failed deploy. Downloading image %s: %s", workflowExecution.ExecutionId, image, err)
err := downloadDockerImageBackend(&http.Client{Timeout: 60 * time.Second}, image) err := downloadDockerImageBackend(&http.Client{Timeout: imagedownloadTimeout}, image)
executed := false executed := false
if err == nil { if err == nil {
log.Printf("[DEBUG] Downloaded image %s from backend (CLEANUP)", image) log.Printf("[DEBUG] Downloaded image %s from backend (CLEANUP)", image)
//err = deployApp(dockercli, image, identifier, env, workflow, action) //err = deployApp(dockercli, image, identifier, env, workflow, action)
err = deployApp(dockercli, image, identifier, env, workflowExecution, action) err = deployApp(dockercli, image, identifier, env, workflowExecution, action)
if err != nil && !strings.Contains(err.Error(), "Conflict. The container name") { if err != nil && !strings.Contains(err.Error(), "Conflict. The container name") {
log.Printf("[ERROR] Err: %s", err)
if strings.Contains(err.Error(), "exited prematurely") { if strings.Contains(err.Error(), "exited prematurely") {
log.Printf("[DEBUG] Shutting down (40)") log.Printf("[DEBUG] Shutting down (40)")
shutdown(workflowExecution, action.ID, fmt.Sprintf("%s", err.Error()), true) shutdown(workflowExecution, action.ID, fmt.Sprintf("%s", err.Error()), true)
@@ -1268,6 +1537,7 @@ func handleExecutionResult(workflowExecution shuffle.WorkflowExecution) {
image = images[2] image = images[2]
err = deployApp(dockercli, image, identifier, env, workflowExecution, action) err = deployApp(dockercli, image, identifier, env, workflowExecution, action)
if err != nil && !strings.Contains(err.Error(), "Conflict. The container name") { if err != nil && !strings.Contains(err.Error(), "Conflict. The container name") {
log.Printf("[ERROR] Err: %s", err)
if strings.Contains(err.Error(), "exited prematurely") { if strings.Contains(err.Error(), "exited prematurely") {
log.Printf("[DEBUG] Shutting down (11)") log.Printf("[DEBUG] Shutting down (11)")
shutdown(workflowExecution, action.ID, fmt.Sprintf("%s", err.Error()), true) shutdown(workflowExecution, action.ID, fmt.Sprintf("%s", err.Error()), true)
@@ -1276,6 +1546,11 @@ func handleExecutionResult(workflowExecution shuffle.WorkflowExecution) {
log.Printf("[WARNING] Failed deploying image THREE TIMES. Attempting to download %s as last resort from backend and dockerhub: %s", image, err) log.Printf("[WARNING] Failed deploying image THREE TIMES. Attempting to download %s as last resort from backend and dockerhub: %s", image, err)
if isKubernetes == "true" {
log.Printf("[ERROR] Image %s doesn't exist. Returning error for now")
return
}
reader, err := dockercli.ImagePull(context.Background(), image, pullOptions) reader, err := dockercli.ImagePull(context.Background(), image, pullOptions)
if err != nil && !strings.Contains(err.Error(), "Conflict. The container name") { if err != nil && !strings.Contains(err.Error(), "Conflict. The container name") {
log.Printf("[ERROR] Failed getting %s. The couldn't be find locally, AND is missing.", image) log.Printf("[ERROR] Failed getting %s. The couldn't be find locally, AND is missing.", image)
@@ -1625,13 +1900,11 @@ func handleSubflowPoller(ctx context.Context, workflowExecution shuffle.Workflow
} }
} }
if workflowExecution.Status == "WAITING" && workflowExecution.ExecutionSource != "default" && os.Getenv("SHUFFLE_SWARM_CONFIG") != "run" && os.Getenv("SHUFFLE_SWARM_CONFIG") != "swarm" { if workflowExecution.Status == "WAITING" && workflowExecution.ExecutionSource != "default" && os.Getenv("SHUFFLE_SWARM_CONFIG") != "run" && os.Getenv("SHUFFLE_SWARM_CONFIG") != "swarm" {
log.Printf("[INFO][%s] Workflow execution is waiting. Exiting worker, as backend will restart it.", workflowExecution.ExecutionId) log.Printf("[INFO][%s] Workflow execution is waiting. Exiting worker, as backend will restart it.", workflowExecution.ExecutionId)
shutdown(workflowExecution, "", "", true) shutdown(workflowExecution, "", "", true)
} }
log.Printf("[INFO][%s] (2) Status: %s, Results: %d, actions: %d. Userinput: %#v", workflowExecution.ExecutionId, workflowExecution.Status, len(workflowExecution.Results), len(workflowExecution.Workflow.Actions)+extra, hasUserinput) log.Printf("[INFO][%s] (2) Status: %s, Results: %d, actions: %d. Userinput: %#v", workflowExecution.ExecutionId, workflowExecution.Status, len(workflowExecution.Results), len(workflowExecution.Workflow.Actions)+extra, hasUserinput)
return errors.New("Subflow status not found yet") return errors.New("Subflow status not found yet")
} }
@@ -1898,7 +2171,6 @@ func buildEnvVars(envMap map[string]string) []corev1.EnvVar {
func handleWorkflowQueue(resp http.ResponseWriter, request *http.Request) { func handleWorkflowQueue(resp http.ResponseWriter, request *http.Request) {
if request.Body == nil { if request.Body == nil {
log.Printf("[WARNING] (2) No body in request for workflowqueue")
resp.WriteHeader(http.StatusBadRequest) resp.WriteHeader(http.StatusBadRequest)
return return
} }
@@ -2003,7 +2275,6 @@ func runWorkflowExecutionTransaction(ctx context.Context, attempts int64, workfl
resp.Write([]byte(fmt.Sprintf(`{"success": true, "reason": "Execution is not executing, but %s"}`, workflowExecution.Status))) resp.Write([]byte(fmt.Sprintf(`{"success": true, "reason": "Execution is not executing, but %s"}`, workflowExecution.Status)))
} }
log.Printf("[DEBUG][%s] Shutting down (35)", workflowExecution.ExecutionId) log.Printf("[DEBUG][%s] Shutting down (35)", workflowExecution.ExecutionId)
// Force sending result // Force sending result
@@ -2376,7 +2647,11 @@ func getAvailablePort() (net.Listener, error) {
func webserverSetup(workflowExecution shuffle.WorkflowExecution) net.Listener { func webserverSetup(workflowExecution shuffle.WorkflowExecution) net.Listener {
hostname = getLocalIP() hostname = getLocalIP()
if isKubernetes == "true" {
os.Setenv("WORKER_HOSTNAME", "shuffle-workers")
} else {
os.Setenv("WORKER_HOSTNAME", hostname) os.Setenv("WORKER_HOSTNAME", hostname)
}
// FIXME: This MAY not work because of speed between first // FIXME: This MAY not work because of speed between first
// container being launched and port being assigned to webserver // container being launched and port being assigned to webserver
@@ -2623,6 +2898,10 @@ if err != nil {
return err return err
} }
if isKubernetes == "true" {
appName = strings.Replace(appName, "_", "-", -1)
}
streamUrl := fmt.Sprintf("http://%s:%d/api/v1/run", appName, port) streamUrl := fmt.Sprintf("http://%s:%d/api/v1/run", appName, port)
// log.Printf("[DEBUG][%s] Worker URL: %s, Backend URL: %s, Target App: %s", workflowExecution.ExecutionId, parsedRequest.BaseUrl, parsedRequest.Url, streamUrl) // log.Printf("[DEBUG][%s] Worker URL: %s, Backend URL: %s, Target App: %s", workflowExecution.ExecutionId, parsedRequest.BaseUrl, parsedRequest.Url, streamUrl)
req, err := http.NewRequest( req, err := http.NewRequest(
@@ -2724,13 +3003,17 @@ if err != nil {
// Has some issues with loading when running multiple workers and such. // Has some issues with loading when running multiple workers and such.
func baseDeploy() { func baseDeploy() {
var cli *dockerclient.Client
var err error
if isKubernetes != "true" {
cli, err := dockerclient.NewEnvClient() cli, err := dockerclient.NewEnvClient()
if err != nil { if err != nil {
log.Printf("[ERROR] Unable to create docker client (3): %s", err) log.Printf("[ERROR] Unable to create docker client (3): %s", err)
return return
} }
defer cli.Close() defer cli.Close()
}
for key, value := range autoDeploy { for key, value := range autoDeploy {
newNameSplit := strings.Split(key, ":") newNameSplit := strings.Split(key, ":")
@@ -2850,7 +3133,7 @@ func getStreamResultsWrapper(client *http.Client, req *http.Request, workflowExe
} }
// Checks if a subflow is child of the startnode, as sub-subflows aren't working properly yet // Checks if a subflow is child of the startnode, as sub-subflows aren't working properly yet
childNodes := shuffle.FindChildNodes(workflowExecution, workflowExecution.Start, []string{}, []string{}) childNodes := shuffle.FindChildNodes(workflowExecution.Workflow, workflowExecution.Start, []string{}, []string{})
log.Printf("[DEBUG] Looking for subflow in %#v to check execution pattern as child of %s", childNodes, workflowExecution.Start) log.Printf("[DEBUG] Looking for subflow in %#v to check execution pattern as child of %s", childNodes, workflowExecution.Start)
subflowFound := false subflowFound := false
for _, childNode := range childNodes { for _, childNode := range childNodes {
@@ -2893,7 +3176,6 @@ func getStreamResultsWrapper(client *http.Client, req *http.Request, workflowExe
// Set environment variable // Set environment variable
//log.Printf("Before wait") //log.Printf("Before wait")
//wg := sync.WaitGroup{} //wg := sync.WaitGroup{}
//wg.Add(1) //wg.Add(1)
@@ -2944,7 +3226,11 @@ func main() {
log.Printf("[ERROR] Failed to run worker init: %s", err) log.Printf("[ERROR] Failed to run worker init: %s", err)
} }
} else { } else {
if isKubernetes != "true" {
log.Printf("[DEBUG] Ran init for worker to set up cache system. Docker version: %s", dockerApiVersion) log.Printf("[DEBUG] Ran init for worker to set up cache system. Docker version: %s", dockerApiVersion)
} else {
log.Printf("[DEBUG] Ran init for worker to set up cache system on Kubernetes")
}
} }
log.Printf("[INFO] Setting up worker environment") log.Printf("[INFO] Setting up worker environment")
@@ -3270,7 +3556,6 @@ func handleDownloadImage(resp http.ResponseWriter, request *http.Request) {
return return
} }
for _, img := range images { for _, img := range images {
for _, tag := range img.RepoTags { for _, tag := range img.RepoTags {
splitTag := strings.Split(tag, ":") splitTag := strings.Split(tag, ":")
@@ -3283,7 +3568,7 @@ func handleDownloadImage(resp http.ResponseWriter, request *http.Request) {
possibleNames = append(possibleNames, fmt.Sprintf("frikky/shuffle:%s", baseTag)) possibleNames = append(possibleNames, fmt.Sprintf("frikky/shuffle:%s", baseTag))
possibleNames = append(possibleNames, fmt.Sprintf("registry.hub.docker.com/frikky/shuffle:%s", baseTag)) possibleNames = append(possibleNames, fmt.Sprintf("registry.hub.docker.com/frikky/shuffle:%s", baseTag))
if (arrayContains(possibleNames, image.Image)) { if arrayContains(possibleNames, image.Image) {
log.Printf("[DEBUG] Image %s already downloaded that has been requested to download", image.Image) log.Printf("[DEBUG] Image %s already downloaded that has been requested to download", image.Image)
resp.WriteHeader(200) resp.WriteHeader(200)
resp.Write([]byte(fmt.Sprintf(`{"success": false, "reason": "image already present"}`))) resp.Write([]byte(fmt.Sprintf(`{"success": false, "reason": "image already present"}`)))
@@ -3293,7 +3578,7 @@ func handleDownloadImage(resp http.ResponseWriter, request *http.Request) {
} }
log.Printf("[INFO] Downloading image %s", image.Image) log.Printf("[INFO] Downloading image %s", image.Image)
downloadDockerImageBackend(&http.Client{Timeout: 60 * time.Second}, image.Image) downloadDockerImageBackend(&http.Client{Timeout: imagedownloadTimeout}, image.Image)
// return success // return success
resp.WriteHeader(200) resp.WriteHeader(200)
@@ -3326,6 +3611,7 @@ func runWebserver(listener net.Listener) {
//log.Fatal(http.Serve(listener, nil)) //log.Fatal(http.Serve(listener, nil))
log.Printf("[DEBUG] NEW webserver setup") log.Printf("[DEBUG] NEW webserver setup")
http.Handle("/", r) http.Handle("/", r)