Skip to content

Commit 65afbcb

Browse files
committed
feat(instance): 为 instance exec 命令添加 --shell 和 --workdir 参数
- 新增 --shell 参数:支持指定使用的 shell(如 /bin/sh, /bin/bash),解决 Alpine 等镜像只有 sh 的问题 - 新增 --workdir 参数:支持自定义初始工作目录,解决默认强制进入 /code 目录的问题 - 新增 --no-workdir 参数:不 cd 到任何目录,直接使用容器的 WORKDIR - 保持完全向后兼容:不传参数时行为与之前完全一致 问题背景: 1. 当前 instance exec 硬编码使用 bash,导致只有 sh 的镜像(如 Alpine)无法使用 2. 默认强制尝试进入 /code 目录,对于使用其他工作目录的容器不够灵活 解决方案: 1. --shell 参数允许用户指定 shell 类型,默认值为 bash 2. --workdir 参数支持三种模式: - 不指定:默认行为,尝试 cd /code || cd / - 指定路径:cd 到指定目录 - 空字符串或 --no-workdir:不执行 cd,直接使用容器默认 WORKDIR Signed-off-by: hugh.li <hugh.li@foxmail.com>
1 parent 918bcbd commit 65afbcb

File tree

2 files changed

+31
-5
lines changed

2 files changed

+31
-5
lines changed

src/commands-help/instance.ts

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,16 @@ export default {
1010
Examples with Yaml:
1111
$ s instance exec --instance-id c-6******-27c4833c325445879a28 --cmd "ls -lh"
1212
$ s instance exec --instance-id c-6******-27c4833c325445879a28
13+
$ s instance exec --instance-id c-6******-27c4833c325445879a28 --shell /bin/sh
14+
$ s instance exec --instance-id c-6******-27c4833c325445879a28 --workdir /app
15+
$ s instance exec --instance-id c-6******-27c4833c325445879a28 --no-workdir
1316
$ s instance exec --instance-id \`s invoke | grep "Invoke instanceId:" | sed "s/.*: //"\`
1417
1518
Examples with CLI:
16-
$ s cli fc3 instance --instance-id c-64fec1fc-27c4833c325445879a28 --region cn-hangzhou --function-name test -a default`,
19+
$ s cli fc3 instance exec --instance-id c-64fec1fc-27c4833c325445879a28 --region cn-hangzhou --function-name test -a default
20+
$ s cli fc3 instance exec --instance-id c-64fec1fc-27c4833c325445879a28 --region cn-hangzhou --function-name test --shell /bin/sh -a default
21+
$ s cli fc3 instance exec --instance-id c-64fec1fc-27c4833c325445879a28 --region cn-hangzhou --function-name test --workdir / -a default
22+
$ s cli fc3 instance exec --instance-id c-64fec1fc-27c4833c325445879a28 --region cn-hangzhou --function-name test --no-workdir -a default`,
1723
summary: 'Execute a command in a instance',
1824
option: [
1925
[
@@ -23,6 +29,9 @@ Examples with CLI:
2329
['--function-name <functionName>', '[C-Required] Specify function name'],
2430
['--instance-id <instanceId>', '[Required] Specify function instance id'],
2531
['--cmd <cmd>', '[Optional] Command string to be executed'],
32+
['--shell <shell>', '[Optional] Specify shell to use (e.g., /bin/sh, /bin/bash), default is bash'],
33+
['--workdir <workdir>', '[Optional] Specify initial working directory (e.g., /, /app). If not specified, defaults to /code or / as fallback'],
34+
['--no-workdir', '[Optional] Do not cd to any directory, use container\'s default WORKDIR. Same as --workdir ""'],
2635
['--qualifier <qualifier>', '[Optional] Specify version or alias, default is LATEST'],
2736
],
2837
},

src/subCommands/instance/index.ts

Lines changed: 21 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,8 @@ export default class Instance {
1717
constructor(readonly inputs: IInputs) {
1818
const opts = parseArgv(inputs.args, {
1919
alias: { help: 'h', 'assume-yes': 'y' },
20-
boolean: ['help', 'y'],
21-
string: ['region', 'function-name', 'qualifier'],
20+
boolean: ['help', 'y', 'no-workdir'],
21+
string: ['region', 'function-name', 'qualifier', 'shell', 'workdir'],
2222
});
2323
logger.debug(`Instance opts: ${JSON.stringify(opts)}`);
2424
const { region, _: subCommands } = opts;
@@ -58,6 +58,8 @@ export default class Instance {
5858
/**
5959
* s instance exec --instance-id c-64fec1fc-27c4833c325445879a28 --cmd "ls -lh"
6060
* s instance exec --instance-id c-64fec1fc-27c4833c325445879a28
61+
* s instance exec --instance-id c-64fec1fc-27c4833c325445879a28 --shell /bin/sh
62+
* s instance exec --instance-id c-64fec1fc-27c4833c325445879a28 --workdir /app
6163
* s instance exec --instance-id `s invoke | grep 'Invoke instanceId:' | sed 's/.*: //'`
6264
*/
6365
async exec() {
@@ -71,11 +73,26 @@ export default class Instance {
7173
}
7274
const qualifier = this.opts.qualifier || 'LATEST';
7375
const cmd = this.opts.cmd as string;
76+
const shell = this.opts.shell || 'bash';
77+
const workdir = this.opts.workdir;
78+
const noWorkdir = this.opts['no-workdir'];
7479
let rawData = [];
7580
if (cmd) {
76-
rawData = ['bash', '-c', cmd];
81+
rawData = [shell, '-c', cmd];
7782
} else {
78-
rawData = ['bash', '-c', '(cd /code || cd / ) && bash'];
83+
// Build the default command based on workdir option
84+
let defaultCmd: string;
85+
if (noWorkdir || workdir === '') {
86+
// --no-workdir flag or empty string: don't cd anywhere, use container's default WORKDIR
87+
defaultCmd = shell;
88+
} else if (workdir) {
89+
// User specified a custom workdir
90+
defaultCmd = `cd ${workdir} && ${shell}`;
91+
} else {
92+
// Default behavior (workdir undefined): try /code first, fallback to /
93+
defaultCmd = `(cd /code || cd /) && ${shell}`;
94+
}
95+
rawData = [shell, '-c', defaultCmd];
7996
}
8097
await this.fcSdk.instanceExec(functionName, instanceId, rawData, qualifier, true);
8198
}

0 commit comments

Comments
 (0)