vitess.io/vitess@v0.16.2/go/test/endtoend/cluster/vtbackup_process.go (about)

     1  /*
     2  Copyright 2019 The Vitess Authors.
     3  
     4  Licensed under the Apache License, Version 2.0 (the "License");
     5  you may not use this file except in compliance with the License.
     6  You may obtain a copy of the License at
     7  
     8      http://www.apache.org/licenses/LICENSE-2.0
     9  
    10  Unless required by applicable law or agreed to in writing, software
    11  distributed under the License is distributed on an "AS IS" BASIS,
    12  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13  See the License for the specific language governing permissions and
    14  limitations under the License.
    15  */
    16  
    17  package cluster
    18  
    19  import (
    20  	"fmt"
    21  	"os"
    22  	"os/exec"
    23  	"path"
    24  	"strings"
    25  	"syscall"
    26  	"time"
    27  
    28  	"vitess.io/vitess/go/vt/log"
    29  )
    30  
    31  // VtbackupProcess is a generic handle for a running Vtbackup.
    32  // It can be spawned manually
    33  type VtbackupProcess struct {
    34  	Name      string
    35  	Binary    string
    36  	CommonArg VtctlProcess
    37  	LogDir    string
    38  	MysqlPort int
    39  	Directory string
    40  
    41  	Cell        string
    42  	Keyspace    string
    43  	Shard       string
    44  	TabletAlias string
    45  	Server      string
    46  
    47  	ExtraArgs     []string
    48  	initialBackup bool
    49  	initDBfile    string
    50  
    51  	proc *exec.Cmd
    52  	exit chan error
    53  }
    54  
    55  // Setup starts vtbackup process with required arguements
    56  func (vtbackup *VtbackupProcess) Setup() (err error) {
    57  
    58  	vtbackup.proc = exec.Command(
    59  		vtbackup.Binary,
    60  		"--topo_implementation", vtbackup.CommonArg.TopoImplementation,
    61  		"--topo_global_server_address", vtbackup.CommonArg.TopoGlobalAddress,
    62  		"--topo_global_root", vtbackup.CommonArg.TopoGlobalRoot,
    63  		"--log_dir", vtbackup.LogDir,
    64  
    65  		//initDBfile is required to run vtbackup
    66  		"--mysql_port", fmt.Sprintf("%d", vtbackup.MysqlPort),
    67  		"--init_db_sql_file", vtbackup.initDBfile,
    68  		"--init_keyspace", vtbackup.Keyspace,
    69  		"--init_shard", vtbackup.Shard,
    70  
    71  		//Backup Arguments are not optional
    72  		"--backup_storage_implementation", "file",
    73  		"--file_backup_storage_root",
    74  		path.Join(os.Getenv("VTDATAROOT"), "tmp", "backupstorage"),
    75  	)
    76  
    77  	if vtbackup.initialBackup {
    78  		vtbackup.proc.Args = append(vtbackup.proc.Args, "--initial_backup")
    79  	}
    80  	if vtbackup.ExtraArgs != nil {
    81  		vtbackup.proc.Args = append(vtbackup.proc.Args, vtbackup.ExtraArgs...)
    82  	}
    83  
    84  	vtbackup.proc.Stderr = os.Stderr
    85  	vtbackup.proc.Stdout = os.Stdout
    86  
    87  	vtbackup.proc.Env = append(vtbackup.proc.Env, os.Environ()...)
    88  	log.Infof("Running vtbackup with args: %v", strings.Join(vtbackup.proc.Args, " "))
    89  
    90  	err = vtbackup.proc.Run()
    91  	if err != nil {
    92  		return
    93  	}
    94  
    95  	vtbackup.exit = make(chan error)
    96  	go func() {
    97  		if vtbackup.proc != nil {
    98  			vtbackup.exit <- vtbackup.proc.Wait()
    99  			close(vtbackup.exit)
   100  		}
   101  	}()
   102  
   103  	return nil
   104  }
   105  
   106  // TearDown shutdowns the running vtbackup process
   107  func (vtbackup *VtbackupProcess) TearDown() error {
   108  	if vtbackup.proc == nil || vtbackup.exit == nil {
   109  		return nil
   110  	}
   111  
   112  	// Attempt graceful shutdown with SIGTERM first
   113  	vtbackup.proc.Process.Signal(syscall.SIGTERM)
   114  
   115  	select {
   116  	case err := <-vtbackup.exit:
   117  		vtbackup.proc = nil
   118  		return err
   119  
   120  	case <-time.After(10 * time.Second):
   121  		vtbackup.proc.Process.Kill()
   122  		err := <-vtbackup.exit
   123  		vtbackup.proc = nil
   124  		return err
   125  	}
   126  }
   127  
   128  // VtbackupProcessInstance returns a vtbackup handle
   129  // configured with the given Config.
   130  // The process must be manually started by calling Setup()
   131  func VtbackupProcessInstance(tabletUID int, mysqlPort int, newInitDBFile string, keyspace string, shard string,
   132  	cell string, hostname string, tmpDirectory string, topoPort int, initialBackup bool) *VtbackupProcess {
   133  	vtctl := VtctlProcessInstance(topoPort, hostname)
   134  	vtbackup := &VtbackupProcess{
   135  		Name:          "vtbackup",
   136  		Binary:        "vtbackup",
   137  		CommonArg:     *vtctl,
   138  		LogDir:        tmpDirectory,
   139  		Directory:     os.Getenv("VTDATAROOT"),
   140  		TabletAlias:   fmt.Sprintf("%s-%010d", cell, tabletUID),
   141  		initDBfile:    newInitDBFile,
   142  		Keyspace:      keyspace,
   143  		Shard:         shard,
   144  		Cell:          cell,
   145  		MysqlPort:     mysqlPort,
   146  		initialBackup: initialBackup,
   147  	}
   148  	return vtbackup
   149  }