Skip to content

Commit 2445d8b

Browse files
author
Roberto Sora
committed
Add repertory to store installation id and secret
1 parent bb971a7 commit 2445d8b

File tree

8 files changed

+81
-45
lines changed

8 files changed

+81
-45
lines changed

cli/cli.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ package cli
1717

1818
import (
1919
"fmt"
20+
"github.com/arduino/arduino-cli/repertory"
2021
"io/ioutil"
2122
"os"
2223
"path/filepath"
@@ -167,6 +168,9 @@ func preRun(cmd *cobra.Command, args []string) {
167168
configuration.Init(configPath)
168169
configFile := viper.ConfigFileUsed()
169170

171+
// initialize repertory
172+
repertory.Init()
173+
170174
//
171175
// Prepare logging
172176
//

cli/daemon/daemon.go

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ package daemon
1818
import (
1919
"errors"
2020
"fmt"
21+
"github.com/segmentio/stats/v4"
2122
"io"
2223
"io/ioutil"
2324
"net"
@@ -62,8 +63,8 @@ var daemonize bool
6263
func runDaemonCommand(cmd *cobra.Command, args []string) {
6364

6465
if viper.GetBool("telemetry.enabled") {
65-
telemetry.Activate("daemon", viper.GetString("installation.id"))
66-
defer telemetry.Engine.Flush()
66+
telemetry.Activate("daemon")
67+
defer stats.Flush()
6768
}
6869

6970
port := viper.GetString("daemon.port")
@@ -102,7 +103,7 @@ func runDaemonCommand(cmd *cobra.Command, args []string) {
102103
// Stdin is closed when the controlling parent process ends
103104
_, _ = io.Copy(ioutil.Discard, os.Stdin)
104105
if viper.GetBool("telemetry.enabled") {
105-
telemetry.Engine.Flush()
106+
stats.Flush()
106107
}
107108
os.Exit(0)
108109
}()

commands/board/list.go

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@ package board
1818
import (
1919
"encoding/json"
2020
"fmt"
21-
"github.com/arduino/arduino-cli/telemetry"
2221
"github.com/segmentio/stats/v4"
2322
"io/ioutil"
2423
"net/http"
@@ -108,13 +107,13 @@ func List(instanceID int32) ([]*rpc.DetectedPort, error) {
108107

109108
pm := commands.GetPackageManager(instanceID)
110109
if pm == nil {
111-
telemetry.Engine.Incr("board.list", stats.T("success", "false"))
110+
stats.Incr("board.list", stats.T("success", "false"))
112111
return nil, errors.New("invalid instance")
113112
}
114113

115114
ports, err := commands.ListBoards(pm)
116115
if err != nil {
117-
telemetry.Engine.Incr("board.list", stats.T("success", "false"))
116+
stats.Incr("board.list", stats.T("success", "false"))
118117
return nil, errors.Wrap(err, "error getting port list from serial-discovery")
119118
}
120119

@@ -140,7 +139,7 @@ func List(instanceID int32) ([]*rpc.DetectedPort, error) {
140139
logrus.Debug("Board not recognized")
141140
} else if err != nil {
142141
// this is bad, bail out
143-
telemetry.Engine.Incr("board.list", stats.T("success", "false"))
142+
stats.Incr("board.list", stats.T("success", "false"))
144143
return nil, errors.Wrap(err, "error getting board info from Arduino Cloud")
145144
}
146145

@@ -161,6 +160,6 @@ func List(instanceID int32) ([]*rpc.DetectedPort, error) {
161160
retVal = append(retVal, p)
162161
}
163162

164-
telemetry.Engine.Incr("board.list", stats.T("success", "true"))
163+
stats.Incr("board.list", stats.T("success", "true"))
165164
return retVal, nil
166165
}

commands/compile/compile.go

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -63,19 +63,19 @@ func Compile(ctx context.Context, req *rpc.CompileReq, outStream, errStream io.W
6363

6464
pm := commands.GetPackageManager(req.GetInstance().GetId())
6565
if pm == nil {
66-
telemetry.Engine.Incr("compile", stats.M(tags)...)
66+
stats.Incr("compile", stats.M(tags)...)
6767
return nil, errors.New("invalid instance")
6868
}
6969

7070
logrus.Tracef("Compile %s for %s started", req.GetSketchPath(), req.GetFqbn())
7171
if req.GetSketchPath() == "" {
72-
telemetry.Engine.Incr("compile", stats.M(tags)...)
72+
stats.Incr("compile", stats.M(tags)...)
7373
return nil, fmt.Errorf("missing sketchPath")
7474
}
7575
sketchPath := paths.New(req.GetSketchPath())
7676
sketch, err := sketches.NewSketchFromPath(sketchPath)
7777
if err != nil {
78-
telemetry.Engine.Incr("compile", stats.M(tags)...)
78+
stats.Incr("compile", stats.M(tags)...)
7979
return nil, fmt.Errorf("opening sketch: %s", err)
8080
}
8181

@@ -84,12 +84,12 @@ func Compile(ctx context.Context, req *rpc.CompileReq, outStream, errStream io.W
8484
fqbnIn = sketch.Metadata.CPU.Fqbn
8585
}
8686
if fqbnIn == "" {
87-
telemetry.Engine.Incr("compile", stats.M(tags)...)
87+
stats.Incr("compile", stats.M(tags)...)
8888
return nil, fmt.Errorf("no FQBN provided")
8989
}
9090
fqbn, err := cores.ParseFQBN(fqbnIn)
9191
if err != nil {
92-
telemetry.Engine.Incr("compile", stats.M(tags)...)
92+
stats.Incr("compile", stats.M(tags)...)
9393
return nil, fmt.Errorf("incorrect FQBN: %s", err)
9494
}
9595

@@ -103,7 +103,7 @@ func Compile(ctx context.Context, req *rpc.CompileReq, outStream, errStream io.W
103103
// "\"%[1]s:%[2]s\" platform is not installed, please install it by running \""+
104104
// version.GetAppName()+" core install %[1]s:%[2]s\".", fqbn.Package, fqbn.PlatformArch)
105105
// feedback.Error(errorMessage)
106-
telemetry.Engine.Incr("compile", stats.M(tags)...)
106+
stats.Incr("compile", stats.M(tags)...)
107107
return nil, fmt.Errorf("platform not installed")
108108
}
109109

@@ -123,7 +123,7 @@ func Compile(ctx context.Context, req *rpc.CompileReq, outStream, errStream io.W
123123
builderCtx.BuildPath = paths.New(req.GetBuildPath())
124124
err = builderCtx.BuildPath.MkdirAll()
125125
if err != nil {
126-
telemetry.Engine.Incr("compile", stats.M(tags)...)
126+
stats.Incr("compile", stats.M(tags)...)
127127
return nil, fmt.Errorf("cannot create build directory: %s", err)
128128
}
129129
}
@@ -152,7 +152,7 @@ func Compile(ctx context.Context, req *rpc.CompileReq, outStream, errStream io.W
152152
builderCtx.BuildCachePath = paths.New(req.GetBuildCachePath())
153153
err = builderCtx.BuildCachePath.MkdirAll()
154154
if err != nil {
155-
telemetry.Engine.Incr("compile", stats.M(tags)...)
155+
stats.Incr("compile", stats.M(tags)...)
156156
return nil, fmt.Errorf("cannot create build cache directory: %s", err)
157157
}
158158
}
@@ -186,17 +186,17 @@ func Compile(ctx context.Context, req *rpc.CompileReq, outStream, errStream io.W
186186
// if --preprocess or --show-properties were passed, we can stop here
187187
if req.GetShowProperties() {
188188
tags["success"] = "true"
189-
telemetry.Engine.Incr("compile", stats.M(tags)...)
189+
stats.Incr("compile", stats.M(tags)...)
190190
return &rpc.CompileResp{}, builder.RunParseHardwareAndDumpBuildProperties(builderCtx)
191191
} else if req.GetPreprocess() {
192192
tags["success"] = "true"
193-
telemetry.Engine.Incr("compile", stats.M(tags)...)
193+
stats.Incr("compile", stats.M(tags)...)
194194
return &rpc.CompileResp{}, builder.RunPreprocess(builderCtx)
195195
}
196196

197197
// if it's a regular build, go on...
198198
if err := builder.RunBuilder(builderCtx); err != nil {
199-
telemetry.Engine.Incr("compile", stats.M(tags)...)
199+
stats.Incr("compile", stats.M(tags)...)
200200
return nil, err
201201
}
202202

@@ -232,7 +232,7 @@ func Compile(ctx context.Context, req *rpc.CompileReq, outStream, errStream io.W
232232
// Copy "sketch.ino.*.hex" / "sketch.ino.*.bin" artifacts to sketch directory
233233
srcDir, err := outputPath.Parent().ReadDir() // read "/build/path/*"
234234
if err != nil {
235-
telemetry.Engine.Incr("compile", stats.M(tags)...)
235+
stats.Incr("compile", stats.M(tags)...)
236236
return nil, fmt.Errorf("reading build directory: %s", err)
237237
}
238238
srcDir.FilterPrefix(base + ".")
@@ -243,7 +243,7 @@ func Compile(ctx context.Context, req *rpc.CompileReq, outStream, errStream io.W
243243
dstOutput := exportPath.Join(exportFile + srcFilename)
244244
logrus.WithField("from", srcOutput).WithField("to", dstOutput).Debug("copying sketch build output")
245245
if err = srcOutput.CopyTo(dstOutput); err != nil {
246-
telemetry.Engine.Incr("compile", stats.M(tags)...)
246+
stats.Incr("compile", stats.M(tags)...)
247247
return nil, fmt.Errorf("copying output file: %s", err)
248248
}
249249
}
@@ -254,13 +254,13 @@ func Compile(ctx context.Context, req *rpc.CompileReq, outStream, errStream io.W
254254
dstElf := exportPath.Join(exportFile + ".elf")
255255
logrus.WithField("from", srcElf).WithField("to", dstElf).Debug("copying sketch build output")
256256
if err = srcElf.CopyTo(dstElf); err != nil {
257-
telemetry.Engine.Incr("compile", stats.M(tags)...)
257+
stats.Incr("compile", stats.M(tags)...)
258258
return nil, fmt.Errorf("copying elf file: %s", err)
259259
}
260260
}
261261

262262
logrus.Tracef("Compile %s for %s successful", sketch.Name, fqbnIn)
263263
tags["success"] = "true"
264-
telemetry.Engine.Incr("compile", stats.M(tags)...)
264+
stats.Incr("compile", stats.M(tags)...)
265265
return &rpc.CompileResp{}, nil
266266
}

configuration/configuration.go

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ func Init(configPath string) {
3838

3939
// Get default data path if none was provided
4040
if configPath == "" {
41-
configPath = getDefaultArduinoDataDir()
41+
configPath = GetDefaultArduinoDataDir()
4242
}
4343

4444
// Add paths where to search for a config file
@@ -58,7 +58,7 @@ func Init(configPath string) {
5858
// those were set through env vars or cli flags
5959
dataDir := viper.GetString("directories.Data")
6060
if dataDir == "" {
61-
dataDir = getDefaultArduinoDataDir()
61+
dataDir = GetDefaultArduinoDataDir()
6262
}
6363
userDir := viper.GetString("directories.User")
6464
if userDir == "" {
@@ -76,10 +76,11 @@ func Init(configPath string) {
7676
feedback.Errorf("Error reading config file: %v", err)
7777
}
7878
}
79+
7980
}
8081

81-
// getDefaultArduinoDataDir returns the full path to the default arduino folder
82-
func getDefaultArduinoDataDir() string {
82+
// GetDefaultArduinoDataDir returns the full path to the default arduino folder
83+
func GetDefaultArduinoDataDir() string {
8384
userHomeDir, err := os.UserHomeDir()
8485
if err != nil {
8586
feedback.Errorf("Unable to get user home dir: %v", err)

configuration/defaults.go

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@ package configuration
1818
import (
1919
"path/filepath"
2020

21-
"github.com/gofrs/uuid"
2221
"github.com/spf13/viper"
2322
)
2423

@@ -42,11 +41,4 @@ func setDefaults(dataDir, userDir string) {
4241
viper.SetDefault("telemetry.addr", ":2112")
4342
viper.SetDefault("telemetry.pattern", "/metrics")
4443

45-
//Installation ID
46-
// FIXME: how should I treat this error?
47-
installationID, _ := uuid.NewV4()
48-
installationSecret, _ := uuid.NewV4()
49-
viper.SetDefault("installation.id", installationID.String())
50-
viper.SetDefault("installation.secret", installationSecret.String())
51-
5244
}

repertory/repertory.go

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
package repertory
2+
3+
import (
4+
"github.com/arduino/arduino-cli/cli/feedback"
5+
"github.com/arduino/arduino-cli/configuration"
6+
"github.com/gofrs/uuid"
7+
"github.com/spf13/viper"
8+
"os"
9+
)
10+
11+
// Store is the Read Only config storage
12+
var Store = viper.New()
13+
14+
// Configure configures the Read Only config storage
15+
func Init() {
16+
configPath := configuration.GetDefaultArduinoDataDir()
17+
Store.SetConfigType("yaml")
18+
Store.SetConfigName("repertory.yaml")
19+
Store.AddConfigPath(configPath)
20+
// Attempt to read config file
21+
if err := Store.ReadInConfig(); err != nil {
22+
// ConfigFileNotFoundError is acceptable, anything else
23+
// should be reported to the user
24+
if _, ok := err.(viper.ConfigFileNotFoundError); ok {
25+
// FIXME: how should I treat this error?
26+
installationID, _ := uuid.NewV4()
27+
Store.SetDefault("installation.id", installationID.String())
28+
installationSecret, _ := uuid.NewV4()
29+
Store.SetDefault("installation.secret", installationSecret.String())
30+
if err = Store.SafeWriteConfigAs(configPath); err != nil {
31+
if os.IsNotExist(err) {
32+
err = Store.WriteConfigAs(configPath)
33+
}
34+
}
35+
} else {
36+
feedback.Errorf("Error reading repertory file: %v", err)
37+
38+
}
39+
}
40+
}

telemetry/telemetry.go

Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import (
44
"crypto/hmac"
55
"crypto/sha256"
66
"encoding/hex"
7+
"github.com/arduino/arduino-cli/repertory"
78
"net/http"
89
"path/filepath"
910

@@ -13,19 +14,16 @@ import (
1314
"github.com/spf13/viper"
1415
)
1516

16-
// Engine is the engine used by global helper functions for this module.
17-
var Engine = stats.DefaultEngine
18-
19-
// Activate configure and starts the telemetry server exposing a Prometheus resource
20-
func Activate(metricPrefix, installationID string) {
21-
// Configure telemetry engine
17+
// Activate configures and starts the telemetry server exposing a Prometheus resource
18+
func Activate(metricPrefix string) {
2219
// Create a Prometheus default handler
2320
ph := prometheus.DefaultHandler
2421
// Create a new stats engine with an engine that prepends the "daemon" prefix to all metrics
25-
// and includes the installationID as a tag
26-
Engine = stats.WithPrefix(metricPrefix, stats.T("installationID", installationID))
22+
// and includes the installationID as a tag, then replace the default stats engine
23+
stats.DefaultEngine = stats.WithPrefix(metricPrefix, stats.T("installationID",
24+
repertory.Store.GetString("installation.id")))
2725
// Register the handler so it receives metrics from the default engine.
28-
Engine.Register(ph)
26+
stats.Register(ph)
2927

3028
// Configure using viper settings
3129
serverAddr := viper.GetString("telemetry.addr")
@@ -41,7 +39,8 @@ func Activate(metricPrefix, installationID string) {
4139
// SanitizeSketchPath uses config generated UUID (installation.secret) as an HMAC secret to sanitize and anonymize the sketch
4240
// name maintaining it distinguishable from a different sketch from the same Installation
4341
func SanitizeSketchPath(sketchPath string) string {
44-
installationSecret := viper.GetString("installation.secret")
42+
logrus.Infof("repertory.Store.ConfigFileUsed() %s", repertory.Store.ConfigFileUsed())
43+
installationSecret := repertory.Store.GetString("installation.secret")
4544
sketchName := filepath.Base(sketchPath)
4645
// Create a new HMAC by defining the hash type and the key (as byte array)
4746
h := hmac.New(sha256.New, []byte(installationSecret))

0 commit comments

Comments
 (0)