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
2264f7d8
Commit
2264f7d8
authored
Dec 20, 2013
by
Mitchell Hashimoto
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
packer: PausedProvisioner
parent
ca70cd8f
Changes
4
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
176 additions
and
6 deletions
+176
-6
packer/provisioner.go
packer/provisioner.go
+77
-0
packer/provisioner_mock.go
packer/provisioner_mock.go
+7
-5
packer/provisioner_test.go
packer/provisioner_test.go
+91
-0
packer/template_test.go
packer/template_test.go
+1
-1
No files found.
packer/provisioner.go
View file @
2264f7d8
...
...
@@ -2,6 +2,7 @@ package packer
import
(
"sync"
"time"
)
// A provisioner is responsible for installing and configuring software
...
...
@@ -65,3 +66,79 @@ func (h *ProvisionHook) Cancel() {
h
.
runningProvisioner
.
Cancel
()
}
}
// PausedProvisioner is a Provisioner implementation that pauses before
// the provisioner is actually run.
type
PausedProvisioner
struct
{
PauseBefore
time
.
Duration
Provisioner
Provisioner
cancelCh
chan
struct
{}
doneCh
chan
struct
{}
lock
sync
.
Mutex
}
func
(
p
*
PausedProvisioner
)
Prepare
(
raws
...
interface
{})
error
{
return
p
.
Provisioner
.
Prepare
(
raws
...
)
}
func
(
p
*
PausedProvisioner
)
Provision
(
ui
Ui
,
comm
Communicator
)
error
{
p
.
lock
.
Lock
()
cancelCh
:=
make
(
chan
struct
{})
p
.
cancelCh
=
cancelCh
// Setup the done channel, which is trigger when we're done
doneCh
:=
make
(
chan
struct
{})
defer
close
(
doneCh
)
p
.
doneCh
=
doneCh
p
.
lock
.
Unlock
()
defer
func
()
{
p
.
lock
.
Lock
()
defer
p
.
lock
.
Unlock
()
if
p
.
cancelCh
==
cancelCh
{
p
.
cancelCh
=
nil
}
if
p
.
doneCh
==
doneCh
{
p
.
doneCh
=
nil
}
}()
// Use a select to determine if we get cancelled during the wait
select
{
case
<-
time
.
After
(
p
.
PauseBefore
)
:
case
<-
cancelCh
:
return
nil
}
provDoneCh
:=
make
(
chan
error
,
1
)
go
p
.
provision
(
provDoneCh
,
ui
,
comm
)
select
{
case
err
:=
<-
provDoneCh
:
return
err
case
<-
cancelCh
:
p
.
Provisioner
.
Cancel
()
return
<-
provDoneCh
}
}
func
(
p
*
PausedProvisioner
)
Cancel
()
{
var
doneCh
chan
struct
{}
p
.
lock
.
Lock
()
if
p
.
cancelCh
!=
nil
{
close
(
p
.
cancelCh
)
p
.
cancelCh
=
nil
}
if
p
.
doneCh
!=
nil
{
doneCh
=
p
.
doneCh
}
p
.
lock
.
Unlock
()
<-
doneCh
}
func
(
p
*
PausedProvisioner
)
provision
(
result
chan
<-
error
,
ui
Ui
,
comm
Communicator
)
{
result
<-
p
.
Provisioner
.
Provision
(
ui
,
comm
)
}
packer/provisioner_mock.go
View file @
2264f7d8
...
...
@@ -5,11 +5,12 @@ package packer
type
MockProvisioner
struct
{
ProvFunc
func
()
error
PrepCalled
bool
PrepConfigs
[]
interface
{}
ProvCalled
bool
ProvUi
Ui
CancelCalled
bool
PrepCalled
bool
PrepConfigs
[]
interface
{}
ProvCalled
bool
ProvCommunicator
Communicator
ProvUi
Ui
CancelCalled
bool
}
func
(
t
*
MockProvisioner
)
Prepare
(
configs
...
interface
{})
error
{
...
...
@@ -20,6 +21,7 @@ func (t *MockProvisioner) Prepare(configs ...interface{}) error {
func
(
t
*
MockProvisioner
)
Provision
(
ui
Ui
,
comm
Communicator
)
error
{
t
.
ProvCalled
=
true
t
.
ProvCommunicator
=
comm
t
.
ProvUi
=
ui
if
t
.
ProvFunc
==
nil
{
...
...
packer/provisioner_test.go
View file @
2264f7d8
...
...
@@ -80,3 +80,94 @@ func TestProvisionHook_cancel(t *testing.T) {
}
// TODO(mitchellh): Test that they're run in the proper order
func
TestPausedProvisioner_impl
(
t
*
testing
.
T
)
{
var
_
Provisioner
=
new
(
PausedProvisioner
)
}
func
TestPausedProvisionerPrepare
(
t
*
testing
.
T
)
{
mock
:=
new
(
MockProvisioner
)
prov
:=
&
PausedProvisioner
{
Provisioner
:
mock
,
}
prov
.
Prepare
(
42
)
if
!
mock
.
PrepCalled
{
t
.
Fatal
(
"prepare should be called"
)
}
if
mock
.
PrepConfigs
[
0
]
!=
42
{
t
.
Fatal
(
"should have proper configs"
)
}
}
func
TestPausedProvisionerProvision
(
t
*
testing
.
T
)
{
mock
:=
new
(
MockProvisioner
)
prov
:=
&
PausedProvisioner
{
Provisioner
:
mock
,
}
ui
:=
testUi
()
comm
:=
new
(
MockCommunicator
)
prov
.
Provision
(
ui
,
comm
)
if
!
mock
.
ProvCalled
{
t
.
Fatal
(
"prov should be called"
)
}
if
mock
.
ProvUi
!=
ui
{
t
.
Fatal
(
"should have proper ui"
)
}
if
mock
.
ProvCommunicator
!=
comm
{
t
.
Fatal
(
"should have proper comm"
)
}
}
func
TestPausedProvisionerProvision_waits
(
t
*
testing
.
T
)
{
mock
:=
new
(
MockProvisioner
)
prov
:=
&
PausedProvisioner
{
PauseBefore
:
50
*
time
.
Millisecond
,
Provisioner
:
mock
,
}
dataCh
:=
make
(
chan
struct
{})
mock
.
ProvFunc
=
func
()
error
{
close
(
dataCh
)
return
nil
}
go
prov
.
Provision
(
testUi
(),
new
(
MockCommunicator
))
select
{
case
<-
time
.
After
(
10
*
time
.
Millisecond
)
:
case
<-
dataCh
:
t
.
Fatal
(
"should not be called"
)
}
select
{
case
<-
time
.
After
(
100
*
time
.
Millisecond
)
:
t
.
Fatal
(
"never called"
)
case
<-
dataCh
:
}
}
func
TestPausedProvisionerCancel
(
t
*
testing
.
T
)
{
mock
:=
new
(
MockProvisioner
)
prov
:=
&
PausedProvisioner
{
Provisioner
:
mock
,
}
provCh
:=
make
(
chan
struct
{})
mock
.
ProvFunc
=
func
()
error
{
close
(
provCh
)
time
.
Sleep
(
10
*
time
.
Millisecond
)
return
nil
}
// Start provisioning and wait for it to start
go
prov
.
Provision
(
testUi
(),
new
(
MockCommunicator
))
<-
provCh
// Cancel it
prov
.
Cancel
()
if
!
mock
.
CancelCalled
{
t
.
Fatal
(
"cancel should be called"
)
}
}
packer/template_test.go
View file @
2264f7d8
...
...
@@ -473,7 +473,7 @@ func TestParseTemplate_ProvisionerPauseBefore(t *testing.T) {
if
result
.
Provisioners
[
0
]
.
Type
!=
"shell"
{
t
.
Fatalf
(
"bad: %#v"
,
result
.
Provisioners
[
0
]
.
Type
)
}
if
result
.
Provisioners
[
0
]
.
pauseBefore
!=
10
*
time
.
Second
{
if
result
.
Provisioners
[
0
]
.
pauseBefore
!=
10
*
time
.
Second
{
t
.
Fatalf
(
"bad: %s"
,
result
.
Provisioners
[
0
]
.
pauseBefore
)
}
}
...
...
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