Skip to content

Commit

Permalink
feat(initializer): Use subcommand to keep the real logic (#83)
Browse files Browse the repository at this point in the history
* feat: Add a subcommand for initializer

Signed-off-by: Ce Gao <[email protected]>

* feat: Update the dockerfile

Signed-off-by: Ce Gao <[email protected]>

* feat: Add move logic

Signed-off-by: Ce Gao <[email protected]>

* feat: Add demo

Signed-off-by: Ce Gao <[email protected]>
  • Loading branch information
gaocegege authored Jul 6, 2020
1 parent f10964c commit 45e5160
Show file tree
Hide file tree
Showing 4 changed files with 123 additions and 55 deletions.
2 changes: 1 addition & 1 deletion build/ormb-storage-initializer/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,4 @@ FROM debian:stretch

COPY bin/ormb-storage-initializer /usr/local/bin/ormb-storage-initializer

ENTRYPOINT ["ormb-storage-initializer"]
ENTRYPOINT ["ormb-storage-initializer", "pull-and-export"]
115 changes: 115 additions & 0 deletions cmd/ormb-storage-initializer/cmd/pull-and-export.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
/*
Copyright © 2020 NAME HERE <EMAIL ADDRESS>
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package cmd

import (
"fmt"
"io/ioutil"
"os"
"path/filepath"
"strings"

"github.com/spf13/cobra"
"github.com/spf13/viper"

"github.com/caicloud/ormb/pkg/consts"
"github.com/caicloud/ormb/pkg/oras"
"github.com/caicloud/ormb/pkg/ormb"
)

// pullExportCmd represents the pull-and-export command.
var pullExportCmd = &cobra.Command{
Use: "pull-and-export",
Short: "Pull and export the model",
Long: ``,
PreRunE: preRunE,
RunE: func(cmd *cobra.Command, args []string) error {
// TODO(gaocegege): Check the args.
modelURI := args[0]
dstDir := args[1]

// Get username and password from environment
// Here AWS_SECRET_ACCESS_KEY and AWS_ACCESS_KEY_ID are used
// because Seldon Core does not support renaming the environment variable name.
username := viper.GetString("AWS_ACCESS_KEY_ID")
pwd := viper.GetString("AWS_SECRET_ACCESS_KEY")
// Get the host from the URL.
strs := strings.Split(modelURI, "/")
if len(strs) == 0 {
return fmt.Errorf("Failed to get the host from %s", modelURI)
}
fmt.Printf("Logging to the remote registry %s\n", strs[0])
fmt.Printf("Username: %s\n", username)
if err := ormbClient.Login(strs[0], username, pwd, true); err != nil {
return err
}

// Recreate the ORMB client to let it know the registry and config.
rootPath, err := filepath.Abs(viper.GetString("rootPath"))
if err != nil {
return err
}
fmt.Printf("Using %s as the root path\n", rootPath)

ormbClient, err = ormb.New(
oras.ClientOptRootPath(rootPath),
oras.ClientOptWriter(os.Stdout),
oras.ClientOptPlainHTTP(plainHTTPOpt),
)
if err != nil {
return err
}

// Pull the model from the remote registry.
if err := ormbClient.Pull(modelURI); err != nil {
return err
}
// Export it to the specified directory.
if err := ormbClient.Export(modelURI, dstDir); err != nil {
return err
}

// Move the files in model directory to the upper directory.
// e.g. Move /mnt/models/model to /mnt/models (dstDir).
// Seldon core will run `--model_base_path=dstDir` directly.
originalDir, err := filepath.Abs(
filepath.Join(dstDir, consts.ORMBModelDirectory))
if err != nil {
return err
}
destinationDir, err := filepath.Abs(dstDir)
if err != nil {
return err
}
files, err := ioutil.ReadDir(originalDir)
if err != nil {
return err
}
for _, f := range files {
oldPath := filepath.Join(originalDir, f.Name())
newPath := filepath.Join(destinationDir, f.Name())
fmt.Printf("Moving %s to %s\n", oldPath, newPath)
if err := os.Rename(oldPath, newPath); err != nil {
return err
}
}
return nil
},
}

func init() {
rootCmd.AddCommand(pullExportCmd)
}
57 changes: 3 additions & 54 deletions cmd/ormb-storage-initializer/cmd/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,73 +20,22 @@ import (
"io/ioutil"
"os"
"path/filepath"
"strings"

"github.com/sirupsen/logrus"
"github.com/spf13/cobra"
"github.com/spf13/viper"

"github.com/caicloud/ormb/pkg/consts"
"github.com/caicloud/ormb/pkg/oras"
"github.com/caicloud/ormb/pkg/ormb"
)

var ormbClient ormb.Interface

// rootCmd represents the base command when called without any subcommands
var rootCmd = &cobra.Command{
Use: "ormb-storage-initializer",
Short: "Download model from remote registry in Seldon Core and KFSerivng",
Long: ``,
PreRunE: preRunE,
RunE: func(cmd *cobra.Command, args []string) error {
modelURI := args[0]
dstDir := args[1]

// Get username and password from environment
// Here AWS_SECRET_ACCESS_KEY and AWS_ACCESS_KEY_ID are used
// because Seldon Core does not support renaming the environment variable name.
username := viper.GetString("AWS_ACCESS_KEY_ID")
pwd := viper.GetString("AWS_SECRET_ACCESS_KEY")
// Get the host from the URL.
strs := strings.Split(modelURI, "/")
if len(strs) == 0 {
return fmt.Errorf("Failed to get the host from %s", modelURI)
}
fmt.Printf("Logging to the remote registry %s\n", strs[0])
fmt.Printf("Username: %s\n", username)
if err := ormbClient.Login(strs[0], username, pwd, true); err != nil {
return err
}

// Recreate the ORMB client to let it know the registry and config.
rootPath, err := filepath.Abs(viper.GetString("rootPath"))
if err != nil {
return err
}
fmt.Printf("Using %s as the root path\n", rootPath)

ormbClient, err = ormb.New(
oras.ClientOptRootPath(rootPath),
oras.ClientOptWriter(os.Stdout),
oras.ClientOptPlainHTTP(plainHTTPOpt),
)
if err != nil {
return err
}

// Pull the model from the remote registry.
if err := ormbClient.Pull(modelURI); err != nil {
return err
}
// Export it to the specified directory.
if err := ormbClient.Export(modelURI, dstDir); err != nil {
return err
}

// Do not need to call moveToUpperDir since we do not have version directory.
return nil
},
Use: "ormb-storage-initializer",
Short: "Download model from remote registry in Seldon Core and KFSerivng",
Long: ``,
}

// Execute adds all child commands to the root command and sets flags appropriately.
Expand Down
4 changes: 4 additions & 0 deletions docs/tutorial-serving-seldon.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,10 @@ ormb can be used to pull models in Seldon Core. First we need to deploy Seldon C

In this tutorial, we use [SavedModel-fashion](../examples/SavedModel-fashion) as an example, to illustrate the feature.

## Demo

[![asciicast](https://asciinema.org/a/345568.svg)](https://asciinema.org/a/345568)

## Push the model to remote registry

In this tutorial, we use [demo.goharbor.io][] as the remote registry. First you need to register an account in [demo.goharbor.io][]. We use `ormbtest` as username, `ORMBtest12345` as password here.
Expand Down

0 comments on commit 45e5160

Please sign in to comment.