Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
K
k3s
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Jacklull
k3s
Commits
875ba289
Unverified
Commit
875ba289
authored
Apr 26, 2019
by
Darren Shepherd
Committed by
GitHub
Apr 26, 2019
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #375 from galal-hussein/schedule_svclb
Add node selector to service loadbalancer controller
parents
50f405dd
f293e146
Hide whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
249 additions
and
210 deletions
+249
-210
controller.go
pkg/servicelb/controller.go
+76
-37
zz_generated_daemon_set_controller.go
types/apis/apps/v1/zz_generated_daemon_set_controller.go
+137
-137
zz_generated_daemon_set_lifecycle_adapter.go
...apis/apps/v1/zz_generated_daemon_set_lifecycle_adapter.go
+17
-17
zz_generated_deepcopy.go
types/apis/apps/v1/zz_generated_deepcopy.go
+6
-6
zz_generated_k8s_client.go
types/apis/apps/v1/zz_generated_k8s_client.go
+11
-11
zz_generated_scheme.go
types/apis/apps/v1/zz_generated_scheme.go
+1
-1
main.go
types/codegen/main.go
+1
-1
No files found.
pkg/servicelb/controller.go
View file @
875ba289
...
@@ -21,13 +21,16 @@ import (
...
@@ -21,13 +21,16 @@ import (
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/util/intstr"
"k8s.io/apimachinery/pkg/util/intstr"
"k8s.io/client-go/kubernetes"
"k8s.io/client-go/kubernetes"
v1getter
"k8s.io/client-go/kubernetes/typed/apps/v1"
coregetter
"k8s.io/client-go/kubernetes/typed/core/v1"
coregetter
"k8s.io/client-go/kubernetes/typed/core/v1"
)
)
const
(
const
(
image
=
"rancher/klipper-lb:v0.1.1"
image
=
"rancher/klipper-lb:v0.1.1"
svcNameLabel
=
"svccontroller.k3s.cattle.io/svcname"
svcNameLabel
=
"svccontroller.k3s.cattle.io/svcname"
Ready
=
condition
.
Cond
(
"Ready"
)
daemonsetNodeLabel
=
"svccontroller.k3s.cattle.io/enablelb"
nodeSelectorLabel
=
"svccontroller.k3s.cattle.io/nodeselector"
Ready
=
condition
.
Cond
(
"Ready"
)
)
)
var
(
var
(
...
@@ -44,12 +47,14 @@ func Register(ctx context.Context, kubernetes kubernetes.Interface, enabled, roo
...
@@ -44,12 +47,14 @@ func Register(ctx context.Context, kubernetes kubernetes.Interface, enabled, roo
nodeCache
:
clients
.
Node
.
Cache
(),
nodeCache
:
clients
.
Node
.
Cache
(),
podCache
:
clients
.
Pod
.
Cache
(),
podCache
:
clients
.
Pod
.
Cache
(),
processor
:
objectset
.
NewProcessor
(
"svccontroller"
)
.
processor
:
objectset
.
NewProcessor
(
"svccontroller"
)
.
Client
(
appClients
.
D
eploymen
t
),
Client
(
appClients
.
D
aemonSe
t
),
serviceCache
:
clients
.
Service
.
Cache
(),
serviceCache
:
clients
.
Service
.
Cache
(),
services
:
kubernetes
.
CoreV1
(),
services
:
kubernetes
.
CoreV1
(),
daemonsets
:
kubernetes
.
AppsV1
(),
}
}
clients
.
Service
.
OnChange
(
ctx
,
"svccontroller"
,
h
.
onChange
)
clients
.
Service
.
OnChange
(
ctx
,
"svccontroller"
,
h
.
onChangeService
)
clients
.
Node
.
OnChange
(
ctx
,
"svccontroller"
,
h
.
onChangeNode
)
changeset
.
Watch
(
ctx
,
"svccontroller-watcher"
,
changeset
.
Watch
(
ctx
,
"svccontroller-watcher"
,
h
.
onResourceChange
,
h
.
onResourceChange
,
clients
.
Service
,
clients
.
Service
,
...
@@ -67,6 +72,7 @@ type handler struct {
...
@@ -67,6 +72,7 @@ type handler struct {
processor
*
objectset
.
Processor
processor
*
objectset
.
Processor
serviceCache
coreclient
.
ServiceClientCache
serviceCache
coreclient
.
ServiceClientCache
services
coregetter
.
ServicesGetter
services
coregetter
.
ServicesGetter
daemonsets
v1getter
.
DaemonSetsGetter
}
}
func
(
h
*
handler
)
onResourceChange
(
name
,
namespace
string
,
obj
runtime
.
Object
)
([]
changeset
.
Key
,
error
)
{
func
(
h
*
handler
)
onResourceChange
(
name
,
namespace
string
,
obj
runtime
.
Object
)
([]
changeset
.
Key
,
error
)
{
...
@@ -101,7 +107,7 @@ func (h *handler) onResourceChange(name, namespace string, obj runtime.Object) (
...
@@ -101,7 +107,7 @@ func (h *handler) onResourceChange(name, namespace string, obj runtime.Object) (
},
nil
},
nil
}
}
func
(
h
*
handler
)
onChange
(
svc
*
core
.
Service
)
(
runtime
.
Object
,
error
)
{
func
(
h
*
handler
)
onChange
Service
(
svc
*
core
.
Service
)
(
runtime
.
Object
,
error
)
{
if
svc
.
Spec
.
Type
!=
core
.
ServiceTypeLoadBalancer
||
svc
.
Spec
.
ClusterIP
==
""
||
if
svc
.
Spec
.
Type
!=
core
.
ServiceTypeLoadBalancer
||
svc
.
Spec
.
ClusterIP
==
""
||
svc
.
Spec
.
ClusterIP
==
"None"
{
svc
.
Spec
.
ClusterIP
==
"None"
{
return
svc
,
nil
return
svc
,
nil
...
@@ -116,6 +122,18 @@ func (h *handler) onChange(svc *core.Service) (runtime.Object, error) {
...
@@ -116,6 +122,18 @@ func (h *handler) onChange(svc *core.Service) (runtime.Object, error) {
return
nil
,
err
return
nil
,
err
}
}
func
(
h
*
handler
)
onChangeNode
(
node
*
core
.
Node
)
(
runtime
.
Object
,
error
)
{
if
_
,
ok
:=
node
.
Labels
[
daemonsetNodeLabel
];
!
ok
{
return
node
,
nil
}
if
err
:=
h
.
updateDaemonSets
();
err
!=
nil
{
return
node
,
err
}
return
node
,
nil
}
func
(
h
*
handler
)
updateService
(
svc
*
core
.
Service
)
(
runtime
.
Object
,
error
)
{
func
(
h
*
handler
)
updateService
(
svc
*
core
.
Service
)
(
runtime
.
Object
,
error
)
{
pods
,
err
:=
h
.
podCache
.
List
(
svc
.
Namespace
,
labels
.
SelectorFromSet
(
map
[
string
]
string
{
pods
,
err
:=
h
.
podCache
.
List
(
svc
.
Namespace
,
labels
.
SelectorFromSet
(
map
[
string
]
string
{
svcNameLabel
:
svc
.
Name
,
svcNameLabel
:
svc
.
Name
,
...
@@ -200,43 +218,27 @@ func (h *handler) podIPs(pods []*core.Pod) ([]string, error) {
...
@@ -200,43 +218,27 @@ func (h *handler) podIPs(pods []*core.Pod) ([]string, error) {
}
}
func
(
h
*
handler
)
deployPod
(
svc
*
core
.
Service
)
error
{
func
(
h
*
handler
)
deployPod
(
svc
*
core
.
Service
)
error
{
objs
:=
objectset
.
NewObjectSet
()
objs
:=
objectset
.
NewObjectSet
()
if
!
h
.
enabled
{
if
!
h
.
enabled
{
return
h
.
processor
.
NewDesiredSet
(
svc
,
objs
)
.
Apply
()
return
h
.
processor
.
NewDesiredSet
(
svc
,
objs
)
.
Apply
()
}
}
d
ep
,
err
:=
h
.
newDeploymen
t
(
svc
)
d
s
,
err
:=
h
.
newDaemonSe
t
(
svc
)
if
err
!=
nil
{
if
err
!=
nil
{
return
err
return
err
}
}
if
d
ep
!=
nil
{
if
d
s
!=
nil
{
objs
.
Add
(
d
ep
)
objs
.
Add
(
d
s
)
}
}
return
h
.
processor
.
NewDesiredSet
(
svc
,
objs
)
.
Apply
()
return
h
.
processor
.
NewDesiredSet
(
svc
,
objs
)
.
Apply
()
}
}
func
(
h
*
handler
)
newD
eployment
(
svc
*
core
.
Service
)
(
*
apps
.
Deploymen
t
,
error
)
{
func
(
h
*
handler
)
newD
aemonSet
(
svc
*
core
.
Service
)
(
*
apps
.
DaemonSe
t
,
error
)
{
name
:=
fmt
.
Sprintf
(
"svclb-%s"
,
svc
.
Name
)
name
:=
fmt
.
Sprintf
(
"svclb-%s"
,
svc
.
Name
)
zeroInt
:=
intstr
.
FromInt
(
0
)
oneInt
:=
intstr
.
FromInt
(
1
)
oneInt
:=
intstr
.
FromInt
(
1
)
replicas
:=
int32
(
0
)
nodes
,
err
:=
h
.
nodeCache
.
List
(
""
,
labels
.
Everything
())
if
err
!=
nil
{
return
nil
,
err
}
for
_
,
node
:=
range
nodes
{
ds
:=
&
apps
.
DaemonSet
{
if
Ready
.
IsTrue
(
node
)
{
replicas
++
}
if
replicas
>=
2
{
break
}
}
dep
:=
&
apps
.
Deployment
{
ObjectMeta
:
meta
.
ObjectMeta
{
ObjectMeta
:
meta
.
ObjectMeta
{
Name
:
name
,
Name
:
name
,
Namespace
:
svc
.
Namespace
,
Namespace
:
svc
.
Namespace
,
...
@@ -249,13 +251,15 @@ func (h *handler) newDeployment(svc *core.Service) (*apps.Deployment, error) {
...
@@ -249,13 +251,15 @@ func (h *handler) newDeployment(svc *core.Service) (*apps.Deployment, error) {
Controller
:
&
trueVal
,
Controller
:
&
trueVal
,
},
},
},
},
Labels
:
map
[
string
]
string
{
nodeSelectorLabel
:
"false"
,
},
},
},
TypeMeta
:
meta
.
TypeMeta
{
TypeMeta
:
meta
.
TypeMeta
{
Kind
:
"D
eploymen
t"
,
Kind
:
"D
aemonSe
t"
,
APIVersion
:
"apps/v1"
,
APIVersion
:
"apps/v1"
,
},
},
Spec
:
apps
.
DeploymentSpec
{
Spec
:
apps
.
DaemonSetSpec
{
Replicas
:
&
replicas
,
Selector
:
&
meta
.
LabelSelector
{
Selector
:
&
meta
.
LabelSelector
{
MatchLabels
:
map
[
string
]
string
{
MatchLabels
:
map
[
string
]
string
{
"app"
:
name
,
"app"
:
name
,
...
@@ -269,10 +273,9 @@ func (h *handler) newDeployment(svc *core.Service) (*apps.Deployment, error) {
...
@@ -269,10 +273,9 @@ func (h *handler) newDeployment(svc *core.Service) (*apps.Deployment, error) {
},
},
},
},
},
},
Strategy
:
apps
.
DeploymentStrategy
{
UpdateStrategy
:
apps
.
DaemonSetUpdateStrategy
{
Type
:
apps
.
RollingUpdateDeploymentStrategyType
,
Type
:
apps
.
RollingUpdateDaemonSetStrategyType
,
RollingUpdate
:
&
apps
.
RollingUpdateDeployment
{
RollingUpdate
:
&
apps
.
RollingUpdateDaemonSet
{
MaxSurge
:
&
zeroInt
,
MaxUnavailable
:
&
oneInt
,
MaxUnavailable
:
&
oneInt
,
},
},
},
},
...
@@ -319,8 +322,44 @@ func (h *handler) newDeployment(svc *core.Service) (*apps.Deployment, error) {
...
@@ -319,8 +322,44 @@ func (h *handler) newDeployment(svc *core.Service) (*apps.Deployment, error) {
},
},
}
}
dep
.
Spec
.
Template
.
Spec
.
Containers
=
append
(
dep
.
Spec
.
Template
.
Spec
.
Containers
,
container
)
ds
.
Spec
.
Template
.
Spec
.
Containers
=
append
(
ds
.
Spec
.
Template
.
Spec
.
Containers
,
container
)
}
// Add node selector only if label "svccontroller.k3s.cattle.io/enablelb" exists on the nodes
selector
,
err
:=
labels
.
Parse
(
daemonsetNodeLabel
)
if
err
!=
nil
{
return
nil
,
err
}
nodesWithLabel
,
err
:=
h
.
nodeCache
.
List
(
""
,
selector
)
if
err
!=
nil
{
return
nil
,
err
}
if
len
(
nodesWithLabel
)
>
0
{
ds
.
Spec
.
Template
.
Spec
.
NodeSelector
=
map
[
string
]
string
{
daemonsetNodeLabel
:
"true"
,
}
ds
.
Labels
[
nodeSelectorLabel
]
=
"true"
}
return
ds
,
nil
}
func
(
h
*
handler
)
updateDaemonSets
()
error
{
daemonsets
,
err
:=
h
.
daemonsets
.
DaemonSets
(
""
)
.
List
(
meta
.
ListOptions
{
LabelSelector
:
nodeSelectorLabel
+
"=false"
,
})
if
err
!=
nil
{
return
err
}
for
_
,
ds
:=
range
daemonsets
.
Items
{
ds
.
Spec
.
Template
.
Spec
.
NodeSelector
=
map
[
string
]
string
{
daemonsetNodeLabel
:
"true"
,
}
ds
.
Labels
[
nodeSelectorLabel
]
=
"true"
if
_
,
err
:=
h
.
daemonsets
.
DaemonSets
(
ds
.
Namespace
)
.
Update
(
&
ds
);
err
!=
nil
{
return
err
}
}
}
return
dep
,
nil
return
nil
}
}
types/apis/apps/v1/zz_generated_d
eploymen
t_controller.go
→
types/apis/apps/v1/zz_generated_d
aemon_se
t_controller.go
View file @
875ba289
...
@@ -17,83 +17,83 @@ import (
...
@@ -17,83 +17,83 @@ import (
)
)
var
(
var
(
D
eploymen
tGroupVersionKind
=
schema
.
GroupVersionKind
{
D
aemonSe
tGroupVersionKind
=
schema
.
GroupVersionKind
{
Version
:
Version
,
Version
:
Version
,
Group
:
GroupName
,
Group
:
GroupName
,
Kind
:
"D
eploymen
t"
,
Kind
:
"D
aemonSe
t"
,
}
}
D
eploymen
tResource
=
metav1
.
APIResource
{
D
aemonSe
tResource
=
metav1
.
APIResource
{
Name
:
"d
eploymen
ts"
,
Name
:
"d
aemonse
ts"
,
SingularName
:
"d
eploymen
t"
,
SingularName
:
"d
aemonse
t"
,
Namespaced
:
true
,
Namespaced
:
true
,
Kind
:
D
eploymen
tGroupVersionKind
.
Kind
,
Kind
:
D
aemonSe
tGroupVersionKind
.
Kind
,
}
}
)
)
func
NewD
eployment
(
namespace
,
name
string
,
obj
v1
.
Deployment
)
*
v1
.
Deploymen
t
{
func
NewD
aemonSet
(
namespace
,
name
string
,
obj
v1
.
DaemonSet
)
*
v1
.
DaemonSe
t
{
obj
.
APIVersion
,
obj
.
Kind
=
D
eploymen
tGroupVersionKind
.
ToAPIVersionAndKind
()
obj
.
APIVersion
,
obj
.
Kind
=
D
aemonSe
tGroupVersionKind
.
ToAPIVersionAndKind
()
obj
.
Name
=
name
obj
.
Name
=
name
obj
.
Namespace
=
namespace
obj
.
Namespace
=
namespace
return
&
obj
return
&
obj
}
}
type
D
eploymen
tList
struct
{
type
D
aemonSe
tList
struct
{
metav1
.
TypeMeta
`json:",inline"`
metav1
.
TypeMeta
`json:",inline"`
metav1
.
ListMeta
`json:"metadata,omitempty"`
metav1
.
ListMeta
`json:"metadata,omitempty"`
Items
[]
v1
.
D
eploymen
t
Items
[]
v1
.
D
aemonSe
t
}
}
type
D
eploymentHandlerFunc
func
(
key
string
,
obj
*
v1
.
Deploymen
t
)
(
runtime
.
Object
,
error
)
type
D
aemonSetHandlerFunc
func
(
key
string
,
obj
*
v1
.
DaemonSe
t
)
(
runtime
.
Object
,
error
)
type
D
eploymentChangeHandlerFunc
func
(
obj
*
v1
.
Deploymen
t
)
(
runtime
.
Object
,
error
)
type
D
aemonSetChangeHandlerFunc
func
(
obj
*
v1
.
DaemonSe
t
)
(
runtime
.
Object
,
error
)
type
D
eploymen
tLister
interface
{
type
D
aemonSe
tLister
interface
{
List
(
namespace
string
,
selector
labels
.
Selector
)
(
ret
[]
*
v1
.
D
eploymen
t
,
err
error
)
List
(
namespace
string
,
selector
labels
.
Selector
)
(
ret
[]
*
v1
.
D
aemonSe
t
,
err
error
)
Get
(
namespace
,
name
string
)
(
*
v1
.
D
eploymen
t
,
error
)
Get
(
namespace
,
name
string
)
(
*
v1
.
D
aemonSe
t
,
error
)
}
}
type
D
eploymen
tController
interface
{
type
D
aemonSe
tController
interface
{
Generic
()
controller
.
GenericController
Generic
()
controller
.
GenericController
Informer
()
cache
.
SharedIndexInformer
Informer
()
cache
.
SharedIndexInformer
Lister
()
D
eploymen
tLister
Lister
()
D
aemonSe
tLister
AddHandler
(
ctx
context
.
Context
,
name
string
,
handler
D
eploymen
tHandlerFunc
)
AddHandler
(
ctx
context
.
Context
,
name
string
,
handler
D
aemonSe
tHandlerFunc
)
AddClusterScopedHandler
(
ctx
context
.
Context
,
name
,
clusterName
string
,
handler
D
eploymen
tHandlerFunc
)
AddClusterScopedHandler
(
ctx
context
.
Context
,
name
,
clusterName
string
,
handler
D
aemonSe
tHandlerFunc
)
Enqueue
(
namespace
,
name
string
)
Enqueue
(
namespace
,
name
string
)
Sync
(
ctx
context
.
Context
)
error
Sync
(
ctx
context
.
Context
)
error
Start
(
ctx
context
.
Context
,
threadiness
int
)
error
Start
(
ctx
context
.
Context
,
threadiness
int
)
error
}
}
type
D
eploymen
tInterface
interface
{
type
D
aemonSe
tInterface
interface
{
ObjectClient
()
*
objectclient
.
ObjectClient
ObjectClient
()
*
objectclient
.
ObjectClient
Create
(
*
v1
.
D
eployment
)
(
*
v1
.
Deploymen
t
,
error
)
Create
(
*
v1
.
D
aemonSet
)
(
*
v1
.
DaemonSe
t
,
error
)
GetNamespaced
(
namespace
,
name
string
,
opts
metav1
.
GetOptions
)
(
*
v1
.
D
eploymen
t
,
error
)
GetNamespaced
(
namespace
,
name
string
,
opts
metav1
.
GetOptions
)
(
*
v1
.
D
aemonSe
t
,
error
)
Get
(
name
string
,
opts
metav1
.
GetOptions
)
(
*
v1
.
D
eploymen
t
,
error
)
Get
(
name
string
,
opts
metav1
.
GetOptions
)
(
*
v1
.
D
aemonSe
t
,
error
)
Update
(
*
v1
.
D
eployment
)
(
*
v1
.
Deploymen
t
,
error
)
Update
(
*
v1
.
D
aemonSet
)
(
*
v1
.
DaemonSe
t
,
error
)
Delete
(
name
string
,
options
*
metav1
.
DeleteOptions
)
error
Delete
(
name
string
,
options
*
metav1
.
DeleteOptions
)
error
DeleteNamespaced
(
namespace
,
name
string
,
options
*
metav1
.
DeleteOptions
)
error
DeleteNamespaced
(
namespace
,
name
string
,
options
*
metav1
.
DeleteOptions
)
error
List
(
opts
metav1
.
ListOptions
)
(
*
D
eploymen
tList
,
error
)
List
(
opts
metav1
.
ListOptions
)
(
*
D
aemonSe
tList
,
error
)
Watch
(
opts
metav1
.
ListOptions
)
(
watch
.
Interface
,
error
)
Watch
(
opts
metav1
.
ListOptions
)
(
watch
.
Interface
,
error
)
DeleteCollection
(
deleteOpts
*
metav1
.
DeleteOptions
,
listOpts
metav1
.
ListOptions
)
error
DeleteCollection
(
deleteOpts
*
metav1
.
DeleteOptions
,
listOpts
metav1
.
ListOptions
)
error
Controller
()
D
eploymen
tController
Controller
()
D
aemonSe
tController
AddHandler
(
ctx
context
.
Context
,
name
string
,
sync
D
eploymen
tHandlerFunc
)
AddHandler
(
ctx
context
.
Context
,
name
string
,
sync
D
aemonSe
tHandlerFunc
)
AddLifecycle
(
ctx
context
.
Context
,
name
string
,
lifecycle
D
eploymen
tLifecycle
)
AddLifecycle
(
ctx
context
.
Context
,
name
string
,
lifecycle
D
aemonSe
tLifecycle
)
AddClusterScopedHandler
(
ctx
context
.
Context
,
name
,
clusterName
string
,
sync
D
eploymen
tHandlerFunc
)
AddClusterScopedHandler
(
ctx
context
.
Context
,
name
,
clusterName
string
,
sync
D
aemonSe
tHandlerFunc
)
AddClusterScopedLifecycle
(
ctx
context
.
Context
,
name
,
clusterName
string
,
lifecycle
D
eploymen
tLifecycle
)
AddClusterScopedLifecycle
(
ctx
context
.
Context
,
name
,
clusterName
string
,
lifecycle
D
aemonSe
tLifecycle
)
}
}
type
d
eploymen
tLister
struct
{
type
d
aemonSe
tLister
struct
{
controller
*
d
eploymen
tController
controller
*
d
aemonSe
tController
}
}
func
(
l
*
d
eploymentLister
)
List
(
namespace
string
,
selector
labels
.
Selector
)
(
ret
[]
*
v1
.
Deploymen
t
,
err
error
)
{
func
(
l
*
d
aemonSetLister
)
List
(
namespace
string
,
selector
labels
.
Selector
)
(
ret
[]
*
v1
.
DaemonSe
t
,
err
error
)
{
err
=
cache
.
ListAllByNamespace
(
l
.
controller
.
Informer
()
.
GetIndexer
(),
namespace
,
selector
,
func
(
obj
interface
{})
{
err
=
cache
.
ListAllByNamespace
(
l
.
controller
.
Informer
()
.
GetIndexer
(),
namespace
,
selector
,
func
(
obj
interface
{})
{
ret
=
append
(
ret
,
obj
.
(
*
v1
.
D
eploymen
t
))
ret
=
append
(
ret
,
obj
.
(
*
v1
.
D
aemonSe
t
))
})
})
return
return
}
}
func
(
l
*
d
eploymentLister
)
Get
(
namespace
,
name
string
)
(
*
v1
.
Deploymen
t
,
error
)
{
func
(
l
*
d
aemonSetLister
)
Get
(
namespace
,
name
string
)
(
*
v1
.
DaemonSe
t
,
error
)
{
var
key
string
var
key
string
if
namespace
!=
""
{
if
namespace
!=
""
{
key
=
namespace
+
"/"
+
name
key
=
namespace
+
"/"
+
name
...
@@ -106,32 +106,32 @@ func (l *deploymentLister) Get(namespace, name string) (*v1.Deployment, error) {
...
@@ -106,32 +106,32 @@ func (l *deploymentLister) Get(namespace, name string) (*v1.Deployment, error) {
}
}
if
!
exists
{
if
!
exists
{
return
nil
,
errors
.
NewNotFound
(
schema
.
GroupResource
{
return
nil
,
errors
.
NewNotFound
(
schema
.
GroupResource
{
Group
:
D
eploymen
tGroupVersionKind
.
Group
,
Group
:
D
aemonSe
tGroupVersionKind
.
Group
,
Resource
:
"d
eploymen
t"
,
Resource
:
"d
aemonSe
t"
,
},
key
)
},
key
)
}
}
return
obj
.
(
*
v1
.
D
eploymen
t
),
nil
return
obj
.
(
*
v1
.
D
aemonSe
t
),
nil
}
}
type
d
eploymen
tController
struct
{
type
d
aemonSe
tController
struct
{
controller
.
GenericController
controller
.
GenericController
}
}
func
(
c
*
d
eploymen
tController
)
Generic
()
controller
.
GenericController
{
func
(
c
*
d
aemonSe
tController
)
Generic
()
controller
.
GenericController
{
return
c
.
GenericController
return
c
.
GenericController
}
}
func
(
c
*
d
eploymentController
)
Lister
()
Deploymen
tLister
{
func
(
c
*
d
aemonSetController
)
Lister
()
DaemonSe
tLister
{
return
&
d
eploymen
tLister
{
return
&
d
aemonSe
tLister
{
controller
:
c
,
controller
:
c
,
}
}
}
}
func
(
c
*
d
eploymentController
)
AddHandler
(
ctx
context
.
Context
,
name
string
,
handler
Deploymen
tHandlerFunc
)
{
func
(
c
*
d
aemonSetController
)
AddHandler
(
ctx
context
.
Context
,
name
string
,
handler
DaemonSe
tHandlerFunc
)
{
c
.
GenericController
.
AddHandler
(
ctx
,
name
,
func
(
key
string
,
obj
interface
{})
(
interface
{},
error
)
{
c
.
GenericController
.
AddHandler
(
ctx
,
name
,
func
(
key
string
,
obj
interface
{})
(
interface
{},
error
)
{
if
obj
==
nil
{
if
obj
==
nil
{
return
handler
(
key
,
nil
)
return
handler
(
key
,
nil
)
}
else
if
v
,
ok
:=
obj
.
(
*
v1
.
D
eploymen
t
);
ok
{
}
else
if
v
,
ok
:=
obj
.
(
*
v1
.
D
aemonSe
t
);
ok
{
return
handler
(
key
,
v
)
return
handler
(
key
,
v
)
}
else
{
}
else
{
return
nil
,
nil
return
nil
,
nil
...
@@ -139,11 +139,11 @@ func (c *deploymentController) AddHandler(ctx context.Context, name string, hand
...
@@ -139,11 +139,11 @@ func (c *deploymentController) AddHandler(ctx context.Context, name string, hand
})
})
}
}
func
(
c
*
d
eploymentController
)
AddClusterScopedHandler
(
ctx
context
.
Context
,
name
,
cluster
string
,
handler
Deploymen
tHandlerFunc
)
{
func
(
c
*
d
aemonSetController
)
AddClusterScopedHandler
(
ctx
context
.
Context
,
name
,
cluster
string
,
handler
DaemonSe
tHandlerFunc
)
{
c
.
GenericController
.
AddHandler
(
ctx
,
name
,
func
(
key
string
,
obj
interface
{})
(
interface
{},
error
)
{
c
.
GenericController
.
AddHandler
(
ctx
,
name
,
func
(
key
string
,
obj
interface
{})
(
interface
{},
error
)
{
if
obj
==
nil
{
if
obj
==
nil
{
return
handler
(
key
,
nil
)
return
handler
(
key
,
nil
)
}
else
if
v
,
ok
:=
obj
.
(
*
v1
.
D
eploymen
t
);
ok
&&
controller
.
ObjectInCluster
(
cluster
,
obj
)
{
}
else
if
v
,
ok
:=
obj
.
(
*
v1
.
D
aemonSe
t
);
ok
&&
controller
.
ObjectInCluster
(
cluster
,
obj
)
{
return
handler
(
key
,
v
)
return
handler
(
key
,
v
)
}
else
{
}
else
{
return
nil
,
nil
return
nil
,
nil
...
@@ -151,228 +151,228 @@ func (c *deploymentController) AddClusterScopedHandler(ctx context.Context, name
...
@@ -151,228 +151,228 @@ func (c *deploymentController) AddClusterScopedHandler(ctx context.Context, name
})
})
}
}
type
d
eploymen
tFactory
struct
{
type
d
aemonSe
tFactory
struct
{
}
}
func
(
c
d
eploymen
tFactory
)
Object
()
runtime
.
Object
{
func
(
c
d
aemonSe
tFactory
)
Object
()
runtime
.
Object
{
return
&
v1
.
D
eploymen
t
{}
return
&
v1
.
D
aemonSe
t
{}
}
}
func
(
c
d
eploymen
tFactory
)
List
()
runtime
.
Object
{
func
(
c
d
aemonSe
tFactory
)
List
()
runtime
.
Object
{
return
&
D
eploymen
tList
{}
return
&
D
aemonSe
tList
{}
}
}
func
(
s
*
d
eploymentClient
)
Controller
()
Deploymen
tController
{
func
(
s
*
d
aemonSetClient
)
Controller
()
DaemonSe
tController
{
s
.
client
.
Lock
()
s
.
client
.
Lock
()
defer
s
.
client
.
Unlock
()
defer
s
.
client
.
Unlock
()
c
,
ok
:=
s
.
client
.
d
eploymen
tControllers
[
s
.
ns
]
c
,
ok
:=
s
.
client
.
d
aemonSe
tControllers
[
s
.
ns
]
if
ok
{
if
ok
{
return
c
return
c
}
}
genericController
:=
controller
.
NewGenericController
(
D
eploymen
tGroupVersionKind
.
Kind
+
"Controller"
,
genericController
:=
controller
.
NewGenericController
(
D
aemonSe
tGroupVersionKind
.
Kind
+
"Controller"
,
s
.
objectClient
)
s
.
objectClient
)
c
=
&
d
eploymen
tController
{
c
=
&
d
aemonSe
tController
{
GenericController
:
genericController
,
GenericController
:
genericController
,
}
}
s
.
client
.
d
eploymen
tControllers
[
s
.
ns
]
=
c
s
.
client
.
d
aemonSe
tControllers
[
s
.
ns
]
=
c
s
.
client
.
starters
=
append
(
s
.
client
.
starters
,
c
)
s
.
client
.
starters
=
append
(
s
.
client
.
starters
,
c
)
return
c
return
c
}
}
type
d
eploymen
tClient
struct
{
type
d
aemonSe
tClient
struct
{
client
*
Client
client
*
Client
ns
string
ns
string
objectClient
*
objectclient
.
ObjectClient
objectClient
*
objectclient
.
ObjectClient
controller
D
eploymen
tController
controller
D
aemonSe
tController
}
}
func
(
s
*
d
eploymen
tClient
)
ObjectClient
()
*
objectclient
.
ObjectClient
{
func
(
s
*
d
aemonSe
tClient
)
ObjectClient
()
*
objectclient
.
ObjectClient
{
return
s
.
objectClient
return
s
.
objectClient
}
}
func
(
s
*
d
eploymentClient
)
Create
(
o
*
v1
.
Deployment
)
(
*
v1
.
Deploymen
t
,
error
)
{
func
(
s
*
d
aemonSetClient
)
Create
(
o
*
v1
.
DaemonSet
)
(
*
v1
.
DaemonSe
t
,
error
)
{
obj
,
err
:=
s
.
objectClient
.
Create
(
o
)
obj
,
err
:=
s
.
objectClient
.
Create
(
o
)
return
obj
.
(
*
v1
.
D
eploymen
t
),
err
return
obj
.
(
*
v1
.
D
aemonSe
t
),
err
}
}
func
(
s
*
d
eploymentClient
)
Get
(
name
string
,
opts
metav1
.
GetOptions
)
(
*
v1
.
Deploymen
t
,
error
)
{
func
(
s
*
d
aemonSetClient
)
Get
(
name
string
,
opts
metav1
.
GetOptions
)
(
*
v1
.
DaemonSe
t
,
error
)
{
obj
,
err
:=
s
.
objectClient
.
Get
(
name
,
opts
)
obj
,
err
:=
s
.
objectClient
.
Get
(
name
,
opts
)
return
obj
.
(
*
v1
.
D
eploymen
t
),
err
return
obj
.
(
*
v1
.
D
aemonSe
t
),
err
}
}
func
(
s
*
d
eploymentClient
)
GetNamespaced
(
namespace
,
name
string
,
opts
metav1
.
GetOptions
)
(
*
v1
.
Deploymen
t
,
error
)
{
func
(
s
*
d
aemonSetClient
)
GetNamespaced
(
namespace
,
name
string
,
opts
metav1
.
GetOptions
)
(
*
v1
.
DaemonSe
t
,
error
)
{
obj
,
err
:=
s
.
objectClient
.
GetNamespaced
(
namespace
,
name
,
opts
)
obj
,
err
:=
s
.
objectClient
.
GetNamespaced
(
namespace
,
name
,
opts
)
return
obj
.
(
*
v1
.
D
eploymen
t
),
err
return
obj
.
(
*
v1
.
D
aemonSe
t
),
err
}
}
func
(
s
*
d
eploymentClient
)
Update
(
o
*
v1
.
Deployment
)
(
*
v1
.
Deploymen
t
,
error
)
{
func
(
s
*
d
aemonSetClient
)
Update
(
o
*
v1
.
DaemonSet
)
(
*
v1
.
DaemonSe
t
,
error
)
{
obj
,
err
:=
s
.
objectClient
.
Update
(
o
.
Name
,
o
)
obj
,
err
:=
s
.
objectClient
.
Update
(
o
.
Name
,
o
)
return
obj
.
(
*
v1
.
D
eploymen
t
),
err
return
obj
.
(
*
v1
.
D
aemonSe
t
),
err
}
}
func
(
s
*
d
eploymen
tClient
)
Delete
(
name
string
,
options
*
metav1
.
DeleteOptions
)
error
{
func
(
s
*
d
aemonSe
tClient
)
Delete
(
name
string
,
options
*
metav1
.
DeleteOptions
)
error
{
return
s
.
objectClient
.
Delete
(
name
,
options
)
return
s
.
objectClient
.
Delete
(
name
,
options
)
}
}
func
(
s
*
d
eploymen
tClient
)
DeleteNamespaced
(
namespace
,
name
string
,
options
*
metav1
.
DeleteOptions
)
error
{
func
(
s
*
d
aemonSe
tClient
)
DeleteNamespaced
(
namespace
,
name
string
,
options
*
metav1
.
DeleteOptions
)
error
{
return
s
.
objectClient
.
DeleteNamespaced
(
namespace
,
name
,
options
)
return
s
.
objectClient
.
DeleteNamespaced
(
namespace
,
name
,
options
)
}
}
func
(
s
*
d
eploymentClient
)
List
(
opts
metav1
.
ListOptions
)
(
*
Deploymen
tList
,
error
)
{
func
(
s
*
d
aemonSetClient
)
List
(
opts
metav1
.
ListOptions
)
(
*
DaemonSe
tList
,
error
)
{
obj
,
err
:=
s
.
objectClient
.
List
(
opts
)
obj
,
err
:=
s
.
objectClient
.
List
(
opts
)
return
obj
.
(
*
D
eploymen
tList
),
err
return
obj
.
(
*
D
aemonSe
tList
),
err
}
}
func
(
s
*
d
eploymen
tClient
)
Watch
(
opts
metav1
.
ListOptions
)
(
watch
.
Interface
,
error
)
{
func
(
s
*
d
aemonSe
tClient
)
Watch
(
opts
metav1
.
ListOptions
)
(
watch
.
Interface
,
error
)
{
return
s
.
objectClient
.
Watch
(
opts
)
return
s
.
objectClient
.
Watch
(
opts
)
}
}
// Patch applies the patch and returns the patched deployment.
// Patch applies the patch and returns the patched deployment.
func
(
s
*
d
eploymentClient
)
Patch
(
o
*
v1
.
Deployment
,
patchType
types
.
PatchType
,
data
[]
byte
,
subresources
...
string
)
(
*
v1
.
Deploymen
t
,
error
)
{
func
(
s
*
d
aemonSetClient
)
Patch
(
o
*
v1
.
DaemonSet
,
patchType
types
.
PatchType
,
data
[]
byte
,
subresources
...
string
)
(
*
v1
.
DaemonSe
t
,
error
)
{
obj
,
err
:=
s
.
objectClient
.
Patch
(
o
.
Name
,
o
,
patchType
,
data
,
subresources
...
)
obj
,
err
:=
s
.
objectClient
.
Patch
(
o
.
Name
,
o
,
patchType
,
data
,
subresources
...
)
return
obj
.
(
*
v1
.
D
eploymen
t
),
err
return
obj
.
(
*
v1
.
D
aemonSe
t
),
err
}
}
func
(
s
*
d
eploymen
tClient
)
DeleteCollection
(
deleteOpts
*
metav1
.
DeleteOptions
,
listOpts
metav1
.
ListOptions
)
error
{
func
(
s
*
d
aemonSe
tClient
)
DeleteCollection
(
deleteOpts
*
metav1
.
DeleteOptions
,
listOpts
metav1
.
ListOptions
)
error
{
return
s
.
objectClient
.
DeleteCollection
(
deleteOpts
,
listOpts
)
return
s
.
objectClient
.
DeleteCollection
(
deleteOpts
,
listOpts
)
}
}
func
(
s
*
d
eploymentClient
)
AddHandler
(
ctx
context
.
Context
,
name
string
,
sync
Deploymen
tHandlerFunc
)
{
func
(
s
*
d
aemonSetClient
)
AddHandler
(
ctx
context
.
Context
,
name
string
,
sync
DaemonSe
tHandlerFunc
)
{
s
.
Controller
()
.
AddHandler
(
ctx
,
name
,
sync
)
s
.
Controller
()
.
AddHandler
(
ctx
,
name
,
sync
)
}
}
func
(
s
*
d
eploymentClient
)
AddLifecycle
(
ctx
context
.
Context
,
name
string
,
lifecycle
Deploymen
tLifecycle
)
{
func
(
s
*
d
aemonSetClient
)
AddLifecycle
(
ctx
context
.
Context
,
name
string
,
lifecycle
DaemonSe
tLifecycle
)
{
sync
:=
NewD
eploymen
tLifecycleAdapter
(
name
,
false
,
s
,
lifecycle
)
sync
:=
NewD
aemonSe
tLifecycleAdapter
(
name
,
false
,
s
,
lifecycle
)
s
.
Controller
()
.
AddHandler
(
ctx
,
name
,
sync
)
s
.
Controller
()
.
AddHandler
(
ctx
,
name
,
sync
)
}
}
func
(
s
*
d
eploymentClient
)
AddClusterScopedHandler
(
ctx
context
.
Context
,
name
,
clusterName
string
,
sync
Deploymen
tHandlerFunc
)
{
func
(
s
*
d
aemonSetClient
)
AddClusterScopedHandler
(
ctx
context
.
Context
,
name
,
clusterName
string
,
sync
DaemonSe
tHandlerFunc
)
{
s
.
Controller
()
.
AddClusterScopedHandler
(
ctx
,
name
,
clusterName
,
sync
)
s
.
Controller
()
.
AddClusterScopedHandler
(
ctx
,
name
,
clusterName
,
sync
)
}
}
func
(
s
*
d
eploymentClient
)
AddClusterScopedLifecycle
(
ctx
context
.
Context
,
name
,
clusterName
string
,
lifecycle
Deploymen
tLifecycle
)
{
func
(
s
*
d
aemonSetClient
)
AddClusterScopedLifecycle
(
ctx
context
.
Context
,
name
,
clusterName
string
,
lifecycle
DaemonSe
tLifecycle
)
{
sync
:=
NewD
eploymen
tLifecycleAdapter
(
name
+
"_"
+
clusterName
,
true
,
s
,
lifecycle
)
sync
:=
NewD
aemonSe
tLifecycleAdapter
(
name
+
"_"
+
clusterName
,
true
,
s
,
lifecycle
)
s
.
Controller
()
.
AddClusterScopedHandler
(
ctx
,
name
,
clusterName
,
sync
)
s
.
Controller
()
.
AddClusterScopedHandler
(
ctx
,
name
,
clusterName
,
sync
)
}
}
type
D
eploymentIndexer
func
(
obj
*
v1
.
Deploymen
t
)
([]
string
,
error
)
type
D
aemonSetIndexer
func
(
obj
*
v1
.
DaemonSe
t
)
([]
string
,
error
)
type
D
eploymen
tClientCache
interface
{
type
D
aemonSe
tClientCache
interface
{
Get
(
namespace
,
name
string
)
(
*
v1
.
D
eploymen
t
,
error
)
Get
(
namespace
,
name
string
)
(
*
v1
.
D
aemonSe
t
,
error
)
List
(
namespace
string
,
selector
labels
.
Selector
)
([]
*
v1
.
D
eploymen
t
,
error
)
List
(
namespace
string
,
selector
labels
.
Selector
)
([]
*
v1
.
D
aemonSe
t
,
error
)
Index
(
name
string
,
indexer
D
eploymen
tIndexer
)
Index
(
name
string
,
indexer
D
aemonSe
tIndexer
)
GetIndexed
(
name
,
key
string
)
([]
*
v1
.
D
eploymen
t
,
error
)
GetIndexed
(
name
,
key
string
)
([]
*
v1
.
D
aemonSe
t
,
error
)
}
}
type
D
eploymen
tClient
interface
{
type
D
aemonSe
tClient
interface
{
Create
(
*
v1
.
D
eployment
)
(
*
v1
.
Deploymen
t
,
error
)
Create
(
*
v1
.
D
aemonSet
)
(
*
v1
.
DaemonSe
t
,
error
)
Get
(
namespace
,
name
string
,
opts
metav1
.
GetOptions
)
(
*
v1
.
D
eploymen
t
,
error
)
Get
(
namespace
,
name
string
,
opts
metav1
.
GetOptions
)
(
*
v1
.
D
aemonSe
t
,
error
)
Update
(
*
v1
.
D
eployment
)
(
*
v1
.
Deploymen
t
,
error
)
Update
(
*
v1
.
D
aemonSet
)
(
*
v1
.
DaemonSe
t
,
error
)
Delete
(
namespace
,
name
string
,
options
*
metav1
.
DeleteOptions
)
error
Delete
(
namespace
,
name
string
,
options
*
metav1
.
DeleteOptions
)
error
List
(
namespace
string
,
opts
metav1
.
ListOptions
)
(
*
D
eploymen
tList
,
error
)
List
(
namespace
string
,
opts
metav1
.
ListOptions
)
(
*
D
aemonSe
tList
,
error
)
Watch
(
opts
metav1
.
ListOptions
)
(
watch
.
Interface
,
error
)
Watch
(
opts
metav1
.
ListOptions
)
(
watch
.
Interface
,
error
)
Cache
()
D
eploymen
tClientCache
Cache
()
D
aemonSe
tClientCache
OnCreate
(
ctx
context
.
Context
,
name
string
,
sync
D
eploymen
tChangeHandlerFunc
)
OnCreate
(
ctx
context
.
Context
,
name
string
,
sync
D
aemonSe
tChangeHandlerFunc
)
OnChange
(
ctx
context
.
Context
,
name
string
,
sync
D
eploymen
tChangeHandlerFunc
)
OnChange
(
ctx
context
.
Context
,
name
string
,
sync
D
aemonSe
tChangeHandlerFunc
)
OnRemove
(
ctx
context
.
Context
,
name
string
,
sync
D
eploymen
tChangeHandlerFunc
)
OnRemove
(
ctx
context
.
Context
,
name
string
,
sync
D
aemonSe
tChangeHandlerFunc
)
Enqueue
(
namespace
,
name
string
)
Enqueue
(
namespace
,
name
string
)
Generic
()
controller
.
GenericController
Generic
()
controller
.
GenericController
ObjectClient
()
*
objectclient
.
ObjectClient
ObjectClient
()
*
objectclient
.
ObjectClient
Interface
()
D
eploymen
tInterface
Interface
()
D
aemonSe
tInterface
}
}
type
d
eploymen
tClientCache
struct
{
type
d
aemonSe
tClientCache
struct
{
client
*
d
eploymen
tClient2
client
*
d
aemonSe
tClient2
}
}
type
d
eploymen
tClient2
struct
{
type
d
aemonSe
tClient2
struct
{
iface
D
eploymen
tInterface
iface
D
aemonSe
tInterface
controller
D
eploymen
tController
controller
D
aemonSe
tController
}
}
func
(
n
*
d
eploymentClient2
)
Interface
()
Deploymen
tInterface
{
func
(
n
*
d
aemonSetClient2
)
Interface
()
DaemonSe
tInterface
{
return
n
.
iface
return
n
.
iface
}
}
func
(
n
*
d
eploymen
tClient2
)
Generic
()
controller
.
GenericController
{
func
(
n
*
d
aemonSe
tClient2
)
Generic
()
controller
.
GenericController
{
return
n
.
iface
.
Controller
()
.
Generic
()
return
n
.
iface
.
Controller
()
.
Generic
()
}
}
func
(
n
*
d
eploymen
tClient2
)
ObjectClient
()
*
objectclient
.
ObjectClient
{
func
(
n
*
d
aemonSe
tClient2
)
ObjectClient
()
*
objectclient
.
ObjectClient
{
return
n
.
Interface
()
.
ObjectClient
()
return
n
.
Interface
()
.
ObjectClient
()
}
}
func
(
n
*
d
eploymen
tClient2
)
Enqueue
(
namespace
,
name
string
)
{
func
(
n
*
d
aemonSe
tClient2
)
Enqueue
(
namespace
,
name
string
)
{
n
.
iface
.
Controller
()
.
Enqueue
(
namespace
,
name
)
n
.
iface
.
Controller
()
.
Enqueue
(
namespace
,
name
)
}
}
func
(
n
*
d
eploymentClient2
)
Create
(
obj
*
v1
.
Deployment
)
(
*
v1
.
Deploymen
t
,
error
)
{
func
(
n
*
d
aemonSetClient2
)
Create
(
obj
*
v1
.
DaemonSet
)
(
*
v1
.
DaemonSe
t
,
error
)
{
return
n
.
iface
.
Create
(
obj
)
return
n
.
iface
.
Create
(
obj
)
}
}
func
(
n
*
d
eploymentClient2
)
Get
(
namespace
,
name
string
,
opts
metav1
.
GetOptions
)
(
*
v1
.
Deploymen
t
,
error
)
{
func
(
n
*
d
aemonSetClient2
)
Get
(
namespace
,
name
string
,
opts
metav1
.
GetOptions
)
(
*
v1
.
DaemonSe
t
,
error
)
{
return
n
.
iface
.
GetNamespaced
(
namespace
,
name
,
opts
)
return
n
.
iface
.
GetNamespaced
(
namespace
,
name
,
opts
)
}
}
func
(
n
*
d
eploymentClient2
)
Update
(
obj
*
v1
.
Deployment
)
(
*
v1
.
Deploymen
t
,
error
)
{
func
(
n
*
d
aemonSetClient2
)
Update
(
obj
*
v1
.
DaemonSet
)
(
*
v1
.
DaemonSe
t
,
error
)
{
return
n
.
iface
.
Update
(
obj
)
return
n
.
iface
.
Update
(
obj
)
}
}
func
(
n
*
d
eploymen
tClient2
)
Delete
(
namespace
,
name
string
,
options
*
metav1
.
DeleteOptions
)
error
{
func
(
n
*
d
aemonSe
tClient2
)
Delete
(
namespace
,
name
string
,
options
*
metav1
.
DeleteOptions
)
error
{
return
n
.
iface
.
DeleteNamespaced
(
namespace
,
name
,
options
)
return
n
.
iface
.
DeleteNamespaced
(
namespace
,
name
,
options
)
}
}
func
(
n
*
d
eploymentClient2
)
List
(
namespace
string
,
opts
metav1
.
ListOptions
)
(
*
Deploymen
tList
,
error
)
{
func
(
n
*
d
aemonSetClient2
)
List
(
namespace
string
,
opts
metav1
.
ListOptions
)
(
*
DaemonSe
tList
,
error
)
{
return
n
.
iface
.
List
(
opts
)
return
n
.
iface
.
List
(
opts
)
}
}
func
(
n
*
d
eploymen
tClient2
)
Watch
(
opts
metav1
.
ListOptions
)
(
watch
.
Interface
,
error
)
{
func
(
n
*
d
aemonSe
tClient2
)
Watch
(
opts
metav1
.
ListOptions
)
(
watch
.
Interface
,
error
)
{
return
n
.
iface
.
Watch
(
opts
)
return
n
.
iface
.
Watch
(
opts
)
}
}
func
(
n
*
d
eploymentClientCache
)
Get
(
namespace
,
name
string
)
(
*
v1
.
Deploymen
t
,
error
)
{
func
(
n
*
d
aemonSetClientCache
)
Get
(
namespace
,
name
string
)
(
*
v1
.
DaemonSe
t
,
error
)
{
return
n
.
client
.
controller
.
Lister
()
.
Get
(
namespace
,
name
)
return
n
.
client
.
controller
.
Lister
()
.
Get
(
namespace
,
name
)
}
}
func
(
n
*
d
eploymentClientCache
)
List
(
namespace
string
,
selector
labels
.
Selector
)
([]
*
v1
.
Deploymen
t
,
error
)
{
func
(
n
*
d
aemonSetClientCache
)
List
(
namespace
string
,
selector
labels
.
Selector
)
([]
*
v1
.
DaemonSe
t
,
error
)
{
return
n
.
client
.
controller
.
Lister
()
.
List
(
namespace
,
selector
)
return
n
.
client
.
controller
.
Lister
()
.
List
(
namespace
,
selector
)
}
}
func
(
n
*
d
eploymentClient2
)
Cache
()
Deploymen
tClientCache
{
func
(
n
*
d
aemonSetClient2
)
Cache
()
DaemonSe
tClientCache
{
n
.
loadController
()
n
.
loadController
()
return
&
d
eploymen
tClientCache
{
return
&
d
aemonSe
tClientCache
{
client
:
n
,
client
:
n
,
}
}
}
}
func
(
n
*
d
eploymentClient2
)
OnCreate
(
ctx
context
.
Context
,
name
string
,
sync
Deploymen
tChangeHandlerFunc
)
{
func
(
n
*
d
aemonSetClient2
)
OnCreate
(
ctx
context
.
Context
,
name
string
,
sync
DaemonSe
tChangeHandlerFunc
)
{
n
.
loadController
()
n
.
loadController
()
n
.
iface
.
AddLifecycle
(
ctx
,
name
+
"-create"
,
&
d
eploymen
tLifecycleDelegate
{
create
:
sync
})
n
.
iface
.
AddLifecycle
(
ctx
,
name
+
"-create"
,
&
d
aemonSe
tLifecycleDelegate
{
create
:
sync
})
}
}
func
(
n
*
d
eploymentClient2
)
OnChange
(
ctx
context
.
Context
,
name
string
,
sync
Deploymen
tChangeHandlerFunc
)
{
func
(
n
*
d
aemonSetClient2
)
OnChange
(
ctx
context
.
Context
,
name
string
,
sync
DaemonSe
tChangeHandlerFunc
)
{
n
.
loadController
()
n
.
loadController
()
n
.
iface
.
AddLifecycle
(
ctx
,
name
+
"-change"
,
&
d
eploymen
tLifecycleDelegate
{
update
:
sync
})
n
.
iface
.
AddLifecycle
(
ctx
,
name
+
"-change"
,
&
d
aemonSe
tLifecycleDelegate
{
update
:
sync
})
}
}
func
(
n
*
d
eploymentClient2
)
OnRemove
(
ctx
context
.
Context
,
name
string
,
sync
Deploymen
tChangeHandlerFunc
)
{
func
(
n
*
d
aemonSetClient2
)
OnRemove
(
ctx
context
.
Context
,
name
string
,
sync
DaemonSe
tChangeHandlerFunc
)
{
n
.
loadController
()
n
.
loadController
()
n
.
iface
.
AddLifecycle
(
ctx
,
name
,
&
d
eploymen
tLifecycleDelegate
{
remove
:
sync
})
n
.
iface
.
AddLifecycle
(
ctx
,
name
,
&
d
aemonSe
tLifecycleDelegate
{
remove
:
sync
})
}
}
func
(
n
*
d
eploymentClientCache
)
Index
(
name
string
,
indexer
Deploymen
tIndexer
)
{
func
(
n
*
d
aemonSetClientCache
)
Index
(
name
string
,
indexer
DaemonSe
tIndexer
)
{
err
:=
n
.
client
.
controller
.
Informer
()
.
GetIndexer
()
.
AddIndexers
(
map
[
string
]
cache
.
IndexFunc
{
err
:=
n
.
client
.
controller
.
Informer
()
.
GetIndexer
()
.
AddIndexers
(
map
[
string
]
cache
.
IndexFunc
{
name
:
func
(
obj
interface
{})
([]
string
,
error
)
{
name
:
func
(
obj
interface
{})
([]
string
,
error
)
{
if
v
,
ok
:=
obj
.
(
*
v1
.
D
eploymen
t
);
ok
{
if
v
,
ok
:=
obj
.
(
*
v1
.
D
aemonSe
t
);
ok
{
return
indexer
(
v
)
return
indexer
(
v
)
}
}
return
nil
,
nil
return
nil
,
nil
...
@@ -384,14 +384,14 @@ func (n *deploymentClientCache) Index(name string, indexer DeploymentIndexer) {
...
@@ -384,14 +384,14 @@ func (n *deploymentClientCache) Index(name string, indexer DeploymentIndexer) {
}
}
}
}
func
(
n
*
d
eploymentClientCache
)
GetIndexed
(
name
,
key
string
)
([]
*
v1
.
Deploymen
t
,
error
)
{
func
(
n
*
d
aemonSetClientCache
)
GetIndexed
(
name
,
key
string
)
([]
*
v1
.
DaemonSe
t
,
error
)
{
var
result
[]
*
v1
.
D
eploymen
t
var
result
[]
*
v1
.
D
aemonSe
t
objs
,
err
:=
n
.
client
.
controller
.
Informer
()
.
GetIndexer
()
.
ByIndex
(
name
,
key
)
objs
,
err
:=
n
.
client
.
controller
.
Informer
()
.
GetIndexer
()
.
ByIndex
(
name
,
key
)
if
err
!=
nil
{
if
err
!=
nil
{
return
nil
,
err
return
nil
,
err
}
}
for
_
,
obj
:=
range
objs
{
for
_
,
obj
:=
range
objs
{
if
v
,
ok
:=
obj
.
(
*
v1
.
D
eploymen
t
);
ok
{
if
v
,
ok
:=
obj
.
(
*
v1
.
D
aemonSe
t
);
ok
{
result
=
append
(
result
,
v
)
result
=
append
(
result
,
v
)
}
}
}
}
...
@@ -399,41 +399,41 @@ func (n *deploymentClientCache) GetIndexed(name, key string) ([]*v1.Deployment,
...
@@ -399,41 +399,41 @@ func (n *deploymentClientCache) GetIndexed(name, key string) ([]*v1.Deployment,
return
result
,
nil
return
result
,
nil
}
}
func
(
n
*
d
eploymen
tClient2
)
loadController
()
{
func
(
n
*
d
aemonSe
tClient2
)
loadController
()
{
if
n
.
controller
==
nil
{
if
n
.
controller
==
nil
{
n
.
controller
=
n
.
iface
.
Controller
()
n
.
controller
=
n
.
iface
.
Controller
()
}
}
}
}
type
d
eploymen
tLifecycleDelegate
struct
{
type
d
aemonSe
tLifecycleDelegate
struct
{
create
D
eploymen
tChangeHandlerFunc
create
D
aemonSe
tChangeHandlerFunc
update
D
eploymen
tChangeHandlerFunc
update
D
aemonSe
tChangeHandlerFunc
remove
D
eploymen
tChangeHandlerFunc
remove
D
aemonSe
tChangeHandlerFunc
}
}
func
(
n
*
d
eploymen
tLifecycleDelegate
)
HasCreate
()
bool
{
func
(
n
*
d
aemonSe
tLifecycleDelegate
)
HasCreate
()
bool
{
return
n
.
create
!=
nil
return
n
.
create
!=
nil
}
}
func
(
n
*
d
eploymentLifecycleDelegate
)
Create
(
obj
*
v1
.
Deploymen
t
)
(
runtime
.
Object
,
error
)
{
func
(
n
*
d
aemonSetLifecycleDelegate
)
Create
(
obj
*
v1
.
DaemonSe
t
)
(
runtime
.
Object
,
error
)
{
if
n
.
create
==
nil
{
if
n
.
create
==
nil
{
return
obj
,
nil
return
obj
,
nil
}
}
return
n
.
create
(
obj
)
return
n
.
create
(
obj
)
}
}
func
(
n
*
d
eploymen
tLifecycleDelegate
)
HasFinalize
()
bool
{
func
(
n
*
d
aemonSe
tLifecycleDelegate
)
HasFinalize
()
bool
{
return
n
.
remove
!=
nil
return
n
.
remove
!=
nil
}
}
func
(
n
*
d
eploymentLifecycleDelegate
)
Remove
(
obj
*
v1
.
Deploymen
t
)
(
runtime
.
Object
,
error
)
{
func
(
n
*
d
aemonSetLifecycleDelegate
)
Remove
(
obj
*
v1
.
DaemonSe
t
)
(
runtime
.
Object
,
error
)
{
if
n
.
remove
==
nil
{
if
n
.
remove
==
nil
{
return
obj
,
nil
return
obj
,
nil
}
}
return
n
.
remove
(
obj
)
return
n
.
remove
(
obj
)
}
}
func
(
n
*
d
eploymentLifecycleDelegate
)
Updated
(
obj
*
v1
.
Deploymen
t
)
(
runtime
.
Object
,
error
)
{
func
(
n
*
d
aemonSetLifecycleDelegate
)
Updated
(
obj
*
v1
.
DaemonSe
t
)
(
runtime
.
Object
,
error
)
{
if
n
.
update
==
nil
{
if
n
.
update
==
nil
{
return
obj
,
nil
return
obj
,
nil
}
}
...
...
types/apis/apps/v1/zz_generated_d
eploymen
t_lifecycle_adapter.go
→
types/apis/apps/v1/zz_generated_d
aemon_se
t_lifecycle_adapter.go
View file @
875ba289
...
@@ -6,54 +6,54 @@ import (
...
@@ -6,54 +6,54 @@ import (
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/runtime"
)
)
type
D
eploymen
tLifecycle
interface
{
type
D
aemonSe
tLifecycle
interface
{
Create
(
obj
*
v1
.
D
eploymen
t
)
(
runtime
.
Object
,
error
)
Create
(
obj
*
v1
.
D
aemonSe
t
)
(
runtime
.
Object
,
error
)
Remove
(
obj
*
v1
.
D
eploymen
t
)
(
runtime
.
Object
,
error
)
Remove
(
obj
*
v1
.
D
aemonSe
t
)
(
runtime
.
Object
,
error
)
Updated
(
obj
*
v1
.
D
eploymen
t
)
(
runtime
.
Object
,
error
)
Updated
(
obj
*
v1
.
D
aemonSe
t
)
(
runtime
.
Object
,
error
)
}
}
type
d
eploymen
tLifecycleAdapter
struct
{
type
d
aemonSe
tLifecycleAdapter
struct
{
lifecycle
D
eploymen
tLifecycle
lifecycle
D
aemonSe
tLifecycle
}
}
func
(
w
*
d
eploymen
tLifecycleAdapter
)
HasCreate
()
bool
{
func
(
w
*
d
aemonSe
tLifecycleAdapter
)
HasCreate
()
bool
{
o
,
ok
:=
w
.
lifecycle
.
(
lifecycle
.
ObjectLifecycleCondition
)
o
,
ok
:=
w
.
lifecycle
.
(
lifecycle
.
ObjectLifecycleCondition
)
return
!
ok
||
o
.
HasCreate
()
return
!
ok
||
o
.
HasCreate
()
}
}
func
(
w
*
d
eploymen
tLifecycleAdapter
)
HasFinalize
()
bool
{
func
(
w
*
d
aemonSe
tLifecycleAdapter
)
HasFinalize
()
bool
{
o
,
ok
:=
w
.
lifecycle
.
(
lifecycle
.
ObjectLifecycleCondition
)
o
,
ok
:=
w
.
lifecycle
.
(
lifecycle
.
ObjectLifecycleCondition
)
return
!
ok
||
o
.
HasFinalize
()
return
!
ok
||
o
.
HasFinalize
()
}
}
func
(
w
*
d
eploymen
tLifecycleAdapter
)
Create
(
obj
runtime
.
Object
)
(
runtime
.
Object
,
error
)
{
func
(
w
*
d
aemonSe
tLifecycleAdapter
)
Create
(
obj
runtime
.
Object
)
(
runtime
.
Object
,
error
)
{
o
,
err
:=
w
.
lifecycle
.
Create
(
obj
.
(
*
v1
.
D
eploymen
t
))
o
,
err
:=
w
.
lifecycle
.
Create
(
obj
.
(
*
v1
.
D
aemonSe
t
))
if
o
==
nil
{
if
o
==
nil
{
return
nil
,
err
return
nil
,
err
}
}
return
o
,
err
return
o
,
err
}
}
func
(
w
*
d
eploymen
tLifecycleAdapter
)
Finalize
(
obj
runtime
.
Object
)
(
runtime
.
Object
,
error
)
{
func
(
w
*
d
aemonSe
tLifecycleAdapter
)
Finalize
(
obj
runtime
.
Object
)
(
runtime
.
Object
,
error
)
{
o
,
err
:=
w
.
lifecycle
.
Remove
(
obj
.
(
*
v1
.
D
eploymen
t
))
o
,
err
:=
w
.
lifecycle
.
Remove
(
obj
.
(
*
v1
.
D
aemonSe
t
))
if
o
==
nil
{
if
o
==
nil
{
return
nil
,
err
return
nil
,
err
}
}
return
o
,
err
return
o
,
err
}
}
func
(
w
*
d
eploymen
tLifecycleAdapter
)
Updated
(
obj
runtime
.
Object
)
(
runtime
.
Object
,
error
)
{
func
(
w
*
d
aemonSe
tLifecycleAdapter
)
Updated
(
obj
runtime
.
Object
)
(
runtime
.
Object
,
error
)
{
o
,
err
:=
w
.
lifecycle
.
Updated
(
obj
.
(
*
v1
.
D
eploymen
t
))
o
,
err
:=
w
.
lifecycle
.
Updated
(
obj
.
(
*
v1
.
D
aemonSe
t
))
if
o
==
nil
{
if
o
==
nil
{
return
nil
,
err
return
nil
,
err
}
}
return
o
,
err
return
o
,
err
}
}
func
NewD
eploymentLifecycleAdapter
(
name
string
,
clusterScoped
bool
,
client
DeploymentInterface
,
l
DeploymentLifecycle
)
Deploymen
tHandlerFunc
{
func
NewD
aemonSetLifecycleAdapter
(
name
string
,
clusterScoped
bool
,
client
DaemonSetInterface
,
l
DaemonSetLifecycle
)
DaemonSe
tHandlerFunc
{
adapter
:=
&
d
eploymen
tLifecycleAdapter
{
lifecycle
:
l
}
adapter
:=
&
d
aemonSe
tLifecycleAdapter
{
lifecycle
:
l
}
syncFn
:=
lifecycle
.
NewObjectLifecycleAdapter
(
name
,
clusterScoped
,
adapter
,
client
.
ObjectClient
())
syncFn
:=
lifecycle
.
NewObjectLifecycleAdapter
(
name
,
clusterScoped
,
adapter
,
client
.
ObjectClient
())
return
func
(
key
string
,
obj
*
v1
.
D
eploymen
t
)
(
runtime
.
Object
,
error
)
{
return
func
(
key
string
,
obj
*
v1
.
D
aemonSe
t
)
(
runtime
.
Object
,
error
)
{
newObj
,
err
:=
syncFn
(
key
,
obj
)
newObj
,
err
:=
syncFn
(
key
,
obj
)
if
o
,
ok
:=
newObj
.
(
runtime
.
Object
);
ok
{
if
o
,
ok
:=
newObj
.
(
runtime
.
Object
);
ok
{
return
o
,
err
return
o
,
err
...
...
types/apis/apps/v1/zz_generated_deepcopy.go
View file @
875ba289
...
@@ -6,13 +6,13 @@ import (
...
@@ -6,13 +6,13 @@ import (
)
)
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func
(
in
*
D
eploymentList
)
DeepCopyInto
(
out
*
Deploymen
tList
)
{
func
(
in
*
D
aemonSetList
)
DeepCopyInto
(
out
*
DaemonSe
tList
)
{
*
out
=
*
in
*
out
=
*
in
out
.
TypeMeta
=
in
.
TypeMeta
out
.
TypeMeta
=
in
.
TypeMeta
out
.
ListMeta
=
in
.
ListMeta
out
.
ListMeta
=
in
.
ListMeta
if
in
.
Items
!=
nil
{
if
in
.
Items
!=
nil
{
in
,
out
:=
&
in
.
Items
,
&
out
.
Items
in
,
out
:=
&
in
.
Items
,
&
out
.
Items
*
out
=
make
([]
appsv1
.
D
eploymen
t
,
len
(
*
in
))
*
out
=
make
([]
appsv1
.
D
aemonSe
t
,
len
(
*
in
))
for
i
:=
range
*
in
{
for
i
:=
range
*
in
{
(
*
in
)[
i
]
.
DeepCopyInto
(
&
(
*
out
)[
i
])
(
*
in
)[
i
]
.
DeepCopyInto
(
&
(
*
out
)[
i
])
}
}
...
@@ -20,18 +20,18 @@ func (in *DeploymentList) DeepCopyInto(out *DeploymentList) {
...
@@ -20,18 +20,18 @@ func (in *DeploymentList) DeepCopyInto(out *DeploymentList) {
return
return
}
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new D
eploymen
tList.
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new D
aemonSe
tList.
func
(
in
*
D
eploymentList
)
DeepCopy
()
*
Deploymen
tList
{
func
(
in
*
D
aemonSetList
)
DeepCopy
()
*
DaemonSe
tList
{
if
in
==
nil
{
if
in
==
nil
{
return
nil
return
nil
}
}
out
:=
new
(
D
eploymen
tList
)
out
:=
new
(
D
aemonSe
tList
)
in
.
DeepCopyInto
(
out
)
in
.
DeepCopyInto
(
out
)
return
out
return
out
}
}
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
func
(
in
*
D
eploymen
tList
)
DeepCopyObject
()
runtime
.
Object
{
func
(
in
*
D
aemonSe
tList
)
DeepCopyObject
()
runtime
.
Object
{
if
c
:=
in
.
DeepCopy
();
c
!=
nil
{
if
c
:=
in
.
DeepCopy
();
c
!=
nil
{
return
c
return
c
}
}
...
...
types/apis/apps/v1/zz_generated_k8s_client.go
View file @
875ba289
...
@@ -20,13 +20,13 @@ type Interface interface {
...
@@ -20,13 +20,13 @@ type Interface interface {
RESTClient
()
rest
.
Interface
RESTClient
()
rest
.
Interface
controller
.
Starter
controller
.
Starter
D
eploymen
tsGetter
D
aemonSe
tsGetter
}
}
type
Clients
struct
{
type
Clients
struct
{
Interface
Interface
Interface
Interface
D
eployment
Deploymen
tClient
D
aemonSet
DaemonSe
tClient
}
}
type
Client
struct
{
type
Client
struct
{
...
@@ -34,7 +34,7 @@ type Client struct {
...
@@ -34,7 +34,7 @@ type Client struct {
restClient
rest
.
Interface
restClient
rest
.
Interface
starters
[]
controller
.
Starter
starters
[]
controller
.
Starter
d
eploymentControllers
map
[
string
]
Deploymen
tController
d
aemonSetControllers
map
[
string
]
DaemonSe
tController
}
}
func
Factory
(
ctx
context
.
Context
,
config
rest
.
Config
)
(
context
.
Context
,
controller
.
Starter
,
error
)
{
func
Factory
(
ctx
context
.
Context
,
config
rest
.
Config
)
(
context
.
Context
,
controller
.
Starter
,
error
)
{
...
@@ -70,8 +70,8 @@ func NewClientsFromInterface(iface Interface) *Clients {
...
@@ -70,8 +70,8 @@ func NewClientsFromInterface(iface Interface) *Clients {
return
&
Clients
{
return
&
Clients
{
Interface
:
iface
,
Interface
:
iface
,
D
eployment
:
&
deploymen
tClient2
{
D
aemonSet
:
&
daemonSe
tClient2
{
iface
:
iface
.
D
eploymen
ts
(
""
),
iface
:
iface
.
D
aemonSe
ts
(
""
),
},
},
}
}
}
}
...
@@ -89,7 +89,7 @@ func NewForConfig(config rest.Config) (Interface, error) {
...
@@ -89,7 +89,7 @@ func NewForConfig(config rest.Config) (Interface, error) {
return
&
Client
{
return
&
Client
{
restClient
:
restClient
,
restClient
:
restClient
,
d
eploymentControllers
:
map
[
string
]
Deploymen
tController
{},
d
aemonSetControllers
:
map
[
string
]
DaemonSe
tController
{},
},
nil
},
nil
}
}
...
@@ -105,13 +105,13 @@ func (c *Client) Start(ctx context.Context, threadiness int) error {
...
@@ -105,13 +105,13 @@ func (c *Client) Start(ctx context.Context, threadiness int) error {
return
controller
.
Start
(
ctx
,
threadiness
,
c
.
starters
...
)
return
controller
.
Start
(
ctx
,
threadiness
,
c
.
starters
...
)
}
}
type
D
eploymen
tsGetter
interface
{
type
D
aemonSe
tsGetter
interface
{
D
eployments
(
namespace
string
)
Deploymen
tInterface
D
aemonSets
(
namespace
string
)
DaemonSe
tInterface
}
}
func
(
c
*
Client
)
D
eployments
(
namespace
string
)
Deploymen
tInterface
{
func
(
c
*
Client
)
D
aemonSets
(
namespace
string
)
DaemonSe
tInterface
{
objectClient
:=
objectclient
.
NewObjectClient
(
namespace
,
c
.
restClient
,
&
D
eploymentResource
,
DeploymentGroupVersionKind
,
deploymen
tFactory
{})
objectClient
:=
objectclient
.
NewObjectClient
(
namespace
,
c
.
restClient
,
&
D
aemonSetResource
,
DaemonSetGroupVersionKind
,
daemonSe
tFactory
{})
return
&
d
eploymen
tClient
{
return
&
d
aemonSe
tClient
{
ns
:
namespace
,
ns
:
namespace
,
client
:
c
,
client
:
c
,
objectClient
:
objectClient
,
objectClient
:
objectClient
,
...
...
types/apis/apps/v1/zz_generated_scheme.go
View file @
875ba289
...
@@ -33,7 +33,7 @@ func addKnownTypes(scheme *runtime.Scheme) error {
...
@@ -33,7 +33,7 @@ func addKnownTypes(scheme *runtime.Scheme) error {
// TODO this gets cleaned up when the types are fixed
// TODO this gets cleaned up when the types are fixed
scheme
.
AddKnownTypes
(
SchemeGroupVersion
,
scheme
.
AddKnownTypes
(
SchemeGroupVersion
,
&
D
eploymen
tList
{},
&
D
aemonSe
tList
{},
)
)
return
nil
return
nil
}
}
types/codegen/main.go
View file @
875ba289
...
@@ -99,7 +99,7 @@ func main() {
...
@@ -99,7 +99,7 @@ func main() {
}
}
if
err
:=
generator
.
ControllersForForeignTypes
(
basePackage
,
appsv1
.
SchemeGroupVersion
,
[]
interface
{}{
if
err
:=
generator
.
ControllersForForeignTypes
(
basePackage
,
appsv1
.
SchemeGroupVersion
,
[]
interface
{}{
appsv1
.
D
eploymen
t
{},
appsv1
.
D
aemonSe
t
{},
},
nil
);
err
!=
nil
{
},
nil
);
err
!=
nil
{
logrus
.
Fatal
(
err
)
logrus
.
Fatal
(
err
)
}
}
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment