Skip to content

Commit

Permalink
Merge branch 'release/0.7.1'
Browse files Browse the repository at this point in the history
  • Loading branch information
nbari committed Sep 1, 2016
2 parents 682c7a6 + 7193f4c commit 6e303a2
Show file tree
Hide file tree
Showing 21 changed files with 650 additions and 556 deletions.
2 changes: 1 addition & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
language: go

go:
- 1.6
- 1.7
- tip

before_install:
Expand Down
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ get:

build: get
# ${GO} get -u gopkg.in/yaml.v2;
${GO} build -race -ldflags "-X main.version=${VERSION}" -o ${BIN_NAME} cmd/immortal/main.go;
${GO} build -ldflags "-X main.version=${VERSION}" -o ${BIN_NAME} cmd/immortal/main.go;

clean:
@rm -rf ir-* ${BIN_NAME} ${BIN_NAME}.debug *.out build debian
Expand Down
6 changes: 0 additions & 6 deletions a_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,3 @@ func expect(t *testing.T, a interface{}, b interface{}) {
t.Fatalf("Expected: %v (type %v) Got: %v (type %v) in %s:%d", a, reflect.TypeOf(a), b, reflect.TypeOf(b), fn, line)
}
}

type myFork struct{}

func (self myFork) Fork() (int, error) {
return 0, nil
}
6 changes: 2 additions & 4 deletions cmd/immortal/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -53,19 +53,17 @@ func main() {

// fork
if os.Getppid() > 1 {
if pid, err := daemon.Fork(); err != nil {
if pid, err := immortal.Fork(); err != nil {
log.Printf("Error while forking: %s", err)
os.Exit(1)
} else {
if pid > 0 {
fmt.Printf("%c %d\n", immortal.Logo(), pid)
os.Exit(0)
}
}
}

log.Printf("%c %d", immortal.Logo(), os.Getpid())

daemon.Run()
immortal.Supervise(&immortal.Sup{}, daemon)
immortal.Supervise(daemon)
}
16 changes: 0 additions & 16 deletions control.go

This file was deleted.

172 changes: 44 additions & 128 deletions daemon.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,147 +2,67 @@ package immortal

import (
"fmt"
"io"
"io/ioutil"
"log"
"os"
"os/exec"
"path/filepath"
"strconv"
"sync/atomic"
"syscall"
"time"
)

type Daemon struct {
*Config
*Control
Forker
Logger
lock uint32
lock_defer uint32
start time.Time
cmd *exec.Cmd
type Return struct {
err error
msg string
}

func (self *Daemon) Process() *os.Process {
return self.cmd.Process
type Daemon struct {
cfg *Config
count uint64
fifo chan Return
fifo_control *os.File
fifo_ok *os.File
lock uint32
lock_once uint32
quit chan struct{}
sTime time.Time
}

func (self *Daemon) Run() {
if atomic.SwapUint32(&self.lock, uint32(1)) != 0 {
if self.cmd == nil {
log.Printf("Service down")
} else {
log.Printf("PID %d (WANT IT DOWN) FIX THIS", self.cmd.Process.Pid)
//log.Println("FIX THIS")
}
return
}

// Command to execute
self.cmd = exec.Command(self.command[0], self.command[1:]...)

// change working directory
if self.Cwd != "" {
self.cmd.Dir = self.Cwd
}

// set environment vars
if self.Env != nil {
env := os.Environ()
for k, v := range self.Env {
env = append(env, fmt.Sprintf("%s=%s", k, v))
}
self.cmd.Env = env
}

sysProcAttr := new(syscall.SysProcAttr)

// set owner
if self.user != nil {
uid, err := strconv.Atoi(self.user.Uid)
if err != nil {
self.Control.state <- err
return
}

gid, err := strconv.Atoi(self.user.Gid)
if err != nil {
self.Control.state <- err
return
}

// https://golang.org/pkg/syscall/#SysProcAttr
sysProcAttr.Credential = &syscall.Credential{
Uid: uint32(uid),
Gid: uint32(gid),
}
func (d *Daemon) Run(p Process) (*process, error) {
if atomic.SwapUint32(&d.lock, uint32(1)) != 0 {
return nil, fmt.Errorf("lock: %d lock once: %d", d.lock, d.lock_once)
}

// Set process group ID to Pgid, or, if Pgid == 0, to new pid
sysProcAttr.Setpgid = true
sysProcAttr.Pgid = 0
// increment count by 1
atomic.AddUint64(&d.count, 1)

// set the attributes
self.cmd.SysProcAttr = sysProcAttr
time.Sleep(time.Duration(d.cfg.Wait) * time.Second)

// log only if are available loggers
var (
r *io.PipeReader
w *io.PipeWriter
)
if self.Logger.IsLogging() {
r, w = io.Pipe()
self.cmd.Stdout = w
self.cmd.Stderr = w
go self.Logger.StdHandler(r)
} else {
self.cmd.Stdin = nil
self.cmd.Stdout = nil
self.cmd.Stderr = nil
process, err := p.Start()
if err != nil {
atomic.StoreUint32(&d.lock, d.lock_once)
return nil, err
}

// wait N seconds before starting
if self.Wait > 0 {
time.Sleep(time.Duration(self.Wait) * time.Second)
}

if err := self.cmd.Start(); err != nil {
self.Control.state <- err
return
}

// set start time
self.start = time.Now()

// write parent pid
if self.Pid.Parent != "" {
if err := self.WritePid(self.Pid.Parent, os.Getpid()); err != nil {
log.Print(err)
if d.cfg.Pid.Parent != "" {
if err := d.WritePid(d.cfg.Pid.Parent, os.Getpid()); err != nil {
log.Println(err)
}
}

// write child pid
if self.Pid.Child != "" {
if err := self.WritePid(self.Pid.Child, self.cmd.Process.Pid); err != nil {
log.Print(err)
if d.cfg.Pid.Child != "" {
if err := d.WritePid(d.cfg.Pid.Child, p.Pid()); err != nil {
log.Println(err)
}
}

go func() {
defer func() {
if self.Logger.IsLogging() {
w.Close()
}
// lock_defer defaults to 0, 1 to run only once/down (don't restart)
atomic.StoreUint32(&self.lock, self.lock_defer)
}()
self.Control.state <- self.cmd.Wait()
}()
return process, nil
}

func (self *Daemon) WritePid(file string, pid int) error {
// WritePid write pid to file
func (d *Daemon) WritePid(file string, pid int) error {
if err := ioutil.WriteFile(file, []byte(fmt.Sprintf("%d", pid)), 0644); err != nil {
return err
}
Expand All @@ -151,8 +71,10 @@ func (self *Daemon) WritePid(file string, pid int) error {

func New(cfg *Config) (*Daemon, error) {
var (
supDir string
err error
err error
fifo_control *os.File
fifo_ok *os.File
supDir string
)

if cfg.Cwd != "" {
Expand All @@ -165,12 +87,6 @@ func New(cfg *Config) (*Daemon, error) {
supDir = filepath.Join(d, "supervise")
}

control := &Control{
fifo: make(chan Return),
quit: make(chan struct{}),
state: make(chan error),
}

// if ctrl create supervise dir
if cfg.ctrl {
// create fifo
Expand All @@ -189,20 +105,20 @@ func New(cfg *Config) (*Daemon, error) {
}

// read fifo
if control.fifo_control, err = OpenFifo(filepath.Join(supDir, "control")); err != nil {
if fifo_control, err = OpenFifo(filepath.Join(supDir, "control")); err != nil {
return nil, err
}
if control.fifo_ok, err = OpenFifo(filepath.Join(supDir, "ok")); err != nil {
if fifo_ok, err = OpenFifo(filepath.Join(supDir, "ok")); err != nil {
return nil, err
}
}

return &Daemon{
Config: cfg,
Control: control,
Forker: &Fork{},
Logger: &LogWriter{
logger: NewLogger(cfg),
},
cfg: cfg,
fifo: make(chan Return),
fifo_control: fifo_control,
fifo_ok: fifo_ok,
quit: make(chan struct{}),
sTime: time.Now(),
}, nil
}

0 comments on commit 6e303a2

Please sign in to comment.