Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Downstream Component Images (PROJQUAY-828) #319

Merged
merged 1 commit into from
Oct 20, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
107 changes: 84 additions & 23 deletions apis/quay/v1/quayregistry_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,15 +18,14 @@ package v1

import (
"errors"
"os"
"strings"

"k8s.io/apimachinery/pkg/api/meta"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
runtime "k8s.io/apimachinery/pkg/runtime"
)

type QuayVersion string

const (
SupportsRoutesAnnotation = "supports-routes"
ClusterHostnameAnnotation = "router-canonical-hostname"
Expand All @@ -36,28 +35,76 @@ const (
StorageBucketNameAnnotation = "storage-bucketname"
StorageAccessKeyAnnotation = "storage-access-key"
StorageSecretKeyAnnotation = "storage-secret-key"

defaultVersionStreamKey = "DEFAULT_STREAM"
)

type QuayStream string

const (
QuayUpstream QuayStream = "upstream"
QuayDownstream QuayStream = "downstream"

QuayStreamNone QuayStream = ""
)

type QuayVersion string

const (
QuayVersionVader QuayVersion = "vader"
QuayVersionQuiGon QuayVersion = "qui-gon"
// Upstream versions
QuayVersionVader QuayVersion = "vader"

// Downstream versions
QuayVersion340 QuayVersion = "v3.4.0"

// QuayVersionDev is used to provide Kustomize overrides.
QuayVersionDev QuayVersion = "dev"

QuayVersionNone QuayVersion = ""
)

var quayVersions = map[QuayVersion]int{
QuayVersionDev: 0,
QuayVersionQuiGon: 1,
QuayVersionVader: 2,
var quayVersions = map[QuayVersion]struct {
Next QuayVersion
Stream QuayStream
}{
QuayVersionVader: {
Next: "",
Stream: QuayUpstream,
},
QuayVersion340: {
Next: "",
Stream: QuayDownstream,
},
QuayVersionDev: {
Next: QuayVersionDev,
Stream: QuayStreamNone,
},
QuayVersionNone: {
Next: QuayVersionNone,
Stream: QuayStreamNone,
},
}

// Next returns the version that succeeds this version.
func (version QuayVersion) Next() QuayVersion {
return quayVersions[version].Next
}

// Stream returns the source for this version.
func (version QuayVersion) Stream() QuayStream {
return quayVersions[version].Stream
}

func mostRecentVersion() QuayVersion {
var mostRecent QuayVersion
mostRecentRank := 0
for v, rank := range quayVersions {
if rank > mostRecentRank {
mostRecent = v
mostRecentRank = rank
defaultVersionStream := QuayUpstream
if os.Getenv(defaultVersionStreamKey) == string(QuayDownstream) {
defaultVersionStream = QuayDownstream
}

mostRecent := QuayVersionNone
for version, info := range quayVersions {
if info.Stream == defaultVersionStream && info.Next == QuayVersionNone {
mostRecent = version
}
}

Expand Down Expand Up @@ -197,18 +244,32 @@ func ComponentsMatch(firstComponents, secondComponents []Component) bool {
func EnsureDesiredVersion(quay *QuayRegistry) (*QuayRegistry, error) {
updatedQuay := quay.DeepCopy()

if updatedQuay.Spec.DesiredVersion == "" {
updatedQuay.Spec.DesiredVersion = mostRecentVersion()
if quay.Status.CurrentVersion == QuayVersionNone {
if updatedQuay.Spec.DesiredVersion == QuayVersionNone {
updatedQuay.Spec.DesiredVersion = mostRecentVersion()
return updatedQuay, nil
}

return updatedQuay, nil
}
if _, ok := quayVersions[updatedQuay.Spec.DesiredVersion]; !ok {
return updatedQuay, errors.New("invalid `desiredVersion`: " + string(updatedQuay.Spec.DesiredVersion))
}
} else {
if updatedQuay.Spec.DesiredVersion == QuayVersionNone {
updatedQuay.Spec.DesiredVersion = quay.Status.CurrentVersion
return updatedQuay, nil
}

if quay.Status.CurrentVersion != "" && quayVersions[quay.Status.CurrentVersion] > quayVersions[updatedQuay.Spec.DesiredVersion] {
return updatedQuay, errors.New("cannot downgrade from `currentVersion`: " + string(quay.Status.CurrentVersion) + " > " + string(updatedQuay.Spec.DesiredVersion))
}
if quay.Spec.DesiredVersion == quay.Status.CurrentVersion {
return updatedQuay, nil
}

if _, ok := quayVersions[updatedQuay.Spec.DesiredVersion]; !ok {
return updatedQuay, errors.New("invalid `desiredVersion`: " + string(updatedQuay.Spec.DesiredVersion))
if _, ok := quayVersions[updatedQuay.Spec.DesiredVersion]; !ok {
return updatedQuay, errors.New("invalid `desiredVersion`: " + string(updatedQuay.Spec.DesiredVersion))
}

if updatedQuay.Spec.DesiredVersion != quay.Status.CurrentVersion.Next() {
return updatedQuay, errors.New("cannot downgrade from `currentVersion`: " + string(quay.Status.CurrentVersion) + " > " + string(updatedQuay.Spec.DesiredVersion))
}
}

return updatedQuay, nil
Expand Down
39 changes: 31 additions & 8 deletions apis/quay/v1/quayregistry_types_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -194,6 +194,22 @@ var ensureDesiredVersionTests = []struct {
expected QuayVersion
expectedErr error
}{
{
"DesiredVersionEmptyCurrentVersionEmpty",
QuayRegistry{},
QuayVersionVader,
nil,
},
{
"DesiredVersionEmptyCurrentVersionSet",
QuayRegistry{
Status: QuayRegistryStatus{
CurrentVersion: QuayVersionVader,
},
},
QuayVersionVader,
nil,
},
{
"InvalidDesiredVersion",
QuayRegistry{
Expand All @@ -205,33 +221,40 @@ var ensureDesiredVersionTests = []struct {
errors.New("invalid `desiredVersion`: not-a-real-version"),
},
{
"EmptyDesiredVersion",
QuayRegistry{},
QuayVersionVader,
"DevOverrideDesiredVersionCurrentVersionEmpty",
QuayRegistry{
Spec: QuayRegistrySpec{
DesiredVersion: QuayVersionDev,
},
},
QuayVersionDev,
nil,
},
{
"DevOverrideDesiredVersion",
"DevOverrideDesiredVersionCurrentVersionSet",
QuayRegistry{
Spec: QuayRegistrySpec{
DesiredVersion: QuayVersionDev,
},
Status: QuayRegistryStatus{
CurrentVersion: QuayVersionVader,
},
},
QuayVersionDev,
nil,
QuayVersionVader,
errors.New("cannot downgrade from `currentVersion`: vader > dev"),
},
{
"DowngradeProhibited",
QuayRegistry{
Spec: QuayRegistrySpec{
DesiredVersion: QuayVersionQuiGon,
DesiredVersion: QuayVersionDev,
},
Status: QuayRegistryStatus{
CurrentVersion: QuayVersionVader,
},
},
QuayVersionVader,
errors.New("cannot downgrade from `currentVersion`: qui-gon > vader"),
errors.New("cannot downgrade from `currentVersion`: vader > dev"),
},
}

Expand Down
7 changes: 6 additions & 1 deletion controllers/quay/quayregistry_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ import (
)

const upgradePollInterval = time.Second * 10
const upgradePollTimeout = time.Second * 120
const upgradePollTimeout = time.Second * 360

// QuayRegistryReconciler reconciles a QuayRegistry object
type QuayRegistryReconciler struct {
Expand Down Expand Up @@ -217,6 +217,11 @@ func (r *QuayRegistryReconciler) Reconcile(req ctrl.Request) (ctrl.Result, error

return upgradeDeployment.Status.ReadyReplicas > 0, nil
})

if err != nil {
log.Error(err, "Quay upgrade deployment never reached ready phase")
// TODO(alecmerdler): Update `status` block with failure condition.
}
}(updatedQuay.DeepCopy())
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,14 +18,16 @@ metadata:
"name": "example-registry"
},
"spec": {
"desiredVersion": "v3.4.0",
"configBundleSecret": "example-registry-config-bundle",
"components": [
{"kind": "clair", "managed": true},
{"kind": "postgres", "managed": true},
{"kind": "objectstorage", "managed": true},
{"kind": "redis", "managed": true},
{"kind": "horizontalpodautoscaler", "managed": true},
{"kind": "route", "managed": true}
{"kind": "route", "managed": true},
{"kind": "mirror", "managed": true}
]
}
}
Expand Down Expand Up @@ -62,8 +64,7 @@ spec:
displayName: Desired Version
description: Declares the version of Quay that should deployed and managed. Defaults to latest version.
x-descriptors:
- 'urn:alm:descriptor:com.tectonic.ui:select:padme'
- 'urn:alm:descriptor:com.tectonic.ui:select:qui-gon'
- 'urn:alm:descriptor:com.tectonic.ui:select:v3.4.0'
- 'urn:alm:descriptor:com.tectonic.ui:advanced'
- path: components
displayName: Components
Expand Down Expand Up @@ -116,6 +117,9 @@ spec:
valueFrom:
fieldRef:
fieldPath: metadata.annotations['olm.targetNamespaces']
# NOTE: This controls the default value for `desiredVersion` if left blank.
- name: DEFAULT_STREAM
value: downstream
image: quay.io/projectquay/quay-operator@sha256:4f88b7231dcac284893e7c6371ee631fccf592b553d0df76e624068bc9bb7553
name: quay-operator
volumeMounts:
Expand Down
5 changes: 4 additions & 1 deletion kustomize/components/clair/clair.deployment.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,10 @@ spec:
name: config
- mountPath: /var/run/certs
name: certs
# TODO(alecmerdler): Define `readinessProbe` which waits until indexer/matcher services are ready.
readinessProbe:
httpGet:
path: /indexer/api/v1/index_state
port: 8080
restartPolicy: Always
volumes:
- name: config
Expand Down
18 changes: 10 additions & 8 deletions kustomize/components/clair/postgres.deployment.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -18,22 +18,24 @@ spec:
- name: postgres-data
persistentVolumeClaim:
claimName: clair-postgres
securityContext:
fsGroup: 0
containers:
- name: postgres
image: postgres:latest
image: centos/postgresql-10-centos7
imagePullPolicy: "IfNotPresent"
ports:
- containerPort: 5432
protocol: TCP
env:
- name: POSTGRES_USER
- name: POSTGRESQL_USER
value: postgres
- name: POSTGRES_DB
value: clair
- name: POSTGRES_PASSWORD
- name: POSTGRESQL_DATABASE
value: postgres
- name: POSTGRESQL_PASSWORD
value: postgres
- name: POSTGRESQL_ADMIN_PASSWORD
value: postgres
- name: PGDATA
value: /var/lib/postgresql/data/pgdata
volumeMounts:
- name: postgres-data
mountPath: /var/lib/postgresql/data
mountPath: /var/lib/pgsql/data
6 changes: 6 additions & 0 deletions kustomize/components/postgres/create-extensions.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
#!/bin/sh

echo "attempting to create pg_trgm extension"
psql -d $POSTGRESQL_DATABASE -h $POSTGRESQL_DATABASE -U postgres -c 'CREATE EXTENSION pg_trgm;' || true
echo "succesfully created pg_trgm extension"
break
35 changes: 35 additions & 0 deletions kustomize/components/postgres/init.job.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
apiVersion: batch/v1
kind: Job
metadata:
name: quay-postgres-init
spec:
template:
metadata:
name: quay-postgres-init
spec:
restartPolicy: Never
securityContext:
fsGroup: 0
volumes:
- name: postgres-bootstrap
secret:
secretName: postgres-bootstrap
defaultMode: 0777
items:
- key: create-extensions.sh
path: create-extensions.sh
- key: restore.sh
path: restore.sh
containers:
- name: quay-postgres-init
image: centos/postgresql-10-centos7
command:
- /opt/app-root/src/docker-entrypoint-initdb.d/create-extensions.sh
env:
- name: POSTGRESQL_DATABASE
value: $(POSTGRES_DEPLOYMENT_NAME)
- name: PGPASSWORD
value: postgres
volumeMounts:
- name: postgres-bootstrap
mountPath: /opt/app-root/src/docker-entrypoint-initdb.d
6 changes: 3 additions & 3 deletions kustomize/components/postgres/kustomization.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,14 @@ resources:
- ./postgres.persistentvolumeclaim.yaml
- ./postgres.deployment.yaml
- ./postgres.service.yaml
- ./init.job.yaml
generatorOptions:
disableNameSuffixHash: true
secretGenerator:
- name: postgres-bootstrap
literals:
- create-extensions.sql=CREATE EXTENSION pg_trgm;
files:
- restore.sh=./restore.sh
- ./restore.sh
- ./create-extensions.sh
vars:
- name: POSTGRES_DEPLOYMENT_NAME
objref:
Expand Down
Loading