Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Do not support SIGUSR1 and SIGUSR2 syscall handling in windows #970

Merged
merged 6 commits into from
Sep 23, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ endif
CTIMEVAR=-X $(NOTARY_PKG)/version.GitCommit=$(GITCOMMIT) -X $(NOTARY_PKG)/version.NotaryVersion=$(NOTARY_VERSION)
GO_LDFLAGS=-ldflags "-w $(CTIMEVAR)"
GO_LDFLAGS_STATIC=-ldflags "-w $(CTIMEVAR) -extldflags -static"
GOOSES = darwin linux
GOOSES = darwin linux windows
NOTARY_BUILDTAGS ?= pkcs11
NOTARYDIR := /go/src/github.com/docker/notary

Expand Down
1 change: 1 addition & 0 deletions buildscripts/circle_parallelism.sh
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ case $CIRCLE_NODE_INDEX in
;;
2) SKIPENVCHECK=1 make TESTDB=mysql testdb
SKIPENVCHECK=1 make TESTDB=mysql integration
SKIPENVCHECK=1 make cross # just trying not to exceed 5 builders
;;
3) SKIPENVCHECK=1 make TESTDB=rethink testdb
SKIPENVCHECK=1 make TESTDB=rethink integration
Expand Down
2 changes: 1 addition & 1 deletion buildscripts/covertest.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ def get_coverprofile_filename(pkg, buildtags):
buildtags = "." + buildtags.replace(' ', '.')
return pkg.replace('/', '-').replace(' ', '_') + buildtags + ".coverage.txt"

def run_test_with_coverage(buildtags="", coverdir=".cover", pkgs=None, opts="", covermode="count"):
def run_test_with_coverage(buildtags="", coverdir=".cover", pkgs=None, opts="", covermode="atomic"):
"""
Run go test with coverage over the the given packages, with the following options
"""
Expand Down
24 changes: 15 additions & 9 deletions buildscripts/cross.sh
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,10 @@

GOARCH="amd64"

if [[ "${NOTARY_BUILDTAGS}" == *pkcs11* ]]; then
export CGO_ENABLED=1
else
export CGO_ENABLED=0
fi


for os in "$@"; do
export GOOS="${os}"
BUILDTAGS="${NOTARY_BUILDTAGS}"
OUTFILE=notary

if [[ "${GOOS}" == "darwin" ]]; then
export CC="o64-clang"
Expand All @@ -24,18 +19,29 @@ for os in "$@"; do
# darwin binaries can't be compiled to be completely static with the -static flag
LDFLAGS="-s"
else
# no building with Cgo. Also no building with pkcs11
if [[ "${GOOS}" == "windows" ]]; then
BUILDTAGS=
OUTFILE=notary.exe
fi
unset CC
unset CXX
LDFLAGS="-extldflags -static"
fi

if [[ "${BUILDTAGS}" == *pkcs11* ]]; then
export CGO_ENABLED=1
else
export CGO_ENABLED=0
fi

mkdir -p "${NOTARYDIR}/cross/${GOOS}/${GOARCH}";

set -x;
go build \
-o "${NOTARYDIR}/cross/${GOOS}/${GOARCH}/notary" \
-o "${NOTARYDIR}/cross/${GOOS}/${GOARCH}/${OUTFILE}" \
-a \
-tags "${NOTARY_BUILDTAGS}" \
-tags "${BUILDTAGS}" \
-ldflags "-w ${CTIMEVAR} ${LDFLAGS}" \
./cmd/notary;
set +x;
Expand Down
31 changes: 0 additions & 31 deletions cmd/notary-server/config.go
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
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
5 changes: 3 additions & 2 deletions cmd/notary/main_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (
"net/http/httptest"
"os"
"path/filepath"
"strconv"
"strings"
"testing"
"time"
Expand Down Expand Up @@ -343,10 +344,10 @@ func TestConfigFileTLSCanBeRelativeToConfigOrAbsolute(t *testing.T) {
"remote_server": {
"url": "%s",
"root_ca": "root-ca.crt",
"tls_client_cert": "%s",
"tls_client_cert": %s,
"tls_client_key": "notary-server.key"
}
}`, s.URL, filepath.Join(tempDir, "notary-server.crt"))
}`, s.URL, strconv.Quote(filepath.Join(tempDir, "notary-server.crt")))
configFile.Close()

// copy the certs to be relative to the config directory
Expand Down
14 changes: 1 addition & 13 deletions const.go
Original file line number Diff line number Diff line change
@@ -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
Original file line number Diff line number Diff line change
@@ -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
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
// +build windows
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fine with leaving it in for explicit-ness but for my own understanding, we don't technically need it when using the *_windows.go filename right?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yep, not needed. I just like having the labels since we also have a nowindows that matches against everything else.


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
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
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 {
Copy link
Contributor

@riyazdf riyazdf Sep 22, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

non-blocking-nit: can we test this case with some mocking? I'm fine with assigning this const to empty for the test and deferring to return it back to its original value, to mock what Windows would do

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍 I was actually going to see if I could try to set up CI for windows (not sure if we want to do it in this PR) so that we can get coverage numbers for it, in which case this should be tested. I'll follow up on this later today and if it proves to be a ton of work I'll stub out the const instead. :)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, I think we can probably set this up. In case it goes horribly badly and doesn't work, I've added a mocking test for this in a commit we can revert once we have the CI set up.

return nil

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

return c
}
Loading