code: func validatePodManifest(cfg PrepareConfig, dir string) ([]byte, error) {
  	pmb, err := ioutil.ReadFile(cfg.PodManifest)
  	if err != nil {
  		return nil, errwrap.Wrap(errors.New("error reading pod manifest"), err)
  	}
  	var pm schema.PodManifest
  	if err := json.Unmarshal(pmb, &pm); err != nil {
  		return nil, errwrap.Wrap(errors.New("error unmarshaling pod manifest"), err)
  	}
  
  	appNames := make(map[types.ACName]struct{})
  	for _, ra := range pm.Apps {
  		img := ra.Image
  
  		if img.ID.Empty() {
  			return nil, fmt.Errorf("no image ID for app %q", ra.Name)
  		}
  		am, err := cfg.Store.GetImageManifest(img.ID.String())
  		if err != nil {
  			return nil, errwrap.Wrap(errors.New("error getting the image manifest from store"), err)
  		}
  		if _, err := prepareAppImage(cfg, ra.Name, img.ID, dir, cfg.UseOverlay); err != nil {
  			return nil, errwrap.Wrap(fmt.Errorf("error preparing image %s", img), err)
  		}
  		if _, ok := appNames[ra.Name]; ok {
  			return nil, fmt.Errorf("multiple apps with same name %s", ra.Name)
  		}
  		appNames[ra.Name] = struct{}{}
  		if ra.App == nil && am.App == nil {
  			return nil, fmt.Errorf("no app section in the pod manifest or the image manifest")
  		}
  	}
  
  	// Validate forwarded ports
  	if _, err := commonnet.ForwardedPorts(&pm); err != nil {
  		return nil, err
  	}
  	return pmb, nil
  }
docs: // validatePodManifest reads the user-specified pod manifest, prepares the app images
  // and validates the pod manifest. If the pod manifest passes validation, it returns
  // the manifest as []byte.
  // TODO(yifan): More validation in the future.