Skip to content

Commit

Permalink
Do not support SIGUSR1 and SIGUSR2 syscall handling in windows
Browse files Browse the repository at this point in the history
Signed-off-by: Ying Li <ying.li@docker.com>
  • Loading branch information
cyli committed Sep 22, 2016
1 parent 3b5c8ad commit eb87d5c
Show file tree
Hide file tree
Showing 14 changed files with 196 additions and 76 deletions.
31 changes: 0 additions & 31 deletions cmd/notary-server/config.go
Expand Up @@ -3,12 +3,9 @@ package main
import (
"crypto/tls"
"fmt"
"os"
"os/signal"
"path"
"strconv"
"strings"
"syscall"
"time"

"github.com/Sirupsen/logrus"
Expand Down Expand Up @@ -293,31 +290,3 @@ func parseServerConfig(configFilePath string, hRegister healthRegister, doBootst
ConsistentCacheControlConfig: consistentCache,
}, nil
}

func setupSignalTrap() {
c := make(chan os.Signal, 1)
signal.Notify(c, notary.NotarySupportedSignals...)
go func() {
for {
signalHandle(<-c)
}
}()
}

// signalHandle will increase/decrease the logging level via the signal we get.
func signalHandle(sig os.Signal) {
switch sig {
case syscall.SIGUSR1:
if err := utils.AdjustLogLevel(true); err != nil {
fmt.Printf("Attempt to increase log level failed, will remain at %s level, error: %s\n", logrus.GetLevel(), err)
return
}
case syscall.SIGUSR2:
if err := utils.AdjustLogLevel(false); err != nil {
fmt.Printf("Attempt to decrease log level failed, will remain at %s level, error: %s\n", logrus.GetLevel(), err)
return
}
}

fmt.Println("Successfully setting log level to ", logrus.GetLevel())
}
7 changes: 6 additions & 1 deletion cmd/notary-server/main.go
Expand Up @@ -7,10 +7,12 @@ import (
"net/http"
_ "net/http/pprof"
"os"
"os/signal"

"github.com/Sirupsen/logrus"
"github.com/docker/distribution/health"
"github.com/docker/notary/server"
"github.com/docker/notary/utils"
"github.com/docker/notary/version"
)

Expand Down Expand Up @@ -61,7 +63,10 @@ func main() {
logrus.Fatal(err.Error())
}

setupSignalTrap()
c := utils.SetupSignalTrap(utils.LogLevelSignalHandle)
if c != nil {
defer signal.Stop(c)
}

if flagStorage.doBootstrap {
err = bootstrap(ctx)
Expand Down
30 changes: 0 additions & 30 deletions cmd/notary-server/main_test.go
Expand Up @@ -6,14 +6,11 @@ import (
"fmt"
"io/ioutil"
"os"
"path/filepath"
"reflect"
"strings"
"syscall"
"testing"
"time"

"github.com/Sirupsen/logrus"
"github.com/docker/distribution/health"
"github.com/docker/notary"
"github.com/docker/notary/server/storage"
Expand Down Expand Up @@ -416,30 +413,3 @@ func TestSampleConfig(t *testing.T) {
// once for the DB, once for the trust service
require.Equal(t, registerCalled, 2)
}

func TestSignalHandle(t *testing.T) {
tempdir, err := ioutil.TempDir("", "test-signal-handle")
require.NoError(t, err)
defer os.RemoveAll(tempdir)
f, err := os.Create(filepath.Join(tempdir, "testSignalHandle.json"))
require.NoError(t, err)

f.WriteString(`{"logging": {"level": "info"}}`)

v := viper.New()
utils.SetupViper(v, "envPrefix")
err = utils.ParseViper(v, f.Name())
require.NoError(t, err)

// Info + SIGUSR1 -> Debug
signalHandle(syscall.SIGUSR1)
require.Equal(t, logrus.GetLevel(), logrus.DebugLevel)

// Debug + SIGUSR1 -> Debug
signalHandle(syscall.SIGUSR1)
require.Equal(t, logrus.GetLevel(), logrus.DebugLevel)

// Debug + SIGUSR2-> Info
signalHandle(syscall.SIGUSR2)
require.Equal(t, logrus.GetLevel(), logrus.InfoLevel)
}
7 changes: 7 additions & 0 deletions cmd/notary-signer/main.go
Expand Up @@ -6,8 +6,10 @@ import (
"log"
"net/http"
"os"
"os/signal"

"github.com/Sirupsen/logrus"
"github.com/docker/notary/utils"
"github.com/docker/notary/version"
_ "github.com/go-sql-driver/mysql"
)
Expand Down Expand Up @@ -66,6 +68,11 @@ func main() {
log.Println("RPC server listening on", signerConfig.GRPCAddr)
}

c := utils.SetupSignalTrap(utils.LogLevelSignalHandle)
if c != nil {
defer signal.Stop(c)
}

grpcServer.Serve(lis)
}

Expand Down
14 changes: 1 addition & 13 deletions const.go
@@ -1,10 +1,6 @@
package notary

import (
"os"
"syscall"
"time"
)
import "time"

// application wide constants
const (
Expand Down Expand Up @@ -72,11 +68,3 @@ var NotaryDefaultExpiries = map[string]time.Duration{
"snapshot": NotarySnapshotExpiry,
"timestamp": NotaryTimestampExpiry,
}

// NotarySupportedSignals contains the signals we would like to capture:
// - SIGUSR1, indicates a increment of the log level.
// - SIGUSR2, indicates a decrement of the log level.
var NotarySupportedSignals = []os.Signal{
syscall.SIGUSR1,
syscall.SIGUSR2,
}
16 changes: 16 additions & 0 deletions const_nowindows.go
@@ -0,0 +1,16 @@
// +build !windows

package notary

import (
"os"
"syscall"
)

// NotarySupportedSignals contains the signals we would like to capture:
// - SIGUSR1, indicates a increment of the log level.
// - SIGUSR2, indicates a decrement of the log level.
var NotarySupportedSignals = []os.Signal{
syscall.SIGUSR1,
syscall.SIGUSR2,
}
8 changes: 8 additions & 0 deletions const_windows.go
@@ -0,0 +1,8 @@
// +build windows

package notary

import "os"

// NotarySupportedSignals does not contain any signals, because SIGUSR1/2 are not supported on windows
var NotarySupportedSignals = []os.Signal{}
4 changes: 3 additions & 1 deletion docs/reference/server-config.md
Expand Up @@ -362,10 +362,12 @@ Example:
</table>

## Hot logging level reload
We don't support completely reloading notary configuration files yet at present. What we support for now is:
We don't support completely reloading notary configuration files yet at present. What we support for Linux and OSX now is:
- increase logging level by signaling `SIGUSR1`
- decrease logging level by signaling `SIGUSR2`

No signals and no dynamic logging level changes are supported for Windows yet.

Example:

To increase logging level
Expand Down
38 changes: 38 additions & 0 deletions docs/reference/signer-config.md
Expand Up @@ -210,6 +210,44 @@ The environment variables for the older passwords are optional, but Notary
Signer will not be able to decrypt older keys if they are not provided, and
attempts to sign data using those keys will fail.

## Hot logging level reload
We don't support completely reloading notary signer configuration files yet at present. What we support for Linux and OSX now is:
- increase logging level by signaling `SIGUSR1`
- decrease logging level by signaling `SIGUSR2`

No signals and no dynamic logging level changes are supported for Windows yet.

Example:

To increase logging level
```
$ kill -s SIGUSR1 PID
or
$ docker exec -i CONTAINER_ID kill -s SIGUSR1 PID
```

To decrease logging level
```
$ kill -s SIGUSR2 PID
or
$ docker exec -i CONTAINER_ID kill -s SIGUSR2 PID
```
PID is the process id of `notary-signer` and it may not the PID 1 process if you are running
the container with some kind of wrapper startup script or something.

You can get the PID of `notary-signer` through
```
$ docker exec CONTAINER_ID ps aux
or
$ ps aux | grep "notary-signer -config" | grep -v "grep"
```


## Related information

Expand Down
19 changes: 19 additions & 0 deletions utils/configuration.go
Expand Up @@ -5,6 +5,8 @@ package utils
import (
"crypto/tls"
"fmt"
"os"
"os/signal"
"path/filepath"
"strings"

Expand Down Expand Up @@ -244,3 +246,20 @@ func AdjustLogLevel(increment bool) error {
logrus.SetLevel(lvl)
return nil
}

// SetupSignalTrap is a utility to trap supported signals hand handle them (currently by increasing logging)
func SetupSignalTrap(handler func(os.Signal)) chan os.Signal {
if len(notary.NotarySupportedSignals) == 0 {
return nil

}
c := make(chan os.Signal, 1)
signal.Notify(c, notary.NotarySupportedSignals...)
go func() {
for {
handler(<-c)
}
}()

return c
}
29 changes: 29 additions & 0 deletions utils/configuration_nowindows.go
@@ -0,0 +1,29 @@
// +build !windows

package utils

import (
"fmt"
"os"
"syscall"

"github.com/Sirupsen/logrus"
)

// LogLevelSignalHandle will increase/decrease the logging level via the signal we get.
func LogLevelSignalHandle(sig os.Signal) {
switch sig {
case syscall.SIGUSR1:
if err := AdjustLogLevel(true); err != nil {
fmt.Printf("Attempt to increase log level failed, will remain at %s level, error: %s\n", logrus.GetLevel(), err)
return
}
case syscall.SIGUSR2:
if err := AdjustLogLevel(false); err != nil {
fmt.Printf("Attempt to decrease log level failed, will remain at %s level, error: %s\n", logrus.GetLevel(), err)
return
}
}

fmt.Println("Successfully setting log level to ", logrus.GetLevel())
}
33 changes: 33 additions & 0 deletions utils/configuration_nowindows_test.go
@@ -0,0 +1,33 @@
// +build !windows

package utils

import (
"io/ioutil"
"os"
"syscall"
"testing"

"github.com/Sirupsen/logrus"
"github.com/stretchr/testify/require"
)

func TestLogLevelSignalHandle(t *testing.T) {
tempdir, err := ioutil.TempDir("", "test-signal-handle")
require.NoError(t, err)
defer os.RemoveAll(tempdir)

logrus.SetLevel(logrus.InfoLevel)

// Info + SIGUSR1 -> Debug
LogLevelSignalHandle(syscall.SIGUSR1)
require.Equal(t, logrus.GetLevel(), logrus.DebugLevel)

// Debug + SIGUSR1 -> Debug
LogLevelSignalHandle(syscall.SIGUSR1)
require.Equal(t, logrus.GetLevel(), logrus.DebugLevel)

// Debug + SIGUSR2-> Info
LogLevelSignalHandle(syscall.SIGUSR2)
require.Equal(t, logrus.GetLevel(), logrus.InfoLevel)
}
27 changes: 27 additions & 0 deletions utils/configuration_test.go
Expand Up @@ -6,8 +6,10 @@ import (
"fmt"
"io/ioutil"
"os"
"os/signal"
"path/filepath"
"reflect"
"syscall"
"testing"

"github.com/Sirupsen/logrus"
Expand Down Expand Up @@ -560,3 +562,28 @@ func TestAdjustLogLevel(t *testing.T) {
err = AdjustLogLevel(optDecrement)
require.Error(t, err)
}

func TestSetSignalTrap(t *testing.T) {
var signalsPassedOn map[string]struct{}

signalHandler := func(s os.Signal) {
signalsPassedOn := make(map[string]struct{})
signalsPassedOn[s.String()] = struct{}{}
}
c := SetupSignalTrap(signalHandler)

if len(notary.NotarySupportedSignals) == 0 { // currently, windows only
require.Nil(t, c)
} else {
require.NotNil(t, c)
defer signal.Stop(c)
}

for _, s := range notary.NotarySupportedSignals {
syscallSignal, ok := s.(syscall.Signal)
require.True(t, ok)
require.NoError(t, syscall.Kill(syscall.Getpid(), syscallSignal))
require.Len(t, signalsPassedOn, 0)
require.NotNil(t, signalsPassedOn[s.String()])
}
}
9 changes: 9 additions & 0 deletions utils/configuration_windows.go
@@ -0,0 +1,9 @@
// +build windows

package utils

import "os"

// LogLevelSignalHandle will do nothing, because we aren't currently supporting signal handling in windows
func LogLevelSignalHandle(sig os.Signal) {
}

0 comments on commit eb87d5c

Please sign in to comment.