Update deps
This commit is contained in:
parent
07e605e9f4
commit
ed5431d7b9
7
go.mod
7
go.mod
|
@ -5,7 +5,8 @@ go 1.13
|
|||
require (
|
||||
github.com/BurntSushi/toml v0.3.1
|
||||
github.com/VividCortex/ewma v1.1.1
|
||||
github.com/coreos/go-systemd v0.0.0-20190719114852-fd7a80b32e1f
|
||||
github.com/agl/ed25519 v0.0.0-20170116200512-5312a6153412
|
||||
github.com/coreos/go-systemd v0.0.0-20191104093116-d3cd4ed1dbcf
|
||||
github.com/dchest/safefile v0.0.0-20151022103144-855e8d98f185
|
||||
github.com/facebookgo/atomicfile v0.0.0-20151019160806-2de1f203e7d5 // indirect
|
||||
github.com/facebookgo/pidfile v0.0.0-20150612191647-f242e2999868
|
||||
|
@ -18,12 +19,12 @@ require (
|
|||
github.com/jedisct1/go-minisign v0.0.0-20190909160543-45766022959e
|
||||
github.com/jedisct1/xsecretbox v0.0.0-20190909160646-b731c21297f9
|
||||
github.com/k-sone/critbitgo v1.4.0
|
||||
github.com/kardianos/service v1.0.1-0.20191017145738-4df36c9fc1c6
|
||||
github.com/kardianos/service v1.0.1-0.20191211031725-3c356ae54c8a
|
||||
github.com/miekg/dns v1.1.25
|
||||
github.com/powerman/check v1.2.1
|
||||
golang.org/x/crypto v0.0.0-20191206172530-e9b2fee46413
|
||||
golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553
|
||||
golang.org/x/sys v0.0.0-20191210023423-ac6580df4449
|
||||
gopkg.in/natefinch/lumberjack.v2 v2.0.0
|
||||
gopkg.in/yaml.v2 v2.2.5 // indirect
|
||||
gopkg.in/yaml.v2 v2.2.7 // indirect
|
||||
)
|
||||
|
|
14
go.sum
14
go.sum
|
@ -6,8 +6,10 @@ github.com/aead/chacha20 v0.0.0-20180709150244-8b13a72661da h1:KjTM2ks9d14ZYCvmH
|
|||
github.com/aead/chacha20 v0.0.0-20180709150244-8b13a72661da/go.mod h1:eHEWzANqSiWQsof+nXEI9bUVUyV6F53Fp89EuCh2EAA=
|
||||
github.com/aead/poly1305 v0.0.0-20180717145839-3fee0db0b635 h1:52m0LGchQBBVqJRyYYufQuIbVqRawmubW3OFGqK1ekw=
|
||||
github.com/aead/poly1305 v0.0.0-20180717145839-3fee0db0b635/go.mod h1:lmLxL+FV291OopO93Bwf9fQLQeLyt33VJRUg5VJ30us=
|
||||
github.com/coreos/go-systemd v0.0.0-20190719114852-fd7a80b32e1f h1:JOrtw2xFKzlg+cbHpyrpLDmnN1HqhBfnX7WDiW7eG2c=
|
||||
github.com/coreos/go-systemd v0.0.0-20190719114852-fd7a80b32e1f/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
|
||||
github.com/agl/ed25519 v0.0.0-20170116200512-5312a6153412 h1:w1UutsfOrms1J05zt7ISrnJIXKzwaspym5BTKGx93EI=
|
||||
github.com/agl/ed25519 v0.0.0-20170116200512-5312a6153412/go.mod h1:WPjqKcmVOxf0XSf3YxCJs6N6AOSrOx3obionmG7T0y0=
|
||||
github.com/coreos/go-systemd v0.0.0-20191104093116-d3cd4ed1dbcf h1:iW4rZ826su+pqaw19uhpSCzhj44qo35pNgKFGqzDKkU=
|
||||
github.com/coreos/go-systemd v0.0.0-20191104093116-d3cd4ed1dbcf/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
|
||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/dchest/safefile v0.0.0-20151022103144-855e8d98f185 h1:3T8ZyTDp5QxTx3NU48JVb2u+75xc040fofcBaN+6jPA=
|
||||
|
@ -44,8 +46,8 @@ github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7
|
|||
github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU=
|
||||
github.com/k-sone/critbitgo v1.4.0 h1:l71cTyBGeh6X5ATh6Fibgw3+rtNT80BA0uNNWgkPrbE=
|
||||
github.com/k-sone/critbitgo v1.4.0/go.mod h1:7E6pyoyADnFxlUBEKcnfS49b7SUAQGMK+OAp/UQvo0s=
|
||||
github.com/kardianos/service v1.0.1-0.20191017145738-4df36c9fc1c6 h1:yXmAejtSQYYDbY5Zv4BQDV4irr8r88UjcWufn4PtF5I=
|
||||
github.com/kardianos/service v1.0.1-0.20191017145738-4df36c9fc1c6/go.mod h1:8CzDhVuCuugtsHyZoTvsOBuvonN/UDBvl0kH+BUxvbo=
|
||||
github.com/kardianos/service v1.0.1-0.20191211031725-3c356ae54c8a h1:T/nL7taPRFDwzB7c31FQTuykulaA11ERY3K6NcoQ/Bg=
|
||||
github.com/kardianos/service v1.0.1-0.20191211031725-3c356ae54c8a/go.mod h1:8CzDhVuCuugtsHyZoTvsOBuvonN/UDBvl0kH+BUxvbo=
|
||||
github.com/miekg/dns v1.1.25 h1:dFwPR6SfLtrSwgDcIq2bcU/gVutB4sNApq2HBdqcakg=
|
||||
github.com/miekg/dns v1.1.25/go.mod h1:bPDLeHnStXmXAq1m/Ch/hvfNHr14JKNPMBo3VZKjuso=
|
||||
github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I=
|
||||
|
@ -93,5 +95,5 @@ gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+
|
|||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/natefinch/lumberjack.v2 v2.0.0 h1:1Lc07Kr7qY4U2YPouBjpCLxpiyxIVoxqXgkXLknAOE8=
|
||||
gopkg.in/natefinch/lumberjack.v2 v2.0.0/go.mod h1:l0ndWWf7gzL7RNwBG7wST/UCcT4T24xpD6X8LsfU/+k=
|
||||
gopkg.in/yaml.v2 v2.2.5 h1:ymVxjfMaHvXD8RqPRmzHHsB3VvucivSkIAvJFDI5O3c=
|
||||
gopkg.in/yaml.v2 v2.2.5/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.2.7 h1:VUgggvou5XRW9mHwD/yXxIYSMtY0zoKQf/v226p2nyo=
|
||||
gopkg.in/yaml.v2 v2.2.7/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
|
|
|
@ -0,0 +1,27 @@
|
|||
Copyright (c) 2012 The Go Authors. All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are
|
||||
met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above
|
||||
copyright notice, this list of conditions and the following disclaimer
|
||||
in the documentation and/or other materials provided with the
|
||||
distribution.
|
||||
* Neither the name of Google Inc. nor the names of its
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
@ -0,0 +1,127 @@
|
|||
// Copyright 2013 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// Package ed25519 implements the Ed25519 signature algorithm. See
|
||||
// http://ed25519.cr.yp.to/.
|
||||
package ed25519
|
||||
|
||||
// This code is a port of the public domain, "ref10" implementation of ed25519
|
||||
// from SUPERCOP.
|
||||
|
||||
import (
|
||||
"crypto/sha512"
|
||||
"crypto/subtle"
|
||||
"io"
|
||||
|
||||
"github.com/agl/ed25519/edwards25519"
|
||||
)
|
||||
|
||||
const (
|
||||
PublicKeySize = 32
|
||||
PrivateKeySize = 64
|
||||
SignatureSize = 64
|
||||
)
|
||||
|
||||
// GenerateKey generates a public/private key pair using randomness from rand.
|
||||
func GenerateKey(rand io.Reader) (publicKey *[PublicKeySize]byte, privateKey *[PrivateKeySize]byte, err error) {
|
||||
privateKey = new([64]byte)
|
||||
publicKey = new([32]byte)
|
||||
_, err = io.ReadFull(rand, privateKey[:32])
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
h := sha512.New()
|
||||
h.Write(privateKey[:32])
|
||||
digest := h.Sum(nil)
|
||||
|
||||
digest[0] &= 248
|
||||
digest[31] &= 127
|
||||
digest[31] |= 64
|
||||
|
||||
var A edwards25519.ExtendedGroupElement
|
||||
var hBytes [32]byte
|
||||
copy(hBytes[:], digest)
|
||||
edwards25519.GeScalarMultBase(&A, &hBytes)
|
||||
A.ToBytes(publicKey)
|
||||
|
||||
copy(privateKey[32:], publicKey[:])
|
||||
return
|
||||
}
|
||||
|
||||
// Sign signs the message with privateKey and returns a signature.
|
||||
func Sign(privateKey *[PrivateKeySize]byte, message []byte) *[SignatureSize]byte {
|
||||
h := sha512.New()
|
||||
h.Write(privateKey[:32])
|
||||
|
||||
var digest1, messageDigest, hramDigest [64]byte
|
||||
var expandedSecretKey [32]byte
|
||||
h.Sum(digest1[:0])
|
||||
copy(expandedSecretKey[:], digest1[:])
|
||||
expandedSecretKey[0] &= 248
|
||||
expandedSecretKey[31] &= 63
|
||||
expandedSecretKey[31] |= 64
|
||||
|
||||
h.Reset()
|
||||
h.Write(digest1[32:])
|
||||
h.Write(message)
|
||||
h.Sum(messageDigest[:0])
|
||||
|
||||
var messageDigestReduced [32]byte
|
||||
edwards25519.ScReduce(&messageDigestReduced, &messageDigest)
|
||||
var R edwards25519.ExtendedGroupElement
|
||||
edwards25519.GeScalarMultBase(&R, &messageDigestReduced)
|
||||
|
||||
var encodedR [32]byte
|
||||
R.ToBytes(&encodedR)
|
||||
|
||||
h.Reset()
|
||||
h.Write(encodedR[:])
|
||||
h.Write(privateKey[32:])
|
||||
h.Write(message)
|
||||
h.Sum(hramDigest[:0])
|
||||
var hramDigestReduced [32]byte
|
||||
edwards25519.ScReduce(&hramDigestReduced, &hramDigest)
|
||||
|
||||
var s [32]byte
|
||||
edwards25519.ScMulAdd(&s, &hramDigestReduced, &expandedSecretKey, &messageDigestReduced)
|
||||
|
||||
signature := new([64]byte)
|
||||
copy(signature[:], encodedR[:])
|
||||
copy(signature[32:], s[:])
|
||||
return signature
|
||||
}
|
||||
|
||||
// Verify returns true iff sig is a valid signature of message by publicKey.
|
||||
func Verify(publicKey *[PublicKeySize]byte, message []byte, sig *[SignatureSize]byte) bool {
|
||||
if sig[63]&224 != 0 {
|
||||
return false
|
||||
}
|
||||
|
||||
var A edwards25519.ExtendedGroupElement
|
||||
if !A.FromBytes(publicKey) {
|
||||
return false
|
||||
}
|
||||
edwards25519.FeNeg(&A.X, &A.X)
|
||||
edwards25519.FeNeg(&A.T, &A.T)
|
||||
|
||||
h := sha512.New()
|
||||
h.Write(sig[:32])
|
||||
h.Write(publicKey[:])
|
||||
h.Write(message)
|
||||
var digest [64]byte
|
||||
h.Sum(digest[:0])
|
||||
|
||||
var hReduced [32]byte
|
||||
edwards25519.ScReduce(&hReduced, &digest)
|
||||
|
||||
var R edwards25519.ProjectiveGroupElement
|
||||
var b [32]byte
|
||||
copy(b[:], sig[32:])
|
||||
edwards25519.GeDoubleScalarMultVartime(&R, &hReduced, &A, &b)
|
||||
|
||||
var checkR [32]byte
|
||||
R.ToBytes(&checkR)
|
||||
return subtle.ConstantTimeCompare(sig[:32], checkR[:]) == 1
|
||||
}
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -77,6 +77,8 @@ const (
|
|||
optionSessionCreateDefault = false
|
||||
optionLogOutput = "LogOutput"
|
||||
optionLogOutputDefault = false
|
||||
optionPrefix = "Prefix"
|
||||
optionPrefixDefault = "application"
|
||||
|
||||
optionRunWait = "RunWait"
|
||||
optionReloadSignal = "ReloadSignal"
|
||||
|
@ -141,7 +143,7 @@ type Config struct {
|
|||
// - RunWait func() (wait for SIGNAL) - Do not install signal but wait for this function to return.
|
||||
// - ReloadSignal string () [USR1, ...] - Signal to send on reaload.
|
||||
// - PIDFile string () [/run/prog.pid] - Location of the PID file.
|
||||
// - LogOutput bool (false) - Redirect StdErr & StdOut to files.
|
||||
// - LogOutput bool (false) - Redirect StdErr & StandardOutPath to files.
|
||||
// - Restart string (always) - How shall service be restarted.
|
||||
// - SuccessExitStatus string () - The list of exit status that shall be considered as successful,
|
||||
// in addition to the default ones.
|
||||
|
|
|
@ -0,0 +1,278 @@
|
|||
// Copyright 2015 Daniel Theophanes.
|
||||
// Use of this source code is governed by a zlib-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package service
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"os"
|
||||
"os/exec"
|
||||
"os/signal"
|
||||
"regexp"
|
||||
"strconv"
|
||||
"strings"
|
||||
"syscall"
|
||||
"text/template"
|
||||
"time"
|
||||
)
|
||||
|
||||
const maxPathSize = 32 * 1024
|
||||
|
||||
const version = "aix-ssrc"
|
||||
|
||||
type aixSystem struct{}
|
||||
|
||||
func (aixSystem) String() string {
|
||||
return version
|
||||
}
|
||||
func (aixSystem) Detect() bool {
|
||||
return true
|
||||
}
|
||||
func (aixSystem) Interactive() bool {
|
||||
return interactive
|
||||
}
|
||||
func (aixSystem) New(i Interface, c *Config) (Service, error) {
|
||||
s := &aixService{
|
||||
i: i,
|
||||
Config: c,
|
||||
}
|
||||
|
||||
return s, nil
|
||||
}
|
||||
|
||||
func getPidOfSvcMaster() int {
|
||||
pat := regexp.MustCompile(`\s+root\s+(\d+)\s+\d+\s+\d+\s+\w+\s+\d+\s+\S+\s+[0-9:]+\s+/usr/sbin/srcmstr`)
|
||||
cmd := exec.Command("ps", "-ef")
|
||||
var out bytes.Buffer
|
||||
cmd.Stdout = &out
|
||||
pid := 0
|
||||
if err := cmd.Run(); err == nil {
|
||||
matches := pat.FindAllStringSubmatch(out.String(),-1)
|
||||
for _, match := range matches {
|
||||
pid, _ = strconv.Atoi(match[1])
|
||||
break
|
||||
}
|
||||
}
|
||||
return pid
|
||||
}
|
||||
|
||||
func init() {
|
||||
ChooseSystem(aixSystem{})
|
||||
}
|
||||
|
||||
var interactive = false
|
||||
|
||||
func init() {
|
||||
var err error
|
||||
interactive, err = isInteractive()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
||||
func isInteractive() (bool, error) {
|
||||
// The PPid of a service process should match PID of srcmstr.
|
||||
return os.Getppid() != getPidOfSvcMaster(), nil
|
||||
}
|
||||
|
||||
type aixService struct {
|
||||
i Interface
|
||||
*Config
|
||||
}
|
||||
|
||||
func (s *aixService) String() string {
|
||||
if len(s.DisplayName) > 0 {
|
||||
return s.DisplayName
|
||||
}
|
||||
return s.Name
|
||||
}
|
||||
|
||||
func (s *aixService) Platform() string {
|
||||
return version
|
||||
}
|
||||
|
||||
func (s *aixService) template() *template.Template {
|
||||
functions := template.FuncMap{
|
||||
"bool": func(v bool) string {
|
||||
if v {
|
||||
return "true"
|
||||
}
|
||||
return "false"
|
||||
},
|
||||
}
|
||||
|
||||
customConfig := s.Option.string(optionSysvScript, "")
|
||||
|
||||
if customConfig != "" {
|
||||
return template.Must(template.New("").Funcs(functions).Parse(customConfig))
|
||||
} else {
|
||||
return template.Must(template.New("").Funcs(functions).Parse(svcConfig))
|
||||
}
|
||||
}
|
||||
|
||||
func (s *aixService) configPath() (cp string, err error) {
|
||||
cp = "/etc/rc.d/init.d/" + s.Config.Name
|
||||
return
|
||||
}
|
||||
|
||||
func (s *aixService) Install() error {
|
||||
// install service
|
||||
path, err := s.execPath()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = run("mkssys", "-s", s.Name, "-p", path, "-u", "0", "-R", "-Q", "-S", "-n", "15", "-f", "9", "-d", "-w", "30" )
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// write start script
|
||||
confPath, err := s.configPath()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
_, err = os.Stat(confPath)
|
||||
if err == nil {
|
||||
return fmt.Errorf("Init already exists: %s", confPath)
|
||||
}
|
||||
|
||||
f, err := os.Create(confPath)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer f.Close()
|
||||
|
||||
var to = &struct {
|
||||
*Config
|
||||
Path string
|
||||
}{
|
||||
s.Config,
|
||||
path,
|
||||
}
|
||||
|
||||
err = s.template().Execute(f, to)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err = os.Chmod(confPath, 0755); err != nil {
|
||||
return err
|
||||
}
|
||||
for _, i := range [...]string{"2", "3"} {
|
||||
if err = os.Symlink(confPath, "/etc/rc"+i+".d/S50"+s.Name); err != nil {
|
||||
continue
|
||||
}
|
||||
if err = os.Symlink(confPath, "/etc/rc"+i+".d/K02"+s.Name); err != nil {
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *aixService) Uninstall() error {
|
||||
s.Stop()
|
||||
|
||||
err := run("rmssys", "-s", s.Name)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
confPath, err := s.configPath()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return os.Remove(confPath)
|
||||
}
|
||||
|
||||
func (s *aixService) Status() (Status, error) {
|
||||
exitCode, out, err := runWithOutput("lssrc", "-s", s.Name)
|
||||
if exitCode == 0 && err != nil {
|
||||
if !strings.Contains(err.Error(), "failed with stderr") {
|
||||
return StatusUnknown, err
|
||||
}
|
||||
}
|
||||
|
||||
re := regexp.MustCompile(`\s+` + s.Name + `\s+(\w+\s+)?(\d+\s+)?(\w+)`)
|
||||
matches := re.FindStringSubmatch(out)
|
||||
if len(matches) == 4 {
|
||||
status := string(matches[3])
|
||||
if status == "inoperative" {
|
||||
return StatusStopped, nil
|
||||
} else if status == "active" {
|
||||
return StatusRunning, nil
|
||||
} else {
|
||||
fmt.Printf("Got unknown service status %s\n", status)
|
||||
return StatusUnknown, err
|
||||
}
|
||||
}
|
||||
|
||||
confPath, err := s.configPath()
|
||||
if err != nil {
|
||||
return StatusUnknown, err
|
||||
}
|
||||
|
||||
if _, err = os.Stat(confPath); err == nil {
|
||||
return StatusStopped, nil
|
||||
}
|
||||
|
||||
return StatusUnknown, ErrNotInstalled
|
||||
}
|
||||
|
||||
func (s *aixService) Start() error {
|
||||
return run("startsrc", "-s", s.Name)
|
||||
}
|
||||
func (s *aixService) Stop() error {
|
||||
return run("stopsrc", "-s", s.Name)
|
||||
}
|
||||
func (s *aixService) Restart() error {
|
||||
err := s.Stop()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
time.Sleep(50 * time.Millisecond)
|
||||
return s.Start()
|
||||
}
|
||||
|
||||
func (s *aixService) Run() error {
|
||||
var err error
|
||||
|
||||
err = s.i.Start(s)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
s.Option.funcSingle(optionRunWait, func() {
|
||||
var sigChan = make(chan os.Signal, 3)
|
||||
signal.Notify(sigChan, syscall.SIGTERM, os.Interrupt)
|
||||
<-sigChan
|
||||
})()
|
||||
|
||||
return s.i.Stop(s)
|
||||
}
|
||||
|
||||
func (s *aixService) Logger(errs chan<- error) (Logger, error) {
|
||||
if interactive {
|
||||
return ConsoleLogger, nil
|
||||
}
|
||||
return s.SystemLogger(errs)
|
||||
}
|
||||
func (s *aixService) SystemLogger(errs chan<- error) (Logger, error) {
|
||||
return newSysLogger(s.Name, errs)
|
||||
}
|
||||
|
||||
var svcConfig = `#!/bin/ksh
|
||||
case "$1" in
|
||||
start )
|
||||
startsrc -s {{.Name}}
|
||||
;;
|
||||
stop )
|
||||
stopsrc -s {{.Name}}
|
||||
;;
|
||||
* )
|
||||
echo "Usage: $0 (start | stop)"
|
||||
exit 1
|
||||
esac
|
||||
`
|
|
@ -160,6 +160,9 @@ func (s *darwinLaunchdService) Install() error {
|
|||
|
||||
KeepAlive, RunAtLoad bool
|
||||
SessionCreate bool
|
||||
StandardOut bool
|
||||
StandardError bool
|
||||
|
||||
}{
|
||||
Config: s.Config,
|
||||
Path: path,
|
||||
|
@ -184,7 +187,7 @@ func (s *darwinLaunchdService) Uninstall() error {
|
|||
func (s *darwinLaunchdService) Status() (Status, error) {
|
||||
exitCode, out, err := runWithOutput("launchctl", "list", s.Name)
|
||||
if exitCode == 0 && err != nil {
|
||||
if !strings.Contains(err.Error(), "failed with stderr") {
|
||||
if !strings.Contains(err.Error(), "failed with StandardError") {
|
||||
return StatusUnknown, err
|
||||
}
|
||||
}
|
||||
|
@ -261,22 +264,36 @@ var launchdConfig = `<?xml version='1.0' encoding='UTF-8'?>
|
|||
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN"
|
||||
"http://www.apple.com/DTDs/PropertyList-1.0.dtd" >
|
||||
<plist version='1.0'>
|
||||
<dict>
|
||||
<key>Label</key><string>{{html .Name}}</string>
|
||||
<key>ProgramArguments</key>
|
||||
<array>
|
||||
<string>{{html .Path}}</string>
|
||||
{{range .Config.Arguments}}
|
||||
<string>{{html .}}</string>
|
||||
{{end}}
|
||||
</array>
|
||||
{{if .UserName}}<key>UserName</key><string>{{html .UserName}}</string>{{end}}
|
||||
{{if .ChRoot}}<key>RootDirectory</key><string>{{html .ChRoot}}</string>{{end}}
|
||||
{{if .WorkingDirectory}}<key>WorkingDirectory</key><string>{{html .WorkingDirectory}}</string>{{end}}
|
||||
<key>SessionCreate</key><{{bool .SessionCreate}}/>
|
||||
<key>KeepAlive</key><{{bool .KeepAlive}}/>
|
||||
<key>RunAtLoad</key><{{bool .RunAtLoad}}/>
|
||||
<key>Disabled</key><false/>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>Label</key>
|
||||
<string>{{html .Name}}</string>
|
||||
<key>ProgramArguments</key>
|
||||
<array>
|
||||
<string>{{html .Path}}</string>
|
||||
{{range .Config.Arguments}}
|
||||
<string>{{html .}}</string>
|
||||
{{end}}
|
||||
</array>
|
||||
{{if .UserName}}<key>UserName</key>
|
||||
<string>{{html .UserName}}</string>{{end}}
|
||||
{{if .ChRoot}}<key>RootDirectory</key>
|
||||
<string>{{html .ChRoot}}</string>{{end}}
|
||||
{{if .WorkingDirectory}}<key>WorkingDirectory</key>
|
||||
<string>{{html .WorkingDirectory}}</string>{{end}}
|
||||
<key>SessionCreate</key>
|
||||
<{{bool .SessionCreate}}/>
|
||||
<key>KeepAlive</key>
|
||||
<{{bool .KeepAlive}}/>
|
||||
<key>RunAtLoad</key>
|
||||
<{{bool .RunAtLoad}}/>
|
||||
<key>Disabled</key>
|
||||
<false/>
|
||||
|
||||
<key>StandardOutPath</key>
|
||||
<string>/usr/local/var/log/{{html .Name}}.out.log</string>
|
||||
<key>StandardErrorPath</key>
|
||||
<string>/usr/local/var/log/{{html .Name}}.err.log</string>
|
||||
|
||||
</dict>
|
||||
</plist>
|
||||
`
|
||||
|
|
|
@ -0,0 +1,308 @@
|
|||
// Copyright 2015 Daniel Theophanes.
|
||||
// Use of this source code is governed by a zlib-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package service
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/xml"
|
||||
"fmt"
|
||||
"os"
|
||||
"os/signal"
|
||||
"regexp"
|
||||
"syscall"
|
||||
"text/template"
|
||||
"time"
|
||||
)
|
||||
|
||||
const maxPathSize = 32 * 1024
|
||||
|
||||
const version = "solaris-smf"
|
||||
|
||||
type solarisSystem struct{}
|
||||
|
||||
func (solarisSystem) String() string {
|
||||
return version
|
||||
}
|
||||
func (solarisSystem) Detect() bool {
|
||||
return true
|
||||
}
|
||||
func (solarisSystem) Interactive() bool {
|
||||
return interactive
|
||||
}
|
||||
func (solarisSystem) New(i Interface, c *Config) (Service, error) {
|
||||
s := &solarisService{
|
||||
i: i,
|
||||
Config: c,
|
||||
|
||||
Prefix: c.Option.string(optionPrefix, optionPrefixDefault),
|
||||
}
|
||||
|
||||
return s, nil
|
||||
}
|
||||
|
||||
func init() {
|
||||
ChooseSystem(solarisSystem{})
|
||||
}
|
||||
|
||||
var interactive = false
|
||||
|
||||
func init() {
|
||||
var err error
|
||||
interactive, err = isInteractive()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
||||
func isInteractive() (bool, error) {
|
||||
// The PPid of a service process be 1 / init.
|
||||
return os.Getppid() != 1, nil
|
||||
}
|
||||
|
||||
type solarisService struct {
|
||||
i Interface
|
||||
*Config
|
||||
|
||||
Prefix string
|
||||
}
|
||||
|
||||
func (s *solarisService) String() string {
|
||||
if len(s.DisplayName) > 0 {
|
||||
return s.DisplayName
|
||||
}
|
||||
return s.Name
|
||||
}
|
||||
|
||||
func (s *solarisService) Platform() string {
|
||||
return version
|
||||
}
|
||||
|
||||
func (s *solarisService) template() *template.Template {
|
||||
functions := template.FuncMap{
|
||||
"bool": func(v bool) string {
|
||||
if v {
|
||||
return "true"
|
||||
}
|
||||
return "false"
|
||||
},
|
||||
}
|
||||
|
||||
customConfig := s.Option.string(optionSysvScript, "")
|
||||
|
||||
if customConfig != "" {
|
||||
return template.Must(template.New("").Funcs(functions).Parse(customConfig))
|
||||
} else {
|
||||
return template.Must(template.New("").Funcs(functions).Parse(manifest))
|
||||
}
|
||||
}
|
||||
|
||||
func (s *solarisService) configPath() (string, error) {
|
||||
return "/lib/svc/manifest/" + s.Prefix + "/" + s.Config.Name + ".xml", nil
|
||||
}
|
||||
|
||||
func (s *solarisService) getFMRI() string {
|
||||
return "svc:/" + s.Prefix + "/" + s.Config.Name + ":default"
|
||||
}
|
||||
|
||||
func (s *solarisService) Install() error {
|
||||
// write start script
|
||||
confPath, err := s.configPath()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
_, err = os.Stat(confPath)
|
||||
if err == nil {
|
||||
return fmt.Errorf("Manifest already exists: %s", confPath)
|
||||
}
|
||||
|
||||
f, err := os.Create(confPath)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer f.Close()
|
||||
|
||||
path, err := s.execPath()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
Display := ""
|
||||
escaped := &bytes.Buffer{}
|
||||
if err := xml.EscapeText(escaped, []byte(s.DisplayName)); err == nil {
|
||||
Display = escaped.String()
|
||||
}
|
||||
var to = &struct {
|
||||
*Config
|
||||
Prefix string
|
||||
Display string
|
||||
Path string
|
||||
}{
|
||||
s.Config,
|
||||
s.Prefix,
|
||||
Display,
|
||||
path,
|
||||
}
|
||||
|
||||
err = s.template().Execute(f, to)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// import service
|
||||
err = run("svcadm", "restart", "manifest-import" )
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *solarisService) Uninstall() error {
|
||||
s.Stop()
|
||||
|
||||
confPath, err := s.configPath()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = os.Remove(confPath)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// unregister service
|
||||
err = run("svcadm", "restart", "manifest-import" )
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *solarisService) Status() (Status, error) {
|
||||
fmri := s.getFMRI()
|
||||
exitCode, out, err := runWithOutput("svcs", fmri)
|
||||
if exitCode != 0 {
|
||||
return StatusUnknown, ErrNotInstalled
|
||||
}
|
||||
|
||||
re := regexp.MustCompile(`(degraded|disabled|legacy_run|maintenance|offline|online)\s+\w+` + fmri)
|
||||
matches := re.FindStringSubmatch(out)
|
||||
if len(matches) == 2 {
|
||||
status := string(matches[1])
|
||||
if status == "online" {
|
||||
return StatusRunning, nil
|
||||
} else {
|
||||
return StatusStopped, nil
|
||||
}
|
||||
}
|
||||
return StatusUnknown, err
|
||||
}
|
||||
|
||||
func (s *solarisService) Start() error {
|
||||
return run("/usr/sbin/svcadm", "enable", s.getFMRI())
|
||||
}
|
||||
func (s *solarisService) Stop() error {
|
||||
return run("/usr/sbin/svcadm", "disable", s.getFMRI())
|
||||
}
|
||||
func (s *solarisService) Restart() error {
|
||||
err := s.Stop()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
time.Sleep(50 * time.Millisecond)
|
||||
return s.Start()
|
||||
}
|
||||
|
||||
func (s *solarisService) Run() error {
|
||||
var err error
|
||||
|
||||
err = s.i.Start(s)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
s.Option.funcSingle(optionRunWait, func() {
|
||||
var sigChan = make(chan os.Signal, 3)
|
||||
signal.Notify(sigChan, syscall.SIGTERM, os.Interrupt)
|
||||
<-sigChan
|
||||
})()
|
||||
|
||||
return s.i.Stop(s)
|
||||
}
|
||||
|
||||
func (s *solarisService) Logger(errs chan<- error) (Logger, error) {
|
||||
if interactive {
|
||||
return ConsoleLogger, nil
|
||||
}
|
||||
return s.SystemLogger(errs)
|
||||
}
|
||||
func (s *solarisService) SystemLogger(errs chan<- error) (Logger, error) {
|
||||
return newSysLogger(s.Name, errs)
|
||||
}
|
||||
|
||||
var manifest = `<?xml version="1.0"?>
|
||||
<!DOCTYPE service_bundle SYSTEM "/usr/share/lib/xml/dtd/service_bundle.dtd.1">
|
||||
|
||||
<service_bundle type='manifest' name='golang-{{.Name}}'>
|
||||
<service
|
||||
name='{{.Prefix}}/{{.Name}}'
|
||||
type='service'
|
||||
version='1'>
|
||||
|
||||
<create_default_instance enabled='false' />
|
||||
|
||||
<single_instance />
|
||||
|
||||
<!--
|
||||
Wait for network interfaces to be initialized.
|
||||
-->
|
||||
<dependency name='network'
|
||||
grouping='require_all'
|
||||
restart_on='restart'
|
||||
type='service'>
|
||||
<service_fmri value='svc:/milestone/network:default'/>
|
||||
</dependency>
|
||||
|
||||
<!--
|
||||
Wait for all local filesystems to be mounted.
|
||||
-->
|
||||
<dependency name='filesystem-local'
|
||||
grouping='require_all'
|
||||
restart_on='none'
|
||||
type='service'>
|
||||
<service_fmri
|
||||
value='svc:/system/filesystem/local:default'/>
|
||||
</dependency>
|
||||
|
||||
<exec_method
|
||||
type='method'
|
||||
name='start'
|
||||
exec='bash -c {{.Path}} &'
|
||||
timeout_seconds='10' />
|
||||
|
||||
<exec_method
|
||||
type='method'
|
||||
name='stop'
|
||||
exec='pkill -TERM -f {{.Path}}'
|
||||
timeout_seconds='60' />
|
||||
|
||||
<!--
|
||||
<property_group name='startd' type='framework'>
|
||||
<propval name='duration' type='astring' value='transient' />
|
||||
</property_group>
|
||||
-->
|
||||
|
||||
<stability value='Unstable' />
|
||||
|
||||
<template>
|
||||
<common_name>
|
||||
<loctext xml:lang='C'>
|
||||
{{.Display}}
|
||||
</loctext>
|
||||
</common_name>
|
||||
</template>
|
||||
</service>
|
||||
|
||||
</service_bundle>
|
||||
`
|
|
@ -2,7 +2,7 @@
|
|||
// Use of this source code is governed by a zlib-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// +build linux darwin
|
||||
// +build linux darwin solaris aix
|
||||
|
||||
package service
|
||||
|
||||
|
|
|
@ -13,7 +13,6 @@ import (
|
|||
"strings"
|
||||
"syscall"
|
||||
"text/template"
|
||||
"time"
|
||||
)
|
||||
|
||||
func isUpstart() bool {
|
||||
|
@ -225,12 +224,7 @@ func (s *upstart) Stop() error {
|
|||
}
|
||||
|
||||
func (s *upstart) Restart() error {
|
||||
err := s.Stop()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
time.Sleep(50 * time.Millisecond)
|
||||
return s.Start()
|
||||
return run("initctl", "restart", s.Name)
|
||||
}
|
||||
|
||||
// The upstart script should stop with an INT or the Go runtime will terminate
|
||||
|
|
|
@ -6,7 +6,10 @@ github.com/VividCortex/ewma
|
|||
github.com/aead/chacha20/chacha
|
||||
# github.com/aead/poly1305 v0.0.0-20180717145839-3fee0db0b635
|
||||
github.com/aead/poly1305
|
||||
# github.com/coreos/go-systemd v0.0.0-20190719114852-fd7a80b32e1f
|
||||
# github.com/agl/ed25519 v0.0.0-20170116200512-5312a6153412
|
||||
github.com/agl/ed25519
|
||||
github.com/agl/ed25519/edwards25519
|
||||
# github.com/coreos/go-systemd v0.0.0-20191104093116-d3cd4ed1dbcf
|
||||
github.com/coreos/go-systemd/activation
|
||||
github.com/coreos/go-systemd/daemon
|
||||
# github.com/davecgh/go-spew v1.1.1
|
||||
|
@ -39,7 +42,7 @@ github.com/jedisct1/go-minisign
|
|||
github.com/jedisct1/xsecretbox
|
||||
# github.com/k-sone/critbitgo v1.4.0
|
||||
github.com/k-sone/critbitgo
|
||||
# github.com/kardianos/service v1.0.1-0.20191017145738-4df36c9fc1c6
|
||||
# github.com/kardianos/service v1.0.1-0.20191211031725-3c356ae54c8a
|
||||
github.com/kardianos/service
|
||||
# github.com/miekg/dns v1.1.25
|
||||
github.com/miekg/dns
|
||||
|
|
Loading…
Reference in New Issue