Files
unkin-agent 9da206dc7c Implement autobackup-operator controllers, tests, CI and packaging
PVCs and CloudNativePG Clusters need S3 buckets and backup schedules
provisioned consistently. This operator watches the
backups.unkin.net/{schedule,destination} annotations on those objects and
provisions everything needed to back them up, with no new CRDs.

- Add a PVC controller that provisions cephrgw ObjectStoreUser/Bucket/BucketAccess,
  auto-generates a restic repo-password Secret and creates a k8up Schedule scoped
  to the PVC via spec.backup.volumes[].persistentVolumeClaim.claimName.
- Add a CNPG Cluster controller that provisions the same bucket stack, idempotently
  patches spec.backup.barmanObjectStore (leaving a user-set destinationPath alone
  with a Warning event) and creates a ScheduledBackup.
- Resolve destinations through a ConfigMap lookup table; requeue until the
  BucketAccess is Ready before creating schedule resources; own-reference created
  resources and retain bucket data by default.
- Add schedule-mapping helpers (k8up 5-field/shortcut pass-through, CNPG 6-field
  seconds-first) and deterministic, length-bounded name derivation.
- Add unit tests (schedule mapping, name derivation, destination resolution) and
  envtest controller tests for both paths, wiring the external CRDs into envtest.
- Add kubebuilder-generated RBAC, a Dockerfile (distroless/nonroot), Woodpecker
  lint/test/build pipelines and a tag-triggered image push to the artifactapi
  docker-internal registry, plus a version-bump Makefile and deploy manifests.
2026-08-14 00:08:37 +10:00

75 lines
2.1 KiB
Go

package reflect2
import (
"reflect"
"unsafe"
)
type UnsafeStructField struct {
reflect.StructField
structType *UnsafeStructType
rtype unsafe.Pointer
ptrRType unsafe.Pointer
}
func newUnsafeStructField(structType *UnsafeStructType, structField reflect.StructField) *UnsafeStructField {
return &UnsafeStructField{
StructField: structField,
rtype: unpackEFace(structField.Type).data,
ptrRType: unpackEFace(reflect.PtrTo(structField.Type)).data,
structType: structType,
}
}
func (field *UnsafeStructField) Offset() uintptr {
return field.StructField.Offset
}
func (field *UnsafeStructField) Name() string {
return field.StructField.Name
}
func (field *UnsafeStructField) PkgPath() string {
return field.StructField.PkgPath
}
func (field *UnsafeStructField) Type() Type {
return field.structType.cfg.Type2(field.StructField.Type)
}
func (field *UnsafeStructField) Tag() reflect.StructTag {
return field.StructField.Tag
}
func (field *UnsafeStructField) Index() []int {
return field.StructField.Index
}
func (field *UnsafeStructField) Anonymous() bool {
return field.StructField.Anonymous
}
func (field *UnsafeStructField) Set(obj interface{}, value interface{}) {
objEFace := unpackEFace(obj)
assertType("StructField.SetIndex argument 1", field.structType.ptrRType, objEFace.rtype)
valueEFace := unpackEFace(value)
assertType("StructField.SetIndex argument 2", field.ptrRType, valueEFace.rtype)
field.UnsafeSet(objEFace.data, valueEFace.data)
}
func (field *UnsafeStructField) UnsafeSet(obj unsafe.Pointer, value unsafe.Pointer) {
fieldPtr := add(obj, field.StructField.Offset, "same as non-reflect &v.field")
typedmemmove(field.rtype, fieldPtr, value)
}
func (field *UnsafeStructField) Get(obj interface{}) interface{} {
objEFace := unpackEFace(obj)
assertType("StructField.GetIndex argument 1", field.structType.ptrRType, objEFace.rtype)
value := field.UnsafeGet(objEFace.data)
return packEFace(field.ptrRType, value)
}
func (field *UnsafeStructField) UnsafeGet(obj unsafe.Pointer) unsafe.Pointer {
return add(obj, field.StructField.Offset, "same as non-reflect &v.field")
}