Update proxy config if present

If the system has a containerd-proxy managing the lifecycle
of the daemon, make sure the config is updated with the new image
on update.

Signed-off-by: Daniel Hiltgen <daniel.hiltgen@docker.com>
This commit is contained in:
Daniel Hiltgen 2018-08-28 10:10:30 -07:00
parent e25e9d68be
commit f96ddaedf7
3 changed files with 142 additions and 0 deletions

View File

@ -0,0 +1,66 @@
package containerized
import (
"encoding/json"
"io/ioutil"
"os"
"path/filepath"
)
var (
proxydir = "/etc/containerd-proxy"
)
type proxyConfig struct {
ID string `json:"-"`
Namespace string `json:"namespace"`
Image string `json:"image"`
ImagePath string `json:"imagePath"`
Args []string `json:"args"`
Scope string `json:"scope"`
}
func updateConfig(name, newImage string) error {
cfg, err := loadConfig(name)
if err != nil && os.IsNotExist(err) {
return nil
}
if err != nil {
return err
}
cfg.Image = newImage
cfg.ImagePath = ""
return storeConfig(name, cfg)
}
func loadConfig(name string) (*proxyConfig, error) {
configFile := filepath.Join(proxydir, name+".json")
data, err := ioutil.ReadFile(configFile)
if err != nil {
return nil, err
}
var cfg proxyConfig
err = json.Unmarshal(data, &cfg)
if err != nil {
return nil, err
}
return &cfg, nil
}
// storeConfig will write out the config only if it already exists
func storeConfig(name string, cfg *proxyConfig) error {
configFile := filepath.Join(proxydir, name+".json")
fd, err := os.OpenFile(configFile, os.O_RDWR, 0644)
if err != nil && os.IsNotExist(err) {
return nil
}
if err != nil {
return err
}
err = fd.Truncate(0)
if err != nil {
return err
}
enc := json.NewEncoder(fd)
return enc.Encode(cfg)
}

View File

@ -0,0 +1,68 @@
package containerized
import (
"encoding/json"
"io/ioutil"
"os"
"path/filepath"
"testing"
"gotest.tools/assert"
)
func TestUpdateConfigNotExist(t *testing.T) {
tmpdir, err := ioutil.TempDir("", "cfg-update")
assert.NilError(t, err)
defer os.RemoveAll(tmpdir)
origProxyDir := proxydir
defer func() {
proxydir = origProxyDir
}()
proxydir = tmpdir
name := "myname"
newImage := "newimage:foo"
err = updateConfig(name, newImage)
assert.NilError(t, err)
}
func TestUpdateConfigBadJson(t *testing.T) {
tmpdir, err := ioutil.TempDir("", "cfg-update")
assert.NilError(t, err)
defer os.RemoveAll(tmpdir)
origProxyDir := proxydir
defer func() {
proxydir = origProxyDir
}()
proxydir = tmpdir
filename := filepath.Join(tmpdir, "dockerd.json")
err = ioutil.WriteFile(filename, []byte("not json"), 0644)
assert.NilError(t, err)
name := "dockerd"
newImage := "newimage:foo"
err = updateConfig(name, newImage)
assert.ErrorContains(t, err, "invalid character")
}
func TestUpdateConfigHappyPath(t *testing.T) {
tmpdir, err := ioutil.TempDir("", "cfg-update")
assert.NilError(t, err)
defer os.RemoveAll(tmpdir)
origProxyDir := proxydir
defer func() {
proxydir = origProxyDir
}()
proxydir = tmpdir
filename := filepath.Join(tmpdir, "dockerd.json")
err = ioutil.WriteFile(filename, []byte("{}"), 0644)
assert.NilError(t, err)
name := "dockerd"
newImage := "newimage:foo"
err = updateConfig(name, newImage)
assert.NilError(t, err)
data, err := ioutil.ReadFile(filename)
assert.NilError(t, err)
var cfg map[string]string
err = json.Unmarshal(data, &cfg)
assert.NilError(t, err)
assert.Assert(t, cfg["image"] == newImage)
}

View File

@ -50,6 +50,10 @@ func WithUpgrade(i containerd.Image) containerd.UpdateContainerOpts {
return err return err
} }
c.Image = i.Name() c.Image = i.Name()
err = updateConfig(c.ID, c.Image)
if err != nil {
return err
}
c.SnapshotKey = revision.Key c.SnapshotKey = revision.Key
return nil return nil
} }
@ -74,6 +78,10 @@ func WithRollback(ctx context.Context, client *containerd.Client, c *containers.
return fmt.Errorf("snapshot %s has an empty service image label", prev.Key) return fmt.Errorf("snapshot %s has an empty service image label", prev.Key)
} }
c.Image = snapshotImage c.Image = snapshotImage
err = updateConfig(c.ID, c.Image)
if err != nil {
return err
}
c.SnapshotKey = prev.Key c.SnapshotKey = prev.Key
return nil return nil
} }