feat: add support for osctl logs -f

Now default is not to follow the logs (which is similar to `kubectl logs`).

Integration test was added for `Logs()` API and `osctl logs` command.

Signed-off-by: Andrey Smirnov <smirnov.andrey@gmail.com>
This commit is contained in:
Andrey Smirnov 2019-12-05 21:20:27 +03:00 committed by Andrew Rynhard
parent 509ec5b6ff
commit edb40437ec
15 changed files with 443 additions and 147 deletions

View File

@ -1985,6 +1985,7 @@ type LogsRequest struct {
Id string `protobuf:"bytes,2,opt,name=id,proto3" json:"id,omitempty"`
// driver might be default "containerd" or "cri"
Driver common.ContainerDriver `protobuf:"varint,3,opt,name=driver,proto3,enum=common.ContainerDriver" json:"driver,omitempty"`
Follow bool `protobuf:"varint,4,opt,name=follow,proto3" json:"follow,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
@ -2040,6 +2041,13 @@ func (m *LogsRequest) GetDriver() common.ContainerDriver {
return common.ContainerDriver_CONTAINERD
}
func (m *LogsRequest) GetFollow() bool {
if m != nil {
return m.Follow
}
return false
}
type ReadRequest struct {
Path string `protobuf:"bytes,1,opt,name=path,proto3" json:"path,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
@ -2129,100 +2137,101 @@ func init() {
func init() { proto.RegisterFile("machine/machine.proto", fileDescriptor_84b4f59d98cc997c) }
var fileDescriptor_84b4f59d98cc997c = []byte{
// 1483 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xac, 0x58, 0xdd, 0x6f, 0x13, 0xc7,
0x16, 0xd7, 0x3a, 0x1f, 0xb6, 0x8f, 0x13, 0x07, 0x26, 0x1f, 0x18, 0x13, 0xbe, 0x16, 0xee, 0x05,
0x21, 0xc5, 0xe1, 0x86, 0x80, 0xb8, 0x70, 0x75, 0x45, 0x21, 0x41, 0x54, 0x24, 0x80, 0x36, 0x6d,
0xa5, 0xf6, 0xc5, 0x1d, 0xdb, 0x13, 0x7b, 0xc4, 0xee, 0xce, 0x76, 0x67, 0x1c, 0x94, 0xaa, 0x7d,
0x6f, 0xfb, 0xda, 0x3f, 0xa1, 0x6f, 0xfd, 0x23, 0xab, 0x6a, 0x3e, 0x3d, 0x5e, 0xc7, 0x01, 0xd5,
0x3c, 0x79, 0xe6, 0xcc, 0xd9, 0x73, 0xce, 0xef, 0x7c, 0xcd, 0x19, 0xc3, 0x7a, 0x82, 0xbb, 0x03,
0x9a, 0x92, 0x6d, 0xf3, 0xdb, 0xca, 0x72, 0x26, 0x18, 0x2a, 0x9b, 0x6d, 0xf3, 0x4a, 0x9f, 0xb1,
0x7e, 0x4c, 0xb6, 0x15, 0xb9, 0x33, 0x3c, 0xde, 0x26, 0x49, 0x26, 0x4e, 0x35, 0x57, 0xf3, 0x7a,
0xf1, 0x50, 0xd0, 0x84, 0x70, 0x81, 0x93, 0xcc, 0x30, 0xac, 0x76, 0x59, 0x92, 0xb0, 0x74, 0x5b,
0xff, 0x68, 0x62, 0xf8, 0x12, 0xea, 0x11, 0xe9, 0x30, 0x26, 0x22, 0xc2, 0x33, 0x96, 0x72, 0x82,
0x76, 0xa1, 0x92, 0x10, 0x81, 0x7b, 0x58, 0xe0, 0x46, 0x70, 0x23, 0xb8, 0x5b, 0xdb, 0x69, 0xb4,
0xcc, 0x27, 0x96, 0xe7, 0xd0, 0x9c, 0x47, 0x8e, 0x33, 0x7c, 0x0e, 0x35, 0x2b, 0x27, 0x8b, 0x4f,
0xd1, 0x03, 0xa8, 0xe4, 0x86, 0xb9, 0x11, 0xdc, 0x98, 0xbb, 0x5b, 0xdb, 0xb9, 0xd4, 0xb2, 0xa0,
0xc6, 0xf5, 0x45, 0x8e, 0x31, 0xdc, 0x87, 0xe5, 0x88, 0x70, 0x32, 0xab, 0x29, 0xcf, 0x00, 0x8c,
0x18, 0x69, 0xc9, 0xce, 0x84, 0x25, 0x1b, 0x9e, 0x25, 0x9e, 0x36, 0xcf, 0x90, 0x57, 0x70, 0xe1,
0x68, 0x30, 0x14, 0x3d, 0xf6, 0x21, 0x9d, 0xd1, 0x96, 0x97, 0xb0, 0x3c, 0x92, 0x24, 0xcd, 0x79,
0x38, 0x61, 0xce, 0x65, 0x67, 0x4e, 0x51, 0xa7, 0x67, 0xd1, 0xbf, 0xa1, 0xfe, 0x75, 0xd6, 0xcf,
0x71, 0x8f, 0x44, 0xe4, 0x87, 0x21, 0xe1, 0x02, 0xad, 0xc1, 0x02, 0x4d, 0x70, 0x9f, 0x28, 0x63,
0xaa, 0x91, 0xde, 0x84, 0xdf, 0xc2, 0x8a, 0xe3, 0x9b, 0xc5, 0x70, 0x74, 0x01, 0xe6, 0x70, 0xf7,
0x7d, 0xa3, 0xa4, 0x84, 0xcb, 0x65, 0xb8, 0x07, 0x4b, 0x4e, 0xb4, 0x44, 0xb2, 0x3b, 0x81, 0xa4,
0xe1, 0x90, 0x14, 0x6c, 0xf0, 0x80, 0xfc, 0x0c, 0xab, 0x47, 0x24, 0x3f, 0xa1, 0x5d, 0x72, 0x40,
0xf9, 0x8c, 0x91, 0x46, 0xf7, 0xa1, 0xc2, 0xb5, 0x30, 0xde, 0x28, 0x29, 0x13, 0xd6, 0x46, 0xce,
0xd4, 0x07, 0x5f, 0xa6, 0xc7, 0x2c, 0x72, 0x5c, 0xe1, 0x01, 0x5c, 0x18, 0x53, 0x2f, 0x81, 0x3c,
0x9e, 0x00, 0xb2, 0x59, 0x94, 0xe2, 0xdb, 0xea, 0x81, 0xf9, 0x3d, 0x80, 0x9a, 0xa7, 0x07, 0xd5,
0xa1, 0x44, 0x7b, 0x26, 0x20, 0x25, 0xda, 0x93, 0x31, 0xe2, 0x02, 0x0b, 0x62, 0xdc, 0xa8, 0x37,
0xa8, 0x05, 0x8b, 0xe4, 0x84, 0xa4, 0x82, 0x37, 0xe6, 0x14, 0xd2, 0x8d, 0xa2, 0xb6, 0x7d, 0x75,
0x1a, 0x19, 0x2e, 0xc9, 0x3f, 0x20, 0x38, 0x16, 0x83, 0xc6, 0xfc, 0xd9, 0xfc, 0xaf, 0xd4, 0x69,
0x64, 0xb8, 0xc2, 0xff, 0xc3, 0xf2, 0x98, 0x20, 0xb4, 0xe5, 0x14, 0x6a, 0x78, 0xeb, 0x67, 0x2a,
0xb4, 0xfa, 0xc2, 0x0e, 0x2c, 0xf9, 0x74, 0x99, 0x0a, 0x09, 0xef, 0x1b, 0x58, 0x72, 0x39, 0x05,
0xd7, 0x3d, 0x28, 0x39, 0x4c, 0xcd, 0x96, 0xee, 0x46, 0x2d, 0xdb, 0x8d, 0x5a, 0x5f, 0xd9, 0x6e,
0x14, 0x95, 0x04, 0x0f, 0xff, 0x08, 0x9c, 0x91, 0xda, 0x7a, 0xd4, 0x80, 0xf2, 0x30, 0x7d, 0x9f,
0xb2, 0x0f, 0xa9, 0xd2, 0x54, 0x89, 0xec, 0x56, 0x9e, 0x68, 0x64, 0xa7, 0x4a, 0x5f, 0x25, 0xb2,
0x5b, 0x74, 0x13, 0x96, 0x62, 0xcc, 0x45, 0x3b, 0x21, 0x9c, 0xcb, 0x52, 0x98, 0x53, 0xe6, 0xd4,
0x24, 0xed, 0x50, 0x93, 0xd0, 0x53, 0x50, 0xdb, 0x76, 0x77, 0x80, 0xd3, 0x3e, 0x31, 0x1e, 0x3c,
0xcf, 0x3a, 0x90, 0xec, 0x2f, 0x14, 0x77, 0xf8, 0x2f, 0x97, 0xac, 0x47, 0x02, 0xe7, 0xc2, 0x96,
0x5e, 0x21, 0xcc, 0xe1, 0xf7, 0xb0, 0x36, 0xce, 0x36, 0x53, 0x52, 0x23, 0x98, 0x97, 0x09, 0x66,
0x7c, 0xab, 0xd6, 0xe1, 0x1b, 0xb8, 0x38, 0xae, 0x41, 0xe6, 0xed, 0x7f, 0x27, 0xf2, 0xf6, 0x6a,
0x31, 0xb0, 0x63, 0xf6, 0x78, 0x89, 0x7b, 0x1b, 0x90, 0xe3, 0x60, 0xd9, 0x34, 0x5c, 0x6d, 0x0f,
0xbe, 0xe4, 0xfa, 0xec, 0xb0, 0x46, 0xd5, 0xa8, 0x15, 0x7c, 0x62, 0x35, 0xfa, 0xd6, 0x78, 0xa0,
0xee, 0xc0, 0xba, 0x61, 0x88, 0x64, 0x2c, 0xa7, 0xc7, 0xab, 0x03, 0x1b, 0x45, 0xc6, 0xcf, 0x0e,
0x2d, 0x72, 0xbe, 0x73, 0x3a, 0x24, 0xba, 0xa7, 0x13, 0xe8, 0xae, 0x17, 0xd1, 0x15, 0x6c, 0xf2,
0x00, 0x86, 0xb0, 0x74, 0x5e, 0x1e, 0x3e, 0x29, 0x35, 0x82, 0xf0, 0x36, 0x80, 0x97, 0x22, 0xd6,
0xb2, 0x60, 0x64, 0x99, 0xe2, 0xba, 0x09, 0xb5, 0x73, 0x02, 0xaf, 0x58, 0x6e, 0x41, 0x75, 0x14,
0x94, 0x69, 0x72, 0xb6, 0xa0, 0xfe, 0x82, 0x65, 0xa7, 0x6f, 0x87, 0xce, 0xa6, 0x2b, 0x50, 0xcd,
0x19, 0x13, 0xed, 0x0c, 0x8b, 0x81, 0x61, 0xaf, 0x48, 0xc2, 0x3b, 0x2c, 0x06, 0x61, 0x07, 0xaa,
0x07, 0x47, 0x96, 0x53, 0xca, 0x64, 0x4c, 0x38, 0x99, 0x8c, 0x09, 0x59, 0xea, 0x39, 0xe9, 0x0e,
0x73, 0x4e, 0x6c, 0xa9, 0x9b, 0x2d, 0xba, 0x03, 0x2b, 0x7a, 0x49, 0x59, 0xda, 0xee, 0x91, 0x4c,
0x0c, 0x54, 0xb5, 0x2f, 0x44, 0x75, 0x47, 0xde, 0x93, 0xd4, 0xf0, 0xaf, 0x00, 0x2a, 0x2f, 0x69,
0xac, 0x1b, 0xf2, 0x3f, 0x8e, 0x67, 0x8a, 0x13, 0xdb, 0xdd, 0xd4, 0x5a, 0xd2, 0x38, 0xfd, 0x51,
0xb7, 0x98, 0xb9, 0x48, 0xad, 0x25, 0x2d, 0x61, 0x3d, 0xdd, 0x54, 0x96, 0x23, 0xb5, 0x46, 0x4d,
0xa8, 0x24, 0xac, 0x47, 0x8f, 0x29, 0xe9, 0x35, 0x16, 0x14, 0xaf, 0xdb, 0xa3, 0x75, 0x58, 0xa4,
0xbc, 0xdd, 0xa3, 0x79, 0x63, 0x51, 0x81, 0x5b, 0xa0, 0x7c, 0x8f, 0xe6, 0xb2, 0x9b, 0x92, 0x3c,
0x67, 0x79, 0xa3, 0xac, 0xbb, 0xa9, 0xda, 0x48, 0xe1, 0x31, 0x4d, 0xdf, 0x37, 0x2a, 0xda, 0x08,
0xb9, 0x46, 0xb7, 0x60, 0x39, 0x27, 0x31, 0x16, 0xf4, 0x84, 0xb4, 0x95, 0x85, 0x55, 0x75, 0xb8,
0x64, 0x89, 0x6f, 0x70, 0x42, 0xc2, 0x0c, 0xea, 0x87, 0x6c, 0x28, 0x2f, 0x90, 0xd9, 0xb2, 0xfa,
0xae, 0x6e, 0xf2, 0xf6, 0x66, 0x45, 0x2e, 0x4f, 0x95, 0xf4, 0x23, 0x81, 0x85, 0x6e, 0xfc, 0x5c,
0xce, 0x7e, 0x56, 0xe3, 0xc7, 0x66, 0xbf, 0x71, 0xcb, 0xbc, 0xdc, 0xfe, 0x09, 0xaa, 0x4e, 0x2e,
0xba, 0x06, 0x70, 0x4c, 0x63, 0xc2, 0x4f, 0xb9, 0x20, 0x89, 0x49, 0x10, 0x8f, 0xe2, 0x82, 0x21,
0x03, 0x34, 0x6f, 0x82, 0xb1, 0x09, 0x55, 0x7c, 0x82, 0x69, 0x8c, 0x3b, 0xb1, 0x8e, 0xd2, 0x7c,
0x34, 0x22, 0xa0, 0xab, 0x00, 0x89, 0x14, 0x4f, 0x7a, 0x6d, 0x96, 0xaa, 0x80, 0x55, 0xa3, 0xaa,
0xa1, 0xbc, 0x4d, 0xc3, 0x3f, 0x03, 0x58, 0xf9, 0x86, 0xa8, 0x2c, 0x9a, 0xd1, 0x6b, 0x2d, 0x28,
0x9f, 0x68, 0x41, 0xca, 0x3a, 0x7f, 0x22, 0x31, 0x0a, 0xd4, 0x44, 0x62, 0x99, 0xd0, 0x7f, 0xa0,
0x92, 0xc5, 0x58, 0x1c, 0xb3, 0x3c, 0x31, 0x57, 0xe7, 0xe8, 0x76, 0x7e, 0x67, 0x0e, 0xf4, 0x0c,
0x63, 0xd9, 0xe4, 0x20, 0xe6, 0x6c, 0xfd, 0xd8, 0x20, 0x56, 0x00, 0xe5, 0x39, 0xfc, 0xb7, 0x00,
0x6a, 0x9e, 0x45, 0xf2, 0x96, 0x17, 0xd8, 0xdd, 0xf2, 0x02, 0xf7, 0x25, 0x85, 0x0f, 0xb0, 0x1d,
0x01, 0xf9, 0x00, 0xcb, 0x4c, 0xed, 0x0c, 0x69, 0x2c, 0xcc, 0x45, 0xab, 0x37, 0xd2, 0xb7, 0x7d,
0xd6, 0xb6, 0xa8, 0x8d, 0x6f, 0xfb, 0xcc, 0x08, 0x97, 0xcd, 0x85, 0x71, 0x55, 0x0b, 0xd5, 0xa8,
0xc4, 0xb8, 0x0c, 0x1e, 0xce, 0xbb, 0x03, 0x55, 0x03, 0xd5, 0x48, 0xad, 0xc3, 0x47, 0xb0, 0xe4,
0x83, 0x75, 0x15, 0x18, 0x8c, 0x57, 0xa0, 0xaa, 0x36, 0x53, 0x95, 0x72, 0x1d, 0xc6, 0x50, 0x3b,
0x60, 0x7d, 0x6e, 0x5b, 0xca, 0x26, 0x54, 0x25, 0x2b, 0xcf, 0x70, 0xd7, 0x7e, 0x3b, 0x22, 0x98,
0x2e, 0x57, 0x72, 0xd3, 0xd9, 0x36, 0x2c, 0xf6, 0x72, 0x7a, 0x42, 0x72, 0x05, 0xa7, 0xbe, 0x73,
0xc9, 0x86, 0xf7, 0x05, 0x4b, 0x05, 0xa6, 0x29, 0xc9, 0xf7, 0xd4, 0x71, 0x64, 0xd8, 0x64, 0xd7,
0x8c, 0x08, 0xee, 0x79, 0x0d, 0xcc, 0xeb, 0x72, 0x6a, 0xbd, 0xf3, 0x6b, 0x05, 0xca, 0x87, 0xda,
0xf7, 0xe8, 0x09, 0x94, 0x4d, 0x73, 0x44, 0xa3, 0x02, 0x18, 0x6f, 0x97, 0xcd, 0x35, 0xab, 0x73,
0x4f, 0xa6, 0x91, 0x89, 0xcd, 0xfd, 0x00, 0xfd, 0x0f, 0xe0, 0xf5, 0xb0, 0x43, 0xba, 0x2c, 0x3d,
0xa6, 0x7d, 0xb4, 0x31, 0x31, 0xaf, 0xec, 0xcb, 0x87, 0xdf, 0xd4, 0xaf, 0xb7, 0xa0, 0x74, 0x70,
0x84, 0x46, 0x15, 0xeb, 0x9a, 0x6e, 0xf3, 0xa2, 0xa3, 0xd9, 0x1e, 0x79, 0x3f, 0x40, 0xbb, 0x30,
0x2f, 0xbd, 0x88, 0x46, 0xa9, 0xea, 0x39, 0x75, 0xaa, 0x92, 0x47, 0xb0, 0xa8, 0xab, 0xf9, 0x1c,
0xf3, 0x8a, 0x65, 0xaf, 0xd3, 0x75, 0x5e, 0x7a, 0xd1, 0xd3, 0xe6, 0x39, 0xf5, 0x3c, 0x6d, 0xfa,
0xdd, 0xf8, 0x09, 0xda, 0xfc, 0x87, 0xe8, 0x2e, 0x2c, 0xa8, 0x57, 0xde, 0xd4, 0xcf, 0x56, 0x8b,
0xaf, 0x41, 0xf9, 0xd5, 0x33, 0x37, 0xd7, 0xcb, 0xc9, 0x7f, 0xea, 0xb7, 0x97, 0xcf, 0x7e, 0x27,
0x48, 0x09, 0x6f, 0xa0, 0x3e, 0x7e, 0x9f, 0xa3, 0x6b, 0x53, 0x2f, 0x7a, 0x8d, 0x7c, 0x73, 0xea,
0xb9, 0x94, 0xf7, 0xca, 0x0d, 0xe5, 0xea, 0x7a, 0x47, 0x9b, 0x53, 0x46, 0x3d, 0x2d, 0xab, 0x39,
0xe5, 0x54, 0x4a, 0xda, 0x77, 0xd8, 0xe4, 0xfd, 0x8e, 0xae, 0x9c, 0x3d, 0x5d, 0x69, 0x39, 0x97,
0xcf, 0x3e, 0x94, 0x62, 0x9e, 0x40, 0xc5, 0xbe, 0x57, 0xa7, 0xfa, 0x67, 0xe3, 0x8c, 0xa7, 0xad,
0x9e, 0x5c, 0xcb, 0xe6, 0x85, 0xe8, 0x55, 0xc6, 0xf8, 0xfb, 0xb6, 0xb9, 0x3e, 0x79, 0xa0, 0xc7,
0xc3, 0x05, 0xed, 0x00, 0xef, 0x11, 0xe3, 0x23, 0x5f, 0x2d, 0x92, 0xb3, 0xf8, 0x34, 0x9c, 0xfb,
0xa5, 0x14, 0xa0, 0x87, 0x30, 0xaf, 0x00, 0x7b, 0x4f, 0x44, 0x0f, 0x29, 0x2a, 0x50, 0xdd, 0x67,
0x8f, 0xa1, 0x6c, 0x3b, 0xd9, 0x34, 0x98, 0xeb, 0x93, 0xed, 0x36, 0x8b, 0x4f, 0x9f, 0xbf, 0x86,
0x95, 0x2e, 0x4b, 0xdc, 0x19, 0xce, 0xe8, 0x73, 0x30, 0xbd, 0xe1, 0x8b, 0x8c, 0xbe, 0x0b, 0xbe,
0xbb, 0xd7, 0xa7, 0x62, 0x30, 0xec, 0xc8, 0x8c, 0xdf, 0x16, 0x38, 0x66, 0x7c, 0x4b, 0xdf, 0x6f,
0x5c, 0xef, 0xb6, 0x71, 0x46, 0xed, 0x3f, 0x41, 0x9d, 0x45, 0xa5, 0xf3, 0xc1, 0xdf, 0x01, 0x00,
0x00, 0xff, 0xff, 0xb3, 0x68, 0xfa, 0xac, 0x23, 0x12, 0x00, 0x00,
// 1498 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xac, 0x58, 0xdd, 0x6f, 0x13, 0x47,
0x10, 0xd7, 0x39, 0x1f, 0xb6, 0xc7, 0x89, 0x03, 0x9b, 0x0f, 0x8c, 0x09, 0x5f, 0x07, 0x2d, 0x08,
0x29, 0x0e, 0x0d, 0x01, 0x51, 0xa8, 0x2a, 0x0a, 0x09, 0xa2, 0x22, 0x01, 0x74, 0x69, 0x2b, 0xb5,
0x2f, 0xee, 0xda, 0xde, 0xd8, 0x2b, 0xee, 0x6e, 0xaf, 0xb7, 0xeb, 0xa0, 0x54, 0xed, 0x5b, 0x1f,
0xda, 0xbe, 0xf6, 0x4f, 0xe8, 0x5b, 0xff, 0xc8, 0xaa, 0xda, 0x4f, 0xaf, 0xcf, 0x71, 0x40, 0x0d,
0x4f, 0xde, 0x9d, 0x9d, 0x9b, 0xf9, 0xfd, 0x76, 0x66, 0x67, 0x67, 0x0d, 0xab, 0x09, 0xee, 0x0e,
0x68, 0x4a, 0x36, 0xcd, 0x6f, 0x2b, 0xcb, 0x99, 0x60, 0xa8, 0x6c, 0xa6, 0xcd, 0x4b, 0x7d, 0xc6,
0xfa, 0x31, 0xd9, 0x54, 0xe2, 0xce, 0xf0, 0x70, 0x93, 0x24, 0x99, 0x38, 0xd6, 0x5a, 0xcd, 0xab,
0xc5, 0x45, 0x41, 0x13, 0xc2, 0x05, 0x4e, 0x32, 0xa3, 0xb0, 0xdc, 0x65, 0x49, 0xc2, 0xd2, 0x4d,
0xfd, 0xa3, 0x85, 0xe1, 0x73, 0xa8, 0x47, 0xa4, 0xc3, 0x98, 0x88, 0x08, 0xcf, 0x58, 0xca, 0x09,
0xda, 0x86, 0x4a, 0x42, 0x04, 0xee, 0x61, 0x81, 0x1b, 0xc1, 0xb5, 0xe0, 0x76, 0x6d, 0xab, 0xd1,
0x32, 0x9f, 0x58, 0x9d, 0x7d, 0xb3, 0x1e, 0x39, 0xcd, 0xf0, 0x29, 0xd4, 0xac, 0x9d, 0x2c, 0x3e,
0x46, 0xf7, 0xa0, 0x92, 0x1b, 0xe5, 0x46, 0x70, 0x6d, 0xe6, 0x76, 0x6d, 0xeb, 0x42, 0xcb, 0x92,
0x1a, 0xf7, 0x17, 0x39, 0xc5, 0x70, 0x17, 0x16, 0x23, 0xc2, 0xc9, 0x59, 0xa1, 0x3c, 0x01, 0x30,
0x66, 0x24, 0x92, 0xad, 0x09, 0x24, 0x6b, 0x1e, 0x12, 0xcf, 0x9b, 0x07, 0xe4, 0x05, 0x9c, 0x3b,
0x18, 0x0c, 0x45, 0x8f, 0xbd, 0x4b, 0xcf, 0x88, 0xe5, 0x39, 0x2c, 0x8e, 0x2c, 0x49, 0x38, 0xf7,
0x27, 0xe0, 0x5c, 0x74, 0x70, 0x8a, 0x3e, 0x3d, 0x44, 0x9f, 0x42, 0xfd, 0xdb, 0xac, 0x9f, 0xe3,
0x1e, 0x89, 0xc8, 0x4f, 0x43, 0xc2, 0x05, 0x5a, 0x81, 0x39, 0x9a, 0xe0, 0x3e, 0x51, 0x60, 0xaa,
0x91, 0x9e, 0x84, 0xdf, 0xc3, 0x92, 0xd3, 0x3b, 0x0b, 0x70, 0x74, 0x0e, 0x66, 0x70, 0xf7, 0x6d,
0xa3, 0xa4, 0x8c, 0xcb, 0x61, 0xb8, 0x03, 0x0b, 0xce, 0xb4, 0x64, 0xb2, 0x3d, 0xc1, 0xa4, 0xe1,
0x98, 0x14, 0x30, 0x78, 0x44, 0x7e, 0x85, 0xe5, 0x03, 0x92, 0x1f, 0xd1, 0x2e, 0xd9, 0xa3, 0xfc,
0x8c, 0x91, 0x46, 0x77, 0xa1, 0xc2, 0xb5, 0x31, 0xde, 0x28, 0x29, 0x08, 0x2b, 0xa3, 0xcd, 0xd4,
0x0b, 0x5f, 0xa7, 0x87, 0x2c, 0x72, 0x5a, 0xe1, 0x1e, 0x9c, 0x1b, 0x73, 0x2f, 0x89, 0x3c, 0x9c,
0x20, 0xb2, 0x5e, 0xb4, 0xe2, 0x63, 0xf5, 0xc8, 0xfc, 0x15, 0x40, 0xcd, 0xf3, 0x83, 0xea, 0x50,
0xa2, 0x3d, 0x13, 0x90, 0x12, 0xed, 0xc9, 0x18, 0x71, 0x81, 0x05, 0x31, 0xdb, 0xa8, 0x27, 0xa8,
0x05, 0xf3, 0xe4, 0x88, 0xa4, 0x82, 0x37, 0x66, 0x14, 0xd3, 0xb5, 0xa2, 0xb7, 0x5d, 0xb5, 0x1a,
0x19, 0x2d, 0xa9, 0x3f, 0x20, 0x38, 0x16, 0x83, 0xc6, 0xec, 0xc9, 0xfa, 0x2f, 0xd4, 0x6a, 0x64,
0xb4, 0xc2, 0x2f, 0x61, 0x71, 0xcc, 0x10, 0xda, 0x70, 0x0e, 0x35, 0xbd, 0xd5, 0x13, 0x1d, 0x5a,
0x7f, 0x61, 0x07, 0x16, 0x7c, 0xb9, 0x4c, 0x85, 0x84, 0xf7, 0x0d, 0x2d, 0x39, 0x9c, 0xc2, 0xeb,
0x0e, 0x94, 0x1c, 0xa7, 0x66, 0x4b, 0x57, 0xa3, 0x96, 0xad, 0x46, 0xad, 0x6f, 0x6c, 0x35, 0x8a,
0x4a, 0x82, 0x87, 0x7f, 0x07, 0x0e, 0xa4, 0x46, 0x8f, 0x1a, 0x50, 0x1e, 0xa6, 0x6f, 0x53, 0xf6,
0x2e, 0x55, 0x9e, 0x2a, 0x91, 0x9d, 0xca, 0x15, 0xcd, 0xec, 0x58, 0xf9, 0xab, 0x44, 0x76, 0x8a,
0xae, 0xc3, 0x42, 0x8c, 0xb9, 0x68, 0x27, 0x84, 0x73, 0x79, 0x14, 0x66, 0x14, 0x9c, 0x9a, 0x94,
0xed, 0x6b, 0x11, 0x7a, 0x0c, 0x6a, 0xda, 0xee, 0x0e, 0x70, 0xda, 0x27, 0x66, 0x07, 0x4f, 0x43,
0x07, 0x52, 0xfd, 0x99, 0xd2, 0x0e, 0x3f, 0x71, 0xc9, 0x7a, 0x20, 0x70, 0x2e, 0xec, 0xd1, 0x2b,
0x84, 0x39, 0xfc, 0x11, 0x56, 0xc6, 0xd5, 0xce, 0x94, 0xd4, 0x08, 0x66, 0x65, 0x82, 0x99, 0xbd,
0x55, 0xe3, 0xf0, 0x15, 0x9c, 0x1f, 0xf7, 0x20, 0xf3, 0xf6, 0xf3, 0x89, 0xbc, 0xbd, 0x5c, 0x0c,
0xec, 0x18, 0x1e, 0x2f, 0x71, 0x6f, 0x02, 0x72, 0x1a, 0x2c, 0x9b, 0xc6, 0xab, 0xed, 0xd1, 0x97,
0x5a, 0x1f, 0x9d, 0xd6, 0xe8, 0x34, 0x6a, 0x07, 0x1f, 0x78, 0x1a, 0x7d, 0x34, 0x1e, 0xa9, 0x5b,
0xb0, 0x6a, 0x14, 0x22, 0x19, 0xcb, 0xe9, 0xf1, 0xea, 0xc0, 0x5a, 0x51, 0xf1, 0xa3, 0x53, 0x8b,
0xdc, 0xde, 0x39, 0x1f, 0x92, 0xdd, 0xe3, 0x09, 0x76, 0x57, 0x8b, 0xec, 0x0a, 0x98, 0x3c, 0x82,
0x21, 0x2c, 0x9c, 0x96, 0x87, 0x8f, 0x4a, 0x8d, 0x20, 0xbc, 0x09, 0xe0, 0xa5, 0x88, 0x45, 0x16,
0x8c, 0x90, 0x29, 0xad, 0xeb, 0x50, 0x3b, 0x25, 0xf0, 0x4a, 0xe5, 0x06, 0x54, 0x47, 0x41, 0x99,
0x66, 0x67, 0x03, 0xea, 0xcf, 0x58, 0x76, 0xfc, 0x7a, 0xe8, 0x30, 0x5d, 0x82, 0x6a, 0xce, 0x98,
0x68, 0x67, 0x58, 0x0c, 0x8c, 0x7a, 0x45, 0x0a, 0xde, 0x60, 0x31, 0x08, 0x3b, 0x50, 0xdd, 0x3b,
0xb0, 0x9a, 0xd2, 0x26, 0x63, 0xc2, 0xd9, 0x64, 0x4c, 0xc8, 0xa3, 0x9e, 0x93, 0xee, 0x30, 0xe7,
0xc4, 0x1e, 0x75, 0x33, 0x45, 0xb7, 0x60, 0x49, 0x0f, 0x29, 0x4b, 0xdb, 0x3d, 0x92, 0x89, 0x81,
0x3a, 0xed, 0x73, 0x51, 0xdd, 0x89, 0x77, 0xa4, 0x34, 0xfc, 0x37, 0x80, 0xca, 0x73, 0x1a, 0xeb,
0x82, 0xfc, 0xbf, 0xe3, 0x99, 0xe2, 0xc4, 0x56, 0x37, 0x35, 0x96, 0x32, 0x4e, 0x7f, 0xd6, 0x25,
0x66, 0x26, 0x52, 0x63, 0x29, 0x4b, 0x58, 0x4f, 0x17, 0x95, 0xc5, 0x48, 0x8d, 0x51, 0x13, 0x2a,
0x09, 0xeb, 0xd1, 0x43, 0x4a, 0x7a, 0x8d, 0x39, 0xa5, 0xeb, 0xe6, 0x68, 0x15, 0xe6, 0x29, 0x6f,
0xf7, 0x68, 0xde, 0x98, 0x57, 0xe4, 0xe6, 0x28, 0xdf, 0xa1, 0xb9, 0xac, 0xa6, 0x24, 0xcf, 0x59,
0xde, 0x28, 0xeb, 0x6a, 0xaa, 0x26, 0xd2, 0x78, 0x4c, 0xd3, 0xb7, 0x8d, 0x8a, 0x06, 0x21, 0xc7,
0xe8, 0x06, 0x2c, 0xe6, 0x24, 0xc6, 0x82, 0x1e, 0x91, 0xb6, 0x42, 0x58, 0x55, 0x8b, 0x0b, 0x56,
0xf8, 0x0a, 0x27, 0x24, 0xcc, 0xa0, 0xbe, 0xcf, 0x86, 0xf2, 0x02, 0x39, 0x5b, 0x56, 0xdf, 0xd6,
0x45, 0xde, 0xde, 0xac, 0xc8, 0xe5, 0xa9, 0xb2, 0x7e, 0x20, 0xb0, 0xd0, 0x85, 0x9f, 0xcb, 0xde,
0xcf, 0x7a, 0x7c, 0x5f, 0xef, 0x37, 0x8e, 0xcc, 0xcb, 0xed, 0x5f, 0xa0, 0xea, 0xec, 0xa2, 0x2b,
0x00, 0x87, 0x34, 0x26, 0xfc, 0x98, 0x0b, 0x92, 0x98, 0x04, 0xf1, 0x24, 0x2e, 0x18, 0x32, 0x40,
0xb3, 0x26, 0x18, 0xeb, 0x50, 0xc5, 0x47, 0x98, 0xc6, 0xb8, 0x13, 0xeb, 0x28, 0xcd, 0x46, 0x23,
0x01, 0xba, 0x0c, 0x90, 0x48, 0xf3, 0xa4, 0xd7, 0x66, 0xa9, 0x0a, 0x58, 0x35, 0xaa, 0x1a, 0xc9,
0xeb, 0x34, 0xfc, 0x27, 0x80, 0xa5, 0xef, 0x88, 0xca, 0xa2, 0x33, 0xee, 0x5a, 0x0b, 0xca, 0x47,
0xda, 0x90, 0x42, 0xe7, 0x77, 0x24, 0xc6, 0x81, 0xea, 0x48, 0xac, 0x12, 0xfa, 0x0c, 0x2a, 0x59,
0x8c, 0xc5, 0x21, 0xcb, 0x13, 0x73, 0x75, 0x8e, 0x6e, 0xe7, 0x37, 0x66, 0x41, 0xf7, 0x30, 0x56,
0x4d, 0x36, 0x62, 0x0e, 0xeb, 0xfb, 0x1a, 0xb1, 0x02, 0x29, 0x6f, 0xc3, 0xff, 0x0c, 0xa0, 0xe6,
0x21, 0x92, 0xb7, 0xbc, 0xc0, 0xee, 0x96, 0x17, 0xb8, 0x2f, 0x25, 0x7c, 0x80, 0x6d, 0x0b, 0xc8,
0x07, 0x58, 0x66, 0x6a, 0x67, 0x48, 0x63, 0x61, 0x2e, 0x5a, 0x3d, 0x91, 0x7b, 0xdb, 0x67, 0x6d,
0xcb, 0xda, 0xec, 0x6d, 0x9f, 0x19, 0xe3, 0xb2, 0xb8, 0x30, 0xae, 0xce, 0x42, 0x35, 0x2a, 0x31,
0x2e, 0x83, 0x87, 0xf3, 0xee, 0x40, 0x9d, 0x81, 0x6a, 0xa4, 0xc6, 0xe1, 0x03, 0x58, 0xf0, 0xc9,
0xba, 0x13, 0x18, 0x8c, 0x9f, 0x40, 0x75, 0xda, 0xcc, 0xa9, 0x94, 0xe3, 0xf0, 0xb7, 0x00, 0x6a,
0x7b, 0xac, 0xcf, 0x6d, 0x4d, 0x59, 0x87, 0xaa, 0xd4, 0xe5, 0x19, 0xee, 0xda, 0x8f, 0x47, 0x02,
0x53, 0xe6, 0x4a, 0xae, 0x3d, 0xdb, 0x84, 0xf9, 0x5e, 0x4e, 0x8f, 0x48, 0xae, 0xf8, 0xd4, 0xb7,
0x2e, 0xd8, 0xf8, 0x3e, 0x63, 0xa9, 0xc0, 0x34, 0x25, 0xf9, 0x8e, 0x5a, 0x8e, 0x8c, 0x1a, 0x5a,
0x83, 0xf9, 0x43, 0x16, 0xc7, 0xec, 0x9d, 0x62, 0x59, 0x89, 0xcc, 0x4c, 0x96, 0xd3, 0x88, 0xe0,
0x9e, 0x57, 0xd9, 0xbc, 0xf2, 0xa7, 0xc6, 0x5b, 0x7f, 0x54, 0xa0, 0xbc, 0xaf, 0x83, 0x82, 0x1e,
0x41, 0xd9, 0x54, 0x4d, 0x34, 0x3a, 0x19, 0xe3, 0x75, 0xb4, 0xb9, 0x62, 0xb1, 0xec, 0xc8, 0xfc,
0x32, 0x41, 0xbb, 0x1b, 0xa0, 0x2f, 0x00, 0x5e, 0x0e, 0x3b, 0xa4, 0xcb, 0xd2, 0x43, 0xda, 0x47,
0x6b, 0x13, 0x8d, 0xcc, 0xae, 0x7c, 0x11, 0x4e, 0xfd, 0x7a, 0x03, 0x4a, 0x7b, 0x07, 0x68, 0x74,
0x94, 0x5d, 0x35, 0x6e, 0x9e, 0x77, 0x32, 0x5b, 0x3c, 0xef, 0x06, 0x68, 0x1b, 0x66, 0xe5, 0xee,
0xa2, 0x51, 0x0e, 0x7b, 0x9b, 0x3d, 0xd5, 0xc9, 0x03, 0x98, 0xd7, 0xc7, 0xfc, 0x14, 0x78, 0xc5,
0x7a, 0xa0, 0xf3, 0x78, 0x56, 0xee, 0xa2, 0xe7, 0xcd, 0xdb, 0xd4, 0xd3, 0xbc, 0xe9, 0x07, 0xe5,
0x07, 0x78, 0xf3, 0x5f, 0xa8, 0xdb, 0x30, 0xa7, 0x9e, 0x7f, 0x53, 0x3f, 0x5b, 0x2e, 0x3e, 0x13,
0xe5, 0x57, 0x4f, 0x5c, 0xc3, 0x2f, 0x9f, 0x04, 0x53, 0xbf, 0xbd, 0x78, 0xf2, 0x03, 0x42, 0x5a,
0x78, 0x05, 0xf5, 0xf1, 0x8b, 0x1e, 0x5d, 0x99, 0xda, 0x01, 0x68, 0xe6, 0xeb, 0x53, 0xd7, 0xa5,
0xbd, 0x17, 0xae, 0x5b, 0x57, 0xf7, 0x3e, 0x5a, 0x9f, 0xd2, 0x03, 0x6a, 0x5b, 0xcd, 0x29, 0xab,
0xd2, 0xd2, 0xae, 0xe3, 0x26, 0x2f, 0x7e, 0x74, 0xe9, 0xe4, 0xb6, 0x4b, 0xdb, 0xb9, 0x78, 0xf2,
0xa2, 0x34, 0xf3, 0x08, 0x2a, 0xf6, 0x21, 0x3b, 0x75, 0x7f, 0xd6, 0x4e, 0x78, 0xf3, 0xea, 0x96,
0xb6, 0x6c, 0x9e, 0x8e, 0xde, 0xc9, 0x18, 0x7f, 0xf8, 0x36, 0x57, 0x27, 0x17, 0x74, 0xdf, 0x38,
0xa7, 0x37, 0xc0, 0x7b, 0xdd, 0xf8, 0xcc, 0x97, 0x8b, 0xe2, 0x2c, 0x3e, 0x0e, 0x67, 0x7e, 0x2f,
0x05, 0xe8, 0x3e, 0xcc, 0x2a, 0xc2, 0xde, 0xdb, 0xd1, 0x63, 0x8a, 0x0a, 0x52, 0xf7, 0xd9, 0x43,
0x28, 0xdb, 0x12, 0x37, 0x8d, 0xe6, 0xea, 0x64, 0x1d, 0xce, 0xe2, 0xe3, 0xa7, 0x2f, 0x61, 0xa9,
0xcb, 0x12, 0xb7, 0x86, 0x33, 0xfa, 0x14, 0x4c, 0x6d, 0xf8, 0x2a, 0xa3, 0x6f, 0x82, 0x1f, 0xee,
0xf4, 0xa9, 0x18, 0x0c, 0x3b, 0x32, 0xe3, 0x37, 0x05, 0x8e, 0x19, 0xdf, 0xd0, 0x17, 0x1f, 0xd7,
0xb3, 0x4d, 0x9c, 0x51, 0xfb, 0x17, 0x51, 0x67, 0x5e, 0xf9, 0xbc, 0xf7, 0x5f, 0x00, 0x00, 0x00,
0xff, 0xff, 0xea, 0x65, 0x81, 0x0d, 0x3c, 0x12, 0x00, 0x00,
}
// Reference imports to suppress errors if they are not otherwise used.

View File

@ -257,6 +257,7 @@ message LogsRequest {
string id = 2;
// driver might be default "containerd" or "cri"
common.ContainerDriver driver = 3;
bool follow = 4;
}
message ReadRequest {

View File

@ -23,6 +23,8 @@ import (
"github.com/talos-systems/talos/pkg/constants"
)
var follow bool
// logsCmd represents the logs command
var logsCmd = &cobra.Command{
Use: "logs <id>",
@ -46,7 +48,7 @@ var logsCmd = &cobra.Command{
driver = common.ContainerDriver_CRI
}
stream, err := c.Logs(globalCtx, namespace, driver, args[0])
stream, err := c.Logs(globalCtx, namespace, driver, args[0], follow)
if err != nil {
helpers.Fatalf("error fetching logs: %s", err)
}
@ -59,6 +61,7 @@ var logsCmd = &cobra.Command{
if data.Metadata != nil && data.Metadata.Error != "" {
_, err = fmt.Fprintf(os.Stderr, "ERROR: %s\n", data.Metadata.Error)
helpers.Should(err)
continue
}
node := defaultNode
@ -70,7 +73,9 @@ var logsCmd = &cobra.Command{
helpers.Should(err)
}
helpers.Should(<-errCh)
if err = <-errCh; err != nil {
helpers.Fatalf("error getting logs: %v", err)
}
})
},
}
@ -172,5 +177,6 @@ func (slicer *lineSlicer) run(stream machine.Machine_LogsClient) {
func init() {
logsCmd.Flags().BoolVarP(&kubernetes, "kubernetes", "k", false, "use the k8s.io containerd namespace")
logsCmd.Flags().BoolVarP(&useCRI, "use-cri", "c", false, "use the CRI driver")
logsCmd.Flags().BoolVarP(&follow, "follow", "f", false, "specify if the logs should be streamed")
rootCmd.AddCommand(logsCmd)
}

View File

@ -31,7 +31,7 @@ import (
"github.com/talos-systems/talos/pkg/net"
)
// Credentials represents the set of values required to initialize a vaild
// Credentials represents the set of values required to initialize a valid
// Client.
type Credentials struct {
ca []byte
@ -159,7 +159,7 @@ func (c *Client) KubeconfigRaw(ctx context.Context) (io.Reader, <-chan error, er
return nil, nil, err
}
return readStream(stream)
return ReadStream(stream)
}
// Kubeconfig returns K8s client config (kubeconfig).
@ -268,11 +268,12 @@ func (c *Client) Dmesg(ctx context.Context) (*common.DataReply, error) {
}
// Logs implements the proto.OSClient interface.
func (c *Client) Logs(ctx context.Context, namespace string, driver common.ContainerDriver, id string) (stream machineapi.Machine_LogsClient, err error) {
func (c *Client) Logs(ctx context.Context, namespace string, driver common.ContainerDriver, id string, follow bool) (stream machineapi.Machine_LogsClient, err error) {
stream, err = c.MachineClient.Logs(ctx, &machineapi.LogsRequest{
Namespace: namespace,
Driver: driver,
Id: id,
Follow: follow,
})
return
@ -362,7 +363,7 @@ func (c *Client) CopyOut(ctx context.Context, rootPath string) (io.Reader, <-cha
return nil, nil, err
}
return readStream(stream)
return ReadStream(stream)
}
// Upgrade initiates a Talos upgrade ... and implements the proto.OSClient
@ -487,15 +488,17 @@ func (c *Client) Read(ctx context.Context, path string) (io.Reader, <-chan error
return nil, nil, err
}
return readStream(stream)
return ReadStream(stream)
}
type machineStream interface {
// MachineStream is a common interface for streams returned by streaming APIs.
type MachineStream interface {
Recv() (*common.DataResponse, error)
grpc.ClientStream
}
func readStream(stream machineStream) (io.Reader, <-chan error, error) {
// ReadStream converts grpc stream into io.Reader.
func ReadStream(stream MachineStream) (io.Reader, <-chan error, error) {
errCh := make(chan error)
pr, pw := io.Pipe()
@ -528,5 +531,5 @@ func readStream(stream machineStream) (io.Reader, <-chan error, error) {
}
}()
return pr, errCh, nil
return pr, errCh, stream.CloseSend()
}

View File

@ -92,4 +92,4 @@ run "osctl config target 10.5.0.4 && osctl -t 10.5.0.4 service etcd | grep Runni
run "osctl --target 10.5.0.2,10.5.0.3,10.5.0.4,10.5.0.5 containers"
run "osctl --target 10.5.0.2,10.5.0.3,10.5.0.4,10.5.0.5 services"
run "integration-test -test.v -talos.target 10.5.0.2"
run "integration-test -test.v"

View File

@ -452,7 +452,12 @@ func (r *Registrator) Logs(req *machineapi.LogsRequest, l machineapi.Machine_Log
// nolint: errcheck
defer file.Close()
chunk = filechunker.NewChunker(file)
options := []filechunker.Option{}
if req.Follow {
options = append(options, filechunker.WithFollow())
}
chunk = filechunker.NewChunker(file, options...)
default:
var file io.Closer
@ -489,7 +494,7 @@ func k8slogs(ctx context.Context, req *machineapi.LogsRequest) (chunker.Chunker,
return nil, nil, fmt.Errorf("container %q not found", req.Id)
}
return container.GetLogChunker()
return container.GetLogChunker(req.Follow)
}
func getContainerInspector(ctx context.Context, namespace string, driver common.ContainerDriver) (containers.Inspector, error) {

View File

@ -5,7 +5,6 @@
package log
import (
"context"
"fmt"
"os"
"path/filepath"
@ -70,12 +69,6 @@ func (l *Log) Close() error {
return l.source.Close()
}
// Read implements chunker.Chunker.
func (l *Log) Read(ctx context.Context) <-chan []byte {
c := filechunker.NewChunker(l.source)
return c.Read(ctx)
}
// FormatLogPath formats the path the log file.
func FormatLogPath(p, rootPath string) string {
return filepath.Join(rootPath, p+".log")

View File

@ -0,0 +1,171 @@
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
// +build integration_api
package api
import (
"context"
"io"
"io/ioutil"
"time"
"github.com/talos-systems/talos/api/common"
"github.com/talos-systems/talos/cmd/osctl/pkg/client"
"github.com/talos-systems/talos/internal/integration/base"
"github.com/talos-systems/talos/pkg/constants"
)
// VersionSuite verifies version API
type LogsSuite struct {
base.APISuite
ctx context.Context
ctxCancel context.CancelFunc
}
// SuiteName ...
func (suite *LogsSuite) SuiteName() string {
return "api.LogsSuite"
}
// SetupTest ...
func (suite *LogsSuite) SetupTest() {
// make sure API calls have timeout
suite.ctx, suite.ctxCancel = context.WithTimeout(context.Background(), 2*time.Minute)
}
// TearDownTest ...
func (suite *LogsSuite) TearDownTest() {
suite.ctxCancel()
}
// TestServicesHaveLogs verifies that each service has logs
func (suite *LogsSuite) TestServicesHaveLogs() {
servicesReply, err := suite.Client.ServiceList(suite.ctx)
suite.Require().NoError(err)
suite.Require().Len(servicesReply.Response, 1)
logsSize := int64(0)
for _, svc := range servicesReply.Response[0].Services {
logsStream, err := suite.Client.Logs(
suite.ctx,
constants.SystemContainerdNamespace,
common.ContainerDriver_CONTAINERD,
svc.Id,
false,
)
suite.Require().NoError(err)
logReader, errCh, err := client.ReadStream(logsStream)
suite.Require().NoError(err)
n, err := io.Copy(ioutil.Discard, logReader)
suite.Require().NoError(err)
logsSize += n
suite.Require().NoError(<-errCh)
}
// overall logs shouldn't be empty
suite.Require().Greater(logsSize, int64(1024))
}
// TODO: TestContainersHaveLogs (CRI, containerd)
// TestServiceNotFound verifies error if service name is not found
func (suite *LogsSuite) TestServiceNotFound() {
logsStream, err := suite.Client.Logs(
suite.ctx,
constants.SystemContainerdNamespace,
common.ContainerDriver_CONTAINERD,
"nosuchservice",
false,
)
suite.Require().NoError(err)
suite.Require().NoError(logsStream.CloseSend())
_, err = logsStream.Recv()
suite.Require().Error(err)
suite.Require().Regexp(`.+nosuchservice\.log: no such file or directory$`, err.Error())
}
// TestStreaming verifies that logs are streamed in real-time
func (suite *LogsSuite) TestStreaming() {
logsStream, err := suite.Client.Logs(
suite.ctx,
constants.SystemContainerdNamespace,
common.ContainerDriver_CONTAINERD,
"machined-api",
true,
)
suite.Require().NoError(err)
suite.Require().NoError(logsStream.CloseSend())
respCh := make(chan *common.DataResponse)
errCh := make(chan error, 1)
go func() {
defer close(respCh)
for {
msg, err := logsStream.Recv()
if err != nil {
errCh <- err
return
}
respCh <- msg
}
}()
defer func() {
suite.ctxCancel()
// drain respCh
for range respCh {
}
}()
// first, drain the stream until flow stops
DrainLoop:
for {
select {
case msg, ok := <-respCh:
suite.Require().True(ok)
suite.Assert().NotEmpty(msg.Bytes)
case <-time.After(200 * time.Millisecond):
break DrainLoop
}
}
// invoke machined API
_, err = suite.Client.Version(suite.ctx)
suite.Require().NoError(err)
// there should be line in the logs
select {
case msg, ok := <-respCh:
suite.Require().True(ok)
suite.Assert().NotEmpty(msg.Bytes)
case <-time.After(200 * time.Millisecond):
suite.Assert().Fail("no log message received")
}
select {
case err = <-errCh:
suite.Require().NoError(err)
default:
}
}
func init() {
allSuites = append(allSuites, new(LogsSuite))
}

View File

@ -22,8 +22,10 @@ type RunOption func(*runOptions)
type runOptions struct {
shouldFail bool
stdoutEmpty bool
stderrNotEmpty bool
stdoutRegexps []*regexp.Regexp
stderrRegexps []*regexp.Regexp
}
// ShouldFail tells Run command should fail.
@ -43,12 +45,19 @@ func ShouldSucceed() RunOption {
}
// StderrNotEmpty tells run that stderr of the command should not be empty.
func StdErrNotEmpty() RunOption {
func StderrNotEmpty() RunOption {
return func(opts *runOptions) {
opts.stderrNotEmpty = true
}
}
// StdoutEmpty tells run that stdout of the command should be empty.
func StdoutEmpty() RunOption {
return func(opts *runOptions) {
opts.stdoutEmpty = true
}
}
// StdoutShouldMatch appends to the set of regexps stdout contents should match.
func StdoutShouldMatch(r *regexp.Regexp) RunOption {
return func(opts *runOptions) {
@ -56,6 +65,13 @@ func StdoutShouldMatch(r *regexp.Regexp) RunOption {
}
}
// StderrShouldMatch appends to the set of regexps sterr contents should match.
func StderrShouldMatch(r *regexp.Regexp) RunOption {
return func(opts *runOptions) {
opts.stderrRegexps = append(opts.stderrRegexps, r)
}
}
// Run executes command and asserts on its exit status/output
func Run(suite *suite.Suite, cmd *exec.Cmd, options ...RunOption) {
var opts runOptions
@ -106,6 +122,12 @@ func Run(suite *suite.Suite, cmd *exec.Cmd, options ...RunOption) {
}
}
if opts.stdoutEmpty {
suite.Assert().Empty(stdout.String(), "stdout should be empty")
} else {
suite.Assert().NotEmpty(stdout.String(), "stdout should be not empty")
}
if opts.stderrNotEmpty {
suite.Assert().NotEmpty(stderr.String(), "stderr should be not empty")
} else {
@ -115,4 +137,8 @@ func Run(suite *suite.Suite, cmd *exec.Cmd, options ...RunOption) {
for _, rx := range opts.stdoutRegexps {
suite.Assert().Regexp(rx, stdout.String())
}
for _, rx := range opts.stderrRegexps {
suite.Assert().Regexp(rx, stderr.String())
}
}

View File

@ -0,0 +1,42 @@
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
// +build integration_cli
package cli
import (
"regexp"
"github.com/talos-systems/talos/internal/integration/base"
)
// LogsSuite verifies logs command
type LogsSuite struct {
base.CLISuite
}
// SuiteName ...
func (suite *LogsSuite) SuiteName() string {
return "cli.LogsSuite"
}
// TestServiceLogs verifies that logs are displayed.
func (suite *LogsSuite) TestServiceLogs() {
suite.RunOsctl([]string{"logs", "kubelet"}) // default checks for stdout not empty
}
// TestServiceNotFound verifies that logs displays an error if service is not found.
func (suite *LogsSuite) TestServiceNotFound() {
suite.RunOsctl([]string{"logs", "servicenotfound"},
base.ShouldFail(),
base.StdoutEmpty(),
base.StderrNotEmpty(),
base.StderrShouldMatch(regexp.MustCompile("error getting logs: .*servicenotfound.log: no such file or directory")),
)
}
func init() {
allSuites = append(allSuites, new(LogsSuite))
}

View File

@ -12,7 +12,7 @@ import (
"github.com/talos-systems/talos/internal/integration/base"
)
// VersionSuite verifies version API
// VersionSuite verifies version command
type VersionSuite struct {
base.CLISuite
}

View File

@ -66,7 +66,7 @@ func (c *Container) Kill(signal syscall.Signal) error {
}
// GetLogChunker returns chunker for container log file
func (c *Container) GetLogChunker() (chunker.Chunker, io.Closer, error) {
func (c *Container) GetLogChunker(follow bool) (chunker.Chunker, io.Closer, error) {
logFile := c.GetLogFile()
if logFile != "" {
f, err := os.OpenFile(logFile, os.O_RDONLY, 0)
@ -74,7 +74,12 @@ func (c *Container) GetLogChunker() (chunker.Chunker, io.Closer, error) {
return nil, nil, err
}
return file.NewChunker(f), f, nil
chunkerOptions := []file.Option{}
if follow {
chunkerOptions = append(chunkerOptions, file.WithFollow())
}
return file.NewChunker(f, chunkerOptions...), f, nil
}
filename, err := c.GetProcessStderr()

View File

@ -238,7 +238,7 @@ func basicIntegration() error {
ctx,
cli,
runnerConfig,
"integration-test -test.v -talos.target 10.5.0.2",
"osctl config target 10.5.0.2 && integration-test -test.v",
); err != nil {
return err
}

View File

@ -18,19 +18,27 @@ import (
// Options is the functional options struct.
type Options struct {
Size int
Size int
Follow bool
}
// Option is the functional option func.
type Option func(*Options)
// Size sets the chunk size of the Chunker.
func Size(s int) Option {
// WithSize sets the chunk size of the Chunker.
func WithSize(s int) Option {
return func(args *Options) {
args.Size = s
}
}
// WithFollow file updates using inotify().
func WithFollow() Option {
return func(args *Options) {
args.Follow = true
}
}
// File is a conecrete type that implements the chunker.Chunker interface.
type File struct {
source Source
@ -68,36 +76,39 @@ func (c *File) Read(ctx context.Context) <-chan []byte {
go func(ch chan []byte) {
defer close(ch)
watcher, err := fsnotify.NewWatcher()
if err != nil {
log.Printf("failed to watch: %v\n", err)
return
}
// nolint: errcheck
defer watcher.Close()
var (
watcherEvents chan fsnotify.Event
watcherErrors chan error
)
if err = watcher.Add(filepath.Dir(filename)); err != nil {
log.Printf("failed to watch add: %v\n", err)
return
}
offset, err := c.source.Seek(0, io.SeekStart)
if err != nil {
log.Printf("failed to seek: %v\n", err)
return
if c.options.Follow {
watcher, err := fsnotify.NewWatcher()
if err != nil {
log.Printf("failed to watch: %v\n", err)
return
}
// nolint: errcheck
defer watcher.Close()
watcherEvents = watcher.Events
watcherErrors = watcher.Errors
if err = watcher.Add(filepath.Dir(filename)); err != nil {
log.Printf("failed to watch add: %v\n", err)
return
}
}
buf := make([]byte, c.options.Size)
for {
for {
n, err := c.source.ReadAt(buf, offset)
n, err := c.source.Read(buf)
if err != nil && err != io.EOF {
log.Printf("read error: %s\n", err.Error())
return
}
offset += int64(n)
if n > 0 {
// Copy the buffer since we will modify it in the next loop.
b := make([]byte, n)
@ -107,7 +118,7 @@ func (c *File) Read(ctx context.Context) <-chan []byte {
select {
case <-ctx.Done():
return
case event := <-watcher.Events:
case event := <-watcherEvents:
// drain events while waiting for the buffer to be delivered
// otherwise inotify() queue might overflow
if event.Name == filename && event.Op == fsnotify.Write {
@ -125,11 +136,15 @@ func (c *File) Read(ctx context.Context) <-chan []byte {
}
}
if !c.options.Follow {
return
}
WATCH:
select {
case <-ctx.Done():
return
case event := <-watcher.Events:
case event := <-watcherEvents:
if event.Name != filename {
// ignore events for other files
goto WATCH
@ -144,7 +159,7 @@ func (c *File) Read(ctx context.Context) <-chan []byte {
log.Printf("ignoring fsnotify event: %v\n", event)
goto WATCH
}
case err := <-watcher.Errors:
case err := <-watcherErrors:
log.Printf("failed to watch: %v\n", err)
return
}

View File

@ -71,7 +71,7 @@ func collectChunks(chunksCh <-chan []byte) <-chan []byte {
}
func (suite *FileChunkerSuite) TestStreaming() {
chunker := file.NewChunker(suite.reader)
chunker := file.NewChunker(suite.reader, file.WithFollow())
ctx, ctxCancel := context.WithCancel(context.Background())
defer ctxCancel()
@ -98,7 +98,7 @@ func (suite *FileChunkerSuite) TestStreaming() {
}
func (suite *FileChunkerSuite) TestStreamingWithSomeHead() {
chunker := file.NewChunker(suite.reader)
chunker := file.NewChunker(suite.reader, file.WithFollow())
ctx, ctxCancel := context.WithCancel(context.Background())
defer ctxCancel()
@ -127,7 +127,7 @@ func (suite *FileChunkerSuite) TestStreamingWithSomeHead() {
}
func (suite *FileChunkerSuite) TestStreamingSmallBuffer() {
chunker := file.NewChunker(suite.reader, file.Size(1))
chunker := file.NewChunker(suite.reader, file.WithSize(1), file.WithFollow())
ctx, ctxCancel := context.WithCancel(context.Background())
defer ctxCancel()
@ -159,7 +159,7 @@ func (suite *FileChunkerSuite) TestStreamingSmallBuffer() {
}
func (suite *FileChunkerSuite) TestStreamingDeleted() {
chunker := file.NewChunker(suite.reader)
chunker := file.NewChunker(suite.reader, file.WithFollow())
ctx, ctxCancel := context.WithCancel(context.Background())
defer ctxCancel()
@ -186,6 +186,26 @@ func (suite *FileChunkerSuite) TestStreamingDeleted() {
suite.Require().Equal([]byte("abcdefghijklmno"), <-combinedCh)
}
func (suite *FileChunkerSuite) TestNoFollow() {
chunker := file.NewChunker(suite.reader)
ctx, ctxCancel := context.WithCancel(context.Background())
defer ctxCancel()
// nolint: errcheck
suite.writer.WriteString("abc")
// nolint: errcheck
suite.writer.WriteString("def")
// nolint: errcheck
suite.writer.WriteString("ghi")
time.Sleep(50 * time.Millisecond)
chunksCh := chunker.Read(ctx)
combinedCh := collectChunks(chunksCh)
suite.Require().Equal([]byte("abcdefghi"), <-combinedCh)
}
func TestFileChunkerSuite(t *testing.T) {
suite.Run(t, new(FileChunkerSuite))
}