| package hcsshim |
| |
| import ( |
| "encoding/json" |
| "fmt" |
| "syscall" |
| "unsafe" |
| |
| "github.com/Sirupsen/logrus" |
| ) |
| |
| // processParameters is use to both the input of CreateProcessInComputeSystem |
| // and to convert the parameters to JSON for passing onto the HCS |
| type CreateProcessParams struct { |
| ApplicationName string |
| CommandLine string |
| WorkingDirectory string |
| StdInPipe, StdOutPipe, StdErrPipe string |
| Environment map[string]string |
| EmulateConsole bool |
| ConsoleSize [2]int |
| } |
| |
| // CreateProcessInComputeSystem starts a process in a container. This is invoked, for example, |
| // as a result of docker run, docker exec, or RUN in Dockerfile. If successful, |
| // it returns the PID of the process. |
| func CreateProcessInComputeSystem(id string, params CreateProcessParams) (processid uint32, err error) { |
| |
| title := "HCSShim::CreateProcessInComputeSystem" |
| logrus.Debugf(title+"id=%s params=%s", id, params) |
| |
| // Load the DLL and get a handle to the procedure we need |
| dll, proc, err := loadAndFind(procCreateProcessInComputeSystem) |
| if dll != nil { |
| defer dll.Release() |
| } |
| if err != nil { |
| return 0, err |
| } |
| |
| // Convert id to uint16 pointer for calling the procedure |
| idp, err := syscall.UTF16PtrFromString(id) |
| if err != nil { |
| err = fmt.Errorf(title+" - Failed conversion of id %s to pointer %s", id, err) |
| logrus.Error(err) |
| return 0, err |
| } |
| |
| // If we are not emulating a console, ignore any console size passed to us |
| if !params.EmulateConsole { |
| params.ConsoleSize[0] = 0 |
| params.ConsoleSize[1] = 0 |
| } |
| |
| paramsJson, err := json.Marshal(params) |
| if err != nil { |
| err = fmt.Errorf(title+" - Failed to marshall params %v %s", params, err) |
| return 0, err |
| } |
| |
| // Convert paramsJson to uint16 pointer for calling the procedure |
| paramsJsonp, err := syscall.UTF16PtrFromString(string(paramsJson)) |
| if err != nil { |
| return 0, err |
| } |
| |
| // Get a POINTER to variable to take the pid outparm |
| pid := new(uint32) |
| |
| logrus.Debugf(title+" - Calling the procedure itself %s %s", id, paramsJson) |
| |
| // Call the procedure itself. |
| r1, _, _ := proc.Call( |
| uintptr(unsafe.Pointer(idp)), |
| uintptr(unsafe.Pointer(paramsJsonp)), |
| uintptr(unsafe.Pointer(pid))) |
| |
| use(unsafe.Pointer(idp)) |
| use(unsafe.Pointer(paramsJsonp)) |
| |
| if r1 != 0 { |
| err = fmt.Errorf(title+" - Win32 API call returned error r1=%d err=%s id=%s params=%v", r1, syscall.Errno(r1), id, params) |
| logrus.Error(err) |
| return 0, err |
| } |
| |
| logrus.Debugf(title+" - succeeded id=%s params=%s pid=%d", id, paramsJson, *pid) |
| return *pid, nil |
| } |