Skip to content

Commit

Permalink
Merge pull request #364 from SkycoinProject/feature/versioned-config-…
Browse files Browse the repository at this point in the history
…#362

Versioned visor configs.
  • Loading branch information
jdknives authored May 21, 2020
2 parents 6c4c0d5 + a7a056c commit 1505b8b
Show file tree
Hide file tree
Showing 36 changed files with 1,159 additions and 810 deletions.
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ install-generate: ## Installs required execs for go generate.
# git config --global url.git@github.com:.insteadOf https://github.com/
# Source: https://stackoverflow.com/questions/27500861/whats-the-proper-way-to-go-get-a-private-repository
# We are using 'go get' instead of 'go install' here, because we don't have a git tag in which 'readmegen' is already implemented.
${OPTS} go get -u github.com/SkycoinPro/skywire-services/cmd/readmegen@master
${OPTS} go get -u github.com/SkycoinPro/skywire-services/cmd/readmegen

generate: ## Generate mocks and config README's
go generate ./...
Expand Down
3 changes: 3 additions & 0 deletions ci_scripts/install-golangci-lint.sh
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@ if [[ "$VERSION" != "latest" ]]; then
VERSION="v$VERSION"
fi

if [[ -z "${GOBIN}" ]]; then export GOBIN=$HOME/go/bin; fi
echo "GOBIN=${GOBIN}"

# In alpine linux (as it does not come with curl by default)
wget -O - -q https://install.goreleaser.com/github.com/golangci/golangci-lint.sh | sh -s -- -b "${GOBIN}" "${VERSION}"

Expand Down
2 changes: 1 addition & 1 deletion cmd/apps/skychat/static.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion cmd/hypervisor/statik/statik.go

Large diffs are not rendered by default.

112 changes: 63 additions & 49 deletions cmd/skywire-cli/commands/visor/gen-config.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,90 +2,104 @@ package visor

import (
"encoding/json"
"fmt"
"io/ioutil"
"path"
"os"
"path/filepath"

"github.com/SkycoinProject/skycoin/src/util/logging"
"github.com/sirupsen/logrus"

"github.com/SkycoinProject/skywire-mainnet/pkg/visor/visorconfig"

"github.com/SkycoinProject/dmsg/cipher"
"github.com/spf13/cobra"

"github.com/SkycoinProject/skywire-mainnet/pkg/util/pathutil"
"github.com/SkycoinProject/skywire-mainnet/pkg/visor"
)

func init() {
RootCmd.AddCommand(genConfigCmd)
}

var (
sk cipher.SecKey
output string
replace bool
retainKeys bool
configLocType = pathutil.WorkingDirLoc
testenv bool
sk cipher.SecKey
output string
replace bool
testEnv bool
)

func init() {
genConfigCmd.Flags().VarP(&sk, "secret-key", "s", "if unspecified, a random key pair will be generated.")
genConfigCmd.Flags().StringVarP(&output, "output", "o", "", "path of output config file. Uses default of 'type' flag if unspecified.")
genConfigCmd.Flags().BoolVarP(&replace, "replace", "r", false, "whether to allow rewrite of a file that already exists.")
genConfigCmd.Flags().BoolVar(&retainKeys, "retain-keys", false, "retain current keys")
genConfigCmd.Flags().BoolVarP(&testenv, "testing-environment", "t", false, "whether to use production or test deployment service.")

// TODO(evanlinjin): Re-implement this at a later stage.
//genConfigCmd.Flags().VarP(&configLocType, "type", "m", fmt.Sprintf("config generation mode. Valid values: %v", pathutil.AllConfigLocationTypes()))
genConfigCmd.Flags().Var(&sk, "sk", "if unspecified, a random key pair will be generated.")
genConfigCmd.Flags().StringVarP(&output, "output", "o", "skywire-config.json", "path of output config file.")
genConfigCmd.Flags().BoolVarP(&replace, "replace", "r", false, "whether to allow rewrite of a file that already exists (this retains the keys).")
genConfigCmd.Flags().BoolVarP(&testEnv, "testenv", "t", false, "whether to use production or test deployment service.")
}

var genConfigCmd = &cobra.Command{
Use: "gen-config",
Short: "Generates a config file",
PreRun: func(_ *cobra.Command, _ []string) {
if output == "" {
output = pathutil.VisorDefaults().Get(configLocType)
logger.Infof("No 'output' set; using default path: %s", output)
}
var err error
if output, err = filepath.Abs(output); err != nil {
logger.WithError(err).Fatalln("invalid output provided")
logger.WithError(err).Fatal("Invalid output provided.")
}
},
Run: func(_ *cobra.Command, _ []string) {
var conf *visor.Config

// TODO(evanlinjin): Decide whether we still need this feature in the future.
// https://github.com/SkycoinProject/skywire-mainnet/pull/360#discussion_r425080223
switch configLocType {
case pathutil.WorkingDirLoc:
var err error
if conf, err = visor.DefaultConfig(nil, output, visor.NewKeyPair()); err != nil {
logger.WithError(err).Fatal("Failed to create default config.")
}
default:
logger.Fatalln("invalid config type:", configLocType)
mLog := logging.NewMasterLogger()
mLog.SetLevel(logrus.InfoLevel)

// Read in old config (if any) and obtain old secret key.
// Otherwise, we generate a new random secret key.
var sk cipher.SecKey
if oldConf, ok := readOldConfig(mLog, output, replace); !ok {
_, sk = cipher.GenerateKeyPair()
} else {
sk = oldConf.SK
}

// Determine config type to generate.
var genConf func(log *logging.MasterLogger, confPath string, sk *cipher.SecKey) (*visorconfig.V1, error)
if testEnv {
genConf = visorconfig.MakeTestConfig
} else {
genConf = visorconfig.MakeDefaultConfig
}
if replace && retainKeys && pathutil.Exists(output) {
if err := fillInOldKeys(output, conf); err != nil {
logger.WithError(err).Fatalln("Error retaining old keys")
}

// Generate config.
conf, err := genConf(mLog, output, &sk)
if err != nil {
logger.WithError(err).Fatal("Failed to create config.")
}
pathutil.WriteJSONConfig(conf, output, replace)

// Save config to file.
if err := conf.Flush(); err != nil {
logger.WithError(err).Fatal("Failed to flush config to file.")
}

// Print results.
j, err := json.MarshalIndent(conf, "", "\t")
if err != nil {
logger.WithError(err).Fatal("An unexpected error occurred. Please contact a developer.")
}
logger.Infof("Updated file '%s' to: %s", output, j)
},
}

func fillInOldKeys(confPath string, conf *visor.Config) error {
oldConfBytes, err := ioutil.ReadFile(path.Clean(confPath))
func readOldConfig(log *logging.MasterLogger, confPath string, replace bool) (*visorconfig.V1, bool) {
raw, err := ioutil.ReadFile(confPath) //nolint:gosec
if err != nil {
return fmt.Errorf("error reading old config file: %w", err)
if os.IsNotExist(err) {
return nil, false
}
logger.WithError(err).Fatal("Unexpected error occurred when attempting to read old config.")
}

var oldConf visor.Config
if err := json.Unmarshal(oldConfBytes, &oldConf); err != nil {
return fmt.Errorf("invalid old configuration file: %w", err)
if !replace {
logger.Fatal("Config file already exists. Specify the 'replace,r' flag to replace this.")
}

conf.KeyPair = oldConf.KeyPair
conf, err := visorconfig.Parse(log, confPath, raw)
if err != nil {
logger.WithError(err).Fatal("Failed to parse old config file.")
}

return nil
return conf, true
}
Loading

0 comments on commit 1505b8b

Please sign in to comment.