diff --git a/dashboard/src/components/FolderView.vue b/dashboard/src/components/FolderView.vue
index 33bb8cf67..c815c583f 100644
--- a/dashboard/src/components/FolderView.vue
+++ b/dashboard/src/components/FolderView.vue
@@ -521,7 +521,7 @@ onMounted(async () => {
-
+
diff --git a/dashboard/src/components/Terminal.vue b/dashboard/src/components/Terminal.vue
index 061de69f8..ee8b4f1d7 100644
--- a/dashboard/src/components/Terminal.vue
+++ b/dashboard/src/components/Terminal.vue
@@ -28,6 +28,7 @@ const showFilemanager = ref(false);
const manifestVersion = ref('');
const schedulerMenuModel = ref([]);
const id = ref('');
+const cwd = ref('');
const name = ref('');
const link = ref('');
const downloadFileDownloadUrl = ref('');
@@ -165,7 +166,9 @@ async function connect(retry = false) {
let execId;
try {
- const result = await fetcher.post(`${API_ORIGIN}/api/v1/apps/${id.value}/exec`, { cmd: [ '/bin/bash' ], tty: true, lang: 'C.UTF-8' }, { access_token: accessToken });
+ const execBody = { cmd: [ '/bin/bash' ], tty: true, lang: 'C.UTF-8' };
+ if (cwd.value) execBody.cwd = cwd.value;
+ const result = await fetcher.post(`${API_ORIGIN}/api/v1/apps/${id.value}/exec`, execBody, { access_token: accessToken });
execId = result.body.id;
} catch (error) {
console.error('Cannot create socket.', error);
@@ -216,6 +219,7 @@ onMounted(async () => {
const urlParams = new URLSearchParams(window.location.search);
id.value = urlParams.get('id');
+ cwd.value = urlParams.get('cwd') || '';
if (!id.value) {
console.error('No app id specified');
diff --git a/src/apps.js b/src/apps.js
index d84e9666e..4ef3fac7f 100644
--- a/src/apps.js
+++ b/src/apps.js
@@ -2725,6 +2725,8 @@ async function createExec(app, options) {
// currently the webterminal and cli sets C.UTF-8
if (options.lang) createOptions.Env = [ 'LANG=' + options.lang ];
+ if (options.cwd) createOptions.WorkingDir = options.cwd;
+
return await docker.createExec(app.containerId, createOptions);
}
diff --git a/src/routes/apps.js b/src/routes/apps.js
index d780eb3d0..354c58f00 100644
--- a/src/routes/apps.js
+++ b/src/routes/apps.js
@@ -838,9 +838,11 @@ async function createExec(req, res, next) {
if ('lang' in req.body && typeof req.body.lang !== 'string') return next(new HttpError(400, 'lang must be a string'));
+ if ('cwd' in req.body && typeof req.body.cwd !== 'string') return next(new HttpError(400, 'cwd must be a string'));
+
if (safe.query(req.resources.app, 'manifest.addons.docker') && req.user.role !== users.ROLE_OWNER) return next(new HttpError(403, '"owner" role is requied to exec app with docker addon'));
- const [error, id] = await safe(apps.createExec(req.resources.app, { cmd, tty, lang: req.body.lang }));
+ const [error, id] = await safe(apps.createExec(req.resources.app, { cmd, tty, lang: req.body.lang, cwd: req.body.cwd }));
if (error) return next(BoxError.toHttpError(error));
next(new HttpSuccess(200, { id }));