From d0448c11c07893b83985f94f5667649377e7b55c Mon Sep 17 00:00:00 2001 From: gauron99 Date: Mon, 5 Oct 2026 13:55:52 +0200 Subject: [PATCH] docs: replace em dashes with hyphens --- CONTRIBUTING.md | 12 +++--- docs/architecture.md | 34 +++++++-------- docs/development/gitea-integration.md | 42 +++++++++---------- ...ket-notifications-adapter-configuration.md | 6 +-- .../2026-04-23-reconcile-state-design.md | 2 +- ...-refactor-handleMiddlewareUpdate-design.md | 10 ++--- .../2026-04-29-ssh-url-support-design.md | 20 ++++----- docs/release.md | 4 +- test/utils/func.go | 2 +- 9 files changed, 66 insertions(+), 66 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 97947716..4125e878 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -23,9 +23,9 @@ To backport a merged PR to a release branch, comment `/cherry-pick release-X.Y` ## Further Reading -- [Architecture Overview](docs/architecture.md) — system components, reconciliation flow, CRD lifecycle -- [Release Process](docs/release.md) — branching model, versioning, automated tag management -- [Gitea Integration](docs/development/gitea-integration.md) — e2e test infrastructure details +- [Architecture Overview](docs/architecture.md) - system components, reconciliation flow, CRD lifecycle +- [Release Process](docs/release.md) - branching model, versioning, automated tag management +- [Gitea Integration](docs/development/gitea-integration.md) - e2e test infrastructure details ## Development @@ -96,9 +96,9 @@ make update-codegen ``` This runs three sub-targets: -- `generate` — DeepCopy and DeepCopyInto methods -- `manifests` — CRDs, ClusterRoles, and webhook configurations -- `gen-mocks` — Mock implementations via [mockery](https://github.com/vektra/mockery) +- `generate` - DeepCopy and DeepCopyInto methods +- `manifests` - CRDs, ClusterRoles, and webhook configurations +- `gen-mocks` - Mock implementations via [mockery](https://github.com/vektra/mockery) ## Go Modules diff --git a/docs/architecture.md b/docs/architecture.md index 29f6e217..1ddc6f1a 100644 --- a/docs/architecture.md +++ b/docs/architecture.md @@ -8,40 +8,40 @@ The operator does **not** handle initial deployment. Functions must first be dep ## Components -- **FunctionReconciler** (`internal/controller/`) — The central controller. Watches `Function` custom resources and reconciles them. Also watches the `func-operator-controller-config` ConfigMap to re-reconcile functions when the operator-wide `autoUpdateMiddleware` default changes. Runs up to 10 concurrent reconciliations. +- **FunctionReconciler** (`internal/controller/`) - The central controller. Watches `Function` custom resources and reconciles them. Also watches the `func-operator-controller-config` ConfigMap to re-reconcile functions when the operator-wide `autoUpdateMiddleware` default changes. Runs up to 10 concurrent reconciliations. -- **FuncCliManager** (`internal/funccli/`) — Wraps the Knative `func` CLI binary. Periodically checks GitHub for new releases and downloads them (with SHA256 checksum verification and atomic install). Runs `func deploy`, `func describe`, and `func version` as subprocesses. The download logic (`DownloadAndInstall`) is shared with e2e test utilities via `internal/funccli/download.go`. +- **FuncCliManager** (`internal/funccli/`) - Wraps the Knative `func` CLI binary. Periodically checks GitHub for new releases and downloads them (with SHA256 checksum verification and atomic install). Runs `func deploy`, `func describe`, and `func version` as subprocesses. The download logic (`DownloadAndInstall`) is shared with e2e test utilities via `internal/funccli/download.go`. -- **GitManager** (`internal/git/`) — Clones function source repositories with authentication support: HTTP/HTTPS (token or basic auth) and SSH (private key with optional passphrase and known_hosts). Uses go-git for pure-Go shallow cloning (single-branch, depth 1). +- **GitManager** (`internal/git/`) - Clones function source repositories with authentication support: HTTP/HTTPS (token or basic auth) and SSH (private key with optional passphrase and known_hosts). Uses go-git for pure-Go shallow cloning (single-branch, depth 1). -- **StatusTracker** (`internal/controller/status_tracker.go`) — Buffers status changes during reconciliation and persists them in a single API call at the end via `Flush()`. Supports mid-reconcile flushes for long-running operations (e.g., before a deployment starts) so users see progress. +- **StatusTracker** (`internal/controller/status_tracker.go`) - Buffers status changes during reconciliation and persists them in a single API call at the end via `Flush()`. Supports mid-reconcile flushes for long-running operations (e.g., before a deployment starts) so users see progress. ## CRD: Function Defined in `api/v1alpha1/function_types.go`. A `Function` resource represents a deployed serverless function that the operator should monitor. **Spec** (user-provided): -- `repository.url` — Git repository containing the function source -- `repository.revision` — Branch name or full ref to build (optional, defaults to the repo's default branch) -- `repository.dir` — Directory within the repo that holds the function (for monorepos) -- `repository.authSecretRef` — Secret for private repo authentication -- `registry.authSecretRef` — Secret for container registry authentication -- `autoUpdateMiddleware` — Override operator default (optional) +- `repository.url` - Git repository containing the function source +- `repository.revision` - Branch name or full ref to build (optional, defaults to the repo's default branch) +- `repository.dir` - Directory within the repo that holds the function (for monorepos) +- `repository.authSecretRef` - Secret for private repo authentication +- `registry.authSecretRef` - Secret for container registry authentication +- `autoUpdateMiddleware` - Override operator default (optional) **Status** (operator-managed): -- `git` — Resolved revision, observed commit, last check time -- `deployment` — Current image, build time, deployer, runtime -- `middleware` — Current/available versions, auto-update config, rebuild state -- `service` — URL and readiness of the underlying Knative Service -- `conditions` — Standard Kubernetes conditions (see below) -- `history` — Last 20 reconciliation events +- `git` - Resolved revision, observed commit, last check time +- `deployment` - Current image, build time, deployer, runtime +- `middleware` - Current/available versions, auto-update config, rebuild state +- `service` - URL and readiness of the underlying Knative Service +- `conditions` - Standard Kubernetes conditions (see below) +- `history` - Last 20 reconciliation events ## Reconciliation Flow ```mermaid flowchart TD start["Reconcile()"] --> get["Get Function CR"] - get -->|Not found| ignore["Exit — already deleted"] + get -->|Not found| ignore["Exit - already deleted"] get -->|Found| tracker["Create StatusTracker"] tracker --> prepare diff --git a/docs/development/gitea-integration.md b/docs/development/gitea-integration.md index 2c47dc70..1a675775 100644 --- a/docs/development/gitea-integration.md +++ b/docs/development/gitea-integration.md @@ -44,37 +44,37 @@ BeforeEach(func() { ### Available Helper Methods **RepositoryProvider Interface:** -- `CreateUser(username, password, email string) (cleanup func(), err error)` — Create user with cleanup function -- `DeleteUser(username string) error` — Delete a user and all their data -- `CreateRandomUser() (username, password, email string, cleanup func(), err error)` — Create user with random credentials -- `CreateRepo(owner, name string, private bool) (url string, cleanup func(), err error)` — Create repository -- `DeleteRepo(owner, name string) error` — Delete a repository -- `CreateRandomRepo(owner string, private bool) (name, url string, cleanup func(), err error)` — Create repo with random name -- `CreateAccessToken(username, password, tokenName string) (string, error)` — Generate access token -- `CreateSSHKey(username, password, title, publicKey string) error` — Register SSH public key for user -- `SSHRepoURL(owner, repo string) (string, error)` — Get SSH URL for a repository +- `CreateUser(username, password, email string) (cleanup func(), err error)` - Create user with cleanup function +- `DeleteUser(username string) error` - Delete a user and all their data +- `CreateRandomUser() (username, password, email string, cleanup func(), err error)` - Create user with random credentials +- `CreateRepo(owner, name string, private bool) (url string, cleanup func(), err error)` - Create repository +- `DeleteRepo(owner, name string) error` - Delete a repository +- `CreateRandomRepo(owner string, private bool) (name, url string, cleanup func(), err error)` - Create repo with random name +- `CreateAccessToken(username, password, tokenName string) (string, error)` - Generate access token +- `CreateSSHKey(username, password, title, publicKey string) error` - Register SSH public key for user +- `SSHRepoURL(owner, repo string) (string, error)` - Get SSH URL for a repository Note: `CreateUser`, `CreateRepo`, and `CreateRandomRepo` return cleanup functions that call `DeleteUser`/`DeleteRepo` internally. Prefer `DeferCleanup(cleanup)` over calling the delete methods directly. **Git Helper Functions:** -- `InitializeRepoWithFunction(url, user, pass, lang string, opts ...RepoOption) (repoDir string, err error)` — Clone, init function, push -- `CommitAndPush(repoDir, msg, file string, otherFiles ...string) error` — Commit and push files +- `InitializeRepoWithFunction(url, user, pass, lang string, opts ...RepoOption) (repoDir string, err error)` - Clone, init function, push +- `CommitAndPush(repoDir, msg, file string, otherFiles ...string) error` - Commit and push files `InitializeRepoWithFunction` accepts functional options: -- `WithSubDir(subDir string)` — Place the function in a subdirectory (for monorepo testing) -- `WithCliVersion(version string)` — Use a specific func CLI version to initialize the function +- `WithSubDir(subDir string)` - Place the function in a subdirectory (for monorepo testing) +- `WithCliVersion(version string)` - Use a specific func CLI version to initialize the function **func CLI Helper Functions:** -- `RunFunc(command string, args ...string) (string, error)` — Run the current/latest func CLI -- `RunFuncWithVersion(version, command string, args ...string) (string, error)` — Run a specific func CLI version (downloads and caches automatically) -- `RunFuncDeploy(functionDir string, opts ...FuncDeployOption) (string, error)` — Deploy a function with retry logic +- `RunFunc(command string, args ...string) (string, error)` - Run the current/latest func CLI +- `RunFuncWithVersion(version, command string, args ...string) (string, error)` - Run a specific func CLI version (downloads and caches automatically) +- `RunFuncDeploy(functionDir string, opts ...FuncDeployOption) (string, error)` - Deploy a function with retry logic `RunFuncDeploy` accepts functional options: -- `WithNamespace(namespace string)` — Target namespace -- `WithBuilder(builder string)` — Builder to use (e.g. `pack`, `s2i`) -- `WithDeployer(deployer string)` — Deployer to use (e.g. `knative`, `keda`) -- `WithDeployCliVersion(version string)` — Use a specific func CLI version -- `WithEnvVars(envVars map[string]string)` — Set environment variables for the deploy command +- `WithNamespace(namespace string)` - Target namespace +- `WithBuilder(builder string)` - Builder to use (e.g. `pack`, `s2i`) +- `WithDeployer(deployer string)` - Deployer to use (e.g. `knative`, `keda`) +- `WithDeployCliVersion(version string)` - Use a specific func CLI version +- `WithEnvVars(envVars map[string]string)` - Set environment variables for the deploy command Defaults for `RunFuncDeploy` are read from environment variables: `REGISTRY` (or `REGISTRY_URL`), `REGISTRY_INSECURE`, `DEFAULT_BUILDER`, `DEFAULT_DEPLOYER`. diff --git a/docs/objectbucket-notifications-adapter-configuration.md b/docs/objectbucket-notifications-adapter-configuration.md index 1bfac3db..b15948a6 100644 --- a/docs/objectbucket-notifications-adapter-configuration.md +++ b/docs/objectbucket-notifications-adapter-configuration.md @@ -38,7 +38,7 @@ These settings can be changed at runtime by modifying the ConfigMap. The adapter | `RADOSGW_ADAPTER_ID` | `rgw-adapter` | Identifier used in the S3 bucket notification configuration for RadosGW-managed OBCs | | `RADOSGW_ADAPTER_TOPIC_ARN` | `arn:aws:sns:ocs-storagecluster-cephobjectstore::rgw-adapter-notifications` | RadosGW SNS TopicArn used in put-bucket-notification calls | | `RADOSGW_ADAPTER_STORAGECLASS_PATTERN` | `.*ceph-rgw$` | Regex matched against OBC `spec.storageClassName` to classify as RadosGW-managed | -| `NOTIFICATIONS_MODE` | value of `--notifications-mode` (`http`) | `http` or `kafka` — selects how the adapter receives NooBaa/RadosGW notifications. Switching modes restarts the notification runner. | +| `NOTIFICATIONS_MODE` | value of `--notifications-mode` (`http`) | `http` or `kafka` - selects how the adapter receives NooBaa/RadosGW notifications. Switching modes restarts the notification runner. | | `KAFKA_BROKERS` | value of `--kafka-brokers` | Comma-separated list of Kafka broker addresses (required for Kafka mode). Changing it gracefully restarts the Kafka consumer. | | `KAFKA_NOTIFICATIONS_TOPICS` | value of `--kafka-notifications-topics` | Comma-separated list of Kafka topics to consume notifications from (required for Kafka mode). Changing it gracefully restarts the Kafka consumer. | | `KAFKA_NOTIFICATIONS_GROUP_ID` | value of `--kafka-notifications-group-id` | Consumer group ID for consuming notifications (required for Kafka mode). Changing it gracefully restarts the Kafka consumer. | @@ -138,7 +138,7 @@ When any of them change, the adapter: This means you can, for example, switch the adapter from `http` to `kafka` mode, point the consumer at different brokers, subscribe to different topics, change the consumer group ID, -or rotate the Kafka credentials — all without restarting the pod. +or rotate the Kafka credentials - all without restarting the pod. The runner is restarted only when a change actually affects it: changes to unrelated ConfigMap keys (e.g. adapter IDs) do not restart it, and a Kafka credential change only @@ -166,7 +166,7 @@ To rotate Kafka credentials without restarting the adapter pod: 1. Update the Kafka Secret with new credentials in place, **or** update the ConfigMap to reference a new secret via `KAFKA_SECRET`. 2. The adapter watches both the ConfigMap and the referenced Kafka Secret, so it detects the - change automatically, rebuilds the Kafka configuration, and — if Kafka is in use — + change automatically, rebuilds the Kafka configuration, and - if Kafka is in use - gracefully restarts its Kafka producer/consumer so the new credentials take effect immediately. diff --git a/docs/plans/2026-04-23-reconcile-state-design.md b/docs/plans/2026-04-23-reconcile-state-design.md index 7a8bcc02..64a00458 100644 --- a/docs/plans/2026-04-23-reconcile-state-design.md +++ b/docs/plans/2026-04-23-reconcile-state-design.md @@ -208,4 +208,4 @@ Helpers populate the state struct and return plain errors. They never call `Mark - **Pro**: All condition logic in one place, easy to read the full status story - **Pro**: Helpers are pure data gatherers, easy to test - **Pro**: Mid-reconcile flushes use the same mechanism -- **Con**: State struct and `syncStatus` must be kept in sync with helpers — two places to update when adding new status fields \ No newline at end of file +- **Con**: State struct and `syncStatus` must be kept in sync with helpers - two places to update when adding new status fields \ No newline at end of file diff --git a/docs/plans/2026-04-24-refactor-handleMiddlewareUpdate-design.md b/docs/plans/2026-04-24-refactor-handleMiddlewareUpdate-design.md index 48c408d0..3823758c 100644 --- a/docs/plans/2026-04-24-refactor-handleMiddlewareUpdate-design.md +++ b/docs/plans/2026-04-24-refactor-handleMiddlewareUpdate-design.md @@ -8,7 +8,7 @@ 2. **Decision logic** - should we redeploy or not? 3. **Status bookkeeping** - ~15 status field assignments scattered throughout -This makes the method hard to follow. There's also a redundant `Describe` call — the second one (line 321) re-fetches data that only changes after a redeploy. +This makes the method hard to follow. There's also a redundant `Describe` call - the second one (line 321) re-fetches data that only changes after a redeploy. ## Design @@ -69,10 +69,10 @@ The second `Describe` call only happens inside the deploy branch (where it's act ### Cleanup -`isMiddlewareLatest` is no longer needed — the version comparison happens inside `checkMiddlewareState` using data from the single `Describe` call. +`isMiddlewareLatest` is no longer needed - the version comparison happens inside `checkMiddlewareState` using data from the single `Describe` call. ## Decisions -- **Keep status field duplication across switch cases** — each case is self-contained and readable top-to-bottom -- **`autoUpdate` lives as a field on `middlewareOutdated`** rather than being a third type — the two outdated cases share the same data -- **All types are unexported** — this is controller-internal \ No newline at end of file +- **Keep status field duplication across switch cases** - each case is self-contained and readable top-to-bottom +- **`autoUpdate` lives as a field on `middlewareOutdated`** rather than being a third type - the two outdated cases share the same data +- **All types are unexported** - this is controller-internal \ No newline at end of file diff --git a/docs/plans/2026-04-29-ssh-url-support-design.md b/docs/plans/2026-04-29-ssh-url-support-design.md index e7fa30ac..e036813b 100644 --- a/docs/plans/2026-04-29-ssh-url-support-design.md +++ b/docs/plans/2026-04-29-ssh-url-support-design.md @@ -31,9 +31,9 @@ Add support for SSH repository URLs in the Function CR, allowing users to specif - For `http`/`https` scheme: existing token/username-password logic unchanged. **Auth secret fields (SSH):** -- `sshPrivateKey` (required for private repos) — PEM-encoded private key -- `sshPrivateKeyPassword` (optional) — passphrase for encrypted keys -- `known_hosts` (optional) — known_hosts file content for host key verification +- `sshPrivateKey` (required for private repos) - PEM-encoded private key +- `sshPrivateKeyPassword` (optional) - passphrase for encrypted keys +- `known_hosts` (optional) - known_hosts file content for host key verification ### 2. Unit Tests (`internal/git/manager_test.go`) @@ -48,20 +48,20 @@ New test file covering `getClientOptions`: ### 3. E2E Test Utilities **`test/utils/gitea.go`:** -- `GetSSHEndpoint()` — reads `ssh` key from `gitea-endpoint` ConfigMap -- `CreateSSHKey(username, password, title, publicKey string)` — registers SSH public key via Gitea SDK `CreatePublicKey()` -- `SSHRepoURL(owner, repo string)` — builds SCP-style URL from SSH endpoint +- `GetSSHEndpoint()` - reads `ssh` key from `gitea-endpoint` ConfigMap +- `CreateSSHKey(username, password, title, publicKey string)` - registers SSH public key via Gitea SDK `CreatePublicKey()` +- `SSHRepoURL(owner, repo string)` - builds SCP-style URL from SSH endpoint **`test/utils/git.go`:** -- `WithSSHKey(privateKeyPath string)` option — configures `InitializeRepoWithFunction` to clone/push via SSH using `GIT_SSH_COMMAND` with the provided private key +- `WithSSHKey(privateKeyPath string)` option - configures `InitializeRepoWithFunction` to clone/push via SSH using `GIT_SSH_COMMAND` with the provided private key ### 4. E2E Tests (`test/e2e/func_deploy_test.go`) Three new test cases under a new `Context("with an SSH repository URL", ...)`: -1. **Public repo with SSH URL** — Create public repo, push via HTTP, create Function CR with SSH URL, verify function becomes ready. -2. **Private repo with SSH key auth** — Generate SSH keypair, register public key in Gitea, create Secret with `sshPrivateKey`, create Function CR with SSH URL + authSecretRef, verify function becomes ready. -3. **Private repo without auth secret** — Create private repo, create Function CR with SSH URL but no authSecretRef, verify function fails with auth error. +1. **Public repo with SSH URL** - Create public repo, push via HTTP, create Function CR with SSH URL, verify function becomes ready. +2. **Private repo with SSH key auth** - Generate SSH keypair, register public key in Gitea, create Secret with `sshPrivateKey`, create Function CR with SSH URL + authSecretRef, verify function becomes ready. +3. **Private repo without auth secret** - Create private repo, create Function CR with SSH URL but no authSecretRef, verify function fails with auth error. ### 5. README Updates diff --git a/docs/release.md b/docs/release.md index 8164cd41..890cb0f2 100644 --- a/docs/release.md +++ b/docs/release.md @@ -6,8 +6,8 @@ The project uses [semantic versioning](https://semver.org/) with a `v` prefix: ` ## Branch Model -- **`main`** — Active development. All PRs target `main`. -- **`release-{MAJOR}.{MINOR}`** — Maintenance branches for each minor version (e.g. `release-0.3`). Created when a minor version is ready to ship. +- **`main`** - Active development. All PRs target `main`. +- **`release-{MAJOR}.{MINOR}`** - Maintenance branches for each minor version (e.g. `release-0.3`). Created when a minor version is ready to ship. ## Creating a New Minor Release diff --git a/test/utils/func.go b/test/utils/func.go index 9d988a21..b18dd8a7 100644 --- a/test/utils/func.go +++ b/test/utils/func.go @@ -211,7 +211,7 @@ func ensureFuncVersion(version string) (string, error) { } defer syscall.Flock(int(lockFile.Fd()), syscall.LOCK_UN) //nolint:errcheck - // Re-check after acquiring the lock — another process may have finished the download + // Re-check after acquiring the lock - another process may have finished the download if _, err := os.Stat(funcBinary); err == nil { return funcBinary, nil }