mirror of https://github.com/docker/cli.git
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:
parent
e25e9d68be
commit
f96ddaedf7
|
@ -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)
|
||||||
|
}
|
|
@ -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)
|
||||||
|
}
|
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue