зеркало из https://github.com/microsoft/docker.git
Remove engine usage for events
Signed-off-by: Alexander Morozov <lk4d4@docker.com>
This commit is contained in:
Родитель
868f56e083
Коммит
c9eb37f975
|
@ -3,6 +3,7 @@ package server
|
||||||
import (
|
import (
|
||||||
"bufio"
|
"bufio"
|
||||||
"bytes"
|
"bytes"
|
||||||
|
"time"
|
||||||
|
|
||||||
"encoding/base64"
|
"encoding/base64"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
|
@ -23,7 +24,9 @@ import (
|
||||||
"github.com/docker/docker/daemon"
|
"github.com/docker/docker/daemon"
|
||||||
"github.com/docker/docker/daemon/networkdriver/bridge"
|
"github.com/docker/docker/daemon/networkdriver/bridge"
|
||||||
"github.com/docker/docker/engine"
|
"github.com/docker/docker/engine"
|
||||||
|
"github.com/docker/docker/pkg/jsonmessage"
|
||||||
"github.com/docker/docker/pkg/parsers"
|
"github.com/docker/docker/pkg/parsers"
|
||||||
|
"github.com/docker/docker/pkg/parsers/filters"
|
||||||
"github.com/docker/docker/pkg/stdcopy"
|
"github.com/docker/docker/pkg/stdcopy"
|
||||||
"github.com/docker/docker/pkg/streamformatter"
|
"github.com/docker/docker/pkg/streamformatter"
|
||||||
"github.com/docker/docker/pkg/version"
|
"github.com/docker/docker/pkg/version"
|
||||||
|
@ -324,13 +327,104 @@ func getEvents(eng *engine.Engine, version version.Version, w http.ResponseWrite
|
||||||
if err := parseForm(r); err != nil {
|
if err := parseForm(r); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
var since int64 = -1
|
||||||
|
if r.Form.Get("since") != "" {
|
||||||
|
s, err := strconv.ParseInt(r.Form.Get("since"), 10, 64)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
since = s
|
||||||
|
}
|
||||||
|
|
||||||
var job = eng.Job("events")
|
var until int64 = -1
|
||||||
streamJSON(job, w, true)
|
if r.Form.Get("until") != "" {
|
||||||
job.Setenv("since", r.Form.Get("since"))
|
u, err := strconv.ParseInt(r.Form.Get("until"), 10, 64)
|
||||||
job.Setenv("until", r.Form.Get("until"))
|
if err != nil {
|
||||||
job.Setenv("filters", r.Form.Get("filters"))
|
return err
|
||||||
return job.Run()
|
}
|
||||||
|
until = u
|
||||||
|
}
|
||||||
|
timer := time.NewTimer(0)
|
||||||
|
timer.Stop()
|
||||||
|
if until > 0 {
|
||||||
|
dur := time.Unix(until, 0).Sub(time.Now())
|
||||||
|
timer = time.NewTimer(dur)
|
||||||
|
}
|
||||||
|
|
||||||
|
ef, err := filters.FromParam(r.Form.Get("filters"))
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
isFiltered := func(field string, filter []string) bool {
|
||||||
|
if len(filter) == 0 {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
for _, v := range filter {
|
||||||
|
if v == field {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
if strings.Contains(field, ":") {
|
||||||
|
image := strings.Split(field, ":")
|
||||||
|
if image[0] == v {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
d := getDaemon(eng)
|
||||||
|
es := d.EventsService
|
||||||
|
w.Header().Set("Content-Type", "application/json")
|
||||||
|
enc := json.NewEncoder(utils.NewWriteFlusher(w))
|
||||||
|
|
||||||
|
getContainerId := func(cn string) string {
|
||||||
|
c, err := d.Get(cn)
|
||||||
|
if err != nil {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
return c.ID
|
||||||
|
}
|
||||||
|
|
||||||
|
sendEvent := func(ev *jsonmessage.JSONMessage) error {
|
||||||
|
//incoming container filter can be name,id or partial id, convert and replace as a full container id
|
||||||
|
for i, cn := range ef["container"] {
|
||||||
|
ef["container"][i] = getContainerId(cn)
|
||||||
|
}
|
||||||
|
|
||||||
|
if isFiltered(ev.Status, ef["event"]) || isFiltered(ev.From, ef["image"]) ||
|
||||||
|
isFiltered(ev.ID, ef["container"]) {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return enc.Encode(ev)
|
||||||
|
}
|
||||||
|
|
||||||
|
current, l := es.Subscribe()
|
||||||
|
defer es.Evict(l)
|
||||||
|
for _, ev := range current {
|
||||||
|
if ev.Time < since {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if err := sendEvent(ev); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for {
|
||||||
|
select {
|
||||||
|
case ev := <-l:
|
||||||
|
jev, ok := ev.(*jsonmessage.JSONMessage)
|
||||||
|
if !ok {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if err := sendEvent(jev); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
case <-timer.C:
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func getImagesHistory(eng *engine.Engine, version version.Version, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
|
func getImagesHistory(eng *engine.Engine, version version.Version, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
|
||||||
|
|
|
@ -250,47 +250,6 @@ func TestGetContainersByName(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestGetEvents(t *testing.T) {
|
|
||||||
eng := engine.New()
|
|
||||||
var called bool
|
|
||||||
eng.Register("events", func(job *engine.Job) error {
|
|
||||||
called = true
|
|
||||||
since := job.Getenv("since")
|
|
||||||
if since != "1" {
|
|
||||||
t.Fatalf("'since' should be 1, found %#v instead", since)
|
|
||||||
}
|
|
||||||
until := job.Getenv("until")
|
|
||||||
if until != "0" {
|
|
||||||
t.Fatalf("'until' should be 0, found %#v instead", until)
|
|
||||||
}
|
|
||||||
v := &engine.Env{}
|
|
||||||
v.Set("since", since)
|
|
||||||
v.Set("until", until)
|
|
||||||
if _, err := v.WriteTo(job.Stdout); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
})
|
|
||||||
r := serveRequest("GET", "/events?since=1&until=0", nil, eng, t)
|
|
||||||
if !called {
|
|
||||||
t.Fatal("handler was not called")
|
|
||||||
}
|
|
||||||
assertContentType(r, "application/json", t)
|
|
||||||
var stdoutJSON struct {
|
|
||||||
Since int
|
|
||||||
Until int
|
|
||||||
}
|
|
||||||
if err := json.Unmarshal(r.Body.Bytes(), &stdoutJSON); err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
if stdoutJSON.Since != 1 {
|
|
||||||
t.Errorf("since != 1: %#v", stdoutJSON.Since)
|
|
||||||
}
|
|
||||||
if stdoutJSON.Until != 0 {
|
|
||||||
t.Errorf("until != 0: %#v", stdoutJSON.Until)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestLogs(t *testing.T) {
|
func TestLogs(t *testing.T) {
|
||||||
eng := engine.New()
|
eng := engine.New()
|
||||||
var inspect bool
|
var inspect bool
|
||||||
|
|
|
@ -8,7 +8,6 @@ import (
|
||||||
"github.com/docker/docker/autogen/dockerversion"
|
"github.com/docker/docker/autogen/dockerversion"
|
||||||
"github.com/docker/docker/daemon/networkdriver/bridge"
|
"github.com/docker/docker/daemon/networkdriver/bridge"
|
||||||
"github.com/docker/docker/engine"
|
"github.com/docker/docker/engine"
|
||||||
"github.com/docker/docker/events"
|
|
||||||
"github.com/docker/docker/pkg/parsers/kernel"
|
"github.com/docker/docker/pkg/parsers/kernel"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -19,9 +18,6 @@ func Register(eng *engine.Engine) error {
|
||||||
if err := remote(eng); err != nil {
|
if err := remote(eng); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if err := events.New().Install(eng); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
if err := eng.Register("version", dockerVersion); err != nil {
|
if err := eng.Register("version", dockerVersion); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
|
@ -200,9 +200,11 @@ func (container *Container) WriteHostConfig() error {
|
||||||
|
|
||||||
func (container *Container) LogEvent(action string) {
|
func (container *Container) LogEvent(action string) {
|
||||||
d := container.daemon
|
d := container.daemon
|
||||||
if err := d.eng.Job("log", action, container.ID, d.Repositories().ImageName(container.ImageID)).Run(); err != nil {
|
d.EventsService.Log(
|
||||||
logrus.Errorf("Error logging event %s for %s: %s", action, container.ID, err)
|
action,
|
||||||
}
|
container.ID,
|
||||||
|
d.Repositories().ImageName(container.ImageID),
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (container *Container) getResourcePath(path string) (string, error) {
|
func (container *Container) getResourcePath(path string) (string, error) {
|
||||||
|
|
|
@ -19,6 +19,7 @@ import (
|
||||||
"github.com/Sirupsen/logrus"
|
"github.com/Sirupsen/logrus"
|
||||||
"github.com/docker/docker/api"
|
"github.com/docker/docker/api"
|
||||||
"github.com/docker/docker/autogen/dockerversion"
|
"github.com/docker/docker/autogen/dockerversion"
|
||||||
|
"github.com/docker/docker/daemon/events"
|
||||||
"github.com/docker/docker/daemon/execdriver"
|
"github.com/docker/docker/daemon/execdriver"
|
||||||
"github.com/docker/docker/daemon/execdriver/execdrivers"
|
"github.com/docker/docker/daemon/execdriver/execdrivers"
|
||||||
"github.com/docker/docker/daemon/execdriver/lxc"
|
"github.com/docker/docker/daemon/execdriver/lxc"
|
||||||
|
@ -109,6 +110,7 @@ type Daemon struct {
|
||||||
statsCollector *statsCollector
|
statsCollector *statsCollector
|
||||||
defaultLogConfig runconfig.LogConfig
|
defaultLogConfig runconfig.LogConfig
|
||||||
RegistryService *registry.Service
|
RegistryService *registry.Service
|
||||||
|
EventsService *events.Events
|
||||||
}
|
}
|
||||||
|
|
||||||
// Install installs daemon capabilities to eng.
|
// Install installs daemon capabilities to eng.
|
||||||
|
@ -932,8 +934,9 @@ func NewDaemonFromDirectory(config *Config, eng *engine.Engine, registryService
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
eventsService := events.New()
|
||||||
logrus.Debug("Creating repository list")
|
logrus.Debug("Creating repository list")
|
||||||
repositories, err := graph.NewTagStore(path.Join(config.Root, "repositories-"+driver.String()), g, trustKey, registryService)
|
repositories, err := graph.NewTagStore(path.Join(config.Root, "repositories-"+driver.String()), g, trustKey, registryService, eventsService)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("Couldn't create Tag store: %s", err)
|
return nil, fmt.Errorf("Couldn't create Tag store: %s", err)
|
||||||
}
|
}
|
||||||
|
@ -1025,6 +1028,7 @@ func NewDaemonFromDirectory(config *Config, eng *engine.Engine, registryService
|
||||||
statsCollector: newStatsCollector(1 * time.Second),
|
statsCollector: newStatsCollector(1 * time.Second),
|
||||||
defaultLogConfig: config.LogConfig,
|
defaultLogConfig: config.LogConfig,
|
||||||
RegistryService: registryService,
|
RegistryService: registryService,
|
||||||
|
EventsService: eventsService,
|
||||||
}
|
}
|
||||||
|
|
||||||
eng.OnShutdown(func() {
|
eng.OnShutdown(func() {
|
||||||
|
|
|
@ -108,7 +108,7 @@ func (daemon *Daemon) DeleteImage(eng *engine.Engine, name string, list *[]types
|
||||||
*list = append(*list, types.ImageDelete{
|
*list = append(*list, types.ImageDelete{
|
||||||
Untagged: utils.ImageReference(repoName, tag),
|
Untagged: utils.ImageReference(repoName, tag),
|
||||||
})
|
})
|
||||||
eng.Job("log", "untag", img.ID, "").Run()
|
daemon.EventsService.Log("untag", img.ID, "")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
tags = daemon.Repositories().ByID()[img.ID]
|
tags = daemon.Repositories().ByID()[img.ID]
|
||||||
|
@ -123,6 +123,7 @@ func (daemon *Daemon) DeleteImage(eng *engine.Engine, name string, list *[]types
|
||||||
*list = append(*list, types.ImageDelete{
|
*list = append(*list, types.ImageDelete{
|
||||||
Deleted: img.ID,
|
Deleted: img.ID,
|
||||||
})
|
})
|
||||||
|
daemon.EventsService.Log("delete", img.ID, "")
|
||||||
eng.Job("log", "delete", img.ID, "").Run()
|
eng.Job("log", "delete", img.ID, "").Run()
|
||||||
if img.Parent != "" && !noprune {
|
if img.Parent != "" && !noprune {
|
||||||
err := daemon.DeleteImage(eng, img.Parent, list, false, force, noprune)
|
err := daemon.DeleteImage(eng, img.Parent, list, false, force, noprune)
|
||||||
|
|
|
@ -51,11 +51,6 @@ func (daemon *Daemon) CmdInfo(job *engine.Job) error {
|
||||||
initPath = daemon.SystemInitPath()
|
initPath = daemon.SystemInitPath()
|
||||||
}
|
}
|
||||||
|
|
||||||
cjob := job.Eng.Job("subscribers_count")
|
|
||||||
env, _ := cjob.Stdout.AddEnv()
|
|
||||||
if err := cjob.Run(); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
v := &engine.Env{}
|
v := &engine.Env{}
|
||||||
v.SetJson("ID", daemon.ID)
|
v.SetJson("ID", daemon.ID)
|
||||||
v.SetInt("Containers", len(daemon.List()))
|
v.SetInt("Containers", len(daemon.List()))
|
||||||
|
@ -71,7 +66,7 @@ func (daemon *Daemon) CmdInfo(job *engine.Job) error {
|
||||||
v.Set("SystemTime", time.Now().Format(time.RFC3339Nano))
|
v.Set("SystemTime", time.Now().Format(time.RFC3339Nano))
|
||||||
v.Set("ExecutionDriver", daemon.ExecutionDriver().Name())
|
v.Set("ExecutionDriver", daemon.ExecutionDriver().Name())
|
||||||
v.Set("LoggingDriver", daemon.defaultLogConfig.Type)
|
v.Set("LoggingDriver", daemon.defaultLogConfig.Type)
|
||||||
v.SetInt("NEventsListener", env.GetInt("count"))
|
v.SetInt("NEventsListener", daemon.EventsService.SubscribersCount())
|
||||||
v.Set("KernelVersion", kernelVersion)
|
v.Set("KernelVersion", kernelVersion)
|
||||||
v.Set("OperatingSystem", operatingSystem)
|
v.Set("OperatingSystem", operatingSystem)
|
||||||
v.Set("IndexServerAddress", registry.IndexServerAddress())
|
v.Set("IndexServerAddress", registry.IndexServerAddress())
|
||||||
|
|
|
@ -7,7 +7,6 @@ import (
|
||||||
"net/http"
|
"net/http"
|
||||||
"net/url"
|
"net/url"
|
||||||
|
|
||||||
"github.com/Sirupsen/logrus"
|
|
||||||
"github.com/docker/docker/engine"
|
"github.com/docker/docker/engine"
|
||||||
"github.com/docker/docker/pkg/archive"
|
"github.com/docker/docker/pkg/archive"
|
||||||
"github.com/docker/docker/pkg/progressreader"
|
"github.com/docker/docker/pkg/progressreader"
|
||||||
|
@ -92,8 +91,7 @@ func (s *TagStore) CmdImport(job *engine.Job) error {
|
||||||
if tag != "" {
|
if tag != "" {
|
||||||
logID = utils.ImageReference(logID, tag)
|
logID = utils.ImageReference(logID, tag)
|
||||||
}
|
}
|
||||||
if err = job.Eng.Job("log", "import", logID, "").Run(); err != nil {
|
|
||||||
logrus.Errorf("Error logging event 'import' for %s: %s", logID, err)
|
s.eventsService.Log("import", logID, "")
|
||||||
}
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -85,9 +85,7 @@ func (s *TagStore) CmdPull(job *engine.Job) error {
|
||||||
|
|
||||||
logrus.Debugf("pulling v2 repository with local name %q", repoInfo.LocalName)
|
logrus.Debugf("pulling v2 repository with local name %q", repoInfo.LocalName)
|
||||||
if err := s.pullV2Repository(job.Eng, r, job.Stdout, repoInfo, tag, sf, job.GetenvBool("parallel")); err == nil {
|
if err := s.pullV2Repository(job.Eng, r, job.Stdout, repoInfo, tag, sf, job.GetenvBool("parallel")); err == nil {
|
||||||
if err = job.Eng.Job("log", "pull", logName, "").Run(); err != nil {
|
s.eventsService.Log("pull", logName, "")
|
||||||
logrus.Errorf("Error logging event 'pull' for %s: %s", logName, err)
|
|
||||||
}
|
|
||||||
return nil
|
return nil
|
||||||
} else if err != registry.ErrDoesNotExist && err != ErrV2RegistryUnavailable {
|
} else if err != registry.ErrDoesNotExist && err != ErrV2RegistryUnavailable {
|
||||||
logrus.Errorf("Error from V2 registry: %s", err)
|
logrus.Errorf("Error from V2 registry: %s", err)
|
||||||
|
@ -101,9 +99,7 @@ func (s *TagStore) CmdPull(job *engine.Job) error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if err = job.Eng.Job("log", "pull", logName, "").Run(); err != nil {
|
s.eventsService.Log("pull", logName, "")
|
||||||
logrus.Errorf("Error logging event 'pull' for %s: %s", logName, err)
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,6 +13,7 @@ import (
|
||||||
"strings"
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
|
|
||||||
|
"github.com/docker/docker/daemon/events"
|
||||||
"github.com/docker/docker/image"
|
"github.com/docker/docker/image"
|
||||||
"github.com/docker/docker/pkg/parsers"
|
"github.com/docker/docker/pkg/parsers"
|
||||||
"github.com/docker/docker/pkg/stringid"
|
"github.com/docker/docker/pkg/stringid"
|
||||||
|
@ -40,6 +41,7 @@ type TagStore struct {
|
||||||
pullingPool map[string]chan struct{}
|
pullingPool map[string]chan struct{}
|
||||||
pushingPool map[string]chan struct{}
|
pushingPool map[string]chan struct{}
|
||||||
registryService *registry.Service
|
registryService *registry.Service
|
||||||
|
eventsService *events.Events
|
||||||
}
|
}
|
||||||
|
|
||||||
type Repository map[string]string
|
type Repository map[string]string
|
||||||
|
@ -62,7 +64,7 @@ func (r Repository) Contains(u Repository) bool {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewTagStore(path string, graph *Graph, key libtrust.PrivateKey, registryService *registry.Service) (*TagStore, error) {
|
func NewTagStore(path string, graph *Graph, key libtrust.PrivateKey, registryService *registry.Service, eventsService *events.Events) (*TagStore, error) {
|
||||||
abspath, err := filepath.Abs(path)
|
abspath, err := filepath.Abs(path)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
@ -76,6 +78,7 @@ func NewTagStore(path string, graph *Graph, key libtrust.PrivateKey, registrySer
|
||||||
pullingPool: make(map[string]chan struct{}),
|
pullingPool: make(map[string]chan struct{}),
|
||||||
pushingPool: make(map[string]chan struct{}),
|
pushingPool: make(map[string]chan struct{}),
|
||||||
registryService: registryService,
|
registryService: registryService,
|
||||||
|
eventsService: eventsService,
|
||||||
}
|
}
|
||||||
// Load the json file if it exists, otherwise create it.
|
// Load the json file if it exists, otherwise create it.
|
||||||
if err := store.reload(); os.IsNotExist(err) {
|
if err := store.reload(); os.IsNotExist(err) {
|
||||||
|
|
|
@ -7,6 +7,7 @@ import (
|
||||||
"path"
|
"path"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
"github.com/docker/docker/daemon/events"
|
||||||
"github.com/docker/docker/daemon/graphdriver"
|
"github.com/docker/docker/daemon/graphdriver"
|
||||||
_ "github.com/docker/docker/daemon/graphdriver/vfs" // import the vfs driver so it is used in the tests
|
_ "github.com/docker/docker/daemon/graphdriver/vfs" // import the vfs driver so it is used in the tests
|
||||||
"github.com/docker/docker/image"
|
"github.com/docker/docker/image"
|
||||||
|
@ -59,7 +60,7 @@ func mkTestTagStore(root string, t *testing.T) *TagStore {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
store, err := NewTagStore(path.Join(root, "tags"), graph, nil, nil)
|
store, err := NewTagStore(path.Join(root, "tags"), graph, nil, nil, events.New())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
Загрузка…
Ссылка в новой задаче