packer-cn/builder/oracle/classic/pv_config.go

141 lines
4.2 KiB
Go
Raw Normal View History

2018-09-12 19:16:08 -04:00
package classic
import (
2018-10-24 17:40:32 -04:00
"fmt"
2018-10-26 18:47:49 -04:00
"github.com/hashicorp/packer/helper/communicator"
2018-09-12 19:16:08 -04:00
"github.com/hashicorp/packer/packer"
"github.com/hashicorp/packer/template/interpolate"
)
2018-10-24 17:40:32 -04:00
const imageListDefault = "/oracle/public/OL_7.2_UEKR4_x86_64"
const imageListEntryDefault = 5
const usernameDefault = "opc"
const shapeDefault = "oc3"
2018-10-26 19:44:46 -04:00
const uploadImageCommandDefault = `
# https://www.oracle.com/webfolder/technetwork/tutorials/obe/cloud/objectstorage/upload_files_gt_5GB_REST_API/upload_files_gt_5GB_REST_API.html
# Split diskimage in to 100mb chunks
split -b 100m diskimage.tar.gz segment_
printf "Split diskimage into %s segments\n" $(ls segment_* | wc -l)
# Download jq tool
2018-10-27 05:04:36 -04:00
curl -OLs https://github.com/stedolan/jq/releases/download/jq-1.5/jq-linux64
2018-10-26 19:44:46 -04:00
mv jq-linux64 jq
chmod u+x jq
# Create manifest file
(
for i in segment_*; do
./jq -n --arg path "{{.SegmentPath}}/$i" \
--arg etag $(md5sum $i | cut -f1 -d' ') \
2018-10-27 05:04:36 -04:00
--arg size_bytes $(stat --printf "%s" $i) \
'{path: $path, etag: $etag, size_bytes: $size_bytes}'
2018-10-26 19:44:46 -04:00
done
) | ./jq -s . > manifest.json
# Authenticate
curl -D auth-headers -s -X GET \
2018-10-27 05:04:36 -04:00
-H "X-Storage-User: Storage-{{.AccountID}}:{{.Username}}" \
-H "X-Storage-Pass: {{.Password}}" \
https://{{.AccountID}}.storage.oraclecloud.com/auth/v1.0
2018-10-26 19:44:46 -04:00
export AUTH_TOKEN=$(awk 'BEGIN {FS=": "; RS="\r\n"}/^X-Auth-Token/{print $2}' auth-headers)
export STORAGE_URL=$(awk 'BEGIN {FS=": "; RS="\r\n"}/^X-Storage-Url/{print $2}' auth-headers)
# Upload segments
for i in segment_*; do
2018-10-27 05:04:36 -04:00
echo "Uploading segment $i"
2018-10-26 19:44:46 -04:00
2018-10-27 05:04:36 -04:00
curl -s -X PUT -T $i \
-H "X-Auth-Token: $AUTH_TOKEN" ${STORAGE_URL}/{{.SegmentPath}}/$i;
2018-10-26 19:44:46 -04:00
done
# Create machine image from manifest
curl -s -X PUT \
2018-10-27 05:04:36 -04:00
-H "X-Auth-Token: $AUTH_TOKEN" \
"${STORAGE_URL}/compute_images/{{.ImageFile}}?multipart-manifest=put" \
-T ./manifest.json
2018-10-26 19:44:46 -04:00
# Get uploaded image description
2018-10-27 05:04:36 -04:00
echo "Details of ${STORAGE_URL}/compute_images/{{.ImageFile}}:"
2018-10-26 19:44:46 -04:00
curl -I -X HEAD \
2018-10-27 05:04:36 -04:00
-H "X-Auth-Token: $AUTH_TOKEN" \
"${STORAGE_URL}/compute_images/{{.ImageFile}}"
2018-10-26 19:44:46 -04:00
`
2018-10-24 17:40:32 -04:00
2018-09-12 19:16:08 -04:00
type PVConfig struct {
// PersistentVolumeSize lets us control the volume size by using persistent boot storage
2018-09-12 20:12:35 -04:00
PersistentVolumeSize int `mapstructure:"persistent_volume_size"`
BuilderUploadImageCommand string `mapstructure:"builder_upload_image_command"`
2018-10-24 17:40:32 -04:00
// Builder Image
BuilderShape string `mapstructure:"builder_shape"`
BuilderImageList string `mapstructure:"builder_image_list"`
BuilderImageListEntry *int `mapstructure:"builder_image_list_entry"`
2018-10-26 18:47:49 -04:00
BuilderComm communicator.Config `mapstructure:"builder_communicator"`
2018-09-12 19:16:08 -04:00
}
2018-10-20 17:11:11 -04:00
// IsPV tells us if we're using a persistent volume for this build
2018-09-12 20:12:35 -04:00
func (c *PVConfig) IsPV() bool {
return c.PersistentVolumeSize > 0
}
2018-09-12 19:16:08 -04:00
func (c *PVConfig) Prepare(ctx *interpolate.Context) (errs *packer.MultiError) {
2018-09-12 20:12:35 -04:00
if !c.IsPV() {
2018-10-24 17:40:32 -04:00
if c.BuilderShape != "" {
errs = packer.MultiErrorAppend(errs,
fmt.Errorf("`builder_shape` has no meaning when `persistent_volume_size` is not set."))
}
if c.BuilderImageList != "" {
errs = packer.MultiErrorAppend(errs,
fmt.Errorf("`builder_image_list` has no meaning when `persistent_volume_size` is not set."))
}
if c.BuilderImageListEntry != nil {
errs = packer.MultiErrorAppend(errs,
fmt.Errorf("`builder_image_list_entry` has no meaning when `persistent_volume_size` is not set."))
2018-10-24 17:40:32 -04:00
}
return errs
}
2018-10-26 18:47:49 -04:00
c.BuilderComm.SSHPty = true
if c.BuilderComm.Type == "winrm" {
errs = packer.MultiErrorAppend(errs,
fmt.Errorf("`ssh` is the only valid builder communicator type."))
}
2018-10-24 17:40:32 -04:00
if c.BuilderShape == "" {
c.BuilderShape = shapeDefault
}
2018-10-26 18:47:49 -04:00
if c.BuilderComm.SSHUsername == "" {
c.BuilderComm.SSHUsername = usernameDefault
2018-10-24 17:40:32 -04:00
}
if c.BuilderImageList == "" {
c.BuilderImageList = imageListDefault
}
// Set to known working default if this is unset and we're using the
// default image list
if c.BuilderImageListEntry == nil {
var entry int
if c.BuilderImageList == imageListDefault {
entry = imageListEntryDefault
}
c.BuilderImageListEntry = &entry
2018-09-12 19:16:08 -04:00
}
if c.BuilderUploadImageCommand == "" {
2018-10-26 19:44:46 -04:00
c.BuilderUploadImageCommand = uploadImageCommandDefault
2018-09-12 19:16:08 -04:00
}
2018-10-24 17:59:15 -04:00
2018-10-26 18:47:49 -04:00
if es := c.BuilderComm.Prepare(ctx); len(es) > 0 {
errs = packer.MultiErrorAppend(errs, es...)
}
2018-09-12 19:16:08 -04:00
return
}