Add exec and terminal support

Signed-off-by: Kenfe-Mickael Laventure <mickael.laventure@gmail.com>
This commit is contained in:
Kenfe-Mickael Laventure 2016-12-09 09:17:34 -08:00
parent aee6045292
commit 0aad42f5cf
10 changed files with 531 additions and 231 deletions

View File

@ -102,9 +102,10 @@ func (*StartContainerRequest) Descriptor() ([]byte, []int) { return fileDescript
type CreateContainerRequest struct {
ID string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"`
BundlePath string `protobuf:"bytes,2,opt,name=bundle_path,json=bundlePath,proto3" json:"bundle_path,omitempty"`
Stdin string `protobuf:"bytes,3,opt,name=stdin,proto3" json:"stdin,omitempty"`
Stdout string `protobuf:"bytes,4,opt,name=stdout,proto3" json:"stdout,omitempty"`
Stderr string `protobuf:"bytes,5,opt,name=stderr,proto3" json:"stderr,omitempty"`
Console bool `protobuf:"varint,3,opt,name=console,proto3" json:"console,omitempty"`
Stdin string `protobuf:"bytes,4,opt,name=stdin,proto3" json:"stdin,omitempty"`
Stdout string `protobuf:"bytes,5,opt,name=stdout,proto3" json:"stdout,omitempty"`
Stderr string `protobuf:"bytes,6,opt,name=stderr,proto3" json:"stderr,omitempty"`
}
func (m *CreateContainerRequest) Reset() { *m = CreateContainerRequest{} }
@ -146,9 +147,10 @@ func (*ListContainersResponse) Descriptor() ([]byte, []int) { return fileDescrip
type StartProcessRequest struct {
ContainerId string `protobuf:"bytes,1,opt,name=container_id,json=containerId,proto3" json:"container_id,omitempty"`
Process *Process `protobuf:"bytes,2,opt,name=process" json:"process,omitempty"`
Stdin string `protobuf:"bytes,3,opt,name=stdin,proto3" json:"stdin,omitempty"`
Stdout string `protobuf:"bytes,4,opt,name=stdout,proto3" json:"stdout,omitempty"`
Stderr string `protobuf:"bytes,5,opt,name=stderr,proto3" json:"stderr,omitempty"`
Console bool `protobuf:"varint,3,opt,name=console,proto3" json:"console,omitempty"`
Stdin string `protobuf:"bytes,4,opt,name=stdin,proto3" json:"stdin,omitempty"`
Stdout string `protobuf:"bytes,5,opt,name=stdout,proto3" json:"stdout,omitempty"`
Stderr string `protobuf:"bytes,6,opt,name=stderr,proto3" json:"stderr,omitempty"`
}
func (m *StartProcessRequest) Reset() { *m = StartProcessRequest{} }
@ -330,10 +332,11 @@ func (this *CreateContainerRequest) GoString() string {
if this == nil {
return "nil"
}
s := make([]string, 0, 9)
s := make([]string, 0, 10)
s = append(s, "&execution.CreateContainerRequest{")
s = append(s, "ID: "+fmt.Sprintf("%#v", this.ID)+",\n")
s = append(s, "BundlePath: "+fmt.Sprintf("%#v", this.BundlePath)+",\n")
s = append(s, "Console: "+fmt.Sprintf("%#v", this.Console)+",\n")
s = append(s, "Stdin: "+fmt.Sprintf("%#v", this.Stdin)+",\n")
s = append(s, "Stdout: "+fmt.Sprintf("%#v", this.Stdout)+",\n")
s = append(s, "Stderr: "+fmt.Sprintf("%#v", this.Stderr)+",\n")
@ -388,12 +391,13 @@ func (this *StartProcessRequest) GoString() string {
if this == nil {
return "nil"
}
s := make([]string, 0, 9)
s := make([]string, 0, 10)
s = append(s, "&execution.StartProcessRequest{")
s = append(s, "ContainerId: "+fmt.Sprintf("%#v", this.ContainerId)+",\n")
if this.Process != nil {
s = append(s, "Process: "+fmt.Sprintf("%#v", this.Process)+",\n")
}
s = append(s, "Console: "+fmt.Sprintf("%#v", this.Console)+",\n")
s = append(s, "Stdin: "+fmt.Sprintf("%#v", this.Stdin)+",\n")
s = append(s, "Stdout: "+fmt.Sprintf("%#v", this.Stdout)+",\n")
s = append(s, "Stderr: "+fmt.Sprintf("%#v", this.Stderr)+",\n")
@ -1136,20 +1140,30 @@ func (m *CreateContainerRequest) MarshalTo(dAtA []byte) (int, error) {
i = encodeVarintExecution(dAtA, i, uint64(len(m.BundlePath)))
i += copy(dAtA[i:], m.BundlePath)
}
if m.Console {
dAtA[i] = 0x18
i++
if m.Console {
dAtA[i] = 1
} else {
dAtA[i] = 0
}
i++
}
if len(m.Stdin) > 0 {
dAtA[i] = 0x1a
dAtA[i] = 0x22
i++
i = encodeVarintExecution(dAtA, i, uint64(len(m.Stdin)))
i += copy(dAtA[i:], m.Stdin)
}
if len(m.Stdout) > 0 {
dAtA[i] = 0x22
dAtA[i] = 0x2a
i++
i = encodeVarintExecution(dAtA, i, uint64(len(m.Stdout)))
i += copy(dAtA[i:], m.Stdout)
}
if len(m.Stderr) > 0 {
dAtA[i] = 0x2a
dAtA[i] = 0x32
i++
i = encodeVarintExecution(dAtA, i, uint64(len(m.Stderr)))
i += copy(dAtA[i:], m.Stderr)
@ -1303,20 +1317,30 @@ func (m *StartProcessRequest) MarshalTo(dAtA []byte) (int, error) {
}
i += n2
}
if m.Console {
dAtA[i] = 0x18
i++
if m.Console {
dAtA[i] = 1
} else {
dAtA[i] = 0
}
i++
}
if len(m.Stdin) > 0 {
dAtA[i] = 0x1a
dAtA[i] = 0x22
i++
i = encodeVarintExecution(dAtA, i, uint64(len(m.Stdin)))
i += copy(dAtA[i:], m.Stdin)
}
if len(m.Stdout) > 0 {
dAtA[i] = 0x22
dAtA[i] = 0x2a
i++
i = encodeVarintExecution(dAtA, i, uint64(len(m.Stdout)))
i += copy(dAtA[i:], m.Stdout)
}
if len(m.Stderr) > 0 {
dAtA[i] = 0x2a
dAtA[i] = 0x32
i++
i = encodeVarintExecution(dAtA, i, uint64(len(m.Stderr)))
i += copy(dAtA[i:], m.Stderr)
@ -1905,6 +1929,9 @@ func (m *CreateContainerRequest) Size() (n int) {
if l > 0 {
n += 1 + l + sovExecution(uint64(l))
}
if m.Console {
n += 2
}
l = len(m.Stdin)
if l > 0 {
n += 1 + l + sovExecution(uint64(l))
@ -1975,6 +2002,9 @@ func (m *StartProcessRequest) Size() (n int) {
l = m.Process.Size()
n += 1 + l + sovExecution(uint64(l))
}
if m.Console {
n += 2
}
l = len(m.Stdin)
if l > 0 {
n += 1 + l + sovExecution(uint64(l))
@ -2236,6 +2266,7 @@ func (this *CreateContainerRequest) String() string {
s := strings.Join([]string{`&CreateContainerRequest{`,
`ID:` + fmt.Sprintf("%v", this.ID) + `,`,
`BundlePath:` + fmt.Sprintf("%v", this.BundlePath) + `,`,
`Console:` + fmt.Sprintf("%v", this.Console) + `,`,
`Stdin:` + fmt.Sprintf("%v", this.Stdin) + `,`,
`Stdout:` + fmt.Sprintf("%v", this.Stdout) + `,`,
`Stderr:` + fmt.Sprintf("%v", this.Stderr) + `,`,
@ -2290,6 +2321,7 @@ func (this *StartProcessRequest) String() string {
s := strings.Join([]string{`&StartProcessRequest{`,
`ContainerId:` + fmt.Sprintf("%v", this.ContainerId) + `,`,
`Process:` + strings.Replace(fmt.Sprintf("%v", this.Process), "Process", "Process", 1) + `,`,
`Console:` + fmt.Sprintf("%v", this.Console) + `,`,
`Stdin:` + fmt.Sprintf("%v", this.Stdin) + `,`,
`Stdout:` + fmt.Sprintf("%v", this.Stdout) + `,`,
`Stderr:` + fmt.Sprintf("%v", this.Stderr) + `,`,
@ -2638,6 +2670,26 @@ func (m *CreateContainerRequest) Unmarshal(dAtA []byte) error {
m.BundlePath = string(dAtA[iNdEx:postIndex])
iNdEx = postIndex
case 3:
if wireType != 0 {
return fmt.Errorf("proto: wrong wireType = %d for field Console", wireType)
}
var v int
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowExecution
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
v |= (int(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
m.Console = bool(v != 0)
case 4:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field Stdin", wireType)
}
@ -2666,7 +2718,7 @@ func (m *CreateContainerRequest) Unmarshal(dAtA []byte) error {
}
m.Stdin = string(dAtA[iNdEx:postIndex])
iNdEx = postIndex
case 4:
case 5:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field Stdout", wireType)
}
@ -2695,7 +2747,7 @@ func (m *CreateContainerRequest) Unmarshal(dAtA []byte) error {
}
m.Stdout = string(dAtA[iNdEx:postIndex])
iNdEx = postIndex
case 5:
case 6:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field Stderr", wireType)
}
@ -3159,6 +3211,26 @@ func (m *StartProcessRequest) Unmarshal(dAtA []byte) error {
}
iNdEx = postIndex
case 3:
if wireType != 0 {
return fmt.Errorf("proto: wrong wireType = %d for field Console", wireType)
}
var v int
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowExecution
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
v |= (int(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
m.Console = bool(v != 0)
case 4:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field Stdin", wireType)
}
@ -3187,7 +3259,7 @@ func (m *StartProcessRequest) Unmarshal(dAtA []byte) error {
}
m.Stdin = string(dAtA[iNdEx:postIndex])
iNdEx = postIndex
case 4:
case 5:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field Stdout", wireType)
}
@ -3216,7 +3288,7 @@ func (m *StartProcessRequest) Unmarshal(dAtA []byte) error {
}
m.Stdout = string(dAtA[iNdEx:postIndex])
iNdEx = postIndex
case 5:
case 6:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field Stderr", wireType)
}
@ -5033,66 +5105,67 @@ var (
func init() { proto.RegisterFile("execution.proto", fileDescriptorExecution) }
var fileDescriptorExecution = []byte{
// 967 bytes of a gzipped FileDescriptorProto
// 980 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0xc4, 0x56, 0xdd, 0x6e, 0x1b, 0x45,
0x14, 0xce, 0xfa, 0x2f, 0xf1, 0x71, 0xb7, 0x98, 0x89, 0xb3, 0xac, 0x0c, 0xb8, 0xe9, 0xd2, 0x96,
0x08, 0x29, 0x4e, 0x30, 0x08, 0x21, 0x71, 0xd5, 0xc6, 0xc6, 0x44, 0x0a, 0xc6, 0x1d, 0xd7, 0xaa,
0xc4, 0x4d, 0xb4, 0xf1, 0x0e, 0xee, 0x22, 0x67, 0xd7, 0xdd, 0x99, 0x4d, 0xcb, 0x5d, 0xdf, 0x02,
0x6e, 0x78, 0x07, 0x1e, 0xa3, 0x97, 0x70, 0xc7, 0x15, 0x22, 0x7e, 0x02, 0x1e, 0x01, 0xcd, 0xcf,
0xfa, 0x67, 0x77, 0xed, 0x18, 0xb7, 0x12, 0x77, 0x33, 0x67, 0xbf, 0xf9, 0xe6, 0x3b, 0x73, 0x66,
0xbf, 0x39, 0xf0, 0x0e, 0x79, 0x49, 0x06, 0x21, 0x73, 0x7d, 0xaf, 0x3e, 0x0e, 0x7c, 0xe6, 0x23,
0x7d, 0xe0, 0x7b, 0xcc, 0x76, 0x3d, 0x12, 0x38, 0xf5, 0xab, 0x4f, 0xab, 0xef, 0x0f, 0x7d, 0x7f,
0x38, 0x22, 0x47, 0xe2, 0xe3, 0x45, 0xf8, 0xc3, 0x11, 0xb9, 0x1c, 0xb3, 0x9f, 0x24, 0xb6, 0x5a,
0x19, 0xfa, 0x43, 0x5f, 0x0c, 0x8f, 0xf8, 0x48, 0x46, 0xad, 0x23, 0xd8, 0xeb, 0x31, 0x3b, 0x60,
0x27, 0x11, 0x11, 0x26, 0xcf, 0x43, 0x42, 0x19, 0x32, 0x20, 0xe3, 0x3a, 0xa6, 0xb6, 0xaf, 0x1d,
0x14, 0x1f, 0x15, 0x26, 0x7f, 0xdd, 0xc9, 0x9c, 0x36, 0x71, 0xc6, 0x75, 0xac, 0x9f, 0x35, 0x30,
0x4e, 0x02, 0x62, 0x33, 0xb2, 0xee, 0x12, 0x74, 0x07, 0x4a, 0x17, 0xa1, 0xe7, 0x8c, 0xc8, 0xf9,
0xd8, 0x66, 0xcf, 0xcc, 0x0c, 0x07, 0x60, 0x90, 0xa1, 0xae, 0xcd, 0x9e, 0xa1, 0x0a, 0xe4, 0x29,
0x73, 0x5c, 0xcf, 0xcc, 0x8a, 0x4f, 0x72, 0x82, 0x0c, 0x28, 0x50, 0xe6, 0xf8, 0x21, 0x33, 0x73,
0x22, 0xac, 0x66, 0x2a, 0x4e, 0x82, 0xc0, 0xcc, 0x4f, 0xe3, 0x24, 0x08, 0xac, 0xc7, 0xf0, 0x5e,
0x42, 0x18, 0x1d, 0xfb, 0x1e, 0x25, 0xe8, 0x0b, 0x28, 0x4e, 0x4f, 0x4a, 0x08, 0x2c, 0x35, 0xcc,
0xfa, 0xc2, 0xd9, 0xd5, 0x67, 0x8b, 0x66, 0x50, 0xeb, 0x18, 0x8c, 0x26, 0x19, 0x91, 0xf5, 0x73,
0xb5, 0x0e, 0x61, 0xef, 0xcc, 0xa5, 0xb3, 0xe3, 0xa4, 0xd1, 0x82, 0x0a, 0xe4, 0xfd, 0x17, 0x72,
0xfb, 0x2c, 0xcf, 0x51, 0x4c, 0x2c, 0x0c, 0x46, 0x1c, 0xae, 0x24, 0x7f, 0x09, 0x30, 0xd5, 0x41,
0xc5, 0xa2, 0x55, 0x9a, 0xe7, 0xb0, 0xd6, 0x6f, 0x1a, 0xec, 0x8a, 0x9a, 0x76, 0x03, 0x7f, 0x40,
0xe8, 0x54, 0xc1, 0x5d, 0xb8, 0x35, 0x45, 0x9d, 0x47, 0xe2, 0x71, 0x69, 0x1a, 0x3b, 0x75, 0xd0,
0x31, 0x6c, 0x8f, 0xe5, 0x22, 0x51, 0xa5, 0x52, 0xc3, 0x88, 0xed, 0x18, 0x51, 0x46, 0xb0, 0xb7,
0x54, 0xba, 0x6f, 0xa0, 0xb2, 0xa8, 0x58, 0x1d, 0xc2, 0x9c, 0x1e, 0x6d, 0x2d, 0x3d, 0x16, 0x85,
0xe2, 0xf4, 0x54, 0x36, 0xbf, 0x90, 0x87, 0x5c, 0xa7, 0xcd, 0x42, 0x2a, 0xf4, 0xdf, 0x6e, 0xec,
0xc5, 0xb6, 0xed, 0x89, 0x8f, 0x58, 0x81, 0xac, 0x3f, 0x34, 0xd8, 0x56, 0x4a, 0x96, 0xee, 0x59,
0x86, 0xec, 0xd8, 0x75, 0xc4, 0x5e, 0x59, 0xcc, 0x87, 0x08, 0x41, 0xce, 0x0e, 0x86, 0xd4, 0xcc,
0x8a, 0x0b, 0x21, 0xc6, 0x1c, 0x45, 0xbc, 0x2b, 0x33, 0x27, 0x42, 0x7c, 0x88, 0x3e, 0x86, 0x5c,
0x48, 0x89, 0x3c, 0xb0, 0x52, 0x63, 0x37, 0x26, 0xa4, 0x4f, 0x49, 0x80, 0x05, 0x80, 0x2f, 0x1d,
0xbc, 0x70, 0xcc, 0x82, 0x48, 0x86, 0x0f, 0x51, 0x15, 0x76, 0x18, 0x09, 0x2e, 0x5d, 0xcf, 0x1e,
0x99, 0xdb, 0xfb, 0xda, 0xc1, 0x0e, 0x9e, 0xce, 0xf9, 0x11, 0x90, 0x97, 0x2e, 0x3b, 0x57, 0x69,
0xee, 0xec, 0x6b, 0x07, 0x3a, 0x06, 0x1e, 0x92, 0xb9, 0x59, 0x18, 0x72, 0x7d, 0x45, 0x1b, 0xaa,
0x84, 0x74, 0xcc, 0x87, 0x3c, 0x32, 0x54, 0x99, 0xe8, 0x98, 0x0f, 0xd1, 0x03, 0xb8, 0x6d, 0x3b,
0x8e, 0xcb, 0x8d, 0xc9, 0x1e, 0xb5, 0x5d, 0x47, 0xe6, 0xa4, 0xe3, 0x58, 0xd4, 0x3a, 0x84, 0xdd,
0x36, 0x59, 0xdf, 0x6a, 0x3a, 0x50, 0x59, 0x84, 0xbf, 0xe1, 0xdf, 0xfc, 0x1c, 0x8c, 0xfe, 0xd8,
0x49, 0x73, 0xae, 0x0d, 0x19, 0x6f, 0xbc, 0x48, 0xdc, 0x5e, 0xbb, 0x76, 0x48, 0xd7, 0xf7, 0x8f,
0x63, 0x30, 0x30, 0xa1, 0xe1, 0xe5, 0xfa, 0x2b, 0x7e, 0x84, 0x77, 0xdb, 0x24, 0xfe, 0xaf, 0x6f,
0x9a, 0xd0, 0x87, 0x00, 0xea, 0x4f, 0x3a, 0x57, 0x25, 0x2e, 0xe2, 0xa2, 0x8a, 0x9c, 0x3a, 0xd6,
0xd7, 0x80, 0xe6, 0xf7, 0xda, 0xf8, 0x2f, 0xfd, 0x45, 0x83, 0x4a, 0xcf, 0x1d, 0x7a, 0xf6, 0xe8,
0x2d, 0xe9, 0xfe, 0xef, 0xc6, 0xc5, 0xad, 0x48, 0x28, 0x10, 0xce, 0xa5, 0x63, 0x35, 0xb3, 0x5e,
0x69, 0x50, 0x91, 0x9e, 0xff, 0x7f, 0x49, 0xe3, 0xf7, 0x9e, 0x3f, 0x0a, 0x2a, 0x4e, 0xde, 0x54,
0x81, 0xf5, 0xad, 0x7c, 0x93, 0xe6, 0xf8, 0x54, 0xe1, 0x3e, 0x87, 0xa8, 0xb6, 0x24, 0x7a, 0x62,
0x96, 0x89, 0x9b, 0x01, 0x3f, 0xf9, 0x0a, 0x0a, 0xd2, 0x23, 0x50, 0x09, 0xb6, 0x4f, 0x70, 0xeb,
0xe1, 0x93, 0x56, 0xb3, 0xbc, 0xc5, 0x27, 0xb8, 0xdf, 0xe9, 0x9c, 0x76, 0xda, 0x65, 0x8d, 0x4f,
0x7a, 0x4f, 0xbe, 0xeb, 0x76, 0x5b, 0xcd, 0x72, 0x06, 0x01, 0x14, 0xba, 0x0f, 0xfb, 0xbd, 0x56,
0xb3, 0x9c, 0x6d, 0xfc, 0xba, 0x03, 0xe5, 0x56, 0xd4, 0xc5, 0xf4, 0x48, 0x70, 0xe5, 0x0e, 0x08,
0x7a, 0x0a, 0x05, 0xf9, 0x72, 0xa3, 0xfb, 0xf1, 0x7c, 0x52, 0x3b, 0x8d, 0xea, 0x83, 0x9b, 0x60,
0x2a, 0xc1, 0x16, 0xe4, 0xc5, 0xbb, 0x82, 0xee, 0x25, 0x0d, 0x3c, 0xd9, 0xf3, 0x54, 0x8d, 0xba,
0x6c, 0xa0, 0xea, 0x51, 0x03, 0x55, 0x6f, 0xf1, 0x06, 0x0a, 0xb5, 0xa1, 0x20, 0x8d, 0x23, 0xa1,
0x2f, 0xdd, 0x4f, 0x96, 0x12, 0xb5, 0x20, 0x2f, 0xec, 0x20, 0xa1, 0x27, 0xd5, 0x24, 0x56, 0xe9,
0x91, 0x26, 0x91, 0xd0, 0x93, 0xee, 0x1d, 0xab, 0x88, 0xe4, 0x5d, 0x4f, 0x10, 0xa5, 0xb7, 0x3d,
0x4b, 0x89, 0x3a, 0x90, 0x6d, 0x13, 0x86, 0xac, 0x18, 0x4b, 0x8a, 0xdb, 0x57, 0x3f, 0x5a, 0x89,
0x51, 0x85, 0xeb, 0x41, 0x8e, 0x5f, 0xd9, 0xc4, 0x39, 0xa5, 0xf6, 0x56, 0xd5, 0xfb, 0x37, 0xa0,
0x14, 0xe9, 0x53, 0xb8, 0x35, 0xdf, 0x65, 0x24, 0xd4, 0xa6, 0x34, 0x4d, 0x09, 0xb5, 0xa9, 0x6d,
0xca, 0x63, 0x80, 0x99, 0x2d, 0xa2, 0xfd, 0x64, 0x82, 0x31, 0xd2, 0xbb, 0x2b, 0x10, 0x8a, 0xf2,
0x0c, 0xf4, 0x05, 0x83, 0x44, 0x09, 0x21, 0x29, 0xf6, 0xb9, 0xb4, 0x3c, 0x67, 0xa0, 0x2f, 0x78,
0x5a, 0x82, 0x2d, 0xcd, 0xf1, 0x96, 0xb2, 0x7d, 0x0f, 0xfa, 0x82, 0x9f, 0x24, 0xd8, 0xd2, 0xdc,
0xab, 0x7a, 0x6f, 0x35, 0x48, 0xe6, 0xfd, 0xe8, 0x83, 0xd7, 0xd7, 0xb5, 0xad, 0x3f, 0xaf, 0x6b,
0x5b, 0xff, 0x5c, 0xd7, 0xb4, 0x57, 0x93, 0x9a, 0xf6, 0x7a, 0x52, 0xd3, 0x7e, 0x9f, 0xd4, 0xb4,
0xbf, 0x27, 0x35, 0xed, 0xa2, 0x20, 0x94, 0x7c, 0xf6, 0x6f, 0x00, 0x00, 0x00, 0xff, 0xff, 0x47,
0xce, 0x74, 0xfe, 0x09, 0x0d, 0x00, 0x00,
0x14, 0xce, 0xfa, 0x37, 0x3e, 0xee, 0x16, 0x33, 0x71, 0x96, 0x95, 0x01, 0x37, 0x5d, 0xda, 0x12,
0x21, 0xc5, 0x09, 0x06, 0x21, 0x24, 0xae, 0xda, 0xd8, 0x98, 0x48, 0xc1, 0xb8, 0xe3, 0x5a, 0x95,
0xb8, 0x89, 0x36, 0xde, 0xc1, 0x5d, 0xe4, 0xec, 0xba, 0x3b, 0xb3, 0x69, 0xb9, 0xeb, 0x63, 0x70,
0xc3, 0x43, 0xf0, 0x16, 0x15, 0x57, 0x70, 0xc7, 0x15, 0x22, 0x7e, 0x02, 0x1e, 0x01, 0xcd, 0xcf,
0xfa, 0x67, 0x77, 0xed, 0x98, 0x14, 0xc4, 0xdd, 0xcc, 0xd9, 0xef, 0x9c, 0xf9, 0xce, 0x39, 0xb3,
0xdf, 0x1c, 0x78, 0x8b, 0xbc, 0x24, 0xc3, 0x90, 0xb9, 0xbe, 0xd7, 0x98, 0x04, 0x3e, 0xf3, 0x91,
0x3e, 0xf4, 0x3d, 0x66, 0xbb, 0x1e, 0x09, 0x9c, 0xc6, 0xe5, 0xc7, 0xb5, 0x77, 0x47, 0xbe, 0x3f,
0x1a, 0x93, 0x43, 0xf1, 0xf1, 0x3c, 0xfc, 0xee, 0x90, 0x5c, 0x4c, 0xd8, 0x0f, 0x12, 0x5b, 0xab,
0x8e, 0xfc, 0x91, 0x2f, 0x96, 0x87, 0x7c, 0x25, 0xad, 0xd6, 0x21, 0xec, 0xf6, 0x99, 0x1d, 0xb0,
0xe3, 0x28, 0x10, 0x26, 0xcf, 0x43, 0x42, 0x19, 0x32, 0x20, 0xe3, 0x3a, 0xa6, 0xb6, 0xa7, 0xed,
0x97, 0x1e, 0x15, 0xa6, 0x7f, 0xdc, 0xc9, 0x9c, 0xb4, 0x70, 0xc6, 0x75, 0xac, 0x9f, 0x35, 0x30,
0x8e, 0x03, 0x62, 0x33, 0xb2, 0xa9, 0x0b, 0xba, 0x03, 0xe5, 0xf3, 0xd0, 0x73, 0xc6, 0xe4, 0x6c,
0x62, 0xb3, 0x67, 0x66, 0x86, 0x03, 0x30, 0x48, 0x53, 0xcf, 0x66, 0xcf, 0x90, 0x09, 0xc5, 0xa1,
0xef, 0x51, 0x7f, 0x4c, 0xcc, 0xec, 0x9e, 0xb6, 0xbf, 0x8d, 0xa3, 0x2d, 0xaa, 0x42, 0x9e, 0x32,
0xc7, 0xf5, 0xcc, 0x9c, 0x70, 0x92, 0x1b, 0x64, 0x40, 0x81, 0x32, 0xc7, 0x0f, 0x99, 0x99, 0x17,
0x66, 0xb5, 0x53, 0x76, 0x12, 0x04, 0x66, 0x61, 0x66, 0x27, 0x41, 0x60, 0x3d, 0x86, 0x77, 0x12,
0x94, 0xe9, 0xc4, 0xf7, 0x28, 0x41, 0x9f, 0x41, 0x69, 0x56, 0x43, 0x41, 0xbd, 0xdc, 0x34, 0x1b,
0x4b, 0x55, 0x6d, 0xcc, 0x9d, 0xe6, 0x50, 0xeb, 0x08, 0x8c, 0x16, 0x19, 0x93, 0xcd, 0xab, 0x60,
0x1d, 0xc0, 0xee, 0xa9, 0x4b, 0xe7, 0x85, 0xa6, 0x91, 0x43, 0x15, 0xf2, 0xfe, 0x0b, 0x79, 0x7c,
0x96, 0xe7, 0x28, 0x36, 0x16, 0x06, 0x23, 0x0e, 0x57, 0x94, 0x3f, 0x07, 0x98, 0xf1, 0xa0, 0xc2,
0x69, 0x1d, 0xe7, 0x05, 0xac, 0xf5, 0x8b, 0x06, 0x3b, 0xa2, 0xdb, 0xbd, 0xc0, 0x1f, 0x12, 0x3a,
0x63, 0x70, 0x17, 0x6e, 0xcd, 0x50, 0x67, 0x11, 0x79, 0x5c, 0x9e, 0xd9, 0x4e, 0x1c, 0x74, 0x04,
0xc5, 0x89, 0x74, 0x12, 0xfd, 0x2b, 0x37, 0x8d, 0xd8, 0x89, 0x51, 0xc8, 0x08, 0xf6, 0x9f, 0x37,
0xf5, 0x2b, 0xa8, 0x2e, 0xe7, 0xa2, 0xca, 0xb3, 0xc0, 0x54, 0xdb, 0x88, 0xa9, 0x45, 0xa1, 0x34,
0xab, 0xd7, 0xcd, 0x2f, 0xf1, 0x01, 0xe7, 0x69, 0xb3, 0x90, 0x8a, 0xb4, 0x6e, 0x37, 0x77, 0x63,
0xc7, 0xf6, 0xc5, 0x47, 0xac, 0x40, 0xd6, 0x6f, 0x1a, 0x14, 0x15, 0x93, 0x95, 0x67, 0x56, 0x20,
0x3b, 0x71, 0x1d, 0x71, 0x56, 0x16, 0xf3, 0x25, 0x42, 0x90, 0xb3, 0x83, 0x11, 0x35, 0xb3, 0xe2,
0xaa, 0x88, 0x35, 0x47, 0x11, 0xef, 0xd2, 0xcc, 0x09, 0x13, 0x5f, 0xa2, 0x0f, 0x21, 0x17, 0x52,
0x12, 0x88, 0x42, 0x96, 0x9b, 0x3b, 0x31, 0x22, 0x03, 0x4a, 0x02, 0x2c, 0x00, 0xdc, 0x75, 0xf8,
0xc2, 0x51, 0x85, 0xe5, 0x4b, 0x54, 0x83, 0x6d, 0x46, 0x82, 0x0b, 0xd7, 0xb3, 0xc7, 0x66, 0x51,
0xb4, 0x6d, 0xb6, 0xe7, 0x25, 0x20, 0x2f, 0x5d, 0x76, 0xa6, 0xd2, 0xdc, 0xde, 0xd3, 0xf6, 0x75,
0x0c, 0xdc, 0x24, 0x73, 0xb3, 0x30, 0xe4, 0x06, 0x2a, 0x6c, 0xa8, 0x12, 0xd2, 0x31, 0x5f, 0x72,
0xcb, 0x48, 0x65, 0xa2, 0x63, 0xbe, 0x44, 0x0f, 0xe0, 0xb6, 0xed, 0x38, 0x2e, 0x17, 0x33, 0x7b,
0xdc, 0x71, 0x1d, 0x99, 0x93, 0x8e, 0x63, 0x56, 0xeb, 0x00, 0x76, 0x3a, 0x64, 0x73, 0x79, 0xea,
0x42, 0x75, 0x19, 0xfe, 0x86, 0xff, 0xf9, 0x73, 0x30, 0x06, 0x13, 0x27, 0x4d, 0xed, 0x6e, 0x18,
0xf1, 0xda, 0x8b, 0xc4, 0x25, 0xb9, 0x67, 0x87, 0x74, 0x73, 0x65, 0x39, 0x02, 0x03, 0x13, 0x1a,
0x5e, 0x6c, 0xee, 0xf1, 0x3d, 0xbc, 0xdd, 0x21, 0x71, 0x15, 0xb8, 0x69, 0x42, 0xef, 0x03, 0xa8,
0x3f, 0xe9, 0x4c, 0xb5, 0xb8, 0x84, 0x4b, 0xca, 0x72, 0xe2, 0x58, 0x5f, 0x02, 0x5a, 0x3c, 0xeb,
0xc6, 0x7f, 0xe9, 0x8f, 0x1a, 0x54, 0xfb, 0xee, 0xc8, 0xb3, 0xc7, 0xff, 0x12, 0xef, 0x7f, 0x2e,
0x69, 0x5c, 0x8a, 0x04, 0x03, 0xa1, 0x68, 0x3a, 0x56, 0x3b, 0xeb, 0x95, 0x06, 0x55, 0xf9, 0x1a,
0xfc, 0x5f, 0xd4, 0xf8, 0xbd, 0xe7, 0xcf, 0x85, 0xb2, 0x93, 0x37, 0x65, 0x60, 0x7d, 0x2d, 0x5f,
0xab, 0x85, 0x78, 0xaa, 0x71, 0x9f, 0x42, 0xd4, 0x5b, 0x12, 0x3d, 0x3e, 0xab, 0xc8, 0xcd, 0x81,
0x1f, 0x7d, 0x01, 0x05, 0xa9, 0x11, 0xa8, 0x0c, 0xc5, 0x63, 0xdc, 0x7e, 0xf8, 0xa4, 0xdd, 0xaa,
0x6c, 0xf1, 0x0d, 0x1e, 0x74, 0xbb, 0x27, 0xdd, 0x4e, 0x45, 0xe3, 0x9b, 0xfe, 0x93, 0x6f, 0x7a,
0xbd, 0x76, 0xab, 0x92, 0x41, 0x00, 0x85, 0xde, 0xc3, 0x41, 0xbf, 0xdd, 0xaa, 0x64, 0x9b, 0x3f,
0x6d, 0x43, 0xa5, 0x1d, 0x4d, 0x3e, 0x7d, 0x12, 0x5c, 0xba, 0x43, 0x82, 0x9e, 0x42, 0x41, 0xbe,
0xe9, 0xe8, 0x7e, 0x3c, 0x9f, 0xd4, 0xe9, 0xa4, 0xf6, 0xe0, 0x3a, 0x98, 0x4a, 0xb0, 0x0d, 0x79,
0xf1, 0xae, 0xa0, 0x7b, 0x49, 0x01, 0x4f, 0xce, 0x49, 0x35, 0xa3, 0x21, 0x87, 0xae, 0x46, 0x34,
0x74, 0x35, 0xda, 0x7c, 0xe8, 0x42, 0x1d, 0x28, 0x48, 0xe1, 0x48, 0xf0, 0x4b, 0xd7, 0x93, 0x95,
0x81, 0xda, 0x90, 0x17, 0x72, 0x90, 0xe0, 0x93, 0x2a, 0x12, 0xeb, 0xf8, 0x48, 0x91, 0x48, 0xf0,
0x49, 0xd7, 0x8e, 0x75, 0x81, 0xe4, 0x5d, 0x4f, 0x04, 0x4a, 0x1f, 0x88, 0x56, 0x06, 0xea, 0x42,
0xb6, 0x43, 0x18, 0xb2, 0x62, 0x51, 0x52, 0xd4, 0xbe, 0xf6, 0xc1, 0x5a, 0x8c, 0x6a, 0x5c, 0x1f,
0x72, 0xfc, 0xca, 0x26, 0xea, 0x94, 0x3a, 0x75, 0xd5, 0xee, 0x5f, 0x83, 0x52, 0x41, 0x9f, 0xc2,
0xad, 0xc5, 0x29, 0x23, 0xc1, 0x36, 0x65, 0x9c, 0x4a, 0xb0, 0x4d, 0x1d, 0x53, 0x1e, 0x03, 0xcc,
0x65, 0x11, 0xed, 0x25, 0x13, 0x8c, 0x05, 0xbd, 0xbb, 0x06, 0xa1, 0x42, 0x9e, 0x82, 0xbe, 0x24,
0x90, 0x28, 0x41, 0x24, 0x45, 0x3e, 0x57, 0xb6, 0xe7, 0x14, 0xf4, 0x25, 0x4d, 0x4b, 0x44, 0x4b,
0x53, 0xbc, 0x95, 0xd1, 0xbe, 0x05, 0x7d, 0x49, 0x4f, 0x12, 0xd1, 0xd2, 0xd4, 0xab, 0x76, 0x6f,
0x3d, 0x48, 0xe6, 0xfd, 0xe8, 0xbd, 0xd7, 0x57, 0xf5, 0xad, 0xdf, 0xaf, 0xea, 0x5b, 0x7f, 0x5d,
0xd5, 0xb5, 0x57, 0xd3, 0xba, 0xf6, 0x7a, 0x5a, 0xd7, 0x7e, 0x9d, 0xd6, 0xb5, 0x3f, 0xa7, 0x75,
0xed, 0xbc, 0x20, 0x98, 0x7c, 0xf2, 0x77, 0x00, 0x00, 0x00, 0xff, 0xff, 0xeb, 0x07, 0xf1, 0x5d,
0x3d, 0x0d, 0x00, 0x00,
}

View File

@ -30,9 +30,10 @@ message StartContainerRequest {
message CreateContainerRequest {
string id = 1 [(gogoproto.customname) = "ID"];
string bundle_path = 2;
string stdin = 3;
string stdout = 4;
string stderr = 5;
bool console = 3;
string stdin = 4;
string stdout = 5;
string stderr = 6;
}
message CreateContainerResponse {
@ -54,9 +55,10 @@ message ListContainersResponse {
message StartProcessRequest {
string container_id = 1;
Process process = 2;
string stdin = 3;
string stdout = 4;
string stderr = 5;
bool console = 3;
string stdin = 4;
string stdout = 5;
string stderr = 6;
}
message StartProcessResponse {

87
cmd/ctr/exec.go Normal file
View File

@ -0,0 +1,87 @@
package main
import (
"os"
"path/filepath"
gocontext "context"
"github.com/docker/containerd/api/execution"
"github.com/urfave/cli"
)
var execCommand = cli.Command{
Name: "exec",
Usage: "exec a new process in a running container",
Flags: []cli.Flag{
cli.StringFlag{
Name: "id, i",
Usage: "target container id",
},
cli.StringFlag{
Name: "cwd, c",
Usage: "current working directory for the process",
},
cli.BoolFlag{
Name: "tty, t",
Usage: "create a terminal for the process",
},
cli.StringSliceFlag{
Name: "env, e",
Value: &cli.StringSlice{},
Usage: "environment variables for the process",
},
},
Action: func(context *cli.Context) error {
executionService, err := getExecutionService(context)
if err != nil {
return err
}
id := context.String("id")
tmpDir, err := getTempDir(id)
if err != nil {
return err
}
defer os.RemoveAll(tmpDir)
sOpts := &execution.StartProcessRequest{
ContainerId: id,
Process: &execution.Process{
Cwd: context.String("cwd"),
Terminal: context.Bool("tty"),
Args: context.Args(),
Env: context.StringSlice("env"),
},
Stdin: filepath.Join(tmpDir, "stdin"),
Stdout: filepath.Join(tmpDir, "stdout"),
Stderr: filepath.Join(tmpDir, "stderr"),
Console: context.Bool("tty"),
}
fwg, err := prepareStdio(sOpts.Stdin, sOpts.Stdout, sOpts.Stderr)
if err != nil {
return err
}
sr, err := executionService.StartProcess(gocontext.Background(), sOpts)
if err != nil {
return err
}
_, err = executionService.DeleteProcess(gocontext.Background(), &execution.DeleteProcessRequest{
Container: &execution.Container{
ID: id,
},
Process: sr.Process,
})
if err != nil {
return err
}
// Ensure we read all io
fwg.Wait()
return nil
},
}

View File

@ -14,12 +14,12 @@ func main() {
app.Name = "ctr"
app.Version = containerd.Version
app.Usage = `
__
__
_____/ /______
/ ___/ __/ ___/
/ /__/ /_/ /
\___/\__/_/
/ /__/ /_/ /
\___/\__/_/
containerd client
`
app.Flags = []cli.Flag{
@ -35,6 +35,7 @@ containerd client
}
app.Commands = []cli.Command{
runCommand,
execCommand,
}
app.Before = func(context *cli.Context) error {
if context.GlobalBool("debug") {

View File

@ -2,23 +2,13 @@ package main
import (
"fmt"
"io"
"io/ioutil"
"log"
"net"
"os"
"path/filepath"
"sync"
"syscall"
"time"
"google.golang.org/grpc"
"google.golang.org/grpc/grpclog"
gocontext "context"
"github.com/docker/containerd/api/execution"
"github.com/tonistiigi/fifo"
"github.com/urfave/cli"
)
@ -47,6 +37,10 @@ var runCommand = cli.Command{
Name: "bundle, b",
Usage: "path to the container's bundle",
},
cli.BoolFlag{
Name: "tty, t",
Usage: "allocate a TTY for the container",
},
},
Action: func(context *cli.Context) error {
// var config runConfig
@ -71,6 +65,7 @@ var runCommand = cli.Command{
crOpts := &execution.CreateContainerRequest{
ID: id,
BundlePath: context.String("bundle"),
Console: context.Bool("tty"),
Stdin: filepath.Join(tmpDir, "stdin"),
Stdout: filepath.Join(tmpDir, "stdout"),
Stderr: filepath.Join(tmpDir, "stderr"),
@ -118,103 +113,3 @@ var runCommand = cli.Command{
return nil
},
}
var grpcConn *grpc.ClientConn
func prepareStdio(in, out, err string) (*sync.WaitGroup, error) {
var (
wg sync.WaitGroup
dst io.Writer
src io.Reader
close func()
)
for _, f := range []struct {
name string
flags int
src bool
reader io.Reader
writer io.Writer
}{
{in, syscall.O_WRONLY | syscall.O_CREAT | syscall.O_NONBLOCK, false, os.Stdin, nil},
{out, syscall.O_RDONLY | syscall.O_CREAT | syscall.O_NONBLOCK, true, nil, os.Stdout},
{err, syscall.O_RDONLY | syscall.O_CREAT | syscall.O_NONBLOCK, true, nil, os.Stderr},
} {
ff, err := fifo.OpenFifo(gocontext.Background(), f.name, f.flags, 0700)
if err != nil {
return nil, err
}
defer func(c io.Closer) {
if err != nil {
c.Close()
}
}(ff)
if f.src {
src = ff
dst = f.writer
close = func() {
ff.Close()
wg.Done()
}
wg.Add(1)
} else {
src = f.reader
dst = ff
close = func() { ff.Close() }
}
go func(dst io.Writer, src io.Reader, close func()) {
io.Copy(dst, src)
close()
}(dst, src, close)
}
return &wg, nil
}
func getGRPCConnection(context *cli.Context) (*grpc.ClientConn, error) {
if grpcConn != nil {
return grpcConn, nil
}
bindSocket := context.GlobalString("socket")
// reset the logger for grpc to log to dev/null so that it does not mess with our stdio
grpclog.SetLogger(log.New(ioutil.Discard, "", log.LstdFlags))
dialOpts := []grpc.DialOption{grpc.WithInsecure(), grpc.WithTimeout(100 * time.Second)}
dialOpts = append(dialOpts,
grpc.WithDialer(func(addr string, timeout time.Duration) (net.Conn, error) {
return net.DialTimeout("unix", bindSocket, timeout)
},
))
conn, err := grpc.Dial(fmt.Sprintf("unix://%s", bindSocket), dialOpts...)
if err != nil {
return nil, err
}
grpcConn = conn
return grpcConn, nil
}
func getExecutionService(context *cli.Context) (execution.ExecutionServiceClient, error) {
conn, err := getGRPCConnection(context)
if err != nil {
return nil, err
}
return execution.NewExecutionServiceClient(conn), nil
}
func getTempDir(id string) (string, error) {
err := os.MkdirAll(filepath.Join(os.TempDir(), "ctr"), 0700)
if err != nil {
return "", err
}
tmpDir, err := ioutil.TempDir(filepath.Join(os.TempDir(), "ctr"), fmt.Sprintf("%s-", id))
if err != nil {
return "", err
}
return tmpDir, nil
}

122
cmd/ctr/utils.go Normal file
View File

@ -0,0 +1,122 @@
package main
import (
"fmt"
"io"
"io/ioutil"
"log"
"net"
"os"
"path/filepath"
"sync"
"syscall"
"time"
gocontext "context"
"github.com/docker/containerd/api/execution"
"github.com/tonistiigi/fifo"
"github.com/urfave/cli"
"google.golang.org/grpc"
"google.golang.org/grpc/grpclog"
)
var grpcConn *grpc.ClientConn
func prepareStdio(in, out, err string) (*sync.WaitGroup, error) {
var (
wg sync.WaitGroup
dst io.Writer
src io.Reader
close func()
)
for _, f := range []struct {
name string
flags int
src bool
reader io.Reader
writer io.Writer
}{
{in, syscall.O_WRONLY | syscall.O_CREAT | syscall.O_NONBLOCK, false, os.Stdin, nil},
{out, syscall.O_RDONLY | syscall.O_CREAT | syscall.O_NONBLOCK, true, nil, os.Stdout},
{err, syscall.O_RDONLY | syscall.O_CREAT | syscall.O_NONBLOCK, true, nil, os.Stderr},
} {
ff, err := fifo.OpenFifo(gocontext.Background(), f.name, f.flags, 0700)
if err != nil {
return nil, err
}
defer func(c io.Closer) {
if err != nil {
c.Close()
}
}(ff)
if f.src {
src = ff
dst = f.writer
close = func() {
ff.Close()
wg.Done()
}
wg.Add(1)
} else {
src = f.reader
dst = ff
close = func() { ff.Close() }
}
go func(dst io.Writer, src io.Reader, close func()) {
io.Copy(dst, src)
close()
}(dst, src, close)
}
return &wg, nil
}
func getGRPCConnection(context *cli.Context) (*grpc.ClientConn, error) {
if grpcConn != nil {
return grpcConn, nil
}
bindSocket := context.GlobalString("socket")
// reset the logger for grpc to log to dev/null so that it does not mess with our stdio
grpclog.SetLogger(log.New(ioutil.Discard, "", log.LstdFlags))
dialOpts := []grpc.DialOption{grpc.WithInsecure(), grpc.WithTimeout(100 * time.Second)}
dialOpts = append(dialOpts,
grpc.WithDialer(func(addr string, timeout time.Duration) (net.Conn, error) {
return net.DialTimeout("unix", bindSocket, timeout)
},
))
conn, err := grpc.Dial(fmt.Sprintf("unix://%s", bindSocket), dialOpts...)
if err != nil {
return nil, err
}
grpcConn = conn
return grpcConn, nil
}
func getExecutionService(context *cli.Context) (execution.ExecutionServiceClient, error) {
conn, err := getGRPCConnection(context)
if err != nil {
return nil, err
}
return execution.NewExecutionServiceClient(conn), nil
}
func getTempDir(id string) (string, error) {
err := os.MkdirAll(filepath.Join(os.TempDir(), "ctr"), 0700)
if err != nil {
return "", err
}
tmpDir, err := ioutil.TempDir(filepath.Join(os.TempDir(), "ctr"), fmt.Sprintf("%s-", id))
if err != nil {
return "", err
}
return tmpDir, nil
}

View File

@ -7,17 +7,19 @@ import (
)
type CreateOpts struct {
Bundle string
Stdin string
Stdout string
Stderr string
Bundle string
Console bool
Stdin string
Stdout string
Stderr string
}
type CreateProcessOpts struct {
Spec specs.Process
Stdin string
Stdout string
Stderr string
type StartProcessOpts struct {
Spec specs.Process
Console bool
Stdin string
Stdout string
Stderr string
}
type Executor interface {
@ -30,7 +32,7 @@ type Executor interface {
Delete(*Container) error
Start(*Container) error
StartProcess(*Container, CreateProcessOpts) (Process, error)
StartProcess(*Container, StartProcessOpts) (Process, error)
SignalProcess(*Container, string, os.Signal) error
DeleteProcess(*Container, string) error
}

View File

@ -0,0 +1,54 @@
package oci
import (
"fmt"
"os"
"syscall"
"unsafe"
)
// NewConsole returns an initialized console that can be used within a container by copying bytes
// from the master side to the slave that is attached as the tty for the container's init process.
func newConsole(uid, gid int) (*os.File, string, error) {
master, err := os.OpenFile("/dev/ptmx", syscall.O_RDWR|syscall.O_NOCTTY|syscall.O_CLOEXEC, 0)
if err != nil {
return nil, "", err
}
console, err := ptsname(master)
if err != nil {
return nil, "", err
}
if err := unlockpt(master); err != nil {
return nil, "", err
}
if err := os.Chmod(console, 0600); err != nil {
return nil, "", err
}
if err := os.Chown(console, uid, gid); err != nil {
return nil, "", err
}
return master, console, nil
}
func ioctl(fd uintptr, flag, data uintptr) error {
if _, _, err := syscall.Syscall(syscall.SYS_IOCTL, fd, flag, data); err != 0 {
return err
}
return nil
}
// unlockpt unlocks the slave pseudoterminal device corresponding to the master pseudoterminal referred to by f.
// unlockpt should be called before opening the slave side of a pty.
func unlockpt(f *os.File) error {
var u int32
return ioctl(f.Fd(), syscall.TIOCSPTLCK, uintptr(unsafe.Pointer(&u)))
}
// ptsname retrieves the name of the first available pts for the given master.
func ptsname(f *os.File) (string, error) {
var n int32
if err := ioctl(f.Fd(), syscall.TIOCGPTN, uintptr(unsafe.Pointer(&n))); err != nil {
return "", err
}
return fmt.Sprintf("/dev/pts/%d", n), nil
}

View File

@ -3,6 +3,7 @@ package oci
import (
"errors"
"fmt"
"io"
"os"
"path/filepath"
"syscall"
@ -62,16 +63,43 @@ func getRuncIO(stdin, stdout, stderr string) (io runc.IO, err error) {
return
}
func setupConsole(rio runc.IO) (*os.File, string, error) {
master, console, err := newConsole(0, 0)
if err != nil {
return nil, "", err
}
go io.Copy(master, rio.Stdin)
go func() {
io.Copy(rio.Stdout, master)
master.Close()
}()
return master, console, nil
}
func (r *OCIRuntime) Create(id string, o execution.CreateOpts) (container *execution.Container, err error) {
io, err := getRuncIO(o.Stdin, o.Stdout, o.Stderr)
rio, err := getRuncIO(o.Stdin, o.Stdout, o.Stderr)
if err != nil {
return nil, err
}
defer func() {
if err != nil {
closeRuncIO(io)
closeRuncIO(rio)
}
}()
consolePath := ""
if o.Console {
master, console, err := setupConsole(rio)
if err != nil {
return nil, err
}
consolePath = console
defer func() {
if err != nil {
master.Close()
}
}()
}
if container, err = execution.NewContainer(r.root, id, o.Bundle, "created"); err != nil {
return nil, err
@ -89,7 +117,8 @@ func (r *OCIRuntime) Create(id string, o execution.CreateOpts) (container *execu
pidFile := filepath.Join(initDir, "pid")
err = r.runc.Create(id, o.Bundle, &runc.CreateOpts{
PidFile: pidFile,
IO: io,
Console: consolePath,
IO: rio,
})
if err != nil {
return nil, err
@ -112,7 +141,7 @@ func (r *OCIRuntime) Create(id string, o execution.CreateOpts) (container *execu
container.AddProcess(process, true)
r.ios[id] = io
r.ios[id] = rio
return container, nil
}
@ -145,6 +174,10 @@ func (r *OCIRuntime) load(runcC *runc.Container) (*execution.Container, error) {
for _, d := range dirs {
pid, err := runc.ReadPidFile(filepath.Join(d, "pid"))
if err != nil {
if os.IsNotExist(err) {
// Process died in between
continue
}
return nil, err
}
process, err := newProcess(filepath.Base(d), pid)
@ -203,16 +236,29 @@ func (r *OCIRuntime) Resume(c *execution.Container) error {
return r.runc.Resume(c.ID())
}
func (r *OCIRuntime) StartProcess(c *execution.Container, o execution.CreateProcessOpts) (p execution.Process, err error) {
io, err := getRuncIO(o.Stdin, o.Stdout, o.Stderr)
func (r *OCIRuntime) StartProcess(c *execution.Container, o execution.StartProcessOpts) (p execution.Process, err error) {
rio, err := getRuncIO(o.Stdin, o.Stdout, o.Stderr)
if err != nil {
return nil, err
}
defer func() {
if err != nil {
closeRuncIO(io)
closeRuncIO(rio)
}
}()
consolePath := ""
if o.Console {
master, console, err := setupConsole(rio)
if err != nil {
return nil, err
}
consolePath = console
defer func() {
if err != nil {
master.Close()
}
}()
}
processStateDir, err := c.StateDir().NewProcess()
if err != nil {
@ -227,8 +273,10 @@ func (r *OCIRuntime) StartProcess(c *execution.Container, o execution.CreateProc
pidFile := filepath.Join(processStateDir, "pid")
if err := r.runc.ExecProcess(c.ID(), o.Spec, &runc.ExecOpts{
PidFile: pidFile,
Detach: true,
IO: io,
Detach: false,
Console: consolePath,
Cwd: o.Spec.Cwd,
IO: rio,
}); err != nil {
return nil, err
}
@ -244,7 +292,7 @@ func (r *OCIRuntime) StartProcess(c *execution.Container, o execution.CreateProc
c.AddProcess(process, false)
r.ios[fmt.Sprintf("%s-%s", c.ID(), process.ID())] = io
r.ios[fmt.Sprintf("%s-%s", c.ID(), process.ID())] = rio
return process, nil
}

View File

@ -10,7 +10,10 @@ import (
"golang.org/x/net/context"
)
var emptyResponse = &google_protobuf.Empty{}
var (
emptyResponse = &google_protobuf.Empty{}
ErrProcessNotFound = fmt.Errorf("Process not found")
)
func New(executor Executor) (*Service, error) {
return &Service{
@ -28,10 +31,11 @@ func (s *Service) Create(ctx context.Context, r *api.CreateContainerRequest) (*a
var err error
container, err := s.executor.Create(r.ID, CreateOpts{
Bundle: r.BundlePath,
Stdin: r.Stdin,
Stdout: r.Stdout,
Stderr: r.Stderr,
Bundle: r.BundlePath,
Console: r.Console,
Stdin: r.Stdin,
Stdout: r.Stdout,
Stderr: r.Stderr,
})
if err != nil {
return nil, err
@ -112,12 +116,24 @@ func (s *Service) StartProcess(ctx context.Context, r *api.StartProcessRequest)
}
// TODO: generate spec
var spec specs.Process
process, err := s.executor.StartProcess(container, CreateProcessOpts{
Spec: spec,
Stdin: r.Stdin,
Stdout: r.Stdout,
Stderr: r.Stderr,
spec := specs.Process{
Terminal: r.Process.Terminal,
ConsoleSize: specs.Box{
80,
80,
},
Args: r.Process.Args,
Env: r.Process.Env,
Cwd: r.Process.Cwd,
NoNewPrivileges: true,
}
process, err := s.executor.StartProcess(container, StartProcessOpts{
Spec: spec,
Console: r.Console,
Stdin: r.Stdin,
Stdout: r.Stdout,
Stderr: r.Stderr,
})
if err != nil {
return nil, err
@ -137,7 +153,7 @@ func (s *Service) GetProcess(ctx context.Context, r *api.GetProcessRequest) (*ap
}
process := container.GetProcess(r.ProcessId)
if process == nil {
return nil, fmt.Errorf("Make me a constant! Process not foumd!")
return nil, ErrProcessNotFound
}
return &api.GetProcessResponse{
Process: toGRPCProcess(process),