func (rm *P2RM) configureStorage(client consulutil.ConsulClient, labeler labels.ApplicatorWithoutWatches) { rm.Client = client rm.Store = kp.NewConsulStore(client) rm.RCStore = rcstore.NewConsul(client, labeler, 5) rm.Labeler = labeler rm.PodStore = podstore.NewConsul(client.KV()) }
// Instantiates a preparer with a podStore and podStatusStore backed by a fake // consul KV implementation. The podStore field is necessary for acquiring the // "intent" manifest for uuid pods, while the podStatusStore is necessary for // getting the reality manifest func testResultSetPreparer() *Preparer { fakeStatusStore := statusstoretest.NewFake() return &Preparer{ podStatusStore: podstatus.NewConsul(fakeStatusStore, kp.PreparerPodStatusNamespace), podStore: podstore.NewConsul(consulutil.NewFakeClient().KV()), } }
func setupServerWithFakePodStore() (podstore.Store, store) { fakePodStore := podstore.NewConsul(consulutil.NewFakeClient().KV_) server := store{ scheduler: fakePodStore, } return fakePodStore, server }
func NewConsulStore(client consulutil.ConsulClient) *consulStore { statusStore := statusstore.NewConsul(client) podStatusStore := podstatus.NewConsul(statusStore, PreparerPodStatusNamespace) podStore := podstore.NewConsul(client.KV()) return &consulStore{ client: client, podStore: podStore, podStatusStore: podStatusStore, } }
func main() { kingpin.Version(version.VERSION) _, opts, _ := flags.ParseWithConsulOptions() client := kp.NewConsulClient(opts) store := kp.NewConsulStore(client) podStore := podstore.NewConsul(client.KV()) if *nodeName == "" { hostname, err := os.Hostname() if err != nil { log.Fatalf("Could not get the hostname to do scheduling: %s", err) } *nodeName = hostname } if *manifestPath == "" { kingpin.Usage() log.Fatalln("No manifest given") } podManifest, err := manifest.FromPath(*manifestPath) if err != nil { log.Fatalf("Could not read manifest at %s: %s\n", *manifestPath, err) } out := schedule.Output{ PodID: podManifest.ID(), } if *uuidPod { out.PodUniqueKey, err = podStore.Schedule(podManifest, types.NodeName(*nodeName)) if err != nil { log.Fatalf("Could not schedule pod: %s", err) } } else { // Legacy pod podPrefix := kp.INTENT_TREE if *hookGlobal { podPrefix = kp.HOOK_TREE } _, err := store.SetPod(podPrefix, types.NodeName(*nodeName), podManifest) if err != nil { log.Fatalf("Could not write manifest %s to intent store: %s\n", podManifest.ID(), err) } } outBytes, err := json.Marshal(out) if err != nil { log.Fatalf("Successfully scheduled manifest but couldn't marshal JSON output") } fmt.Println(string(outBytes)) }
func main() { // Parse custom flags + standard Consul routing options _, opts, _ := flags.ParseWithConsulOptions() client := kp.NewConsulClient(opts) podStore := kp_podstore.NewConsul(client.KV()) podStatusStore := podstatus.NewConsul(statusstore.NewConsul(client), kp.PreparerPodStatusNamespace) logger := log.New(os.Stderr, "", 0) port := getPort(logger) lis, err := net.Listen("tcp", fmt.Sprintf("localhost:%d", port)) if err != nil { logger.Fatalf("failed to listen: %v", err) } s := grpc.NewServer() podstore_protos.RegisterP2PodStoreServer(s, podstore.NewServer(podStore, podStatusStore)) if err := s.Serve(lis); err != nil { logger.Fatalf("failed to serve: %v", err) } }
func NewConsulStore(client consulutil.ConsulClient) Store { return &consulStore{ client: client, podStore: podstore.NewConsul(client.KV()), } }
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 }
func main() { // 1. Generate pod for preparer in this code version (`rake artifact:prepare`) // 2. Locate manifests for preparer pod, premade consul pod // 3. Execute bootstrap with premade consul pod and preparer pod // 4. Delete all pods from the pod store (uuid pods). This allows the same vagrant VM to be used // between tests // 5. Deploy p2-rctl-server pod with p2-schedule // 6. Schedule a hello pod manifest with a replication controller // 7. Schedule a hello pod as a "uuid pod" // 8. Verify that p2-rctl-server is running by checking health. // 9. Verify that the RC-deployed hello is running by checking health. // Monitor using written pod label queries. // 10. Verify that the uuid hello pod is running by curling its HTTP port. // Health is not checked for uuid pods so checking health cannot be used. // list of services running on integration test host services := []string{"p2-preparer", "hello"} tempdir, err := ioutil.TempDir("", "single-node-check") log.Printf("Putting test manifests in %s\n", tempdir) if err != nil { log.Fatalln("Could not create temp directory, bailing") } userHookManifest, err := userCreationHookManifest(tempdir) if err != nil { log.Fatalf("Couldn't schedule the user creation hook: %s", err) } preparerManifest, err := generatePreparerPod(tempdir, userHookManifest) if err != nil { log.Fatalf("Could not generate preparer pod: %s\n", err) } config, err := preparer.LoadConfig(preparerManifest) if err != nil { log.Fatalf("could not unmarshal config: %s\n", err) } consulManifest, err := getConsulManifest(tempdir) if err != nil { log.Fatalf("Could not generate consul pod: %s\n", err) } signedPreparerManifest, err := signManifest(preparerManifest, tempdir) if err != nil { log.Fatalf("Could not sign preparer manifest: %s\n", err) } signedConsulManifest, err := signManifest(consulManifest, tempdir) if err != nil { log.Fatalf("Could not sign consul manifest: %s\n", err) } fmt.Println("Executing bootstrap") err = executeBootstrap(signedPreparerManifest, signedConsulManifest) if err != nil { log.Fatalf("Could not execute bootstrap: %s\n%s", err, targetLogs()) } // Wait a bit for preparer's http server to be ready err = waitForStatus(preparerStatusPort, "preparer", 10*time.Second) if err != nil { log.Fatalf("Couldn't check preparer status: %s", err) } consulClient := kp.NewConsulClient(kp.Options{}) // Get all the pod unique keys so we can unschedule them all keys, _, err := consulClient.KV().Keys(podstore.PodTree+"/", "", nil) if err != nil { log.Fatalf("Could not fetch pod keys to remove from store at beginning of test: %s", err) } podStore := podstore.NewConsul(consulClient.KV()) for _, key := range keys { keyParts := strings.Split(key, "/") err = podStore.Unschedule(types.PodUniqueKey(keyParts[len(keyParts)-1])) if err != nil { log.Fatalf("Could not unschedule pod %s from consul: %s", keyParts[len(keyParts)-1], err) } } err = scheduleRCTLServer(tempdir) if err != nil { log.Fatalf("Could not schedule RCTL server: %s", err) } // Now we're going to test some conditions that each take non-negligible amount of time to verify. // We'll spin up a goroutine for each "test" which either closes the error channel, or passes an error. type testCase struct { testName string errCh chan error logger logging.Logger } var testCases []testCase // Test that a "legacy" pod installed by an RC comes up correctly and has health reported legacyTest := make(chan error) verifyLegacyPodLogger := logging.DefaultLogger.SubLogger(logrus.Fields{ "test_case": "verifyLegacyPod", }) go verifyLegacyPod(legacyTest, tempdir, config, services, verifyLegacyPodLogger) testCases = append(testCases, testCase{ testName: "verifyLegacyPod", errCh: legacyTest, logger: verifyLegacyPodLogger, }) // Test that a "uuid" pod installed by p2-schedule comes up correctly uuidTest := make(chan error) verifyUUIDPodLogger := logging.DefaultLogger.SubLogger(logrus.Fields{ "test_case": "verifyUUIDPod", }) testCases = append(testCases, testCase{ testName: "verifyUUIDPod", errCh: uuidTest, logger: verifyUUIDPodLogger, }) go verifyUUIDPod(uuidTest, tempdir, verifyUUIDPodLogger) // Test that exit information for a process started by a pod is properly recorded in consul. processExitTest := make(chan error) verifyProcessExitLogger := logging.DefaultLogger.SubLogger(logrus.Fields{ "test_case": "verifyProcessExit", }) go verifyProcessExit(processExitTest, tempdir, verifyProcessExitLogger) testCases = append(testCases, testCase{ testName: "verifyProcessResult", errCh: processExitTest, logger: verifyProcessExitLogger, }) for _, t := range testCases { select { case err, ok := <-t.errCh: if err != nil { t.logger.Fatal(err) } if ok { t.logger.Fatal("Error channel not closed") } case <-time.After(1 * time.Minute): t.logger.Fatal("Timed out waiting for a result") } t.logger.Infoln("Success!") } }