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
56ec6bf7
Commit
56ec6bf7
authored
Aug 09, 2014
by
Jason A. Beranek
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
common/command/template,packer/template: fix build name ConfigTemplate processing [GH-858]
parent
a5bc5bec
Changes
4
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
396 additions
and
64 deletions
+396
-64
common/command/template.go
common/command/template.go
+22
-6
common/command/template_test.go
common/command/template_test.go
+93
-11
packer/template.go
packer/template.go
+57
-43
packer/template_test.go
packer/template_test.go
+224
-4
No files found.
common/command/template.go
View file @
56ec6bf7
...
...
@@ -66,6 +66,12 @@ func (f *BuildOptions) AllUserVars() (map[string]string, error) {
func
(
f
*
BuildOptions
)
Builds
(
t
*
packer
.
Template
,
cf
*
packer
.
ComponentFinder
)
([]
packer
.
Build
,
error
)
{
buildNames
:=
t
.
BuildNames
()
// Process the name
tpl
,
_
,
err
:=
t
.
NewConfigTemplate
()
if
err
!=
nil
{
return
nil
,
err
}
checks
:=
make
(
map
[
string
][]
string
)
checks
[
"except"
]
=
f
.
Except
checks
[
"only"
]
=
f
.
Only
...
...
@@ -73,7 +79,12 @@ func (f *BuildOptions) Builds(t *packer.Template, cf *packer.ComponentFinder) ([
for
_
,
n
:=
range
ns
{
found
:=
false
for
_
,
actual
:=
range
buildNames
{
if
actual
==
n
{
var
processed
string
processed
,
err
=
tpl
.
Process
(
actual
,
nil
)
if
err
!=
nil
{
return
nil
,
err
}
if
actual
==
n
||
processed
==
n
{
found
=
true
break
}
...
...
@@ -88,17 +99,22 @@ func (f *BuildOptions) Builds(t *packer.Template, cf *packer.ComponentFinder) ([
builds
:=
make
([]
packer
.
Build
,
0
,
len
(
buildNames
))
for
_
,
buildName
:=
range
buildNames
{
var
processedBuildName
string
processedBuildName
,
err
=
tpl
.
Process
(
buildName
,
nil
)
if
err
!=
nil
{
return
nil
,
err
}
if
len
(
f
.
Except
)
>
0
{
found
:=
false
for
_
,
except
:=
range
f
.
Except
{
if
buildName
==
except
{
if
buildName
==
except
||
processedBuildName
==
except
{
found
=
true
break
}
}
if
found
{
log
.
Printf
(
"Skipping build '%s' because specified by -except."
,
b
uildName
)
log
.
Printf
(
"Skipping build '%s' because specified by -except."
,
processedB
uildName
)
continue
}
}
...
...
@@ -106,19 +122,19 @@ func (f *BuildOptions) Builds(t *packer.Template, cf *packer.ComponentFinder) ([
if
len
(
f
.
Only
)
>
0
{
found
:=
false
for
_
,
only
:=
range
f
.
Only
{
if
buildName
==
only
{
if
buildName
==
only
||
processedBuildName
==
only
{
found
=
true
break
}
}
if
!
found
{
log
.
Printf
(
"Skipping build '%s' because not specified by -only."
,
b
uildName
)
log
.
Printf
(
"Skipping build '%s' because not specified by -only."
,
processedB
uildName
)
continue
}
}
log
.
Printf
(
"Creating build: %s"
,
b
uildName
)
log
.
Printf
(
"Creating build: %s"
,
processedB
uildName
)
build
,
err
:=
t
.
Build
(
buildName
,
cf
)
if
err
!=
nil
{
return
nil
,
fmt
.
Errorf
(
"Failed to create build '%s':
\n\n
%s"
,
buildName
,
err
)
...
...
common/command/template_test.go
View file @
56ec6bf7
...
...
@@ -7,17 +7,23 @@ import (
func
testTemplate
()
(
*
packer
.
Template
,
*
packer
.
ComponentFinder
)
{
tplData
:=
`{
"builders": [
{
"type": "foo"
},
{
"type": "bar"
}
]
}`
tpl
,
err
:=
packer
.
ParseTemplate
([]
byte
(
tplData
),
nil
)
"variables": {
"foo": null
},
"builders": [
{
"type": "foo"
},
{
"name": "{{user \"foo\"}}",
"type": "bar"
}
]
}
`
tpl
,
err
:=
packer
.
ParseTemplate
([]
byte
(
tplData
),
map
[
string
]
string
{
"foo"
:
"bar"
})
if
err
!=
nil
{
panic
(
err
)
}
...
...
@@ -59,6 +65,44 @@ func TestBuildOptionsBuilds_except(t *testing.T) {
}
}
//Test to make sure the build name pattern matches
func
TestBuildOptionsBuilds_exceptConfigTemplateRaw
(
t
*
testing
.
T
)
{
opts
:=
new
(
BuildOptions
)
opts
.
Except
=
[]
string
{
"{{user
\"
foo
\"
}}"
}
bs
,
err
:=
opts
.
Builds
(
testTemplate
())
if
err
!=
nil
{
t
.
Fatalf
(
"err: %s"
,
err
)
}
if
len
(
bs
)
!=
1
{
t
.
Fatalf
(
"bad: %d"
,
len
(
bs
))
}
if
bs
[
0
]
.
Name
()
!=
"foo"
{
t
.
Fatalf
(
"bad: %s"
,
bs
[
0
]
.
Name
())
}
}
//Test to make sure the processed build name matches
func
TestBuildOptionsBuilds_exceptConfigTemplateProcessed
(
t
*
testing
.
T
)
{
opts
:=
new
(
BuildOptions
)
opts
.
Except
=
[]
string
{
"bar"
}
bs
,
err
:=
opts
.
Builds
(
testTemplate
())
if
err
!=
nil
{
t
.
Fatalf
(
"err: %s"
,
err
)
}
if
len
(
bs
)
!=
1
{
t
.
Fatalf
(
"bad: %d"
,
len
(
bs
))
}
if
bs
[
0
]
.
Name
()
!=
"foo"
{
t
.
Fatalf
(
"bad: %s"
,
bs
[
0
]
.
Name
())
}
}
func
TestBuildOptionsBuilds_only
(
t
*
testing
.
T
)
{
opts
:=
new
(
BuildOptions
)
opts
.
Only
=
[]
string
{
"foo"
}
...
...
@@ -77,6 +121,44 @@ func TestBuildOptionsBuilds_only(t *testing.T) {
}
}
//Test to make sure the build name pattern matches
func
TestBuildOptionsBuilds_onlyConfigTemplateRaw
(
t
*
testing
.
T
)
{
opts
:=
new
(
BuildOptions
)
opts
.
Only
=
[]
string
{
"{{user
\"
foo
\"
}}"
}
bs
,
err
:=
opts
.
Builds
(
testTemplate
())
if
err
!=
nil
{
t
.
Fatalf
(
"err: %s"
,
err
)
}
if
len
(
bs
)
!=
1
{
t
.
Fatalf
(
"bad: %d"
,
len
(
bs
))
}
if
bs
[
0
]
.
Name
()
!=
"bar"
{
t
.
Fatalf
(
"bad: %s"
,
bs
[
0
]
.
Name
())
}
}
//Test to make sure the processed build name matches
func
TestBuildOptionsBuilds_onlyConfigTemplateProcessed
(
t
*
testing
.
T
)
{
opts
:=
new
(
BuildOptions
)
opts
.
Only
=
[]
string
{
"bar"
}
bs
,
err
:=
opts
.
Builds
(
testTemplate
())
if
err
!=
nil
{
t
.
Fatalf
(
"err: %s"
,
err
)
}
if
len
(
bs
)
!=
1
{
t
.
Fatalf
(
"bad: %d"
,
len
(
bs
))
}
if
bs
[
0
]
.
Name
()
!=
"bar"
{
t
.
Fatalf
(
"bad: %s"
,
bs
[
0
]
.
Name
())
}
}
func
TestBuildOptionsBuilds_exceptNonExistent
(
t
*
testing
.
T
)
{
opts
:=
new
(
BuildOptions
)
opts
.
Except
=
[]
string
{
"i-dont-exist"
}
...
...
packer/template.go
View file @
56ec6bf7
...
...
@@ -473,52 +473,13 @@ func (t *Template) Build(name string, components *ComponentFinder) (b Build, err
return
}
// Prepare the variable template processor, which is a bit unique
// because we don't allow user variable usage and we add a function
// to read from the environment.
varTpl
,
err
:=
NewConfigTemplate
()
if
err
!=
nil
{
return
nil
,
err
}
varTpl
.
Funcs
(
template
.
FuncMap
{
"env"
:
templateEnv
,
"user"
:
templateDisableUser
,
})
// Prepare the variables
var
varErrors
[]
error
variables
:=
make
(
map
[
string
]
string
)
for
k
,
v
:=
range
t
.
Variables
{
if
v
.
Required
&&
!
v
.
HasValue
{
varErrors
=
append
(
varErrors
,
fmt
.
Errorf
(
"Required user variable '%s' not set"
,
k
))
}
var
val
string
if
v
.
HasValue
{
val
=
v
.
Value
}
else
{
val
,
err
=
varTpl
.
Process
(
v
.
Default
,
nil
)
if
err
!=
nil
{
varErrors
=
append
(
varErrors
,
fmt
.
Errorf
(
"Error processing user variable '%s': %s'"
,
k
,
err
))
}
}
variables
[
k
]
=
val
}
if
len
(
varErrors
)
>
0
{
return
nil
,
&
MultiError
{
varErrors
}
}
// Process the name
tpl
,
err
:=
NewConfigTemplate
()
tpl
,
variables
,
err
:=
t
.
NewConfigTemplate
()
if
err
!=
nil
{
return
nil
,
err
}
tpl
.
UserVars
=
variables
rawName
:=
name
name
,
err
=
tpl
.
Process
(
name
,
nil
)
if
err
!=
nil
{
return
nil
,
err
...
...
@@ -552,7 +513,7 @@ func (t *Template) Build(name string, components *ComponentFinder) (b Build, err
for
_
,
rawPPs
:=
range
t
.
PostProcessors
{
current
:=
make
([]
coreBuildPostProcessor
,
0
,
len
(
rawPPs
))
for
_
,
rawPP
:=
range
rawPPs
{
if
rawPP
.
TemplateOnlyExcept
.
Skip
(
n
ame
)
{
if
rawPP
.
TemplateOnlyExcept
.
Skip
(
rawN
ame
)
{
continue
}
...
...
@@ -585,7 +546,7 @@ func (t *Template) Build(name string, components *ComponentFinder) (b Build, err
// Prepare the provisioners
provisioners
:=
make
([]
coreBuildProvisioner
,
0
,
len
(
t
.
Provisioners
))
for
_
,
rawProvisioner
:=
range
t
.
Provisioners
{
if
rawProvisioner
.
TemplateOnlyExcept
.
Skip
(
n
ame
)
{
if
rawProvisioner
.
TemplateOnlyExcept
.
Skip
(
rawN
ame
)
{
continue
}
...
...
@@ -634,6 +595,59 @@ func (t *Template) Build(name string, components *ComponentFinder) (b Build, err
return
}
//Build a ConfigTemplate object populated by the values within a
//parsed template
func
(
t
*
Template
)
NewConfigTemplate
()
(
c
*
ConfigTemplate
,
variables
map
[
string
]
string
,
err
error
)
{
// Prepare the variable template processor, which is a bit unique
// because we don't allow user variable usage and we add a function
// to read from the environment.
varTpl
,
err
:=
NewConfigTemplate
()
if
err
!=
nil
{
return
nil
,
nil
,
err
}
varTpl
.
Funcs
(
template
.
FuncMap
{
"env"
:
templateEnv
,
"user"
:
templateDisableUser
,
})
// Prepare the variables
var
varErrors
[]
error
variables
=
make
(
map
[
string
]
string
)
for
k
,
v
:=
range
t
.
Variables
{
if
v
.
Required
&&
!
v
.
HasValue
{
varErrors
=
append
(
varErrors
,
fmt
.
Errorf
(
"Required user variable '%s' not set"
,
k
))
}
var
val
string
if
v
.
HasValue
{
val
=
v
.
Value
}
else
{
val
,
err
=
varTpl
.
Process
(
v
.
Default
,
nil
)
if
err
!=
nil
{
varErrors
=
append
(
varErrors
,
fmt
.
Errorf
(
"Error processing user variable '%s': %s'"
,
k
,
err
))
}
}
variables
[
k
]
=
val
}
if
len
(
varErrors
)
>
0
{
return
nil
,
variables
,
&
MultiError
{
varErrors
}
}
// Process the name
tpl
,
err
:=
NewConfigTemplate
()
if
err
!=
nil
{
return
nil
,
variables
,
err
}
tpl
.
UserVars
=
variables
return
tpl
,
variables
,
nil
}
// TemplateOnlyExcept contains the logic required for "only" and "except"
// meta-parameters.
type
TemplateOnlyExcept
struct
{
...
...
packer/template_test.go
View file @
56ec6bf7
...
...
@@ -1165,7 +1165,62 @@ func TestTemplateBuild_exceptPP(t *testing.T) {
t
.
Fatal
(
"should have no postProcessors"
)
}
// Verify test2 has no post-processors
// Verify test2 has one post-processors
build
,
err
=
template
.
Build
(
"test2"
,
testTemplateComponentFinder
())
if
err
!=
nil
{
t
.
Fatalf
(
"err: %s"
,
err
)
}
cbuild
=
build
.
(
*
coreBuild
)
if
len
(
cbuild
.
postProcessors
)
!=
1
{
t
.
Fatalf
(
"invalid: %d"
,
len
(
cbuild
.
postProcessors
))
}
}
func
TestTemplateBuild_exceptPPConfigTemplateName
(
t
*
testing
.
T
)
{
data
:=
`
{
"variables": {
"foo": null
},
"builders": [
{
"name": "test1-{{user \"foo\"}}",
"type": "test-builder"
},
{
"name": "test2",
"type": "test-builder"
}
],
"post-processors": [
{
"type": "test-pp",
"except": ["test1-{{user \"foo\"}}"]
}
]
}
`
template
,
err
:=
ParseTemplate
([]
byte
(
data
),
map
[
string
]
string
{
"foo"
:
"bar"
})
if
err
!=
nil
{
t
.
Fatalf
(
"err: %s"
,
err
)
}
// Verify test1 has no post-processors
build
,
err
:=
template
.
Build
(
"test1-{{user
\"
foo
\"
}}"
,
testTemplateComponentFinder
())
if
err
!=
nil
{
t
.
Fatalf
(
"err: %s"
,
err
)
}
cbuild
:=
build
.
(
*
coreBuild
)
if
len
(
cbuild
.
postProcessors
)
>
0
{
t
.
Fatal
(
"should have no postProcessors"
)
}
// Verify test2 has one post-processors
build
,
err
=
template
.
Build
(
"test2"
,
testTemplateComponentFinder
())
if
err
!=
nil
{
t
.
Fatalf
(
"err: %s"
,
err
)
...
...
@@ -1245,7 +1300,62 @@ func TestTemplateBuild_exceptProv(t *testing.T) {
t
.
Fatal
(
"should have no provisioners"
)
}
// Verify test2 has no provisioners
// Verify test2 has one provisioners
build
,
err
=
template
.
Build
(
"test2"
,
testTemplateComponentFinder
())
if
err
!=
nil
{
t
.
Fatalf
(
"err: %s"
,
err
)
}
cbuild
=
build
.
(
*
coreBuild
)
if
len
(
cbuild
.
provisioners
)
!=
1
{
t
.
Fatalf
(
"invalid: %d"
,
len
(
cbuild
.
provisioners
))
}
}
func
TestTemplateBuild_exceptProvConfigTemplateName
(
t
*
testing
.
T
)
{
data
:=
`
{
"variables": {
"foo": null
},
"builders": [
{
"name": "test1-{{user \"foo\"}}",
"type": "test-builder"
},
{
"name": "test2",
"type": "test-builder"
}
],
"provisioners": [
{
"type": "test-prov",
"except": ["test1-{{user \"foo\"}}"]
}
]
}
`
template
,
err
:=
ParseTemplate
([]
byte
(
data
),
map
[
string
]
string
{
"foo"
:
"bar"
})
if
err
!=
nil
{
t
.
Fatalf
(
"err: %s"
,
err
)
}
// Verify test1 has no provisioners
build
,
err
:=
template
.
Build
(
"test1-{{user
\"
foo
\"
}}"
,
testTemplateComponentFinder
())
if
err
!=
nil
{
t
.
Fatalf
(
"err: %s"
,
err
)
}
cbuild
:=
build
.
(
*
coreBuild
)
if
len
(
cbuild
.
provisioners
)
>
0
{
t
.
Fatal
(
"should have no provisioners"
)
}
// Verify test2 has one provisioners
build
,
err
=
template
.
Build
(
"test2"
,
testTemplateComponentFinder
())
if
err
!=
nil
{
t
.
Fatalf
(
"err: %s"
,
err
)
...
...
@@ -1325,7 +1435,7 @@ func TestTemplateBuild_onlyPP(t *testing.T) {
t
.
Fatal
(
"should have no postProcessors"
)
}
// Verify test2 has
no
post-processors
// Verify test2 has
one
post-processors
build
,
err
=
template
.
Build
(
"test2"
,
testTemplateComponentFinder
())
if
err
!=
nil
{
t
.
Fatalf
(
"err: %s"
,
err
)
...
...
@@ -1337,6 +1447,61 @@ func TestTemplateBuild_onlyPP(t *testing.T) {
}
}
func
TestTemplateBuild_onlyPPConfigTemplateName
(
t
*
testing
.
T
)
{
data
:=
`
{
"variables": {
"foo": null
},
"builders": [
{
"name": "test1",
"type": "test-builder"
},
{
"name": "test2-{{user \"foo\"}}",
"type": "test-builder"
}
],
"post-processors": [
{
"type": "test-pp",
"only": ["test2-{{user \"foo\"}}"]
}
]
}
`
template
,
err
:=
ParseTemplate
([]
byte
(
data
),
map
[
string
]
string
{
"foo"
:
"bar"
})
if
err
!=
nil
{
t
.
Fatalf
(
"err: %s"
,
err
)
}
// Verify test1 has no post-processors
build
,
err
:=
template
.
Build
(
"test1"
,
testTemplateComponentFinder
())
if
err
!=
nil
{
t
.
Fatalf
(
"err: %s"
,
err
)
}
cbuild
:=
build
.
(
*
coreBuild
)
if
len
(
cbuild
.
postProcessors
)
>
0
{
t
.
Fatal
(
"should have no postProcessors"
)
}
// Verify test2 has one post-processors
build
,
err
=
template
.
Build
(
"test2-{{user
\"
foo
\"
}}"
,
testTemplateComponentFinder
())
if
err
!=
nil
{
t
.
Fatalf
(
"err: %s"
,
err
)
}
cbuild
=
build
.
(
*
coreBuild
)
if
len
(
cbuild
.
postProcessors
)
!=
1
{
t
.
Fatalf
(
"invalid: %d"
,
len
(
cbuild
.
postProcessors
))
}
}
func
TestTemplateBuild_onlyProvInvalid
(
t
*
testing
.
T
)
{
data
:=
`
{
...
...
@@ -1405,7 +1570,7 @@ func TestTemplateBuild_onlyProv(t *testing.T) {
t
.
Fatal
(
"should have no provisioners"
)
}
// Verify test2 has
no
provisioners
// Verify test2 has
one
provisioners
build
,
err
=
template
.
Build
(
"test2"
,
testTemplateComponentFinder
())
if
err
!=
nil
{
t
.
Fatalf
(
"err: %s"
,
err
)
...
...
@@ -1417,6 +1582,61 @@ func TestTemplateBuild_onlyProv(t *testing.T) {
}
}
func
TestTemplateBuild_onlyProvConfigTemplateName
(
t
*
testing
.
T
)
{
data
:=
`
{
"variables": {
"foo": null
},
"builders": [
{
"name": "test1",
"type": "test-builder"
},
{
"name": "test2-{{user \"foo\"}}",
"type": "test-builder"
}
],
"provisioners": [
{
"type": "test-prov",
"only": ["test2-{{user \"foo\"}}"]
}
]
}
`
template
,
err
:=
ParseTemplate
([]
byte
(
data
),
map
[
string
]
string
{
"foo"
:
"bar"
})
if
err
!=
nil
{
t
.
Fatalf
(
"err: %s"
,
err
)
}
// Verify test1 has no provisioners
build
,
err
:=
template
.
Build
(
"test1"
,
testTemplateComponentFinder
())
if
err
!=
nil
{
t
.
Fatalf
(
"err: %s"
,
err
)
}
cbuild
:=
build
.
(
*
coreBuild
)
if
len
(
cbuild
.
provisioners
)
>
0
{
t
.
Fatal
(
"should have no provisioners"
)
}
// Verify test2 has one provisioners
build
,
err
=
template
.
Build
(
"test2-{{user
\"
foo
\"
}}"
,
testTemplateComponentFinder
())
if
err
!=
nil
{
t
.
Fatalf
(
"err: %s"
,
err
)
}
cbuild
=
build
.
(
*
coreBuild
)
if
len
(
cbuild
.
provisioners
)
!=
1
{
t
.
Fatalf
(
"invalid: %d"
,
len
(
cbuild
.
provisioners
))
}
}
func
TestTemplate_Build_ProvisionerOverride
(
t
*
testing
.
T
)
{
data
:=
`
{
...
...
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