mirror of
https://github.com/jesseduffield/lazydocker.git
synced 2026-07-25 08:31:03 +00:00
feat: support tls with context config
This commit is contained in:
parent
577797d9ed
commit
bcd2807aa7
2 changed files with 99 additions and 8 deletions
|
|
@ -78,11 +78,75 @@ func (c *DockerCommand) NewCommandObject(obj CommandObject) CommandObject {
|
|||
// API version negotiation to support older Docker daemons.
|
||||
// See https://github.com/jesseduffield/lazydocker/issues/715
|
||||
func newDockerClient(dockerHost string) (*client.Client, error) {
|
||||
return client.NewClientWithOpts(
|
||||
client.WithTLSClientConfigFromEnv(),
|
||||
opts := []client.Opt{
|
||||
client.WithAPIVersionNegotiation(),
|
||||
client.WithHost(dockerHost),
|
||||
}
|
||||
|
||||
// Load TLS config from environment variables (for backward compatibility)
|
||||
tlsOpts := []client.Opt{client.WithTLSClientConfigFromEnv()}
|
||||
|
||||
// Also try to load TLS config from the current Docker context
|
||||
contextTLSOpts, err := getContextTLSOptions()
|
||||
if err == nil && contextTLSOpts != nil {
|
||||
// If we have context TLS config, use it instead of env config
|
||||
tlsOpts = contextTLSOpts
|
||||
}
|
||||
|
||||
opts = append(opts, tlsOpts...)
|
||||
|
||||
return client.NewClientWithOpts(opts...)
|
||||
}
|
||||
|
||||
// getContextTLSOptions loads TLS configuration from the current Docker context
|
||||
func getContextTLSOptions() ([]client.Opt, error) {
|
||||
currentContext := os.Getenv("DOCKER_CONTEXT")
|
||||
if currentContext == "" {
|
||||
cf, err := cliconfig.Load(cliconfig.Dir())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
currentContext = cf.CurrentContext
|
||||
}
|
||||
|
||||
// Skip if no context or using default context
|
||||
if currentContext == "" || currentContext == "default" {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
storeConfig := ctxstore.NewConfig(
|
||||
func() interface{} { return &ddocker.EndpointMeta{} },
|
||||
ctxstore.EndpointTypeGetter(ddocker.DockerEndpoint, func() interface{} { return &ddocker.EndpointMeta{} }),
|
||||
)
|
||||
|
||||
st := ctxstore.New(cliconfig.ContextStoreDir(), storeConfig)
|
||||
|
||||
// First load the endpoint metadata
|
||||
md, err := st.GetMetadata(currentContext)
|
||||
if err != nil {
|
||||
// Context doesn't exist or can't be read - not an error for our use case
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
dockerEP, ok := md.Endpoints[ddocker.DockerEndpoint]
|
||||
if !ok {
|
||||
return nil, nil // No docker endpoint in this context
|
||||
}
|
||||
|
||||
dockerEPMeta, ok := dockerEP.(ddocker.EndpointMeta)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("expected docker.EndpointMeta, got %T", dockerEP)
|
||||
}
|
||||
|
||||
// Now load the endpoint with TLS data
|
||||
endpoint, err := ddocker.WithTLSData(st, currentContext, dockerEPMeta)
|
||||
if err != nil {
|
||||
// If we can't load TLS data, that's okay - just return nil
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
// Get client options from the endpoint (includes TLS config)
|
||||
return endpoint.ClientOpts()
|
||||
}
|
||||
|
||||
// NewDockerCommand it runs docker commands
|
||||
|
|
|
|||
|
|
@ -53,11 +53,38 @@ func TestNewDockerClientVersionNegotiation(t *testing.T) {
|
|||
assert.NoError(t, err)
|
||||
defer cli.Close()
|
||||
|
||||
// Version is NOT locked to the env var value (1.25).
|
||||
// Instead, it uses the library's default version and will negotiate
|
||||
// with the server on first request. This is the key difference that
|
||||
// fixes the "version too old" error.
|
||||
assert.NotEqual(t, "1.25", cli.ClientVersion(),
|
||||
"client version should not be locked to DOCKER_API_VERSION env var")
|
||||
// Version should still be negotiable (not locked to env var)
|
||||
assert.NotEqual(t, "1.25", cli.ClientVersion())
|
||||
})
|
||||
}
|
||||
|
||||
// TestGetContextTLSOptions tests that TLS options can be loaded from Docker contexts
|
||||
func TestGetContextTLSOptions(t *testing.T) {
|
||||
// Save original env vars and restore after test
|
||||
originalContext := os.Getenv("DOCKER_CONTEXT")
|
||||
defer func() {
|
||||
if originalContext == "" {
|
||||
os.Unsetenv("DOCKER_CONTEXT")
|
||||
} else {
|
||||
os.Setenv("DOCKER_CONTEXT", originalContext)
|
||||
}
|
||||
}()
|
||||
|
||||
// Test with no context set (should return nil)
|
||||
os.Unsetenv("DOCKER_CONTEXT")
|
||||
opts, err := getContextTLSOptions()
|
||||
assert.NoError(t, err)
|
||||
assert.Nil(t, opts)
|
||||
|
||||
// Test with default context (should return nil)
|
||||
os.Setenv("DOCKER_CONTEXT", "default")
|
||||
opts, err = getContextTLSOptions()
|
||||
assert.NoError(t, err)
|
||||
assert.Nil(t, opts)
|
||||
|
||||
// Test with non-existent context (should return nil, not error)
|
||||
os.Setenv("DOCKER_CONTEXT", "nonexistent-context")
|
||||
opts, err = getContextTLSOptions()
|
||||
assert.NoError(t, err)
|
||||
assert.Nil(t, opts)
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue