Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

tt: add command tt upgrade #936

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,10 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.

### Added

- `tt replicaset upgrade`: command to upgrade the schema on a Tarantool cluster.
* `-r (--replicaset)`: specify the replicaset name(s) to upgrade.
* `-t (--timeout)`: timeout for waiting the LSN synchronization (in seconds) (default 5).

### Changed

### Fixed
Expand Down
53 changes: 52 additions & 1 deletion cli/cmd/replicaset.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,12 +46,42 @@ var (
replicasetIsGlobal bool
rebootstrapConfirmed bool

chosenReplicasetAliases []string
lsnTimeout int

replicasetUriHelp = " The URI can be specified in the following formats:\n" +
" * [tcp://][username:password@][host:port]\n" +
" * [unix://][username:password@]socketpath\n" +
" To specify relative path without `unix://` use `./`."
)

// newUpgradeCmd creates a "replicaset upgrade" command.
func newUpgradeCmd() *cobra.Command {
cmd := &cobra.Command{
Use: "upgrade (<APP_NAME>) [flags]",
DisableFlagsInUseLine: true,
Short: "Upgrade tarantool cluster",
Long: "Upgrade tarantool cluster.\n\n" +
libconnect.EnvCredentialsHelp + "\n\n",
Run: func(cmd *cobra.Command, args []string) {
cmdCtx.CommandName = cmd.Name()
err := modules.RunCmd(&cmdCtx, cmd.CommandPath(), &modulesInfo,
internalReplicasetUpgradeModule, args)
util.HandleCmdErr(cmd, err)
},
Args: cobra.ExactArgs(1),
}

cmd.Flags().StringArrayVarP(&chosenReplicasetAliases, "replicaset", "r",
[]string{}, "specify the replicaset name(s) to upgrade")

cmd.Flags().IntVarP(&lsnTimeout, "timeout", "t", 5,
"timeout for waiting the LSN synchronization (in seconds)")

addOrchestratorFlags(cmd)
return cmd
}

// newStatusCmd creates a "replicaset status" command.
func newStatusCmd() *cobra.Command {
cmd := &cobra.Command{
Expand Down Expand Up @@ -341,6 +371,7 @@ func NewReplicasetCmd() *cobra.Command {
Aliases: []string{"rs"},
}

cmd.AddCommand(newUpgradeCmd())
cmd.AddCommand(newStatusCmd())
cmd.AddCommand(newPromoteCmd())
cmd.AddCommand(newDemoteCmd())
Expand Down Expand Up @@ -490,6 +521,26 @@ func replicasetFillCtx(cmdCtx *cmdcontext.CmdCtx, ctx *replicasetCtx, args []str
return nil
}

// internalReplicasetUpgradeModule is a "upgrade" command for the replicaset module.
func internalReplicasetUpgradeModule(cmdCtx *cmdcontext.CmdCtx, args []string) error {
var ctx replicasetCtx
if err := replicasetFillCtx(cmdCtx, &ctx, args, false); err != nil {
return err
}
if ctx.IsInstanceConnect {
defer ctx.Conn.Close()
}
return replicasetcmd.Upgrade(replicasetcmd.DiscoveryCtx{
IsApplication: ctx.IsApplication,
RunningCtx: ctx.RunningCtx,
Conn: ctx.Conn,
Orchestrator: ctx.Orchestrator,
}, replicasetcmd.UpgradeOpts{
ChosenReplicasetAliases: chosenReplicasetAliases,
LsnTimeout: lsnTimeout,
})
}

// internalReplicasetPromoteModule is a "promote" command for the replicaset module.
func internalReplicasetPromoteModule(cmdCtx *cmdcontext.CmdCtx, args []string) error {
var ctx replicasetCtx
Expand Down Expand Up @@ -561,7 +612,7 @@ func internalReplicasetStatusModule(cmdCtx *cmdcontext.CmdCtx, args []string) er
if ctx.IsInstanceConnect {
defer ctx.Conn.Close()
}
return replicasetcmd.Status(replicasetcmd.StatusCtx{
return replicasetcmd.Status(replicasetcmd.DiscoveryCtx{
IsApplication: ctx.IsApplication,
RunningCtx: ctx.RunningCtx,
Conn: ctx.Conn,
Expand Down
10 changes: 10 additions & 0 deletions cli/replicaset/cmd/lua/upgrade.lua
DerekBum marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
local ok, err = pcall(box.schema.upgrade)
if ok then
ok, err = pcall(box.snapshot)
end

return {
lsn = box.info.lsn,
iid = box.info.id,
err = (not ok) and tostring(err) or nil,
}
40 changes: 21 additions & 19 deletions cli/replicaset/cmd/status.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,41 +10,43 @@ import (
"github.com/tarantool/tt/cli/running"
)

// StatusCtx contains information about replicaset status command execution
// context.
type StatusCtx struct {
// DiscoveryCtx contains information about replicaset discovery.
type DiscoveryCtx struct {
// IsApplication true if an application passed.
IsApplication bool
// RunningCtx is an application running context.
RunningCtx running.RunningCtx
// Conn is an active connection to a passed instance.
Conn connector.Connector
// Orchestrator is a forced orchestator choice.
// Orchestrator is a forced orchestrator choice.
Orchestrator replicaset.Orchestrator
}

// Status shows a replicaset status.
func Status(statusCtx StatusCtx) error {
orchestratorType, err := getOrchestratorType(statusCtx.Orchestrator,
statusCtx.Conn, statusCtx.RunningCtx)
// getReplicasets discovers and returns the list of replicasets.
func getReplicasets(ctx DiscoveryCtx) (replicaset.Replicasets, error) {
orchestratorType, err := getOrchestratorType(ctx.Orchestrator, ctx.Conn, ctx.RunningCtx)
if err != nil {
return err
return replicaset.Replicasets{}, err
}

var orchestrator replicasetOrchestrator
if statusCtx.IsApplication {
if orchestrator, err = makeApplicationOrchestrator(
orchestratorType, statusCtx.RunningCtx, nil, nil); err != nil {
return err
}
if ctx.IsApplication {
orchestrator, err = makeApplicationOrchestrator(orchestratorType,
ctx.RunningCtx, nil, nil)
} else {
if orchestrator, err = makeInstanceOrchestrator(
orchestratorType, statusCtx.Conn); err != nil {
return err
}
orchestrator, err = makeInstanceOrchestrator(orchestratorType, ctx.Conn)
}

if err != nil {
return replicaset.Replicasets{}, err
}

replicasets, err := orchestrator.Discovery(replicaset.SkipCache)
return orchestrator.Discovery(replicaset.SkipCache)
}

// Status shows a replicaset status.
func Status(discoveryCtx DiscoveryCtx) error {
replicasets, err := getReplicasets(discoveryCtx)
if err != nil {
return err
}
Expand Down
Loading
Loading