Skip to content

Commit

Permalink
feat: Adds .kraftignore feature to ignore files and directories from …
Browse files Browse the repository at this point in the history
…sharing with unikernel via rootfs

Signed-off-by: Md Sahil <[email protected]>
  • Loading branch information
MdSahil-oss committed Nov 23, 2023
1 parent 6b23248 commit 32e420e
Show file tree
Hide file tree
Showing 3 changed files with 133 additions and 4 deletions.
21 changes: 20 additions & 1 deletion initrd/directory.go
Original file line number Diff line number Diff line change
Expand Up @@ -75,17 +75,36 @@ func (initrd *directory) Build(ctx context.Context) (string, error) {
writer := cpio.NewWriter(f)
defer writer.Close()

ignoringItems, err := getKraftignoreItems(ctx, initrd)
if err != nil {
return "", err
}

if err := filepath.WalkDir(initrd.path, func(path string, d fs.DirEntry, err error) error {
if err != nil {
return fmt.Errorf("received error before parsing path: %w", err)
}

internal := strings.TrimPrefix(path, filepath.Clean(initrd.path))
internal = filepath.ToSlash(internal)
if internal == "" {
return nil // Do not archive empty paths
}

if len(ignoringItems) > 0 && path != initrd.path {
switch isExistInKraftignoreFile(internal, d, ignoringItems) {
case "SkipDir":
log.G(ctx).
WithField("directory", internal).
Trace("ignoring from archiving")
return filepath.SkipDir
case "Exist":
log.G(ctx).
WithField("file", internal).
Trace("ignoring from archiving")
return nil
}
}

info, err := d.Info()
if err != nil {
return fmt.Errorf("could not get directory entry info: %w", err)
Expand Down
97 changes: 97 additions & 0 deletions initrd/kraftignore.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
package initrd

import (
"bufio"
"context"
"errors"
"io/fs"
"os"
"path/filepath"
"strings"

"kraftkit.sh/log"
)

// kraftignore filename
const KraftignoreFileName = ".kraftignore"

func getKraftignoreItems(ctx context.Context, initrd *directory) ([]string, error) {
if initrd.opts.kraftignorePath == "" {
cwd, err := os.Getwd()
if err != nil {
return []string{}, err
}
initrd.opts.kraftignorePath = filepath.Join(cwd, KraftignoreFileName)
}

if _, err := os.Stat(initrd.opts.kraftignorePath); errors.Is(err, os.ErrNotExist) {
return []string{}, nil
} else if err != nil {
return []string{}, err
}

kraftignoreFile, err := os.Open(initrd.opts.kraftignorePath)
defer kraftignoreFile.Close()

Check failure on line 34 in initrd/kraftignore.go

View workflow job for this annotation

GitHub Actions / All

SA5001: should check returned error before deferring kraftignoreFile.Close() (staticcheck)

Check failure on line 34 in initrd/kraftignore.go

View workflow job for this annotation

GitHub Actions / All

SA5001: should check returned error before deferring kraftignoreFile.Close() (staticcheck)

if err != nil {
return []string{}, err
}
kraftignoreScanner := bufio.NewScanner(kraftignoreFile)
kraftignoreScanner.Split(bufio.ScanLines)
var kraftignoreFileLines, ignoringItems []string

for kraftignoreScanner.Scan() {
kraftignoreFileLines = append(kraftignoreFileLines, kraftignoreScanner.Text())
}

for _, line := range kraftignoreFileLines {
line = strings.TrimSpace(line)
if line == "" || strings.HasPrefix(line, "#") {
continue
}
items := strings.Split(line, " ")
for _, item := range items {
item = strings.TrimSpace(item)
if item == "" {
continue
}

if hasGlobPatterns(item) {
log.G(ctx).
WithField("file", initrd.opts.kraftignorePath).
Warn("contains a glob pattern ", item,
" which is not supported by Kraftkit")
continue
}

if strings.HasPrefix(item, "./") {
item = strings.TrimPrefix(item, ".")
} else if !strings.HasPrefix(item, "/") {
item = "/" + item
}
ignoringItems = append(ignoringItems, item)
}
}

return ignoringItems, nil
}

func isExistInKraftignoreFile(internal string, pathInfo fs.DirEntry, kraftignoreItems []string) string {
for _, ignoringItem := range kraftignoreItems {
if internal == ignoringItem {
if pathInfo.IsDir() {
return "SkipDir"
}
return "Exist"
}
}
return ""
}

func hasGlobPatterns(item string) bool {
if strings.Contains(item, "*") || strings.Contains(item, "?") ||
strings.Contains(item, "!") || strings.Contains(item, "[") {
return true
}
return false
}
19 changes: 16 additions & 3 deletions initrd/options.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,15 @@
// You may not use this file except in compliance with the License.
package initrd

import (
"path/filepath"
)

type InitrdOptions struct {
output string
cacheDir string
arch string
output string
cacheDir string
arch string
kraftignorePath string
}

type InitrdOption func(*InitrdOptions) error
Expand Down Expand Up @@ -41,3 +46,11 @@ func WithArchitecture(arch string) InitrdOption {
return nil
}
}

// WithKraftignorePath sets the path for .kraftignore.
func WithKraftignorePath(dir string) InitrdOption {
return func(opts *InitrdOptions) error {
opts.kraftignorePath = filepath.Join(dir, KraftignoreFileName)
return nil
}
}

0 comments on commit 32e420e

Please sign in to comment.