Take an Excel file that looks like:
/ | < |
---|---|
1/1/2019 | Event 1 |
1/2/2019 | Event 2 |
1/3/2019 | Event 3 |
as an upload and produce a PDF calendar, one month for page, and an ICS file that can be imported into calendars with that data on them.
- https://hub.docker.com/r/tiangolo/uwsgi-nginx-flask/
- https://stackoverflow.com/questions/5068591/rendering-a-reportlab-pdf-built-from-simpledoctemplate
#!/usr/bin/env python3 response = HttpResponse(mimetype='application/pdf') response['Content-Disposition'] = 'attachment; filename={}'.format(pdf_name) buff = BytesIO() doc = SimpleDocTemplate(buff, pagesize=letter) doc.build(elements) response.write(buff.getvalue()) buff.close() return response
- Maybe hosting?
- https://devcenter.heroku.com/articles/container-registry-and-runtime
- https://collabnix.com/category/docker/docker-for-gcp/
- https://cloud.google.com/cloud-build/docs/quickstart-docker
- https://cloudacademy.com/blog/the-4-best-docker-hosting-services/
- https://aws.amazon.com/fargate/
- https://docs.microsoft.com/en-us/azure/virtual-network/virtual-network-public-ip-address
brew install az
installs the Azure cli command- https://docs.microsoft.com/en-us/cli/azure/network/public-ip?view=azure-cli-latest#az-network-public-ip-create
- https://docs.microsoft.com/en-us/azure/aks/kubernetes-walkthrough
- https://docs.microsoft.com/en-us/azure/app-service/app-service-web-tutorial-custom-domain
- https://docs.microsoft.com/en-us/azure/aks/tutorial-kubernetes-app-update
- https://cloud.google.com/kubernetes-engine/docs/tutorials/configuring-domain-name-static-ip
This didn’t work, though, with the error:
ERROR: (gcloud.container.clusters.create) Operation [<Operation clusterConditions: [<StatusCondition code: CodeValueValuesEnum(GCE_STOCKOUT, 1) message: u'Try a different location, or try again later: Google Compute Engine does not have enough resources available to fulfill request: us-central1-b.'>] detail: u'Try a different location, or try again later: Google Compute Engine does not have enough resources available to fulfill request: us-central1-b.' endTime: u'2019-02-07T01:52:24.015219227Z' name: u'operation-1549504333886-880ea104' nodepoolConditions: [] operationType: OperationTypeValueValuesEnum(CREATE_CLUSTER, 1) selfLink: u'https://container.googleapis.com/v1/projects/180749766837/zones/us-central1-b/operations/operation-1549504333886-880ea104' startTime: u'2019-02-07T01:52:13.886673043Z' status: StatusValueValuesEnum(DONE, 3) statusMessage: u'Try a different location, or try again later: Google Compute Engine does not have enough resources available to fulfill request: us-central1-b.' targetLink: u'https://container.googleapis.com/v1/projects/180749766837/zones/us-central1-b/clusters/xlsx-cal' zone: u'us-central1-b'>] finished with error: Try a different location, or try again later: Google Compute Engine does not have enough resources available to fulfill request: us-central1-b.
Which is, according to search results, not uncommon.
az group create --name acaird-xls2cal --location eastus
az aks create \
--resource-group acaird-xls2cal \
--name xls2cal \
--node-count 1 \
--generate-ssh-keys
az aks get-credentials --resource-group acaird-xls2cal --name xls2cal
Merged "xls2cal" as current context in /Users/acaird/.kube/config
kubectl get nodes -o wide
NAME STATUS ROLES AGE VERSION EXTERNAL-IP OS-IMAGE KERNEL-VERSION CONTAINER-RUNTIME aks-nodepool1-21317057-0 Ready agent 4m v1.9.11 <none> Ubuntu 16.04.5 LTS 4.15.0-1036-azure docker://3.0.1
apiVersion: apps/v1
kind: Deployment
metadata:
name: xls2cal
spec:
replicas: 1
selector:
matchLabels:
app: xls2cal
template:
metadata:
labels:
app: xls2cal
spec:
containers:
- name: xls2cal
image: acaird/xls2cal
resources:
requests:
cpu: 100m
memory: 128Mi
limits:
cpu: 250m
memory: 256Mi
ports:
- containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
name: xls2cal
spec:
type: LoadBalancer
ports:
- port: 80
selector:
app: xls2cal
kubectl config get-contexts
CURRENT NAME CLUSTER AUTHINFO NAMESPACE docker-for-desktop docker-for-desktop-cluster docker-for-desktop * xls2cal xls2cal clusterUser_acaird-xls2cal_xls2cal
kubectl apply -f xls2cal.yaml
deployment.apps "xls2cal" created service "xls2cal" created
kubectl get service xls2cal
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE xls2cal LoadBalancer 10.0.42.132 <pending> 80:31270/TCP 18s
After a bit…
kubectl get service xls2cal
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE xls2cal LoadBalancer 10.0.42.132 xx.xx.xx.xx 80:31270/TCP 1m
curl -s http://xx.xx.xx.xx/ | html2text
You should have a Microsoft XLSX file that has a list of dates in Column A and a list of events in Column B. Click the "Browse" button below and locate that file. Press the "Create Zip file of PDF and ICS file" button and you will be prompted to open or save a Zip file. You should save it. In that Zip file will be a PDF file with a monthly calendar for each month that has an event and an ICS file that can be imported into your calendar program (Microsoft Outlook, MacOS Calendar, etc.) [File] [Create Zip file of PDF and ICS files]
kubectl get pods,svc -o wide
NAME READY STATUS RESTARTS AGE IP NODE pod/xls2cal-75c6b755cd-2nkc5 1/1 Running 0 3m 10.244.0.8 aks-nodepool1-21317057-0 NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE SELECTOR service/kubernetes ClusterIP 10.0.0.1 <none> 443/TCP 45m <none> service/xls2cal LoadBalancer 10.0.42.132 xx.xx.xx.xx 80:31270/TCP 3m app=xls2cal
kubectl logs xls2cal-75c6b755cd-2nkc5
Checking for script in /app/prestart.sh Running script /app/prestart.sh Running inside /app/prestart.sh, you could add migrations to this file, e.g.: #! /usr/bin/env bash # Let the DB start sleep 10; # Run migrations alembic upgrade head /usr/lib/python2.7/dist-packages/supervisor/options.py:298: UserWarning: Supervisord is running as root and it is searching for its configuration file in default locations (including its current working directory); you probably want to specify a "-c" argument specifying an absolute path to a configuration file for improved security. 'Supervisord is running as root and it is searching ' 2019-02-10 16:35:52,041 CRIT Supervisor running as root (no user in config file) 2019-02-10 16:35:52,041 INFO Included extra file "/etc/supervisor/conf.d/supervisord.conf" during parsing 2019-02-10 16:35:52,051 INFO RPC interface 'supervisor' initialized 2019-02-10 16:35:52,051 CRIT Server 'unix_http_server' running without any HTTP authentication checking 2019-02-10 16:35:52,051 INFO supervisord started with pid 1 2019-02-10 16:35:53,053 INFO spawned: 'nginx' with pid 9 2019-02-10 16:35:53,055 INFO spawned: 'uwsgi' with pid 10 [uWSGI] getting INI configuration from /app/uwsgi.ini [uWSGI] getting INI configuration from /etc/uwsgi/uwsgi.ini ;uWSGI instance configuration [uwsgi] cheaper = 2 processes = 16 ini = /app/uwsgi.ini module = main callable = app ini = /etc/uwsgi/uwsgi.ini socket = /tmp/uwsgi.sock chown-socket = nginx:nginx chmod-socket = 664 hook-master-start = unix_signal:15 gracefully_kill_them_all need-app = true die-on-term = true show-config = true ;end of configuration *** Starting uWSGI 2.0.17.1 (64bit) on [Sun Feb 10 16:35:53 2019] *** compiled with version: 6.3.0 20170516 on 02 February 2019 20:07:18 os: Linux-4.15.0-1036-azure #38~16.04.1-Ubuntu SMP Fri Dec 7 03:21:52 UTC 2018 nodename: xls2cal-75c6b755cd-2nkc5 machine: x86_64 clock source: unix ------ [...] ------ [pid: 13|app: 0|req: 1/1] 10.244.0.1 () {32 vars in 331 bytes} [Sun Feb 10 16:36:54 2019] GET / => generated 1522 bytes in 17 msecs (HTTP/1.1 200) 2 headers in 81 bytes (1 switches on core 0) 10.244.0.1 - - [10/Feb/2019:16:36:54 +0000] "GET / HTTP/1.1" 200 1522 "-" "curl/7.54.0" "-" 10.244.0.1 - - [10/Feb/2019:16:39:03 +0000] "GET / HTTP/1.1" 200 1522 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.13; rv:64.0) Gecko/20100101 Firefox/64.0" "-" [pid: 12|app: 0|req: 1/2] 10.244.0.1 () {40 vars in 601 bytes} [Sun Feb 10 16:39:03 2019] GET / => generated 1522 bytes in 18 msecs (HTTP/1.1 200) 2 headers in 81 bytes (1 switches on core 0) [pid: 13|app: 0|req: 2/3] 10.244.0.1 () {38 vars in 588 bytes} [Sun Feb 10 16:39:03 2019] GET /favicon.ico => generated 233 bytes in 8 msecs (HTTP/1.1 404) 2 headers in 72 bytes (1 switches on core 0) 10.244.0.1 - - [10/Feb/2019:16:39:03 +0000] "GET /favicon.ico HTTP/1.1" 404 233 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.13; rv:64.0) Gecko/20100101 Firefox/64.0" "-" [pid: 13|app: 0|req: 3/4] 10.244.0.1 () {46 vars in 875 bytes} [Sun Feb 10 16:39:18 2019] POST /uploader => generated 6008 bytes in 40 msecs (HTTP/1.1 200) 3 headers in 124 bytes (1 switches on core 0) 10.244.0.1 - - [10/Feb/2019:16:39:18 +0000] "POST /uploader HTTP/1.1" 200 6008 "http://xx.xx.xx.xx/" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.13; rv:64.0) Gecko/20100101 Firefox/64.0" "-" 10.244.0.1 - - [10/Feb/2019:16:39:58 +0000] "GET / HTTP/1.1" 200 1522 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_6) AppleWebKit/601.7.7 (KHTML, like Gecko) Version/9.1.2 Safari/601.7.7" "-" [pid: 13|app: 0|req: 4/5] 10.244.0.1 () {32 vars in 446 bytes} [Sun Feb 10 16:39:58 2019] GET / => generated 1522 bytes in 0 msecs (HTTP/1.1 200) 2 headers in 81 bytes (1 switches on core 0)
At https://dcc.godaddy.com/manage/acaird.com/dns click “Add”,
select “A” as the type (an A record) hostname, xxxxxx
, and the
IP address above, xx.xx.xx.xx
.
dig xxxxxx.acaird.com
; <<>> DiG 9.10.6 <<>> xxxxxx.acaird.com ;; global options: +cmd ;; Got answer: ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 64238 ;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1 ;; OPT PSEUDOSECTION: ; EDNS: version: 0, flags:; udp: 4096 ;; QUESTION SECTION: ;xxxxxxxx.acaird.com. IN A ;; ANSWER SECTION: xxxxxxx.acaird.com. 3562 IN A xx.xx.xx.xx ;; Query time: 77 msec ;; SERVER: 192.168.117.1#53(192.168.117.1) ;; WHEN: Sun Feb 10 12:33:25 EST 2019 ;; MSG SIZE rcvd: 64
and now the curl
command can use the hostname and not the IP
address:
curl -s http://xxxxxx.acaird.com/ | html2text
You should have a Microsoft XLSX file that has a list of dates in Column A and a list of events in Column B. Click the "Browse" button below and locate that file. Press the "Create Zip file of PDF and ICS file" button and you will be prompted to open or save a Zip file. You should save it. In that Zip file will be a PDF file with a monthly calendar for each month that has an event and an ICS file that can be imported into your calendar program (Microsoft Outlook, MacOS Calendar, etc.) [File] [Create Zip file of PDF and ICS files]
I started the container at 16:36 on 10 Feb 2019, and by 18:34 it was being nmap’d:
kubectl logs --tail=15 xls2cal-75c6b755cd-2nkc5
10.244.0.1 - - [10/Feb/2019:18:34:32 +0000] "\x16\x03\x01\x00\xF5\x01\x00\x00\xF1\x03\x03~\x92\xDEzo\xAC\x85\xDEs\x9DL*\x22\x8D\x84\xA5\x0C\x15+\xE0\x14\x89\xBA\xD7\xA4\x9BY\xE5S\xD9~\xA3\x00\x00\x92\x00\x05\x00\x04\x00\x02\x00\x01\x00\x15\x00\x16\x003\x009\x00:\x00\x1A\x00\x18\x005\x00\x09\x00" 400 157 "-" "-" "-" 10.244.0.1 - - [10/Feb/2019:18:34:32 +0000] "\x16\x03\x01\x00\xF5\x01\x00\x00\xF1\x03\x03NDyj\xC1\xE4+\xCC\xB48\xEA\xAB%\x16\x82\xDF:\xCA7\x1D\xD3\xFF:\x96\x9C\x07 \xF5\x85<.a\x00\x00\x92\x00\x05\x00\x04\x00\x02\x00\x01\x00\x15\x00\x16\x003\x009\x00:\x00\x1A\x00\x18\x005\x00\x09\x00" 400 157 "-" "-" "-" 10.244.0.1 - - [10/Feb/2019:18:34:32 +0000] "\x16\x03\x01\x00\xF5\x01\x00\x00\xF1\x03\x03\x11\x1Ez\x99\xD1L\xCF\xC6\xD8\xF4\xB9\xDF[\x0C\xA9]k)M4:\xF7 \x8CDW\xD0\x93\xE7D\x1Fs\x00\x00\x92\x00\x05\x00\x04\x00\x02\x00\x01\x00\x15\x00\x16\x003\x009\x00:\x00\x1A\x00\x18\x005\x00\x09\x00" 400 157 "-" "-" "-" 10.244.0.1 - - [10/Feb/2019:18:34:33 +0000] "\x16\x03\x01\x00\xF5\x01\x00\x00\xF1\x03\x03V\x0F\xBA\x1A\xFE\xFA\xAC\xF9\x85|\xFC\x80\x22\xEE\xC2~i\xC7j\x16|\x10\xB9\xAFn\xFC\x85(V\xD0\xA6\xC4\x00\x00\x92\x00\x05\x00\x04\x00\x02\x00\x01\x00\x15\x00\x16\x003\x009\x00:\x00\x1A\x00\x18\x005\x00\x09\x00" 400 157 "-" "-" "-" 10.244.0.1 - - [10/Feb/2019:18:34:33 +0000] "\x16\x03\x01\x00\xF5\x01\x00\x00\xF1\x03\x03}Ur\xBB\x7F<0\xFDC_\x9F\x05\xE4\xF2HX\x1F\x93e\xFB\xF6Z\xEC\xA1\xB1>\xC9v};#\xA0\x00\x00\x92\x00\x05\x00\x04\x00\x02\x00\x01\x00\x15\x00\x16\x003\x009\x00:\x00\x1A\x00\x18\x005\x00\x09\x00" 400 157 "-" "-" "-" 10.244.0.1 - - [10/Feb/2019:18:34:33 +0000] "\x16\x03\x01\x00\xF5\x01\x00\x00\xF1\x03\x03\xA0*\x16\xC8\xC2[\x16\xD3\xCB\xE7\xA8\x15\x1C\xC0\x87H\xE4\xE8d\x8AkFD\xF71\x9A:G\x00\xFC\xB05\x00\x00\x92\x00\x05\x00\x04\x00\x02\x00\x01\x00\x15\x00\x16\x003\x009\x00:\x00\x1A\x00\x18\x005\x00\x09\x00" 400 157 "-" "-" "-" 10.244.0.1 - - [10/Feb/2019:18:34:33 +0000] "\x16\x03\x01\x00\xF5\x01\x00\x00\xF1\x03\x03{:\xB3\xFC6\x9B\x0Cn\xCARE\xD5\x0E\xA1\x12t\xAF&T\xEB\x1D\x83\x06\x1B3m\xDD\xE8\xF7\xF4\x8A\x11\x00\x00\x92\x00\x05\x00\x04\x00\x02\x00\x01\x00\x15\x00\x16\x003\x009\x00:\x00\x1A\x00\x18\x005\x00\x09\x00" 400 157 "-" "-" "-" [pid: 13|app: 0|req: 27/44] 10.244.0.1 () {40 vars in 619 bytes} [Sun Feb 10 19:16:45 2019] GET /admin => generated 233 bytes in 0 msecs (HTTP/1.1 404) 2 headers in 72 bytes (1 switches on core 0) 10.244.0.1 - - [10/Feb/2019:19:16:45 +0000] "GET /admin HTTP/1.1" 404 233 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.13; rv:64.0) Gecko/20100101 Firefox/64.0" "-" [pid: 12|app: 0|req: 18/45] 10.244.0.1 () {38 vars in 596 bytes} [Sun Feb 10 19:16:45 2019] GET /favicon.ico => generated 233 bytes in 0 msecs (HTTP/1.1 404) 2 headers in 72 bytes (1 switches on core 0) 10.244.0.1 - - [10/Feb/2019:19:16:45 +0000] "GET /favicon.ico HTTP/1.1" 404 233 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.13; rv:64.0) Gecko/20100101 Firefox/64.0" "-" [pid: 13|app: 0|req: 28/46] 10.244.0.1 () {40 vars in 609 bytes} [Sun Feb 10 19:16:55 2019] GET / => generated 1522 bytes in 0 msecs (HTTP/1.1 200) 2 headers in 81 bytes (1 switches on core 0) 10.244.0.1 - - [10/Feb/2019:19:16:55 +0000] "GET / HTTP/1.1" 200 1522 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.13; rv:64.0) Gecko/20100101 Firefox/64.0" "-" [pid: 13|app: 0|req: 29/47] 10.244.0.1 () {38 vars in 596 bytes} [Sun Feb 10 19:16:55 2019] GET /favicon.ico => generated 233 bytes in 0 msecs (HTTP/1.1 404) 2 headers in 72 bytes (1 switches on core 0) 10.244.0.1 - - [10/Feb/2019:19:16:55 +0000] "GET /favicon.ico HTTP/1.1" 404 233 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.13; rv:64.0) Gecko/20100101 Firefox/64.0" "-"
- [X] Get Docker-ized Flask app that accepts the upload of an Excel file into memory, turns it into a Python data object, and prints an HTML page
- [X] Produce a PDF calendar for each month that has data and make them available for download or initiate downloads for them or something
- [X] Produce an ICS file with the data and make it available for download or initiate a download or something
- [ ] put a timestamp on the PDF files saying when they were generated
- [X] better error handling in the code; right now it just 500s
when it doesn’t like something
- [X] get the basics
- [X] some better styling so the page is prettier and has more
instructions and stuff
- [X] use flask_bootstrap and some lame styling
- [ ] password protect the whole thing
- Kubernetes
- Google Cloud run: https://alexolivier.me/posts/deploy-container-stateless-cheap-google-cloud-run-serverless
Cool documentation at https://help.github.com/en/actions/reference/workflow-syntax-for-github-actions
# This workflow will build a docker container, publish it to Google Container Registry, and deploy it to GKE.
#
# To configure this workflow:
#
# 1. Ensure that your repository contains the necessary configuration
# for your Google Kubernetes Engine cluster, including deployment.yml,
# kustomization.yml, service.yml, etc.
#
# 2. Set up secrets in your workspace: GKE_PROJECT with the name of
# the project, GKE_EMAIL with the service account email, GKE_KEY with
# the Base64 encoded JSON service account key
# (https://github.com/GoogleCloudPlatform/github-actions/tree/docs/service-account-key/setup-gcloud#inputs).
#
# 3. Change the values for the GKE_ZONE, GKE_CLUSTER, IMAGE,
# REGISTRY_HOSTNAME and DEPLOYMENT_NAME environment variables (below).
name: Build and Push to GCR
on:
push:
tags:
- v*
# Environment variables available to all jobs and steps in this workflow
# GKE_EMAIL: ${{ secrets.GKE_EMAIL }}
# GKE_KEY: ${{ secrets.GKE_KEY }}
env:
GITHUB_SHA: ${{ github.sha }}
GITHUB_REF: ${{ github.ref }}
IMAGE: cal-pdf-ics/cal-pdf-ics
REGISTRY_HOSTNAME: gcr.io
jobs:
setup-build-publish-deploy:
name: Setup, Build, and Publish
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v2
# Setup gcloud CLI
- uses: GoogleCloudPlatform/github-actions/setup-gcloud@master
with:
version: '270.0.0'
service_account_key: ${{ secrets.GCR_KEY }}
# Configure docker to use the gcloud command-line tool as a credential helper
- run: |
# Set up docker to authenticate
# via gcloud command-line tool.
gcloud auth configure-docker
# Build the Docker image
- name: Build
run: |
export TAG=`echo $GITHUB_REF | awk -F/ '{print $NF}'`
echo $TAG
docker build -t "$REGISTRY_HOSTNAME"/"$IMAGE":"$TAG" \
--build-arg GITHUB_SHA="$GITHUB_SHA" \
--build-arg GITHUB_REF="$GITHUB_REF" .
# Push the Docker image to Google Container Registry
- name: Publish
run: |
export TAG=`echo $GITHUB_REF | awk -F/ '{print $NF}'`
echo $TAG
docker push "$REGISTRY_HOSTNAME"/"$IMAGE":"$TAG"
docker tag "$REGISTRY_HOSTNAME"/"$IMAGE":"$TAG" "$REGISTRY_HOSTNAME"/"$IMAGE":latest
docker push "$REGISTRY_HOSTNAME"/"$IMAGE":latest
This requires a Github secret for the project.
I made this following the instructions at https://cloud.google.com/iam/docs/creating-managing-service-account-keys#iam-service-account-keys-create-console
To do this via the gcloud
command line, first type:
gcloud iam service-accounts list --project $PROJECT_NAME
then create a token by typing:
gcloud iam service-accounts keys \
create $PATH_TO_KEY_FILE \
--iam-account $ACCOUNT_EMAIL_FROM_PRIOR_COMMAND \
--project $PROJECT_NAME
this will create a file in $PATH_TO_KEY_FILE
.
That file needs to be base64-encoded and copied to the Github project’s secrets.
- Go to the project’s page at Github
- From the list of options along the top of the project (below the title) click “Settings” then from the menu on the left click “Secrets”
- Click Add Secret, set the Name to
GCR_KEY
and the Value to the base64-encoded version of$PATH_TO_KEY_FILE
. Click the “Add Secret” button
Now Github can access your Google project; there may be better security that this, but 🤷
Add the YAML file to =$PROJECT_ROOT/.github/workflows/google.yml
Now when you push a branch, it will get built, tagged with the
branch version and the latest
version.
This still won’t make that version show up in Google Cloud Run when you access your application. For that, there is more…
- [X] make authentication file using
gcloud
command line - [ ] set up builds to only happen on new tags, and use tag as image tag
- [ ] actually re-deploy Google Cloud Run image when that happens
Many fun commands.
- List the services
gcloud run services list --platform managed
SERVICE REGION URL LAST DEPLOYED BY LAST DEPLOYED AT + cal-pdf-ics us-central1 https://cal-pdf-ics-qzug6go32q-uc.a.run.app [email protected] 2020-01-18T20:49:57.875Z
- List the projects:
gcloud run revisions list --region us-central1 --platform managed
REVISION ACTIVE SERVICE DEPLOYED DEPLOYED BY + cal-pdf-ics-00003-fal yes cal-pdf-ics 2020-01-18 20:49:43 UTC [email protected]
- List the images in the project
gcloud container images list --project cal-pdf-ics
NAME gcr.io/cal-pdf-ics/cal-pdf-ics
- List the tags for a given image in a project
gcloud container images list-tags gcr.io/cal-pdf-ics/cal-pdf-ics
DIGEST TAGS TIMESTAMP e3ae68fe03b8 latest,v0.84 2020-02-11T15:14:39 b7baca4e21ec v0.83 2020-02-11T15:09:08 b175bd33fc7a GITHUB_REF 2020-02-11T14:57:38 bc3ba66b5286 c8617a563c703f2c6814110fb6f9fa4974df1b26 2020-02-11T09:17:15 79fc49734706 2020-02-11T08:16:13 e1deff5d707d 2020-01-18T15:48:33 002076e7d4a7 2020-01-15T20:23:08 76c434c653c5 2020-01-15T19:31:49
- List the Kubernetes details for a project
gcloud run revisions describe --region us-central1 --platform managed cal-pdf-ics-00003-fal
- Delete an image with the (literal) tag
GITHUB_REF
(because I can’t work shell variables); the--quiet
flag prevents the confirmation prompt (weird name for that behavior, right?)gcloud container images delete gcr.io/cal-pdf-ics/cal-pdf-ics:GITHUB_REF --quiet
Digests: - gcr.io/cal-pdf-ics/cal-pdf-ics@sha256:b175bd33fc7af4262154bbac39f7a080f01d7801c0e5599db29ee7913b5e1b62 Associated tags: - GITHUB_REF Tags: - gcr.io/cal-pdf-ics/cal-pdf-ics:GITHUB_REF Deleted [gcr.io/cal-pdf-ics/cal-pdf-ics:GITHUB_REF]. Deleted [gcr.io/cal-pdf-ics/cal-pdf-ics@sha256:b175bd33fc7af4262154bbac39f7a080f01d7801c0e5599db29ee7913b5e1b62].
(Note that the digest listed here is the long version of the digest from the
container images list-tags
DIGEST
column shown above,b175...
) - Reporting what image a service is using
gcloud run revisions describe \ --region us-central1 \ --platform managed \ --format=json cal-pdf-ics-00003-fal | \ jq '.spec.containers[].image'
"gcr.io/cal-pdf-ics/cal-pdf-ics@sha256:e1deff5d707dbf56a25450ceeecf8d7d4d6c69db84b5d12adf31b2aba54030ee"
Comparing that to the list of images above, this is the image from “2020-01-18T15:48:33” that is untagged. Also, there might be a better way of finding this information. (lmk @acaird)
- Changing what image a service is using to the image tagged
:latest
gcloud run deploy cal-pdf-ics \ --platform managed \ --region us-central1 \ --image gcr.io/cal-pdf-ics/cal-pdf-ics:latest
This can take a few tens of seconds to complete with the final output being something like
Deploying container to Cloud Run service [cal-pdf-ics] in project [cal-pdf-ics] region [us-central1] ✓ Deploying... Done. ✓ Creating Revision... ✓ Routing traffic... Done. Service [cal-pdf-ics] revision [cal-pdf-ics-00004-hab] has been deployed and is serving 100 percent of traffic at https://cal-pdf-ics-qzug6go32q-uc.a.run.app
This can then be confirmed by listing the tags for a given image in a project
gcloud container images list-tags gcr.io/cal-pdf-ics/cal-pdf-ics