Skip to content

Commit

Permalink
automate cloud shell
Browse files Browse the repository at this point in the history
  • Loading branch information
kunmingg committed Nov 13, 2018
1 parent a0a772e commit 7c5b7de
Show file tree
Hide file tree
Showing 6 changed files with 119 additions and 17 deletions.
31 changes: 29 additions & 2 deletions bootstrap/cmd/bootstrap/app/ksServer.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,20 +38,23 @@ import (
"io/ioutil"
"math/rand"
"github.com/cenkalti/backoff"
"bytes"
)

// The name of the prototype for Jupyter.
const JupyterPrototype = "jupyterhub"

// root dir of local cached VERSIONED REGISTRIES
const CachedRegistries = "/opt/versioned_registries"
const CloudShellTemplatePath = "/opt/registries/kubeflow/deployment/gke/cloud_shell_templates"

// key used for storing start time of a request to deploy in the request contexts
const StartTime = "StartTime"

const KubeflowRegName = "kubeflow"
const KubeflowFolder = "ks_app"
const DmFolder = "gcp_config"
const CloudShellFolder = "kf_util"

// KsService defines an interface for working with ksonnet.
type KsService interface {
Expand Down Expand Up @@ -495,8 +498,9 @@ func (s *ksServer) CreateApp(ctx context.Context, request CreateRequest, dmDeplo
}

if dmDeploy != nil {
s.UpdateDmConfig(repoDir, request.Project, request.Name, kfVersion, dmDeploy)
UpdateDmConfig(repoDir, request.Project, request.Name, kfVersion, dmDeploy)
}
UpdateCloudShellConfig(repoDir, request.Project, request.Name, kfVersion, request.Zone)
err = s.SaveAppToRepo(request.Project, request.Email, repoDir)
if err != nil {
log.Errorf("There was a problem saving config to cloud repo; %v", err)
Expand Down Expand Up @@ -834,7 +838,7 @@ func (s *ksServer) GetApp(project string, appName string, kfVersion string, toke

// Save ks app config local changes to project source repo.
// Not thread safe, be aware when call it.
func (s *ksServer) UpdateDmConfig(repoDir string, project string, appName string, kfVersion string, dmDeploy *deploymentmanager.Deployment) error {
func UpdateDmConfig(repoDir string, project string, appName string, kfVersion string, dmDeploy *deploymentmanager.Deployment) error {
confDir := path.Join(repoDir, GetRepoName(project), kfVersion, appName, DmFolder)
if err := os.RemoveAll(confDir); err != nil {
return err
Expand All @@ -853,6 +857,29 @@ func (s *ksServer) UpdateDmConfig(repoDir string, project string, appName string
return nil
}

// Save cloud shell config to project source repo.
func UpdateCloudShellConfig(repoDir string, project string, appName string, kfVersion string, zone string) error {
confDir := path.Join(repoDir, GetRepoName(project), kfVersion, appName, CloudShellFolder)
if err := os.RemoveAll(confDir); err != nil {
return err
}
if err := os.MkdirAll(confDir, os.ModePerm); err != nil {
return err
}
for _, filename := range([]string{"conn.sh", "conn.md"}) {
data, err := ioutil.ReadFile(path.Join(CloudShellTemplatePath, filename))
if err != nil {
return err
}
data = bytes.Replace(data, []byte("project_id_placeholder"), []byte(project), -1)
data = bytes.Replace(data, []byte("zone_placeholder"), []byte(zone), -1)
data = bytes.Replace(data, []byte("deploy_name_placeholder"), []byte(appName), -1)
if err := ioutil.WriteFile(path.Join(confDir, filename), data, os.ModePerm); err != nil {
return err
}
}
return nil
}

// Save ks app config local changes to project source repo.
// Not thread safe, be aware when call it.
Expand Down
4 changes: 1 addition & 3 deletions components/gcp-click-to-deploy/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -139,9 +139,7 @@ class App extends React.Component<any, { signedIn: boolean }> {
</ul>
<ul>
<ul>
<li> Click Cloud Shell; run command in pop up window; kubeflow UI will be at
<a href="https://ssh.cloud.google.com/devshell/proxy?authuser=0&port=8081" style={{ color: 'inherit', marginLeft: 5 }} target="_blank"
>here</a>
<li> Click Cloud Shell; follow instructions on right side of the new tab.
</li>
</ul>
</ul>
Expand Down
18 changes: 6 additions & 12 deletions components/gcp-click-to-deploy/src/DeployForm.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -293,13 +293,10 @@ export default class DeployForm extends React.Component<any, DeployFormState> {
});
return;
}
window.open('https://console.cloud.google.com/home/dashboard?cloudshell=true&project=' + this.state.project, '_blank');
this.setState({
dialogBody: 'gcloud container clusters get-credentials ' + this.state.deploymentName
+ ' --zone ' + this.state.zone + ' --project ' + this.state.project + '; ' +
'kubectl port-forward -n kubeflow $(kubectl get pods -n kubeflow --selector=service=ambassador -o jsonpath="{.items[0].metadata.name}") 8081:80',
dialogTitle: 'In Cloud Shell, run following command:',
});
const cloudShellConfPath = this.state.kfverison + '/' + this.state.deploymentName + '/kf_util';
const cloudShellUrl = 'https://cloud.google.com/console/cloudshell/open?shellonly=true&git_repo=https://source.developers.google.com/p/' +
this.state.project + '/r/' + this.state.project + '-kubeflow-config&working_dir=' + cloudShellConfPath + '&tutorial=conn.md';
window.open(cloudShellUrl, '_blank');
}

private async _iapAddress() {
Expand Down Expand Up @@ -520,12 +517,9 @@ export default class DeployForm extends React.Component<any, DeployFormState> {
} else if (r.operation!.status! && r.operation!.status === 'DONE') {
const readyTime = new Date();
readyTime.setTime(readyTime.getTime() + (20 * 60 * 1000));
this._appendLine('Deployment is done');
this._appendLine('Deployment initialized, configuring environment');
if (this.state.clientId === '' || this.state.clientSecret === '') {
this._appendLine('(IAP skipped), cluster should be ready within 5 minutes. To connect to cluster, click cloud shell and run:');
this._appendLine('gcloud container clusters get-credentials ' + this.state.deploymentName
+ ' --zone ' + this.state.zone + ' --project ' + this.state.project);
this._appendLine('kubectl port-forward -n kubeflow $(kubectl get pods -n kubeflow --selector=service=ambassador -o jsonpath="{.items[0].metadata.name}") 8080:80');
this._appendLine('(IAP skipped), cluster should be ready within 5 minutes. To connect to cluster, click cloud shell and follow instruction');
} else {
this._appendLine('your kubeflow app url should be ready within 20 minutes (by '
+ readyTime.toLocaleTimeString() + '): https://'
Expand Down
56 changes: 56 additions & 0 deletions components/gcp-click-to-deploy/src/configs/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
{
"deployment" : { "id" : 806689925228672508, "name" : "gbus" },
"matches" : [ ],
"project" : "kunming-dev4",
"requestId" : "576851b7-2f49-3a6a-9ac3-31a79e1cc24c",
"resource" :
{
"name" : "set-iam-policy-add",
"properties" :
{
"gcpIamPolicyPatch" :
{
"add" : [
{ "members" : [ "serviceAccount:447707085492@cloudservices.gserviceaccount.com" ], "role" : "roles/container.admin" },
{ "members" : [ "serviceAccount:gbus-user@kunming-dev4.iam.gserviceaccount.com" ], "role" : "roles/cloudbuild.builds.editor" },
{ "members" : [ "serviceAccount:gbus-user@kunming-dev4.iam.gserviceaccount.com" ], "role" : "roles/viewer" },
{ "members" : [ "serviceAccount:gbus-admin@kunming-dev4.iam.gserviceaccount.com", "serviceAccount:gbus-user@kunming-dev4.iam.gserviceaccount.com" ], "role" : "roles/source.admin" },
{ "members" : [ "serviceAccount:gbus-admin@kunming-dev4.iam.gserviceaccount.com" ], "role" : "roles/servicemanagement.admin" },
{ "members" : [ "serviceAccount:gbus-admin@kunming-dev4.iam.gserviceaccount.com" ], "role" : "roles/compute.networkAdmin" },
{ "members" : [ "serviceAccount:gbus-user@kunming-dev4.iam.gserviceaccount.com" ], "role" : "roles/storage.admin" },
{ "members" : [ "serviceAccount:gbus-user@kunming-dev4.iam.gserviceaccount.com" ], "role" : "roles/bigquery.admin" },
{ "members" : [ "serviceAccount:gbus-user@kunming-dev4.iam.gserviceaccount.com" ], "role" : "roles/dataflow.admin" },
{ "members" : [ "serviceAccount:gbus-vm@kunming-dev4.iam.gserviceaccount.com" ], "role" : "roles/logging.logWriter" },
{ "members" : [ "serviceAccount:gbus-vm@kunming-dev4.iam.gserviceaccount.com" ], "role" : "roles/monitoring.metricWriter" },
{ "members" : [ "serviceAccount:gbus-vm@kunming-dev4.iam.gserviceaccount.com" ], "role" : "roles/storage.objectViewer" },
{ "members" : [ { "user" : "kunming@google.com" } ], "role" : "roles/iap.httpsResourceAccessor" }
],
},
"policy" :
{
"bindings" : [
{ "members" : [ "serviceAccount:kubeflow-user@kunming-dev4.iam.gserviceaccount.com" ], "role" : "roles/bigquery.admin" },
{ "members" : [ "serviceAccount:kubeflow-user@kunming-dev4.iam.gserviceaccount.com" ], "role" : "roles/cloudbuild.builds.editor" },
{ "members" : [ "serviceAccount:kubeflow-admin@kunming-dev4.iam.gserviceaccount.com" ], "role" : "roles/compute.networkAdmin" },
{ "members" : [ "serviceAccount:service-447707085492@compute-system.iam.gserviceaccount.com" ], "role" : "roles/compute.serviceAgent" },
{ "members" : [ "serviceAccount:447707085492@cloudservices.gserviceaccount.com" ], "role" : "roles/container.admin" },
{ "members" : [ "serviceAccount:service-447707085492@container-engine-robot.iam.gserviceaccount.com" ], "role" : "roles/container.serviceAgent" },
{ "members" : [ "serviceAccount:kubeflow-user@kunming-dev4.iam.gserviceaccount.com" ], "role" : "roles/dataflow.admin" },
{ "members" : [ "serviceAccount:447707085492-compute@developer.gserviceaccount.com", "serviceAccount:447707085492@cloudservices.gserviceaccount.com", "serviceAccount:service-447707085492@containerregistry.iam.gserviceaccount.com" ], "role" : "roles/editor" },
{ "members" : [ "user:kunming@google.com" ], "role" : "roles/iap.httpsResourceAccessor" }, { "members" : [ "serviceAccount:kubeflow-vm@kunming-dev4.iam.gserviceaccount.com" ], "role" : "roles/logging.logWriter" },
{ "members" : [ "serviceAccount:kubeflow-vm@kunming-dev4.iam.gserviceaccount.com" ], "role" : "roles/monitoring.metricWriter" }, { "members" : [ "user:kunming@google.com" ], "role" : "roles/owner" },
{ "members" : [ "serviceAccount:447707085492@cloudservices.gserviceaccount.com" ], "role" : "roles/resourcemanager.projectIamAdmin" },
{ "members" : [ "serviceAccount:kubeflow-admin@kunming-dev4.iam.gserviceaccount.com" ], "role" : "roles/servicemanagement.admin" },
{ "members" : [ "serviceAccount:kubeflow-admin@kunming-dev4.iam.gserviceaccount.com", "serviceAccount:kubeflow-user@kunming-dev4.iam.gserviceaccount.com" ], "role" : "roles/source.admin" },
{ "members" : [ "serviceAccount:kubeflow-user@kunming-dev4.iam.gserviceaccount.com" ], "role" : "roles/storage.admin" },
{ "members" : [ "serviceAccount:kubeflow-vm@kunming-dev4.iam.gserviceaccount.com" ], "role" : "roles/storage.objectViewer" },
{ "members" : [ "serviceAccount:kubeflow-user@kunming-dev4.iam.gserviceaccount.com" ], "role" : "roles/viewer" }
],
"etag" : "BwV0mmCfkYU=",
"version" : 1,
},
"resource" : "kunming-dev4",
},
"self" : { },
},
}
5 changes: 5 additions & 0 deletions deployment/gke/cloud_shell_templates/conn.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# To establish connection to your kubeflow cluster

## Run following command in your cloud shell terminal

**./conn.sh**
22 changes: 22 additions & 0 deletions deployment/gke/cloud_shell_templates/conn.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
#!/bin/bash

# conn.sh - establish connection to kubeflow cluster

set -e # exit on error

PROJECT_ID=project_id_placeholder
ZONE=zone_placeholder
DEPLOY_NAME=deploy_name_placeholder

gcloud container clusters get-credentials ${DEPLOY_NAME} --zone ${ZONE} --project ${PROJECT_ID}

echo "Checking load balancing resource"
for i in $(seq 1 10)
do kubectl get pods -n kubeflow --selector=service=ambassador --field-selector=status.phase=Running | grep -q 'Running' && break || sleep 10
done

POD_NAME=$(kubectl get pods -n kubeflow --selector=service=ambassador --field-selector=status.phase=Running -o jsonpath="{.items[0].metadata.name}")

echo "Load balancing now ready"
echo "Your kubeflow service now accessible via: https://ssh.cloud.google.com/devshell/proxy?authuser=0&port=8081"
kubectl port-forward -n kubeflow ${POD_NAME} 8081:80

0 comments on commit 7c5b7de

Please sign in to comment.