summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKamil Trzcinski <ayufan@ayufan.eu>2016-10-12 11:27:13 +0200
committerKamil Trzcinski <ayufan@ayufan.eu>2016-10-12 11:27:13 +0200
commit2bac9790e7ec9d5bf3dd58b29585840bf1d01872 (patch)
tree722b915cccc80aba35faf0ff4f4fd2ff361f3bf0
parentaacf10758c4456f0829ec071c131fe3de800c801 (diff)
parent7ca77debf39f5990440bf29c162969895f21b54b (diff)
downloadgitlab-ce-2bac9790e7ec9d5bf3dd58b29585840bf1d01872.tar.gz
terminal support
-rw-r--r--app/assets/javascripts/terminal/terminal.js.es695
-rw-r--r--app/assets/javascripts/terminal/terminal_bundle.js.es62
-rw-r--r--app/assets/stylesheets/framework/buttons.scss7
-rw-r--r--app/controllers/projects/deployments_controller.rb15
-rw-r--r--app/views/projects/deployments/_actions.haml6
-rw-r--r--app/views/projects/deployments/terminal.html.haml4
-rw-r--r--app/views/shared/icons/_icon_terminal.svg2
7 files changed, 76 insertions, 55 deletions
diff --git a/app/assets/javascripts/terminal/terminal.js.es6 b/app/assets/javascripts/terminal/terminal.js.es6
index 67435aa3db0..f797f1ac637 100644
--- a/app/assets/javascripts/terminal/terminal.js.es6
+++ b/app/assets/javascripts/terminal/terminal.js.es6
@@ -1,62 +1,67 @@
-window.gl = window.gl || {};
+((global) => {
-gl.Terminal = class {
+ class GLTerminal {
- constructor(options) {
- this.options = options || {};
+ constructor(options) {
+ this.options = options || {};
- options.cursorBlink = options.cursorBlink || true;
- options.screenKeys = options.screenKeys || true;
- options.cols = options.cols || 100;
- options.rows = options.rows || 40;
- this.container = document.querySelector(options.selector);
+ options.cursorBlink = options.cursorBlink || true;
+ options.screenKeys = options.screenKeys || true;
+ options.cols = options.cols || 100;
+ options.rows = options.rows || 40;
+ this.container = document.querySelector(options.selector);
- this.setSocketUrl();
- this.createTerminal();
- }
+ this.setSocketUrl();
+ this.createTerminal();
+ }
- setSocketUrl() {
- const {protocol, hostname, port} = window.location;
- const wsProtocol = protocol === 'https:' ? 'wss://' : 'ws://';
+ setSocketUrl() {
+ const {protocol, hostname, port} = window.location;
+ const wsProtocol = protocol === 'https:' ? 'wss://' : 'ws://';
+ const path = this.container.dataset.projectPath;
- this.socketUrl = `${wsProtocol}${hostname}:${port}/gitlab-org/gitlab-ce/deployments/4/terminal_websocket`
- }
+ this.socketUrl = `${wsProtocol}${hostname}:${port}${path}/deployments/4/terminal_websocket`
+ }
- createTerminal() {
- this.terminal = new Terminal(this.options);
- this.socket = new WebSocket(this.socketUrl);
+ createTerminal() {
+ this.terminal = new Terminal(this.options);
+ this.socket = new WebSocket(this.socketUrl);
- this.terminal.open(this.container);
- this.terminal.fit();
+ this.terminal.open(this.container);
+ this.terminal.fit();
- this.socket.onopen = () => { this.runTerminal() };
- this.socket.onclose = () => { this.handleSocketFailure() };
- this.socket.onerror = () => { this.handleSocketFailure() };
- }
+ this.socket.onopen = () => { this.runTerminal() };
+ this.socket.onclose = () => { this.handleSocketFailure() };
+ this.socket.onerror = () => { this.handleSocketFailure() };
+ }
- runTerminal() {
- const {cols, rows} = this.terminal.proposeGeometry();
- const {offsetWidth, offsetHeight} = this.terminal.element;
+ runTerminal() {
+ const {cols, rows} = this.terminal.proposeGeometry();
+ const {offsetWidth, offsetHeight} = this.terminal.element;
- this.charWidth = Math.ceil(offsetWidth / cols);
- this.charHeight = Math.ceil(offsetHeight / rows);
+ this.charWidth = Math.ceil(offsetWidth / cols);
+ this.charHeight = Math.ceil(offsetHeight / rows);
- this.terminal.attach(this.socket);
- this.isTerminalInitialized = true;
- this.setTerminalSize(cols, rows);
- }
+ this.terminal.attach(this.socket);
+ this.isTerminalInitialized = true;
+ this.setTerminalSize(cols, rows);
+ }
- setTerminalSize (cols, rows) {
- const width = `${(cols * this.charWidth).toString()}px`;
- const height = `${(rows * this.charHeight).toString()}px`;
+ setTerminalSize (cols, rows) {
+ const width = `${(cols * this.charWidth).toString()}px`;
+ const height = `${(rows * this.charHeight).toString()}px`;
- this.container.style.width = width;
- this.container.style.height = height;
- this.terminal.resize(cols, rows);
- }
+ this.container.style.width = width;
+ this.container.style.height = height;
+ this.terminal.resize(cols, rows);
+ }
+
+ handleSocketFailure() {
+ console.error('There is a problem with Terminal connection. Please try again!');
+ }
- handleSocketFailure() {
- console.error('There is a problem with Terminal connection. Please try again!');
}
-}
+ global.Terminal = GLTerminal;
+
+})(window.gl || (window.gl = {}))
diff --git a/app/assets/javascripts/terminal/terminal_bundle.js.es6 b/app/assets/javascripts/terminal/terminal_bundle.js.es6
index fa476221a02..f451548abf7 100644
--- a/app/assets/javascripts/terminal/terminal_bundle.js.es6
+++ b/app/assets/javascripts/terminal/terminal_bundle.js.es6
@@ -3,7 +3,7 @@
//= require ./xterm/fit.js
//= require ./terminal.js
-$(function() {
+$(() => {
new gl.Terminal({
selector: '#terminal'
});
diff --git a/app/assets/stylesheets/framework/buttons.scss b/app/assets/stylesheets/framework/buttons.scss
index d11b2fe7ec2..371f1dfe1bb 100644
--- a/app/assets/stylesheets/framework/buttons.scss
+++ b/app/assets/stylesheets/framework/buttons.scss
@@ -219,6 +219,13 @@
}
}
+.btn-terminal{
+ svg{
+ height: 14px;
+ width: 18px;
+ }
+}
+
.btn-lg {
padding: 12px 20px;
}
diff --git a/app/controllers/projects/deployments_controller.rb b/app/controllers/projects/deployments_controller.rb
index 321f8324866..edbe624a31a 100644
--- a/app/controllers/projects/deployments_controller.rb
+++ b/app/controllers/projects/deployments_controller.rb
@@ -8,11 +8,18 @@ class Projects::DeploymentsController < Projects::ApplicationController
def terminal_websocket_authorize
Gitlab::Workhorse.verify_api_request!(request.headers)
- openshift_project = project.variables.find('CI_PROJECT_NAME').to_s
- openshift_app = project.variables.find('APP').to_s
- if openshift_project.present? && openshift_app.present?
+
+ variables = Hash[*%w[
+ openshift_project CI_PROJECT_NAME
+ openshift_app APP
+ openshift_server OPENSHIFT_SERVER
+ openshift_token OPENSHIFT_TOKEN
+ ]].map { |json_key, variable_key| [json_key, project.variables.find_by(key: variable_key)] }.to_h
+
+ # TODO: restrict access: this allows even 'guests' to have terminal access
+ if variables.values.all?(&:present?)
set_workhorse_internal_api_content_type
- render json: {openshift_app: openshift_app, openshift_project: openshift_project}
+ render json: variables.map { |k, v| [k, v.value] }.to_h
else
render text: 'Not found', status: 404
end
diff --git a/app/views/projects/deployments/_actions.haml b/app/views/projects/deployments/_actions.haml
index a11ddd2d80b..716eb8d2c12 100644
--- a/app/views/projects/deployments/_actions.haml
+++ b/app/views/projects/deployments/_actions.haml
@@ -5,11 +5,13 @@
= link_to external_url, target: '_blank', class: 'btn external-url' do
= icon('external-link')
+ - if can?(current_user, :update_deployment, deployment) && deployment.deployable
+ %a.btn.btn-default.btn-terminal{href: "deployments/#{deployment.id}/terminal"}
+ = custom_icon('icon_terminal')
+
- if can?(current_user, :create_deployment, deployment) && deployment.deployable && local_assigns.fetch(:show_actions, false)
- actions = deployment.manual_actions
- if actions.present?
- %a.btn.btn-default{href: 'deployments/1/terminal'}
- = custom_icon('icon_terminal')
.inline
.dropdown
%a.dropdown-new.btn.btn-default{type: 'button', 'data-toggle' => 'dropdown'}
diff --git a/app/views/projects/deployments/terminal.html.haml b/app/views/projects/deployments/terminal.html.haml
index 26ef7f06797..7384efa4899 100644
--- a/app/views/projects/deployments/terminal.html.haml
+++ b/app/views/projects/deployments/terminal.html.haml
@@ -9,10 +9,10 @@
- content_for :page_specific_javascripts do
= page_specific_javascript_tag("terminal/terminal_bundle.js")
- .terminal-container{ class: container_class }
+ .terminal-container{class: container_class}
%p.content-block
Environment:
%a{href: '#'} add information
- #terminal
+ #terminal{data:{project_path: project_path(@project)}}
diff --git a/app/views/shared/icons/_icon_terminal.svg b/app/views/shared/icons/_icon_terminal.svg
index 0f56540b684..c80f44c3edf 100644
--- a/app/views/shared/icons/_icon_terminal.svg
+++ b/app/views/shared/icons/_icon_terminal.svg
@@ -1 +1 @@
-<svg width="19" height="14" viewBox="0 0 19 14" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><title>Icon</title><defs><rect id="a" width="19" height="14" rx="2.5"/><mask id="b" x="0" y="0" width="19" height="14" fill="#fff"><use xlink:href="#a"/></mask></defs><g fill="none" fill-rule="evenodd"><rect fill="#848484" x="7.2" y="9.25" width="6.46" height="1.5" rx=".5"/><path d="M5.851 7.016L3.81 9.103a.503.503 0 0 0 .017.709l.35.334c.207.198.524.191.717-.006l2.687-2.748a.493.493 0 0 0 .137-.376.493.493 0 0 0-.137-.376L4.894 3.892a.507.507 0 0 0-.717-.006l-.35.334a.503.503 0 0 0-.017.709L5.85 7.016z" fill="#848484"/><use stroke="#848484" mask="url(#b)" stroke-width="2.5" xlink:href="#a"/></g></svg>
+<svg width="19" height="14" viewBox="0 0 19 14" xmlns="http://www.w3.org/2000/svg"><rect fill="#848484" x="7.2" y="9.25" width="6.46" height="1.5" rx=".5"/><path d="M5.851 7.016L3.81 9.103a.503.503 0 0 0 .017.709l.35.334c.207.198.524.191.717-.006l2.687-2.748a.493.493 0 0 0 .137-.376.493.493 0 0 0-.137-.376L4.894 3.892a.507.507 0 0 0-.717-.006l-.35.334a.503.503 0 0 0-.017.709L5.85 7.016z"/><path d="M1.25 11.497c0 .691.562 1.253 1.253 1.253h13.994c.694 0 1.253-.56 1.253-1.253V2.503c0-.691-.562-1.253-1.253-1.253H2.503c-.694 0-1.253.56-1.253 1.253v8.994zM2.503 0h13.994A2.504 2.504 0 0 1 19 2.503v8.994A2.501 2.501 0 0 1 16.497 14H2.503A2.504 2.504 0 0 1 0 11.497V2.503A2.501 2.501 0 0 1 2.503 0z"/></svg>