Skip to content

Commit

Permalink
refactor: refactor container update diskquota type
Browse files Browse the repository at this point in the history
refactor container update diskquota type, change it from `string` to
`map[string]string`, make it consistent with container create api.

Signed-off-by: Rudy Zhang <rudyflyzhang@gmail.com>
  • Loading branch information
rudyfly committed Jun 21, 2018
1 parent a9777c7 commit 079e680
Show file tree
Hide file tree
Showing 7 changed files with 90 additions and 24 deletions.
4 changes: 4 additions & 0 deletions apis/plugins/ContainerPlugin.go
Expand Up @@ -16,4 +16,8 @@ type ContainerPlugin interface {
// and if this endpoint should enable resolver and a map which will be used as generic params to create endpoints of
// this container
PreCreateEndpoint(string, []string) (priority int, disableResolver bool, genericParam map[string]interface{})

// PreUpdate defines plugin point where receives an container update request, in this plugin point user
// could change the container update body passed-in by http request body
PreUpdate(io.ReadCloser) (io.ReadCloser, error)
}
13 changes: 12 additions & 1 deletion apis/server/container_bridge.go
Expand Up @@ -266,8 +266,19 @@ func (s *Server) attachContainer(ctx context.Context, rw http.ResponseWriter, re

func (s *Server) updateContainer(ctx context.Context, rw http.ResponseWriter, req *http.Request) error {
config := &types.UpdateConfig{}

// set pre update hook plugin
reader := req.Body
if s.ContainerPlugin != nil {
var err error
logrus.Infof("invoke container pre-update hook in plugin")
if reader, err = s.ContainerPlugin.PreUpdate(req.Body); err != nil {
return errors.Wrapf(err, "failed to execute pre-create plugin point")
}
}

// decode request body
if err := json.NewDecoder(req.Body).Decode(config); err != nil {
if err := json.NewDecoder(reader).Decode(config); err != nil {
return httputils.NewHTTPError(err, http.StatusBadRequest)
}
// validate request body
Expand Down
5 changes: 4 additions & 1 deletion apis/swagger.yml
Expand Up @@ -2201,8 +2201,11 @@ definitions:
items:
type: "string"
DiskQuota:
type: "string"
type: "object"
description: "update disk quota for container"
x-nullable: true
additionalProperties:
type: "string"

ContainerUpgradeConfig:
description: |
Expand Down
6 changes: 3 additions & 3 deletions apis/types/update_config.go

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

10 changes: 7 additions & 3 deletions cli/update.go
Expand Up @@ -18,7 +18,6 @@ type UpdateCommand struct {
baseCommand
container
image string
quota string
}

// Init initialize update command.
Expand Down Expand Up @@ -52,7 +51,7 @@ func (uc *UpdateCommand) addFlags() {
flagSet.StringSliceVarP(&uc.env, "env", "e", nil, "Set environment variables for container")
flagSet.StringSliceVarP(&uc.labels, "label", "l", nil, "Set label for container")
flagSet.StringVar(&uc.restartPolicy, "restart", "", "Restart policy to apply when container exits")
flagSet.StringVar(&uc.quota, "quota", "", "Update disk quota for container")
flagSet.StringSliceVar(&uc.diskQuota, "disk-quota", nil, "Update disk quota for container")
}

// updateRun is the entry of update command.
Expand Down Expand Up @@ -86,12 +85,17 @@ func (uc *UpdateCommand) updateRun(args []string) error {
return err
}

diskQuota, err := opts.ParseDiskQuota(uc.diskQuota)
if err != nil {
return err
}

updateConfig := &types.UpdateConfig{
Env: uc.env,
Label: uc.labels,
RestartPolicy: restartPolicy,
Resources: resource,
DiskQuota: uc.quota,
DiskQuota: diskQuota,
}

apiClient := uc.cli.Client()
Expand Down
33 changes: 17 additions & 16 deletions daemon/mgr/container.go
Expand Up @@ -878,6 +878,11 @@ func (mgr *ContainerManager) Update(ctx context.Context, name string, config *ty
return fmt.Errorf("failed to update container %s: can not update kernel memory to a running container, please stop it first", c.ID)
}

// update container disk quota
if err := mgr.updateContainerDiskQuota(ctx, c, config.DiskQuota); err != nil {
return errors.Wrapf(err, "failed to update diskquota of container %s", c.ID)
}

c.Lock()

// init Container Labels
Expand Down Expand Up @@ -906,19 +911,18 @@ func (mgr *ContainerManager) Update(ctx context.Context, name string, config *ty
// TODO(ziren): we should use meta.Config.DiskQuota to record container diskquota
// compatibility with alidocker, when set DiskQuota for container
// add a DiskQuota label
if config.DiskQuota != "" {
if config.DiskQuota != nil {
if _, ok := c.Config.Labels["DiskQuota"]; ok {
c.Config.Labels["DiskQuota"] = config.DiskQuota
labels := []string{}
for dir, quota := range c.Config.DiskQuota {
labels = append(labels, fmt.Sprintf("%s=%s", dir, quota))
}
c.Config.Labels["DiskQuota"] = strings.Join(labels, ";")
}
}

c.Unlock()

// update container disk quota
if err := mgr.updateContainerDiskQuota(ctx, c, config.DiskQuota); err != nil {
return errors.Wrapf(err, "failed to update diskquota of container %s", c.ID)
}

// update Resources of a container.
if err := mgr.updateContainerResources(c, config.Resources); err != nil {
restore = true
Expand Down Expand Up @@ -1052,18 +1056,15 @@ func (mgr *ContainerManager) Remove(ctx context.Context, name string, options *t
return nil
}

func (mgr *ContainerManager) updateContainerDiskQuota(ctx context.Context, c *Container, diskQuota string) error {
if diskQuota == "" {
func (mgr *ContainerManager) updateContainerDiskQuota(ctx context.Context, c *Container, diskQuota map[string]string) error {
if diskQuota == nil {
return nil
}

quotaMap, err := opts.ParseDiskQuota([]string{diskQuota})
if err != nil {
return errors.Wrapf(err, "failed to parse disk quota")
}

c.Lock()
c.Config.DiskQuota = quotaMap
for dir, quota := range diskQuota {
c.Config.DiskQuota[dir] = quota
}
c.Unlock()

// set mount point disk quota
Expand Down Expand Up @@ -1094,7 +1095,7 @@ func (mgr *ContainerManager) updateContainerDiskQuota(ctx context.Context, c *Co
c.Unlock()

// get rootfs quota
defaultQuota := quota.GetDefaultQuota(quotaMap)
defaultQuota := quota.GetDefaultQuota(c.Config.DiskQuota)
if qid > 0 && defaultQuota == "" {
return fmt.Errorf("set quota id but have no set default quota size")
}
Expand Down
43 changes: 43 additions & 0 deletions test/cli_update_test.go
Expand Up @@ -392,3 +392,46 @@ func (suite *PouchUpdateSuite) TestUpdateContainerDeleteEnv(c *check.C) {
c.Errorf("foo=bar env should be deleted from container's env")
}
}

// TestUpdateContainerDiskQuota is to verify the correctness of delete env by update interface
func (suite *PouchUpdateSuite) TestUpdateContainerDiskQuota(c *check.C) {
if !environment.IsDiskQuota() {
c.Skip("Host does not support disk quota")
}

// create container with disk quota
name := "update-container-diskquota"
command.PouchRun("run", "-d", "--disk-quota", "/=2000m", "--name", name, busyboxImage, "top").Assert(c, icmd.Success)
defer DelContainerForceMultyTime(c, name)

ret := command.PouchRun("exec", name, "df")
//ret.Assert(c, icmd.Success)
out := ret.Combined()

found := false
for _, line := range strings.Split(out, "\n") {
if strings.Contains(line, "/") &&
strings.Contains(line, "2048000") {
found = true
break
}
}
c.Assert(found, check.Equals, true)

// update diskquota
command.PouchRun("update", "--disk-quota", "/=1000m", name).Assert(c, icmd.Success)

ret = command.PouchRun("exec", name, "df")
//ret.Assert(c, icmd.Success)
out = ret.Combined()

found = false
for _, line := range strings.Split(out, "\n") {
if strings.Contains(line, "/") &&
strings.Contains(line, "1024000") {
found = true
break
}
}
c.Assert(found, check.Equals, true)
}

0 comments on commit 079e680

Please sign in to comment.