feat: added journald collection package to bootstrapper internal packages

This commit is contained in:
miampf 2023-03-29 14:45:13 +02:00 committed by GitHub
parent 2a8169dd3b
commit c1dbf0561a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 127 additions and 0 deletions

View File

@ -0,0 +1,16 @@
load("@io_bazel_rules_go//go:def.bzl", "go_library")
load("//bazel/go:go_test.bzl", "go_test")
go_library(
name = "journald",
srcs = ["journald.go"],
importpath = "github.com/edgelesssys/constellation/v2/bootstrapper/internal/journald",
visibility = ["//bootstrapper:__subpackages__"],
)
go_test(
name = "journald_test",
srcs = ["journald_test.go"],
embed = [":journald"],
deps = ["@com_github_stretchr_testify//assert"],
)

View File

@ -0,0 +1,47 @@
/*
Copyright (c) Edgeless Systems GmbH
SPDX-License-Identifier: AGPL-3.0-only
*/
/*
Package journald provides functions to read and collect journald logs.
*/
package journald
import (
"context"
"errors"
"fmt"
"os/exec"
)
type command interface {
Output() ([]byte, error)
}
// Collector collects logs from journald.
type Collector struct {
cmd command
}
// NewCollector creates a new Collector for journald logs.
func NewCollector(ctx context.Context) (*Collector, error) {
cmd := exec.CommandContext(ctx, "journalctl")
if cmd.Err != nil {
return nil, cmd.Err
}
return &Collector{cmd}, nil
}
// Collect gets all journald logs from a service and returns a byte slice with the plain text logs.
func (c *Collector) Collect() ([]byte, error) {
out, err := c.cmd.Output()
var exitErr *exec.ExitError
if errors.As(err, &exitErr) {
return nil, fmt.Errorf("executing %q failed: %s", c.cmd, exitErr.Stderr)
} else if err != nil {
return nil, fmt.Errorf("executing command: %w", err)
}
return out, nil
}

View File

@ -0,0 +1,64 @@
/*
Copyright (c) Edgeless Systems GmbH
SPDX-License-Identifier: AGPL-3.0-only
*/
package journald
import (
"errors"
"os/exec"
"testing"
"github.com/stretchr/testify/assert"
)
type stubJournaldCommand struct {
outputReturn []byte
outputError error
}
func (j *stubJournaldCommand) Output() ([]byte, error) {
return j.outputReturn, j.outputError
}
func TestCollect(t *testing.T) {
someError := errors.New("failed")
testCases := map[string]struct {
command *stubJournaldCommand
wantedOutput []byte
wantErr bool
}{
"success": {
command: &stubJournaldCommand{},
},
"execution failed": {
command: &stubJournaldCommand{outputError: someError},
wantErr: true,
},
"exit error": {
command: &stubJournaldCommand{outputError: &exec.ExitError{}},
wantErr: true,
},
"output check": {
command: &stubJournaldCommand{outputReturn: []byte("asdf")},
wantedOutput: []byte("asdf"),
},
}
for name, tc := range testCases {
t.Run(name, func(t *testing.T) {
assert := assert.New(t)
collector := Collector{cmd: tc.command}
out, err := collector.Collect()
if tc.wantErr {
assert.Error(err)
}
assert.Equal(out, tc.wantedOutput)
})
}
}