devcontainers / cli

A reference implementation for the specification that can create and configure a dev container from a devcontainer.json.
https://containers.dev
MIT License
1.39k stars 192 forks source link

Support updating lifecycle scripts on existing containers #821

Open cmbrose opened 2 months ago

cmbrose commented 2 months ago

Because the container configuration is cached in the container labels after creation, any changes to the local config file are ignored for future operations on the container.

In the case of the lifecycle scripts (onCreateCommand, postCreateCommand, ...) it would be useful in cases of pooling container if changes to the config would be honored so that the container doesn't need to be recreated.

For example, if a container is created with an empty configuration for a pool, then we should be able to later change the configuration to and re-apply the post-creation lifecycle logic against the existing container.

{
    "postCreateCommand": "touch foo"
}

It would also be useful if the cli could detect the case of a configuration collision and fail with a reasonable message. For example, if the container is created with a postCreateCommand already and then the value is changed, then this re-application logic should fail.

joshspicer commented 2 months ago

For example, if a container is created with an empty configuration for a pool

Important to call out here that there's never a container created via an "empty configuration" (that's more a Codespace user-concept, but behind the scenes there's always a config)

+1 I think this is a nice optimization, either automatically or via a new CLI command codespaces could invoke (like devcontainers update ... or devcontainers reconcile or devcontainers rebuild).

As a couple folks discussed offline, this could drastically shorten the "rebuild" flow by re-applying configuration that doesn't need a full container rebuild. Think of it as an "incremental" rebuild that doesn't ever delete the container or take you out of the editor experience (for changes that do not require a rebuild, like adding a postStartCommand)

chrmarti commented 2 months ago

To make the pooling work, we could add a command line option (maybe --reapply-config?) that would make the code at https://github.com/devcontainers/cli/blob/be1f2034e10395f42843ebf26600a42e11e66531/src/spec-node/imageMetadata.ts#L427 take the else case.

That would add the config on top of the existing metadata on the container (which is readonly). We also use this codepath when we locally attach to a container that was started by the user using the Docker CLI and the image comes with dev container metadata. The merging is the same codepath as when you regularly start a dev container.