Skip to content

Commit 3a8fa03

Browse files
committed
daemon: add daemon module
`tt daemon` module is used to manage HTTP server running on the background. HTTP server can process `tt` commands such as `start`, `status`, etc. Daemon can be configurated with `tt_daemon.yaml` config. The following set of commands is implemented: * `tt daemon start` - launch of a daemon; * `tt daemon stop` - terminate of the daemon; * `tt daemon status` - get daemon status; * `tt daemon restart` - daemon restart. Closes #10
1 parent 69e4b94 commit 3a8fa03

File tree

24 files changed

+1818
-166
lines changed

24 files changed

+1818
-166
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
1010
### Added
1111

1212
- Module ``tt init``, to create tt environment configuration file.
13+
- Module ``tt daemon``, to manage the ``tt`` daemon.
1314

1415
## [0.1.0] - 2022-10-12
1516

README.rst

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -293,6 +293,56 @@ use the .rockspec.
293293

294294
`Custom template example <https://github.com/tarantool/tt/blob/master/doc/examples.rst#working-with-application-templates>`_
295295

296+
Working with tt daemon (experimental)
297+
-------------------------------------
298+
299+
``tt daemon`` module is used to manage ``tt`` running
300+
on the background on a given machine. This way instances
301+
can be operated remotely.
302+
Daemon can be configured with ``tt_daemon.yaml`` config.
303+
304+
``tt_daemon.yaml`` file format:
305+
306+
.. code-block:: yaml
307+
308+
daemon:
309+
run_dir: path
310+
log_dir: path
311+
log_maxsize: num (MB)
312+
log_maxage: num (Days)
313+
log_maxbackups: num
314+
log_file: string (file name)
315+
listen_interface: string
316+
port: num
317+
pidfile: string (file name)
318+
319+
Where:
320+
321+
* ``run_dir`` (string) - path to directory that stores various instance
322+
runtime artifacts like console socket, PID file, etc. Default: ``run``.
323+
* ``log_dir`` (string) - directory that stores log files. Default: ``log``.
324+
* ``log_maxsize`` (number) - the maximum size in MB of the log file before it gets
325+
rotated. Default: 100 MB.
326+
* ``log_maxage`` (numder) - is the maximum number of days to retain old log files
327+
based on the timestamp encoded in their filename. Note that a day is defined
328+
as 24 hours and may not exactly correspond to calendar days due to daylight
329+
savings, leap seconds, etc. Default: not to remove old log files based
330+
on age.
331+
* ``log_maxbackups`` (number) - the maximum number of old log files to retain.
332+
Default: to retain all old log files (though log_maxage may still cause
333+
them to get deleted).
334+
* ``log_file`` (string) - name of file contains log of daemon process.
335+
Default: ``tt_daemon.log``.
336+
* ``listen_interface`` (string) - network interface the IP address
337+
should be found on to bind http server socket.
338+
Default: loopback (``lo``/``lo0``).
339+
* ``port`` (number) - port number to be used for daemon http server.
340+
Default: 1024.
341+
* ``pidfile`` (string) - name of file contains pid of daemon process.
342+
Default: ``tt_daemon.pid``.
343+
344+
`TT daemon example <https://github.com/tarantool/tt/blob/master/doc/examples.rst#working-with-tt-daemon>`_
345+
296346
Commands
297347
--------
298348
Common description. For a detailed description, use ``tt help command`` .
@@ -319,3 +369,4 @@ Common description. For a detailed description, use ``tt help command`` .
319369
* ``install`` - install tarantool/tt.
320370
* ``remove`` - remove tarantool/tt.
321371
* ``init`` - create tt environment configuration file.
372+
* ``daemon (experimental)`` - manage tt daemon.

cli/cmd/daemon.go

Lines changed: 152 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,152 @@
1+
package cmd
2+
3+
import (
4+
"github.com/apex/log"
5+
"github.com/spf13/cobra"
6+
"github.com/tarantool/tt/cli/cmdcontext"
7+
"github.com/tarantool/tt/cli/configure"
8+
"github.com/tarantool/tt/cli/daemon"
9+
"github.com/tarantool/tt/cli/modules"
10+
"github.com/tarantool/tt/cli/process_utils"
11+
)
12+
13+
// NewDaemonCmd creates daemon command.
14+
func NewDaemonCmd() *cobra.Command {
15+
var daemonCmd = &cobra.Command{
16+
Use: "daemon",
17+
Short: "Perform manipulations with the tt daemon (experimental)",
18+
}
19+
20+
var startCmd = &cobra.Command{
21+
Use: "start",
22+
Short: "start tt daemon",
23+
Run: func(cmd *cobra.Command, args []string) {
24+
if len(args) != 0 {
25+
log.Fatalf("Wrong number of arguments")
26+
}
27+
28+
err := modules.RunCmd(&cmdCtx, cmd.Name(), &modulesInfo,
29+
internalDaemonStartModule, args)
30+
if err != nil {
31+
log.Fatalf(err.Error())
32+
}
33+
},
34+
}
35+
36+
var stopCmd = &cobra.Command{
37+
Use: "stop",
38+
Short: "stop tt daemon",
39+
Run: func(cmd *cobra.Command, args []string) {
40+
if len(args) != 0 {
41+
log.Fatalf("Wrong number of arguments")
42+
}
43+
44+
err := modules.RunCmd(&cmdCtx, cmd.Name(), &modulesInfo,
45+
internalDaemonStopModule, args)
46+
if err != nil {
47+
log.Fatalf(err.Error())
48+
}
49+
},
50+
}
51+
52+
var statusCmd = &cobra.Command{
53+
Use: "status",
54+
Short: "status of tt daemon",
55+
Run: func(cmd *cobra.Command, args []string) {
56+
if len(args) != 0 {
57+
log.Fatalf("Wrong number of arguments")
58+
}
59+
60+
err := modules.RunCmd(&cmdCtx, cmd.Name(), &modulesInfo,
61+
internalDaemonStatusModule, args)
62+
if err != nil {
63+
log.Fatalf(err.Error())
64+
}
65+
},
66+
}
67+
68+
var restartCmd = &cobra.Command{
69+
Use: "restart",
70+
Short: "restart tt daemon",
71+
Run: func(cmd *cobra.Command, args []string) {
72+
if len(args) != 0 {
73+
log.Fatalf("Wrong number of arguments")
74+
}
75+
76+
err := modules.RunCmd(&cmdCtx, cmd.Name(), &modulesInfo,
77+
internalDaemonRestartModule, args)
78+
if err != nil {
79+
log.Fatalf(err.Error())
80+
}
81+
},
82+
}
83+
84+
daemonSubCommands := []*cobra.Command{
85+
startCmd,
86+
stopCmd,
87+
statusCmd,
88+
restartCmd,
89+
}
90+
91+
for _, cmd := range daemonSubCommands {
92+
daemonCmd.AddCommand(cmd)
93+
}
94+
95+
return daemonCmd
96+
}
97+
98+
// internalDaemonStartModule is a default restart module.
99+
func internalDaemonRestartModule(cmdCtx *cmdcontext.CmdCtx, args []string) error {
100+
if err := internalDaemonStopModule(cmdCtx, args); err != nil {
101+
return err
102+
}
103+
104+
if err := internalDaemonStartModule(cmdCtx, args); err != nil {
105+
return err
106+
}
107+
108+
return nil
109+
}
110+
111+
// internalDaemonStartModule is a default start module.
112+
func internalDaemonStartModule(cmdCtx *cmdcontext.CmdCtx, args []string) error {
113+
opts, err := configure.GetDaemonOpts(cmdCtx.Cli.DaemonCfgPath)
114+
if err != nil {
115+
return err
116+
}
117+
118+
daemonCtx := daemon.NewDaemonCtx(opts)
119+
if err := daemon.RunHTTPServerOnBackground(daemonCtx); err != nil {
120+
log.Fatalf(err.Error())
121+
}
122+
123+
return nil
124+
}
125+
126+
// internalDaemonStopModule is a default stop module.
127+
func internalDaemonStopModule(cmdCtx *cmdcontext.CmdCtx, args []string) error {
128+
opts, err := configure.GetDaemonOpts(cmdCtx.Cli.DaemonCfgPath)
129+
if err != nil {
130+
return err
131+
}
132+
133+
daemonCtx := daemon.NewDaemonCtx(opts)
134+
if err := process_utils.StopProcess(daemonCtx.PIDFile, "", "Daemon"); err != nil {
135+
return err
136+
}
137+
138+
return nil
139+
}
140+
141+
// internalDaemonStatusModule is a default status module.
142+
func internalDaemonStatusModule(cmdCtx *cmdcontext.CmdCtx, args []string) error {
143+
opts, err := configure.GetDaemonOpts(cmdCtx.Cli.DaemonCfgPath)
144+
if err != nil {
145+
return err
146+
}
147+
148+
daemonCtx := daemon.NewDaemonCtx(opts)
149+
log.Info(process_utils.ProcessStatus(daemonCtx.PIDFile))
150+
151+
return nil
152+
}

cli/cmd/root.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,7 @@ func NewCmdRoot() *cobra.Command {
117117
NewRemoveCmd(),
118118
NewPackCmd(),
119119
NewInitCmd(),
120+
NewDaemonCmd(),
120121
)
121122
if err := injectCmds(rootCmd); err != nil {
122123
panic(err.Error())

cli/cmdcontext/cmdcontext.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@ type CliCtx struct {
2121
LocalLaunchDir string
2222
// Path to Tarantool CLI (tarantool.yaml) config.
2323
ConfigPath string
24+
// Path to tt daemon (tt_daemon.yaml) config.
25+
DaemonCfgPath string
2426
// Path to Tarantool executable (detected if CLI launch is local).
2527
TarantoolExecutable string
2628
// Tarantool version.

cli/config/daemon_cfg.go

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
package config
2+
3+
// DaemonCfg used to store all information from the
4+
// tt_daemon.yaml configuration file.
5+
type DaemonCfg struct {
6+
DaemonConfig *DaemonOpts `mapstructure:"daemon" yaml:"daemon"`
7+
}
8+
9+
// DaemonOpts stores information about tt daemon configuration.
10+
// Filled in when parsing the tt_daemon.yaml configuration file.
11+
//
12+
// tt_daemon.yaml file format:
13+
// daemon:
14+
//
15+
// run_dir: path
16+
// log_dir: path
17+
// log_maxsize: num (MB)
18+
// log_maxage: num (Days)
19+
// log_maxbackups: num
20+
// log_file: string (file name)
21+
// listen_interface: string
22+
// port: num
23+
// pidfile: string (file name)
24+
type DaemonOpts struct {
25+
// PIDFile is name of file contains pid of daemon process.
26+
PIDFile string `mapstructure:"pidfile"`
27+
// Port is a port number to be used for daemon http server.
28+
Port int `mapstructure:"port"`
29+
// LogDir is a directory that stores log files.
30+
LogDir string `mapstructure:"log_dir"`
31+
// LogFile is a name of file contains log of daemon process.
32+
LogFile string `mapstructure:"log_file"`
33+
// LogMaxSize is a maximum size in MB of the log file before
34+
// it gets rotated.
35+
LogMaxSize int `mapstructure:"log_maxsize"`
36+
// LogMaxAge is the maximum number of days to retain old log files
37+
// based on the timestamp encoded in their filename. Note that a
38+
// day is defined as 24 hours and may not exactly correspond to
39+
// calendar days due to daylight savings, leap seconds, etc. The
40+
// default is not to remove old log files based on age.
41+
LogMaxAge int `mapstructure:"log_maxage"`
42+
// LogMaxBackups is the maximum number of old log files to retain.
43+
// The default is to retain all old log files (though LogMaxAge may
44+
// still cause them to get deleted).
45+
LogMaxBackups int `mapstructure:"log_maxbackups"`
46+
// ListenInterface is a network interface the IP address
47+
// should be found on to bind http server socket.
48+
ListenInterface string `mapstructure:"listen_interface"`
49+
// RunDir is a path to directory that stores various instance
50+
// runtime artifacts like console socket, PID file, etc.
51+
RunDir string `mapstructure:"run_dir" yaml:"run_dir"`
52+
}

0 commit comments

Comments
 (0)