Skip to content

Commit 5ef8ace

Browse files
committed
Add support for configs.file's and secrets.file's on remote docker hosts
Copy configs.file's and secrets.file's instead of bind-mounting them to make it possible to use file configs when working with remote docker hosts (like setting DOCKER_HOST to a ssh address or setting docker context) Includes support for config.files and secrets.files as directories. Note that file.Content as source of secrets is denied elsewhere with the error "validating docker-compose.yml: secrets.content_secret Additional property content is not allowed", but it is implemented here in case this restriction is liften in the future. Configs and secrets from environment is also handled as plain content inserted into target file. implements: docker#11867
1 parent 517f87a commit 5ef8ace

File tree

2 files changed

+188
-182
lines changed

2 files changed

+188
-182
lines changed

pkg/compose/create.go

-128
Original file line numberDiff line numberDiff line change
@@ -941,137 +941,9 @@ func fillBindMounts(p types.Project, s types.ServiceConfig, m map[string]mount.M
941941
m[bindMount.Target] = bindMount
942942
}
943943

944-
secrets, err := buildContainerSecretMounts(p, s)
945-
if err != nil {
946-
return nil, err
947-
}
948-
for _, s := range secrets {
949-
if _, found := m[s.Target]; found {
950-
continue
951-
}
952-
m[s.Target] = s
953-
}
954-
955-
configs, err := buildContainerConfigMounts(p, s)
956-
if err != nil {
957-
return nil, err
958-
}
959-
for _, c := range configs {
960-
if _, found := m[c.Target]; found {
961-
continue
962-
}
963-
m[c.Target] = c
964-
}
965944
return m, nil
966945
}
967946

968-
func buildContainerConfigMounts(p types.Project, s types.ServiceConfig) ([]mount.Mount, error) {
969-
var mounts = map[string]mount.Mount{}
970-
971-
configsBaseDir := "/"
972-
for _, config := range s.Configs {
973-
target := config.Target
974-
if config.Target == "" {
975-
target = configsBaseDir + config.Source
976-
} else if !isAbsTarget(config.Target) {
977-
target = configsBaseDir + config.Target
978-
}
979-
980-
definedConfig := p.Configs[config.Source]
981-
if definedConfig.External {
982-
return nil, fmt.Errorf("unsupported external config %s", definedConfig.Name)
983-
}
984-
985-
if definedConfig.Driver != "" {
986-
return nil, errors.New("Docker Compose does not support configs.*.driver")
987-
}
988-
if definedConfig.TemplateDriver != "" {
989-
return nil, errors.New("Docker Compose does not support configs.*.template_driver")
990-
}
991-
992-
if definedConfig.Environment != "" || definedConfig.Content != "" {
993-
continue
994-
}
995-
996-
if config.UID != "" || config.GID != "" || config.Mode != nil {
997-
logrus.Warn("config `uid`, `gid` and `mode` are not supported, they will be ignored")
998-
}
999-
1000-
bindMount, err := buildMount(p, types.ServiceVolumeConfig{
1001-
Type: types.VolumeTypeBind,
1002-
Source: definedConfig.File,
1003-
Target: target,
1004-
ReadOnly: true,
1005-
})
1006-
if err != nil {
1007-
return nil, err
1008-
}
1009-
mounts[target] = bindMount
1010-
}
1011-
values := make([]mount.Mount, 0, len(mounts))
1012-
for _, v := range mounts {
1013-
values = append(values, v)
1014-
}
1015-
return values, nil
1016-
}
1017-
1018-
func buildContainerSecretMounts(p types.Project, s types.ServiceConfig) ([]mount.Mount, error) {
1019-
var mounts = map[string]mount.Mount{}
1020-
1021-
secretsDir := "/run/secrets/"
1022-
for _, secret := range s.Secrets {
1023-
target := secret.Target
1024-
if secret.Target == "" {
1025-
target = secretsDir + secret.Source
1026-
} else if !isAbsTarget(secret.Target) {
1027-
target = secretsDir + secret.Target
1028-
}
1029-
1030-
definedSecret := p.Secrets[secret.Source]
1031-
if definedSecret.External {
1032-
return nil, fmt.Errorf("unsupported external secret %s", definedSecret.Name)
1033-
}
1034-
1035-
if definedSecret.Driver != "" {
1036-
return nil, errors.New("Docker Compose does not support secrets.*.driver")
1037-
}
1038-
if definedSecret.TemplateDriver != "" {
1039-
return nil, errors.New("Docker Compose does not support secrets.*.template_driver")
1040-
}
1041-
1042-
if definedSecret.Environment != "" {
1043-
continue
1044-
}
1045-
1046-
if secret.UID != "" || secret.GID != "" || secret.Mode != nil {
1047-
logrus.Warn("secrets `uid`, `gid` and `mode` are not supported, they will be ignored")
1048-
}
1049-
1050-
if _, err := os.Stat(definedSecret.File); os.IsNotExist(err) {
1051-
logrus.Warnf("secret file %s does not exist", definedSecret.Name)
1052-
}
1053-
1054-
mnt, err := buildMount(p, types.ServiceVolumeConfig{
1055-
Type: types.VolumeTypeBind,
1056-
Source: definedSecret.File,
1057-
Target: target,
1058-
ReadOnly: true,
1059-
Bind: &types.ServiceVolumeBind{
1060-
CreateHostPath: false,
1061-
},
1062-
})
1063-
if err != nil {
1064-
return nil, err
1065-
}
1066-
mounts[target] = mnt
1067-
}
1068-
values := make([]mount.Mount, 0, len(mounts))
1069-
for _, v := range mounts {
1070-
values = append(values, v)
1071-
}
1072-
return values, nil
1073-
}
1074-
1075947
func isAbsTarget(p string) bool {
1076948
return isUnixAbs(p) || isWindowsAbs(p)
1077949
}

0 commit comments

Comments
 (0)