Last active
October 23, 2023 21:58
-
-
Save mrccnt/ab862481c98033c63143993405a39b0c to your computer and use it in GitHub Desktop.
Start and stop redis server as process in background in golang
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package main | |
import ( | |
"log" | |
"os" | |
"syscall" | |
"time" | |
) | |
// Prerequisites: | |
// | |
// * redis binary available | |
// * redis.conf available | |
// * redis user and group available | |
// * /var/lib/redis exists and ownership is redis:redis | |
// | |
// Example redis.conf: | |
// | |
// protected-mode yes | |
// requirepass redis | |
// dir /var/lib/redis | |
// appendonly yes | |
// maxmemory 128mb | |
// | |
// Concerning `Files []*os.File`: | |
// | |
// The first three entries correspond to standard input, standard output, | |
// and standard error. | |
// | |
// On Unix systems, StartProcess will change these File values | |
// to blocking mode, which means that SetDeadline will stop working | |
// and calling Close will not interrupt a Read or Write. | |
// | |
// Attention: | |
// | |
// Starting a process with specific UIDs/GIDs requires being root. | |
// I do not like running `sudo go run` so I just build as usual and | |
// execute binary via sudo but hey; fire at will... | |
// go build -o mybin . && sudo ./mybin | |
func main() { | |
// Replace own paths, uids, gids, etc | |
ex := "/usr/bin/redis-server" | |
cfg := "/etc/redis.conf" | |
dir := "/var/lib/redis" | |
uid := uint32(133) | |
gid := uint32(137) | |
redis, err := os.StartProcess(ex, []string{ex, cfg}, &os.ProcAttr{ | |
Dir: dir, | |
Env: os.Environ(), | |
Files: []*os.File{ | |
os.Stdin, | |
os.Stdout, | |
os.Stderr, | |
}, | |
Sys: &syscall.SysProcAttr{ | |
Credential: &syscall.Credential{ | |
Uid: uid, | |
Gid: gid, | |
Groups: []uint32{}, | |
}, | |
Noctty: true, | |
}, | |
}) | |
if err != nil { | |
log.Fatalln(err.Error()) | |
} | |
pid := redis.Pid | |
_ = redis.Release() | |
// Wait 10 secs before shutting down | |
time.Sleep(10 * time.Second) | |
p, err := os.FindProcess(pid) | |
if err != nil { | |
log.Fatalln(err.Error()) | |
} | |
if err = p.Signal(syscall.SIGTERM); err != nil { | |
log.Fatalln(err.Error()) | |
} | |
state, err := p.Wait() | |
if err != nil { | |
log.Println("Wait:", err.Error()) | |
} | |
log.Println("State:", state.String()) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment