Skip to content
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

[pull] master from GoogleCloudPlatform:master #10

Open
wants to merge 28 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
10c54d7
new --force_new_clone flag in Cloud Run (#206)
jamesward Dec 21, 2020
c85077c
Expose deployed service URL to post-deploy command (#207)
Dec 29, 2020
d2082d5
add --use-http2 flag support - fixes #202 (#203)
jamesward Jan 5, 2021
3efeb65
provide env ordering via "order" key (#209)
ahmetb Jan 15, 2021
a5b50d9
implement signaling clone status (#211)
ahmetb Jan 21, 2021
ff276c6
if http2 option is true then use gcloud alpha - fixes #213 (#214)
jamesward Jan 26, 2021
9b5bbac
try to clean disk space (#218)
jamesward Mar 22, 2021
318d5c1
add note about package.toml - fixes #215 (#217)
jamesward Mar 23, 2021
d48aa3a
Success = 1 & Failure = 0
jamesward Apr 13, 2021
b0dc7d0
experiment: instrumentless for users without projects or billing acco…
jamesward Apr 23, 2021
c6f7e91
handling for invalid trycgp url and option to create a project (#220)
jamesward May 21, 2021
18b4cd0
Port is expected to be an int not string (#221)
geshan Jun 4, 2021
d75fc48
bump gcp lib and remove api endpoint workaround (#224)
jamesward Jan 24, 2022
af3f130
Update CONTIRBUTING.md based on troubleshooting (#229)
glasnt Feb 28, 2022
808ba68
remove a TODO, --use-http2 is GA (#230)
pokutuna Jun 6, 2022
feb90bf
Add max-instances and concurrency options (#228)
glasnt Jun 19, 2022
39a340b
Introduce integration tests (#233)
glasnt Nov 7, 2022
d7f23a8
Migrate cleanup script to cleanup all services (#234)
glasnt Nov 14, 2022
3a1655d
Improve debug capabilities (#235)
glasnt Nov 18, 2022
b8b7a89
Add a sleep after deployment (#237)
glasnt Dec 11, 2022
0420a54
use paketobuildpacks for custom builder validation (#246)
glasnt Dec 4, 2023
fddaf97
fix: small int test fixes (#253)
glasnt Mar 12, 2024
8289084
feat: implement artifact registry integration (#273)
glasnt Sep 15, 2024
33bb0f9
chore: apply image tags to button images b/370251901 (#277)
glasnt Oct 14, 2024
f4b3b42
Add renovate.json (#261)
renovate-bot Oct 14, 2024
62bbf25
chore: batch renovatebot (#289)
glasnt Oct 22, 2024
e3a17a1
chore(all): migrate config renovate.json (#291)
renovate-bot Oct 29, 2024
1075bf1
Bump golang.org/x/crypto from 0.26.0 to 0.31.0 (#295)
dependabot[bot] Dec 12, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 12 additions & 4 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,17 @@ jobs:
cloudshell_open:
runs-on: ubuntu-latest
steps:
- name: Free disk space
run: |
docker system prune -a -f
sudo rm -rf /usr/local/lib/android
df /var/
df -h
- uses: actions/checkout@master
- uses: actions/setup-go@v1
- uses: actions/setup-go@v5
with:
go-version: 1.14
go-version: 1.21
- run: git config --global init.defaultBranch main # TODO remove later as git updates to a newer version
- run: go mod download
- name: Set up git
run: |
Expand All @@ -21,13 +28,14 @@ jobs:
working-directory: ./cmd/cloudshell_open
- name: Build docker image
run: docker build -t runbutton .

redirector:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@master
- uses: actions/setup-go@v1
- uses: actions/setup-go@v5
with:
go-version: 1.14
go-version: 1.21
- run: go mod download
working-directory: ./cmd/redirector
- name: Validate formatting with go fmt
Expand Down
25 changes: 20 additions & 5 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

## Test Cloud Run Button's Underlying Command Locally with Local Go

1. Download Go 1.14.x
1. Download Go 1.14 (see [`Dockerfile`](Dockerfile) for the exact version used)
1. Run the tests:
```
go test ./cmd/cloudshell_open
Expand All @@ -14,24 +14,31 @@
1. To test the command:
1. [Enable the cloudresourcemanager API](https://console.developers.google.com/apis/api/cloudresourcemanager.googleapis.com/overview)
1. [Enable the billing API](https://console.developers.google.com/apis/api/cloudbilling.googleapis.com/overview)
1. Create a Service Account with the *Cloud Run Admin*, *ServiceEnabler*, *Service Account User*, and *Storage Admin* roles
1. Download the JSON key
1. Create a Service Account with the following roles:
* Cloud Run Admin (`roles/run.admin`),
* Service Usage Admin (`roles/serviceusage.serviceUsageAdmin`),
* Service Account User (`roles/iam.serviceAccountUser`), and
* Storage Admin (`roles/storage.admin`).
1. [Download the Service Account key as a JSON file](https://cloud.google.com/iam/docs/creating-managing-service-account-keys#creating)
1. Authenticate gcloud as the service account:
```
export GOOGLE_APPLICATION_CREDENTIALS=PATH_TO_YOUR_SERVICE_ACCOUNT_KEY_FILE
gcloud auth activate-service-account --key-file=$GOOGLE_APPLICATION_CREDENTIALS
export TRUSTED_ENVIRONMENT=true
export SKIP_CLONE_REPORTING=true
```
1. Run the button:
```
(cd /tmp; ./cloudshell_open --repo_url=https://github.com/GoogleCloudPlatform/cloud-run-hello.git; rm -rf cloud-run-hello)
(cd /tmp; rm -rf cloud-run-hello; ./cloudshell_open --repo_url=https://github.com/GoogleCloudPlatform/cloud-run-hello.git; rm -rf cloud-run-hello)
```
Other `cloudshell_open` flags: `--git_branch`, `--dir`, `--context`

Env vars you can set to avoid STDIN questions: `GOOGLE_CLOUD_PROJECT` `GOOGLE_CLOUD_REGION`
Optionally, you can set to `GOOGLE_CLOUD_PROJECT` `GOOGLE_CLOUD_REGION` to avoid being prompted for these.

## Test Cloud Run Button's Underlying Command Locally in a Container

⚠️ This will download very large Docker images to your system.

1. [Create a Service Account in a test account](https://console.cloud.google.com/iam-admin/serviceaccounts)
1. Download the key json file for the new service account
1. Build the Container
Expand All @@ -52,13 +59,21 @@
-v $KEY_FILE:/root/user.json \
-e GOOGLE_APPLICATION_CREDENTIALS=/root/user.json \
-e TRUSTED_ENVIRONMENT=true \
-e SKIP_CLONE_REPORTING=true \
--entrypoint=/bin/sh cloud-run-button -c \
"gcloud auth activate-service-account --key-file=/root/user.json \
--quiet && gcloud auth configure-docker --quiet && \
/bin/cloudshell_open \
--repo_url=https://github.com/GoogleCloudPlatform/cloud-run-hello.git"
```

## Test Instrumentless

Test getting a coupon from the instrumentless API:
```
go run ./cmd/instrumentless_test YOUR_EVENT $(gcloud auth print-access-token)
```

## Contributor License Agreement

Contributions to this project must be accompanied by a Contributor License
Expand Down
2 changes: 1 addition & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
FROM golang:1.14-alpine AS build
FROM golang:1.21-alpine AS build
RUN apk add --no-cache git
WORKDIR /src
COPY go.mod go.sum ./
Expand Down
21 changes: 17 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -63,13 +63,20 @@ For example, a fully populated `app.json` file looks like this:
},
"APP_SECRET": {
"generator": "secret"
},
"ORDERED_ENV": {
"description": "control the order env variables are prompted",
"order": 100
}
},
"options": {
"allow-unauthenticated": false,
"memory": "512Mi",
"cpu": "1",
"port": "80"
"port": 80,
"http2": false,
"concurrency": 80,
"max-instances": 10
},
"build": {
"skip": false,
Expand Down Expand Up @@ -114,17 +121,23 @@ Reference:
- `required`, _(optional, default: `true`)_ indicates if they user must provide
a value for this variable.
- `generator`, _(optional)_ use a generator for the value, currently only support `secret`
- `order`, _(optional)_ if specified, used to indicate the order in which the
variable is prompted to the user. If some variables specify this and some
don't, then the unspecified ones are prompted last.
- `options`: _(optional)_ Options when deploying the service
- `allow-unauthenticated`: _(optional, default: `true`)_ allow unauthenticated requests
- `memory`: _(optional)_ memory for each instance
- `cpu`: _(optional)_ cpu for each instance
- `port`: _(optional)_ if your application doesn't respect the PORT environment
variable provided by Cloud Run, specify the port number it listens on.
variable provided by Cloud Run, specify the port number it listens on
- `http2`: _(optional)_ use http2 for the connection
- `concurrency`: _(optional)_ concurrent requests for each instance
- `max-instances`: _(optional)_ autoscaling limit (max 1000)
- `build`: _(optional)_ Build configuration
- `skip`: _(optional, default: `false`)_ skips the built-in build methods (`docker build`, `Maven Jib`, and
`buildpacks`), but still allows for `prebuild` and `postbuild` hooks to be run in order to build the container image
manually
- `buildpacks`: _(optional)_ buildpacks config
- `buildpacks`: _(optional)_ buildpacks config (Note: Additional Buildpack config can be specified using a `project.toml` file. [See the spec for details](https://buildpacks.io/docs/reference/config/project-descriptor/).)
- `builder`: _(optional, default: `gcr.io/buildpacks/builder:v1`)_ overrides the buildpack builder image
- `hooks`: _(optional)_ Run commands in separate bash shells with the environment variables configured for the
application and environment variables `GOOGLE_CLOUD_PROJECT` (Google Cloud project), `GOOGLE_CLOUD_REGION`
Expand All @@ -138,7 +151,7 @@ Reference:
- `commands`: _(array of strings)_ The list of commands to run
- `precreate`: _(optional)_ Runs the specified commands before the service has been created
- `commands`: _(array of strings)_ The list of commands to run
- `postcreate`: _(optional)_ Runs the specified commands after the service has been created
- `postcreate`: _(optional)_ Runs the specified commands after the service has been created; the `SERVICE_URL` environment variable provides the URL of the deployed Cloud Run service
- `commands`: _(array of strings)_ The list of commands to run

### Notes
Expand Down
38 changes: 31 additions & 7 deletions cloudbuild.yaml
Original file line number Diff line number Diff line change
@@ -1,12 +1,36 @@
# Copyright 2019 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

# Default cloudbuild.yaml for Cloud Shell custom images.
# This file is used by the Cloud Build trigger that builds this image.

steps:
- name: 'gcr.io/cloud-builders/docker'
args: ['build', '-t', 'gcr.io/$PROJECT_ID/button', '.']
- name: 'gcr.io/cloudshell-images/custom-image-validation'
args: ['image_test.py', '--image', 'gcr.io/$PROJECT_ID/button']
images: ['gcr.io/$PROJECT_ID/button']
timeout: '3600s'
- name: "gcr.io/cloud-builders/docker"
args:
[
"build",
"-t",
"gcr.io/$PROJECT_ID/button",
"-t",
"gcr.io/$PROJECT_ID/button:public-image-${COMMIT_SHA}",
".",
]
- name: "gcr.io/cloudshell-images/custom-image-validation"
args: ["image_test.py", "--image", "gcr.io/$PROJECT_ID/button"]
images:
- "gcr.io/$PROJECT_ID/button"
- "gcr.io/$PROJECT_ID/button:public-image-${COMMIT_SHA}"
timeout: "3600s"
options:
machineType: 'N1_HIGHCPU_8'
machineType: "N1_HIGHCPU_8"
4 changes: 0 additions & 4 deletions cmd/cloudshell_open/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,6 @@ func enableAPIs(project string, apis []string) error {
return fmt.Errorf("failed to create resource manager client: %w", err)
}

// TODO(ahmetb) specify this explicitly, otherwise for some reason this becomes serviceusage.mtls.googleapis.com (and 404s)
// while querying the Operation. investigate later with the client library teams.
client.BasePath = "https://serviceusage.googleapis.com/"

enabled, err := enabledAPIs(client, project)
if err != nil {
return err
Expand Down
55 changes: 47 additions & 8 deletions cmd/cloudshell_open/appfile.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import (
"io"
"os"
"path/filepath"
"sort"

"github.com/fatih/color"

Expand All @@ -33,13 +34,17 @@ type env struct {
Value string `json:"value"`
Required *bool `json:"required"`
Generator string `json:"generator"`
Order *int `json:"order"`
}

type options struct {
AllowUnauthenticated *bool `json:"allow-unauthenticated"`
Memory string `json:"memory"`
CPU string `json:"cpu"`
Port int `json:"port"`
HTTP2 *bool `json:"http2"`
Concurrency int `json:"concurrency"`
MaxInstances int `json:"max-instances"`
}

type hook struct {
Expand Down Expand Up @@ -190,7 +195,6 @@ func promptOrGenerateEnvs(list map[string]env) ([]string, error) {
}

func generateEnvs(keys []string) ([]string, error) {

for i, key := range keys {
resp, err := rand64String()
if err != nil {
Expand All @@ -202,15 +206,50 @@ func generateEnvs(keys []string) ([]string, error) {
return keys, nil
}

func promptEnv(list map[string]env) ([]string, error) {
// TODO(ahmetb): remove these defers and make customizations at the
// individual prompt-level once survey lib allows non-global settings.
type envKeyValuePair struct {
k string
v env
}

type envKeyValuePairs []envKeyValuePair

func (e envKeyValuePairs) Len() int { return len(e) }

func (e envKeyValuePairs) Swap(i, j int) {
e[i], e[j] = e[j], e[i]
}

func (e envKeyValuePairs) Less(i, j int) bool {
// if env.Order is unspecified, it should appear less.
// otherwise, less values show earlier.
if e[i].v.Order == nil {
return false
}
if e[j].v.Order == nil {
return true
}
return *e[i].v.Order < *e[j].v.Order
}

func sortedEnvs(envs map[string]env) []string {
var v envKeyValuePairs
for key, value := range envs {
v = append(v, envKeyValuePair{key, value})
}
sort.Sort(v)
var keys []string
for _, vv := range v {
keys = append(keys, vv.k)
}
return keys
}

func promptEnv(list map[string]env) ([]string, error) {
var out []string
// TODO(ahmetb): we should ideally use an ordered map structure for Env
// field and prompt the questions as they appear in the app.json file as
// opposed to random order we do here.
for k, e := range list {
sortedKeys := sortedEnvs(list)

for _, k := range sortedKeys {
e := list[k]
var resp string

if err := survey.AskOne(&survey.Input{
Expand Down
22 changes: 22 additions & 0 deletions cmd/cloudshell_open/appfile_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -233,3 +233,25 @@ func TestGetAppFile(t *testing.T) {
t.Fatalf("wrong parsed value: got=%#v, expected=%#v", v, expected)
}
}

func Test_sortedEnvs(t *testing.T) {
envs := map[string]env{
"NIL_ORDER": {},
"ORDER_100": {Order: mkInt(100)},
"ORDER_0": {Order: mkInt(0)},
"ORDER_-10": {Order: mkInt(-10)},
"ORDER_50": {Order: mkInt(50)},
}
got := sortedEnvs(envs)
expected := []string{
"ORDER_-10", "ORDER_0", "ORDER_50", "ORDER_100", "NIL_ORDER",
}

if !reflect.DeepEqual(got, expected) {
t.Fatalf("sorted envs in wrong order: expected:%v\ngot=%v", expected, got)
}
}

func mkInt(i int) *int {
return &i
}
Loading