Example #1
0
func main() {
	var configPath string

	flag.StringVar(&configPath, "config", "", "Path to redis config")
	flag.Parse()

	if configPath == "" {
		log.Fatal("Missing flag --config")
	}

	if _, err := os.Stat(configPath); os.IsNotExist(err) {
		log.Fatal("Redis config does not exist")
	}

	conf, err := redisconf.Load(configPath)
	if err != nil {
		log.Fatal("Invalid redis config")
	}

	_, err = client.Connect(client.Host(conf.Host()), client.Port(conf.Port()))
	if err != nil {
		log.Fatal("Can not connect to Redis")
	}

	m := metrics.Metrics{
		metrics.Metric{
			Name:  "foo",
			Value: 1,
			Unit:  "bar",
		},
	}
	encoder := json.NewEncoder(os.Stdout)
	encoder.Encode(m)
}
func PingServer(instance *Instance) error {
	client, err := client.Connect(
		client.Host(instance.Host),
		client.Port(instance.Port),
		client.Password(instance.Password),
	)
	if err != nil {
		return err
	}

	return client.Ping()
}
Example #3
0
func main() {
	var configPath string

	flag.StringVar(&configPath, "config", "", "Path to redis config file")
	flag.Parse()

	if configPath == "" {
		log.Fatal("Missing flag --config")
	}

	config, err := redisconf.Load(configPath)
	if err != nil {
		log.Fatalf("Error loading Redis config file: %s", err)
	}

	port := config.Port()
	host := config.Host()
	password := config.Password()

	clientConnection, err := client.Connect(
		client.Port(port),
		client.Host(host),
		client.Password(password),
	)
	if err != nil {
		log.Fatalf("Error connecting to Redis: %s", err)
	}

	m, err := metrics.CPULoad(clientConnection)
	if err != nil {
		log.Fatalf("Error getting metrics: %s", err)
	}

	if err := json.NewEncoder(os.Stdout).Encode(m); err != nil {
		log.Fatalf("Error encoding json: %s", err)
	}
}
Example #4
0
func redisPIDProvider(instancePath string) process.PIDProvider {
	return func() (int, error) {
		instanceConf, err := redisconf.Load(path.Join(instancePath, "redis.conf"))
		if err != nil {
			return 0, err
		}

		client, err := client.Connect(
			client.Host("localhost"),
			client.Port(instanceConf.Port()),
			client.Password(instanceConf.Password()),
			client.CmdAliases(instanceConf.CommandAliases()),
		)
		if err != nil {
			return 0, err
		}

		pidfile, err := client.GetConfig("pidfile")
		if err != nil {
			return 0, err
		}
		return process.ReadPID(pidfile)
	}
}
	redisPort := integration.RedisPort

	redisRunner = &integration.RedisRunner{}
	redisRunner.Start([]string{"--bind", redisHost, "--port", fmt.Sprintf("%d", redisPort)})

	localDumpRdbPath = filepath.Join(redisRunner.Dir, "dump.rdb")

	var err error
	s3Server, err = s3test.NewServer(&s3test.Config{
		Send409Conflict: true,
	})
	Expect(err).ToNot(HaveOccurred())

	logger := lager.NewLogger("logger")

	client, err := redis.Connect(redis.Host(redisHost), redis.Port(redisPort))
	Expect(err).ToNot(HaveOccurred())

	Expect(localDumpRdbPath).ToNot(BeAnExistingFile())

	bucketName := "test-bucket"
	targetPath := "target"

	bucket := goamzBucket(bucketName, s3Server.URL())
	_, err = bucket.Get(targetPath)
	Expect(err).To(HaveOccurred())

	tmpDir, err = ioutil.TempDir("", "redis-backups-integration-tests")
	Expect(err).NotTo(HaveOccurred())

	backuper := backup.NewRedisBackuper(
Example #6
0
func main() {
	fmt.Println("Starting redis restore")

	if len(os.Args) != 3 {
		log.Fatalf("usage: restore <instance_id> <rdb_path>")
	}

	instanceID := os.Args[1]
	rdbPath := os.Args[2]

	logger := lager.NewLogger("redis-restore")
	logger.RegisterSink(lager.NewWriterSink(os.Stdout, lager.DEBUG))
	logger.RegisterSink(lager.NewWriterSink(os.Stderr, lager.ERROR))

	startStep("Loading config")
	config, err := restoreconfig.Load(restoreConfigPath())
	if err != nil {
		finishStepFatal("Could not load config")
	}
	finishStep("OK")

	monitExecutablePath := config.MonitExecutablePath
	instanceDirPath := config.InstanceDataDir(instanceID)

	startStep("Checking instance directory and backup file")
	if _, err := os.Stat(instanceDirPath); os.IsNotExist(err) {
		finishStepFatal("Instance not found")
	}

	if _, err := os.Stat(rdbPath); os.IsNotExist(err) {
		log.Fatalf("RDB file not found")
	}
	finishStep("OK")

	commandRunner := system.OSCommandRunner{
		Logger: logger,
	}

	startStep("Disabling Redis process watcher")
	if config.DedicatedInstance {
		finishStep("Skipped")
	} else {
		err = stopViaMonit(monitExecutablePath, "process-watcher")
		if err != nil {
			finishStep("ERROR")
			logger.Fatal("stop-process-watcher", err)
		}
		finishStep("OK")
	}

	processKiller := &process.ProcessKiller{}

	processController := &redis.OSProcessController{
		CommandRunner:             commandRunner,
		InstanceInformer:          &config,
		Logger:                    logger,
		ProcessChecker:            &process.ProcessChecker{},
		ProcessKiller:             processKiller,
		PingFunc:                  redis.PingServer,
		WaitUntilConnectableFunc:  availability.Check,
		RedisServerExecutablePath: config.RedisServerExecutablePath,
	}

	instance := &redis.Instance{ID: instanceID, Host: "localhost", Port: 6379}

	pidfilePath := config.InstancePidFilePath(instanceID)

	startStep("Stopping Redis")
	if config.DedicatedInstance {
		if err = unmonit(monitExecutablePath, "redis"); err == nil {
			err = processKiller.KillProvidedPID(redisPIDProvider(instanceDirPath))
		}
	} else {
		err = processController.Kill(instance)
	}

	if err != nil {
		finishStep("ERROR")
		logger.Fatal("killing-redis", err)
	}
	finishStep("OK")

	startStep("Copying backup file to instance directory")
	err = copyRdbFileIntoInstance(rdbPath, instanceDirPath)
	if err != nil {
		finishStep("ERROR")
		logger.Fatal("copy-rdb", err)
	}
	finishStep("OK")

	startStep("Starting Redis from backup file")
	err = processController.StartAndWaitUntilReadyWithConfig(
		instance,
		[]string{
			"--pidfile", pidfilePath,
			"--daemonize", "yes",
			"--dir", instanceDirPath,
			"--bind", "127.0.0.1",
		},
		time.Duration(config.StartRedisTimeoutSeconds)*time.Second,
	)
	if err != nil {
		finishStep("ERROR")
		logger.Fatal("starting-redis", err)
	}
	finishStep("OK")

	startStep("Waiting for redis to finish loading data into memory")
	client, err := client.Connect(
		client.Host(instance.Host),
		client.Port(instance.Port),
	)

	if err != nil {
		finishStep("ERROR")
		logger.Fatal("connecting-to-redis", err)
	}

	err = client.WaitUntilRedisNotLoading(config.StartRedisTimeoutSeconds * 1000)
	if err != nil {
		finishStep("ERROR")
		logger.Fatal("starting-redis", err)
	}
	finishStep("OK")

	startStep("Enabling appendonly mode")
	err = client.EnableAOF()
	if err != nil {
		finishStep("ERROR")
		logger.Fatal("enabling-aof", err)
	}
	finishStep("OK")

	startStep("Waiting for appendonly rewrite to finish")
	for {
		aofRewriteInProgress, err := client.InfoField("aof_rewrite_in_progress")
		if err != nil {
			finishStep("ERROR")
			logger.Fatal("querying-aof-progress", err)
		}

		if aofRewriteInProgress == "0" {
			break
		}

		time.Sleep(time.Millisecond * aofRewriteInProgressCheckIntervalMilliseconds)
	}

	aofRewriteStatus, err := client.InfoField("aof_last_bgrewrite_status")
	if err != nil {
		logger.Fatal("getting-aof-write-status", err)
	}

	if aofRewriteStatus != "ok" {
		logger.Fatal(
			"verifying-aof-write-status",
			fmt.Errorf("Invalid AOF write status: %s", aofRewriteStatus),
		)
	}

	finishStep("OK")

	startStep("Stopping Redis")
	err = processController.Kill(instance)
	if err != nil {
		finishStep("ERROR")
		logger.Fatal("killing-redis", err)
	}
	finishStep("OK")

	startStep("Setting correct permissions on appendonly file")
	aofPath := path.Join(instanceDirPath, "appendonly.aof")
	err = chownAof("vcap", aofPath)
	if err != nil {
		finishStep("ERROR")
		logger.Fatal("chown-aof", err)
	}
	finishStep("OK")

	startStep("Restarting Redis process watcher/redis")
	if config.DedicatedInstance {
		err = startViaMonit(monitExecutablePath, "redis")
	} else {
		err = startViaMonit(monitExecutablePath, "process-watcher")
	}

	if err != nil {
		finishStep("ERROR")
		logger.Fatal("start redis/process watcher", err)
	}
	finishStep("OK")

	fmt.Println("Restore completed successfully")
}
	BeforeEach(func() {
		pidFile, err := ioutil.TempFile("", "pid")
		Ω(err).ShouldNot(HaveOccurred())
		pidFilePath = pidFile.Name()
		redisArgs = []string{"--port", fmt.Sprintf("%d", port), "--pidfile", pidFilePath}
	})

	AfterEach(func() {
		os.Remove(pidFilePath)
	})

	Describe("connecting to a redis server", func() {
		Context("when the server is not running", func() {
			It("returns an error", func() {
				_, err := client.Connect(
					client.Host(host),
					client.Port(port),
				)

				// on OS X, "getsockopt:" is also present in the error message from the system
				Ω(err).Should(MatchError(MatchRegexp("dial tcp 127.0.0.1:6480: (getsockopt: )?connection refused")))
			})
		})

		Context("when the server is running", func() {
			JustBeforeEach(func() {
				redisRunner = &integration.RedisRunner{}
				redisRunner.Start(redisArgs)
			})

			AfterEach(func() {
Example #8
0
func (b *instanceBackuper) instanceBackup(redisConfig instance.RedisConfig) BackupResult {
	result := BackupResult{
		RedisConfigPath: redisConfig.Path,
		NodeIP:          b.backupConfig.NodeIP,
	}

	logger := b.logger.WithData(
		lager.Data{
			"node_ip":           b.backupConfig.NodeIP,
			"redis_config_path": redisConfig.Path,
		},
	)

	logger.Info("instance-backup", lager.Data{"event": "starting"})

	logger.Info("instance-backup.locate-iid", lager.Data{"event": "starting"})
	instanceID, err := b.instanceIDLocator.LocateID(
		redisConfig.Path,
		b.backupConfig.NodeIP,
	)
	if err != nil {
		logger.Error("instance-backup.locate-iid", err, lager.Data{"event": "failed"})
		result.Err = err
		return result
	}

	result.InstanceID = instanceID

	logger.Info("instance-backup.locate-iid", lager.Data{
		"event":       "done",
		"instance_id": instanceID,
	})

	redisAddress := fmt.Sprintf("%s:%d", redisConfig.Conf.Host(), redisConfig.Conf.Port())
	logger.Info("instance-backup.redis-connect", lager.Data{
		"event":         "starting",
		"redis_address": redisAddress,
	})
	redisClient, err := b.redisClientProvider(
		redis.Host(redisConfig.Conf.Host()),
		redis.Port(redisConfig.Conf.Port()),
		redis.Password(redisConfig.Conf.Password()),
		redis.CmdAliases(redisConfig.Conf.CommandAliases()),
	)
	if err != nil {
		logger.Error("instance-backup.redis-connect", err, lager.Data{"event": "failed"})
		result.Err = err
		return result
	}
	defer func() {
		if err := redisClient.Disconnect(); err != nil {
			logger.Error("instance-backup.redis-disconnect", err, lager.Data{"event": "failed"})
		}
	}()
	logger.Info("instance-backup.redis-connect", lager.Data{
		"event":         "done",
		"redis_address": redisAddress,
	})

	targetPath := b.buildTargetPath(instanceID)
	logger.Info("instance-backup.redis-backup", lager.Data{
		"event":       "starting",
		"target_path": targetPath,
	})
	err = b.redisBackuper.Backup(redisClient, targetPath)
	if err != nil {
		logger.Error("instance-backup.redis-backup", err, lager.Data{"event": "failed"})
		result.Err = err
		return result
	}
	logger.Info("instance-backup.redis-backup", lager.Data{
		"event":       "done",
		"target_path": targetPath,
	})

	logger.Info("instance-backup", lager.Data{"event": "done"})
	return result
}