Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Bmcjob controller implementation #6

Merged
merged 15 commits into from
Jun 1, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
59 changes: 50 additions & 9 deletions api/v1alpha1/baseboardmanagement_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,8 @@ type BootDevice string
// BaseboardManagementConditionType represents the condition of the BaseboardManagement.
type BaseboardManagementConditionType string

// BaseboardManagementConditionStatus represents the status of a BaseboardManagementCondition.
type BaseboardManagementConditionStatus string
// ConditionStatus represents the status of a Condition.
type ConditionStatus string

const (
On PowerState = "on"
Expand All @@ -52,10 +52,14 @@ const (
)

const (
BaseboardManagementConditionTrue BaseboardManagementConditionStatus = "True"
BaseboardManagementConditionFalse BaseboardManagementConditionStatus = "False"
ConditionTrue ConditionStatus = "True"
ConditionFalse ConditionStatus = "False"
)

// PausedAnnotation is an annotation that can be applied to BaseboardManagement
// object to prevent a controller from processing a resource.
const PausedAnnotation = "bmc.tinkerbell.org/paused"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Rufuio.tinkerbell.org


// BaseboardManagementSpec defines the desired state of BaseboardManagement
type BaseboardManagementSpec struct {

Expand Down Expand Up @@ -102,10 +106,10 @@ type BaseboardManagementCondition struct {

// Status is the status of the BaseboardManagement condition.
// Can be True or False.
Status BaseboardManagementConditionStatus `json:"status"`
Status ConditionStatus `json:"status"`

// Last time the BaseboardManagement condition was updated.
LastUpdateTime metav1.Time `json:"lastUpdateTime"`
LastUpdateTime metav1.Time `json:"lastUpdateTime,omitempty"`

// Message represents human readable message indicating details about last transition.
// +optional
Expand All @@ -117,7 +121,7 @@ type BaseboardManagementSetConditionOption func(*BaseboardManagementCondition)

// SetCondition applies the cType condition to bm. If the condition already exists,
// it is updated.
func (bm *BaseboardManagement) SetCondition(cType BaseboardManagementConditionType, status BaseboardManagementConditionStatus, opts ...BaseboardManagementSetConditionOption) {
func (bm *BaseboardManagement) SetCondition(cType BaseboardManagementConditionType, status ConditionStatus, opts ...BaseboardManagementSetConditionOption) {
var condition *BaseboardManagementCondition

// Check if there's an existing condition.
Expand All @@ -136,19 +140,56 @@ func (bm *BaseboardManagement) SetCondition(cType BaseboardManagementConditionTy
condition = &bm.Status.Conditions[len(bm.Status.Conditions)-1]
}

condition.Status = status
condition.LastUpdateTime = metav1.Now()
if condition.Status != status {
condition.Status = status
condition.LastUpdateTime = metav1.Now()
}

for _, opt := range opts {
opt(condition)
}
}

// WithBaseboardManagementConditionMessage sets message m to the BaseboardManagementCondition.
func WithBaseboardManagementConditionMessage(m string) BaseboardManagementSetConditionOption {
return func(c *BaseboardManagementCondition) {
c.Message = m
}
}

// PauseReconcile adds the pausedAnnotation to the BaseboardManagement object.
func (bm *BaseboardManagement) PauseReconcile() {
if bm.Annotations == nil {
bm.initAnnotations()
}
bm.Annotations[PausedAnnotation] = "true"
}

// ClearPauseAnnotation deletes the pausedAnnotation from the BaseboardManagement object.
func (bm *BaseboardManagement) ClearPauseAnnotation() {
if bm.Annotations != nil {
delete(bm.Annotations, PausedAnnotation)
}
}

// IsReconcilePaused checks if the pausedAnnotation is present on the BaseboardManagement object.
func (bm *BaseboardManagement) IsReconcilePaused() bool {
if bm.Annotations == nil {
return false
}

if s, ok := bm.Annotations[PausedAnnotation]; ok {
return s == "true"
}

return false
}

// initAnnotations initalizes the BaseboardManagement metadata annotations.
func (bm *BaseboardManagement) initAnnotations() {
bm.Annotations = map[string]string{}
}

// BaseboardManagementRef defines the reference information to a BaseboardManagement resource.
type BaseboardManagementRef struct {
// Name is unique within a namespace to reference a BaseboardManagement resource.
Expand Down
75 changes: 67 additions & 8 deletions api/v1alpha1/bmcjob_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ limitations under the License.
package v1alpha1
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A general comment: why are we using BMCJob instead of BaseboardManagementJob (same for tasks)? We have inconsistency in the API naming.


import (
"fmt"

metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)

Expand All @@ -32,16 +34,16 @@ const (
JobRunning BMCJobConditionType = "Running"
)

// PowerControl represents the power control operation on the baseboard management.
type PowerControl string
// PowerAction represents the power control operation on the baseboard management.
type PowerAction string

const (
PowerOn PowerControl = "on"
HardPowerOff PowerControl = "off"
SoftPowerOff PowerControl = "soft"
Cycle PowerControl = "cycle"
Reset PowerControl = "reset"
Status PowerControl = "status"
PowerOn PowerAction = "on"
HardPowerOff PowerAction = "off"
SoftPowerOff PowerAction = "soft"
Cycle PowerAction = "cycle"
Reset PowerAction = "reset"
Status PowerAction = "status"
)

// BMCJobSpec defines the desired state of BMCJob
Expand Down Expand Up @@ -77,11 +79,68 @@ type BMCJobCondition struct {
// Type of the BMCJob condition.
Type BMCJobConditionType `json:"type"`

// Status is the status of the BMCJob condition.
// Can be True or False.
Status ConditionStatus `json:"status"`

// Message represents human readable message indicating details about last transition.
// +optional
Message string `json:"message,omitempty"`
}

// +kubebuilder:object:generate=false
type BMCJobSetConditionOption func(*BMCJobCondition)

// SetCondition applies the cType condition to bmj. If the condition already exists,
// it is updated.
func (bmj *BMCJob) SetCondition(cType BMCJobConditionType, status ConditionStatus, opts ...BMCJobSetConditionOption) {
var condition *BMCJobCondition

// Check if there's an existing condition.
for i, c := range bmj.Status.Conditions {
if c.Type == cType {
condition = &bmj.Status.Conditions[i]
break
}
}

// We didn't find an existing condition so create a new one and append it.
if condition == nil {
bmj.Status.Conditions = append(bmj.Status.Conditions, BMCJobCondition{
Type: cType,
})
condition = &bmj.Status.Conditions[len(bmj.Status.Conditions)-1]
}

condition.Status = status
for _, opt := range opts {
opt(condition)
}
}

// WithJobConditionMessage sets message m to the BMCJobCondition.
func WithJobConditionMessage(m string) BMCJobSetConditionOption {
pokearu marked this conversation as resolved.
Show resolved Hide resolved
return func(c *BMCJobCondition) {
c.Message = m
}
}

// HasCondition checks if the cType condition is present with status cStatus on a bmj.
func (bmj *BMCJob) HasCondition(cType BMCJobConditionType, cStatus ConditionStatus) bool {
for _, c := range bmj.Status.Conditions {
if c.Type == cType {
return c.Status == cStatus
}
}

return false
}

// FormatTaskName returns a BMCTask name based on BMCJob name.
func FormatTaskName(job BMCJob, n int) string {
return fmt.Sprintf("%s-task-%d", job.Name, n)
}

//+kubebuilder:object:root=true
//+kubebuilder:subresource:status
//+kubebuilder:resource:path=bmcjobs,scope=Namespaced,categories=tinkerbell,singular=bmcjob,shortName=bmj
Expand Down
68 changes: 59 additions & 9 deletions api/v1alpha1/bmctask_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,20 +20,23 @@ import (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)

// BMCTaskConditionType represents the condition of the BMC Job.
// BMCTaskConditionType represents the condition of the BMC Task.
type BMCTaskConditionType string

const (
// TaskCompleted represents successful completion of the BMC Task.
TaskCompleted BMCJobConditionType = "Completed"
TaskCompleted BMCTaskConditionType = "Completed"
// TaskFailed represents failure in BMC task execution.
TaskFailed BMCJobConditionType = "Failed"
TaskFailed BMCTaskConditionType = "Failed"
)

// BMCTaskSpec defines the desired state of BMCTask
type BMCTaskSpec struct {
// Task defines the specific action to be performed.
Task Task `json:"task"`

// Connection represents the BaseboardManagement connectivity information.
Connection Connection `json:"connection,omitempty"`
}

// Task represents the action to be performed.
Expand All @@ -42,18 +45,13 @@ type BMCTaskSpec struct {
// +kubebuilder:validation:MaxProperties:=1
type Task struct {
// PowerAction represents a baseboard management power operation.
// +kubebuilder:validation:Enum=on;off;soft;status;cycle;reset
PowerAction *PowerAction `json:"powerAction,omitempty"`

// OneTimeBootDeviceAction represents a baseboard management one time set boot device operation.
OneTimeBootDeviceAction *OneTimeBootDeviceAction `json:"oneTimeBootDeviceAction,omitempty"`
}

type PowerAction struct {
// State represents the requested power state to set for the baseboard management.
// +kubebuilder:validation:Enum=PowerOn;HardPowerOff;SoftPowerOff;Status;Cycle;Reset
PowerControl PowerControl `json:"powerControl"`
}

type OneTimeBootDeviceAction struct {
// Devices represents the boot devices, in order for setting one time boot.
// Currently only the first device in the slice is used to set one time boot.
Expand Down Expand Up @@ -86,11 +84,63 @@ type BMCTaskCondition struct {
// Type of the BMCTask condition.
Type BMCTaskConditionType `json:"type"`

// Status is the status of the BMCTask condition.
// Can be True or False.
Status ConditionStatus `json:"status"`

// Message represents human readable message indicating details about last transition.
// +optional
Message string `json:"message,omitempty"`
}

// +kubebuilder:object:generate=false
type BMCTaskSetConditionOption func(*BMCTaskCondition)

// SetCondition applies the cType condition to bmt. If the condition already exists,
// it is updated.
func (bmt *BMCTask) SetCondition(cType BMCTaskConditionType, status ConditionStatus, opts ...BMCTaskSetConditionOption) {
var condition *BMCTaskCondition

// Check if there's an existing condition.
for i, c := range bmt.Status.Conditions {
if c.Type == cType {
condition = &bmt.Status.Conditions[i]
break
}
}

// We didn't find an existing condition so create a new one and append it.
if condition == nil {
bmt.Status.Conditions = append(bmt.Status.Conditions, BMCTaskCondition{
Type: cType,
})
condition = &bmt.Status.Conditions[len(bmt.Status.Conditions)-1]
}

condition.Status = status
for _, opt := range opts {
opt(condition)
}
}

// WithTaskConditionMessage sets message m to the BMCTaskCondition.
func WithTaskConditionMessage(m string) BMCTaskSetConditionOption {
return func(c *BMCTaskCondition) {
c.Message = m
}
}

// HasCondition checks if the cType condition is present with status cStatus on a bmt.
func (bmt *BMCTask) HasCondition(cType BMCTaskConditionType, cStatus ConditionStatus) bool {
for _, c := range bmt.Status.Conditions {
if c.Type == cType {
return c.Status == cStatus
}
}

return false
}

//+kubebuilder:object:root=true
//+kubebuilder:subresource:status
//+kubebuilder:resource:path=bmctasks,scope=Namespaced,categories=tinkerbell,singular=bmctask,shortName=bmt
Expand Down
16 changes: 1 addition & 15 deletions api/v1alpha1/zz_generated.deepcopy.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,6 @@ spec:
description: Type of the BaseboardManagement condition.
type: string
required:
- lastUpdateTime
- status
- type
type: object
Expand Down
Loading