chore: print all available logs containers in logs command completions

This is a small quality of life improvement that allows `logs` subcommand to suggest all available logs.

Signed-off-by: Dmitriy Matrenichev <dmitry.matrenichev@siderolabs.com>
This commit is contained in:
Dmitriy Matrenichev 2024-03-11 17:01:29 +03:00
parent e89d755c52
commit 32e0877607
No known key found for this signature in database
GPG Key ID: D3363CF894E68892
15 changed files with 2619 additions and 1944 deletions

View File

@ -60,6 +60,7 @@ service MachineService {
rpc DiskUsage(DiskUsageRequest) returns (stream DiskUsageInfo);
rpc LoadAvg(google.protobuf.Empty) returns (LoadAvgResponse);
rpc Logs(LogsRequest) returns (stream common.Data);
rpc LogsContainers(google.protobuf.Empty) returns (LogsContainersResponse);
rpc Memory(google.protobuf.Empty) returns (MemoryResponse);
rpc Mounts(google.protobuf.Empty) returns (MountsResponse);
rpc NetworkDeviceStats(google.protobuf.Empty) returns (NetworkDeviceStatsResponse);
@ -570,6 +571,16 @@ message ReadRequest {
string path = 1;
}
// LogsContainer desribes all avalaible registered log containers.
message LogsContainer {
common.Metadata metadata = 1;
repeated string ids = 2;
}
message LogsContainersResponse {
repeated LogsContainer messages = 1;
}
// rpc rollback
message RollbackRequest {}

View File

@ -15,7 +15,9 @@ import (
criconstants "github.com/containerd/containerd/pkg/cri/constants"
"github.com/siderolabs/gen/xslices"
"github.com/spf13/cobra"
"google.golang.org/grpc"
"google.golang.org/grpc/codes"
"google.golang.org/grpc/peer"
"github.com/siderolabs/talos/pkg/cli"
"github.com/siderolabs/talos/pkg/machinery/api/common"
@ -29,7 +31,6 @@ var (
tailLines int32
)
// logsCmd represents the logs command.
var logsCmd = &cobra.Command{
Use: "logs <service name>",
Short: "Retrieve logs for a service",
@ -44,7 +45,7 @@ var logsCmd = &cobra.Command{
return getContainersFromNode(kubernetes), cobra.ShellCompDirectiveNoFileComp
}
return mergeSuggestions(getServiceFromNode(), getContainersFromNode(kubernetes)), cobra.ShellCompDirectiveNoFileComp
return mergeSuggestions(getServiceFromNode(), getContainersFromNode(kubernetes), getLogsContainers()), cobra.ShellCompDirectiveNoFileComp
},
RunE: func(cmd *cobra.Command, args []string) error {
return WithClient(func(ctx context.Context, c *client.Client) error {
@ -206,6 +207,28 @@ func (slicer *lineSlicer) run(stream machine.MachineService_LogsClient) {
}
}
func getLogsContainers() []string {
var result []string
//nolint:errcheck
WithClient(
func(ctx context.Context, c *client.Client) error {
var remotePeer peer.Peer
resp, err := c.LogsContainers(ctx, grpc.Peer(&remotePeer))
if err != nil {
return err
}
result = xslices.FlatMap(resp.Messages, func(lc *machine.LogsContainer) []string { return lc.Ids })
return nil
},
)
return result
}
func init() {
logsCmd.Flags().BoolVarP(&kubernetes, "kubernetes", "k", false, "use the k8s.io containerd namespace")
logsCmd.Flags().BoolVarP(&follow, "follow", "f", false, "specify if the logs should be streamed")

View File

@ -9,7 +9,6 @@ import (
"fmt"
"io"
"slices"
"sort"
"strings"
criconstants "github.com/containerd/containerd/pkg/cri/constants"
@ -222,23 +221,12 @@ func getContainersFromNode(kubernetes bool) []string {
return containerIDs
}
func mergeSuggestions(a, b []string) []string {
merged := append(slices.Clone(a), b...)
func mergeSuggestions(s ...[]string) []string {
merged := slices.Concat(s...)
sort.Strings(merged)
slices.Sort(merged)
n := 1
for i := 1; i < len(merged); i++ {
if merged[i] != merged[i-1] {
merged[n] = merged[i]
n++
}
}
merged = merged[:n]
return merged
return slices.Compact(merged)
}
func relativeTo(fullPath string, filter string) bool {

View File

@ -10,7 +10,7 @@ import (
"fmt"
"io"
"os"
"sort"
"slices"
"strings"
"time"
@ -229,7 +229,7 @@ func (a *Tracker) Run() error {
})
if len(failedNodes) > 0 {
sort.Strings(failedNodes)
slices.Sort(failedNodes)
fmt.Fprintf(os.Stderr, "console logs for nodes %q:\n", failedNodes)
@ -288,7 +288,7 @@ func (a *Tracker) processNodeUpdate(update nodeUpdate) reporter.Update {
}
nodes := maps.Keys(a.nodeToLatestStatusUpdate)
sort.Strings(nodes)
slices.Sort(nodes)
messages := make([]string, 0, len(nodes)+1)
messages = append(messages, fmt.Sprintf("watching nodes: %v", nodes))

View File

@ -1223,6 +1223,17 @@ func (s *Server) Logs(req *machine.LogsRequest, l machine.MachineService_LogsSer
return nil
}
// LogsContainers provide a list of registered log containers.
func (s *Server) LogsContainers(context.Context, *emptypb.Empty) (*machine.LogsContainersResponse, error) {
return &machine.LogsContainersResponse{
Messages: []*machine.LogsContainer{
{
Ids: s.Controller.Runtime().Logging().RegisteredLogs(),
},
},
}, nil
}
func k8slogs(ctx context.Context, req *machine.LogsRequest) (chunker.Chunker, io.Closer, error) {
inspector, err := getContainerInspector(ctx, req.Namespace, req.Driver)
if err != nil {

View File

@ -23,6 +23,9 @@ type LoggingManager interface {
//
// SetSenders should be thread-safe.
SetSenders(senders []LogSender) []LogSender
// RegisteredLogs returns a list of registered logs containers.
RegisteredLogs() []string
}
// LogOptions for LogHandler.Reader.

View File

@ -118,6 +118,19 @@ func (manager *CircularBufferLoggingManager) getBuffer(id string, create bool) (
return buf.(*circular.Buffer), nil
}
// RegisteredLogs implements runtime.LoggingManager interface.
func (manager *CircularBufferLoggingManager) RegisteredLogs() []string {
var result []string
manager.buffers.Range(func(key, val any) bool {
result = append(result, key.(string))
return true
})
return result
}
type circularHandler struct {
manager *CircularBufferLoggingManager
id string

View File

@ -13,6 +13,7 @@ import (
"path/filepath"
"strings"
"github.com/siderolabs/gen/containers"
"github.com/siderolabs/go-tail"
"github.com/siderolabs/talos/internal/app/machined/pkg/runtime"
@ -22,6 +23,8 @@ import (
// FileLoggingManager implements simple logging to files.
type FileLoggingManager struct {
logDirectory string
registeredLogs containers.ConcurrentMap[string, struct{}]
}
// NewFileLoggingManager initializes new FileLoggingManager.
@ -36,6 +39,7 @@ func (manager *FileLoggingManager) ServiceLog(id string) runtime.LogHandler {
return &fileLogHandler{
logDirectory: manager.logDirectory,
id: id,
manager: manager,
}
}
@ -44,11 +48,23 @@ func (manager *FileLoggingManager) SetSenders([]runtime.LogSender) []runtime.Log
return nil
}
// RegisteredLogs implements runtime.LoggingManager interface.
func (manager *FileLoggingManager) RegisteredLogs() []string {
var result []string
manager.registeredLogs.ForEach(func(key string, _ struct{}) {
result = append(result, key)
})
return result
}
type fileLogHandler struct {
path string
logDirectory string
id string
manager *FileLoggingManager
}
func (handler *fileLogHandler) buildPath() error {
@ -67,7 +83,14 @@ func (handler *fileLogHandler) Writer() (io.WriteCloser, error) {
return nil, err
}
return os.OpenFile(handler.path, os.O_CREATE|os.O_APPEND|os.O_WRONLY, 0o666)
result, err := os.OpenFile(handler.path, os.O_CREATE|os.O_APPEND|os.O_WRONLY, 0o666)
if err != nil {
return nil, err
}
handler.manager.registeredLogs.GetOrCreate(handler.id, struct{}{})
return result, nil
}
// Reader implements runtime.LogHandler interface.

View File

@ -29,6 +29,11 @@ func (*NullLoggingManager) SetSenders([]runtime.LogSender) []runtime.LogSender {
return nil
}
// RegisteredLogs implements runtime.LoggingManager interface (by doing nothing).
func (*NullLoggingManager) RegisteredLogs() []string {
return nil
}
type nullLogHandler struct{}
func (*nullLogHandler) Writer() (io.WriteCloser, error) {

View File

@ -65,6 +65,7 @@ var rules = map[string]role.Set{
"/machine.MachineService/List": role.MakeSet(role.Admin, role.Operator, role.Reader),
"/machine.MachineService/LoadAvg": role.MakeSet(role.Admin, role.Operator, role.Reader),
"/machine.MachineService/Logs": role.MakeSet(role.Admin, role.Operator, role.Reader),
"/machine.MachineService/LogsContainers": role.MakeSet(role.Admin, role.Operator, role.Reader),
"/machine.MachineService/Memory": role.MakeSet(role.Admin, role.Operator, role.Reader),
"/machine.MachineService/MetaWrite": role.MakeSet(role.Admin),
"/machine.MachineService/MetaDelete": role.MakeSet(role.Admin),

File diff suppressed because it is too large Load Diff

View File

@ -48,6 +48,7 @@ const (
MachineService_DiskUsage_FullMethodName = "/machine.MachineService/DiskUsage"
MachineService_LoadAvg_FullMethodName = "/machine.MachineService/LoadAvg"
MachineService_Logs_FullMethodName = "/machine.MachineService/Logs"
MachineService_LogsContainers_FullMethodName = "/machine.MachineService/LogsContainers"
MachineService_Memory_FullMethodName = "/machine.MachineService/Memory"
MachineService_Mounts_FullMethodName = "/machine.MachineService/Mounts"
MachineService_NetworkDeviceStats_FullMethodName = "/machine.MachineService/NetworkDeviceStats"
@ -127,6 +128,7 @@ type MachineServiceClient interface {
DiskUsage(ctx context.Context, in *DiskUsageRequest, opts ...grpc.CallOption) (MachineService_DiskUsageClient, error)
LoadAvg(ctx context.Context, in *emptypb.Empty, opts ...grpc.CallOption) (*LoadAvgResponse, error)
Logs(ctx context.Context, in *LogsRequest, opts ...grpc.CallOption) (MachineService_LogsClient, error)
LogsContainers(ctx context.Context, in *emptypb.Empty, opts ...grpc.CallOption) (*LogsContainersResponse, error)
Memory(ctx context.Context, in *emptypb.Empty, opts ...grpc.CallOption) (*MemoryResponse, error)
Mounts(ctx context.Context, in *emptypb.Empty, opts ...grpc.CallOption) (*MountsResponse, error)
NetworkDeviceStats(ctx context.Context, in *emptypb.Empty, opts ...grpc.CallOption) (*NetworkDeviceStatsResponse, error)
@ -603,6 +605,15 @@ func (x *machineServiceLogsClient) Recv() (*common.Data, error) {
return m, nil
}
func (c *machineServiceClient) LogsContainers(ctx context.Context, in *emptypb.Empty, opts ...grpc.CallOption) (*LogsContainersResponse, error) {
out := new(LogsContainersResponse)
err := c.cc.Invoke(ctx, MachineService_LogsContainers_FullMethodName, in, out, opts...)
if err != nil {
return nil, err
}
return out, nil
}
func (c *machineServiceClient) Memory(ctx context.Context, in *emptypb.Empty, opts ...grpc.CallOption) (*MemoryResponse, error) {
out := new(MemoryResponse)
err := c.cc.Invoke(ctx, MachineService_Memory_FullMethodName, in, out, opts...)
@ -949,6 +960,7 @@ type MachineServiceServer interface {
DiskUsage(*DiskUsageRequest, MachineService_DiskUsageServer) error
LoadAvg(context.Context, *emptypb.Empty) (*LoadAvgResponse, error)
Logs(*LogsRequest, MachineService_LogsServer) error
LogsContainers(context.Context, *emptypb.Empty) (*LogsContainersResponse, error)
Memory(context.Context, *emptypb.Empty) (*MemoryResponse, error)
Mounts(context.Context, *emptypb.Empty) (*MountsResponse, error)
NetworkDeviceStats(context.Context, *emptypb.Empty) (*NetworkDeviceStatsResponse, error)
@ -1063,6 +1075,9 @@ func (UnimplementedMachineServiceServer) LoadAvg(context.Context, *emptypb.Empty
func (UnimplementedMachineServiceServer) Logs(*LogsRequest, MachineService_LogsServer) error {
return status.Errorf(codes.Unimplemented, "method Logs not implemented")
}
func (UnimplementedMachineServiceServer) LogsContainers(context.Context, *emptypb.Empty) (*LogsContainersResponse, error) {
return nil, status.Errorf(codes.Unimplemented, "method LogsContainers not implemented")
}
func (UnimplementedMachineServiceServer) Memory(context.Context, *emptypb.Empty) (*MemoryResponse, error) {
return nil, status.Errorf(codes.Unimplemented, "method Memory not implemented")
}
@ -1633,6 +1648,24 @@ func (x *machineServiceLogsServer) Send(m *common.Data) error {
return x.ServerStream.SendMsg(m)
}
func _MachineService_LogsContainers_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(emptypb.Empty)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(MachineServiceServer).LogsContainers(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: MachineService_LogsContainers_FullMethodName,
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(MachineServiceServer).LogsContainers(ctx, req.(*emptypb.Empty))
}
return interceptor(ctx, in, info, handler)
}
func _MachineService_Memory_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(emptypb.Empty)
if err := dec(in); err != nil {
@ -2163,6 +2196,10 @@ var MachineService_ServiceDesc = grpc.ServiceDesc{
MethodName: "LoadAvg",
Handler: _MachineService_LoadAvg_Handler,
},
{
MethodName: "LogsContainers",
Handler: _MachineService_LogsContainers_Handler,
},
{
MethodName: "Memory",
Handler: _MachineService_Memory_Handler,

View File

@ -3501,6 +3501,115 @@ func (m *ReadRequest) MarshalToSizedBufferVT(dAtA []byte) (int, error) {
return len(dAtA) - i, nil
}
func (m *LogsContainer) MarshalVT() (dAtA []byte, err error) {
if m == nil {
return nil, nil
}
size := m.SizeVT()
dAtA = make([]byte, size)
n, err := m.MarshalToSizedBufferVT(dAtA[:size])
if err != nil {
return nil, err
}
return dAtA[:n], nil
}
func (m *LogsContainer) MarshalToVT(dAtA []byte) (int, error) {
size := m.SizeVT()
return m.MarshalToSizedBufferVT(dAtA[:size])
}
func (m *LogsContainer) MarshalToSizedBufferVT(dAtA []byte) (int, error) {
if m == nil {
return 0, nil
}
i := len(dAtA)
_ = i
var l int
_ = l
if m.unknownFields != nil {
i -= len(m.unknownFields)
copy(dAtA[i:], m.unknownFields)
}
if len(m.Ids) > 0 {
for iNdEx := len(m.Ids) - 1; iNdEx >= 0; iNdEx-- {
i -= len(m.Ids[iNdEx])
copy(dAtA[i:], m.Ids[iNdEx])
i = protohelpers.EncodeVarint(dAtA, i, uint64(len(m.Ids[iNdEx])))
i--
dAtA[i] = 0x12
}
}
if m.Metadata != nil {
if vtmsg, ok := interface{}(m.Metadata).(interface {
MarshalToSizedBufferVT([]byte) (int, error)
}); ok {
size, err := vtmsg.MarshalToSizedBufferVT(dAtA[:i])
if err != nil {
return 0, err
}
i -= size
i = protohelpers.EncodeVarint(dAtA, i, uint64(size))
} else {
encoded, err := proto.Marshal(m.Metadata)
if err != nil {
return 0, err
}
i -= len(encoded)
copy(dAtA[i:], encoded)
i = protohelpers.EncodeVarint(dAtA, i, uint64(len(encoded)))
}
i--
dAtA[i] = 0xa
}
return len(dAtA) - i, nil
}
func (m *LogsContainersResponse) MarshalVT() (dAtA []byte, err error) {
if m == nil {
return nil, nil
}
size := m.SizeVT()
dAtA = make([]byte, size)
n, err := m.MarshalToSizedBufferVT(dAtA[:size])
if err != nil {
return nil, err
}
return dAtA[:n], nil
}
func (m *LogsContainersResponse) MarshalToVT(dAtA []byte) (int, error) {
size := m.SizeVT()
return m.MarshalToSizedBufferVT(dAtA[:size])
}
func (m *LogsContainersResponse) MarshalToSizedBufferVT(dAtA []byte) (int, error) {
if m == nil {
return 0, nil
}
i := len(dAtA)
_ = i
var l int
_ = l
if m.unknownFields != nil {
i -= len(m.unknownFields)
copy(dAtA[i:], m.unknownFields)
}
if len(m.Messages) > 0 {
for iNdEx := len(m.Messages) - 1; iNdEx >= 0; iNdEx-- {
size, err := m.Messages[iNdEx].MarshalToSizedBufferVT(dAtA[:i])
if err != nil {
return 0, err
}
i -= size
i = protohelpers.EncodeVarint(dAtA, i, uint64(size))
i--
dAtA[i] = 0xa
}
}
return len(dAtA) - i, nil
}
func (m *RollbackRequest) MarshalVT() (dAtA []byte, err error) {
if m == nil {
return nil, nil
@ -11359,6 +11468,48 @@ func (m *ReadRequest) SizeVT() (n int) {
return n
}
func (m *LogsContainer) SizeVT() (n int) {
if m == nil {
return 0
}
var l int
_ = l
if m.Metadata != nil {
if size, ok := interface{}(m.Metadata).(interface {
SizeVT() int
}); ok {
l = size.SizeVT()
} else {
l = proto.Size(m.Metadata)
}
n += 1 + l + protohelpers.SizeOfVarint(uint64(l))
}
if len(m.Ids) > 0 {
for _, s := range m.Ids {
l = len(s)
n += 1 + l + protohelpers.SizeOfVarint(uint64(l))
}
}
n += len(m.unknownFields)
return n
}
func (m *LogsContainersResponse) SizeVT() (n int) {
if m == nil {
return 0
}
var l int
_ = l
if len(m.Messages) > 0 {
for _, e := range m.Messages {
l = e.SizeVT()
n += 1 + l + protohelpers.SizeOfVarint(uint64(l))
}
}
n += len(m.unknownFields)
return n
}
func (m *RollbackRequest) SizeVT() (n int) {
if m == nil {
return 0
@ -21624,6 +21775,218 @@ func (m *ReadRequest) UnmarshalVT(dAtA []byte) error {
}
return nil
}
func (m *LogsContainer) UnmarshalVT(dAtA []byte) error {
l := len(dAtA)
iNdEx := 0
for iNdEx < l {
preIndex := iNdEx
var wire uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return protohelpers.ErrIntOverflow
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
wire |= uint64(b&0x7F) << shift
if b < 0x80 {
break
}
}
fieldNum := int32(wire >> 3)
wireType := int(wire & 0x7)
if wireType == 4 {
return fmt.Errorf("proto: LogsContainer: wiretype end group for non-group")
}
if fieldNum <= 0 {
return fmt.Errorf("proto: LogsContainer: illegal tag %d (wire type %d)", fieldNum, wire)
}
switch fieldNum {
case 1:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field Metadata", wireType)
}
var msglen int
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return protohelpers.ErrIntOverflow
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
msglen |= int(b&0x7F) << shift
if b < 0x80 {
break
}
}
if msglen < 0 {
return protohelpers.ErrInvalidLength
}
postIndex := iNdEx + msglen
if postIndex < 0 {
return protohelpers.ErrInvalidLength
}
if postIndex > l {
return io.ErrUnexpectedEOF
}
if m.Metadata == nil {
m.Metadata = &common.Metadata{}
}
if unmarshal, ok := interface{}(m.Metadata).(interface {
UnmarshalVT([]byte) error
}); ok {
if err := unmarshal.UnmarshalVT(dAtA[iNdEx:postIndex]); err != nil {
return err
}
} else {
if err := proto.Unmarshal(dAtA[iNdEx:postIndex], m.Metadata); err != nil {
return err
}
}
iNdEx = postIndex
case 2:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field Ids", wireType)
}
var stringLen uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return protohelpers.ErrIntOverflow
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
stringLen |= uint64(b&0x7F) << shift
if b < 0x80 {
break
}
}
intStringLen := int(stringLen)
if intStringLen < 0 {
return protohelpers.ErrInvalidLength
}
postIndex := iNdEx + intStringLen
if postIndex < 0 {
return protohelpers.ErrInvalidLength
}
if postIndex > l {
return io.ErrUnexpectedEOF
}
m.Ids = append(m.Ids, string(dAtA[iNdEx:postIndex]))
iNdEx = postIndex
default:
iNdEx = preIndex
skippy, err := protohelpers.Skip(dAtA[iNdEx:])
if err != nil {
return err
}
if (skippy < 0) || (iNdEx+skippy) < 0 {
return protohelpers.ErrInvalidLength
}
if (iNdEx + skippy) > l {
return io.ErrUnexpectedEOF
}
m.unknownFields = append(m.unknownFields, dAtA[iNdEx:iNdEx+skippy]...)
iNdEx += skippy
}
}
if iNdEx > l {
return io.ErrUnexpectedEOF
}
return nil
}
func (m *LogsContainersResponse) UnmarshalVT(dAtA []byte) error {
l := len(dAtA)
iNdEx := 0
for iNdEx < l {
preIndex := iNdEx
var wire uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return protohelpers.ErrIntOverflow
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
wire |= uint64(b&0x7F) << shift
if b < 0x80 {
break
}
}
fieldNum := int32(wire >> 3)
wireType := int(wire & 0x7)
if wireType == 4 {
return fmt.Errorf("proto: LogsContainersResponse: wiretype end group for non-group")
}
if fieldNum <= 0 {
return fmt.Errorf("proto: LogsContainersResponse: illegal tag %d (wire type %d)", fieldNum, wire)
}
switch fieldNum {
case 1:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field Messages", wireType)
}
var msglen int
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return protohelpers.ErrIntOverflow
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
msglen |= int(b&0x7F) << shift
if b < 0x80 {
break
}
}
if msglen < 0 {
return protohelpers.ErrInvalidLength
}
postIndex := iNdEx + msglen
if postIndex < 0 {
return protohelpers.ErrInvalidLength
}
if postIndex > l {
return io.ErrUnexpectedEOF
}
m.Messages = append(m.Messages, &LogsContainer{})
if err := m.Messages[len(m.Messages)-1].UnmarshalVT(dAtA[iNdEx:postIndex]); err != nil {
return err
}
iNdEx = postIndex
default:
iNdEx = preIndex
skippy, err := protohelpers.Skip(dAtA[iNdEx:])
if err != nil {
return err
}
if (skippy < 0) || (iNdEx+skippy) < 0 {
return protohelpers.ErrInvalidLength
}
if (iNdEx + skippy) > l {
return io.ErrUnexpectedEOF
}
m.unknownFields = append(m.unknownFields, dAtA[iNdEx:iNdEx+skippy]...)
iNdEx += skippy
}
}
if iNdEx > l {
return io.ErrUnexpectedEOF
}
return nil
}
func (m *RollbackRequest) UnmarshalVT(dAtA []byte) error {
l := len(dAtA)
iNdEx := 0

View File

@ -460,6 +460,21 @@ func (c *Client) Logs(ctx context.Context, namespace string, driver common.Conta
return
}
// LogsContainers implements the proto.MachineServiceClient interface.
func (c *Client) LogsContainers(ctx context.Context, callOptions ...grpc.CallOption) (resp *machineapi.LogsContainersResponse, err error) {
resp, err = c.MachineClient.LogsContainers(
ctx,
&emptypb.Empty{},
callOptions...,
)
var filtered interface{}
filtered, err = FilterMessages(resp, err)
resp, _ = filtered.(*machineapi.LogsContainersResponse) //nolint:errcheck
return
}
// Version implements the proto.MachineServiceClient interface.
func (c *Client) Version(ctx context.Context, callOptions ...grpc.CallOption) (resp *machineapi.VersionResponse, err error) {
resp, err = c.MachineClient.Version(

View File

@ -343,6 +343,8 @@ description: Talos gRPC API reference.
- [ListRequest](#machine.ListRequest)
- [LoadAvg](#machine.LoadAvg)
- [LoadAvgResponse](#machine.LoadAvgResponse)
- [LogsContainer](#machine.LogsContainer)
- [LogsContainersResponse](#machine.LogsContainersResponse)
- [LogsRequest](#machine.LogsRequest)
- [MachineConfig](#machine.MachineConfig)
- [MachineStatusEvent](#machine.MachineStatusEvent)
@ -5950,6 +5952,37 @@ ListRequest describes a request to list the contents of a directory.
<a name="machine.LogsContainer"></a>
### LogsContainer
LogsContainer desribes all avalaible registered log containers.
| Field | Type | Label | Description |
| ----- | ---- | ----- | ----------- |
| metadata | [common.Metadata](#common.Metadata) | | |
| ids | [string](#string) | repeated | |
<a name="machine.LogsContainersResponse"></a>
### LogsContainersResponse
| Field | Type | Label | Description |
| ----- | ---- | ----- | ----------- |
| messages | [LogsContainer](#machine.LogsContainer) | repeated | |
<a name="machine.LogsRequest"></a>
### LogsRequest
@ -7649,6 +7682,7 @@ The machine service definition.
| DiskUsage | [DiskUsageRequest](#machine.DiskUsageRequest) | [DiskUsageInfo](#machine.DiskUsageInfo) stream | |
| LoadAvg | [.google.protobuf.Empty](#google.protobuf.Empty) | [LoadAvgResponse](#machine.LoadAvgResponse) | |
| Logs | [LogsRequest](#machine.LogsRequest) | [.common.Data](#common.Data) stream | |
| LogsContainers | [.google.protobuf.Empty](#google.protobuf.Empty) | [LogsContainersResponse](#machine.LogsContainersResponse) | |
| Memory | [.google.protobuf.Empty](#google.protobuf.Empty) | [MemoryResponse](#machine.MemoryResponse) | |
| Mounts | [.google.protobuf.Empty](#google.protobuf.Empty) | [MountsResponse](#machine.MountsResponse) | |
| NetworkDeviceStats | [.google.protobuf.Empty](#google.protobuf.Empty) | [NetworkDeviceStatsResponse](#machine.NetworkDeviceStatsResponse) | |