github.com/makyo/juju@v0.0.0-20160425123129-2608902037e9/cloudconfig/cloudinit/progress.go (about) 1 // Copyright 2013 Canonical Ltd. 2 // Licensed under the AGPLv3, see LICENCE file for details. 3 4 package cloudinit 5 6 import ( 7 "fmt" 8 9 "github.com/juju/utils" 10 ) 11 12 // progressFd is the file descriptor to which progress is logged. 13 // This is necessary so that we can redirect all non-progress 14 // related stderr away. 15 // 16 // Note, from the Bash manual: 17 // "Redirections using file descriptors greater than 9 should be 18 // used with care, as they may conflict with file descriptors the 19 // shell uses internally." 20 const progressFd = 9 21 22 // InitProgressCmd will return a command to initialise progress 23 // reporting, sending messages to stderr. If LogProgressCmd is 24 // used in a script, InitProgressCmd MUST be executed beforehand. 25 // 26 // The returned command is idempotent; this is important, to 27 // allow a script to be embedded in another with stderr redirected, 28 // in which case InitProgressCmd must precede the redirection. 29 func InitProgressCmd() string { 30 return fmt.Sprintf("test -e /proc/self/fd/%d || exec %d>&2", progressFd, progressFd) 31 } 32 33 // LogProgressCmd will return a command to log the specified progress 34 // message to stderr; the resultant command should be added to the 35 // configuration as a runcmd or bootcmd as appropriate. 36 // 37 // If there are any uses of LogProgressCmd in a configuration, the 38 // configuration MUST precede the command with the result of 39 // InitProgressCmd. 40 func LogProgressCmd(format string, args ...interface{}) string { 41 msg := utils.ShQuote(fmt.Sprintf(format, args...)) 42 return fmt.Sprintf("echo %s >&%d", msg, progressFd) 43 }