Example #1
0
// DeleteTrustedKeyPrefix deletes the prefix trusted key identified by fingerprint.
func (ks *Keystore) DeleteTrustedKeyPrefix(prefix, fingerprint string) error {
	acname, err := types.NewACName(prefix)
	if err != nil {
		return err
	}
	return os.Remove(path.Join(ks.LocalPrefixPath, acname.String(), fingerprint))
}
Example #2
0
func handleAppAnnotation(w http.ResponseWriter, r *http.Request, pm *schema.PodManifest, im *schema.ImageManifest) {
	defer r.Body.Close()

	n := mux.Vars(r)["name"]
	k, err := types.NewACIdentifier(n)
	if err != nil {
		w.WriteHeader(http.StatusBadRequest)
		fmt.Fprintf(w, "App annotation name %q is not a valid AC Identifier", n)
		return
	}

	n = mux.Vars(r)["app"]
	an, err := types.NewACName(n)
	if err != nil {
		w.WriteHeader(http.StatusBadRequest)
		fmt.Fprintf(w, "App name %q is not a valid AC Name", n)
		return
	}

	merged := mergeAppAnnotations(im, pm, an)

	v, ok := merged.Get(k.String())
	if !ok {
		w.WriteHeader(http.StatusNotFound)
		fmt.Fprintf(w, "App annotation %q not found", k)
		return
	}

	w.Header().Add("Content-Type", "text/plain")
	w.WriteHeader(http.StatusOK)
	w.Write([]byte(v))
}
Example #3
0
// getAppName returns the app name to enter
// If one was supplied in the flags then it's simply returned
// If the PM contains a single app, that app's name is returned
// If the PM has multiple apps, the names are printed and an error is returned
func getAppName(p *pod) (*types.ACName, error) {
	if flagAppName != "" {
		return types.NewACName(flagAppName)
	}

	// figure out the app name, or show a list if multiple are present
	b, err := ioutil.ReadFile(common.PodManifestPath(p.path()))
	if err != nil {
		return nil, fmt.Errorf("error reading pod manifest: %v", err)
	}

	m := schema.PodManifest{}
	if err = m.UnmarshalJSON(b); err != nil {
		return nil, fmt.Errorf("unable to load manifest: %v", err)
	}

	switch len(m.Apps) {
	case 0:
		return nil, fmt.Errorf("pod contains zero apps")
	case 1:
		return &m.Apps[0].Name, nil
	default:
	}

	stderr("Pod contains multiple apps:")
	for _, ra := range m.Apps {
		stderr("\t%v", ra.Name)
	}

	return nil, fmt.Errorf("specify app using \"rkt enter --app= ...\"")
}
Example #4
0
// NewAppFromString takes a command line app parameter and returns a map of labels.
//
// Example app parameters:
// 	example.com/reduce-worker:1.0.0
// 	example.com/reduce-worker,channel=alpha,label=value
func NewAppFromString(app string) (*App, error) {
	var (
		name   string
		labels map[types.ACName]string
	)

	app = strings.Replace(app, ":", ",version=", -1)
	app = "name=" + app
	v, err := url.ParseQuery(strings.Replace(app, ",", "&", -1))
	if err != nil {
		return nil, err
	}
	labels = make(map[types.ACName]string, 0)
	for key, val := range v {
		if len(val) > 1 {
			return nil, fmt.Errorf("label %s with multiple values %q", key, val)
		}
		if key == "name" {
			name = val[0]
			continue
		}
		labelName, err := types.NewACName(key)
		if err != nil {
			return nil, err
		}
		labels[*labelName] = val[0]
	}
	a, err := NewApp(name, labels)
	if err != nil {
		return nil, err
	}
	return a, nil
}
Example #5
0
// StoreTrustedKeyPrefix stores the contents of public key r as a prefix trusted key.
func (ks *Keystore) StoreTrustedKeyPrefix(prefix string, r io.Reader) (string, error) {
	acname, err := types.NewACName(prefix)
	if err != nil {
		return "", err
	}
	return storeTrustedKey(path.Join(ks.LocalPrefixPath, acname.String()), r)
}
Example #6
0
func mergeManifests(manifests []schema.ImageManifest) schema.ImageManifest {
	// FIXME(iaguis) we take app layer's manifest as the final manifest for now
	manifest := manifests[0]

	manifest.Dependencies = nil

	layerIndex := -1
	for i, l := range manifest.Labels {
		if l.Name.String() == "layer" {
			layerIndex = i
		}
	}

	if layerIndex != -1 {
		manifest.Labels = append(manifest.Labels[:layerIndex], manifest.Labels[layerIndex+1:]...)
	}

	// this can't fail because the old name is legal
	nameWithoutLayerID, _ := appctypes.NewACName(stripLayerID(manifest.Name.String()))

	manifest.Name = *nameWithoutLayerID

	// once the image is squashed, we don't need a pathWhitelist
	manifest.PathWhitelist = nil

	return manifest
}
Example #7
0
// MaskTrustedKeySystemPrefix masks the system prefix trusted key identified by fingerprint.
func (ks *Keystore) MaskTrustedKeySystemPrefix(prefix, fingerprint string) (string, error) {
	acname, err := types.NewACName(prefix)
	if err != nil {
		return "", err
	}
	dst := path.Join(ks.LocalPrefixPath, acname.String(), fingerprint)
	return dst, ioutil.WriteFile(dst, []byte(""), 0644)
}
Example #8
0
func (ks *Keystore) loadKeyring(prefix string) (openpgp.KeyRing, error) {
	acname, err := types.NewACName(prefix)
	if err != nil {
		return nil, err
	}
	var keyring openpgp.EntityList
	trustedKeys := make(map[string]*openpgp.Entity)

	prefixRoot := strings.Split(acname.String(), "/")[0]
	paths := []struct {
		root     string
		fullPath string
	}{
		{ks.SystemRootPath, ks.SystemRootPath},
		{ks.LocalRootPath, ks.LocalRootPath},
		{path.Join(ks.SystemPrefixPath, prefixRoot), path.Join(ks.SystemPrefixPath, acname.String())},
		{path.Join(ks.LocalPrefixPath, prefixRoot), path.Join(ks.LocalPrefixPath, acname.String())},
	}
	for _, p := range paths {
		err := filepath.Walk(p.root, func(path string, info os.FileInfo, err error) error {
			if err != nil && !os.IsNotExist(err) {
				return err
			}
			if info == nil {
				return nil
			}
			if info.IsDir() {
				switch {
				case strings.HasPrefix(p.fullPath, path):
					return nil
				default:
					return filepath.SkipDir
				}
			}
			// Remove trust for default keys.
			if info.Size() == 0 {
				delete(trustedKeys, info.Name())
				return nil
			}
			entity, err := entityFromFile(path)
			if err != nil {
				return err
			}
			trustedKeys[fingerprintToFilename(entity.PrimaryKey.Fingerprint)] = entity
			return nil
		})
		if err != nil {
			return nil, err
		}
	}

	for _, v := range trustedKeys {
		keyring = append(keyring, v)
	}
	return keyring, nil
}
Example #9
0
func NewApp(name string, labels map[types.ACName]string) (*App, error) {
	if labels == nil {
		labels = make(map[types.ACName]string, 0)
	}
	acn, err := types.NewACName(name)
	if err != nil {
		return nil, err
	}
	return &App{
		Name:   *acn,
		Labels: labels,
	}, nil
}
Example #10
0
func checkSignature(ks *Keystore, prefix string, signed, signature io.Reader) (*openpgp.Entity, error) {
	acname, err := types.NewACName(prefix)
	if err != nil {
		return nil, err
	}
	keyring, err := ks.loadKeyring(acname.String())
	if err != nil {
		return nil, fmt.Errorf("keystore: error loading keyring %v", err)
	}
	entities, err := openpgp.CheckArmoredDetachedSignature(keyring, signed, signature)
	if err == io.EOF {
		// otherwise, the client failure is just "EOF", which is not helpful
		return nil, fmt.Errorf("keystore: no signatures found")
	}
	return entities, err
}
Example #11
0
func handleAppAnnotations(w http.ResponseWriter, r *http.Request, pm *schema.PodManifest, im *schema.ImageManifest) {
	defer r.Body.Close()

	n := mux.Vars(r)["app"]
	an, err := types.NewACName(n)
	if err != nil {
		w.WriteHeader(http.StatusBadRequest)
		fmt.Fprintf(w, "App name %q is not a valid AC Name", n)
		return
	}

	w.Header().Add("Content-Type", "text/plain")
	w.WriteHeader(http.StatusOK)

	for _, annot := range mergeAppAnnotations(im, pm, an) {
		fmt.Fprintln(w, string(annot.Name))
	}
}
Example #12
0
func handleAppID(w http.ResponseWriter, r *http.Request, pm *schema.PodManifest, im *schema.ImageManifest) {
	defer r.Body.Close()

	n := mux.Vars(r)["app"]
	an, err := types.NewACName(n)
	if err != nil {
		w.WriteHeader(http.StatusBadRequest)
		fmt.Fprintf(w, "App name %q is not a valid AC Name", n)
		return
	}

	w.Header().Add("Content-Type", "text/plain")
	w.WriteHeader(http.StatusOK)
	app := pm.Apps.Get(*an)
	if app == nil {
		// This is impossiple as we have already checked that
		// the image manifest is not nil in the parent function.
		panic("could not find app in manifest!")
	}
	w.Write([]byte(app.Image.ID.String()))
}
func handlePodAnnotation(w http.ResponseWriter, r *http.Request, pm *schema.PodManifest) {
	defer r.Body.Close()

	k, err := types.NewACName(mux.Vars(r)["name"])
	if err != nil {
		w.WriteHeader(http.StatusNotFound)
		fmt.Fprintf(w, "Pod annotation is not a valid AC Name")
		return
	}

	v, ok := pm.Annotations.Get(k.String())
	if !ok {
		w.WriteHeader(http.StatusNotFound)
		fmt.Fprintf(w, "Pod annotation (%v) not found", k)
		return
	}

	w.Header().Add("Content-Type", "text/plain")
	w.WriteHeader(http.StatusOK)
	w.Write([]byte(v))
}
Example #14
0
func (al *appMount) Set(s string) error {
	mount := schema.Mount{}

	// this is intentionally made similar to types.VolumeFromString()
	// TODO(iaguis) use MakeQueryString() when appc/spec#520 is merged
	m, err := url.ParseQuery(strings.Replace(s, ",", "&", -1))
	if err != nil {
		return err
	}

	for key, val := range m {
		if len(val) > 1 {
			return fmt.Errorf("label %s with multiple values %q", key, val)
		}
		switch key {
		case "volume":
			mv, err := types.NewACName(val[0])
			if err != nil {
				return fmt.Errorf("invalid volume name %q in --mount flag %q: %v", val[0], s, err)
			}
			mount.Volume = *mv
		case "target":
			mount.Path = val[0]
		default:
			return fmt.Errorf("unknown mount parameter %q", key)
		}
	}

	as := (*apps.Apps)(al)
	if as.Count() == 0 {
		as.Mounts = append(as.Mounts, mount)
	} else {
		app := as.Last()
		app.Mounts = append(app.Mounts, mount)
	}

	return nil
}
Example #15
0
File: run.go Project: fdserr/rkt
func (pl *portList) Set(s string) error {
	parts := strings.SplitN(s, ":", 2)
	if len(parts) != 2 {
		return fmt.Errorf("%q is not in name:port format", s)
	}

	name, err := types.NewACName(parts[0])
	if err != nil {
		return fmt.Errorf("%q is not a valid port name: %v", parts[0], err)
	}

	port, err := strconv.ParseUint(parts[1], 10, 16)
	if err != nil {
		return fmt.Errorf("%q is not a valid port number", parts[1])
	}

	p := types.ExposedPort{
		Name:     *name,
		HostPort: uint(port),
	}

	*pl = append(*pl, p)
	return nil
}
Example #16
0
func GenerateManifest(layerData types.DockerImageData, dockerURL *types.ParsedDockerURL) (*schema.ImageManifest, error) {
	dockerConfig := layerData.Config
	genManifest := &schema.ImageManifest{}

	appURL := ""
	// omit docker hub index URL in app name
	if dockerURL.IndexURL != defaultIndex {
		appURL = dockerURL.IndexURL + "/"
	}
	appURL += dockerURL.ImageName + "-" + layerData.ID
	appURL, err := appctypes.SanitizeACName(appURL)
	if err != nil {
		return nil, err
	}
	name, err := appctypes.NewACName(appURL)
	if err != nil {
		return nil, err
	}
	genManifest.Name = *name

	acVersion, err := appctypes.NewSemVer(schemaVersion)
	if err != nil {
		panic("invalid appc spec version")
	}
	genManifest.ACVersion = *acVersion

	genManifest.ACKind = appctypes.ACKind(schema.ImageManifestKind)

	var labels appctypes.Labels
	var parentLabels appctypes.Labels

	layer, _ := appctypes.NewACName("layer")
	labels = append(labels, appctypes.Label{Name: *layer, Value: layerData.ID})

	tag := dockerURL.Tag
	version, _ := appctypes.NewACName("version")
	labels = append(labels, appctypes.Label{Name: *version, Value: tag})

	if layerData.OS != "" {
		os, _ := appctypes.NewACName("os")
		labels = append(labels, appctypes.Label{Name: *os, Value: layerData.OS})
		parentLabels = append(parentLabels, appctypes.Label{Name: *os, Value: layerData.OS})

		if layerData.Architecture != "" {
			arch, _ := appctypes.NewACName("arch")
			parentLabels = append(parentLabels, appctypes.Label{Name: *arch, Value: layerData.Architecture})
		}
	}

	genManifest.Labels = labels

	if dockerConfig != nil {
		exec := getExecCommand(dockerConfig.Entrypoint, dockerConfig.Cmd)
		if exec != nil {
			user, group := parseDockerUser(dockerConfig.User)
			var env appctypes.Environment
			for _, v := range dockerConfig.Env {
				parts := strings.SplitN(v, "=", 2)
				env.Set(parts[0], parts[1])
			}
			app := &appctypes.App{
				Exec:             exec,
				User:             user,
				Group:            group,
				Environment:      env,
				WorkingDirectory: dockerConfig.WorkingDir,
			}
			genManifest.App = app
		}
	}

	if layerData.Parent != "" {
		parentAppNameString := dockerURL.IndexURL + "/" + dockerURL.ImageName + "-" + layerData.Parent
		parentAppNameString, err := appctypes.SanitizeACName(parentAppNameString)
		if err != nil {
			return nil, err
		}
		parentAppName, err := appctypes.NewACName(parentAppNameString)
		if err != nil {
			return nil, err
		}

		genManifest.Dependencies = append(genManifest.Dependencies, appctypes.Dependency{App: *parentAppName, Labels: parentLabels})
	}

	return genManifest, nil
}
Example #17
0
func patchManifest(im *schema.ImageManifest) error {

	if patchName != "" {
		name, err := types.NewACName(patchName)
		if err != nil {
			return err
		}
		im.Name = *name
	}

	if patchExec != "" {
		im.App.Exec = strings.Split(patchExec, " ")
	}

	if patchUser != "" {
		im.App.User = patchUser
	}
	if patchGroup != "" {
		im.App.Group = patchGroup
	}

	if patchCaps != "" {
		app := im.App
		if app == nil {
			return fmt.Errorf("no app in the manifest")
		}
		isolator := app.Isolators.GetByName(types.LinuxCapabilitiesRetainSetName)
		if isolator != nil {
			return fmt.Errorf("isolator already exists")
		}

		// Instantiate a Isolator with the content specified by the --capability
		// parameter.

		// TODO: Instead of creating a JSON and then unmarshalling it, the isolator
		// should be instantiated directory. But it requires a constructor, see:
		// https://github.com/appc/spec/issues/268
		capsList := strings.Split(patchCaps, ",")
		caps := fmt.Sprintf(`"set": ["%s"]`, strings.Join(capsList, `", "`))
		isolatorStr := getIsolatorStr(types.LinuxCapabilitiesRetainSetName, caps)
		isolator = &types.Isolator{}
		err := isolator.UnmarshalJSON([]byte(isolatorStr))
		if err != nil {
			return err
		}
		app.Isolators = append(app.Isolators, *isolator)
	}

	if patchMounts != "" {
		app := im.App
		if app == nil {
			return fmt.Errorf("no app in the manifest")
		}
		mounts := strings.Split(patchMounts, ":")
		for _, m := range mounts {
			mountPoint, err := types.MountPointFromString(m)
			if err != nil {
				return fmt.Errorf("cannot parse mount point %q", m)
			}
			app.MountPoints = append(app.MountPoints, *mountPoint)
		}
	}
	return nil
}