Skip to content

Commit

Permalink
Merge pull request #9938 from phantomjinx/1.14.x
Browse files Browse the repository at this point in the history
ENTESB-18466 - Reworking of operator conditions ensuring step upgrades
  • Loading branch information
phantomjinx committed Apr 25, 2022
2 parents 0fb6dc2 + 754964f commit 7321d5b
Show file tree
Hide file tree
Showing 20 changed files with 237 additions and 35 deletions.
13 changes: 12 additions & 1 deletion install/operator/.lib.sh
Expand Up @@ -136,6 +136,11 @@ build_operator()
go build -o ./dist/${GOOS}-${GOARCH}/platform-detect \
-gcflags all=-trimpath=${GOPATH} -asmflags all=-trimpath=${GOPATH} -mod=vendor \
./cmd/detect

echo building ./dist/${GOOS}-${GOARCH}/operator-init executable
go build -o ./dist/${GOOS}-${GOARCH}/operator-init \
-gcflags all=-trimpath=${GOPATH} -asmflags all=-trimpath=${GOPATH} -ldflags "-s -w" -mod=vendor \
./cmd/operator-init
done
done
mkdir -p ./build/_output/bin
Expand Down Expand Up @@ -168,8 +173,11 @@ COPY . .
RUN go generate ./pkg/...
RUN go test -test.short -mod=vendor ./cmd/... ./pkg/...
RUN GOOS=linux GOARCH=amd64 go build $OPTS -o /dist/linux-amd64/syndesis-operator -gcflags all=-trimpath=\${GOPATH} -asmflags all=-trimpath=\${GOPATH} -mod=vendor github.com/syndesisio/syndesis/install/operator/cmd/manager
RUN GOOS=linux GOARCH=amd64 go build $OPTS -o /dist/linux-amd64/operator-init -gcflags all=-trimpath=\${GOPATH} -asmflags all=-trimpath=\${GOPATH} -mod=vendor github.com/syndesisio/syndesis/install/operator/cmd/operator-init
RUN GOOS=darwin GOARCH=amd64 go build $OPTS -o /dist/darwin-amd64/syndesis-operator -gcflags all=-trimpath=\${GOPATH} -asmflags all=-trimpath=\${GOPATH} -mod=vendor github.com/syndesisio/syndesis/install/operator/cmd/manager
RUN GOOS=darwin GOARCH=amd64 go build $OPTS -o /dist/darwin-amd64/operator-init -gcflags all=-trimpath=\${GOPATH} -asmflags all=-trimpath=\${GOPATH} -mod=vendor github.com/syndesisio/syndesis/install/operator/cmd/operator-init
RUN GOOS=windows GOARCH=amd64 go build $OPTS -o /dist/windows-amd64/syndesis-operator -gcflags all=-trimpath=\${GOPATH} -asmflags all=-trimpath=\${GOPATH} -mod=vendor github.com/syndesisio/syndesis/install/operator/cmd/manager
RUN GOOS=windows GOARCH=amd64 go build $OPTS -o /dist/windows-amd64/operator-init -gcflags all=-trimpath=\${GOPATH} -asmflags all=-trimpath=\${GOPATH} -mod=vendor github.com/syndesisio/syndesis/install/operator/cmd/operator-init
EODockerfile

docker build -t "${BUILDER_IMAGE_NAME}" . -f "${BUILDER_IMAGE_NAME}.tmp"
Expand All @@ -179,14 +187,17 @@ EODockerfile

for GOARCH in amd64 ; do
for GOOS in linux darwin windows ; do
echo extracting executable to ./dist/${GOOS}-${GOARCH}/syndesis-operator
echo extracting executables to ./dist/${GOOS}-${GOARCH}
mkdir -p ./dist/${GOOS}-${GOARCH}
docker run "${BUILDER_IMAGE_NAME}" cat /dist/${GOOS}-${GOARCH}/syndesis-operator > ./dist/${GOOS}-${GOARCH}/syndesis-operator
docker run "${BUILDER_IMAGE_NAME}" cat /dist/${GOOS}-${GOARCH}/operator-init > ./dist/${GOOS}-${GOARCH}/operator-init
done
done
chmod a+x ./dist/*/syndesis-operator
chmod a+x ./dist/*/operator-init
mkdir -p ./build/_output/bin
cp ./dist/linux-amd64/syndesis-operator ./build/_output/bin/syndesis-operator
cp ./dist/linux-amd64/operator-init ./build/_output/bin/operator-init
;;
*)
echo invalid build strategy: $strategy
Expand Down
3 changes: 2 additions & 1 deletion install/operator/build.sh
Expand Up @@ -45,7 +45,8 @@ fi
BUILD_TIME=$(date +%Y-%m-%dT%H:%M:%S%z)

if [ $OPERATOR_BUILD_MODE != "skip" ] ; then
LD_FLAGS=$(echo "-X github.com/syndesisio/syndesis/install/operator/pkg.DefaultOperatorImage=${OPERATOR_IMAGE_NAME}" \
LD_FLAGS=$(echo "-s -w " \
"-X github.com/syndesisio/syndesis/install/operator/pkg.DefaultOperatorImage=${OPERATOR_IMAGE_NAME}" \
"-X github.com/syndesisio/syndesis/install/operator/pkg.DefaultOperatorTag=${OPERATOR_IMAGE_TAG}" \
"-X github.com/syndesisio/syndesis/install/operator/pkg.BuildDateTime=${BUILD_TIME}")
echo "LD_FLAGS: ${LD_FLAGS}"
Expand Down
2 changes: 2 additions & 0 deletions install/operator/build/Dockerfile
@@ -1,11 +1,13 @@
FROM registry.access.redhat.com/ubi7/ubi-minimal:latest

ENV OPERATOR=/usr/local/bin/syndesis-operator \
OPINIT=/usr/local/bin/operator-init \
USER_UID=1001 \
USER_NAME=operator

# install operator binary
COPY build/_output/bin/syndesis-operator ${OPERATOR}
COPY build/_output/bin/operator-init ${OPINIT}
COPY build/bin /usr/local/bin
RUN /usr/local/bin/user_setup
USER ${USER_UID}
Expand Down
110 changes: 110 additions & 0 deletions install/operator/cmd/operator-init/main.go
@@ -0,0 +1,110 @@
/*
* Copyright (C) 2019 Red Hat, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package main

import (
"context"
"fmt"
"os"

gerrors "github.com/pkg/errors"
synapis "github.com/syndesisio/syndesis/install/operator/pkg/apis"
synapi "github.com/syndesisio/syndesis/install/operator/pkg/apis/syndesis/v1beta3"
"github.com/syndesisio/syndesis/install/operator/pkg/syndesis/clienttools"
"github.com/syndesisio/syndesis/install/operator/pkg/syndesis/olm"
kerrors "k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"sigs.k8s.io/controller-runtime/pkg/client"
)

func main() {
clientTools := &clienttools.ClientTools{}

//
// Ensure runtime client knows about syndesis apis
//
scheme := clientTools.GetScheme()
if err := synapis.AddToScheme(scheme); err != nil {
fmt.Println(err, "Error occurred")
os.Exit(1)
}

ctx := context.TODO()

nm, found := os.LookupEnv("POD_NAMESPACE")
if !found {
fmt.Println("Error: No POD_NAMESPACE has been set")
os.Exit(1)
} else {
fmt.Println("Info: Using POD_NAMESPACE: ", nm)
}

prodName, found := os.LookupEnv("PRODUCT_NAME")
if !found {
fmt.Println("Error: No PRODUCT_NAME has been set")
os.Exit(1)
} else {
fmt.Println("Info: Using PRODUCT_NAME: ", prodName)
}

if err := setUpgradeCondition(ctx, clientTools, nm, prodName); err != nil {
fmt.Println(err, "Error occurred")
os.Exit(1)
}
}

func setUpgradeCondition(ctx context.Context, clientTools *clienttools.ClientTools, nm string, prodName string) error {
found, err := hasSyndesis(ctx, clientTools, nm)
if err != nil {
return gerrors.Wrap(err, "Failed to get Syndesis resource")
} else if !found {
fmt.Println("Info: No Syndesis Custom Resource. Upgrade disablement not required")
return nil
}

//
// Disable the upgrade until enabled
//
state := olm.ConditionState{
Status: metav1.ConditionFalse,
Reason: "NotReady",
Message: "Disable any operator upgrade until reconciliation allows it",
}
if upgErr := olm.SetUpgradeCondition(ctx, clientTools, nm, prodName, state); upgErr != nil {
return gerrors.Wrap(upgErr, "Failed to set the upgrade condition on the operator")
}

return nil
}

func hasSyndesis(ctx context.Context, clientTools *clienttools.ClientTools, nm string) (bool, error) {
synList := synapi.SyndesisList{}
rtclient, err := clientTools.RuntimeClient()
if err != nil {
return false, err
}

err = rtclient.List(ctx, &synList, &client.ListOptions{Namespace: nm})
if err != nil {
if kerrors.IsNotFound(err) {
return false, nil
}
return false, err
}

return len(synList.Items) > 0, nil
}
6 changes: 6 additions & 0 deletions install/operator/config/manager/Makefile
Expand Up @@ -6,6 +6,8 @@ USER_VAR := {KUBE_USER}
TAG_VAR := {TAG}
IMAGE_VAR := {IMAGE}
DB_IMAGE_VAR := {DB_IMAGE}
VERSION_VAR := {VERSION}
PRODUCT_NAME_VAR := {PRODUCT_NAME}

ROLENAME := syndesis-operator
MANAGER_RESOURCE := ./manager.gen
Expand Down Expand Up @@ -42,6 +44,8 @@ sync:
sed -i 's/{{.Tag}}/$(TAG_VAR)/' $(MANAGER_RESOURCE).$(TMPL)
sed -i 's/{{.Image}}/$(IMAGE_VAR)/' $(MANAGER_RESOURCE).$(TMPL)
sed -i 's/{{.DatabaseImage}}/$(DB_IMAGE_VAR)/' $(MANAGER_RESOURCE).$(TMPL)
sed -i 's/{{.Version}}/$(VERSION_VAR)/' $(MANAGER_RESOURCE).$(TMPL)
sed -i 's/{{.ProductName}}/$(PRODUCT_NAME_VAR)/' $(MANAGER_RESOURCE).$(TMPL)
sed -i '/{{- \|{{else}}\|{{end}}\|^$$/d' $(MANAGER_RESOURCE).$(TMPL)
# end-sync

Expand All @@ -52,4 +56,6 @@ init: sync
sed -i 's/$(TAG_VAR)/$(TAG)/' $${resource}.$(YAML); \
sed -i 's~$(IMAGE_VAR)~$(IMAGE)~' $${resource}.$(YAML); \
sed -i 's~$(DB_IMAGE_VAR)~$(DB_IMAGE)~' $${resource}.$(YAML); \
sed -i 's~$(VERSION_VAR)~$(VERSION:.0=)~' $${resource}.$(YAML); \
sed -i 's~$(PRODUCT_NAME_VAR)~$(PACKAGE:.0=)~' $${resource}.$(YAML); \
done
8 changes: 8 additions & 0 deletions install/operator/pkg/cmd/internal/install/install.go
Expand Up @@ -46,13 +46,15 @@ type Install struct {
eject string
image string
tag string
version string
addons string
customResource string
devSupport bool
logLevel int
apiServer capabilities.ApiServerSpec
databaseImage string
templateName string
productName string

// processing state
ejectedResources []unstructured.Unstructured
Expand Down Expand Up @@ -165,6 +167,8 @@ func (o *Install) before(_ *cobra.Command, args []string) (err error) {
config, err := configuration.GetProperties(o.Context, configuration.TemplateConfig, o.ClientTools(), &synapi.Syndesis{})
if err == nil {
o.databaseImage = config.Syndesis.Components.Database.Image
o.version = config.Version
o.productName = config.ProductName
}

return nil
Expand Down Expand Up @@ -210,7 +214,9 @@ type RenderScope struct {
Role string
Kind string
EnabledAddons []string
Version string
DatabaseImage string
ProductName string
}

func (o *Install) install(action string, resources []unstructured.Unstructured) error {
Expand Down Expand Up @@ -270,6 +276,8 @@ func (o *Install) render(fromFile string) ([]unstructured.Unstructured, error) {
Kind: "Role",
EnabledAddons: addons,
DatabaseImage: o.databaseImage,
Version: o.version,
ProductName: o.productName,
})
return resources, err
}
60 changes: 57 additions & 3 deletions install/operator/pkg/controller/syndesis/syndesis_controller.go
Expand Up @@ -19,6 +19,9 @@ import (
synapi "github.com/syndesisio/syndesis/install/operator/pkg/apis/syndesis/v1beta3"
"github.com/syndesisio/syndesis/install/operator/pkg/syndesis/action"
"github.com/syndesisio/syndesis/install/operator/pkg/syndesis/clienttools"
"github.com/syndesisio/syndesis/install/operator/pkg/syndesis/configuration"
"github.com/syndesisio/syndesis/install/operator/pkg/syndesis/olm"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)

var log = logf.Log.WithName("controller")
Expand Down Expand Up @@ -88,25 +91,76 @@ func (r *ReconcileSyndesis) Reconcile(ctx context.Context, request reconcile.Req

// Fetch the Syndesis syndesis
syndesis := &synapi.Syndesis{}

client, _ := r.clientTools.RuntimeClient()
productName, err := configuration.GetProductName(configuration.TemplateConfig)
if err != nil {
log.Error(err, "Failed to determine product name")
}

err := client.Get(ctx, request.NamespacedName, syndesis)
err = client.Get(ctx, request.NamespacedName, syndesis)
if err != nil {
if errors.IsNotFound(err) {

//
// Allow the operator to be upgradeable if no syndesis resource is installed
//
state := olm.ConditionState{
Status: metav1.ConditionTrue,
Reason: "Ready",
Message: "No Syndesis Resource installed so operator can be upgraded",
}
if upgErr := olm.SetUpgradeCondition(ctx, r.clientTools, request.Namespace, productName, state); upgErr != nil {
log.Error(upgErr, "Failed to set the upgrade condition on the operator")
}

// Request object not found, could have been deleted after reconcile request.
// Owned objects are automatically garbage collected. For additional cleanup logic use finalizers.
// Return and don't requeue
return reconcile.Result{}, nil
}

// Error reading the object - requeue the request.
log.Error(err, "Cannot read object", request.NamespacedName)

//
// Stop the operator being upgradeable until a state can be read
//
state := olm.ConditionState{
Status: metav1.ConditionFalse,
Reason: "NotReady",
Message: "Read error detecting syndesis resource",
}
if upgErr := olm.SetUpgradeCondition(ctx, r.clientTools, request.Namespace, productName, state); upgErr != nil {
log.Error(upgErr, "Failed to set the upgrade condition on the operator")
}

return reconcile.Result{
Requeue: true,
RequeueAfter: 10 * time.Second,
}, err
}

//
// Check the syndesis resource allows for upgrades. Otherwise disable
//
stateMsg := ""
if syndesis.Status.Version != synpkg.DefaultOperatorTag {
stateMsg = "Not upgradeable due to version mismatch of operator and Syndesis Resource"
} else if syndesis.Status.Phase != synapi.SyndesisPhaseInstalled {
stateMsg = "Not upgradeable due to Syndesis Resource phase not reaching 'Installed'"
}

if len(stateMsg) > 0 {
state := olm.ConditionState{
Status: metav1.ConditionFalse,
Reason: "NotReady",
Message: stateMsg,
}
if upgErr := olm.SetUpgradeCondition(ctx, r.clientTools, request.Namespace, productName, state); upgErr != nil {
log.Error(upgErr, "Failed to set the upgrade condition on the operator")
}
}

for _, a := range actions {
// Don't want to do anything if the syndesis resource has been updated in the meantime
// This happens when a processing takes more tha the resync period
Expand All @@ -120,7 +174,7 @@ func (r *ReconcileSyndesis) Reconcile(ctx context.Context, request reconcile.Req

if a.CanExecute(syndesis) {
log.V(synpkg.DEBUG_LOGGING_LVL).Info("Running action", "action", reflect.TypeOf(a))
if err := a.Execute(ctx, syndesis, request.Namespace); err != nil {
if err := a.Execute(ctx, syndesis, request.Namespace, productName); err != nil {
log.Error(err, "Error reconciling", "action", reflect.TypeOf(a), "phase", syndesis.Status.Phase)
return reconcile.Result{
Requeue: true,
Expand Down
Expand Up @@ -74,6 +74,17 @@ spec:
- name: syndesis-operator-data
mountPath: /data
initContainers:
- name: operator-init
image: {{.Image}}:{{.Tag}}
imagePullPolicy: Always
command: ["/usr/local/bin/operator-init"]
env:
- name: POD_NAMESPACE
valueFrom:
fieldRef:
fieldPath: metadata.namespace
- name: PRODUCT_NAME
value: {{.ProductName}}
- command:
- bash
- -c
Expand Down
2 changes: 1 addition & 1 deletion install/operator/pkg/syndesis/action/action.go
Expand Up @@ -36,7 +36,7 @@ var actionLog = logf.Log.WithName("action")

type SyndesisOperatorAction interface {
CanExecute(syndesis *synapi.Syndesis) bool
Execute(ctx context.Context, syndesis *synapi.Syndesis, operatorNamespace string) error
Execute(ctx context.Context, syndesis *synapi.Syndesis, operatorNamespace string, productName string) error
}

// NewOperatorActions gives the default set of actions operator will perform
Expand Down
2 changes: 1 addition & 1 deletion install/operator/pkg/syndesis/action/backup.go
Expand Up @@ -49,7 +49,7 @@ func (a *backupAction) CanExecute(syndesis *synapi.Syndesis) bool {
}

// Schedule a cronjob for systematic backups
func (a *backupAction) Execute(ctx context.Context, syndesis *synapi.Syndesis, operatorNamespace string) error {
func (a *backupAction) Execute(ctx context.Context, syndesis *synapi.Syndesis, operatorNamespace string, productName string) error {
entries := c.Entries()

if s := syndesis.Spec.Backup.Schedule; s != "" {
Expand Down

0 comments on commit 7321d5b

Please sign in to comment.