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
fbc15510
Commit
fbc15510
authored
Oct 28, 2014
by
Mitchell Hashimoto
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
command/push: partially implemented, tests
parent
84c83447
Changes
6
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
240 additions
and
2 deletions
+240
-2
command/command_test.go
command/command_test.go
+15
-0
command/push.go
command/push.go
+92
-2
command/push_test.go
command/push_test.go
+122
-0
command/test-fixtures/push-no-name/template.json
command/test-fixtures/push-no-name/template.json
+3
-0
command/test-fixtures/push/template.json
command/test-fixtures/push/template.json
+7
-0
packer/template.go
packer/template.go
+1
-0
No files found.
command/command_test.go
View file @
fbc15510
package
command
import
(
"path/filepath"
"testing"
"github.com/mitchellh/cli"
)
const
fixturesDir
=
"./test-fixtures"
func
fatalCommand
(
t
*
testing
.
T
,
m
Meta
)
{
ui
:=
m
.
Ui
.
(
*
cli
.
MockUi
)
t
.
Fatalf
(
"Bad exit code.
\n\n
Stdout:
\n\n
%s
\n\n
Stderr:
\n\n
%s"
,
ui
.
OutputWriter
.
String
(),
ui
.
ErrorWriter
.
String
())
}
func
testFixture
(
n
string
)
string
{
return
filepath
.
Join
(
fixturesDir
,
n
)
}
func
testMeta
(
t
*
testing
.
T
)
Meta
{
return
Meta
{
Ui
:
new
(
cli
.
MockUi
),
...
...
command/push.go
View file @
fbc15510
...
...
@@ -3,18 +3,30 @@ package command
import
(
"flag"
"fmt"
"io"
"path/filepath"
"strings"
"github.com/hashicorp/harmony-go/archive"
"github.com/mitchellh/packer/packer"
)
// archiveTemplateEntry is the name the template always takes within the slug.
const
archiveTemplateEntry
=
".packer-template.json"
type
PushCommand
struct
{
Meta
// For tests:
uploadFn
func
(
io
.
Reader
,
*
uploadOpts
)
(
<-
chan
struct
{},
<-
chan
error
,
error
)
}
func
(
c
*
PushCommand
)
Run
(
args
[]
string
)
int
{
var
token
string
f
:=
flag
.
NewFlagSet
(
"push"
,
flag
.
ContinueOnError
)
f
.
Usage
=
func
()
{
c
.
Ui
.
Error
(
c
.
Help
())
}
f
.
StringVar
(
&
token
,
"token"
,
""
,
"token"
)
if
err
:=
f
.
Parse
(
args
);
err
!=
nil
{
return
1
}
...
...
@@ -32,8 +44,66 @@ func (c *PushCommand) Run(args []string) int {
return
1
}
// TODO: validate the template
println
(
tpl
.
Push
.
Name
)
// Validate some things
if
tpl
.
Push
.
Name
==
""
{
c
.
Ui
.
Error
(
fmt
.
Sprintf
(
"The 'push' section must be specified in the template with
\n
"
+
"at least the 'name' option set."
))
return
1
}
// Build the archiving options
var
opts
archive
.
ArchiveOpts
opts
.
Include
=
tpl
.
Push
.
Include
opts
.
Exclude
=
tpl
.
Push
.
Exclude
opts
.
VCS
=
tpl
.
Push
.
VCS
opts
.
Extra
=
map
[
string
]
string
{
archiveTemplateEntry
:
args
[
0
],
}
// Determine the path we're archiving
path
:=
tpl
.
Push
.
BaseDir
if
path
==
""
{
path
,
err
=
filepath
.
Abs
(
args
[
0
])
if
err
!=
nil
{
c
.
Ui
.
Error
(
fmt
.
Sprintf
(
"Error determining path to archive: %s"
,
err
))
return
1
}
path
=
filepath
.
Dir
(
path
)
}
// Build the upload options
var
uploadOpts
uploadOpts
uploadOpts
.
Slug
=
tpl
.
Push
.
Name
uploadOpts
.
Token
=
token
// Start the archiving process
r
,
archiveErrCh
,
err
:=
archive
.
Archive
(
path
,
&
opts
)
if
err
!=
nil
{
c
.
Ui
.
Error
(
fmt
.
Sprintf
(
"Error archiving: %s"
,
err
))
return
1
}
// Start the upload process
doneCh
,
uploadErrCh
,
err
:=
c
.
upload
(
r
,
&
uploadOpts
)
if
err
!=
nil
{
c
.
Ui
.
Error
(
fmt
.
Sprintf
(
"Error starting upload: %s"
,
err
))
return
1
}
err
=
nil
select
{
case
err
=
<-
archiveErrCh
:
err
=
fmt
.
Errorf
(
"Error archiving: %s"
,
err
)
case
err
=
<-
uploadErrCh
:
err
=
fmt
.
Errorf
(
"Error uploading: %s"
,
err
)
case
<-
doneCh
:
}
if
err
!=
nil
{
c
.
Ui
.
Error
(
err
.
Error
())
return
1
}
return
0
}
...
...
@@ -45,6 +115,11 @@ Usage: packer push [options] TEMPLATE
Push the template and the files it needs to a Packer build service.
This will not initiate any builds, it will only update the templates
used for builds.
Options:
-token=<token> Access token to use to upload. If blank, the
TODO environmental variable will be used.
`
return
strings
.
TrimSpace
(
helpText
)
...
...
@@ -53,3 +128,18 @@ Usage: packer push [options] TEMPLATE
func
(
*
PushCommand
)
Synopsis
()
string
{
return
"push template files to a Packer build service"
}
func
(
c
*
PushCommand
)
upload
(
r
io
.
Reader
,
opts
*
uploadOpts
)
(
<-
chan
struct
{},
<-
chan
error
,
error
)
{
if
c
.
uploadFn
!=
nil
{
return
c
.
uploadFn
(
r
,
opts
)
}
return
nil
,
nil
,
nil
}
type
uploadOpts
struct
{
URL
string
Slug
string
Token
string
}
command/push_test.go
View file @
fbc15510
package
command
import
(
"fmt"
"archive/tar"
"bytes"
"compress/gzip"
"io"
"path/filepath"
"reflect"
"sort"
"testing"
)
...
...
@@ -19,3 +27,117 @@ func TestPush_multiArgs(t *testing.T) {
t
.
Fatalf
(
"bad: %#v"
,
code
)
}
}
func
TestPush
(
t
*
testing
.
T
)
{
var
actualR
io
.
Reader
var
actualOpts
*
uploadOpts
uploadFn
:=
func
(
r
io
.
Reader
,
opts
*
uploadOpts
)
(
<-
chan
struct
{},
<-
chan
error
,
error
)
{
actualR
=
r
actualOpts
=
opts
doneCh
:=
make
(
chan
struct
{})
close
(
doneCh
)
return
doneCh
,
nil
,
nil
}
c
:=
&
PushCommand
{
Meta
:
testMeta
(
t
),
uploadFn
:
uploadFn
,
}
args
:=
[]
string
{
filepath
.
Join
(
testFixture
(
"push"
),
"template.json"
)}
if
code
:=
c
.
Run
(
args
);
code
!=
0
{
fatalCommand
(
t
,
c
.
Meta
)
}
actual
:=
testArchive
(
t
,
actualR
)
expected
:=
[]
string
{
archiveTemplateEntry
,
"template.json"
,
}
if
!
reflect
.
DeepEqual
(
actual
,
expected
)
{
t
.
Fatalf
(
"bad: %#v"
,
actual
)
}
}
func
TestPush_noName
(
t
*
testing
.
T
)
{
uploadFn
:=
func
(
r
io
.
Reader
,
opts
*
uploadOpts
)
(
<-
chan
struct
{},
<-
chan
error
,
error
)
{
return
nil
,
nil
,
nil
}
c
:=
&
PushCommand
{
Meta
:
testMeta
(
t
),
uploadFn
:
uploadFn
,
}
args
:=
[]
string
{
filepath
.
Join
(
testFixture
(
"push-no-name"
),
"template.json"
)}
if
code
:=
c
.
Run
(
args
);
code
!=
1
{
fatalCommand
(
t
,
c
.
Meta
)
}
}
func
TestPush_uploadError
(
t
*
testing
.
T
)
{
uploadFn
:=
func
(
r
io
.
Reader
,
opts
*
uploadOpts
)
(
<-
chan
struct
{},
<-
chan
error
,
error
)
{
return
nil
,
nil
,
fmt
.
Errorf
(
"bad"
)
}
c
:=
&
PushCommand
{
Meta
:
testMeta
(
t
),
uploadFn
:
uploadFn
,
}
args
:=
[]
string
{
filepath
.
Join
(
testFixture
(
"push"
),
"template.json"
)}
if
code
:=
c
.
Run
(
args
);
code
!=
1
{
fatalCommand
(
t
,
c
.
Meta
)
}
}
func
TestPush_uploadErrorCh
(
t
*
testing
.
T
)
{
uploadFn
:=
func
(
r
io
.
Reader
,
opts
*
uploadOpts
)
(
<-
chan
struct
{},
<-
chan
error
,
error
)
{
errCh
:=
make
(
chan
error
,
1
)
errCh
<-
fmt
.
Errorf
(
"bad"
)
return
nil
,
errCh
,
nil
}
c
:=
&
PushCommand
{
Meta
:
testMeta
(
t
),
uploadFn
:
uploadFn
,
}
args
:=
[]
string
{
filepath
.
Join
(
testFixture
(
"push"
),
"template.json"
)}
if
code
:=
c
.
Run
(
args
);
code
!=
1
{
fatalCommand
(
t
,
c
.
Meta
)
}
}
func
testArchive
(
t
*
testing
.
T
,
r
io
.
Reader
)
[]
string
{
// Finish the archiving process in-memory
var
buf
bytes
.
Buffer
if
_
,
err
:=
io
.
Copy
(
&
buf
,
r
);
err
!=
nil
{
t
.
Fatalf
(
"err: %s"
,
err
)
}
gzipR
,
err
:=
gzip
.
NewReader
(
&
buf
)
if
err
!=
nil
{
t
.
Fatalf
(
"err: %s"
,
err
)
}
tarR
:=
tar
.
NewReader
(
gzipR
)
// Read all the entries
result
:=
make
([]
string
,
0
,
5
)
for
{
hdr
,
err
:=
tarR
.
Next
()
if
err
==
io
.
EOF
{
break
}
if
err
!=
nil
{
t
.
Fatalf
(
"err: %s"
,
err
)
}
result
=
append
(
result
,
hdr
.
Name
)
}
sort
.
Strings
(
result
)
return
result
}
command/test-fixtures/push-no-name/template.json
0 → 100644
View file @
fbc15510
{
"builders"
:
[{
"type"
:
"dummy"
}]
}
command/test-fixtures/push/template.json
0 → 100644
View file @
fbc15510
{
"builders"
:
[{
"type"
:
"dummy"
}],
"push"
:
{
"name"
:
"foo/bar"
}
}
packer/template.go
View file @
fbc15510
...
...
@@ -45,6 +45,7 @@ type Template struct {
// PushConfig is the configuration structure for the push settings.
type
PushConfig
struct
{
Name
string
BaseDir
string
Include
[]
string
Exclude
[]
string
VCS
bool
...
...
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