@vercel/sandbox 0.0.12 → 0.0.13

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.
@@ -1,4 +1,4 @@
1
1
 
2
- > @vercel/sandbox@0.0.12 build /home/runner/work/sandbox-sdk/sandbox-sdk/packages/sandbox
2
+ > @vercel/sandbox@0.0.13 build /home/runner/work/sandbox-sdk/sandbox-sdk/packages/sandbox
3
3
  > tsc
4
4
 
@@ -1,4 +1,4 @@
1
1
 
2
- > @vercel/sandbox@0.0.12 typecheck /home/runner/work/sandbox-sdk/sandbox-sdk/packages/sandbox
2
+ > @vercel/sandbox@0.0.13 typecheck /home/runner/work/sandbox-sdk/sandbox-sdk/packages/sandbox
3
3
  > tsc --noEmit
4
4
 
package/CHANGELOG.md CHANGED
@@ -1,5 +1,11 @@
1
1
  # @vercel/sandbox
2
2
 
3
+ ## 0.0.13
4
+
5
+ ### Patch Changes
6
+
7
+ - Add sudo support to running commands ([#72](https://github.com/vercel/sandbox-sdk/pull/72))
8
+
3
9
  ## 0.0.12
4
10
 
5
11
  ### Patch Changes
package/README.md CHANGED
@@ -89,6 +89,7 @@ const sandbox = await Sandbox.create({
89
89
  type: "git",
90
90
  },
91
91
  resources: { vcpus: 4 },
92
+ // Defaults to 5 minutes. The maximum is 45 minutes.
92
93
  timeout: ms("5m"),
93
94
  ports: [3000],
94
95
  runtime: "node22",
@@ -97,8 +98,9 @@ const sandbox = await Sandbox.create({
97
98
 
98
99
  ## Limitations
99
100
 
100
- - `sudo` is not available. User code is executed as the `vercel-sandbox` user.
101
101
  - Max resources: 8 vCPUs. You will get 2048 MB of memory per vCPU.
102
+ - Sandboxes have a maximum runtime duration of 45 minutes, with a default of 5
103
+ minutes. This can be configured using the `timeout` option of `Sandbox.create()`.
102
104
 
103
105
  ## System
104
106
 
@@ -131,5 +133,33 @@ zstd
131
133
  - User code is executed as the `vercel-sandbox` user.
132
134
  - `/vercel/sandbox` is writable.
133
135
 
136
+ ## Sudo access
137
+
138
+ The `node22` and `python3.13` images allow users to run commands as root. This
139
+ can be used to install packages and system tools:
140
+
141
+ ```typescript
142
+ import { Sandbox } from "@vercel/sandbox";
143
+
144
+ const sandbox = await Sandbox.create();
145
+ await sandbox.runCommand({
146
+ cmd: "dnf",
147
+ args: ["install", "-y", "golang"],
148
+ sudo: true,
149
+ });
150
+ ```
151
+
152
+ Sandbox runs sudo in the following configuration:
153
+
154
+ - `HOME` is set to `/root` – Executed commands will source root's configuration
155
+ files (e.g. `.gitconfig`, `.bashrc`, etc).
156
+ - Environment variables are not reset before executing the command.
157
+ - `PATH` is left unchanged – sudo won’t change the value of PATH, so local or
158
+ project-specific binaries will still be found.
159
+
160
+ Both these images are based on Amazon Linux 2023. The full package list is
161
+ available [here](https://docs.aws.amazon.com/linux/al2023/release-notes/all-packages-AL2023.7.html).
162
+
134
163
  [create-token]: https://vercel.com/account/settings/tokens
135
164
  [hive]: https://vercel.com/blog/a-deep-dive-into-hive-vercels-builds-infrastructure
165
+ [al-2023-packages]: https://docs.aws.amazon.com/linux/al2023/release-notes/all-packages-AL2023.7.html
@@ -83,6 +83,7 @@ export declare class APIClient extends BaseClient {
83
83
  command: string;
84
84
  args: string[];
85
85
  env: Record<string, string>;
86
+ sudo: boolean;
86
87
  }): Promise<Parsed<{
87
88
  command: {
88
89
  name: string;
@@ -66,6 +66,7 @@ class APIClient extends base_client_1.BaseClient {
66
66
  args: params.args,
67
67
  cwd: params.cwd,
68
68
  env: params.env,
69
+ sudo: params.sudo,
69
70
  }),
70
71
  }));
71
72
  }
package/dist/sandbox.d.ts CHANGED
@@ -78,6 +78,10 @@ interface RunCommandParams {
78
78
  * Environment variables to set for this command
79
79
  */
80
80
  env?: Record<string, string>;
81
+ /**
82
+ * If true, execute this command with root privileges. Defaults to false.
83
+ */
84
+ sudo?: boolean;
81
85
  /**
82
86
  * If true, the command will return without waiting for `exitCode`
83
87
  */
package/dist/sandbox.js CHANGED
@@ -112,6 +112,7 @@ class Sandbox {
112
112
  args: params.args ?? [],
113
113
  cwd: params.cwd,
114
114
  env: params.env ?? {},
115
+ sudo: params.sudo ?? false,
115
116
  });
116
117
  const command = new command_1.Command({
117
118
  client: this.client,
package/dist/version.d.ts CHANGED
@@ -1 +1 @@
1
- export declare const VERSION = "0.0.12";
1
+ export declare const VERSION = "0.0.13";
package/dist/version.js CHANGED
@@ -2,4 +2,4 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.VERSION = void 0;
4
4
  // Autogenerated by inject-version.ts
5
- exports.VERSION = "0.0.12";
5
+ exports.VERSION = "0.0.13";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vercel/sandbox",
3
- "version": "0.0.12",
3
+ "version": "0.0.13",
4
4
  "description": "",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -102,6 +102,7 @@ export class APIClient extends BaseClient {
102
102
  command: string;
103
103
  args: string[];
104
104
  env: Record<string, string>;
105
+ sudo: boolean;
105
106
  }) {
106
107
  return parseOrThrow(
107
108
  CommandResponse,
@@ -112,6 +113,7 @@ export class APIClient extends BaseClient {
112
113
  args: params.args,
113
114
  cwd: params.cwd,
114
115
  env: params.env,
116
+ sudo: params.sudo,
115
117
  }),
116
118
  }),
117
119
  );
@@ -72,3 +72,35 @@ it("Kills a command with a SIGTERM", async () => {
72
72
  const result = await cmd.wait();
73
73
  expect(result.exitCode).toBe(143); // 128 + 15
74
74
  });
75
+
76
+ it("can execute commands with sudo", async () => {
77
+ const cmd = await sandbox.runCommand({
78
+ cmd: "env",
79
+ sudo: true,
80
+ env: {
81
+ FOO: "bar",
82
+ },
83
+ });
84
+
85
+ expect(cmd.exitCode).toBe(0);
86
+
87
+ const output = await cmd.stdout();
88
+ expect(output).toContain("FOO=bar\n");
89
+ expect(output).toContain("USER=root\n");
90
+ expect(output).toContain("SUDO_USER=vercel-sandbox\n");
91
+
92
+ // The actual path contains more, but this is enough
93
+ // to verify that we do not reset it to a default path.
94
+ expect(output).toContain("PATH=/vercel/bin");
95
+
96
+ const dnf = await sandbox.runCommand({
97
+ cmd: "dnf",
98
+ args: ["install", "-y", "golang"],
99
+ sudo: true,
100
+ });
101
+
102
+ expect(dnf.exitCode).toBe(0);
103
+
104
+ const which = await sandbox.runCommand("which", ["go"]);
105
+ expect(which.output()).resolves.toContain("/usr/bin/go");
106
+ });
package/src/sandbox.ts CHANGED
@@ -80,6 +80,10 @@ interface RunCommandParams {
80
80
  * Environment variables to set for this command
81
81
  */
82
82
  env?: Record<string, string>;
83
+ /**
84
+ * If true, execute this command with root privileges. Defaults to false.
85
+ */
86
+ sudo?: boolean;
83
87
  /**
84
88
  * If true, the command will return without waiting for `exitCode`
85
89
  */
@@ -268,6 +272,7 @@ export class Sandbox {
268
272
  args: params.args ?? [],
269
273
  cwd: params.cwd,
270
274
  env: params.env ?? {},
275
+ sudo: params.sudo ?? false,
271
276
  });
272
277
 
273
278
  const command = new Command({
package/src/version.ts CHANGED
@@ -1,2 +1,2 @@
1
1
  // Autogenerated by inject-version.ts
2
- export const VERSION = "0.0.12";
2
+ export const VERSION = "0.0.13";