@pablozaiden/devbox 0.1.6 → 0.1.7
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 +9 -0
- package/dist/devbox.js +47 -7
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -99,6 +99,15 @@ cd examples/smoke-workspace
|
|
|
99
99
|
../../dist/devbox.js up <port> --allow-missing-ssh
|
|
100
100
|
```
|
|
101
101
|
|
|
102
|
+
For a more realistic feature-heavy example, this repository also includes `examples/complex-workspace/.devcontainer/devcontainer.json`:
|
|
103
|
+
|
|
104
|
+
```bash
|
|
105
|
+
cd examples/complex-workspace
|
|
106
|
+
../../dist/devbox.js up <port>
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
The complex example uses several devcontainer features, so the first `up` or `rebuild` can take a while. `devbox` prints periodic elapsed-time progress lines while the devcontainer image/features are still being prepared and while the SSH runner is being installed.
|
|
110
|
+
|
|
102
111
|
## Notes
|
|
103
112
|
|
|
104
113
|
- The generated config is written next to the original devcontainer config, using the alternate accepted devcontainer filename so relative Dockerfile paths keep working.
|
package/dist/devbox.js
CHANGED
|
@@ -1932,6 +1932,11 @@ async function handleUpLike(command, workspacePath, state, explicitPort, allowMi
|
|
|
1932
1932
|
if (environment.warning) {
|
|
1933
1933
|
console.warn(`Warning: ${environment.warning}`);
|
|
1934
1934
|
}
|
|
1935
|
+
if (environment.sshAuthSock === DOCKER_DESKTOP_SSH_AUTH_SOCK_SOURCE) {
|
|
1936
|
+
console.log("Using Docker Desktop SSH agent sharing.");
|
|
1937
|
+
} else if (environment.sshAuthSock) {
|
|
1938
|
+
console.log(`Using host SSH agent socket from ${environment.sshAuthSock}.`);
|
|
1939
|
+
}
|
|
1935
1940
|
await ensureGeneratedConfigIgnored(workspacePath, generatedConfigPath);
|
|
1936
1941
|
await removeGeneratedConfig(legacyGeneratedConfigPath);
|
|
1937
1942
|
await writeManagedConfig(generatedConfigPath, managedConfig);
|
|
@@ -1955,11 +1960,16 @@ async function handleUpLike(command, workspacePath, state, explicitPort, allowMi
|
|
|
1955
1960
|
const allowCurrentPort = existingInspects.some((container) => container.State?.Running && getPublishedHostPorts(container).includes(port));
|
|
1956
1961
|
await assertPortAvailable(port, allowCurrentPort);
|
|
1957
1962
|
console.log(`Starting workspace on port ${port}...`);
|
|
1958
|
-
const upResult = await
|
|
1959
|
-
|
|
1960
|
-
|
|
1961
|
-
|
|
1962
|
-
|
|
1963
|
+
const upResult = await runStepWithHeartbeat({
|
|
1964
|
+
startMessage: "Preparing devcontainer. First builds with features may take several minutes...",
|
|
1965
|
+
heartbeatMessage: "Still preparing devcontainer",
|
|
1966
|
+
successMessage: "Devcontainer is ready",
|
|
1967
|
+
action: () => devcontainerUp({
|
|
1968
|
+
workspacePath,
|
|
1969
|
+
generatedConfigPath,
|
|
1970
|
+
userDataDir,
|
|
1971
|
+
labels
|
|
1972
|
+
})
|
|
1963
1973
|
});
|
|
1964
1974
|
const remoteWorkspaceFolder = upResult.remoteWorkspaceFolder ?? getDefaultRemoteWorkspaceFolder(workspacePath);
|
|
1965
1975
|
console.log("Configuring SSH access inside the devcontainer...");
|
|
@@ -1978,8 +1988,12 @@ async function handleUpLike(command, workspacePath, state, explicitPort, allowMi
|
|
|
1978
1988
|
}
|
|
1979
1989
|
await stopManagedSshd(upResult.containerId);
|
|
1980
1990
|
await restoreRunnerHostKeys(upResult.containerId, remoteWorkspaceFolder);
|
|
1981
|
-
|
|
1982
|
-
|
|
1991
|
+
await runStepWithHeartbeat({
|
|
1992
|
+
startMessage: "Installing and starting the SSH server inside the container (first run can take a bit)...",
|
|
1993
|
+
heartbeatMessage: "Still installing and starting the SSH server",
|
|
1994
|
+
successMessage: "SSH server is ready",
|
|
1995
|
+
action: () => startRunner(upResult.containerId, port, remoteWorkspaceFolder)
|
|
1996
|
+
});
|
|
1983
1997
|
console.log("Saving SSH server state for future runs...");
|
|
1984
1998
|
await persistRunnerHostKeys(upResult.containerId, remoteWorkspaceFolder);
|
|
1985
1999
|
await saveWorkspaceState(createWorkspaceState({
|
|
@@ -2060,6 +2074,32 @@ function getPublishedHostPorts(container) {
|
|
|
2060
2074
|
}
|
|
2061
2075
|
return [...values];
|
|
2062
2076
|
}
|
|
2077
|
+
async function runStepWithHeartbeat(input) {
|
|
2078
|
+
const startedAt = Date.now();
|
|
2079
|
+
const intervalMs = input.intervalMs ?? 20000;
|
|
2080
|
+
console.log(input.startMessage);
|
|
2081
|
+
const intervalId = setInterval(() => {
|
|
2082
|
+
console.log(`${input.heartbeatMessage} (${formatElapsed(Date.now() - startedAt)} elapsed)...`);
|
|
2083
|
+
}, intervalMs);
|
|
2084
|
+
try {
|
|
2085
|
+
const result = await input.action();
|
|
2086
|
+
if (input.successMessage) {
|
|
2087
|
+
console.log(`${input.successMessage} (${formatElapsed(Date.now() - startedAt)}).`);
|
|
2088
|
+
}
|
|
2089
|
+
return result;
|
|
2090
|
+
} finally {
|
|
2091
|
+
clearInterval(intervalId);
|
|
2092
|
+
}
|
|
2093
|
+
}
|
|
2094
|
+
function formatElapsed(milliseconds) {
|
|
2095
|
+
const totalSeconds = Math.max(0, Math.round(milliseconds / 1000));
|
|
2096
|
+
const minutes = Math.floor(totalSeconds / 60);
|
|
2097
|
+
const seconds = totalSeconds % 60;
|
|
2098
|
+
if (minutes === 0) {
|
|
2099
|
+
return `${seconds}s`;
|
|
2100
|
+
}
|
|
2101
|
+
return `${minutes}m ${seconds}s`;
|
|
2102
|
+
}
|
|
2063
2103
|
main().catch((error) => {
|
|
2064
2104
|
if (error instanceof UserError) {
|
|
2065
2105
|
console.error(`Error: ${error.message}`);
|