diff --git a/src/js/client.js b/src/js/client.js index 16cd8f2ea..3fd7ea8b6 100644 --- a/src/js/client.js +++ b/src/js/client.js @@ -786,6 +786,15 @@ angular.module('Application').service('Client', ['$http', '$interval', '$timeout }); }; + Client.prototype.createExec = function (id, options, callback) { + post('/api/v1/apps/' + id + '/exec', options, null, function (error, data, status) { + if (error) return callback(error); + if (status !== 200) return callback(new ClientError(status, data)); + + callback(null, data.id); + }); + }; + Client.prototype.version = function (callback) { get('/api/v1/cloudron/status', null, function (error, data, status) { if (error) return callback(error); diff --git a/src/js/terminal.js b/src/js/terminal.js index f0df7983c..ba90e07e2 100644 --- a/src/js/terminal.js +++ b/src/js/terminal.js @@ -146,24 +146,30 @@ angular.module('Application').controller('TerminalController', ['$scope', '$tran }); }; - function createTerminalSocket() { - try { - // websocket cannot use relative urls - var cmd = JSON.stringify([ '/bin/bash' ]); - var url = Client.apiOrigin.replace('https', 'wss') + '/api/v1/apps/' + $scope.selected.value + '/execws?tty=true&rows=' + $scope.terminal.rows + '&columns=' + $scope.terminal.cols + '&access_token=' + Client.getToken() + '&cmd=' + cmd; - $scope.terminalSocket = new WebSocket(url); - $scope.terminal.loadAddon(new AttachAddon.AttachAddon($scope.terminalSocket)); + function createTerminalSocket(callback) { + var appId = $scope.selected.value; - $scope.terminalSocket.onclose = function () { - // retry in one second - $scope.terminalReconnectTimeout = setTimeout(function () { - showTerminal(true); - }, 1000); - }; + Client.createExec(appId, { cmd: [ '/bin/bash' ], tty: true }, function (error, execId) { + if (error) return callback(error); - } catch (e) { - console.error(e); - } + try { + // websocket cannot use relative urls + var url = Client.apiOrigin.replace('https', 'wss') + '/api/v1/apps/' + appId + '/exec/' + execId + '/startws?tty=true&rows=' + $scope.terminal.rows + '&columns=' + $scope.terminal.cols + '&access_token=' + Client.getToken(); + $scope.terminalSocket = new WebSocket(url); + $scope.terminal.loadAddon(new AttachAddon.AttachAddon($scope.terminalSocket)); + + $scope.terminalSocket.onclose = function () { + // retry in one second + $scope.terminalReconnectTimeout = setTimeout(function () { + showTerminal(true); + }, 1000); + }; + + callback(); + } catch (e) { + callback(e); + } + }); } function refreshApp(id, callback) { @@ -220,7 +226,7 @@ angular.module('Application').controller('TerminalController', ['$scope', '$tran $scope.fitAddon.fit(); // create exec container after we fit() since we cannot resize exec container post-creation - createTerminalSocket(); + createTerminalSocket(function (error) { if (error) console.error(error); }); $scope.terminal.focus(); }, 1000); @@ -364,7 +370,7 @@ angular.module('Application').controller('TerminalController', ['$scope', '$tran // setup all the dialog focus handling ['downloadFileModal'].forEach(function (id) { $('#' + id).on('shown.bs.modal', function () { - $(this).find("[autofocus]:first").focus(); + $(this).find('[autofocus]:first').focus(); }); }); }]);