feat(container): migrate filesystem operations to io.Local abstraction

Migrate state.go:
- os.ReadFile → io.Local.Read
- os.MkdirAll → io.Local.EnsureDir
- os.WriteFile → io.Local.Write

Migrate templates.go:
- os.Stat → io.Local.IsFile/IsDir
- os.ReadFile → io.Local.Read
- os.ReadDir → io.Local.List

Part of #101 (io.Medium migration tracking issue).

Closes #108

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
Snider 2026-02-02 04:35:09 +00:00
parent 68f2f658f4
commit bd665e0892
2 changed files with 17 additions and 13 deletions

View file

@ -5,6 +5,8 @@ import (
"os" "os"
"path/filepath" "path/filepath"
"sync" "sync"
"github.com/host-uk/core/pkg/io"
) )
// State manages persistent container state. // State manages persistent container state.
@ -56,7 +58,7 @@ func NewState(filePath string) *State {
func LoadState(filePath string) (*State, error) { func LoadState(filePath string) (*State, error) {
state := NewState(filePath) state := NewState(filePath)
data, err := os.ReadFile(filePath) dataStr, err := io.Local.Read(filePath)
if err != nil { if err != nil {
if os.IsNotExist(err) { if os.IsNotExist(err) {
return state, nil return state, nil
@ -64,7 +66,7 @@ func LoadState(filePath string) (*State, error) {
return nil, err return nil, err
} }
if err := json.Unmarshal(data, state); err != nil { if err := json.Unmarshal([]byte(dataStr), state); err != nil {
return nil, err return nil, err
} }
@ -78,7 +80,7 @@ func (s *State) SaveState() error {
// Ensure the directory exists // Ensure the directory exists
dir := filepath.Dir(s.filePath) dir := filepath.Dir(s.filePath)
if err := os.MkdirAll(dir, 0755); err != nil { if err := io.Local.EnsureDir(dir); err != nil {
return err return err
} }
@ -87,7 +89,7 @@ func (s *State) SaveState() error {
return err return err
} }
return os.WriteFile(s.filePath, data, 0644) return io.Local.Write(s.filePath, string(data))
} }
// Add adds a container to the state and persists it. // Add adds a container to the state and persists it.
@ -166,5 +168,5 @@ func EnsureLogsDir() error {
if err != nil { if err != nil {
return err return err
} }
return os.MkdirAll(logsDir, 0755) return io.Local.EnsureDir(logsDir)
} }

View file

@ -7,6 +7,8 @@ import (
"path/filepath" "path/filepath"
"regexp" "regexp"
"strings" "strings"
"github.com/host-uk/core/pkg/io"
) )
//go:embed templates/*.yml //go:embed templates/*.yml
@ -71,12 +73,12 @@ func GetTemplate(name string) (string, error) {
userTemplatesDir := getUserTemplatesDir() userTemplatesDir := getUserTemplatesDir()
if userTemplatesDir != "" { if userTemplatesDir != "" {
templatePath := filepath.Join(userTemplatesDir, name+".yml") templatePath := filepath.Join(userTemplatesDir, name+".yml")
if _, err := os.Stat(templatePath); err == nil { if io.Local.IsFile(templatePath) {
content, err := os.ReadFile(templatePath) content, err := io.Local.Read(templatePath)
if err != nil { if err != nil {
return "", fmt.Errorf("failed to read user template %s: %w", name, err) return "", fmt.Errorf("failed to read user template %s: %w", name, err)
} }
return string(content), nil return content, nil
} }
} }
@ -194,7 +196,7 @@ func getUserTemplatesDir() string {
cwd, err := os.Getwd() cwd, err := os.Getwd()
if err == nil { if err == nil {
wsDir := filepath.Join(cwd, ".core", "linuxkit") wsDir := filepath.Join(cwd, ".core", "linuxkit")
if info, err := os.Stat(wsDir); err == nil && info.IsDir() { if io.Local.IsDir(wsDir) {
return wsDir return wsDir
} }
} }
@ -206,7 +208,7 @@ func getUserTemplatesDir() string {
} }
homeDir := filepath.Join(home, ".core", "linuxkit") homeDir := filepath.Join(home, ".core", "linuxkit")
if info, err := os.Stat(homeDir); err == nil && info.IsDir() { if io.Local.IsDir(homeDir) {
return homeDir return homeDir
} }
@ -217,7 +219,7 @@ func getUserTemplatesDir() string {
func scanUserTemplates(dir string) []Template { func scanUserTemplates(dir string) []Template {
var templates []Template var templates []Template
entries, err := os.ReadDir(dir) entries, err := io.Local.List(dir)
if err != nil { if err != nil {
return templates return templates
} }
@ -266,12 +268,12 @@ func scanUserTemplates(dir string) []Template {
// extractTemplateDescription reads the first comment block from a YAML file // extractTemplateDescription reads the first comment block from a YAML file
// to use as a description. // to use as a description.
func extractTemplateDescription(path string) string { func extractTemplateDescription(path string) string {
content, err := os.ReadFile(path) content, err := io.Local.Read(path)
if err != nil { if err != nil {
return "" return ""
} }
lines := strings.Split(string(content), "\n") lines := strings.Split(content, "\n")
var descLines []string var descLines []string
for _, line := range lines { for _, line := range lines {