func (p *demoProvisioner) Provision(data provisioner.ProvisionData) (result provisioner.Result, err error) {
	hostName := p.objectMeta.Name
	p.log.Info("provisioning image to host")
	switch hostName {
	case ValidationErrorHost:
		p.log.Info("setting validation error")
		result.ErrorMessage = "validation failed"
	case ProvisioningHost:
		p.log.Info("provisioning host")
		result.Dirty = true
		result.RequeueAfter = time.Second * 5
	default:
		p.log.Info("finished provisioning")
	}
	return result, nil
}
Provision writes the image from the host spec to the host. It may
be called multiple times, and should return true for its dirty flag
until the provisioning operation is completed.
package demo
import (
	"time"
	"github.com/metal3-io/baremetal-operator/pkg/ironic/bmc"
	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
	"github.com/go-logr/logr"
	logz "sigs.k8s.io/controller-runtime/pkg/log/zap"
	metal3v1alpha1 "github.com/metal3-io/baremetal-operator/apis/metal3.io/v1alpha1"
	"github.com/metal3-io/baremetal-operator/pkg/provisioner"
)
var log = logz.New().WithName("provisioner").WithName("demo")
var deprovisionRequeueDelay = time.Second * 10
var provisionRequeueDelay = time.Second * 10
const (
	RegistrationErrorHost string = "demo-registration-error"
	RegisteringHost string = "demo-registering"
	AvailableHost string = "demo-available"
	InspectingHost string = "demo-inspecting"
	PreparingErrorHost string = "demo-preparing-error"
	PreparingHost string = "demo-preparing"
	ValidationErrorHost string = "demo-validation-error"
	ProvisioningHost string = "demo-provisioning"
	ProvisionedHost string = "demo-provisioned"
)
type demoProvisioner struct {
	objectMeta metav1.ObjectMeta
	provID string
	bmcCreds bmc.Credentials
	log logr.Logger
	publisher provisioner.EventPublisher
}
type Demo struct{}
func (d Demo) NewProvisioner(hostData provisioner.HostData, publisher provisioner.EventPublisher) (provisioner.Provisioner, error) {
	p := &demoProvisioner{
		objectMeta: hostData.ObjectMeta,
		provID:     hostData.ProvisionerID,
		bmcCreds:   hostData.BMCCredentials,
		log:        log.WithValues("host", hostData.ObjectMeta.Name),
		publisher:  publisher,
	}
	return p, nil
}
func (p *demoProvisioner) HasCapacity() (result bool, err error) {
	return true, nil
}
func (p *demoProvisioner) ValidateManagementAccess(data provisioner.ManagementAccessData, credentialsChanged, force bool) (result provisioner.Result, provID string, err error) {
	p.log.Info("testing management access")
	hostName := p.objectMeta.Name
	switch hostName {
	case RegistrationErrorHost:
		result.ErrorMessage = "failed to register new host"
		p.log.Info("setting registration error")
	case RegisteringHost:
		result.Dirty = true
		result.RequeueAfter = time.Second * 5
	default:
		if p.provID == "" {
			provID = p.objectMeta.Name
			p.log.Info("setting provisioning id", "provisioningID", provID)
			result.Dirty = true
		}
	}
	return
}
func (p *demoProvisioner) PreprovisioningImageFormats() ([]metal3v1alpha1.ImageFormat, error) {
	return nil, nil
}
func (p *demoProvisioner) InspectHardware(data provisioner.InspectData, force, refresh bool) (result provisioner.Result, started bool, details *metal3v1alpha1.HardwareDetails, err error) {
	started = true
	hostName := p.objectMeta.Name
	if hostName == InspectingHost {
		result.Dirty = true
		result.RequeueAfter = time.Second * 5
		return
	}
	p.log.Info("continuing inspection by setting details")
	details =
		&metal3v1alpha1.HardwareDetails{
			RAMMebibytes: 128 * 1024,
			NIC: []metal3v1alpha1.NIC{
				{
					Name:      "nic-1",
					Model:     "virt-io",
					MAC:       "some:mac:address",
					IP:        "192.168.100.1",
					SpeedGbps: 1,
					PXE:       true,
				},
				{
					Name:      "nic-2",
					Model:     "e1000",
					MAC:       "some:other:mac:address",
					IP:        "192.168.100.2",
					SpeedGbps: 1,
					PXE:       false,
				},
			},
			Storage: []metal3v1alpha1.Storage{
				{
					Name:       "disk-1 (boot)",
					Rotational: false,
					SizeBytes:  metal3v1alpha1.TebiByte * 93,
					Model:      "Dell CFJ61",
				},
				{
					Name:       "disk-2",
					Rotational: false,
					SizeBytes:  metal3v1alpha1.TebiByte * 93,
					Model:      "Dell CFJ61",
				},
			},
			CPU: metal3v1alpha1.CPU{
				Arch:           "x86_64",
				Model:          "Core 2 Duo",
				ClockMegahertz: 3.0 * metal3v1alpha1.GigaHertz,
				Flags:          []string{"lm", "hypervisor", "vmx"},
				Count:          1,
			},
		}
	p.publisher("InspectionComplete", "Hardware inspection completed")
	return
}
func (p *demoProvisioner) UpdateHardwareState() (hwState provisioner.HardwareState, err error) {
	p.log.Info("updating hardware state")
	return
}
func (p *demoProvisioner) Prepare(data provisioner.PrepareData, unprepared bool) (result provisioner.Result, started bool, err error) {
	hostName := p.objectMeta.Name
	switch hostName {
	case PreparingErrorHost:
		p.log.Info("preparing error host")
		result.ErrorMessage = "preparing failed"
	case PreparingHost:
		p.log.Info("preparing host")
		started = unprepared
		result.Dirty = true
		result.RequeueAfter = time.Second * 5
	default:
		p.log.Info("finished preparing")
		started = true
	}
	return
}
func (p *demoProvisioner) Adopt(data provisioner.AdoptData, force bool) (result provisioner.Result, err error) {
	p.log.Info("adopting host")
	result.Dirty = false
	return
}