diff --git a/config/crd/bases/aggregation.coder.com_codertemplates.yaml b/config/crd/bases/aggregation.coder.com_codertemplates.yaml deleted file mode 100644 index 7d587483..00000000 --- a/config/crd/bases/aggregation.coder.com_codertemplates.yaml +++ /dev/null @@ -1,90 +0,0 @@ ---- -apiVersion: apiextensions.k8s.io/v1 -kind: CustomResourceDefinition -metadata: - annotations: - controller-gen.kubebuilder.io/version: v0.20.0 - name: codertemplates.aggregation.coder.com -spec: - group: aggregation.coder.com - names: - kind: CoderTemplate - listKind: CoderTemplateList - plural: codertemplates - singular: codertemplate - scope: Namespaced - versions: - - name: v1alpha1 - schema: - openAPIV3Schema: - description: |- - CoderTemplate is the schema for Coder template resources. - metadata.name is .. - properties: - apiVersion: - description: |- - APIVersion defines the versioned schema of this representation of an object. - Servers should convert recognized schemas to the latest internal value, and - may reject unrecognized values. - More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources - type: string - kind: - description: |- - Kind is a string value representing the REST resource this object represents. - Servers may infer this from the endpoint the client submits requests to. - Cannot be updated. - In CamelCase. - More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds - type: string - metadata: - type: object - spec: - description: CoderTemplateSpec defines the desired state of a CoderTemplate. - properties: - description: - type: string - displayName: - type: string - icon: - type: string - organization: - description: Organization is the Coder organization name (must match - the organization prefix in metadata.name). - type: string - running: - description: Running is a legacy flag retained temporarily for in-repo - callers that still read template run-state directly. - type: boolean - versionID: - description: VersionID is the Coder template version UUID used on - creation (required for CREATE). - type: string - required: - - organization - - versionID - type: object - status: - description: CoderTemplateStatus defines the observed state of a CoderTemplate. - properties: - activeVersionID: - type: string - autoShutdown: - description: AutoShutdown is a legacy timestamp retained temporarily - for in-repo callers that still surface template shutdown timestamps. - format: date-time - type: string - deprecated: - type: boolean - id: - type: string - organizationName: - type: string - updatedAt: - format: date-time - type: string - type: object - type: object - served: true - storage: true - subresources: - status: {} diff --git a/config/crd/bases/aggregation.coder.com_coderworkspaces.yaml b/config/crd/bases/aggregation.coder.com_coderworkspaces.yaml deleted file mode 100644 index 50abcb09..00000000 --- a/config/crd/bases/aggregation.coder.com_coderworkspaces.yaml +++ /dev/null @@ -1,92 +0,0 @@ ---- -apiVersion: apiextensions.k8s.io/v1 -kind: CustomResourceDefinition -metadata: - annotations: - controller-gen.kubebuilder.io/version: v0.20.0 - name: coderworkspaces.aggregation.coder.com -spec: - group: aggregation.coder.com - names: - kind: CoderWorkspace - listKind: CoderWorkspaceList - plural: coderworkspaces - singular: coderworkspace - scope: Namespaced - versions: - - name: v1alpha1 - schema: - openAPIV3Schema: - description: |- - CoderWorkspace is the schema for Coder workspace resources. - metadata.name is ... - properties: - apiVersion: - description: |- - APIVersion defines the versioned schema of this representation of an object. - Servers should convert recognized schemas to the latest internal value, and - may reject unrecognized values. - More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources - type: string - kind: - description: |- - Kind is a string value representing the REST resource this object represents. - Servers may infer this from the endpoint the client submits requests to. - Cannot be updated. - In CamelCase. - More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds - type: string - metadata: - type: object - spec: - description: CoderWorkspaceSpec defines the desired state of a CoderWorkspace. - properties: - autostartSchedule: - type: string - organization: - description: Organization is the Coder organization name. - type: string - running: - description: Running drives start/stop via CreateWorkspaceBuild. - type: boolean - templateName: - description: TemplateName resolves via TemplateByName(organization, - templateName). - type: string - templateVersionID: - description: TemplateVersionID optionally pins to a specific template - version. - type: string - ttlMillis: - format: int64 - type: integer - required: - - running - type: object - status: - description: CoderWorkspaceStatus defines the observed state of a CoderWorkspace. - properties: - autoShutdown: - format: date-time - type: string - id: - type: string - lastUsedAt: - format: date-time - type: string - latestBuildID: - type: string - latestBuildStatus: - type: string - organizationName: - type: string - ownerName: - type: string - templateName: - type: string - type: object - type: object - served: true - storage: true - subresources: - status: {} diff --git a/docs/how-to/troubleshooting.md b/docs/how-to/troubleshooting.md index 3bdd7e67..b26a414b 100644 --- a/docs/how-to/troubleshooting.md +++ b/docs/how-to/troubleshooting.md @@ -40,6 +40,30 @@ kubectl apply -f config/crd/bases/ kubectl get clusterrolebinding coder-k8s-controller ``` +## Aggregated `codertemplates` / `coderworkspaces` reads are empty or inconsistent + +If `kubectl get codertemplates.aggregation.coder.com` or `kubectl get coderworkspaces.aggregation.coder.com` returns empty data unexpectedly, check for CRD/APIService conflicts. + +When both of these exist at once: + +- `APIService` `v1alpha1.aggregation.coder.com` +- CRDs `codertemplates.aggregation.coder.com` and/or `coderworkspaces.aggregation.coder.com` + +Kubernetes may not route reads the way you expect for demos. + +```bash +kubectl get apiservice v1alpha1.aggregation.coder.com +kubectl get crd codertemplates.aggregation.coder.com coderworkspaces.aggregation.coder.com +``` + +For APIService-based demos, remove the conflicting aggregation CRDs: + +```bash +kubectl delete crd codertemplates.aggregation.coder.com coderworkspaces.aggregation.coder.com +kubectl apply -f deploy/apiserver-apiservice.yaml +kubectl wait --for=condition=Available apiservice/v1alpha1.aggregation.coder.com --timeout=120s +``` + ## Aggregated APIService shows `False` / `Unavailable` - Ensure the deployment and service exist: diff --git a/hack/kind-dev.sh b/hack/kind-dev.sh index ae44726a..b8ba2ee3 100755 --- a/hack/kind-dev.sh +++ b/hack/kind-dev.sh @@ -76,6 +76,29 @@ ensure_cluster_node_image_matches() { exit 1 } +assert_no_aggregation_resource_conflict() { + local has_apiservice="false" + local has_template_crd="false" + local has_workspace_crd="false" + + if kubectl_ctx get apiservice v1alpha1.aggregation.coder.com >/dev/null 2>&1; then + has_apiservice="true" + fi + if kubectl_ctx get crd codertemplates.aggregation.coder.com >/dev/null 2>&1; then + has_template_crd="true" + fi + if kubectl_ctx get crd coderworkspaces.aggregation.coder.com >/dev/null 2>&1; then + has_workspace_crd="true" + fi + + if [[ "${has_apiservice}" == "true" && ( "${has_template_crd}" == "true" || "${has_workspace_crd}" == "true" ) ]]; then + echo "assertion failed: detected aggregation API conflict in ${KUBE_CONTEXT}: APIService v1alpha1.aggregation.coder.com and aggregation.coder.com CRDs are both installed." >&2 + echo "Delete conflicting CRDs before aggregated API demos:" >&2 + echo " kubectl --context ${KUBE_CONTEXT} delete crd codertemplates.aggregation.coder.com coderworkspaces.aggregation.coder.com" >&2 + exit 1 + fi +} + build_binary() { local resolved_goarch="${GOARCH}" if [[ -z "${resolved_goarch}" ]]; then @@ -115,8 +138,10 @@ cmd_up() { kubectl config use-context "${KUBE_CONTEXT}" >/dev/null kubectl_ctx wait --for=condition=Ready node --all --timeout="${NODE_READY_TIMEOUT}" + assert_no_aggregation_resource_conflict kubectl_ctx apply -f config/e2e/namespace.yaml + # config/crd/bases intentionally contains only operator-owned coder.com CRDs. kubectl_ctx apply -f config/crd/bases/ kubectl_ctx apply -f config/rbac/ diff --git a/hack/update-manifests.sh b/hack/update-manifests.sh index e4c34847..bb436ea0 100755 --- a/hack/update-manifests.sh +++ b/hack/update-manifests.sh @@ -14,9 +14,15 @@ if [[ ! -d "${SCRIPT_ROOT}/internal/controller" ]]; then fi cd "${SCRIPT_ROOT}" + +# Generate CRDs for operator-owned coder.com APIs only. GOFLAGS=-mod=vendor go run ./vendor/sigs.k8s.io/controller-tools/cmd/controller-gen \ crd:crdVersions=v1 \ + paths=./api/v1alpha1 \ + output:crd:artifacts:config=config/crd/bases + +# Generate RBAC across the repo. +GOFLAGS=-mod=vendor go run ./vendor/sigs.k8s.io/controller-tools/cmd/controller-gen \ rbac:roleName=manager-role \ paths=./... \ - output:crd:artifacts:config=config/crd/bases \ output:rbac:artifacts:config=config/rbac