terminal: support addon injection
This commit is contained in:
@@ -8,6 +8,13 @@
|
||||
<span class="title">{{ name }}</span>
|
||||
</template>
|
||||
<template #right>
|
||||
|
||||
<!-- addon actions -->
|
||||
<Button severity="help" style="margin-right: 5px;" @click="terminalInject('mysql')" v-show="usesAddon('mysql')" :disabled="!connected" label="MySQL"/>
|
||||
<Button severity="help" style="margin-right: 5px;" @click="terminalInject('postgresql')" v-show="usesAddon('postgresql')" :disabled="!connected" label="Postgres"/>
|
||||
<Button severity="help" style="margin-right: 5px;" @click="terminalInject('mongodb')" v-show="usesAddon('mongodb')" :disabled="!connected" label="MongoDB"/>
|
||||
<Button severity="help" style="margin-right: 5px;" @click="terminalInject('redis')" v-show="usesAddon('redis')" :disabled="!connected" label="Redis"/>
|
||||
|
||||
<a style="margin-left: 20px; margin-right: 5px;" :href="'/frontend/logs.html?appId=' + id" target="_blank"><Button severity="secondary" icon="pi pi-align-left" :label="$t('logs.title')" /></a>
|
||||
<a style="margin-right: 5px;" :href="'/frontend/filemanager.html#/home/app/' + id" target="_blank"><Button type="button" severity="secondary" icon="pi pi-folder" :label="$t('filemanager.title')" /></a>
|
||||
<Button type="button" :label="$t('filemanager.toolbar.restartApp')" severity="secondary" icon="pi pi-sync" @click="onRestartApp" :loading="busyRestart"/>
|
||||
@@ -58,13 +65,57 @@ export default {
|
||||
apiOrigin: API_ORIGIN || '',
|
||||
appModel: null,
|
||||
busyRestart: false,
|
||||
connected: false,
|
||||
addons: {},
|
||||
manifestVersion: '',
|
||||
id: '',
|
||||
name: '',
|
||||
socket: null,
|
||||
terminal: null
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
onClear() {
|
||||
usesAddon(addon) {
|
||||
return !!Object.keys(this.addons).find(function (a) { return a === addon; });
|
||||
},
|
||||
terminalInject(addon, extra) {
|
||||
if (!this.socket) return;
|
||||
|
||||
let cmd = '';
|
||||
if (addon === 'mysql') {
|
||||
if (this.manifestVersion === 1) {
|
||||
cmd = 'mysql --user=${MYSQL_USERNAME} --password=${MYSQL_PASSWORD} --host=${MYSQL_HOST} ${MYSQL_DATABASE}';
|
||||
} else {
|
||||
cmd = 'mysql --user=${CLOUDRON_MYSQL_USERNAME} --password=${CLOUDRON_MYSQL_PASSWORD} --host=${CLOUDRON_MYSQL_HOST} ${CLOUDRON_MYSQL_DATABASE}';
|
||||
}
|
||||
} else if (addon === 'postgresql') {
|
||||
if (this.manifestVersion === 1) {
|
||||
cmd = 'PGPASSWORD=${POSTGRESQL_PASSWORD} psql -h ${POSTGRESQL_HOST} -p ${POSTGRESQL_PORT} -U ${POSTGRESQL_USERNAME} -d ${POSTGRESQL_DATABASE}';
|
||||
} else {
|
||||
cmd = 'PGPASSWORD=${CLOUDRON_POSTGRESQL_PASSWORD} psql -h ${CLOUDRON_POSTGRESQL_HOST} -p ${CLOUDRON_POSTGRESQL_PORT} -U ${CLOUDRON_POSTGRESQL_USERNAME} -d ${CLOUDRON_POSTGRESQL_DATABASE}';
|
||||
}
|
||||
} else if (addon === 'mongodb') {
|
||||
if (this.manifestVersion === 1) {
|
||||
cmd = 'mongo -u "${MONGODB_USERNAME}" -p "${MONGODB_PASSWORD}" ${MONGODB_HOST}:${MONGODB_PORT}/${MONGODB_DATABASE}';
|
||||
} else {
|
||||
cmd = 'mongosh -u "${CLOUDRON_MONGODB_USERNAME}" -p "${CLOUDRON_MONGODB_PASSWORD}" ${CLOUDRON_MONGODB_HOST}:${CLOUDRON_MONGODB_PORT}/${CLOUDRON_MONGODB_DATABASE}';
|
||||
}
|
||||
} else if (addon === 'redis') {
|
||||
if (this.manifestVersion === 1) {
|
||||
cmd = 'redis-cli -h "${REDIS_HOST}" -p "${REDIS_PORT}" -a "${REDIS_PASSWORD}"';
|
||||
} else {
|
||||
cmd = 'redis-cli -h "${CLOUDRON_REDIS_HOST}" -p "${CLOUDRON_REDIS_PORT}" -a "${CLOUDRON_REDIS_PASSWORD}" --no-auth-warning';
|
||||
}
|
||||
} else if (addon === 'scheduler' && extra) {
|
||||
cmd = extra.command;
|
||||
}
|
||||
|
||||
if (!cmd) return;
|
||||
|
||||
cmd += ' ';
|
||||
|
||||
this.socket.send(cmd);
|
||||
this.terminal.focus();
|
||||
},
|
||||
async onRestartApp() {
|
||||
if (this.type !== 'app') return;
|
||||
@@ -104,16 +155,22 @@ export default {
|
||||
|
||||
// websocket cannot use relative urls
|
||||
var url = `${this.apiOrigin.replace('https', 'wss')}/api/v1/apps/${this.id}/exec/${execId}/startws?tty=true&rows=${this.terminal.rows}&columns=${this.terminal.cols}&access_token=${this.accessToken}`;
|
||||
const socket = new WebSocket(url);
|
||||
this.socket = new WebSocket(url);
|
||||
|
||||
this.terminal.loadAddon(new AttachAddon(socket));
|
||||
this.terminal.loadAddon(new AttachAddon(this.socket));
|
||||
|
||||
socket.addEventListener('close', (event) => {
|
||||
this.socket.addEventListener('open', (event) => {
|
||||
this.connected = true;
|
||||
});
|
||||
|
||||
this.socket.addEventListener('close', (event) => {
|
||||
this.connected = false;
|
||||
console.log('Socket closed. Reconnecting...');
|
||||
return setTimeout(() => this.connect(true), 1000);
|
||||
});
|
||||
|
||||
socket.addEventListener('error', (error) => {
|
||||
this.socket.addEventListener('error', (error) => {
|
||||
this.connected = false;
|
||||
console.log('Socket error. Reconnecting...', error);
|
||||
return setTimeout(() => this.connect(true), 1000);
|
||||
});
|
||||
@@ -143,6 +200,8 @@ export default {
|
||||
try {
|
||||
const app = await this.appModel.get();
|
||||
this.name = `${app.label || app.fqdn} (${app.manifest.title})`;
|
||||
this.addons = app.manifest.addons;
|
||||
this.manifestVersion = app.manifest.manifestVersion;
|
||||
} catch (e) {
|
||||
console.error(`Failed to get app info for ${this.id}:`, e);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user