Skip to content

Commit

Permalink
OpenStack: automatically populate RHCOS image
Browse files Browse the repository at this point in the history
  • Loading branch information
Fedosin committed Oct 8, 2019
1 parent 8c78182 commit 8a4153b
Show file tree
Hide file tree
Showing 12 changed files with 112 additions and 26 deletions.
7 changes: 1 addition & 6 deletions data/data/openstack/bootstrap/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -109,19 +109,14 @@ EOF
}
}

data "openstack_images_image_v2" "bootstrap_image" {
name = var.image_name
most_recent = true
}

data "openstack_compute_flavor_v2" "bootstrap_flavor" {
name = var.flavor_name
}

resource "openstack_compute_instance_v2" "bootstrap" {
name = "${var.cluster_id}-bootstrap"
flavor_id = data.openstack_compute_flavor_v2.bootstrap_flavor.id
image_id = data.openstack_images_image_v2.bootstrap_image.id
image_id = var.base_image_id

user_data = data.ignition_config.redirect.rendered

Expand Down
4 changes: 2 additions & 2 deletions data/data/openstack/bootstrap/variables.tf
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
variable "image_name" {
variable "base_image_id" {
type = string
description = "The name of the Glance image for the bootstrap node."
description = "The identifier of the Glance image for the bootstrap node."
}

variable "extra_tags" {
Expand Down
21 changes: 19 additions & 2 deletions data/data/openstack/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ module "bootstrap" {

cluster_id = var.cluster_id
extra_tags = var.openstack_extra_tags
image_name = var.openstack_base_image
base_image_id = data.openstack_images_image_v2.base_image.id
flavor_name = var.openstack_master_flavor_name
ignition = var.ignition_bootstrap
api_int_ip = var.openstack_api_int_ip
Expand All @@ -42,7 +42,7 @@ module "bootstrap" {
module "masters" {
source = "./masters"

base_image = var.openstack_base_image
base_image_id = data.openstack_images_image_v2.base_image.id
cluster_id = var.cluster_id
flavor_name = var.openstack_master_flavor_name
instance_count = var.master_count
Expand Down Expand Up @@ -72,3 +72,20 @@ module "topology" {
trunk_support = var.openstack_trunk_support
octavia_support = var.openstack_octavia_support
}

resource "openstack_images_image_v2" "base_image" {
count = var.openstack_base_image_url == "" ? 0 : 1

name = var.openstack_base_image
image_source_url = var.openstack_base_image_url
container_format = "bare"
disk_format = "qcow2"

tags = ["openshiftClusterID=${var.cluster_id}"]
}

data "openstack_images_image_v2" "base_image" {
name = var.openstack_base_image

depends_on = ["openstack_images_image_v2.base_image"]
}
9 changes: 2 additions & 7 deletions data/data/openstack/masters/main.tf
Original file line number Diff line number Diff line change
@@ -1,8 +1,3 @@
data "openstack_images_image_v2" "masters_img" {
name = var.base_image
most_recent = true
}

data "openstack_compute_flavor_v2" "masters_flavor" {
name = var.flavor_name
}
Expand Down Expand Up @@ -38,15 +33,15 @@ resource "openstack_blockstorage_volume_v3" "master_volume" {

size = var.root_volume_size
volume_type = var.root_volume_type
image_id = data.openstack_images_image_v2.masters_img.id
image_id = var.base_image_id
}

resource "openstack_compute_instance_v2" "master_conf" {
name = "${var.cluster_id}-master-${count.index}"
count = var.instance_count

flavor_id = data.openstack_compute_flavor_v2.masters_flavor.id
image_id = var.root_volume_size == null ? data.openstack_images_image_v2.masters_img.id : null
image_id = var.root_volume_size == null ? var.base_image_id : null
security_groups = var.master_sg_ids
user_data = element(
data.ignition_config.master_ignition_config.*.rendered,
Expand Down
5 changes: 3 additions & 2 deletions data/data/openstack/masters/variables.tf
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
variable "base_image" {
type = string
variable "base_image_id" {
type = string
description = "The identifier of the Glance image for master nodes."
}

variable "cluster_id" {
Expand Down
6 changes: 6 additions & 0 deletions data/data/openstack/variables-openstack.tf
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,12 @@ variable "openstack_base_image" {
description = "Name of the base image to use for the nodes."
}

variable "openstack_base_image_url" {
type = string
default = ""
description = "URL of the base image to use for the nodes."
}

variable "openstack_credentials_auth_url" {
type = string
default = ""
Expand Down
24 changes: 24 additions & 0 deletions pkg/asset/cluster/tfvars.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"encoding/json"
"fmt"
"os"
"time"

igntypes "github.com/coreos/ignition/config/v2_2/types"
gcpprovider "github.com/openshift/cluster-api-provider-gcp/pkg/apis/gcpprovider/v1beta1"
Expand All @@ -24,6 +25,7 @@ import (
gcpconfig "github.com/openshift/installer/pkg/asset/installconfig/gcp"
"github.com/openshift/installer/pkg/asset/machines"
"github.com/openshift/installer/pkg/asset/rhcos"
rhcosplatforms "github.com/openshift/installer/pkg/rhcos"
"github.com/openshift/installer/pkg/tfvars"
awstfvars "github.com/openshift/installer/pkg/tfvars/aws"
azuretfvars "github.com/openshift/installer/pkg/tfvars/azure"
Expand Down Expand Up @@ -270,6 +272,26 @@ func (t *TerraformVariables) Generate(parents asset.Parents) error {
if err != nil {
return err
}

baseImage := string(*rhcosImage)
var baseImageURL string

// If baseImage is empty then it was not provided by the user and we need to create it.
// For doing this we get the image URL and give it to Terraform.
// Image name in this case will be: <InfraID>-rhcos, i.e. user-rdd6e-rhcos
if baseImage == "" {
var err error
ctx, cancel := context.WithTimeout(context.TODO(), 30*time.Second)
defer cancel()

baseImageURL, err = rhcosplatforms.OpenStack(ctx)
if err != nil {
return err
}

baseImage = clusterID.InfraID + "-rhcos"
}

data, err = openstacktfvars.TFVars(
masters[0].Spec.ProviderSpec.Value.Object.(*openstackprovider.OpenstackProviderSpec),
installConfig.Config.Platform.OpenStack.Cloud,
Expand All @@ -280,6 +302,8 @@ func (t *TerraformVariables) Generate(parents asset.Parents) error {
ingressVIP.String(),
installConfig.Config.Platform.OpenStack.TrunkSupport,
installConfig.Config.Platform.OpenStack.OctaviaSupport,
baseImage,
baseImageURL,
)
if err != nil {
return errors.Wrapf(err, "failed to get %s Terraform variables", platform)
Expand Down
6 changes: 5 additions & 1 deletion pkg/asset/machines/master.go
Original file line number Diff line number Diff line change
Expand Up @@ -216,8 +216,12 @@ func (m *Master) Generate(dependencies asset.Parents) error {
mpool.Set(ic.Platform.BareMetal.DefaultMachinePlatform)
mpool.Set(pool.Platform.BareMetal)
pool.Platform.BareMetal = &mpool
imageName := string(*rhcosImage)
if imageName == "" {
imageName = clusterID.InfraID + "-rhcos"
}

machines, err = baremetal.Machines(clusterID.InfraID, ic, pool, string(*rhcosImage), "master", "master-user-data")
machines, err = baremetal.Machines(clusterID.InfraID, ic, pool, imageName, "master", "master-user-data")
if err != nil {
return errors.Wrap(err, "failed to create master machine objects")
}
Expand Down
6 changes: 5 additions & 1 deletion pkg/asset/machines/worker.go
Original file line number Diff line number Diff line change
Expand Up @@ -246,8 +246,12 @@ func (w *Worker) Generate(dependencies asset.Parents) error {
mpool.Set(ic.Platform.OpenStack.DefaultMachinePlatform)
mpool.Set(pool.Platform.OpenStack)
pool.Platform.OpenStack = &mpool
imageName := string(*rhcosImage)
if imageName == "" {
imageName = clusterID.InfraID + "-rhcos"
}

sets, err := openstack.MachineSets(clusterID.InfraID, ic, &pool, string(*rhcosImage), "worker", "worker-user-data")
sets, err := openstack.MachineSets(clusterID.InfraID, ic, &pool, imageName, "worker", "worker-user-data")
if err != nil {
return errors.Wrap(err, "failed to create master machine objects")
}
Expand Down
4 changes: 1 addition & 3 deletions pkg/asset/rhcos/image.go
Original file line number Diff line number Diff line change
Expand Up @@ -77,16 +77,14 @@ func osImage(config *types.InstallConfig) (string, error) {
osimage, err = rhcos.GCP(ctx)
case libvirt.Name:
osimage, err = rhcos.QEMU(ctx)
case openstack.Name:
osimage = "rhcos"
case azure.Name:
osimage, err = rhcos.VHD(ctx)
case baremetal.Name:
// Note that baremetal IPI currently uses the OpenStack image
// because this contains the necessary ironic config drive
// ignition support, which isn't enabled in the UPI BM images
osimage, err = rhcos.OpenStack(ctx)
case none.Name, vsphere.Name:
case none.Name, openstack.Name, vsphere.Name:
default:
return "", errors.New("invalid Platform")
}
Expand Down
40 changes: 40 additions & 0 deletions pkg/destroy/openstack/openstack.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import (
"github.com/gophercloud/gophercloud"
"github.com/gophercloud/gophercloud/openstack/blockstorage/v3/volumes"
"github.com/gophercloud/gophercloud/openstack/compute/v2/servers"
"github.com/gophercloud/gophercloud/openstack/imageservice/v2/images"
"github.com/gophercloud/gophercloud/openstack/loadbalancer/v2/apiversions"
"github.com/gophercloud/gophercloud/openstack/loadbalancer/v2/loadbalancers"
"github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/layer3/floatingips"
Expand Down Expand Up @@ -133,6 +134,7 @@ func populateDeleteFuncs(funcs map[string]deleteFunc) {
funcs["deleteContainers"] = deleteContainers
funcs["deleteVolumes"] = deleteVolumes
funcs["deleteFloatingIPs"] = deleteFloatingIPs
funcs["deleteImages"] = deleteImages
}

// filterObjects will do client-side filtering given an appropriately filled out
Expand Down Expand Up @@ -876,3 +878,41 @@ func deleteFloatingIPs(opts *clientconfig.ClientOpts, filter Filter, logger logr
}
return len(allFloatingIPs) == 0, nil
}

func deleteImages(opts *clientconfig.ClientOpts, filter Filter, logger logrus.FieldLogger) (bool, error) {
logger.Debug("Deleting openstack base image")
defer logger.Debugf("Exiting deleting openstack base image")

conn, err := clientconfig.NewServiceClient("image", opts)
if err != nil {
logger.Fatalf("%v", err)
os.Exit(1)
}

listOpts := images.ListOpts{
Tags: filterTags(filter),
}

allPages, err := images.List(conn, listOpts).AllPages()
if err != nil {
logger.Fatalf("%v", err)
os.Exit(1)
}

allImages, err := images.ExtractImages(allPages)
if err != nil {
logger.Fatalf("%v", err)
os.Exit(1)
}

for _, image := range allImages {
logger.Debugf("Deleting image: %+v", image.ID)
err := images.Delete(conn, image.ID).ExtractErr()
if err != nil {
// This can fail if the image is still in use by other VMs
logger.Debugf("Deleting Image failed: %v", err)
return false, nil
}
}
return true, nil
}
6 changes: 4 additions & 2 deletions pkg/tfvars/openstack/openstack.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import (

type config struct {
BaseImage string `json:"openstack_base_image,omitempty"`
BaseImageURL string `json:"openstack_base_image_url,omitempty"`
ExternalNetwork string `json:"openstack_external_network,omitempty"`
Cloud string `json:"openstack_credentials_cloud,omitempty"`
FlavorName string `json:"openstack_master_flavor_name,omitempty"`
Expand All @@ -23,9 +24,10 @@ type config struct {
}

// TFVars generates OpenStack-specific Terraform variables.
func TFVars(masterConfig *v1alpha1.OpenstackProviderSpec, cloud string, externalNetwork string, lbFloatingIP string, apiVIP string, dnsVIP string, ingressVIP string, trunkSupport string, octaviaSupport string) ([]byte, error) {
func TFVars(masterConfig *v1alpha1.OpenstackProviderSpec, cloud string, externalNetwork string, lbFloatingIP string, apiVIP string, dnsVIP string, ingressVIP string, trunkSupport string, octaviaSupport string, baseImage string, baseImageURL string) ([]byte, error) {
cfg := &config{
BaseImage: masterConfig.Image,
BaseImage: baseImage,
BaseImageURL: baseImageURL,
ExternalNetwork: externalNetwork,
Cloud: cloud,
FlavorName: masterConfig.Flavor,
Expand Down

0 comments on commit 8a4153b

Please sign in to comment.