Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

CLOUD-724: copy_out_guest_install_log #57

Open
wants to merge 8 commits into
base: release/v1.7.0
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ crash.log
packer-builder-veertu-anka
mapstructure-to-hcl2
dist/
pkg
bin

# generated code
builder/anka/config.hcl2spec.go
Expand Down Expand Up @@ -41,3 +43,4 @@ _testmain.go
*.prof

.DS_Store
install-anka-packer*.log
3 changes: 3 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,9 @@ packer-test: install
packer-test2: build
PACKER_LOG=1 packer build examples/macos-catalina.json

big-sur: install
PACKER_LOG=1 packer build examples/macos-bigsur.json

clean:
rm -f $(BIN)

Expand Down
2 changes: 1 addition & 1 deletion VERSION
Original file line number Diff line number Diff line change
@@ -1 +1 @@
1.6.0
1.6.1
10 changes: 9 additions & 1 deletion builder/anka/builder.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,15 @@ import (
"github.com/hashicorp/packer/helper/multistep"
"github.com/hashicorp/packer/packer"
"github.com/veertuinc/packer-builder-veertu-anka/client"
"golang.org/x/mod/semver"
)

// The unique ID for this builder.
const BuilderId = "packer.veertu-anka"

// The oldest version of the Anka Build utility this plugin supports
const OldestSupportedVersion = "2.3.0"

// Builder represents a Packer Builder.
type Builder struct {
config *Config
Expand All @@ -40,7 +44,11 @@ func (b *Builder) Run(ctx context.Context, ui packer.Ui, hook packer.Hook) (pack
if err != nil {
return nil, err
}
log.Printf("[DEBUG] Anka version: %s", version)
log.Printf("[DEBUG] Anka version: %s version %s (build %s)", version.Body.Product, version.Body.Version, version.Body.Build)

if semver.Compare(version.Body.Version, OldestSupportedVersion) < 0 {
return nil, errors.New("This plugin requires at least Anka " + OldestSupportedVersion + ". You are running " + version.Body.Version)
}

steps := []multistep.Step{
&StepTempDir{},
Expand Down
130 changes: 22 additions & 108 deletions builder/anka/communicator.go
Original file line number Diff line number Diff line change
@@ -1,18 +1,14 @@
package anka

import (
"fmt"
"errors"
"context"
"io"
"io/ioutil"
"log"
"os"
"path"
"path/filepath"
"context"

"github.com/veertuinc/packer-builder-veertu-anka/client"

"github.com/hashicorp/packer/packer"
"github.com/veertuinc/packer-builder-veertu-anka/client"
)

type Communicator struct {
Expand Down Expand Up @@ -52,15 +48,17 @@ func (c *Communicator) Start(ctx context.Context, remote *packer.RemoteCmd) erro
}

func (c *Communicator) Upload(dst string, src io.Reader, fi *os.FileInfo) error {
log.Printf("Communicator Upload")
log.Printf("Uploading file to VM: %s", dst)

// Create a temporary file to store the upload
tempfile, err := ioutil.TempFile(c.HostDir, "upload")
if err != nil {
return err
}
defer os.Remove(tempfile.Name())
defer tempfile.Close()

// Copy the contents to the temporary file
log.Printf("Copying from reader to %s", tempfile.Name())
w, err := io.Copy(tempfile, src)
if err != nil {
return err
Expand All @@ -71,106 +69,20 @@ func (c *Communicator) Upload(dst string, src io.Reader, fi *os.FileInfo) error
}
tempfile.Close()

log.Printf("Created temp dir in %s", tempfile.Name())
log.Printf("Copying %d bytes from %s to %s", w, tempfile.Name(), dst)

log.Printf("Destination os %v", dst)

err, _ = c.Client.Run(client.RunParams{
VMName: c.VMName,
Command: []string{"cp", path.Base(tempfile.Name()), dst},
Volume: c.HostDir,
err = c.Client.Copy(client.CopyParams{
Src: tempfile.Name(),
Dst: c.VMName + ":" + dst,
})

log.Printf("Copied %d bytes from %s to %s", w, tempfile.Name(), dst)
return err
}

func (c *Communicator) UploadDir(dst string, src string, exclude []string) error {
// Create the temporary directory that will store the contents of "src"
// for copying into the container.
td, err := ioutil.TempDir(c.HostDir, "dirupload")
if err != nil {
return err
}
defer os.RemoveAll(td)

walkFn := func(path string, info os.FileInfo, err error) error {
if err != nil {
return err
}

relpath, err := filepath.Rel(src, path)
if err != nil {
return err
}
hostpath := filepath.Join(td, relpath)

// If it is a directory, just create it
if info.IsDir() {
return os.MkdirAll(hostpath, info.Mode())
}

if info.Mode()&os.ModeSymlink == os.ModeSymlink {
dest, err := os.Readlink(path)

if err != nil {
return err
}

return os.Symlink(dest, hostpath)
}

// It is a file, copy it over, including mode.
src, err := os.Open(path)
if err != nil {
return err
}
defer src.Close()

dst, err := os.Create(hostpath)
if err != nil {
return err
}
defer dst.Close()

log.Printf("Copying %s to %s", src.Name(), dst.Name())
if _, err := io.Copy(dst, src); err != nil {
return err
}

si, err := src.Stat()
if err != nil {
return err
}

return dst.Chmod(si.Mode())
}

// Copy the entire directory tree to the temporary directory
if err := filepath.Walk(src, walkFn); err != nil {
return err
}

// Determine the destination directory
// containerSrc := filepath.Join(c.ContainerDir, filepath.Base(td))
containerDst := dst
if src[len(src)-1] != '/' {
containerDst = filepath.Join(dst, filepath.Base(src))
}

log.Printf("from %#v to %#v", td, containerDst)

// Make the directory, then copy into it
command := fmt.Sprintf("set -e; mkdir -p %s; command cp -R %s/* %s",
containerDst, filepath.Base(td), containerDst,
)
err, _ = c.Client.Run(client.RunParams{
VMName: c.VMName,
Command: []string{"bash", "-c", command},
Volume: c.HostDir,
return c.Client.Copy(client.CopyParams{
Src: src,
Dst: c.VMName + ":" + dst,
})

return err
}

func (c *Communicator) Download(src string, dst io.Writer) error {
Expand All @@ -182,12 +94,11 @@ func (c *Communicator) Download(src string, dst io.Writer) error {
return err
}
defer os.Remove(tempfile.Name())
defer tempfile.Close()

// Copy it to a local file mounted on shared fs
err, _ = c.Client.Run(client.RunParams{
VMName: c.VMName,
Command: []string{"cp", src, "./" + path.Base(tempfile.Name())},
Volume: c.HostDir,
err = c.Client.Copy(client.CopyParams{
Src: c.VMName + ":" + src,
Dst: tempfile.Name(),
})

log.Printf("Copying from %s to writer", tempfile.Name())
Expand All @@ -201,5 +112,8 @@ func (c *Communicator) Download(src string, dst io.Writer) error {
}

func (c *Communicator) DownloadDir(src string, dst string, exclude []string) error {
return errors.New("communicator.DownloadDir isn't implemented")
return c.Client.Copy(client.CopyParams{
Src: c.VMName + ":" + src,
Dst: dst,
})
}
3 changes: 2 additions & 1 deletion builder/anka/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import (
"github.com/mitchellh/mapstructure"
)

const DEFAULT_BOOT_DELAY = "10s"
const DEFAULT_BOOT_DELAY = "20s"

type Config struct {
common.PackerConfig `mapstructure:",squash"`
Expand All @@ -39,6 +39,7 @@ type Config struct {
BootDelay string `mapstructure:"boot_delay"`
EnableHtt bool `mapstructure:"enable_htt"`
DisableHtt bool `mapstructure:"disable_htt"`
CopyOutGuestInstallLog bool `mapstructure:"copy_out_guest_install_log"`

ctx interpolate.Context
}
Expand Down
27 changes: 23 additions & 4 deletions builder/anka/step_create_vm.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,11 +26,12 @@ func init() {
type StepCreateVM struct {
client *client.Client
vmName string
config *Config
}

const (
DEFAULT_DISK_SIZE = "25G"
DEFAULT_RAM_SIZE = "2G"
DEFAULT_DISK_SIZE = "35G"
DEFAULT_RAM_SIZE = "4G"
DEFAULT_CPU_COUNT = "2"
)

Expand Down Expand Up @@ -154,11 +155,14 @@ func (s *StepCreateVM) modifyVMProperties(describeResponse client.DescribeRespon

func (s *StepCreateVM) Run(ctx context.Context, state multistep.StateBag) multistep.StepAction {
config := state.Get("config").(*Config)

ui := state.Get("ui").(packer.Ui)

s.client = state.Get("client").(*client.Client)
sourceVMName := config.SourceVMName

s.config = config

onError := func(err error) multistep.StepAction {
return stepError(ui, state, err)
}
Expand Down Expand Up @@ -287,6 +291,8 @@ func (s *StepCreateVM) Run(ctx context.Context, state multistep.StateBag) multis
}

func (s *StepCreateVM) Cleanup(state multistep.StateBag) {
var err error

ui := state.Get("ui").(packer.Ui)

log.Println("Cleaning up create VM step")
Expand All @@ -303,17 +309,30 @@ func (s *StepCreateVM) Cleanup(state multistep.StateBag) {
case *common.VMNotFoundException:
return
default:
if s.config.CopyOutGuestInstallLog {
dir, dir_err := os.Getwd()
if dir_err == nil {
err = s.client.Copy(client.CopyParams{
Src: s.vmName + ":/var/log/install.log",
Dst: dir + "/install-" + s.vmName + ".log",
})
if err != nil {
log.Println("Error downloading install log from VM")
}
ui.Say(fmt.Sprintf("Saved install.log from %s to ./install-%s.log", s.vmName, s.vmName))
}
}
if halted || canceled {
ui.Say(fmt.Sprintf("Deleting VM %s", s.vmName))
err := s.client.Delete(client.DeleteParams{VMName: s.vmName})
err = s.client.Delete(client.DeleteParams{VMName: s.vmName})
if err != nil {
ui.Error(fmt.Sprint(err))
}
return
}
}

err := s.client.Suspend(client.SuspendParams{
err = s.client.Suspend(client.SuspendParams{
VMName: s.vmName,
})
if err != nil {
Expand Down
9 changes: 5 additions & 4 deletions builder/anka/step_start_vm.go
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
package anka

import (
"time"
"fmt"
"context"
"github.com/hashicorp/packer/packer"
"fmt"
"log"
"time"

"github.com/hashicorp/packer/packer"

"github.com/veertuinc/packer-builder-veertu-anka/client"
"github.com/hashicorp/packer/helper/multistep"
"github.com/veertuinc/packer-builder-veertu-anka/client"
)

type StepStartVM struct{}
Expand Down
Loading