blob: 2ed38969815be4c57f101ea826692b64e5ef28ef [file] [log] [blame]
Lorenz Brun878f5f92020-05-12 16:15:39 +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 node
18
19// Implements a debug gRPC service for testing and introspection
20// This is attached to the SmalltownNode because most other services are instantiated there and thus are accessible
21// from there. Have a look at //core/cmd/dbg if you need to interact with this from a CLI.
22
23import (
24 "context"
25 "math"
26
27 "google.golang.org/grpc/codes"
28 "google.golang.org/grpc/status"
29
30 schema "git.monogon.dev/source/nexantic.git/core/generated/api"
31 "git.monogon.dev/source/nexantic.git/core/internal/storage"
32)
33
34func (s *SmalltownNode) GetDebugKubeconfig(ctx context.Context, req *schema.GetDebugKubeconfigRequest) (*schema.GetDebugKubeconfigResponse, error) {
35 return s.Kubernetes.GetDebugKubeconfig(ctx, req)
36}
37
38// GetComponentLogs gets various logbuffers from binaries we call. This function just deals with the first path component,
39// delegating the rest to the service-specific handlers.
40func (s *SmalltownNode) GetComponentLogs(ctx context.Context, req *schema.GetComponentLogsRequest) (*schema.GetComponentLogsResponse, error) {
41 if len(req.ComponentPath) < 1 {
42 return nil, status.Error(codes.InvalidArgument, "component_path needs to contain at least one part")
43 }
44 linesToRead := int(req.TailLines)
45 if linesToRead == 0 {
46 linesToRead = math.MaxInt32
47 }
48 var lines []string
49 var err error
50 switch req.ComponentPath[0] {
51 case "containerd":
Lorenz Brun6acfc322020-05-13 17:01:26 +020052 if len(req.ComponentPath) < 2 {
53 lines = s.Containerd.Log.ReadLinesTruncated(linesToRead, "...")
54 } else if req.ComponentPath[1] == "runsc" {
55 lines = s.Containerd.RunscLog.ReadLinesTruncated(linesToRead, "...")
56 }
Lorenz Brun878f5f92020-05-12 16:15:39 +020057 case "kube":
58 if len(req.ComponentPath) < 2 {
59 return nil, status.Error(codes.NotFound, "Component not found")
60 }
61 lines, err = s.Kubernetes.GetComponentLogs(req.ComponentPath[1], linesToRead)
62 if err != nil {
63 return nil, status.Error(codes.NotFound, "Component not found")
64 }
65 default:
66 return nil, status.Error(codes.NotFound, "component not found")
67 }
68 return &schema.GetComponentLogsResponse{Line: lines}, nil
69}
70
71// GetCondition checks for various conditions exposed by different services. Mostly intended for testing. If you need
72// to make sure something is available in an E2E test, consider adding a condition here.
73func (s *SmalltownNode) GetCondition(ctx context.Context, req *schema.GetConditionRequest) (*schema.GetConditionResponse, error) {
74 var ok bool
75 switch req.Name {
76 case "IPAssigned":
77 ip, err := s.Network.GetIP(ctx, false)
78 if err == nil && ip != nil {
79 ok = true
80 }
81 case "DataAvailable":
82 _, err := s.Storage.GetPathInPlace(storage.PlaceData, "test")
83 if err == nil {
84 ok = true
85 }
86 default:
87 return nil, status.Errorf(codes.NotFound, "condition %v not found", req.Name)
88 }
89 return &schema.GetConditionResponse{
90 Ok: ok,
91 }, nil
92}