mirror of
https://github.com/moby/moby.git
synced 2022-11-09 12:21:53 -05:00
6212ea669b
Wire templating support of swarmkit for the engine, in order to be used through services. Signed-off-by: Vincent Demeester <vincent@sbr.pm>
118 lines
2.9 KiB
Go
118 lines
2.9 KiB
Go
package template
|
|
|
|
import (
|
|
"fmt"
|
|
"strings"
|
|
|
|
"github.com/docker/swarmkit/api"
|
|
"github.com/pkg/errors"
|
|
)
|
|
|
|
// ExpandContainerSpec expands templated fields in the runtime using the task
|
|
// state. Templating is all evaluated on the agent-side, before execution.
|
|
//
|
|
// Note that these are projected only on runtime values, since active task
|
|
// values are typically manipulated in the manager.
|
|
func ExpandContainerSpec(t *api.Task) (*api.ContainerSpec, error) {
|
|
container := t.Spec.GetContainer()
|
|
if container == nil {
|
|
return nil, errors.Errorf("task missing ContainerSpec to expand")
|
|
}
|
|
|
|
container = container.Copy()
|
|
ctx := NewContextFromTask(t)
|
|
|
|
var err error
|
|
container.Env, err = expandEnv(ctx, container.Env)
|
|
if err != nil {
|
|
return container, errors.Wrap(err, "expanding env failed")
|
|
}
|
|
|
|
// For now, we only allow templating of string-based mount fields
|
|
container.Mounts, err = expandMounts(ctx, container.Mounts)
|
|
if err != nil {
|
|
return container, errors.Wrap(err, "expanding mounts failed")
|
|
}
|
|
|
|
container.Hostname, err = ctx.Expand(container.Hostname)
|
|
return container, errors.Wrap(err, "expanding hostname failed")
|
|
}
|
|
|
|
func expandMounts(ctx Context, mounts []api.Mount) ([]api.Mount, error) {
|
|
if len(mounts) == 0 {
|
|
return mounts, nil
|
|
}
|
|
|
|
expanded := make([]api.Mount, len(mounts))
|
|
for i, mount := range mounts {
|
|
var err error
|
|
mount.Source, err = ctx.Expand(mount.Source)
|
|
if err != nil {
|
|
return mounts, errors.Wrapf(err, "expanding mount source %q", mount.Source)
|
|
}
|
|
|
|
mount.Target, err = ctx.Expand(mount.Target)
|
|
if err != nil {
|
|
return mounts, errors.Wrapf(err, "expanding mount target %q", mount.Target)
|
|
}
|
|
|
|
if mount.VolumeOptions != nil {
|
|
mount.VolumeOptions.Labels, err = expandMap(ctx, mount.VolumeOptions.Labels)
|
|
if err != nil {
|
|
return mounts, errors.Wrap(err, "expanding volume labels")
|
|
}
|
|
|
|
if mount.VolumeOptions.DriverConfig != nil {
|
|
mount.VolumeOptions.DriverConfig.Options, err = expandMap(ctx, mount.VolumeOptions.DriverConfig.Options)
|
|
if err != nil {
|
|
return mounts, errors.Wrap(err, "expanding volume driver config")
|
|
}
|
|
}
|
|
}
|
|
|
|
expanded[i] = mount
|
|
}
|
|
|
|
return expanded, nil
|
|
}
|
|
|
|
func expandMap(ctx Context, m map[string]string) (map[string]string, error) {
|
|
var (
|
|
n = make(map[string]string, len(m))
|
|
err error
|
|
)
|
|
|
|
for k, v := range m {
|
|
v, err = ctx.Expand(v)
|
|
if err != nil {
|
|
return m, errors.Wrapf(err, "expanding map entry %q=%q", k, v)
|
|
}
|
|
|
|
n[k] = v
|
|
}
|
|
|
|
return n, nil
|
|
}
|
|
|
|
func expandEnv(ctx Context, values []string) ([]string, error) {
|
|
var result []string
|
|
for _, value := range values {
|
|
var (
|
|
parts = strings.SplitN(value, "=", 2)
|
|
entry = parts[0]
|
|
)
|
|
|
|
if len(parts) > 1 {
|
|
expanded, err := ctx.Expand(parts[1])
|
|
if err != nil {
|
|
return values, errors.Wrapf(err, "expanding env %q", value)
|
|
}
|
|
|
|
entry = fmt.Sprintf("%s=%s", entry, expanded)
|
|
}
|
|
|
|
result = append(result, entry)
|
|
}
|
|
|
|
return result, nil
|
|
}
|