mirror of
https://github.com/dobin/lxd-webgui
synced 2025-10-05 15:42:50 +02:00
correctly handle and sync terminal sizes
This commit is contained in:
@@ -219,9 +219,15 @@ angular.module('myApp.container', ['ngRoute'])
|
||||
|
||||
container.isTerminalShown = true;
|
||||
|
||||
TerminalServices.getTerminal2(container.name).then(function(term) {
|
||||
container.terminal = term;
|
||||
term.open(document.getElementById('console' + container.name));
|
||||
// get JS terminal emulator
|
||||
container.terminal = TerminalServices.getJavascriptTerminal();
|
||||
container.terminal.open(document.getElementById('console' + container.name));
|
||||
|
||||
var initialGeometry = container.terminal.proposeGeometry();
|
||||
console.log("Rows: " + initialGeometry.rows + " Cols: " + initialGeometry.cols);
|
||||
|
||||
TerminalServices.getTerminal2(container.name, container.terminal, initialGeometry).then(function(term) {
|
||||
container.terminal.fit();
|
||||
});
|
||||
};
|
||||
|
||||
|
@@ -10,41 +10,44 @@
|
||||
</div>
|
||||
|
||||
<div class="row bottomline" ng-repeat="container in containers">
|
||||
<div class="col-md-3 col-xs-3"> {{container.name}} </div>
|
||||
<div class="col-md-1 col-xs-1"> {{container.status}} </div>
|
||||
<div class="col-md-2 col-xs-2"> {{container.architecture}} </div>
|
||||
<div class="col-md-1 col-xs-1"> {{container.stateful}} </div>
|
||||
<div class="col-md-1 col-xs-1">
|
||||
<div ng-if="container.status != 'Running'">
|
||||
<a class="btn btn-sm btn-success" ng-click="changeState(container, 'start')"><i
|
||||
class="glyphicon glyphicon-play"></i> Start</a>
|
||||
<div class="row">
|
||||
<div class="col-md-3 col-xs-3"> {{container.name}} </div>
|
||||
<div class="col-md-1 col-xs-1"> {{container.status}} </div>
|
||||
<div class="col-md-2 col-xs-2"> {{container.architecture}} </div>
|
||||
<div class="col-md-1 col-xs-1"> {{container.stateful}} </div>
|
||||
<div class="col-md-1 col-xs-1">
|
||||
<div ng-if="container.status != 'Running'">
|
||||
<a class="btn btn-sm btn-success" ng-click="changeState(container, 'start')"><i
|
||||
class="glyphicon glyphicon-play"></i> Start</a>
|
||||
</div>
|
||||
<div ng-if="container.status == 'Running'">
|
||||
<a class="btn btn-sm btn-danger" ng-click="changeState(container, 'stop')"><i
|
||||
class="glyphicon glyphicon-stop"></i> Stop</a>
|
||||
</div>
|
||||
</div>
|
||||
<div ng-if="container.status == 'Running'">
|
||||
<a class="btn btn-sm btn-danger" ng-click="changeState(container, 'stop')"><i
|
||||
class="glyphicon glyphicon-stop"></i> Stop</a>
|
||||
|
||||
<div class="col-md-4 col-xs-3">
|
||||
<a class="btn btn-sm btn-primary" href="#/container-view/{{container.name}}"><i
|
||||
class="glyphicon glyphicon-edit"></i> Details</a>
|
||||
<a class="btn btn-sm btn-primary" href="#/container-snapshots/{{container.name}}"><i
|
||||
class="glyphicon glyphicon-edit"></i> Snapshots</a>
|
||||
<a class="btn btn-sm btn-danger" ng-click="delete(container)"><i
|
||||
class="glyphicon glyphicon-remove"></i> Delete</a>
|
||||
|
||||
<a ng-show="container.status=='Running'" class="btn btn-sm btn-info" ng-click="showTerminal(container)"><i
|
||||
class="glyphicon glyphicon-modal-window"></i> Term</a>
|
||||
<a ng-show="container.status=='Running'" class="btn btn-sm btn-info" href="#/terminal/{{container.name}}"><i
|
||||
class="glyphicon glyphicon-modal-window"></i> Term Tab</a>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-md-4 col-xs-3">
|
||||
<a class="btn btn-sm btn-primary" href="#/container-view/{{container.name}}"><i
|
||||
class="glyphicon glyphicon-edit"></i> Details</a>
|
||||
<a class="btn btn-sm btn-primary" href="#/container-snapshots/{{container.name}}"><i
|
||||
class="glyphicon glyphicon-edit"></i> Snapshots</a>
|
||||
<a class="btn btn-sm btn-danger" ng-click="delete(container)"><i
|
||||
class="glyphicon glyphicon-remove"></i> Delete</a>
|
||||
|
||||
<a ng-show="container.status=='Running'" class="btn btn-sm btn-info" ng-click="showTerminal(container)"><i
|
||||
class="glyphicon glyphicon-modal-window"></i> Term</a>
|
||||
<a ng-show="container.status=='Running'" class="btn btn-sm btn-info" href="#/terminal/{{container.name}}"><i
|
||||
class="glyphicon glyphicon-modal-window"></i> Term Tab</a>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="col-md-6">
|
||||
<div id="console{{container.name}}" style="background-color:black;"></div>
|
||||
<div class="row">
|
||||
<div class="col-md-6">
|
||||
<div class="terminal" id="console{{container.name}}" style="background-color:black;"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
@@ -14,9 +14,18 @@ angular.module('myApp.terminal', ['ngRoute'])
|
||||
.controller('terminalPageCtrl', function ($scope, $routeParams, $filter, $location,
|
||||
TerminalServices, SettingServices) {
|
||||
$scope.containerName = $routeParams.containerName;
|
||||
var container = {};
|
||||
|
||||
TerminalServices.getTerminal2($scope.containerName).then(function(term) {
|
||||
term.open(document.getElementById('console'));
|
||||
// get JS terminal emulator
|
||||
container.terminal = TerminalServices.getJavascriptTerminal();
|
||||
container.terminal.open(document.getElementById('console'));
|
||||
|
||||
var initialGeometry = container.terminal.proposeGeometry();
|
||||
console.log("Rows: " + initialGeometry.rows + " Cols: " + initialGeometry.cols);
|
||||
|
||||
TerminalServices.getTerminal2($scope.containerName, container.terminal, initialGeometry).then(function(term) {
|
||||
container.terminal.fit();
|
||||
});
|
||||
|
||||
})
|
||||
;
|
||||
|
@@ -5,7 +5,21 @@ angular.module('myApp.remoteimage')
|
||||
function ($http, $q, SettingServices) {
|
||||
var obj = {};
|
||||
|
||||
obj.getTerminal = function(containerName) {
|
||||
|
||||
obj.getJavascriptTerminal = function() {
|
||||
var term = new Terminal({
|
||||
cols: 120,
|
||||
rows: 25,
|
||||
useStyle: true,
|
||||
screenKeys: true,
|
||||
cursorBlink: false
|
||||
});
|
||||
|
||||
return term;
|
||||
}
|
||||
|
||||
|
||||
obj.getTerminal = function(containerName, geometry) {
|
||||
var data = {
|
||||
"command": ["bash"],
|
||||
"environment": {
|
||||
@@ -14,7 +28,9 @@ angular.module('myApp.remoteimage')
|
||||
"USER": "root"
|
||||
},
|
||||
"wait-for-websocket": true,
|
||||
"interactive": true
|
||||
"interactive": true,
|
||||
"width": geometry.cols,
|
||||
"height": geometry.rows
|
||||
}
|
||||
|
||||
return $http.post(SettingServices.getLxdApiUrl() + '/containers/' + containerName + "/exec", data).then(function(data) {
|
||||
@@ -31,9 +47,8 @@ angular.module('myApp.remoteimage')
|
||||
}
|
||||
|
||||
|
||||
obj.getTerminal2 = function(containerName) {
|
||||
|
||||
return obj.getTerminal(containerName).then(function(data) {
|
||||
obj.getTerminal2 = function(containerName, term, geometry) {
|
||||
return obj.getTerminal(containerName, geometry).then(function(data) {
|
||||
var operationId = data.data.metadata.id;
|
||||
var secret = data.data.metadata.metadata.fds[0];
|
||||
|
||||
@@ -44,48 +59,36 @@ angular.module('myApp.remoteimage')
|
||||
|
||||
var sock = new WebSocket(wssurl);
|
||||
|
||||
var term = new Terminal({
|
||||
cols: 120,
|
||||
rows: 25,
|
||||
useStyle: true,
|
||||
screenKeys: true,
|
||||
cursorBlink: false
|
||||
});
|
||||
|
||||
term.on('data', function (data) {
|
||||
sock.send(new Blob([data]));
|
||||
});
|
||||
|
||||
|
||||
sock.onopen = function (e) {
|
||||
//container.terminal = term;
|
||||
//term.open(document.getElementById('console'));
|
||||
sock.onmessage = function (msg) {
|
||||
if (msg.data instanceof Blob) {
|
||||
var reader = new FileReader();
|
||||
reader.addEventListener('loadend', function () {
|
||||
term.write(reader.result);
|
||||
});
|
||||
reader.readAsBinaryString(msg.data);
|
||||
} else {
|
||||
term.write(msg.data);
|
||||
}
|
||||
|
||||
sock.onmessage = function (msg) {
|
||||
if (msg.data instanceof Blob) {
|
||||
var reader = new FileReader();
|
||||
reader.addEventListener('loadend', function () {
|
||||
term.write(reader.result);
|
||||
});
|
||||
reader.readAsBinaryString(msg.data);
|
||||
} else {
|
||||
term.write(msg.data);
|
||||
}
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
sock.onclose = function (msg) {
|
||||
console.log('WebSocket closed');
|
||||
term.destroy();
|
||||
};
|
||||
sock.onerror = function (err) {
|
||||
console.error(err);
|
||||
};
|
||||
};
|
||||
|
||||
return term;
|
||||
})
|
||||
sock.onclose = function (msg) {
|
||||
console.log('WebSocket closed');
|
||||
term.destroy();
|
||||
};
|
||||
sock.onerror = function (err) {
|
||||
console.error(err);
|
||||
};
|
||||
};
|
||||
|
||||
return term;
|
||||
})
|
||||
}
|
||||
|
||||
return obj;
|
||||
|
Reference in New Issue
Block a user