diff --git a/data/data/baremetal/bootstrap/main.tf b/data/data/baremetal/bootstrap/main.tf index f18f23b4672..38d4e791566 100644 --- a/data/data/baremetal/bootstrap/main.tf +++ b/data/data/baremetal/bootstrap/main.tf @@ -11,7 +11,7 @@ resource "libvirt_ignition" "bootstrap" { resource "libvirt_domain" "bootstrap" { name = "${var.cluster_id}-bootstrap" - memory = "4096" + memory = "6144" vcpu = "4" diff --git a/data/data/baremetal/main.tf b/data/data/baremetal/main.tf index 22ba6c78df0..9d209a83a5d 100644 --- a/data/data/baremetal/main.tf +++ b/data/data/baremetal/main.tf @@ -3,8 +3,9 @@ provider "libvirt" { } provider "ironic" { - url = var.ironic_uri + url = "http://${var.bootstrap_provisioning_ip}:6385/v1" microversion = "1.52" + timeout = 1500 } module "bootstrap" { diff --git a/data/data/baremetal/variables-baremetal.tf b/data/data/baremetal/variables-baremetal.tf index 287457c6ef3..8afaaf96028 100644 --- a/data/data/baremetal/variables-baremetal.tf +++ b/data/data/baremetal/variables-baremetal.tf @@ -1,6 +1,6 @@ -variable "ironic_uri" { +variable "bootstrap_provisioning_ip" { type = string - description = "ironic connection URI" + description = "IP for the bootstrap VM provisioning nic" } variable "libvirt_uri" { diff --git a/data/data/bootstrap/baremetal/files/usr/local/bin/startironic.sh.template b/data/data/bootstrap/baremetal/files/usr/local/bin/startironic.sh.template new file mode 100755 index 00000000000..c30d58e16e8 --- /dev/null +++ b/data/data/bootstrap/baremetal/files/usr/local/bin/startironic.sh.template @@ -0,0 +1,120 @@ +#!/bin/bash + +set -ex + +# We should switch to openshift builds of these images when ready ref +# https://github.com/openshift/installer/issues/2090 +IRONIC_IMAGE=${IRONIC_IMAGE:-"quay.io/metal3-io/ironic:master"} +IRONIC_INSPECTOR_IMAGE=${IRONIC_INSPECTOR_IMAGE:-"quay.io/metal3-io/ironic-inspector:master"} +IPA_DOWNLOADER_IMAGE=${IPA_DOWNLOADER_IMAGE:-"quay.io/metal3-io/ironic-ipa-downloader:master"} +COREOS_DOWNLOADER_IMAGE=${COREOS_DOWNLOADER_IMAGE:-"quay.io/openshift-metal3/rhcos-downloader:master"} + +# This image is templated in via the installer pkg/asset/ignition/bootstrap/bootstrap.go +RHCOS_BOOT_IMAGE_URL="{{.BootImage}}" + +# First we stop any previously started containers, because ExecStop only runs when the ExecStart process +# e.g this script is still running, but we exit if *any* of the containers exits unexpectedly +for name in ironic-api ironic-conductor ironic-inspector dnsmasq httpd mariadb ipa-downloader coreos-downloader; do + podman ps | grep -w "$name$" && podman kill $name + podman ps --all | grep -w "$name$" && podman rm $name -f +done + +# Start the provisioning nic if not already started +# Note removal of the hard-coded subnet tracked via https://github.com/openshift/installer/issues/2091 +PROVISIONING_NIC=ens4 +if ! nmcli -t device | grep "$PROVISIONING_NIC:ethernet:connected:provisioning"; then + nmcli c add type ethernet ifname $PROVISIONING_NIC con-name provisioning ip4 172.22.0.2/24 gw4 172.22.0.1 + nmcli c up provisioning +fi + +# Wait for the interface to come up +# This is how the ironic container currently detects IRONIC_IP, this could probably be improved by using +# nmcli show provisioning there instead, but we need to confirm that works with the static-ip-manager +while [ -z "$(ip -4 address show dev "$PROVISIONING_NIC" | grep -oP '(?<=inet\s)\d+(\.\d+){3}' | head -n 1)" ]; do + sleep 1 +done + +# set password for mariadb +mariadb_password=$(uuidgen -r | sed "s/-//g") + +IRONIC_SHARED_VOLUME="ironic" +# Ignore errors here so we reuse any existing volume on pod restart +# this is helpful if an API service causes restart after the images +# have been downloaded +podman volume create $IRONIC_SHARED_VOLUME || true + +# Apparently network-online doesn't necessarily mean iptables is ready, so wait until it is.. +while ! iptables -L; do + sleep 1 +done + +# Add firewall rules to ensure the IPA ramdisk can reach httpd, Ironic and the Inspector API on the host +for port in 80 5050 6385 ; do + if ! sudo iptables -C INPUT -i $PROVISIONING_NIC -p tcp -m tcp --dport $port -j ACCEPT > /dev/null 2>&1; then + sudo iptables -I INPUT -i $PROVISIONING_NIC -p tcp -m tcp --dport $port -j ACCEPT + fi +done + +# Start dnsmasq, http, mariadb, and ironic containers using same image +# Currently we do this outside of a pod because we need to ensure the images +# are downloaded before starting the API pods +podman run -d --net host --privileged --name mariadb \ + -v $IRONIC_SHARED_VOLUME:/shared:z --entrypoint /bin/runmariadb \ + --env MARIADB_PASSWORD=$mariadb_password ${IRONIC_IMAGE} + +podman run -d --net host --privileged --name dnsmasq \ + --env PROVISIONING_INTERFACE=$PROVISIONING_NIC \ + -v $IRONIC_SHARED_VOLUME:/shared:z --entrypoint /bin/rundnsmasq ${IRONIC_IMAGE} + +podman run -d --net host --privileged --name httpd \ + --env PROVISIONING_INTERFACE=$PROVISIONING_NIC \ + -v $IRONIC_SHARED_VOLUME:/shared:z --entrypoint /bin/runhttpd ${IRONIC_IMAGE} + +# Set CACHEURL to the default route, so we try to consume any images cached on the host +# running the VM (dev-scripts configures a cache here), if none is found then the +# downloader containers just skip and download from the internet location +CACHEURL="http://$(ip r | grep default | head -n1 | awk '{print $3}')/images" +podman run -d --net host --name ipa-downloader \ + --env CACHEURL=${CACHEURL} \ + -v $IRONIC_SHARED_VOLUME:/shared:z ${IPA_DOWNLOADER_IMAGE} /usr/local/bin/get-resource.sh + +podman run -d --net host --name coreos-downloader \ + --env CACHEURL=${CACHEURL} \ + -v $IRONIC_SHARED_VOLUME:/shared:z ${COREOS_DOWNLOADER_IMAGE} /usr/local/bin/get-resource.sh $RHCOS_BOOT_IMAGE_URL + +# Wait for images to be downloaded/ready +podman wait -i 1000 ipa-downloader +podman wait -i 1000 coreos-downloader +while ! curl --fail http://localhost/images/rhcos-ootpa-latest.qcow2.md5sum ; do sleep 1; done +while ! curl --fail --head http://localhost/images/ironic-python-agent.initramfs ; do sleep 1; done +while ! curl --fail --head http://localhost/images/ironic-python-agent.tar.headers ; do sleep 1; done +while ! curl --fail --head http://localhost/images/ironic-python-agent.kernel ; do sleep 1; done + +sudo podman run -d --net host --privileged --name ironic-conductor \ + --env MARIADB_PASSWORD=$mariadb_password \ + --env PROVISIONING_INTERFACE=$PROVISIONING_NIC \ + --env OS_CONDUCTOR__HEARTBEAT_TIMEOUT=120 \ + --entrypoint /bin/runironic-conductor \ + -v $IRONIC_SHARED_VOLUME:/shared:z ${IRONIC_IMAGE} + +# We need a better way to wait for the DB sync to happen.. +sleep 10 + +podman run -d --net host --privileged --name ironic-inspector \ + --env PROVISIONING_INTERFACE=$PROVISIONING_NIC \ + -v $IRONIC_SHARED_VOLUME:/shared:z "${IRONIC_INSPECTOR_IMAGE}" + +sudo podman run -d --net host --privileged --name ironic-api \ + --env MARIADB_PASSWORD=$mariadb_password \ + --env PROVISIONING_INTERFACE=$PROVISIONING_NIC \ + --entrypoint /bin/runironic-api \ + -v $IRONIC_SHARED_VOLUME:/shared:z ${IRONIC_IMAGE} + +# Now loop so the service remains active and restart everything should one of the containers exit unexpectedly. +# The alternative would be RemainAfterExit=yes but then we lose the ability to restart if something crashes. +while true; do + for name in ironic-api ironic-conductor ironic-inspector dnsmasq httpd mariadb; do + podman ps | grep -w "$name$" || exit 1 + done + sleep 10 +done diff --git a/data/data/bootstrap/baremetal/files/usr/local/bin/stopironic.sh b/data/data/bootstrap/baremetal/files/usr/local/bin/stopironic.sh new file mode 100755 index 00000000000..5a986b439f6 --- /dev/null +++ b/data/data/bootstrap/baremetal/files/usr/local/bin/stopironic.sh @@ -0,0 +1,8 @@ +#!/bin/bash + +set -x + +for name in ironic-api ironic-conductor ironic-inspector dnsmasq httpd mariadb ipa-downloader coreos-downloader; do + podman ps | grep -w "$name$" && podman kill $name + podman ps --all | grep -w "$name$" && podman rm $name -f +done diff --git a/data/data/bootstrap/baremetal/systemd/units/ironic.service b/data/data/bootstrap/baremetal/systemd/units/ironic.service new file mode 100644 index 00000000000..839bacf8f96 --- /dev/null +++ b/data/data/bootstrap/baremetal/systemd/units/ironic.service @@ -0,0 +1,16 @@ +[Unit] +Description=Baremetal Deployment Ironic Services +Wants=network-online.target crio.service +After=network-online.target crio.service + +[Service] +Type=exec +ExecStart=/usr/local/bin/startironic.sh +ExecStop=/usr/local/bin/stopironic.sh + +Restart=on-failure +RestartSec=10 +TimeoutStartSec=600 + +[Install] +WantedBy=multi-user.target diff --git a/docs/user/metal/install_ipi.md b/docs/user/metal/install_ipi.md index 07836c0e682..875b9ebd34e 100644 --- a/docs/user/metal/install_ipi.md +++ b/docs/user/metal/install_ipi.md @@ -15,18 +15,6 @@ deployments, see [install_upi.md](install_upi.md). ## Prerequisites -### Ironic - -Currently, the `baremetal` platform requires an existing Ironic environment. -This will eventually be handled by `openshift-install`, with Ironic being -deployed onto the bootstrap node. Until then, users of the `baremetal` platform -should use the -[openshift-metal3/dev-scripts](https://github.com/openshift-metal3/dev-scripts) -repository to handle configuration of Ironic. - -The following PR contains the WIP changes for automating Ironic from -`openshift-install`: https://github.com/openshift-metal3/kni-installer/pull/100 - ### Network Requirements It is assumed that all hosts have at least 2 NICs, used for the following @@ -111,8 +99,6 @@ platform should be considered experimental and still subject to change without backwards compatibility. In particular, some items likely to change soon include: -* The `image` section will get completely removed. - * The `hardwareProfile` is currently exposed as a way to allow specifying different hardware parameters for deployment. By default, we will deploy RHCOS to the first disk, but that may not be appropriate for all hardware. @@ -174,11 +160,6 @@ platform: password: password bootMACAddress: 00:11:07:4e:f6:71 hardwareProfile: default - image: - source: "http://172.22.0.1/images/rhcos-ootpa-latest.qcow2" - checksum: 2b3b1e19e18627d89da400b63430d5bb - deployKernel: http://172.22.0.1/images/ironic-python-agent.kernel - deployRamdisk: http://172.22.0.1/images/ironic-python-agent.initramfs pullSecret: ... sshKey: ... ``` @@ -227,3 +208,18 @@ When an installation fails, `openshift-install` will attempt to gather debug information from hosts. This is not yet supported by the `baremetal` platform. https://github.com/openshift-metal3/kni-installer/issues/79 + +### Provisioning subnet not fully configurable + +There are some install-config parameters to control templating of the provisioning +network configuration, but fully supporting alternative subnets for the +provisioning network is incomplete. + +https://github.com/openshift/installer/issues/2091 + +### Ironic services are using upstream images + +We need to move to downstream openshift images for the Ironic containers that are +started on the boostrap VM + +https://github.com/openshift/installer/issues/2090 diff --git a/pkg/asset/cluster/baremetal/baremetal.go b/pkg/asset/cluster/baremetal/baremetal.go index 54c42accf8b..4e631c2c850 100644 --- a/pkg/asset/cluster/baremetal/baremetal.go +++ b/pkg/asset/cluster/baremetal/baremetal.go @@ -11,6 +11,5 @@ import ( func Metadata(config *types.InstallConfig) *baremetal.Metadata { return &baremetal.Metadata{ LibvirtURI: config.Platform.BareMetal.LibvirtURI, - IronicURI: config.Platform.BareMetal.IronicURI, } } diff --git a/pkg/asset/cluster/tfvars.go b/pkg/asset/cluster/tfvars.go index 0da5ccc5d2c..239bc49a99d 100644 --- a/pkg/asset/cluster/tfvars.go +++ b/pkg/asset/cluster/tfvars.go @@ -280,12 +280,12 @@ func (t *TerraformVariables) Generate(parents asset.Parents) error { case baremetal.Name: data, err = baremetaltfvars.TFVars( installConfig.Config.Platform.BareMetal.LibvirtURI, - installConfig.Config.Platform.BareMetal.IronicURI, + installConfig.Config.Platform.BareMetal.BootstrapProvisioningIP, string(*rhcosBootstrapImage), "baremetal", "provisioning", installConfig.Config.Platform.BareMetal.Hosts, - installConfig.Config.Platform.BareMetal.Image, + string(*rhcosImage), ) if err != nil { return errors.Wrapf(err, "failed to get %s Terraform variables", platform) diff --git a/pkg/asset/ignition/bootstrap/bootstrap.go b/pkg/asset/ignition/bootstrap/bootstrap.go index bbb47891c0b..80f44090220 100644 --- a/pkg/asset/ignition/bootstrap/bootstrap.go +++ b/pkg/asset/ignition/bootstrap/bootstrap.go @@ -27,6 +27,7 @@ import ( "github.com/openshift/installer/pkg/asset/machines" "github.com/openshift/installer/pkg/asset/manifests" "github.com/openshift/installer/pkg/asset/releaseimage" + "github.com/openshift/installer/pkg/asset/rhcos" "github.com/openshift/installer/pkg/asset/tls" "github.com/openshift/installer/pkg/types" ) @@ -46,6 +47,7 @@ type bootstrapTemplateData struct { ReleaseImage string Proxy *configv1.ProxyStatus Registries []sysregistriesv2.Registry + BootImage string } // Bootstrap is an asset that generates the ignition config for bootstrap nodes. @@ -109,6 +111,7 @@ func (a *Bootstrap) Dependencies() []asset.Asset { &tls.RootCA{}, &tls.ServiceAccountKeyPair{}, &releaseimage.Image{}, + new(rhcos.Image), } } @@ -117,9 +120,10 @@ func (a *Bootstrap) Generate(dependencies asset.Parents) error { installConfig := &installconfig.InstallConfig{} proxy := &manifests.Proxy{} releaseImage := &releaseimage.Image{} - dependencies.Get(installConfig, proxy, releaseImage) + rhcosImage := new(rhcos.Image) + dependencies.Get(installConfig, proxy, releaseImage, rhcosImage) - templateData, err := a.getTemplateData(installConfig.Config, releaseImage.PullSpec, installConfig.Config.ImageContentSources, proxy.Config) + templateData, err := a.getTemplateData(installConfig.Config, releaseImage.PullSpec, installConfig.Config.ImageContentSources, proxy.Config, rhcosImage) if err != nil { return errors.Wrap(err, "failed to get bootstrap templates") @@ -195,7 +199,7 @@ func (a *Bootstrap) Files() []*asset.File { } // getTemplateData returns the data to use to execute bootstrap templates. -func (a *Bootstrap) getTemplateData(installConfig *types.InstallConfig, releaseImage string, imageSources []types.ImageContentSource, proxy *configv1.Proxy) (*bootstrapTemplateData, error) { +func (a *Bootstrap) getTemplateData(installConfig *types.InstallConfig, releaseImage string, imageSources []types.ImageContentSource, proxy *configv1.Proxy, rhcosImage *rhcos.Image) (*bootstrapTemplateData, error) { etcdEndpoints := make([]string, *installConfig.ControlPlane.Replicas) for i := range etcdEndpoints { @@ -224,6 +228,7 @@ func (a *Bootstrap) getTemplateData(installConfig *types.InstallConfig, releaseI EtcdCluster: strings.Join(etcdEndpoints, ","), Proxy: &proxy.Status, Registries: registries, + BootImage: string(*rhcosImage), }, nil } @@ -293,6 +298,7 @@ func (a *Bootstrap) addSystemdUnits(uri string, templateData *bootstrapTemplateD // baremetal & openstack platform services "keepalived.service": {}, "coredns.service": {}, + "ironic.service": {}, } directory, err := data.Assets.Open(uri) diff --git a/pkg/asset/machines/baremetal/machines.go b/pkg/asset/machines/baremetal/machines.go index e6ad5808428..b19beb37bd4 100644 --- a/pkg/asset/machines/baremetal/machines.go +++ b/pkg/asset/machines/baremetal/machines.go @@ -3,6 +3,8 @@ package baremetal import ( "fmt" + "path" + "strings" baremetalprovider "github.com/metal3-io/cluster-api-provider-baremetal/pkg/apis/baremetal/v1alpha1" @@ -16,7 +18,7 @@ import ( ) // Machines returns a list of machines for a machinepool. -func Machines(clusterID string, config *types.InstallConfig, pool *types.MachinePool, role, userDataSecret string) ([]machineapi.Machine, error) { +func Machines(clusterID string, config *types.InstallConfig, pool *types.MachinePool, osImage, role, userDataSecret string) ([]machineapi.Machine, error) { if configPlatform := config.Platform.Name(); configPlatform != baremetal.Name { return nil, fmt.Errorf("non bare metal configuration: %q", configPlatform) } @@ -30,7 +32,7 @@ func Machines(clusterID string, config *types.InstallConfig, pool *types.Machine if pool.Replicas != nil { total = *pool.Replicas } - provider := provider(clustername, config.Networking.MachineCIDR.String(), platform, userDataSecret) + provider := provider(clustername, config.Networking.MachineCIDR.String(), platform, osImage, userDataSecret) var machines []machineapi.Machine for idx := int64(0); idx < total; idx++ { machine := machineapi.Machine{ @@ -60,11 +62,22 @@ func Machines(clusterID string, config *types.InstallConfig, pool *types.Machine return machines, nil } -func provider(clusterName string, networkInterfaceAddress string, platform *baremetal.Platform, userDataSecret string) *baremetalprovider.BareMetalMachineProviderSpec { +func provider(clusterName string, networkInterfaceAddress string, platform *baremetal.Platform, osImage string, userDataSecret string) *baremetalprovider.BareMetalMachineProviderSpec { + // The rhcos-downloader container launched by the baremetal-operator downloads the image, + // compresses it to speed up deployments and makes it available on platform.ClusterProvisioningIP, via http + // osImage looks like: + // https://releases-art-rhcos.svc.ci.openshift.org/art/storage/releases/rhcos-4.2/42.80.20190725.1/rhcos-42.80.20190725.1-openstack.qcow2 + // But the cached URL looks like: + // http://172.22.0.3:6180/images/rhcos-42.80.20190725.1-openstack.qcow2/rhcos-42.80.20190725.1-compressed.qcow2 + // See https://github.com/openshift/ironic-rhcos-downloader for more details + imageFilename := path.Base(osImage) + compressedImageFilename := strings.Replace(imageFilename, "openstack", "compressed", 1) + cacheImageURL := fmt.Sprintf("http://%s:6180/images/%s/%s", platform.ClusterProvisioningIP, imageFilename, compressedImageFilename) + cacheChecksumURL := fmt.Sprintf("%s.md5sum", cacheImageURL) return &baremetalprovider.BareMetalMachineProviderSpec{ Image: baremetalprovider.Image{ - URL: platform.Image.Source, - Checksum: platform.Image.Checksum, + URL: cacheImageURL, + Checksum: cacheChecksumURL, }, UserData: &corev1.SecretReference{Name: userDataSecret}, } diff --git a/pkg/asset/machines/baremetal/machinesets.go b/pkg/asset/machines/baremetal/machinesets.go index aa226fa61e8..8efd6fc3cfb 100644 --- a/pkg/asset/machines/baremetal/machinesets.go +++ b/pkg/asset/machines/baremetal/machinesets.go @@ -14,7 +14,7 @@ import ( ) // MachineSets returns a list of machinesets for a machinepool. -func MachineSets(clusterID string, config *types.InstallConfig, pool *types.MachinePool, role, userDataSecret string) ([]*machineapi.MachineSet, error) { +func MachineSets(clusterID string, config *types.InstallConfig, pool *types.MachinePool, osImage, role, userDataSecret string) ([]*machineapi.MachineSet, error) { if configPlatform := config.Platform.Name(); configPlatform != baremetal.Name { return nil, fmt.Errorf("non bare metal configuration: %q", configPlatform) } @@ -32,7 +32,7 @@ func MachineSets(clusterID string, config *types.InstallConfig, pool *types.Mach total = *pool.Replicas } - provider := provider(clustername, config.Networking.MachineCIDR.String(), platform, userDataSecret) + provider := provider(clustername, config.Networking.MachineCIDR.String(), platform, osImage, userDataSecret) name := fmt.Sprintf("%s-%s-%d", clustername, pool.Name, 0) mset := &machineapi.MachineSet{ TypeMeta: metav1.TypeMeta{ diff --git a/pkg/asset/machines/master.go b/pkg/asset/machines/master.go index 720ff99d4a6..b396959e51a 100644 --- a/pkg/asset/machines/master.go +++ b/pkg/asset/machines/master.go @@ -217,7 +217,7 @@ func (m *Master) Generate(dependencies asset.Parents) error { mpool.Set(pool.Platform.BareMetal) pool.Platform.BareMetal = &mpool - machines, err = baremetal.Machines(clusterID.InfraID, ic, pool, "master", "master-user-data") + machines, err = baremetal.Machines(clusterID.InfraID, ic, pool, string(*rhcosImage), "master", "master-user-data") if err != nil { return errors.Wrap(err, "failed to create master machine objects") } diff --git a/pkg/asset/machines/worker.go b/pkg/asset/machines/worker.go index 7fb6ee9e799..39eccdffec0 100644 --- a/pkg/asset/machines/worker.go +++ b/pkg/asset/machines/worker.go @@ -203,7 +203,7 @@ func (w *Worker) Generate(dependencies asset.Parents) error { mpool.Set(ic.Platform.BareMetal.DefaultMachinePlatform) mpool.Set(pool.Platform.BareMetal) pool.Platform.BareMetal = &mpool - sets, err := baremetal.MachineSets(clusterID.InfraID, ic, &pool, "worker", "worker-user-data") + sets, err := baremetal.MachineSets(clusterID.InfraID, ic, &pool, string(*rhcosImage), "worker", "worker-user-data") if err != nil { return errors.Wrap(err, "failed to create worker machine objects") } diff --git a/pkg/destroy/baremetal/baremetal.go b/pkg/destroy/baremetal/baremetal.go index cf00d3ac00d..58225dc814f 100644 --- a/pkg/destroy/baremetal/baremetal.go +++ b/pkg/destroy/baremetal/baremetal.go @@ -13,9 +13,9 @@ import ( // ClusterUninstaller holds the various options for the cluster we want to delete. type ClusterUninstaller struct { - LibvirtURI string - IronicURI string - Logger logrus.FieldLogger + LibvirtURI string + BootstrapProvisioningIP string + Logger logrus.FieldLogger } // Run is the entrypoint to start the uninstall process. @@ -36,8 +36,8 @@ func (o *ClusterUninstaller) Run() error { // New returns bare metal Uninstaller from ClusterMetadata. func New(logger logrus.FieldLogger, metadata *types.ClusterMetadata) (providers.Destroyer, error) { return &ClusterUninstaller{ - LibvirtURI: metadata.ClusterPlatformMetadata.BareMetal.LibvirtURI, - IronicURI: metadata.ClusterPlatformMetadata.BareMetal.IronicURI, - Logger: logger, + LibvirtURI: metadata.ClusterPlatformMetadata.BareMetal.LibvirtURI, + BootstrapProvisioningIP: metadata.ClusterPlatformMetadata.BareMetal.BootstrapProvisioningIP, + Logger: logger, }, nil } diff --git a/pkg/terraform/exec/plugins/Gopkg.lock b/pkg/terraform/exec/plugins/Gopkg.lock index 0f30a142088..ead5a27b319 100644 --- a/pkg/terraform/exec/plugins/Gopkg.lock +++ b/pkg/terraform/exec/plugins/Gopkg.lock @@ -481,7 +481,7 @@ version = "v2.0.5" [[projects]] - digest = "1:c1024fa089f6cf75ea25d2a6d10bb001643e8464d710fa4d8205f8edfa8454bb" + digest = "1:ce9cf77f57551c62d4af395cc26c4aaac7a4b901cd8ccff5981b4867ae7c68b8" name = "github.com/gophercloud/gophercloud" packages = [ ".", @@ -489,6 +489,7 @@ "openstack", "openstack/baremetal/noauth", "openstack/baremetal/v1/allocations", + "openstack/baremetal/v1/drivers", "openstack/baremetal/v1/nodes", "openstack/baremetal/v1/ports", "openstack/baremetalintrospection/noauth", @@ -788,15 +789,12 @@ version = "v1.0.0" [[projects]] - digest = "1:25ec929333575de2487c7107a4452f41d2a06ad165014d0b610de92541cfcf98" + digest = "1:80b145e3cfe196d8f4de68afd2632aab3cc1feb93571c0998d01e5e1ab244c52" name = "github.com/openshift-metal3/terraform-provider-ironic" - packages = [ - ".", - "ironic", - ] + packages = ["ironic"] pruneopts = "NUT" - revision = "392753730a1dbbcc1ae580905e40590c196a13f9" - version = "v0.1.5" + revision = "c8fa7040d10d6cd0abdf6084687723517712abb1" + version = "v0.1.6" [[projects]] branch = "master" @@ -1187,7 +1185,6 @@ analyzer-version = 1 input-imports = [ "github.com/dmacvicar/terraform-provider-libvirt/libvirt", - "github.com/openshift-metal3/terraform-provider-ironic", "github.com/openshift-metal3/terraform-provider-ironic/ironic", "github.com/terraform-providers/terraform-provider-aws/aws", "github.com/terraform-providers/terraform-provider-azurerm/azurerm", diff --git a/pkg/terraform/exec/plugins/Gopkg.toml b/pkg/terraform/exec/plugins/Gopkg.toml index 076f8ff581f..7f6e3b4cb36 100644 --- a/pkg/terraform/exec/plugins/Gopkg.toml +++ b/pkg/terraform/exec/plugins/Gopkg.toml @@ -70,4 +70,4 @@ ignored = [ [[constraint]] name = "github.com/openshift-metal3/terraform-provider-ironic" - version = "v0.1.5" + version = "v0.1.6" diff --git a/pkg/terraform/exec/plugins/vendor/github.com/gophercloud/gophercloud/openstack/baremetal/v1/drivers/doc.go b/pkg/terraform/exec/plugins/vendor/github.com/gophercloud/gophercloud/openstack/baremetal/v1/drivers/doc.go new file mode 100644 index 00000000000..252c01b76ad --- /dev/null +++ b/pkg/terraform/exec/plugins/vendor/github.com/gophercloud/gophercloud/openstack/baremetal/v1/drivers/doc.go @@ -0,0 +1,43 @@ +/* +Package drivers contains the functionality for Listing drivers, driver details, +driver properties and driver logical disk properties + +API reference: https://developer.openstack.org/api-ref/baremetal/#drivers-drivers + +Example to List Drivers + + drivers.ListDrivers(client.ServiceClient(), drivers.ListDriversOpts{}).EachPage(func(page pagination.Page) (bool, error) { + driversList, err := drivers.ExtractDrivers(page) + if err != nil { + return false, err + } + + for _, n := range driversList { + // Do something + } + + return true, nil + }) + +Example to Get single Driver Details + + showDriverDetails, err := drivers.GetDriverDetails(client, "ipmi").Extract() + if err != nil { + panic(err) + } + +Example to Get single Driver Properties + + showDriverProperties, err := drivers.GetDriverProperties(client, "ipmi").Extract() + if err != nil { + panic(err) + } + +Example to Get single Driver Logical Disk Properties + + showDriverDiskProperties, err := drivers.GetDriverDiskProperties(client, "ipmi").Extract() + if err != nil { + panic(err) + } +*/ +package drivers diff --git a/pkg/terraform/exec/plugins/vendor/github.com/gophercloud/gophercloud/openstack/baremetal/v1/drivers/requests.go b/pkg/terraform/exec/plugins/vendor/github.com/gophercloud/gophercloud/openstack/baremetal/v1/drivers/requests.go new file mode 100644 index 00000000000..ab962c8ef7e --- /dev/null +++ b/pkg/terraform/exec/plugins/vendor/github.com/gophercloud/gophercloud/openstack/baremetal/v1/drivers/requests.go @@ -0,0 +1,70 @@ +package drivers + +import ( + "github.com/gophercloud/gophercloud" + "github.com/gophercloud/gophercloud/pagination" +) + +// ListDriversOptsBuilder allows extensions to add additional parameters to the +// ListDrivers request. +type ListDriversOptsBuilder interface { + ToListDriversOptsQuery() (string, error) +} + +// ListDriversOpts defines query options that can be passed to ListDrivers +type ListDriversOpts struct { + // Provide detailed information about the drivers + Detail bool `q:"detail"` + + // Filter the list by the type of the driver + Type string `q:"type"` +} + +// ToListDriversOptsQuery formats a ListOpts into a query string +func (opts ListDriversOpts) ToListDriversOptsQuery() (string, error) { + q, err := gophercloud.BuildQueryString(opts) + return q.String(), err +} + +// ListDrivers makes a request against the API to list all drivers +func ListDrivers(client *gophercloud.ServiceClient, opts ListDriversOptsBuilder) pagination.Pager { + url := driversURL(client) + if opts != nil { + query, err := opts.ToListDriversOptsQuery() + if err != nil { + return pagination.Pager{Err: err} + } + url += query + } + return pagination.NewPager(client, url, func(r pagination.PageResult) pagination.Page { + return DriverPage{pagination.LinkedPageBase{PageResult: r}} + }) +} + +// GetDriverDetails Shows details for a driver +func GetDriverDetails(client *gophercloud.ServiceClient, driverName string) (r GetDriverResult) { + _, r.Err = client.Get(driverDetailsURL(client, driverName), &r.Body, &gophercloud.RequestOpts{ + OkCodes: []int{200}, + }) + return +} + +// GetDriverProperties Shows the required and optional parameters that +// driverName expects to be supplied in the driver_info field for every +// Node it manages +func GetDriverProperties(client *gophercloud.ServiceClient, driverName string) (r GetPropertiesResult) { + _, r.Err = client.Get(driverPropertiesURL(client, driverName), &r.Body, &gophercloud.RequestOpts{ + OkCodes: []int{200}, + }) + return +} + +// GetDriverDiskProperties Show the required and optional parameters that +// driverName expects to be supplied in the node’s raid_config field, if a +// RAID configuration change is requested. +func GetDriverDiskProperties(client *gophercloud.ServiceClient, driverName string) (r GetDiskPropertiesResult) { + _, r.Err = client.Get(driverDiskPropertiesURL(client, driverName), &r.Body, &gophercloud.RequestOpts{ + OkCodes: []int{200}, + }) + return +} diff --git a/pkg/terraform/exec/plugins/vendor/github.com/gophercloud/gophercloud/openstack/baremetal/v1/drivers/results.go b/pkg/terraform/exec/plugins/vendor/github.com/gophercloud/gophercloud/openstack/baremetal/v1/drivers/results.go new file mode 100644 index 00000000000..424079c8eaf --- /dev/null +++ b/pkg/terraform/exec/plugins/vendor/github.com/gophercloud/gophercloud/openstack/baremetal/v1/drivers/results.go @@ -0,0 +1,198 @@ +package drivers + +import ( + "github.com/gophercloud/gophercloud" + "github.com/gophercloud/gophercloud/pagination" +) + +type driverResult struct { + gophercloud.Result +} + +// Extract interprets any driverResult as a Driver, if possible. +func (r driverResult) Extract() (*Driver, error) { + var s Driver + err := r.ExtractInto(&s) + return &s, err +} + +func (r driverResult) ExtractInto(v interface{}) error { + return r.Result.ExtractIntoStructPtr(v, "") +} + +func ExtractDriversInto(r pagination.Page, v interface{}) error { + return r.(DriverPage).Result.ExtractIntoSlicePtr(v, "drivers") +} + +// Driver represents a driver in the OpenStack Bare Metal API. +type Driver struct { + // Name and Identifier of the driver + Name string `json:"name"` + + // A list of active hosts that support this driver + Hosts []string `json:"hosts"` + + // Type of this driver (“classic” or “dynamic”) + Type string `json:"type"` + + // The default bios interface used for a node with a dynamic driver, + // if no bios interface is specified for the node. + DefaultBiosInterface string `json:"default_bios_interface"` + + // The default boot interface used for a node with a dynamic driver, + // if no boot interface is specified for the node. + DefaultBootInterface string `json:"default_boot_interface"` + + // The default console interface used for a node with a dynamic driver, + // if no console interface is specified for the node. + DefaultConsoleInterface string `json:"default_console_interface"` + + // The default deploy interface used for a node with a dynamic driver, + // if no deploy interface is specified for the node. + DefaultDeployInterface string `json:"default_deploy_interface"` + + // The default inspection interface used for a node with a dynamic driver, + // if no inspection interface is specified for the node. + DefaultInspectInterface string `json:"default_inspect_interface"` + + // The default management interface used for a node with a dynamic driver, + // if no management interface is specified for the node. + DefaultManagementInterface string `json:"default_management_interface"` + + // The default network interface used for a node with a dynamic driver, + // if no network interface is specified for the node. + DefaultNetworkInterface string `json:"default_network_interface"` + + // The default power interface used for a node with a dynamic driver, + // if no power interface is specified for the node. + DefaultPowerInterface string `json:"default_power_interface"` + + // The default RAID interface used for a node with a dynamic driver, + // if no RAID interface is specified for the node. + DefaultRaidInterface string `json:"default_raid_interface"` + + // The default rescue interface used for a node with a dynamic driver, + // if no rescue interface is specified for the node. + DefaultRescueInterface string `json:"default_rescue_interface"` + + // The default storage interface used for a node with a dynamic driver, + // if no storage interface is specified for the node. + DefaultStorageInterface string `json:"default_storage_interface"` + + // The default vendor interface used for a node with a dynamic driver, + // if no vendor interface is specified for the node. + DefaultVendorInterface string `json:"default_vendor_interface"` + + // The enabled bios interfaces for this driver. + EnabledBiosInterfaces []string `json:"enabled_bios_interfaces"` + + // The enabled boot interfaces for this driver. + EnabledBootInterfaces []string `json:"enabled_boot_interfaces"` + + // The enabled console interfaces for this driver. + EnabledConsoleInterface []string `json:"enabled_console_interfaces"` + + // The enabled deploy interfaces for this driver. + EnabledDeployInterfaces []string `json:"enabled_deploy_interfaces"` + + // The enabled inspection interfaces for this driver. + EnabledInspectInterfaces []string `json:"enabled_inspect_interfaces"` + + // The enabled management interfaces for this driver. + EnabledManagementInterfaces []string `json:"enabled_management_interfaces"` + + // The enabled network interfaces for this driver. + EnabledNetworkInterfaces []string `json:"enabled_network_interfaces"` + + // The enabled power interfaces for this driver. + EnabledPowerInterfaces []string `json:"enabled_power_interfaces"` + + // The enabled rescue interfaces for this driver. + EnabledRescueInterfaces []string `json:"enabled_rescue_interfaces"` + + // The enabled RAID interfaces for this driver. + EnabledRaidInterfaces []string `json:"enabled_raid_interfaces"` + + // The enabled storage interfaces for this driver. + EnabledStorageInterfaces []string `json:"enabled_storage_interfaces"` + + // The enabled vendor interfaces for this driver. + EnabledVendorInterfaces []string `json:"enabled_vendor_interfaces"` + + //A list of relative links. Includes the self and bookmark links. + Links []interface{} `json:"links"` + + // A list of links to driver properties. + Properties []interface{} `json:"properties"` +} + +// DriverPage abstracts the raw results of making a ListDrivers() request +// against the API. +type DriverPage struct { + pagination.LinkedPageBase +} + +// IsEmpty returns true if a page contains no Driver results. +func (r DriverPage) IsEmpty() (bool, error) { + s, err := ExtractDrivers(r) + return len(s) == 0, err +} + +// NextPageURL uses the response's embedded link reference to navigate to the +// next page of results. +func (r DriverPage) NextPageURL() (string, error) { + var s struct { + Links []gophercloud.Link `json:"drivers_links"` + } + err := r.ExtractInto(&s) + if err != nil { + return "", err + } + return gophercloud.ExtractNextURL(s.Links) +} + +// ExtractDrivers interprets the results of a single page from ListDrivers() +// call, producing a slice of Driver entities. +func ExtractDrivers(r pagination.Page) ([]Driver, error) { + var s []Driver + err := ExtractDriversInto(r, &s) + return s, err +} + +// GetDriverResult is the response from a Get operation. +// Call its Extract method to interpret it as a Driver. +type GetDriverResult struct { + driverResult +} + +// DriverProperties represents driver properties in the OpenStack Bare Metal API. +type DriverProperties map[string]interface{} + +// Extract interprets any GetPropertiesResult as DriverProperties, if possible. +func (r GetPropertiesResult) Extract() (*DriverProperties, error) { + var s DriverProperties + err := r.ExtractInto(&s) + return &s, err +} + +// GetPropertiesResult is the response from a GetDriverProperties operation. +// Call its Extract method to interpret it as DriverProperties. +type GetPropertiesResult struct { + gophercloud.Result +} + +// DiskProperties represents driver disk properties in the OpenStack Bare Metal API. +type DiskProperties map[string]interface{} + +// Extract interprets any GetDiskPropertiesResult as DiskProperties, if possible. +func (r GetDiskPropertiesResult) Extract() (*DiskProperties, error) { + var s DiskProperties + err := r.ExtractInto(&s) + return &s, err +} + +// GetDiskPropertiesResult is the response from a GetDriverDiskProperties operation. +// Call its Extract method to interpret it as DiskProperties. +type GetDiskPropertiesResult struct { + gophercloud.Result +} diff --git a/pkg/terraform/exec/plugins/vendor/github.com/gophercloud/gophercloud/openstack/baremetal/v1/drivers/urls.go b/pkg/terraform/exec/plugins/vendor/github.com/gophercloud/gophercloud/openstack/baremetal/v1/drivers/urls.go new file mode 100644 index 00000000000..d5ddba7d89e --- /dev/null +++ b/pkg/terraform/exec/plugins/vendor/github.com/gophercloud/gophercloud/openstack/baremetal/v1/drivers/urls.go @@ -0,0 +1,19 @@ +package drivers + +import "github.com/gophercloud/gophercloud" + +func driversURL(client *gophercloud.ServiceClient) string { + return client.ServiceURL("drivers") +} + +func driverDetailsURL(client *gophercloud.ServiceClient, driverName string) string { + return client.ServiceURL("drivers", driverName) +} + +func driverPropertiesURL(client *gophercloud.ServiceClient, driverName string) string { + return client.ServiceURL("drivers", driverName, "properties") +} + +func driverDiskPropertiesURL(client *gophercloud.ServiceClient, driverName string) string { + return client.ServiceURL("drivers", driverName, "raid", "logical_disk_properties") +} diff --git a/pkg/terraform/exec/plugins/vendor/github.com/openshift-metal3/terraform-provider-ironic/ironic/provider.go b/pkg/terraform/exec/plugins/vendor/github.com/openshift-metal3/terraform-provider-ironic/ironic/provider.go index 733377da53a..0f1cd089495 100644 --- a/pkg/terraform/exec/plugins/vendor/github.com/openshift-metal3/terraform-provider-ironic/ironic/provider.go +++ b/pkg/terraform/exec/plugins/vendor/github.com/openshift-metal3/terraform-provider-ironic/ironic/provider.go @@ -4,7 +4,9 @@ import ( "fmt" "github.com/gophercloud/gophercloud" "github.com/gophercloud/gophercloud/openstack/baremetal/noauth" + "github.com/gophercloud/gophercloud/openstack/baremetal/v1/drivers" noauthintrospection "github.com/gophercloud/gophercloud/openstack/baremetalintrospection/noauth" + "github.com/gophercloud/gophercloud/pagination" "github.com/hashicorp/terraform/helper/schema" "github.com/hashicorp/terraform/terraform" "log" @@ -206,8 +208,22 @@ func waitForAPI(timeout int, client *gophercloud.ServiceClient) error { statusCode := r.StatusCode r.Body.Close() if statusCode == http.StatusOK { - log.Printf("[DEBUG] API successfully connected.") - return nil + log.Printf("[DEBUG] API successfully connected, waiting for conductor...") + driverCount := 0 + drivers.ListDrivers(client, drivers.ListDriversOpts{ + Detail: false, + }).EachPage(func(page pagination.Page) (bool, error) { + actual, err := drivers.ExtractDrivers(page) + if err != nil { + return false, err + } + driverCount += len(actual) + return true, nil + }) + // If we have any drivers, conductor is up. + if driverCount > 0 { + return nil + } } } diff --git a/pkg/terraform/exec/plugins/vendor/github.com/openshift-metal3/terraform-provider-ironic/main.go b/pkg/terraform/exec/plugins/vendor/github.com/openshift-metal3/terraform-provider-ironic/main.go deleted file mode 100644 index 439d8c90aab..00000000000 --- a/pkg/terraform/exec/plugins/vendor/github.com/openshift-metal3/terraform-provider-ironic/main.go +++ /dev/null @@ -1,15 +0,0 @@ -package main - -import ( - "github.com/hashicorp/terraform/plugin" - "github.com/hashicorp/terraform/terraform" - "github.com/openshift-metal3/terraform-provider-ironic/ironic" -) - -func main() { - plugin.Serve(&plugin.ServeOpts{ - ProviderFunc: func() terraform.ResourceProvider { - return ironic.Provider() - }, - }) -} diff --git a/pkg/tfvars/baremetal/baremetal.go b/pkg/tfvars/baremetal/baremetal.go index a17c18a4faf..ac6f5617c48 100644 --- a/pkg/tfvars/baremetal/baremetal.go +++ b/pkg/tfvars/baremetal/baremetal.go @@ -3,19 +3,22 @@ package baremetal import ( "encoding/json" + "fmt" "github.com/metal3-io/baremetal-operator/pkg/bmc" "github.com/metal3-io/baremetal-operator/pkg/hardware" libvirttfvars "github.com/openshift/installer/pkg/tfvars/libvirt" "github.com/openshift/installer/pkg/types/baremetal" "github.com/pkg/errors" + "path" + "strings" ) type config struct { - LibvirtURI string `json:"libvirt_uri,omitempty"` - IronicURI string `json:"ironic_uri,omitempty"` - BootstrapOSImage string `json:"bootstrap_os_image,omitempty"` - ExternalBridge string `json:"external_bridge,omitempty"` - ProvisioningBridge string `json:"provisioning_bridge,omitempty"` + LibvirtURI string `json:"libvirt_uri,omitempty"` + BootstrapProvisioningIP string `json:"bootstrap_provisioning_ip,omitempty"` + BootstrapOSImage string `json:"bootstrap_os_image,omitempty"` + ExternalBridge string `json:"external_bridge,omitempty"` + ProvisioningBridge string `json:"provisioning_bridge,omitempty"` // Data required for control plane deployment - several maps per host, because of terraform's limitations Hosts []map[string]interface{} `json:"hosts"` @@ -26,7 +29,7 @@ type config struct { } // TFVars generates bare metal specific Terraform variables. -func TFVars(libvirtURI, ironicURI, bootstrapOSImage, externalBridge, provisioningBridge string, platformHosts []*baremetal.Host, image baremetal.Image) ([]byte, error) { +func TFVars(libvirtURI, bootstrapProvisioningIP, bootstrapOSImage, externalBridge, provisioningBridge string, platformHosts []*baremetal.Host, image string) ([]byte, error) { bootstrapOSImage, err := libvirttfvars.CachedImage(bootstrapOSImage) if err != nil { return nil, errors.Wrap(err, "failed to use cached bootstrap libvirt image") @@ -55,8 +58,8 @@ func TFVars(libvirtURI, ironicURI, bootstrapOSImage, externalBridge, provisionin Password: host.BMC.Password, } driverInfo := accessDetails.DriverInfo(credentials) - driverInfo["deploy_kernel"] = image.DeployKernel - driverInfo["deploy_ramdisk"] = image.DeployRamdisk + driverInfo["deploy_kernel"] = fmt.Sprintf("http://%s/images/ironic-python-agent.kernel", bootstrapProvisioningIP) + driverInfo["deploy_ramdisk"] = fmt.Sprintf("http://%s/images/ironic-python-agent.initramfs", bootstrapProvisioningIP) // Host Details hostMap := map[string]interface{}{ @@ -80,10 +83,16 @@ func TFVars(libvirtURI, ironicURI, bootstrapOSImage, externalBridge, provisionin } // Instance Info + // The rhcos-downloader container downloads the image, compresses it to speed up deployments + // and then makes it available on bootstrapProvisioningIP via http + imageFilename := path.Base(image) + compressedImageFilename := strings.Replace(imageFilename, "openstack", "compressed", 1) + cacheImageURL := fmt.Sprintf("http://%s/images/%s/%s", bootstrapProvisioningIP, imageFilename, compressedImageFilename) + cacheChecksumURL := fmt.Sprintf("%s.md5sum", cacheImageURL) instanceInfo := map[string]interface{}{ "root_gb": 25, // FIXME(stbenjam): Needed until https://storyboard.openstack.org/#!/story/2005165 - "image_source": image.Source, - "image_checksum": image.Checksum, + "image_source": cacheImageURL, + "image_checksum": cacheChecksumURL, } hosts = append(hosts, hostMap) @@ -94,16 +103,16 @@ func TFVars(libvirtURI, ironicURI, bootstrapOSImage, externalBridge, provisionin } cfg := &config{ - LibvirtURI: libvirtURI, - IronicURI: ironicURI, - BootstrapOSImage: bootstrapOSImage, - ExternalBridge: externalBridge, - ProvisioningBridge: provisioningBridge, - Hosts: hosts, - Properties: properties, - DriverInfos: driverInfos, - RootDevices: rootDevices, - InstanceInfos: instanceInfos, + LibvirtURI: libvirtURI, + BootstrapProvisioningIP: bootstrapProvisioningIP, + BootstrapOSImage: bootstrapOSImage, + ExternalBridge: externalBridge, + ProvisioningBridge: provisioningBridge, + Hosts: hosts, + Properties: properties, + DriverInfos: driverInfos, + RootDevices: rootDevices, + InstanceInfos: instanceInfos, } return json.MarshalIndent(cfg, "", " ") diff --git a/pkg/types/baremetal/defaults/platform.go b/pkg/types/baremetal/defaults/platform.go index d51ac98f522..47e03cc3e50 100644 --- a/pkg/types/baremetal/defaults/platform.go +++ b/pkg/types/baremetal/defaults/platform.go @@ -10,13 +10,14 @@ import ( // Defaults for the baremetal platform. const ( - LibvirtURI = "qemu:///system" - IronicURI = "http://localhost:6385/v1" - ExternalBridge = "baremetal" - ProvisioningBridge = "provisioning" - HardwareProfile = "default" - APIVIP = "" - IngressVIP = "" + LibvirtURI = "qemu:///system" + BootstrapProvisioningIP = "172.22.0.2" + ClusterProvisioningIP = "172.22.0.3" + ExternalBridge = "baremetal" + ProvisioningBridge = "provisioning" + HardwareProfile = "default" + APIVIP = "" + IngressVIP = "" ) // SetPlatformDefaults sets the defaults for the platform. @@ -25,8 +26,12 @@ func SetPlatformDefaults(p *baremetal.Platform, c *types.InstallConfig) { p.LibvirtURI = LibvirtURI } - if p.IronicURI == "" { - p.IronicURI = IronicURI + if p.BootstrapProvisioningIP == "" { + p.BootstrapProvisioningIP = BootstrapProvisioningIP + } + + if p.ClusterProvisioningIP == "" { + p.ClusterProvisioningIP = ClusterProvisioningIP } if p.ExternalBridge == "" { diff --git a/pkg/types/baremetal/metadata.go b/pkg/types/baremetal/metadata.go index bfa3b5ebc95..691e3b2237c 100644 --- a/pkg/types/baremetal/metadata.go +++ b/pkg/types/baremetal/metadata.go @@ -2,6 +2,7 @@ package baremetal // Metadata contains baremetal metadata (e.g. for uninstalling the cluster). type Metadata struct { - LibvirtURI string `json:"libvirtURI"` - IronicURI string `json:"ironicURI"` + LibvirtURI string `json:"libvirtURI"` + BootstrapProvisioningIP string `json:"bootstrapProvisioningIP"` + ClusterProvisioningIP string `json:"provisioningHostIP"` } diff --git a/pkg/types/baremetal/platform.go b/pkg/types/baremetal/platform.go index 38dd8fa1fb5..7c28bbe0eed 100644 --- a/pkg/types/baremetal/platform.go +++ b/pkg/types/baremetal/platform.go @@ -16,15 +16,6 @@ type Host struct { HardwareProfile string `json:"hardwareProfile"` } -// Image stores details about the locations of various images needed for deployment. -// FIXME: This should be determined by the installer once Ironic and image downloading occurs in bootstrap VM. -type Image struct { - Source string `json:"source"` - Checksum string `json:"checksum"` - DeployKernel string `json:"deployKernel"` - DeployRamdisk string `json:"deployRamdisk"` -} - // Platform stores all the global configuration that all machinesets use. type Platform struct { // LibvirtURI is the identifier for the libvirtd connection. It must be @@ -33,10 +24,17 @@ type Platform struct { // Default is qemu:///system LibvirtURI string `json:"libvirtURI,omitempty"` - // IronicURI is the identifier for the Ironic connection. It must be - // reachable from the host where the installer is run. + // ClusterProvisioningIP is the IP on the dedicated provisioning network + // where the baremetal-operator pod runs provisioning services, + // and an http server to cache some downloaded content e.g RHCOS/IPA images // +optional - IronicURI string `json:"ironicURI,omitempty"` + ClusterProvisioningIP string `json:"provisioningHostIP,omitempty"` + + // BootstrapProvisioningIP is the IP used on the bootstrap VM to + // bring up provisioning services that are used to create the + // control-plane machines + // +optional + BootstrapProvisioningIP string `json:"bootstrapProvisioningIP,omitempty"` // External bridge is used for external communication. // +optional @@ -49,9 +47,6 @@ type Platform struct { // Hosts is the information needed to create the objects in Ironic. Hosts []*Host `json:"hosts"` - // Images contains the information needed to provision a host - Image Image `json:"image"` - // DefaultMachinePlatform is the default configuration used when // installing on bare metal for machine pools which do not define their own // platform configuration. diff --git a/pkg/types/baremetal/validation/platform.go b/pkg/types/baremetal/validation/platform.go index 1a48f9dda8b..3547951075b 100644 --- a/pkg/types/baremetal/validation/platform.go +++ b/pkg/types/baremetal/validation/platform.go @@ -24,8 +24,12 @@ func ValidatePlatform(p *baremetal.Platform, n *types.Networking, fldPath *field allErrs = append(allErrs, field.Invalid(fldPath.Child("libvirtURI"), p.LibvirtURI, err.Error())) } - if err := validate.URI(p.IronicURI); err != nil { - allErrs = append(allErrs, field.Invalid(fldPath.Child("ironicURI"), p.LibvirtURI, err.Error())) + if err := validate.IP(p.ClusterProvisioningIP); err != nil { + allErrs = append(allErrs, field.Invalid(fldPath.Child("provisioningHostIP"), p.ClusterProvisioningIP, err.Error())) + } + + if err := validate.IP(p.BootstrapProvisioningIP); err != nil { + allErrs = append(allErrs, field.Invalid(fldPath.Child("bootstrapProvisioningIP"), p.BootstrapProvisioningIP, err.Error())) } if err := validate.Interface(p.ExternalBridge); err != nil { diff --git a/pkg/types/validation/installconfig_test.go b/pkg/types/validation/installconfig_test.go index 19544c4e6eb..4ba4121b0ce 100644 --- a/pkg/types/validation/installconfig_test.go +++ b/pkg/types/validation/installconfig_test.go @@ -91,10 +91,10 @@ func validVSpherePlatform() *vsphere.Platform { func validBareMetalPlatform() *baremetal.Platform { iface, _ := net.Interfaces() return &baremetal.Platform{ - LibvirtURI: "qemu+tcp://192.168.122.1/system", - IronicURI: "https://localhost:6385", + LibvirtURI: "qemu+tcp://192.168.122.1/system", + BootstrapProvisioningIP: "127.0.0.1", + ClusterProvisioningIP: "192.168.111.1", Hosts: []*baremetal.Host{}, - Image: baremetal.Image{}, ExternalBridge: iface[0].Name, ProvisioningBridge: iface[0].Name, DefaultMachinePlatform: &baremetal.MachinePool{},