Skip to content

Commit

Permalink
Revendor hcsshim
Browse files Browse the repository at this point in the history
Signed-off-by: Darren Stahl <[email protected]>
  • Loading branch information
darstahl committed May 31, 2016
1 parent 0b5e84c commit d96e36c
Show file tree
Hide file tree
Showing 7 changed files with 165 additions and 111 deletions.
2 changes: 1 addition & 1 deletion hack/vendor.sh
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ esac

# the following lines are in sorted order, FYI
clone git github.com/Azure/go-ansiterm 388960b655244e76e24c75f48631564eaefade62
clone git github.com/Microsoft/hcsshim v0.3.0
clone git github.com/Microsoft/hcsshim v0.3.1
clone git github.com/Microsoft/go-winio v0.3.4
clone git github.com/Sirupsen/logrus v0.10.0 # logrus is a common dependency among multiple deps
clone git github.com/docker/libtrust 9cbd2a1374f46905c68a4eb3694a130610adc62a
Expand Down
15 changes: 15 additions & 0 deletions integration-cli/docker_cli_build_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -6740,3 +6740,18 @@ func (s *DockerSuite) TestBuildLabelsOverride(c *check.C) {
}

}

// Test case for #22855
func (s *DockerSuite) TestBuildDeleteCommittedFile(c *check.C) {
name := "test-delete-committed-file"

_, err := buildImage(name,
`FROM busybox
RUN echo test > file
RUN test -e file
RUN rm file
RUN sh -c "! test -e file"`, false)
if err != nil {
c.Fatal(err)
}
}
49 changes: 23 additions & 26 deletions vendor/src/github.com/Microsoft/hcsshim/callback.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,39 +40,36 @@ type hcsNotification uint32
type notificationChannel chan error

type notifcationWatcherContext struct {
channel notificationChannel
expectedNotification hcsNotification
handle hcsCallback
channels notificationChannels
handle hcsCallback
}

type notificationChannels map[hcsNotification]notificationChannel

func newChannels() notificationChannels {
channels := make(notificationChannels)

channels[hcsNotificationSystemExited] = make(notificationChannel, 1)
channels[hcsNotificationSystemCreateCompleted] = make(notificationChannel, 1)
channels[hcsNotificationSystemStartCompleted] = make(notificationChannel, 1)
channels[hcsNotificationSystemPauseCompleted] = make(notificationChannel, 1)
channels[hcsNotificationSystemResumeCompleted] = make(notificationChannel, 1)
channels[hcsNotificationProcessExited] = make(notificationChannel, 1)
channels[hcsNotificationServiceDisconnect] = make(notificationChannel, 1)
return channels
}

func notificationWatcher(notificationType hcsNotification, callbackNumber uintptr, notificationStatus uintptr, notificationData *uint16) uintptr {
var (
result error
completeWait = false
)
var result error
if int32(notificationStatus) < 0 {
result = syscall.Errno(win32FromHresult(notificationStatus))
}

callbackMapLock.RLock()
context := callbackMap[callbackNumber]
channels := callbackMap[callbackNumber].channels
callbackMapLock.RUnlock()

if notificationType == context.expectedNotification {
if int32(notificationStatus) < 0 {
result = syscall.Errno(win32FromHresult(notificationStatus))
} else {
result = nil
}
completeWait = true
} else if notificationType == hcsNotificationSystemExited {
result = ErrUnexpectedContainerExit
completeWait = true
} else if notificationType == hcsNotificationServiceDisconnect {
result = ErrUnexpectedProcessAbort
completeWait = true
}

if completeWait {
context.channel <- result
}
channels[notificationType] <- result

return 0
}
71 changes: 51 additions & 20 deletions vendor/src/github.com/Microsoft/hcsshim/container.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,9 @@ type ContainerError struct {
}

type container struct {
handle hcsSystem
id string
handle hcsSystem
id string
callbackNumber uintptr
}

type containerProperties struct {
Expand All @@ -47,7 +48,6 @@ type containerProperties struct {
func CreateContainer(id string, c *ContainerConfig) (Container, error) {
operation := "CreateContainer"
title := "HCSShim::" + operation
logrus.Debugf(title+" id=%s", id)

container := &container{
id: id,
Expand All @@ -59,21 +59,28 @@ func CreateContainer(id string, c *ContainerConfig) (Container, error) {
}

configuration := string(configurationb)
logrus.Debugf(title+" id=%s config=%s", id, configuration)

var (
handle hcsSystem
resultp *uint16
createError error
)
if hcsCallbacksSupported {
var identity syscall.Handle
createError = hcsCreateComputeSystem(id, configuration, identity, &handle, &resultp)
createError = hcsCreateComputeSystem(id, configuration, identity, &container.handle, &resultp)

if createError == nil || createError == ErrVmcomputeOperationPending {
if err := container.registerCallback(); err != nil {
err := &ContainerError{Container: container, Operation: operation, Err: err}
logrus.Error(err)
return nil, err
}
}
} else {
createError = hcsCreateComputeSystemTP5(id, configuration, &handle, &resultp)
createError = hcsCreateComputeSystemTP5(id, configuration, &container.handle, &resultp)
}
container.handle = handle

err = processAsyncHcsResult(container, createError, resultp, hcsNotificationSystemCreateCompleted, &defaultTimeout)
err = processAsyncHcsResult(createError, resultp, container.callbackNumber, hcsNotificationSystemCreateCompleted, &defaultTimeout)
if err != nil {
err := &ContainerError{Container: container, Operation: operation, ExtraInfo: configuration, Err: err}
logrus.Error(err)
Expand Down Expand Up @@ -122,7 +129,7 @@ func (container *container) Start() error {

var resultp *uint16
err := hcsStartComputeSystemTP5(container.handle, nil, &resultp)
err = processAsyncHcsResult(container, err, resultp, hcsNotificationSystemStartCompleted, &defaultTimeout)
err = processAsyncHcsResult(err, resultp, container.callbackNumber, hcsNotificationSystemStartCompleted, &defaultTimeout)
if err != nil {
err := &ContainerError{Container: container, Operation: operation, Err: err}
logrus.Error(err)
Expand Down Expand Up @@ -186,7 +193,7 @@ func (container *container) Wait() error {
logrus.Debugf(title+" id=%s", container.id)

if hcsCallbacksSupported {
err := registerAndWaitForCallback(container, hcsNotificationSystemExited)
err := waitForNotification(container.callbackNumber, hcsNotificationSystemExited, nil)
if err != nil {
err := &ContainerError{Container: container, Operation: operation, Err: err}
logrus.Error(err)
Expand Down Expand Up @@ -217,7 +224,7 @@ func (container *container) WaitTimeout(timeout time.Duration) error {
logrus.Debugf(title+" id=%s", container.id)

if hcsCallbacksSupported {
err := registerAndWaitForCallbackTimeout(container, hcsNotificationSystemExited, timeout)
err := waitForNotification(container.callbackNumber, hcsNotificationSystemExited, &timeout)
if err == ErrTimeout {
return ErrTimeout
} else if err != nil {
Expand Down Expand Up @@ -304,7 +311,7 @@ func (container *container) Pause() error {

var resultp *uint16
err := hcsPauseComputeSystemTP5(container.handle, nil, &resultp)
err = processAsyncHcsResult(container, err, resultp, hcsNotificationSystemPauseCompleted, &defaultTimeout)
err = processAsyncHcsResult(err, resultp, container.callbackNumber, hcsNotificationSystemPauseCompleted, &defaultTimeout)
if err != nil {
err := &ContainerError{Container: container, Operation: operation, Err: err}
logrus.Error(err)
Expand All @@ -325,7 +332,7 @@ func (container *container) Resume() error {
)

err := hcsResumeComputeSystemTP5(container.handle, nil, &resultp)
err = processAsyncHcsResult(container, err, resultp, hcsNotificationSystemResumeCompleted, &defaultTimeout)
err = processAsyncHcsResult(err, resultp, container.callbackNumber, hcsNotificationSystemResumeCompleted, &defaultTimeout)
if err != nil {
err := &ContainerError{Container: container, Operation: operation, Err: err}
logrus.Error(err)
Expand All @@ -340,7 +347,6 @@ func (container *container) Resume() error {
func (container *container) CreateProcess(c *ProcessConfig) (Process, error) {
operation := "CreateProcess"
title := "HCSShim::Container::" + operation
logrus.Debugf(title+" id=%s", container.id)
var (
processInfo hcsProcessInformation
processHandle hcsProcess
Expand All @@ -359,6 +365,7 @@ func (container *container) CreateProcess(c *ProcessConfig) (Process, error) {
}

configuration := string(configurationb)
logrus.Debugf(title+" id=%s config=%s", container.id, configuration)

err = hcsCreateProcess(container.handle, configuration, &processInfo, &processHandle, &resultp)
err = processHcsResult(err, resultp)
Expand All @@ -379,6 +386,14 @@ func (container *container) CreateProcess(c *ProcessConfig) (Process, error) {
},
}

if hcsCallbacksSupported {
if err := process.registerCallback(); err != nil {
err = &ContainerError{Container: container, Operation: operation, Err: err}
logrus.Error(err)
return nil, err
}
}

logrus.Debugf(title+" succeeded id=%s processid=%s", container.id, process.processID)
runtime.SetFinalizer(process, closeProcess)
return process, nil
Expand Down Expand Up @@ -408,6 +423,12 @@ func (container *container) OpenProcess(pid int) (Process, error) {
container: container,
}

if err := process.registerCallback(); err != nil {
err = &ContainerError{Container: container, Operation: operation, Err: err}
logrus.Error(err)
return nil, err
}

logrus.Debugf(title+" succeeded id=%s processid=%s", container.id, process.processID)
runtime.SetFinalizer(process, closeProcess)
return process, nil
Expand All @@ -424,6 +445,14 @@ func (container *container) Close() error {
return nil
}

if hcsCallbacksSupported {
if err := container.unregisterCallback(); err != nil {
err = &ContainerError{Container: container, Operation: operation, Err: err}
logrus.Error(err)
return err
}
}

if err := hcsCloseComputeSystem(container.handle); err != nil {
err = &ContainerError{Container: container, Operation: operation, Err: err}
logrus.Error(err)
Expand All @@ -441,30 +470,32 @@ func closeContainer(container *container) {
container.Close()
}

func (container *container) registerCallback(expectedNotification hcsNotification) (uintptr, error) {
func (container *container) registerCallback() error {
callbackMapLock.Lock()
defer callbackMapLock.Unlock()

callbackNumber := nextCallback
nextCallback++

context := &notifcationWatcherContext{
expectedNotification: expectedNotification,
channel: make(chan error, 1),
channels: newChannels(),
}
callbackMap[callbackNumber] = context

var callbackHandle hcsCallback
err := hcsRegisterComputeSystemCallback(container.handle, notificationWatcherCallback, callbackNumber, &callbackHandle)
if err != nil {
return 0, err
return err
}
context.handle = callbackHandle
container.callbackNumber = callbackNumber

return callbackNumber, nil
return nil
}

func (container *container) unregisterCallback(callbackNumber uintptr) error {
func (container *container) unregisterCallback() error {
callbackNumber := container.callbackNumber

callbackMapLock.Lock()
defer callbackMapLock.Unlock()

Expand Down
11 changes: 8 additions & 3 deletions vendor/src/github.com/Microsoft/hcsshim/legacy.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"bufio"
"encoding/binary"
"errors"
"fmt"
"io"
"os"
"path/filepath"
Expand Down Expand Up @@ -77,7 +78,7 @@ func readTombstones(path string) (map[string]([]string), error) {

ts := make(map[string]([]string))
for s.Scan() {
t := s.Text()[1:] // skip leading `\`
t := filepath.Join("Files", s.Text()[1:]) // skip leading `\`
dir := filepath.Dir(t)
ts[dir] = append(ts[dir], t)
}
Expand Down Expand Up @@ -107,6 +108,7 @@ func (r *legacyLayerReader) walkUntilCancelled() error {
if path == r.root || path == filepath.Join(r.root, "tombstones.txt") || strings.HasSuffix(path, ".$wcidirs$") {
return nil
}

r.result <- &fileEntry{path, info, nil}
if !<-r.proceed {
return errorIterationCanceled
Expand All @@ -120,7 +122,7 @@ func (r *legacyLayerReader) walkUntilCancelled() error {
}
if dts, ok := ts[relPath]; ok {
for _, t := range dts {
r.result <- &fileEntry{t, nil, nil}
r.result <- &fileEntry{filepath.Join(r.root, t), nil, nil}
if !<-r.proceed {
return errorIterationCanceled
}
Expand Down Expand Up @@ -397,7 +399,10 @@ func (w *legacyLayerWriter) AddLink(name string, target string) error {
}

func (w *legacyLayerWriter) Remove(name string) error {
w.tombstones = append(w.tombstones, name)
if !strings.HasPrefix(name, `Files\`) {
return fmt.Errorf("invalid tombstone %s", name)
}
w.tombstones = append(w.tombstones, name[len(`Files\`):])
return nil
}

Expand Down
Loading

0 comments on commit d96e36c

Please sign in to comment.