2017-02-11 00:06:14 +00:00
|
|
|
package proxmox
|
|
|
|
|
|
|
|
import (
|
|
|
|
"fmt"
|
|
|
|
"github.com/hashicorp/terraform/communicator"
|
|
|
|
"github.com/hashicorp/terraform/communicator/remote"
|
|
|
|
"github.com/hashicorp/terraform/helper/schema"
|
|
|
|
// "github.com/hashicorp/terraform/terraform"
|
|
|
|
// "github.com/mitchellh/go-linereader"
|
|
|
|
"io"
|
2017-02-13 21:09:55 +00:00
|
|
|
"log"
|
2017-02-13 19:11:33 +00:00
|
|
|
"strconv"
|
|
|
|
"strings"
|
2017-02-15 23:32:37 +00:00
|
|
|
"time"
|
2017-02-11 00:06:14 +00:00
|
|
|
)
|
|
|
|
|
2017-02-13 19:11:33 +00:00
|
|
|
const eth0Payload = "echo $'%s' > /tmp/tf_eth0_payload"
|
|
|
|
const provisionPayload = "echo $'%s' > /tmp/tf_preprovision.sh"
|
|
|
|
|
2017-02-11 00:06:14 +00:00
|
|
|
// preprovision VM (setup eth0 and hostname)
|
2017-02-13 19:11:33 +00:00
|
|
|
const ubuntuPreprovisionScript = `
|
|
|
|
BOX_HOSTNAME=%s
|
|
|
|
BOX_SHORT_HOSTNAME=%s
|
2017-02-14 22:52:42 +00:00
|
|
|
SSH_CLIENT=$1
|
2017-02-13 19:11:33 +00:00
|
|
|
MY_IP=$(echo $SSH_CLIENT | awk "{ print \$1 }")
|
|
|
|
echo Using my ip $MY_IP to provision at $(date)
|
|
|
|
if [ -z "$(grep $BOX_SHORT_HOSTNAME /etc/hosts)" ]; then
|
|
|
|
echo 127.0.1.1 $BOX_HOSTNAME $BOX_SHORT_HOSTNAME >> /etc/hosts
|
|
|
|
else
|
|
|
|
echo Hosts file already set includes $BOX_SHORT_HOSTNAME
|
|
|
|
fi
|
|
|
|
echo $BOX_SHORT_HOSTNAME > /etc/hostname
|
|
|
|
hostname $BOX_SHORT_HOSTNAME
|
|
|
|
echo Hostname set $BOX_SHORT_HOSTNAME
|
|
|
|
if [ -z "$(grep eth0 /etc/network/interfaces)" ]; then
|
|
|
|
echo Setting up eth0 for $BOX_HOSTNAME
|
|
|
|
cat /tmp/tf_eth0_payload >> /etc/network/interfaces
|
|
|
|
else
|
|
|
|
echo eth0 already setup for $BOX_HOSTNAME
|
|
|
|
fi
|
|
|
|
|
|
|
|
echo Attempting to bring up eth0
|
|
|
|
ip route add $MY_IP via 10.0.2.2
|
|
|
|
ip route del default via 10.0.2.2
|
|
|
|
ifup eth0
|
2017-02-14 22:52:42 +00:00
|
|
|
if [ -e /etc/auto_resize_vda.sh ]; then
|
|
|
|
echo Auto-resizing file-system
|
|
|
|
/etc/auto_resize_vda.sh
|
|
|
|
fi
|
2017-02-13 19:11:33 +00:00
|
|
|
echo Preprovision done at $(date)
|
|
|
|
`
|
2017-02-11 00:06:14 +00:00
|
|
|
|
2017-03-30 22:40:34 +00:00
|
|
|
// preprovision VM (setup eth0 and hostname)
|
|
|
|
const centosPreprovisionScript = `
|
|
|
|
BOX_HOSTNAME=%s
|
|
|
|
BOX_SHORT_HOSTNAME=%s
|
|
|
|
SSH_CLIENT=$1
|
|
|
|
MY_IP=$(echo $SSH_CLIENT | awk "{ print \$1 }")
|
|
|
|
echo Using my ip $MY_IP to provision at $(date)
|
|
|
|
if [ -z "$(grep $BOX_SHORT_HOSTNAME /etc/hosts)" ]; then
|
|
|
|
echo 127.0.1.1 $BOX_HOSTNAME $BOX_SHORT_HOSTNAME >> /etc/hosts
|
|
|
|
else
|
|
|
|
echo Hosts file already set includes $BOX_SHORT_HOSTNAME
|
|
|
|
fi
|
|
|
|
echo $BOX_SHORT_HOSTNAME > /etc/hostname
|
|
|
|
hostname $BOX_SHORT_HOSTNAME
|
|
|
|
echo Hostname set $BOX_SHORT_HOSTNAME
|
|
|
|
if [ -z "$(grep -i yes /etc/sysconfig/network-scripts/ifcfg-eth0)" ]; then
|
|
|
|
echo Setting up eth0 for $BOX_HOSTNAME
|
2017-04-04 15:53:51 +00:00
|
|
|
cat /tmp/tf_eth0_payload > /etc/sysconfig/network-scripts/ifcfg-eth0
|
2017-03-30 22:40:34 +00:00
|
|
|
else
|
|
|
|
echo eth0 already setup for $BOX_HOSTNAME
|
|
|
|
fi
|
|
|
|
|
|
|
|
echo Attempting to bring up eth0
|
|
|
|
ip route add $MY_IP via 10.0.2.2
|
|
|
|
ip route del default via 10.0.2.2
|
|
|
|
ifup eth0
|
|
|
|
if [ -e /etc/auto_resize_vda.sh ]; then
|
|
|
|
echo Auto-resizing file-system
|
|
|
|
/etc/auto_resize_vda.sh
|
|
|
|
fi
|
|
|
|
echo Preprovision done at $(date)
|
|
|
|
`
|
|
|
|
|
|
|
|
func preProvisionCentos(d *schema.ResourceData) error {
|
|
|
|
return preProvisionLinux(d, centosPreprovisionScript)
|
|
|
|
}
|
|
|
|
|
2017-02-11 00:06:14 +00:00
|
|
|
func preProvisionUbuntu(d *schema.ResourceData) error {
|
2017-03-30 22:40:34 +00:00
|
|
|
return preProvisionLinux(d, ubuntuPreprovisionScript)
|
|
|
|
}
|
|
|
|
|
|
|
|
func preProvisionLinux(d *schema.ResourceData, provisionBash string) error {
|
2017-02-11 00:06:14 +00:00
|
|
|
|
|
|
|
// Get a new communicator
|
2017-03-30 22:40:34 +00:00
|
|
|
log.Print("[DEBUG] connecting to SSH on linux")
|
2017-02-11 00:06:14 +00:00
|
|
|
comm, err := communicator.New(d.State())
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
2017-02-13 21:09:55 +00:00
|
|
|
log.Print("[DEBUG] sending os_network_config")
|
2017-02-15 23:32:37 +00:00
|
|
|
|
|
|
|
// on this first one allow some retries to connect
|
|
|
|
rr := 0
|
|
|
|
for {
|
|
|
|
rr++
|
|
|
|
err = runCommand(comm, fmt.Sprintf(eth0Payload, strings.Trim(strconv.Quote(d.Get("os_network_config").(string)), "\"")))
|
|
|
|
if err != nil {
|
|
|
|
if rr > 3 {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
time.Sleep(2 * time.Second)
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
break
|
2017-02-13 19:11:33 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
hostname := d.Get("name").(string)
|
2017-03-30 22:40:34 +00:00
|
|
|
pScript := fmt.Sprintf(provisionBash, hostname, strings.Split(hostname, ".")[0])
|
2017-02-13 21:09:55 +00:00
|
|
|
|
|
|
|
log.Print("[DEBUG] sending provisionPayload")
|
2017-02-13 19:11:33 +00:00
|
|
|
err = runCommand(comm, fmt.Sprintf(provisionPayload, strings.Trim(strconv.Quote(pScript), "\"")))
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
2017-02-13 21:09:55 +00:00
|
|
|
log.Print("[DEBUG] running provisionPayload")
|
2017-02-14 22:52:42 +00:00
|
|
|
err = runCommand(comm, "sudo bash /tmp/tf_preprovision.sh \"$SSH_CLIENT\" >> /tmp/tf_preprovision.log 2>&1")
|
2017-02-13 19:11:33 +00:00
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
2017-02-11 00:06:14 +00:00
|
|
|
|
2017-02-13 21:09:55 +00:00
|
|
|
log.Print("[DEBUG] disconnecting SSH")
|
2017-02-11 00:06:14 +00:00
|
|
|
comm.Disconnect()
|
|
|
|
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
// runCommand is used to run already prepared commands
|
|
|
|
func runCommand(
|
|
|
|
comm communicator.Communicator,
|
|
|
|
command string) error {
|
|
|
|
|
|
|
|
_, outW := io.Pipe()
|
|
|
|
_, errW := io.Pipe()
|
|
|
|
//outDoneCh := make(chan struct{})
|
|
|
|
//errDoneCh := make(chan struct{})
|
|
|
|
// go copyOutput(o, outR, outDoneCh)
|
|
|
|
// go copyOutput(o, errR, errDoneCh)
|
|
|
|
|
|
|
|
cmd := &remote.Cmd{
|
|
|
|
Command: command,
|
|
|
|
Stdout: outW,
|
|
|
|
Stderr: errW,
|
|
|
|
}
|
|
|
|
|
|
|
|
err := comm.Start(cmd)
|
|
|
|
if err != nil {
|
|
|
|
return fmt.Errorf("Error executing command %q: %v", cmd.Command, err)
|
|
|
|
}
|
|
|
|
|
2018-04-05 09:36:51 +00:00
|
|
|
if err := cmd.Wait(); err != nil {
|
|
|
|
return err
|
2017-02-11 00:06:14 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// Wait for output to clean up
|
|
|
|
outW.Close()
|
|
|
|
errW.Close()
|
|
|
|
//<-outDoneCh
|
|
|
|
//<-errDoneCh
|
|
|
|
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
//
|
|
|
|
// func copyOutput(o terraform.UIOutput, r io.Reader, doneCh chan<- struct{}) {
|
|
|
|
// defer close(doneCh)
|
|
|
|
// lr := linereader.New(r)
|
|
|
|
// for line := range lr.Ch {
|
|
|
|
// o.Output(line)
|
|
|
|
// }
|
|
|
|
// }
|