summaryrefslogtreecommitdiff
path: root/recipes-containers
diff options
context:
space:
mode:
authorRicardo Salveti <ricardo@opensourcefoundries.com>2017-10-17 03:36:53 -0200
committerRicardo Salveti <ricardo@opensourcefoundries.com>2017-10-17 22:56:25 -0200
commitd62536c6126086602ec6a874f86b8f6c3bd73b5b (patch)
treecccac96638226170c064de95e74092075d24a08a /recipes-containers
parent922c2c654519d94e13d5ac5726ce79ad73eb9925 (diff)
docker: backport patch that updates go-fsinotify for arm64 compatibility
Backport 0001-fix-TestLogsFollowGoroutinesWithStdout-in-arm64.patch for better arm64 compatibility (e.g. docker logs -f on arm64). Signed-off-by: Ricardo Salveti <ricardo@opensourcefoundries.com>
Diffstat (limited to 'recipes-containers')
-rw-r--r--recipes-containers/docker/docker/0001-fix-TestLogsFollowGoroutinesWithStdout-in-arm64.patch688
-rw-r--r--recipes-containers/docker/docker_git.bbappend6
2 files changed, 694 insertions, 0 deletions
diff --git a/recipes-containers/docker/docker/0001-fix-TestLogsFollowGoroutinesWithStdout-in-arm64.patch b/recipes-containers/docker/docker/0001-fix-TestLogsFollowGoroutinesWithStdout-in-arm64.patch
new file mode 100644
index 0000000..d0af094
--- /dev/null
+++ b/recipes-containers/docker/docker/0001-fix-TestLogsFollowGoroutinesWithStdout-in-arm64.patch
@@ -0,0 +1,688 @@
+From 6e590d3b99f9f225feecaabbd035089de67ecd2a Mon Sep 17 00:00:00 2001
+From: FengtuWang <wangfengtu@huawei.com>
+Date: Tue, 1 Aug 2017 22:38:16 +0800
+Subject: [PATCH] fix TestLogsFollowGoroutinesWithStdout in arm64
+
+Test case TestLogsFollowGoroutinesWithStdout failed in
+arm64 because gopkg.in/fsnotify.v1 does not support
+arm64 until version v1.3.0. Update fsnotify to latest
+version v1.4.2 to support arm64.
+
+see issue https://github.com/fsnotify/fsnotify/issues/112
+
+Signed-off-by: Fengtu Wang <wangfengtu@huawei.com>
+---
+ vendor.conf | 2 +-
+ vendor/github.com/fsnotify/fsnotify/README.md | 10 ++--
+ vendor/github.com/fsnotify/fsnotify/fsnotify.go | 26 +++++-----
+ vendor/github.com/fsnotify/fsnotify/inotify.go | 57 +++++++++++-----------
+ .../github.com/fsnotify/fsnotify/inotify_poller.go | 53 ++++++++++----------
+ vendor/github.com/fsnotify/fsnotify/kqueue.go | 51 +++++++++----------
+ .../github.com/fsnotify/fsnotify/open_mode_bsd.go | 4 +-
+ .../fsnotify/fsnotify/open_mode_darwin.go | 4 +-
+ vendor/github.com/fsnotify/fsnotify/windows.go | 8 +--
+ 9 files changed, 111 insertions(+), 104 deletions(-)
+
+diff --git a/src/import/vendor.conf b/src/import/vendor.conf
+index 23384e4a5..017eecaee 100644
+--- a/src/import/vendor.conf
++++ b/src/import/vendor.conf
+@@ -83,7 +83,7 @@ github.com/philhofer/fwd 98c11a7a6ec829d672b03833c3d69a7fae1ca972
+ github.com/tinylib/msgp 75ee40d2601edf122ef667e2a07d600d4c44490c
+
+ # fsnotify
+-github.com/fsnotify/fsnotify v1.2.11
++github.com/fsnotify/fsnotify v1.4.2
+
+ # awslogs deps
+ github.com/aws/aws-sdk-go v1.4.22
+diff --git a/src/import/vendor/github.com/fsnotify/fsnotify/README.md b/src/import/vendor/github.com/fsnotify/fsnotify/README.md
+index fee2a36ba..3c891e349 100644
+--- a/src/import/vendor/github.com/fsnotify/fsnotify/README.md
++++ b/src/import/vendor/github.com/fsnotify/fsnotify/README.md
+@@ -1,8 +1,12 @@
+ # File system notifications for Go
+
+-[![GoDoc](https://godoc.org/github.com/fsnotify/fsnotify?status.svg)](https://godoc.org/github.com/fsnotify/fsnotify) [![Go Report Card](https://goreportcard.com/badge/github.com/fsnotify/fsnotify)](https://goreportcard.com/report/github.com/fsnotify/fsnotify) [![Coverage](http://gocover.io/_badge/github.com/fsnotify/fsnotify)](http://gocover.io/github.com/fsnotify/fsnotify)
++[![GoDoc](https://godoc.org/github.com/fsnotify/fsnotify?status.svg)](https://godoc.org/github.com/fsnotify/fsnotify) [![Go Report Card](https://goreportcard.com/badge/github.com/fsnotify/fsnotify)](https://goreportcard.com/report/github.com/fsnotify/fsnotify)
+
+-Go 1.3+ required.
++fsnotify utilizes [golang.org/x/sys](https://godoc.org/golang.org/x/sys) rather than `syscall` from the standard library. Ensure you have the latest version installed by running:
++
++```console
++go get -u golang.org/x/sys/...
++```
+
+ Cross platform: Windows, Linux, BSD and OS X.
+
+@@ -27,7 +31,7 @@ fsnotify is a fork of [howeyc/fsnotify](https://godoc.org/github.com/howeyc/fsno
+
+ All [releases](https://github.com/fsnotify/fsnotify/releases) are tagged based on [Semantic Versioning](http://semver.org/). Further API changes are [planned](https://github.com/fsnotify/fsnotify/milestones), and will be tagged with a new major revision number.
+
+-Go 1.6 supports dependencies located in the `vendor/` folder. Unless you are creating a library, it is recommended that you copy fsnotify into `vendor/github.com/fsnotify/fsnotify` within your project.
++Go 1.6 supports dependencies located in the `vendor/` folder. Unless you are creating a library, it is recommended that you copy fsnotify into `vendor/github.com/fsnotify/fsnotify` within your project, and likewise for `golang.org/x/sys`.
+
+ ## Contributing
+
+diff --git a/src/import/vendor/github.com/fsnotify/fsnotify/fsnotify.go b/src/import/vendor/github.com/fsnotify/fsnotify/fsnotify.go
+index d1d39a0eb..e7f55fee7 100644
+--- a/src/import/vendor/github.com/fsnotify/fsnotify/fsnotify.go
++++ b/src/import/vendor/github.com/fsnotify/fsnotify/fsnotify.go
+@@ -30,33 +30,33 @@ const (
+ Chmod
+ )
+
+-// String returns a string representation of the event in the form
+-// "file: REMOVE|WRITE|..."
+-func (e Event) String() string {
++func (op Op) String() string {
+ // Use a buffer for efficient string concatenation
+ var buffer bytes.Buffer
+
+- if e.Op&Create == Create {
++ if op&Create == Create {
+ buffer.WriteString("|CREATE")
+ }
+- if e.Op&Remove == Remove {
++ if op&Remove == Remove {
+ buffer.WriteString("|REMOVE")
+ }
+- if e.Op&Write == Write {
++ if op&Write == Write {
+ buffer.WriteString("|WRITE")
+ }
+- if e.Op&Rename == Rename {
++ if op&Rename == Rename {
+ buffer.WriteString("|RENAME")
+ }
+- if e.Op&Chmod == Chmod {
++ if op&Chmod == Chmod {
+ buffer.WriteString("|CHMOD")
+ }
+-
+- // If buffer remains empty, return no event names
+ if buffer.Len() == 0 {
+- return fmt.Sprintf("%q: ", e.Name)
++ return ""
+ }
++ return buffer.String()[1:] // Strip leading pipe
++}
+
+- // Return a list of event names, with leading pipe character stripped
+- return fmt.Sprintf("%q: %s", e.Name, buffer.String()[1:])
++// String returns a string representation of the event in the form
++// "file: REMOVE|WRITE|..."
++func (e Event) String() string {
++ return fmt.Sprintf("%q: %s", e.Name, e.Op.String())
+ }
+diff --git a/src/import/vendor/github.com/fsnotify/fsnotify/inotify.go b/src/import/vendor/github.com/fsnotify/fsnotify/inotify.go
+index 780b2a005..f3b74c51f 100644
+--- a/src/import/vendor/github.com/fsnotify/fsnotify/inotify.go
++++ b/src/import/vendor/github.com/fsnotify/fsnotify/inotify.go
+@@ -14,8 +14,9 @@ import (
+ "path/filepath"
+ "strings"
+ "sync"
+- "syscall"
+ "unsafe"
++
++ "golang.org/x/sys/unix"
+ )
+
+ // Watcher watches a set of files, delivering events to a channel.
+@@ -35,14 +36,14 @@ type Watcher struct {
+ // NewWatcher establishes a new watcher with the underlying OS and begins waiting for events.
+ func NewWatcher() (*Watcher, error) {
+ // Create inotify fd
+- fd, errno := syscall.InotifyInit()
++ fd, errno := unix.InotifyInit1(unix.IN_CLOEXEC)
+ if fd == -1 {
+ return nil, errno
+ }
+ // Create epoll
+ poller, err := newFdPoller(fd)
+ if err != nil {
+- syscall.Close(fd)
++ unix.Close(fd)
+ return nil, err
+ }
+ w := &Watcher{
+@@ -95,9 +96,9 @@ func (w *Watcher) Add(name string) error {
+ return errors.New("inotify instance already closed")
+ }
+
+- const agnosticEvents = syscall.IN_MOVED_TO | syscall.IN_MOVED_FROM |
+- syscall.IN_CREATE | syscall.IN_ATTRIB | syscall.IN_MODIFY |
+- syscall.IN_MOVE_SELF | syscall.IN_DELETE | syscall.IN_DELETE_SELF
++ const agnosticEvents = unix.IN_MOVED_TO | unix.IN_MOVED_FROM |
++ unix.IN_CREATE | unix.IN_ATTRIB | unix.IN_MODIFY |
++ unix.IN_MOVE_SELF | unix.IN_DELETE | unix.IN_DELETE_SELF
+
+ var flags uint32 = agnosticEvents
+
+@@ -106,9 +107,9 @@ func (w *Watcher) Add(name string) error {
+ w.mu.Unlock()
+ if found {
+ watchEntry.flags |= flags
+- flags |= syscall.IN_MASK_ADD
++ flags |= unix.IN_MASK_ADD
+ }
+- wd, errno := syscall.InotifyAddWatch(w.fd, name, flags)
++ wd, errno := unix.InotifyAddWatch(w.fd, name, flags)
+ if wd == -1 {
+ return errno
+ }
+@@ -140,7 +141,7 @@ func (w *Watcher) Remove(name string) error {
+ // by calling inotify_rm_watch() below. e.g. readEvents() goroutine receives IN_IGNORE
+ // so that EINVAL means that the wd is being rm_watch()ed or its file removed
+ // by another thread and we have not received IN_IGNORE event.
+- success, errno := syscall.InotifyRmWatch(w.fd, watch.wd)
++ success, errno := unix.InotifyRmWatch(w.fd, watch.wd)
+ if success == -1 {
+ // TODO: Perhaps it's not helpful to return an error here in every case.
+ // the only two possible errors are:
+@@ -170,16 +171,16 @@ type watch struct {
+ // received events into Event objects and sends them via the Events channel
+ func (w *Watcher) readEvents() {
+ var (
+- buf [syscall.SizeofInotifyEvent * 4096]byte // Buffer for a maximum of 4096 raw events
+- n int // Number of bytes read with read()
+- errno error // Syscall errno
+- ok bool // For poller.wait
++ buf [unix.SizeofInotifyEvent * 4096]byte // Buffer for a maximum of 4096 raw events
++ n int // Number of bytes read with read()
++ errno error // Syscall errno
++ ok bool // For poller.wait
+ )
+
+ defer close(w.doneResp)
+ defer close(w.Errors)
+ defer close(w.Events)
+- defer syscall.Close(w.fd)
++ defer unix.Close(w.fd)
+ defer w.poller.close()
+
+ for {
+@@ -202,20 +203,20 @@ func (w *Watcher) readEvents() {
+ continue
+ }
+
+- n, errno = syscall.Read(w.fd, buf[:])
++ n, errno = unix.Read(w.fd, buf[:])
+ // If a signal interrupted execution, see if we've been asked to close, and try again.
+ // http://man7.org/linux/man-pages/man7/signal.7.html :
+ // "Before Linux 3.8, reads from an inotify(7) file descriptor were not restartable"
+- if errno == syscall.EINTR {
++ if errno == unix.EINTR {
+ continue
+ }
+
+- // syscall.Read might have been woken up by Close. If so, we're done.
++ // unix.Read might have been woken up by Close. If so, we're done.
+ if w.isClosed() {
+ return
+ }
+
+- if n < syscall.SizeofInotifyEvent {
++ if n < unix.SizeofInotifyEvent {
+ var err error
+ if n == 0 {
+ // If EOF is received. This should really never happen.
+@@ -238,9 +239,9 @@ func (w *Watcher) readEvents() {
+ var offset uint32
+ // We don't know how many events we just read into the buffer
+ // While the offset points to at least one whole event...
+- for offset <= uint32(n-syscall.SizeofInotifyEvent) {
++ for offset <= uint32(n-unix.SizeofInotifyEvent) {
+ // Point "raw" to the event in the buffer
+- raw := (*syscall.InotifyEvent)(unsafe.Pointer(&buf[offset]))
++ raw := (*unix.InotifyEvent)(unsafe.Pointer(&buf[offset]))
+
+ mask := uint32(raw.Mask)
+ nameLen := uint32(raw.Len)
+@@ -253,7 +254,7 @@ func (w *Watcher) readEvents() {
+ w.mu.Unlock()
+ if nameLen > 0 {
+ // Point "bytes" at the first byte of the filename
+- bytes := (*[syscall.PathMax]byte)(unsafe.Pointer(&buf[offset+syscall.SizeofInotifyEvent]))
++ bytes := (*[unix.PathMax]byte)(unsafe.Pointer(&buf[offset+unix.SizeofInotifyEvent]))
+ // The filename is padded with NULL bytes. TrimRight() gets rid of those.
+ name += "/" + strings.TrimRight(string(bytes[0:nameLen]), "\000")
+ }
+@@ -270,7 +271,7 @@ func (w *Watcher) readEvents() {
+ }
+
+ // Move to the next event in the buffer
+- offset += syscall.SizeofInotifyEvent + nameLen
++ offset += unix.SizeofInotifyEvent + nameLen
+ }
+ }
+ }
+@@ -280,7 +281,7 @@ func (w *Watcher) readEvents() {
+ // against files that do not exist.
+ func (e *Event) ignoreLinux(w *Watcher, wd int32, mask uint32) bool {
+ // Ignore anything the inotify API says to ignore
+- if mask&syscall.IN_IGNORED == syscall.IN_IGNORED {
++ if mask&unix.IN_IGNORED == unix.IN_IGNORED {
+ w.mu.Lock()
+ defer w.mu.Unlock()
+ name := w.paths[int(wd)]
+@@ -305,19 +306,19 @@ func (e *Event) ignoreLinux(w *Watcher, wd int32, mask uint32) bool {
+ // newEvent returns an platform-independent Event based on an inotify mask.
+ func newEvent(name string, mask uint32) Event {
+ e := Event{Name: name}
+- if mask&syscall.IN_CREATE == syscall.IN_CREATE || mask&syscall.IN_MOVED_TO == syscall.IN_MOVED_TO {
++ if mask&unix.IN_CREATE == unix.IN_CREATE || mask&unix.IN_MOVED_TO == unix.IN_MOVED_TO {
+ e.Op |= Create
+ }
+- if mask&syscall.IN_DELETE_SELF == syscall.IN_DELETE_SELF || mask&syscall.IN_DELETE == syscall.IN_DELETE {
++ if mask&unix.IN_DELETE_SELF == unix.IN_DELETE_SELF || mask&unix.IN_DELETE == unix.IN_DELETE {
+ e.Op |= Remove
+ }
+- if mask&syscall.IN_MODIFY == syscall.IN_MODIFY {
++ if mask&unix.IN_MODIFY == unix.IN_MODIFY {
+ e.Op |= Write
+ }
+- if mask&syscall.IN_MOVE_SELF == syscall.IN_MOVE_SELF || mask&syscall.IN_MOVED_FROM == syscall.IN_MOVED_FROM {
++ if mask&unix.IN_MOVE_SELF == unix.IN_MOVE_SELF || mask&unix.IN_MOVED_FROM == unix.IN_MOVED_FROM {
+ e.Op |= Rename
+ }
+- if mask&syscall.IN_ATTRIB == syscall.IN_ATTRIB {
++ if mask&unix.IN_ATTRIB == unix.IN_ATTRIB {
+ e.Op |= Chmod
+ }
+ return e
+diff --git a/src/import/vendor/github.com/fsnotify/fsnotify/inotify_poller.go b/src/import/vendor/github.com/fsnotify/fsnotify/inotify_poller.go
+index 23a5ca146..cc7db4b22 100644
+--- a/src/import/vendor/github.com/fsnotify/fsnotify/inotify_poller.go
++++ b/src/import/vendor/github.com/fsnotify/fsnotify/inotify_poller.go
+@@ -8,7 +8,8 @@ package fsnotify
+
+ import (
+ "errors"
+- "syscall"
++
++ "golang.org/x/sys/unix"
+ )
+
+ type fdPoller struct {
+@@ -39,32 +40,32 @@ func newFdPoller(fd int) (*fdPoller, error) {
+ poller.fd = fd
+
+ // Create epoll fd
+- poller.epfd, errno = syscall.EpollCreate1(0)
++ poller.epfd, errno = unix.EpollCreate1(0)
+ if poller.epfd == -1 {
+ return nil, errno
+ }
+ // Create pipe; pipe[0] is the read end, pipe[1] the write end.
+- errno = syscall.Pipe2(poller.pipe[:], syscall.O_NONBLOCK)
++ errno = unix.Pipe2(poller.pipe[:], unix.O_NONBLOCK)
+ if errno != nil {
+ return nil, errno
+ }
+
+ // Register inotify fd with epoll
+- event := syscall.EpollEvent{
++ event := unix.EpollEvent{
+ Fd: int32(poller.fd),
+- Events: syscall.EPOLLIN,
++ Events: unix.EPOLLIN,
+ }
+- errno = syscall.EpollCtl(poller.epfd, syscall.EPOLL_CTL_ADD, poller.fd, &event)
++ errno = unix.EpollCtl(poller.epfd, unix.EPOLL_CTL_ADD, poller.fd, &event)
+ if errno != nil {
+ return nil, errno
+ }
+
+ // Register pipe fd with epoll
+- event = syscall.EpollEvent{
++ event = unix.EpollEvent{
+ Fd: int32(poller.pipe[0]),
+- Events: syscall.EPOLLIN,
++ Events: unix.EPOLLIN,
+ }
+- errno = syscall.EpollCtl(poller.epfd, syscall.EPOLL_CTL_ADD, poller.pipe[0], &event)
++ errno = unix.EpollCtl(poller.epfd, unix.EPOLL_CTL_ADD, poller.pipe[0], &event)
+ if errno != nil {
+ return nil, errno
+ }
+@@ -80,11 +81,11 @@ func (poller *fdPoller) wait() (bool, error) {
+ // I don't know whether epoll_wait returns the number of events returned,
+ // or the total number of events ready.
+ // I decided to catch both by making the buffer one larger than the maximum.
+- events := make([]syscall.EpollEvent, 7)
++ events := make([]unix.EpollEvent, 7)
+ for {
+- n, errno := syscall.EpollWait(poller.epfd, events, -1)
++ n, errno := unix.EpollWait(poller.epfd, events, -1)
+ if n == -1 {
+- if errno == syscall.EINTR {
++ if errno == unix.EINTR {
+ continue
+ }
+ return false, errno
+@@ -103,31 +104,31 @@ func (poller *fdPoller) wait() (bool, error) {
+ epollin := false
+ for _, event := range ready {
+ if event.Fd == int32(poller.fd) {
+- if event.Events&syscall.EPOLLHUP != 0 {
++ if event.Events&unix.EPOLLHUP != 0 {
+ // This should not happen, but if it does, treat it as a wakeup.
+ epollhup = true
+ }
+- if event.Events&syscall.EPOLLERR != 0 {
++ if event.Events&unix.EPOLLERR != 0 {
+ // If an error is waiting on the file descriptor, we should pretend
+- // something is ready to read, and let syscall.Read pick up the error.
++ // something is ready to read, and let unix.Read pick up the error.
+ epollerr = true
+ }
+- if event.Events&syscall.EPOLLIN != 0 {
++ if event.Events&unix.EPOLLIN != 0 {
+ // There is data to read.
+ epollin = true
+ }
+ }
+ if event.Fd == int32(poller.pipe[0]) {
+- if event.Events&syscall.EPOLLHUP != 0 {
++ if event.Events&unix.EPOLLHUP != 0 {
+ // Write pipe descriptor was closed, by us. This means we're closing down the
+ // watcher, and we should wake up.
+ }
+- if event.Events&syscall.EPOLLERR != 0 {
++ if event.Events&unix.EPOLLERR != 0 {
+ // If an error is waiting on the pipe file descriptor.
+ // This is an absolute mystery, and should never ever happen.
+ return false, errors.New("Error on the pipe descriptor.")
+ }
+- if event.Events&syscall.EPOLLIN != 0 {
++ if event.Events&unix.EPOLLIN != 0 {
+ // This is a regular wakeup, so we have to clear the buffer.
+ err := poller.clearWake()
+ if err != nil {
+@@ -147,9 +148,9 @@ func (poller *fdPoller) wait() (bool, error) {
+ // Close the write end of the poller.
+ func (poller *fdPoller) wake() error {
+ buf := make([]byte, 1)
+- n, errno := syscall.Write(poller.pipe[1], buf)
++ n, errno := unix.Write(poller.pipe[1], buf)
+ if n == -1 {
+- if errno == syscall.EAGAIN {
++ if errno == unix.EAGAIN {
+ // Buffer is full, poller will wake.
+ return nil
+ }
+@@ -161,9 +162,9 @@ func (poller *fdPoller) wake() error {
+ func (poller *fdPoller) clearWake() error {
+ // You have to be woken up a LOT in order to get to 100!
+ buf := make([]byte, 100)
+- n, errno := syscall.Read(poller.pipe[0], buf)
++ n, errno := unix.Read(poller.pipe[0], buf)
+ if n == -1 {
+- if errno == syscall.EAGAIN {
++ if errno == unix.EAGAIN {
+ // Buffer is empty, someone else cleared our wake.
+ return nil
+ }
+@@ -175,12 +176,12 @@ func (poller *fdPoller) clearWake() error {
+ // Close all poller file descriptors, but not the one passed to it.
+ func (poller *fdPoller) close() {
+ if poller.pipe[1] != -1 {
+- syscall.Close(poller.pipe[1])
++ unix.Close(poller.pipe[1])
+ }
+ if poller.pipe[0] != -1 {
+- syscall.Close(poller.pipe[0])
++ unix.Close(poller.pipe[0])
+ }
+ if poller.epfd != -1 {
+- syscall.Close(poller.epfd)
++ unix.Close(poller.epfd)
+ }
+ }
+diff --git a/src/import/vendor/github.com/fsnotify/fsnotify/kqueue.go b/src/import/vendor/github.com/fsnotify/fsnotify/kqueue.go
+index b8ea30846..c2b4acb18 100644
+--- a/src/import/vendor/github.com/fsnotify/fsnotify/kqueue.go
++++ b/src/import/vendor/github.com/fsnotify/fsnotify/kqueue.go
+@@ -13,8 +13,9 @@ import (
+ "os"
+ "path/filepath"
+ "sync"
+- "syscall"
+ "time"
++
++ "golang.org/x/sys/unix"
+ )
+
+ // Watcher watches a set of files, delivering events to a channel.
+@@ -113,12 +114,12 @@ func (w *Watcher) Remove(name string) error {
+ return fmt.Errorf("can't remove non-existent kevent watch for: %s", name)
+ }
+
+- const registerRemove = syscall.EV_DELETE
++ const registerRemove = unix.EV_DELETE
+ if err := register(w.kq, []int{watchfd}, registerRemove, 0); err != nil {
+ return err
+ }
+
+- syscall.Close(watchfd)
++ unix.Close(watchfd)
+
+ w.mu.Lock()
+ isDir := w.paths[watchfd].isDir
+@@ -152,7 +153,7 @@ func (w *Watcher) Remove(name string) error {
+ }
+
+ // Watch all events (except NOTE_EXTEND, NOTE_LINK, NOTE_REVOKE)
+-const noteAllEvents = syscall.NOTE_DELETE | syscall.NOTE_WRITE | syscall.NOTE_ATTRIB | syscall.NOTE_RENAME
++const noteAllEvents = unix.NOTE_DELETE | unix.NOTE_WRITE | unix.NOTE_ATTRIB | unix.NOTE_RENAME
+
+ // keventWaitTime to block on each read from kevent
+ var keventWaitTime = durationToTimespec(100 * time.Millisecond)
+@@ -219,7 +220,7 @@ func (w *Watcher) addWatch(name string, flags uint32) (string, error) {
+ }
+ }
+
+- watchfd, err = syscall.Open(name, openMode, 0700)
++ watchfd, err = unix.Open(name, openMode, 0700)
+ if watchfd == -1 {
+ return "", err
+ }
+@@ -227,9 +228,9 @@ func (w *Watcher) addWatch(name string, flags uint32) (string, error) {
+ isDir = fi.IsDir()
+ }
+
+- const registerAdd = syscall.EV_ADD | syscall.EV_CLEAR | syscall.EV_ENABLE
++ const registerAdd = unix.EV_ADD | unix.EV_CLEAR | unix.EV_ENABLE
+ if err := register(w.kq, []int{watchfd}, registerAdd, flags); err != nil {
+- syscall.Close(watchfd)
++ unix.Close(watchfd)
+ return "", err
+ }
+
+@@ -245,8 +246,8 @@ func (w *Watcher) addWatch(name string, flags uint32) (string, error) {
+ // or if it was watched before, but perhaps only a NOTE_DELETE (watchDirectoryFiles)
+ w.mu.Lock()
+
+- watchDir := (flags&syscall.NOTE_WRITE) == syscall.NOTE_WRITE &&
+- (!alreadyWatching || (w.dirFlags[name]&syscall.NOTE_WRITE) != syscall.NOTE_WRITE)
++ watchDir := (flags&unix.NOTE_WRITE) == unix.NOTE_WRITE &&
++ (!alreadyWatching || (w.dirFlags[name]&unix.NOTE_WRITE) != unix.NOTE_WRITE)
+ // Store flags so this watch can be updated later
+ w.dirFlags[name] = flags
+ w.mu.Unlock()
+@@ -263,13 +264,13 @@ func (w *Watcher) addWatch(name string, flags uint32) (string, error) {
+ // readEvents reads from kqueue and converts the received kevents into
+ // Event values that it sends down the Events channel.
+ func (w *Watcher) readEvents() {
+- eventBuffer := make([]syscall.Kevent_t, 10)
++ eventBuffer := make([]unix.Kevent_t, 10)
+
+ for {
+ // See if there is a message on the "done" channel
+ select {
+ case <-w.done:
+- err := syscall.Close(w.kq)
++ err := unix.Close(w.kq)
+ if err != nil {
+ w.Errors <- err
+ }
+@@ -282,7 +283,7 @@ func (w *Watcher) readEvents() {
+ // Get new events
+ kevents, err := read(w.kq, eventBuffer, &keventWaitTime)
+ // EINTR is okay, the syscall was interrupted before timeout expired.
+- if err != nil && err != syscall.EINTR {
++ if err != nil && err != unix.EINTR {
+ w.Errors <- err
+ continue
+ }
+@@ -356,16 +357,16 @@ func (w *Watcher) readEvents() {
+ // newEvent returns an platform-independent Event based on kqueue Fflags.
+ func newEvent(name string, mask uint32) Event {
+ e := Event{Name: name}
+- if mask&syscall.NOTE_DELETE == syscall.NOTE_DELETE {
++ if mask&unix.NOTE_DELETE == unix.NOTE_DELETE {
+ e.Op |= Remove
+ }
+- if mask&syscall.NOTE_WRITE == syscall.NOTE_WRITE {
++ if mask&unix.NOTE_WRITE == unix.NOTE_WRITE {
+ e.Op |= Write
+ }
+- if mask&syscall.NOTE_RENAME == syscall.NOTE_RENAME {
++ if mask&unix.NOTE_RENAME == unix.NOTE_RENAME {
+ e.Op |= Rename
+ }
+- if mask&syscall.NOTE_ATTRIB == syscall.NOTE_ATTRIB {
++ if mask&unix.NOTE_ATTRIB == unix.NOTE_ATTRIB {
+ e.Op |= Chmod
+ }
+ return e
+@@ -451,7 +452,7 @@ func (w *Watcher) internalWatch(name string, fileInfo os.FileInfo) (string, erro
+ flags := w.dirFlags[name]
+ w.mu.Unlock()
+
+- flags |= syscall.NOTE_DELETE | syscall.NOTE_RENAME
++ flags |= unix.NOTE_DELETE | unix.NOTE_RENAME
+ return w.addWatch(name, flags)
+ }
+
+@@ -461,7 +462,7 @@ func (w *Watcher) internalWatch(name string, fileInfo os.FileInfo) (string, erro
+
+ // kqueue creates a new kernel event queue and returns a descriptor.
+ func kqueue() (kq int, err error) {
+- kq, err = syscall.Kqueue()
++ kq, err = unix.Kqueue()
+ if kq == -1 {
+ return kq, err
+ }
+@@ -470,16 +471,16 @@ func kqueue() (kq int, err error) {
+
+ // register events with the queue
+ func register(kq int, fds []int, flags int, fflags uint32) error {
+- changes := make([]syscall.Kevent_t, len(fds))
++ changes := make([]unix.Kevent_t, len(fds))
+
+ for i, fd := range fds {
+ // SetKevent converts int to the platform-specific types:
+- syscall.SetKevent(&changes[i], fd, syscall.EVFILT_VNODE, flags)
++ unix.SetKevent(&changes[i], fd, unix.EVFILT_VNODE, flags)
+ changes[i].Fflags = fflags
+ }
+
+ // register the events
+- success, err := syscall.Kevent(kq, changes, nil, nil)
++ success, err := unix.Kevent(kq, changes, nil, nil)
+ if success == -1 {
+ return err
+ }
+@@ -488,8 +489,8 @@ func register(kq int, fds []int, flags int, fflags uint32) error {
+
+ // read retrieves pending events, or waits until an event occurs.
+ // A timeout of nil blocks indefinitely, while 0 polls the queue.
+-func read(kq int, events []syscall.Kevent_t, timeout *syscall.Timespec) ([]syscall.Kevent_t, error) {
+- n, err := syscall.Kevent(kq, nil, events, timeout)
++func read(kq int, events []unix.Kevent_t, timeout *unix.Timespec) ([]unix.Kevent_t, error) {
++ n, err := unix.Kevent(kq, nil, events, timeout)
+ if err != nil {
+ return nil, err
+ }
+@@ -497,6 +498,6 @@ func read(kq int, events []syscall.Kevent_t, timeout *syscall.Timespec) ([]sysca
+ }
+
+ // durationToTimespec prepares a timeout value
+-func durationToTimespec(d time.Duration) syscall.Timespec {
+- return syscall.NsecToTimespec(d.Nanoseconds())
++func durationToTimespec(d time.Duration) unix.Timespec {
++ return unix.NsecToTimespec(d.Nanoseconds())
+ }
+diff --git a/src/import/vendor/github.com/fsnotify/fsnotify/open_mode_bsd.go b/src/import/vendor/github.com/fsnotify/fsnotify/open_mode_bsd.go
+index c57ccb427..7d8de1451 100644
+--- a/src/import/vendor/github.com/fsnotify/fsnotify/open_mode_bsd.go
++++ b/src/import/vendor/github.com/fsnotify/fsnotify/open_mode_bsd.go
+@@ -6,6 +6,6 @@
+
+ package fsnotify
+
+-import "syscall"
++import "golang.org/x/sys/unix"
+
+-const openMode = syscall.O_NONBLOCK | syscall.O_RDONLY
++const openMode = unix.O_NONBLOCK | unix.O_RDONLY
+diff --git a/src/import/vendor/github.com/fsnotify/fsnotify/open_mode_darwin.go b/src/import/vendor/github.com/fsnotify/fsnotify/open_mode_darwin.go
+index 174b2c331..9139e1716 100644
+--- a/src/import/vendor/github.com/fsnotify/fsnotify/open_mode_darwin.go
++++ b/src/import/vendor/github.com/fsnotify/fsnotify/open_mode_darwin.go
+@@ -6,7 +6,7 @@
+
+ package fsnotify
+
+-import "syscall"
++import "golang.org/x/sys/unix"
+
+ // note: this constant is not defined on BSD
+-const openMode = syscall.O_EVTONLY
++const openMode = unix.O_EVTONLY
+diff --git a/src/import/vendor/github.com/fsnotify/fsnotify/windows.go b/src/import/vendor/github.com/fsnotify/fsnotify/windows.go
+index c836bdb3d..09436f31d 100644
+--- a/src/import/vendor/github.com/fsnotify/fsnotify/windows.go
++++ b/src/import/vendor/github.com/fsnotify/fsnotify/windows.go
+@@ -306,7 +306,7 @@ func (w *Watcher) remWatch(pathname string) error {
+ watch.mask = 0
+ } else {
+ name := filepath.Base(pathname)
+- w.sendEvent(watch.path+"\\"+name, watch.names[name]&sysFSIGNORED)
++ w.sendEvent(filepath.Join(watch.path, name), watch.names[name]&sysFSIGNORED)
+ delete(watch.names, name)
+ }
+ return w.startRead(watch)
+@@ -316,7 +316,7 @@ func (w *Watcher) remWatch(pathname string) error {
+ func (w *Watcher) deleteWatch(watch *watch) {
+ for name, mask := range watch.names {
+ if mask&provisional == 0 {
+- w.sendEvent(watch.path+"\\"+name, mask&sysFSIGNORED)
++ w.sendEvent(filepath.Join(watch.path, name), mask&sysFSIGNORED)
+ }
+ delete(watch.names, name)
+ }
+@@ -453,7 +453,7 @@ func (w *Watcher) readEvents() {
+ raw := (*syscall.FileNotifyInformation)(unsafe.Pointer(&watch.buf[offset]))
+ buf := (*[syscall.MAX_PATH]uint16)(unsafe.Pointer(&raw.FileName))
+ name := syscall.UTF16ToString(buf[:raw.FileNameLength/2])
+- fullname := watch.path + "\\" + name
++ fullname := filepath.Join(watch.path, name)
+
+ var mask uint64
+ switch raw.Action {
+@@ -491,7 +491,7 @@ func (w *Watcher) readEvents() {
+ }
+ }
+ if raw.Action == syscall.FILE_ACTION_RENAMED_NEW_NAME {
+- fullname = watch.path + "\\" + watch.rename
++ fullname = filepath.Join(watch.path, watch.rename)
+ sendNameEvent()
+ }
+
+--
+2.14.1
+
diff --git a/recipes-containers/docker/docker_git.bbappend b/recipes-containers/docker/docker_git.bbappend
new file mode 100644
index 0000000..bf53c9c
--- /dev/null
+++ b/recipes-containers/docker/docker_git.bbappend
@@ -0,0 +1,6 @@
+FILESEXTRAPATHS_prepend := "${THISDIR}/${PN}:"
+
+# Additional bugfixes already available upstream
+SRC_URI += " \
+ file://0001-fix-TestLogsFollowGoroutinesWithStdout-in-arm64.patch \
+"