Skip to content

Commit 4e65f64

Browse files
author
James Bardin
committed
Work with change to content-addressable IDs
- Strip the leading "sha256:" from content-addressable images to match the displayed IDs. - Only warn if an image is pulled where the image ID doesn't match the recorded VersionID. Move warning to the code that starts the service. - Don't stop containers when the image ID doesn't match. If the config version matches, it's the right container. If the image doesn't match, we'll still get warnings when checking for the latest image, and can fix by redeploying a new config. - Don't InspectImage before pulling, since PullImage will do the same. - Don't pull every 10s, since the service check will pull again. - Warn when a contaner dies and is automatically restarted. - Periodically warn when a container's image doesn't match the config.
1 parent b6d8f8e commit 4e65f64

File tree

4 files changed

+48
-44
lines changed

4 files changed

+48
-44
lines changed

cmd/commander/main.go

+21-26
Original file line numberDiff line numberDiff line change
@@ -107,27 +107,13 @@ func pullImageAsync(appCfg config.App, errChan chan error) {
107107
}
108108

109109
func pullImage(appCfg config.App) (*docker.Image, error) {
110-
111-
image, err := serviceRuntime.InspectImage(appCfg.Version())
112-
if image != nil && image.ID == appCfg.VersionID() || appCfg.VersionID() == "" {
113-
return image, nil
114-
}
115-
116-
log.Printf("Pulling %s version %s\n", appCfg.Name(), appCfg.Version())
117-
image, err = serviceRuntime.PullImage(appCfg.Version(),
118-
appCfg.VersionID())
110+
image, err := serviceRuntime.PullImage(appCfg.Version(), appCfg.VersionID())
119111
if image == nil || err != nil {
120-
log.Errorf("ERROR: Could not pull image %s: %s",
121-
appCfg.Version(), err)
112+
log.Errorf("ERROR: Could not pull image %s: %s", appCfg.Version(), err)
122113
return nil, err
123114
}
124115

125-
if image.ID != appCfg.VersionID() && len(appCfg.VersionID()) > 12 {
126-
log.Errorf("WARNING: Pulled image for %s does not match expected ID. Expected: %s: Got: %s",
127-
appCfg.Version(), image.ID[0:12], appCfg.VersionID()[0:12])
128-
}
129-
130-
log.Printf("Pulled %s\n", appCfg.Version())
116+
log.Printf("Pulled %s version %s\n", appCfg.Name(), appCfg.Version())
131117
return image, nil
132118
}
133119

@@ -173,11 +159,13 @@ func startService(appCfg config.App, logStatus bool) {
173159
}
174160
}
175161

176-
err = serviceRuntime.StopAllButCurrentVersion(appCfg)
162+
err = serviceRuntime.StopOldVersion(appCfg, -1)
177163
if err != nil {
178164
log.Errorf("ERROR: Could not stop old containers: %s", err)
179165
}
180166

167+
// check the image version, and log any inconsistencies
168+
inspectImage(appCfg)
181169
}
182170

183171
func heartbeatHost() {
@@ -217,6 +205,21 @@ func appAssigned(app string) (bool, error) {
217205
return true, nil
218206
}
219207

208+
// inspectImage checks that the running image matches the config.
209+
// We only use this to print warnings, since we likely need to deploy a new
210+
// config version to fix the inconsistency.
211+
func inspectImage(appCfg config.App) {
212+
image, err := serviceRuntime.InspectImage(appCfg.Version())
213+
if err != nil {
214+
log.Println("error inspecting image", appCfg.Version)
215+
return
216+
}
217+
218+
if utils.StripSHA(image.ID) != appCfg.VersionID() {
219+
log.Printf("warning: %s image ID does not match config", appCfg.Name())
220+
}
221+
}
222+
220223
func restartContainers(app string, cmdChan chan string) {
221224
defer wg.Done()
222225
logOnce := true
@@ -314,14 +317,6 @@ func restartContainers(app string, cmdChan chan string) {
314317
continue
315318
}
316319

317-
_, err = pullImage(appCfg)
318-
if err != nil {
319-
if !loop {
320-
return
321-
}
322-
log.Errorf("ERROR: Could not pull images: %s", err)
323-
continue
324-
}
325320
startService(appCfg, logOnce)
326321
}
327322

commander/app.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -130,7 +130,7 @@ func AppDeploy(configStore *config.Store, serviceRuntime *runtime.ServiceRuntime
130130
}
131131

132132
svcCfg.SetVersion(version)
133-
svcCfg.SetVersionID(image.ID)
133+
svcCfg.SetVersionID(utils.StripSHA(image.ID))
134134

135135
updated, err := configStore.UpdateApp(svcCfg, env)
136136
if err != nil {

runtime/runtime.go

+21-17
Original file line numberDiff line numberDiff line change
@@ -280,17 +280,21 @@ func (s *ServiceRuntime) StopOldVersion(appCfg config.App, limit int) error {
280280

281281
version := env["GALAXY_VERSION"]
282282

283-
imageDiffers := image.ID != appCfg.VersionID() && appCfg.VersionID() != ""
284-
versionDiffers := version != strconv.FormatInt(appCfg.ID(), 10) && version != ""
283+
if version == "" {
284+
log.Printf("WARNING: %s missing GALAXY_VERSION", appCfg.ContainerName())
285+
}
285286

286-
if imageDiffers || versionDiffers {
287+
if version != strconv.FormatInt(appCfg.ID(), 10) && version != "" {
287288
s.stopContainer(container)
288289
stopped = stopped + 1
289290
}
290291
}
292+
291293
return nil
292294
}
293295

296+
/*
297+
FIXME: using StopOldVersion(cfg, -1) for now
294298
func (s *ServiceRuntime) StopAllButCurrentVersion(appCfg config.App) error {
295299
containers, err := s.ManagedContainers()
296300
if err != nil {
@@ -328,6 +332,7 @@ func (s *ServiceRuntime) StopAllButCurrentVersion(appCfg config.App) error {
328332
}
329333
return nil
330334
}
335+
*/
331336

332337
// TODO: these aren't called from anywhere. Are they useful?
333338
/*
@@ -607,16 +612,15 @@ func (s *ServiceRuntime) Start(env, pool string, appCfg config.App) (*docker.Con
607612

608613
img := appCfg.Version()
609614

610-
imgIdRef := appCfg.Version()
611-
if appCfg.VersionID() != "" {
612-
imgIdRef = appCfg.VersionID()
613-
}
614-
// see if we have the image locally
615-
image, err := s.PullImage(img, imgIdRef)
615+
image, err := s.PullImage(img, appCfg.VersionID())
616616
if err != nil {
617617
return nil, err
618618
}
619619

620+
if utils.StripSHA(image.ID) != appCfg.VersionID() {
621+
log.Warnf("warning: ID for image %s doesn't match configuration", img)
622+
}
623+
620624
// setup env vars from etcd
621625
var envVars []string
622626
envVars = append(envVars, "ENV"+"="+env)
@@ -802,20 +806,23 @@ func findAuth(registry string) docker.AuthConfiguration {
802806
return auths.Configs[defaultIndexServer]
803807
}
804808

809+
// Pull a docker image.
810+
// If we have an image matching the tag, and the given id matches the current
811+
// image, don't fetch a new one from the registry.
805812
func (s *ServiceRuntime) PullImage(version, id string) (*docker.Image, error) {
806813
image, err := s.InspectImage(version)
807814

808815
if err != nil && err != docker.ErrNoSuchImage {
809816
return nil, err
810817
}
811818

812-
if image != nil && image.ID == id {
819+
if image != nil && utils.StripSHA(image.ID) == id {
813820
return image, nil
814821
}
815822

816823
registry, repository, tag := utils.SplitDockerImage(version)
817824

818-
// No, pull it down locally
825+
// pull it down locally
819826
pullOpts := docker.PullImageOptions{
820827
Repository: repository,
821828
Tag: tag,
@@ -837,11 +844,6 @@ func (s *ServiceRuntime) PullImage(version, id string) (*docker.Image, error) {
837844
err = s.dockerClient.PullImage(pullOpts, dockerAuth)
838845
if err != nil {
839846

840-
// Don't retry 404, they'll never succeed
841-
if err.Error() == "HTTP code: 404" {
842-
return image, nil
843-
}
844-
845847
if retries > 3 {
846848
return image, err
847849
}
@@ -852,7 +854,6 @@ func (s *ServiceRuntime) PullImage(version, id string) (*docker.Image, error) {
852854
}
853855

854856
return s.InspectImage(version)
855-
856857
}
857858

858859
func (s *ServiceRuntime) RegisterAll(env, pool, hostIP string) ([]*config.ServiceRegistration, error) {
@@ -967,6 +968,9 @@ func (s *ServiceRuntime) RegisterEvents(env, pool, hostIP string, listener chan
967968

968969
// if a container is restarting, don't continue re-registering the app
969970
if container.State.Restarting {
971+
if e.Status == "die" {
972+
log.Println("WARN: restarting", container.Name)
973+
}
970974
continue
971975
}
972976

utils/utils.go

+5
Original file line numberDiff line numberDiff line change
@@ -172,3 +172,8 @@ func ParseMemory(mem string) (int64, error) {
172172
}
173173
return i * multiplier, nil
174174
}
175+
176+
// strip the leading sha256: from content adressable images
177+
func StripSHA(s string) string {
178+
return strings.TrimPrefix(s, "sha256:")
179+
}

0 commit comments

Comments
 (0)