Compare commits
9 Commits
3cd53b3dd9
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
1978e263d6 | ||
|
|
7726d732d4 | ||
|
|
32bc44c90f | ||
|
|
805f42d828 | ||
|
|
e8349360cc | ||
|
|
4e58df9c9b | ||
|
|
f90421e5db | ||
|
|
c9f2c56d65 | ||
|
|
92b645f34c |
3
.gitignore
vendored
Normal file
3
.gitignore
vendored
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
/hnctl
|
||||||
|
/router
|
||||||
|
/wrench
|
||||||
44
cli/cli.go
44
cli/cli.go
@@ -5,7 +5,10 @@ package cli
|
|||||||
import "os"
|
import "os"
|
||||||
import "fmt"
|
import "fmt"
|
||||||
import "flag"
|
import "flag"
|
||||||
|
import "os/user"
|
||||||
import "strings"
|
import "strings"
|
||||||
|
import "strconv"
|
||||||
|
import "path/filepath"
|
||||||
|
|
||||||
// Sayf is like Printf, but prints the program name before the message. This is
|
// Sayf is like Printf, but prints the program name before the message. This is
|
||||||
// used for printing messages and errors.
|
// used for printing messages and errors.
|
||||||
@@ -25,6 +28,16 @@ func ServiceUser (service string) string {
|
|||||||
return "hn-" + strings.ToLower(service)
|
return "hn-" + strings.ToLower(service)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// DataDir returns the standard Hnakra data directory.
|
||||||
|
func DataDir () string {
|
||||||
|
return "/var/hnakra"
|
||||||
|
}
|
||||||
|
|
||||||
|
// ServiceDir returns the standard data directory of a service.
|
||||||
|
func ServiceDir (service string) string {
|
||||||
|
return filepath.Join(DataDir(), "services", ServiceUser(service))
|
||||||
|
}
|
||||||
|
|
||||||
// NeedRoot halts the program and displays an error if it is not being run as
|
// NeedRoot halts the program and displays an error if it is not being run as
|
||||||
// root. This should be called whenever an operation takes place that requires
|
// root. This should be called whenever an operation takes place that requires
|
||||||
// root privelages.
|
// root privelages.
|
||||||
@@ -35,3 +48,34 @@ func NeedRoot() {
|
|||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// MkdirFor makes a directory makes the specified directory (if it doesnt
|
||||||
|
// already exist) and gives ownership of it to the specified uid and gid.
|
||||||
|
func MkdirFor (directory string, uid, gid int) error {
|
||||||
|
err := os.MkdirAll(directory, 0755)
|
||||||
|
if err != nil { return err }
|
||||||
|
err = os.Chmod(directory, 0770)
|
||||||
|
if err != nil { return err }
|
||||||
|
err = os.Chown(directory, uid, gid)
|
||||||
|
if err != nil { return err }
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// LookupUID returns the uid and gid of the given username, if it exists.
|
||||||
|
func LookupUID (name string) (uid, gid uint32, err error) {
|
||||||
|
user, err := user.Lookup(name)
|
||||||
|
if err != nil {
|
||||||
|
return 0, 0, err
|
||||||
|
}
|
||||||
|
|
||||||
|
puid, err := strconv.Atoi(user.Uid)
|
||||||
|
if err != nil {
|
||||||
|
return 0, 0, err
|
||||||
|
}
|
||||||
|
pgid, err := strconv.Atoi(user.Gid)
|
||||||
|
if err != nil {
|
||||||
|
return 0, 0, err
|
||||||
|
}
|
||||||
|
return uint32(puid), uint32(pgid), nil
|
||||||
|
}
|
||||||
|
|||||||
@@ -10,8 +10,8 @@ import "hnakra/daemon"
|
|||||||
import "hnakra/routines"
|
import "hnakra/routines"
|
||||||
import "hnakra/router/rcon"
|
import "hnakra/router/rcon"
|
||||||
import "hnakra/router/config"
|
import "hnakra/router/config"
|
||||||
import "hnakra/cmd/router/srvhttps"
|
import "hnakra/cmd/hn-router/srvhttps"
|
||||||
import "hnakra/cmd/router/srvhnakra"
|
import "hnakra/cmd/hn-router/srvhnakra"
|
||||||
|
|
||||||
const banner = "\n" +
|
const banner = "\n" +
|
||||||
" -=\\\n" +
|
" -=\\\n" +
|
||||||
@@ -11,6 +11,8 @@ type Server struct {
|
|||||||
underlying net.Listener
|
underlying net.Listener
|
||||||
Config config.Config
|
Config config.Config
|
||||||
Router *router.Router
|
Router *router.Router
|
||||||
|
|
||||||
|
running bool
|
||||||
}
|
}
|
||||||
|
|
||||||
func (server *Server) Run () (err error) {
|
func (server *Server) Run () (err error) {
|
||||||
@@ -18,17 +20,25 @@ func (server *Server) Run () (err error) {
|
|||||||
"tcp", fmt.Sprint(":", server.Config.RouterPort()),
|
"tcp", fmt.Sprint(":", server.Config.RouterPort()),
|
||||||
config.TLSConfigFor(server.Config))
|
config.TLSConfigFor(server.Config))
|
||||||
if err != nil { return err }
|
if err != nil { return err }
|
||||||
|
|
||||||
|
server.running = true
|
||||||
log.Println(".// router on", server.underlying.Addr())
|
log.Println(".// router on", server.underlying.Addr())
|
||||||
|
|
||||||
for {
|
for {
|
||||||
conn, err := server.underlying.Accept()
|
conn, err := server.underlying.Accept()
|
||||||
if err != nil { return err }
|
if err != nil {
|
||||||
|
if server.running {
|
||||||
|
return err
|
||||||
|
} else {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
log.Println("-=E incoming connection from", conn.RemoteAddr())
|
log.Println("-=E incoming connection from", conn.RemoteAddr())
|
||||||
server.Router.Accept(conn)
|
server.Router.Accept(conn)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (server *Server) Shutdown () error {
|
func (server *Server) Shutdown () error {
|
||||||
|
server.running = false
|
||||||
return server.underlying.Close()
|
return server.underlying.Close()
|
||||||
}
|
}
|
||||||
@@ -9,6 +9,8 @@ type Server struct {
|
|||||||
underlying *http.Server
|
underlying *http.Server
|
||||||
Config config.Config
|
Config config.Config
|
||||||
Handler http.Handler
|
Handler http.Handler
|
||||||
|
|
||||||
|
running bool
|
||||||
}
|
}
|
||||||
|
|
||||||
func (server *Server) Run () error {
|
func (server *Server) Run () error {
|
||||||
@@ -22,10 +24,17 @@ func (server *Server) Run () error {
|
|||||||
Handler: server.Handler,
|
Handler: server.Handler,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
server.running = true
|
||||||
log.Println(".// https on", server.underlying.Addr)
|
log.Println(".// https on", server.underlying.Addr)
|
||||||
return server.underlying.ListenAndServeTLS("", "")
|
err := server.underlying.ListenAndServeTLS("", "")
|
||||||
|
if server.running {
|
||||||
|
return err
|
||||||
|
} else {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (server *Server) Shutdown () error {
|
func (server *Server) Shutdown () error {
|
||||||
|
server.running = false
|
||||||
return server.underlying.Close()
|
return server.underlying.Close()
|
||||||
}
|
}
|
||||||
@@ -30,7 +30,7 @@ func main () {
|
|||||||
stopService := stopCommand.String("s", "router", "Service to stop")
|
stopService := stopCommand.String("s", "router", "Service to stop")
|
||||||
|
|
||||||
restartCommand := flag.NewFlagSet("restart", flag.ExitOnError)
|
restartCommand := flag.NewFlagSet("restart", flag.ExitOnError)
|
||||||
restartService := stopCommand.String("s", "router", "Service to restart")
|
restartService := restartCommand.String("s", "router", "Service to restart")
|
||||||
|
|
||||||
flag.Parse()
|
flag.Parse()
|
||||||
|
|
||||||
@@ -60,27 +60,27 @@ func execStart (service string) {
|
|||||||
|
|
||||||
pid, err := spawn.PidOf(fullName)
|
pid, err := spawn.PidOf(fullName)
|
||||||
if err == nil && spawn.Running(pid) {
|
if err == nil && spawn.Running(pid) {
|
||||||
cli.Sayf("service is already running")
|
cli.Sayf("service is already running\n")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
uid, gid, err := spawn.LookupUID(fullName)
|
uid, gid, err := cli.LookupUID(fullName)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
cli.Sayf("cannot start service: %v", err)
|
cli.Sayf("cannot start service: %v\n", err)
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
|
|
||||||
path, err := exec.LookPath(fullName)
|
path, err := exec.LookPath(fullName)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
cli.Sayf("cannot start service: %v", err)
|
cli.Sayf("cannot start service: %v\n", err)
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
|
|
||||||
logDir := filepath.Join("/var/log/", fullName)
|
logDir := filepath.Join("/var/log/", fullName)
|
||||||
env := append(os.Environ(), "HNAKRA_LOG_DIR=" + logDir)
|
env := append(os.Environ(), "HNAKRA_LOG_DIR=" + logDir)
|
||||||
err = ensureLogDir(logDir, int(uid), int(gid))
|
err = cli.MkdirFor(logDir, int(uid), int(gid))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
cli.Sayf("cannot start service: %v", err)
|
cli.Sayf("cannot start service: %v\n", err)
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -88,14 +88,14 @@ func execStart (service string) {
|
|||||||
// to it
|
// to it
|
||||||
err = ensurePidFile(spawn.PidFile(fullName), int(uid), int(gid))
|
err = ensurePidFile(spawn.PidFile(fullName), int(uid), int(gid))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
cli.Sayf("cannot start service: %v", err)
|
cli.Sayf("cannot start service: %v\n", err)
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
|
|
||||||
// spawn the service
|
// spawn the service
|
||||||
pid, err = spawn.Spawn(path, uid, gid, env)
|
pid, err = spawn.Spawn(path, uid, gid, env)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
cli.Sayf("cannot start service: %v", err)
|
cli.Sayf("cannot start service: %v\n", err)
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -108,34 +108,23 @@ func execStop (service string) {
|
|||||||
|
|
||||||
pid, err := spawn.PidOf(fullName)
|
pid, err := spawn.PidOf(fullName)
|
||||||
if err != nil || !spawn.Running(pid) {
|
if err != nil || !spawn.Running(pid) {
|
||||||
cli.Sayf("service is not running")
|
cli.Sayf("service is not running\n")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
process, err := os.FindProcess(pid)
|
process, err := os.FindProcess(pid)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
cli.Sayf("service is not running")
|
cli.Sayf("service is not running\n")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
err = spawn.KillAndWait(process, 16 * time.Second)
|
err = spawn.KillAndWait(process, 16 * time.Second)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
cli.Sayf("could not stop service: %v", err)
|
cli.Sayf("could not stop service: %v\n", err)
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func ensureLogDir (directory string, uid, gid int) error {
|
|
||||||
err := os.MkdirAll(directory, 0755)
|
|
||||||
if err != nil { return err }
|
|
||||||
err = os.Chmod(directory, 0770)
|
|
||||||
if err != nil { return err }
|
|
||||||
err = os.Chown(directory, uid, gid)
|
|
||||||
if err != nil { return err }
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func ensurePidFile (file string, uid, gid int) error {
|
func ensurePidFile (file string, uid, gid int) error {
|
||||||
pidFile, err := os.Create(file)
|
pidFile, err := os.Create(file)
|
||||||
if err != nil { return err }
|
if err != nil { return err }
|
||||||
|
|||||||
@@ -6,7 +6,6 @@ import "fmt"
|
|||||||
import "time"
|
import "time"
|
||||||
import "errors"
|
import "errors"
|
||||||
import "syscall"
|
import "syscall"
|
||||||
import "os/user"
|
|
||||||
import "strconv"
|
import "strconv"
|
||||||
import "path/filepath"
|
import "path/filepath"
|
||||||
|
|
||||||
@@ -45,24 +44,6 @@ func Spawn (path string, uid, gid uint32, env []string, args ...string) (pid int
|
|||||||
return process.Pid, process.Release()
|
return process.Pid, process.Release()
|
||||||
}
|
}
|
||||||
|
|
||||||
// LookupUID returns the uid and gid of the given username, if it exists.
|
|
||||||
func LookupUID (name string) (uid, gid uint32, err error) {
|
|
||||||
user, err := user.Lookup(name)
|
|
||||||
if err != nil {
|
|
||||||
return 0, 0, err
|
|
||||||
}
|
|
||||||
|
|
||||||
puid, err := strconv.Atoi(user.Uid)
|
|
||||||
if err != nil {
|
|
||||||
return 0, 0, err
|
|
||||||
}
|
|
||||||
pgid, err := strconv.Atoi(user.Gid)
|
|
||||||
if err != nil {
|
|
||||||
return 0, 0, err
|
|
||||||
}
|
|
||||||
return uint32(puid), uint32(pgid), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// PidFile returns the path of a pidfile under the specified name. More
|
// PidFile returns the path of a pidfile under the specified name. More
|
||||||
// specifically, it returns `/run/<name>.pid`.
|
// specifically, it returns `/run/<name>.pid`.
|
||||||
func PidFile (name string) string {
|
func PidFile (name string) string {
|
||||||
|
|||||||
@@ -76,6 +76,8 @@ func main () {
|
|||||||
delUserCommand := flag.NewFlagSet("deluser", flag.ExitOnError)
|
delUserCommand := flag.NewFlagSet("deluser", flag.ExitOnError)
|
||||||
delUserService := delUserCommand.String ("s", "router",
|
delUserService := delUserCommand.String ("s", "router",
|
||||||
"Service to delete the user for")
|
"Service to delete the user for")
|
||||||
|
delUserRmData := delUserCommand.Bool ("D", false,
|
||||||
|
"Whether to remove the service's data directory")
|
||||||
|
|
||||||
authCommand := flag.NewFlagSet("auth", flag.ExitOnError)
|
authCommand := flag.NewFlagSet("auth", flag.ExitOnError)
|
||||||
authService := authCommand.String ("s", "router",
|
authService := authCommand.String ("s", "router",
|
||||||
@@ -108,7 +110,7 @@ func main () {
|
|||||||
execAdduser(*addUserService)
|
execAdduser(*addUserService)
|
||||||
case "deluser":
|
case "deluser":
|
||||||
delUserCommand.Parse(subCommandArgs)
|
delUserCommand.Parse(subCommandArgs)
|
||||||
execDeluser(*delUserService)
|
execDeluser(*delUserService, *delUserRmData)
|
||||||
case "auth":
|
case "auth":
|
||||||
authCommand.Parse(subCommandArgs)
|
authCommand.Parse(subCommandArgs)
|
||||||
execAuth(*authService, *authUser)
|
execAuth(*authService, *authUser)
|
||||||
@@ -144,55 +146,68 @@ func execHash (cost int, key string) {
|
|||||||
|
|
||||||
func execAdduser (service string) {
|
func execAdduser (service string) {
|
||||||
fullName := cli.ServiceUser(service)
|
fullName := cli.ServiceUser(service)
|
||||||
|
dataDir := cli.ServiceDir(service)
|
||||||
|
|
||||||
// BUSYBOX
|
if adduser, err := exec.LookPath("adduser"); err == nil {
|
||||||
adduser, err := exec.LookPath("adduser")
|
// BUSYBOX
|
||||||
if err == nil {
|
|
||||||
addgroup, _ := exec.LookPath("addgroup")
|
addgroup, _ := exec.LookPath("addgroup")
|
||||||
tryCommand (exec.Command(addgroup, fullName, "-S"),
|
tryCommand (exec.Command(addgroup, fullName, "-S"),
|
||||||
"could not add group")
|
"could not add group")
|
||||||
tryCommand (exec.Command(adduser, fullName, "-SHDG", fullName),
|
tryCommand (exec.Command (
|
||||||
|
adduser, fullName, "-SHDG", fullName, "-h", dataDir),
|
||||||
"could not add user")
|
"could not add user")
|
||||||
return
|
} else if useradd, err := exec.LookPath("useradd"); err == nil {
|
||||||
}
|
// GNU
|
||||||
|
|
||||||
// GNU
|
|
||||||
useradd, err := exec.LookPath("useradd")
|
|
||||||
if err == nil {
|
|
||||||
tryCommand (exec.Command (
|
tryCommand (exec.Command (
|
||||||
useradd, fullName, "-rUM",
|
useradd, fullName, "-rUM",
|
||||||
"--shell", "/sbin/nologin"), "could not add user")
|
"--shell", "/sbin/nologin",
|
||||||
return
|
"-d", dataDir), "could not add user")
|
||||||
|
} else {
|
||||||
|
cli.Sayf("could not add user: no command adduser or useradd\n")
|
||||||
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
|
|
||||||
cli.Sayf("could not add user: no command adduser or useradd\n")
|
// create data directory
|
||||||
os.Exit(1)
|
uid, gid, err := cli.LookupUID(fullName)
|
||||||
|
if err != nil {
|
||||||
|
cli.Sayf("could not create data dir: %v\n", err)
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
err = cli.MkdirFor(dataDir, int(uid), int(gid))
|
||||||
|
if err != nil {
|
||||||
|
cli.Sayf("could not create data dir: %v\n", err)
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func execDeluser (service string) {
|
func execDeluser (service string, rmData bool) {
|
||||||
fullName := cli.ServiceUser(service)
|
fullName := cli.ServiceUser(service)
|
||||||
|
dataDir := cli.ServiceDir(service)
|
||||||
|
|
||||||
// BUSYBOX
|
if deluser, err := exec.LookPath("deluser"); err == nil {
|
||||||
deluser, err := exec.LookPath("deluser")
|
// BUSYBOX
|
||||||
if err == nil {
|
|
||||||
tryCommand (exec.Command(deluser, fullName, "--remove-home"),
|
tryCommand (exec.Command(deluser, fullName, "--remove-home"),
|
||||||
"could not delete user")
|
"could not delete user")
|
||||||
return
|
} else if userdel, err := exec.LookPath("userdel"); err == nil {
|
||||||
}
|
// GNU
|
||||||
|
|
||||||
// GNU
|
|
||||||
userdel, err := exec.LookPath("userdel")
|
|
||||||
if err == nil {
|
|
||||||
tryCommand (exec.Command(userdel, fullName, "-r"),
|
tryCommand (exec.Command(userdel, fullName, "-r"),
|
||||||
"could not delete user")
|
"could not delete user")
|
||||||
groupdel, _ := exec.LookPath("groupdel")
|
groupdel, _ := exec.LookPath("groupdel")
|
||||||
tryCommand (exec.Command(groupdel, fullName),
|
tryCommand (exec.Command(groupdel, fullName),
|
||||||
"could not delete group")
|
"could not delete group")
|
||||||
return
|
} else {
|
||||||
|
cli.Sayf("could not delete user: no command deluser or userdel\n")
|
||||||
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
|
|
||||||
cli.Sayf("could not delete user: no command deluser or userdel\n")
|
// delete data directory
|
||||||
os.Exit(1)
|
if rmData {
|
||||||
|
err := os.RemoveAll(dataDir)
|
||||||
|
if err != nil {
|
||||||
|
cli.Sayf("could not delete data dir: %v\n", err)
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func execAuth (service, user string) {
|
func execAuth (service, user string) {
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ import "fmt"
|
|||||||
import "log"
|
import "log"
|
||||||
import "time"
|
import "time"
|
||||||
import "sync"
|
import "sync"
|
||||||
|
import "errors"
|
||||||
|
|
||||||
type routine struct {
|
type routine struct {
|
||||||
run, shutdown func () error
|
run, shutdown func () error
|
||||||
@@ -71,17 +72,16 @@ type Manager struct {
|
|||||||
// Run returns only when all routines have exited.
|
// Run returns only when all routines have exited.
|
||||||
func (manager *Manager) Run () error {
|
func (manager *Manager) Run () error {
|
||||||
var waitGroup sync.WaitGroup
|
var waitGroup sync.WaitGroup
|
||||||
var errExit error
|
|
||||||
|
|
||||||
for _, routine := range manager.Routines {
|
for _, routine := range manager.Routines {
|
||||||
if routine != nil {
|
if routine != nil {
|
||||||
waitGroup.Add(1)
|
waitGroup.Add(1)
|
||||||
go manager.runRoutine(routine, &waitGroup, &errExit)
|
go manager.runRoutine(routine, &waitGroup)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
waitGroup.Wait()
|
waitGroup.Wait()
|
||||||
return errExit
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Shutdown shuts down all routines in the manager.
|
// Shutdown shuts down all routines in the manager.
|
||||||
@@ -113,21 +113,26 @@ func (manager *Manager) log (message ...any) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (manager *Manager) runRoutine (routine Routine, group *sync.WaitGroup, errExit *error) {
|
func (manager *Manager) runRoutine (routine Routine, group *sync.WaitGroup) {
|
||||||
defer group.Done()
|
defer group.Done()
|
||||||
|
|
||||||
var err error
|
|
||||||
for {
|
for {
|
||||||
|
lastStart := time.Now()
|
||||||
|
err := panicWrap(routine.Run)
|
||||||
|
|
||||||
stopping := false
|
stopping := false
|
||||||
manager.stoppingMutex.Lock()
|
manager.stoppingMutex.Lock()
|
||||||
stopping = manager.stopping
|
stopping = manager.stopping
|
||||||
manager.stoppingMutex.Unlock()
|
manager.stoppingMutex.Unlock()
|
||||||
if stopping { break }
|
if stopping {
|
||||||
|
if err == nil {
|
||||||
// TODO: recover from panics
|
manager.log("(i) stopped routine")
|
||||||
lastStart := time.Now()
|
} else {
|
||||||
err = routine.Run()
|
manager.log("!!! stopped routine, with error:", err)
|
||||||
|
}
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
if err == nil {
|
if err == nil {
|
||||||
manager.log("(i) routine exited")
|
manager.log("(i) routine exited")
|
||||||
break
|
break
|
||||||
@@ -142,8 +147,15 @@ func (manager *Manager) runRoutine (routine Routine, group *sync.WaitGroup, errE
|
|||||||
manager.log("(i) routine is being restarted")
|
manager.log("(i) routine is being restarted")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
if err != nil {
|
|
||||||
*errExit = err
|
func panicWrap (f func () error) (err error) {
|
||||||
}
|
defer func () {
|
||||||
|
if pan := recover(); pan != nil {
|
||||||
|
err = errors.New(fmt.Sprint(pan))
|
||||||
|
}
|
||||||
|
} ()
|
||||||
|
|
||||||
|
err = f()
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,11 +19,13 @@ type HTTP struct {
|
|||||||
Handler http.Handler
|
Handler http.Handler
|
||||||
|
|
||||||
conn *Conn
|
conn *Conn
|
||||||
|
running bool
|
||||||
requests requestManager
|
requests requestManager
|
||||||
}
|
}
|
||||||
|
|
||||||
// Close closes the mount abruptly, interrupting any active connections.
|
// Close closes the mount abruptly, interrupting any active connections.
|
||||||
func (htmount *HTTP) Close () error {
|
func (htmount *HTTP) Close () error {
|
||||||
|
htmount.running = false
|
||||||
return htmount.conn.Close()
|
return htmount.conn.Close()
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -44,12 +46,19 @@ func (htmount *HTTP) Run (service ServiceInfo) (err error) {
|
|||||||
}
|
}
|
||||||
htmount.conn, err = Dial(htmount.MountInfo, service)
|
htmount.conn, err = Dial(htmount.MountInfo, service)
|
||||||
if err != nil { return }
|
if err != nil { return }
|
||||||
|
|
||||||
|
htmount.running = true
|
||||||
htmount.requests.init()
|
htmount.requests.init()
|
||||||
|
|
||||||
for {
|
for {
|
||||||
message, err := htmount.conn.Receive()
|
message, err := htmount.conn.Receive()
|
||||||
if err != nil { return err }
|
if err != nil {
|
||||||
|
if htmount.running {
|
||||||
|
return err
|
||||||
|
} else {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
switch message.(type) {
|
switch message.(type) {
|
||||||
case protocol.MessageHTTPRequest:
|
case protocol.MessageHTTPRequest:
|
||||||
|
|||||||
Reference in New Issue
Block a user