Merge "feat: Adding terminal feature to Zun detail page."
This commit is contained in:
commit
f57e8e6edc
@ -0,0 +1,4 @@
|
|||||||
|
---
|
||||||
|
features:
|
||||||
|
- |
|
||||||
|
Adding terminal feature to Zun detail page.
|
@ -66,6 +66,10 @@ export class ZunClient extends Base {
|
|||||||
key: 'execute',
|
key: 'execute',
|
||||||
method: 'post',
|
method: 'post',
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
key: 'attach',
|
||||||
|
method: 'get',
|
||||||
|
},
|
||||||
{
|
{
|
||||||
key: 'network_attach',
|
key: 'network_attach',
|
||||||
method: 'post',
|
method: 'post',
|
||||||
|
@ -0,0 +1,78 @@
|
|||||||
|
// 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.
|
||||||
|
|
||||||
|
import React, { useEffect } from "react";
|
||||||
|
import globalContainersStore from 'src/stores/zun/containers';
|
||||||
|
|
||||||
|
export default function Console(props) {
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
globalContainersStore.attach(props.detail.uuid).then((res) => {
|
||||||
|
const head = document.head;
|
||||||
|
|
||||||
|
const xtermCssLink = document.createElement("link");
|
||||||
|
xtermCssLink.rel = "stylesheet";
|
||||||
|
xtermCssLink.href = "https://cdn.jsdelivr.net/npm/xterm@4.19.0/css/xterm.css";
|
||||||
|
head.appendChild(xtermCssLink);
|
||||||
|
|
||||||
|
|
||||||
|
const xtermScript = document.createElement("script");
|
||||||
|
xtermScript.src = "https://cdnjs.cloudflare.com/ajax/libs/xterm/3.14.5/xterm.min.js";
|
||||||
|
|
||||||
|
xtermScript.onload = () => {
|
||||||
|
const term = new window.Terminal({
|
||||||
|
cursorBlink: true,
|
||||||
|
});
|
||||||
|
term.write(" >$ ");
|
||||||
|
term.open(document.getElementById('terminal'));
|
||||||
|
let socket = new WebSocket(res, ['binary', 'base64']);
|
||||||
|
term.on('data', function (data) {
|
||||||
|
socket.send(str2ab(data));
|
||||||
|
});
|
||||||
|
socket.onmessage = function (e) {
|
||||||
|
if (e.data instanceof Blob) {
|
||||||
|
let f = new FileReader();
|
||||||
|
f.onload = function () {
|
||||||
|
term.write(f.result);
|
||||||
|
};
|
||||||
|
f.readAsText(e.data);
|
||||||
|
} else {
|
||||||
|
term.write(e.data);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
function str2ab(str) {
|
||||||
|
let buf = new ArrayBuffer(str.length); // 2 bytes for each char
|
||||||
|
let bufView = new Uint8Array(buf);
|
||||||
|
for (let i = 0, strLen = str.length; i < strLen; i++) {
|
||||||
|
bufView[i] = str.charCodeAt(i);
|
||||||
|
}
|
||||||
|
return buf;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
head.appendChild(xtermScript);
|
||||||
|
|
||||||
|
return () => {
|
||||||
|
head.removeChild(xtermCssLink);
|
||||||
|
head.removeChild(xtermScript);
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<div id="terminal">
|
||||||
|
</div>
|
||||||
|
</div >
|
||||||
|
);
|
||||||
|
|
||||||
|
}
|
@ -19,6 +19,7 @@ import actionConfigs from '../actions';
|
|||||||
import BaseDetail from './BaseDetail';
|
import BaseDetail from './BaseDetail';
|
||||||
import ActionLogs from './ActionLogs';
|
import ActionLogs from './ActionLogs';
|
||||||
import Logs from './Logs';
|
import Logs from './Logs';
|
||||||
|
import Console from './Console';
|
||||||
|
|
||||||
export class ContainerDetail extends Base {
|
export class ContainerDetail extends Base {
|
||||||
init() {
|
init() {
|
||||||
@ -84,6 +85,13 @@ export class ContainerDetail extends Base {
|
|||||||
component: Logs,
|
component: Logs,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
if (this.detailData.interactive === true) {
|
||||||
|
items.push({
|
||||||
|
title: t('Console'),
|
||||||
|
key: 'console',
|
||||||
|
component: Console,
|
||||||
|
});
|
||||||
|
}
|
||||||
return items;
|
return items;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -98,6 +98,11 @@ export class ContainersStore extends Base {
|
|||||||
return this.client.execute(id, data);
|
return this.client.execute(id, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@action
|
||||||
|
async attach(id) {
|
||||||
|
return this.client.attach(id);
|
||||||
|
}
|
||||||
|
|
||||||
@action
|
@action
|
||||||
async attachNetwork(id, data) {
|
async attachNetwork(id, data) {
|
||||||
return this.client.network_attach(id, null, data);
|
return this.client.network_attach(id, null, data);
|
||||||
|
Loading…
Reference in New Issue
Block a user