terraform-provider-proxmox/proxmox/preprovision.go
2018-07-10 10:37:45 -07:00

185 lines
4.5 KiB
Go

package proxmox
import (
"fmt"
"github.com/hashicorp/terraform/communicator"
"github.com/hashicorp/terraform/communicator/remote"
"github.com/hashicorp/terraform/helper/schema"
"io"
"log"
"strconv"
"strings"
"time"
)
const eth0Payload = "echo $'%s' > /tmp/tf_eth0_payload"
const provisionPayload = "echo $'%s' > /tmp/tf_preprovision.sh"
// preprovision VM (setup eth0 and hostname)
const ubuntuPreprovisionScript = `
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 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
if [ -e /etc/auto_resize_vda.sh ]; then
echo Auto-resizing file-system
/etc/auto_resize_vda.sh
fi
echo Preprovision done at $(date)
`
// 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
cat /tmp/tf_eth0_payload > /etc/sysconfig/network-scripts/ifcfg-eth0
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)
}
func preProvisionUbuntu(d *schema.ResourceData) error {
return preProvisionLinux(d, ubuntuPreprovisionScript)
}
func preProvisionLinux(d *schema.ResourceData, provisionBash string) error {
// Get a new communicator
log.Print("[DEBUG] connecting to SSH on linux")
comm, err := communicator.New(d.State())
if err != nil {
return err
}
log.Print("[DEBUG] sending os_network_config")
// 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
}
hostname := d.Get("name").(string)
pScript := fmt.Sprintf(provisionBash, hostname, strings.Split(hostname, ".")[0])
log.Print("[DEBUG] sending provisionPayload")
err = runCommand(comm, fmt.Sprintf(provisionPayload, strings.Trim(strconv.Quote(pScript), "\"")))
if err != nil {
return err
}
log.Print("[DEBUG] running provisionPayload")
err = runCommand(comm, "sudo bash /tmp/tf_preprovision.sh \"$SSH_CLIENT\" >> /tmp/tf_preprovision.log 2>&1")
if err != nil {
return err
}
log.Print("[DEBUG] disconnecting SSH")
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)
}
if err := cmd.Wait(); err != nil {
return err
}
// 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)
// }
// }