func testHookListener(t *testing.T) (HookListener, string, <-chan struct{}) { hookPrefix := kp.HOOK_TREE destDir, _ := ioutil.TempDir("", "pods") defer os.RemoveAll(destDir) execDir, err := ioutil.TempDir("", "exec") defer os.RemoveAll(execDir) Assert(t).IsNil(err, "should not have erred creating a tempdir") current, err := user.Current() Assert(t).IsNil(err, "test setup: could not get the current user") builder := manifest.NewBuilder() builder.SetID("users") builder.SetRunAsUser(current.Username) builder.SetLaunchables(map[launch.LaunchableID]launch.LaunchableStanza{ "create": { Location: util.From(runtime.Caller(0)).ExpandPath("hoisted-hello_def456.tar.gz"), LaunchableType: "hoist", LaunchableId: "create", }, }) podManifest := builder.GetManifest() manifestBytes, err := podManifest.Marshal() Assert(t).IsNil(err, "manifest bytes error should have been nil") fakeSigner, err := openpgp.NewEntity("p2", "p2-test", "*****@*****.**", nil) Assert(t).IsNil(err, "NewEntity error should have been nil") var buf bytes.Buffer sigWriter, err := clearsign.Encode(&buf, fakeSigner.PrivateKey, nil) Assert(t).IsNil(err, "clearsign encode error should have been nil") sigWriter.Write(manifestBytes) sigWriter.Close() podManifest, err = manifest.FromBytes(buf.Bytes()) Assert(t).IsNil(err, "should have generated manifest from signed bytes") fakeIntent := fakeStoreWithManifests(kp.ManifestResult{ Manifest: podManifest, }) hookFactory := pods.NewHookFactory(destDir, "testNode") listener := HookListener{ Intent: fakeIntent, HookPrefix: hookPrefix, ExecDir: execDir, HookFactory: hookFactory, Logger: logging.DefaultLogger, authPolicy: auth.FixedKeyringPolicy{openpgp.EntityList{fakeSigner}, nil}, artifactVerifier: auth.NopVerifier(), artifactRegistry: artifact.NewRegistry(nil, uri.DefaultFetcher, osversion.DefaultDetector), } return listener, destDir, fakeIntent.quit }
func TestInstallHooks(t *testing.T) { destDir, _ := ioutil.TempDir("", "pods") defer os.RemoveAll(destDir) execDir, err := ioutil.TempDir("", "exec") defer os.RemoveAll(execDir) Assert(t).IsNil(err, "should not have erred creating a tempdir") current, err := user.Current() Assert(t).IsNil(err, "test setup: could not get the current user") builder := manifest.NewBuilder() builder.SetID("users") builder.SetRunAsUser(current.Username) builder.SetLaunchables(map[launch.LaunchableID]launch.LaunchableStanza{ "create": { Location: util.From(runtime.Caller(0)).ExpandPath("testdata/hoisted-hello_def456.tar.gz"), LaunchableType: "hoist", }, }) podManifest := builder.GetManifest() hookFactory := pods.NewHookFactory(destDir, "testNode") hooksPod := hookFactory.NewHookPod(podManifest.ID()) preparer := Preparer{ hooksManifest: podManifest, hooksPod: hooksPod, hooksExecDir: execDir, Logger: logging.DefaultLogger, artifactRegistry: artifact.NewRegistry(nil, uri.DefaultFetcher, osversion.DefaultDetector), artifactVerifier: auth.NopVerifier(), } err = preparer.InstallHooks() Assert(t).IsNil(err, "There should not have been an error in the call to SyncOnce()") currentAlias := filepath.Join(destDir, "users", "create", "current", "bin", "launch") _, err = os.Stat(currentAlias) Assert(t).IsNil(err, fmt.Sprintf("%s should have been created", currentAlias)) hookFile := filepath.Join(execDir, "users__create__launch") _, err = os.Stat(hookFile) Assert(t).IsNil(err, "should have created the user launch script") }
func main() { kingpin.Version(version.VERSION) kingpin.Parse() if *nodeName == "" { hostname, err := os.Hostname() if err != nil { log.Fatalf("error getting node name: %v", err) } *nodeName = hostname } manifest, err := manifest.FromURI(*manifestURI) if err != nil { log.Fatalf("%s", err) } hookFactory := pods.NewHookFactory(filepath.Join(*podRoot, "hooks", *hookType), types.NodeName(*nodeName)) // /data/pods/hooks/<event>/<id> // if the event is the empty string (global hook), then that path segment // will be cleaned out pod := hookFactory.NewHookPod(manifest.ID()) // for now use noop verifier in this CLI err = pod.Install(manifest, auth.NopVerifier(), artifact.NewRegistry(*registryURI, uri.DefaultFetcher, osversion.DefaultDetector)) if err != nil { log.Fatalf("Could not install manifest %s: %s", manifest.ID(), err) } // hooks write their current manifest manually since it's normally done at // launch time _, err = pod.WriteCurrentManifest(manifest) if err != nil { log.Fatalf("Could not write current manifest for %s: %s", manifest.ID(), err) } err = hooks.InstallHookScripts(*hookRoot, pod, manifest, logging.DefaultLogger) if err != nil { log.Fatalf("Could not write hook scripts: %s", err) } }
func New(preparerConfig *PreparerConfig, logger logging.Logger) (*Preparer, error) { addHooks(preparerConfig, logger) if preparerConfig.ConsulAddress == "" { return nil, util.Errorf("No Consul address given to the preparer") } if preparerConfig.PodRoot == "" { return nil, util.Errorf("No pod root given to the preparer") } if preparerConfig.LogLevel != "" { lv, err := logrus.ParseLevel(preparerConfig.LogLevel) if err != nil { return nil, util.Errorf("Received invalid log level %q", preparerConfig.LogLevel) } logger.Logger.Level = lv } authPolicy, err := getDeployerAuth(preparerConfig) if err != nil { return nil, err } artifactVerifier, err := getArtifactVerifier(preparerConfig, &logger) if err != nil { return nil, err } artifactRegistry, err := getArtifactRegistry(preparerConfig) if err != nil { return nil, err } store, err := preparerConfig.GetStore() if err != nil { return nil, err } maxLaunchableDiskUsage := launch.DefaultAllowableDiskUsage if preparerConfig.MaxLaunchableDiskUsage != "" { maxLaunchableDiskUsage, err = size.Parse(preparerConfig.MaxLaunchableDiskUsage) if err != nil { return nil, util.Errorf("Unparseable value for max_launchable_disk_usage %v, %v", preparerConfig.MaxLaunchableDiskUsage, err) } } listener := HookListener{ Intent: store, HookPrefix: kp.HOOK_TREE, Node: preparerConfig.NodeName, HookFactory: pods.NewHookFactory(filepath.Join(preparerConfig.PodRoot, "hooks"), preparerConfig.NodeName), ExecDir: preparerConfig.HooksDirectory, Logger: logger, authPolicy: authPolicy, artifactVerifier: artifactVerifier, artifactRegistry: artifactRegistry, } err = os.MkdirAll(preparerConfig.PodRoot, 0755) if err != nil { return nil, util.Errorf("Could not create preparer pod directory: %s", err) } var logExec []string if len(preparerConfig.LogExec) > 0 { logExec = preparerConfig.LogExec } else { logExec = runit.DefaultLogExec() } var finishExec []string if len(preparerConfig.FinishExec) > 0 { finishExec = preparerConfig.FinishExec } else { finishExec = pods.DefaultFinishExec } return &Preparer{ node: preparerConfig.NodeName, store: store, hooks: hooks.Hooks(preparerConfig.HooksDirectory, &logger), hookListener: listener, Logger: logger, podFactory: pods.NewFactory(preparerConfig.PodRoot, preparerConfig.NodeName), authPolicy: authPolicy, maxLaunchableDiskUsage: maxLaunchableDiskUsage, finishExec: finishExec, logExec: logExec, logBridgeBlacklist: preparerConfig.LogBridgeBlacklist, artifactVerifier: artifactVerifier, artifactRegistry: artifactRegistry, }, nil }
func New(preparerConfig *PreparerConfig, logger logging.Logger) (*Preparer, error) { addHooks(preparerConfig, logger) if preparerConfig.ConsulAddress == "" { return nil, util.Errorf("No Consul address given to the preparer") } if preparerConfig.PodRoot == "" { return nil, util.Errorf("No pod root given to the preparer") } if preparerConfig.LogLevel != "" { lv, err := logrus.ParseLevel(preparerConfig.LogLevel) if err != nil { return nil, util.Errorf("Received invalid log level %q", preparerConfig.LogLevel) } logger.Logger.Level = lv } authPolicy, err := getDeployerAuth(preparerConfig) if err != nil { return nil, err } artifactVerifier, err := getArtifactVerifier(preparerConfig, &logger) if err != nil { return nil, err } artifactRegistry, err := getArtifactRegistry(preparerConfig) if err != nil { return nil, err } client, err := preparerConfig.GetConsulClient() if err != nil { return nil, err } statusStore := statusstore.NewConsul(client) podStatusStore := podstatus.NewConsul(statusStore, kp.PreparerPodStatusNamespace) podStore := podstore.NewConsul(client.KV()) store := kp.NewConsulStore(client) maxLaunchableDiskUsage := launch.DefaultAllowableDiskUsage if preparerConfig.MaxLaunchableDiskUsage != "" { maxLaunchableDiskUsage, err = size.Parse(preparerConfig.MaxLaunchableDiskUsage) if err != nil { return nil, util.Errorf("Unparseable value for max_launchable_disk_usage %v, %v", preparerConfig.MaxLaunchableDiskUsage, err) } } err = os.MkdirAll(preparerConfig.PodRoot, 0755) if err != nil { return nil, util.Errorf("Could not create preparer pod directory: %s", err) } var logExec []string if len(preparerConfig.LogExec) > 0 { logExec = preparerConfig.LogExec } else { logExec = runit.DefaultLogExec() } finishExec := pods.NopFinishExec var podProcessReporter *podprocess.Reporter if preparerConfig.PodProcessReporterConfig.FullyConfigured() { podProcessReporterLogger := logger.SubLogger(logrus.Fields{ "component": "PodProcessReporter", }) podProcessReporter, err = podprocess.New(preparerConfig.PodProcessReporterConfig, podProcessReporterLogger, podStatusStore) if err != nil { return nil, err } finishExec = preparerConfig.PodProcessReporterConfig.FinishExec() } var hooksManifest manifest.Manifest var hooksPod *pods.Pod if preparerConfig.HooksManifest != NoHooksSentinelValue { if preparerConfig.HooksManifest == "" { return nil, util.Errorf("Most provide a hooks_manifest or sentinel value %q to indicate that there are no hooks", NoHooksSentinelValue) } hooksManifest, err = manifest.FromBytes([]byte(preparerConfig.HooksManifest)) if err != nil { return nil, util.Errorf("Could not parse configured hooks manifest: %s", err) } hooksPodFactory := pods.NewHookFactory(filepath.Join(preparerConfig.PodRoot, "hooks"), preparerConfig.NodeName) hooksPod = hooksPodFactory.NewHookPod(hooksManifest.ID()) } return &Preparer{ node: preparerConfig.NodeName, store: store, hooks: hooks.Hooks(preparerConfig.HooksDirectory, preparerConfig.PodRoot, &logger), podStatusStore: podStatusStore, podStore: podStore, Logger: logger, podFactory: pods.NewFactory(preparerConfig.PodRoot, preparerConfig.NodeName), authPolicy: authPolicy, maxLaunchableDiskUsage: maxLaunchableDiskUsage, finishExec: finishExec, logExec: logExec, logBridgeBlacklist: preparerConfig.LogBridgeBlacklist, artifactVerifier: artifactVerifier, artifactRegistry: artifactRegistry, PodProcessReporter: podProcessReporter, hooksManifest: hooksManifest, hooksPod: hooksPod, hooksExecDir: preparerConfig.HooksDirectory, }, nil }