Example #1
0
File: pod.go Project: drcapulet/p2
// Write servicebuilder *.yaml file and run servicebuilder, which will register runit services for this
// pod.
func (pod *Pod) buildRunitServices(launchables []launch.Launchable, newManifest manifest.Manifest) error {
	// if the service is new, building the runit services also starts them
	sbTemplate := make(map[string]runit.ServiceTemplate)
	for _, launchable := range launchables {
		executables, err := launchable.Executables(pod.ServiceBuilder)
		if err != nil {
			pod.logLaunchableError(launchable.ServiceID(), err, "Unable to list executables")
			continue
		}
		for _, executable := range executables {
			if _, ok := sbTemplate[executable.Service.Name]; ok {
				return util.Errorf("Duplicate executable %q for launchable %q", executable.Service.Name, launchable.ServiceID())
			}
			sbTemplate[executable.Service.Name] = runit.ServiceTemplate{
				Log:    pod.LogExec,
				Run:    executable.Exec,
				Finish: pod.FinishExecForLaunchable(launchable),
			}
		}
	}
	err := pod.ServiceBuilder.Activate(string(pod.Id), sbTemplate, newManifest.GetRestartPolicy())
	if err != nil {
		return err
	}

	// as with the original servicebuilder, prune after creating
	// new services
	return pod.ServiceBuilder.Prune()
}
Example #2
0
File: pod.go Project: drcapulet/p2
func (pod *Pod) Launchables(manifest manifest.Manifest) ([]launch.Launchable, error) {
	launchableStanzas := manifest.GetLaunchableStanzas()
	launchables := make([]launch.Launchable, 0, len(launchableStanzas))

	for _, launchableStanza := range launchableStanzas {
		launchable, err := pod.getLaunchable(launchableStanza, manifest.RunAsUser(), manifest.GetRestartPolicy())
		if err != nil {
			return nil, err
		}
		launchables = append(launchables, launchable)
	}

	return launchables, nil
}
Example #3
0
File: pod.go Project: drcapulet/p2
func (pod *Pod) Verify(manifest manifest.Manifest, authPolicy auth.Policy) error {
	for _, stanza := range manifest.GetLaunchableStanzas() {
		if stanza.DigestLocation == "" {
			continue
		}
		launchable, err := pod.getLaunchable(stanza, manifest.RunAsUser(), manifest.GetRestartPolicy())
		if err != nil {
			return err
		}

		digestLocationURL, err := url.Parse(stanza.DigestLocation)
		if err != nil {
			return util.Errorf("Couldn't parse digest location '%s' as a url: %s", stanza.DigestLocation, err)
		}

		digestSignatureLocationURL, err := url.Parse(stanza.DigestSignatureLocation)
		if err != nil {
			return util.Errorf("Couldn't parse digest signature location '%s' as a url: %s", stanza.DigestSignatureLocation, err)
		}

		// Retrieve the digest data
		launchableDigest, err := digest.ParseUris(
			uri.DefaultFetcher,
			digestLocationURL,
			digestSignatureLocationURL,
		)
		if err != nil {
			return err
		}

		// Check that the digest is certified
		err = authPolicy.CheckDigest(launchableDigest)
		if err != nil {
			return err
		}

		// Check that the installed files match the digest
		err = launchableDigest.VerifyDir(launchable.InstallDir())
		if err != nil {
			return err
		}
	}
	return nil
}
Example #4
0
File: pod.go Project: drcapulet/p2
// Install will ensure that executables for all required services are present on the host
// machine and are set up to run. In the case of Hoist artifacts (which is the only format
// supported currently, this will set up runit services.).
func (pod *Pod) Install(manifest manifest.Manifest, verifier auth.ArtifactVerifier, artifactRegistry artifact.Registry) error {
	podHome := pod.home
	uid, gid, err := user.IDs(manifest.RunAsUser())
	if err != nil {
		return util.Errorf("Could not determine pod UID/GID for %s: %s", manifest.RunAsUser(), err)
	}

	err = util.MkdirChownAll(podHome, uid, gid, 0755)
	if err != nil {
		return util.Errorf("Could not create pod home: %s", err)
	}

	launchables, err := pod.Launchables(manifest)
	if err != nil {
		return err
	}

	downloader := artifact.NewLocationDownloader(pod.Fetcher, verifier)
	for launchableID, stanza := range manifest.GetLaunchableStanzas() {
		// TODO: investigate passing in necessary fields to InstallDir()
		launchable, err := pod.getLaunchable(stanza, manifest.RunAsUser(), manifest.GetRestartPolicy())
		if err != nil {
			pod.logLaunchableError(launchable.ServiceID(), err, "Unable to install launchable")
			return err
		}

		if launchable.Installed() {
			continue
		}

		launchableURL, verificationData, err := artifactRegistry.LocationDataForLaunchable(launchableID, stanza)
		if err != nil {
			pod.logLaunchableError(launchable.ServiceID(), err, "Unable to install launchable")
			return err
		}

		err = downloader.Download(launchableURL, verificationData, launchable.InstallDir(), manifest.RunAsUser())
		if err != nil {
			pod.logLaunchableError(launchable.ServiceID(), err, "Unable to install launchable")
			_ = os.Remove(launchable.InstallDir())
			return err
		}

		err = launchable.PostInstall()
		if err != nil {
			pod.logLaunchableError(launchable.ServiceID(), err, "Unable to install launchable")
			_ = os.Remove(launchable.InstallDir())
			return err
		}
	}

	// we may need to write config files to a unique directory per pod version, depending on restart semantics. Need
	// to think about this more.
	err = pod.setupConfig(manifest, launchables)
	if err != nil {
		pod.logError(err, "Could not setup config")
		return util.Errorf("Could not setup config: %s", err)
	}

	pod.logInfo("Successfully installed")

	return nil
}