Skip to content

Commit 4e97b7a

Browse files
tmshortbentito
authored andcommitted
Helm POC rebase-a-thon
1 parent a458282 commit 4e97b7a

25 files changed

+1503
-789
lines changed

.github/workflows/tilt.yaml

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -22,10 +22,6 @@ jobs:
2222
- uses: actions/checkout@v4
2323
with:
2424
path: operator-controller
25-
- uses: actions/checkout@v4
26-
with:
27-
repository: operator-framework/rukpak
28-
path: rukpak
2925
- uses: actions/checkout@v4
3026
with:
3127
repository: operator-framework/catalogd

CONTRIBUTING.md

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,8 @@ The user experience captured in the OLM V1 PRD introduces many requirements that
1919
- [The Operator-Controller project](https://github.com/operator-framework/operator-controller/), which is the top level component allowing users to specify operators they'd like to install.
2020
- [The Catalogd project](https://github.com/operator-framework/catalogd/), which hosts operator content and helps users discover installable content.
2121
- [The Deppy project](https://github.com/operator-framework/deppy/), which enables the operator-controller to identify valid installs and upgrades from the list of installable content provided via the Catalogd project.
22-
- [The RukPak project](https://github.com/operator-framework/rukpak/), which facilitates the installation of operators.
2322

24-
Each of the projects listed above have their own governance, release milestones, and release cadence. However, from a technical perspective, the "OLM V1 experience" matches the experienced offered by the operator-controller project, the top level component which introduces dependencies on RukPak, Deppy, and the Catalogd projects.
23+
Each of the projects listed above have their own governance, release milestones, and release cadence. However, from a technical perspective, the "OLM V1 experience" matches the experienced offered by the operator-controller project, the top level component which introduces dependencies on Deppy and the Catalogd projects.
2524

2625
## How do we collaborate
2726

@@ -62,7 +61,7 @@ Ongoing or previous Operator-Controller milestones can always be found in the [m
6261

6362
### How are Subproject Issues Tracked?
6463

65-
As discussed earlier, the operator-controller adheres to a microservice architecture, where multiple projects contribute to the overall experience. As such, when designing an operator-controller milestone, the community may need to file an issue against RukPak, Deppy, or Catalogd. Unfortunately, the operator-controller milestone cannot contain issues from one of its subprojects. As such, we've introduced the concept of a "Dependency Issue", described below:
64+
As discussed earlier, the operator-controller adheres to a microservice architecture, where multiple projects contribute to the overall experience. As such, when designing an operator-controller milestone, the community may need to file an issue against Deppy or Catalogd. Unfortunately, the operator-controller milestone cannot contain issues from one of its subprojects. As such, we've introduced the concept of a "Dependency Issue", described below:
6665

6766
> Dependency Issues: An issue tracked in a milestone that "points" to an issue in another project with a URL.
6867
@@ -72,7 +71,6 @@ Unsure where to submit an issue?
7271
- [The Operator-Controller project](https://github.com/operator-framework/operator-controller/), which is the top level component allowing users to specify operators they'd like to install.
7372
- [The Catalogd project](https://github.com/operator-framework/catalogd/), which hosts operator content and helps users discover installable content.
7473
- [The Deppy project](https://github.com/operator-framework/deppy/), which enables the operator-controller to identify valid installs and upgrades from the list of installable content provided via the Catalogd project.
75-
- [The RukPak project](https://github.com/operator-framework/rukpak/), which facilitates the installation of operators.
7674

7775
Don't worry if you accidentally submit an issue against the wrong project, if we notice that an issue would fit better with a separate project we'll move it to the correct repository and mention it in the #olm-dev slack channel.
7876

Makefile

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,6 @@ IMG := $(IMAGE_REPO):$(IMAGE_TAG)
2222
# Define dependency versions (use go.mod if we also use Go code from dependency)
2323
export CERT_MGR_VERSION := v1.9.0
2424
export CATALOGD_VERSION := $(shell go list -mod=mod -m -f "{{.Version}}" github.com/operator-framework/catalogd)
25-
export RUKPAK_VERSION := $(shell go list -mod=mod -m -f "{{.Version}}" github.com/operator-framework/rukpak)
2625
export WAIT_TIMEOUT := 60s
2726

2827
# By default setup-envtest will write to $XDG_DATA_HOME, or $HOME/.local/share if that is not defined.
@@ -162,10 +161,16 @@ e2e-coverage:
162161
kind-load: $(KIND) #EXHELP Loads the currently constructed image onto the cluster.
163162
$(CONTAINER_RUNTIME) save $(IMG) | $(KIND) load image-archive /dev/stdin --name $(KIND_CLUSTER_NAME)
164163

165-
kind-deploy: export MANIFEST := ./operator-controller.yaml
164+
.PHONY: kind-deploy
165+
kind-deploy: export MANIFEST="./operator-controller.yaml"
166166
kind-deploy: manifests $(KUSTOMIZE) #EXHELP Install controller and dependencies onto the kind cluster.
167167
$(KUSTOMIZE) build $(KUSTOMIZE_BUILD_DIR) > operator-controller.yaml
168-
envsubst '$$CATALOGD_VERSION,$$CERT_MGR_VERSION,$$RUKPAK_VERSION,$$MANIFEST' < scripts/install.tpl.sh | bash -s
168+
envsubst '$$CATALOGD_VERSION,$$CERT_MGR_VERSION,$$MANIFEST' < scripts/install.tpl.sh | bash -s
169+
170+
.PHONY: kind-redeploy
171+
kind-redeploy: generate docker-build kind-load kind-deploy #EXHELP Redeploy newly built executables
172+
kubectl delete pod -l control-plane=controller-manager -n $(OPERATOR_CONTROLLER_NAMESPACE)
173+
envsubst '$$CATALOGD_VERSION,$$CERT_MGR_VERSION,$$MANIFEST' < scripts/install.tpl.sh | bash -s
169174

170175
.PHONY: kind-cluster
171176
kind-cluster: $(KIND) #EXHELP Standup a kind cluster.
@@ -255,7 +260,7 @@ release: $(GORELEASER) #EXHELP Runs goreleaser for the operator-controller. By d
255260
quickstart: export MANIFEST := https://github.com/operator-framework/operator-controller/releases/download/$(VERSION)/operator-controller.yaml
256261
quickstart: $(KUSTOMIZE) manifests #EXHELP Generate the installation release manifests and scripts.
257262
$(KUSTOMIZE) build $(KUSTOMIZE_BUILD_DIR) | sed "s/:devel/:$(VERSION)/g" > operator-controller.yaml
258-
envsubst '$$CATALOGD_VERSION,$$CERT_MGR_VERSION,$$RUKPAK_VERSION,$$MANIFEST' < scripts/install.tpl.sh > install.sh
263+
envsubst '$$CATALOGD_VERSION,$$CERT_MGR_VERSION,$$MANIFEST' < scripts/install.tpl.sh > install.sh
259264

260265
##@ Docs
261266

README.md

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@ OLM v1 is the follow-up to OLM v0, located [here](https://github.com/operator-fr
1717
OLM v1 consists of four different components:
1818
* operator-controller (this repository)
1919
* [deppy](https://github.com/operator-framework/deppy)
20-
* [rukpak](https://github.com/operator-framework/rukpak)
2120
* [catalogd](https://github.com/operator-framework/catalogd)
2221

2322
For a more complete overview of OLM v1 and how it differs from OLM v0, see our [overview](./docs/olmv1_overview.md).
@@ -76,7 +75,7 @@ Install the CRDs and the operator-controller into a new [KIND cluster](https://k
7675
make run
7776
```
7877
This will build a local container image of the operator-controller, create a new KIND cluster and then deploy onto that cluster.
79-
This will also deploy the catalogd, rukpak and cert-manager dependencies.
78+
This will also deploy the catalogd and cert-manager dependencies.
8079

8180
### Modifying the API definitions
8281
If you are editing the API definitions, generate the manifests such as CRs or CRDs using:

Tiltfile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ load('../tilt-support/Tiltfile', 'deploy_repo')
55

66
config.define_string_list('repos', args=True)
77
cfg = config.parse()
8-
repos = cfg.get('repos', ['operator-controller', 'rukpak', 'catalogd'])
8+
repos = cfg.get('repos', ['operator-controller', 'catalogd'])
99

1010
repo = {
1111
'image': 'quay.io/operator-framework/operator-controller',

api/v1alpha1/clusterextension_types.go

Lines changed: 22 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,11 @@ import (
2222
"github.com/operator-framework/operator-controller/internal/conditionsets"
2323
)
2424

25+
var (
26+
ClusterExtensionGVK = SchemeBuilder.GroupVersion.WithKind("ClusterExtension")
27+
ClusterExtensionKind = ClusterExtensionGVK.Kind
28+
)
29+
2530
type UpgradeConstraintPolicy string
2631

2732
const (
@@ -77,15 +82,20 @@ type ClusterExtensionSpec struct {
7782

7883
const (
7984
// TODO(user): add more Types, here and into init()
80-
TypeInstalled = "Installed"
81-
TypeResolved = "Resolved"
85+
TypeInstalled = "Installed"
86+
TypeResolved = "Resolved"
87+
TypeHasValidBundle = "HasValidBundle"
88+
TypeHealthy = "Healthy"
89+
8290
// TypeDeprecated is a rollup condition that is present when
8391
// any of the deprecated conditions are present.
8492
TypeDeprecated = "Deprecated"
8593
TypePackageDeprecated = "PackageDeprecated"
8694
TypeChannelDeprecated = "ChannelDeprecated"
8795
TypeBundleDeprecated = "BundleDeprecated"
8896

97+
ReasonErrorGettingClient = "ErrorGettingClient"
98+
ReasonBundleLoadFailed = "BundleLoadFailed"
8999
ReasonBundleLookupFailed = "BundleLookupFailed"
90100
ReasonInstallationFailed = "InstallationFailed"
91101
ReasonInstallationStatusUnknown = "InstallationStatusUnknown"
@@ -95,13 +105,18 @@ const (
95105
ReasonResolutionUnknown = "ResolutionUnknown"
96106
ReasonSuccess = "Success"
97107
ReasonDeprecated = "Deprecated"
108+
ReasonErrorGettingReleaseState = "ErrorGettingReleaseState"
109+
ReasonUpgradeFailed = "UpgradeFailed"
110+
ReasonCreateDynamicWatchFailed = "CreateDynamicWatchFailed"
98111
)
99112

100113
func init() {
101114
// TODO(user): add Types from above
102115
conditionsets.ConditionTypes = append(conditionsets.ConditionTypes,
103116
TypeInstalled,
104117
TypeResolved,
118+
TypeHasValidBundle,
119+
TypeHealthy,
105120
TypeDeprecated,
106121
TypePackageDeprecated,
107122
TypeChannelDeprecated,
@@ -118,6 +133,11 @@ func init() {
118133
ReasonInvalidSpec,
119134
ReasonSuccess,
120135
ReasonDeprecated,
136+
ReasonErrorGettingReleaseState,
137+
ReasonUpgradeFailed,
138+
ReasonCreateDynamicWatchFailed,
139+
ReasonBundleLoadFailed,
140+
ReasonErrorGettingClient,
121141
)
122142
}
123143

@@ -132,7 +152,6 @@ type ClusterExtensionStatus struct {
132152
InstalledBundle *BundleMetadata `json:"installedBundle,omitempty"`
133153
// +optional
134154
ResolvedBundle *BundleMetadata `json:"resolvedBundle,omitempty"`
135-
136155
// +patchMergeKey=type
137156
// +patchStrategy=merge
138157
// +listType=map

cmd/manager/main.go

Lines changed: 87 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -17,23 +17,37 @@ limitations under the License.
1717
package main
1818

1919
import (
20+
"crypto/x509"
2021
"flag"
2122
"fmt"
2223
"net/http"
24+
"net/url"
2325
"os"
2426
"time"
2527

2628
"github.com/spf13/pflag"
2729
"go.uber.org/zap/zapcore"
30+
k8slabels "k8s.io/apimachinery/pkg/labels"
31+
"k8s.io/apimachinery/pkg/selection"
2832
_ "k8s.io/client-go/plugin/pkg/client/auth"
2933
ctrl "sigs.k8s.io/controller-runtime"
34+
crcache "sigs.k8s.io/controller-runtime/pkg/cache"
35+
"sigs.k8s.io/controller-runtime/pkg/client"
3036
"sigs.k8s.io/controller-runtime/pkg/healthz"
3137
"sigs.k8s.io/controller-runtime/pkg/log/zap"
3238
"sigs.k8s.io/controller-runtime/pkg/metrics/server"
3339

40+
helmclient "github.com/operator-framework/helm-operator-plugins/pkg/client"
41+
"github.com/operator-framework/rukpak/pkg/source"
42+
"github.com/operator-framework/rukpak/pkg/storage"
43+
"github.com/operator-framework/rukpak/pkg/util"
44+
45+
"github.com/operator-framework/operator-controller/api/v1alpha1"
3446
"github.com/operator-framework/operator-controller/internal/catalogmetadata/cache"
3547
catalogclient "github.com/operator-framework/operator-controller/internal/catalogmetadata/client"
3648
"github.com/operator-framework/operator-controller/internal/controllers"
49+
"github.com/operator-framework/operator-controller/internal/handler"
50+
"github.com/operator-framework/operator-controller/internal/labels"
3751
"github.com/operator-framework/operator-controller/internal/version"
3852
"github.com/operator-framework/operator-controller/pkg/features"
3953
"github.com/operator-framework/operator-controller/pkg/scheme"
@@ -45,19 +59,27 @@ var (
4559

4660
func main() {
4761
var (
48-
metricsAddr string
49-
enableLeaderElection bool
50-
probeAddr string
51-
cachePath string
52-
operatorControllerVersion bool
62+
metricsAddr string
63+
enableLeaderElection bool
64+
probeAddr string
65+
cachePath string
66+
operatorControllerVersion bool
67+
httpExternalAddr string
68+
systemNamespace string
69+
unpackImage string
70+
provisionerStorageDirectory string
5371
)
5472
flag.StringVar(&metricsAddr, "metrics-bind-address", ":8080", "The address the metric endpoint binds to.")
5573
flag.StringVar(&probeAddr, "health-probe-bind-address", ":8081", "The address the probe endpoint binds to.")
74+
flag.StringVar(&httpExternalAddr, "http-external-address", "http://localhost:8080", "The external address at which the http server is reachable.")
5675
flag.BoolVar(&enableLeaderElection, "leader-elect", false,
5776
"Enable leader election for controller manager. "+
5877
"Enabling this will ensure there is only one active controller manager.")
5978
flag.StringVar(&cachePath, "cache-path", "/var/cache", "The local directory path used for filesystem based caching")
6079
flag.BoolVar(&operatorControllerVersion, "version", false, "Prints operator-controller version information")
80+
flag.StringVar(&systemNamespace, "system-namespace", "", "Configures the namespace that gets used to deploy system resources.")
81+
flag.StringVar(&unpackImage, "unpack-image", util.DefaultUnpackImage, "Configures the container image that gets used to unpack Bundle contents.")
82+
flag.StringVar(&provisionerStorageDirectory, "provisioner-storage-dir", storage.DefaultBundleCacheDir, "The directory that is used to store bundle contents.")
6183
opts := zap.Options{
6284
Development: true,
6385
}
@@ -75,12 +97,33 @@ func main() {
7597
ctrl.SetLogger(zap.New(zap.UseFlagOptions(&opts), zap.StacktraceLevel(zapcore.DPanicLevel)))
7698
setupLog.Info("starting up the controller", "version info", version.String())
7799

100+
if systemNamespace == "" {
101+
systemNamespace = util.PodNamespace()
102+
}
103+
104+
dependentRequirement, err := k8slabels.NewRequirement(labels.OwnerKindKey, selection.In, []string{v1alpha1.ClusterExtensionKind})
105+
if err != nil {
106+
setupLog.Error(err, "unable to create dependent label selector for cache")
107+
os.Exit(1)
108+
}
109+
dependentSelector := k8slabels.NewSelector().Add(*dependentRequirement)
110+
111+
fmt.Println("set up manager")
78112
mgr, err := ctrl.NewManager(ctrl.GetConfigOrDie(), ctrl.Options{
79113
Scheme: scheme.Scheme,
80114
Metrics: server.Options{BindAddress: metricsAddr},
81115
HealthProbeBindAddress: probeAddr,
82116
LeaderElection: enableLeaderElection,
83117
LeaderElectionID: "9c4404e7.operatorframework.io",
118+
Cache: crcache.Options{
119+
ByObject: map[client.Object]crcache.ByObject{
120+
&v1alpha1.ClusterExtension{}: {},
121+
},
122+
DefaultNamespaces: map[string]crcache.Config{
123+
systemNamespace: {},
124+
crcache.AllNamespaces: {LabelSelector: dependentSelector},
125+
},
126+
},
84127
// LeaderElectionReleaseOnCancel defines if the leader should step down voluntarily
85128
// when the Manager ends. This requires the binary to immediately end when the
86129
// Manager is stopped, otherwise, this setting is unsafe. Setting this significantly
@@ -101,9 +144,46 @@ func main() {
101144
cl := mgr.GetClient()
102145
catalogClient := catalogclient.New(cl, cache.NewFilesystemCache(cachePath, &http.Client{Timeout: 10 * time.Second}))
103146

147+
cfgGetter, err := helmclient.NewActionConfigGetter(mgr.GetConfig(), mgr.GetRESTMapper(), helmclient.StorageNamespaceMapper(func(o client.Object) (string, error) {
148+
return systemNamespace, nil
149+
}))
150+
if err != nil {
151+
setupLog.Error(err, "unable to config for creating helm client")
152+
os.Exit(1)
153+
}
154+
155+
acg, err := helmclient.NewActionClientGetter(cfgGetter)
156+
if err != nil {
157+
setupLog.Error(err, "unable to create helm client")
158+
os.Exit(1)
159+
}
160+
161+
unpacker, err := source.NewDefaultUnpacker(mgr, systemNamespace, unpackImage, (*x509.CertPool)(nil))
162+
if err != nil {
163+
setupLog.Error(err, "unable to create unpacker")
164+
os.Exit(1)
165+
}
166+
167+
storageURL, err := url.Parse(fmt.Sprintf("%s/bundles/", httpExternalAddr))
168+
if err != nil {
169+
setupLog.Error(err, "unable to parse bundle content server URL")
170+
os.Exit(1)
171+
}
172+
173+
localStorage := &storage.LocalDirectory{
174+
RootDirectory: provisionerStorageDirectory,
175+
URL: *storageURL,
176+
}
177+
104178
if err = (&controllers.ClusterExtensionReconciler{
105-
Client: cl,
106-
BundleProvider: catalogClient,
179+
Client: cl,
180+
ReleaseNamespace: systemNamespace,
181+
BundleProvider: catalogClient,
182+
Scheme: mgr.GetScheme(),
183+
ActionClientGetter: acg,
184+
Unpacker: unpacker,
185+
Storage: localStorage,
186+
Handler: handler.HandlerFunc(handler.HandleClusterExtension),
107187
}).SetupWithManager(mgr); err != nil {
108188
setupLog.Error(err, "unable to create controller", "controller", "ClusterExtension")
109189
os.Exit(1)

config/manager/manager.yaml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,8 @@ spec:
6161
volumeMounts:
6262
- name: cache
6363
mountPath: /var/cache
64+
- name: bundle-cache
65+
mountPath: /var/cache/bundles
6466
securityContext:
6567
allowPrivilegeEscalation: false
6668
capabilities:
@@ -111,3 +113,5 @@ spec:
111113
volumes:
112114
- name: cache
113115
emptyDir: {}
116+
- name: bundle-cache
117+
emptyDir: {}

config/rbac/role.yaml

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,12 @@ kind: ClusterRole
44
metadata:
55
name: manager-role
66
rules:
7+
- apiGroups:
8+
- '*'
9+
resources:
10+
- '*'
11+
verbs:
12+
- '*'
713
- apiGroups:
814
- catalogd.operatorframework.io
915
resources:
@@ -19,15 +25,20 @@ rules:
1925
- list
2026
- watch
2127
- apiGroups:
22-
- core.rukpak.io
28+
- ""
2329
resources:
24-
- bundledeployments
30+
- configmaps
31+
verbs:
32+
- list
33+
- watch
34+
- apiGroups:
35+
- ""
36+
resources:
37+
- pods
2538
verbs:
2639
- create
27-
- get
40+
- delete
2841
- list
29-
- patch
30-
- update
3142
- watch
3243
- apiGroups:
3344
- olm.operatorframework.io

docs/components.md

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,6 @@ OLM v1 is composed of various component projects:
22

33
* [operator-controller](https://github.com/operator-framework/operator-controller): operator-controller is the central component of OLM v1, that consumes all of the components below to extend Kubernetes to allows users to install, and manage the lifecycle of other extensions
44

5-
* [rukpak](https://github.com/operator-framework/rukpak): RukPak is a pluggable solution for the packaging and distribution of cloud-native content and supports advanced strategies for installation, updates, and policy. The project provides a content ecosystem for installing a variety of artifacts, such as Git repositories, Helm charts, OLM bundles, and more onto a Kubernetes cluster. These artifacts can then be managed, scaled, and upgraded in a safe way to enable powerful cluster extensions.
6-
At its core, RukPak is a small set of APIs, packaged as Kubernetes CustomResourceDefinitions, and controllers that watch for those APIs. These APIs express what content is being installed on-cluster and how to create a running deployment of the content.
7-
8-
95
* [deppy](https://github.com/operator-framework/deppy): Deppy is a Kubernetes API that runs on- or off-cluster for resolving constraints over catalogs of RukPak bundles. Deppy is part of the next iteration of OLM and was first introduced here. The initial goal of the project is to remove the dependency manager from the Operator Lifecycle Manager (OLM) and make it its own generic component.
106

11-
127
* [catalogD](https://github.com/operator-framework/catalogd): Catalogd is a Kubernetes extension that unpacks [file-based catalog (FBC)](https://olm.operatorframework.io/docs/reference/file-based-catalogs/#docs) content that is packaged and shipped in container images, for consumption by clients on-clusters (unpacking from other sources, like git repos, OCI artifacts etc, are in the roadmap for catalogD). As component of the Operator Lifecycle Manager (OLM) v1 microservices architecture, catalogD hosts metadata for Kubernetes extensions packaged by the authors of the extensions, as a result helping customers discover installable content.

0 commit comments

Comments
 (0)