102 lines
2.6 KiB
Go
102 lines
2.6 KiB
Go
|
package yandexexport
|
||
|
|
||
|
import (
|
||
|
"bytes"
|
||
|
"context"
|
||
|
"fmt"
|
||
|
"strings"
|
||
|
"sync"
|
||
|
|
||
|
"github.com/hashicorp/packer-plugin-sdk/multistep"
|
||
|
packersdk "github.com/hashicorp/packer-plugin-sdk/packer"
|
||
|
"github.com/hashicorp/packer/builder/yandex"
|
||
|
)
|
||
|
|
||
|
type StepUploadToS3 struct {
|
||
|
Paths []string
|
||
|
}
|
||
|
|
||
|
// Run reads the instance metadata and looks for the log entry
|
||
|
// indicating the cloud-init script finished.
|
||
|
func (s *StepUploadToS3) Run(ctx context.Context, state multistep.StateBag) multistep.StepAction {
|
||
|
ui := state.Get("ui").(packersdk.Ui)
|
||
|
comm := state.Get("communicator").(packersdk.Communicator)
|
||
|
|
||
|
cmdUploadToS3 := &packersdk.RemoteCmd{
|
||
|
Command: fmt.Sprintf(
|
||
|
"%s=%s aws s3 --region=%s --endpoint-url=https://%s cp disk.qcow2 %s",
|
||
|
"AWS_SHARED_CREDENTIALS_FILE",
|
||
|
sharedAWSCredFile,
|
||
|
defaultStorageRegion,
|
||
|
defaultStorageEndpoint,
|
||
|
s.Paths[0],
|
||
|
),
|
||
|
}
|
||
|
ui.Say("Upload to S3...")
|
||
|
if err := cmdUploadToS3.RunWithUi(ctx, comm, ui); err != nil {
|
||
|
return yandex.StepHaltWithError(state, err)
|
||
|
}
|
||
|
if cmdUploadToS3.ExitStatus() != 0 {
|
||
|
return yandex.StepHaltWithError(state, fmt.Errorf("Cannout upload to S3, exit code %d", cmdUploadToS3.ExitStatus()))
|
||
|
}
|
||
|
|
||
|
versionExtraFlags, err := getVersionExtraFlags(ctx, comm)
|
||
|
if err != nil {
|
||
|
ui.Message(fmt.Sprintf("[WARN] Cannot upload to other storage: %s", err))
|
||
|
return multistep.ActionContinue
|
||
|
}
|
||
|
wg := new(sync.WaitGroup)
|
||
|
defer wg.Wait()
|
||
|
for _, path := range s.Paths[1:] {
|
||
|
|
||
|
wg.Add(1)
|
||
|
go func(path string) {
|
||
|
defer wg.Done()
|
||
|
ui.Message(fmt.Sprintf("Start copy %s to %s...", s.Paths[0], path))
|
||
|
cmd := &packersdk.RemoteCmd{
|
||
|
Command: fmt.Sprintf(
|
||
|
"%s=%s aws s3 --region=%s --endpoint-url=https://%s cp %s %s %s",
|
||
|
"AWS_SHARED_CREDENTIALS_FILE",
|
||
|
sharedAWSCredFile,
|
||
|
defaultStorageRegion,
|
||
|
defaultStorageEndpoint,
|
||
|
versionExtraFlags,
|
||
|
s.Paths[0],
|
||
|
path,
|
||
|
),
|
||
|
}
|
||
|
if err := cmd.RunWithUi(ctx, comm, ui); err != nil {
|
||
|
ui.Message(fmt.Sprintf("[WARN] Failed upload to %s", path))
|
||
|
}
|
||
|
if cmd.ExitStatus() != 0 {
|
||
|
ui.Message(fmt.Sprintf("[WARN] Failed upload to %s", path))
|
||
|
}
|
||
|
}(path)
|
||
|
}
|
||
|
|
||
|
return multistep.ActionContinue
|
||
|
}
|
||
|
|
||
|
// Cleanup nothing
|
||
|
func (s *StepUploadToS3) Cleanup(state multistep.StateBag) {}
|
||
|
|
||
|
func getVersionExtraFlags(ctx context.Context, comm packersdk.Communicator) (string, error) {
|
||
|
buff := new(bytes.Buffer)
|
||
|
cmd := &packersdk.RemoteCmd{
|
||
|
Command: "aws --version",
|
||
|
Stdout: buff,
|
||
|
}
|
||
|
if err := comm.Start(ctx, cmd); err != nil {
|
||
|
return "", err
|
||
|
}
|
||
|
if cmd.Wait() != 0 {
|
||
|
return "", fmt.Errorf("Cannot detect aws version")
|
||
|
}
|
||
|
vsn := buff.String()
|
||
|
switch {
|
||
|
case strings.HasPrefix(vsn, "aws-cli/2."):
|
||
|
return "--copy-props metadata-directive", nil
|
||
|
}
|
||
|
return "", nil
|
||
|
}
|