Skip to content

Commit

Permalink
(feat): Big overhaul of layer and actions
Browse files Browse the repository at this point in the history
  • Loading branch information
lasith-kg committed Nov 28, 2023
1 parent 96207ae commit ae0505f
Show file tree
Hide file tree
Showing 19 changed files with 105 additions and 139 deletions.
5 changes: 2 additions & 3 deletions cmd/ebs-bootstrap.go
Original file line number Diff line number Diff line change
Expand Up @@ -55,17 +55,16 @@ func main() {
})
checkError(bv.Validate(c))
// Layers
layers := layer.NewExponentialBackoffLayerExecutor([]layer.Layer{
le := layer.NewExponentialBackoffLayerExecutor([]layer.Layer{
layer.NewFormatDeviceLayer(db),
layer.NewLabelDeviceLayer(db),
layer.NewUnmountDeviceLayer(db, fb),
layer.NewCreateDirectoryLayer(db, fb),
layer.NewMountDeviceLayer(db, fb),
layer.NewResizeDeviceLayer(drb),
layer.NewChangeOwnerLayer(ub, fb),
layer.NewChangePermissionsLayer(fb),
}, ae)
checkError(layers.Execute(c))
checkError(le.Execute(c))
}

func checkError(err error) {
Expand Down
6 changes: 3 additions & 3 deletions configs/ubuntu.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,11 @@ defaults:
mode: healthcheck
devices:
/dev/vdb:
fs: ext4
fs: xfs
label: lasith-rules
mountPoint: /ifmx/dev/james
mountPoint: /ifmx/tempp
mountOptions: defaults
group: ubuntu
user: ubuntu
permissions: 644
permissions: 0644
resizeFs: true
13 changes: 2 additions & 11 deletions internal/action/action.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,18 +9,12 @@ import (
"github.com/reecetech/ebs-bootstrap/internal/utils"
)

const (
DisabledWarning = ""
FormatActionWarning = "Formatting larger disks can take several seconds ⌛ Please wait patiently 🙇"
)

type Action interface {
Execute() error
GetDeviceName() string
Success() string
Prompt() string
Refuse() string
Warning() string
}

type ActionExecutor struct {
Expand Down Expand Up @@ -53,9 +47,6 @@ func (ae *ActionExecutor) ExecuteAction(action Action) error {
}

func (ae *ActionExecutor) executeAction(action Action) error {
if w := action.Warning(); w != DisabledWarning {
log.Printf("🟠 %s: %s", action.GetDeviceName(), w)
}
if err := action.Execute(); err != nil {
return err
}
Expand All @@ -64,8 +55,8 @@ func (ae *ActionExecutor) executeAction(action Action) error {
}

func (ae *ActionExecutor) ExecuteActions(actions []Action) error {
for _, action := range actions {
err := ae.ExecuteAction(action)
for _, a := range actions {
err := ae.ExecuteAction(a)
if err != nil {
return err
}
Expand Down
12 changes: 0 additions & 12 deletions internal/action/file.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,10 +44,6 @@ func (a *CreateDirectoryAction) Success() string {
return fmt.Sprintf("Successfully created directory %s", a.path)
}

func (a *CreateDirectoryAction) Warning() string {
return DisabledWarning
}

type ChangeOwnerAction struct {
deviceName string
path string
Expand Down Expand Up @@ -84,10 +80,6 @@ func (a *ChangeOwnerAction) Success() string {
return fmt.Sprintf("Successfully changed ownership (%d:%d) of %s", a.uid, a.gid, a.path)
}

func (a *ChangeOwnerAction) Warning() string {
return DisabledWarning
}

type ChangePermissionsAction struct {
deviceName string
path string
Expand Down Expand Up @@ -129,7 +121,3 @@ func (a *ChangePermissionsAction) Refuse() string {
func (a *ChangePermissionsAction) Success() string {
return fmt.Sprintf("Successfully change permissions of %s to %s", a.path, a.perms)
}

func (a *ChangePermissionsAction) Warning() string {
return DisabledWarning
}
4 changes: 0 additions & 4 deletions internal/action/format.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,3 @@ func (a *FormatDeviceAction) Refuse() string {
func (a *FormatDeviceAction) Success() string {
return fmt.Sprintf("Successfully formated to %s", a.fileSystemService.GetFileSystem())
}

func (a *FormatDeviceAction) Warning() string {
return FormatActionWarning
}
4 changes: 0 additions & 4 deletions internal/action/label.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,3 @@ func (a *LabelDeviceAction) Refuse() string {
func (a *LabelDeviceAction) Success() string {
return fmt.Sprintf("Successfully labelled to %s", a.label)
}

func (a *LabelDeviceAction) Warning() string {
return DisabledWarning
}
8 changes: 0 additions & 8 deletions internal/action/mount.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,10 +46,6 @@ func (a *MountDeviceAction) Success() string {
return fmt.Sprintf("Successfully mounted %s to %s (%s)", a.source, a.target, a.options)
}

func (a *MountDeviceAction) Warning() string {
return DisabledWarning
}

type UnmountDeviceAction struct {
source string
target string
Expand Down Expand Up @@ -87,7 +83,3 @@ func (a *UnmountDeviceAction) Refuse() string {
func (a *UnmountDeviceAction) Success() string {
return fmt.Sprintf("Successfully unmounted %s from %s", a.source, a.target)
}

func (a *UnmountDeviceAction) Warning() string {
return DisabledWarning
}
25 changes: 17 additions & 8 deletions internal/backend/device.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import (

type DeviceBackend interface {
GetBlockDevice(device string) (*model.BlockDevice, error)
Label(bd *model.BlockDevice, label string) (action.Action, error)
Label(bd *model.BlockDevice, label string) ([]action.Action, error)
Format(bd *model.BlockDevice, fileSystem model.FileSystem) (action.Action, error)
Mount(bd *model.BlockDevice, target string, options model.MountOptions) action.Action
Remount(bd *model.BlockDevice, target string, options model.MountOptions) action.Action
Expand Down Expand Up @@ -41,26 +41,35 @@ func (db *LinuxDeviceBackend) GetBlockDevice(device string) (*model.BlockDevice,
return blockDevice, nil
}

func (db *LinuxDeviceBackend) Label(bd *model.BlockDevice, label string) (action.Action, error) {
fs, err := db.fileSystemServiceFactory.Select(bd.FileSystem)
// This method is unique in the sense that some file-systems like xfs might require
// that the device be unmounted before any labelling operations can commence. For these
// file systems, we would preprend any label action with an unmount action (if the device is already mounted)
func (db *LinuxDeviceBackend) Label(bd *model.BlockDevice, label string) ([]action.Action, error) {
actions := make([]action.Action, 0)
fss, err := db.fileSystemServiceFactory.Select(bd.FileSystem)
if err != nil {
return nil, err
}
return action.NewLabelDeviceAction(
if fss.DoesLabelRequireUnmount() && bd.MountPoint != "" {
a := db.Umount(bd)
actions = append(actions, a)
}
a := action.NewLabelDeviceAction(
bd.Name,
label,
fs,
), nil
fss,
)
return append(actions, a), nil
}

func (db *LinuxDeviceBackend) Format(bd *model.BlockDevice, fileSystem model.FileSystem) (action.Action, error) {
fs, err := db.fileSystemServiceFactory.Select(fileSystem)
fss, err := db.fileSystemServiceFactory.Select(fileSystem)
if err != nil {
return nil, err
}
return action.NewFormatDeviceAction(
bd.Name,
fs,
fss,
), nil
}

Expand Down
8 changes: 6 additions & 2 deletions internal/backend/resize.go
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ func (dmb *LinuxDeviceResizeBackend) Resize(bd *model.BlockDevice) (action.Actio
return nil, err
}
target := bd.Name
if fss.DoesResizeRequiresMount() {
if fss.DoesResizeRequireMount() {
if bd.MountPoint == "" {
return nil, fmt.Errorf("🔴 %s: To resize the %s file system, device must be mounted", fss.GetFileSystem(), bd.Name)
}
Expand Down Expand Up @@ -87,7 +87,11 @@ func (dmb *LinuxDeviceResizeBackend) From(config *config.Config) error {
return err
}
// Can not fetch file system metrics from a device with
// no file system. Therefore, we continue if this is the case
// no file system. Therefore, we exit with error if this is the case
// The reason we exit early, rather than continuing is because we want
// to simplify the data view of the Device Resize Backend as much as possible
// With this check, we ensure that all devices in the resize backend have a
// valid file system
if bd.FileSystem == model.Unformatted {
return fmt.Errorf("🔴 %s: Can not resize a device with no file system", bd.Name)
}
Expand Down
8 changes: 6 additions & 2 deletions internal/layer/directory.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,8 +50,8 @@ func (fdl *CreateDirectoryLayer) Modify(c *config.Config) ([]action.Action, erro
if d != nil {
continue
}
action := fdl.fileBackend.CreateDirectory(bd.Name, cd.MountPoint)
actions = append(actions, action)
a := fdl.fileBackend.CreateDirectory(bd.Name, cd.MountPoint)
actions = append(actions, a)
}
return actions, nil
}
Expand All @@ -68,3 +68,7 @@ func (fdl *CreateDirectoryLayer) Validate(c *config.Config) error {
log.Println("🟢 Passed directory validation checks")
return nil
}

func (fdl *CreateDirectoryLayer) Warning() string {
return DisableWarning
}
10 changes: 7 additions & 3 deletions internal/layer/format.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,12 +34,12 @@ func (fdl *FormatDeviceLayer) Modify(c *config.Config) ([]action.Action, error)
if bd.FileSystem == cd.Fs {
continue
}
if cd.Fs == model.Unformatted {
return nil, fmt.Errorf("🔴 %s: Can not erase the file system of a device", bd.Name)
}
if bd.FileSystem != model.Unformatted {
return nil, fmt.Errorf("🔴 %s: Can not format a device that already has a %s file system", bd.Name, bd.FileSystem)
}
if bd.MountPoint != "" {
return nil, fmt.Errorf("🔴 %s: Can not format a device that is already mounted to %s", bd.Name, bd.MountPoint)
}
action, err := fdl.deviceBackend.Format(bd, cd.Fs)
if err != nil {
return nil, err
Expand All @@ -62,3 +62,7 @@ func (fdl *FormatDeviceLayer) Validate(c *config.Config) error {
log.Println("🟢 Passed file system validation checks")
return nil
}

func (fdl *FormatDeviceLayer) Warning() string {
return "Formatting larger disks can take several seconds ⌛"
}
8 changes: 6 additions & 2 deletions internal/layer/label.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,11 +40,11 @@ func (fdl *LabelDeviceLayer) Modify(c *config.Config) ([]action.Action, error) {
if bd.FileSystem == model.Unformatted {
return nil, fmt.Errorf("🔴 %s: Can not label a device with no file system", bd.Name)
}
action, err := fdl.deviceBackend.Label(bd, cd.Label)
a, err := fdl.deviceBackend.Label(bd, cd.Label)
if err != nil {
return nil, err
}
actions = append(actions, action)
actions = append(actions, a...)
}
return actions, nil
}
Expand All @@ -65,3 +65,7 @@ func (fdl *LabelDeviceLayer) Validate(c *config.Config) error {
log.Println("🟢 Passed label validation checks")
return nil
}

func (fdl *LabelDeviceLayer) Warning() string {
return "Certain file systems require that devices be unmounted prior to labeling"
}
11 changes: 11 additions & 0 deletions internal/layer/layer.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package layer

import (
"log"
"math"
"time"

Expand All @@ -15,10 +16,15 @@ const (
MaxRetries = 3
)

const (
DisableWarning = ""
)

type Layer interface {
From(config *config.Config) error
Modify(c *config.Config) ([]action.Action, error)
Validate(config *config.Config) error
Warning() string
}

type LayerExecutor interface {
Expand Down Expand Up @@ -58,6 +64,11 @@ func (le *ExponentialBackoffLayerExecutor) Execute(config *config.Config) error
if err != nil {
return err
}
// Only print warning if actions are detected and a valid warning
// message is provided
if warning := layer.Warning(); len(actions) > 0 && warning != DisableWarning {
log.Printf("🟠 %s", warning)
}
err = le.actionExecutor.ExecuteActions(actions)
if err != nil {
return err
Expand Down
27 changes: 17 additions & 10 deletions internal/layer/mount.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
"github.com/reecetech/ebs-bootstrap/internal/action"
"github.com/reecetech/ebs-bootstrap/internal/backend"
"github.com/reecetech/ebs-bootstrap/internal/config"
"github.com/reecetech/ebs-bootstrap/internal/model"
)

type MountDeviceLayer struct {
Expand Down Expand Up @@ -39,16 +40,14 @@ func (fdl *MountDeviceLayer) Modify(c *config.Config) ([]action.Action, error) {
if cd.MountPoint == "" {
continue
}
if bd.MountPoint != "" && bd.MountPoint != cd.MountPoint {
return nil, fmt.Errorf("🔴 %s: Device is already mounted to %s. Thus cannot be mounted to %s", name, bd.MountPoint, cd.MountPoint)
if bd.FileSystem == model.Unformatted {
return nil, fmt.Errorf("🔴 %s: Can not mount a device with no file system", bd.Name)
}

var a action.Action
if bd.MountPoint == cd.MountPoint {
if !c.GetRemount(name) {
continue
if c.GetRemount(name) {
a := fdl.deviceBackend.Remount(bd, cd.MountPoint, cd.MountOptions)
actions = append(actions, a)
}
a = fdl.deviceBackend.Remount(bd, cd.MountPoint, cd.MountOptions)
} else {
_, err = fdl.fileBackend.GetDirectory(cd.MountPoint)
if err != nil {
Expand All @@ -60,10 +59,14 @@ func (fdl *MountDeviceLayer) Modify(c *config.Config) ([]action.Action, error) {
if fdl.fileBackend.IsMount(cd.MountPoint) {
return nil, fmt.Errorf("🔴 %s: %s is already mounted by another device", name, cd.MountPoint)
}
a = fdl.deviceBackend.Mount(bd, cd.MountPoint, cd.MountOptions)
// If mount point already exists, then lets unmount it first
if bd.MountPoint != "" {
a := fdl.deviceBackend.Umount(bd)
actions = append(actions, a)
}
a := fdl.deviceBackend.Mount(bd, cd.MountPoint, cd.MountOptions)
actions = append(actions, a)
}

actions = append(actions, a)
}
return actions, nil
}
Expand All @@ -84,3 +87,7 @@ func (fdl *MountDeviceLayer) Validate(c *config.Config) error {
log.Printf("🟢 Passed mountpoint validation checks")
return nil
}

func (fdl *MountDeviceLayer) Warning() string {
return "Devices mounted to a location not specified in the configuration will be unmounted"
}
8 changes: 6 additions & 2 deletions internal/layer/owner.go
Original file line number Diff line number Diff line change
Expand Up @@ -68,8 +68,8 @@ func (fdl *ChangeOwnerLayer) Modify(c *config.Config) ([]action.Action, error) {
if d.Uid == uid && d.Gid == gid {
continue
}
action := fdl.fileBackend.ChangeOwner(name, cd.MountPoint, uid, gid)
actions = append(actions, action)
a := fdl.fileBackend.ChangeOwner(name, cd.MountPoint, uid, gid)
actions = append(actions, a)
}
return actions, nil
}
Expand Down Expand Up @@ -119,3 +119,7 @@ func (fdl *ChangeOwnerLayer) Validate(c *config.Config) error {
log.Printf("🟢 Passed ownership validation checks")
return nil
}

func (fdl *ChangeOwnerLayer) Warning() string {
return DisableWarning
}
Loading

0 comments on commit ae0505f

Please sign in to comment.