Skip to content

Commit 475c5f1

Browse files
efiacorliamfallonmozesl-nokia
authored
Feature 1.6 (kptdev#492)
* Fix boilerplate YEAR on generated code (kptdev#391) (kptdev#456) * api * More generated files added * Fix dates on boilerplate * Fix date generation from boiler plate * Fix copyright dates * Fixed copyright date * Use environment variable for generation year on boilerplate * Updates after rebase * Cleanup after rebase * Cleanup after rebase * Removed blank line that broke generation of PackageRevisionResources deepcopy --------- Signed-off-by: liamfallon <liam.fallon@est.tech> Co-authored-by: Liam Fallon <35595825+liamfallon@users.noreply.github.com> * Porch Repository controller (kptdev#406) * Fix boilerplate YEAR on generated code (kptdev#391) * api Signed-off-by: liamfallon <liam.fallon@est.tech> * More generated files added Signed-off-by: liamfallon <liam.fallon@est.tech> * Fix dates on boilerplate Signed-off-by: liamfallon <liam.fallon@est.tech> * Fix date generation from boiler plate Signed-off-by: liamfallon <liam.fallon@est.tech> * Fix copyright dates Signed-off-by: liamfallon <liam.fallon@est.tech> * Fixed copyright date Signed-off-by: liamfallon <liam.fallon@est.tech> * Use environment variable for generation year on boilerplate Signed-off-by: liamfallon <liam.fallon@est.tech> * Updates after rebase Signed-off-by: liamfallon <liam.fallon@est.tech> * Cleanup after rebase Signed-off-by: liamfallon <liam.fallon@est.tech> * Cleanup after rebase Signed-off-by: liamfallon <liam.fallon@est.tech> * Removed blank line that broke generation of PackageRevisionResources deepcopy Signed-off-by: liamfallon <liam.fallon@est.tech> --------- Signed-off-by: liamfallon <liam.fallon@est.tech> * Move Repository API from api/porchconfig to controllers/repositories - Move Repository CRD and API types to controllers/repositories/api/v1alpha1 - Update all import paths across the codebase - Remove old api/porchconfig directory - Update CRD generation location * Add dedicated repository controller - Add standalone repository controller with event-driven reconciliation - Support both generation-based and event-based triggers - Implement proper finalizer handling and status management - Add comprehensive test coverage and utilities - Support embedded and standalone deployment modes * Refactor sync utilities and add repository status management * Add embedded controller support for porch-server - Enable running repository controller embedded in porch-server - Add configuration options for database cache integration - Support both standalone and embedded controller modes * Update cache layer for repository controller integration - Enhance cache interfaces for better repository lifecycle management - Update both CR cache and DB cache implementations - Add sync event support and improved error handling - Update test utilities and comprehensive test coverage * Update remaining components and dependencies - Update engine and registry components for new repository API - Enhance task handlers and repository management - Update external repository implementations and Git cache cleanup - Update test utilities, mock implementations, and deployment configs - Update dependencies * Fix sync manager lifecycle and add global deletion watcher - Add GlobalDeletionWatcher to monitor repository deletions - Implement periodic cleanup for orphaned sync managers - Add comprehensive event recording and cleanup mechanisms - Fix race conditions in sync manager lifecycle - Improve test coverage and add test helpers - Resolve e2e test failures with proper sync manager cleanup * Update repository controller for enhanced sync integration - Update copyright year to 2026 - Improve repository controller documentation - Prepare controller for sync manager integration * Improve package registry and e2e test stability - Add package common utilities - Update e2e repository tests for better reliability * Enhance repository controller with sync integration and testing - Add database cache creation for standalone controller mode - Integrate sync manager functionality with controller lifecycle - Expand controller test coverage with sync scenarios - Update cache layer for improved controller coordination - Enhance event handling and sync manager capabilities - Improve E2E test stability and package registry handling This prepares the foundation for migrating sync functionality from cache layer to controller-managed scheduling. * chore: add testbin/ to .gitignore Test binaries generated by envtest should not be committed. * refactor: remove event-based repository sync mechanism Remove the event-driven sync system that used channels and goroutines for repository synchronization. This simplifies the codebase and eliminates race conditions and complexity. * refactor: implement direct sync in repository controller Replace event-driven sync with direct synchronous calls: - Add sync.go with SyncRepository method for on-demand syncing - Refactor controller to call sync directly during reconciliation - Simplify status updates to use standard conditions - Remove event channel dependencies from cache and status logic - Update tests to use direct sync calls instead of event mocking * feat: update controller configuration defaults - Set MaxConcurrentReconciles to 100 (was 25) for both embedded and standalone modes - Set MaxConcurrentSyncs to 50 for both modes - Update flag defaults to match documented performance analysis - Align embedded and standalone configurations for consistency * refactor: simplify cache sync layer - Remove event channel dependencies from sync.go - Update sync tests to use direct method calls - Simplify repository cache interfaces - Remove event-based status update mechanisms - Clean up cache directory pool logging * refactor: update apiserver for direct sync model - Remove event manager initialization from embedded controller - Update controller setup to use new sync configuration - Simplify embedded controller tests - Update dependencies * test: add integration tests for repository controller - Add Makefile for running controller tests - Add integration test suite using envtest - Test repository reconciliation and sync behavior * test: refactor CLI e2e tests to use shared repository - Migrate all CLI tests to use shared 'porch-test' repository - Add RecreateGiteaRepo utility for resetting repo state between tests - Update test configs to use usesPorchTestRepo flag - Add ignoreWhitespace flag for kubectl custom-columns output - Add sleep after repo unregister to allow async deletion * test: improve CLI test suite infrastructure - Add IsRepoControllerRunningInCluster() to detect controller deployment - Use LoadBalancer IP when controller runs locally (can't resolve cluster DNS) - Add signal handler for Ctrl-C cleanup in test suite - Add --wait=false to namespace deletion for faster cleanup - Simplify test suite by removing redundant code * test: update API e2e tests for new sync model - Remove event-based sync expectations - Update repository status checks for new condition format - Adjust test timing for direct sync behavior * Clean up comments and documentation - Remove references to old code (background.go, SyncManager) from controller comments - Add comments explaining sync decision priority in determineSyncDecision - Document that most of repostatusconds.go will be removed when legacy sync is removed - Clarify resource bump in adjust_porch_server_resources is for CR cache with controller-based sync - Reduce events RBAC permissions to read-only (get, list, watch) - Move indirect dependencies to main require block in go.mod - Reorganize sync.go functions into logical groups for better readability * Add missed go.mod update Signed-off-by: Fiachra Corcoran <fiachra.corcoran@est.tech> * Implement smart defaults for use-legacy-sync based on cache type - CR cache: defaults to use-legacy-sync=false (embedded controller) - DB cache: defaults to use-legacy-sync=true (no standalone controller required) - Users can explicitly override defaults with --use-legacy-sync flag - Add warnings to guide users on deployment requirements - Group server flags into logical sections for better readability Benefits: - CR cache users get best experience (embedded controller, no extra deployment) - DB cache users aren't forced to deploy standalone controller - Clear migration path from legacy to controller-based sync - Backward compatible for existing deployments * Address failing CI Signed-off-by: Fiachra Corcoran <fiachra.corcoran@est.tech> * Address failing tests Signed-off-by: Fiachra Corcoran <fiachra.corcoran@est.tech> * Fix faling tests etc Signed-off-by: Fiachra Corcoran <fiachra.corcoran@est.tech> * Fix remaining test failures Signed-off-by: Fiachra Corcoran <fiachra.corcoran@est.tech> * Adjust timings on sync tests Signed-off-by: Fiachra Corcoran <fiachra.corcoran@est.tech> * Increase test coverage Signed-off-by: Fiachra Corcoran <fiachra.corcoran@est.tech> * Add test coverage Signed-off-by: Fiachra Corcoran <fiachra.corcoran@est.tech> * Add Repository status fields and fix sync reliability Add Repository status fields (LastFullSyncTime, ObservedGeneration, PackageCount, GitCommitHash) for better observability. Implement BranchCommitHash() interface method across all repository types. Fix 1-second requeue loop by using HealthCheckFrequency as floor when sync intervals are overdue. Improve error recovery and panic handling in async sync operations. * Skip repo integration suite in unti test runs Signed-off-by: Fiachra Corcoran <fiachra.corcoran@est.tech> * Fix failing unit tests Signed-off-by: Fiachra Corcoran <fiachra.corcoran@est.tech> * Add unit coverage and enhance int suite Signed-off-by: Fiachra Corcoran <fiachra.corcoran@est.tech> * More code coverage Signed-off-by: Fiachra Corcoran <fiachra.corcoran@est.tech> * Repo Controller logging enhancements Signed-off-by: Fiachra Corcoran <fiachra.corcoran@est.tech> * Remove legacy sync support Completes migration to controller-based repository synchronization. Removes background.go, SyncManager, and related configuration flags. Signed-off-by: Fiachra Corcoran <fiachra.corcoran@est.tech> * Fix dbcache tests Signed-off-by: Fiachra Corcoran <fiachra.corcoran@est.tech> * Address CI failures Signed-off-by: Fiachra Corcoran <fiachra.corcoran@est.tech> * Revert sonar CI fix attempt Signed-off-by: Fiachra Corcoran <fiachra.corcoran@est.tech> * Add storage limits to controllers Deployment Signed-off-by: Fiachra Corcoran <fiachra.corcoran@est.tech> * Fix rebase error Signed-off-by: Fiachra Corcoran <fiachra.corcoran@est.tech> * Add descriptive name to logs from e2e Signed-off-by: Fiachra Corcoran <fiachra.corcoran@est.tech> * Refactor porchctl upgrade cli e2e Signed-off-by: Fiachra Corcoran <fiachra.corcoran@est.tech> * Missed change on rebase Signed-off-by: Fiachra Corcoran <fiachra.corcoran@est.tech> * Move buildRepositoryCondition to repo controller Signed-off-by: Fiachra Corcoran <fiachra.corcoran@est.tech> * Address review comments Signed-off-by: Fiachra Corcoran <fiachra.corcoran@est.tech> * Move Repo validation to CEL in CRD Signed-off-by: Fiachra Corcoran <fiachra.corcoran@est.tech> * Remove duplicate CEL rules Signed-off-by: Fiachra Corcoran <fiachra.corcoran@est.tech> * Regenerate Repo CRD Signed-off-by: Fiachra Corcoran <fiachra.corcoran@est.tech> * Fix repo validation test Signed-off-by: Fiachra Corcoran <fiachra.corcoran@est.tech> * Add wait group for cache cleanup race Signed-off-by: Fiachra Corcoran <fiachra.corcoran@est.tech> * Fix failing db tests Signed-off-by: Fiachra Corcoran <fiachra.corcoran@est.tech> * Fix dbcache repo race and retry Signed-off-by: Fiachra Corcoran <fiachra.corcoran@est.tech> * Add db connection config Signed-off-by: Fiachra Corcoran <fiachra.corcoran@est.tech> * Address review comments Signed-off-by: Fiachra Corcoran <fiachra.corcoran@est.tech> * Rename confusing fns Signed-off-by: Fiachra Corcoran <fiachra.corcoran@est.tech> * Fix missed updates and linting Signed-off-by: Fiachra Corcoran <fiachra.corcoran@est.tech> * Use default client from Embedded Controller Signed-off-by: Fiachra Corcoran <fiachra.corcoran@est.tech> * Fix missed cleanup Signed-off-by: Fiachra Corcoran <fiachra.corcoran@est.tech> * Add ObservedRunOnceAt status to address redundant syncs Signed-off-by: Fiachra Corcoran <fiachra.corcoran@est.tech> * Updates after rebase Signed-off-by: Fiachra Corcoran <fiachra.corcoran@est.tech> * refactor: move sync scheduling to dedicated status field - Add NextFullSyncTime field to Repository status for tracking next sync - Add Branch and Age printer columns to Repository CRD for better visibility - Simplify condition messages by removing inline sync/retry timestamps - Remove timestamp parsing logic from condition messages * Fix failing CI Signed-off-by: Fiachra Corcoran <fiachra.corcoran@est.tech> * Fix cli e2e fails Signed-off-by: Fiachra Corcoran <fiachra.corcoran@est.tech> * Fix failing cli e2e test Signed-off-by: Fiachra Corcoran <fiachra.corcoran@est.tech> * Delete PR_ENTRY.md * Adress review comments Signed-off-by: Fiachra Corcoran <fiachra.corcoran@est.tech> * Fix perms and cli after rebase Signed-off-by: Fiachra Corcoran <fiachra.corcoran@est.tech> * Fix unit test Signed-off-by: Fiachra Corcoran <fiachra.corcoran@est.tech> * Fix failing cli tests Signed-off-by: Fiachra Corcoran <fiachra.corcoran@est.tech> * Address review comments Signed-off-by: Fiachra Corcoran <fiachra.corcoran@est.tech> * Remove redundant test Signed-off-by: Fiachra Corcoran <fiachra.corcoran@est.tech> * Remove Embedded controller option Signed-off-by: Fiachra Corcoran <fiachra.corcoran@est.tech> * Revert change to e2e workflow Signed-off-by: Fiachra Corcoran <fiachra.corcoran@est.tech> * Fix unit test Signed-off-by: Fiachra Corcoran <fiachra.corcoran@est.tech> * Revert repo config api move Signed-off-by: Fiachra Corcoran <fiachra.corcoran@est.tech> * Add boilerplate header chnages Signed-off-by: Fiachra Corcoran <fiachra.corcoran@est.tech> * Remove testbin artifacts Signed-off-by: Fiachra Corcoran <fiachra.corcoran@est.tech> --------- Signed-off-by: liamfallon <liam.fallon@est.tech> Signed-off-by: Fiachra Corcoran <fiachra.corcoran@est.tech> Co-authored-by: Liam Fallon <35595825+liamfallon@users.noreply.github.com> * Fix missed merge conflict Signed-off-by: Fiachra Corcoran <fiachra.corcoran@est.tech> * Fix failing build Signed-off-by: Fiachra Corcoran <fiachra.corcoran@est.tech> * Readd missing import Signed-off-by: Fiachra Corcoran <fiachra.corcoran@est.tech> * Make WS name unique Signed-off-by: Fiachra Corcoran <fiachra.corcoran@est.tech> * Fix failing fn runner e2e Signed-off-by: Fiachra Corcoran <fiachra.corcoran@est.tech> * Try again to avoid clone failure Signed-off-by: Fiachra Corcoran <fiachra.corcoran@est.tech> * Skeleton for passing request information via context (kptdev#465) * porch context skeleton * fix package path for create PR * remove and ignore docs/go.mod and go.sum * fix lint, group PorchServerOptions * fix context mock expectations * readd docs go.mod * rebase, adapt logs added in kptdev#460 to structured logs * Add Repo Controller docs (kptdev#458) * Add Repo Controller docs Signed-off-by: Fiachra Corcoran <fiachra.corcoran@est.tech> * Trigger netlify preview Signed-off-by: Fiachra Corcoran <fiachra.corcoran@est.tech> * Address review comments Signed-off-by: Fiachra Corcoran <fiachra.corcoran@est.tech> * Update wonky diagram arrows Signed-off-by: Fiachra Corcoran <fiachra.corcoran@est.tech> --------- Signed-off-by: Fiachra Corcoran <fiachra.corcoran@est.tech> * Align context import alias with main branch Change porchcontext to context1 to match the implementation in main branch. This will allow clean merge of main into feature-1.6. * Fix broken merge Signed-off-by: Fiachra Corcoran <fiachra.corcoran@est.tech> * Fix missed merge conflicts Signed-off-by: Fiachra Corcoran <fiachra.corcoran@est.tech> * Make tidy Signed-off-by: Fiachra Corcoran <fiachra.corcoran@est.tech> * Remove on_push for e2e Signed-off-by: Fiachra Corcoran <fiachra.corcoran@est.tech> * Run make tidy Signed-off-by: Fiachra Corcoran <fiachra.corcoran@est.tech> --------- Signed-off-by: liamfallon <liam.fallon@est.tech> Signed-off-by: Fiachra Corcoran <fiachra.corcoran@est.tech> Co-authored-by: Liam Fallon <35595825+liamfallon@users.noreply.github.com> Co-authored-by: mozesl-nokia <laszlo.mozes@nokia.com>
1 parent a8ee18c commit 475c5f1

126 files changed

Lines changed: 7609 additions & 3569 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.github/workflows/porch-e2e-ci-jobs.yaml

Lines changed: 16 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -124,22 +124,22 @@ jobs:
124124
make_target: "run-in-kind"
125125
test_path: "${GITHUB_WORKSPACE}/test/e2e/api"
126126
test_env: "E2E=1"
127-
log_name: "porch-e2e-server.log"
127+
log_prefix: "porch-e2e"
128128
- name: "Porch E2E Tests (DB Cache)"
129129
make_target: "run-in-kind-db-cache"
130130
test_path: "${GITHUB_WORKSPACE}/test/e2e/api"
131131
test_env: "E2E=1 DB_CACHE=1"
132-
log_name: "porch-e2e-dbcache-server.log"
132+
log_prefix: "porch-e2e-dbcache"
133133
- name: "Porch CLI E2E Tests"
134-
make_target: "run-in-kind-no-git"
134+
make_target: "run-in-kind"
135135
test_path: "${GITHUB_WORKSPACE}/test/e2e/cli"
136136
test_env: "E2E=1"
137-
log_name: "porch-cli-e2e-server.log"
137+
log_prefix: "porch-cli-e2e"
138138
- name: "Porch CLI E2E Tests (DB Cache)"
139-
make_target: "run-in-kind-db-cache-no-git"
139+
make_target: "run-in-kind-db-cache"
140140
test_path: "${GITHUB_WORKSPACE}/test/e2e/cli"
141141
test_env: "E2E=1"
142-
log_name: "porch-cli-e2e-dbcache-server.log"
142+
log_prefix: "porch-cli-e2e-dbcache"
143143

144144
steps:
145145
- name: Checkout Porch
@@ -178,13 +178,20 @@ jobs:
178178
if: always()
179179
run: |
180180
name=$(kubectl -n porch-system get pod -l app=porch-server -o custom-columns=NAME:.metadata.name --no-headers=true)
181-
kubectl -n porch-system logs $name > ${{ matrix.log_name }}
181+
kubectl -n porch-system logs $name > ${{ matrix.log_prefix }}-server.log
182+
- name: Export porch controllers logs
183+
if: always()
184+
run: |
185+
name=$(kubectl -n porch-system get pod -l k8s-app=porch-controllers -o custom-columns=NAME:.metadata.name --no-headers=true 2>/dev/null || true)
186+
if [ -n "$name" ]; then
187+
kubectl -n porch-system logs $name > ${{ matrix.log_prefix }}-controllers.log 2>/dev/null || true
188+
fi
182189
- name: Archive logs
183190
if: always()
184191
uses: actions/upload-artifact@v4
185192
with:
186-
name: ${{ matrix.log_name }}
187-
path: ${{ matrix.log_name }}
193+
name: ${{ matrix.log_prefix }}-logs
194+
path: "*.log"
188195
compression-level: 0
189196
retention-days: 2
190197

.github/workflows/sonarcloud.yml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,7 @@ jobs:
8383
workflow: CI test report
8484
run_id: ${{ github.event.workflow_run.id }}
8585
name: coverage-report
86+
use_unzip: true
8687

8788
- name: Fix Go module paths in coverage
8889
run: |
@@ -111,4 +112,4 @@ jobs:
111112
args:
112113
-Dsonar.projectKey=nephio-project_porch
113114
-Dsonar.organization=nephio-project
114-
-Dproject.settings=sonar-project.properties
115+
-Dproject.settings=sonar-project.properties

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,5 +50,8 @@ docs/go.sum
5050
# Temporary lock file while building
5151
/.hugo_build.lock
5252

53+
# Test binaries
54+
testbin/
55+
5356
# gosec artifacts
5457
*.sarif

api/porchconfig/v1alpha1/config.porch.kpt.dev_repositories.yaml

Lines changed: 60 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@ spec:
2424
kind: Repository
2525
listKind: RepositoryList
2626
plural: repositories
27+
shortNames:
28+
- repo
2729
singular: repository
2830
scope: Namespaced
2931
versions:
@@ -46,6 +48,12 @@ spec:
4648
- jsonPath: .spec['git','oci']['repo','registry']
4749
name: Address
4850
type: string
51+
- jsonPath: .spec.git.branch
52+
name: Branch
53+
type: string
54+
- jsonPath: .metadata.creationTimestamp
55+
name: Age
56+
type: date
4957
name: v1alpha1
5058
schema:
5159
openAPIV3Schema:
@@ -101,19 +109,19 @@ spec:
101109
type: string
102110
branch:
103111
default: main
104-
description: Name of the branch containing the packages. Finalized
105-
packages will be committed to this branch (if the repository
106-
allows write access). If unspecified, defaults to "main".
112+
description: |-
113+
Name of the branch containing the packages. Finalized packages will be committed to this branch (if the repository allows write access). If unspecified, defaults to "main".
114+
This field is immutable after creation.
107115
minLength: 1
108116
type: string
109117
createBranch:
110118
description: CreateBranch specifies if Porch should create the
111119
package branch if it doesn't exist.
112120
type: boolean
113121
directory:
114-
description: Directory within the Git repository where the packages
115-
are stored. A subdirectory of this directory containing a Kptfile
116-
is considered a package. If unspecified, defaults to root directory.
122+
description: |-
123+
Directory within the Git repository where the packages are stored. A subdirectory of this directory containing a Kptfile is considered a package. If unspecified, defaults to root directory.
124+
This field is immutable after creation.
117125
type: string
118126
email:
119127
description: Email to use for commits
@@ -162,9 +170,8 @@ spec:
162170
description: Repository sync/reconcile details
163171
properties:
164172
runOnceAt:
165-
description: Value in metav1.Time format to indicate when the
166-
repository should be synced once outside the periodic cron based
167-
reconcile loop.
173+
description: Value in metav1.Time format to trigger a one-time
174+
cache sync outside the periodic schedule.
168175
format: date-time
169176
type: string
170177
schedule:
@@ -238,13 +245,57 @@ spec:
238245
- type
239246
type: object
240247
type: array
248+
gitCommitHash:
249+
description: |-
250+
GitCommitHash is the commit hash of the configured branch for git repositories.
251+
Empty for OCI repositories.
252+
type: string
253+
lastFullSyncTime:
254+
description: LastFullSyncTime is the timestamp of the last successful
255+
full repository sync.
256+
format: date-time
257+
type: string
258+
nextFullSyncTime:
259+
description: NextFullSyncTime is the timestamp when the next full
260+
sync is scheduled to occur.
261+
format: date-time
262+
type: string
263+
observedGeneration:
264+
description: ObservedGeneration is the generation of the Repository
265+
spec that was last reconciled.
266+
format: int64
267+
type: integer
268+
observedRunOnceAt:
269+
description: |-
270+
ObservedRunOnceAt tracks the last observed value of spec.sync.runOnceAt.
271+
Used to detect when runOnceAt is set, updated, or cleared to prevent redundant syncs.
272+
format: date-time
273+
type: string
274+
packageCount:
275+
description: PackageCount is the number of package revisions discovered
276+
in the repository.
277+
type: integer
241278
type: object
242279
type: object
243280
x-kubernetes-validations:
244281
- message: metadata.name must conform to the RFC1123 DNS label standard
245282
rule: self.metadata.name.matches('^[a-z0-9]([-a-z0-9]*[a-z0-9])?$')
246283
- message: metadata.name must be no more than 63 characters
247284
rule: size(self.metadata.name) <= 63
285+
- message: spec.type is immutable
286+
rule: '!has(oldSelf.spec.type) || self.spec.type == oldSelf.spec.type'
287+
- message: spec.git.repo is immutable
288+
rule: '!has(oldSelf.spec.git) || !has(oldSelf.spec.git.repo) || self.spec.git.repo
289+
== oldSelf.spec.git.repo'
290+
- message: spec.git.branch is immutable
291+
rule: '!has(oldSelf.spec.git) || !has(oldSelf.spec.git.branch) || self.spec.git.branch
292+
== oldSelf.spec.git.branch'
293+
- message: spec.git.directory is immutable
294+
rule: '!has(oldSelf.spec.git) || !has(oldSelf.spec.git.directory) || self.spec.git.directory
295+
== oldSelf.spec.git.directory'
296+
- message: spec.oci.registry is immutable
297+
rule: '!has(oldSelf.spec.oci) || !has(oldSelf.spec.oci.registry) || self.spec.oci.registry
298+
== oldSelf.spec.oci.registry'
248299
served: true
249300
storage: true
250301
subresources:

api/porchconfig/v1alpha1/groupversion_info.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// Copyright 2022,2026 The kpt and Nephio Authors
1+
// Copyright 2022-2026 The kpt and Nephio Authors
22
//
33
// Licensed under the Apache License, Version 2.0 (the "License");
44
// you may not use this file except in compliance with the License.

api/porchconfig/v1alpha1/types.go

Lines changed: 32 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// Copyright 2022-2025 The kpt and Nephio Authors
1+
// Copyright 2022-2026 The kpt and Nephio Authors
22
//
33
// Licensed under the Apache License, Version 2.0 (the "License");
44
// you may not use this file except in compliance with the License.
@@ -20,15 +20,22 @@ import (
2020

2121
//+kubebuilder:object:root=true
2222
//+kubebuilder:subresource:status
23-
//+kubebuilder:resource:path=repositories,singular=repository
23+
//+kubebuilder:resource:path=repositories,singular=repository,shortName=repo
2424
//+kubebuilder:printcolumn:name="Type",type=string,JSONPath=`.spec.type`
2525
//+kubebuilder:printcolumn:name="Content",type=string,JSONPath=`.spec.content`
2626
// +kubebuilder:printcolumn:name="Sync schedule",type=string,JSONPath=`.spec.sync.schedule`
2727
//+kubebuilder:printcolumn:name="Deployment",type=boolean,JSONPath=`.spec.deployment`
2828
//+kubebuilder:printcolumn:name="Ready",type=string,JSONPath=`.status.conditions[?(@.type=='Ready')].status`
2929
//+kubebuilder:printcolumn:name="Address",type=string,JSONPath=`.spec['git','oci']['repo','registry']`
30+
//+kubebuilder:printcolumn:name="Branch",type=string,JSONPath=`.spec.git.branch`
31+
//+kubebuilder:printcolumn:name="Age",type=date,JSONPath=`.metadata.creationTimestamp`
3032
// +kubebuilder:validation:XValidation:rule="self.metadata.name.matches('^[a-z0-9]([-a-z0-9]*[a-z0-9])?$')",message="metadata.name must conform to the RFC1123 DNS label standard"
3133
// +kubebuilder:validation:XValidation:rule="size(self.metadata.name) <= 63",message="metadata.name must be no more than 63 characters"
34+
// +kubebuilder:validation:XValidation:rule="!has(oldSelf.spec.type) || self.spec.type == oldSelf.spec.type",message="spec.type is immutable"
35+
// +kubebuilder:validation:XValidation:rule="!has(oldSelf.spec.git) || !has(oldSelf.spec.git.repo) || self.spec.git.repo == oldSelf.spec.git.repo",message="spec.git.repo is immutable"
36+
// +kubebuilder:validation:XValidation:rule="!has(oldSelf.spec.git) || !has(oldSelf.spec.git.branch) || self.spec.git.branch == oldSelf.spec.git.branch",message="spec.git.branch is immutable"
37+
// +kubebuilder:validation:XValidation:rule="!has(oldSelf.spec.git) || !has(oldSelf.spec.git.directory) || self.spec.git.directory == oldSelf.spec.git.directory",message="spec.git.directory is immutable"
38+
// +kubebuilder:validation:XValidation:rule="!has(oldSelf.spec.oci) || !has(oldSelf.spec.oci.registry) || self.spec.oci.registry == oldSelf.spec.oci.registry",message="spec.oci.registry is immutable"
3239

3340
// Repository
3441
type Repository struct {
@@ -77,7 +84,7 @@ type RepositorySpec struct {
7784
}
7885

7986
type RepositorySync struct {
80-
// Value in metav1.Time format to indicate when the repository should be synced once outside the periodic cron based reconcile loop.
87+
// Value in metav1.Time format to trigger a one-time cache sync outside the periodic schedule.
8188
RunOnceAt *metav1.Time `json:"runOnceAt,omitempty"`
8289
// Cron value to indicate when the repository should be synced periodically. Example: `*/10 * * * *` to sync every 10 minutes.
8390
Schedule string `json:"schedule,omitempty"`
@@ -92,10 +99,12 @@ type GitRepository struct {
9299
// +kubebuilder:default=main
93100
// +kubebuilder:validation:MinLength=1
94101
// Name of the branch containing the packages. Finalized packages will be committed to this branch (if the repository allows write access). If unspecified, defaults to "main".
102+
// This field is immutable after creation.
95103
Branch string `json:"branch,omitempty"`
96104
// CreateBranch specifies if Porch should create the package branch if it doesn't exist.
97105
CreateBranch bool `json:"createBranch,omitempty"`
98106
// Directory within the Git repository where the packages are stored. A subdirectory of this directory containing a Kptfile is considered a package. If unspecified, defaults to root directory.
107+
// This field is immutable after creation.
99108
Directory string `json:"directory,omitempty"`
100109
// Reference to secret containing authentication credentials.
101110
SecretRef SecretRef `json:"secretRef,omitempty"`
@@ -160,6 +169,26 @@ const (
160169
type RepositoryStatus struct {
161170
// Conditions describes the reconciliation state of the object.
162171
Conditions []metav1.Condition `json:"conditions,omitempty"`
172+
// LastFullSyncTime is the timestamp of the last successful full repository sync.
173+
// +optional
174+
LastFullSyncTime *metav1.Time `json:"lastFullSyncTime,omitempty"`
175+
// ObservedGeneration is the generation of the Repository spec that was last reconciled.
176+
// +optional
177+
ObservedGeneration int64 `json:"observedGeneration,omitempty"`
178+
// ObservedRunOnceAt tracks the last observed value of spec.sync.runOnceAt.
179+
// Used to detect when runOnceAt is set, updated, or cleared to prevent redundant syncs.
180+
// +optional
181+
ObservedRunOnceAt *metav1.Time `json:"observedRunOnceAt,omitempty"`
182+
// PackageCount is the number of package revisions discovered in the repository.
183+
// +optional
184+
PackageCount int `json:"packageCount,omitempty"`
185+
// GitCommitHash is the commit hash of the configured branch for git repositories.
186+
// Empty for OCI repositories.
187+
// +optional
188+
GitCommitHash string `json:"gitCommitHash,omitempty"`
189+
// NextFullSyncTime is the timestamp when the next full sync is scheduled to occur.
190+
// +optional
191+
NextFullSyncTime *metav1.Time `json:"nextFullSyncTime,omitempty"`
163192
}
164193

165194
//+kubebuilder:object:root=true

api/porchconfig/v1alpha1/zz_generated.deepcopy.go

Lines changed: 12 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

controllers/main.go

Lines changed: 30 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// Copyright 2022,2026 The kpt and Nephio Authors
1+
// Copyright 2022-2026 The kpt and Nephio Authors
22
//
33
// Licensed under the Apache License, Version 2.0 (the "License");
44
// you may not use this file except in compliance with the License.
@@ -38,9 +38,9 @@ import (
3838
"sigs.k8s.io/controller-runtime/pkg/client"
3939
"sigs.k8s.io/controller-runtime/pkg/webhook"
4040

41-
porchapi "github.com/nephio-project/porch/api/porch/v1alpha1"
4241
"github.com/nephio-project/porch/controllers/packagevariants/pkg/controllers/packagevariant"
4342
"github.com/nephio-project/porch/controllers/packagevariantsets/pkg/controllers/packagevariantset"
43+
"github.com/nephio-project/porch/controllers/repositories/pkg/controllers/repository"
4444
porchotel "github.com/nephio-project/porch/internal/otel"
4545
"github.com/nephio-project/porch/pkg/controllerrestmapper"
4646
"k8s.io/apimachinery/pkg/runtime"
@@ -49,13 +49,20 @@ import (
4949
"sigs.k8s.io/controller-runtime/pkg/healthz"
5050
metricsserver "sigs.k8s.io/controller-runtime/pkg/metrics/server"
5151
"sigs.k8s.io/controller-runtime/pkg/reconcile"
52+
53+
porchapi "github.com/nephio-project/porch/api/porch/v1alpha1"
54+
configapi "github.com/nephio-project/porch/api/porchconfig/v1alpha1"
55+
porchinternal "github.com/nephio-project/porch/internal/api/porchinternal/v1alpha1"
5256
//+kubebuilder:scaffold:imports
5357
)
5458

59+
const errInitScheme = "error initializing scheme: %w"
60+
5561
var (
5662
reconcilers = map[string]Reconciler{
5763
"packagevariants": &packagevariant.PackageVariantReconciler{},
5864
"packagevariantsets": &packagevariantset.PackageVariantSetReconciler{},
65+
"repositories": &repository.RepositoryReconciler{},
5966
}
6067
)
6168

@@ -71,6 +78,9 @@ type Reconciler interface {
7178

7279
// SetupWithManager registers the reconciler to run under the specified manager
7380
SetupWithManager(ctrl.Manager) error
81+
82+
// SetLogger sets the logger for the reconciler
83+
SetLogger(name string)
7484
}
7585

7686
// We include our lease / events permissions in the main RBAC role
@@ -117,11 +127,19 @@ func run(ctx context.Context) error {
117127

118128
scheme := runtime.NewScheme()
119129
if err := clientgoscheme.AddToScheme(scheme); err != nil {
120-
return fmt.Errorf("error initializing scheme: %w", err)
130+
return fmt.Errorf(errInitScheme, err)
121131
}
122132

123133
if err := porchapi.AddToScheme(scheme); err != nil {
124-
return fmt.Errorf("error initializing scheme: %w", err)
134+
return fmt.Errorf(errInitScheme, err)
135+
}
136+
137+
if err := configapi.AddToScheme(scheme); err != nil {
138+
return fmt.Errorf(errInitScheme, err)
139+
}
140+
141+
if err := porchinternal.AddToScheme(scheme); err != nil {
142+
return fmt.Errorf(errInitScheme, err)
125143
}
126144

127145
managerOptions := ctrl.Options{
@@ -174,6 +192,8 @@ func run(ctx context.Context) error {
174192
if !reconcilerIsEnabled(enabledReconcilers, name) {
175193
continue
176194
}
195+
reconciler.SetLogger(name)
196+
ctrl.Log.WithName(name).Info("setting up controller")
177197
if err = reconciler.SetupWithManager(mgr); err != nil {
178198
return fmt.Errorf("error creating %s reconciler: %w", name, err)
179199
}
@@ -212,8 +232,12 @@ func reconcilerIsEnabled(reconcilers []string, reconciler string) bool {
212232
if slices.Contains(reconcilers, reconciler) {
213233
return true
214234
}
215-
if _, found := os.LookupEnv(fmt.Sprintf("ENABLE_%s", strings.ToUpper(reconciler))); found {
216-
return true
235+
// Check env var value (not just existence)
236+
envVar := fmt.Sprintf("ENABLE_%s", strings.ToUpper(reconciler))
237+
if val := os.Getenv(envVar); val != "" {
238+
// Parse as boolean: "true", "1", "yes" = enabled
239+
valLower := strings.ToLower(val)
240+
return valLower == "true" || val == "1" || valLower == "yes"
217241
}
218242
return false
219243
}

0 commit comments

Comments
 (0)