Skip to content

Commit 46a02cb

Browse files
authored
Merge pull request #70 from picostack/staging
v1.4.3
2 parents 82a8a02 + c1c7c9c commit 46a02cb

File tree

9 files changed

+150
-71
lines changed

9 files changed

+150
-71
lines changed

go.mod

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ require (
1515
github.com/hashicorp/vault/api v1.0.5-0.20200117231345-460d63e36490
1616
github.com/hashicorp/vault/sdk v0.1.14-0.20200121232954-73f411823aa0 // indirect
1717
github.com/joho/godotenv v1.3.0
18+
github.com/kelseyhightower/envconfig v1.4.0
1819
github.com/pierrec/lz4 v2.4.1+incompatible // indirect
1920
github.com/pkg/errors v0.9.1
2021
github.com/robertkrimen/otto v0.0.0-20191219234010-c382bd3c16ff

go.sum

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,8 @@ github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99/go.mod h1:1lJo3i
111111
github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI=
112112
github.com/joho/godotenv v1.3.0 h1:Zjp+RcGpHhGlrMbJzXTrZZPrWj+1vfm90La1wgB6Bhc=
113113
github.com/joho/godotenv v1.3.0/go.mod h1:7hK45KPybAkOC6peb+G5yklZfMxEjkZhHbwpqxOKXbg=
114+
github.com/kelseyhightower/envconfig v1.4.0 h1:Im6hONhd3pLkfDFsbRgu68RDNkGF1r3dvMUtDTo2cv8=
115+
github.com/kelseyhightower/envconfig v1.4.0/go.mod h1:cccZRl6mQpaq41TPp5QxidR+Sa3axMbJDNb//FQX6Gg=
114116
github.com/kevinburke/ssh_config v0.0.0-20190725054713-01f96b0aa0cd h1:Coekwdh0v2wtGp9Gmz1Ze3eVRAWJMLokvN3QjdzCHLY=
115117
github.com/kevinburke/ssh_config v0.0.0-20190725054713-01f96b0aa0cd/go.mod h1:CT57kijsi8u/K/BOFA39wgDQJ9CxiF4nAY/ojJ6r6mM=
116118
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=

logger/logger.go

Lines changed: 44 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,32 +1,68 @@
11
package logger
22

33
import (
4+
"fmt"
45
"os"
5-
"strconv"
66
"strings"
77

8+
"github.com/joho/godotenv"
9+
"github.com/kelseyhightower/envconfig"
10+
"github.com/pkg/errors"
811
"go.uber.org/zap"
912
"go.uber.org/zap/zapcore"
1013
)
1114

15+
type Env string
16+
17+
type cfg struct {
18+
Environment Env `envconfig:"ENVIRONMENT" default:"production"`
19+
LogLevel zapcore.Level `envconfig:"LOG_LEVEL" default:"info"`
20+
}
21+
22+
const (
23+
EnvironmentProd Env = "production"
24+
EnvironmentDev Env = "development"
25+
)
26+
27+
func (e *Env) UnmarshalText(text []byte) error {
28+
switch strings.ToLower(string(text)) {
29+
case string(EnvironmentProd):
30+
*e = EnvironmentProd
31+
case string(EnvironmentDev):
32+
*e = EnvironmentDev
33+
default:
34+
return errors.Errorf("unknown environment type: '%s'", string(text))
35+
}
36+
return nil
37+
}
38+
1239
func init() {
13-
// constructs a logger and replaces the default global logger
40+
godotenv.Load("../.env", ".env") //nolint:errcheck
41+
42+
var c cfg
43+
envconfig.MustProcess("", &c)
44+
1445
var config zap.Config
15-
if d, e := strconv.ParseBool(os.Getenv("DEVELOPMENT")); d && e == nil || isInTests() {
46+
if c.Environment == EnvironmentDev || isInTests() {
1647
config = zap.NewDevelopmentConfig()
1748
} else {
1849
config = zap.NewProductionConfig()
1950
}
51+
52+
config.Level.SetLevel(c.LogLevel)
2053
config.EncoderConfig.EncodeTime = zapcore.ISO8601TimeEncoder
21-
config.DisableStacktrace = true
22-
if d, e := strconv.ParseBool(os.Getenv("DEBUG")); d && e == nil || isInTests() {
23-
config.Level = zap.NewAtomicLevelAt(zap.DebugLevel)
24-
}
54+
2555
logger, err := config.Build()
2656
if err != nil {
27-
panic(err)
57+
fmt.Println("Error during logging config:", err)
58+
os.Exit(1)
2859
}
2960
zap.ReplaceGlobals(logger)
61+
62+
zap.L().Info("logger configured",
63+
zap.String("level", c.LogLevel.String()),
64+
zap.String("env", string(c.Environment)))
65+
3066
}
3167

3268
func isInTests() bool {

main.go

Lines changed: 29 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,12 @@ package main
22

33
import (
44
"context"
5-
"log"
5+
"fmt"
66
"os"
77
"os/signal"
8+
"regexp"
89
"runtime"
10+
"strings"
911
"time"
1012

1113
_ "github.com/joho/godotenv/autoload"
@@ -57,7 +59,7 @@ this repository has new commits, Pico will automatically reconfigure.`,
5759
Action: func(c *cli.Context) (err error) {
5860
if !c.Args().Present() {
5961
cli.ShowCommandHelp(c, "run")
60-
return errors.New("missing argument: target")
62+
return errors.New("missing argument: configuration repository URL")
6163
}
6264

6365
ctx, cancel := context.WithCancel(context.Background())
@@ -72,9 +74,7 @@ this repository has new commits, Pico will automatically reconfigure.`,
7274
}
7375
}
7476

75-
zap.L().Debug("initialising service")
76-
77-
svc, err := service.Initialise(service.Config{
77+
cfg := service.Config{
7878
Target: task.Repo{
7979
URL: c.Args().First(),
8080
User: c.String("git-username"),
@@ -90,7 +90,11 @@ this repository has new commits, Pico will automatically reconfigure.`,
9090
VaultPath: c.String("vault-path"),
9191
VaultRenewal: c.Duration("vault-renew-interval"),
9292
VaultConfig: c.String("vault-config-path"),
93-
})
93+
}
94+
95+
zap.L().Debug("initialising service", zap.Any("config", cfg))
96+
97+
svc, err := service.Initialise(cfg)
9498
if err != nil {
9599
return errors.Wrap(err, "failed to initialise")
96100
}
@@ -111,26 +115,32 @@ this repository has new commits, Pico will automatically reconfigure.`,
111115
case err = <-errs:
112116
}
113117

118+
if strings.ToLower(os.Getenv("LOG_LEVEL")) == "debug" {
119+
doTrace()
120+
}
121+
114122
return
115123
},
116124
},
117125
}
118126

119-
if os.Getenv("DEBUG") != "" {
120-
go func() {
121-
sigs := make(chan os.Signal, 1)
122-
signal.Notify(sigs, os.Interrupt)
123-
buf := make([]byte, 1<<20)
124-
for {
125-
<-sigs
126-
stacklen := runtime.Stack(buf, true)
127-
log.Printf("\nPrinting goroutine stack trace because `DEBUG` was set.\n%s\n", buf[:stacklen])
128-
}
129-
}()
130-
}
131-
132127
err := app.Run(os.Args)
133128
if err != nil {
134129
zap.L().Fatal("exit", zap.Error(err))
135130
}
136131
}
132+
133+
var waitpoints = regexp.MustCompile(`__waitpoint__(.+)\(`)
134+
135+
func doTrace() {
136+
buf := make([]byte, 1<<20)
137+
stacklen := runtime.Stack(buf, true)
138+
139+
fmt.Printf("\nPrinting goroutine stack trace because `DEBUG` was set.\n%s\n", buf[:stacklen])
140+
fmt.Println("Code that was waiting:")
141+
142+
for _, s := range waitpoints.FindAllStringSubmatch(string(buf[:stacklen]), 1) {
143+
fmt.Printf(" - %s\n", s[1])
144+
}
145+
fmt.Println("\nSee the docs on https://pico.sh/ for more information.")
146+
}

reconfigurer/git.go

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -126,13 +126,18 @@ func (p *GitProvider) watchConfig() (err error) {
126126
}()
127127
zap.L().Debug("created new config watcher, awaiting setup")
128128

129+
err = p.__waitpoint__watch_config(errs)
130+
131+
zap.L().Debug("config watcher initialised")
132+
133+
return
134+
}
135+
136+
func (p *GitProvider) __waitpoint__watch_config(errs chan error) (err error) {
129137
select {
130138
case <-p.configWatcher.InitialDone:
131139
case err = <-errs:
132140
}
133-
134-
zap.L().Debug("config watcher initialised")
135-
136141
return
137142
}
138143

secret/vault/vault.go

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@ func (v *VaultSecrets) GetSecretsForTarget(name string) (map[string]string, erro
8787
}
8888

8989
zap.L().Debug("found secrets in vault",
90-
zap.Any("secret", secret))
90+
zap.Strings("secret", keys(env)))
9191

9292
return env, nil
9393
}
@@ -152,6 +152,13 @@ func kvToMap(version int, data map[string]interface{}) (env map[string]string, e
152152
return
153153
}
154154

155+
func keys(m map[string]string) (k []string) {
156+
for x := range m {
157+
k = append(k, x)
158+
}
159+
return
160+
}
161+
155162
// because Vault has no way to know if a kv engine is v1 or v2, we have to check
156163
// for the /config path and if it doesn't exist, attempt to LIST the path, if
157164
// that succeeds, it's a v1, if it doesn't succeed, it *might still* be a v1 but

service/service.go

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ type Config struct {
3232
PassEnvironment bool
3333
CheckInterval time.Duration
3434
VaultAddress string
35-
VaultToken string
35+
VaultToken string `json:"-"`
3636
VaultPath string
3737
VaultRenewal time.Duration
3838
VaultConfig string
@@ -63,7 +63,7 @@ func Initialise(c Config) (app *App, err error) {
6363

6464
secretStore, err = vault.New(c.VaultAddress, c.VaultPath, c.VaultToken, c.VaultRenewal)
6565
if err != nil {
66-
return nil, err
66+
return nil, errors.Wrap(err, "failed to create vault secret store")
6767
}
6868
} else {
6969
secretStore = &memory.MemorySecrets{
@@ -118,16 +118,25 @@ func (app *App) Start(ctx context.Context) error {
118118

119119
gw := app.watcher.(*watcher.GitWatcher)
120120
go func() {
121-
errs <- errors.Wrap(gw.Start(), "git watcher terminated fatally")
121+
errs <- errors.Wrap(
122+
gw.Start(),
123+
"git watcher crashed",
124+
)
122125
}()
123126

124127
go func() {
125-
errs <- errors.Wrap(app.reconfigurer.Configure(app.watcher), "git watcher terminated fatally")
128+
errs <- errors.Wrap(
129+
app.reconfigurer.Configure(app.watcher),
130+
"reconfigure provider crashed",
131+
)
126132
}()
127133

128134
if s, ok := app.secrets.(*vault.VaultSecrets); ok {
129135
go func() {
130-
errs <- errors.Wrap(retrier.New(retrier.ConstantBackoff(3, 100*time.Millisecond), nil).RunCtx(ctx, s.Renew), "git watcher terminated fatally")
136+
errs <- errors.Wrap(
137+
retrier.New(retrier.ConstantBackoff(3, 100*time.Millisecond), nil).RunCtx(ctx, s.Renew),
138+
"vault token renewal job failed",
139+
)
131140
}()
132141
}
133142

task/target.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ type ExecutionTask struct {
2020
type Repo struct {
2121
URL string
2222
User string
23-
Pass string
23+
Pass string `json:"-"`
2424
}
2525

2626
// Targets is just a list of target objects, to implement the Sort interface

0 commit comments

Comments
 (0)