Skip to content

Commit

Permalink
feat: Project restructure
Browse files Browse the repository at this point in the history
Restructure core package to make it more organized.
Add disk-related unit tests.
  • Loading branch information
matbme authored Feb 5, 2024
1 parent e088eac commit 6620f7f
Show file tree
Hide file tree
Showing 16 changed files with 525 additions and 345 deletions.
4 changes: 2 additions & 2 deletions .github/workflows/deb-build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,11 +23,11 @@ jobs:
rm -r /run/host${{ runner.tool_cache }}
- name: Install needed packages
run: apt update && apt install dpkg-dev build-essential debhelper libbtrfs-dev libdevmapper-dev libgpgme-dev lvm2 dh-golang golang-go gcc pkg-config -y
run: apt update && apt install dpkg-dev build-essential debhelper libbtrfs-dev libdevmapper-dev libgpgme-dev lvm2 dh-golang golang-go gcc pkg-config make -y

- name: Build debian package
run: |
dpkg-buildpackage --no-sign
make deb
mv ../*.deb ../albius.deb
- uses: softprops/action-gh-release@v1
Expand Down
6 changes: 3 additions & 3 deletions .github/workflows/go.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,10 @@ jobs:
- name: Install build dependencies
run: |
apt-get update
apt-get install -y gcc pkg-config libbtrfs-dev libdevmapper-dev libgpgme-dev lvm2
apt-get install -y gcc pkg-config libbtrfs-dev libdevmapper-dev libgpgme-dev lvm2 make
- name: Build
run: go build -v ./...
run: make build

test:
runs-on: ubuntu-latest
Expand All @@ -40,4 +40,4 @@ jobs:
- name: Test
run: |
distrobox enter -r albius_test -- sudo go test -v ./...
distrobox enter -r albius_test -- sudo make test
16 changes: 16 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
all: build test
all-deb: build test deb

build:
go build

deb:
dpkg-buildpackage --no-sign

test:
sudo go test -v ./...

.PHONY: clean

clean:
rm albius
80 changes: 57 additions & 23 deletions core/disk.go → core/disk/disk.go
Original file line number Diff line number Diff line change
@@ -1,14 +1,16 @@
package albius
package disk

import (
"cmp"
"encoding/json"
"fmt"
"reflect"
"slices"
"strconv"
"strings"

"github.com/vanilla-os/albius/core/lvm"
"github.com/vanilla-os/albius/core/util"
)

const (
Expand Down Expand Up @@ -72,7 +74,7 @@ func (disk *Disk) AvailableSectors() ([]Sector, error) {

func LocateDisk(diskname string) (*Disk, error) {
findPartitionCmd := "parted -sj %s unit MiB print"
output, err := OutputCommand(fmt.Sprintf(findPartitionCmd, diskname))
output, err := util.OutputCommand(fmt.Sprintf(findPartitionCmd, diskname))
// If disk is unformatted, parted returns the expected json but also throws an error.
// We can assume we have all the necessary information if output isn't empty.
if err != nil && output == "" {
Expand All @@ -91,10 +93,10 @@ func LocateDisk(diskname string) (*Disk, error) {
decoded.Disk.Partitions[i].FillPath(decoded.Disk.Path)
}

// Partitions may be unordered
slices.SortFunc(decoded.Disk.Partitions, func(a, b Partition) int {
return cmp.Compare(a.Number, b.Number)
})
// Partitions may be unordered
slices.SortFunc(decoded.Disk.Partitions, func(a, b Partition) int {
return cmp.Compare(a.Number, b.Number)
})

return &decoded.Disk, nil
}
Expand All @@ -121,13 +123,13 @@ func (disk *Disk) Update() error {
// inform the OS of changes to the partition table (using `partprobe`) and
// ensure the system is aware of it before proceeding.
func (disk *Disk) waitForNewPartition() error {
err := RunCommand(fmt.Sprintf("partprobe %s", disk.Path))
err := util.RunCommand(fmt.Sprintf("partprobe %s", disk.Path))
if err != nil {
return err
}

for {
output, err := OutputCommand(fmt.Sprintf("lsblk -nro NAME %s | wc -l", disk.Path))
output, err := util.OutputCommand(fmt.Sprintf("lsblk -nro NAME %s | wc -l", disk.Path))
if err != nil {
return err
}
Expand Down Expand Up @@ -178,7 +180,7 @@ func (disk *Disk) LabelDisk(label DiskLabel) error {
}
}

err = RunCommand(fmt.Sprintf(labelDiskCmd, disk.Path, label))
err = util.RunCommand(fmt.Sprintf(labelDiskCmd, disk.Path, label))
if err != nil {
return fmt.Errorf("failed to label disk: %s", err)
}
Expand Down Expand Up @@ -214,7 +216,7 @@ func (target *Disk) NewPartition(name string, fsType PartitionFs, start, end int
partName = fmt.Sprintf(" \"%s\"", name)
}

err := RunCommand(fmt.Sprintf(createPartCmd, target.Path, partType, partName, fsType, start, endStr))
err := util.RunCommand(fmt.Sprintf(createPartCmd, target.Path, partType, partName, fsType, start, endStr))
if err != nil {
return nil, fmt.Errorf("failed to create partition: %s", err)
}
Expand Down Expand Up @@ -266,17 +268,49 @@ func (target *Disk) NewPartition(name string, fsType PartitionFs, start, end int
//
// [Issue #44]: https://github.com/Vanilla-OS/Albius/issues/44
func (target *Disk) GetPartition(partNum int) *Partition {
// Happy path: No partitions are missing
if target.Partitions[partNum-1].Number == partNum {
return &target.Partitions[partNum-1]
}

// Missing partition numbers, find correct partition manually
for _, part := range target.Partitions {
if part.Number == partNum {
return &part
}
}

return nil
// Happy path: No partitions are missing
if target.Partitions[partNum-1].Number == partNum {
return &target.Partitions[partNum-1]
}

// Missing partition numbers, find correct partition manually
for _, part := range target.Partitions {
if part.Number == partNum {
return &part
}
}

return nil
}

func setField(obj interface{}, name string, value interface{}) error {
structValue := reflect.ValueOf(obj).Elem()
structFieldValue := structValue.FieldByName(name)

if !structFieldValue.IsValid() {
return fmt.Errorf("no such field: %s in obj", name)
}

if !structFieldValue.CanSet() {
return fmt.Errorf("cannot set %s field value", name)
}

structFieldType := structFieldValue.Type()
val := reflect.ValueOf(value)
var convertedVal reflect.Value
if structFieldType != val.Type() {
// Type conversions
if structFieldType.Kind() == reflect.Int && val.Type().Kind() == reflect.Float64 {
convertedVal = reflect.ValueOf(int(val.Interface().(float64)))
} else if structFieldType.Name() == "DiskLabel" && val.Type().Kind() == reflect.String {
convertedVal = reflect.ValueOf(DiskLabel(val.Interface().(string)))
} else {
return fmt.Errorf("provided value type for %s did not match obj field type. Expected %v, got %v", name, structFieldType, val.Type())
}
} else {
convertedVal = val
}

structFieldValue.Set(convertedVal)
return nil
}
136 changes: 136 additions & 0 deletions core/disk/disk_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,136 @@
package disk

import (
"os"
"os/exec"
"runtime"
"strings"
"testing"

luks "github.com/vanilla-os/albius/core/disk/luks"
)

var diskPath string

func TestMain(m *testing.M) {
_, filename, _, _ := runtime.Caller(0)
projRoot, _, _ := strings.Cut(filename, "core/")

device, err := exec.Command(projRoot+"utils/create_test_device.sh", "-o", "test.img", "-s", "51200").Output()
if err != nil {
panic(err)
}
diskPath = strings.TrimSpace(string(device))

status := m.Run()

err = exec.Command(projRoot+"utils/remove_test_device.sh", diskPath, "test.img").Run()
if err != nil {
panic(err)
}
os.Exit(status)
}

func TestLocateDisk(t *testing.T) {
d, err := LocateDisk(diskPath)
if err != nil {
t.Error(err)
}

if d.Path != diskPath {
t.Errorf("Located incorrect disk: %v", d)
}
}

func TestLabelDisk(t *testing.T) {
d, err := LocateDisk(diskPath)
if err != nil {
t.Error(err)
}

err = d.LabelDisk(GPT)
if err != nil {
t.Error(err)
}
}

func TestNewPartition(t *testing.T) {
d, err := LocateDisk(diskPath)
if err != nil {
t.Error(err)
}

_, err = d.NewPartition("", EXT4, 1, 25)
if err != nil {
t.Error(err)
}

_, err = d.NewPartition("", EXT4, 26, -1)
if err != nil {
t.Error(err)
}
}

func TestGetPartition(t *testing.T) {
d, err := LocateDisk(diskPath)
if err != nil {
t.Error(err)
}

if p := d.GetPartition(1); p == nil {
t.Error(err)
}
}

func TestLuksFormat(t *testing.T) {
d, err := LocateDisk(diskPath)
if err != nil {
t.Error(err)
}

if err = luks.LuksFormat(&d.Partitions[0], "test"); err != nil {
t.Error(err)
}
}

func TestIsLuks(t *testing.T) {
d, err := LocateDisk(diskPath)
if err != nil {
t.Error(err)
}

isLuks, err := luks.IsLuks(&d.Partitions[0])
if err != nil {
t.Error(err)
}
if !isLuks {
t.Error("Failed to detect partition as LUKS-encrypted")
}

isLuks, err = luks.IsLuks(&d.Partitions[1])
if err != nil {
t.Error(err)
}
if isLuks {
t.Error("Wrongly detected partition as LUKS-encrypted")
}
}

func TestLuksOpen(t *testing.T) {
d, err := LocateDisk(diskPath)
if err != nil {
t.Error(err)
}

err = luks.LuksOpen(&d.Partitions[0], "luks-test", "test")
if err != nil {
t.Error(err)
}
}

func TestLuksClose(t *testing.T) {
err := luks.LuksClose("luks-test")
if err != nil {
t.Error(err)
}
}
Loading

0 comments on commit 6620f7f

Please sign in to comment.