blob: e66b6d71d1bfa0e3ab59514b1b7fe9a031ea51c2 [file] [log] [blame]
Serge Bazanski1ebd1e12020-07-13 19:17:16 +02001// Copyright 2020 The Monogon Project Authors.
2//
3// SPDX-License-Identifier: Apache-2.0
4//
5// Licensed under the Apache License, Version 2.0 (the "License");
6// you may not use this file except in compliance with the License.
7// You may obtain a copy of the License at
8//
9// http://www.apache.org/licenses/LICENSE-2.0
10//
11// Unless required by applicable law or agreed to in writing, software
12// distributed under the License is distributed on an "AS IS" BASIS,
13// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14// See the License for the specific language governing permissions and
15// limitations under the License.
16
17package main
18
19import (
20 "context"
21 "math"
22
23 "git.monogon.dev/source/nexantic.git/core/internal/cluster"
24 "git.monogon.dev/source/nexantic.git/core/internal/containerd"
25 "git.monogon.dev/source/nexantic.git/core/internal/kubernetes"
26 apb "git.monogon.dev/source/nexantic.git/core/proto/api"
27
28 "google.golang.org/grpc/codes"
29 "google.golang.org/grpc/status"
30)
31
32// debugService implements the Smalltown node debug API.
33// TODO(q3k): this should probably be implemented somewhere else way once we have a better
34// supervision introspection/status API.
35type debugService struct {
36 cluster *cluster.Manager
37 kubernetes *kubernetes.Service
38 containerd *containerd.Service
39}
40
41func (s *debugService) GetDebugKubeconfig(ctx context.Context, req *apb.GetDebugKubeconfigRequest) (*apb.GetDebugKubeconfigResponse, error) {
42 return s.kubernetes.GetDebugKubeconfig(ctx, req)
43}
44
45// GetComponentLogs gets various logbuffers from binaries we call. This function just deals with the first path component,
46// delegating the rest to the service-specific handlers.
47func (s *debugService) GetComponentLogs(ctx context.Context, req *apb.GetComponentLogsRequest) (*apb.GetComponentLogsResponse, error) {
48 if len(req.ComponentPath) < 1 {
49 return nil, status.Error(codes.InvalidArgument, "component_path needs to contain at least one part")
50 }
51 linesToRead := int(req.TailLines)
52 if linesToRead == 0 {
53 linesToRead = math.MaxInt32
54 }
55 var lines []string
56 var err error
57 switch req.ComponentPath[0] {
58 case "containerd":
59 if len(req.ComponentPath) < 2 {
60 lines = s.containerd.Log.ReadLinesTruncated(linesToRead, "...")
61 } else if req.ComponentPath[1] == "runsc" {
62 lines = s.containerd.RunscLog.ReadLinesTruncated(linesToRead, "...")
63 }
64 case "kube":
65 if len(req.ComponentPath) < 2 {
66 return nil, status.Error(codes.NotFound, "Component not found")
67 }
68 lines, err = s.kubernetes.GetComponentLogs(req.ComponentPath[1], linesToRead)
69 if err != nil {
70 return nil, status.Error(codes.NotFound, "Component not found")
71 }
72 default:
73 return nil, status.Error(codes.NotFound, "component not found")
74 }
75 return &apb.GetComponentLogsResponse{Line: lines}, nil
76}
77
78// GetCondition checks for various conditions exposed by different services. Mostly intended for testing. If you need
79// to make sure something is available in an E2E test, consider adding a condition here.
80// TODO(q3k): since all conditions are now 'true' after the node lifecycle refactor, remove this call - or, start the
81// debug service earlier.
82func (s *debugService) GetCondition(ctx context.Context, req *apb.GetConditionRequest) (*apb.GetConditionResponse, error) {
83 var ok bool
84 switch req.Name {
85 case "IPAssigned":
86 ok = true
87 case "DataAvailable":
88 ok = true
89 default:
90 return nil, status.Errorf(codes.NotFound, "condition %v not found", req.Name)
91 }
92 return &apb.GetConditionResponse{
93 Ok: ok,
94 }, nil
95}