Add quay-kubernetes package / Add quay CD to k8s

This commit is contained in:
Antoine Legrand 2017-07-17 01:24:31 +02:00
parent 2f750bfc87
commit 1d0313229e
45 changed files with 1129 additions and 10 deletions

View file

@ -25,4 +25,6 @@ coverage
test/__pycache__
__pycache__
**/__pycache__
static/build/**
static/build/**
.gitlab-ci/*
.gitlab-ci.*

2
.gitignore vendored
View file

@ -1,7 +1,7 @@
*.pyc
venv
screenshots/screenshots/
stack
conf/stack
*/node_modules
dist
dest

View file

@ -6,8 +6,10 @@ local baseJob = (import '.gitlab-ci/base_jobs.libsonnet')(vars);
local stages_list = [
// gitlab-ci stages
'docker_base',
'deploy',
'docker_build',
'docker_base',
'unit_tests',
'integration',
'docker_release',
@ -91,6 +93,13 @@ local jobs = {
env={ [key]: dbname for key in ['MYSQL_ROOT_PASSWORD', 'MYSQL_DATABASE',
'MYSQL_USER', 'MYSQL_PASSWORD'] }),
"deploy-preview": baseJob.QuayDeploy {
environment+: {on_stop: "stop-preview"},
} + onlyBranch,
"stop-preview": baseJob.QuayDeployStop {
} + onlyBranch,
};
{

View file

@ -47,6 +47,28 @@ container-release:
variables:
DOCKER_DRIVER: overlay
DOCKER_HOST: tcp://docker-host.gitlab-runner.svc.cluster.local:2375
deploy-preview:
before_script:
- appr login -u $DOCKER_USER -p $DOCKER_PASS quay.io
environment:
name: review/${CI_COMMIT_REF_SLUG}
on_stop: stop-preview
url: https://quay-${CI_COMMIT_REF_SLUG}.k8s.devtable.com
image: quay.io/appr/appr:kubectl
only:
- branches
script:
- cd deploy/quay-demo-app
- echo -n 1.0.0-${CI_COMMIT_REF_SLUG} > VERSION
- 'echo "{\"image\": \"quay.io/quay/quay-ci:${CI_COMMIT_REF_SLUG}\", \"tag\": \"${CI_COMMIT_REF_SLUG}\"}" > params.json'
- cat params.json
- appr push quay.io/quay -f
- appr deploy quay.io/quay/quay-demo-app@1.0.0-${CI_COMMIT_REF_SLUG} --namespace ci-quay-${CI_COMMIT_REF_SLUG} -x docker_user=$DOCKER_USER -x docker_pass=$DOCKER_PASS
- kubectl get ingresses -n ci-quay-${CI_COMMIT_REF_SLUG} -o wide
stage: deploy
tags:
- kubernetes
when: manual
karma-tests:
before_script:
- cd $QUAYDIR
@ -130,12 +152,34 @@ registry-tests:
QUAYDIR: /quay-registry
TEST: 'true'
stages:
- docker_base
- deploy
- docker_build
- docker_base
- unit_tests
- integration
- docker_release
- teardown
stop-preview:
before_script:
- appr login -u $DOCKER_USER -p $DOCKER_PASS quay.io
environment:
action: stop
name: review/${CI_COMMIT_REF_SLUG}
url: https://quay-${CI_COMMIT_REF_SLUG}.k8s.devtable.com
image: quay.io/appr/appr:kubectl
only:
- branches
script:
- 'echo "{\"image\": \"quay.io/quay/quay-ci:${CI_COMMIT_REF_SLUG}\", \"tag\": \"${CI_COMMIT_REF_SLUG}\"}" > params.json'
- cat params.json
- appr remove quay.io/quay/quay-demo-app@1.0.0-${CI_COMMIT_REF_SLUG} --namespace ci-quay-${CI_COMMIT_REF_SLUG} -x docker_user=$DOCKER_USER -x docker_pass=$DOCKER_PASS -x params.json
- kubectl get pods -n ci-quay-${CI_COMMIT_REF_SLUG} -o wide
stage: deploy
tags:
- kubernetes
variables:
GIT_STRATEGY: none
when: manual
unit-tests:
before_script:
- cd $QUAYDIR

View file

@ -35,6 +35,46 @@ function(vars={})
],
},
local appversion = "1.0.0-%s" % vars.images.quayci.tag,
local namespace = "ci-quay-%s" % vars.images.quayci.tag,
QuayDeploy: {
image: "quay.io/appr/appr:kubectl",
when: "manual",
environment: {
name: "review/%s" % vars.images.quayci.tag,
url: "https://quay-%s.k8s.devtable.com" % vars.images.quayci.tag,
},
tags: [
"kubernetes",
],
stage: "deploy",
before_script: [
"appr login -u $DOCKER_USER -p $DOCKER_PASS quay.io",
],
script: [
"cd deploy/quay-demo-app",
"echo -n %s > VERSION" % appversion,
'echo "{\\"image\\": \\"%s\\", \\"tag\\": \\"%s\\"}" > params.json' % [vars.images.quayci.name, vars.images.quayci.tag],
"cat params.json",
"appr push quay.io/quay -f",
"appr deploy quay.io/quay/quay-demo-app@%s --namespace %s -x docker_user=$DOCKER_USER -x docker_pass=$DOCKER_PASS" % [appversion, namespace],
"kubectl get ingresses -n %s -o wide" % namespace,
],
},
QuayDeployStop: self.QuayDeploy {
variables: {GIT_STRATEGY: "none"},
environment+: {
action: "stop"
},
script: [
'echo "{\\"image\\": \\"%s\\", \\"tag\\": \\"%s\\"}" > params.json' % [vars.images.quayci.name, vars.images.quayci.tag],
"cat params.json",
"appr remove quay.io/quay/quay-demo-app@%s --namespace %s -x docker_user=$DOCKER_USER -x docker_pass=$DOCKER_PASS -x params.json" % [appversion, namespace],
"kubectl get pods -n %s -o wide" % namespace,
],
},
dbTest(scheme, image, env):: self.QuayTest {
variables+: {
SKIP_DB_SCHEMA: 'true',

View file

@ -0,0 +1 @@
variables.yaml

View file

@ -0,0 +1,8 @@
postgres/postgres
===========
# Install
kpm deploy postgres/postgres

View file

@ -0,0 +1,29 @@
---
package:
name: quay/postgres-app
author: Antoine Legrand
version: 9.6.1-1
description: postgres
license: MIT
variables:
image: postgres:9.6.1
dbname: quay
user: quay
password: quay
data_volumes:
- name: postgres-data
emptyDir:
medium: ""
resources:
- file: postgres-deployment.yaml
name: postgres
type: deployment
- file: postgres-service.yaml
name: postgres
type: service
deploy:
- name: $self

View file

@ -0,0 +1,46 @@
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: postgres
labels:
k8s-app: postgres
spec:
replicas: 1
selector:
matchLabels:
k8s-app: postgres
template:
metadata:
labels:
k8s-app: postgres
spec:
containers:
- image: {{image}}
name: postgres
env:
- name: POSTGRES_PASSWORD
value: "{{password}}"
- name: PGPASSWORD
value: "{{password}}"
- name: POSTGRES_USER
value: "{{user}}"
- name: POSTGRES_DB
value: "{{dbname}}"
- name: PGDATA
value: /var/lib/postgresql/data/pgdata
ports:
- containerPort: 5432
name: postgres
volumeMounts:
- name: postgres-data
mountPath: /var/lib/postgresql/data
# livenessProbe:
# tcpSocket:
# port: "postgres"
# initialDelaySeconds: 5
# timeoutSeconds: 1
# readinessProbe:
# initialDelaySeconds: 600
# exec:
# command: ["psql", "-h", "localhost", "-U", "postgres"]
volumes: {{data_volumes}}

View file

@ -0,0 +1,14 @@
---
apiVersion: v1
kind: Service
metadata:
labels:
k8s-app: postgres
name: postgres
spec:
type: ClusterIP
ports:
- port: 5432
name: postgres
selector:
k8s-app: postgres

View file

@ -0,0 +1,7 @@
user: quay
password: quay
dbname: quay
data_volumes:
- name: "postgres-data"
persistentVolumeClaim:
claimName: pvc-postgres-master

View file

@ -0,0 +1 @@
stack/

View file

@ -0,0 +1,8 @@
{
name: 'quay/quay-app',
author: 'Antoine Legrand',
version: std.split(importstr "VERSION", "\n")[0],
description: 'quay',
license: 'MIT',
expander: 'jinja2'
}

View file

@ -0,0 +1,9 @@
# Configure
##
- The package reads automatically ./stack/* and use every files there in configuration.
- if a `./stack/config.yaml` exists, the file is merged with the variable `config`.
Config precedence order:
1. Default defined in the package level
2. file content in `stack/*`
3. value variables.stack_files
Except for `config.yaml`, precedence is a strict replacement, for config.yaml is a mergePatch.

View file

@ -0,0 +1,16 @@
local appr = import 'appr.libsonnet';
{
# Read all files in a directory
# @todo(ant31): replace walk by listdir
load_stack_files(path):: (
if appr.path_exists(path)
then {[appr.path.basename(file)]: appr.readfile(file, encode=true) for file in appr.walkdir(path)}
else {}
),
# Create a patch to add/update annotation with a rand value.
# Use to force a Deployment rolling-update
rand_label():: {metadata+: {annotations+: {'resource.appr/rand': appr.randAlphaNum()}}},
}

View file

@ -0,0 +1,155 @@
local appr = import 'appr.libsonnet';
local quaylib = import 'lib/quay.libsonnet';
function(
params={}
)
appr.package({
package: import "Chart.jsonnet",
variables: {
namespace: 'default',
cluster_domain_name: 'cluster.local',
# Minimum configuration
base_config: (import "templates/conf/config.libsonnet")($.variables),
# Additional values stack/config.yaml values
config: {},
# path to the local stack configuration directory
stack_path: "stack",
# load local `stack` directory if exists
stack_files: {
"syslog-ng-extra.conf": appr.b64encode(importstr "templates/conf/syslog-ng-extra.conf")} +
if $.variables.license != null then {"license": appr.b64encode($.variables.license) } else {} +
quaylib.load_stack_files($.variables.stack_path),
# load license
license: null,
# Image tag and repo
tag: $.package.version,
image: 'quay.io/quay/quay:%s' % self.tag,
# Used in the pull secret
docker_user: 'changeme',
docker_pass: 'changeme',
# Redis configuration
redis_host: 'quay-redis.%s.svc.%s:6379' % [$.variables.namespace, $.variables.cluster_domain_name],
redisconf: {redis_parts:: std.split($.variables.redis_host, ":"),
"host": self.redis_parts[0], port: self.redis_parts[1]},
# Configure the ingress with the ingress controller class and domain to use
domain: 'quay.%s.example.com' % $.variables.namespace,
ingress: {
class: 'nginx',
tls: "kubernetes.io/tls-acme",
domains: std.split($.variables.domain, ','),
annotations: {}
},
# Force to reload the secret/configuration
reconfigure: "false",
# Deploy a postgres (don't use it for prod)
deploy_db: 'false',
# Postgres deployment configuratio
db: {
user: 'quay',
password: 'quay',
name: 'quay',
},
# Quay DB_URI
db_uri: 'postgresql://%s:%s@postgres.%s.svc.%s/%s' % [$.variables.db.user,
$.variables.db.password,
$.variables.namespace,
$.variables.cluster_domain_name,
$.variables.db.name],
},
# ServiceAccount to attach Rbac rules
resources: appr.compact([ # + appr.importResourceDir('templates/')
{
value: {apiVersion: 'v1', kind: 'ServiceAccount',
metadata: {name: 'quay-enterprise'}}
},
# Grant secret read/write permission inside the namespace
{
value: (import 'templates/quay-enterprise-role.libsonnet')($.variables),
},
# Bind role to the Service account
{
value: (import 'templates/quay-enterprise-rolebinding.libsonnet')($.variables),
},
# Quay.io robot / user account. Protected from default values
{
value: (import 'templates/quay-enterprise-pullsecret.libsonnet')($.variables),
protected: if $.variables.docker_user == "changeme" || $.variables.docker_pass == "changeme"
then true else false
},
# Quay configuration files (quay/conf/stack), automatically read local the "./stack" directory to load values.
# Values can also be loaded from $.variables.stack_files
# Protected unless explicitly requested (reconfigure == "true").
{
value: (import 'templates/quay-enterprise-secret.libsonnet')($.variables),
protected: if $.variables.reconfigure == "true" then false else true
},
# Quay-registry deployment
# Force a rollout when the secret is reconfigured by updating a label (see randLabel)
{
value: appr.loadObject(appr.jinja2(importstr 'templates/quay-enterprise-app-dp.yaml', $.variables)) +
if $.variables.reconfigure == "true" then
# trigger a rollout
quaylib.rand_label()
else {}
}, # + {value+: if $.variables.reconfigure == "true" then randLabel() else {},},
{
template: (importstr 'templates/quay-enterprise-service.yaml'),
},
# Redis
{
template: (importstr 'templates/quay-enterprise-redis-service.yaml'),
},
{
template: (importstr 'templates/quay-enterprise-redis.yaml'),
},
# Ingress, assumes usage of kube-lego and an ingress controller.
# see variables.ingress for configuration
{
value: (import 'templates/quay-enterprise-ingress.libsonnet')($.variables.ingress),
},
]),
deploy: appr.compact([
if $.variables.deploy_db == 'true' then
{name: 'quay/postgres-app',
variables: {
user: $.variables.db.user,
dbname: $.variables.db.name,
password: $.variables.db.password
}},
{name: '$self'},
]),
}, params)

View file

@ -0,0 +1,53 @@
function(vars)
{
BUILDLOGS_REDIS: vars.redisconf,
USER_EVENTS_REDIS: vars.redisconf,
DB_URI: vars.db_uri,
SETUP_COMPLETE: true,
# Not deployed, features forced turn off
FEATURE_SECURITY_SCANNER: false,
FEATURE_BUILD_SUPPORT: false,
FEATURE_ACI_CONVERSION: false,
FEATURE_GITHUB_BUILD: false,
FEATURE_BITBUCKET_BUILD: false,
FEATURE_GITLAB_BUILD: false,
GITHUB_TRIGGER_CONFIG: null,
GITLAB_TRIGGER_KIND: {},
AUTHENTICATION_TYPE: "Database",
PREFERRED_URL_SCHEME: "https",
SERVER_HOSTNAME: vars.ingress.domains[0],
EXTERNAL_TLS_TERMINATION: true,
INSTANCE_SERVICE_KEY_KID_LOCATION: 'conf/quay.kid',
INSTANCE_SERVICE_KEY_LOCATION: 'conf/quay.pem',
}
# local s3_storage = { local_us: ["S3Storage",
# {storage_path: "",
# s3_access_key: vars.storage.s3.access_key,
# s3_secret_key: vars.storage.s3.secret_key,
# s3_bucket: vars.storage.s3.bucket},
# ]
# };
# extra: {
# REGISTRY_TITLE: "Quay (%s)" % vars.ingress.host,
# REGISTRY_TITLE_SHORT: "Quay (%s)" % vars.ingress.host,
# TESTING: true,
# DEBUGGING: true,
# USE_CDN: false,
# FEATURE_ANONYMOUS_ACCESS: true,
# FEATURE_MAILING: false,
# AUTHENTICATION_TYPE: "Database",
# ENTERPRISE_LOGO_URL: "/static/img/quay-logo.png",
# LOG_ARCHIVE_LOCATION: "default",
# TAG_EXPIRATION_OPTIONS: ["2d"],
# DISTRIBUTED_STORAGE_CONFIG: {
# default: [
# "LocalStorage",
# {storage_path: "/datastorage/registry"}]},
# DISTRIBUTED_STORAGE_DEFAULT_LOCATIONS: [],
# DISTRIBUTED_STORAGE_PREFERENCE: ["default"],
# USERFILES_LOCATION: "default",
# USERFILES_PATH: "userfiles/",
# }
# }

View file

@ -0,0 +1,7 @@
destination d_stdout {
pipe("/dev/stdout");
};
log {
source(s_src); destination(d_stdout);
};

View file

@ -0,0 +1,37 @@
---
apiVersion: batch/v1
kind: Job
metadata:
name: quay-dev-initdb
spec:
activeDeadlineSeconds: 100
template:
metadata:
name: quay-dev-initdb
spec:
containers:
- name: quay
image: quay.io/quay/quay-ci:master
env:
- name: TEST_DATABASE_URI
value: "postgres://"
- name: SKIP_DB_SCHEMA
value: "true"
command:
- venv/bin/python
- initdb.py
volumeMounts:
- name: configvolume
readOnly: false
mountPath: /conf/stack
resources:
limits:
cpu: 500m
memory: 500Mi
imagePullSecrets:
- name: coreos-pull-secret
volumes:
- name: configvolume
secret:
secretName: quay-enterprise-config-secret
restartPolicy: Never

View file

@ -0,0 +1,55 @@
---
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
namespace: quay-enterprise
name: quay-enterprise-app
labels:
quay-enterprise-component: app
spec:
replicas: 1
template:
metadata:
labels:
quay-enterprise-component: app
spec:
serviceAccountName: "quay-enterprise"
containers:
- name: quay-enterprise-app
livenessProbe:
httpGet:
path: /status
port: 80
initialDelaySeconds: 300
periodSeconds: 30
failureThreshold: 3
successThreshold: 1
readinessProbe:
httpGet:
path: /status
port: 80
initialDelaySeconds: 45
failureThreshold: 6
periodSeconds: 20
env:
- name: QE_K8S_NAMESPACE
valueFrom:
fieldRef:
fieldPath: metadata.namespace
image: {{image}}
ports:
- containerPort: 80
volumeMounts:
- name: configvolume
readOnly: false
mountPath: /conf/stack
resources:
limits:
cpu: 1
memory: 2Gi
imagePullSecrets:
- name: coreos-pull-secret
volumes:
- name: configvolume
secret:
secretName: quay-enterprise-config-secret

View file

@ -0,0 +1,31 @@
function(ingress={ class: 'none', tls: "true", domains: ['quay.example.com'] })
{
apiVersion: "extensions/v1beta1",
kind: "Ingress",
metadata: {
annotations: {
"kubernetes.io/ingress.class": ingress.class,
[if std.type(ingress.tls) == "string" then ingress.tls]: "true"} +
if std.objectHas(ingress, "annotations") then ingress.annotations else {},
name: "quay-enterprise",
},
spec: {
rules: [{
host: domain,
http: {
paths: [{
backend: {
serviceName: "quay-enterprise",
servicePort: 80,},
path: "/"}]},
} for domain in ingress.domains],
} +
if std.type(ingress.tls) == "string" then
{tls: [{
hosts: ingress.domains,
secretName: "quay-enterprise-tls",
}]} else {},
}

View file

@ -0,0 +1,14 @@
local appr = import "appr.libsonnet";
function(variables={})
{
local docker_login = [variables.docker_user, variables.docker_pass],
data: {
".dockercfg": appr.b64encode('{"quay.io": {"username": "%s", "password": "%s","email":"toto@toto.com","auth": "%s"}}' % (docker_login + [appr.b64encode("%s:%s" % docker_login)])),
},
kind: "Secret",
metadata: {
name: "coreos-pull-secret",
},
type: "kubernetes.io/dockercfg"
}

View file

@ -0,0 +1,13 @@
apiVersion: v1
kind: Service
metadata:
namespace: quay-redis
name: quay-redis
spec:
type: ClusterIP
ports:
- protocol: TCP
port: 6379
targetPort: 6379
selector:
quay-enterprise-component: redis

View file

@ -0,0 +1,24 @@
---
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
namespace: quay-enterprise
name: quay-enterprise-redis
labels:
quay-enterprise-component: redis
spec:
replicas: 1
template:
metadata:
labels:
quay-enterprise-component: redis
spec:
containers:
- name: redis-master
image: quay.io/quay/redis
ports:
- containerPort: 6379
resources:
limits:
cpu: 100m
memory: 500Mi

View file

@ -0,0 +1,21 @@
local appr = import "appr.libsonnet";
function(vars={})
{
kind: "Role",
apiVersion: 'rbac.authorization.k8s.io/v1beta1',
metadata: {
name: "quay-enterprise",
},
rules: [
{
apiGroups: [""],
resources: ["secrets"],
verbs: ["get", "update", "patch"],
},
{
apiGroups: [""],
resources: ["namespaces"],
verbs: ["get"],
},
],
}

View file

@ -0,0 +1,21 @@
function(vars={})
{
apiVersion: "rbac.authorization.k8s.io/v1beta1",
kind: "RoleBinding",
metadata: {
name: "quay-enterprise-binding",
namespace: vars.namespace,
},
roleRef: {
apiGroup: "rbac.authorization.k8s.io",
kind: "Role",
name: "quay-enterprise",
},
subjects: [
{
kind: "ServiceAccount",
name: "quay-enterprise",
namespace: vars.namespace,
}
]
}

View file

@ -0,0 +1,34 @@
local appr = import "appr.libsonnet";
local b64e = appr.b64decode;
function(vars={})
# Deserialize config.yaml if exists
local local_stack_config = (
local confpath = "config.yaml";
if std.objectHasAll(vars.stack_files, confpath)
then appr.loadObject(appr.b64decode(vars.stack_files[confpath]))
else {}
);
# Merge all config together
# Precedence: package-config (vars.config) < local stack/config.yaml < base-config (vars.base-config)
local config_yaml = {'config.yaml': appr.b64encode(appr.to_yaml(
vars.config +
local_stack_config +
vars.base_config))};
# Merge stack files
local stack_files = vars.stack_files + config_yaml;
{
apiVersion: "v1",
kind: "Secret",
metadata: {
namespace: "quay-enterprise",
name: "quay-enterprise-config-secret"},
# base64 encode all files
data: { [file]: stack_files[file]
for file in std.objectFields(stack_files) if stack_files[file] != null}
}

View file

@ -0,0 +1,13 @@
apiVersion: v1
kind: Service
metadata:
namespace: quay-enterprise
name: quay-enterprise
spec:
type: ClusterIP
ports:
- protocol: TCP
port: 80
targetPort: 80
selector:
quay-enterprise-component: app

View file

@ -0,0 +1,8 @@
quay/quay
===========
# Install
kpm deploy quay/quay

View file

@ -0,0 +1 @@
2.4.0-1

View file

@ -0,0 +1,176 @@
---
# Uncomment to use a real mysql db running in docker
# DB_URI: mysql+pymysql://root:password@192.168.59.103/quay
# DB_CONNECTION_ARGS:
# threadlocals: true
# autorollback: true
SECRET_KEY: a36c9d7d-25a9-4d3f-a586-3d2f8dc40a83
REGISTRY_TITLE: Quay.io (local)
REGISTRY_TITLE_SHORT: Quay.io (local)
GITHUB_LOGIN_CONFIG:
GITHUB_ENDPOINT: https://github.com/
API_ENDPOINT: https://api.github.com/
CLIENT_ID: 0e8dbe15c4c7630b5480
CLIENT_SECRET: d4a58ddd3dbe08b7fec109e85564a0d153d3e256
ORG_RESTRICT: true
ALLOWED_ORGANIZATIONS:
- DevTables
- cOREOS
#GITHUB_LOGIN_CONFIG:
# GITHUB_ENDPOINT: http://192.168.59.104
# CLIENT_ID: dc6468ad8690e5aad485
# CLIENT_SECRET: 78ed1f22b1cce0aafbe363b7cb38258874dbdca6
GITHUB_TRIGGER_CONFIG:
GITHUB_ENDPOINT: https://github.com/
API_ENDPOINT: https://api.github.com/
CLIENT_ID: cfbc4aca88e5c1b40679
CLIENT_SECRET: 334cd66a7868259697726e2a1980c6869dbdef49
GOOGLE_LOGIN_CONFIG:
CLIENT_ID: 342710155188-onh8ko4uge0mu4odl4vchios4m92ncuu.apps.googleusercontent.com
CLIENT_SECRET: PWgfDNB0RAP4Nrqu9pZT37n9
BITBUCKET_TRIGGER_CONFIG:
CONSUMER_KEY: xKcfYn9tjKTq8pELgp
CONSUMER_SECRET: E6ewPUDwvFxY7HUPUsGpMvXHPKDkR8Ur
GITLAB_TRIGGER_CONFIG:
GITLAB_ENDPOINT: https://gitlab.com
CLIENT_ID: 5f12a8b50aafcf9f3dc1394eeb00d1ccb217d07f0c7f85bb9cb3ffb2d836043f
CLIENT_SECRET: f8dd18718bd2cbd35196eaca62ae56785d947ddd45fbcd7963353c25fcc27ea3
FEATURE_BILLING: true
BILLING_TYPE: Stripe
STRIPE_SECRET_KEY: sk_test_PEbmJCYrLXPW0VRLSnWUiZ7Y
STRIPE_PUBLISHABLE_KEY: pk_test_uEDHANKm9CHCvVa2DLcipGRh
MAIL_SERVER: email-smtp.us-east-1.amazonaws.com
MAIL_USE_TLS: true
MAIL_PORT: 587
MAIL_USERNAME: AKIAIXV5SDGCPVMU3N4Q
MAIL_PASSWORD: AhmX/vWE91uQ2RtcEKTkfNrzZehEjPNXOXeOXgQNfLao
MAIL_DEFAULT_SENDER: support@quay.io
MAIL_FAIL_SILENTLY: false
AVATAR_KIND: gravatar
TESTING: false
DEBUGGING: true
USE_CDN: true
# Feature Flag: Whether to display the support chat.
FEATURE_SUPPORT_CHAT: true
# Feature Flag: Whether GitHub login is supported.
FEATURE_GITHUB_LOGIN: true
# Feature Flag: Whether Google login is supported.
FEATURE_GOOGLE_LOGIN: true
# Analytics
ANALYTICS_TYPE: Mixpanel
MIXPANEL_KEY: 38014a0f27e7bdc3ff8cc7cc29c869f9
# Uncomment this to enable Marketo for dev
# USER_ANALYTICS_TYPE: Marketo
# MARKETO_MUNCHKIN_ID: 231-DAD-511
# MARKETO_MUNCHKIN_PRIVATE_KEY: corechella16!
# MARKETO_CLIENT_ID: 873e9474-367c-42ee-9f53-af43d895c956
# MARKETO_CLIENT_SECRET: qqvYC1slFvEJkiye5X3J8fsgEKMu8Dlt
# MARKETO_LEAD_SOURCE: Quay Hosted - Test
# Build logs
BUILDLOGS_REDIS:
host: 192.168.59.103
BUILDLOGS_OPTIONS:
- devtable
- building
- deadbeef-dead-beef-dead-beefdeadbeef
- true
BUILDLOGS_MODULE_AND_CLASS:
- test.testlogs
- testlogs.TestBuildLogs
# User events
USER_EVENTS_REDIS:
host: 192.168.59.103
FEATURE_GITHUB_BUILD: true
FEATURE_BITBUCKET_BUILD: true
FEATURE_GITLAB_BUILD: true
FEATURE_SUPER_USERS: true
SUPER_USERS:
- devtable
SIGNING_ENGINE: gpg2
GPG2_PRIVATE_KEY_NAME: EEB32221
GPG2_PRIVATE_KEY_FILENAME: signing-private.gpg
GPG2_PUBLIC_KEY_FILENAME: signing-public.gpg
FEATURE_ACI_CONVERSION: true
SETUP_COMPLETE: true
# Uncomment to test LDAP.
# Information: http://www.forumsys.com/tutorials/integration-how-to/ldap/online-ldap-test-server/
# AUTHENTICATION_TYPE: 'LDAP'
# LDAP_URI: 'ldap://ldap.forumsys.com'
# LDAP_BASE_DN: ['dc=example', 'dc=com']
# LDAP_ADMIN_DN: 'cn=read-only-admin,dc=example,dc=com'
# LDAP_ADMIN_PASSWD: 'password'
# LDAP_USER_RDN: []
# Uncomment to test S3 Uploads to an ephemeral bucket
# DISTRIBUTED_STORAGE_CONFIG:
# local_us:
# - S3Storage
# - storage_path: ""
# s3_access_key: AKIAJDF3UKLGZJ7RLJ2A
# s3_secret_key: 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
# s3_bucket: quay-registry-test
# Uncomment to test swift storage
# DISTRIBUTED_STORAGE_CONFIG:
# local_us:
# - SwiftStorage
# - swift_container: container_name
# storage_path: /datastorage/registry
# auth_url: http://192.168.59.103:32768/auth/v1.0
# swift_user: test:tester
# swift_password: testing
# auth_version: 1
# simple_path_concat: true
#FEATURE_ANONYMOUS_ACCESS: False
# CloudWatch AWS Keys
#CLOUDWATCH_AWS_ACCESS_KEY: AKIAJUSUTJ3TGBAC2LMQ
#CLOUDWATCH_AWS_SECRET_KEY: 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
#CLOUDWATCH_NAMESPACE: Quay/Local
# Security scanner
FEATURE_SECURITY_SCANNER: true
FEATURE_SECURITY_NOTIFICATIONS: true
SECURITY_SCANNER:
ENDPOINT: https://192.168.99.100:6060
ENGINE_VERSION_TARGET: 1
API_VERSION: v1
API_TIMEOUT_SECONDS: 10
INSTANCE_SERVICE_KEY_KID_LOCATION: 'conf/stack/quay.kid'
INSTANCE_SERVICE_KEY_LOCATION: 'conf/stack/quay.pem'
PROMETHEUS_AGGREGATOR_URL: null
STAGGER_WORKERS: false
STATIC_SITE_BUCKET: 'https://s3.amazonaws.com/prod-s3.quay.io/'
FEATURE_APP_REGISTRY: true

View file

@ -0,0 +1 @@
eyJhbGciOiJSUzI1NiJ9.eyJzY2hlbWFWZXJzaW9uIjoidjIiLCJ2ZXJzaW9uIjoiMjciLCJjcmVhdGlvbkRhdGUiOiIyMDE2LTEwLTI1VDAwOjA2OjQzWiIsImV4cGlyYXRpb25EYXRlIjoiMjAxNy0xMC0yNVQwMDowNjo0M1oiLCJsaWNlbnNlIjoie1wic2NoZW1hVmVyc2lvblwiOlwidjJcIixcInZlcnNpb25cIjpcIjI3XCIsXCJhY2NvdW50SURcIjpcIkFDQy02ODY0N0FCRC03REI3LTQ4QzItQjZDNS0yMjEzOEQ5RFwiLFwiYWNjb3VudFNlY3JldFwiOlwiMGIyMjk4ZTAtZDRmOC00M2M4LTk3NDUtNjY5Y2I2NDc2MzA5XCIsXCJjcmVhdGlvbkRhdGVcIjpcIjIwMTYtMTAtMjVUMDA6MDY6NDMuMTgzMzIzWlwiLFwiZXhwaXJhdGlvbkRhdGVcIjpcIjIwMTctMTAtMjVUMDA6MDY6NDMuMTgzMzIzWlwiLFwic3Vic2NyaXB0aW9uc1wiOntcIlNVQi0yMkVDRjk4RS00QUVFLTQzNjktODgwQy0zMjg3ODEyM1wiOntcInBsYW5OYW1lXCI6XCJ0ZWN0b25pYy1lbnRlcnByaXNlLXBvY1wiLFwicHVibGljUGxhbk5hbWVcIjpcIlRlY3RvbmljIEVudGVycHJpc2UgUE9DXCIsXCJwbGFuSURcIjpcIlBSUC1EMzkwN0ZDQS1FM0ExLTQxNUEtQUJBRS1CNEEwMkI1OVwiLFwicHJvZHVjdE5hbWVcIjpcInRlY3RvbmljLWVudGVycHJpc2VcIixcInB1YmxpY1Byb2R1Y3ROYW1lXCI6XCJUZWN0b25pYyBFbnRlcnByaXNlXCIsXCJwcm9kdWN0SURcIjpcIlBSTy04NDU4RUJGRS00NDZDLTQwQUUtQjU3OC1DQjU1QUMyN1wiLFwic2VydmljZVN0YXJ0XCI6XCIyMDE2LTA0LTIwVDIwOjQ0OjAwWlwiLFwic2VydmljZUVuZFwiOlwiMjAxNy0wNC0yMFQyMDo0NDowMFpcIixcImluVHJpYWxcIjpmYWxzZSxcInRyaWFsT25seVwiOmZhbHNlLFwiZHVyYXRpb25cIjo2MCxcImR1cmF0aW9uUGVyaW9kXCI6XCJkYXlzXCIsXCJlbnRpdGxlbWVudHNcIjp7XCJzb2Z0d2FyZS5jb3JldXBkYXRlXCI6MSxcInNvZnR3YXJlLnF1YXlcIjoxLFwic29mdHdhcmUucXVheS5idWlsZGVyc1wiOjk5OTksXCJzb2Z0d2FyZS5xdWF5LmRlcGxveW1lbnRzXCI6MSxcInNvZnR3YXJlLnF1YXkucmVnaW9uc1wiOjEsXCJzb2Z0d2FyZS50ZWN0b25pY1wiOjEsXCJzb2Z0d2FyZS50ZWN0b25pYy5yYW1cIjoxMDI0LFwic3VwcG9ydC5jb3Jlb3NsaW51eC5wcmVtaXVtXCI6MSxcInN1cHBvcnQuY29yZXVwZGF0ZS5wcmVtaXVtXCI6MSxcInN1cHBvcnQucXVheS5wcmVtaXVtXCI6MSxcInN1cHBvcnQudGVjdG9uaWMucHJlbWl1bVwiOjF9fSxcIlNVQi00NjI3QjRDOC0zOUU3LTQ5QTQtODFCRS01OEQ0MUM1NlwiOntcInBsYW5OYW1lXCI6XCJ0ZWN0b25pYy1zdGFydGVyXCIsXCJwdWJsaWNQbGFuTmFtZVwiOlwiVGVjdG9uaWMgU3RhcnRlciBQbGFuXCIsXCJwbGFuSURcIjpcIlBSUC1DNEE0MEQ1NS1CODVGLTREQTAtQTVCNS1BMzQ1QkEwNlwiLFwicHJvZHVjdE5hbWVcIjpcInRlY3RvbmljLXN0YXJ0ZXJcIixcInB1YmxpY1Byb2R1Y3ROYW1lXCI6XCJUZWN0b25pYyBTdGFydGVyXCIsXCJwcm9kdWN0SURcIjpcIlBSTy01ODk0QTE4Qy1FQTIxLTRFRTctOTc3My1COUI2MDBBNVwiLFwic2VydmljZVN0YXJ0XCI6XCIyMDE2LTEwLTAyVDE3OjAxOjM4WlwiLFwic2VydmljZUVuZFwiOlwiMjAxNi0xMS0wMlQxNzowMTozOFpcIixcImluVHJpYWxcIjpmYWxzZSxcInRyaWFsT25seVwiOmZhbHNlLFwiZHVyYXRpb25cIjoxLFwiZHVyYXRpb25QZXJpb2RcIjpcIm1vbnRoc1wiLFwiZW50aXRsZW1lbnRzXCI6e1wiY29zdFwiOjEsXCJzb2Z0d2FyZS50ZWN0b25pY2NvbnNvbGVcIjoxfX0sXCJTVUItOUIxRTA2RTMtMkEyMC00M0E5LTlFQUMtRDJCODEwN0JcIjp7XCJwbGFuTmFtZVwiOlwicHJlbWl1bS1jdXN0b21cIixcInB1YmxpY1BsYW5OYW1lXCI6XCJQcmVtaXVtIC0gQ3VzdG9tXCIsXCJwbGFuSURcIjpcIlBSUC05NjRBQUM4Qi01NjhBLTQwMEMtOTEzQS1CMzQ2NDRGRVwiLFwicHJvZHVjdE5hbWVcIjpcInF1YXktZW50ZXJwcmlzZVwiLFwicHVibGljUHJvZHVjdE5hbWVcIjpcIlF1YXkgRW50ZXJwcmlzZVwiLFwicHJvZHVjdElEXCI6XCJQUk8tNDNFNEQ4QTYtOEQ1MS00NDZFLUIyNjMtRDBBNjVDOUZcIixcInNlcnZpY2VTdGFydFwiOlwiMjAxNi0xMC0xM1QxODowOTowMFpcIixcInNlcnZpY2VFbmRcIjpcIjIwMTctMTAtMTNUMTg6MDk6MDBaXCIsXCJpblRyaWFsXCI6ZmFsc2UsXCJ0cmlhbE9ubHlcIjpmYWxzZSxcImR1cmF0aW9uXCI6MSxcImR1cmF0aW9uUGVyaW9kXCI6XCJ5ZWFyc1wiLFwiZW50aXRsZW1lbnRzXCI6e1wiY29zdFwiOjAsXCJzb2Z0d2FyZS5xdWF5XCI6MSxcInNvZnR3YXJlLnF1YXkuYnVpbGRlcnNcIjo5OTk5OTksXCJzb2Z0d2FyZS5xdWF5LmRlcGxveW1lbnRzXCI6MSxcInNvZnR3YXJlLnF1YXkucmVnaW9uc1wiOjEsXCJzdXBwb3J0LnF1YXkucHJlbWl1bVwiOjF9fSxcIlNVQi1ERjAwNTdENC1CMEEwLTRFQjktOTQ0QS05RTAzQzZCQ1wiOntcInBsYW5OYW1lXCI6XCJxdWF5LWVudGVycHJpc2UtYW5udWFsLWN1c3RvbVwiLFwicHVibGljUGxhbk5hbWVcIjpcIlF1YXkgRW50ZXJwcmlzZVwiLFwicGxhbklEXCI6XCJQUlAtQzNFNkU5NTktMkZGRi00QkI3LTgxMjItRDNFOTdFNkFcIixcInByb2R1Y3ROYW1lXCI6XCJxdWF5LWVudGVycHJpc2VcIixcInB1YmxpY1Byb2R1Y3ROYW1lXCI6XCJRdWF5IEVudGVycHJpc2VcIixcInByb2R1Y3RJRFwiOlwiUFJPLTQzRTREOEE2LThENTEtNDQ2RS1CMjYzLUQwQTY1QzlGXCIsXCJzZXJ2aWNlU3RhcnRcIjpcIjIwMTYtMTAtMjVUMDA6MDU6MDBaXCIsXCJzZXJ2aWNlRW5kXCI6XCIyMDE3LTEwLTI0VDAwOjA1OjAwWlwiLFwiaW5UcmlhbFwiOmZhbHNlLFwidHJpYWxPbmx5XCI6ZmFsc2UsXCJkdXJhdGlvblwiOjEsXCJkdXJhdGlvblBlcmlvZFwiOlwieWVhcnNcIixcImVudGl0bGVtZW50c1wiOntcImNvc3RcIjowLFwic29mdHdhcmUucXVheVwiOjEsXCJzb2Z0d2FyZS5xdWF5LmRlcGxveW1lbnRzXCI6OTk5OTk5LFwic3VwcG9ydC5xdWF5LnByZW1pdW1cIjoxfX19fSJ9.XwPbWiyIthfXKhKj5YEO76kCErEmRyjIK5wMhRz8d6bC7spROyrNC0aikP7UuGOA94I-ZdL-bnrrD8Ijc4hNzvA5SwglmBoJ7uYsqm492DNf3AimXPBX8aMolfjvnBVWs4UaCbzwX2ow95GVPxz6M8DdgypzuPWahpR12jkQ63Ryc6jnDh_9DmtUrQXy0y2xcZmRGsgBMQoC9kJANOQ0jmbAuhhZCG15mTmsEC4S12RnJy7wP_tfYoGikRe01FW-_GsRpPV5BXqP55cSR17PvTGsg3l_dNtmKDa_hrhk3F9u2DNE3h-onbezYUa5J4szJfnZU9hcSK0GurpK4H34Sw

View file

@ -0,0 +1,27 @@
-----BEGIN RSA PRIVATE KEY-----
MIIEogIBAAKCAQEAwJYjuXSCqTAEdSz2lv7GtkT2dXkwTS+wE8sj0+k8QEBK8xQb
gkaDGzXSn22mAO2e5cND8wWj8sWeplOFqa7LA/kU+AA/HGV04xrS122yCRJ2D49J
k9gn8RJv7fnzSahK3v+ZhKeXWaPtA+kwl4u3AkEYiG6w38+vl4HCcg3GFY64iaRw
Us2vRs3OaaCS0vkJ2sgZAAl5x5Tke+FKOC3ubqojDs5g2hfLT5QMIpj158YdKNaP
sztRBzh8Dm6mt8UsHECDde2e4VZwlx3ebEoQCcfsY8s5i6OyUphprZYr0P2/E0qM
7dvhbGOBN4eAw2ZJ3el33anQCdWnFzS4gycpawIDAQABAoIBAGjd2FoVzUgfM24y
q5uQ49dAOgvBj8GX5AMDLGEpsXszBxzRqCEKED3y0tupMylyOoHWD9v3CE0busXK
2Q+KdFWXfgmE6NinjjxT0NcpjjZObScP2Pq+SxGD/prQ7d7/2rUO7SNEtq9DCb6F
bcY3d9GsbJVt4LYeOvj+2UiNo3z8pixIVIYBEIAJbiFUf8ImNy18aI2YsgcIKKx3
XRcZrQc3lJQO4SgzLEflovl11B8Nvw5XXwXaFn35wmp31L5CtKlPeDT6CDNydTqw
T2ri0xPu4vyvuVidDcVJOh3Bpw5FSI9fwBr9PDjOLi2YgjRtQBQhnvvtPpk7vSeU
bVhNN4ECgYEA5C5v1AHURu5tRj7o9I0Po2DLpt1zszd2ly7ED190Ko9qmZqfTyLz
uBzSk86r2+NMxPhp+uMY2LR0c6LiPAbSVpTOSWL2eatfy/9td9TlK5fVcg6N9vH5
LYrzuelxSnypm6H300t6CvycrfrscOP4Vs2fdx1yZI0wEngTxL5+sgsCgYEA2BDI
OY+eJ53KRVEp5stbUryW7HJC6HBlH2ZHeMCLese6fsvdTyhL0/2OanXdxG3bOK6F
Ilr3UzTK1Krj7U8W0zRnGMVJfaMoEJOwgBtUqm7rjksP2bujRT9OuLKR+MJbLVLC
0ycoS8iOJWCDIczeL21rgqe1pOp839It/MI+YiECgYBZi9u48IrU10as9Y1IQ39q
l1b0gh2grFhu1hx9B/G3rhagdyyjysyoaS8+cDHDlj0PY4l7utmKWa8Fnlt4QRkU
f0tBQ4QElXt/vBrClxrkc66BFzMhQS6Pb+NcBz+9gpSxDewK0KjxXNdD86AMYXqY
3hMBlN3KlhnSdasUX8mqpwKBgDmAFdkDuIIwguD5nZ4XJmGZYMziB55WMwMtM/4V
t8jgGGigFnB3d96dzuXUIkWhOsMV5sZi0QkqtoPsSqYf8yIYAwvbjRhLcGEg/MrK
+zg0NqnynfBC+Et4cpnCpAhAqQUhzkllVVr9r56Q1bUMEWErzH3D5hpScRMbmzN1
+iYhAoGACxsSOXRHUMOC3tdcErAsfjc04v13MuuiglH29Ap5e/WoGcr++fCWBnCD
9IGnHZvY+th/vkuaefZqE6oDYMa4TvyJJnU/tx+h1+jbuCwpdqGkKp9z0xjIvUJ5
L6imBl4Dwl5DjJLL1HhbzF3C7DHWTbHsRF/HWwNjbV9nCIii4AY=
-----END RSA PRIVATE KEY-----

View file

@ -0,0 +1 @@
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDAliO5dIKpMAR1LPaW/sa2RPZ1eTBNL7ATyyPT6TxAQErzFBuCRoMbNdKfbaYA7Z7lw0PzBaPyxZ6mU4WprssD+RT4AD8cZXTjGtLXbbIJEnYPj0mT2CfxEm/t+fNJqEre/5mEp5dZo+0D6TCXi7cCQRiIbrDfz6+XgcJyDcYVjriJpHBSza9Gzc5poJLS+QnayBkACXnHlOR74Uo4Le5uqiMOzmDaF8tPlAwimPXnxh0o1o+zO1EHOHwObqa3xSwcQIN17Z7hVnCXHd5sShAJx+xjyzmLo7JSmGmtlivQ/b8TSozt2+FsY4E3h4DDZknd6XfdqdAJ1acXNLiDJylr jake@coreserver

View file

@ -0,0 +1,20 @@
-----BEGIN CERTIFICATE-----
MIIDVDCCAjwCCQDNYtlT1+tGbzANBgkqhkiG9w0BAQUFADBsMQswCQYDVQQGEwJV
UzERMA8GA1UECBMITmV3IFlvcmsxETAPBgNVBAcTCE5ldyBZb3JrMRQwEgYDVQQK
EwtDb3JlT1MsIEluYzENMAsGA1UECxMEUXVheTESMBAGA1UEAxMJMTI3LjAuMC4x
MB4XDTE2MDUyMzE1MjUxOVoXDTI2MDUyMTE1MjUxOVowbDELMAkGA1UEBhMCVVMx
ETAPBgNVBAgTCE5ldyBZb3JrMREwDwYDVQQHEwhOZXcgWW9yazEUMBIGA1UEChML
Q29yZU9TLCBJbmMxDTALBgNVBAsTBFF1YXkxEjAQBgNVBAMTCTEyNy4wLjAuMTCC
ASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKRvOt/XGNIovlr1BWxl2oqs
KDlgnESj6bFENDjs9+YLrB3mSWX6w4Dk2IdNU0EKHeVnnsAuBs83jaFsIVJxrC99
ndv0PaejBovUbWyYN3zCMur8iNGse/FT4WRqks2m0Wr0jmEAX5piX/eWo/7OQdea
wNAGyH7wE0voMpyVSZMBmxRw07zWnwWBihvhOiiCnXZh32GQMplq0wxk4DkBf3hC
SEaAqsFHKfEFPxVXfdPGeiKKK+P2SAh+uN4miJpGf7Xkuj/Mmzxr1ajNczhPT6OM
pw0R3h/mok1S8zcp8lN/eDdKwjMeP4Rx+Lc0cRluZNa8otq9qYPNSCIkvsSz5b8C
AwEAATANBgkqhkiG9w0BAQUFAAOCAQEAZaaD8fLWEh4RGZ7X38IM/ocwDKaXWpDp
0EC3KMEuar1MET3MtVIXy/k/BLr0HmLRQ2KSV3wFfyOInseVeCvIcKZZo/JF28gR
LJVBcjExSIr6X8RoPgmKt7AdjlUjPV5XpRzDpfYcMaqpjJa75x6RoxC2ybh5Apyk
EzL3Naysk6TVPi5ckUYMLfw3JEbCeaEY4KNwVgsNcs447EcBxwGHTBqGOYtpIfku
SMas81oniMo9LMKv19Bn1oOforaqh8P2c57yregDsCDmP6j0gqkYjhJFCj5JNAKK
KT35QIfTbVFeCXAoLw0+o9Ma1Q+j7LfwdxnikUHNVZmlmjQmTBMwqg==
-----END CERTIFICATE-----

View file

@ -0,0 +1,27 @@
-----BEGIN RSA PRIVATE KEY-----
MIIEowIBAAKCAQEApG8639cY0ii+WvUFbGXaiqwoOWCcRKPpsUQ0OOz35gusHeZJ
ZfrDgOTYh01TQQod5WeewC4GzzeNoWwhUnGsL32d2/Q9p6MGi9RtbJg3fMIy6vyI
0ax78VPhZGqSzabRavSOYQBfmmJf95aj/s5B15rA0AbIfvATS+gynJVJkwGbFHDT
vNafBYGKG+E6KIKddmHfYZAymWrTDGTgOQF/eEJIRoCqwUcp8QU/FVd908Z6Ioor
4/ZICH643iaImkZ/teS6P8ybPGvVqM1zOE9Po4ynDRHeH+aiTVLzNynyU394N0rC
Mx4/hHH4tzRxGW5k1ryi2r2pg81IIiS+xLPlvwIDAQABAoIBAANdV0oPP63FMafw
zYybRO6DeUs7Q9dPt09uQtdLWgM2B+6QsL3KdMelZxzVozd4eoYgKaprBq6kx1wf
N0tVkh1ip6FBjSVp+49O6HJJZxFBdANE6ZPIwLx+Z+VDHP/iQvS6TlODy3EARFBv
n6luFQDRZNKc4OtgBDUQakCz+U5tuJLqoR8wk/WGQP4FJiZlVwJqNPXMA1A2Mrri
n6WkhfpB30Z5dl9zsR+zJRbwRBjgJCYN37YC7zdHRfIhBPBvDT+8ApR50BGvPGN3
sLQuH2FsskbgPsIrWMfCxtWr2xbw028GOe7TSjEG63EG7oGAT0O2eQmAcuPc4Dqj
Urn8saECgYEA2LkCe6MysmOtattC/gi3B/rIoOCd+4l9yTnW7S7nk/hdeOzxyqX1
P7OgVeoYLLk3UJy3qTrNDnc0eGTJz0XyPhLlX0f9lduiSMH92XpNsBG7ngnyMCQF
eAZz8ZlDZC39I8y9CzdcHSLxuHKmQ9jhgUm+EIuf8OlrkjchPdE06i8CgYEAwjxG
cDA5X1hKYgQTObq245vR3txkvETmLVB7hWkjWLzR//a4hXHJT1fg2LxD5EMtCKZ2
WXKhcy3tbja+c/IEI1L1wA2v/aWlEvi9n354EQ1QzkvCBDFP5enLnItAUzJQ0IgE
dtSUskK+li8aY2LB0EPt0eJmYU0cZUJXbl/ZKXECgYAAtttjPO512A5CQ+a8n5q6
1ADFRvg+U/2uJBqpPXZV7oOgWmeRm2prg1QL9HGP9CxSf7G7RQ5X9dyeaPahUEG0
IqvO3JXhYI/wXXNQvC51XhmYM8AwmG3ML3lCWpb2RZCIBay51Lzg+7SAPyB9KMHV
g0C1HUCxspNAMB5T7dSW0QKBgGkxRaCarWeypE4jENpyAXyRNf8xcyj3U4V1EgB1
qVv0nvK2BsbWkgTzfeVDSK2FqA0IQg49Y6zCUdUfttOKXa1Xz5ocj5SaMiVtKx0G
3DW39WxUYRXuMuw8SzZTwBmOpW/aSjik9ob4WMlzZyIuKPMG5vSFXZcSsO8yF7HC
HRUxAoGBAKtCRLT9I5Ap37gWT8W6AAZygoUqhlYO9qygQrBDaJsHj0ZSHM0TO3ig
Bwq/UxDHBKFV3hmqx5Zmpoa9ZrURb4cBw/+TLq2ppXPLEU+XmEVmqL2323Vyr/Ih
CAIVWFsY3EGQL7TArOfag+v0Nxq3pypOhjweqIWEMDg+gV2+GHhQ
-----END RSA PRIVATE KEY-----

Binary file not shown.

View file

@ -0,0 +1,19 @@
-----BEGIN PGP PUBLIC KEY BLOCK-----
Version: GnuPG v2
mQENBFTVMzABCAC8jcnCrNHKk0LgyZTdTFtf9Qm2bK27Y0EyyI8tWefUt4LhQRCA
14dksJVzqWBtpHJnqkYUwfoXZmdz4e9fSS1mmoiHlDwzkuNXx2J1HAnXSxgNMV1D
JQmfxhKQzFTgkTEN03txPZrOMrDNIZSw0gkAbiBGuQXk9/HNGbzdjkd3vk1GF7Vk
v1vITmWQG+QQi7H8zR1NYYuFQb5cdDDuOoQWHXNMIZmK27StZ6MUot3NlquZbs1q
5Gr1HHog0qx+0uYn441zghZ9R1JqaAig0V3eJ8UAbTIMZPO09UUBQKC7O7OgOX/H
92zGWGwkTMUqJNJUr/dj5ocQbpFk8X3yz+d9ABEBAAG0RFF1YXkuaW8gQUNJIENv
bnZlcnRlciAoQUNJIGNvbnZlcnNpb24gc2lnbmluZyBrZXkpIDxzdXBwb3J0QHF1
YXkuaW8+iQE5BBMBAgAjBQJU1TMwAhsDBwsJCAcDAgEGFQgCCQoLBBYCAwECHgEC
F4AACgkQRjIEfu6zIiHo9Af+MCE4bUOrQ6yrHSPHebHwSARULaTB0Rlj4BAXlv+A
nUJDaaYaYExo8SHZMWF5X4d4mh57DJOsIXMjIWNKpf9/0hpxRu+P8p77YtXOOeRS
3xFdq7cOK1yQ8h/iRoXyLaxAFgWvVH+Ttmx4DLr+NsyzEQBjADeBCcF4YR9OZ7fj
ZYsoq68hH0W7zgZTSrCgvyGxdpu+UWWk/eV/foktxKBMV8K2GmAwyOlsAm59PgUI
EhfFH0WAEx6+jsMFLkn7USPWomFeyMwJJEiMKYCwALWIbNz1/1dtrZZs2QmBcjAu
AMFQhx8fykH4ON8a6fpS3TOEzf0HV1NX295O8wb8vS9B7w==
=aImY
-----END PGP PUBLIC KEY BLOCK-----

View file

@ -0,0 +1,66 @@
local appr = import "appr.libsonnet";
function(
params={}
)
appr.package({
package: {
name: "quay/quay-ci-app",
author: "Antoine Legrand",
version: std.split(importstr "VERSION", "\n")[0],
description: "quay",
license: "MIT",
expander: "jinja2"
},
variables: {
stack_path: "ci_stack",
config: (import "templates/config.libsonnet")($.variables),
namespace: "default",
tag: "master",
image: "quay.io/quay/quay-ci:%s" % $.variables.tag,
docker_user: 'changeme',
docker_pass: 'changeme',
domain: 'quay-%s.k8s.devtable.com' % $.variables.tag,
ingress: {
class: 'nginx',
tls: "kubernetes.io/tls-acme-stg",
domains: std.split($.variables.domain, ","),
annotations: {}
},
license: null,
db: {
user: 'quay',
password: 'quay',
name: 'quay',
},
} + (import "params.json"),
resources: appr.compact([
{
template: (importstr "templates/quay-dev-initdb-job.yaml"),
},
]),
deploy: [
{
name: "quay/postgres-app",
variables: {
user: $.variables.db.user,
dbname: $.variables.db.name,
password: $.variables.db.password
}
},
{
name: "quay/quay-app",
variables: $.variables
},
# Deploy the initdb script
{name: "$self"},
],
}, params)

View file

@ -0,0 +1 @@
{"image": "quay.io/quay/quay-ci:master", "tag": "master"}

View file

@ -0,0 +1,23 @@
function(vars={})
{
REGISTRY_TITLE: "Quay (%s)" % vars.domain,
REGISTRY_TITLE_SHORT: "Quay (%s)" % vars.domain,
TESTING: true,
DEBUGGING: true,
USE_CDN: false,
FEATURE_ANONYMOUS_ACCESS: true,
FEATURE_MAILING: false,
ENTERPRISE_LOGO_URL: "/static/img/quay-logo.png",
LOG_ARCHIVE_LOCATION: "default",
SERVER_HOSTNAME: vars.domain,
EXTERNAL_TLS_TERMINATION: true,
TAG_EXPIRATION_OPTIONS: ["2d"],
DISTRIBUTED_STORAGE_CONFIG: {
default: [
"LocalStorage",
{storage_path: "/datastorage/registry"}]},
DISTRIBUTED_STORAGE_DEFAULT_LOCATIONS: [],
DISTRIBUTED_STORAGE_PREFERENCE: ["default"],
USERFILES_LOCATION: "default",
USERFILES_PATH: "userfiles/",
}

View file

@ -0,0 +1,37 @@
---
apiVersion: batch/v1
kind: Job
metadata:
name: quay-dev-initdb
spec:
activeDeadlineSeconds: 600
template:
metadata:
name: quay-dev-initdb
spec:
containers:
- name: quay
image: quay.io/quay/quay-ci:master
env:
- name: TEST_DATABASE_URI
value: "postgres://"
- name: SKIP_DB_SCHEMA
value: "true"
command:
- venv/bin/python
- initdb.py
volumeMounts:
- name: configvolume
readOnly: false
mountPath: /conf/stack
resources:
limits:
cpu: 500m
memory: 500Mi
imagePullSecrets:
- name: coreos-pull-secret
volumes:
- name: configvolume
secret:
secretName: quay-enterprise-config-secret
restartPolicy: Never

Binary file not shown.

View file

@ -109,7 +109,7 @@ class BaseProvider(object):
indicating that this container requires a restart.
"""
raise NotImplementedError
def get_volume_path(self, directory, filename):
""" Helper for constructing file paths, which may differ between providers. For example,
kubernetes can't have subfolders in configmaps """

View file

@ -54,20 +54,20 @@ class KubernetesConfigProvider(FileConfigProvider):
self._update_secret_file(filename, contents)
except IOError as ioe:
raise CannotWriteConfigException(str(ioe))
def volume_file_exists(self, filename):
secret = self._lookup_secret()
if not secret or not secret.get('data'):
return False
return filename in secret['data']
def list_volume_directory(self, path):
secret = self._lookup_secret()
if not secret:
return []
paths = []
for filename in secret.get('data', {}):
if filename.startswith(path):
@ -150,4 +150,4 @@ class KubernetesConfigProvider(FileConfigProvider):
return session.send(request.prepare(), verify=False, timeout=2)
def get_volume_path(self, directory, filename):
return "_".join([directory.rstrip('/'), filename])
return "_".join([directory.rstrip('/'), filename])