@rancher/shell 0.3.17 → 0.3.18
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/assets/translations/en-us.yaml +8 -4
- package/assets/translations/zh-hans.yaml +64 -8
- package/components/AsyncButton.vue +1 -1
- package/components/Inactivity.vue +10 -0
- package/components/LazyImage.vue +2 -2
- package/components/PromptRestore.vue +7 -5
- package/components/ResourceDetail/Masthead.vue +1 -1
- package/components/ResourceDetail/index.vue +4 -2
- package/components/__tests__/PromptRestore.test.ts +72 -0
- package/components/auth/AzureWarning.vue +1 -1
- package/components/fleet/FleetResources.vue +3 -64
- package/components/form/FileImageSelector.vue +9 -0
- package/components/form/FileSelector.vue +2 -1
- package/components/form/MatchExpressions.vue +1 -3
- package/components/form/__tests__/FileImageSelector.test.ts +42 -0
- package/components/form/__tests__/FileSelector.test.ts +76 -0
- package/components/formatter/ClusterProvider.vue +3 -1
- package/components/formatter/__tests__/ClusterProvider.test.ts +24 -0
- package/components/nav/WindowManager/ContainerShell.vue +60 -36
- package/components/nav/WindowManager/__tests__/ContainerShell.test.ts +561 -0
- package/config/labels-annotations.js +2 -1
- package/config/persistentVolume.ts +108 -0
- package/config/product/manager.js +5 -1
- package/config/types.js +2 -0
- package/core/plugin-helpers.js +19 -3
- package/core/types.ts +4 -0
- package/detail/fleet.cattle.io.gitrepo.vue +10 -2
- package/detail/pod.vue +36 -3
- package/detail/workload/index.vue +40 -9
- package/edit/__tests__/ui.cattle.io.navlink.test.ts +110 -0
- package/edit/fleet.cattle.io.clustergroup.vue +14 -3
- package/edit/persistentvolume/__tests__/persistentvolume.test.ts +82 -0
- package/edit/persistentvolume/index.vue +2 -1
- package/edit/persistentvolume/plugins/csi.vue +3 -1
- package/edit/persistentvolume/plugins/longhorn.vue +12 -12
- package/edit/provisioning.cattle.io.cluster/RegistryConfigs.vue +15 -11
- package/edit/provisioning.cattle.io.cluster/index.vue +1 -1
- package/edit/provisioning.cattle.io.cluster/rke2.vue +5 -1
- package/edit/storage.k8s.io.storageclass/index.vue +1 -2
- package/edit/ui.cattle.io.navlink.vue +213 -187
- package/layouts/default.vue +1 -1
- package/list/group.principal.vue +1 -1
- package/middleware/authenticated.js +12 -4
- package/mixins/create-edit-view/impl.js +2 -2
- package/models/chart.js +1 -1
- package/models/fleet.cattle.io.cluster.js +33 -4
- package/models/fleet.cattle.io.gitrepo.js +112 -38
- package/models/management.cattle.io.kontainerdriver.js +14 -0
- package/models/persistentvolume.js +2 -111
- package/models/pod.js +30 -0
- package/models/rke.cattle.io.etcdsnapshot.js +10 -7
- package/package.json +1 -1
- package/pages/c/_cluster/auth/group.principal/assign-edit.vue +1 -1
- package/pages/c/_cluster/auth/roles/index.vue +1 -1
- package/pages/c/_cluster/explorer/index.vue +1 -1
- package/pages/c/_cluster/manager/cloudCredential/_id.vue +0 -1
- package/pages/c/_cluster/manager/cloudCredential/create.vue +0 -1
- package/pages/c/_cluster/settings/brand.vue +11 -8
- package/pages/c/_cluster/uiplugins/index.vue +9 -4
- package/pages/home.vue +1 -1
- package/plugins/dashboard-store/__tests__/actions.spec.ts +165 -0
- package/plugins/dashboard-store/__tests__/getters.spec.ts +100 -0
- package/plugins/dashboard-store/__tests__/{mutations.spec.js → mutations.spec.ts} +2 -2
- package/plugins/dashboard-store/actions.js +1 -1
- package/plugins/dashboard-store/resource-class.js +4 -0
- package/plugins/steve/__tests__/getters.spec.ts +93 -0
- package/plugins/steve/getters.js +21 -1
- package/plugins/steve/subscribe.js +1 -3
- package/rancher-components/components/BadgeState/BadgeState.spec.ts +12 -0
- package/rancher-components/components/BadgeState/BadgeState.vue +111 -0
- package/rancher-components/components/BadgeState/index.ts +1 -0
- package/rancher-components/components/Banner/Banner.test.ts +63 -0
- package/rancher-components/components/Banner/Banner.vue +244 -0
- package/rancher-components/components/Banner/index.ts +1 -0
- package/rancher-components/components/Card/Card.test.ts +37 -0
- package/rancher-components/components/Card/Card.vue +167 -0
- package/rancher-components/components/Card/index.ts +1 -0
- package/rancher-components/components/Form/Checkbox/Checkbox.test.ts +68 -0
- package/rancher-components/components/Form/Checkbox/Checkbox.vue +420 -0
- package/rancher-components/components/Form/Checkbox/index.ts +1 -0
- package/rancher-components/components/Form/LabeledInput/LabeledInput.test.ts +23 -0
- package/rancher-components/components/Form/LabeledInput/LabeledInput.vue +355 -0
- package/rancher-components/components/Form/LabeledInput/index.ts +1 -0
- package/rancher-components/components/Form/Radio/RadioButton.test.ts +31 -0
- package/rancher-components/components/Form/Radio/RadioButton.vue +287 -0
- package/rancher-components/components/Form/Radio/RadioGroup.vue +254 -0
- package/rancher-components/components/Form/Radio/index.ts +2 -0
- package/rancher-components/components/Form/TextArea/TextAreaAutoGrow.vue +170 -0
- package/rancher-components/components/Form/TextArea/index.ts +1 -0
- package/rancher-components/components/Form/ToggleSwitch/ToggleSwitch.test.ts +94 -0
- package/rancher-components/components/Form/ToggleSwitch/ToggleSwitch.vue +149 -0
- package/rancher-components/components/Form/ToggleSwitch/index.ts +1 -0
- package/rancher-components/components/Form/index.ts +5 -0
- package/rancher-components/components/LabeledTooltip/LabeledTooltip.vue +151 -0
- package/rancher-components/components/LabeledTooltip/index.ts +1 -0
- package/rancher-components/components/StringList/StringList.test.ts +484 -0
- package/rancher-components/components/StringList/StringList.vue +611 -0
- package/rancher-components/components/StringList/index.ts +1 -0
- package/scripts/typegen.sh +10 -2
- package/store/index.js +1 -3
- package/store/store-types.js +2 -0
- package/types/api.d.ts +1 -0
- package/types/fleet.d.ts +1 -0
- package/types/shell/index.d.ts +695 -2
- package/types/userPreferences.d.ts +1 -1
- package/utils/__mocks__/socket.js +21 -0
- package/utils/grafana.js +23 -11
- package/utils/selector.js +2 -1
- package/utils/validators/formRules/index.ts +3 -3
- package/plugins/steve/urloptions.js +0 -47
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
/* eslint-disable jest/no-hooks */
|
|
2
|
+
import FileSelector from '@shell/components/form/FileSelector';
|
|
3
|
+
import { mount } from '@vue/test-utils';
|
|
4
|
+
|
|
5
|
+
describe('component: FileSelector', () => {
|
|
6
|
+
let wrapper: any;
|
|
7
|
+
|
|
8
|
+
beforeEach(() => {
|
|
9
|
+
jest.restoreAllMocks();
|
|
10
|
+
});
|
|
11
|
+
afterEach(() => {
|
|
12
|
+
wrapper.destroy();
|
|
13
|
+
});
|
|
14
|
+
|
|
15
|
+
const binaryString = Buffer.from('/9j/4AAQSkZJRgABAQAASABIAAD/4QCARXhpZgAATU0AKgAAAAgABQESAAMAAAABAAEAAAEaAAUAAAABAAAASgEbAAUAAAABAAAAUgEoAAMAAAABAAIAAIdpAAQAAAABAAAAWgAAAAAAAABIAAAAAQAAAEgAAAABAAKgAgAEAAAAAQAAADmgAwAEAAAAAQAAAFEAAAAA/+0AOFBob3Rvc2hvcCAzLjAAOEJJTQQEAAAAAAAAOEJJTQQlAAAAAAAQ1B2M2Y8AsgTpgAmY7PhCfv/iAihJQ0NfUFJPRklMRQABAQAAAhgAAAAABDAAAG1udHJSR0IgWFlaIAAAAAAAAAAAAAAAAGFjc3AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD21gABAAAAANMtAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACWRlc2MAAADwAAAAdHJYWVoAAAFkAAAAFGdYWVoAAAF4AAAAFGJYWVoAAAGMAAAAFHJUUkMAAAGgAAAAKGdUUkMAAAGgAAAAKGJUUkMAAAGgAAAAKHd0cHQAAAHIAAAAFGNwcnQAAAHcAAAAPG1sdWMAAAAAAAAAAQAAAAxlblVTAAAAWAAAABwAcwBSAEcAQgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAWFlaIAAAAAAAAG+iAAA49QAAA5BYWVogAAAAAAAAYpkAALeFAAAY2lhZWiAAAAAAAAAkoAAAD4QAALbPcGFyYQAAAAAABAAAAAJmZgAA8qcAAA1ZAAAT0AAAClsAAAAAAAAAAFhZWiAAAAAAAAD21gABAAAAANMtbWx1YwAAAAAAAAABAAAADGVuVVMAAAAgAAAAHABHAG8AbwBnAGwAZQAgAEkAbgBjAC4AIAAyADAAMQA2/8AAEQgAUQA5AwEiAAIRAQMRAf/EAB8AAAEFAQEBAQEBAAAAAAAAAAABAgMEBQYHCAkKC//EALUQAAIBAwMCBAMFBQQEAAABfQECAwAEEQUSITFBBhNRYQcicRQygZGhCCNCscEVUtHwJDNicoIJChYXGBkaJSYnKCkqNDU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6g4SFhoeIiYqSk5SVlpeYmZqio6Slpqeoqaqys7S1tre4ubrCw8TFxsfIycrS09TV1tfY2drh4uPk5ebn6Onq8fLz9PX29/j5+v/EAB8BAAMBAQEBAQEBAQEAAAAAAAABAgMEBQYHCAkKC//EALURAAIBAgQEAwQHBQQEAAECdwABAgMRBAUhMQYSQVEHYXETIjKBCBRCkaGxwQkjM1LwFWJy0QoWJDThJfEXGBkaJicoKSo1Njc4OTpDREVGR0hJSlNUVVZXWFlaY2RlZmdoaWpzdHV2d3h5eoKDhIWGh4iJipKTlJWWl5iZmqKjpKWmp6ipqrKztLW2t7i5usLDxMXGx8jJytLT1NXW19jZ2uLj5OXm5+jp6vLz9PX29/j5+v/bAEMAEAsMDgwKEA4NDhIREBMYKBoYFhYYMSMlHSg6Mz08OTM4N0BIXE5ARFdFNzhQbVFXX2JnaGc+TXF5cGR4XGVnY//bAEMBERISGBUYLxoaL2NCOEJjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY//dAAQABP/aAAwDAQACEQMRAD8AdRRRX0B4gUUUUAFFFFABRRRQB//QdRRRX0B4gUUUUAFFFFABRRRQB//RdRRRX0B4gUUUUAFFFFABRRRQB//SdRRRX0B4gUUUUAFFFFABRRRQB//TdRRRX0B4gUUUUAFFFFAwooooA//UdRRRX0B4gUUUUAFFFFAwooooA//Z', 'base64'); // Binary data string
|
|
16
|
+
const jpegBlobFile = new Blob([binaryString], { type: 'image/jpeg' });
|
|
17
|
+
const obj = { hello: 'world' };
|
|
18
|
+
const jsonBlobFile = new Blob([JSON.stringify(obj, null, 2)], { type: 'application/json' });
|
|
19
|
+
|
|
20
|
+
it('should render', () => {
|
|
21
|
+
wrapper = mount(FileSelector, {
|
|
22
|
+
propsData: { label: 'upload' },
|
|
23
|
+
mocks: {},
|
|
24
|
+
methods: {},
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
const uploadButton = wrapper.find('.btn');
|
|
28
|
+
|
|
29
|
+
expect(wrapper.isVisible()).toBe(true);
|
|
30
|
+
expect(uploadButton.exists()).toBeTruthy();
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
it('should succeed when loading an image', async() => {
|
|
34
|
+
wrapper = mount(FileSelector, {
|
|
35
|
+
propsData: { label: 'upload', accept: 'image/jpeg,image/png,image/svg+xml' },
|
|
36
|
+
mocks: {},
|
|
37
|
+
methods: {},
|
|
38
|
+
});
|
|
39
|
+
const readAsTextSpy = jest.spyOn(FileReader.prototype, 'readAsText');
|
|
40
|
+
|
|
41
|
+
const event = {
|
|
42
|
+
target: {
|
|
43
|
+
files: [
|
|
44
|
+
jpegBlobFile
|
|
45
|
+
]
|
|
46
|
+
}
|
|
47
|
+
};
|
|
48
|
+
|
|
49
|
+
await wrapper.vm.fileChange(event);
|
|
50
|
+
expect(wrapper.emitted('selected')).toHaveLength(1);
|
|
51
|
+
expect(readAsTextSpy).toHaveBeenCalledWith(jpegBlobFile);
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
it('should fail when file is too big', async() => {
|
|
55
|
+
wrapper = mount(FileSelector, {
|
|
56
|
+
propsData: {
|
|
57
|
+
label: 'upload', accept: 'image/jpeg,image/png,image/svg+xml', byteLimit: 10
|
|
58
|
+
},
|
|
59
|
+
mocks: {},
|
|
60
|
+
methods: {},
|
|
61
|
+
});
|
|
62
|
+
const readAsTextSpy = jest.spyOn(FileReader.prototype, 'readAsText');
|
|
63
|
+
|
|
64
|
+
const event = {
|
|
65
|
+
target: {
|
|
66
|
+
files: [
|
|
67
|
+
jpegBlobFile
|
|
68
|
+
]
|
|
69
|
+
}
|
|
70
|
+
};
|
|
71
|
+
|
|
72
|
+
await wrapper.vm.fileChange(event);
|
|
73
|
+
expect(wrapper.emitted('error')).toHaveLength(1);
|
|
74
|
+
expect(readAsTextSpy).not.toHaveBeenCalledWith(jsonBlobFile);
|
|
75
|
+
});
|
|
76
|
+
});
|
|
@@ -12,7 +12,9 @@ export default {
|
|
|
12
12
|
// model doesn't work for imported K3s clusters, in
|
|
13
13
|
// which case it returns 'k3s' instead of 'imported.'
|
|
14
14
|
// This is the workaround.
|
|
15
|
-
isImported: props.row
|
|
15
|
+
isImported: props.row?.mgmt?.providerForEmberParam === 'import' ||
|
|
16
|
+
// when imported cluster is Google GKE
|
|
17
|
+
props.row?.mgmt?.spec?.gkeConfig?.imported
|
|
16
18
|
};
|
|
17
19
|
},
|
|
18
20
|
};
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { mount } from '@vue/test-utils';
|
|
2
|
+
import ClusterProvider from '@shell/components/formatter/ClusterProvider.vue';
|
|
3
|
+
|
|
4
|
+
describe('component: ClusterProvider', () => {
|
|
5
|
+
const importedGkeClusterInfo = { mgmt: { spec: { gkeConfig: { imported: true } } } };
|
|
6
|
+
const notImportedGkeClusterInfo = { mgmt: { spec: { gkeConfig: { imported: false } } } };
|
|
7
|
+
const importedClusterInfoWithProviderForEmberParam = { mgmt: { providerForEmberParam: 'import' } };
|
|
8
|
+
|
|
9
|
+
describe('isImported', () => {
|
|
10
|
+
const testCases = [
|
|
11
|
+
[importedGkeClusterInfo, true],
|
|
12
|
+
[notImportedGkeClusterInfo, false],
|
|
13
|
+
[importedClusterInfoWithProviderForEmberParam, true],
|
|
14
|
+
[{}, undefined],
|
|
15
|
+
];
|
|
16
|
+
|
|
17
|
+
it.each(testCases)('should return the isImported value properly based on the props data', (row, expected) => {
|
|
18
|
+
const wrapper = mount(ClusterProvider, { propsData: { row } });
|
|
19
|
+
|
|
20
|
+
expect(wrapper.vm.$data.isImported).toBe(expected);
|
|
21
|
+
}
|
|
22
|
+
);
|
|
23
|
+
});
|
|
24
|
+
});
|
|
@@ -3,7 +3,6 @@ import { allHash } from '@shell/utils/promise';
|
|
|
3
3
|
import { addParams } from '@shell/utils/url';
|
|
4
4
|
import { base64Decode, base64Encode } from '@shell/utils/crypto';
|
|
5
5
|
import Select from '@shell/components/form/Select';
|
|
6
|
-
import isEmpty from 'lodash/isEmpty';
|
|
7
6
|
import { NODE } from '@shell/config/types';
|
|
8
7
|
|
|
9
8
|
import Socket, {
|
|
@@ -16,11 +15,14 @@ import Socket, {
|
|
|
16
15
|
} from '@shell/utils/socket';
|
|
17
16
|
import Window from './Window';
|
|
18
17
|
|
|
19
|
-
const
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
]
|
|
18
|
+
const commands = {
|
|
19
|
+
linux: [
|
|
20
|
+
'/bin/sh',
|
|
21
|
+
'-c',
|
|
22
|
+
'TERM=xterm-256color; export TERM; [ -x /bin/bash ] && ([ -x /usr/bin/script ] && /usr/bin/script -q -c "/bin/bash" /dev/null || exec /bin/bash) || exec /bin/sh',
|
|
23
|
+
],
|
|
24
|
+
windows: ['cmd']
|
|
25
|
+
};
|
|
24
26
|
|
|
25
27
|
export default {
|
|
26
28
|
components: { Window, Select },
|
|
@@ -40,8 +42,8 @@ export default {
|
|
|
40
42
|
|
|
41
43
|
// The height of the window
|
|
42
44
|
height: {
|
|
43
|
-
type:
|
|
44
|
-
|
|
45
|
+
type: Number,
|
|
46
|
+
default: undefined,
|
|
45
47
|
},
|
|
46
48
|
|
|
47
49
|
// The width of the window
|
|
@@ -82,6 +84,10 @@ export default {
|
|
|
82
84
|
backlog: [],
|
|
83
85
|
node: null,
|
|
84
86
|
keepAliveTimer: null,
|
|
87
|
+
errorMsg: '',
|
|
88
|
+
backupShells: ['linux', 'windows'],
|
|
89
|
+
os: undefined,
|
|
90
|
+
retries: 0
|
|
85
91
|
};
|
|
86
92
|
},
|
|
87
93
|
|
|
@@ -120,7 +126,16 @@ export default {
|
|
|
120
126
|
},
|
|
121
127
|
|
|
122
128
|
async mounted() {
|
|
123
|
-
|
|
129
|
+
const nodeId = this.pod.spec?.nodeName;
|
|
130
|
+
|
|
131
|
+
try {
|
|
132
|
+
const schema = this.$store.getters[`cluster/schemaFor`](NODE);
|
|
133
|
+
|
|
134
|
+
if (schema) {
|
|
135
|
+
await this.$store.dispatch('cluster/find', { type: NODE, id: nodeId });
|
|
136
|
+
}
|
|
137
|
+
} catch {}
|
|
138
|
+
|
|
124
139
|
await this.setupTerminal();
|
|
125
140
|
await this.connect();
|
|
126
141
|
|
|
@@ -131,26 +146,6 @@ export default {
|
|
|
131
146
|
},
|
|
132
147
|
|
|
133
148
|
methods: {
|
|
134
|
-
async fetchNode() {
|
|
135
|
-
if (this.node) {
|
|
136
|
-
return;
|
|
137
|
-
}
|
|
138
|
-
|
|
139
|
-
const nodeId = this.pod.spec?.nodeName;
|
|
140
|
-
|
|
141
|
-
if ( !nodeId ) {
|
|
142
|
-
return;
|
|
143
|
-
}
|
|
144
|
-
|
|
145
|
-
try {
|
|
146
|
-
this.node = await this.$store.dispatch('cluster/find', {
|
|
147
|
-
type: NODE,
|
|
148
|
-
id: nodeId,
|
|
149
|
-
});
|
|
150
|
-
} catch (e) {
|
|
151
|
-
console.error('Failed to fetch node', nodeId); // eslint-disable-line no-console
|
|
152
|
-
}
|
|
153
|
-
},
|
|
154
149
|
async setupTerminal() {
|
|
155
150
|
const docStyle = getComputedStyle(document.querySelector('body'));
|
|
156
151
|
const xterm = await import(/* webpackChunkName: "xterm" */ 'xterm');
|
|
@@ -220,11 +215,11 @@ export default {
|
|
|
220
215
|
return;
|
|
221
216
|
}
|
|
222
217
|
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
218
|
+
if (this.pod.os) {
|
|
219
|
+
this.os = this.pod.os;
|
|
220
|
+
this.backupShells = this.backupShells.filter((shell) => shell !== this.pod.os);
|
|
221
|
+
} else {
|
|
222
|
+
this.os = this.backupShells.shift();
|
|
228
223
|
}
|
|
229
224
|
|
|
230
225
|
const url = addParams(
|
|
@@ -235,7 +230,7 @@ export default {
|
|
|
235
230
|
stdin: 1,
|
|
236
231
|
stderr: 1,
|
|
237
232
|
tty: 1,
|
|
238
|
-
command:
|
|
233
|
+
command: commands[this.os],
|
|
239
234
|
}
|
|
240
235
|
);
|
|
241
236
|
|
|
@@ -260,6 +255,7 @@ export default {
|
|
|
260
255
|
this.socket.addEventListener(EVENT_CONNECTING, (e) => {
|
|
261
256
|
this.isOpen = false;
|
|
262
257
|
this.isOpening = true;
|
|
258
|
+
this.errorMsg = '';
|
|
263
259
|
});
|
|
264
260
|
|
|
265
261
|
this.socket.addEventListener(EVENT_CONNECT_ERROR, (e) => {
|
|
@@ -282,16 +278,44 @@ export default {
|
|
|
282
278
|
this.socket.addEventListener(EVENT_DISCONNECTED, (e) => {
|
|
283
279
|
this.isOpen = false;
|
|
284
280
|
this.isOpening = false;
|
|
281
|
+
|
|
282
|
+
// If we had an error message, try connecting with the next command
|
|
283
|
+
if (this.errorMsg) {
|
|
284
|
+
this.terminal.write(this.errorMsg);
|
|
285
|
+
if (this.backupShells.length && this.retries < 2) {
|
|
286
|
+
this.retries++;
|
|
287
|
+
// we're not really counting on this being a reactive change so there's no need to fire the whole action
|
|
288
|
+
this.pod.os = undefined;
|
|
289
|
+
// the pod will still return an os if one's been defined in the node so we'll skip the backups if that's the case and rely on retry count to break the retry loop
|
|
290
|
+
if (!this.pod.os) {
|
|
291
|
+
this.os = this.backupShells.shift();
|
|
292
|
+
}
|
|
293
|
+
this.connect();
|
|
294
|
+
} else {
|
|
295
|
+
// Output an message to let he user know none of the shell commands worked
|
|
296
|
+
this.terminal.write(this.t('wm.containerShell.failed'));
|
|
297
|
+
}
|
|
298
|
+
}
|
|
285
299
|
});
|
|
286
300
|
|
|
287
301
|
this.socket.addEventListener(EVENT_MESSAGE, (e) => {
|
|
288
302
|
const type = e.detail.data.substr(0, 1);
|
|
289
303
|
const msg = base64Decode(e.detail.data.substr(1));
|
|
290
304
|
|
|
305
|
+
this.errorMsg = '';
|
|
306
|
+
|
|
291
307
|
if (`${ type }` === '1') {
|
|
308
|
+
if (msg) {
|
|
309
|
+
// we're not really counting on this being a reactive change so there's no need to fire the whole action
|
|
310
|
+
this.pod.os = this.os;
|
|
311
|
+
}
|
|
292
312
|
this.terminal.write(msg);
|
|
293
313
|
} else {
|
|
294
314
|
console.error(msg); // eslint-disable-line no-console
|
|
315
|
+
|
|
316
|
+
if (`${ type }` === '3') {
|
|
317
|
+
this.errorMsg = msg;
|
|
318
|
+
}
|
|
295
319
|
}
|
|
296
320
|
});
|
|
297
321
|
|
|
@@ -316,7 +340,7 @@ export default {
|
|
|
316
340
|
|
|
317
341
|
this.fitAddon.fit();
|
|
318
342
|
|
|
319
|
-
const { rows, cols } = this.fitAddon.proposeDimensions();
|
|
343
|
+
const { rows, cols } = this.fitAddon.proposeDimensions() || {};
|
|
320
344
|
|
|
321
345
|
if (!this.isOpen) {
|
|
322
346
|
return;
|