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
|
// Package jailmgr talks to jail(8) directly via jail.conf.d and the base
// system's `service jail` rc.d script - no bastille/iocage in the loop.
package jailmgr
import (
"context"
"fmt"
"io"
"os"
"path/filepath"
"skiff/internal/layout"
"skiff/internal/sh"
"skiff/internal/tmpl"
)
// WriteConf renders jail.conf.d/<app>.conf and the jail's own rc.d service
// script + rc.conf enable line. Called once, from `skiff new-app`.
func WriteConf(cfg layout.Config, app, ip string) error {
conf, err := tmpl.JailConf(tmpl.JailConfData{
Name: app,
JailRoot: cfg.JailRoot(app),
IP: ip,
})
if err != nil {
return err
}
if err := os.WriteFile(cfg.JailConfPath(app), []byte(conf), 0644); err != nil {
return fmt.Errorf("write jail.conf: %w", err)
}
rc, err := tmpl.RCScript(tmpl.RCData{Name: app})
if err != nil {
return err
}
rcPath := filepath.Join(cfg.JailRoot(app), "usr", "local", "etc", "rc.d", app)
if err := os.MkdirAll(filepath.Dir(rcPath), 0755); err != nil {
return err
}
if err := os.WriteFile(rcPath, []byte(rc), 0755); err != nil {
return fmt.Errorf("write rc.d script: %w", err)
}
rcConfLine := fmt.Sprintf("\n%s_enable=\"YES\"\n", app)
f, err := os.OpenFile(filepath.Join(cfg.JailRoot(app), "etc", "rc.conf"), os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644)
if err != nil {
return fmt.Errorf("open jail rc.conf: %w", err)
}
defer f.Close()
if _, err := f.WriteString(rcConfLine); err != nil {
return fmt.Errorf("enable service in jail rc.conf: %w", err)
}
return nil
}
func Start(ctx context.Context, out io.Writer, app string) error {
return sh.Run(ctx, out, "", "service", "jail", "start", app)
}
func Stop(ctx context.Context, out io.Writer, app string) error {
return sh.Run(ctx, out, "", "service", "jail", "stop", app)
}
// Restart restarts an already-running jail, or starts it if this is its
// first deploy and it isn't up yet.
func Restart(ctx context.Context, out io.Writer, app string) error {
if err := sh.Run(ctx, out, "", "service", "jail", "restart", app); err != nil {
return sh.Run(ctx, out, "", "service", "jail", "start", app)
}
return nil
}
|