Skip to content

Commit

Permalink
Deprecate --v2-deprecation and schedule to remove it in 3.8
Browse files Browse the repository at this point in the history
Signed-off-by: Benjamin Wang <[email protected]>
  • Loading branch information
ahrtr committed Dec 4, 2024
1 parent 084d872 commit f54c8f5
Show file tree
Hide file tree
Showing 5 changed files with 80 additions and 24 deletions.
4 changes: 3 additions & 1 deletion server/embed/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -459,7 +459,9 @@ type Config struct {
// ExperimentalStopGRPCServiceOnDefrag enables etcd gRPC service to stop serving client requests on defragmentation.
ExperimentalStopGRPCServiceOnDefrag bool `json:"experimental-stop-grpc-service-on-defrag"`

// V2Deprecation describes phase of API & Storage V2 support
// V2Deprecation describes phase of API & Storage V2 support.
// Deprecated and scheduled for removal in v3.8.
// Do not set this field for embedded use cases, as it has no effect. However, setting it will not cause any harm.
V2Deprecation config.V2DeprecationEnum `json:"v2-deprecation"`

// ServerFeatureGate is a server level feature gate
Expand Down
2 changes: 2 additions & 0 deletions server/embed/etcd.go
Original file line number Diff line number Diff line change
Expand Up @@ -376,6 +376,8 @@ func print(lg *zap.Logger, ec Config, sc config.ServerConfig, memberInitialized

zap.String("downgrade-check-interval", sc.DowngradeCheckTime.String()),
zap.Int("max-learners", sc.ExperimentalMaxLearners),

zap.String("v2-deprecation", string(ec.V2Deprecation)),
)
}

Expand Down
16 changes: 9 additions & 7 deletions server/etcdmain/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ var (
deprecatedFlags = map[string]string{
// TODO: remove in 3.7.
"snapshot-count": "--snapshot-count is deprecated in 3.6 and will be decommissioned in 3.7.",
"v2-deprecation": "--v2-deprecation is deprecated and scheduled for removal in v3.8. The default value is enforced, ignoring user input.",
}
)

Expand All @@ -74,9 +75,11 @@ type config struct {

// configFlags has the set of flags used for command line parsing a Config
type configFlags struct {
flagSet *flag.FlagSet
clusterState *flags.SelectiveStringValue
fallback *flags.SelectiveStringValue
flagSet *flag.FlagSet
clusterState *flags.SelectiveStringValue
fallback *flags.SelectiveStringValue
// Deprecated and scheduled for removal in v3.8. The default value is enforced, ignoring user input.
// TODO: remove in v3.8.
v2deprecation *flags.SelectiveStringsValue
}

Expand Down Expand Up @@ -108,7 +111,7 @@ func newConfig() *config {
fs.StringVar(&cfg.configFile, "config-file", "", "Path to the server configuration file. Note that if a configuration file is provided, other command line flags and environment variables will be ignored.")
fs.Var(cfg.cf.fallback, "discovery-fallback", fmt.Sprintf("Valid values include %q", cfg.cf.fallback.Valids()))
fs.Var(cfg.cf.clusterState, "initial-cluster-state", "Initial cluster state ('new' when bootstrapping a new cluster or 'existing' when adding new members to an existing cluster). After successful initialization (bootstrapping or adding), flag is ignored on restarts.")
fs.Var(cfg.cf.v2deprecation, "v2-deprecation", fmt.Sprintf("v2store deprecation stage: %q. ", cfg.cf.v2deprecation.Valids()))
fs.Var(cfg.cf.v2deprecation, "v2-deprecation", fmt.Sprintf("v2store deprecation stage: %q. Deprecated and scheduled for removal in v3.8. The default value is enforced, ignoring user input.", cfg.cf.v2deprecation.Valids()))

fs.BoolVar(&cfg.printVersion, "version", false, "Print the version and exit.")
// ignored
Expand Down Expand Up @@ -161,9 +164,8 @@ func (cfg *config) parse(arguments []string) error {
err = cfg.configFromCmdLine()
}

if cfg.ec.V2Deprecation == "" {
cfg.ec.V2Deprecation = cconfig.V2DeprDefault
}
// `V2Deprecation` (--v2-deprecation) is deprecated and scheduled for removal in v3.8. The default value is enforced, ignoring user input.
cfg.ec.V2Deprecation = cconfig.V2DeprDefault

cfg.ec.WarningUnaryRequestDuration, perr = cfg.parseWarningUnaryRequestDuration()
if perr != nil {
Expand Down
8 changes: 4 additions & 4 deletions server/etcdmain/help.go
Original file line number Diff line number Diff line change
Expand Up @@ -169,12 +169,12 @@ Clustering:
--auto-compaction-mode 'periodic'
Interpret 'auto-compaction-retention' one of: periodic|revision. 'periodic' for duration based retention, defaulting to hours if no time unit is provided (e.g. '5m'). 'revision' for revision number based retention.
--v2-deprecation '` + string(cconfig.V2DeprDefault) + `'
Phase of v2store deprecation. Allows to opt-in for higher compatibility mode.
Phase of v2store deprecation. Deprecated and scheduled for removal in v3.8. The default value is enforced, ignoring user input.
Supported values:
'not-yet' // Issues a warning if v2store have meaningful content (default in v3.5)
'write-only' // Custom v2 state is not allowed (planned default in v3.6)
'write-only-drop-data' // Custom v2 state will get DELETED !
'gone' // v2store is not maintained any longer. (planned default in v3.7)
'write-only' // Custom v2 state is not allowed (default in v3.6)
'write-only-drop-data' // Custom v2 state will get DELETED ! (planned default in v3.7)
'gone' // v2store is not maintained any longer. (planned to cleanup anything related to v2store in v3.8)
Security:
--cert-file ''
Expand Down
74 changes: 62 additions & 12 deletions tests/e2e/etcd_config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -666,17 +666,67 @@ func TestEtcdTLSVersion(t *testing.T) {
func TestEtcdDeprecatedFlags(t *testing.T) {
e2e.SkipInShortMode(t)

proc, err := e2e.SpawnCmd(
[]string{
e2e.BinPath.Etcd,
"--name", "e1",
"--snapshot-count=100",
}, nil,
)
require.NoError(t, err)
require.NoError(t, e2e.WaitReadyExpectProc(context.TODO(), proc, []string{"--snapshot-count is deprecated in 3.6 and will be decommissioned in 3.7"}))
require.NoError(t, proc.Stop())
commonArgs := []string{
e2e.BinPath.Etcd,
"--name", "e1",
}

proc.Wait() // ensure the port has been released
proc.Close()
testCases := []struct {
name string
args []string
expectedMsg string
}{
{
name: "snapshot-count",
args: append(commonArgs, "--snapshot-count=100"),
expectedMsg: "--snapshot-count is deprecated in 3.6 and will be decommissioned in 3.7",
},
{
name: "v2-deprecation",
args: append(commonArgs, "--v2-deprecation", "write-only-drop-data"),
expectedMsg: "--v2-deprecation is deprecated and scheduled for removal in v3.8. The default value is enforced, ignoring user input",
},
}

for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
proc, err := e2e.SpawnCmd(
tc.args, nil,
)
require.NoError(t, err)
require.NoError(t, e2e.WaitReadyExpectProc(context.TODO(), proc, []string{tc.expectedMsg}))
require.NoError(t, proc.Stop())

proc.Wait() // ensure the port has been released
proc.Close()
})
}
}

// TestV2DeprecationEnforceDefaultValue verifies that etcd enforces the default V2Deprecation level
// and ignores users input.
func TestV2DeprecationEnforceDefaultValue(t *testing.T) {
e2e.SkipInShortMode(t)

commonArgs := []string{
e2e.BinPath.Etcd,
"--name", "e1",
}

validV2DeprecationLevels := []string{"write-only", "write-only-drop-data", "gone"}
expectedDeprecationLevelMsg := `"v2-deprecation":"write-only"`

for _, optionLevel := range validV2DeprecationLevels {
t.Run(optionLevel, func(t *testing.T) {
proc, err := e2e.SpawnCmd(
append(commonArgs, "--v2-deprecation", optionLevel), nil,
)
require.NoError(t, err)
require.NoError(t, e2e.WaitReadyExpectProc(context.TODO(), proc, []string{expectedDeprecationLevelMsg}))
require.NoError(t, proc.Stop())

proc.Wait() // ensure the port has been released
proc.Close()
})
}
}

0 comments on commit f54c8f5

Please sign in to comment.