Skip to content

Commit

Permalink
Merge branch 'master' into nomac
Browse files Browse the repository at this point in the history
  • Loading branch information
MalloZup committed Sep 28, 2018
2 parents a13c304 + e68c3e5 commit 9110601
Show file tree
Hide file tree
Showing 18 changed files with 350 additions and 388 deletions.
2 changes: 0 additions & 2 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,5 +17,3 @@ script:
- make gofmtcheck
- make vet
- golint -set_exit_status libvirt/
- make test
- goveralls -coverprofile=profile.cov -service=travis-ci
4 changes: 4 additions & 0 deletions examples/resize_base/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
*.img
*.qcow2
*.tfstate*
.terraform
11 changes: 11 additions & 0 deletions examples/resize_base/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@

This example takes a base image of 2G and uses it as the backing store of a bigger volume. _cloud-init_ is then used to resize the original partition to the new available space.

See https://github.com/dmacvicar/terraform-provider-libvirt/issues/369

# Running

```console
$ terraform apply
$ ssh -i id_rsa "root@$(terraform output ip)"
```
27 changes: 27 additions & 0 deletions examples/resize_base/id_rsa
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
-----BEGIN RSA PRIVATE KEY-----
MIIEpAIBAAKCAQEAzKsKBhrbzq5Ur80tDE2t5fsAkJ5qHnm5w0v9cEVKkkPgeUTi
+VswoBAFMjf1nTKbGZAEsXS8nphD4XURdztV+p1m7XopzS1uC0DDyPm5TxWptMSd
ZAS2DA0l0eeyvKmNGveKKcrgFAjwMENr3syjwfNKao5waYSkLBvvgp6oWkPJG7RK
SER6z/n1JBhJoGwAu8plNsLWRhhoYrGMaVTsOcYj2ohFNM3c59UarwLPsKlV2TRJ
PFpLkGm69BYMR2fxHyFLn1iEMvy21X0wcs4bh2SLB8qTu1uDko6MneAAlFQgPgvJ
cIYWhgdyIi0VGhatvPFH4E0C2wfADqV3us5qzwIDAQABAoIBAQCJ0LplNfzBBX6d
ConE+SGZ9RSCTUmjz8+YhDjaOq5mIzKqNgqoYhEyFteI40mOWp857VJbtAG2wU0k
KdJi+R+CLC88xcAUGv04spmjYRS4/htST/qzeMClCM1otJ4UkA8mE32Desq8cvBZ
b2zZj+7NEOgRLGzhgKGT2hPDXtZ6QGn9+K6xUrjGp9gOhKgFWz7jNqlxQQh/bvLt
BHj/YHcCT32TFf7AciZK/gDT+8D9a3rTzBKFhmCoHnCyJlqF/EPlA29VEL2rOFR8
638MIXSWCnK2LXCD6V7x+l9KKyJndh5TFlcdUIZ7YOpDcnWrRNjzuCkzb2KK2cdD
URekeL5RAoGBAPMTEGHCwBkq2tB93tWl3M6rMqs2pLoWv+r74dIBhSdvzFhq7vrL
TGwR59JhXPlcde97ANyZpulxEIKzVJE0mRHFebnNxz+MmRVcj4cNeE4b1GKwmx00
hcy2RSjM+9YnFFLUWyZIPKY0NiW3aBC98aPn0biiG6ZGIXJVmAlladz1AoGBANeN
J8YTLpVb7p5+B9nbSM3mvx+ZtAifAeDR792nTSN7DjQSYOfNrzTqdfqveSPtrpnZ
wgMa9nQyFFtMp0eDB835dy/ZA/w918H5YwFgabgTQ+eBJjZNI2iSyptITCbieUHV
MOin5nlhonx1jirhZEHDS8gGoIV3TQQlzu/E2g4zAoGAIr7e4JqOCwrtLFBRwghr
f79JBuBQu6j01gobRYGiHvkEJL9kWcUlr2z/zjrMp3hoA0t53A66pTPcQFKSDA+Q
sdGgjMa1bIgUedE5UvzB7ahcu56zDYGsfo6vZB2pAfukFBL21IoO4VMlSk7lOT9t
gxhoChRiD2qG7Wj+ypkMgOECgYB7LSvcchu9uHJM2gKMiVY6a7EuUrxh7NO68N1c
0f0v2GNOeG4uKQkFeTKAVgQo9us++gR3l9Hcpr2hStWQ9RzhpLxqeF5hp8mDDIt6
PulLCp9UTSZUA5LHcJMdV5xE4EigyT6QxVncZWHgM6FRecm8FulYXgkfHATD6QMv
W1OspwKBgQDviiVBtlUvRWo9wUs1Y1tYCwBjFVztaJBGQ+Qx5uhYAhSobwUTW/MI
1lrxpGWaBfe63Iy+3V8v7YLU/bjjUMrzNFTrvoERwoRndL5EDqL5clljHO5kW+2g
wXfNa8BPj2EiqmmMcM3rcxd7Kw7qvEFLeJk9WE6EvKjvYiirr20mhQ==
-----END RSA PRIVATE KEY-----
1 change: 1 addition & 0 deletions examples/resize_base/id_rsa.pub
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDMqwoGGtvOrlSvzS0MTa3l+wCQnmoeebnDS/1wRUqSQ+B5ROL5WzCgEAUyN/WdMpsZkASxdLyemEPhdRF3O1X6nWbteinNLW4LQMPI+blPFam0xJ1kBLYMDSXR57K8qY0a94opyuAUCPAwQ2vezKPB80pqjnBphKQsG++CnqhaQ8kbtEpIRHrP+fUkGEmgbAC7ymU2wtZGGGhisYxpVOw5xiPaiEU0zdzn1RqvAs+wqVXZNEk8WkuQabr0FgxHZ/EfIUufWIQy/LbVfTByzhuHZIsHypO7W4OSjoyd4ACUVCA+C8lwhhaGB3IiLRUaFq288UfgTQLbB8AOpXe6zmrP duncan@piscolita.suse.de
76 changes: 76 additions & 0 deletions examples/resize_base/main.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
provider "libvirt" {
uri = "qemu:///system"
}

resource "libvirt_volume" "os_image_ubuntu" {
name = "os_image_ubuntu"
pool = "default"
source = "https://cloud-images.ubuntu.com/releases/xenial/release/ubuntu-16.04-server-cloudimg-amd64-disk1.img"
}

resource "libvirt_volume" "disk_ubuntu_resized" {
name = "disk"
base_volume_id = "${libvirt_volume.os_image_ubuntu.id}"
pool = "default"
size = 5361393152
}

# Use CloudInit to add our ssh-key to the instance
resource "libvirt_cloudinit_disk" "cloudinit_ubuntu_resized" {
name = "cloudinit_ubuntu_resized.iso"
pool = "default"
user_data = <<EOF
#cloud-config
disable_root: 0
ssh_pwauth: 1
users:
- name: root
ssh-authorized-keys:
- ${file("id_rsa.pub")}
growpart:
mode: auto
devices: ['/']
EOF
}

resource "libvirt_domain" "domain_ubuntu_resized" {
name = "doman_ubuntu_resized"
memory = "512"
vcpu = 1

cloudinit = "${libvirt_cloudinit_disk.cloudinit_ubuntu_resized.id}"

network_interface {
network_name = "default"
wait_for_lease = true
}

# IMPORTANT
# Ubuntu can hang if an isa-serial is not present at boot time.
# If you find your CPU 100% and never is available this is why
console {
type = "pty"
target_port = "0"
target_type = "serial"
}

console {
type = "pty"
target_type = "virtio"
target_port = "1"
}

disk {
volume_id = "${libvirt_volume.disk_ubuntu_resized.id}"
}

graphics {
type = "spice"
listen_type = "address"
autoport = true
}
}

output "ip" {
value = "${libvirt_domain.domain_ubuntu_resized.network_interface.0.addresses.0}"
}
60 changes: 60 additions & 0 deletions libvirt/acceptance_tests_functions_helpers.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,18 @@ package libvirt

import (
"fmt"
"log"

"github.com/hashicorp/terraform/helper/resource"
"github.com/hashicorp/terraform/terraform"
libvirt "github.com/libvirt/libvirt-go"
"github.com/libvirt/libvirt-go-xml"
)

// This file contain function helpers used for testsuite/testacc

// the following helpers are used in mostly all testacc.

// getResourceFromTerraformState get aresource by name
// from terraform states produced during testacc
// and return the resource
Expand All @@ -21,5 +27,59 @@ func getResourceFromTerraformState(resourceName string, state *terraform.State)
return nil, fmt.Errorf("No libvirt resource key ID is set")
}
return rs, nil
}

// test in all testacc that resource is destroyed
func testaccCheckLibvirtDestroyResource(resourceName string, virConn libvirt.Connect) resource.TestCheckFunc {
return func(s *terraform.State) error {
for _, rs := range s.RootModule().Resources {
if rs.Type != resourceName {
continue
}

_, err := virConn.LookupDomainByUUIDString(rs.Primary.ID)
if err == nil {
return fmt.Errorf(
"Error waiting for resource (%s) to be destroyed: %s",
rs.Primary.ID, err)
}
}

return nil
}
}

// ** resource specifics helpers **

// getVolumeFromTerraformState lookup volume by name and return the libvirt volume from a terraform state
func getVolumeFromTerraformState(name string, state *terraform.State, virConn libvirt.Connect) (*libvirt.StorageVol, error) {
rs, err := getResourceFromTerraformState(name, state)
if err != nil {
return nil, err
}

vol, err := virConn.LookupStorageVolByKey(rs.Primary.ID)
if err != nil {
return nil, err
}
log.Printf("[DEBUG]:The ID is %s", rs.Primary.ID)
return vol, nil
}

// helper used in network tests for retrieve xml network definition.
func getNetworkDef(state *terraform.State, name string, virConn libvirt.Connect) (*libvirtxml.Network, error) {
var network *libvirt.Network
rs, err := getResourceFromTerraformState(name, state)
if err != nil {
return nil, err
}
network, err = virConn.LookupNetworkByUUIDString(rs.Primary.ID)
if err != nil {
return nil, err
}
networkDef, err := getXMLNetworkDefFromLibvirt(network)
if err != nil {
return nil, fmt.Errorf("Error reading libvirt network XML description: %s", err)
}
return &networkDef, nil
}
17 changes: 7 additions & 10 deletions libvirt/data_source_libvirt_network_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,8 @@ import (

func TestAccLibvirtNetworkDataSource_DNSHostTemplate(t *testing.T) {
resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
CheckDestroy: testAccCheckLibvirtNetworkDestroy,
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
Steps: []resource.TestStep{

{
Expand All @@ -33,13 +32,11 @@ func TestAccLibvirtNetworkDataSource_DNSHostTemplate(t *testing.T) {
}

func checkDNSHostTemplate(id, name, value string) resource.TestCheckFunc {
return func(s *terraform.State) error {
rs, ok := s.RootModule().Resources[id]
if !ok {
return fmt.Errorf("Not found: %s", id)
}
if rs.Primary.ID == "" {
return fmt.Errorf("No ID is set")
return func(state *terraform.State) error {

rs, err := getResourceFromTerraformState(id, state)
if err != nil {
return err
}

v := rs.Primary.Attributes[name]
Expand Down
83 changes: 6 additions & 77 deletions libvirt/domain.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ const domWaitLeaseDone = "all-addresses-obtained"
var errDomainInvalidState = errors.New("invalid state for domain")

func domainWaitForLeases(domain *libvirt.Domain, waitForLeases []*libvirtxml.DomainInterface,
timeout time.Duration, domainDef libvirtxml.Domain, virConn *libvirt.Connect, rd *schema.ResourceData) error {
timeout time.Duration, rd *schema.ResourceData) error {
waitFunc := func() (interface{}, string, error) {

state, err := domainGetState(*domain)
Expand All @@ -46,7 +46,7 @@ func domainWaitForLeases(domain *libvirt.Domain, waitForLeases []*libvirtxml.Dom

// check we have IPs for all the interfaces we are waiting for
for _, iface := range waitForLeases {
found, ignore, err := domainIfaceHasAddress(*domain, *iface, domainDef, virConn, rd)
found, ignore, err := domainIfaceHasAddress(*domain, *iface, rd)
if err != nil {
return false, "", err
}
Expand Down Expand Up @@ -78,9 +78,7 @@ func domainWaitForLeases(domain *libvirt.Domain, waitForLeases []*libvirtxml.Dom
return err
}

func domainIfaceHasAddress(domain libvirt.Domain, iface libvirtxml.DomainInterface,
domainDef libvirtxml.Domain, virConn *libvirt.Connect, rd *schema.ResourceData) (found bool, ignore bool, err error) {

func domainIfaceHasAddress(domain libvirt.Domain, iface libvirtxml.DomainInterface, rd *schema.ResourceData) (found bool, ignore bool, err error) {
// domainGetIfacesInfo retrieve network info from qemu-agent(disabled by default)
// and from libvirt-api, which will give the NetIfaces with adress and mac
ifacesWithAddr, err := domainGetIfacesInfo(domain, domainDef, virConn, rd)
Expand Down Expand Up @@ -141,8 +139,7 @@ func domainIsRunning(domain libvirt.Domain) (bool, error) {
return state == libvirt.DOMAIN_RUNNING, nil
}

func domainGetIfacesInfo(domain libvirt.Domain, domainDef libvirtxml.Domain,
virConn *libvirt.Connect, rd *schema.ResourceData) ([]libvirt.DomainInterface, error) {
func domainGetIfacesInfo(domain libvirt.Domain, rd *schema.ResourceData) ([]libvirt.DomainInterface, error) {
qemuAgentEnabled := rd.Get("qemu_agent").(bool)
if qemuAgentEnabled {
// get all the interfaces using the qemu-agent, this includes also
Expand All @@ -159,12 +156,7 @@ func domainGetIfacesInfo(domain libvirt.Domain, domainDef libvirtxml.Domain,
} else {
log.Printf("[DEBUG] qemu-agent is not used")
}

log.Print("[DEBUG] getting domain addresses from networks")
interfaces := getDomainInterfacesFromNetworks(domainDef, virConn)
if len(interfaces) > 0 {
return interfaces, nil
}
var interfaces []libvirt.DomainInterface

// get all the interfaces attached to libvirt networks
log.Print("[DEBUG] no interfaces could be obtained with qemu-agent: falling back to the libvirt API")
Expand Down Expand Up @@ -193,67 +185,4 @@ func domainGetIfacesInfo(domain libvirt.Domain, domainDef libvirtxml.Domain,
log.Printf("[DEBUG] Interfaces info obtained with libvirt API:\n%s\n", spew.Sdump(interfaces))

return interfaces, nil
}

func getDomainInterfacesFromNetworks(domain libvirtxml.Domain,
virConn *libvirt.Connect) []libvirt.DomainInterface {

var ifacesList []libvirt.DomainInterface
var networkNames []string
var macAddresses []string

for _, networkInterface := range domain.Devices.Interfaces {
// only for devices with a network associated to it
if networkInterface.Source.Network == nil {
continue
}
networkNames = append(networkNames, networkInterface.Source.Network.Network)
if networkInterface.MAC != nil {
macAddresses = append(macAddresses, strings.ToUpper(networkInterface.MAC.Address))
}
}

networkMacAddresses := make(map[string]map[string][]string)
for _, networkName := range networkNames {
network, err := virConn.LookupNetworkByName(networkName)
if err != nil {
log.Printf("[ERROR] Error retrieving libvirt network: %s", err)
return ifacesList
}
defer network.Free()

networkDef, err := getXMLNetworkDefFromLibvirt(network)
macAddresses := make(map[string][]string)
for _, ips := range networkDef.IPs {
if ips.DHCP != nil {
for _, dhcpHost := range ips.DHCP.Hosts {
if dhcpHost.MAC != "" {
macAddresses[dhcpHost.MAC] = append(macAddresses[dhcpHost.MAC], dhcpHost.IP)
}
}
}
}
networkMacAddresses[networkName] = macAddresses
}

for name, networkMacAddress := range networkMacAddresses {
for mac, ips := range networkMacAddress {
for _, domMac := range macAddresses {
if mac == domMac {
virDom := libvirt.DomainInterface{}
virDom.Name = name
virDom.Hwaddr = mac
for _, ip := range ips {
virDomIP := libvirt.DomainIPAddress{}
virDomIP.Addr = ip
virDom.Addrs = append(virDom.Addrs, virDomIP)
}
ifacesList = append(ifacesList, virDom)
}
}
}
}

log.Printf("[DEBUG] Interfaces: %s", spew.Sdump(ifacesList))
return ifacesList
}
}
13 changes: 6 additions & 7 deletions libvirt/resource_libvirt_cloud_init_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,9 @@ func TestAccLibvirtCloudInit_CreateCloudInitDiskAndUpdate(t *testing.T) {
expectedContentsEmpty := Expected{UserData: "#cloud-config2", NetworkConfig: "", MetaData: ""}
randomIsoName := acctest.RandString(10) + ".iso"
resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
CheckDestroy: func(s *terraform.State) error {
return nil
},
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
CheckDestroy: testaccCheckLibvirtDestroyResource("libvirt_cloudinit_disk", *testAccProvider.Meta().(*Client).libvirt),
Steps: []resource.TestStep{
{
Config: fmt.Sprintf(`
Expand Down Expand Up @@ -107,8 +105,9 @@ func TestAccLibvirtCloudInit_ManuallyDestroyed(t *testing.T) {
}`, randomResourceName, randomResourceName)

resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
CheckDestroy: testaccCheckLibvirtDestroyResource("libvirt_cloudinit_disk", *testAccProvider.Meta().(*Client).libvirt),
Steps: []resource.TestStep{
{
Config: testAccCheckLibvirtCloudInitConfigBasic,
Expand Down
Loading

0 comments on commit 9110601

Please sign in to comment.