Skip to content

Commit 2df43de

Browse files
committed
adds migrate command and ansible base image scaffolds
The `operator-sdk migrate` command adds go source and other files necessary to convert an ansible operator to a hybrid operator. The scaffolds used for `migrate` are also made available for use in creating the ansible-operator base image through `commands/ansible-operator-base/main.go`.
1 parent fd86f9d commit 2df43de

File tree

14 files changed

+523
-133
lines changed

14 files changed

+523
-133
lines changed

Diff for: commands/ansible-operator-base/main.go

+46
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
// Copyright 2018 The Operator-SDK Authors
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
package main
16+
17+
import (
18+
"log"
19+
20+
"github.com/operator-framework/operator-sdk/internal/util/projutil"
21+
"github.com/operator-framework/operator-sdk/pkg/scaffold"
22+
"github.com/operator-framework/operator-sdk/pkg/scaffold/ansible"
23+
"github.com/operator-framework/operator-sdk/pkg/scaffold/input"
24+
)
25+
26+
// main renders scaffolds that are required to build the ansible operator base
27+
// image. It is intended for release engineering use only. After running this,
28+
// you can `dep ensure` and then `operator-sdk build`.
29+
func main() {
30+
cfg := &input.Config{
31+
AbsProjectPath: projutil.MustGetwd(),
32+
ProjectName: "ansible-operator",
33+
}
34+
35+
s := &scaffold.Scaffold{}
36+
err := s.Execute(cfg,
37+
&ansible.Main{},
38+
&ansible.GopkgToml{},
39+
&ansible.DockerfileHybrid{},
40+
&ansible.Entrypoint{},
41+
&ansible.UserSetup{},
42+
)
43+
if err != nil {
44+
log.Fatalf("add scaffold failed: (%v)", err)
45+
}
46+
}

Diff for: commands/operator-sdk/cmd/migrate.go

+92
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
// Copyright 2018 The Operator-SDK Authors
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
package cmd
16+
17+
import (
18+
"log"
19+
"os"
20+
"path/filepath"
21+
22+
"github.com/operator-framework/operator-sdk/internal/util/projutil"
23+
"github.com/operator-framework/operator-sdk/pkg/scaffold"
24+
"github.com/operator-framework/operator-sdk/pkg/scaffold/ansible"
25+
"github.com/operator-framework/operator-sdk/pkg/scaffold/input"
26+
27+
"github.com/spf13/cobra"
28+
)
29+
30+
func NewMigrateCmd() *cobra.Command {
31+
return &cobra.Command{
32+
Use: "migrate",
33+
Short: "Adds source code for an operator",
34+
Long: `operator-sdk migrate adds a main.go source file and any associated source files for an operator that is not of the "go" type.`,
35+
Run: migrateRun,
36+
}
37+
}
38+
39+
func migrateRun(cmd *cobra.Command, args []string) {
40+
projutil.MustInProjectRoot()
41+
42+
_ = projutil.CheckAndGetProjectGoPkg()
43+
44+
opType := projutil.GetOperatorType()
45+
switch opType {
46+
case projutil.OperatorTypeAnsible:
47+
migrateAnsible()
48+
default:
49+
log.Fatalf("operator of type %s cannot be migrated.", opType)
50+
}
51+
}
52+
53+
func migrateAnsible() {
54+
wd, err := os.Getwd()
55+
if err != nil {
56+
log.Fatalf("could not identify current working directory: (%v)", err)
57+
}
58+
59+
cfg := &input.Config{
60+
AbsProjectPath: projutil.MustGetwd(),
61+
ProjectName: filepath.Base(wd),
62+
}
63+
64+
dockerfile := ansible.DockerfileHybrid{
65+
Watches: true,
66+
Roles: true,
67+
}
68+
_, err = os.Stat("playbook.yaml")
69+
if err == nil {
70+
dockerfile.Playbook = true
71+
} else if !os.IsNotExist(err) {
72+
log.Fatalf("error trying to stat playbook.yaml: (%v)", err)
73+
}
74+
75+
dockerfilePath := filepath.Join(scaffold.BuildDir, scaffold.DockerfileFile)
76+
err = os.Rename(dockerfilePath, dockerfilePath+".sdkold")
77+
if err != nil {
78+
log.Fatalf("failed to rename Dockerfile: (%v)", err)
79+
}
80+
81+
s := &scaffold.Scaffold{}
82+
err = s.Execute(cfg,
83+
&ansible.Main{},
84+
&ansible.GopkgToml{},
85+
&dockerfile,
86+
&ansible.Entrypoint{},
87+
&ansible.UserSetup{},
88+
)
89+
if err != nil {
90+
log.Fatalf("add scaffold failed: (%v)", err)
91+
}
92+
}

Diff for: commands/operator-sdk/cmd/root.go

+1
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ func NewRootCmd() *cobra.Command {
3535
cmd.AddCommand(NewCompletionCmd())
3636
cmd.AddCommand(NewTestCmd())
3737
cmd.AddCommand(NewPrintDepsCmd())
38+
cmd.AddCommand(NewMigrateCmd())
3839

3940
return cmd
4041
}

Diff for: hack/image/build-ansible-image.sh

+19-3
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,24 @@
22

33
set -eux
44

5+
source hack/lib/test_lib.sh
6+
7+
ROOTDIR="$(pwd)"
8+
GOTMP="$(mktemp -d -p $GOPATH/src)"
9+
trap_add 'rm -rf $GOTMP' EXIT
10+
BASEIMAGEDIR="$GOTMP/ansible-operator"
11+
mkdir -p "$BASEIMAGEDIR"
12+
513
# build operator binary and base image
6-
go build -o test/ansible-operator/ansible-operator test/ansible-operator/cmd/ansible-operator/main.go
7-
pushd test/ansible-operator
8-
docker build -t "$1" .
14+
pushd "$BASEIMAGEDIR"
15+
go run "$ROOTDIR/commands/ansible-operator-base/main.go"
16+
dep ensure
17+
18+
# overwrite operator-sdk source with the latest source from the local checkout
19+
pushd vendor/github.com/operator-framework/
20+
rm -Rf operator-sdk/*
21+
cp -a "$ROOTDIR"/{pkg,version,LICENSE} operator-sdk/
22+
popd
23+
24+
operator-sdk build $1
925
popd

Diff for: hack/tests/e2e-ansible.sh

+104-69
Original file line numberDiff line numberDiff line change
@@ -1,99 +1,134 @@
11
#!/usr/bin/env bash
22

3+
set -eux
4+
35
source hack/lib/test_lib.sh
46

57
DEST_IMAGE="quay.io/example/memcached-operator:v0.0.2"
6-
7-
set -ex
8+
ROOTDIR="$(pwd)"
9+
GOTMP="$(mktemp -d -p $GOPATH/src)"
10+
trap_add 'rm -rf $GOTMP' EXIT
11+
12+
deploy_operator() {
13+
kubectl create -f "$OPERATORDIR/deploy/service_account.yaml"
14+
kubectl create -f "$OPERATORDIR/deploy/role.yaml"
15+
kubectl create -f "$OPERATORDIR/deploy/role_binding.yaml"
16+
kubectl create -f "$OPERATORDIR/deploy/crds/ansible_v1alpha1_memcached_crd.yaml"
17+
kubectl create -f "$OPERATORDIR/deploy/operator.yaml"
18+
}
19+
20+
remove_operator() {
21+
kubectl delete --ignore-not-found=true -f "$OPERATORDIR/deploy/service_account.yaml"
22+
kubectl delete --ignore-not-found=true -f "$OPERATORDIR/deploy/role.yaml"
23+
kubectl delete --ignore-not-found=true -f "$OPERATORDIR/deploy/role_binding.yaml"
24+
kubectl delete --ignore-not-found=true -f "$OPERATORDIR/deploy/crds/ansible_v1alpha1_memcached_crd.yaml"
25+
kubectl delete --ignore-not-found=true -f "$OPERATORDIR/deploy/operator.yaml"
26+
}
27+
28+
test_operator() {
29+
# wait for operator pod to run
30+
if ! timeout 1m kubectl rollout status deployment/memcached-operator;
31+
then
32+
echo FAIL: operator failed to run
33+
kubectl logs deployment/memcached-operator
34+
exit 1
35+
fi
36+
37+
# create CR
38+
kubectl create -f deploy/crds/ansible_v1alpha1_memcached_cr.yaml
39+
if ! timeout 20s bash -c -- 'until kubectl get deployment -l app=memcached | grep memcached; do sleep 1; done';
40+
then
41+
echo FAIL: operator failed to create memcached Deployment
42+
kubectl logs deployment/memcached-operator
43+
exit 1
44+
fi
45+
memcached_deployment=$(kubectl get deployment -l app=memcached -o jsonpath="{..metadata.name}")
46+
if ! timeout 1m kubectl rollout status deployment/${memcached_deployment};
47+
then
48+
echo FAIL: memcached Deployment failed rollout
49+
kubectl logs deployment/${memcached_deployment}
50+
exit 1
51+
fi
52+
53+
54+
# make a configmap that the finalizer should remove
55+
kubectl create configmap deleteme
56+
trap_add 'kubectl delete --ignore-not-found configmap deleteme' EXIT
57+
58+
kubectl delete -f ${OPERATORDIR}/deploy/crds/ansible_v1alpha1_memcached_cr.yaml --wait=true
59+
# if the finalizer did not delete the configmap...
60+
if kubectl get configmap deleteme 2> /dev/null;
61+
then
62+
echo FAIL: the finalizer did not delete the configmap
63+
kubectl logs deployment/memcached-operator
64+
exit 1
65+
fi
66+
67+
# The deployment should get garbage collected, so we expect to fail getting the deployment.
68+
if ! timeout 20s bash -c -- "while kubectl get deployment ${memcached_deployment} 2> /dev/null; do sleep 1; done";
69+
then
70+
echo FAIL: memcached Deployment did not get garbage collected
71+
kubectl logs deployment/memcached-operator
72+
exit 1
73+
fi
74+
75+
## TODO enable when this is fixed: https://github.com/operator-framework/operator-sdk/issues/818
76+
# if kubectl logs deployment/memcached-operator | grep -i error;
77+
# then
78+
# echo FAIL: the operator log includes errors
79+
# kubectl logs deployment/memcached-operator
80+
# exit 1
81+
# fi
82+
}
883

984
# switch to the "default" namespace if on openshift, to match the minikube test
1085
if which oc 2>/dev/null; then oc project default; fi
1186

12-
# Make a test directory for Ansible tests so we avoid using default GOPATH.
13-
# Save test directory so we can delete it on exit.
14-
ANSIBLE_TEST_DIR="$(mktemp -d)"
15-
trap_add 'rm -rf $ANSIBLE_TEST_DIR' EXIT
16-
cp -a test/ansible-* "$ANSIBLE_TEST_DIR"
17-
pushd "$ANSIBLE_TEST_DIR"
18-
19-
# Ansible tests should not run in a Golang environment.
20-
unset GOPATH GOROOT
21-
2287
# create and build the operator
88+
pushd "$GOTMP"
2389
operator-sdk new memcached-operator --api-version=ansible.example.com/v1alpha1 --kind=Memcached --type=ansible
24-
cp ansible-memcached/tasks.yml memcached-operator/roles/Memcached/tasks/main.yml
25-
cp ansible-memcached/defaults.yml memcached-operator/roles/Memcached/defaults/main.yml
26-
cp -a ansible-memcached/memfin memcached-operator/roles/
27-
cat ansible-memcached/watches-finalizer.yaml >> memcached-operator/watches.yaml
90+
cp "$ROOTDIR/test/ansible-memcached/tasks.yml" memcached-operator/roles/Memcached/tasks/main.yml
91+
cp "$ROOTDIR/test/ansible-memcached/defaults.yml" memcached-operator/roles/Memcached/defaults/main.yml
92+
cp -a "$ROOTDIR/test/ansible-memcached/memfin" memcached-operator/roles/
93+
cat "$ROOTDIR/test/ansible-memcached/watches-finalizer.yaml" >> memcached-operator/watches.yaml
2894

2995
pushd memcached-operator
3096
sed -i 's|\(FROM quay.io/operator-framework/ansible-operator\)\(:.*\)\?|\1:dev|g' build/Dockerfile
3197
operator-sdk build "$DEST_IMAGE"
3298
sed -i "s|REPLACE_IMAGE|$DEST_IMAGE|g" deploy/operator.yaml
3399
sed -i 's|Always|Never|g' deploy/operator.yaml
34100

35-
DIR2="$(pwd)"
36-
# deploy the operator
37-
kubectl create -f deploy/service_account.yaml
38-
trap_add 'kubectl delete -f ${DIR2}/deploy/service_account.yaml' EXIT
39-
kubectl create -f deploy/role.yaml
40-
trap_add 'kubectl delete -f ${DIR2}/deploy/role.yaml' EXIT
41-
kubectl create -f deploy/role_binding.yaml
42-
trap_add 'kubectl delete -f ${DIR2}/deploy/role_binding.yaml' EXIT
43-
kubectl create -f deploy/crds/ansible_v1alpha1_memcached_crd.yaml
44-
trap_add 'kubectl delete -f ${DIR2}/deploy/crds/ansible_v1alpha1_memcached_crd.yaml' EXIT
45-
kubectl create -f deploy/operator.yaml
46-
trap_add 'kubectl delete -f ${DIR2}/deploy/operator.yaml' EXIT
47-
48-
# wait for operator pod to run
49-
if ! timeout 1m kubectl rollout status deployment/memcached-operator;
50-
then
51-
kubectl logs deployment/memcached-operator
52-
exit 1
53-
fi
101+
OPERATORDIR="$(pwd)"
54102

55-
# create CR
56-
kubectl create -f deploy/crds/ansible_v1alpha1_memcached_cr.yaml
57-
if ! timeout 20s bash -c -- 'until kubectl get deployment -l app=memcached | grep memcached; do sleep 1; done';
58-
then
59-
kubectl logs deployment/memcached-operator
60-
exit 1
61-
fi
62-
memcached_deployment=$(kubectl get deployment -l app=memcached -o jsonpath="{..metadata.name}")
63-
if ! timeout 1m kubectl rollout status deployment/${memcached_deployment};
64-
then
65-
kubectl logs deployment/${memcached_deployment}
66-
exit 1
67-
fi
103+
deploy_operator
104+
trap_add 'remove_operator' EXIT
105+
test_operator
106+
remove_operator
68107

69-
# make a configmap that the finalizer should remove
70-
kubectl create configmap deleteme
71-
trap_add 'kubectl delete --ignore-not-found configmap deleteme' EXIT
108+
echo "###"
109+
echo "### Base image testing passed"
110+
echo "### Now testing migrate to hybrid operator"
111+
echo "###"
72112

73-
kubectl delete -f ${DIR2}/deploy/crds/ansible_v1alpha1_memcached_cr.yaml --wait=true
74-
# if the finalizer did not delete the configmap...
75-
if kubectl get configmap deleteme;
76-
then
77-
echo FAIL: the finalizer did not delete the configmap
78-
kubectl logs deployment/memcached-operator
79-
exit 1
80-
fi
113+
operator-sdk migrate
81114

82-
# The deployment should get garbage collected, so we expect to fail getting the deployment.
83-
if ! timeout 20s bash -c -- "while kubectl get deployment ${memcached_deployment}; do sleep 1; done";
115+
if [[ ! -e build/Dockerfile.sdkold ]];
84116
then
85-
kubectl logs deployment/memcached-operator
117+
echo FAIL the old Dockerful should have been renamed to Dockerfile.sdkold
86118
exit 1
87119
fi
88120

121+
dep ensure
122+
# overwrite operator-sdk source with the latest source from the local checkout
123+
pushd vendor/github.com/operator-framework/
124+
rm -Rf operator-sdk/*
125+
cp -a "$ROOTDIR"/{pkg,version,LICENSE} operator-sdk/
126+
popd
127+
128+
operator-sdk build "$DEST_IMAGE"
89129

90-
## TODO enable when this is fixed: https://github.com/operator-framework/operator-sdk/issues/818
91-
# if kubectl logs deployment/memcached-operator | grep -i error;
92-
# then
93-
# echo FAIL: the operator log includes errors
94-
# kubectl logs deployment/memcached-operator
95-
# exit 1
96-
# fi
130+
deploy_operator
131+
test_operator
97132

98133
popd
99134
popd

0 commit comments

Comments
 (0)