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
vCenter push capability #1929
vCenter push capability #1929
Conversation
src/cmd/linuxkit/push_vcenter.go
Outdated
newVM.vSphereHost = flags.String("hostname", os.Getenv("VMHOST"), "The Server that will host the image") | ||
newVM.path = flags.String("path", "", "Path to a specific image") | ||
|
||
newVM.vmName = flags.String("folder", "", "A Folder on the datastore to push the image too") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
its confusing calling it "folder" and "vmName" - maybe call both folder?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Opted for vmFolder, as it makes sense in both use cases. With the run
the vmFolder is both the name of the VM and the name of the folder that will be created to house the various VM files. With push
the vmFolder is simply a folder created on a datastore that a will hold the VM iso
file. Does that sound OK?
src/cmd/linuxkit/push_vcenter.go
Outdated
// Ensure an iso has been passed to the vCenter push Command | ||
if strings.HasSuffix(*newVM.path, ".iso") { | ||
// Used as a folder to hold the images that are pushed | ||
if *newVM.vmName == "" { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
there is no need for this to be in this condition, it can be unconditional below.
src/cmd/linuxkit/push_vcenter.go
Outdated
newVM.dsName = flags.String("datastore", os.Getenv("VMDATASTORE"), "The Name of the DataStore to host the image") | ||
newVM.networkName = flags.String("network", os.Getenv("VMNETWORK"), "The VMware vSwitch the image will use") | ||
newVM.vSphereHost = flags.String("hostname", os.Getenv("VMHOST"), "The Server that will host the image") | ||
newVM.path = flags.String("path", "", "Path to a specific image") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Are these standard environment variables or made up? They seem to be inconsistently named and I would prefer if they had a common prefix...
src/cmd/linuxkit/push_vcenter.go
Outdated
flags := flag.NewFlagSet("vCenter", flag.ExitOnError) | ||
invoked := filepath.Base(os.Args[0]) | ||
|
||
newVM.vCenterURL = flags.String("url", os.Getenv("VCURL"), "URL in the format of https://username:password@host/sdk") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this the URL to the vcenter host? Id so, mention it in the help message
src/cmd/linuxkit/push_vcenter.go
Outdated
invoked := filepath.Base(os.Args[0]) | ||
|
||
newVM.vCenterURL = flags.String("url", os.Getenv("VCURL"), "URL in the format of https://username:password@host/sdk") | ||
newVM.dsName = flags.String("datastore", os.Getenv("VMDATASTORE"), "The Name of the DataStore to host the image") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: Name -> name
src/cmd/linuxkit/push_vcenter.go
Outdated
|
||
newVM.vCenterURL = flags.String("url", os.Getenv("VCURL"), "URL in the format of https://username:password@host/sdk") | ||
newVM.dsName = flags.String("datastore", os.Getenv("VMDATASTORE"), "The Name of the DataStore to host the image") | ||
newVM.networkName = flags.String("network", os.Getenv("VMNETWORK"), "The VMware vSwitch the image will use") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this the name of the network the VM will be placed on or the name of a vSwitch as the help message implies?
src/cmd/linuxkit/push_vcenter.go
Outdated
newVM.vCenterURL = flags.String("url", os.Getenv("VCURL"), "URL in the format of https://username:password@host/sdk") | ||
newVM.dsName = flags.String("datastore", os.Getenv("VMDATASTORE"), "The Name of the DataStore to host the image") | ||
newVM.networkName = flags.String("network", os.Getenv("VMNETWORK"), "The VMware vSwitch the image will use") | ||
newVM.vSphereHost = flags.String("hostname", os.Getenv("VMHOST"), "The Server that will host the image") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: Server -> server
src/cmd/linuxkit/push_vcenter.go
Outdated
newVM.vmFolder = flags.String("folder", "", "A Folder on the datastore to push the image too") | ||
|
||
flags.Usage = func() { | ||
fmt.Printf("USAGE: %s push vcenter [options] [name]\n\n", invoked) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
is name
optional as the brackets imply? To be consistent with the qemu runner this should probably be called path
src/cmd/linuxkit/push_vcenter.go
Outdated
|
||
// Ensure an iso has been passed to the vCenter push Command | ||
if !strings.HasSuffix(*newVM.path, ".iso") { | ||
log.Fatalln("Ensure that an \".iso\" file is used as part of the path") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
maybe rephrase: Please pass an ".iso" file as the path
or somesuch.
} | ||
|
||
if err := flags.Parse(args); err != nil { | ||
log.Fatalln("Unable to parse args") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
should we include the error message? log.Fatalf("Unable to parse args: %v", err)
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We should probably standardise this across all of the backends?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actually, looking through the source code as we use ExitOnError
and the parse
does the following:
case ExitOnError:
os.Exit(2)
The log.fatalln(...)
will never be called.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does that look right @justincormack / @rneugeba / @riyazdf ?
As we have this same snippet in a lot of places.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes thats probably true, but the linter will complain if we don't catch the error I guess so it doesn't really matter. Just be consistent with elsewhere.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
OK, i'll leave it as is for now.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
got it - yeah we can probably standardize this with a custom error type (in a followup PR across backends) but this is good for now
src/cmd/linuxkit/push_vcenter.go
Outdated
newVM.vSphereHost = flags.String("hostname", os.Getenv("VCHOST"), "The server that will host the image") | ||
newVM.path = flags.String("path", "", "Path to a specific image") | ||
|
||
newVM.vmFolder = flags.String("folder", "", "A Folder on the datastore to push the image too") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: can we lowercase to folder
?
src/cmd/linuxkit/run_vcenter.go
Outdated
|
||
newVM.vmName = flags.String("vmname", "", "Specify a name for virtual Machine") | ||
newVM.vmFolder = flags.String("vmfolder", "", "Specify a name/folder for the virtual Machine to reside in") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: can we lowercase to machine
?
newVM.vCenterURL = flags.String("url", os.Getenv("VCURL"), "URL of VMware vCenter in the format of https://username:password@VCaddress/sdk") | ||
newVM.dsName = flags.String("datastore", os.Getenv("VCDATASTORE"), "The name of the DataStore to host the VM") | ||
newVM.networkName = flags.String("network", os.Getenv("VCNETWORK"), "The network label the VM will use") | ||
newVM.vSphereHost = flags.String("hostname", os.Getenv("VCHOST"), "The server that will run the VM") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
what is the reason for changing to VC*
? Should we update the other flags like vmfolder
? I'm not too familiar with vCenter so I'm not sure what makes most sense here :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The VC**** environment variables are there to make it a bit more clearer when repeatedly deploying VMs. The credentials and labels for vCenter internals will stay the same, so we can store them elsewhere (env vars in this case), the rest of the flags we can pass as usual as there is some need for uniqueness. Also @rneugeba, suggested some format for the env variables so I opted for VC.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍 SGTM
src/cmd/linuxkit/run_vcenter.go
Outdated
// Parse URL from string | ||
u, err := url.Parse(*newVM.vCenterURL) | ||
if err != nil { | ||
log.Fatalf("URL can't be parsed, ensure it is https://username:password/<address>/sdk") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
might be helpful to include the err message here? log.Fatalf("URL can't be parsed, ensure it is https://username:password/<address>/sdk: %v", err)
src/cmd/linuxkit/run_vcenter.go
Outdated
// Connect and log in to ESX or vCenter | ||
c, err := govmomi.NewClient(ctx, u, true) | ||
if err != nil { | ||
log.Fatalln("Error logging into vCenter, check address and credentials") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
same comment re: including error message: log.Fatalf("Error logging into vCenter, check address and credentials: %v", err)
src/cmd/linuxkit/run_vcenter.go
Outdated
// Find one and only datacenter, not sure how VMware linked mode will work | ||
dc, err := f.DefaultDatacenter(ctx) | ||
if err != nil { | ||
log.Fatalln("No Datacenter instance could be found inside of vCenter") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
same comment re: including error message for this and subsequent errors
@@ -248,7 +260,7 @@ func addVMDK(ctx context.Context, vm *object.VirtualMachine, dss *object.Datasto | |||
log.Fatalf("Unable to find SCSI device from VM configuration\n%v", err) | |||
} | |||
// The default is to have all persistent disks named linuxkit.vmdk | |||
disk := devices.CreateDisk(controller, dss.Reference(), dss.Path(fmt.Sprintf("%s/%s", *newVM.vmName, "linuxkit.vmdk"))) | |||
disk := devices.CreateDisk(controller, dss.Reference(), dss.Path(fmt.Sprintf("%s/%s", *newVM.vmFolder, "linuxkit.vmdk"))) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
should this become configurable? Can be a separate PR, but wondering if we should open a tracking issue
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It was to begin with, but then it became apparent that uploading avmdk
from workstation to server required a lot more steps (image conversion from thin to fat, meant uploading GBs of zeros etc.) As there is a 1:1 mapping inside of VMware vCenter VMs I opted to keep it simple and in the event the run
requires a persistent disk they just get a new disk inside of their VM folder to use.
Happy to revisit this, it felt that uploading large existing disks or having to manipulate the disk controllers to support additional SCSI disks might be outside of what run
should be doing :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ah got it. Makes sense to keep it like this for now then, thank you for the explanation!
src/cmd/linuxkit/run_vcenter.go
Outdated
fmt.Printf("USAGE: %s run vcenter [options] [name]\n\n", invoked) | ||
fmt.Printf("'name' specifies the full path of an image that will be ran\n") | ||
fmt.Printf("USAGE: %s run vcenter [options] path\n\n", invoked) | ||
fmt.Printf("'path' specifies the full path of an image that will be ran\n") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
"that will be ran" reads weirdly, "to run" is better
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Updating, i've used "to run" below so changing it keeps the language consistent.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM after nits, thanks @thebsdbox!
} | ||
|
||
if err := flags.Parse(args); err != nil { | ||
log.Fatalln("Unable to parse args") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
got it - yeah we can probably standardize this with a custom error type (in a followup PR across backends) but this is good for now
newVM.vCenterURL = flags.String("url", os.Getenv("VCURL"), "URL of VMware vCenter in the format of https://username:password@VCaddress/sdk") | ||
newVM.dsName = flags.String("datastore", os.Getenv("VCDATASTORE"), "The name of the DataStore to host the VM") | ||
newVM.networkName = flags.String("network", os.Getenv("VCNETWORK"), "The network label the VM will use") | ||
newVM.vSphereHost = flags.String("hostname", os.Getenv("VCHOST"), "The server that will run the VM") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍 SGTM
src/cmd/linuxkit/run_vcenter.go
Outdated
// Find one and only datacenter, not sure how VMware linked mode will work | ||
dc, err := f.DefaultDatacenter(ctx) | ||
if err != nil { | ||
log.Fatalln("No Datacenter instance could be found inside of vCenter %v", err) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: I think this should be log.Fatalf
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
true :D fixed.
@@ -248,7 +260,7 @@ func addVMDK(ctx context.Context, vm *object.VirtualMachine, dss *object.Datasto | |||
log.Fatalf("Unable to find SCSI device from VM configuration\n%v", err) | |||
} | |||
// The default is to have all persistent disks named linuxkit.vmdk | |||
disk := devices.CreateDisk(controller, dss.Reference(), dss.Path(fmt.Sprintf("%s/%s", *newVM.vmName, "linuxkit.vmdk"))) | |||
disk := devices.CreateDisk(controller, dss.Reference(), dss.Path(fmt.Sprintf("%s/%s", *newVM.vmFolder, "linuxkit.vmdk"))) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ah got it. Makes sense to keep it like this for now then, thank you for the explanation!
Re-factored the `run` code to create the `push` functionality. Signed-off-by: Dan Finneran <daniel.finneran@gmail.com>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM on green, thanks for the quick fix!
Re-factored the
run
code to create thepush
functionality.Signed-off-by: Dan Finneran daniel.finneran@gmail.com
- What I did
Added the capability to
push
Linuxkit.iso
images to VMware vCenter. It uses a either a-folder=<NAME>
or will take the name of the image and create that folder to host the uploaded image.- How I did it
Modified
run_vcenter.go
to allowpush_vcenter.go
to log in to vCenter and upload images without creating a full VM.- How to verify it
Push
functionalityrun
functionality (ensuring changes haven't broken existing functionality.- Description for the changelog
Added the functionality to
push
linuxkit images to VMware vCenter.- A picture of a cute animal (not mandatory but encouraged)