( ctx context.Context, project *types.Project, service types.ServiceConfig, ctr container.Summary, hook types.ServiceHook, )
| 123 | } |
| 124 | |
| 125 | func (s *composeService) createPreStartContainer( |
| 126 | ctx context.Context, project *types.Project, service types.ServiceConfig, |
| 127 | ctr container.Summary, hook types.ServiceHook, |
| 128 | ) (client.ContainerCreateResult, error) { |
| 129 | image := hook.Image |
| 130 | if image == "" { |
| 131 | image = api.GetImageNameOrDefault(service, project.Name) |
| 132 | } |
| 133 | |
| 134 | cfg := &container.Config{ |
| 135 | Image: image, |
| 136 | Cmd: hook.Command, |
| 137 | User: hook.User, |
| 138 | WorkingDir: hook.WorkingDir, |
| 139 | Env: append(ToMobyEnv(service.Environment), ToMobyEnv(hook.Environment)...), |
| 140 | // Tag the ephemeral hook container with the project/service it belongs |
| 141 | // to so a failed AutoRemove leaves something that `compose down` (and |
| 142 | // other label-scoped tooling) can still find. |
| 143 | Labels: map[string]string{ |
| 144 | api.ProjectLabel: project.Name, |
| 145 | api.ServiceLabel: service.Name, |
| 146 | api.VersionLabel: api.ComposeVersion, |
| 147 | }, |
| 148 | } |
| 149 | hostCfg := &container.HostConfig{ |
| 150 | AutoRemove: true, |
| 151 | Privileged: hook.Privileged, |
| 152 | VolumesFrom: []string{ctr.ID}, |
| 153 | } |
| 154 | |
| 155 | apiVersion, err := s.RuntimeAPIVersion(ctx) |
| 156 | if err != nil { |
| 157 | return client.ContainerCreateResult{}, err |
| 158 | } |
| 159 | |
| 160 | networkMode, networkingConfig, err := defaultNetworkSettings(project, service, 0, nil, true, apiVersion) |
| 161 | if err != nil { |
| 162 | return client.ContainerCreateResult{}, err |
| 163 | } |
| 164 | hostCfg.NetworkMode = networkMode |
| 165 | |
| 166 | created, err := s.apiClient().ContainerCreate(ctx, client.ContainerCreateOptions{ |
| 167 | Config: cfg, |
| 168 | HostConfig: hostCfg, |
| 169 | NetworkingConfig: networkingConfig, |
| 170 | }) |
| 171 | if err != nil { |
| 172 | return client.ContainerCreateResult{}, err |
| 173 | } |
| 174 | |
| 175 | if versions.LessThan(apiVersion, apiVersion144) { |
| 176 | if err := s.connectPreStartExtraNetworks(ctx, project, service, created.ID, networkMode); err != nil { |
| 177 | // Same reason as the ContainerStart-failure cleanup: AutoRemove never |
| 178 | // fires on a container that was created but not started. Surface |
| 179 | // any cleanup failure so the orphan is at least visible in logs. |
| 180 | if _, removeErr := s.apiClient().ContainerRemove(ctx, created.ID, client.ContainerRemoveOptions{Force: true}); removeErr != nil { |
| 181 | logrus.Warnf("service %q pre_start: failed to remove orphan hook container %s: %v", service.Name, created.ID, removeErr) |
| 182 | } |
no test coverage detected