Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
P
packer
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Kristopher Ruzic
packer
Commits
8054e66d
Commit
8054e66d
authored
Oct 27, 2014
by
Mitchell Hashimoto
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
command: move more to this package, remove old packages
parent
96b0ec53
Changes
18
Hide whitespace changes
Inline
Side-by-side
Showing
18 changed files
with
208 additions
and
543 deletions
+208
-543
command/build/command.go
command/build/command.go
+0
-283
command/build/command_test.go
command/build/command_test.go
+0
-54
command/build/help.go
command/build/help.go
+0
-19
command/inspect.go
command/inspect.go
+29
-9
command/inspect/command_test.go
command/inspect/command_test.go
+0
-14
command/inspect/help.go
command/inspect/help.go
+0
-13
command/validate.go
command/validate.go
+34
-7
command/validate/command_test.go
command/validate/command_test.go
+0
-14
command/validate/help.go
command/validate/help.go
+0
-20
commands.go
commands.go
+19
-10
log.go
log.go
+29
-0
packer.go
packer.go
+97
-52
plugin/command-build/main.go
plugin/command-build/main.go
+0
-15
plugin/command-build/main_test.go
plugin/command-build/main_test.go
+0
-1
plugin/command-inspect/main.go
plugin/command-inspect/main.go
+0
-15
plugin/command-inspect/main_test.go
plugin/command-inspect/main_test.go
+0
-1
plugin/command-validate/main.go
plugin/command-validate/main.go
+0
-15
plugin/command-validate/main_test.go
plugin/command-validate/main_test.go
+0
-1
No files found.
command/build/command.go
deleted
100644 → 0
View file @
96b0ec53
package
build
import
(
"bytes"
"flag"
"fmt"
cmdcommon
"github.com/mitchellh/packer/common/command"
"github.com/mitchellh/packer/packer"
"log"
"os"
"os/signal"
"strconv"
"strings"
"sync"
)
type
Command
byte
func
(
Command
)
Help
()
string
{
return
strings
.
TrimSpace
(
helpText
)
}
func
(
c
Command
)
Run
(
env
packer
.
Environment
,
args
[]
string
)
int
{
var
cfgColor
,
cfgDebug
,
cfgForce
,
cfgParallel
bool
buildOptions
:=
new
(
cmdcommon
.
BuildOptions
)
cmdFlags
:=
flag
.
NewFlagSet
(
"build"
,
flag
.
ContinueOnError
)
cmdFlags
.
Usage
=
func
()
{
env
.
Ui
()
.
Say
(
c
.
Help
())
}
cmdFlags
.
BoolVar
(
&
cfgColor
,
"color"
,
true
,
"enable or disable color"
)
cmdFlags
.
BoolVar
(
&
cfgDebug
,
"debug"
,
false
,
"debug mode for builds"
)
cmdFlags
.
BoolVar
(
&
cfgForce
,
"force"
,
false
,
"force a build if artifacts exist"
)
cmdFlags
.
BoolVar
(
&
cfgParallel
,
"parallel"
,
true
,
"enable/disable parallelization"
)
cmdcommon
.
BuildOptionFlags
(
cmdFlags
,
buildOptions
)
if
err
:=
cmdFlags
.
Parse
(
args
);
err
!=
nil
{
return
1
}
args
=
cmdFlags
.
Args
()
if
len
(
args
)
!=
1
{
cmdFlags
.
Usage
()
return
1
}
if
err
:=
buildOptions
.
Validate
();
err
!=
nil
{
env
.
Ui
()
.
Error
(
err
.
Error
())
env
.
Ui
()
.
Error
(
""
)
env
.
Ui
()
.
Error
(
c
.
Help
())
return
1
}
userVars
,
err
:=
buildOptions
.
AllUserVars
()
if
err
!=
nil
{
env
.
Ui
()
.
Error
(
fmt
.
Sprintf
(
"Error compiling user variables: %s"
,
err
))
env
.
Ui
()
.
Error
(
""
)
env
.
Ui
()
.
Error
(
c
.
Help
())
return
1
}
// Read the file into a byte array so that we can parse the template
log
.
Printf
(
"Reading template: %s"
,
args
[
0
])
tpl
,
err
:=
packer
.
ParseTemplateFile
(
args
[
0
],
userVars
)
if
err
!=
nil
{
env
.
Ui
()
.
Error
(
fmt
.
Sprintf
(
"Failed to parse template: %s"
,
err
))
return
1
}
// The component finder for our builds
components
:=
&
packer
.
ComponentFinder
{
Builder
:
env
.
Builder
,
Hook
:
env
.
Hook
,
PostProcessor
:
env
.
PostProcessor
,
Provisioner
:
env
.
Provisioner
,
}
// Go through each builder and compile the builds that we care about
builds
,
err
:=
buildOptions
.
Builds
(
tpl
,
components
)
if
err
!=
nil
{
env
.
Ui
()
.
Error
(
err
.
Error
())
return
1
}
if
cfgDebug
{
env
.
Ui
()
.
Say
(
"Debug mode enabled. Builds will not be parallelized."
)
}
// Compile all the UIs for the builds
colors
:=
[
5
]
packer
.
UiColor
{
packer
.
UiColorGreen
,
packer
.
UiColorCyan
,
packer
.
UiColorMagenta
,
packer
.
UiColorYellow
,
packer
.
UiColorBlue
,
}
buildUis
:=
make
(
map
[
string
]
packer
.
Ui
)
for
i
,
b
:=
range
builds
{
var
ui
packer
.
Ui
ui
=
env
.
Ui
()
if
cfgColor
{
ui
=
&
packer
.
ColoredUi
{
Color
:
colors
[
i
%
len
(
colors
)],
Ui
:
env
.
Ui
(),
}
}
buildUis
[
b
.
Name
()]
=
ui
ui
.
Say
(
fmt
.
Sprintf
(
"%s output will be in this color."
,
b
.
Name
()))
}
// Add a newline between the color output and the actual output
env
.
Ui
()
.
Say
(
""
)
log
.
Printf
(
"Build debug mode: %v"
,
cfgDebug
)
log
.
Printf
(
"Force build: %v"
,
cfgForce
)
// Set the debug and force mode and prepare all the builds
for
_
,
b
:=
range
builds
{
log
.
Printf
(
"Preparing build: %s"
,
b
.
Name
())
b
.
SetDebug
(
cfgDebug
)
b
.
SetForce
(
cfgForce
)
warnings
,
err
:=
b
.
Prepare
()
if
err
!=
nil
{
env
.
Ui
()
.
Error
(
err
.
Error
())
return
1
}
if
len
(
warnings
)
>
0
{
ui
:=
buildUis
[
b
.
Name
()]
ui
.
Say
(
fmt
.
Sprintf
(
"Warnings for build '%s':
\n
"
,
b
.
Name
()))
for
_
,
warning
:=
range
warnings
{
ui
.
Say
(
fmt
.
Sprintf
(
"* %s"
,
warning
))
}
ui
.
Say
(
""
)
}
}
// Run all the builds in parallel and wait for them to complete
var
interruptWg
,
wg
sync
.
WaitGroup
interrupted
:=
false
artifacts
:=
make
(
map
[
string
][]
packer
.
Artifact
)
errors
:=
make
(
map
[
string
]
error
)
for
_
,
b
:=
range
builds
{
// Increment the waitgroup so we wait for this item to finish properly
wg
.
Add
(
1
)
// Handle interrupts for this build
sigCh
:=
make
(
chan
os
.
Signal
,
1
)
signal
.
Notify
(
sigCh
,
os
.
Interrupt
)
defer
signal
.
Stop
(
sigCh
)
go
func
(
b
packer
.
Build
)
{
<-
sigCh
interruptWg
.
Add
(
1
)
defer
interruptWg
.
Done
()
interrupted
=
true
log
.
Printf
(
"Stopping build: %s"
,
b
.
Name
())
b
.
Cancel
()
log
.
Printf
(
"Build cancelled: %s"
,
b
.
Name
())
}(
b
)
// Run the build in a goroutine
go
func
(
b
packer
.
Build
)
{
defer
wg
.
Done
()
name
:=
b
.
Name
()
log
.
Printf
(
"Starting build run: %s"
,
name
)
ui
:=
buildUis
[
name
]
runArtifacts
,
err
:=
b
.
Run
(
ui
,
env
.
Cache
())
if
err
!=
nil
{
ui
.
Error
(
fmt
.
Sprintf
(
"Build '%s' errored: %s"
,
name
,
err
))
errors
[
name
]
=
err
}
else
{
ui
.
Say
(
fmt
.
Sprintf
(
"Build '%s' finished."
,
name
))
artifacts
[
name
]
=
runArtifacts
}
}(
b
)
if
cfgDebug
{
log
.
Printf
(
"Debug enabled, so waiting for build to finish: %s"
,
b
.
Name
())
wg
.
Wait
()
}
if
!
cfgParallel
{
log
.
Printf
(
"Parallelization disabled, waiting for build to finish: %s"
,
b
.
Name
())
wg
.
Wait
()
}
if
interrupted
{
log
.
Println
(
"Interrupted, not going to start any more builds."
)
break
}
}
// Wait for both the builds to complete and the interrupt handler,
// if it is interrupted.
log
.
Printf
(
"Waiting on builds to complete..."
)
wg
.
Wait
()
log
.
Printf
(
"Builds completed. Waiting on interrupt barrier..."
)
interruptWg
.
Wait
()
if
interrupted
{
env
.
Ui
()
.
Say
(
"Cleanly cancelled builds after being interrupted."
)
return
1
}
if
len
(
errors
)
>
0
{
env
.
Ui
()
.
Machine
(
"error-count"
,
strconv
.
FormatInt
(
int64
(
len
(
errors
)),
10
))
env
.
Ui
()
.
Error
(
"
\n
==> Some builds didn't complete successfully and had errors:"
)
for
name
,
err
:=
range
errors
{
// Create a UI for the machine readable stuff to be targetted
ui
:=
&
packer
.
TargettedUi
{
Target
:
name
,
Ui
:
env
.
Ui
(),
}
ui
.
Machine
(
"error"
,
err
.
Error
())
env
.
Ui
()
.
Error
(
fmt
.
Sprintf
(
"--> %s: %s"
,
name
,
err
))
}
}
if
len
(
artifacts
)
>
0
{
env
.
Ui
()
.
Say
(
"
\n
==> Builds finished. The artifacts of successful builds are:"
)
for
name
,
buildArtifacts
:=
range
artifacts
{
// Create a UI for the machine readable stuff to be targetted
ui
:=
&
packer
.
TargettedUi
{
Target
:
name
,
Ui
:
env
.
Ui
(),
}
// Machine-readable helpful
ui
.
Machine
(
"artifact-count"
,
strconv
.
FormatInt
(
int64
(
len
(
buildArtifacts
)),
10
))
for
i
,
artifact
:=
range
buildArtifacts
{
var
message
bytes
.
Buffer
fmt
.
Fprintf
(
&
message
,
"--> %s: "
,
name
)
if
artifact
!=
nil
{
fmt
.
Fprintf
(
&
message
,
artifact
.
String
())
}
else
{
fmt
.
Fprint
(
&
message
,
"<nothing>"
)
}
iStr
:=
strconv
.
FormatInt
(
int64
(
i
),
10
)
if
artifact
!=
nil
{
ui
.
Machine
(
"artifact"
,
iStr
,
"builder-id"
,
artifact
.
BuilderId
())
ui
.
Machine
(
"artifact"
,
iStr
,
"id"
,
artifact
.
Id
())
ui
.
Machine
(
"artifact"
,
iStr
,
"string"
,
artifact
.
String
())
files
:=
artifact
.
Files
()
ui
.
Machine
(
"artifact"
,
iStr
,
"files-count"
,
strconv
.
FormatInt
(
int64
(
len
(
files
)),
10
))
for
fi
,
file
:=
range
files
{
fiStr
:=
strconv
.
FormatInt
(
int64
(
fi
),
10
)
ui
.
Machine
(
"artifact"
,
iStr
,
"file"
,
fiStr
,
file
)
}
}
else
{
ui
.
Machine
(
"artifact"
,
iStr
,
"nil"
)
}
ui
.
Machine
(
"artifact"
,
iStr
,
"end"
)
env
.
Ui
()
.
Say
(
message
.
String
())
}
}
}
else
{
env
.
Ui
()
.
Say
(
"
\n
==> Builds finished but no artifacts were created."
)
}
if
len
(
errors
)
>
0
{
// If any errors occurred, exit with a non-zero exit status
return
1
}
return
0
}
func
(
Command
)
Synopsis
()
string
{
return
"build image(s) from template"
}
command/build/command_test.go
deleted
100644 → 0
View file @
96b0ec53
package
build
import
(
"bytes"
"github.com/mitchellh/packer/packer"
"testing"
)
func
testEnvironment
()
packer
.
Environment
{
config
:=
packer
.
DefaultEnvironmentConfig
()
config
.
Ui
=
&
packer
.
BasicUi
{
Reader
:
new
(
bytes
.
Buffer
),
Writer
:
new
(
bytes
.
Buffer
),
}
env
,
err
:=
packer
.
NewEnvironment
(
config
)
if
err
!=
nil
{
panic
(
err
)
}
return
env
}
func
TestCommand_Implements
(
t
*
testing
.
T
)
{
var
_
packer
.
Command
=
new
(
Command
)
}
func
TestCommand_Run_NoArgs
(
t
*
testing
.
T
)
{
command
:=
new
(
Command
)
result
:=
command
.
Run
(
testEnvironment
(),
make
([]
string
,
0
))
if
result
!=
1
{
t
.
Fatalf
(
"bad: %d"
,
result
)
}
}
func
TestCommand_Run_MoreThanOneArg
(
t
*
testing
.
T
)
{
command
:=
new
(
Command
)
args
:=
[]
string
{
"one"
,
"two"
}
result
:=
command
.
Run
(
testEnvironment
(),
args
)
if
result
!=
1
{
t
.
Fatalf
(
"bad: %d"
,
result
)
}
}
func
TestCommand_Run_MissingFile
(
t
*
testing
.
T
)
{
command
:=
new
(
Command
)
args
:=
[]
string
{
"i-better-not-exist"
}
result
:=
command
.
Run
(
testEnvironment
(),
args
)
if
result
!=
1
{
t
.
Fatalf
(
"bad: %d"
,
result
)
}
}
command/build/help.go
deleted
100644 → 0
View file @
96b0ec53
package
build
const
helpText
=
`
Usage: packer build [options] TEMPLATE
Will execute multiple builds in parallel as defined in the template.
The various artifacts created by the template will be outputted.
Options:
-debug Debug mode enabled for builds
-force Force a build to continue if artifacts exist, deletes existing artifacts
-machine-readable Machine-readable output
-except=foo,bar,baz Build all builds other than these
-only=foo,bar,baz Only build the given builds by name
-parallel=false Disable parallelization (on by default)
-var 'key=value' Variable for templates, can be used multiple times.
-var-file=path JSON file containing user variables.
`
command/inspect
/command
.go
→
command/inspect.go
View file @
8054e66d
package
inspect
package
command
import
(
"flag"
...
...
@@ -9,17 +9,17 @@ import (
"strings"
)
type
Command
struct
{}
func
(
Command
)
Help
()
string
{
return
strings
.
TrimSpace
(
helpText
)
type
InspectCommand
struct
{
Meta
}
func
(
c
Command
)
Synopsis
()
string
{
return
"see components of a template"
}
func
(
c
*
InspectCommand
)
Run
(
args
[]
string
)
int
{
env
,
err
:=
c
.
Meta
.
Environment
()
if
err
!=
nil
{
c
.
Ui
.
Error
(
fmt
.
Sprintf
(
"Error initializing environment: %s"
,
err
))
return
1
}
func
(
c
Command
)
Run
(
env
packer
.
Environment
,
args
[]
string
)
int
{
flags
:=
flag
.
NewFlagSet
(
"inspect"
,
flag
.
ContinueOnError
)
flags
.
Usage
=
func
()
{
env
.
Ui
()
.
Say
(
c
.
Help
())
}
if
err
:=
flags
.
Parse
(
args
);
err
!=
nil
{
...
...
@@ -148,3 +148,23 @@ func (c Command) Run(env packer.Environment, args []string) int {
return
0
}
func
(
*
InspectCommand
)
Help
()
string
{
helpText
:=
`
Usage: packer inspect TEMPLATE
Inspects a template, parsing and outputting the components a template
defines. This does not validate the contents of a template (other than
basic syntax by necessity).
Options:
-machine-readable Machine-readable output
`
return
strings
.
TrimSpace
(
helpText
)
}
func
(
c
*
InspectCommand
)
Synopsis
()
string
{
return
"see components of a template"
}
command/inspect/command_test.go
deleted
100644 → 0
View file @
96b0ec53
package
inspect
import
(
"github.com/mitchellh/packer/packer"
"testing"
)
func
TestCommand_Impl
(
t
*
testing
.
T
)
{
var
raw
interface
{}
raw
=
new
(
Command
)
if
_
,
ok
:=
raw
.
(
packer
.
Command
);
!
ok
{
t
.
Fatalf
(
"must be a Command"
)
}
}
command/inspect/help.go
deleted
100644 → 0
View file @
96b0ec53
package
inspect
const
helpText
=
`
Usage: packer inspect TEMPLATE
Inspects a template, parsing and outputting the components a template
defines. This does not validate the contents of a template (other than
basic syntax by necessity).
Options:
-machine-readable Machine-readable output
`
command/validate
/command
.go
→
command/validate.go
View file @
8054e66d
package
validate
package
command
import
(
"flag"
...
...
@@ -9,16 +9,20 @@ import (
"strings"
)
type
Command
byte
func
(
Command
)
Help
()
string
{
return
strings
.
TrimSpace
(
helpString
)
type
ValidateCommand
struct
{
Meta
}
func
(
c
Command
)
Run
(
env
packer
.
Environment
,
args
[]
string
)
int
{
func
(
c
*
ValidateCommand
)
Run
(
args
[]
string
)
int
{
var
cfgSyntaxOnly
bool
buildOptions
:=
new
(
cmdcommon
.
BuildOptions
)
env
,
err
:=
c
.
Meta
.
Environment
()
if
err
!=
nil
{
c
.
Ui
.
Error
(
fmt
.
Sprintf
(
"Error initializing environment: %s"
,
err
))
return
1
}
cmdFlags
:=
flag
.
NewFlagSet
(
"validate"
,
flag
.
ContinueOnError
)
cmdFlags
.
Usage
=
func
()
{
env
.
Ui
()
.
Say
(
c
.
Help
())
}
cmdFlags
.
BoolVar
(
&
cfgSyntaxOnly
,
"syntax-only"
,
false
,
"check syntax only"
)
...
...
@@ -123,6 +127,29 @@ func (c Command) Run(env packer.Environment, args []string) int {
return
0
}
func
(
Command
)
Synopsis
()
string
{
func
(
*
ValidateCommand
)
Help
()
string
{
helpText
:=
`
Usage: packer validate [options] TEMPLATE
Checks the template is valid by parsing the template and also
checking the configuration with the various builders, provisioners, etc.
If it is not valid, the errors will be shown and the command will exit
with a non-zero exit status. If it is valid, it will exit with a zero
exit status.
Options:
-syntax-only Only check syntax. Do not verify config of the template.
-except=foo,bar,baz Validate all builds other than these
-only=foo,bar,baz Validate only these builds
-var 'key=value' Variable for templates, can be used multiple times.
-var-file=path JSON file containing user variables.
`
return
strings
.
TrimSpace
(
helpText
)
}
func
(
*
ValidateCommand
)
Synopsis
()
string
{
return
"check that a template is valid"
}
command/validate/command_test.go
deleted
100644 → 0
View file @
96b0ec53
package
validate
import
(
"github.com/mitchellh/packer/packer"
"testing"
)
func
TestCommand_Impl
(
t
*
testing
.
T
)
{
var
raw
interface
{}
raw
=
new
(
Command
)
if
_
,
ok
:=
raw
.
(
packer
.
Command
);
!
ok
{
t
.
Fatalf
(
"must be a Command"
)
}
}
command/validate/help.go
deleted
100644 → 0
View file @
96b0ec53
package
validate
const
helpString
=
`
Usage: packer validate [options] TEMPLATE
Checks the template is valid by parsing the template and also
checking the configuration with the various builders, provisioners, etc.
If it is not valid, the errors will be shown and the command will exit
with a non-zero exit status. If it is valid, it will exit with a zero
exit status.
Options:
-syntax-only Only check syntax. Do not verify config of the template.
-except=foo,bar,baz Validate all builds other than these
-only=foo,bar,baz Validate only these builds
-var 'key=value' Variable for templates, can be used multiple times.
-var-file=path JSON file containing user variables.
`
commands.go
View file @
8054e66d
...
...
@@ -18,16 +18,13 @@ const ErrorPrefix = "e:"
const
OutputPrefix
=
"o:"
func
init
()
{
Ui
=
&
cli
.
BasicUi
{
Writer
:
os
.
Stdout
}
/*
Ui = &cli.PrefixedUi{
AskPrefix: OutputPrefix,
OutputPrefix: OutputPrefix,
InfoPrefix: OutputPrefix,
ErrorPrefix: ErrorPrefix,
Ui: &cli.BasicUi{Writer: os.Stdout},
}
*/
Ui
=
&
cli
.
PrefixedUi
{
AskPrefix
:
OutputPrefix
,
OutputPrefix
:
OutputPrefix
,
InfoPrefix
:
OutputPrefix
,
ErrorPrefix
:
ErrorPrefix
,
Ui
:
&
cli
.
BasicUi
{
Writer
:
os
.
Stdout
},
}
meta
:=
command
.
Meta
{
EnvConfig
:
&
EnvConfig
,
...
...
@@ -40,6 +37,18 @@ func init() {
Meta
:
meta
,
},
nil
},
"inspect"
:
func
()
(
cli
.
Command
,
error
)
{
return
&
command
.
InspectCommand
{
Meta
:
meta
,
},
nil
},
"validate"
:
func
()
(
cli
.
Command
,
error
)
{
return
&
command
.
ValidateCommand
{
Meta
:
meta
,
},
nil
},
}
}
...
...
log.go
0 → 100644
View file @
8054e66d
package
main
import
(
"io"
"os"
)
// These are the environmental variables that determine if we log, and if
// we log whether or not the log should go to a file.
const
EnvLog
=
"PACKER_LOG"
//Set to True
const
EnvLogFile
=
"PACKER_LOG_PATH"
//Set to a file
// logOutput determines where we should send logs (if anywhere).
func
logOutput
()
(
logOutput
io
.
Writer
,
err
error
)
{
logOutput
=
nil
if
os
.
Getenv
(
EnvLog
)
!=
""
{
logOutput
=
os
.
Stderr
if
logPath
:=
os
.
Getenv
(
EnvLogFile
);
logPath
!=
""
{
var
err
error
logOutput
,
err
=
os
.
Create
(
logPath
)
if
err
!=
nil
{
return
nil
,
err
}
}
}
return
}
packer.go
View file @
8054e66d
...
...
@@ -9,11 +9,13 @@ import (
"os"
"path/filepath"
"runtime"
"sync"
"github.com/mitchellh/cli"
"github.com/mitchellh/packer/packer"
"github.com/mitchellh/packer/packer/plugin"
"github.com/mitchellh/panicwrap"
"github.com/mitchellh/prefixedio"
)
func
main
()
{
...
...
@@ -25,58 +27,77 @@ func main() {
// realMain is executed from main and returns the exit status to exit with.
func
realMain
()
int
{
// If there is no explicit number of Go threads to use, then set it
if
os
.
Getenv
(
"GOMAXPROCS"
)
==
""
{
runtime
.
GOMAXPROCS
(
runtime
.
NumCPU
())
}
var
wrapConfig
panicwrap
.
WrapConfig
// Determine where logs should go in general (requested by the user)
logWriter
,
err
:=
logOutput
()
if
err
!=
nil
{
fmt
.
Fprintf
(
os
.
Stderr
,
"Couldn't setup log output: %s"
,
err
)
return
1
}
if
!
panicwrap
.
Wrapped
(
&
wrapConfig
)
{
// Determine where logs should go in general (requested by the user)
logWriter
,
err
:=
logOutput
()
if
err
!=
nil
{
fmt
.
Fprintf
(
os
.
Stderr
,
"Couldn't setup log output: %s"
,
err
)
return
1
}
if
logWriter
==
nil
{
logWriter
=
ioutil
.
Discard
}
// We also always send logs to a temporary file that we use in case
// there is a panic. Otherwise, we delete it.
logTempFile
,
err
:=
ioutil
.
TempFile
(
""
,
"packer-log"
)
if
err
!=
nil
{
fmt
.
Fprintf
(
os
.
Stderr
,
"Couldn't setup logging tempfile: %s"
,
err
)
return
1
}
defer
os
.
Remove
(
logTempFile
.
Name
())
defer
logTempFile
.
Close
()
// We always send logs to a temporary file that we use in case
// there is a panic. Otherwise, we delete it.
logTempFile
,
err
:=
ioutil
.
TempFile
(
""
,
"packer-log"
)
if
err
!=
nil
{
fmt
.
Fprintf
(
os
.
Stderr
,
"Couldn't setup logging tempfile: %s"
,
err
)
return
1
}
defer
os
.
Remove
(
logTempFile
.
Name
())
defer
logTempFile
.
Close
()
// Tell the logger to log to this file
os
.
Setenv
(
EnvLog
,
""
)
os
.
Setenv
(
EnvLogFile
,
""
)
// Setup the prefixed readers that send data properly to
// stdout/stderr.
doneCh
:=
make
(
chan
struct
{})
outR
,
outW
:=
io
.
Pipe
()
go
copyOutput
(
outR
,
doneCh
)
// Create the configuration for panicwrap and wrap our executable
wrapConfig
.
Handler
=
panicHandler
(
logTempFile
)
wrapConfig
.
Writer
=
io
.
MultiWriter
(
logTempFile
,
logWriter
)
wrapConfig
.
Stdout
=
outW
exitStatus
,
err
:=
panicwrap
.
Wrap
(
&
wrapConfig
)
if
err
!=
nil
{
fmt
.
Fprintf
(
os
.
Stderr
,
"Couldn't start Packer: %s"
,
err
)
return
1
}
// Reset the log variables to minimize work in the subprocess
os
.
Setenv
(
"PACKER_LOG"
,
""
)
os
.
Setenv
(
"PACKER_LOG_FILE"
,
""
)
// If >= 0, we're the parent, so just exit
if
exitStatus
>=
0
{
// Close the stdout writer so that our copy process can finish
outW
.
Close
()
// Create the configuration for panicwrap and wrap our executable
wrapConfig
:=
&
panicwrap
.
WrapConfig
{
Handler
:
panicHandler
(
logTempFile
),
Writer
:
io
.
MultiWriter
(
logTempFile
,
logWriter
),
}
// Wait for the output copying to finish
<-
doneCh
exitStatus
,
err
:=
panicwrap
.
Wrap
(
wrapConfig
)
if
err
!=
nil
{
fmt
.
Fprintf
(
os
.
Stderr
,
"Couldn't start Packer: %s"
,
err
)
return
1
}
return
exitStatus
}
if
exitStatus
>=
0
{
return
exitStatus
// We're the child, so just close the tempfile we made in order to
// save file handles since the tempfile is only used by the parent.
logTempFile
.
Close
()
}
// We're the child, so just close the tempfile we made in order to
// save file handles since the tempfile is only used by the parent.
logTempFile
.
Close
()
// Call the real main
return
wrappedMain
()
}
// 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
(
...
...
@@ -220,20 +241,44 @@ func loadConfig() (*config, error) {
return
&
config
,
nil
}
// logOutput determines where we should send logs (if anywhere).
func
logOutput
()
(
logOutput
io
.
Writer
,
err
error
)
{
logOutput
=
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
{
return
nil
,
err
}
}
// copyOutput uses output prefixes to determine whether data on stdout
// should go to stdout or stderr. This is due to panicwrap using stderr
// as the log and error channel.
func
copyOutput
(
r
io
.
Reader
,
doneCh
chan
<-
struct
{})
{
defer
close
(
doneCh
)
pr
,
err
:=
prefixedio
.
NewReader
(
r
)
if
err
!=
nil
{
panic
(
err
)
}
stderrR
,
err
:=
pr
.
Prefix
(
ErrorPrefix
)
if
err
!=
nil
{
panic
(
err
)
}
stdoutR
,
err
:=
pr
.
Prefix
(
OutputPrefix
)
if
err
!=
nil
{
panic
(
err
)
}
defaultR
,
err
:=
pr
.
Prefix
(
""
)
if
err
!=
nil
{
panic
(
err
)
}
return
var
wg
sync
.
WaitGroup
wg
.
Add
(
3
)
go
func
()
{
defer
wg
.
Done
()
io
.
Copy
(
os
.
Stderr
,
stderrR
)
}()
go
func
()
{
defer
wg
.
Done
()
io
.
Copy
(
os
.
Stdout
,
stdoutR
)
}()
go
func
()
{
defer
wg
.
Done
()
io
.
Copy
(
os
.
Stdout
,
defaultR
)
}()
wg
.
Wait
()
}
plugin/command-build/main.go
deleted
100644 → 0
View file @
96b0ec53
package
main
import
(
"github.com/mitchellh/packer/command/build"
"github.com/mitchellh/packer/packer/plugin"
)
func
main
()
{
server
,
err
:=
plugin
.
Server
()
if
err
!=
nil
{
panic
(
err
)
}
server
.
RegisterCommand
(
new
(
build
.
Command
))
server
.
Serve
()
}
plugin/command-build/main_test.go
deleted
100644 → 0
View file @
96b0ec53
package
main
plugin/command-inspect/main.go
deleted
100644 → 0
View file @
96b0ec53
package
main
import
(
"github.com/mitchellh/packer/command/inspect"
"github.com/mitchellh/packer/packer/plugin"
)
func
main
()
{
server
,
err
:=
plugin
.
Server
()
if
err
!=
nil
{
panic
(
err
)
}
server
.
RegisterCommand
(
new
(
inspect
.
Command
))
server
.
Serve
()
}
plugin/command-inspect/main_test.go
deleted
100644 → 0
View file @
96b0ec53
package
main
plugin/command-validate/main.go
deleted
100644 → 0
View file @
96b0ec53
package
main
import
(
"github.com/mitchellh/packer/command/validate"
"github.com/mitchellh/packer/packer/plugin"
)
func
main
()
{
server
,
err
:=
plugin
.
Server
()
if
err
!=
nil
{
panic
(
err
)
}
server
.
RegisterCommand
(
new
(
validate
.
Command
))
server
.
Serve
()
}
plugin/command-validate/main_test.go
deleted
100644 → 0
View file @
96b0ec53
package
main
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment