zun-ui/zun_ui/static/cloud-shell/cloud-shell.controller.js
Hongbin Lu 2583d574d2 Use labels to identify the cloud-shell container
Change-Id: Ic3dd0f949c3937f0e5b5d4f81aed7ca30ab271ff
Closes-Bug: #1847227
2019-10-14 01:18:54 +00:00

160 lines
5.5 KiB
JavaScript

/**
* 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
*
* http://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.
*/
(function() {
"use strict";
angular
.module('horizon.cloud-shell')
.controller('horizon.cloud-shell.controller', cloudShellController);
cloudShellController.$inject = [
'$scope',
'horizon.app.core.openstack-service-api.zun',
'horizon.dashboard.container.webRoot',
'horizon.framework.util.http.service'
];
function cloudShellController(
$scope,
zun,
webRoot,
http
) {
var ctrl = this;
ctrl.openInNewWindow = openInNewWindow;
ctrl.close = closeShell;
ctrl.consoleUrl = null;
ctrl.container = {};
ctrl.resizeTerminal = resizeTerminal;
// close existing shell
closeShell();
// default size for shell
var cols = 80;
var rows = 24;
// get clouds.yaml for OpenStack Client
var cloudsYaml;
http.get('/project/api_access/clouds.yaml/').then(function(response) {
// cloud.yaml to be set to .config/openstack/clouds.yaml in container
cloudsYaml = response.data;
ctrl.user = cloudsYaml.match(/username: "(.+)"/)[1];
ctrl.project = cloudsYaml.match(/project_name: "(.+)"/)[1];
ctrl.userDomain = cloudsYaml.match(/user_domain_name: "(.+)"/);
ctrl.projectDomain = cloudsYaml.match(/project_domain_name: "(.+)"/);
ctrl.domain = (ctrl.userDomain.length === 2) ? ctrl.userDomain[1] : ctrl.projectDomain[1];
ctrl.region = cloudsYaml.match(/region_name: "(.+)"/)[1];
// container name
ctrl.containerLabel = "cloud-shell-" + ctrl.user + "-" + ctrl.project +
"-" + ctrl.domain + "-" + ctrl.region;
// get container
zun.getContainers().then(findContainer);
});
function findContainer(response) {
var container = response.data.items.find(function(item) {
return item.labels['cloud-shell'] === ctrl.containerLabel;
});
if (typeof (container) === 'undefined') {
onFailGetContainer();
} else {
onGetContainer({data: container});
}
}
function onGetContainer(response) {
ctrl.container = response.data;
// attach console to existing container
ctrl.consoleUrl = webRoot + "containers/" + ctrl.container.id + "/console";
var console = $("<p>To display console, interactive mode needs to be enabled " +
"when this container was created.</p>");
if (ctrl.container.status !== "Running") {
console = $("<p>Container is not running. Please wait for starting up container.</p>");
} else if (ctrl.container.interactive) {
console = $("<iframe id=\"console_embed\" src=\"" + ctrl.consoleUrl +
"\" style=\"width:100%;height:100%\"></iframe>");
// execute openrc.sh on the container
var command = "sh -c 'printf \"" + cloudsYaml + "\" > ~/.config/openstack/clouds.yaml'";
zun.executeContainer(ctrl.container.id, {command: command}).then(function() {
var command = "sh -c 'printf \"export OS_CLOUD=openstack\" > ~/.bashrc'";
zun.executeContainer(ctrl.container.id, {command: command}).then(function() {
angular.noop();
});
});
}
// append shell content
angular.element("#shell-content").append(console);
}
// watcher for iframe contents loading, seems to emit once.
$scope.$watch(function() {
return angular.element("#shell-content > iframe").contents()
.find("#terminalNode").attr("termCols");
}, resizeTerminal);
// event handler to resize console according to window resize.
angular.element(window).bind('resize', resizeTerminal);
// also, add resizeTerminal into callback attribute for resizer directive
function resizeTerminal() {
var shellIframe = angular.element("#shell-content > iframe");
var newCols = shellIframe.contents().find("#terminalNode").attr("termCols");
var newRows = shellIframe.contents().find("#terminalNode").attr("termRows");
if ((newCols !== cols || newRows !== rows) && newCols > 0 && newRows > 0 &&
ctrl.container.id) {
// resize tty
zun.resizeContainer(ctrl.container.id, {width: newCols, height: newRows}).then(function() {
cols = newCols;
rows = newRows;
});
}
}
function onFailGetContainer() {
// create new container and attach console to it.
var image = angular.element("#cloud-shell-menu").attr("cloud-shell-image");
var model = {
image: image,
command: "/bin/bash",
interactive: true,
run: true,
environment: "OS_CLOUD=openstack",
labels: "cloud-shell=" + ctrl.containerLabel
};
zun.createContainer(model).then(function (response) {
// attach
onGetContainer({data: {id: response.data.id}});
});
}
function openInNewWindow() {
// open shell in new window
window.open(ctrl.consoleUrl, "_blank");
closeShell();
}
function closeShell() {
// close shell
angular.element("#cloud-shell").remove();
angular.element("#cloud-shell-resizer").remove();
}
}
})();