// getTmpROC returns a removeOnClose instance wrapping a temporary // file provided by the passed store. The actual file name is based on // a hash of the passed path. func getTmpROC(s *imagestore.Store, path string) (*removeOnClose, error) { h := sha512.New() h.Write([]byte(path)) pathHash := s.HashToKey(h) tmp, err := s.TmpNamedFile(pathHash) if err != nil { return nil, errwrap.Wrap(errors.New("error setting up temporary file"), err) } // let's lock the file to avoid concurrent writes to the temporary file, it // will go away when removing the temp file _, err = lock.TryExclusiveLock(tmp.Name(), lock.RegFile) if err != nil { if err != lock.ErrLocked { return nil, errwrap.Wrap(errors.New("failed to lock temporary file"), err) } log.Printf("another rkt instance is downloading this file, waiting...") _, err = lock.ExclusiveLock(tmp.Name(), lock.RegFile) if err != nil { return nil, errwrap.Wrap(errors.New("failed to lock temporary file"), err) } } return &removeOnClose{File: tmp}, nil }
func keeper(cmd *cobra.Command, args []string) { var err error if cfg.debug { log.SetLevel(zap.DebugLevel) } pg.SetLogger(log) if cfg.dataDir == "" { fmt.Println("data dir required") } if cfg.clusterName == "" { fmt.Println("cluster name required") } if cfg.storeBackend == "" { fmt.Println("store backend type required") } if err = os.MkdirAll(cfg.dataDir, 0700); err != nil { fmt.Printf("cannot create data dir: %v\n", err) os.Exit(1) } if cfg.pgReplUsername == "" { fmt.Println("--pg-repl-username is required") } if cfg.pgReplPassword == "" && cfg.pgReplPasswordFile == "" { fmt.Println("one of --pg-repl-password or --pg-repl-passwordfile is required") } if cfg.pgReplPassword != "" && cfg.pgReplPasswordFile != "" { fmt.Println("only one of --pg-repl-password or --pg-repl-passwordfile must be provided") } if cfg.pgSUPassword == "" && cfg.pgSUPasswordFile == "" { fmt.Println("one of --pg-su-password or --pg-su-passwordfile is required") } if cfg.pgSUPassword != "" && cfg.pgSUPasswordFile != "" { fmt.Println("only one of --pg-su-password or --pg-su-passwordfile must be provided") } if cfg.pgSUUsername == cfg.pgReplUsername { fmt.Println("warning: superuser name and replication user name are the same. Different users are suggested.") if cfg.pgSUPassword != cfg.pgReplPassword { fmt.Println("provided superuser name and replication user name are the same but provided passwords are different") os.Exit(1) } } if cfg.pgReplPasswordFile != "" { cfg.pgReplPassword, err = readPasswordFromFile(cfg.pgReplPasswordFile) if err != nil { fmt.Printf("cannot read pg replication user password: %v\n", err) os.Exit(1) } } if cfg.pgSUPasswordFile != "" { cfg.pgSUPassword, err = readPasswordFromFile(cfg.pgSUPasswordFile) if err != nil { fmt.Printf("cannot read pg superuser password: %v\n", err) os.Exit(1) } } // Take an exclusive lock on dataDir _, err = lock.TryExclusiveLock(cfg.dataDir, lock.Dir) if err != nil { fmt.Printf("cannot take exclusive lock on data dir %q: %v\n", cfg.dataDir, err) os.Exit(1) } log.Info("exclusive lock on data dir taken") if cfg.id != "" { if !pg.IsValidReplSlotName(cfg.id) { fmt.Printf("keeper id %q not valid. It can contain only lower-case letters, numbers and the underscore character\n", cfg.id) os.Exit(1) } } stop := make(chan bool, 0) end := make(chan error, 0) sigs := make(chan os.Signal, 1) signal.Notify(sigs, os.Interrupt, os.Kill) go sigHandler(sigs, stop) p, err := NewPostgresKeeper(&cfg, stop, end) if err != nil { fmt.Printf("cannot create keeper: %v\n", err) os.Exit(1) } go p.Start() <-end }