提交 25f08a71 编写于 作者: O openeuler-ci-bot 提交者: Gitee

!28 message: add info to client when image is deleted successfully

Merge pull request !28 from DCCooper/master
...@@ -90,6 +90,8 @@ func NewContainerImageBuildCmd() *cobra.Command { ...@@ -90,6 +90,8 @@ func NewContainerImageBuildCmd() *cobra.Command {
NewSaveCmd(), NewSaveCmd(),
) )
disableFlags(ctrImgBuildCmd)
return ctrImgBuildCmd return ctrImgBuildCmd
} }
...@@ -97,7 +99,7 @@ func NewContainerImageBuildCmd() *cobra.Command { ...@@ -97,7 +99,7 @@ func NewContainerImageBuildCmd() *cobra.Command {
func NewBuildCmd() *cobra.Command { func NewBuildCmd() *cobra.Command {
// buildCmd represents the "build" command // buildCmd represents the "build" command
buildCmd := &cobra.Command{ buildCmd := &cobra.Command{
Use: "build", Use: "build [FLAGS] PATH",
Short: "Build container images", Short: "Build container images",
Example: buildExample, Example: buildExample,
RunE: buildCommand, RunE: buildCommand,
......
// Copyright (c) Huawei Technologies Co., Ltd. 2020. All rights reserved. // Copyright (c) Huawei Technologies Co., Ltd. 2020. All rights reserved.
// isula-build licensed under the Mulan PSL v2. // isula-build licensed under the Mulan PSL v2.
// You can use this software according to the terms and conditions of the Mulan PSL v2. // You can use this software according to the terms and conditions of the Mulan PSL v2.
// You may obtain a copy of Mulan PSL v2 at: // You may obtain a copy of Mulan PSL v2 at:
// http://license.coscl.org.cn/MulanPSL2 // http://license.coscl.org.cn/MulanPSL2
// THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR // THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR // IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR
// PURPOSE. // PURPOSE.
// See the Mulan PSL v2 for more details. // See the Mulan PSL v2 for more details.
// Author: Zekun Liu // Author: Zekun Liu
// Create: 2020-07-16 // Create: 2020-07-16
// Description: This file is used for command import // Description: This file is used for command import
package main package main
import ( import (
"bufio" "bufio"
"context" "context"
"fmt" "fmt"
"io" "io"
"os" "os"
dockerref "github.com/containers/image/v5/docker/reference" dockerref "github.com/containers/image/v5/docker/reference"
"github.com/pkg/errors" "github.com/pkg/errors"
"github.com/sirupsen/logrus" "github.com/sirupsen/logrus"
"github.com/spf13/cobra" "github.com/spf13/cobra"
pb "isula.org/isula-build/api/services" pb "isula.org/isula-build/api/services"
"isula.org/isula-build/util" "isula.org/isula-build/util"
) )
const ( const (
bufferSize = 32 * 1024 bufferSize = 32 * 1024
maxTarballSize = 10 * 1024 * 1024 * 1024 // support tarball max size at most 10G maxTarballSize = 10 * 1024 * 1024 * 1024 // support tarball max size at most 10G
importExample = `isula-build ctr-img import file [REPOSITORY[:TAG]]` importExample = `isula-build ctr-img import busybox.tar busybox:isula`
importArgsLen = 1 importArgsLen = 1
) )
type importOptions struct { type importOptions struct {
source string source string
reference string reference string
} }
var importOpts importOptions var importOpts importOptions
// NewImportCmd returns import command // NewImportCmd returns import command
func NewImportCmd() *cobra.Command { func NewImportCmd() *cobra.Command {
importCmd := &cobra.Command{ importCmd := &cobra.Command{
Use: "import", Use: "import FILE [REPOSITORY[:TAG]]",
Short: "Import the base image from a tarball to the image store", Short: "Import the base image from a tarball to the image store",
Example: importExample, Example: importExample,
RunE: importCommand, RunE: importCommand,
} }
return importCmd return importCmd
} }
func importCommand(c *cobra.Command, args []string) error { func importCommand(c *cobra.Command, args []string) error {
if len(args) < importArgsLen { if len(args) < importArgsLen {
return errors.New("requires at least one argument") return errors.New("requires at least one argument")
} }
if err := util.CheckFileSize(args[0], maxTarballSize); err != nil { if err := util.CheckFileSize(args[0], maxTarballSize); err != nil {
return err return err
} }
importOpts.source = args[0] importOpts.source = args[0]
if len(args) > importArgsLen { if len(args) > importArgsLen {
importOpts.reference = args[1] importOpts.reference = args[1]
} }
ctx := context.TODO() ctx := context.TODO()
cli, err := NewClient(ctx) cli, err := NewClient(ctx)
if err != nil { if err != nil {
return err return err
} }
return runImport(ctx, cli) return runImport(ctx, cli)
} }
func runImport(ctx context.Context, cli Cli) error { func runImport(ctx context.Context, cli Cli) error {
if importOpts.reference != "" { if importOpts.reference != "" {
if _, err := dockerref.Parse(importOpts.reference); err != nil { if _, err := dockerref.Parse(importOpts.reference); err != nil {
return err return err
} }
} }
file, err := os.Open(importOpts.source) file, err := os.Open(importOpts.source)
if err != nil { if err != nil {
return err return err
} }
defer func() { defer func() {
if ferr := file.Close(); ferr != nil { if ferr := file.Close(); ferr != nil {
logrus.Warnf("Close file %s failed", importOpts.source) logrus.Warnf("Close file %s failed", importOpts.source)
} }
}() }()
rpcCli, err := cli.Client().Import(ctx) rpcCli, err := cli.Client().Import(ctx)
if err != nil { if err != nil {
return err return err
} }
reader := bufio.NewReader(file) reader := bufio.NewReader(file)
buf := make([]byte, bufferSize, bufferSize) buf := make([]byte, bufferSize, bufferSize)
var length int var length int
for { for {
length, err = reader.Read(buf) length, err = reader.Read(buf)
if err != nil && err != io.EOF { if err != nil && err != io.EOF {
return err return err
} }
if length == 0 { if length == 0 {
break break
} }
if err = rpcCli.Send(&pb.ImportRequest{ if err = rpcCli.Send(&pb.ImportRequest{
Data: buf[0:length], Data: buf[0:length],
Reference: importOpts.reference, Reference: importOpts.reference,
}); err != nil { }); err != nil {
return err return err
} }
} }
resp, err := rpcCli.CloseAndRecv() resp, err := rpcCli.CloseAndRecv()
if err != nil { if err != nil {
return err return err
} }
if resp == nil { if resp == nil {
return errors.New("import failed, got nil response") return errors.New("import failed, got nil response")
} }
fmt.Printf("Import success with image id: %s\n", resp.ImageID) fmt.Printf("Import success with image id: %s\n", resp.ImageID)
return nil return nil
} }
...@@ -38,7 +38,7 @@ var infoOpts infoOptions ...@@ -38,7 +38,7 @@ var infoOpts infoOptions
func NewInfoCmd() *cobra.Command { func NewInfoCmd() *cobra.Command {
// infoCmd represents the "info" command // infoCmd represents the "info" command
infoCmd := &cobra.Command{ infoCmd := &cobra.Command{
Use: "info", Use: "info [FLAGS]",
Short: "Show isula-build system information", Short: "Show isula-build system information",
RunE: infoCommand, RunE: infoCommand,
Args: util.NoArgs, Args: util.NoArgs,
......
...@@ -42,7 +42,7 @@ const ( ...@@ -42,7 +42,7 @@ const (
// NewLoadCmd returns image load command // NewLoadCmd returns image load command
func NewLoadCmd() *cobra.Command { func NewLoadCmd() *cobra.Command {
loadCmd := &cobra.Command{ loadCmd := &cobra.Command{
Use: "load", Use: "load [FLAGS]",
Short: "Load images", Short: "Load images",
Example: loadExample, Example: loadExample,
Args: util.NoArgs, Args: util.NoArgs,
......
...@@ -63,7 +63,7 @@ type passReader func() ([]byte, error) ...@@ -63,7 +63,7 @@ type passReader func() ([]byte, error)
func NewLoginCmd() *cobra.Command { func NewLoginCmd() *cobra.Command {
// loginCmd represents the "login" command // loginCmd represents the "login" command
loginCmd := &cobra.Command{ loginCmd := &cobra.Command{
Use: "login", Use: "login SERVER [FLAGS]",
Short: "Login to an image registry", Short: "Login to an image registry",
Example: loginExample, Example: loginExample,
RunE: loginCommand, RunE: loginCommand,
......
...@@ -40,7 +40,7 @@ var logoutOpts logoutOptions ...@@ -40,7 +40,7 @@ var logoutOpts logoutOptions
func NewLogoutCmd() *cobra.Command { func NewLogoutCmd() *cobra.Command {
// logoutCmd represents the "logout" command // logoutCmd represents the "logout" command
logoutCmd := &cobra.Command{ logoutCmd := &cobra.Command{
Use: "logout", Use: "logout [SERVER] [FLAGS]",
Short: "Logout from an image registry", Short: "Logout from an image registry",
Example: logoutExample, Example: logoutExample,
RunE: logoutCommand, RunE: logoutCommand,
......
...@@ -45,12 +45,14 @@ func newCliCommand() *cobra.Command { ...@@ -45,12 +45,14 @@ func newCliCommand() *cobra.Command {
PersistentPreRunE: func(cmd *cobra.Command, args []string) error { PersistentPreRunE: func(cmd *cobra.Command, args []string) error {
return before(cmd) return before(cmd)
}, },
SilenceUsage: true, SilenceUsage: true,
SilenceErrors: true, SilenceErrors: true,
Version: fmt.Sprintf("%s, build %s", version.Version, version.GitCommit), DisableFlagsInUseLine: true,
Version: fmt.Sprintf("%s, build %s", version.Version, version.GitCommit),
} }
setupRootCmd(rootCmd) setupRootCmd(rootCmd)
addCommands(rootCmd) addCommands(rootCmd)
disableFlags(rootCmd)
return rootCmd return rootCmd
} }
...@@ -117,3 +119,9 @@ var completionCmd = &cobra.Command{ ...@@ -117,3 +119,9 @@ var completionCmd = &cobra.Command{
cmd.Root().GenBashCompletion(os.Stdout) // nolint cmd.Root().GenBashCompletion(os.Stdout) // nolint
}, },
} }
func disableFlags(root *cobra.Command) {
for _, c := range root.Commands() {
c.DisableFlagsInUseLine = true
}
}
...@@ -41,7 +41,7 @@ isula-build ctr-img rm --all` ...@@ -41,7 +41,7 @@ isula-build ctr-img rm --all`
func NewRemoveCmd() *cobra.Command { func NewRemoveCmd() *cobra.Command {
// removeCmd represents the "rm" command // removeCmd represents the "rm" command
removeCmd := &cobra.Command{ removeCmd := &cobra.Command{
Use: "rm", Use: "rm IMAGE [IMAGE...] [FLAGS]",
Short: "Remove one or more locally stored images", Short: "Remove one or more locally stored images",
Example: removeExample, Example: removeExample,
RunE: removeCommand, RunE: removeCommand,
......
...@@ -48,7 +48,7 @@ isula-build ctr-img save 21c3e96ac411 -o myimage.tar` ...@@ -48,7 +48,7 @@ isula-build ctr-img save 21c3e96ac411 -o myimage.tar`
// NewSaveCmd cmd for container image saving // NewSaveCmd cmd for container image saving
func NewSaveCmd() *cobra.Command { func NewSaveCmd() *cobra.Command {
saveCmd := &cobra.Command{ saveCmd := &cobra.Command{
Use: "save", Use: "save IMAGE [FLAGS]",
Short: "Save image to tarball", Short: "Save image to tarball",
Example: saveExample, Example: saveExample,
RunE: saveCommand, RunE: saveCommand,
......
...@@ -23,15 +23,15 @@ import ( ...@@ -23,15 +23,15 @@ import (
) )
const ( const (
tagExample = `isula-build ctr-img tag <imageID> busybox:latest tagExample = `isula-build ctr-img tag a24bb4013296 busybox:latest
isula-build ctr-img tag <imageName> busybox:latest` isula-build ctr-img tag busybox:v1.0 busybox:latest`
) )
// NewTagCmd returns tag command // NewTagCmd returns tag command
func NewTagCmd() *cobra.Command { func NewTagCmd() *cobra.Command {
// tagCmd represents the "tag" command // tagCmd represents the "tag" command
tagCmd := &cobra.Command{ tagCmd := &cobra.Command{
Use: "tag", Use: "tag SOURCE_IMAGE[:TAG] TARGET_IMAGE[:TAG]",
Short: "create a tag for source image", Short: "create a tag for source image",
RunE: tagCommand, RunE: tagCommand,
Example: tagExample, Example: tagExample,
......
...@@ -57,12 +57,19 @@ func (b *Backend) Remove(req *pb.RemoveRequest, stream pb.Control_RemoveServer) ...@@ -57,12 +57,19 @@ func (b *Backend) Remove(req *pb.RemoveRequest, stream pb.Control_RemoveServer)
} }
for _, layer := range layers { for _, layer := range layers {
layerString := fmt.Sprintf("Deleted: sha256:%v", layer) layerString := fmt.Sprintf("Deleted layer: sha256:%v", layer)
logrus.Debug(layerString) logrus.Debug(layerString)
if err = stream.Send(&pb.RemoveResponse{LayerMessage: layerString}); err != nil { if err = stream.Send(&pb.RemoveResponse{LayerMessage: layerString}); err != nil {
return err return err
} }
} }
// after image is deleted successfully, print it out
imageString := fmt.Sprintf("Deleted image: %v", imageID)
logrus.Debug(imageString)
if err = stream.Send(&pb.RemoveResponse{LayerMessage: imageString}); err != nil {
return err
}
} }
return nil return nil
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册