@mastra/docker 0.9.3-alpha.1 → 0.9.4-alpha.0

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/README.md CHANGED
@@ -169,6 +169,8 @@ const sandbox = new DockerSandbox({
169
169
  });
170
170
  ```
171
171
 
172
+ If `baseImage` runs as a non-root `USER`, set `owner` to that user (for example `owner: 'node'` or `owner: '1000:1000'`). The checkout is then copied with `COPY --chown`, so git and setup commands can write to it. Without `owner`, the checkout is owned by root.
173
+
172
174
  ## Documentation
173
175
 
174
176
  - [Docker Sandbox integration guide](https://mastra.ai/integrations/sandboxes/docker)
package/dist/index.cjs CHANGED
@@ -1600,6 +1600,11 @@ function renderSecretRun(command, secrets) {
1600
1600
  const prefix = names.length > 0 ? [`export ${exports.join(" ")}`] : [];
1601
1601
  return `RUN ${[...mounts, ""].join(" ")}${[...prefix, ...toCommandList(command)].join(" && ")}`;
1602
1602
  }
1603
+ const OWNER_PATTERN = /^[A-Za-z0-9_.-]+(:[A-Za-z0-9_.-]+)?$/;
1604
+ /** Throws unless `owner` is a `user[:group]` or `uid[:gid]` usable in `COPY --chown`. */
1605
+ function assertValidOwner(owner) {
1606
+ if (typeof owner !== "string" || !OWNER_PATTERN.test(owner)) throw new TypeError(`owner must be user[:group] or uid[:gid], got ${JSON.stringify(owner)}`);
1607
+ }
1603
1608
  function synthesizeDockerfile(definition) {
1604
1609
  const lines = [];
1605
1610
  let mainIndex = 0;
@@ -1621,13 +1626,14 @@ function synthesizeDockerfile(definition) {
1621
1626
  lines.push(`RUN ${toCommandList(operation.args[0]).join(" && ")}`);
1622
1627
  break;
1623
1628
  case "runWithSecrets": {
1624
- const [command, { secrets, output }] = operation.args;
1629
+ const [command, { secrets, output, owner }] = operation.args;
1630
+ if (owner !== void 0) assertValidOwner(owner);
1625
1631
  const snapshot = mainStageName(mainIndex);
1626
1632
  const stage = secretStageName(index);
1627
1633
  lines.push(`FROM ${snapshot} AS ${stage}`, renderSecretRun(command, secrets));
1628
1634
  mainIndex += 1;
1629
1635
  openMain(snapshot);
1630
- lines.push(`COPY --from=${stage} ${output} ${output}`);
1636
+ lines.push(`COPY ${owner !== void 0 ? `--chown=${owner} ` : ""}--from=${stage} ${output} ${output}`);
1631
1637
  break;
1632
1638
  }
1633
1639
  case "aptInstall":
@@ -1658,12 +1664,13 @@ function canonicalOperation(operation) {
1658
1664
  args: [sortedEntries(operation.args[0])]
1659
1665
  };
1660
1666
  case "runWithSecrets": {
1661
- const [command, { secrets, output }] = operation.args;
1667
+ const [command, { secrets, output, owner }] = operation.args;
1662
1668
  return {
1663
1669
  method: "runWithSecrets",
1664
1670
  args: [command, {
1665
1671
  secrets: [...secrets].sort(),
1666
- output
1672
+ output,
1673
+ ...owner !== void 0 ? { owner } : {}
1667
1674
  }]
1668
1675
  };
1669
1676
  }
@@ -1809,11 +1816,17 @@ var DockerTemplate = class DockerTemplate {
1809
1816
  });
1810
1817
  const output = validateString(options.output, "output");
1811
1818
  if (!output.startsWith("/")) throw new TypeError("output must be an absolute path");
1819
+ let owner;
1820
+ if (options.owner !== void 0) {
1821
+ owner = validateString(options.owner, "owner");
1822
+ assertValidOwner(owner);
1823
+ }
1812
1824
  return this.#append({
1813
1825
  method: "runWithSecrets",
1814
1826
  args: [validateStringOrStrings(command, "command"), {
1815
1827
  secrets,
1816
- output
1828
+ output,
1829
+ ...owner !== void 0 ? { owner } : {}
1817
1830
  }]
1818
1831
  });
1819
1832
  }
@@ -2264,6 +2277,7 @@ async function resolveRepoTemplate(options, workingDirectory, resolveOptions = {
2264
2277
  setupCommand: options.setupCommand,
2265
2278
  workingDirectory,
2266
2279
  baseImage: options.baseImage,
2280
+ owner: options.owner,
2267
2281
  dockerOptions: options.dockerOptions
2268
2282
  });
2269
2283
  }
@@ -2290,7 +2304,8 @@ function buildRepoTemplate(inputs) {
2290
2304
  }), `git -C ${shellQuote(destination)} checkout --detach ${shellQuote(sha)}`];
2291
2305
  template = template.runWithSecrets(clone, {
2292
2306
  secrets: tokenEnv ? [tokenEnv] : [],
2293
- output: destination
2307
+ output: destination,
2308
+ ...inputs.owner !== void 0 ? { owner: inputs.owner } : {}
2294
2309
  }).setWorkdir(destination);
2295
2310
  const setupCommands = normalizeSetupCommands(inputs.setupCommand);
2296
2311
  for (const command of setupCommands) template = template.runCmd(command);