func (s *Service) Lock(command string, ttl time.Duration, message string) { userAndHost := "[" + ggn.GetUserAndHost() + "] " message = userAndHost + message logs.WithFields(s.fields).WithField("ttl", ttl).WithField("message", message).Info("Locking") s.runHook(EARLY, command, "lock") defer s.runHook(LATE, command, "lock") kapi := s.env.EtcdClient() resp, err := kapi.Get(context.Background(), s.lockPath, nil) if cerr, ok := err.(*client.ClusterError); ok { logs.WithEF(cerr, s.fields).Fatal("Server error reading on fleet") } else if err != nil { _, err := kapi.Set(context.Background(), s.lockPath, message, &client.SetOptions{TTL: ttl}) if err != nil { logs.WithEF(cerr, s.fields).Fatal("Cannot write lock") } } else if strings.HasPrefix(resp.Node.Value, userAndHost) { _, err := kapi.Set(context.Background(), s.lockPath, message, &client.SetOptions{TTL: ttl}) if err != nil { logs.WithEF(cerr, s.fields).Fatal("Cannot write lock") } } else { logs.WithFields(s.fields).WithField("message", resp.Node.Value). WithField("ttl", resp.Node.TTLDuration().String()). Fatal("Service is already locked") } }
func (e Env) runHook(path string, info HookInfo) { logs.WithFields(e.fields).WithField("path", path).WithField("info", info).Debug("Running hook") files, err := ioutil.ReadDir(e.path + PATH_HOOKS + path) if err != nil { logs.WithEF(err, e.fields).Debug("Cannot read hook directory") return } envs := map[string]string{} envs["ENV"] = e.name envs["COMMAND"] = info.Command if info.Unit != nil { envs["UNIT"] = info.Unit.GetName() } if info.Service != nil { envs["SERVICE"] = info.Service.GetName() } envs["WHO"] = ggn.GetUserAndHost() envs["ACTION"] = info.Action envs["ATTRIBUTES"] = info.Attributes envs["GGN_HOME_PATH"] = ggn.Home.Path for _, f := range files { if !f.IsDir() { hookFields := data.WithField("name", f.Name()) args := []string{e.path + PATH_HOOKS + path + "/" + f.Name()} for key, val := range envs { args = append([]string{key + "='" + strings.Replace(val, "'", "'\"'\"'", -1) + "'"}, args...) } logs.WithFields(hookFields).Debug("Running Hook") if err := common.ExecCmd("bash", "-c", strings.Join(args, " ")); err != nil { logs.WithFields(hookFields).Fatal("Hook status is failed") } } } }