diff --git a/.gitignore b/.gitignore index c6788af..cd708e4 100644 --- a/.gitignore +++ b/.gitignore @@ -16,4 +16,5 @@ dist/ .python-version /examples/.python-version coverage.txt - +output/ +build.sh diff --git a/virtualbox/provider.go b/virtualbox/provider.go index 9ad468c..478960b 100644 --- a/virtualbox/provider.go +++ b/virtualbox/provider.go @@ -10,10 +10,17 @@ import ( "fmt" "log" "os" + "time" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" ) +// Provider configuration structure +type Config struct { + ReadyDelay time.Duration + ReadyTimeout time.Duration +} + func init() { // Terraform is already adding the timestamp for us log.SetFlags(log.Lshortfile) @@ -23,8 +30,41 @@ func init() { // Provider returns a resource provider for virtualbox. func Provider() *schema.Provider { return &schema.Provider{ + // Provider configuration + Schema: map[string]*schema.Schema{ + "ready_delay": &schema.Schema{ + Type: schema.TypeInt, + Optional: true, + }, + "ready_timeout": &schema.Schema{ + Type: schema.TypeInt, + Optional: true, + }, + }, + ResourcesMap: map[string]*schema.Resource{ "virtualbox_vm": resourceVM(), }, + + ConfigureFunc: providerConfigure, } } + +func providerConfigure(d *schema.ResourceData) (interface{}, error) { + config := &Config{ + ReadyDelay: time.Duration(d.Get("ready_delay").(int)) * time.Second, + ReadyTimeout: time.Duration(d.Get("ready_timeout").(int)) * time.Second, + } + + if config.ReadyDelay == 0 { + log.Printf("[INFO] No ready_delay was configured, using 60 seconds by default.") + config.ReadyDelay = time.Duration(60) * time.Second + } + + if config.ReadyTimeout == 0 { + log.Printf("[INFO] No ready_timeout was configured, using 5 seconds by default.") + config.ReadyTimeout = time.Duration(5) * time.Second + } + + return config, nil +} diff --git a/virtualbox/resource_vm.go b/virtualbox/resource_vm.go index 4e46ce2..1a06ec9 100644 --- a/virtualbox/resource_vm.go +++ b/virtualbox/resource_vm.go @@ -512,6 +512,9 @@ func resourceVMDelete(d *schema.ResourceData, meta interface{}) error { // Wait until VM is ready, and 'ready' means the first non NAT NIC get a ipv4_address assigned func waitUntilVMIsReady(ctx context.Context, d *schema.ResourceData, vm *vbox.Machine, meta interface{}) error { + + config := meta.(*Config) + for i, nic := range vm.NICs { if nic.Network == vbox.NICNetNAT { continue @@ -525,8 +528,8 @@ func waitUntilVMIsReady(ctx context.Context, d *schema.ResourceData, vm *vbox.Ma []string{"no"}, key, meta, - 30*time.Second, - 1*time.Second, + config.ReadyDelay, // used to be hardcoded as 30 + config.ReadyTimeout, // used to be hardcoded as 1 ); err != nil { return errors.Wrapf(err, "waiting for VM (%s) to become ready", d.Get("name")) } diff --git a/website/docs/index.html.markdown b/website/docs/index.html.markdown index 0164100..5fc2e2b 100644 --- a/website/docs/index.html.markdown +++ b/website/docs/index.html.markdown @@ -8,10 +8,10 @@ description: |- # Virtualbox Provider -The Virtualbox provider for Terraform allows to manage local virtualbox machines +The Virtualbox provider for Terraform allows managing local VirtualBox machines using Terraform. The main purpose of this provider is to make you familiar with Terraform and provisioning machines, without leaving your machine, therefore -saving you costs. However remember that your local environment might differ +saving you costs. However, remember that your local environment might differ from a cloud provider. ## Example Usage @@ -26,27 +26,32 @@ terraform { } } -# There are currently no configuration options for the provider itself. - -resource "virtualbox_vm" "node" { - count = 2 - name = format("node-%02d", count.index + 1) - image = "https://app.vagrantup.com/ubuntu/boxes/bionic64/versions/20180903.0.0/providers/virtualbox.box" - cpus = 2 +# In general, you can use the provider without the need to set any configuration options. +# However, should you want to adjust how long it will wait for a VM to become ready, +# you can use the following block. Uncomment it and adjust the values (they are in seconds). +# provider "virtualbox" { +# ready_delay = 60 +# ready_timeout = 5 +# } + +resource "virtualbox_vm" "vm1" { + name = "debian-11" + image = "https://app.vagrantup.com/generic/boxes/debian11/versions/4.3.12/providers/virtualbox/amd64/vagrant.box" + cpus = 1 memory = "512 mib" user_data = file("${path.module}/user_data") network_adapter { type = "hostonly" + device = "IntelPro1000MTDesktop" host_interface = "vboxnet1" + # On Windows use this instead + # host_interface = "VirtualBox Host-Only Ethernet Adapter" } } -output "IPAddr" { - value = element(virtualbox_vm.node.*.network_adapter.0.ipv4_address, 1) +output "IPAddress" { + value = element(virtualbox_vm.vm1.*.network_adapter.0.ipv4_address, 1) } -output "IPAddr_2" { - value = element(virtualbox_vm.node.*.network_adapter.0.ipv4_address, 2) -} ``` diff --git a/website/docs/r/vm.html.markdown b/website/docs/r/vm.html.markdown index 6c1aeab..df031a3 100644 --- a/website/docs/r/vm.html.markdown +++ b/website/docs/r/vm.html.markdown @@ -12,17 +12,19 @@ Creates and manages a Virtualbox VM ## Example Usage ```hcl -resource "virtualbox_vm" "node" { - count = 2 - name = format("node-%02d", count.index + 1) - image = "https://app.vagrantup.com/ubuntu/boxes/bionic64/versions/20180903.0.0/providers/virtualbox.box" - cpus = 2 +resource "virtualbox_vm" "vm1" { + name = "debian-11" + image = "https://app.vagrantup.com/generic/boxes/debian11/versions/4.3.12/providers/virtualbox/amd64/vagrant.box" + cpus = 1 memory = "512 mib" user_data = file("${path.module}/user_data") network_adapter { type = "hostonly" + device = "IntelPro1000MTDesktop" host_interface = "vboxnet1" + # On Windows use this instead + # host_interface = "VirtualBox Host-Only Ethernet Adapter" } } ``` @@ -35,10 +37,10 @@ The following arguments are supported: - `image`, string, required: The place of the image file (archive or vagrant box). This can be a remote resource (http/https), or local location. (ex. [Ubuntu Virtualbox image](https://github.com/ccll/terraform-provider-virtualbox-images/releases)) -- `url`, DEPRECATED - USE `image`, string, optional, default not set: The url +- `url`, DEPRECATED - USE `image`, string, optional, default not set: The URL for downloaded vagrant box from external resource. Overrides `image` if set. - `cpus`, int, optional, default=2: The number of CPUs. -- `memory`, string, optional, default="512mib": The size of memory, allow human +- `memory`, string, optional, default="512mib": The size of memory, allows human friendly units like 'MB', 'MiB'. - `user_data`, string, optional, default="": User defined data. - `status`, string, optional, default="running": The status of the VM. This @@ -65,6 +67,5 @@ The following arguments are supported: generated by VirtualBox. - `.#.ipv4_address`, string, computed: The IPv4 address assigned to the adapter. - - `.#.ipv4_address_available`, string, computed: Wheather or not an IPv4 - address is actaully assigned to the adapter, possible values: "yes", "no". + - `.#.ipv4_address_available`, string, computed: Whether or not an IPv4 address is actually assigned to the adapter, possible values: "yes", "no". - `optical_disks`, list: The iso image to attach.