mirror of
https://github.com/ipfs/kubo.git
synced 2025-06-30 09:59:13 +08:00
feat: add dry-run flag for config profile apply command
License: MIT Signed-off-by: chenminjian <727180553@qq.com>
This commit is contained in:

committed by
Steven Allen

parent
dcecab6854
commit
2e3cbe3e27
@ -16,10 +16,17 @@ import (
|
||||
repo "github.com/ipfs/go-ipfs/repo"
|
||||
fsrepo "github.com/ipfs/go-ipfs/repo/fsrepo"
|
||||
|
||||
"gx/ipfs/QmP2i47tnU23ijdshrZtuvrSkQPtf9HhsMb9fwGVe8owj2/jsondiff"
|
||||
config "gx/ipfs/QmSoYrBMibm2T3LupaLuez7LPGnyrJwdRxvTfPUyCp691u/go-ipfs-config"
|
||||
"gx/ipfs/Qmde5VP1qUkyQXKCfmEUA7bP64V2HAptbJ7phuPp7jXWwg/go-ipfs-cmdkit"
|
||||
)
|
||||
|
||||
// ConfigUpdateOutput is config profile apply command's output
|
||||
type ConfigUpdateOutput struct {
|
||||
Old config.Config
|
||||
New config.Config
|
||||
}
|
||||
|
||||
type ConfigField struct {
|
||||
Key string
|
||||
Value interface{}
|
||||
@ -333,6 +340,9 @@ var configProfileApplyCmd = &cmds.Command{
|
||||
Helptext: cmdkit.HelpText{
|
||||
Tagline: "Apply profile to config.",
|
||||
},
|
||||
Options: []cmdkit.Option{
|
||||
cmdkit.BoolOption("dry-run", "print difference between the current config and the config that would be generated"),
|
||||
},
|
||||
Arguments: []cmdkit.Argument{
|
||||
cmdkit.StringArg("profile", true, false, "The profile to apply to the config."),
|
||||
},
|
||||
@ -343,13 +353,40 @@ var configProfileApplyCmd = &cmds.Command{
|
||||
return
|
||||
}
|
||||
|
||||
err := transformConfig(req.InvocContext().ConfigRoot, req.Arguments()[0], profile.Transform)
|
||||
dryRun, _, _ := req.Option("dry-run").Bool()
|
||||
oldCfg, newCfg, err := transformConfig(req.InvocContext().ConfigRoot, req.Arguments()[0], profile.Transform, dryRun)
|
||||
if err != nil {
|
||||
res.SetError(err, cmdkit.ErrNormal)
|
||||
return
|
||||
}
|
||||
res.SetOutput(nil)
|
||||
res.SetOutput(&ConfigUpdateOutput{
|
||||
Old: *oldCfg,
|
||||
New: *newCfg,
|
||||
})
|
||||
},
|
||||
Marshalers: cmds.MarshalerMap{
|
||||
cmds.Text: func(res cmds.Response) (io.Reader, error) {
|
||||
if res.Error() != nil {
|
||||
return nil, res.Error()
|
||||
}
|
||||
|
||||
v, err := unwrapOutput(res.Output())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
apply, ok := v.(*ConfigUpdateOutput)
|
||||
if !ok {
|
||||
return nil, e.TypeErr(apply, v)
|
||||
}
|
||||
|
||||
diff := jsondiff.Compare(apply.Old, apply.New)
|
||||
buf := jsondiff.Format(diff)
|
||||
|
||||
return strings.NewReader(string(buf)), nil
|
||||
},
|
||||
},
|
||||
Type: ConfigUpdateOutput{},
|
||||
}
|
||||
|
||||
func buildProfileHelp() string {
|
||||
@ -367,29 +404,44 @@ func buildProfileHelp() string {
|
||||
return out
|
||||
}
|
||||
|
||||
func transformConfig(configRoot string, configName string, transformer config.Transformer) error {
|
||||
// transformConfig returns old config and new config instead of difference between they,
|
||||
// because apply command can provide stable API through this way.
|
||||
// If dryRun is true, repo's config should not be updated and persisted
|
||||
// to storage. Otherwise, repo's config should be updated and persisted
|
||||
// to storage.
|
||||
func transformConfig(configRoot string, configName string, transformer config.Transformer, dryRun bool) (*config.Config, *config.Config, error) {
|
||||
r, err := fsrepo.Open(configRoot)
|
||||
if err != nil {
|
||||
return err
|
||||
return nil, nil, err
|
||||
}
|
||||
defer r.Close()
|
||||
|
||||
cfg, err := r.Config()
|
||||
if err != nil {
|
||||
return err
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
err = transformer(cfg)
|
||||
// make a copy to avoid updating repo's config unintentionally
|
||||
oldCfg := *cfg
|
||||
newCfg := oldCfg
|
||||
err = transformer(&newCfg)
|
||||
if err != nil {
|
||||
return err
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
_, err = r.BackupConfig("pre-" + configName + "-")
|
||||
if err != nil {
|
||||
return err
|
||||
if !dryRun {
|
||||
_, err = r.BackupConfig("pre-" + configName + "-")
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
err = r.SetConfig(&newCfg)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
}
|
||||
|
||||
return r.SetConfig(cfg)
|
||||
return &oldCfg, &newCfg, nil
|
||||
}
|
||||
|
||||
func getConfig(r repo.Repo, key string) (*ConfigField, error) {
|
||||
|
@ -552,6 +552,12 @@
|
||||
"name": "go-multiaddr-dns",
|
||||
"version": "0.2.4"
|
||||
},
|
||||
{
|
||||
"author": "elgris",
|
||||
"hash": "QmP2i47tnU23ijdshrZtuvrSkQPtf9HhsMb9fwGVe8owj2",
|
||||
"name": "jsondiff",
|
||||
"version": "0.0.0"
|
||||
},
|
||||
{
|
||||
"author": "marten-seemann",
|
||||
"hash": "QmNtLLJMc7TDMSaNuJVFipxLji9NL56QyMnBBPk2X58Mno",
|
||||
|
@ -75,6 +75,17 @@ test_profile_apply_revert() {
|
||||
'
|
||||
}
|
||||
|
||||
test_profile_apply_dry_run_not_alter() {
|
||||
profile=$1
|
||||
|
||||
test_expect_success "'ipfs config profile apply ${profile} --dry-run' doesn't alter config" '
|
||||
cat "$IPFS_PATH/config" >expected &&
|
||||
ipfs config profile apply '${profile}' --dry-run &&
|
||||
cat "$IPFS_PATH/config" >actual &&
|
||||
test_cmp expected actual
|
||||
'
|
||||
}
|
||||
|
||||
test_config_cmd() {
|
||||
test_config_cmd_set "beep" "boop"
|
||||
test_config_cmd_set "beep1" "boop2"
|
||||
@ -220,6 +231,37 @@ test_config_cmd() {
|
||||
# need to do this in reverse as the test profile is already applied in sharness
|
||||
test_profile_apply_revert default-networking test
|
||||
|
||||
test_profile_apply_dry_run_not_alter server
|
||||
|
||||
test_profile_apply_dry_run_not_alter local-discovery
|
||||
|
||||
test_profile_apply_dry_run_not_alter test
|
||||
|
||||
test_expect_success "'ipfs config profile apply local-discovery --dry-run' looks good with different profile info" '
|
||||
ipfs config profile apply local-discovery --dry-run > diff_info &&
|
||||
test `grep "DisableNatPortMap" diff_info | wc -l` = 2
|
||||
'
|
||||
|
||||
test_expect_success "'ipfs config profile apply server --dry-run' looks good with same profile info" '
|
||||
ipfs config profile apply server --dry-run > diff_info &&
|
||||
test `grep "DisableNatPortMap" diff_info | wc -l` = 1
|
||||
'
|
||||
|
||||
test_expect_success "'ipfs config profile apply server' looks good with same profile info" '
|
||||
ipfs config profile apply server > diff_info &&
|
||||
test `grep "DisableNatPortMap" diff_info | wc -l` = 1
|
||||
'
|
||||
|
||||
test_expect_success "'ipfs config profile apply local-discovery' looks good with different profile info" '
|
||||
ipfs config profile apply local-discovery > diff_info &&
|
||||
test `grep "DisableNatPortMap" diff_info | wc -l` = 2
|
||||
'
|
||||
|
||||
test_expect_success "'ipfs config profile apply test' looks good with different profile info" '
|
||||
ipfs config profile apply test > diff_info &&
|
||||
test `grep "DisableNatPortMap" diff_info | wc -l` = 2
|
||||
'
|
||||
|
||||
# won't work as it changes datastore definition, which makes ipfs not launch
|
||||
# without converting first
|
||||
# test_profile_apply_revert badgerds
|
||||
|
Reference in New Issue
Block a user