-
Notifications
You must be signed in to change notification settings - Fork 32
/
daemon.go
102 lines (82 loc) · 2.2 KB
/
daemon.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
package daemon
import (
"fmt"
"github.com/nightlyone/lockfile"
"github.com/arigatomachine/cli/config"
"github.com/arigatomachine/cli/daemon/db"
"github.com/arigatomachine/cli/daemon/session"
"github.com/arigatomachine/cli/daemon/socket"
)
// Daemon is the arigato coprocess that contains session secrets, handles
// cryptographic operations, and communication with the registry.
type Daemon struct {
proxy *socket.AuthProxy
lock lockfile.Lockfile // actually a string
session session.Session
config *config.Config
db *db.DB
hasShutdown bool
}
// New creates a new Daemon.
func New(cfg *config.Config) (*Daemon, error) {
lock, err := lockfile.New(cfg.PidPath)
if err != nil {
return nil, fmt.Errorf("Failed to create lockfile object: %s", err)
}
err = lock.TryLock()
if err != nil {
return nil, fmt.Errorf(
"Failed to create lockfile[%s]: %s", cfg.PidPath, err)
}
// Recover from the panic and return the error; this way we can
// delete the lockfile!
defer func() {
if r := recover(); r != nil {
err, _ = r.(error)
}
}()
session := session.NewSession()
db, err := db.NewDB(cfg.DBPath)
if err != nil {
return nil, err
}
proxy, err := socket.NewAuthProxy(cfg, session, db)
if err != nil {
return nil, fmt.Errorf("Failed to create auth proxy: %s", err)
}
daemon := &Daemon{
proxy: proxy,
lock: lock,
session: session,
config: cfg,
db: db,
hasShutdown: false,
}
return daemon, nil
}
// Addr returns the domain socket the Daemon is listening on.
func (d *Daemon) Addr() string {
return d.proxy.Addr()
}
// Run starts the daemon main loop. It returns on failure, or when the daemon
// has been gracefully shut down.
func (d *Daemon) Run() error {
return d.proxy.Listen()
}
// Shutdown gracefully shuts down the daemon.
func (d *Daemon) Shutdown() error {
if d.hasShutdown {
return nil
}
d.hasShutdown = true
if err := d.lock.Unlock(); err != nil {
return fmt.Errorf("Could not unlock: %s", err)
}
if err := d.proxy.Close(); err != nil {
return fmt.Errorf("Could not stop http proxy: %s", err)
}
if err := d.db.Close(); err != nil {
return fmt.Errorf("Could not close db: %s", err)
}
return nil
}