-
-
Notifications
You must be signed in to change notification settings - Fork 153
/
admin_waitready.go
100 lines (81 loc) · 2.35 KB
/
admin_waitready.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
//go:build linux
package main
import (
"fmt"
"time"
"github.com/spf13/cobra"
"github.com/lxc/incus/v6/client"
cli "github.com/lxc/incus/v6/internal/cmd"
"github.com/lxc/incus/v6/internal/i18n"
"github.com/lxc/incus/v6/shared/logger"
)
type cmdAdminWaitready struct {
global *cmdGlobal
flagTimeout int
}
func (c *cmdAdminWaitready) Command() *cobra.Command {
cmd := &cobra.Command{}
cmd.Use = usage("waitready")
cmd.Short = i18n.G("Wait for the daemon to be ready to process requests")
cmd.Long = cli.FormatSection(i18n.G("Description"), i18n.G(`Wait for the daemon to be ready to process requests
This command will block until the daemon is reachable over its REST API and
is done with early start tasks like re-starting previously started
containers.`))
cmd.RunE = c.Run
cmd.Flags().IntVarP(&c.flagTimeout, "timeout", "t", 0, "Number of seconds to wait before giving up"+"``")
return cmd
}
func (c *cmdAdminWaitready) Run(cmd *cobra.Command, args []string) error {
finger := make(chan error, 1)
var errLast error
go func() {
for i := 0; ; i++ {
// Start logging only after the 10'th attempt (about 5
// seconds). Then after the 30'th attempt (about 15
// seconds), log only only one attempt every 10
// attempts (about 5 seconds), to avoid being too
// verbose.
doLog := false
if i > 10 {
doLog = i < 30 || ((i % 10) == 0)
}
if doLog {
logger.Debugf(i18n.G("Connecting to the daemon (attempt %d)"), i)
}
d, err := incus.ConnectIncusUnix("", nil)
if err != nil {
errLast = err
if doLog {
logger.Debugf(i18n.G("Failed connecting to the daemon (attempt %d): %v"), i, err)
}
time.Sleep(500 * time.Millisecond)
continue
}
if doLog {
logger.Debugf(i18n.G("Checking if the daemon is ready (attempt %d)"), i)
}
_, _, err = d.RawQuery("GET", "/internal/ready", nil, "")
if err != nil {
errLast = err
if doLog {
logger.Debugf(i18n.G("Failed to check if the daemon is ready (attempt %d): %v"), i, err)
}
time.Sleep(500 * time.Millisecond)
continue
}
finger <- nil
return
}
}()
if c.flagTimeout > 0 {
select {
case <-finger:
break
case <-time.After(time.Second * time.Duration(c.flagTimeout)):
return fmt.Errorf(i18n.G("Daemon still not running after %ds timeout (%v)"), c.flagTimeout, errLast)
}
} else {
<-finger
}
return nil
}