Skip to content

Commit 5f7be01

Browse files
hasbro17Shawn Hurley
authored andcommitted
*: update README and fix templates and commands (#542)
1 parent b010221 commit 5f7be01

File tree

8 files changed

+54
-35
lines changed

8 files changed

+54
-35
lines changed

README.md

Lines changed: 25 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -58,37 +58,48 @@ Create and deploy an app-operator using the SDK CLI:
5858
```sh
5959
# Create an app-operator project that defines the App CR.
6060
$ mkdir -p $GOPATH/src/github.com/example-inc/
61+
# Create a new app-operator project
6162
$ cd $GOPATH/src/github.com/example-inc/
62-
$ operator-sdk new app-operator --api-version=app.example.com/v1alpha1 --kind=App
63+
$ operator-sdk new app-operator
6364
$ cd app-operator
6465

66+
# Add a new API for the custom resource AppService
67+
$ operator-sdk add api --api-version=app.example.com/v1alpha1 --kind=AppService
68+
69+
# Add a new controller that watches for AppService
70+
$ operator-sdk add controller --api-version=app.example.com/v1alpha1 --kind=AppService
71+
6572
# Build and push the app-operator image to a public registry such as quay.io
6673
$ operator-sdk build quay.io/example/app-operator
6774
$ docker push quay.io/example/app-operator
6875

6976
# Update the operator manifest to use the built image name
7077
$ sed -i 's|REPLACE_IMAGE|quay.io/example/app-operator|g' deploy/operator.yaml
7178

79+
# Setup RBAC
80+
$ kubectl create -f deploy/role.yaml
81+
$ kubectl create -f deploy/role_binding.yaml
82+
# TODO: kubectl create -f deploy/service_account.yaml
83+
# Setup the CRD
84+
$ kubectl create -f deploy/crds/app_v1alpha1_appservice_crd.yaml
7285
# Deploy the app-operator
73-
$ kubectl create -f deploy/sa.yaml
74-
$ kubectl create -f deploy/rbac.yaml
75-
$ kubectl create -f deploy/crd.yaml
7686
$ kubectl create -f deploy/operator.yaml
7787

78-
# By default, creating a custom resource (App) triggers the app-operator to deploy a busybox pod
79-
$ kubectl create -f deploy/cr.yaml
88+
# Create an AppService CR
89+
# The default controller will watch for AppService objects and create a pod for each CR
90+
$ kubectl create -f deploy/crds/app_v1alpha1_appservice_cr.yaml
8091

81-
# Verify that the busybox pod is created
82-
$ kubectl get pod -l app=busy-box
83-
NAME READY STATUS RESTARTS AGE
84-
busy-box 1/1 Running 0 50s
92+
# Verify that a pod is created
93+
$ kubectl get pod -l app=example-appservice
94+
NAME READY STATUS RESTARTS AGE
95+
example-appservice-pod 1/1 Running 0 1m
8596

8697
# Cleanup
87-
$ kubectl delete -f deploy/cr.yaml
88-
$ kubectl delete -f deploy/crd.yaml
98+
$ kubectl delete -f deploy/app_v1alpha1_appservice_cr.yaml
8999
$ kubectl delete -f deploy/operator.yaml
90-
$ kubectl delete -f deploy/rbac.yaml
91-
$ kubectl delete -f deploy/sa.yaml
100+
$ kubectl delete -f deploy/role.yaml
101+
$ kubectl delete -f deploy/role_binding.yaml
102+
$ kubectl delete -f deploy/app_v1alpha1_appservice_crd.yaml
92103
```
93104

94105
## User Guide

commands/operator-sdk/cmd/add/api.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ import (
2424
"path/filepath"
2525

2626
"github.com/operator-framework/operator-sdk/commands/operator-sdk/cmd/cmdutil"
27+
"github.com/operator-framework/operator-sdk/commands/operator-sdk/cmd/generate"
2728
"github.com/operator-framework/operator-sdk/pkg/scaffold"
2829

2930
"github.com/ghodss/yaml"
@@ -170,6 +171,9 @@ func apiRun(cmd *cobra.Command, args []string) {
170171
if err := updateRoleForResource(r, fullProjectPath); err != nil {
171172
log.Fatalf("failed to update the RBAC manifest for the resource (%v, %v): %v", r.APIVersion, r.Kind, err)
172173
}
174+
175+
// Run k8s codegen for deepcopy
176+
generate.K8sCodegen()
173177
}
174178

175179
func updateRoleForResource(r *scaffold.Resource, fullProjectPath string) error {

commands/operator-sdk/cmd/build.go

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -135,14 +135,14 @@ func renderTestManifest(image string) {
135135
}
136136

137137
const (
138-
build = "./tmp/build/build.sh"
138+
build = "./build/build.sh"
139139
configYaml = "./config/config.yaml"
140140
mainGo = "./cmd/%s/main.go"
141141
)
142142

143143
func buildFunc(cmd *cobra.Command, args []string) {
144144
if len(args) != 1 {
145-
cmdError.ExitWithError(cmdError.ExitBadArgs, fmt.Errorf("build command needs exactly 1 argument"))
145+
log.Fatalf("build command needs 1 argument.")
146146
}
147147

148148
cmdutil.MustInProjectRoot()
@@ -158,7 +158,7 @@ func buildFunc(cmd *cobra.Command, args []string) {
158158
buildCmd.Env = goBuildEnv
159159
o, err := buildCmd.CombinedOutput()
160160
if err != nil {
161-
log.Fatalf("failed to build operator binary: %v (%v)", err, string(o))
161+
cmdError.ExitWithError(cmdError.ExitError, fmt.Errorf("failed to build operator binary: %v (%v)", err, string(o)))
162162
}
163163
fmt.Fprintln(os.Stdout, string(o))
164164
}
@@ -201,6 +201,12 @@ func buildFunc(cmd *cobra.Command, args []string) {
201201
// create test-pod.yaml as well as check image name of deployments in namespaced manifest
202202
renderTestManifest(image)
203203
}
204+
dbcmd := exec.Command("docker", "build", ".", "-f", "build/Dockerfile", "-t", image)
205+
o, err = dbcmd.CombinedOutput()
206+
if err != nil {
207+
log.Fatalf("failed to output build image %v: %v (%v)", image, string(o), err)
208+
}
209+
fmt.Fprintln(os.Stdout, string(o))
204210
}
205211

206212
func mainExists() bool {

commands/operator-sdk/cmd/new.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -187,7 +187,7 @@ func doScaffold() {
187187
}
188188

189189
// create build dir
190-
buildDir := filepath.Join(fullProjectPath, "pkg", "build")
190+
buildDir := filepath.Join(fullProjectPath, "build")
191191
if err := os.MkdirAll(buildDir, defaultDirFileMode); err != nil {
192192
log.Fatalf("failed to create %v: %v", buildDir, err)
193193
}

pkg/scaffold/cmd.go

Lines changed: 7 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -55,17 +55,16 @@ import (
5555
5656
k8sutil "github.com/operator-framework/operator-sdk/pkg/util/k8sutil"
5757
sdkVersion "github.com/operator-framework/operator-sdk/version"
58-
"github.com/sirupsen/logrus"
5958
_ "k8s.io/client-go/plugin/pkg/client/auth/gcp"
6059
"sigs.k8s.io/controller-runtime/pkg/client/config"
6160
"sigs.k8s.io/controller-runtime/pkg/manager"
6261
"sigs.k8s.io/controller-runtime/pkg/runtime/signals"
6362
)
6463
6564
func printVersion() {
66-
logrus.Infof("Go Version: %s", runtime.Version())
67-
logrus.Infof("Go OS/Arch: %s/%s", runtime.GOOS, runtime.GOARCH)
68-
logrus.Infof("operator-sdk Version: %v", sdkVersion.Version)
65+
log.Printf("Go Version: %s", runtime.Version())
66+
log.Printf("Go OS/Arch: %s/%s", runtime.GOOS, runtime.GOARCH)
67+
log.Printf("operator-sdk Version: %v", sdkVersion.Version)
6968
}
7069
7170
func main() {
@@ -74,10 +73,10 @@ func main() {
7473
7574
namespace, err := k8sutil.GetWatchNamespace()
7675
if err != nil {
77-
log.Fatal("Failed to get watch namespace: %v", err)
76+
log.Fatalf("Failed to get watch namespace: %v", err)
7877
}
7978
80-
// Expose metrics port after SDK uses controller-runtime's dynamic client
79+
// TODO: Expose metrics port after SDK uses controller-runtime's dynamic client
8180
// sdk.ExposeMetricsPort()
8281
8382
// Get a config to talk to the apiserver
@@ -87,14 +86,12 @@ func main() {
8786
}
8887
8988
// Create a new Cmd to provide shared dependencies and start components
90-
// TODO: Need to support namespacing the manager upstream to avoid cluster wide permissions
91-
// https://github.com/kubernetes-sigs/controller-runtime/issues/124
9289
mgr, err := manager.New(cfg, manager.Options{Namespace: namespace})
9390
if err != nil {
9491
log.Fatal(err)
9592
}
9693
97-
log.Printf("Registering Components.")
94+
log.Print("Registering Components.")
9895
9996
// Setup Scheme for all resources
10097
if err := apis.AddToScheme(mgr.GetScheme()); err != nil {
@@ -106,7 +103,7 @@ func main() {
106103
log.Fatal(err)
107104
}
108105
109-
log.Printf("Starting the Cmd.")
106+
log.Print("Starting the Cmd.")
110107
111108
// Start the Cmd
112109
log.Fatal(mgr.Start(signals.SetupSignalHandler()))

pkg/scaffold/controller_kind.go

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -58,14 +58,11 @@ import (
5858
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
5959
"k8s.io/apimachinery/pkg/runtime"
6060
"k8s.io/apimachinery/pkg/types"
61-
"sigs.k8s.io/controller-runtime/pkg/cache"
6261
"sigs.k8s.io/controller-runtime/pkg/client"
6362
"sigs.k8s.io/controller-runtime/pkg/controller"
6463
"sigs.k8s.io/controller-runtime/pkg/controller/controllerutil"
65-
"sigs.k8s.io/controller-runtime/pkg/event"
6664
"sigs.k8s.io/controller-runtime/pkg/handler"
6765
"sigs.k8s.io/controller-runtime/pkg/manager"
68-
"sigs.k8s.io/controller-runtime/pkg/predicate"
6966
"sigs.k8s.io/controller-runtime/pkg/reconcile"
7067
"sigs.k8s.io/controller-runtime/pkg/source"
7168
)
@@ -102,7 +99,7 @@ func add(mgr manager.Manager, r reconcile.Reconciler) error {
10299
103100
// TODO(user): Modify this to be the types you create that are owned by the primary resource
104101
// Watch for changes to secondary resource Pods and requeue the owner {{ .Resource.Kind }}
105-
err = c.Watch(&source.Kind{Type: &appsv1.Deployment{}}, &handler.EnqueueRequestForOwner{
102+
err = c.Watch(&source.Kind{Type: &corev1.Pod{}}, &handler.EnqueueRequestForOwner{
106103
IsController: true,
107104
OwnerType: &{{ .Resource.Group}}{{ .Resource.Version }}.{{ .Resource.Kind }}{},
108105
})
@@ -132,6 +129,8 @@ type Reconcile{{ .Resource.Kind }} struct {
132129
// The Controller will requeue the Request to be processed again if the returned error is non-nil or
133130
// Result.Requeue is true, otherwise upon completion it will remove the work from the queue.
134131
func (r *Reconcile{{ .Resource.Kind }}) Reconcile(request reconcile.Request) (reconcile.Result, error) {
132+
log.Printf("Reconciling {{ .Resource.Kind }} %s/%s\n", request.Namespace, request.Name)
133+
135134
// Fetch the {{ .Resource.Kind }} instance
136135
instance := &{{ .Resource.Group}}{{ .Resource.Version }}.{{ .Resource.Kind }}{}
137136
err := r.client.Get(context.TODO(), request.NamespacedName, instance)
@@ -171,11 +170,12 @@ func (r *Reconcile{{ .Resource.Kind }}) Reconcile(request reconcile.Request) (re
171170
}
172171
173172
// Pod already exists - don't requeue
173+
log.Printf("Skip reconcile: Pod %s/%s already exists", found.Namespace, found.Name)
174174
return reconcile.Result{}, nil
175175
}
176176
177177
// newPodForCR returns a busybox pod with the same name/namespace as the cr
178-
func newPodForCR(cr *&{{ .Resource.Group}}{{ .Resource.Version }}.{{ .Resource.Kind }}) *corev1.Pod {
178+
func newPodForCR(cr *{{ .Resource.Group}}{{ .Resource.Version }}.{{ .Resource.Kind }}) *corev1.Pod {
179179
labels := map[string]string{
180180
"app": cr.Name,
181181
}

pkg/scaffold/gopkgtoml.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,10 +64,10 @@ required = [
6464
[prune]
6565
go-tests = true
6666
non-go = true
67-
unused-packages = true
6867
6968
[[prune.project]]
7069
name = "k8s.io/code-generator"
7170
non-go = false
7271
unused-packages = false
72+
7373
`

pkg/scaffold/operator.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,8 @@ spec:
6060
spec:
6161
containers:
6262
- name: {{.ProjectName}}
63-
image: REPLACE_IMAGE // replace this with the built image.
63+
# Replace this with the built image name
64+
image: REPLACE_IMAGE
6465
ports:
6566
- containerPort: 60000
6667
name: metrics

0 commit comments

Comments
 (0)