-
Notifications
You must be signed in to change notification settings - Fork 827
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
Script adding a GCR staging repo #186
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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. |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,149 @@ | ||
#!/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 <repo>" > /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}" | ||
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}" | ||
|
||
# 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 | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. do we just want admins as 'viewers'? what about 'owners'? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. They only need project viewer for the UI to work. They have bucket admin for the specific buckets. We're trying to keep untra-limited perms when possible. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. who is going to manage the projects? just who create them? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. the set of people who can create projects is very small and should, itself be governed by a googlegroup |
||
|
||
# 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" | ||
PHONY="ceci-nest-pas-une-image" | ||
docker pull k8s.gcr.io/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}/${PHONY}: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}" | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. do we need 'legacyBucketReader'? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. without buckets.list it didn't work, and there doesn't seem to be a role that includes that permission that isn't "legacy" (and I didn't want to make a custom role, though we could, I guess...) There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. you are right, the other alternative is 'roles/storage.admin' There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. which is too broad |
||
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" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What happens if this project name happens to be an unrelated 3rd party?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You won't be able to list those. I don't see a way to only list projects under a specific org - do you know of one? Assuming you have a project with this name pattern in your scope, something else will fail. Or if you have project admin, maybe it won't fail.
We could require this create to happen, which makes the scripts not re-runnable. We could add flags to say --project-exists or something. Is that worth the effort?