feat: add expanded_directory to the agent for extension support (#6087)

This will enable opening the default `dir` of an agent in
the VS Code extension!
This commit is contained in:
Kyle Carberry
2023-02-07 21:35:09 +00:00
committed by GitHub
parent f6effdb63e
commit 691495d761
25 changed files with 220 additions and 59 deletions
+36 -6
View File
@@ -75,7 +75,7 @@ type Client interface {
ReportStats(ctx context.Context, log slog.Logger, stats func() *agentsdk.Stats) (io.Closer, error)
PostLifecycle(ctx context.Context, state agentsdk.PostLifecycleRequest) error
PostAppHealth(ctx context.Context, req agentsdk.PostAppHealthsRequest) error
PostVersion(ctx context.Context, version string) error
PostStartup(ctx context.Context, req agentsdk.PostStartupRequest) error
}
func New(options Options) io.Closer {
@@ -236,16 +236,29 @@ func (a *agent) run(ctx context.Context) error {
}
a.sessionToken.Store(&sessionToken)
err = a.client.PostVersion(ctx, buildinfo.Version())
if err != nil {
return xerrors.Errorf("update workspace agent version: %w", err)
}
metadata, err := a.client.Metadata(ctx)
if err != nil {
return xerrors.Errorf("fetch metadata: %w", err)
}
a.logger.Info(ctx, "fetched metadata")
// Expand the directory and send it back to coderd so external
// applications that rely on the directory can use it.
//
// An example is VS Code Remote, which must know the directory
// before initializing a connection.
metadata.Directory, err = expandDirectory(metadata.Directory)
if err != nil {
return xerrors.Errorf("expand directory: %w", err)
}
err = a.client.PostStartup(ctx, agentsdk.PostStartupRequest{
Version: buildinfo.Version(),
ExpandedDirectory: metadata.Directory,
})
if err != nil {
return xerrors.Errorf("update workspace agent version: %w", err)
}
oldMetadata := a.metadata.Swap(metadata)
// The startup script should only execute on the first run!
@@ -1318,3 +1331,20 @@ func userHomeDir() (string, error) {
}
return u.HomeDir, nil
}
// expandDirectory converts a directory path to an absolute path.
// It primarily resolves the home directory and any environment
// variables that may be set
func expandDirectory(dir string) (string, error) {
if dir == "" {
return "", nil
}
if dir[0] == '~' {
home, err := userHomeDir()
if err != nil {
return "", err
}
dir = filepath.Join(home, dir[1:])
}
return os.ExpandEnv(dir), nil
}
+61 -1
View File
@@ -787,6 +787,56 @@ func TestAgent_Lifecycle(t *testing.T) {
})
}
func TestAgent_Startup(t *testing.T) {
t.Parallel()
t.Run("EmptyDirectory", func(t *testing.T) {
t.Parallel()
_, client, _, _ := setupAgent(t, agentsdk.Metadata{
StartupScript: "true",
StartupScriptTimeout: 30 * time.Second,
Directory: "",
}, 0)
assert.Eventually(t, func() bool {
return client.getStartup().Version != ""
}, testutil.WaitShort, testutil.IntervalFast)
require.Equal(t, "", client.getStartup().ExpandedDirectory)
})
t.Run("HomeDirectory", func(t *testing.T) {
t.Parallel()
_, client, _, _ := setupAgent(t, agentsdk.Metadata{
StartupScript: "true",
StartupScriptTimeout: 30 * time.Second,
Directory: "~",
}, 0)
assert.Eventually(t, func() bool {
return client.getStartup().Version != ""
}, testutil.WaitShort, testutil.IntervalFast)
homeDir, err := os.UserHomeDir()
require.NoError(t, err)
require.Equal(t, homeDir, client.getStartup().ExpandedDirectory)
})
t.Run("HomeEnvironmentVariable", func(t *testing.T) {
t.Parallel()
_, client, _, _ := setupAgent(t, agentsdk.Metadata{
StartupScript: "true",
StartupScriptTimeout: 30 * time.Second,
Directory: "$HOME",
}, 0)
assert.Eventually(t, func() bool {
return client.getStartup().Version != ""
}, testutil.WaitShort, testutil.IntervalFast)
homeDir, err := os.UserHomeDir()
require.NoError(t, err)
require.Equal(t, homeDir, client.getStartup().ExpandedDirectory)
})
}
func TestAgent_ReconnectingPTY(t *testing.T) {
t.Parallel()
if runtime.GOOS == "windows" {
@@ -1178,6 +1228,7 @@ type client struct {
mu sync.Mutex // Protects following.
lifecycleStates []codersdk.WorkspaceAgentLifecycle
startup agentsdk.PostStartupRequest
}
func (c *client) Metadata(_ context.Context) (agentsdk.Metadata, error) {
@@ -1250,7 +1301,16 @@ func (*client) PostAppHealth(_ context.Context, _ agentsdk.PostAppHealthsRequest
return nil
}
func (*client) PostVersion(_ context.Context, _ string) error {
func (c *client) getStartup() agentsdk.PostStartupRequest {
c.mu.Lock()
defer c.mu.Unlock()
return c.startup
}
func (c *client) PostStartup(_ context.Context, startup agentsdk.PostStartupRequest) error {
c.mu.Lock()
defer c.mu.Unlock()
c.startup = startup
return nil
}