// Prepares the signal handlers so that we handle interrupts properly. // The signal handler exists in a goroutine. func setupSignalHandlers(ui packer.Ui) { ch := make(chan os.Signal, 1) signal.Notify(ch, os.Interrupt) signal.Notify(ch, syscall.SIGTERM) go func() { // First interrupt. We mostly ignore this because it allows the // plugins time to cleanup. <-ch log.Println("First interrupt. Ignoring to allow plugins to clean up.") ui.Error("Interrupt signal received. Cleaning up...") // Second interrupt. Go down hard. <-ch log.Println("Second interrupt. Exiting now.") ui.Error("Interrupt signal received twice. Forcefully exiting now.") // Force kill all the plugins, but mark that we're killing them // first so that we don't get panics everywhere. plugin.CleanupClients() os.Exit(1) }() }
// Prepares the signal handlers so that we handle interrupts properly. // The signal handler exists in a goroutine. func setupSignalHandlers(env packer.Environment) { ch := make(chan os.Signal, 1) signal.Notify(ch, os.Interrupt) go func() { <-ch log.Println("First interrupt. Ignoring, will let plugins handle...") <-ch log.Println("Second interrupt. Exiting now.") env.Ui().Error("Interrupt signal received twice. Forcefully exiting now.") // Force kill all the plugins plugin.CleanupClients() os.Exit(1) }() }
// Prepares the signal handlers so that we handle interrupts properly. // The signal handler exists in a goroutine. func setupSignalHandlers(env packer.Environment) { ch := make(chan os.Signal, 1) signal.Notify(ch, os.Interrupt) go func() { // First interrupt. We mostly ignore this because it allows the // plugins time to cleanup. <-ch log.Println("First interrupt. Ignoring to allow plugins to clean up.") // Second interrupt. Go down hard. <-ch log.Println("Second interrupt. Exiting now.") env.Ui().Error("Interrupt signal received twice. Forcefully exiting now.") // Force kill all the plugins plugin.CleanupClients() os.Exit(1) }() }
func main() { if os.Getenv("PACKER_LOG") == "" { // If we don't have logging explicitly enabled, then disable it log.SetOutput(ioutil.Discard) } else { // Logging is enabled, make sure it goes to stderr log.SetOutput(os.Stderr) } // If there is no explicit number of Go threads to use, then set it if os.Getenv("GOMAXPROCS") == "" { runtime.GOMAXPROCS(runtime.NumCPU()) } config, err := loadConfig() if err != nil { fmt.Fprintf(os.Stderr, "Error loading configuration: \n\n%s\n", err) os.Exit(1) } log.Printf("Packer config: %+v", config) cacheDir := os.Getenv("PACKER_CACHE_DIR") if cacheDir == "" { cacheDir = "packer_cache" } cacheDir, err = filepath.Abs(cacheDir) if err != nil { fmt.Fprintf(os.Stderr, "Error preparing cache directory: \n\n%s\n", err) os.Exit(1) } if err := os.MkdirAll(cacheDir, 0755); err != nil { fmt.Fprintf(os.Stderr, "Error preparing cache directory: \n\n%s\n", err) os.Exit(1) } log.Printf("Setting cache directory: %s", cacheDir) cache := &packer.FileCache{CacheDir: cacheDir} defer plugin.CleanupClients() envConfig := packer.DefaultEnvironmentConfig() envConfig.Cache = cache envConfig.Commands = config.CommandNames() envConfig.Components.Builder = config.LoadBuilder envConfig.Components.Command = config.LoadCommand envConfig.Components.Hook = config.LoadHook envConfig.Components.PostProcessor = config.LoadPostProcessor envConfig.Components.Provisioner = config.LoadProvisioner env, err := packer.NewEnvironment(envConfig) if err != nil { fmt.Fprintf(os.Stderr, "Packer initialization error: \n\n%s\n", err) os.Exit(1) } setupSignalHandlers(env) exitCode, err := env.Cli(os.Args[1:]) if err != nil { fmt.Fprintf(os.Stderr, "Error executing CLI: %s\n", err.Error()) os.Exit(1) } plugin.CleanupClients() os.Exit(exitCode) }
// wrappedMain is called only when we're wrapped by panicwrap and // returns the exit status to exit with. func wrappedMain() int { // If there is no explicit number of Go threads to use, then set it if os.Getenv("GOMAXPROCS") == "" { runtime.GOMAXPROCS(runtime.NumCPU()) } log.SetOutput(os.Stderr) log.Printf( "[INFO] Packer version: %s %s %s", Version, VersionPrerelease, GitCommit) log.Printf("Packer Target OS/Arch: %s %s", runtime.GOOS, runtime.GOARCH) log.Printf("Built with Go Version: %s", runtime.Version()) // Prepare stdin for plugin usage by switching it to a pipe // But do not switch to pipe in plugin if os.Getenv(plugin.MagicCookieKey) != plugin.MagicCookieValue { setupStdin() } config, err := loadConfig() if err != nil { fmt.Fprintf(os.Stderr, "Error loading configuration: \n\n%s\n", err) return 1 } log.Printf("Packer config: %+v", config) // Fire off the checkpoint. go runCheckpoint(config) cacheDir := os.Getenv("PACKER_CACHE_DIR") if cacheDir == "" { cacheDir = "packer_cache" } cacheDir, err = filepath.Abs(cacheDir) if err != nil { fmt.Fprintf(os.Stderr, "Error preparing cache directory: \n\n%s\n", err) return 1 } log.Printf("Setting cache directory: %s", cacheDir) cache := &packer.FileCache{CacheDir: cacheDir} // Determine if we're in machine-readable mode by mucking around with // the arguments... args, machineReadable := extractMachineReadable(os.Args[1:]) defer plugin.CleanupClients() // Setup the UI if we're being machine-readable var ui packer.Ui = &packer.BasicUi{ Reader: os.Stdin, Writer: os.Stdout, ErrorWriter: os.Stdout, } if machineReadable { ui = &packer.MachineReadableUi{ Writer: os.Stdout, } // Set this so that we don't get colored output in our machine- // readable UI. if err := os.Setenv("PACKER_NO_COLOR", "1"); err != nil { fmt.Fprintf(os.Stderr, "Packer failed to initialize UI: %s\n", err) return 1 } } // Create the CLI meta CommandMeta = &command.Meta{ CoreConfig: &packer.CoreConfig{ Components: packer.ComponentFinder{ Builder: config.LoadBuilder, Hook: config.LoadHook, PostProcessor: config.LoadPostProcessor, Provisioner: config.LoadProvisioner, }, Version: Version, }, Cache: cache, Ui: ui, } //setupSignalHandlers(env) cli := &cli.CLI{ Args: args, Commands: Commands, HelpFunc: excludeHelpFunc(Commands, []string{"plugin"}), HelpWriter: os.Stdout, Version: Version, } exitCode, err := cli.Run() if err != nil { fmt.Fprintf(os.Stderr, "Error executing CLI: %s\n", err) return 1 } return exitCode }
// wrappedMain is called only when we're wrapped by panicwrap and // returns the exit status to exit with. func wrappedMain() int { log.SetOutput(os.Stderr) log.Printf( "Packer Version: %s %s %s", packer.Version, packer.VersionPrerelease, packer.GitCommit) log.Printf("Packer Target OS/Arch: %s %s", runtime.GOOS, runtime.GOARCH) log.Printf("Built with Go Version: %s", runtime.Version()) // Prepare stdin for plugin usage by switching it to a pipe setupStdin() config, err := loadConfig() if err != nil { fmt.Fprintf(os.Stderr, "Error loading configuration: \n\n%s\n", err) return 1 } log.Printf("Packer config: %+v", config) cacheDir := os.Getenv("PACKER_CACHE_DIR") if cacheDir == "" { cacheDir = "packer_cache" } cacheDir, err = filepath.Abs(cacheDir) if err != nil { fmt.Fprintf(os.Stderr, "Error preparing cache directory: \n\n%s\n", err) return 1 } if err := os.MkdirAll(cacheDir, 0755); err != nil { fmt.Fprintf(os.Stderr, "Error preparing cache directory: \n\n%s\n", err) return 1 } log.Printf("Setting cache directory: %s", cacheDir) cache := &packer.FileCache{CacheDir: cacheDir} // Determine if we're in machine-readable mode by mucking around with // the arguments... args, machineReadable := extractMachineReadable(os.Args[1:]) defer plugin.CleanupClients() // Create the environment configuration envConfig := packer.DefaultEnvironmentConfig() envConfig.Cache = cache envConfig.Commands = config.CommandNames() envConfig.Components.Builder = config.LoadBuilder envConfig.Components.Command = config.LoadCommand envConfig.Components.Hook = config.LoadHook envConfig.Components.PostProcessor = config.LoadPostProcessor envConfig.Components.Provisioner = config.LoadProvisioner if machineReadable { envConfig.Ui = &packer.MachineReadableUi{ Writer: os.Stdout, } // Set this so that we don't get colored output in our machine- // readable UI. if err := os.Setenv("PACKER_NO_COLOR", "1"); err != nil { fmt.Fprintf(os.Stderr, "Packer failed to initialize UI: %s\n", err) return 1 } } env, err := packer.NewEnvironment(envConfig) if err != nil { fmt.Fprintf(os.Stderr, "Packer initialization error: \n\n%s\n", err) return 1 } setupSignalHandlers(env) exitCode, err := env.Cli(args) if err != nil { fmt.Fprintf(os.Stderr, "Error executing CLI: %s\n", err.Error()) return 1 } return exitCode }
func main() { // Setup logging if PACKER_LOG is set. // Log to PACKER_LOG_PATH if it is set, otherwise default to stderr. var logOutput io.Writer = ioutil.Discard if os.Getenv("PACKER_LOG") != "" { logOutput = os.Stderr if logPath := os.Getenv("PACKER_LOG_PATH"); logPath != "" { var err error logOutput, err = os.Create(logPath) if err != nil { fmt.Fprintf( os.Stderr, "Couldn't open '%s' for logging: %s", logPath, err) os.Exit(1) } } } log.SetOutput(logOutput) // If there is no explicit number of Go threads to use, then set it if os.Getenv("GOMAXPROCS") == "" { runtime.GOMAXPROCS(runtime.NumCPU()) } log.Printf( "Packer Version: %s %s %s", packer.Version, packer.VersionPrerelease, packer.GitCommit) log.Printf("Packer Target OS/Arch: %s %s", runtime.GOOS, runtime.GOARCH) // Prepare stdin for plugin usage by switching it to a pipe setupStdin() config, err := loadConfig() if err != nil { fmt.Fprintf(os.Stderr, "Error loading configuration: \n\n%s\n", err) os.Exit(1) } log.Printf("Packer config: %+v", config) cacheDir := os.Getenv("PACKER_CACHE_DIR") if cacheDir == "" { cacheDir = "packer_cache" } cacheDir, err = filepath.Abs(cacheDir) if err != nil { fmt.Fprintf(os.Stderr, "Error preparing cache directory: \n\n%s\n", err) os.Exit(1) } if err := os.MkdirAll(cacheDir, 0755); err != nil { fmt.Fprintf(os.Stderr, "Error preparing cache directory: \n\n%s\n", err) os.Exit(1) } log.Printf("Setting cache directory: %s", cacheDir) cache := &packer.FileCache{CacheDir: cacheDir} defer plugin.CleanupClients() envConfig := packer.DefaultEnvironmentConfig() envConfig.Cache = cache envConfig.Commands = config.CommandNames() envConfig.Components.Builder = config.LoadBuilder envConfig.Components.Command = config.LoadCommand envConfig.Components.Hook = config.LoadHook envConfig.Components.PostProcessor = config.LoadPostProcessor envConfig.Components.Provisioner = config.LoadProvisioner env, err := packer.NewEnvironment(envConfig) if err != nil { fmt.Fprintf(os.Stderr, "Packer initialization error: \n\n%s\n", err) os.Exit(1) } setupSignalHandlers(env) exitCode, err := env.Cli(os.Args[1:]) if err != nil { fmt.Fprintf(os.Stderr, "Error executing CLI: %s\n", err.Error()) os.Exit(1) } plugin.CleanupClients() os.Exit(exitCode) }
// wrappedMain is called only when we're wrapped by panicwrap and // returns the exit status to exit with. func wrappedMain() int { // If there is no explicit number of Go threads to use, then set it if os.Getenv("GOMAXPROCS") == "" { runtime.GOMAXPROCS(runtime.NumCPU()) } log.SetOutput(os.Stderr) log.Printf( "[INFO] Packer version: %s %s %s", Version, VersionPrerelease, GitCommit) log.Printf("Packer Target OS/Arch: %s %s", runtime.GOOS, runtime.GOARCH) log.Printf("Built with Go Version: %s", runtime.Version()) // Prepare stdin for plugin usage by switching it to a pipe setupStdin() config, err := loadConfig() if err != nil { fmt.Fprintf(os.Stderr, "Error loading configuration: \n\n%s\n", err) return 1 } log.Printf("Packer config: %+v", config) // Fire off the checkpoint. go runCheckpoint(config) cacheDir := os.Getenv("PACKER_CACHE_DIR") if cacheDir == "" { cacheDir = "packer_cache" } cacheDir, err = filepath.Abs(cacheDir) if err != nil { fmt.Fprintf(os.Stderr, "Error preparing cache directory: \n\n%s\n", err) return 1 } log.Printf("Setting cache directory: %s", cacheDir) cache := &packer.FileCache{CacheDir: cacheDir} // Determine if we're in machine-readable mode by mucking around with // the arguments... args, machineReadable := extractMachineReadable(os.Args[1:]) defer plugin.CleanupClients() // Create the environment configuration EnvConfig = *packer.DefaultEnvironmentConfig() EnvConfig.Cache = cache EnvConfig.Components.Builder = config.LoadBuilder EnvConfig.Components.Hook = config.LoadHook EnvConfig.Components.PostProcessor = config.LoadPostProcessor EnvConfig.Components.Provisioner = config.LoadProvisioner if machineReadable { EnvConfig.Ui = &packer.MachineReadableUi{ Writer: os.Stdout, } // Set this so that we don't get colored output in our machine- // readable UI. if err := os.Setenv("PACKER_NO_COLOR", "1"); err != nil { fmt.Fprintf(os.Stderr, "Packer failed to initialize UI: %s\n", err) return 1 } } //setupSignalHandlers(env) cli := &cli.CLI{ Args: args, Commands: Commands, HelpFunc: cli.BasicHelpFunc("packer"), HelpWriter: os.Stdout, Version: Version, } exitCode, err := cli.Run() if err != nil { fmt.Fprintf(os.Stderr, "Error executing CLI: %s\n", err) return 1 } return exitCode }