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
7a397580
Commit
7a397580
authored
Jun 13, 2015
by
Mitchell Hashimoto
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
helper/communicator: WinRM stuff
parent
0c0f8766
Changes
4
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
202 additions
and
20 deletions
+202
-20
communicator/winrm/communicator.go
communicator/winrm/communicator.go
+7
-7
helper/communicator/config.go
helper/communicator/config.go
+53
-13
helper/communicator/step_connect_winrm.go
helper/communicator/step_connect_winrm.go
+134
-0
helper/communicator/winrm.go
helper/communicator/winrm.go
+8
-0
No files found.
communicator/winrm/communicator.go
View file @
7a397580
...
...
@@ -4,6 +4,7 @@ import (
"fmt"
"io"
"log"
"os"
"github.com/masterzen/winrm/winrm"
"github.com/mitchellh/packer/packer"
...
...
@@ -92,7 +93,7 @@ func runCommand(shell *winrm.Shell, cmd *winrm.Command, rc *packer.RemoteCmd) {
}
// Upload implementation of communicator.Communicator interface
func
(
c
*
Communicator
)
Upload
(
path
string
,
input
io
.
Reader
)
error
{
func
(
c
*
Communicator
)
Upload
(
path
string
,
input
io
.
Reader
,
_
*
os
.
FileInfo
)
error
{
wcp
,
err
:=
c
.
newCopyClient
()
if
err
!=
nil
{
return
err
...
...
@@ -101,13 +102,8 @@ func (c *Communicator) Upload(path string, input io.Reader) error {
return
wcp
.
Write
(
path
,
input
)
}
// UploadScript implementation of communicator.Communicator interface
func
(
c
*
Communicator
)
UploadScript
(
path
string
,
input
io
.
Reader
)
error
{
return
c
.
Upload
(
path
,
input
)
}
// UploadDir implementation of communicator.Communicator interface
func
(
c
*
Communicator
)
UploadDir
(
dst
string
,
src
string
)
error
{
func
(
c
*
Communicator
)
UploadDir
(
dst
string
,
src
string
,
exclude
[]
string
)
error
{
log
.
Printf
(
"Uploading dir '%s' to '%s'"
,
src
,
dst
)
wcp
,
err
:=
c
.
newCopyClient
()
if
err
!=
nil
{
...
...
@@ -116,6 +112,10 @@ func (c *Communicator) UploadDir(dst string, src string) error {
return
wcp
.
Copy
(
src
,
dst
)
}
func
(
c
*
Communicator
)
Download
(
src
string
,
dst
io
.
Writer
)
error
{
panic
(
"download not implemented"
)
}
func
(
c
*
Communicator
)
newCopyClient
()
(
*
winrmcp
.
Winrmcp
,
error
)
{
addr
:=
fmt
.
Sprintf
(
"%s:%d"
,
c
.
endpoint
.
Host
,
c
.
endpoint
.
Port
)
return
winrmcp
.
New
(
addr
,
&
winrmcp
.
Config
{
...
...
helper/communicator/config.go
View file @
7a397580
...
...
@@ -12,7 +12,9 @@ import (
// Config is the common configuration that communicators allow within
// a builder.
type
Config
struct
{
Type
string
`mapstructure:"communicator"`
Type
string
`mapstructure:"communicator"`
// SSH
SSHHost
string
`mapstructure:"ssh_host"`
SSHPort
int
`mapstructure:"ssh_port"`
SSHUsername
string
`mapstructure:"ssh_username"`
...
...
@@ -20,6 +22,13 @@ type Config struct {
SSHPrivateKey
string
`mapstructure:"ssh_private_key_file"`
SSHPty
bool
`mapstructure:"ssh_pty"`
SSHTimeout
time
.
Duration
`mapstructure:"ssh_timeout"`
// WinRM
WinRMUser
string
`mapstructure:"winrm_username"`
WinRMPassword
string
`mapstructure:"winrm_password"`
WinRMHost
string
`mapstructure:"winrm_host"`
WinRMPort
int
`mapstructure:"winrm_port"`
WinRMTimeout
time
.
Duration
`mapstructure:"winrm_timeout"`
}
func
(
c
*
Config
)
Prepare
(
ctx
*
interpolate
.
Context
)
[]
error
{
...
...
@@ -27,6 +36,22 @@ func (c *Config) Prepare(ctx *interpolate.Context) []error {
c
.
Type
=
"ssh"
}
var
errs
[]
error
switch
c
.
Type
{
case
"ssh"
:
if
es
:=
c
.
prepareSSH
(
ctx
);
len
(
es
)
>
0
{
errs
=
append
(
errs
,
es
...
)
}
case
"winrm"
:
if
es
:=
c
.
prepareWinRM
(
ctx
);
len
(
es
)
>
0
{
errs
=
append
(
errs
,
es
...
)
}
}
return
errs
}
func
(
c
*
Config
)
prepareSSH
(
ctx
*
interpolate
.
Context
)
[]
error
{
if
c
.
SSHPort
==
0
{
c
.
SSHPort
=
22
}
...
...
@@ -37,21 +62,36 @@ func (c *Config) Prepare(ctx *interpolate.Context) []error {
// Validation
var
errs
[]
error
if
c
.
Type
==
"ssh"
{
if
c
.
SSHUsername
==
""
{
errs
=
append
(
errs
,
errors
.
New
(
"An ssh_username must be specified"
))
}
if
c
.
SSHUsername
==
""
{
errs
=
append
(
errs
,
errors
.
New
(
"An ssh_username must be specified"
))
}
if
c
.
SSHPrivateKey
!=
""
{
if
_
,
err
:=
os
.
Stat
(
c
.
SSHPrivateKey
);
err
!=
nil
{
errs
=
append
(
errs
,
fmt
.
Errorf
(
"ssh_private_key_file is invalid: %s"
,
err
))
}
else
if
_
,
err
:=
SSHFileSigner
(
c
.
SSHPrivateKey
);
err
!=
nil
{
errs
=
append
(
errs
,
fmt
.
Errorf
(
"ssh_private_key_file is invalid: %s"
,
err
))
}
if
c
.
SSHPrivateKey
!=
""
{
if
_
,
err
:=
os
.
Stat
(
c
.
SSHPrivateKey
);
err
!=
nil
{
errs
=
append
(
errs
,
fmt
.
Errorf
(
"ssh_private_key_file is invalid: %s"
,
err
))
}
else
if
_
,
err
:=
SSHFileSigner
(
c
.
SSHPrivateKey
);
err
!=
nil
{
errs
=
append
(
errs
,
fmt
.
Errorf
(
"ssh_private_key_file is invalid: %s"
,
err
))
}
}
return
errs
}
func
(
c
*
Config
)
prepareWinRM
(
ctx
*
interpolate
.
Context
)
[]
error
{
if
c
.
WinRMPort
==
0
{
c
.
WinRMPort
=
5985
}
if
c
.
WinRMTimeout
==
0
{
c
.
WinRMTimeout
=
30
*
time
.
Minute
}
var
errs
[]
error
if
c
.
WinRMUser
==
""
{
errs
=
append
(
errs
,
errors
.
New
(
"winrm_username must be specified."
))
}
return
errs
}
helper/communicator/step_connect_winrm.go
0 → 100644
View file @
7a397580
package
communicator
import
(
"errors"
"fmt"
"log"
"time"
"github.com/mitchellh/multistep"
"github.com/mitchellh/packer/communicator/winrm"
"github.com/mitchellh/packer/packer"
)
// StepConnectWinRM is a multistep Step implementation that waits for WinRM
// to become available. It gets the connection information from a single
// configuration when creating the step.
//
// Uses:
// ui packer.Ui
//
// Produces:
// communicator packer.Communicator
type
StepConnectWinRM
struct
{
// All the fields below are documented on StepConnect
Config
*
Config
Host
func
(
multistep
.
StateBag
)
(
string
,
error
)
WinRMConfig
func
(
multistep
.
StateBag
)
(
*
WinRMConfig
,
error
)
}
func
(
s
*
StepConnectWinRM
)
Run
(
state
multistep
.
StateBag
)
multistep
.
StepAction
{
ui
:=
state
.
Get
(
"ui"
)
.
(
packer
.
Ui
)
var
comm
packer
.
Communicator
var
err
error
cancel
:=
make
(
chan
struct
{})
waitDone
:=
make
(
chan
bool
,
1
)
go
func
()
{
ui
.
Say
(
"Waiting for WinRM to become available..."
)
comm
,
err
=
s
.
waitForWinRM
(
state
,
cancel
)
waitDone
<-
true
}()
log
.
Printf
(
"Waiting for WinRM, up to timeout: %s"
,
s
.
Config
.
WinRMTimeout
)
timeout
:=
time
.
After
(
s
.
Config
.
WinRMTimeout
)
WaitLoop
:
for
{
// Wait for either WinRM to become available, a timeout to occur,
// or an interrupt to come through.
select
{
case
<-
waitDone
:
if
err
!=
nil
{
ui
.
Error
(
fmt
.
Sprintf
(
"Error waiting for WinRM: %s"
,
err
))
return
multistep
.
ActionHalt
}
ui
.
Say
(
"Connected to WinRM!"
)
state
.
Put
(
"communicator"
,
comm
)
break
WaitLoop
case
<-
timeout
:
err
:=
fmt
.
Errorf
(
"Timeout waiting for WinRM."
)
state
.
Put
(
"error"
,
err
)
ui
.
Error
(
err
.
Error
())
close
(
cancel
)
return
multistep
.
ActionHalt
case
<-
time
.
After
(
1
*
time
.
Second
)
:
if
_
,
ok
:=
state
.
GetOk
(
multistep
.
StateCancelled
);
ok
{
// The step sequence was cancelled, so cancel waiting for WinRM
// and just start the halting process.
close
(
cancel
)
log
.
Println
(
"Interrupt detected, quitting waiting for WinRM."
)
return
multistep
.
ActionHalt
}
}
}
return
multistep
.
ActionContinue
}
func
(
s
*
StepConnectWinRM
)
Cleanup
(
multistep
.
StateBag
)
{
}
func
(
s
*
StepConnectWinRM
)
waitForWinRM
(
state
multistep
.
StateBag
,
cancel
<-
chan
struct
{})
(
packer
.
Communicator
,
error
)
{
var
comm
packer
.
Communicator
for
{
select
{
case
<-
cancel
:
log
.
Println
(
"[INFO] WinRM wait cancelled. Exiting loop."
)
return
nil
,
errors
.
New
(
"WinRM wait cancelled"
)
case
<-
time
.
After
(
5
*
time
.
Second
)
:
}
host
,
err
:=
s
.
Host
(
state
)
if
err
!=
nil
{
log
.
Printf
(
"[DEBUG] Error getting WinRM host: %s"
,
err
)
continue
}
port
:=
s
.
Config
.
WinRMPort
user
:=
s
.
Config
.
WinRMUser
password
:=
s
.
Config
.
WinRMPassword
if
s
.
WinRMConfig
!=
nil
{
config
,
err
:=
s
.
WinRMConfig
(
state
)
if
err
!=
nil
{
log
.
Printf
(
"[DEBUG] Error getting WinRM config: %s"
,
err
)
continue
}
if
config
.
Username
!=
""
{
user
=
config
.
Username
}
if
config
.
Password
!=
""
{
password
=
config
.
Password
}
}
log
.
Println
(
"[INFO] Attempting WinRM connection..."
)
comm
,
err
=
winrm
.
New
(
&
winrm
.
Config
{
Host
:
host
,
Port
:
port
,
Username
:
user
,
Password
:
password
,
Timeout
:
s
.
Config
.
WinRMTimeout
,
})
if
err
!=
nil
{
log
.
Printf
(
"[ERROR] WinRM connection err: %s"
,
err
)
continue
}
break
}
return
comm
,
nil
}
helper/communicator/winrm.go
0 → 100644
View file @
7a397580
package
communicator
// WinRMConfig is configuration that can be returned at runtime to
// dynamically configure WinRM.
type
WinRMConfig
struct
{
Username
string
Password
string
}
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