diff --git a/go/cmd/tools.go b/go/cmd/tools.go new file mode 100644 index 00000000000..9722dbc267c --- /dev/null +++ b/go/cmd/tools.go @@ -0,0 +1,43 @@ +/* +Copyright 2019 The Vitess 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 cmd + +import ( + "fmt" + "os" + "os/exec" + "strings" +) + +// DetachFromTerminalAndExit allows a command line program to detach from the terminal and continue running +// even if the parent process is terminated +func DetachFromTerminalAndExit() { + args := os.Args[1:] + i := 0 + for ; i < len(args); i++ { + if strings.HasPrefix(args[i], "-detach") { + args[i] = "-detach=false" + break + } + } + cmd := exec.Command(os.Args[0], args...) + cmd.Stdin = os.Stdin + cmd.Stdout = os.Stdout + cmd.Stderr = os.Stderr + _ = cmd.Start() + fmt.Println("[PID]", cmd.Process.Pid) + os.Exit(0) +} diff --git a/go/cmd/vtbackup/vtbackup.go b/go/cmd/vtbackup/vtbackup.go index 8c81154b8c1..05717c42f87 100644 --- a/go/cmd/vtbackup/vtbackup.go +++ b/go/cmd/vtbackup/vtbackup.go @@ -70,6 +70,7 @@ import ( "syscall" "time" + "vitess.io/vitess/go/cmd" "vitess.io/vitess/go/exit" "vitess.io/vitess/go/mysql" "vitess.io/vitess/go/sqlescape" @@ -124,17 +125,23 @@ var ( mysqlSocket = flag.String("mysql_socket", "", "path to the mysql socket") mysqlTimeout = flag.Duration("mysql_timeout", 5*time.Minute, "how long to wait for mysqld startup") initDBSQLFile = flag.String("init_db_sql_file", "", "path to .sql file to run after mysql_install_db") + detachedMode = flag.Bool("detach", false, "detached mode - run backups detached from the terminal") ) func main() { defer exit.Recover() - defer logutil.Flush() - dbconfigs.RegisterFlags(dbconfigs.All...) mysqlctl.RegisterFlags() servenv.ParseFlags("vtbackup") + if *detachedMode { + // this method will call os.Exit and kill this process + cmd.DetachFromTerminalAndExit() + } + + defer logutil.Flush() + if *minRetentionCount < 1 { log.Errorf("min_retention_count must be at least 1 to allow restores to succeed") exit.Return(1) diff --git a/go/cmd/vtctl/vtctl.go b/go/cmd/vtctl/vtctl.go index 8365b9c0ab4..fbeb3760f9b 100644 --- a/go/cmd/vtctl/vtctl.go +++ b/go/cmd/vtctl/vtctl.go @@ -26,6 +26,8 @@ import ( "syscall" "time" + "vitess.io/vitess/go/cmd" + "golang.org/x/net/context" "vitess.io/vitess/go/exit" "vitess.io/vitess/go/trace" @@ -40,7 +42,8 @@ import ( ) var ( - waitTime = flag.Duration("wait-time", 24*time.Hour, "time to wait on an action") + waitTime = flag.Duration("wait-time", 24*time.Hour, "time to wait on an action") + detachedMode = flag.Bool("detach", false, "detached mode - run vtcl detached from the terminal") ) func init() { @@ -70,6 +73,11 @@ func main() { defer exit.RecoverAll() defer logutil.Flush() + if *detachedMode { + // this method will call os.Exit and kill this process + cmd.DetachFromTerminalAndExit() + } + args := servenv.ParseFlagsWithArgs("vtctl") action := args[0]