vitess.io/vitess@v0.16.2/go/vt/vttablet/onlineddl/util.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 onlineddl 18 19 import ( 20 "crypto/rand" 21 "crypto/sha256" 22 "encoding/hex" 23 "fmt" 24 "io" 25 "os" 26 "os/exec" 27 "path/filepath" 28 "strings" 29 "time" 30 31 "vitess.io/vitess/go/vt/log" 32 ) 33 34 const ( 35 readableTimeFormat = "20060102150405" 36 ) 37 38 // execCmd searches the PATH for a command and runs it, logging the output. 39 // If input is not nil, pipe it to the command's stdin. 40 func execCmd(name string, args, env []string, dir string, input io.Reader, output io.Writer) (cmd *exec.Cmd, err error) { 41 cmdPath, err := exec.LookPath(name) 42 if err != nil { 43 return cmd, err 44 } 45 log.Infof("execCmd: %v %v %v", name, cmdPath, args) 46 47 cmd = exec.Command(cmdPath, args...) 48 cmd.Env = env 49 cmd.Dir = dir 50 if input != nil { 51 cmd.Stdin = input 52 } 53 if output != nil { 54 cmd.Stdout = output 55 cmd.Stderr = output 56 } 57 err = cmd.Run() 58 if err != nil { 59 err = fmt.Errorf("failed running command: %v %s; error=%v", name, strings.Join(args, " "), err) 60 log.Errorf(err.Error()) 61 } 62 log.Infof("execCmd success: %v", name) 63 return cmd, err 64 } 65 66 // createTempDir creates a temporary directory and returns its name 67 func createTempDir(hint string) (dirName string, err error) { 68 if hint != "" { 69 return os.MkdirTemp("", fmt.Sprintf("online-ddl-%s-*", hint)) 70 } 71 return os.MkdirTemp("", "online-ddl-*") 72 } 73 74 // createTempScript creates an executable file in given directory and with given text as content. 75 func createTempScript(dirName, fileName, text string) (fullName string, err error) { 76 fullName = filepath.Join(dirName, fileName) 77 bytes := []byte(text) 78 err = os.WriteFile(fullName, bytes, 0755) 79 return fullName, err 80 } 81 82 // RandomHash returns a 64 hex character random string 83 func RandomHash() string { 84 size := 64 85 rb := make([]byte, size) 86 _, _ = rand.Read(rb) 87 88 hasher := sha256.New() 89 hasher.Write(rb) 90 return hex.EncodeToString(hasher.Sum(nil)) 91 } 92 93 // ToReadableTimestamp returns a timestamp, in seconds resolution, that is human readable 94 // (as opposed to unix timestamp which is just a number) 95 // Example: for Aug 25 2020, 16:04:25 we return "20200825160425" 96 func ToReadableTimestamp(t time.Time) string { 97 return t.Format(readableTimeFormat) 98 } 99 100 // ReadableTimestamp returns a timestamp, in seconds resolution, that is human readable 101 // (as opposed to unix timestamp which is just a number), and which corresponds to the time now. 102 // Example: for Aug 25 2020, 16:04:25 we return "20200825160425" 103 func ReadableTimestamp() string { 104 return ToReadableTimestamp(time.Now()) 105 }