Skip to content

Commit

Permalink
feature: add upgrade interface
Browse files Browse the repository at this point in the history
Signed-off-by: HusterWan <[email protected]>
  • Loading branch information
HusterWan committed Mar 12, 2018
1 parent 78d8e1a commit 60c173d
Show file tree
Hide file tree
Showing 11 changed files with 296 additions and 0 deletions.
21 changes: 21 additions & 0 deletions apis/server/container_bridge.go
Original file line number Diff line number Diff line change
Expand Up @@ -311,3 +311,24 @@ func (s *Server) updateContainer(ctx context.Context, rw http.ResponseWriter, re
rw.WriteHeader(http.StatusOK)
return nil
}

func (s *Server) upgradeContainer(ctx context.Context, rw http.ResponseWriter, req *http.Request) error {
config := &types.ContainerUpgradeConfig{}
// decode request body
if err := json.NewDecoder(req.Body).Decode(config); err != nil {
return httputils.NewHTTPError(err, http.StatusBadRequest)
}
// validate request body
if err := config.Validate(strfmt.NewFormats()); err != nil {
return httputils.NewHTTPError(err, http.StatusBadRequest)
}

name := mux.Vars(req)["name"]

if err := s.ContainerMgr.Upgrade(ctx, name, config); err != nil {
return err
}

rw.WriteHeader(http.StatusOK)
return nil
}
1 change: 1 addition & 0 deletions apis/server/router.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ func initRoute(s *Server) http.Handler {
r.Path(versionMatcher + "/containers/{name:.*}/pause").Methods(http.MethodPost).Handler(s.filter(s.pauseContainer))
r.Path(versionMatcher + "/containers/{name:.*}/unpause").Methods(http.MethodPost).Handler(s.filter(s.unpauseContainer))
r.Path(versionMatcher + "/containers/{name:.*}/update").Methods(http.MethodPost).Handler(s.filter(s.updateContainer))
r.Path(versionMatcher + "/containers/{name:.*}/upgrade").Methods(http.MethodPost).Handler(s.filter(s.upgradeContainer))

// image
r.Path(versionMatcher + "/images/create").Methods(http.MethodPost).Handler(s.filter(s.pullImage))
Expand Down
34 changes: 34 additions & 0 deletions apis/swagger.yml
Original file line number Diff line number Diff line change
Expand Up @@ -696,6 +696,28 @@ paths:
500:
$ref: "#/responses/500ErrorResponse"
tags: ["Container"]
/containers/{id}/upgrade:
post:
summary: "Upgrade a container with new image and args"
operationId: "ContainerUpgrade"
parameters:
- $ref: "#/parameters/id"
- name: "upgradeConfig"
in: "body"
schema:
$ref: "#/definitions/ContainerUpgradeConfig"
responses:
200:
description: "no error"
400:
description: "bad parameter"
schema:
$ref: "#/definitions/Error"
404:
$ref: "#/responses/404ErrorResponse"
500:
$ref: "#/responses/500ErrorResponse"
tags: ["Container"]

/volumes:
get:
Expand Down Expand Up @@ -1365,6 +1387,18 @@ definitions:
additionalProperties:
type: "string"

ContainerUpgradeConfig:
description: |
ContainerUpgradeConfig is used for API "POST /containers/upgrade".
It wraps all kinds of config used in container upgrade.
It can be used to encode client params in client and unmarshal request body in daemon side.
allOf:
- $ref: "#/definitions/ContainerConfig"
- type: "object"
properties:
HostConfig:
$ref: "#/definitions/HostConfig"

Resources:
description: "A container's resources (cgroups config, ulimits, etc)"
type: "object"
Expand Down
104 changes: 104 additions & 0 deletions apis/types/container_upgrade_config.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions cli/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ func main() {
cli.AddCommand(base, &LoginCommand{})
cli.AddCommand(base, &UpdateCommand{})
cli.AddCommand(base, &LogoutCommand{})
cli.AddCommand(base, &UpgradeCommand{})

// add generate doc command
cli.AddCommand(base, &GenDocCommand{})
Expand Down
70 changes: 70 additions & 0 deletions cli/upgrade.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
package main

import (
"context"
"fmt"

"github.com/spf13/cobra"
)

// upgradeDescription is used to describe upgrade command in detail and auto generate command doc.
var upgradeDescription = ""

// UpgradeCommand use to implement 'upgrade' command, it is used to upgrade a container.
type UpgradeCommand struct {
baseCommand
*container
}

// Init initialize upgrade command.
func (ug *UpgradeCommand) Init(c *Cli) {
ug.cli = c
ug.cmd = &cobra.Command{
Use: "upgrade [OPTIONS] IMAGE [COMMAND] [ARG...]",
Short: "Upgrade a container with new image and args",
Long: upgradeDescription,
Args: cobra.MinimumNArgs(1),
RunE: func(cmd *cobra.Command, args []string) error {
return ug.runUpgrade(args)
},
Example: upgradeExample(),
}
ug.addFlags()
}

// addFlags adds flags for specific command.
func (ug *UpgradeCommand) addFlags() {
flagSet := ug.cmd.Flags()
flagSet.SetInterspersed(false)

c := addCommonFlags(flagSet)
ug.container = c
}

// runUpgrade is the entry of UpgradeCommand command.
func (ug *UpgradeCommand) runUpgrade(args []string) error {
config, err := ug.config()
if err != nil {
return fmt.Errorf("failed to upgrade container: %v", err)
}

config.Image = args[0]
if len(args) > 1 {
config.Cmd = args[1:]
}
containerName := ug.name
if containerName == "" {
return fmt.Errorf("failed to upgrade container: must specify container name")
}

ctx := context.Background()
apiClient := ug.cli.Client()

// TODO if error is image not found, we can pull image, and retry upgrade
return apiClient.ContainerUpgrade(ctx, containerName, config.ContainerConfig, config.HostConfig)
}

//upgradeExample shows examples in exec command, and is used in auto-generated cli docs.
func upgradeExample() string {
return ""
}
5 changes: 5 additions & 0 deletions client/container.go
Original file line number Diff line number Diff line change
Expand Up @@ -181,3 +181,8 @@ func (client *APIClient) ContainerUpdate(ctx context.Context, name string, confi
return err

}

// ContainerUpgrade upgrade a container with new image and args.
func (client *APIClient) ContainerUpgrade(ctx context.Context, name string, config types.ContainerConfig, hostConfig *types.HostConfig) error {
return nil
}
1 change: 1 addition & 0 deletions client/interface.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ type ContainerAPIClient interface {
ContainerPause(ctx context.Context, name string) error
ContainerUnpause(ctx context.Context, name string) error
ContainerUpdate(ctx context.Context, name string, config *types.UpdateConfig) error
ContainerUpgrade(ctx context.Context, name string, config types.ContainerConfig, hostConfig *types.HostConfig) error
}

// ImageAPIClient defines methods of Image client.
Expand Down
9 changes: 9 additions & 0 deletions daemon/mgr/container.go
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,9 @@ type ContainerMgr interface {

// Update updates the configurations of a container.
Update(ctx context.Context, name string, config *types.UpdateConfig) error

// Upgrade upgrades a container with new image and args.
Upgrade(ctx context.Context, name string, config *types.ContainerUpgradeConfig) error
}

// ContainerManager is the default implement of interface ContainerMgr.
Expand Down Expand Up @@ -788,6 +791,12 @@ func (mgr *ContainerManager) Update(ctx context.Context, name string, config *ty
return nil
}

// Upgrade upgrades a container with new image and args.
func (mgr *ContainerManager) Upgrade(ctx context.Context, name string, config *types.ContainerUpgradeConfig) error {
// TODO
return nil
}

func (mgr *ContainerManager) openContainerIO(id string, attach *AttachConfig) (*containerio.IO, error) {
return mgr.openIO(id, attach, false)
}
Expand Down
19 changes: 19 additions & 0 deletions test/api_container_upgrade_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package main

import (
"github.com/alibaba/pouch/test/environment"

"github.com/go-check/check"
)

// APIContainerUpgradeSuite is the test suite for container upgrade API.
type APIContainerUpgradeSuite struct{}

func init() {
check.Suite(&APIContainerUpgradeSuite{})
}

// SetUpTest does common setup in the beginning of each test.
func (suite *APIContainerUpgradeSuite) SetUpTest(c *check.C) {
SkipIfFalse(c, environment.IsLinux)
}
31 changes: 31 additions & 0 deletions test/cli_upgrade_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package main

import (
//"github.com/alibaba/pouch/apis/types"
"github.com/alibaba/pouch/test/command"
"github.com/alibaba/pouch/test/environment"

"github.com/go-check/check"
"github.com/gotestyourself/gotestyourself/icmd"
)

// PouchUpgradeSuite is the test suite for upgrade CLI.
type PouchUpgradeSuite struct{}

func init() {
check.Suite(&PouchUpgradeSuite{})
}

// SetUpSuite does common setup in the beginning of each test suite.
func (suite *PouchUpgradeSuite) SetUpSuite(c *check.C) {
SkipIfFalse(c, environment.IsLinux)

environment.PruneAllContainers(apiClient)

command.PouchRun("pull", busyboxImage).Assert(c, icmd.Success)
}

// TearDownTest does cleanup work in the end of each test.
func (suite *PouchUpgradeSuite) TeadDownTest(c *check.C) {
// TODO
}

0 comments on commit 60c173d

Please sign in to comment.