From a0bdfd08c0f36335e2397a68462437506e38725a Mon Sep 17 00:00:00 2001 From: Tim Hockin Date: Mon, 11 Feb 2019 14:43:32 -0800 Subject: [PATCH 1/3] Script adding a GCR staging repo --- gcr/README.md | 17 +++++++ gcr/add-staging-repo.sh | 107 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 124 insertions(+) create mode 100644 gcr/README.md create mode 100755 gcr/add-staging-repo.sh diff --git a/gcr/README.md b/gcr/README.md new file mode 100644 index 00000000000..e06abd63a12 --- /dev/null +++ b/gcr/README.md @@ -0,0 +1,17 @@ +# Managing Kubernetes container regstries + +This directory is for tools and things that are used to administer the GCR +repositories used to publish official container images for Kubernetes. + +## Staging repos + +Each "project" (as decided by people) that feeds into Kubernetes' main +image-serving system (k8s.gcr.io) gets a staging repository. Each staging +repository is governed by a googlegroup, which grants push access to that +repository. + +Project owners can push to their staging repository and use the image promoter +to promote images to the main serving repository. + +As of Feb 11, 2019 this hierarchical system, including the promoter, are a +work-in-progress. diff --git a/gcr/add-staging-repo.sh b/gcr/add-staging-repo.sh new file mode 100755 index 00000000000..61f8aa5ded9 --- /dev/null +++ b/gcr/add-staging-repo.sh @@ -0,0 +1,107 @@ +#!/bin/sh +# +# This script is used to create a new "staging" repo in GCR. Each sub-project +# that needs to publish container images should have their own staging repo. +# +# Each staging repo exists in its own GCP project, and is writable by a +# dedicated googlegroup. + +set -o errexit +set -o nounset +set -o pipefail + +function usage() { + echo "usage: $0 " > /dev/stderr + echo "example:" > /dev/stderr + echo " $0 coredns" > /dev/stderr + echo > /dev/stderr +} + +function _color() { + tput setf $1 +} + +function _nocolor() { + tput sgr0 +} + +function color() { + _color $1 + shift + echo "$@" + _nocolor +} + +if [ $# != 1 ]; then + usage + exit 1 +fi +if [ -z "$1" ]; then + usage + exit 2 +fi + +# The name of the sub-project being created, e.g. "coredns". +REPO="$1" + +# The GCP project name. +PROJECT="k8s-staging-${REPO}" + +# The GCS bucket that backs the GCR repo. +BUCKET="artifacts.${PROJECT}.appspot.com" + +# The group that is admins all staging repos. +ADMINS="k8s-infra-gcr-admins@googlegroups.com" + +# The group that can write to this staging repo. +WRITERS="k8s-infra-gcr-staging-${REPO}@googlegroups.com" + +# The GCP org stuff needed to turn it all on. +ORG="758905017065" # kubernetes.io +BILLING="018801-93540E-22A20E" + +# Make the project, if needed +if ! gcloud projects describe "${PROJECT}" >/dev/null 2>&1; then + color 6 "Creating project ${PROJECT}" + gcloud projects create "${PROJECT}" \ + --organization "${ORG}" +fi +color 6 "Configuring billing for ${PROJECT}" +gcloud beta billing projects link "${PROJECT}" \ + --billing-account "${BILLING}" + +# Grant project viewer so the UI will work. +color 6 "Granting project viewer to ${ADMINS}" +gcloud \ + projects add-iam-policy-binding "${PROJECT}" \ + --member "group:${ADMINS}" \ + --role roles/viewer + +# Enable container registry API +color 6 "Enabling the container registry API" +gcloud --project "${PROJECT}" \ + services enable containerregistry.googleapis.com + +# Push an image to trigger the bucket to be created +color 6 "Activating the registry bucket" +docker pull k8s.gcr.io/pause +docker tag k8s.gcr.io/pause "gcr.io/${PROJECT}/pause" +docker push "gcr.io/${PROJECT}/pause" +gcloud --project "${PROJECT}" \ + container images delete --quiet "gcr.io/${PROJECT}/pause:latest" + +# Grant cross-repo admins access to admin. +color 6 "Granting bucket objectAdmin to ${ADMINS}" +gsutil iam ch "group:${ADMINS}:objectAdmin" "gs://${BUCKET}" +color 6 "Granting bucket legacyBucketOwner to ${ADMINS}" +gsutil iam ch "group:${ADMINS}:legacyBucketOwner" "gs://${BUCKET}" + +# Make the bucket publicly readable. +color 6 "Making the bucket public" +gsutil iam ch allUsers:objectViewer "gs://${BUCKET}" + +# Grant repo writers access to write. +color 6 "Granting bucket objectAdmin to ${WRITERS}" +gsutil iam ch "group:${WRITERS}:objectAdmin" "gs://${BUCKET}" +color 6 "Granting bucket legacyBucketReader to ${WRITERS}" +gsutil iam ch "group:${WRITERS}:legacyBucketReader" "gs://${BUCKET}" From d9ef140f39d11959f811c1512f0424b28becf660 Mon Sep 17 00:00:00 2001 From: Tim Hockin Date: Mon, 11 Feb 2019 15:45:38 -0800 Subject: [PATCH 2/3] Add lifecyle for GCR staging repos --- gcr/add-staging-repo.sh | 35 ++++++++++++++++++++++++++++++++--- 1 file changed, 32 insertions(+), 3 deletions(-) diff --git a/gcr/add-staging-repo.sh b/gcr/add-staging-repo.sh index 61f8aa5ded9..13ab4669ab7 100755 --- a/gcr/add-staging-repo.sh +++ b/gcr/add-staging-repo.sh @@ -84,11 +84,12 @@ gcloud --project "${PROJECT}" \ # Push an image to trigger the bucket to be created color 6 "Activating the registry bucket" +PHONY="ceci-nest-pas-une-image" docker pull k8s.gcr.io/pause -docker tag k8s.gcr.io/pause "gcr.io/${PROJECT}/pause" -docker push "gcr.io/${PROJECT}/pause" +docker tag k8s.gcr.io/pause "gcr.io/${PROJECT}/${PHONY}" +docker push "gcr.io/${PROJECT}/${PHONY}" gcloud --project "${PROJECT}" \ - container images delete --quiet "gcr.io/${PROJECT}/pause:latest" + container images delete --quiet "gcr.io/${PROJECT}/${PHONY}:latest" # Grant cross-repo admins access to admin. color 6 "Granting bucket objectAdmin to ${ADMINS}" @@ -105,3 +106,31 @@ color 6 "Granting bucket objectAdmin to ${WRITERS}" gsutil iam ch "group:${WRITERS}:objectAdmin" "gs://${BUCKET}" color 6 "Granting bucket legacyBucketReader to ${WRITERS}" gsutil iam ch "group:${WRITERS}:legacyBucketReader" "gs://${BUCKET}" + +# Set lifecycle policies. +color 6 "Setting lifecycle to age-out old data" +echo ' + { + "rule": [ + { + "condition": { + "age": 30 + }, + "action": { + "storageClass": "NEARLINE", + "type": "SetStorageClass" + } + }, + { + "condition": { + "age": 90 + }, + "action": { + "type": "Delete" + } + } + ] + } + ' | gsutil lifecycle set /dev/stdin "gs://${BUCKET}" + +color 6 "Done" From 20ee04c6eb0edcf8965b2ed09897fb262d7c8ffc Mon Sep 17 00:00:00 2001 From: Tim Hockin Date: Thu, 14 Feb 2019 14:51:32 -0800 Subject: [PATCH 3/3] Check that an extant project is ours --- gcr/add-staging-repo.sh | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/gcr/add-staging-repo.sh b/gcr/add-staging-repo.sh index 13ab4669ab7..8ce40d8f1c6 100755 --- a/gcr/add-staging-repo.sh +++ b/gcr/add-staging-repo.sh @@ -60,12 +60,25 @@ WRITERS="k8s-infra-gcr-staging-${REPO}@googlegroups.com" ORG="758905017065" # kubernetes.io BILLING="018801-93540E-22A20E" + # Make the project, if needed if ! gcloud projects describe "${PROJECT}" >/dev/null 2>&1; then color 6 "Creating project ${PROJECT}" gcloud projects create "${PROJECT}" \ --organization "${ORG}" +else + o=$(gcloud projects \ + describe k8s-staging-coredns \ + --flatten='parent[]' \ + --format='csv[no-heading](type, id)' \ + | grep ^organization \ + | cut -f2 -d,) + if [ "$o" != "${ORG}" ]; then + echo "project ${PROJECT} exists, but not in our org: got ${o}" + exit 2 + fi fi + color 6 "Configuring billing for ${PROJECT}" gcloud beta billing projects link "${PROJECT}" \ --billing-account "${BILLING}"