diff options
-rw-r--r-- | app/assets/javascripts/terminal/terminal.js.es6 | 95 | ||||
-rw-r--r-- | app/assets/javascripts/terminal/terminal_bundle.js.es6 | 2 | ||||
-rw-r--r-- | app/assets/stylesheets/framework/buttons.scss | 7 | ||||
-rw-r--r-- | app/controllers/projects/deployments_controller.rb | 15 | ||||
-rw-r--r-- | app/views/projects/deployments/_actions.haml | 6 | ||||
-rw-r--r-- | app/views/projects/deployments/terminal.html.haml | 4 | ||||
-rw-r--r-- | app/views/shared/icons/_icon_terminal.svg | 2 |
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> |