Merge pull request #18183 from ah8ad3/etcdctl-doc

Add examples to `etcdctl snapshot` command's help
This commit is contained in:
James Blair 2024-08-05 16:34:56 +12:00 committed by GitHub
commit bb6ce7865a
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 96 additions and 15 deletions

View File

@ -23,14 +23,37 @@ import (
"go.etcd.io/etcd/client/pkg/v3/logutil" "go.etcd.io/etcd/client/pkg/v3/logutil"
snapshot "go.etcd.io/etcd/client/v3/snapshot" snapshot "go.etcd.io/etcd/client/v3/snapshot"
"go.etcd.io/etcd/etcdctl/v3/util"
"go.etcd.io/etcd/pkg/v3/cobrautl" "go.etcd.io/etcd/pkg/v3/cobrautl"
) )
var (
snapshotExample = util.Normalize(`
# Save snapshot to a given file
etcdctl snapshot save /backup/etcd-snapshot.db
# Get snapshot from given address and save it to file
etcdctl snapshot save --endpoints=127.0.0.1:3000 /backup/etcd-snapshot.db
# Get snapshot from given address with certificates
etcdctl --endpoints=https://127.0.0.1:2379 --cacert=/etc/etcd/ca.crt --cert=/etc/etcd/etcd.crt --key=/etc/etcd/etcd.key snapshot save /backup/etcd-snapshot.db
# Get snapshot wih certain user and password
etcdctl --user=root --password=password123 snapshot save /backup/etcd-snapshot.db
# Get snapshot from given address with timeout
etcdctl --endpoints=https://127.0.0.1:2379 --dial-timeout=20s snapshot save /backup/etcd-snapshot.db
# Save snapshot with desirable time format
etcdctl snapshot save /mnt/backup/etcd/backup_$(date +%Y%m%d_%H%M%S).db`)
)
// NewSnapshotCommand returns the cobra command for "snapshot". // NewSnapshotCommand returns the cobra command for "snapshot".
func NewSnapshotCommand() *cobra.Command { func NewSnapshotCommand() *cobra.Command {
cmd := &cobra.Command{ cmd := &cobra.Command{
Use: "snapshot <subcommand>", Use: "snapshot <subcommand>",
Short: "Manages etcd node snapshots", Short: "Manages etcd node snapshots",
Example: snapshotExample,
} }
cmd.AddCommand(NewSnapshotSaveCommand()) cmd.AddCommand(NewSnapshotSaveCommand())
return cmd return cmd
@ -41,12 +64,13 @@ func NewSnapshotSaveCommand() *cobra.Command {
Use: "save <filename>", Use: "save <filename>",
Short: "Stores an etcd node backend snapshot to a given file", Short: "Stores an etcd node backend snapshot to a given file",
Run: snapshotSaveCommandFunc, Run: snapshotSaveCommandFunc,
Example: snapshotExample,
} }
} }
func snapshotSaveCommandFunc(cmd *cobra.Command, args []string) { func snapshotSaveCommandFunc(cmd *cobra.Command, args []string) {
if len(args) != 1 { if len(args) != 1 {
err := fmt.Errorf("snapshot save expects one argument") err := fmt.Errorf("snapshot save expects one argument <filename>")
cobrautl.ExitWithError(cobrautl.ExitBadArgs, err) cobrautl.ExitWithError(cobrautl.ExitBadArgs, err)
} }

View File

@ -0,0 +1,49 @@
// Copyright 2024 The etcd Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package util
import "strings"
const indentation = " "
// Normalize normalizes a string:
// 1. trim the leading and trailing space
// 2. add an indentation before each line
func Normalize(s string) string {
if len(s) == 0 {
return s
}
return normalizer{s}.trim().indent().string
}
type normalizer struct {
string
}
func (n normalizer) trim() normalizer {
n.string = strings.TrimSpace(n.string)
return n
}
func (n normalizer) indent() normalizer {
indentedLines := []string{}
for _, line := range strings.Split(n.string, "\n") {
trimmed := strings.TrimSpace(line)
indented := indentation + trimmed
indentedLines = append(indentedLines, indented)
}
n.string = strings.Join(indentedLines, "\n")
return n
}

View File

@ -43,6 +43,10 @@ var (
} }
return strings.Join(parts, " ") return strings.Join(parts, " ")
}, },
"indent": func(s string) string {
pad := strings.Repeat(" ", 2)
return pad + strings.Replace(s, "\n", "\n"+pad, -1)
},
} }
) )
@ -52,38 +56,42 @@ func init() {
{{ $cmdname := cmdName .Cmd .Cmd.Root }}\ {{ $cmdname := cmdName .Cmd .Cmd.Root }}\
NAME: NAME:
{{if not .Cmd.HasParent}}\ {{if not .Cmd.HasParent}}\
{{printf "\t%s - %s" .Cmd.Name .Cmd.Short}} {{printf "%s - %s" .Cmd.Name .Cmd.Short | indent}}
{{else}}\ {{else}}\
{{printf "\t%s - %s" $cmdname .Cmd.Short}} {{printf "%s - %s" $cmdname .Cmd.Short | indent}}
{{end}}\ {{end}}\
USAGE: USAGE:
{{printf "\t%s" .Cmd.UseLine}} {{printf "%s" .Cmd.UseLine | indent}}
{{ if not .Cmd.HasParent }}\ {{ if not .Cmd.HasParent }}\
VERSION: VERSION:
{{printf "\t%s" .Version}} {{printf "%s" .Version | indent}}
{{end}}\ {{end}}\
{{if .Cmd.HasSubCommands}}\ {{if .Cmd.HasSubCommands}}\
API VERSION: API VERSION:
{{printf "\t%s" .APIVersion}} {{.APIVersion | indent}}
{{end}}\
{{if .Cmd.HasExample}}\
Examples:
{{.Cmd.Example}}
{{end}}\ {{end}}\
{{if .Cmd.HasSubCommands}}\ {{if .Cmd.HasSubCommands}}\
COMMANDS: COMMANDS:
{{range .SubCommands}}\ {{range .SubCommands}}\
{{ $cmdname := cmdName . $cmd }}\ {{ $cmdname := cmdName . $cmd }}\
{{ if .Runnable }}\ {{ if .Runnable }}\
{{printf "\t%s\t%s" $cmdname .Short}} {{printf "%s\t%s" $cmdname .Short | indent}}
{{end}}\ {{end}}\
{{end}}\ {{end}}\
{{end}}\ {{end}}\
{{ if .Cmd.Long }}\ {{ if .Cmd.Long }}\
DESCRIPTION: DESCRIPTION:
{{range $line := descToLines .Cmd.Long}}{{printf "\t%s" $line}} {{range $line := descToLines .Cmd.Long}}{{printf "%s" $line | indent}}
{{end}}\ {{end}}\
{{end}}\ {{end}}\
{{if .Cmd.HasLocalFlags}}\ {{if .Cmd.HasLocalFlags}}\