Giter Site home page Giter Site logo

sample-controller's People

Contributors

alexzielenski avatar alvaroaleman avatar apelisse avatar ash2k avatar cblecker avatar cici37 avatar danielqsj avatar deads2k avatar dims avatar humblec avatar ixdy avatar jefftree avatar jiahuif avatar jpbetz avatar justaugustus avatar k8s-publish-robot avatar k8s-publishing-bot avatar liggitt avatar madhavjivrajani avatar markusthoemmes avatar mikedanese avatar munnerz avatar nikhita avatar pacoxu avatar pohly avatar roycaihw avatar skitt avatar sttts avatar thockin avatar wojtek-t avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

sample-controller's Issues

Using sample-controller to create a custom version - it doesn't work

I have created a project to create a custom sample-controller.

  1. I updated pkg/api files to setup Runner and RunnerList types to replace Foo and FooList
  2. I created new client code using update-codegen.sh
  3. I modified main.go and controller.go appropriately.

When I build and run I get the following message repeated over and over

E1014 15:31:57.075937 32420 reflector.go:134] github.com/customcontroller/pkg/client/informers/externalversions/factory.go:117: Failed to list *v1alpha1.Runner: no kind "runnerList" is registered for version "customcontroller.k8s.io/v1alpha1" in scheme "github.com/customcontroller/pkg/client/clientset/versioned/scheme/register.go:30"

From this error message can you tell me what I did wrong or give me a hint where I should look ?

godep restore failed

run godep restore failed for downloading the cznic code, for gitlab, the git clone should have the suffix.git, like this git clone https://gitlab.com/cznic/cc.git

[root@localhost sample-controller]# godep restore
cd .; git clone https://gitlab.com/cznic/cc /root/go/src/modernc.org/cc
Cloning into '/root/go/src/modernc.org/cc'...
error: RPC failed; result=22, HTTP code = 404
fatal: The remote end hung up unexpectedly
godep: error downloading dep (modernc.org/cc): exit status 128
cd .; git clone https://gitlab.com/cznic/golex /root/go/src/modernc.org/golex
Cloning into '/root/go/src/modernc.org/golex'...
error: RPC failed; result=22, HTTP code = 404
fatal: The remote end hung up unexpectedly
godep: error downloading dep (modernc.org/golex): exit status 128
cd .; git clone https://gitlab.com/cznic/mathutil /root/go/src/modernc.org/mathutil
Cloning into '/root/go/src/modernc.org/mathutil'...
error: RPC failed; result=22, HTTP code = 404
fatal: The remote end hung up unexpectedly
godep: error downloading dep (modernc.org/mathutil): exit status 128
cd .; git clone https://gitlab.com/cznic/strutil /root/go/src/modernc.org/strutil
Cloning into '/root/go/src/modernc.org/strutil'...
error: RPC failed; result=22, HTTP code = 404
fatal: The remote end hung up unexpectedly
godep: error downloading dep (modernc.org/strutil): exit status 128
cd .; git clone https://gitlab.com/cznic/xc /root/go/src/modernc.org/xc
Cloning into '/root/go/src/modernc.org/xc'...
error: RPC failed; result=22, HTTP code = 404
fatal: The remote end hung up unexpectedly
godep: error downloading dep (modernc.org/xc): exit status 128
godep: Error downloading some deps. Aborting restore and check.

What is the correct way for running update-codegen and go test?

I'm having trouble identifying the correct way to run the update-codegen.sh and go test ./...

I'm working on a project that also has kubernetes controllers and it has go modules setup within it. It's very similar to this sample-controller project. We are looking for a good way to get the k8s.io/code-generator dependency in the vendor directory. Although it seems that this sample-controller project doesn't have a vendor directory in the first place.

Q1: Is it intended for us to run go mod vendor to get the codegen dependencies in the correct place?
Q2: Are we expected to use the latest version of k8s.io/code-generator? That is, I'm having a hard time pinning the version of k8s.io/code-generator.

Environment

$ go version
go version go1.12.4 darwin/amd64
$ go env
GOARCH="amd64"
GOBIN=""
GOCACHE="/Users/wfernandes/Library/Caches/go-build"
GOEXE=""
GOFLAGS=""
GOHOSTARCH="amd64"
GOHOSTOS="darwin"
GOOS="darwin"
GOPATH="/Users/wfernandes/go"
GOPROXY=""
GORACE=""
GOROOT="/usr/local/go"
GOTMPDIR=""
GOTOOLDIR="/usr/local/go/pkg/tool/darwin_amd64"
GCCGO="gccgo"
CC="clang"
CXX="clang++"
CGO_ENABLED="1"
GOMOD=""
CGO_CFLAGS="-g -O2"
CGO_CPPFLAGS=""
CGO_CXXFLAGS="-g -O2"
CGO_FFLAGS="-g -O2"
CGO_LDFLAGS="-g -O2"
PKG_CONFIG="pkg-config"
GOGCCFLAGS="-fPIC -m64 -pthread -fno-caret-diagnostics -Qunused-arguments -fmessage-length=0 -fdebug-prefix-map=/var/folders/w9/_qjbbv15667cxfs7vpply4bh0000gn/T/go-build133647668=/tmp/go-build -gno-record-gcc-switches -fno-common"

Steps to Reproduce

  1. Ensure your GOPATH is set correctly
  2. go get github.com/kubernetes/sample-controller
    I get the following output when I do the above go get
    $ go get github.com/kubernetes/sample-controller
    # k8s.io/sample-controller/pkg/generated/clientset/versioned/typed/samplecontroller/v1alpha1
    ../../k8s.io/sample-controller/pkg/generated/clientset/versioned/typed/samplecontroller/v1alpha1/samplecontroller _client.go:73:45: scheme.Codecs.WithoutConversion undefined (type serializer.CodecFactory has no field or method WithoutConversion)
    
  3. cd $GOPATH/src/github.com/kubernetes/sample-controller
  4. ./hack/update-codegen
    I get the following output
    ./hack/update-codegen.sh: line 28: ../code-generator/generate-groups.sh: No such file or directory
    
  5. Upon inspection of the script, I noticed that it is referring to the vendor directory.
  6. GO111MODULE=on go mod vendor
    This creates a vendor directory in the project with the k8s.io/code-generator dependency.
  7. ./hack/update-codegen.sh
    I get the following output.
     ./hack/update-codegen.sh: line 28: ./vendor/k8s.io/code-generator/generate-groups.sh: Permission denied
    
  8. I edited the hack/update-codegen.sh script by updating the command to the following
     bash "${CODEGEN_PKG}"/generate-groups.sh "deepcopy,client,informer,lister" ....
    
  9. ./hack/update-codegen.sh
    This gets update-codegen to work!!
    Generating deepcopy funcs
    Generating clientset for samplecontroller:v1alpha1 at k8s.io/sample-controller/pkg/generated/clientset
    Generating listers for samplecontroller:v1alpha1 at k8s.io/sample-controller/pkg/generated/listers
    Generating informers for samplecontroller:v1alpha1 at k8s.io/sample-controller/pkg/generated/informers
    
  10. But now when I run go test ./...
# k8s.io/sample-controller/pkg/generated/clientset/versioned/typed/samplecontroller/v1alpha1
../../../k8s.io/sample-controller/pkg/generated/clientset/versioned/typed/samplecontroller/v1alpha1/samplecontroller_client.go:73:45: scheme.Codecs.WithoutConversion undefined (type serializer.CodecFactory has no field or method WithoutConversion)
# github.com/kubernetes/sample-controller/pkg/generated/clientset/versioned/scheme
pkg/generated/clientset/versioned/scheme/register.go:34:26: cannot use v1alpha1.AddToScheme (type func(*"k8s.io/apimachinery/pkg/runtime".Scheme) error) as type func(*"github.com/kubernetes/sample-controller/vendor/k8s.io/apimachinery/pkg/runtime".Scheme) error in array or slice literal
# github.com/kubernetes/sample-controller/pkg/generated/listers/samplecontroller/v1alpha1
pkg/generated/listers/samplecontroller/v1alpha1/foo.go:91:51: cannot use v1alpha1.Resource("foo") (type "k8s.io/apimachinery/pkg/runtime/schema".GroupResource) as type "github.com/kubernetes/sample-controller/vendor/k8s.io/apimachinery/pkg/runtime/schema".GroupResource in argument to "github.com/kubernetes/sample-controller/vendor/k8s.io/apimachinery/pkg/api/errors".NewNotFound
FAIL	github.com/kubernetes/sample-controller [build failed]
?   	github.com/kubernetes/sample-controller/pkg/apis/samplecontroller	[no test files]
# github.com/kubernetes/sample-controller/pkg/generated/clientset/versioned/typed/samplecontroller/v1alpha1
pkg/generated/clientset/versioned/typed/samplecontroller/v1alpha1/foo.go:73:19: cannot use scheme.ParameterCodec (type "k8s.io/apimachinery/pkg/runtime".ParameterCodec) as type "github.com/kubernetes/sample-controller/vendor/k8s.io/apimachinery/pkg/runtime".ParameterCodec in argument to c.client.Get().Namespace(c.ns).Resource("foos").Name(name).VersionedParams:
	"k8s.io/apimachinery/pkg/runtime".ParameterCodec does not implement "github.com/kubernetes/sample-controller/vendor/k8s.io/apimachinery/pkg/runtime".ParameterCodec (wrong type for DecodeParameters method)
		have DecodeParameters(url.Values, "k8s.io/apimachinery/pkg/runtime/schema".GroupVersion, "k8s.io/apimachinery/pkg/runtime".Object) error
		want DecodeParameters(url.Values, "github.com/kubernetes/sample-controller/vendor/k8s.io/apimachinery/pkg/runtime/schema".GroupVersion, "github.com/kubernetes/sample-controller/vendor/k8s.io/apimachinery/pkg/runtime".Object) error
pkg/generated/clientset/versioned/typed/samplecontroller/v1alpha1/foo.go:75:7: cannot use result (type *v1alpha1.Foo) as type "github.com/kubernetes/sample-controller/vendor/k8s.io/apimachinery/pkg/runtime".Object in argument to c.client.Get().Namespace(c.ns).Resource("foos").Name(name).VersionedParams(&options, scheme.ParameterCodec).Do().Into:
	*v1alpha1.Foo does not implement "github.com/kubernetes/sample-controller/vendor/k8s.io/apimachinery/pkg/runtime".Object (wrong type for DeepCopyObject method)
		have DeepCopyObject() "k8s.io/apimachinery/pkg/runtime".Object
		want DeepCopyObject() "github.com/kubernetes/sample-controller/vendor/k8s.io/apimachinery/pkg/runtime".Object
pkg/generated/clientset/versioned/typed/samplecontroller/v1alpha1/foo.go:89:19: cannot use scheme.ParameterCodec (type "k8s.io/apimachinery/pkg/runtime".ParameterCodec) as type "github.com/kubernetes/sample-controller/vendor/k8s.io/apimachinery/pkg/runtime".ParameterCodec in argument to c.client.Get().Namespace(c.ns).Resource("foos").VersionedParams:
	"k8s.io/apimachinery/pkg/runtime".ParameterCodec does not implement "github.com/kubernetes/sample-controller/vendor/k8s.io/apimachinery/pkg/runtime".ParameterCodec (wrong type for DecodeParameters method)
		have DecodeParameters(url.Values, "k8s.io/apimachinery/pkg/runtime/schema".GroupVersion, "k8s.io/apimachinery/pkg/runtime".Object) error
		want DecodeParameters(url.Values, "github.com/kubernetes/sample-controller/vendor/k8s.io/apimachinery/pkg/runtime/schema".GroupVersion, "github.com/kubernetes/sample-controller/vendor/k8s.io/apimachinery/pkg/runtime".Object) error
pkg/generated/clientset/versioned/typed/samplecontroller/v1alpha1/foo.go:92:7: cannot use result (type *v1alpha1.FooList) as type "github.com/kubernetes/sample-controller/vendor/k8s.io/apimachinery/pkg/runtime".Object in argument to c.client.Get().Namespace(c.ns).Resource("foos").VersionedParams(&opts, scheme.ParameterCodec).Timeout(timeout).Do().Into:
	*v1alpha1.FooList does not implement "github.com/kubernetes/sample-controller/vendor/k8s.io/apimachinery/pkg/runtime".Object (wrong type for DeepCopyObject method)
		have DeepCopyObject() "k8s.io/apimachinery/pkg/runtime".Object
		want DeepCopyObject() "github.com/kubernetes/sample-controller/vendor/k8s.io/apimachinery/pkg/runtime".Object
pkg/generated/clientset/versioned/typed/samplecontroller/v1alpha1/foo.go:106:19: cannot use scheme.ParameterCodec (type "k8s.io/apimachinery/pkg/runtime".ParameterCodec) as type "github.com/kubernetes/sample-controller/vendor/k8s.io/apimachinery/pkg/runtime".ParameterCodec in argument to c.client.Get().Namespace(c.ns).Resource("foos").VersionedParams:
	"k8s.io/apimachinery/pkg/runtime".ParameterCodec does not implement "github.com/kubernetes/sample-controller/vendor/k8s.io/apimachinery/pkg/runtime".ParameterCodec (wrong type for DecodeParameters method)
		have DecodeParameters(url.Values, "k8s.io/apimachinery/pkg/runtime/schema".GroupVersion, "k8s.io/apimachinery/pkg/runtime".Object) error
		want DecodeParameters(url.Values, "github.com/kubernetes/sample-controller/vendor/k8s.io/apimachinery/pkg/runtime/schema".GroupVersion, "github.com/kubernetes/sample-controller/vendor/k8s.io/apimachinery/pkg/runtime".Object) error
pkg/generated/clientset/versioned/typed/samplecontroller/v1alpha1/foo.go:119:7: cannot use result (type *v1alpha1.Foo) as type "github.com/kubernetes/sample-controller/vendor/k8s.io/apimachinery/pkg/runtime".Object in argument to c.client.Post().Namespace(c.ns).Resource("foos").Body(foo).Do().Into:
	*v1alpha1.Foo does not implement "github.com/kubernetes/sample-controller/vendor/k8s.io/apimachinery/pkg/runtime".Object (wrong type for DeepCopyObject method)
		have DeepCopyObject() "k8s.io/apimachinery/pkg/runtime".Object
		want DeepCopyObject() "github.com/kubernetes/sample-controller/vendor/k8s.io/apimachinery/pkg/runtime".Object
pkg/generated/clientset/versioned/typed/samplecontroller/v1alpha1/foo.go:132:7: cannot use result (type *v1alpha1.Foo) as type "github.com/kubernetes/sample-controller/vendor/k8s.io/apimachinery/pkg/runtime".Object in argument to c.client.Put().Namespace(c.ns).Resource("foos").Name(foo.ObjectMeta.Name).Body(foo).Do().Into:
	*v1alpha1.Foo does not implement "github.com/kubernetes/sample-controller/vendor/k8s.io/apimachinery/pkg/runtime".Object (wrong type for DeepCopyObject method)
		have DeepCopyObject() "k8s.io/apimachinery/pkg/runtime".Object
		want DeepCopyObject() "github.com/kubernetes/sample-controller/vendor/k8s.io/apimachinery/pkg/runtime".Object
pkg/generated/clientset/versioned/typed/samplecontroller/v1alpha1/foo.go:148:7: cannot use result (type *v1alpha1.Foo) as type "github.com/kubernetes/sample-controller/vendor/k8s.io/apimachinery/pkg/runtime".Object in argument to c.client.Put().Namespace(c.ns).Resource("foos").Name(foo.ObjectMeta.Name).SubResource("status").Body(foo).Do().Into:
	*v1alpha1.Foo does not implement "github.com/kubernetes/sample-controller/vendor/k8s.io/apimachinery/pkg/runtime".Object (wrong type for DeepCopyObject method)
		have DeepCopyObject() "k8s.io/apimachinery/pkg/runtime".Object
		want DeepCopyObject() "github.com/kubernetes/sample-controller/vendor/k8s.io/apimachinery/pkg/runtime".Object
pkg/generated/clientset/versioned/typed/samplecontroller/v1alpha1/foo.go:172:19: cannot use scheme.ParameterCodec (type "k8s.io/apimachinery/pkg/runtime".ParameterCodec) as type "github.com/kubernetes/sample-controller/vendor/k8s.io/apimachinery/pkg/runtime".ParameterCodec in argument to c.client.Delete().Namespace(c.ns).Resource("foos").VersionedParams:
	"k8s.io/apimachinery/pkg/runtime".ParameterCodec does not implement "github.com/kubernetes/sample-controller/vendor/k8s.io/apimachinery/pkg/runtime".ParameterCodec (wrong type for DecodeParameters method)
		have DecodeParameters(url.Values, "k8s.io/apimachinery/pkg/runtime/schema".GroupVersion, "k8s.io/apimachinery/pkg/runtime".Object) error
		want DecodeParameters(url.Values, "github.com/kubernetes/sample-controller/vendor/k8s.io/apimachinery/pkg/runtime/schema".GroupVersion, "github.com/kubernetes/sample-controller/vendor/k8s.io/apimachinery/pkg/runtime".Object) error
pkg/generated/clientset/versioned/typed/samplecontroller/v1alpha1/foo.go:189:7: cannot use result (type *v1alpha1.Foo) as type "github.com/kubernetes/sample-controller/vendor/k8s.io/apimachinery/pkg/runtime".Object in argument to c.client.Patch(pt).Namespace(c.ns).Resource("foos").SubResource(subresources...).Name(name).Body(data).Do().Into:
	*v1alpha1.Foo does not implement "github.com/kubernetes/sample-controller/vendor/k8s.io/apimachinery/pkg/runtime".Object (wrong type for DeepCopyObject method)
		have DeepCopyObject() "k8s.io/apimachinery/pkg/runtime".Object
		want DeepCopyObject() "github.com/kubernetes/sample-controller/vendor/k8s.io/apimachinery/pkg/runtime".Object
pkg/generated/clientset/versioned/typed/samplecontroller/v1alpha1/foo.go:189:7: too many errors
?   	github.com/kubernetes/sample-controller/pkg/apis/samplecontroller/v1alpha1	[no test files]

Can't run the test : go run: cannot run *_test.go files (controller_test.go)

This command is failing when it is executed

go get k8s.io/sample-controller
cd $GOPATH/src/k8s.io/sample-controller
go build .
./hack/update-codegen.sh 
go run *.go -kubeconfig=$HOME/.kube/config
go run: cannot run *_test.go files (controller_test.go)

We can run the test using nevertheless this command

go test .
ok      k8s.io/sample-controller        0.035s

How to install the controller on k8s

Is it possible to enhance the doc in order to explain how we could build a docker image and next install the sample-controller on k8s, openshift ?

Using sample-controller to create a custom version -but it doesn't work.

I have created a project to create a custom sample-controller.

I updated pkg/api files to setup KnightNetwork and KnightNetworkList types to replace Foo and FooList
I created new client code using update-codegen.sh
I modified main.go and controller.go appropriately.
When I build and run I get the following message repeated over and over

Listing and watching *v1.KnightNetwork from github.com/knight/pkg/k8s/client/informers/externalversions/factory.go:117
E1126 13:33:58.833083 29 reflector.go:134] github.com/knight/pkg/k8s/client/informers/externalversions/factory.go:117: Failed to list *v1.KnightNetwork: no kind "KnightnetworkList" is registered for version "knight.io/v1" in scheme "github.com/knight/pkg/k8s/client/clientset/versioned/scheme/register.go:30"

From this error message can you tell me what I did wrong or give me a hint where I should look ?

Running update-codegen.sh results into error unsupported type.

88e9fe562973:sample-controller gauta$ ./hack/update-codegen.sh
go: downloading k8s.io/gengo v0.0.0-20190116091435-f8a0810f38af
go: extracting k8s.io/gengo v0.0.0-20190116091435-f8a0810f38af
Generating deepcopy funcs
F0615 15:31:22.971465 29579 deepcopy.go:873] Hit an unsupported type invalid type.

Object 'Kind' is missing in 'object has no kind field '

I face this issue while trying to update Foo resource. The error that it throws makes sense as the object from informer store doesn't have TypeMeta filled.

&{TypeMeta:{Kind: APIVersion:} ObjectMeta:{Name:example-foo GenerateName: Namespace:default SelfLink:/apis/samplecontroller.k8s.io/v1alpha1/namespaces/default/foos/example-foo UID:a8a7a387-83c1-11e9-b13f-002590947496 ResourceVersion:214806 Generation:1 CreationTimestamp:2019-05-31 16:32:19 +0000 UTC DeletionTimestamp: DeletionGracePeriodSeconds: Labels:map[] Annotations:map[] OwnerReferences:[] Initializers:nil Finalizers:[] ClusterName: ManagedFields:[]} Spec:{DeploymentName:example-foo Replicas:0xc420530ef0} Status:{AvailableReplicas:0}}

Hence, I cannot update status for Foo resource.
Can someone help me in this regard?

[ support ] can't build from source

what happen?

I want to build from source, but get these failed:

# GO15VENDOREXPERIMENT=1 go build .
# github.com/kubernetes/sample-controller
./controller.go:102:26: cannot use "github.com/kubernetes/sample-controller/vendor/k8s.io/client-go/kubernetes/scheme".Scheme (type *"github.com/kubernetes/sample-controller/vendor/k8s.io/apimachinery/pkg/runtime".Scheme) as type *"k8s.io/sample-controller/vendor/k8s.io/apimachinery/pkg/runtime".Scheme in argument to "k8s.io/sample-controller/pkg/client/clientset/versioned/scheme".AddToScheme
./controller.go:292:27: cannot use foo (type *"k8s.io/sample-controller/pkg/apis/samplecontroller/v1alpha1".Foo) as type "github.com/kubernetes/sample-controller/vendor/k8s.io/apimachinery/pkg/apis/meta/v1".Object in argument to "github.com/kubernetes/sample-controller/vendor/k8s.io/apimachinery/pkg/apis/meta/v1".IsControlledBy:
	*"k8s.io/sample-controller/pkg/apis/samplecontroller/v1alpha1".Foo does not implement "github.com/kubernetes/sample-controller/vendor/k8s.io/apimachinery/pkg/apis/meta/v1".Object (wrong type for GetCreationTimestamp method)
		have GetCreationTimestamp() "k8s.io/sample-controller/vendor/k8s.io/apimachinery/pkg/apis/meta/v1".Time
		want GetCreationTimestamp() "github.com/kubernetes/sample-controller/vendor/k8s.io/apimachinery/pkg/apis/meta/v1".Time
./controller.go:294:19: cannot use foo (type *"k8s.io/sample-controller/pkg/apis/samplecontroller/v1alpha1".Foo) as type "github.com/kubernetes/sample-controller/vendor/k8s.io/apimachinery/pkg/runtime".Object in argument to c.recorder.Event:
	*"k8s.io/sample-controller/pkg/apis/samplecontroller/v1alpha1".Foo does not implement "github.com/kubernetes/sample-controller/vendor/k8s.io/apimachinery/pkg/runtime".Object (wrong type for DeepCopyObject method)
		have DeepCopyObject() "k8s.io/sample-controller/vendor/k8s.io/apimachinery/pkg/runtime".Object
		want DeepCopyObject() "github.com/kubernetes/sample-controller/vendor/k8s.io/apimachinery/pkg/runtime".Object
./controller.go:320:18: cannot use foo (type *"k8s.io/sample-controller/pkg/apis/samplecontroller/v1alpha1".Foo) as type "github.com/kubernetes/sample-controller/vendor/k8s.io/apimachinery/pkg/runtime".Object in argument to c.recorder.Event:
	*"k8s.io/sample-controller/pkg/apis/samplecontroller/v1alpha1".Foo does not implement "github.com/kubernetes/sample-controller/vendor/k8s.io/apimachinery/pkg/runtime".Object (wrong type for DeepCopyObject method)
		have DeepCopyObject() "k8s.io/sample-controller/vendor/k8s.io/apimachinery/pkg/runtime".Object
		want DeepCopyObject() "github.com/kubernetes/sample-controller/vendor/k8s.io/apimachinery/pkg/runtime".Object
./controller.go:404:29: cannot use foo (type *"k8s.io/sample-controller/pkg/apis/samplecontroller/v1alpha1".Foo) as type "github.com/kubernetes/sample-controller/vendor/k8s.io/apimachinery/pkg/apis/meta/v1".Object in argument to "github.com/kubernetes/sample-controller/vendor/k8s.io/apimachinery/pkg/apis/meta/v1".NewControllerRef:
	*"k8s.io/sample-controller/pkg/apis/samplecontroller/v1alpha1".Foo does not implement "github.com/kubernetes/sample-controller/vendor/k8s.io/apimachinery/pkg/apis/meta/v1".Object (wrong type for GetCreationTimestamp method)
		have GetCreationTimestamp() "k8s.io/sample-controller/vendor/k8s.io/apimachinery/pkg/apis/meta/v1".Time
		want GetCreationTimestamp() "github.com/kubernetes/sample-controller/vendor/k8s.io/apimachinery/pkg/apis/meta/v1".Time
./main.go:56:46: cannot use cfg (type *"github.com/kubernetes/sample-controller/vendor/k8s.io/client-go/rest".Config) as type *"k8s.io/sample-controller/vendor/k8s.io/client-go/rest".Config in argument to versioned.NewForConfig

update by hack/update-codegen.sh still has this problem

# /bin/bash hack/update-codegen.sh 
Generating deepcopy funcs
Generating clientset for samplecontroller:v1alpha1 at k8s.io/sample-controller/pkg/client/clientset
Generating listers for samplecontroller:v1alpha1 at k8s.io/sample-controller/pkg/client/listers
Generating informers for samplecontroller:v1alpha1 at k8s.io/sample-controller/pkg/client/informers

my env

go version

# go version
go version go1.10.1 linux/amd64

system version

# cat /etc/os-release 
NAME="Ubuntu"
VERSION="16.04.3 LTS (Xenial Xerus)"
ID=ubuntu
ID_LIKE=debian
PRETTY_NAME="Ubuntu 16.04.3 LTS"
VERSION_ID="16.04"
HOME_URL="http://www.ubuntu.com/"
SUPPORT_URL="http://help.ubuntu.com/"
BUG_REPORT_URL="http://bugs.launchpad.net/ubuntu/"
VERSION_CODENAME=xenial
UBUNTU_CODENAME=xenial

Problem with codegen on Windows

I downloaded the repo, modified the api files and codegen script to suit my needs and tried to run update-codegen.sh from Git Bash, but it failed with these errors.

Keith@DESKTOP-021AQFL MINGW64 ~/go/src/gamepod.cc/agent (master)
$ ./hack/update-codegen.sh
Generating deepcopy funcs
Generating clientset for gamepod:v1alpha1 at gamepod.cc/agent/pkg/client/clientse                          t
W1223 18:13:29.376607   33732 import_tracker.go:45] Warning: backslash used in i                          mport path 'gamepod.cc\agent\pkg\client\clientset\versioned\scheme', this is uns                          upported.
F1223 18:13:29.441608   33732 main.go:64] Error: Failed executing generator: som                          e packages had errors:
errors in package "gamepod.cc\\agent\\pkg\\client\\clientset\\versioned":
unable to format file "..\\..\\gamepod.cc\\agent\\pkg\\client\\clientset\\versio                          ned\\clientset.go" (20:34: unknown escape sequence (and 3 more errors)).

errors in package "gamepod.cc\\agent\\pkg\\client\\clientset\\versioned\\fake":
unable to format file "..\\..\\gamepod.cc\\agent\\pkg\\client\\clientset\\versio                          ned\\fake\\clientset_generated.go" (20:34: unknown escape sequence (and 10 more                           errors)).

errors in package "gamepod.cc\\agent\\pkg\\client\\clientset\\versioned\\typed\\                          gamepod\\v1alpha1":
unable to format file "..\\..\\gamepod.cc\\agent\\pkg\\client\\clientset\\versio                          ned\\typed\\gamepod\\v1alpha1\\gameserver.go" (22:11: illegal character U+005C '\                          ' (and 10 more errors)).
unable to format file "..\\..\\gamepod.cc\\agent\\pkg\\client\\clientset\\versio                          ned\\typed\\gamepod\\v1alpha1\\gamepod_client.go" (17:2: invalid import path: "ga                          mepod.cc\\agent\\pkg\\client\\clientset\\versioned\\scheme").

errors in package "gamepod.cc\\agent\\pkg\\client\\clientset\\versioned\\typed\\                          gamepod\\v1alpha1\\fake":
unable to format file "..\\..\\gamepod.cc\\agent\\pkg\\client\\clientset\\versio                          ned\\typed\\gamepod\\v1alpha1\\fake\\fake_gamepod_client.go" (19:28: unknown esca                          pe sequence (and 3 more errors)).

Where gamepod is my api name and gameserver is my CRD. Upon looking in some of the files in the error message I found out that it was using backslashes in import paths for files it generated:

// pkg/client/clientset/versioned/clientset.go

...

package versioned

import (
	flowcontrol "k8s.io/client-go/util/flowcontrol"
	stablev1alpha1 "gamepod.cc\agent\pkg\client\clientset\versioned\typed\gamepod\v1alpha1"
	discovery "k8s.io/client-go/discovery"
	rest "k8s.io/client-go/rest"
)

...

However when I run update-codegen.sh with the same code on a Linux VPS it runs completely fine and generates the correct import paths so it appears this is a problem caused by the scripts not using the correct path separator under Git Bash/MSYS2.

I assume this is less of an issue with sample-controller and probably an issue with kubernetes/code-generator or kubernetes/gengo but I'm not sure where to look so I assume this is the best place to start.

Here are the most relevant files:

// hack/update-codegen.sh

set -o errexit
set -o nounset
set -o pipefail
SCRIPT_ROOT=$(dirname ${BASH_SOURCE})/..
CODEGEN_PKG=${CODEGEN_PKG:-$(cd ${SCRIPT_ROOT}; ls -d -1 ./vendor/k8s.io/code-generator 2>/dev/null || echo ../code-generator)}
# generate the code with:
# --output-base    because this script should also be able to run inside the vendor dir of
#                  k8s.io/kubernetes. The output-base is needed for the generators to output into the vendor dir
#                  instead of the $GOPATH directly. For normal projects this can be dropped.
${CODEGEN_PKG}/generate-groups.sh "deepcopy,client,informer,lister" \
  gamepod.cc/agent/pkg/client gamepod.cc/agent/pkg/apis \
  gamepod:v1alpha1 \
  --output-base "$(dirname ${BASH_SOURCE})/../../.." \
  --go-header-file ${SCRIPT_ROOT}/hack/boilerplate.go.txt
// pkg/apis/gamepod/v1alpa1/types.go

package v1alpa1

import (
	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)

// +genclient
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
// GameServer is a specification for a Game Server resource
type GameServer struct {
	metav1.TypeMeta   `json:",inline"`
	metav1.ObjectMeta `json:"metadata,omitempty"`
	Spec              GameServerSpec   `json:"spec"`
	Status            GameServerStatus `json:"status"`
}

// GameServerSpec is the spec for a GameServer resource
type GameServerSpec struct {
	Game GameServerGame `json:"game"`
}

// GameServerGame is the spec for the Game key of the GameServer resource spec
type GameServerGame struct {
	Name    string `json:"name"`
	Version string `json:"version"`
}

// GameServerStatus is the status for a GameServer resource
type GameServerStatus struct {
	Created bool `json:"installed"`
}

// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
// GameServerList is a list of GameServer resources
type GameServerList struct {
	metav1.TypeMeta `json:",inline"`
	metav1.ListMeta `json:"metadata"`
	Items           []GameServer `json:"items"`
}

Preventing event circulation through workqueue

Looking at how UpdateFunc's are setup, I was wondering why ResourceVersion check is not done when setting up UpdateFunc for Foo?

Also, in the syncHandler, updateFooStatus() is called irrespective of whether an update is warranted or not.

Together these two points lead to a situation where syncHandler keeps getting triggered even after processing of an event (Foo or Deployment) is completed. This seems incorrect to me.

I think we should add ResourceVersion check in the UpdateFunc for fooInformer and also maintain a flag in syncHandler to check whether updateFooStatus() is really needed to be called or not.

What do you think?

Here is a WIP PR that includes these fixes:
kubernetes/kubernetes#69749

Documentation or Support for Go Modules

It seems as though hack/update-codegen.sh isn't updated properly for using go modules. I was able to patch mine by changing the CODEGEN_PKG and removing SCRIPT_ROOT and replacing with:

CODEGEN_PKG=${CODEGEN_PKG:-$(ls -d -1 ${GOPATH}pkg/mod/k8s.io/code-generator* 2>/dev/null || echo ../code-generator)}
chmod +x ${CODEGEN_PKG}/generate-groups.sh

Is there a better way to handle this? Happy to put in a PR if not.

Better documentation on the `update-codegen` process

I feel like I've edited everything I would need to edit to regenerate code for a new controller. My fork is here:

https://github.com/kminehart/ladon-resource-manager

Yet when I run ./hack/update-codegen, I get:

Generating deepcopy funcs
Generating clientset for ladoncontroller:v1alpha1 at github.com/kminehart/ladon-resource-manager/pkg/client/clientset
Generating listers for ladoncontroller:v1alpha1 at github.com/kminehart/ladon-resource-manager/pkg/client/listers
Generating informers for ladoncontroller:v1alpha1 at github.com/kminehart/ladon-resource-manager/pkg/client/informers

which looks right, but nothing is there, and the deepcopy functions are still using Foo and not the new identifier, Policy, which tells me that these files are not actually being generated.

Am I missing something?

I've changed all references to k8s.io/sample-controller to my new path, and sample-controller / samplecontroller have become ladon-controller / ladoncontroller everywhere. No mention of sample exists in my fork; I just can't seem to get the code to generate.

If anyone can point me in the right direction I'd be happy to provide a PR with more details on the code-gen process (if I can figure it out).

Is the `DeleteFunc` useless in the `Informer` event handler register

`fooInformer.Informer().AddEventHandler(cache.ResourceEventHandlerFuncs{

	AddFunc: controller.enqueueFoo,
	UpdateFunc: func(old, new interface{}) {
		controller.enqueueFoo(new)
	},

})`

I find the resource DELETE will also trigger the UpdateFunc, and the periodic resync will triger the UpdateFunc either , So I wonder to know is the DeleteFunc useless, or anything I missing, thanks

code-generator depends on APIMachinery registration package, fails to update generated code

Updating the generated clientsets (after manually vendoring k8s.io/code-generator due to #6) fails because the client-gen's default input directories include k8s.io/apimachinery/pkg/apimachinery/registered, which is not vendored in this repository. AFAICT, it doesn't need to be vendored in this repository (since it's just for API server registration), so it should probably be an optional input directory, not a default one. I can cross-file to k8s.io/code-generator if necessary.

Got error when trying to run go build

I followed the README and tried to run go build -o sample-controller ., then I got the error below:

# k8s.io/sample-controller/pkg/generated/clientset/versioned/typed/samplecontroller/v1alpha1
pkg/generated/clientset/versioned/typed/samplecontroller/v1alpha1/samplecontroller_client.go:73:45: scheme.Codecs.WithoutConversion undefined (type serializer.CodecFactory has no field or method WithoutConversion)

Any idea on how to solve it?

Did you mean "Spec" instead of "Status"

fooCopy.Status.AvailableReplicas = deployment.Status.AvailableReplicas
// If the CustomResourceSubresources feature gate is not enabled,
// we must use Update instead of UpdateStatus to update the Status block of the Foo resource.
// UpdateStatus will not allow changes to the Spec of the resource,
// which is ideal for ensuring nothing other than resource status has been updated.
_, err := c.sampleclientset.SamplecontrollerV1alpha1().Foos(foo.Namespace).Update(fooCopy)

Did you mean on L327, the "Spec"? But in the end you are not updating the Spec anyways, I suppose?

Getting issue while fetching the sample-controller

When I do $go get github.com/kubernetes/sample-controller

I am getting the following issue

github.com/kubernetes/sample-controller
src\github.com\kubernetes\sample-controller\controller.go:102:26: cannot use "github.com/kubernetes/sample-controller/vendor/k8s.io/client-go/kubernetes/scheme".Scheme (
type *"github.com/kubernetes/sample-controller/vendor/k8s.io/apimachinery/pkg/runtime".Scheme) as type *"k8s.io/sample-controller/vendor/k8s.io/apimachinery/pkg/runtime"
.Scheme in argument to "k8s.io/sample-controller/pkg/client/clientset/versioned/scheme".AddToScheme
src\github.com\kubernetes\sample-controller\controller.go:292:27: cannot use foo (type *"k8s.io/sample-controller/pkg/apis/samplecontroller/v1alpha1".Foo) as type "githu
b.com/kubernetes/sample-controller/vendor/k8s.io/apimachinery/pkg/apis/meta/v1".Object in argument to "github.com/kubernetes/sample-controller/vendor/k8s.io/apimachinery
/pkg/apis/meta/v1".IsControlledBy:
*"k8s.io/sample-controller/pkg/apis/samplecontroller/v1alpha1".Foo does not implement "github.com/kubernetes/sample-controller/vendor/k8s.io/apimachinery/pkg/api
s/meta/v1".Object (wrong type for GetCreationTimestamp method)
have GetCreationTimestamp() "k8s.io/sample-controller/vendor/k8s.io/apimachinery/pkg/apis/meta/v1".Time
want GetCreationTimestamp() "github.com/kubernetes/sample-controller/vendor/k8s.io/apimachinery/pkg/apis/meta/v1".Time
src\github.com\kubernetes\sample-controller\controller.go:294:19: cannot use foo (type *"k8s.io/sample-controller/pkg/apis/samplecontroller/v1alpha1".Foo) as type "githu
b.com/kubernetes/sample-controller/vendor/k8s.io/apimachinery/pkg/runtime".Object in argument to c.recorder.Event:
*"k8s.io/sample-controller/pkg/apis/samplecontroller/v1alpha1".Foo does not implement "github.com/kubernetes/sample-controller/vendor/k8s.io/apimachinery/pkg/run
time".Object (wrong type for DeepCopyObject method)
have DeepCopyObject() "k8s.io/sample-controller/vendor/k8s.io/apimachinery/pkg/runtime".Object
want DeepCopyObject() "github.com/kubernetes/sample-controller/vendor/k8s.io/apimachinery/pkg/runtime".Object
src\github.com\kubernetes\sample-controller\controller.go:320:18: cannot use foo (type *"k8s.io/sample-controller/pkg/apis/samplecontroller/v1alpha1".Foo) as type "githu
b.com/kubernetes/sample-controller/vendor/k8s.io/apimachinery/pkg/runtime".Object in argument to c.recorder.Event:
*"k8s.io/sample-controller/pkg/apis/samplecontroller/v1alpha1".Foo does not implement "github.com/kubernetes/sample-controller/vendor/k8s.io/apimachinery/pkg/run
time".Object (wrong type for DeepCopyObject method)
have DeepCopyObject() "k8s.io/sample-controller/vendor/k8s.io/apimachinery/pkg/runtime".Object
want DeepCopyObject() "github.com/kubernetes/sample-controller/vendor/k8s.io/apimachinery/pkg/runtime".Object
src\github.com\kubernetes\sample-controller\controller.go:404:29: cannot use foo (type *"k8s.io/sample-controller/pkg/apis/samplecontroller/v1alpha1".Foo) as type "githu
b.com/kubernetes/sample-controller/vendor/k8s.io/apimachinery/pkg/apis/meta/v1".Object in argument to "github.com/kubernetes/sample-controller/vendor/k8s.io/apimachinery
/pkg/apis/meta/v1".NewControllerRef:
*"k8s.io/sample-controller/pkg/apis/samplecontroller/v1alpha1".Foo does not implement "github.com/kubernetes/sample-controller/vendor/k8s.io/apimachinery/pkg/api
s/meta/v1".Object (wrong type for GetCreationTimestamp method)
have GetCreationTimestamp() "k8s.io/sample-controller/vendor/k8s.io/apimachinery/pkg/apis/meta/v1".Time
want GetCreationTimestamp() "github.com/kubernetes/sample-controller/vendor/k8s.io/apimachinery/pkg/apis/meta/v1".Time
src\github.com\kubernetes\sample-controller\main.go:56:46: cannot use cfg (type *"github.com/kubernetes/sample-controller/vendor/k8s.io/client-go/rest".Config) as type *
"k8s.io/sample-controller/vendor/k8s.io/client-go/rest".Config in argument to versioned.NewForConfig

How to get the log message ?

I am getting error for the log messages:

# ./sample-controller -kubeconfig=$HOME/.kube/config -logtostderr=true -v=2
flag provided but not defined: -logtostderr
Usage of ./sample-controller:
  -kubeconfig string
        Path to a kubeconfig. Only required if out-of-cluster.
  -master string
        The address of the Kubernetes API server. Overrides any value in kubeconfig. Only required if out-of-cluster.

How to check it ?

govet error: "literal copies lock value from fakePtr"

From kubernetes/ingress-gce#163.

Using the auto generating scripts in hack/ with golang 1.10.1 and hit below error when running govet:

# k8s.io/ingress-gce/pkg/serviceextension/client/clientset/versioned/fake
pkg/serviceextension/client/clientset/versioned/fake/clientset_generated.go:56: literal copies lock value from fakePtr: k8s.io/ingress-gce/vendor/k8s.io/client-go/testing.Fake

It seems that is also the case in this repo:

fakePtr := testing.Fake{}
fakePtr.AddReactor("*", "*", testing.ObjectReaction(o))
fakePtr.AddWatchReactor("*", func(action testing.Action) (handled bool, ret watch.Interface, err error) {
gvr := action.GetResource()
ns := action.GetNamespace()
watch, err := o.Watch(gvr, ns)
if err != nil {
return false, nil, err
}
return true, watch, nil
})
return &Clientset{fakePtr, &fakediscovery.FakeDiscovery{Fake: &fakePtr}}

Should we fix the generated code or am I missing something?

How to deploy controller into the cluster

I am a bit confused about where the custom controller is being run from. I had assumed that the customer controller would run within the cluster, just as the deployment controller does, watching and taking action. But based on my reading the custom control is client side and lives outside of kubernetes. I have have seen one example running the custom control client within a Pod in the cluster. But I could not figure out the specific code to make this work.

Simple example with detailed instructions

The controller is complex for the untrained eye, the required steps aren't very clear to me. It would be nice to have a more simple example, with some steps to follow along the development and decision making during it's progress.

This is how far I've gotten:
According to my understanding a controller for a CustomResource is built using the following algorithm:

1. Create the following directory structure:

.
├── Gopkg.lock
├── Gopkg.toml
├── README.md
├── artifacts
│   ├── example1.yaml
│   ├── example2.yaml
│   ├── [...]
│   └── example-crd.yaml
├── generator
│   ├── custom-boilerplate.go.txt
│   ├── update-codegen.sh
│   └── verify-codegen.sh
├── main.go
└── pkg
    └── apis
        └── samplecontroller/
            ├── register.go
            └── v1alpha1
                ├── doc.go
                ├── register.go
                └── types.go

Next up, I'll try to explain the contents of each required file in the above skeleton...

./Gopkg.toml

Example input:

required = ["k8s.io/code-generator/cmd/client-gen"]

[[constraint]]
  name = "k8s.io/apimachinery"
  branch = "release-1.8"

[[constraint]]
  name = "k8s.io/client-go"
  branch = "release-5.0"

[[constraint]]
  name = "k8s.io/code-generator"
  branch = "release-1.8"

# goland/dep does not follow k8s.io/code-generator's Godeps.json and gengo's master
# version does not work with release-1.8 k8s.io/code-generator. So we have to
# override it.
[[override]]
  name = "k8s.io/gengo"
  revision = "9e661e9308f078838e266cca1c673922088c0ea4"

The gist of this file is that it will allow you to generate the required code using the code-generator-project.

./artifacts/example1.yaml

apiVersion: samplecontroller.k8s.io/v1alpha1
kind: Foo
metadata:
  name: example-foo
spec:
  deploymentName: example-foo
  replicas: 1

This is basically the same type of file you'd create for any other resource, but with a different api-endpoint. Refer to the explanation for the ./artifacts/example-crd.yaml -file.

./artifacts/example-crd.yaml

apiVersion: apiextensions.k8s.io/v1beta1
kind: CustomResourceDefinition
metadata:
  name: foos.samplecontroller.k8s.io
spec:
  group: samplecontroller.k8s.io
  version: v1alpha1
  names:
    kind: Foo
    singular: foo
    plural: foos
  scope: Namespaced
  validation:
    openAPIV3Schema:
      properties:
        spec:
          properties:
            replicas:
              type: integer
              minimum: 1
              maximum: 10

This file adds a custom resource at apiVersion samplecontroller.k8s.io, version v1alpa1, kind: Foo.
More info

./generator/update-codegen.sh

#!/bin/bash
set -o errexit
set -o nounset
set -o pipefail

SCRIPT_ROOT=$(dirname ${BASH_SOURCE})/..
CODEGEN_PKG=${CODEGEN_PKG:-$(cd ${SCRIPT_ROOT}; ls -d -1 ./vendor/k8s.io/code-generator 2>/dev/null || echo ../code-generator)}

# generate the code with:
# --output-base    because this script should also be able to run inside the vendor dir of
#                  k8s.io/kubernetes. The output-base is needed for the generators to output into the vendor dir
#                  instead of the $GOPATH directly. For normal projects this can be dropped.
${CODEGEN_PKG}/generate-groups.sh "deepcopy,client,informer,lister" \
  k8s.io/sample-controller/pkg/client k8s.io/sample-controller/pkg/apis \
  samplecontroller:v1alpha1 \
  --output-base "$(dirname ${BASH_SOURCE})/../../.."

# To use your own boilerplate text append:
#   --go-header-file ${SCRIPT_ROOT}/hack/custom-boilerplate.go.txt

This script allows you to generate the required code too create functionality for the most common actions; In this case: "deepcopy,client,informer,lister", which are common components for a CustomResourceController.

k8s.io/sample-controller/pkg/client k8s.io/sample-controller/pkg/apis
Should be swapped by your projects' "apis"-folder location.

samplecontroller:v1alpha1 should be edited into <yoursamplecontroller.com:youversion>.

./generator/verify-codegen.sh

This script is primarily used for CI/CD pipelines, as it invokes the previous script and checks to see if there would have been any changes.

./main.go, ./controller.go

This is where the actual controller should live. It's responsibility would generally be (in case of a CustomResourceController to read events for the CustomResource and invoke actions based on these events.

For example: If I were to create a CustomResource called Staging and wanted to create some deployments based off-of some variables within this resource. I'd need a controller listening for events (Watch) and performing orchestration/cleanup when required.

Some thoughts:

  • You'll need to handle exitting properly through several threads, as we need to stop some loops from running indefinitely
  • You'll need to implement workers, as you don't want events to wait for a deployment orchestration-operation to finish
  • Somehow you'll need to start watching all newly orchestrated components for changes as wel, to ensure they get re-orchestrated when something happens to them
  • ... (whatever many many options I have probably missed up until now)

... Then again, there might be a lot simpler ways to approach this, but these weren't clear yet to me.

./pkg/apis/samplecontroller/v1alpha1/register.go

package samplecontroller

const (
	GroupName = "samplecontroller.k8s.io"
)

Package should match the directory name used within apis & the group name should be adjusted to the name set in the CustomResourceDefinition.

./pkg/apis/samplecontroller/v1alpha1/types.go

package v1alpha1

import (
	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)

// +genclient
// +genclient:noStatus
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object

// Foo is a specification for a Foo resource
type Foo struct {
	metav1.TypeMeta   `json:",inline"`
	metav1.ObjectMeta `json:"metadata,omitempty"`

	Spec   FooSpec   `json:"spec"`
	Status FooStatus `json:"status"`
}

// FooSpec is the spec for a Foo resource
type FooSpec struct {
	DeploymentName string `json:"deploymentName"`
	Replicas       *int32 `json:"replicas"`
}

// FooStatus is the status for a Foo resource
type FooStatus struct {
	AvailableReplicas int32 `json:"availableReplicas"`
}

// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object

// FooList is a list of Foo resources
type FooList struct {
	metav1.TypeMeta `json:",inline"`
	metav1.ListMeta `json:"metadata"`

	Items []Foo `json:"items"`
}

This is a bit harder to explain but to put it bluntly: You create a golang representation of the data described in the CustomResourceDefinition, with the comments starting with // +k8s: depicting a special role:
They tell the code-generator what code to generate.

The package here should match the version chosen

./pkg/apis/samplecontroller/v1alpha1/doc.go

// +k8s:deepcopy-gen=package

// Package v1alpha1 is the v1alpha1 version of the API.
// +groupName=samplecontroller.k8s.io
package v1alpha1

In this case, this file serves solely to set the general settings for the code-generator it

  • sets the group name for the generated files
  • tells the deepcopy-generator to generate deep copy methods for each type in that package (unless the parameters above that type override it)

./pkg/apis/samplecontroller/register.go

package v1alpha1

import (
	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
	"k8s.io/apimachinery/pkg/runtime"
	"k8s.io/apimachinery/pkg/runtime/schema"

	samplecontroller "k8s.io/sample-controller/pkg/apis/samplecontroller"
)

// SchemeGroupVersion is group version used to register these objects
var SchemeGroupVersion = schema.GroupVersion{Group: samplecontroller.GroupName, Version: "v1alpha1"}

// Kind takes an unqualified kind and returns back a Group qualified GroupKind
func Kind(kind string) schema.GroupKind {
	return SchemeGroupVersion.WithKind(kind).GroupKind()
}

// Resource takes an unqualified resource and returns a Group qualified GroupResource
func Resource(resource string) schema.GroupResource {
	return SchemeGroupVersion.WithResource(resource).GroupResource()
}

var (
	SchemeBuilder = runtime.NewSchemeBuilder(addKnownTypes)
	AddToScheme   = SchemeBuilder.AddToScheme
)

// Adds the list of known types to Scheme.
func addKnownTypes(scheme *runtime.Scheme) error {
	scheme.AddKnownTypes(SchemeGroupVersion,
		&Foo{},
		&FooList{},
	)
	metav1.AddToGroupVersion(scheme, SchemeGroupVersion)
	return nil
}

I'm not sure what this file exactly fulfils but I know it is important, you'll need to ensure the:

  • package name is correct (matches the version in the CustomResourceDefinition)
  • the imports are relative to your project, not samplecontroller
  • var SchemeGroupVersion = schema.GroupVersion{Group: samplecontroller.GroupName, Version: "v1alpha1"}'s "v1alpha1" should also be changed to match the version in the CustomResourceDefinition

2. Generate the required code

Allright, this is a fine time to create a commit to run back to when everything hits the fan.

Fetch dependencies

dep ensure

Generate required libraries based off-of your types

./generator/update-codegen.sh

Fetch dependencies

I'm not even sure this is actually always required, but I just like doing it...

dep ensure

3. Create the Controller's logic

Now that all the required code has been generated we've got ourselves some nice options to perform some routine tasks:

  • ./pkg/client/clientset/versioned/typed/samplecontroller/v1alpha1/samplecontroller_client.go which will act as our goto-structure to access any api-endpoint related to the CustomResource we created.
  • ./pkg/client/clientset/versioned/typed/samplecontroller/v1alpha1/foo.go which will add the .Foo("<supply a namespacehere>") which in turn supplies an interface to operations like:
    • List
    • Get
    • Watch
    • ...

End

That's it for now! I'm kind of stuck after managing to really simply listening for added events and printing the contents of my type.
I want to be able to do a lot more, like create complete environments as a result of a CustomResource being added / altered etc... But I'm not there yet. Any help is greatly appreciated. ;)

Please note that I am not fully fluent in golang nor am I a programmer (operations). I just want to be able to understand en grasp the usefulness of this awesome project.

README instructions gives an error while trying to run the controller

I am just following the instructions in README. I see the following error:

$ go run *.go -kubeconfig=$HOME/.kube/config                                                 
E0129 22:06:44.562026    1469 reflector.go:205] github.com/hvishwanath/sample-controller/vendor/k8s.io/client-go/informers/factory.go:87: Failed to list *v1.Deployment: the server could not find the requested resource
E0129 22:06:45.578094    1469 reflector.go:205] github.com/hvishwanath/sample-controller/vendor/k8s.io/client-go/informers/factory.go:87: Failed to list *v1.Deployment: the server could not find the requested resource
E0129 22:06:46.620581    1469 reflector.go:205] github.com/hvishwanath/sample-controller/vendor/k8s.io/client-go/informers/factory.go:87: Failed to list *v1.Deployment: the server could not find the requested resource

Is this outdated?

I can't for the life of me get this working. I can't even get it to build. So I assume I need godep since I see a Godep directory. (also tried using dep ensure)

I've cloned sample-controller. I change to the sample-controller directory. My GOPATH=/path/to/sample-controller.

`
$pwd
/devel/kubernetes/sample-controller

$go version
go version go1.11.5 darwin/amd64

$godep version
godep v80 (darwin/amd64/go1.11.5)

/devel/kubernetes/sample-controller $godep get
godep: [WARNING]: godep should only be used inside a valid go package directory and .
godep: [WARNING]: may not function correctly. You are probably outside of your $GOPATH.
godep: [WARNING]: Current Directory: /devel/kubernetes/sample-controller .
godep: [WARNING]: $GOPATH: /devel/kubernetes/sample-controller .
godep: Unable to find SrcRoot for package .

$echo $GOPATH
/devel/kubernetes/sample-controller
`

What am I doing wrong here. Sorry new to go and its tools.

the server could not find the requested resource

/gopath/src/k8s.io/sample-controller # ./controller -kubeconfig=$HOME/.kube/config
I0416 15:33:06.201192 102295 controller.go:98] Creating event broadcaster
I0416 15:33:06.201399 102295 controller.go:115] Setting up event handlers
I0416 15:33:06.201440 102295 controller.go:156] Starting Foo controller
I0416 15:33:06.201448 102295 controller.go:159] Waiting for informer caches to sync
I0416 15:33:06.202281 102295 reflector.go:128] Starting reflector *v1.Deployment (30s) from k8s.io/client-go/informers/factory.go:133
I0416 15:33:06.202304 102295 reflector.go:166] Listing and watching *v1.Deployment from k8s.io/client-go/informers/factory.go:133
I0416 15:33:06.202287 102295 reflector.go:128] Starting reflector *v1alpha1.Foo (30s) from k8s.io/sample-controller/pkg/generated/informers/externalversions/factory.go:117
I0416 15:33:06.202480 102295 reflector.go:166] Listing and watching *v1alpha1.Foo from k8s.io/sample-controller/pkg/generated/informers/externalversions/factory.go:117
E0416 15:33:06.211787 102295 reflector.go:131] k8s.io/sample-controller/pkg/generated/informers/externalversions/factory.go:117: Failed to list *v1alpha1.Foo: the server could not find the requested resource (get foos.samplecontroller.k8s.io)
I0416 15:33:06.218277 102295 controller.go:369] Processing object: coredns
I0416 15:33:06.218325 102295 controller.go:369] Processing object: calico-kube-controllers
I0416 15:33:06.218336 102295 controller.go:369] Processing object: tiller-deploy
I0416 15:33:07.213361 102295 reflector.go:166] Listing and watching *v1alpha1.Foo from k8s.io/sample-controller/pkg/generated/informers/externalversions/factory.go:117
E0416 15:33:07.215248 102295 reflector.go:131] k8s.io/sample-controller/pkg/generated/informers/externalversions/factory.go:117: Failed to list *v1alpha1.Foo: the server could not find the requested resource (get foos.samplecontroller.k8s.io)
I0416 15:33:08.216289 102295 reflector.go:166] Listing and watching *v1alpha1.Foo from k8s.io/sample-controller/pkg/generated/informers/externalversions/factory.go:117
E0416 15:33:08.218154 102295 reflector.go:131] k8s.io/sample-controller/pkg/generated/informers/externalversions/factory.go:117: Failed to list *v1alpha1.Foo: the server could not find the requested resource (get foos.samplecontroller.k8s.io)
^CI0416 15:33:08.251854 102295 shared_informer.go:119] stop requested

/gopath/src/k8s.io/sample-controller # kubectl version
Client Version: version.Info{Major:"1", Minor:"13", GitVersion:"v1.13.0", GitCommit:"ddf47ac13c1a9483ea035a79cd7c10005ff21a6d", GitTreeState:"clean", BuildDate:"2018-12-03T21:04:45Z", GoVersion:"go1.11.2", Compiler:"gc", Platform:"linux/amd64"}
Server Version: version.Info{Major:"1", Minor:"13", GitVersion:"v1.13.5", GitCommit:"2166946f41b36dea2c4626f90a77706f426cdea2", GitTreeState:"clean", BuildDate:"2019-03-25T15:19:22Z", GoVersion:"go1.11.5", Compiler:"gc", Platform:"linux/amd64"}

Informer AddFunc start processing items before it has been synced

I'm using the sample-controller as a scaffold for handling CRDS: basically, I got a custom resource named IngressClass, just simple counter the amount of registered Ingress resources for each class.

As the code suggests, I create the Kubernetes and custom one informers, then I instantiate a new controller passing the Informers in order to get the func HasSynced required by the func cache.WaitForCacheSync. In the end, I start both informers and start processing.

Sometimes it happens that the cache seems not ready: the events related to Ingress need to fetch data from IngressClass lister but sometimes I face some error (not found) and they seem totally random.

I0225 15:32:47.299991   10670 controller.go:73] creating event broadcaster
I0225 15:32:47.300142   10670 controller.go:90] setting up event handlers
I0225 15:32:47.300172   10670 controller.go:143] starting IngressClass controller
I0225 15:32:47.300178   10670 controller.go:146] waiting for informer caches to sync
I0225 15:32:47.300654   10670 reflector.go:131] Starting reflector *v1beta1.Ingress (1m0s) from k8s.io/client-go/informers/factory.go:132
I0225 15:32:47.300872   10670 reflector.go:169] Listing and watching *v1beta1.Ingress from k8s.io/client-go/informers/factory.go:132
I0225 15:32:47.300673   10670 reflector.go:131] Starting reflector *v1beta1.IngressClass (1m0s) from ingress-class-controller/pkg/client/informers/externalversions/factory.go:117
I0225 15:32:47.301450   10670 reflector.go:169] Listing and watching *v1beta1.IngressClass from ingress-class-controller/pkg/client/informers/externalversions/factory.go:117
I0225 15:32:47.321516   10670 ingress.go:43] processing object: foo
E0225 15:32:47.321665   10670 controller.go:106] cannot retrieve IngressClass default: ingressclass.sharding.foo.net "default" not found
E0225 15:32:47.321742   10670 runtime.go:69] Observed a panic: &errors.errorString{s:"cannot retrieve IngressClass default: ingressclass.sharding.foo.net \"default\" not found"} (cannot retrieve IngressClass default: ingressclass.sharding.fooo.net "default" not found)

It appears that the CRD based lister is not yet populated with the required data: a workaround could be using multiple enqueue<Type> in order to get multiple workqueue.RateLimitingInterface and handle better this cases.

how to handle crd object using 'get/list' request in controller with restful-api?

trustslaveInformer.Informer().AddEventHandler(cache.ResourceEventHandlerFuncs{ AddFunc: controller.enqueueTSItem, UpdateFunc: func(old, new interface{}) { oldtsitem := old.(*trustslavev1.TSItem) newtsitem := new.(*trustslavev1.TSItem) if oldtsitem.ResourceVersion == newtsitem.ResourceVersion { return } // update controller.enqueueTSItem(new) }, DeleteFunc: controller.enqueueTSItemForDelete, })

how can I monitor a 'get crd object request' event in controller? like AddFunc/UpdateFunc/DeleteFunc

An example walk through for new user

I am trying to understand the details of custom controller and planning to write a new one. I could not find a good user doc which talks about the details of file and package. I am looking for something like example other than foo which is being created. The closest I have found is this article but this is not quite accurate anymore.

code-generator is missing from this repo

  1. git cloned this repo
  2. changed the types to my own
  3. removed all generated files (rm -rf pkg/client pkg/apis/prow/v1/zz_generated.deepcopy.go)
  4. ./hack/update-codegen.sh does not work because code-generator is not vendored in this repo
  5. pushd vendor/k8s.io
  6. git clone https://github.com/kubernetes/code-generator
  7. popd; ./hack/update-codegen.sh now works

I didn't expect to do 5-7. I assumed that since this is a standalone repo, code generation should work ootb. Intentional?

@munnerz @sttts

import cycle not allowed

go build -o sample-controller .
import cycle not allowed
package k8s.io/sample-controller
        imports flag
        imports errors
        imports runtime
        imports internal/bytealg
        imports internal/cpu
        imports runtime

Example unit tests

It would be useful to provide examples for how to test the controller.go code.

Using golang 1.12+

If you are using golang 1.12 and up, which supports go modules, you don't need to have the project in your GOPATH.

Here are the steps that you can follow for trying out the project with golang 1.12+

git clone https://github.com/kubernetes/sample-controller.git
cd sample-controller/
go mod vendor
go build -o sample-controller .
./sample-controller -kubeconfig=$HOME/.kube/config

Go client of one crd.

Is there a way to use go client to create one crd after this line kubectl create -f artifacts/examples/crd.yaml?

Requeue work item on syncHandler error

When the syncHandler returns an error, I would expect the work item to be re-added to the workqueue according to this comment. The statefulset controller and the deployment controller both requeue work items when their syncHandlers return errors so I'm guessing this is the desired behavior here as well in order to handle transient errors.

By setting the resync period to 0 on the event handlers and returning an error from the syncHandler, one can see that the work item does not get requeued.

PR to fix

Controllers on other languages than Go

Hello,

I wonder if the controllers API is only available if using Go SDK/Client.

Are all APIs used in this Go sample available on API Server so we can write on our own languages the Controllers?

In case of yes, can someone point to the right doc so I can read more about it?

Thank you! Really appreciate any help.

Forgetting event upon processing functional?

I have designed a Postgres Controller based on the Sample controller. processNextWorkItem is exactly the same in my case as the sample controller. For some reason events keep looping through my queue even after being processed which leads me to believe they may not be correctly being forgotten from the queue. My synchandler also takes the same and I just added the logic for handling Postgres objects. By inserting some print statements I am able to confirm that it always exits successfully and upon returning to the processNextWorkItem function it also funishes successfully and calls the forget function. But for some reason the event is never forgotten and the next time processNextWorkItem is called it comes up with the same event.

The folder "pkg/generated" not being generated

When building the sample-controller from scratch, and executing the command ./hack/update-codegen.sh it does not generate the generated directory under pkg folder.

When commenting out the line --output-base "$(dirname "${BASH_SOURCE[0]}")/../../.." \ only it generates the directories.

But zz_generated.deepcopy.go file is not generated under pkg/apis/samplecontroller/v1alpha1 directory. How to generate it automatically?

Issue with informer factory list interface

I am trying to create a Kubernetes controller inline with how sample-controller is built. But I keep getting this

ERROR: logging before flag.Parse: E0123 13:59:00.293146   57870 reflector.go:205] .....gok8s/client/informers/externalversions/factory.go:73: Failed to list *v1.ContainerVersion: returned object must be a list: object does not implement the List interfaces

but the runtime objects are correctly generated using https://github.com/kubernetes/code-generator with same version branch and structure of objects seems to be same.

I know this is a outside the scope of sample-controller but I have seen sample-controller giving same error but cant reproduce it with sample controller anymore.
Now I get this error on sample controller:

➜  sample-controller git:(master) sample-controller --kubeconfig ~/.kube/config                          
E0123 13:25:34.768384   53728 controller.go:236] error syncing 'default/example-foo': Operation cannot be fulfilled on foos.samplecontroller.k8s.io "example-foo": the object has been modified; please apply your changes to the latest version and try again

I am on k8s 1.9.2 and I have regenerated and verified that runtime objects of sample controller are correct as per 1.9.2. Why is the sample controller giving this error?

Create a SECURITY_CONTACTS file.

As per the email sent to kubernetes-dev[1], please create a SECURITY_CONTACTS
file.

The template for the file can be found in the kubernetes-template repository[2].
A description for the file is in the steering-committee docs[3], you might need
to search that page for "Security Contacts".

Please feel free to ping me on the PR when you make it, otherwise I will see when
you close this issue. :)

Thanks so much, let me know if you have any questions.

(This issue was generated from a tool, apologies for any weirdness.)

[1] https://groups.google.com/forum/#!topic/kubernetes-dev/codeiIoQ6QE
[2] https://github.com/kubernetes/kubernetes-template-project/blob/master/SECURITY_CONTACTS
[3] https://github.com/kubernetes/community/blob/master/committee-steering/governance/sig-governance-template-short.md

Sample controller error syncing 'default/example-foo'

The sample controller is giving me the following error:
error syncing 'default/example-foo': Operation cannot be fulfilled on foos.samplecontroller.k8s.io "example-foo": the object has been modified; please apply your changes to the latest version and try again, requeuing

Build error for Foo template

I was trying to build the code with a simple go build -o controller . and I got the following error:

# k8s.io/sample-controller/pkg/client/informers/externalversions/samplecontroller/v1alpha1
../../../k8s.io/sample-controller/pkg/client/informers/externalversions/samplecontroller/v1alpha1/foo.go:64:5: not enough arguments to return
../../../k8s.io/sample-controller/pkg/client/informers/externalversions/samplecontroller/v1alpha1/foo.go:64:18: client.SamplecontrollerV1alpha1 undefined (type versioned.Interface has no field or method SamplecontrollerV1alpha1)
../../../k8s.io/sample-controller/pkg/client/informers/externalversions/samplecontroller/v1alpha1/foo.go:70:5: not enough arguments to return
../../../k8s.io/sample-controller/pkg/client/informers/externalversions/samplecontroller/v1alpha1/foo.go:70:18: client.SamplecontrollerV1alpha1 undefined (type versioned.Interface has no field or method SamplecontrollerV1alpha1)

This worked before like a charm.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.