2019-05-03 13:59:01 +00:00
|
|
|
from datasette import hookimpl
|
|
|
|
import click
|
|
|
|
import json
|
2019-07-08 02:06:31 +00:00
|
|
|
import os
|
2019-05-03 13:59:01 +00:00
|
|
|
from subprocess import check_call, check_output
|
|
|
|
|
|
|
|
from .common import (
|
|
|
|
add_common_publish_arguments_and_options,
|
|
|
|
fail_if_publish_binary_not_installed,
|
|
|
|
)
|
|
|
|
from ..utils import temporary_docker_directory
|
|
|
|
|
|
|
|
|
|
|
|
@hookimpl
|
|
|
|
def publish_subcommand(publish):
|
|
|
|
@publish.command()
|
|
|
|
@add_common_publish_arguments_and_options
|
|
|
|
@click.option(
|
|
|
|
"-n",
|
|
|
|
"--name",
|
|
|
|
default="datasette",
|
2019-05-09 16:45:01 +00:00
|
|
|
help="Application name to use when building",
|
|
|
|
)
|
|
|
|
@click.option(
|
2019-05-09 16:47:58 +00:00
|
|
|
"--service", default="", help="Cloud Run service to deploy (or over-write)"
|
2019-05-03 13:59:01 +00:00
|
|
|
)
|
|
|
|
@click.option("--spatialite", is_flag=True, help="Enable SpatialLite extension")
|
2019-07-08 02:06:31 +00:00
|
|
|
@click.option(
|
|
|
|
"--show-files",
|
|
|
|
is_flag=True,
|
|
|
|
help="Output the generated Dockerfile and metadata.json",
|
|
|
|
)
|
2019-05-03 13:59:01 +00:00
|
|
|
def cloudrun(
|
|
|
|
files,
|
|
|
|
metadata,
|
|
|
|
extra_options,
|
|
|
|
branch,
|
|
|
|
template_dir,
|
|
|
|
plugins_dir,
|
|
|
|
static,
|
|
|
|
install,
|
2019-07-08 02:06:31 +00:00
|
|
|
plugin_secret,
|
2019-05-03 13:59:01 +00:00
|
|
|
version_note,
|
|
|
|
title,
|
|
|
|
license,
|
|
|
|
license_url,
|
|
|
|
source,
|
|
|
|
source_url,
|
|
|
|
about,
|
|
|
|
about_url,
|
|
|
|
name,
|
2019-05-09 16:45:01 +00:00
|
|
|
service,
|
2019-05-03 13:59:01 +00:00
|
|
|
spatialite,
|
2019-07-08 02:06:31 +00:00
|
|
|
show_files,
|
2019-05-03 13:59:01 +00:00
|
|
|
):
|
2019-05-04 02:15:14 +00:00
|
|
|
fail_if_publish_binary_not_installed(
|
|
|
|
"gcloud", "Google Cloud", "https://cloud.google.com/sdk/"
|
|
|
|
)
|
|
|
|
project = check_output(
|
|
|
|
"gcloud config get-value project", shell=True, universal_newlines=True
|
|
|
|
).strip()
|
2019-05-03 13:59:01 +00:00
|
|
|
|
2019-11-08 02:48:39 +00:00
|
|
|
if not service:
|
|
|
|
# Show the user their current services, then prompt for one
|
|
|
|
click.echo("Please provide a service name for this deployment\n")
|
|
|
|
click.echo("Using an existing service name will over-write it")
|
|
|
|
click.echo("")
|
|
|
|
existing_services = get_existing_services()
|
|
|
|
if existing_services:
|
|
|
|
click.echo("Your existing services:\n")
|
|
|
|
for existing_service in existing_services:
|
|
|
|
click.echo(
|
|
|
|
" {name} - created {created} - {url}".format(
|
|
|
|
**existing_service
|
|
|
|
)
|
|
|
|
)
|
|
|
|
click.echo("")
|
|
|
|
service = click.prompt("Service name", type=str)
|
|
|
|
|
2019-07-08 02:06:31 +00:00
|
|
|
extra_metadata = {
|
|
|
|
"title": title,
|
|
|
|
"license": license,
|
|
|
|
"license_url": license_url,
|
|
|
|
"source": source,
|
|
|
|
"source_url": source_url,
|
|
|
|
"about": about,
|
|
|
|
"about_url": about_url,
|
|
|
|
}
|
|
|
|
|
|
|
|
environment_variables = {}
|
|
|
|
if plugin_secret:
|
|
|
|
extra_metadata["plugins"] = {}
|
|
|
|
for plugin_name, plugin_setting, setting_value in plugin_secret:
|
|
|
|
environment_variable = (
|
|
|
|
"{}_{}".format(plugin_name, plugin_setting)
|
|
|
|
.upper()
|
|
|
|
.replace("-", "_")
|
|
|
|
)
|
|
|
|
environment_variables[environment_variable] = setting_value
|
|
|
|
extra_metadata["plugins"].setdefault(plugin_name, {})[
|
|
|
|
plugin_setting
|
|
|
|
] = {"$env": environment_variable}
|
|
|
|
|
2019-05-03 13:59:01 +00:00
|
|
|
with temporary_docker_directory(
|
|
|
|
files,
|
|
|
|
name,
|
|
|
|
metadata,
|
|
|
|
extra_options,
|
|
|
|
branch,
|
|
|
|
template_dir,
|
|
|
|
plugins_dir,
|
|
|
|
static,
|
|
|
|
install,
|
|
|
|
spatialite,
|
|
|
|
version_note,
|
2019-07-08 02:06:31 +00:00
|
|
|
extra_metadata,
|
|
|
|
environment_variables,
|
2019-05-03 13:59:01 +00:00
|
|
|
):
|
2019-07-08 02:06:31 +00:00
|
|
|
if show_files:
|
|
|
|
if os.path.exists("metadata.json"):
|
|
|
|
print("=== metadata.json ===\n")
|
|
|
|
print(open("metadata.json").read())
|
|
|
|
print("\n==== Dockerfile ====\n")
|
|
|
|
print(open("Dockerfile").read())
|
|
|
|
print("\n====================\n")
|
|
|
|
|
2019-05-03 13:59:01 +00:00
|
|
|
image_id = "gcr.io/{project}/{name}".format(project=project, name=name)
|
|
|
|
check_call("gcloud builds submit --tag {}".format(image_id), shell=True)
|
2019-05-04 02:15:14 +00:00
|
|
|
check_call(
|
2020-01-21 23:28:11 +00:00
|
|
|
"gcloud run deploy --allow-unauthenticated --platform=managed --image {} {}".format(
|
2019-11-08 02:48:39 +00:00
|
|
|
image_id, service,
|
2019-05-04 02:15:14 +00:00
|
|
|
),
|
|
|
|
shell=True,
|
|
|
|
)
|
2019-11-08 02:48:39 +00:00
|
|
|
|
|
|
|
|
|
|
|
def get_existing_services():
|
|
|
|
services = json.loads(
|
|
|
|
check_output(
|
2020-01-21 23:28:11 +00:00
|
|
|
"gcloud run services list --platform=managed --format json",
|
2019-11-08 02:48:39 +00:00
|
|
|
shell=True,
|
|
|
|
universal_newlines=True,
|
|
|
|
)
|
|
|
|
)
|
|
|
|
return [
|
|
|
|
{
|
|
|
|
"name": service["metadata"]["name"],
|
|
|
|
"created": service["metadata"]["creationTimestamp"],
|
|
|
|
"url": service["status"]["address"]["url"],
|
|
|
|
}
|
|
|
|
for service in services
|
|
|
|
]
|