示例#1
0
func runValidate(args []string) (exit int) {
	if len(args) < 1 {
		stderr("must pass one or more files")
		return 1
	}

	for _, path := range args {
		vt := valType
		fi, err := os.Stat(path)
		if err != nil {
			stderr("unable to access %s: %v", path, err)
			return 1
		}
		var fh *os.File
		if fi.IsDir() {
			switch vt {
			case typeImageLayout:
			case "":
				vt = typeImageLayout
			case typeManifest, typeAppImage:
				stderr("%s is a directory (wrong --type?)", path)
				return 1
			default:
				// should never happen
				panic(fmt.Sprintf("unexpected type: %v", vt))
			}
		} else {
			fh, err = os.Open(path)
			if err != nil {
				stderr("%s: unable to open: %v", path, err)
				return 1
			}
		}

		if vt == "" {
			vt, err = detectValType(fh)
			if err != nil {
				stderr("%s: error detecting file type: %v", path, err)
				return 1
			}
		}
		switch vt {
		case typeImageLayout:
			err = aci.ValidateLayout(path)
			if err != nil {
				stderr("%s: invalid image layout: %v", path, err)
				exit = 1
			} else if globalFlags.Debug {
				stderr("%s: valid image layout", path)
			}
		case typeAppImage:
			tr, err := aci.NewCompressedTarReader(fh)
			if err != nil {
				stderr("%s: error decompressing file: %v", path, err)
				return 1
			}
			err = aci.ValidateArchive(tr.Reader)
			tr.Close()
			fh.Close()
			if err != nil {
				if e, ok := err.(aci.ErrOldVersion); ok {
					stderr("%s: warning: %v", path, e)
				} else {
					stderr("%s: error validating: %v", path, err)
					exit = 1
				}
			} else if globalFlags.Debug {
				stderr("%s: valid app container image", path)
			}
		case typeManifest:
			b, err := ioutil.ReadAll(fh)
			fh.Close()
			if err != nil {
				stderr("%s: unable to read file %s", path, err)
				return 1
			}
			k := schema.Kind{}
			if err := k.UnmarshalJSON(b); err != nil {
				stderr("%s: error unmarshaling manifest: %v", path, err)
				return 1
			}
			switch k.ACKind {
			case "ImageManifest":
				m := schema.ImageManifest{}
				err = m.UnmarshalJSON(b)
			case "PodManifest":
				m := schema.PodManifest{}
				err = m.UnmarshalJSON(b)
			default:
				// Should not get here; schema.Kind unmarshal should fail
				panic("bad ACKind")
			}
			if err != nil {
				stderr("%s: invalid %s: %v", path, k.ACKind, err)
				exit = 1
			} else if globalFlags.Debug {
				stderr("%s: valid %s", path, k.ACKind)
			}
		default:
			stderr("%s: unable to detect filetype (try --type)", path)
			return 1
		}
	}

	return
}
示例#2
0
func runBuild(args []string) (exit int) {
	if len(args) != 2 {
		stderr("build: Must provide directory and output file")
		return 1
	}

	root := args[0]
	tgt := args[1]
	ext := filepath.Ext(tgt)
	if ext != schema.ACIExtension {
		stderr("build: Extension must be %s (given %s)", schema.ACIExtension, ext)
		return 1
	}

	// TODO(jonboulle): stream the validation so we don't have to walk the rootfs twice
	if err := aci.ValidateLayout(root); err != nil {
		if e, ok := err.(aci.ErrOldVersion); ok {
			stderr("build: Warning: %v. Please update your manifest.", e)
		} else {
			stderr("build: Layout failed validation: %v", err)
			return 1
		}
	}

	mode := os.O_CREATE | os.O_WRONLY
	if buildOverwrite {
		mode |= os.O_TRUNC
	} else {
		mode |= os.O_EXCL
	}
	fh, err := os.OpenFile(tgt, mode, 0644)
	if err != nil {
		if os.IsExist(err) {
			stderr("build: Target file exists (try --overwrite)")
		} else {
			stderr("build: Unable to open target %s: %v", tgt, err)
		}
		return 1
	}

	var gw *gzip.Writer
	var r io.WriteCloser = fh
	if !buildNocompress {
		gw = gzip.NewWriter(fh)
		r = gw
	}
	tr := tar.NewWriter(r)

	defer func() {
		tr.Close()
		if !buildNocompress {
			gw.Close()
		}
		fh.Close()
		if exit != 0 && !buildOverwrite {
			os.Remove(tgt)
		}
	}()

	mpath := filepath.Join(root, aci.ManifestFile)
	b, err := ioutil.ReadFile(mpath)
	if err != nil {
		stderr("build: Unable to read Image Manifest: %v", err)
		return 1
	}
	var im schema.ImageManifest
	if err := im.UnmarshalJSON(b); err != nil {
		stderr("build: Unable to load Image Manifest: %v", err)
		return 1
	}
	iw := aci.NewImageWriter(im, tr)

	var walkerCb aci.TarHeaderWalkFunc
	if buildOwnerRoot {
		walkerCb = func(hdr *tar.Header) bool {
			hdr.Uid, hdr.Gid = 0, 0
			hdr.Uname, hdr.Gname = "root", "root"
			return true
		}
	}

	err = filepath.Walk(root, aci.BuildWalker(root, iw, walkerCb))
	if err != nil {
		stderr("build: Error walking rootfs: %v", err)
		return 1
	}

	err = iw.Close()
	if err != nil {
		stderr("build: Unable to close image %s: %v", tgt, err)
		return 1
	}

	return
}