feat(env): support env vars for services (both run command and compose)

This commit is contained in:
Pavel Sviderski
2025-04-03 18:14:17 +10:00
parent 4e40a93991
commit 25b173128a
9 changed files with 100 additions and 7 deletions
+17 -1
View File
@@ -107,7 +107,9 @@ type ContainerSpec struct {
Command []string
// Entrypoint overrides the default ENTRYPOINT of the image.
Entrypoint []string
Image string
// Env defines the environment variables to set inside the container.
Env EnvVars
Image string
// Run a custom init inside the container. If nil, use the daemon's configured settings.
Init *bool
// PullPolicy determines when to pull the image from the registry or use the image already available in the cluster.
@@ -164,6 +166,20 @@ func (s *ContainerSpec) Clone() ContainerSpec {
return spec
}
type EnvVars map[string]string
// ToSlice converts the environment variables to a slice of strings in the format "key=value".
func (e EnvVars) ToSlice() []string {
env := make([]string, 0, len(e))
for k, v := range e {
if k == "" {
continue
}
env = append(env, fmt.Sprintf("%s=%s", k, v))
}
return env
}
type Service struct {
ID string
Name string
+1 -1
View File
@@ -4,6 +4,7 @@ import (
"context"
"errors"
"fmt"
"github.com/compose-spec/compose-go/v2/graph"
"github.com/compose-spec/compose-go/v2/types"
"github.com/psviderski/uncloud/pkg/api"
@@ -31,7 +32,6 @@ func NewDeployment(ctx context.Context, cli Client, project *types.Project) (*De
resolver := &deploy.ServiceSpecResolver{
// If the domain is not found (not reserved), an empty domain is used for the resolver.
ClusterDomain: domain,
// TODO: provide an image resolver.
}
return &Deployment{
+12 -1
View File
@@ -2,6 +2,7 @@ package compose
import (
"fmt"
"github.com/compose-spec/compose-go/v2/types"
"github.com/psviderski/uncloud/pkg/api"
)
@@ -19,13 +20,23 @@ func ServiceSpecFromCompose(name string, service types.ServiceConfig) (api.Servi
return api.ServiceSpec{}, fmt.Errorf("unsupported pull policy: '%s'", service.PullPolicy)
}
env := make(map[string]string, len(service.Environment))
for k, v := range service.Environment {
if v == nil {
// nil value means the variable misses a value in the compose file, and it hasn't been resolved
// to a variable from the local environment running this code.
continue
}
env[k] = *v
}
spec := api.ServiceSpec{
Container: api.ContainerSpec{
Command: service.Command,
Env: env,
Image: service.Image,
Init: service.Init,
PullPolicy: pullPolicy,
// TODO: env
// TODO: volumes
},
Name: name,