github.com/docker/compose-on-kubernetes@v0.5.0/internal/registry/strategyprepare.go (about) 1 package registry 2 3 import ( 4 "context" 5 "errors" 6 "fmt" 7 "reflect" 8 "strings" 9 10 "github.com/docker/compose-on-kubernetes/internal/conversions" 11 iv "github.com/docker/compose-on-kubernetes/internal/internalversion" 12 "github.com/docker/compose-on-kubernetes/internal/parsing" 13 log "github.com/sirupsen/logrus" 14 genericapirequest "k8s.io/apiserver/pkg/endpoints/request" 15 ) 16 17 func prepareStackOwnership() prepareStep { 18 return func(ctx context.Context, _, stack *iv.Stack) error { 19 if user, ok := genericapirequest.UserFrom(ctx); ok { 20 stack.Spec.Owner.UserName = user.GetName() 21 stack.Spec.Owner.Groups = user.GetGroups() 22 stack.Spec.Owner.Extra = user.GetExtra() 23 log.Debugf("Set stack owner to %s", stack.Spec.Owner.UserName) 24 return nil 25 } 26 return errors.New("can't extract owner information from request") 27 } 28 } 29 30 func setFieldsForV1beta1Update(oldStack, newStack *iv.Stack) { 31 // mark stack as dirty if composfile has been updated 32 // if not, avoid re-parsing the same compose file 33 if newStack.Spec.ComposeFile != oldStack.Spec.ComposeFile { 34 // composefile was changed, drop the stack (will be reconciled just after) 35 newStack.Spec.Stack = nil 36 } else { 37 // The update likely dropped v1beta2 fields 38 newStack.Spec.Stack = oldStack.Spec.Stack 39 } 40 } 41 func setFieldsForV1beta2Update(oldStack, newStack *iv.Stack) { 42 // check if composefile is still up to date 43 // if the stack itself has been updated, we add a comment at compose file head 44 // warning the user that it is not in sync anymore with the structured stack 45 newStack.Spec.ComposeFile = oldStack.Spec.ComposeFile 46 specSame := reflect.DeepEqual(newStack.Spec.Stack, oldStack.Spec.Stack) 47 if !specSame && !strings.HasPrefix(newStack.Spec.ComposeFile, composeOutOfDate) && newStack.Spec.ComposeFile != "" { 48 newStack.Spec.ComposeFile = composeOutOfDate + newStack.Spec.ComposeFile 49 } 50 } 51 52 type fieldUpdatesFunc func(oldStack, newStack *iv.Stack) 53 54 var fieldUpdatesFuncs = map[APIVersion]fieldUpdatesFunc{ 55 APIV1beta1: setFieldsForV1beta1Update, 56 APIV1beta2: setFieldsForV1beta2Update, 57 } 58 59 func prepareFieldsForUpdate(version APIVersion) prepareStep { 60 if f, ok := fieldUpdatesFuncs[version]; ok { 61 return func(_ context.Context, oldStack, newStack *iv.Stack) error { 62 if oldStack != nil { 63 f(oldStack, newStack) 64 } 65 return nil 66 } 67 } 68 return func(_ context.Context, _, _ *iv.Stack) error { 69 return fmt.Errorf("unknown APIVersion %q", version) 70 } 71 72 } 73 74 func prepareStackFromComposefile(relaxedParsing bool) prepareStep { 75 return func(_ context.Context, _, newStack *iv.Stack) error { 76 if newStack.Spec.Stack == nil { 77 // creation or update from composefile subresource or from v1beta1 API 78 composeConfig, err := parsing.LoadStackData([]byte(newStack.Spec.ComposeFile), nil) 79 if err != nil { 80 if relaxedParsing { 81 newStack.Status = &iv.StackStatus{ 82 Phase: iv.StackFailure, 83 Message: fmt.Sprintf("parsing error: %s", err), 84 } 85 return nil 86 } 87 return fmt.Errorf("parsing error: %s", err) 88 } 89 newStack.Spec.Stack = conversions.FromComposeConfig(composeConfig) 90 } 91 return nil 92 } 93 }