Beispiel #1
0
// prepareAppImage renders and verifies the tree cache of the app image that
// corresponds to the given hash.
// When useOverlay is false, it attempts to render and expand the app image
// TODO(jonboulle): tighten up the Hash type here; currently it is partially-populated (i.e. half-length sha512)
func prepareAppImage(cfg PrepareConfig, img types.Hash, cdir string, useOverlay bool) (*schema.ImageManifest, error) {
	log.Println("Loading image", img.String())

	if useOverlay {
		if err := cfg.Store.RenderTreeStore(img.String(), false); err != nil {
			return nil, fmt.Errorf("error rendering tree image: %v", err)
		}
		if err := cfg.Store.CheckTreeStore(img.String()); err != nil {
			log.Printf("Warning: tree cache is in a bad state. Rebuilding...")
			if err := cfg.Store.RenderTreeStore(img.String(), true); err != nil {
				return nil, fmt.Errorf("error rendering tree image: %v", err)
			}
		}
	} else {
		ad := common.AppImagePath(cdir, img)
		err := os.MkdirAll(ad, 0755)
		if err != nil {
			return nil, fmt.Errorf("error creating image directory: %v", err)
		}

		if err := aci.RenderACIWithImageID(img, ad, cfg.Store); err != nil {
			return nil, fmt.Errorf("error rendering ACI: %v", err)
		}
	}

	am, err := cfg.Store.GetImageManifest(img.String())
	if err != nil {
		return nil, fmt.Errorf("error getting the manifest: %v", err)
	}

	return am, nil
}
Beispiel #2
0
// setupAppImage mounts the overlay filesystem for the app image that
// corresponds to the given hash. Then, it creates the tmp directory.
// When useOverlay is false it just creates the tmp directory for this app.
func setupAppImage(cfg RunConfig, img types.Hash, cdir string, useOverlay bool) error {
	ad := common.AppImagePath(cdir, img)
	if useOverlay {
		err := os.MkdirAll(ad, 0776)
		if err != nil {
			return fmt.Errorf("error creating image directory: %v", err)
		}

		if err := overlayRender(cfg, img, cdir, ad); err != nil {
			return fmt.Errorf("error rendering overlay filesystem: %v", err)
		}
	}

	err := os.MkdirAll(filepath.Join(ad, "rootfs/tmp"), 0777)
	if err != nil {
		return fmt.Errorf("error creating tmp directory: %v", err)
	}

	return nil
}
Beispiel #3
0
// emptyExitedGarbage discards sufficiently aged pods from exitedGarbageDir()
func emptyExitedGarbage(gracePeriod time.Duration) error {
	if err := walkPods(includeExitedGarbageDir, func(p *pod) {
		gp := p.path()
		st := &syscall.Stat_t{}
		if err := syscall.Lstat(gp, st); err != nil {
			if err != syscall.ENOENT {
				stderr("Unable to stat %q, ignoring: %v", gp, err)
			}
			return
		}

		if expiration := time.Unix(st.Ctim.Unix()).Add(gracePeriod); time.Now().After(expiration) {
			if err := p.ExclusiveLock(); err != nil {
				return
			}
			stdout("Garbage collecting pod %q", p.uuid)

			s, err := store.NewStore(globalFlags.Dir)
			if err != nil {
				stderr("Cannot open store: %v", err)
				return
			}
			stage1ID, err := p.getStage1Hash()
			if err != nil {
				stderr("Error getting stage1 hash")
				return
			}
			stage1RootFS := s.GetTreeStoreRootFS(stage1ID.String())

			if p.usesOverlay() {
				apps, err := p.getAppsHashes()
				if err != nil {
					stderr("Error retrieving app hashes from pod manifest: %v", err)
					return
				}
				for _, a := range apps {
					dest := filepath.Join(common.AppImagePath(p.path(), a), "rootfs")
					if err := syscall.Unmount(dest, 0); err != nil {
						// machine could have been rebooted and mounts lost.
						// ignore "does not exist" and "not a mount point" errors
						if err != syscall.ENOENT && err != syscall.EINVAL {
							stderr("Error unmounting app at %v: %v", dest, err)
						}
					}
				}

				s1 := filepath.Join(common.Stage1ImagePath(p.path()), "rootfs")
				if err := syscall.Unmount(s1, 0); err != nil {
					// machine could have been rebooted and mounts lost.
					// ignore "does not exist" and "not a mount point" errors
					if err != syscall.ENOENT && err != syscall.EINVAL {
						stderr("Error unmounting stage1 at %v: %v", s1, err)
						return
					}
				}
			}

			// execute stage1's GC
			if err := stage0.GC(p.path(), p.uuid, stage1RootFS, globalFlags.Debug); err != nil {
				stderr("Stage1 GC of pod %q failed: %v", p.uuid, err)
				return
			}

			if err := os.RemoveAll(gp); err != nil {
				stderr("Unable to remove pod %q: %v", p.uuid, err)
			}
		}
	}); err != nil {
		return err
	}

	return nil
}