Skip to content
This repository was archived by the owner on May 20, 2025. It is now read-only.

Commit 0e76951

Browse files
Paul NikonowiczNatalie Arellano
authored andcommitted
stembuild can convert a VMDK image to a stemcell
[#146327271] Signed-off-by: Natalie Arellano <narellano@pivotal.io>
1 parent be9e96e commit 0e76951

File tree

5 files changed

+105
-46
lines changed

5 files changed

+105
-46
lines changed

README.md

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,26 @@
22

33
# Requirements
44

5-
Only works on Mac right now.
6-
75
Needs:
86

9-
* `ovftool` (VMWare)
10-
* `brew install librsync`
7+
* `ovftool` (VMWare) on your path
8+
* clone librsync: https://github.com/charlievieth/librsync/tree/mingw64-fseeko64-v2.0.0
9+
10+
11+
# Build Instructions
12+
Note: you can only build on your host OS. you cannot cross compile.
13+
14+
1) download cmake
15+
1) set source folder to librsync
16+
1) set destination folder to librsync/build
17+
1) set CMAKE_INSTALL_PREFIX=librsync/install
18+
1) set CMAKE_BUILD_TYPE=release
19+
1) click configure
20+
1) click generate
21+
2) copy all source and header files from librsync/src into rdiff/
22+
2) copy all source and header files from librsync/build/src into rdiff/
23+
3) remove rdiff/rdiff.c
24+
1125

1226
# Instructions
1327

main.go

Lines changed: 81 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ var (
2828
OvaFile string
2929
OvfDir string
3030
VHDFile string
31+
VMDKFile string
3132
DeltaFile string
3233
EnableDebug bool
3334
DebugColor bool
@@ -36,22 +37,35 @@ var (
3637
var Debugf = func(format string, a ...interface{}) {}
3738

3839
const UsageMessage = `
39-
Usage %[1]s: [OPTIONS...] [-VHD FILENAME] [-DELTA FILENAME] [-OUTPUT DIRNAME] [-VERSION version]
40+
Usage %[1]s: [OPTIONS...] [-VMDK FILENAME] [[-VHD FILENAME] [-DELTA FILENAME]]
41+
[-OUTPUT DIRNAME] [-VERSION version]
4042
4143
Creates a BOSH stemcell from a VHD and DELTA (patch) file.
4244
4345
Usage:
4446
The VMware 'ovftool' binary must be on your path or Fusion/Workstation
4547
must be installed (both include the 'ovftool').
4648
47-
The [vhd], [delta] and [version] flags must be specified. If the [output]
48-
flag is not specified the stemcell will be created in the current working
49-
directory.
49+
Patch VHD [-VHD]:
50+
51+
The [vhd], [delta] and [version] flags must be specified. If the [output]
52+
flag is not specified the stemcell will be created in the current working
53+
directory.
54+
55+
Convert VMDK [-VMDK]:
56+
The [vmdk] and [version] flags must be specified. If the [output] flag is
57+
not specified the stemcell will be created in the current working directory.
5058
5159
Examples:
60+
%[1]s -vmdk disk.vmdk -v 1.2
61+
62+
Will create a stemcell using [vmdk] 'disk.vmkd' with version 1.2 in the current
63+
working directory.
64+
5265
%[1]s -vhd disk.vhd -delta patch.file -v 1.2
5366
54-
Will create a stemcell with version 1.2 in the current working directory.
67+
Will create a stemcell using [vhd] 'disk.vhd' and a patch file with
68+
version 1.2 in the current working directory.
5569
5670
%[1]s -vhd disk.vhd -delta patch.file -gzip -v 1.2 -output foo
5771
@@ -68,6 +82,7 @@ func init() {
6882
}
6983

7084
flag.StringVar(&VHDFile, "vhd", "", "VHD file to patch")
85+
flag.StringVar(&VMDKFile, "vmdk", "", "VMDK file to create stemcell from")
7186

7287
flag.StringVar(&DeltaFile, "delta", "", "Patch file that will be applied to the VHD")
7388
flag.StringVar(&DeltaFile, "d", "", "Patch file (shorthand)")
@@ -100,33 +115,46 @@ func validFile(name string) error {
100115
}
101116

102117
func ValidateFlags() []error {
103-
Debugf("validating [vhd] (%s) and [delta] (%s) flags", VHDFile, DeltaFile)
118+
Debugf("validating [vmdk] (%s) [vhd] (%s) and [delta] (%s) flags",
119+
VMDKFile, VHDFile, DeltaFile)
104120

105121
var errs []error
106122
add := func(err error) {
107123
errs = append(errs, err)
108124
}
109125

126+
if VMDKFile != "" && VHDFile != "" {
127+
add(errors.New("both VMDK and VHD flags are specified"))
128+
return errs
129+
}
130+
if VMDKFile == "" && VHDFile == "" {
131+
add(errors.New("missing VMDK and VHD flags, one must be specified"))
132+
return errs
133+
}
134+
110135
// check for extra flags
111136
Debugf("validating that no extra flags or arguments were provided")
112137
if n := len(flag.Args()); n != 0 {
113138
add(fmt.Errorf("extra arguments: %s\n", strings.Join(flag.Args(), ", ")))
114139
}
115140

116-
Debugf("validating VHD file [vhd]: %q", VHDFile)
117-
if VHDFile == "" {
118-
add(errors.New("missing required argument 'vhd'"))
119-
}
120-
if err := validFile(VHDFile); err != nil {
121-
add(fmt.Errorf("invalid [vhd]: %s", err))
122-
}
123-
124-
Debugf("validating patch file [delta]: %q", DeltaFile)
125-
if DeltaFile == "" {
126-
add(errors.New("missing required argument 'delta'"))
127-
}
128-
if err := validFile(DeltaFile); err != nil {
129-
add(fmt.Errorf("invalid [delta]: %s", err))
141+
if VMDKFile != "" {
142+
Debugf("validating VMDK file [vmdk]: %q", VMDKFile)
143+
if err := validFile(VMDKFile); err != nil {
144+
add(fmt.Errorf("invalid [vmdk]: %s", err))
145+
}
146+
} else {
147+
Debugf("validating VHD file [vhd]: %q", VHDFile)
148+
if err := validFile(VHDFile); err != nil {
149+
add(fmt.Errorf("invalid [vhd]: %s", err))
150+
}
151+
Debugf("validating patch file [delta]: %q", DeltaFile)
152+
if DeltaFile == "" {
153+
add(errors.New("missing required argument 'delta'"))
154+
}
155+
if err := validFile(DeltaFile); err != nil {
156+
add(fmt.Errorf("invalid [delta]: %s", err))
157+
}
130158
}
131159

132160
Debugf("validating output directory: %s", OutputDir)
@@ -580,7 +608,27 @@ func (c *Config) CreateImage(vmdk string) error {
580608
return nil
581609
}
582610

583-
func realMain(c *Config, vhd, delta, version string) error {
611+
func (c *Config) ConvertVMDK(vmdk string) (string, error) {
612+
if err := c.CreateImage(vmdk); err != nil {
613+
return "", err
614+
}
615+
if err := c.WriteManifest(); err != nil {
616+
return "", err
617+
}
618+
if err := c.CreateStemcell(); err != nil {
619+
return "", err
620+
}
621+
622+
stemcellPath := filepath.Join(OutputDir, filepath.Base(c.Stemcell))
623+
Debugf("moving stemcell (%s) to: %s", c.Stemcell, stemcellPath)
624+
625+
if err := os.Rename(c.Stemcell, stemcellPath); err != nil {
626+
return "", err
627+
}
628+
return stemcellPath, nil
629+
}
630+
631+
func realMain(c *Config, vmdk, vhd, delta string) error {
584632
start := time.Now()
585633

586634
// PATCH HERE
@@ -589,27 +637,22 @@ func realMain(c *Config, vhd, delta, version string) error {
589637
return err
590638
}
591639

592-
patchedVMDK := filepath.Join(tmpdir, "image.vmdk")
593-
if err := c.ApplyPatch(vhd, delta, patchedVMDK); err != nil {
594-
return err
640+
// This is ugly and I'm sorry
641+
if vmdk == "" {
642+
Debugf("main: creating vmdk from [vhd] (%s) and [delta] (%s)", vhd, delta)
643+
vmdk = filepath.Join(tmpdir, "image.vmdk")
644+
if err := c.ApplyPatch(vhd, delta, vmdk); err != nil {
645+
return err
646+
}
647+
} else {
648+
Debugf("main: using vmdk (%s)", vmdk)
595649
}
596650

597-
if err := c.CreateImage(patchedVMDK); err != nil {
598-
return err
599-
}
600-
if err := c.WriteManifest(); err != nil {
601-
return err
602-
}
603-
if err := c.CreateStemcell(); err != nil {
651+
stemcellPath, err := c.ConvertVMDK(vmdk)
652+
if err != nil {
604653
return err
605654
}
606655

607-
stemcellPath := filepath.Join(OutputDir, filepath.Base(c.Stemcell))
608-
Debugf("moving stemcell (%s) to: %s", c.Stemcell, stemcellPath)
609-
610-
if err := os.Rename(c.Stemcell, stemcellPath); err != nil {
611-
return err
612-
}
613656
Debugf("created stemcell (%s) in: %s", stemcellPath, time.Since(start))
614657
fmt.Println("created stemell:", stemcellPath)
615658

@@ -657,7 +700,7 @@ func main() {
657700
}
658701
}()
659702

660-
if err := realMain(&c, VHDFile, DeltaFile, Version); err != nil {
703+
if err := realMain(&c, VMDKFile, VHDFile, DeltaFile); err != nil {
661704
fmt.Fprintf(os.Stderr, "Error: %s\n", err)
662705
}
663706
c.Cleanup() // remove temp dir

main_test.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -261,16 +261,16 @@ func TestCreateImage(t *testing.T) {
261261
}
262262
}
263263

264-
// the vmx template should generate an ovf file that does not
264+
// the vmx template should generate an ovf file that does
265265
// contain an ethernet section.
266266
//
267267
ovf := filepath.Join(imageDir, "image.ovf")
268268
s, err := readFile(ovf)
269269
if err != nil {
270270
t.Fatal(err)
271271
}
272-
if strings.Contains(strings.ToLower(s), "ethernet") {
273-
t.Errorf("CreateImage: ovf contains 'ethernet':\n%s\n", s)
272+
if !strings.Contains(strings.ToLower(s), "ethernet") {
273+
t.Errorf("CreateImage: ovf does not contain 'ethernet' block:\n%s\n", s)
274274
}
275275
}
276276

rdiff/update.bash

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33
# This *must* be run from the rdiff directory where this
44
# file is located!
55

6+
# Use this fork of librsync: https://github.com/charlievieth/librsync/tree/mingw64-fseeko64-v2.0.0
7+
#
68
# Root directory of librsync
79
LIBRSYNC_DIR="PATH_TO_LIBRSYNC_SRC_DIR"
810

vmx_template_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -174,7 +174,7 @@ VMX File (%[2]s):
174174
t.Fatal(err)
175175
}
176176
ovfSrc := string(b)
177-
if strings.Contains(ovfSrc, "ethernet") {
177+
if !strings.Contains(ovfSrc, "ethernet") {
178178
t.Fatalf(errorMsgFormat, ovf, vmx, ovfSrc, vmxBuf.String())
179179
}
180180
}

0 commit comments

Comments
 (0)