Skip to content

Commit

Permalink
Merge pull request #319 from alecmerdler/PROJQUAY-828
Browse files Browse the repository at this point in the history
Downstream Component Images (PROJQUAY-828)
  • Loading branch information
alecmerdler authored Oct 20, 2020
2 parents d5a8ac3 + 42a4c17 commit 66e215c
Show file tree
Hide file tree
Showing 20 changed files with 244 additions and 122 deletions.
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

0 comments on commit 66e215c

Please sign in to comment.