Skip to content

Commit 1b7e90c

Browse files
authored
Unified selector (#15)
* workflow Signed-off-by: YangKeao <keao.yang@yahoo.com> * unified selector Signed-off-by: Yang Keao <keao.yang@yahoo.com> * wrap Signed-off-by: Yang Keao <keao.yang@yahoo.com> * fix markdown lint Signed-off-by: Yang Keao <keao.yang@yahoo.com>
1 parent d69562f commit 1b7e90c

File tree

1 file changed

+90
-0
lines changed

1 file changed

+90
-0
lines changed
Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
# Unified Selector
2+
3+
## Summary
4+
5+
The whole controller framework should do more things for the implementation of
6+
chaos. Now, every implementation of chaos selects pods by themselves. However,
7+
in order to track the running status, the controller framework should know the
8+
concrete status of every selected targets, which would be a disaster to record
9+
these status inside the implementation of every chaos :(. An unified selector
10+
framework in the controller framework could solve this problem. This RFC will
11+
talk about the design of this unified selector.
12+
13+
## Motivation
14+
15+
There have been a lot of problems about current selector. For example, the
16+
IOChaos should select volumes, but it selects container now (and at first, it
17+
selects pods). Some chaos use `containerName string` to select a container while
18+
some use `containerNames []string` to select several containers at one time. If
19+
we can abstract selectors into one place, these errors won't happen. The
20+
developer of every chaos will not need to consider "select" or these platform
21+
dependent things.
22+
23+
Another benifit is that it could help the controller to track the status. With
24+
it, the controller would know which target (pod/container) has been injected and
25+
which has not. It's the first step towards the target of a standalone `Schedule`
26+
CRD.
27+
28+
## Detailed Design
29+
30+
Every chaos specification would define a function to get the specification of
31+
selectors:
32+
33+
```go
34+
type StatefulObjectWithSelector interface {
35+
v1alpha1.StatefulObject
36+
37+
GetSelectorSpecs() map[string]interface{}
38+
}
39+
```
40+
41+
The method `GetSelectorSpecs` will return a map from `string` to selector
42+
specification (like `struct {v1alpha1.PodSelectorSpec, v1alpha1.PodMode,
43+
v1alpha1.Value}`). The key would be the identifier of the selector, as there
44+
will be multiple selectors in one chaos specification, for example the `.` and
45+
`.Target` selectors in `NetworkChaos`. The controller will iterate this map to
46+
select every `SelectSpec`. It will construct a unified selector first, and then
47+
use this selector to `Select` targets. The unified selector may contain a lot of
48+
implementation inside. The construction would be like:
49+
50+
```go
51+
selector := selector.New(selector.SelectorParams{
52+
PodSelector: pod.New(r.Client, r.Reader, config.ControllerCfg.ClusterScoped, config.ControllerCfg.TargetNamespace, config.ControllerCfg.AllowedNamespaces, config.ControllerCfg.IgnoredNamespaces),
53+
ContainerSelector: container.New(r.Client, r.Reader, config.ControllerCfg.ClusterScoped, config.ControllerCfg.TargetNamespace, config.ControllerCfg.AllowedNamespaces, config.ControllerCfg.IgnoredNamespaces),
54+
})
55+
```
56+
57+
With the help of dependency injection, it would be constructed easier. The
58+
`Selector` method of `PodSelector` would be like:
59+
60+
```go
61+
func (impl *PodSelector) Select(ctx context.Context, ps *v1alpha1.PodSelector) ([]interface{}, error)
62+
```
63+
64+
The type of second parameter will decide which selector to use. For example, if
65+
you want to select with `*v1alpha1.PodSelector`, then the unified selector will
66+
use `*PodSelector`, and if you want to select with
67+
`*v1alpha1.ContainerSelector`, then the unified selector will use
68+
`*ContainerSelector` to select.
69+
70+
The definition of the unified selector would be:
71+
72+
```go
73+
func (s *Selector) Select(ctx context.Context, spec interface{}) ([]interface{}, error)
74+
```
75+
76+
The controller would construct the `Selector` first, and then use the `Selector`
77+
to select the chaos targets. However, as the target may have multiple type (it
78+
could be a pod, a container, a volume or an AWS machine), we can only return an
79+
`interface{}`, and the implementation of chaos would assert the type by
80+
themselves.
81+
82+
After selecting every `selectSpecs`, the controller will iterate over selected
83+
items, and call `Apply`/`Recover` for them. All selected items, current item and
84+
the identifier of the `selectorSpec` of current item will be passed into the
85+
`Apply`/`Recover` function.
86+
87+
## Alternatives
88+
89+
This is a RFC about internal design, and there is little choice. If you have
90+
better idea, please comment.

0 commit comments

Comments
 (0)