kubernetes / sample-controller Goto Github PK
View Code? Open in Web Editor NEWRepository for sample controller. Complements sample-apiserver
License: Apache License 2.0
Repository for sample controller. Complements sample-apiserver
License: Apache License 2.0
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 ?
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
Is there a standardized workflow for deploying the controller within a cluster?
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?
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
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
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?
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 ?
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.
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.
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).
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"`
}
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
CRDs support json-schema schemas. These CRDs don't have them. It would be nice to show how to add them, initially maintained in parallel with the Go types, and then later generated from the Go types (pkg/apis).
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
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.
Just as the title shows,I can create the Foo CRD and then create or delete the Foo resource I created after I build the project but I can't find the DeleteFunc in the fooinformer.Informer().AddEventHandler().
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.
Please clarify what this mean:
https://github.com/kubernetes/sample-controller/blob/master/README.md#running
# assumes you have a working kubeconfig, not required if operating in-cluster
$ go run *.go -kubeconfig=$HOME/.kube/config
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.
`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
I have created a project to create a custom sample-controller.
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 ?
From my point of view, this function seems to miss the following code.
metav1.AddToGroupVersion(scheme, SchemeGroupVersion)
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.
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
go get github.com/kubernetes/sample-controller
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)
cd $GOPATH/src/github.com/kubernetes/sample-controller
./hack/update-codegen
./hack/update-codegen.sh: line 28: ../code-generator/generate-groups.sh: No such file or directory
vendor
directory.GO111MODULE=on go mod vendor
k8s.io/code-generator
dependency../hack/update-codegen.sh
./hack/update-codegen.sh: line 28: ./vendor/k8s.io/code-generator/generate-groups.sh: Permission denied
hack/update-codegen.sh
script by updating the command to the following
bash "${CODEGEN_PKG}"/generate-groups.sh "deepcopy,client,informer,lister" ....
./hack/update-codegen.sh
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
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]
Is there a way to use go client to create one crd after this line kubectl create -f artifacts/examples/crd.yaml
?
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
# /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
# go version
go version go1.10.1 linux/amd64
# 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
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.
/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"}
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?
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
sample-controller/controller.go
Lines 325 to 330 in 325dc0a
Did you mean on L327, the "Spec"? But in the end you are not updating the Spec anyways, I suppose?
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 ?
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.
it seems that go.mod
is generated by hack/update-vendor.sh
which is missing. Is this intended?
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:
Should we fix the generated code or am I missing something?
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.
I didn't expect to do 5-7. I assumed that since this is a standalone repo, code generation should work ootb. Intentional?
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.
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?
It would be useful to provide examples for how to test the controller.go
code.
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
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:
.
├── 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...
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.
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.
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
#!/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>
.
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.
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
calledStaging
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:
... Then again, there might be a lot simpler ways to approach this, but these weren't clear yet to me.
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
.
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
// +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
deepcopy-gen
erator to generate deep copy methods for each type in that package (unless the parameters above that type override it)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:
CustomResourceDefinition
)samplecontroller
var SchemeGroupVersion = schema.GroupVersion{Group: samplecontroller.GroupName, Version: "v1alpha1"}
's "v1alpha1"
should also be changed to match the version in the CustomResourceDefinition
Allright, this is a fine time to create a commit to run back to when everything hits the fan.
dep ensure
./generator/update-codegen.sh
I'm not even sure this is actually always required, but I just like doing it...
dep ensure
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:
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.
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
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.
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.
In this example, we have to use kubectl create the CustomResourceDefinition. But how do we create it through client-go in code ?
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
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.