github.com/niedbalski/juju@v0.0.0-20190215020005-8ff100488e47/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 // progressFdEnvVar is the name of the environment variable set for 13 // the duration of the cloud-init script, identifying the file 14 // descriptor to which progress is logged. This is necessary so that 15 // we can redirect all non-progress related stderr away for interactive 16 // sessions (bootstrap, manual add-machine). 17 const progressFdEnvVar = "JUJU_PROGRESS_FD" 18 19 // InitProgressCmd will return a command to initialise progress 20 // reporting, sending messages to stderr. If LogProgressCmd is 21 // used in a script, InitProgressCmd MUST be executed beforehand. 22 // 23 // The returned commands are idempotent; this is important, to 24 // allow a script to be embedded in another with stderr redirected, 25 // in which case InitProgressCmd must precede the redirection. 26 func InitProgressCmd() string { 27 // This command may be run by either bash or /bin/sh, the 28 // latter of which does not support named file descriptors. 29 // When running under /bin/sh we don't care about progress 30 // logging, so we can allow it to go to FD 2. 31 return fmt.Sprintf( 32 `test -n "$%s" || `+ 33 `(exec {%s}>&2) 2>/dev/null && exec {%s}>&2 || `+ 34 `%s=2`, 35 progressFdEnvVar, 36 progressFdEnvVar, 37 progressFdEnvVar, 38 progressFdEnvVar, 39 ) 40 } 41 42 // LogProgressCmd will return a command to log the specified progress 43 // message to stderr; the resultant command should be added to the 44 // configuration as a runcmd or bootcmd as appropriate. 45 // 46 // If there are any uses of LogProgressCmd in a configuration, the 47 // configuration MUST precede the command with the result of 48 // InitProgressCmd. 49 func LogProgressCmd(format string, args ...interface{}) string { 50 msg := utils.ShQuote(fmt.Sprintf(format, args...)) 51 return fmt.Sprintf("echo %s >&$%s", msg, progressFdEnvVar) 52 }