- Notifications
You must be signed in to change notification settings - Fork909
feat: show devcontainer dirty status and allow recreate#17880
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to ourterms of service andprivacy statement. We’ll occasionally send you account related emails.
Already on GitHub?Sign in to your account
Changes fromall commits
File filter
Filter by extension
Conversations
Uh oh!
There was an error while loading.Please reload this page.
Jump to
Uh oh!
There was an error while loading.Please reload this page.
Diff view
Diff view
There are no files selected for viewing
Some generated files are not rendered by default. Learn more abouthow customized files appear on GitHub.
Uh oh!
There was an error while loading.Please reload this page.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,4 @@ | ||
// Package acmock contains a mock implementation of agentcontainers.Lister for use in tests. | ||
package acmock | ||
//go:generate mockgen -destination ./acmock.go -package acmock .. Lister,DevcontainerCLI |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -69,6 +69,15 @@ func WithClock(clock quartz.Clock) Option { | ||
} | ||
} | ||
// WithCacheDuration sets the cache duration for the API. | ||
// This is used to control how often the API refreshes the list of | ||
// containers. The default is 10 seconds. | ||
func WithCacheDuration(d time.Duration) Option { | ||
return func(api *API) { | ||
api.cacheDuration = d | ||
} | ||
} | ||
// WithExecer sets the agentexec.Execer implementation to use. | ||
func WithExecer(execer agentexec.Execer) Option { | ||
return func(api *API) { | ||
@@ -336,14 +345,29 @@ func (api *API) getContainers(ctx context.Context) (codersdk.WorkspaceAgentListC | ||
} | ||
// Check if the container is running and update the known devcontainers. | ||
for i := range updated.Containers { | ||
container := &updated.Containers[i] | ||
workspaceFolder := container.Labels[DevcontainerLocalFolderLabel] | ||
configFile := container.Labels[DevcontainerConfigFileLabel] | ||
if workspaceFolder == "" { | ||
continue | ||
} | ||
container.DevcontainerDirty = dirtyStates[workspaceFolder] | ||
if container.DevcontainerDirty { | ||
lastModified, hasModTime := api.configFileModifiedTimes[configFile] | ||
if hasModTime && container.CreatedAt.After(lastModified) { | ||
api.logger.Info(ctx, "new container created after config modification, not marking as dirty", | ||
slog.F("container", container.ID), | ||
slog.F("created_at", container.CreatedAt), | ||
slog.F("config_modified_at", lastModified), | ||
slog.F("file", configFile), | ||
) | ||
container.DevcontainerDirty = false | ||
} | ||
} | ||
// Check if this is already in our known list. | ||
if knownIndex := slices.IndexFunc(api.knownDevcontainers, func(dc codersdk.WorkspaceAgentDevcontainer) bool { | ||
return dc.WorkspaceFolder == workspaceFolder | ||
@@ -356,7 +380,7 @@ func (api *API) getContainers(ctx context.Context) (codersdk.WorkspaceAgentListC | ||
} | ||
} | ||
api.knownDevcontainers[knownIndex].Running = container.Running | ||
api.knownDevcontainers[knownIndex].Container = container | ||
// Check if this container was created after the config | ||
// file was modified. | ||
@@ -395,28 +419,14 @@ func (api *API) getContainers(ctx context.Context) (codersdk.WorkspaceAgentListC | ||
} | ||
} | ||
api.knownDevcontainers = append(api.knownDevcontainers, codersdk.WorkspaceAgentDevcontainer{ | ||
ID: uuid.New(), | ||
Name: name, | ||
WorkspaceFolder: workspaceFolder, | ||
ConfigPath: configFile, | ||
Running: container.Running, | ||
Dirty:container.DevcontainerDirty, | ||
Container: container, | ||
}) | ||
} | ||
@@ -510,6 +520,13 @@ func (api *API) handleDevcontainerRecreate(w http.ResponseWriter, r *http.Reques | ||
slog.F("name", api.knownDevcontainers[i].Name), | ||
) | ||
api.knownDevcontainers[i].Dirty = false | ||
// TODO(mafredri): This should be handled by a service that | ||
// updates the devcontainer state periodically and on-demand. | ||
api.knownDevcontainers[i].Container = nil | ||
mafredri marked this conversation as resolved. Show resolvedHide resolvedUh oh!There was an error while loading.Please reload this page. | ||
// Set the modified time to the zero value to indicate that | ||
// the containers list must be refreshed. This will see to | ||
// it that the new container is re-assigned. | ||
api.mtime = time.Time{} | ||
} | ||
return | ||
} | ||
@@ -579,6 +596,9 @@ func (api *API) markDevcontainerDirty(configPath string, modifiedAt time.Time) { | ||
slog.F("modified_at", modifiedAt), | ||
) | ||
api.knownDevcontainers[i].Dirty = true | ||
if api.knownDevcontainers[i].Container != nil { | ||
api.knownDevcontainers[i].Container.DevcontainerDirty = true | ||
} | ||
} | ||
} | ||
}) | ||
This file was deleted.
Uh oh!
There was an error while loading.Please reload this page.
Uh oh!
There was an error while loading.Please reload this page.
Uh oh!
There was an error while loading.Please reload this page.