You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: README.md
+143Lines changed: 143 additions & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -270,6 +270,47 @@ The library provides a wrapper around `logr.Logger`, exposing additional helper
270
270
- There are several `FromContext...` functions for retrieving a logger from a `context.Context` object.
271
271
-`InitFlags(...)` can be used to add the configuration flags for this logger to a cobra `FlagSet`.
272
272
273
+
### threads
274
+
275
+
The `threads` package provides a simple thread managing library. It can be used to run go routines in a non-blocking manner and provides the possibility to react if the routine has exited.
276
+
277
+
The most relevant use-case for this library in the context of k8s controllers is to handle dynamic watches on multiple clusters. To start a watch, that cluster's cache's `Start` method has to be used. Because this method is blocking, it has to be executed in a different go routine, and because it can return an error, a simple `go cache.Start(...)` is not enough, because it would hide the error.
278
+
279
+
#### Noteworthy Functions
280
+
281
+
-`NewThreadManager` creates a new thread manager.
282
+
- The first argument is a `context.Context` used by the manager itself. Cancelling this context will stop the manager, and if the context contains a `logging.Logger`, the manager will use it for logging.
283
+
- The second argument is an optional function that is executed after any go routine executed with this manager has finished. It is also possible to provide such a function for a specific go routine, instead for all of them, see below.
284
+
- Use the `Run` method to start a new go routine.
285
+
- Starting a go routine cancels the context of any running go routine with the same id.
286
+
- This method also takes an optional function to be executed after the actual workload is done.
287
+
- A on-finish function specified here is executed before the on-finish function of the manager is executed.
288
+
- Note that go routines will wait for the thread manager to be started, if that has not yet happened. If the manager has been started, they will be executed immediately.
289
+
- The thread manager will cancel the context that is passed into the workload function when the manager is being stopped. If any long-running commands are being run as part of the workload, it is strongly recommended to listen to the context's `Done` channel.
290
+
- Use `Start()` to start the thread manager.
291
+
- If any go routines have been added before this is called, they will be started now. New go routines added afterwards will be started immediately.
292
+
- Calling this multiple times doesn't have any effect, unless the manager has already been stopped, in which case `Start()` will panic.
293
+
- There are three ways to stop the thread manager again:
294
+
- Use its `Stop()` method.
295
+
- This is a blocking method that waits for all remaining go routines to finish. Their context is cancelled to notify them of the manager being stopped.
296
+
- Cancel the context that was passed into `NewThreadManager` as the first argument.
297
+
- Send a `SIGTERM` or `SIGINT` signal to the process.
298
+
- The `TaskManager`'s `Restart`, `RestartOnError`, and `RestartOnSuccess` methods are pre-defined on-finish functions. They are not meant to be used directly, but instead be used as an argument to `Run`. See the example below.
299
+
300
+
#### Examples
301
+
302
+
```golang
303
+
mgr:= threads.NewThreadManager(ctx, nil)
304
+
mgr.Start()
305
+
// do other stuff
306
+
// start a go routine that is restarted automatically if it finishes with an error
The `pkg/readiness` package provides a simple way to check if a kubernetes resource is ready.
345
+
The meaning of readiness depends on the resource type.
346
+
347
+
#### Example
348
+
349
+
```go
350
+
deployment:= &appsv1.Deployment{}
351
+
err:= r.Client.Get(ctx, types.NamespacedName{
352
+
Name: "my-deployment",
353
+
Namespace: "my-namespace",
354
+
}, deployment)
355
+
356
+
if err != nil {
357
+
return err
358
+
}
359
+
360
+
readiness:= readiness.CheckDeployment(deployment)
361
+
362
+
if readiness.IsReady() {
363
+
fmt.Println("Deployment is ready")
364
+
} else {
365
+
fmt.Printf("Deployment is not ready: %s\n", readiness.Message())
366
+
}
367
+
```
368
+
369
+
### Kubernetes resource management
370
+
371
+
The `pkg/resource` package contains some useful functions for working with Kubernetes resources. The `Mutator` interface can be used to modify resources in a generic way. It is used by the `Mutate` function, which takes a resource and a mutator and applies the mutator to the resource.
372
+
The package also contains convenience types for the most common resource types, e.g. `ConfigMap`, `Secret`, `ClusterRole`, `ClusterRoleBinding`, etc. These types implement the `Mutator` interface and can be used to modify the corresponding resources.
373
+
374
+
#### Examples
375
+
376
+
Create or update a `ConfigMap`, a `ServiceAccount` and a `Deployment` using the `Mutator` interface:
This project is open to feature requests/suggestions, bug reports etc. via [GitHub issues](https://github.com/openmcp-project/controller-utils/issues). Contribution and feedback are encouraged and always welcome. For more information about how to contribute, the project structure, as well as additional contribution information, see our [Contribution Guidelines](CONTRIBUTING.md).
flags.StringVar(&c.cfgPath, fmt.Sprintf("%s-cluster", c.id), "", fmt.Sprintf("Path to the %s cluster kubeconfig file or directory containing either a kubeconfig or host, token, and ca file. Leave empty to use in-cluster config.", c.id))
57
60
}
58
61
62
+
// WithClientOptions allows to overwrite the default client options.
63
+
// It must be called before InitializeClient().
64
+
// Note that using this method disables the the scheme injection during client initialization.
65
+
// This means that the required scheme should already be set in the options that are passed into this method.
0 commit comments