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

Add export command #24

Merged
merged 8 commits into from
Feb 21, 2024
Merged
Show file tree
Hide file tree
Changes from 5 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
2 changes: 2 additions & 0 deletions cmd/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ package cmd

import (
"jmm/pkg/cmd/build"
"jmm/pkg/cmd/export"
"jmm/pkg/cmd/login"
"jmm/pkg/cmd/models"
"jmm/pkg/cmd/pull"
Expand Down Expand Up @@ -42,6 +43,7 @@ func init() {
rootCmd.AddCommand(pull.PullCommand())
rootCmd.AddCommand(push.PushCommand())
rootCmd.AddCommand(models.ModelsCommand())
rootCmd.AddCommand(export.ExportCommand())
rootCmd.AddCommand(version.NewCmdVersion())
}

Expand Down
66 changes: 31 additions & 35 deletions pkg/artifact/model-layer.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,26 +7,16 @@ import (
"os"
"path/filepath"
"strings"

ocispec "github.com/opencontainers/image-spec/specs-go/v1"
)

type ModelLayer struct {
contextDir string
MediaType string
Descriptor ocispec.Descriptor
}

func NewLayer(rootpath string, mediaType string) *ModelLayer {
return &ModelLayer{
contextDir: rootpath,
MediaType: mediaType,
}
BaseDir string
MediaType string
}

func (layer *ModelLayer) Apply(writers ...io.Writer) error {
// Check if path exists
_, err := os.Stat(layer.contextDir)
_, err := os.Stat(layer.BaseDir)
if err != nil {
return err
}
Expand All @@ -40,46 +30,39 @@ func (layer *ModelLayer) Apply(writers ...io.Writer) error {
defer tw.Close()

// walk the context dir and tar everything
err = filepath.Walk(layer.contextDir, func(file string, fi os.FileInfo, err error) error {

err = filepath.Walk(layer.BaseDir, func(file string, fi os.FileInfo, err error) error {
if err != nil {
return err
}

if !fi.Mode().IsRegular() {
// Skip anything that's not a regular file or directory
if !fi.Mode().IsRegular() && !fi.Mode().IsDir() {
return nil
}
// Skip the baseDir itself
if file == layer.BaseDir {
return nil
}

// create a new dir/file header
header, err := tar.FileInfoHeader(fi, fi.Name())
if err != nil {
return err
}

parentDir := filepath.Dir(layer.contextDir)

// update the name to correctly reflect the desired destination when untaring
header.Name = strings.TrimPrefix(
strings.Replace(file, parentDir, "", -1), string(filepath.Separator))
// We want the path in the tarball to be relative to the layer's base directory
subPath := strings.TrimPrefix(strings.Replace(file, layer.BaseDir, "", -1), string(filepath.Separator))
header.Name = subPath

// write the header
if err := tw.WriteHeader(header); err != nil {
return err
}

// open files for taring
f, err := os.Open(file)
if err != nil {
return err
}

// copy file data into tar writer
if _, err := io.Copy(tw, f); err != nil {
return err
if fi.Mode().IsRegular() {
err := writeFileToTar(file, tw)
if err != nil {
return err
}
}

f.Close()

return nil
})

Expand All @@ -88,3 +71,16 @@ func (layer *ModelLayer) Apply(writers ...io.Writer) error {
}
return nil
}

func writeFileToTar(file string, tw *tar.Writer) error {
f, err := os.Open(file)
if err != nil {
return err
}
defer f.Close()

if _, err := io.Copy(tw, f); err != nil {
return err
}
return nil
}
43 changes: 17 additions & 26 deletions pkg/cmd/build/build.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,21 +7,17 @@ import (
"fmt"
"os"
"path"
"path/filepath"

"jmm/pkg/artifact"
"jmm/pkg/lib/constants"
"jmm/pkg/lib/filesystem"
"jmm/pkg/lib/storage"

"github.com/spf13/cobra"
"github.com/spf13/viper"
"oras.land/oras-go/v2/registry"
)

const (
DEFAULT_MODEL_FILE = "Jozufile"
)

var (
shortDesc = `Build a model`
longDesc = `A longer description that spans multiple lines and likely contains examples
Expand Down Expand Up @@ -83,7 +79,7 @@ func NewCmdBuild() *cobra.Command {
func (options *BuildOptions) Complete(cmd *cobra.Command, argsIn []string) error {
options.ContextDir = argsIn[0]
if options.ModelFile == "" {
options.ModelFile = options.ContextDir + "/" + DEFAULT_MODEL_FILE
options.ModelFile = path.Join(options.ContextDir, constants.DefaultModelFileName)
}
options.configHome = viper.GetString("config")
fmt.Println("config: ", options.configHome)
Expand Down Expand Up @@ -114,31 +110,39 @@ func (options *BuildOptions) RunBuild() error {

// 2. package the Code
for _, code := range jozufile.Code {
codePath, err := toAbsPath(options.ContextDir, code.Path)
codePath, err := filesystem.VerifySubpath(options.ContextDir, code.Path)
if err != nil {
return err
}
layer := artifact.NewLayer(codePath, constants.CodeLayerMediaType)
layer := &artifact.ModelLayer{
BaseDir: codePath,
MediaType: constants.CodeLayerMediaType,
}
model.Layers = append(model.Layers, *layer)
}
// 3. package the DataSets
datasetPath := ""
for _, dataset := range jozufile.DataSets {
datasetPath, err = toAbsPath(options.ContextDir, dataset.Path)
datasetPath, err := filesystem.VerifySubpath(options.ContextDir, dataset.Path)
if err != nil {
return err
}
layer := artifact.NewLayer(datasetPath, constants.DataSetLayerMediaType)
layer := &artifact.ModelLayer{
BaseDir: datasetPath,
MediaType: constants.DataSetLayerMediaType,
}
model.Layers = append(model.Layers, *layer)
}

// 4. package the TrainedModels
for _, trainedModel := range jozufile.Models {
modelPath, err := toAbsPath(options.ContextDir, trainedModel.Path)
modelPath, err := filesystem.VerifySubpath(options.ContextDir, trainedModel.Path)
if err != nil {
return err
}
layer := artifact.NewLayer(modelPath, constants.ModelLayerMediaType)
layer := &artifact.ModelLayer{
BaseDir: modelPath,
MediaType: constants.ModelLayerMediaType,
}
model.Layers = append(model.Layers, *layer)
}

Expand Down Expand Up @@ -192,16 +196,3 @@ func (flags *BuildFlags) AddFlags(cmd *cobra.Command) {
func NewBuildFlags() *BuildFlags {
return &BuildFlags{}
}
func toAbsPath(context string, relativePath string) (string, error) {

absContext, err := filepath.Abs(context)
if err != nil {
fmt.Println("Error resolving base path:", err)
return "", err
}
combinedPath := filepath.Join(absContext, relativePath)

cleanPath := filepath.Clean(combinedPath)
return cleanPath, nil

}
4 changes: 3 additions & 1 deletion pkg/cmd/build/build_test.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package build

import (
"jmm/pkg/lib/constants"
"path"
"testing"

"github.com/spf13/cobra"
Expand All @@ -26,7 +28,7 @@ func TestBuildOptions_Complete(t *testing.T) {

assert.NoError(t, err)
assert.Equal(t, args[0], options.ContextDir)
assert.Equal(t, options.ContextDir+"/"+DEFAULT_MODEL_FILE, options.ModelFile)
assert.Equal(t, path.Join(options.ContextDir, constants.DefaultModelFileName), options.ModelFile)
}

func TestBuildOptions_Validate(t *testing.T) {
Expand Down
Loading