diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 1e7a2b1a..e080ef3d 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -26,3 +26,15 @@ repos: language: system entry: bash -c 'cd tgm-collector && go mod tidy' pass_filenames: false + + - id: golangci-lint + name: golangci-lint (collector-framework) must pass + language: system + entry: bash -c 'cd collector-framework && make lint' + pass_filenames: false + + - id: go-mod-tidy + name: run go mod tidy (collector-framework) + language: system + entry: bash -c 'cd collector-framework && go mod tidy' + pass_filenames: false diff --git a/collector-framework/Containerfile b/collector-framework/Containerfile new file mode 100644 index 00000000..331c2b25 --- /dev/null +++ b/collector-framework/Containerfile @@ -0,0 +1,42 @@ +FROM registry.access.redhat.com/ubi9 AS build + +# Config +# ARGs will persist into other images, ENV vars won't. We want these to be available in both. +ENV DIR=/usr/th +ENV BIN_DIR=$DIR/bin +ENV CFG_DIR=$DIR/cfg +ENV SRC_DIR=$DIR/src + +RUN dnf -y install go make + +RUN mkdir ${DIR} && \ + mkdir ${BIN_DIR} && \ + mkdir ${CFG_DIR} && \ + mkdir ${SRC_DIR} + +ADD . ${SRC_DIR} +WORKDIR ${SRC_DIR} + +RUN make install-tools + +RUN pwd && ls +# build the test binary: outputs to ${SRC_DIR}/vse-sync-testsuite +RUN make build + +RUN cp ${SRC_DIR}/vse-sync-testsuite ${BIN_DIR}/collector-tool + +RUN dnf remove -y go make && \ + dnf clean all && \ + rm -rf ${TNF_SRC_DIR} && \ + rm -rf ${TEMP_DIR} && \ + rm -rf /root/.cache && \ + rm -rf /root/go/pkg && \ + rm -rf /root/go/src && \ + rm -rf /usr/lib/golang/pkg && \ + rm -rf /usr/lib/golang/src + + +FROM scratch +COPY --from=build / / +WORKDIR /usr/th/bin +CMD ./collector-tool diff --git a/collector-framework/LICENSE b/collector-framework/LICENSE new file mode 100644 index 00000000..1b04da38 --- /dev/null +++ b/collector-framework/LICENSE @@ -0,0 +1,15 @@ +SPDX-License-Identifier: GPL-2.0-or-later + +This program is free software; you can redistribute it and/or modify it +under the terms of the GNU General Public License as published by the +Free Software Foundation; either version 2 of the License, or (at your +option) any later version. +. +This program is distributed in the hope that it will be useful, but WITHOUT +ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. +. +You should have received a copy of the GNU General Public License along with +this program; if not, write to the Free Software Foundation, Inc., 51 Franklin +Street, Fifth Floor, Boston, MA 02110-1301, USA, search GPL-2.0-or-later or +see . diff --git a/collector-framework/Makefile b/collector-framework/Makefile new file mode 100644 index 00000000..bae2bf0d --- /dev/null +++ b/collector-framework/Makefile @@ -0,0 +1,27 @@ +.PHONY: + install-tools + build + build-image + lint + +# Get default value of $GOBIN if not explicitly set +GO_PATH=$(shell go env GOPATH) +ifeq (,$(shell go env GOBIN)) + GOBIN=${GO_PATH}/bin +else + GOBIN=$(shell go env GOBIN) +endif + +# Install build tools and other required software. +install-tools: + go install github.com/onsi/ginkgo/v2/ginkgo + +# Build test binary +build: + PATH=${PATH}:${GOBIN} go build --race + +build-image: + podman build -t synctest:custom -f Containerfile + +lint: + golangci-lint run --timeout 5m0s --fix diff --git a/collector-framework/README.md b/collector-framework/README.md new file mode 100644 index 00000000..2ac01ee7 --- /dev/null +++ b/collector-framework/README.md @@ -0,0 +1,77 @@ +# synchronization-testsuites + +The main purpose of this repo is build the necessary tooling to collect necessary synchronization-related data logs from a running OpenShift cluster. This data will then be leveraged by different analysis tools to determine if the cluster is running within acceptable bounds synchronization-wise.``` + +The core approach taken is to strongly encourage and enforce separation of concerns between: +1. Declarative description of the cluster(s) under test +1. Configuration of a test (e.g. number of repetitions, acceptable thresholds, etc.) +1. Collectors - methods of collecting indicative information about the cluster +1. Checks - performed on collected values + +## Setup + +1. [Install Go](https://go.dev/doc/install) +1. Install dependencies with `go mod tidy` + +### Development Extras +1. Install dev binaries: `make install-tools`. Ensure your `$GOBIN` is on your `$PATH` +1. yamllint + 1. [Install yamllint](https://yamllint.readthedocs.io/en/stable/) with `sudo yum install yamllint` + 1. run with `yamllint ./` +1. golangci-lint + 1. [Install golangci-lint](https://golangci-lint.run/usage/install/#local-installation) + 1. run with `make lint` +1. license-eye + 1. [Install license-eye](https://github.com/apache/skywalking-eyes) with `go install github.com/apache/skywalking-eyes/cmd/license-eye@latest` + 1. run with `license-eye header check` or `license-eye header fix` +1. pre-commit + 1. on RHEL, `pre-commit` requires recompiling python to include optional sqlite modules: + 1. `sudo yum install sqlite-devel` + 1. See instructions [here](https://tecadmin.net/how-to-install-python-3-10-on-centos-rhel-8-fedora/) + 1. install pre-commit with `pip3.10 install pre-commit` + 1. configure your repository to run pre-commit hooks with `pre-commit install` + 1. manually run against all files with `pre-commit run --all-files` or against staged files with `pre-commit run`. + 1. Otherwise pre-commit will now run automatically when you make a new commit. + +## Usage +### Building binary +Run the following command to build the binary used in the following commands: +```shell +go build +``` +###### NOTE: use the `--race` flag when developing collectors. + +### Checking Enviroment +Run the following command (check help string for more details): + +```shell +./collector-framework env verify --interface="" --kubeconfig="${KUBECONFIG}" +``` + +### Running Collectors + +Run the following command (check help string for more details): + +```shell +./collector-framework collect --interface="" --kubeconfig="${KUBECONFIG}" +``` + +### Fetching logs +The log subcommand has been removed. Instead we have implimented at collector which is enabled by default. +If possible you should use a log aggregator. You can control the collectors running using the `--collector` flag. + +## Running tests + +TODO: implement tests for all packages + +To test the framework components run `ginkgo pkg/`, for example to run the unit tests for the `config` package use `ginkgo pkg/config` + +## Contributing to the repo + +See [Adding a collector](doc/implementing_a_collector.md) + +## To Do List + +* unit tests for all of `pkg/` +* add more collectors +* better data persistance options diff --git a/collector-framework/doc/implementing_a_collector.md b/collector-framework/doc/implementing_a_collector.md new file mode 100644 index 00000000..06a62b8e --- /dev/null +++ b/collector-framework/doc/implementing_a_collector.md @@ -0,0 +1,140 @@ +# Implementing Collectors + +## High level flow +This sequance diagram shows the high level flow of data from the SUT to User and contains +```mermaid +sequenceDiagram + participant User + participant Runner + participant Collector + participant Fetcher + participant SUT + participant callback + + User ->>+ Runner: Runs binary + note left of Runner: runner.Run() + + Runner ->> Runner: Gather collectors + note right of Runner: GetCollectorsToRun() + + Runner ->> Collector: Starts collector + note over Runner,Collector: Runner.start() calls Collector.Start() + + Runner ->> Runner: Spawns Runner.Poller() goroutine for collector + loop Runner.Poller(): Until user interupts or number of polls is reached + Runner ->>+ Collector: Calls Poll + note over Runner,Collector: Runner.Poller() calls Collector.Poll() + + Collector ->>+ Fetcher: Requests Data + note over Collector,Fetcher: Collector.poll() calls function
in devices submodule which
inturn calls Fetcher.Fetch() + Fetcher ->>+ SUT: Runs commands + note left of SUT: Fetcher.Fetch() calls runCommands() + + SUT ->>- Fetcher: Command result + note left of SUT: runCommands() returns result + Fetcher ->>- Collector: Returns results + note left of Fetcher: Fetcher.Fetch() unpacks results into a struct + + + Collector ->> callback: sends data to callback + note left of callback: Callback.Call() + callback ->> User: Presents formatted data to user + Collector ->>- Runner: Sends poll sucess/failure via results channel + note left of Collector: resultsChan <- PollResult{CollectorName, Errors} + + Runner ->> Runner: Reacts to failures + end + Runner ->>- Collector: Stops collector + note left of Collector: Runner.cleanUpAll() calls Collector.CleanUp() +``` + +## Step by step +You will first need to create a stuct for reporting the collected values to the user. It needs to conform to the `callbacks.OutputType` interface and any fields which you wish to show the user will require a json tag. + +Any collector must conform to the collector interface It should use the callback to expose collected information to the user. + +Once you have filled out your collector. Any arguments should be added to the `CollectionConstuctor` and function which takes the `CollectionConstuctor` should also be defined and added to the `registry`. + +An example of a very simple collector: + +In `collectors/collectors.go` any arguments additional should be added to the `CollectionConstuctor` +```go +... +type CollectionConstuctor struct { + ... + Msg string +} +... +``` + +In `collectors/announcement_collector.go` you will first need to create your reporting stuct then +you should define your collector and a constructor function which takes `CollectionConstuctor` as an argument. +```go +package collectors + +import ( + "fmt" + + "github.com/redhat-partner-solutions/vse-sync-collection-tools/collector-framework/pkg/callbacks" +) +const ( + AnnouncementCollectorName = "MyCustomerAnouncer" + AnnouncementMsg = "custom-anouncement" +) + +// Reporting message +type AnnouncementMessage struct { + Msg string `json:"msg"` +} + +func (annMsg *AnnouncementMessage) GetAnalyserFormat() (*callbacks.AnalyserFormatType, error) { + formatted := callbacks.AnalyserFormatType{ + ID: "customAnoucner", + Data: []string{ + annMsg.Msg, + }, + } + return &formatted, nil +} + +// Collector +type AnnouncementCollector struct { + *baseCollector + msg string +} + +func (announcer *AnnouncementCollector) Poll(resultsChan chan PollResult, wg *utils.WaitGroupCount) { + defer func() { + wg.Done() + }() + + msg := &AnnouncementMessage{Msg: announcer.msg} + + errs := make([]error, 0) + err := announcer.callback.Call(&msg, AnnouncementMsg) + if err != nil { + errs = append(errs, fmt.Errorf("callback failed %w", err)) + } + resultsChan <- PollResult{ + CollectorName: AnnouncementCollectorName, + Errors: errorsToReturn, + } +} + +func NewAnnouncementCollector(constuctor *CollectionConstuctor) (Collector, error) { + announcer := AnnouncementCollector{ + baseCollector: newBaseCollector( + constructor.PollInterval, + false, + constructor.Callback, + ), + msg:constructor.Msg, + } + return &announcer, nil +} + +func init(){ + // We'll make this a required collector + RegisterCollector(AnnouncementCollectorName, NewAnnouncementCollector, required) +} +``` diff --git a/collector-framework/doc/implementing_a_fetcher.md b/collector-framework/doc/implementing_a_fetcher.md new file mode 100644 index 00000000..fa21d63b --- /dev/null +++ b/collector-framework/doc/implementing_a_fetcher.md @@ -0,0 +1,96 @@ +Fetchers a how we collect values from the cluster. +After adding commands to the fetcher when `Fetch` is called these commands are executed on the provided context. + +If we wanted to fetch the uptime we could simply add the following command + + +```go +var uptimeFetcher *Fetcher + +func init(){ + uptimeFetcher = NewFetcher() + + // "MyUptimeValue" is the key which the value be returned in the result of the fetch + // "uptime" is the command to execute + // the final parameter weither to trim whitespace from the output. + err := uptimeFetcher.AddNewCommand("MyUptimeValue", "uptime", true) + if err != nil { + panic("Failed to add uptime command to fetcher") + } +} +``` + +We need to provide a stuct to upack the data into. The field which we want to pass the value into must have a `fetcherKey` tag to allow the the fetcher to populate the field. The value of the tag must match the key in the result. + +Note: You will need defined a method `GetAnalyserFormat` [see collector documentation](implementing_a_collector.md) for clarification. + +```go +type MyUptime struct { + Raw string `fetcherKey:"MyUptimeValue"` +} + +func (uptime *MyUptime) GetAnalyserFormat() { + formatted := callbacks.AnalyserFormatType{ + ID: "MyUptimeValue", + Data: []string{ + uptime.Raw, + }, + } + return &formatted, nil +} + +func GetUptime(ctx clients.ContainerContext) (MyUptime, error) { + uptime := MyUptime{} + uptimeFetcher.Fetch(ctx, &uptime) + if err != nil { + log.Debugf("failed to fetch uptime %s", err.Error()) + return gpsNav, err + } + return uptime, nil +} +``` + +If you wish to extract/filter/transform the raw data you can define a post processing function as follows +```go +type MyUptime struct { + Raw string `fetcherKey:"MyUptimeValue"` + Uptime string `fetcherKey:"Uptime"` + Load1 string `fetcherKey:"load1"` + Load5 string `fetcherKey:"load5"` + Load15 string `fetcherKey:"load15"` +} + +var ( + uptimeFetcher *Fetcher + uptimeRegEx = regex.MustCompile( + `\d+:\d+:\d+ up (.*)` + + `,\s+\d+:\d+,\s+\d+ users,` + + `\s+load average:\s+(\d+\.?\d*), (\d+\.?\d*), (\d+\.?\d*)` + // Example 12:57:08 up 49 days, 1:46, 0 users, load average: 7.10, 9.33, 10.35 + ) +) + +func init(){ + uptimeFetcher = NewFetcher() + err := uptimeFetcher.AddNewCommand("MyUptimeValue", "uptime", true) + if err != nil { + panic("Failed to add uptime command to fetcher") + } + // Assign processUptime to uptimeFetcher. + uptimeFetcher.SetPostProcessor(processUptime) +} + +// Here we define something to take the raw result from MyUptimeValue and extracts values +func processUptime(result map[string]string) (map[string]string, error) { + processedResult := make(map[string]string) + match := uptimeRegEx.FindStringSubmatch(result["MyUptimeValue"]) + if len(match) == 0 { + return processedResult, fmt.Errorf("unable to to parse uptime output: %s", result["MyUptimeValue"]) + } + processedResult["Uptime"] = match[1] + processedResult["load1"] = match[2] + processedResult["load5"] = match[3] + processedResult["load15"] = match[4] + return processedResult, nil +} +``` diff --git a/collector-framework/go.mod b/collector-framework/go.mod new file mode 100644 index 00000000..e9395d95 --- /dev/null +++ b/collector-framework/go.mod @@ -0,0 +1,64 @@ +module github.com/redhat-partner-solutions/vse-sync-collection-tools/collector-framework + +go 1.18 + +require ( + github.com/Netflix/go-expect v0.0.0-20220104043353-73e0943537d2 + github.com/icza/backscanner v0.0.0-20230330133933-bf6beb754c70 + github.com/onsi/ginkgo/v2 v2.9.0 + github.com/onsi/gomega v1.27.1 + github.com/openshift/client-go v0.0.0-20230120202327-72f107311084 + github.com/sirupsen/logrus v1.9.0 + golang.org/x/mod v0.8.0 + k8s.io/api v0.26.1 + k8s.io/apimachinery v0.26.1 + k8s.io/client-go v0.26.1 + k8s.io/kubectl v0.26.1 +) + +require ( + github.com/creack/pty v1.1.17 // indirect + github.com/davecgh/go-spew v1.1.1 // indirect + github.com/emicklei/go-restful/v3 v3.10.1 // indirect + github.com/evanphx/json-patch v4.12.0+incompatible // indirect + github.com/go-logr/logr v1.2.3 // indirect + github.com/go-openapi/jsonpointer v0.19.6 // indirect + github.com/go-openapi/jsonreference v0.20.2 // indirect + github.com/go-openapi/swag v0.22.3 // indirect + github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0 // indirect + github.com/gogo/protobuf v1.3.2 // indirect + github.com/golang/protobuf v1.5.2 // indirect + github.com/google/gnostic v0.6.9 // indirect + github.com/google/go-cmp v0.5.9 // indirect + github.com/google/gofuzz v1.2.0 // indirect + github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38 // indirect + github.com/imdario/mergo v0.3.13 // indirect + github.com/josharian/intern v1.0.0 // indirect + github.com/json-iterator/go v1.1.12 // indirect + github.com/mailru/easyjson v0.7.7 // indirect + github.com/moby/spdystream v0.2.0 // indirect + github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect + github.com/modern-go/reflect2 v1.0.2 // indirect + github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect + github.com/openshift/api v0.0.0-20230120195050-6ba31fa438f2 // indirect + github.com/pkg/errors v0.9.1 // indirect + github.com/spf13/pflag v1.0.5 // indirect + golang.org/x/net v0.17.0 // indirect + golang.org/x/oauth2 v0.5.0 // indirect + golang.org/x/sys v0.13.0 // indirect + golang.org/x/term v0.13.0 // indirect + golang.org/x/text v0.13.0 // indirect + golang.org/x/time v0.3.0 // indirect + golang.org/x/tools v0.6.0 // indirect + google.golang.org/appengine v1.6.7 // indirect + google.golang.org/protobuf v1.28.1 // indirect + gopkg.in/inf.v0 v0.9.1 // indirect + gopkg.in/yaml.v2 v2.4.0 // indirect + gopkg.in/yaml.v3 v3.0.1 // indirect + k8s.io/klog/v2 v2.90.0 // indirect + k8s.io/kube-openapi v0.0.0-20230217203603-ff9a8e8fa21d // indirect + k8s.io/utils v0.0.0-20230220204549-a5ecb0141aa5 // indirect + sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd // indirect + sigs.k8s.io/structured-merge-diff/v4 v4.2.3 // indirect + sigs.k8s.io/yaml v1.3.0 // indirect +) diff --git a/collector-framework/go.sum b/collector-framework/go.sum new file mode 100644 index 00000000..6758d8cd --- /dev/null +++ b/collector-framework/go.sum @@ -0,0 +1,297 @@ +cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= +github.com/Netflix/go-expect v0.0.0-20220104043353-73e0943537d2 h1:+vx7roKuyA63nhn5WAunQHLTznkw5W8b1Xc0dNjp83s= +github.com/Netflix/go-expect v0.0.0-20220104043353-73e0943537d2/go.mod h1:HBCaDeC1lPdgDeDbhX8XFpy1jqjK0IBG8W5K+xYqA0w= +github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= +github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY= +github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5 h1:0CwZNZbxp69SHPdPJAN/hZIm0C4OItdklCFmMRWYpio= +github.com/buger/jsonparser v1.1.1/go.mod h1:6RYKKt7H4d4+iWqouImQ9R2FZql3VbhNgx27UK13J/0= +github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= +github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= +github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= +github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= +github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= +github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= +github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= +github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= +github.com/cncf/xds/go v0.0.0-20210312221358-fbca930ec8ed/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= +github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= +github.com/creack/pty v1.1.17 h1:QeVUsEDNrLBW4tMgZHvxy18sKtr6VI492kBhUfhDJNI= +github.com/creack/pty v1.1.17/go.mod h1:MOBLtS5ELjhRRrroQr9kyvTxUAFNvYEK993ew/Vr4O4= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/docopt/docopt-go v0.0.0-20180111231733-ee0de3bc6815/go.mod h1:WwZ+bS3ebgob9U8Nd0kOddGdZWjyMGR8Wziv+TBNwSE= +github.com/elazarl/goproxy v0.0.0-20180725130230-947c36da3153 h1:yUdfgN0XgIJw7foRItutHYUIhlcKzcSf5vDpdhQAKTc= +github.com/emicklei/go-restful/v3 v3.10.1 h1:rc42Y5YTp7Am7CS630D7JmhRjq4UlEUuEKfrDac4bSQ= +github.com/emicklei/go-restful/v3 v3.10.1/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc= +github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= +github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= +github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= +github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= +github.com/envoyproxy/go-control-plane v0.9.9-0.20210512163311-63b5d3c536b0/go.mod h1:hliV/p42l8fGbc6Y9bQ70uLwIvmJyVE5k4iMKlh8wCQ= +github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= +github.com/evanphx/json-patch v4.12.0+incompatible h1:4onqiflcdA9EOZ4RxV643DvftH5pOlLGNtQ5lPWQu84= +github.com/evanphx/json-patch v4.12.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= +github.com/flowstack/go-jsonschema v0.1.1/go.mod h1:yL7fNggx1o8rm9RlgXv7hTBWxdBM0rVwpMwimd3F3N0= +github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= +github.com/go-logr/logr v1.2.0/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= +github.com/go-logr/logr v1.2.3 h1:2DntVwHkVopvECVRSlL5PSo9eG+cAkDCuckLubN+rq0= +github.com/go-logr/logr v1.2.3/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= +github.com/go-openapi/jsonpointer v0.19.6 h1:eCs3fxoIi3Wh6vtgmLTOjdhSpiqphQ+DaPn38N2ZdrE= +github.com/go-openapi/jsonpointer v0.19.6/go.mod h1:osyAmYz/mB/C3I+WsTTSgw1ONzaLJoLCyoi6/zppojs= +github.com/go-openapi/jsonreference v0.20.2 h1:3sVjiK66+uXK/6oQ8xgcRKcFgQ5KXa2KvnJRumpMGbE= +github.com/go-openapi/jsonreference v0.20.2/go.mod h1:Bl1zwGIM8/wsvqjsOQLJ/SH+En5Ap4rVB5KVcIDZG2k= +github.com/go-openapi/swag v0.22.3 h1:yMBqmnQ0gyZvEb/+KzuWZOXgllrXT4SADYbvDaXHv/g= +github.com/go-openapi/swag v0.22.3/go.mod h1:UzaqsxGiab7freDnrUUra0MwWfN/q7tE4j+VcZ0yl14= +github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0 h1:p104kn46Q8WdvHunIJ9dAyjPVtrBPhSr3KT2yUst43I= +github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE= +github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= +github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= +github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= +github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= +github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= +github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= +github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= +github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= +github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= +github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= +github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8= +github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= +github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= +github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= +github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw= +github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= +github.com/google/gnostic v0.6.9 h1:ZK/5VhkoX835RikCHpSUJV9a+S3e1zLh59YnyWeBW+0= +github.com/google/gnostic v0.6.9/go.mod h1:Nm8234We1lq6iB9OmlgNv3nH91XLLVZHCDayfA3xq+E= +github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= +github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= +github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= +github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0= +github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= +github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38 h1:yAJXTCF9TqKcTiHJAE8dj7HMvPfh66eeA2JYW7eFpSE= +github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= +github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw= +github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= +github.com/icza/backscanner v0.0.0-20230330133933-bf6beb754c70 h1:xrd41BUTgqxyYFfFwGdt/bnwS8KNYzPraj8WgvJ5NWk= +github.com/icza/backscanner v0.0.0-20230330133933-bf6beb754c70/go.mod h1:GYeBD1CF7AqnKZK+UCytLcY3G+UKo0ByXX/3xfdNyqQ= +github.com/icza/mighty v0.0.0-20180919140131-cfd07d671de6 h1:8UsGZ2rr2ksmEru6lToqnXgA8Mz1DP11X4zSJ159C3k= +github.com/icza/mighty v0.0.0-20180919140131-cfd07d671de6/go.mod h1:xQig96I1VNBDIWGCdTt54nHt6EeI639SmHycLYL7FkA= +github.com/imdario/mergo v0.3.13 h1:lFzP57bqS/wsqKssCGmtLAb8A0wKjLGrve2q3PPVcBk= +github.com/imdario/mergo v0.3.13/go.mod h1:4lJ1jqUDcsbIECGy0RUJAXNIhg+6ocWgb1ALK2O4oXg= +github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY= +github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= +github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= +github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= +github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= +github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= +github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= +github.com/kr/pretty v0.2.1 h1:Fmg33tUaq4/8ym9TJN1x7sLJnHVwhP33CNkpYV/7rwI= +github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= +github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= +github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= +github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= +github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= +github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0= +github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= +github.com/moby/spdystream v0.2.0 h1:cjW1zVyyoiM0T7b6UoySUFqzXMoqRckQtXwGPiBhOM8= +github.com/moby/spdystream v0.2.0/go.mod h1:f7i0iNDQJ059oMTcWxx8MA/zKFIuD/lY+0GqbN2Wy8c= +github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= +github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M= +github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= +github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA= +github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= +github.com/onsi/ginkgo/v2 v2.9.0 h1:Tugw2BKlNHTMfG+CheOITkYvk4LAh6MFOvikhGVnhE8= +github.com/onsi/ginkgo/v2 v2.9.0/go.mod h1:4xkjoL/tZv4SMWeww56BU5kAt19mVB47gTWxmrTcxyk= +github.com/onsi/gomega v1.27.1 h1:rfztXRbg6nv/5f+Raen9RcGoSecHIFgBBLQK3Wdj754= +github.com/onsi/gomega v1.27.1/go.mod h1:aHX5xOykVYzWOV4WqQy0sy8BQptgukenXpCXfadcIAw= +github.com/openshift/api v0.0.0-20230120195050-6ba31fa438f2 h1:+nw0/d4spq880W7S74Twi5YU2ulsl3/a9o4OEZptYp0= +github.com/openshift/api v0.0.0-20230120195050-6ba31fa438f2/go.mod h1:ctXNyWanKEjGj8sss1KjjHQ3ENKFm33FFnS5BKaIPh4= +github.com/openshift/client-go v0.0.0-20230120202327-72f107311084 h1:66uaqNwA+qYyQDwsMWUfjjau8ezmg1dzCqub13KZOcE= +github.com/openshift/client-go v0.0.0-20230120202327-72f107311084/go.mod h1:M3h9m001PWac3eAudGG3isUud6yBjr5XpzLYLLTlHKo= +github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= +github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= +github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= +github.com/sirupsen/logrus v1.9.0 h1:trlNQbNUG3OdDrDil03MCb1H2o9nJ1x4/5LYw7byDE0= +github.com/sirupsen/logrus v1.9.0/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= +github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= +github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= +github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= +github.com/stoewer/go-strcase v1.2.0/go.mod h1:IBiWB2sKIp3wVVQ3Y035++gc+knqhUQag1KpM8ahLw8= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= +github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= +github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= +github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= +github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= +github.com/stretchr/testify v1.8.1 h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKsk= +github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= +github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU= +github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415/go.mod h1:GwrjFmJcFw6At/Gs6z4yjiIwzuJ1/+UwLxMQDVQXShQ= +github.com/xeipuuv/gojsonschema v1.2.0/go.mod h1:anYRn/JVcOK2ZgGU+IjEV4nwlhoK5sQluxsYJ78Id3Y= +github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= +golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= +golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= +golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.8.0 h1:LUYupSeNrTNCGzR/hVBk2NHZO4hXcVaW1k4Qx7rjPx8= +golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= +golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= +golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= +golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= +golang.org/x/net v0.0.0-20210805182204-aaa1db679c0d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.17.0 h1:pVaXccu2ozPjCXewfr1S7xza/zcXTity9cCdXQYSjIM= +golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE= +golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= +golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/oauth2 v0.5.0 h1:HuArIo48skDwlrvM3sEdHXElYslAMsf3KwRkkW4MC4s= +golang.org/x/oauth2 v0.5.0/go.mod h1:9/XBHVqLaWO3/BRHs5jbpYCnOZVjj5V0ndyaAM7KB4I= +golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.13.0 h1:Af8nKPmuFypiUBjVoU9V20FiaFXOcuZI21p0ycVYYGE= +golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= +golang.org/x/term v0.13.0 h1:bb+I9cTfFazGW51MZqBVmZy7+JEJMouUHTUSKVQLBek= +golang.org/x/term v0.13.0/go.mod h1:LTmsnFJwVN6bCy1rVCoS+qHT1HhALEFxKncY3WNNh4U= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= +golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.13.0 h1:ablQoSUd0tRdKxZewP80B+BaqeKJuVhuRxj/dkrun3k= +golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= +golang.org/x/time v0.3.0 h1:rg5rLMjNzMS1RkNLzCG38eapWhnYLFYXDXj2gOlr8j4= +golang.org/x/time v0.3.0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= +golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.6.0 h1:BOw41kyTf3PuCW1pVQf8+Cyg8pMlkYB1oo9iJ6D/lKM= +golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= +golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= +google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= +google.golang.org/appengine v1.6.7 h1:FZR1q0exgwxzPzp/aF+VccGrSfxfPpkBqjIIEq3ru6c= +google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= +google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= +google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= +google.golang.org/genproto v0.0.0-20200513103714-09dca8ec2884/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= +google.golang.org/genproto v0.0.0-20220107163113-42d7afdf6368/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= +google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= +google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= +google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= +google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= +google.golang.org/grpc v1.33.1/go.mod h1:fr5YgcSWrqhRRxogOsw7RzIpsmvOZ6IcH4kBYTpR3n0= +google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= +google.golang.org/grpc v1.40.0/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9KAK34= +google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= +google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= +google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= +google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE= +google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= +google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= +google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= +google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= +google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= +google.golang.org/protobuf v1.28.1 h1:d0NfwRgPtno5B1Wa6L2DAG+KivqkdutMf1UhdNx175w= +google.golang.org/protobuf v1.28.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= +gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc= +gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= +gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= +gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.0/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +k8s.io/api v0.26.1 h1:f+SWYiPd/GsiWwVRz+NbFyCgvv75Pk9NK6dlkZgpCRQ= +k8s.io/api v0.26.1/go.mod h1:xd/GBNgR0f707+ATNyPmQ1oyKSgndzXij81FzWGsejg= +k8s.io/apimachinery v0.26.1 h1:8EZ/eGJL+hY/MYCNwhmDzVqq2lPl3N3Bo8rvweJwXUQ= +k8s.io/apimachinery v0.26.1/go.mod h1:tnPmbONNJ7ByJNz9+n9kMjNP8ON+1qoAIIC70lztu74= +k8s.io/client-go v0.26.1 h1:87CXzYJnAMGaa/IDDfRdhTzxk/wzGZ+/HUQpqgVSZXU= +k8s.io/client-go v0.26.1/go.mod h1:IWNSglg+rQ3OcvDkhY6+QLeasV4OYHDjdqeWkDQZwGE= +k8s.io/klog/v2 v2.90.0 h1:VkTxIV/FjRXn1fgNNcKGM8cfmL1Z33ZjXRTVxKCoF5M= +k8s.io/klog/v2 v2.90.0/go.mod h1:y1WjHnz7Dj687irZUWR/WLkLc5N1YHtjLdmgWjndZn0= +k8s.io/kube-openapi v0.0.0-20230217203603-ff9a8e8fa21d h1:oFDpQ7FfzinCtrFOl4izwOWsdTprlS2A9IXBENMW0UA= +k8s.io/kube-openapi v0.0.0-20230217203603-ff9a8e8fa21d/go.mod h1:/BYxry62FuDzmI+i9B+X2pqfySRmSOW2ARmj5Zbqhj0= +k8s.io/kubectl v0.26.1 h1:K8A0Jjlwg8GqrxOXxAbjY5xtmXYeYjLU96cHp2WMQ7s= +k8s.io/kubectl v0.26.1/go.mod h1:miYFVzldVbdIiXMrHZYmL/EDWwJKM+F0sSsdxsATFPo= +k8s.io/utils v0.0.0-20230220204549-a5ecb0141aa5 h1:kmDqav+P+/5e1i9tFfHq1qcF3sOrDp+YEkVDAHu7Jwk= +k8s.io/utils v0.0.0-20230220204549-a5ecb0141aa5/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= +sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd h1:EDPBXCAspyGV4jQlpZSudPeMmr1bNJefnuqLsRAsHZo= +sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd/go.mod h1:B8JuhiUyNFVKdsE8h686QcCxMaH6HrOAZj4vswFpcB0= +sigs.k8s.io/structured-merge-diff/v4 v4.2.3 h1:PRbqxJClWWYMNV1dhaG4NsibJbArud9kFxnAMREiWFE= +sigs.k8s.io/structured-merge-diff/v4 v4.2.3/go.mod h1:qjx8mGObPmV2aSZepjQjbmb2ihdVs8cGKBraizNC69E= +sigs.k8s.io/yaml v1.3.0 h1:a2VclLzOGrwOHDiV8EfBGhvjHvP46CtW5j6POvhYGGo= +sigs.k8s.io/yaml v1.3.0/go.mod h1:GeOyir5tyXNByN85N/dRIT9es5UQNerPYEKK56eTBm8= diff --git a/collector-framework/hack/logs.go b/collector-framework/hack/logs.go new file mode 100644 index 00000000..38179d0f --- /dev/null +++ b/collector-framework/hack/logs.go @@ -0,0 +1,262 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + +package main + +import ( + "errors" + "flag" + "fmt" + "io" + "os" + "os/exec" + "path" + "regexp" + "strconv" + "strings" + "time" + + expect "github.com/Netflix/go-expect" + "github.com/icza/backscanner" + log "github.com/sirupsen/logrus" +) + +const ( + timeout = 5 * time.Second + podSafetyWait = 5 * time.Second // generous sleep so we don't create too many debug pods and break. + defaultLogWindow = 2000 * time.Second +) + +var ( + promptRE = regexp.MustCompile(`sh-4\.4#`) // line has ANSI escape characters: \r\x1b[Ksh-4.4# + logfileRE = regexp.MustCompile(`(\d)\.log(\..*)*`) +) + +var ( + kubeconfigPath string + outputPath string + tmpOutputPath string + logWindow time.Duration +) + +func check(e error) { + if e != nil { + log.Fatal(e) + } +} + +func buildDebugCommand(nodeName string) []string { + nodepath := "node/" + nodeName + return []string{"oc", "debug", "--kubeconfig", kubeconfigPath, "--quiet", nodepath} +} + +func getNodeName() string { + nodeNameCommand := []string{"get", "nodes", "--kubeconfig", kubeconfigPath, "-o=jsonpath={.items[0].metadata.name}"} + cmd := exec.Command("oc", nodeNameCommand...) + log.Debug(cmd) + var nodeName strings.Builder + cmd.Stdout = &nodeName + check(cmd.Run()) + log.Debug(nodeName.String()) + return nodeName.String() +} + +func pickLogFiles(filePaths []string) []string { + maxLogNumber := 0 + var candidateFiles []string //nolint:prealloc // performance not the goal here + for _, filePath := range filePaths { + _, fileName := path.Split(filePath) + logNumber, err := strconv.Atoi(strings.SplitN(fileName, ".", 2)[0]) //nolint:gomnd // making constant does not improve code. + if err != nil { + continue // skip file + } + if logNumber < maxLogNumber { + continue // only get files from the biggest log number + } else if logNumber > maxLogNumber { + maxLogNumber = logNumber + candidateFiles = nil + } + candidateFiles = append(candidateFiles, filePath) + } + return candidateFiles +} + +func downloadLogs(nodeName string, logPaths []string) []string { + var createdFiles []string //nolint:prealloc // performance not the goal here + var stderr strings.Builder + for _, filePath := range logPaths { + log.Infof("Getting logs from remote file: %s", filePath) + _, fileName := path.Split(filePath) + args := append(buildDebugCommand(nodeName), "--") + if strings.HasSuffix(fileName, ".gz") { + args = append(args, []string{"gzip", "-d", filePath, "--stdout"}...) + fileName = strings.ReplaceAll(fileName, ".gz", "") + } else { + args = append(args, []string{"cat", filePath}...) + } + cmd := exec.Command(args[0], args[1:]...) //nolint:gosec // accepting security risk. + + localFile := fmt.Sprintf("%s/%s", tmpOutputPath, fileName) + createdFiles = append(createdFiles, localFile) + outputFile, err := os.Create(localFile) + check(err) + cmd.Stdout = outputFile + cmd.Stderr = &stderr + + if err = cmd.Run(); err != nil { + log.Error(stderr.String()) + check(err) + } + err = outputFile.Close() + check(err) + stderr.Reset() + time.Sleep(podSafetyWait) + } + return createdFiles +} + +func getLogsFileNamesForNode(nodeName string) []string { + expecter, err := expect.NewConsole(expect.WithStdout(os.Stdout), expect.WithDefaultTimeout(timeout)) + check(err) + defer expecter.Close() + + args := buildDebugCommand(nodeName) + cmd := exec.Command(args[0], args[1:]...) //nolint:gosec // accepting security risk. + cmd.Stdin = expecter.Tty() + cmd.Stdout = expecter.Tty() + cmd.Stderr = expecter.Tty() + + err = cmd.Start() + check(err) + defer cmd.Process.Kill() //nolint:errcheck // continue regardless of error. + + _, err = expecter.Expect(expect.Regexp(promptRE)) + check(err) + + _, err = expecter.Send("find /host/var/log/pods/openshift-ptp_linuxptp-daemon-*/linuxptp-daemon-container/*log*\n") + check(err) + logFiles, _ := expecter.Expect(expect.Regexp(promptRE)) // Just wait for timeout here as the prompt is full of invisible characters which makes regex a nightmare. + + var candidateFiles []string + for _, line := range strings.Split(logFiles, "\n") { + trimmedLine := strings.TrimSpace(line) + log.Debugf("Got Line:'%q'", trimmedLine) + if match := logfileRE.MatchString(trimmedLine); match { + candidateFiles = append(candidateFiles, trimmedLine) + } + } + logsToRetrieve := pickLogFiles(candidateFiles) + return logsToRetrieve +} + +func processLogLine(line string) (time.Time, string) { //nolint:gocritic //names not needed + splitLine := strings.SplitN(line, " ", 2) //nolint:gomnd // making constant does not improve code. + timestamp, err := time.Parse(time.RFC3339, splitLine[0]) + if err != nil { + return time.Now(), "" + } + // 2023-09-08T11:03:22.315992414+00:00 stdout F ts2phc[1374422.785]: [ts2phc.0.config] nmea sentence: GNGGA,110322.00,4233.01417,N,07112.87799,W,1,12,0.48,58.2,M,-33.0,M,, + // becomes + // ts2phc[1374422.785]: [ts2phc.0.config] nmea sentence: GNGGA,110322.00,4233.01417,N,07112.87799,W,1,12,0.48,58.2,M,-33.0,M,, + return timestamp, line[45:] +} + +func scanFileInReverseToTime(fileName string, targetTime time.Time, output *os.File) (foundTime bool) { + foundTime = false + f, err := os.Open(fileName) + check(err) + defer f.Close() + finfo, err := f.Stat() + check(err) + reverseReader := backscanner.New(f, int(finfo.Size())) + for { + line, _, err := reverseReader.Line() + if errors.Is(err, io.EOF) { + log.Infof("Finished processing file: %s", fileName) + break + } else if err != nil { + log.Errorf("Unexpected error reading file %s: %s", fileName, err) + break + } + ts, logLine := processLogLine(line) + if ts.Before(targetTime) { + foundTime = true + return + } + if line != "" { + _, _ = output.WriteString(logLine + "\n") + } + } + return +} + +func buildSingleLog(fromFiles []string, since time.Time) { + reverseFilename := fmt.Sprintf("%s/logs.gol", tmpOutputPath) + reverseFinalLogFile, err := os.Create(reverseFilename) + check(err) + defer reverseFinalLogFile.Close() + + // assuming order of fromFiles is consistent due to naming scheme: first item is most recent file, the rest are in ascending time order + reverseTimeOrder := []string{fromFiles[0]} + for i := len(fromFiles) - 1; i > 0; i-- { + reverseTimeOrder = append(reverseTimeOrder, fromFiles[i]) + } + foundTime := false + // work over files in descending time order, and lines in each file from end to start, until we find a line before since time. + for _, f := range reverseTimeOrder { + log.Infof("Processing file %s", f) + foundTime = scanFileInReverseToTime(f, since, reverseFinalLogFile) + if foundTime { + log.Infof("Found sinceTime in file %s", f) + break + } + } + if !foundTime { + log.Warn("Processed all log files without satisfying since duration") + } + + cmd := exec.Command("tac", reverseFilename) + finalLogFile, err := os.Create(outputPath) + check(err) + log.Debugf("%s > %s", cmd.Args, finalLogFile.Name()) + cmd.Stdout = finalLogFile + log.Infof("Writing final logs to %s", finalLogFile.Name()) + err = cmd.Run() + check(err) +} + +func main() { + flag.StringVar(&kubeconfigPath, "k", "", "Path to kubeconfig. Required.") + flag.StringVar(&outputPath, "o", "", "Output file for final logs. Target must exist. Required") + flag.DurationVar( + &logWindow, + "d", + defaultLogWindow, + fmt.Sprintf("Optional. Duration of logs to finally output. Defaults to %s.", defaultLogWindow), + ) + flag.StringVar( + &tmpOutputPath, + "t", + ".", + "Optional. Specify the temporary output directory. Target must exist. Defaults to working directory.", + ) + flag.Parse() + + if kubeconfigPath == "" { + log.Error("Kubeconfig path (-k) is Required") + flag.Usage() + os.Exit(1) + } + if outputPath == "" { + log.Error("Output path (-o) is Required") + flag.Usage() + os.Exit(1) + } + + sinceTime := time.Now().Add(-logWindow) + log.Infof("Getting logs since %s", sinceTime) + nodeName := getNodeName() + logFiles := getLogsFileNamesForNode(nodeName) + time.Sleep(podSafetyWait) + localFiles := downloadLogs(nodeName, logFiles) + buildSingleLog(localFiles, sinceTime) +} diff --git a/collector-framework/pkg/callbacks/callbacks.go b/collector-framework/pkg/callbacks/callbacks.go new file mode 100644 index 00000000..2ef75699 --- /dev/null +++ b/collector-framework/pkg/callbacks/callbacks.go @@ -0,0 +1,134 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + +package callbacks + +import ( + "encoding/json" + "errors" + "fmt" + "io" + "os" +) + +const ( + logFilePermissions = 0666 +) + +type Callback interface { + Call(OutputType, string) error + CleanUp() error + getFormat() OutputFormat +} + +type OutputFormat int + +const ( + Raw OutputFormat = iota + AnalyserJSON +) + +type AnalyserFormatType struct { + Data any `json:"data"` + ID string `json:"id"` +} + +type OutputType interface { + GetAnalyserFormat() ([]*AnalyserFormatType, error) +} + +// getFormattedOutput returns the output in the format configured by on the callback +func getFormattedOutput(c Callback, output OutputType, tag string) ([]byte, error) { + switch c.getFormat() { + case Raw: + line, err := json.Marshal(output) + if err != nil { + return []byte{}, fmt.Errorf("failed to marshal %T %w", output, err) + } + return []byte(fmt.Sprintf("%T:%s, %s", output, tag, line)), nil + case AnalyserJSON: + outputs, err := output.GetAnalyserFormat() + if err != nil { + return []byte{}, fmt.Errorf("failed to get AnalyserFormat %w", err) + } + newline := []byte("\n") + lines := make([]byte, 0) + for count, obj := range outputs { + line, err := json.Marshal(obj) + if err != nil { + return []byte{}, fmt.Errorf("failed to marshal AnalyserFormat for %s %w", tag, err) + } + lines = append(lines, line...) + // Append a new line between the entries but not a trailing one + if count < len(outputs)-1 { + lines = append(lines, newline...) + } + } + return lines, nil + default: + return []byte{}, errors.New("unknown format") + } +} + +// Returns the filehandle for callback +// if filename is empty or "-" it will output to stdout otherwise it will +// write to a file of the given name +func GetFileHandle(filename string) (io.WriteCloser, error) { + var ( + fileHandle io.WriteCloser + err error + ) + if filename == "-" || filename == "" { + fileHandle = os.Stdout + } else { + fileHandle, err = os.OpenFile(filename, os.O_CREATE|os.O_WRONLY, logFilePermissions) + if err != nil { + return fileHandle, fmt.Errorf("failed to open file: %w", err) + } + } + return fileHandle, nil +} + +func NewFileCallback(fileHandle io.WriteCloser, format OutputFormat) FileCallBack { + return FileCallBack{fileHandle: fileHandle, format: format} +} + +// SetupCallback returns a FileCallback +// if filename is empty or "-" it will output to stdout otherwise it will +// write to a file of the given name +func SetupCallback(filename string, format OutputFormat) (FileCallBack, error) { + fileHandle, err := GetFileHandle(filename) + if err != nil { + return FileCallBack{}, err + } + return NewFileCallback(fileHandle, format), nil +} + +type FileCallBack struct { + fileHandle io.WriteCloser + format OutputFormat +} + +func (c FileCallBack) Call(output OutputType, tag string) error { + formattedOutput, err := getFormattedOutput(c, output, tag) + if err != nil { + return err + } + formattedOutput = append(formattedOutput, []byte("\n")...) + _, err = c.fileHandle.Write(formattedOutput) + if err != nil { + return fmt.Errorf("failed to write to file in callback: %w", err) + } + return nil +} + +func (c FileCallBack) getFormat() OutputFormat { + return c.format +} + +func (c FileCallBack) CleanUp() error { + err := c.fileHandle.Close() + if err != nil { + return fmt.Errorf("failed to close file handle in callback: %w", err) + } + return nil +} diff --git a/collector-framework/pkg/callbacks/callbacks_test.go b/collector-framework/pkg/callbacks/callbacks_test.go new file mode 100644 index 00000000..663acbb9 --- /dev/null +++ b/collector-framework/pkg/callbacks/callbacks_test.go @@ -0,0 +1,89 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + +package callbacks_test + +import ( + "bytes" + "errors" + "testing" + + . "github.com/onsi/ginkgo/v2" + . "github.com/onsi/gomega" + + "github.com/redhat-partner-solutions/vse-sync-collection-tools/collector-framework/pkg/callbacks" +) + +func NewTestFile() *testFile { + return &testFile{Buffer: *bytes.NewBuffer([]byte{}), open: true} +} + +type testFile struct { + bytes.Buffer + open bool +} + +func (t *testFile) Close() error { + if t.open { + t.open = false + return nil + } + return errors.New("File is already closed") // TODO look up actual errors +} + +type testOutputType struct { + Msg string `json:"msg"` + // responder func() (*callbacks.AnalyserFormatType, error) +} + +func (t *testOutputType) GetAnalyserFormat() ([]*callbacks.AnalyserFormatType, error) { + fomatted := callbacks.AnalyserFormatType{ + ID: "testOutput", + Data: []any{"Hello"}, + } + return []*callbacks.AnalyserFormatType{&fomatted}, nil +} + +var _ = Describe("Callbacks", func() { + var mockedFile *testFile + + BeforeEach(func() { + mockedFile = NewTestFile() + }) + + When("Raw FileCallback is called", func() { + It("should write to the file", func() { + callback := callbacks.NewFileCallback(mockedFile, callbacks.Raw) + out := testOutputType{ + Msg: "This is a test line", + } + err := callback.Call(&out, "testOut") + Expect(err).NotTo(HaveOccurred()) + Expect(mockedFile.ReadString('\n')).To(ContainSubstring("This is a test line")) + }) + }) + When("JSON FileCallback is called", func() { + It("should write to the file", func() { + callback := callbacks.NewFileCallback(mockedFile, callbacks.AnalyserJSON) + out := testOutputType{ + Msg: "This is a test line", + } + err := callback.Call(&out, "testOut") + Expect(err).NotTo(HaveOccurred()) + Expect(mockedFile.ReadString('\n')).To(Equal("{\"data\":[\"Hello\"],\"id\":\"testOutput\"}\n")) + }) + }) + When("A FileCallback is cleaned up", func() { + It("should close the file", func() { + callback := callbacks.NewFileCallback(mockedFile, callbacks.Raw) + err := callback.CleanUp() + Expect(err).NotTo(HaveOccurred()) + Expect(mockedFile.open).To(BeFalse()) + }) + }) + +}) + +func TestCommand(t *testing.T) { + RegisterFailHandler(Fail) + RunSpecs(t, "Clients Suite") +} diff --git a/collector-framework/pkg/clients/clients_test.go b/collector-framework/pkg/clients/clients_test.go new file mode 100644 index 00000000..709ddc46 --- /dev/null +++ b/collector-framework/pkg/clients/clients_test.go @@ -0,0 +1,52 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + +package clients_test + +import ( + "testing" + + . "github.com/onsi/ginkgo/v2" + . "github.com/onsi/gomega" + + "github.com/redhat-partner-solutions/vse-sync-collection-tools/collector-framework/pkg/clients" +) + +const ( + kubeconfigPath string = "test_files/kubeconfig" + notAKubeconfigPath string = "" +) + +var ( + emptyKubeconfigList []string +) + +var _ = Describe("Client", func() { + BeforeEach(func() { + clients.ClearClientSet() + }) + + When("A clientset is requested with no kubeconfig", func() { + It("should return an error", func() { + var clientset *clients.Clientset + clientset, err := clients.GetClientset(notAKubeconfigPath) + Expect(err).To(HaveOccurred()) + Expect(clientset).To(BeNil()) + + clientset, err = clients.GetClientset(emptyKubeconfigList...) + Expect(err).To(HaveOccurred()) + Expect(clientset).To(BeNil()) + }) + }) + When("A clientset is requested using a valid kubeconfig", func() { + It("should be returned", func() { + clientset, err := clients.GetClientset(kubeconfigPath) + Expect(err).NotTo(HaveOccurred()) + Expect(clientset).NotTo(BeNil()) + }) + }) +}) + +func TestCommand(t *testing.T) { + RegisterFailHandler(Fail) + RunSpecs(t, "Clients Suite") +} diff --git a/collector-framework/pkg/clients/clientset.go b/collector-framework/pkg/clients/clientset.go new file mode 100644 index 00000000..5154a6de --- /dev/null +++ b/collector-framework/pkg/clients/clientset.go @@ -0,0 +1,124 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + +package clients + +import ( + "context" + "fmt" + "strings" + "time" + + ocpconfig "github.com/openshift/client-go/config/clientset/versioned" + log "github.com/sirupsen/logrus" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/client-go/dynamic" + "k8s.io/client-go/kubernetes" + "k8s.io/client-go/rest" + "k8s.io/client-go/tools/clientcmd" + + "github.com/redhat-partner-solutions/vse-sync-collection-tools/collector-framework/pkg/utils" +) + +// A Clientset contains clients for the different k8s API groups in one place +type Clientset struct { + RestConfig *rest.Config + DynamicClient dynamic.Interface + OcpClient ocpconfig.Interface + K8sClient kubernetes.Interface + K8sRestClient rest.Interface + KubeConfigPaths []string + ready bool +} + +var clientset = Clientset{} + +// GetClientset returns the singleton clientset object. +func GetClientset(kubeconfigPaths ...string) (*Clientset, error) { + if clientset.ready { + return &clientset, nil + } + + if len(kubeconfigPaths) == 0 { + return nil, utils.NewMissingInputError( + fmt.Errorf("must have at least one kubeconfig to initialise a new Clientset"), + ) + } + clientset, err := newClientset(kubeconfigPaths...) + if err != nil { + return nil, utils.NewMissingInputError( + fmt.Errorf("failed to create k8s clients holder: %w", err), + ) + } + return clientset, nil +} + +// newClientset will initialise the singleton clientset using provided kubeconfigPath +func newClientset(kubeconfigPaths ...string) (*Clientset, error) { + log.Infof("creating new Clientset from %v", kubeconfigPaths) + clientset.KubeConfigPaths = kubeconfigPaths + loadingRules := clientcmd.NewDefaultClientConfigLoadingRules() + + loadingRules.Precedence = kubeconfigPaths // This means it will not load the value from $KUBECONFIG + configOverrides := &clientcmd.ConfigOverrides{} + kubeconfig := clientcmd.NewNonInteractiveDeferredLoadingClientConfig( + loadingRules, + configOverrides, + ) + // Get a rest.Config from the kubeconfig file. This will be passed into all + // the client objects we create. + var err error + clientset.RestConfig, err = kubeconfig.ClientConfig() + if err != nil { + return nil, fmt.Errorf("cannot instantiate rest config: %w", err) + } + + DefaultTimeout := 10 * time.Second + clientset.RestConfig.Timeout = DefaultTimeout + + clientset.DynamicClient, err = dynamic.NewForConfig(clientset.RestConfig) + if err != nil { + return nil, fmt.Errorf("cannot instantiate dynamic client (unstructured/dynamic): %w", err) + } + clientset.K8sClient, err = kubernetes.NewForConfig(clientset.RestConfig) + if err != nil { + return nil, fmt.Errorf("cannot instantiate k8sclient: %w", err) + } + // create the oc client + clientset.OcpClient, err = ocpconfig.NewForConfig(clientset.RestConfig) + if err != nil { + return nil, fmt.Errorf("cannot instantiate ocClient: %w", err) + } + + clientset.K8sRestClient = clientset.K8sClient.CoreV1().RESTClient() + clientset.ready = true + return &clientset, nil +} + +func ClearClientSet() { + clientset = Clientset{} +} + +func (clientsholder *Clientset) FindPodNameFromPrefix(namespace, prefix string) (string, error) { + podList, err := clientsholder.K8sClient.CoreV1().Pods(namespace).List(context.TODO(), metav1.ListOptions{}) + if err != nil { + return "", fmt.Errorf("failed to getting pod list: %w", err) + } + podNames := make([]string, 0) + + for i := range podList.Items { + hasPrefix := strings.HasPrefix(podList.Items[i].Name, prefix) + isDebug := strings.HasSuffix(podList.Items[i].Name, "-debug") + if hasPrefix && !isDebug { + podNames = append(podNames, podList.Items[i].Name) + } + } + + switch len(podNames) { + case 0: + return "", fmt.Errorf("no pod with prefix %v found in namespace %v", prefix, namespace) + case 1: + return podNames[0], nil + default: + return "", fmt.Errorf("too many (%v) pods with prefix %v found in namespace %v", len(podNames), prefix, namespace) + } +} diff --git a/collector-framework/pkg/clients/command.go b/collector-framework/pkg/clients/command.go new file mode 100644 index 00000000..9382b9da --- /dev/null +++ b/collector-framework/pkg/clients/command.go @@ -0,0 +1,107 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + +package clients + +import ( + "fmt" + "regexp" + + log "github.com/sirupsen/logrus" +) + +type Cmder interface { + GetCommand() string + ExtractResult(string) (map[string]string, error) +} + +type Cmd struct { + key string + prefix string + suffix string + cmd string + outputProcessor func(string) (string, error) + regex *regexp.Regexp + fullCmd string +} + +func NewCmd(key, cmd string) (*Cmd, error) { + cmdInstance := Cmd{ + key: key, + cmd: cmd, + prefix: fmt.Sprintf("echo '<%s>'", key), + suffix: fmt.Sprintf("echo ''", key), + } + + cmdInstance.fullCmd = fmt.Sprintf("%s;", cmdInstance.prefix) + cmdInstance.fullCmd += cmdInstance.cmd + if string(cmd[len(cmd)-1]) != ";" { + cmdInstance.fullCmd += ";" + } + cmdInstance.fullCmd += fmt.Sprintf("%s;", cmdInstance.suffix) + + compiledRegex, err := regexp.Compile(`(?s)<` + key + `>\n` + `(.*)` + `\n`) + if err != nil { + return nil, fmt.Errorf("failed to compile regex for key %s: %w", key, err) + } + cmdInstance.regex = compiledRegex + return &cmdInstance, nil +} + +func (c *Cmd) SetOutputProcessor(f func(string) (string, error)) { + c.outputProcessor = f +} + +func (c *Cmd) GetCommand() string { + return c.fullCmd +} + +func (c *Cmd) ExtractResult(s string) (map[string]string, error) { + result := make(map[string]string) + log.Debugf("extract %s from %s", c.key, s) + match := c.regex.FindStringSubmatch(s) + log.Debugf("match %#v", match) + + if len(match) > 0 { + value := match[1] + + if c.outputProcessor != nil { + cleanValue, err := c.outputProcessor(match[1]) + if err != nil { + return result, fmt.Errorf("failed to cleanup value %s of key %s", match[1], c.key) + } + value = cleanValue + } + log.Debugf("r %s", value) + result[c.key] = value + return result, nil + } + return result, fmt.Errorf("failed to find result for key: %s", c.key) +} + +type CmdGroup struct { + cmds []*Cmd +} + +func (cgrp *CmdGroup) AddCommand(c *Cmd) { + cgrp.cmds = append(cgrp.cmds, c) +} + +func (cgrp *CmdGroup) GetCommand() string { + res := "" + for _, c := range cgrp.cmds { + res += c.GetCommand() + } + return res +} + +func (cgrp *CmdGroup) ExtractResult(s string) (map[string]string, error) { + results := make(map[string]string) + for _, c := range cgrp.cmds { + res, err := c.ExtractResult(s) + if err != nil { + return results, err + } + results[c.key] = res[c.key] + } + return results, nil +} diff --git a/collector-framework/pkg/clients/command_test.go b/collector-framework/pkg/clients/command_test.go new file mode 100644 index 00000000..c28f4efd --- /dev/null +++ b/collector-framework/pkg/clients/command_test.go @@ -0,0 +1,95 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + +package clients_test + +import ( + "fmt" + + . "github.com/onsi/ginkgo/v2" + . "github.com/onsi/gomega" + + "github.com/redhat-partner-solutions/vse-sync-collection-tools/collector-framework/pkg/clients" +) + +var _ = Describe("Cmd", func() { + When("NewCmd is called ", func() { + It("should return a Cmd ", func() { + cmd, err := clients.NewCmd("TestKey", "Hello This is a test") + Expect(cmd).ToNot(BeNil()) + Expect(err).ToNot(HaveOccurred()) + }) + }) + When("Cmd is passed a vaild result", func() { + It("should parse it into a dict", func() { + expected := "I am the correct answer" + key := "TestKey" + cmd, _ := clients.NewCmd(key, "Hello This is a test") + result, err := cmd.ExtractResult(fmt.Sprintf("<%s>\n%s\n\n", key, expected, key)) + Expect(result[key]).To(Equal(expected)) + Expect(err).ToNot(HaveOccurred()) + }) + }) + When("Cmd is passed an invaild result", func() { + It("should return an error", func() { + cmd, _ := clients.NewCmd("TestKey", "Hello This is a test") + result, err := cmd.ExtractResult("\nI am not the correct answer\n\n") + Expect(err).To(HaveOccurred()) + Expect(result).To(BeEmpty()) + }) + }) + + When("Cmd when supplied a clean up function", func() { + It("should use it", func() { + part1 := "I am part" + part2 := "of the correct answer" + key := "TestKey" + cmd, _ := clients.NewCmd(key, "Hello This is a test") + cmd.SetOutputProcessor(func(p1 string) (string, error) { return p1 + part2, nil }) + result, err := cmd.ExtractResult(fmt.Sprintf("<%s>\n%s\n\n", key, part1, key)) + Expect(result[key]).To(Equal(part1 + part2)) + Expect(err).ToNot(HaveOccurred()) + }) + }) +}) + +var _ = Describe("CmdGrp", func() { + When("a command is added", func() { + It("should be added to GetCommand's output", func() { + cmd, err := clients.NewCmd("TestKey", "Hello This is a test") + Expect(err).ToNot(HaveOccurred()) + cmdGrp := &clients.CmdGroup{} + cmdGrp.AddCommand(cmd) + cmdString := cmdGrp.GetCommand() + Expect(cmdString).To(Equal(cmd.GetCommand())) + + cmd2, err := clients.NewCmd("TestKey2", "This is another test goodbye.") + Expect(err).ToNot(HaveOccurred()) + cmdGrp.AddCommand(cmd2) + cmdString2 := cmdGrp.GetCommand() + Expect(cmdString2).To(Equal(cmd.GetCommand() + cmd2.GetCommand())) + }) + }) + When("passed a valid result", func() { + It("should set the values to the key", func() { + key1 := "TestKey" + key2 := "TestKey2" + answer1 := "Result of key1" + answer2 := "Result of key2" + cmd, err := clients.NewCmd(key1, "Hello This is a test") + Expect(err).ToNot(HaveOccurred()) + cmd2, err := clients.NewCmd(key2, "This is another test goodbye.") + Expect(err).ToNot(HaveOccurred()) + cmdGrp := &clients.CmdGroup{} + cmdGrp.AddCommand(cmd) + cmdGrp.AddCommand(cmd2) + result, err := cmdGrp.ExtractResult(fmt.Sprintf( + "<%s>\n%s\n\n<%s>\n%s\n\n", + key1, answer1, key1, + key2, answer2, key2, + )) + Expect(result[key1]).To(Equal(answer1)) + Expect(result[key2]).To(Equal(answer2)) + Expect(err).ToNot(HaveOccurred()) + }) + }) +}) diff --git a/collector-framework/pkg/clients/exec_command.go b/collector-framework/pkg/clients/exec_command.go new file mode 100644 index 00000000..d016cf37 --- /dev/null +++ b/collector-framework/pkg/clients/exec_command.go @@ -0,0 +1,385 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + +package clients + +import ( + "bytes" + "context" + "errors" + "fmt" + "strings" + "time" + + log "github.com/sirupsen/logrus" + corev1 "k8s.io/api/core/v1" + k8sErrors "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/fields" + "k8s.io/client-go/tools/remotecommand" + "k8s.io/kubectl/pkg/scheme" +) + +const ( + startTimeout = 2 * time.Minute + deletionTimeout = 10 * time.Minute +) + +type APIContext interface { + GetNamespace() string + GetPodName() string + GetContainerName() string + GetClientset() *Clientset +} + +type ExecContext interface { + ExecCommand([]string) (string, string, error) + ExecCommandStdIn([]string, bytes.Buffer) (string, string, error) +} + +var NewSPDYExecutor = remotecommand.NewSPDYExecutor + +// ContainerExecContext encapsulates the context in which a command is run; the namespace, pod, and container. +type ContainerExecContext struct { + clientset *Clientset + namespace string + podName string + containerName string + podNamePrefix string +} + +func (c *ContainerExecContext) Refresh() error { + newPodname, err := c.clientset.FindPodNameFromPrefix(c.namespace, c.podNamePrefix) + if err != nil { + return err + } + c.podName = newPodname + return nil +} + +func NewContainerContext( + clientset *Clientset, + namespace, podNamePrefix, containerName string, +) (*ContainerExecContext, error) { + podName, err := clientset.FindPodNameFromPrefix(namespace, podNamePrefix) + if err != nil { + return &ContainerExecContext{}, err + } + ctx := ContainerExecContext{ + namespace: namespace, + podName: podName, + containerName: containerName, + podNamePrefix: podNamePrefix, + clientset: clientset, + } + return &ctx, nil +} + +func (c *ContainerExecContext) GetNamespace() string { + return c.namespace +} + +func (c *ContainerExecContext) GetPodName() string { + return c.podName +} + +func (c *ContainerExecContext) GetContainerName() string { + return c.containerName +} + +func (c *ContainerExecContext) GetClientset() *Clientset { + return c.clientset +} + +//nolint:lll,funlen // allow slightly long function definition and function length +func (c *ContainerExecContext) execCommand(command []string, buffInPtr *bytes.Buffer) (stdout, stderr string, err error) { + commandStr := command + var buffOut bytes.Buffer + var buffErr bytes.Buffer + + useBuffIn := buffInPtr != nil + + log.Debugf( + "execute command on ns=%s, pod=%s container=%s, cmd: %s", + c.GetNamespace(), + c.GetPodName(), + c.GetContainerName(), + strings.Join(commandStr, " "), + ) + req := c.clientset.K8sRestClient.Post(). + Namespace(c.GetNamespace()). + Resource("pods"). + Name(c.GetPodName()). + SubResource("exec"). + VersionedParams(&corev1.PodExecOptions{ + Container: c.GetContainerName(), + Command: command, + Stdin: useBuffIn, + Stdout: true, + Stderr: true, + TTY: false, + }, scheme.ParameterCodec) + + exec, err := NewSPDYExecutor(c.clientset.RestConfig, "POST", req.URL()) + if err != nil { + log.Debug(err) + return stdout, stderr, fmt.Errorf("error setting up remote command: %w", err) + } + + var streamOptions remotecommand.StreamOptions + + if useBuffIn { + streamOptions = remotecommand.StreamOptions{ + Stdin: buffInPtr, + Stdout: &buffOut, + Stderr: &buffErr, + } + } else { + streamOptions = remotecommand.StreamOptions{ + Stdout: &buffOut, + Stderr: &buffErr, + } + } + + err = exec.StreamWithContext(context.TODO(), streamOptions) + stdout, stderr = buffOut.String(), buffErr.String() + if err != nil { + if k8sErrors.IsNotFound(err) { + log.Debugf("Pod %s was not found, likely restarted so refreshing context", c.GetPodName()) + refreshErr := c.Refresh() + if refreshErr != nil { + log.Debug("Failed to refresh container context", refreshErr) + } + } + + log.Debug(err) + log.Debug(req.URL()) + log.Debug("command: ", command) + if useBuffIn { + log.Debug("stdin: ", buffInPtr.String()) + } + log.Debug("stderr: ", stderr) + log.Debug("stdout: ", stdout) + return stdout, stderr, fmt.Errorf("error running remote command: %w", err) + } + return stdout, stderr, nil +} + +// ExecCommand runs command in a container and returns output buffers +// +//nolint:lll,funlen // allow slightly long function definition and allow a slightly long function +func (c *ContainerExecContext) ExecCommand(command []string) (stdout, stderr string, err error) { + return c.execCommand(command, nil) +} + +//nolint:lll // allow slightly long function definition +func (c *ContainerExecContext) ExecCommandStdIn(command []string, buffIn bytes.Buffer) (stdout, stderr string, err error) { + return c.execCommand(command, &buffIn) +} + +// ContainerExecContext encapsulates the context in which a command is run; the namespace, pod, and container. +type ContainerCreationExecContext struct { + *ContainerExecContext + labels map[string]string + pod *corev1.Pod + containerSecurityContext *corev1.SecurityContext + containerImage string + command []string + volumes []*Volume + hostNetwork bool +} + +type Volume struct { + VolumeSource corev1.VolumeSource + Name string + MountPath string +} + +func (c *ContainerCreationExecContext) createPod() error { + pod := &corev1.Pod{ + ObjectMeta: metav1.ObjectMeta{ + Name: c.podName, + Namespace: c.namespace, + Labels: c.labels, + }, + Spec: corev1.PodSpec{ + Containers: []corev1.Container{ + { + Name: c.containerName, + Image: c.containerImage, + ImagePullPolicy: corev1.PullIfNotPresent, + }, + }, + HostNetwork: c.hostNetwork, + }, + } + if len(c.command) > 0 { + pod.Spec.Containers[0].Command = c.command + } + if c.containerSecurityContext != nil { + pod.Spec.Containers[0].SecurityContext = c.containerSecurityContext + } + if len(c.volumes) > 0 { + volumes := make([]corev1.Volume, 0) + volumeMounts := make([]corev1.VolumeMount, 0) + + for _, v := range c.volumes { + volumes = append(volumes, corev1.Volume{Name: v.Name, VolumeSource: v.VolumeSource}) + pod.Spec.Volumes = volumes + volumeMounts = append(volumeMounts, corev1.VolumeMount{Name: v.Name, MountPath: v.MountPath}) + pod.Spec.Containers[0].VolumeMounts = volumeMounts + } + } + + pod, err := c.clientset.K8sClient.CoreV1().Pods(pod.Namespace).Create( + context.TODO(), + pod, + metav1.CreateOptions{}, + ) + c.pod = pod + if err != nil { + return fmt.Errorf("failed to create pod: %w", err) + } + return nil +} + +func (c *ContainerCreationExecContext) listPods(options *metav1.ListOptions) (*corev1.PodList, error) { + pods, err := c.clientset.K8sClient.CoreV1().Pods(c.pod.Namespace).List( + context.TODO(), + *options, + ) + if err != nil { + return pods, fmt.Errorf("failed to find pods: %s", err.Error()) + } + return pods, nil +} + +func (c *ContainerCreationExecContext) refeshPod() error { + pods, err := c.listPods(&metav1.ListOptions{ + FieldSelector: fields.OneTermEqualSelector("metadata.name", c.podName).String(), + ResourceVersion: c.pod.ResourceVersion, + }) + if err != nil { + return err + } + if len(pods.Items) == 0 { + return fmt.Errorf("failed to find pod: %s", c.podName) + } + c.pod = &pods.Items[0] + + return nil +} + +func (c *ContainerCreationExecContext) isPodRunning() (bool, error) { + err := c.refeshPod() + if err != nil { + return false, err + } + if c.pod.Status.Phase == corev1.PodRunning { + return true, nil + } + return false, nil +} + +func (c *ContainerCreationExecContext) waitForPodToStart() error { + start := time.Now() + for time.Since(start) <= startTimeout { + running, err := c.isPodRunning() + if err != nil { + return err + } + if running { + return nil + } + time.Sleep(time.Microsecond) + } + return errors.New("timed out waiting for pod to start") +} + +func (c *ContainerCreationExecContext) CreatePodAndWait() error { + var err error + running := false + if c.pod != nil { + running, err = c.isPodRunning() + if err != nil { + return err + } + } + if !running { + err := c.createPod() + if err != nil { + return err + } + } + return c.waitForPodToStart() +} + +func (c *ContainerCreationExecContext) deletePod() error { + deletePolicy := metav1.DeletePropagationForeground + err := c.clientset.K8sClient.CoreV1().Pods(c.pod.Namespace).Delete( + context.TODO(), + c.pod.Name, + metav1.DeleteOptions{ + PropagationPolicy: &deletePolicy, + }) + if err != nil { + return fmt.Errorf("failed to delete pod: %w", err) + } + return nil +} + +func (c *ContainerCreationExecContext) waitForPodToDelete() error { + start := time.Now() + for time.Since(start) <= deletionTimeout { + pods, err := c.listPods(&metav1.ListOptions{}) + if err != nil { + return err + } + found := false + for _, pod := range pods.Items { //nolint:gocritic // This isn't my object I can't use a pointer + if pod.Name == c.podName { + found = true + } + } + if !found { + return nil + } + time.Sleep(time.Microsecond) + } + return errors.New("pod has not terminated within the timeout") +} + +func (c *ContainerCreationExecContext) DeletePodAndWait() error { + err := c.deletePod() + if err != nil { + return err + } + return c.waitForPodToDelete() +} + +func NewContainerCreationExecContext( + clientset *Clientset, + namespace, podName, containerName, containerImage string, + labels map[string]string, + command []string, + containerSecurityContext *corev1.SecurityContext, + hostNetwork bool, + volumes []*Volume, +) *ContainerCreationExecContext { + ctx := ContainerExecContext{ + namespace: namespace, + podNamePrefix: podName, + podName: podName, + containerName: containerName, + clientset: clientset, + } + + return &ContainerCreationExecContext{ + ContainerExecContext: &ctx, + containerImage: containerImage, + labels: labels, + command: command, + containerSecurityContext: containerSecurityContext, + hostNetwork: hostNetwork, + volumes: volumes, + } +} diff --git a/collector-framework/pkg/clients/exec_command_test.go b/collector-framework/pkg/clients/exec_command_test.go new file mode 100644 index 00000000..81feb761 --- /dev/null +++ b/collector-framework/pkg/clients/exec_command_test.go @@ -0,0 +1,131 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + +package clients_test + +import ( + "errors" + "net/url" + + . "github.com/onsi/ginkgo/v2" + . "github.com/onsi/gomega" + + v1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + fakeK8s "k8s.io/client-go/kubernetes/fake" + "k8s.io/client-go/tools/remotecommand" + + "github.com/redhat-partner-solutions/vse-sync-collection-tools/collector-framework/pkg/clients" + "github.com/redhat-partner-solutions/vse-sync-collection-tools/collector-framework/testutils" +) + +var notATestPod = &v1.Pod{ + ObjectMeta: metav1.ObjectMeta{ + Name: "NotATestPod-3989", + Namespace: "TestNamespace", + Annotations: map[string]string{}, + }, +} +var testPod = &v1.Pod{ + ObjectMeta: metav1.ObjectMeta{ + Name: "TestPod-8292", + Namespace: "TestNamespace", + Annotations: map[string]string{}, + }, +} + +var _ = Describe("NewContainerContext", func() { + var clientset *clients.Clientset + BeforeEach(func() { + clients.ClearClientSet() + var err error + clientset, err = clients.GetClientset(kubeconfigPath) + if err != nil { + panic("failed to get clientset") + } + }) + + When("A ContainerContext is requested for a pod which DOES NOT exist", func() { + It("should return an error ", func() { + fakeK8sClient := fakeK8s.NewSimpleClientset(notATestPod) + clientset.K8sClient = fakeK8sClient + + _, err := clients.NewContainerContext(clientset, "TestNamespace", "Test", "TestContainer") + Expect(err).To(HaveOccurred()) + }) + }) + When("A ContainerContext is requested for a pod which DOES exist", func() { + It("should return the context for that pod", func() { + fakeK8sClient := fakeK8s.NewSimpleClientset(notATestPod, testPod) + clientset.K8sClient = fakeK8sClient + + ctx, err := clients.NewContainerContext(clientset, "TestNamespace", "Test", "TestContainer") + Expect(err).NotTo(HaveOccurred()) + Expect(ctx.GetNamespace()).To(Equal("TestNamespace")) + Expect(ctx.GetContainerName()).To(Equal("TestContainer")) + Expect(ctx.GetPodName()).To(Equal("TestPod-8292")) + }) + }) +}) + +var _ = Describe("ExecCommandContainer", func() { + var clientset *clients.Clientset + BeforeEach(func() { + clientset = testutils.GetMockedClientSet(testPod) + }) + + When("given a pod", func() { + It("should exec the command and return the std buffers", func() { + expectedStdOut := "my test command stdout" + expectedStdErr := "my test command stderr" + responder := func(method string, url *url.URL, options remotecommand.StreamOptions) ([]byte, []byte, error) { + return []byte(expectedStdOut), []byte(expectedStdErr), nil + } + clients.NewSPDYExecutor = testutils.NewFakeNewSPDYExecutor(responder, nil) + ctx, _ := clients.NewContainerContext(clientset, "TestNamespace", "Test", "TestContainer") + cmd := []string{"my", "test", "command"} + stdout, stderr, err := ctx.ExecCommand(cmd) + Expect(err).NotTo(HaveOccurred()) + Expect(stdout).To(Equal(expectedStdOut)) + Expect(stderr).To(Equal(expectedStdErr)) + }) + }) + + //nolint:dupl //it is incorrectly saying that this is a duplicate despite the aguments being in a different order + When("NewSPDYExecutor fails", func() { + It("should return an error", func() { + expectedStdOut := "" + expectedStdErr := "" + expectedErr := errors.New("Something went horribly wrong when creating the executor") + responder := func(method string, url *url.URL, options remotecommand.StreamOptions) ([]byte, []byte, error) { + return []byte(expectedStdOut), []byte(expectedStdErr), nil + } + clients.NewSPDYExecutor = testutils.NewFakeNewSPDYExecutor(responder, expectedErr) + ctx, _ := clients.NewContainerContext(clientset, "TestNamespace", "Test", "TestContainer") + cmd := []string{"my", "test", "command"} + stdout, stderr, err := ctx.ExecCommand(cmd) + Expect(err).To(HaveOccurred()) + Expect(expectedErr.Error()).To(ContainSubstring(expectedErr.Error())) + Expect(stdout).To(Equal(expectedStdOut)) + Expect(stderr).To(Equal(expectedStdErr)) + }) + }) + //nolint:dupl //it is incorrectly saying that this is a duplicate despite the aguments being in a different order + When("SteamWithContext fails", func() { + It("should return an error", func() { + expectedStdOut := "" + expectedStdErr := "" + expectedErr := errors.New("Something went horribly wrong with the stream") + responder := func(method string, url *url.URL, options remotecommand.StreamOptions) ([]byte, []byte, error) { + return []byte(expectedStdOut), []byte(expectedStdErr), expectedErr + } + clients.NewSPDYExecutor = testutils.NewFakeNewSPDYExecutor(responder, nil) + ctx, _ := clients.NewContainerContext(clientset, "TestNamespace", "Test", "TestContainer") + cmd := []string{"my", "test", "command"} + stdout, stderr, err := ctx.ExecCommand(cmd) + Expect(err).To(HaveOccurred()) + Expect(expectedErr.Error()).To(ContainSubstring(expectedErr.Error())) + Expect(stdout).To(Equal(expectedStdOut)) + Expect(stderr).To(Equal(expectedStdErr)) + }) + }) +}) diff --git a/collector-framework/pkg/clients/test_files/kubeconfig b/collector-framework/pkg/clients/test_files/kubeconfig new file mode 100644 index 00000000..cbdc648b --- /dev/null +++ b/collector-framework/pkg/clients/test_files/kubeconfig @@ -0,0 +1,32 @@ +apiVersion: v1 +clusters: +- cluster: + certificate-authority-data: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURRRENDQWlpZ0F3SUJBZ0lJR0lUM0ZSNjNmenN3RFFZSktvWklodmNOQVFFTEJRQXdQakVTTUJBR0ExVUUKQ3hNSmIzQmxibk5vYVdaME1TZ3dKZ1lEVlFRREV4OXJkV0psTFdGd2FYTmxjblpsY2kxc2IyTmhiR2h2YzNRdApjMmxuYm1WeU1CNFhEVEl6TURFeU9URXlORGswTkZvWERUTXpNREV5TmpFeU5EazBORm93UGpFU01CQUdBMVVFCkN4TUpiM0JsYm5Ob2FXWjBNU2d3SmdZRFZRUURFeDlyZFdKbExXRndhWE5sY25abGNpMXNiMk5oYkdodmMzUXQKYzJsbmJtVnlNSUlCSWpBTkJna3Foa2lHOXcwQkFRRUZBQU9DQVE4QU1JSUJDZ0tDQVFFQXlIUFdxQTNLRDJXdwoyMUNRcXRDL0FLMklvQk5vbEdBb2NiOTM2bzk1dk1FcmpuRklRU3h1dS9VTWVnVURORVJCTTJzbGFoNVRKdGVkCmcxZjVOc29mYkx2OGlVc2RXUEhGYzhNbytpeXQvcFVVUVkrM3JxbFloRkpNV0RveHZyVkpPT3k5UGQ5UmFvUUcKbVREVUM3UzVOZ01SUVl4bTNNQ0tFb2pMZktiTllxK25RZ0VMSzhqeW00czBEcjhwVUo4SUNodXdUYXdvdG9YTAp0d0NIR210cXE1WTd6VmJMOTRlQytOVFRzS1Z3WFRrcVVQUmd1MHU5VFNubUZmdkFTVXMyRUNXekJjWE8vMlpvCnMxTktpSlphTE9kUVBEOU1XcHlqY0RkNENDa01KYnhLVjRwZDZNT3lpUWFxZ050NGIyUmFzaE5ac2hVd2hJSWIKblhxcHFJNnNjd0lEQVFBQm8wSXdRREFPQmdOVkhROEJBZjhFQkFNQ0FxUXdEd1lEVlIwVEFRSC9CQVV3QXdFQgovekFkQmdOVkhRNEVGZ1FVZFF4aVB1bE1XU0dZUllYYmFZbXJmQURBV24wd0RRWUpLb1pJaHZjTkFRRUxCUUFECmdnRUJBRG1OM1FIZjNmRjVsUUJFNTB6QTI3NGc4cU5kcnhHblFodFpGVGVqTmk3cTdSbUIrRGF1b0ZoUEw0ZnUKTW5Rd21WUWY3M1RVcmtraTZtL2RLNDhUSDVGTVZ5UEc5UFhxUzdPQU9NT1NFYWxUck9qYlpUSTY4WGUyb3JhMApjdEJKcEhXQ1NSbjYxcDlzSFVUVWRleGk1Y09HMzZlVnBnTHBTR0RwODNDVGdsUkk4R1JpblgyZEFxQUlhU2ZOCmNiN1RzUGdLUHA1em5xa0FlN1gvblJUVkREQzdheFBTZTUreXR5dVo0YXdxZXJDSk55b1A5dU5EeS9KN0tJeVQKd1pFMjAzRjE0SXRUMjZUSE9waW91bFhjVWJiUUtCeXMwVE5DVUNhd2x5TTNCUkZEN1g0Yk5SY01idVo3cWZ2SQpxMURZeDdxeFB1MmIwUk5tc2lueiswYkdMdms9Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0KLS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURURENDQWpTZ0F3SUJBZ0lJQ0RlRXFJRlVqZ2N3RFFZSktvWklodmNOQVFFTEJRQXdSREVTTUJBR0ExVUUKQ3hNSmIzQmxibk5vYVdaME1TNHdMQVlEVlFRREV5VnJkV0psTFdGd2FYTmxjblpsY2kxelpYSjJhV05sTFc1bApkSGR2Y21zdGMybG5ibVZ5TUI0WERUSXpNREV5T1RFeU5EazBORm9YRFRNek1ERXlOakV5TkRrME5Gb3dSREVTCk1CQUdBMVVFQ3hNSmIzQmxibk5vYVdaME1TNHdMQVlEVlFRREV5VnJkV0psTFdGd2FYTmxjblpsY2kxelpYSjIKYVdObExXNWxkSGR2Y21zdGMybG5ibVZ5TUlJQklqQU5CZ2txaGtpRzl3MEJBUUVGQUFPQ0FROEFNSUlCQ2dLQwpBUUVBblJMSk5Xb1BiQyttVS9Hb1NvTVVMQ3psZEpxVTFjMmRaRDQ4d20zOWtDanh3V0k5V3pNTDNpcWNscEpWCjhrNVBkTElPY1hCb2ZQTzlYNW8vMnhuNWtlNmx3bngwa242Ri9hdlJ3eHhaNjlPTzVrTGhTWGVZK0I2R25FbnQKSG5MbUtGVmZnaTV5Smx3NytkbndVcDlPcTVVM3pFcFdzQVNlNJR4ZjJsVFFpb3l4TDVNYzM0ZTNJNkRkc3RuNwp5U2czenBKNk5rVWZ5cjd3K2xtVEhQd2NpbkFMbTZad1RpMEJ2WnFiSS9WL25jWEpOM09TUTk5QjdoZ3hTTlhXCkhHUllUcEx6RVJDTTZTdE5Kc1RVOXEwcDkvVE5oYlh1eTlBVnlCYUhMNUN3TWlPNUEyQ3N1WGxrbUV5RzRoUFAKZDNGTzE0cVZPNDBGcnRvZ1lpNmdqeE00YXdJREFRQUJvMEl3UURBT0JnTlZIUThCQWY4RUJBTUNBcVF3RHdZRApWUjBUQVFIL0JBVXdBd0VCL3pBZEJnTlZIUTRFRmdRVXlCa1RlYnBMZk04dEsxeVB4djM4TXVBUHhTTXdEUVlKCktvWklodmNOQVFFTEJRQURnZ0VCQUJmb2gxQVFDbnpzak1sT1pyK3NNT0JPU0xTVGs4djFIc3ZEMnVwcmtmVXUKemw0K0tUWGQzaG9jcDRBZEpxdXBrSUNtVk1IZ0FkUzJjZGJjcGJkdHdoSmRnbkVITThFN2RtTVg1RWltUlhMTApaS00reEVVczlKYTk0NE1hdklvczF2U2hFNjFBWXlUQko0dWJUR0dVVDFPbnVwNkJobVBBRFNwMVhyZkpNaHVFClBLNVRFM0RsaTN3TFZjUUhBbTlIZmRkSjZ3MEx1K1VxN242R3cxS2Z6SlB0aXZDMm5BVzluVFJhSGhjcFAvbloKOFdzSXdvNTlueWMxSFZneUNmOWhNK3l2RmorRnJBdjk5YXRBUWI5NG9wTXE0OEVRTGlZdktjdUlMOUE5RVgwMQoxVnJLeFIrZFJPU1pxZGY3UzFqR21vR3BPVTFoQ1dPbFJWdkQvVG1DdERrPQotLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCi0tLS0tQkVHSU4gQ0VSVElGSUNBVEUtLS0tLQpNSUlETWpDQ0FocWdBd0lCQWdJSUE4Rjg2U1RZRWhFd0RRWUpLb1pJaHZjTkFRRUxCUUF3TnpFU01CQUdBMVVFCkN4TUpiM0JsYm5Ob2FXWjBNU0V3SHdZRFZRUURFeGhyZFdKbExXRndhWE5sY25abGNpMXNZaTF6YVdkdVpYSXcKSGhjTk1qTXdNVEk1TVRJME9UUTBXaGNOTXpNd01USTJNVEkwT1RRMFdqQTNNUkl3RUFZRFZRUUxFd2x2Y0dWdQpjMmhwWm5ReElUQWZCZ05WQkFNVEdHdDFZbVV0WVhCcGMyVnlkbVZ5TFd4aUxYTnBaMjVsY2pDQ0FTSXdEUVlKCktvWklodmNOQVFFQkJRQURnZ0VQQURDQ0FRb0NnZ0VCQU1ia20xbFVxTmk4M21OUFhPSUdVdUp3bHdrL2NuZUoKTCtoMEpzRVF3S0ZUTkNMY2xmZkdtK3VjWVlRZjNnNUp2M0hmcS9NNTdjUUs4QkozOUhZSFp4Y2tya21SUThxVwpYQmZObXVOTDZIRmJRclc5S2hFZlRRMnQ3TlZqMldJbzRhMlh3OFJZVTl1cWxGc3EvODZ4UTRTWDZKS01oQ1k3CmV1dDJmYjUxZmNHc3NTZTRKaGtENFZLckk5T3lyVGFqNGVacEJheDkyZFZwMktSa1RhUEFLb0NDdnUycFRsNDgKRlVzT3FVQUpnc0FwQmZGL3N0T0JxZ3B0eFJvUWlUT2FxMzhzMCtVazBlMG5Sem9SY092dUg1QktuOWU1cW5JeAp2dW14bzdyVCswWmtFWUJBeStnckhzRDUrcVFpUG42ekJCWURzUjBrYzMvT2RLTVV2M3ltN2cwQ0F3RUFBYU5DCk1FQXdEZ1lEVlIwUEFRSC9CQVFEQWdLa01BOEdBMVVkRXdFQi93UUZNQU1CQWY4d0hRWURWUjBPQkJZRUZENjcKREF1VmQ0a21rd1ZLalVScXlKVWcrVitOTUEwR0NTcUdTSWIzRFFFQkN3VUFBNElCQVFDQ25zQTJ3SE9hQWwvUQpkSWI2bXZuMzhXTlR4cXJwdzB1RlpqWWdIeitoWlBMR2lSV0RtSzdTaWxMb2lZelhoTkphV2xpRExLenhOY2dOCkdzSGxjcXVDTWMxdE5xNGwxek1RL2tELysyTTdteVlCUDJma3p3bXNxZGdndFpYVFluOWV4UFNkMGdLL0g2YnUKVmJSblhDbHdyRmpucmZ0bWQ4MXExMmRXa0JaVUdzdndaZHYzSERqQUNPa1VFVS9SSXVhaGxQUC85MGNWRThvMgpsZTI0WDBGYUE4SXk5VEtFL01kTjVpYmdOYUU4SC9RWFpqNUJSdUdyTjdLSzE4Q0t0NkdnOHZBRDcrWnNkVXhjCi9kV3dkVVhVV09wSEYrWVZUNHl2Ymd3QUhtbkc3TXdPVFFLY3F1M2tJT3RzUUQvMzYxdmNSRDVXQUhaUmpXTXoKOW81UFBWT1gKLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQo= + server: https://api.cormorant.wpc.test:6443 + name: api-cormorant-wpc-test:6443 +- cluster: + certificate-authority-data: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURRRENDQWlpZ0F3SUJBZ0lJR0lUM0ZSNjNmenN3RFFZSktvWklodmNOQVFFTEJRQXdQakVTTUJBR0ExVUUKQ3hNSmIzQmxibk5vYVdaME1TZ3dKZ1lEVlFRREV4OXJkV0psTFdGd2FYTmxjblpsY2kxc2IyTmhiR2h2YzNRdApjMmxuYm1WeU1CNFhEVEl6TURFeU9URXlORGswTkZvWERUTXpNREV5TmpFeU5EazBORm93UGpFU01CQUdBMVVFCkN4TUpiM0JsYm5Ob2FXWjBNU2d3SmdZRFZRUURFeDlyZFdKbExXRndhWE5sY25abGNpMXNiMk5oYkdodmMzUXQKYzJsbmJtVnlNSUlCSWpBTkJna3Foa2lHOXcwQkFRRUZBQU9DQVE4QU1JSUJDZ0tDQVFFQXlIUFdxQTNLRDJXdwoyMUNRcXRDL0FLMklvQk5vbEdBb2NiOTM2bzk1dk1FcmpuRklRU3h1dS9VTWVnVURORVJCTTJzbGFoNVRKdGVkCmcxZjVOc29mYkx2OGlVc2RXUEhGYzhNbytpeXQvcFVVUVkrM3JxbFloRkpNV0RveHZyVkpPT3k5UGQ5UmFvUUcKbVREVUM3UzVOZ01SUVl4bTNNQ0tFb2pMZktiTllxK25RZ0VMSzhqeW00czBEcjhwVUo4SUNodXdUYXdvdG9YTAp0d0NIR210cXE1WTd6VmJMOTRlQytOVFRzS1Z3WFRrcVVQUmd1MHU5VFNubUZmdkFTVXMyRUNXekJjWE8vMlpvCnMxTktpSlphTE9kUVBEOU1XcHlqY0RkNENDa01KYnhLVjRwZDZNT3lpUWFxZ050NGIyUmFzaE5ac2hVd2hJSWIKblhxcHFJNnNjd0lEQVFBQm8wSXdRREFPQmdOVkhROEJBZjhFQkFNQ0FxUXdEd1lEVlIwVEFRSC9CQVV3QXdFQgovekFkQmdOVkhRNEVGZ1FVZFF4aVB1bE1XU0dZUllYYmFZbXJmQURBV24wd0RRWUpLb1pJaHZjTkFRRUxCUUFECmdnRUJBRG1OM1FIZjNmRjVsUUJFNTB6QTI3NGc4cU5kcnhHblFodFpGVGVqTmk3cTdSbUIrRGF1b0ZoUEw0ZnUKTW5Rd21WUWY3M1RVcmtraTZtL2RLNDhUSDVGTVZ5UEc5UFhxUzdPQU9NT1NFYWxUck9qYlpUSTY4WGUyb3JhMApjdEJKcEhXQ1NSbjYxcDlzSFVUVWRleGk1Y09HMzZlVnBnTHBTR0RwODNDVGdsUkk4R1JpblgyZEFxQUlhU2ZOCmNiN1RzUGdLUHA1em5xa0FlN1gvblJUVkREQzdheFBTZTUreXR5dVo0YXdxZXJDSk55b1A5dU5EeS9KN0tJeVQKd1pFMjAzRjE0SXRUMjZUSE9waW91bFhjVWJiUUtCeXMwVE5DVUNhd2x5TTNCUkZEN1g0Yk5SY01idVo3cWZ2SQpxMURZeDdxeFB1MmIwUk5tc2lueiswYkdMdms9Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0KLS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURURENDQWpTZ0F3SUJBZ0lJQ0RlRXFJRlVqZ2N3RFFZSktvWklodmNOQVFFTEJRQXdSREVTTUJBR0ExVUUKQ3hNSmIzQmxibk5vYVdaME1TNHdMQVlEVlFRREV5VnJkV0psTFdGd2FYTmxjblpsY2kxelpYSjJhV05sTFc1bApkSGR2Y21zdGMybG5ibVZ5TUI0WERUSXpNREV5T1RFeU5EazBORm9YRFRNek1ERXlOakV5TkRrME5Gb3dSREVTCk1CQUdBMVVFQ3hNSmIzQmxibk5vYVdaME1TNHdMQVlEVlFRREV5VnJkV0psTFdGd2FYTmxjblpsY2kxelpYSjIKYVdObExXNWxkSGR2Y21zdGMybG5ibVZ5TUlJQklqQU5CZ2txaGtpRzl3MEJBUUVGQUFPQ0FROEFNSUlCQ2dLQwpBUUVBblJMSk5Xb1BiQyttVS9Hb1NvTVVMQ3psZEpxVTFjMmRaRDQ4d20zOWtDanh3V0k5V3pNTDNpcWNscEpWCjhrNVBkTElPY1hCb2ZQTzlYNW8vMnhuNWtlNmx3bngwa242Ri9hdlJ3eHhaNjlPTzVrTGhTWGVZK0I2R25FbnQKSG5MbUtGVmZnaTV5Smx3NytkbndVcDlPcTVVM3pFcFdzQVNlNJR4ZjJsVFFpb3l4TDVNYzM0ZTNJNkRkc3RuNwp5U2czenBKNk5rVWZ5cjd3K2xtVEhQd2NpbkFMbTZad1RpMEJ2WnFiSS9WL25jWEpOM09TUTk5QjdoZ3hTTlhXCkhHUllUcEx6RVJDTTZTdE5Kc1RVOXEwcDkvVE5oYlh1eTlBVnlCYUhMNUN3TWlPNUEyQ3N1WGxrbUV5RzRoUFAKZDNGTzE0cVZPNDBGcnRvZ1lpNmdqeE00YXdJREFRQUJvMEl3UURBT0JnTlZIUThCQWY4RUJBTUNBcVF3RHdZRApWUjBUQVFIL0JBVXdBd0VCL3pBZEJnTlZIUTRFRmdRVXlCa1RlYnBMZk04dEsxeVB4djM4TXVBUHhTTXdEUVlKCktvWklodmNOQVFFTEJRQURnZ0VCQUJmb2gxQVFDbnpzak1sT1pyK3NNT0JPU0xTVGs4djFIc3ZEMnVwcmtmVXUKemw0K0tUWGQzaG9jcDRBZEpxdXBrSUNtVk1IZ0FkUzJjZGJjcGJkdHdoSmRnbkVITThFN2RtTVg1RWltUlhMTApaS00reEVVczlKYTk0NE1hdklvczF2U2hFNjFBWXlUQko0dWJUR0dVVDFPbnVwNkJobVBBRFNwMVhyZkpNaHVFClBLNVRFM0RsaTN3TFZjUUhBbTlIZmRkSjZ3MEx1K1VxN242R3cxS2Z6SlB0aXZDMm5BVzluVFJhSGhjcFAvbloKOFdzSXdvNTlueWMxSFZneUNmOWhNK3l2RmorRnJBdjk5YXRBUWI5NG9wTXE0OEVRTGlZdktjdUlMOUE5RVgwMQoxVnJLeFIrZFJPU1pxZGY3UzFqR21vR3BPVTFoQ1dPbFJWdkQvVG1DdERrPQotLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCi0tLS0tQkVHSU4gQ0VSVElGSUNBVEUtLS0tLQpNSUlETWpDQ0FocWdBd0lCQWdJSUE4Rjg2U1RZRWhFd0RRWUpLb1pJaHZjTkFRRUxCUUF3TnpFU01CQUdBMVVFCkN4TUpiM0JsYm5Ob2FXWjBNU0V3SHdZRFZRUURFeGhyZFdKbExXRndhWE5sY25abGNpMXNZaTF6YVdkdVpYSXcKSGhjTk1qTXdNVEk1TVRJME9UUTBXaGNOTXpNd01USTJNVEkwT1RRMFdqQTNNUkl3RUFZRFZRUUxFd2x2Y0dWdQpjMmhwWm5ReElUQWZCZ05WQkFNVEdHdDFZbVV0WVhCcGMyVnlkbVZ5TFd4aUxYTnBaMjVsY2pDQ0FTSXdEUVlKCktvWklodmNOQVFFQkJRQURnZ0VQQURDQ0FRb0NnZ0VCQU1ia20xbFVxTmk4M21OUFhPSUdVdUp3bHdrL2NuZUoKTCtoMEpzRVF3S0ZUTkNMY2xmZkdtK3VjWVlRZjNnNUp2M0hmcS9NNTdjUUs4QkozOUhZSFp4Y2tya21SUThxVwpYQmZObXVOTDZIRmJRclc5S2hFZlRRMnQ3TlZqMldJbzRhMlh3OFJZVTl1cWxGc3EvODZ4UTRTWDZKS01oQ1k3CmV1dDJmYjUxZmNHc3NTZTRKaGtENFZLckk5T3lyVGFqNGVacEJheDkyZFZwMktSa1RhUEFLb0NDdnUycFRsNDgKRlVzT3FVQUpnc0FwQmZGL3N0T0JxZ3B0eFJvUWlUT2FxMzhzMCtVazBlMG5Sem9SY092dUg1QktuOWU1cW5JeAp2dW14bzdyVCswWmtFWUJBeStnckhzRDUrcVFpUG42ekJCWURzUjBrYzMvT2RLTVV2M3ltN2cwQ0F3RUFBYU5DCk1FQXdEZ1lEVlIwUEFRSC9CQVFEQWdLa01BOEdBMVVkRXdFQi93UUZNQU1CQWY4d0hRWURWUjBPQkJZRUZENjcKREF1VmQ0a21rd1ZLalVScXlKVWcrVitOTUEwR0NTcUdTSWIzRFFFQkN3VUFBNElCQVFDQ25zQTJ3SE9hQWwvUQpkSWI2bXZuMzhXTlR4cXJwdzB1RlpqWWdIeitoWlBMR2lSV0RtSzdTaWxMb2lZelhoTkphV2xpRExLenhOY2dOCkdzSGxjcXVDTWMxdE5xNGwxek1RL2tELysyTTdteVlCUDJma3p3bXNxZGdndFpYVFluOWV4UFNkMGdLL0g2YnUKVmJSblhDbHdyRmpucmZ0bWQ4MXExMmRXa0JaVUdzdndaZHYzSERqQUNPa1VFVS9SSXVhaGxQUC85MGNWRThvMgpsZTI0WDBGYUE4SXk5VEtFL01kTjVpYmdOYUU4SC9RWFpqNUJSdUdyTjdLSzE4Q0t0NkdnOHZBRDcrWnNkVXhjCi9kV3dkVVhVV09wSEYrWVZUNHl2Ymd3QUhtbkc3TXdPVFFLY3F1M2tJT3RzUUQvMzYxdmNSRDVXQUhaUmpXTXoKOW81UFBWT1gKLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQo= + server: https://api.cormorant.wpc.test:6443 + name: cormorant +contexts: +- context: + cluster: cormorant + user: admin + name: admin +- context: + cluster: api-cormorant-wpc-test:6443 + namespace: openshift-ptp + user: system:admin/api-cormorant-wpc-test:6443 + name: openshift-ptp/api-cormorant-wpc-test:6443/system:admin +current-context: openshift-ptp/api-cormorant-wpc-test:6443/system:admin +kind: Config +preferences: {} +users: +- name: admin + user: + client-certificate-data: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURaekNDQWsrZ0F3SUJBZ0lJYXA2Q1BYdUFud2N3RFFZSktvWklodmNOQVFFTEJRQXdOakVTTUJBR0ExVUUKQ3hNSmIzQmxibk5vYVdaME1TQXdIZ1lEVlFRREV4ZGhaRzFwYmkxcmRXSmxZMjl1Wm1sbkxYTnBaMjVsY2pBZQpGdzB5TXpBeE1qa3hNalE1TkROYUZ3MHpNekF4TWpZeE1qUTVORE5hTURBeEZ6QVZCZ05WQkFvVERuTjVjM1JsCmJUcHRZWE4wWlhKek1SVXdFd1lEVlFRREV3eHplWE4wWlcwNllXUnRhVzR3Z2dFaU1BMEdDU3FHU0liM0RRRUIKQVFVQUE0SUJEd0F3Z2dFS0FvSUJBUUNYbnlWZ1F2VGhUdGx3ZWlOYWg1aUlNUEhXUVN2ZXc0a0hGTlFVYTJvMQpjdmJaNlJBR3AwcG8ycTRkbGMySmFOVnVQUWJPclNYRlVidVRlL1JXTVJJVWFlbjREc0g0ZGFOMnlRT0haaXBmClhOVUpDRGNndDIyN0F2Wmp2UWNIeUlXcVRZMDAyRE1mYWZXVnovRDB5dS8zRzlRbHVHS2kycmN5bmdrak1PR2UKcE9CajFxTDhBNzJ4TDV5VmJ0T08wVWVKSWRYd0RnNGdSeG5PK1Q1ZHo3MjAzMU9tZ1dWSmk5c2hyTzhZSzdNRwozb2xZSjhoTC9kY09wZ1hoMi9YTVBsTkp3WFRuU1l6Y2I3KzlKWVBLQ2xsUUFWK0cxalVVVENCd3VPV01ZM1puCmoxbTJtNkoydnRZd0pyZG1nc0o3RkxJbTN5andDMFRPQmQ5SEdiUGNRRmpSQWdNQkFBR2pmekI5TUE0R0ExVWQKRHdFQi93UUVBd0lGb0RBZEJnTlZIU1VFRmpBVUJnZ3JCZ0VGQlFjREFRWUlLd1lCQlFVSEF3SXdEQVlEVlIwVApBUUgvQkFJd0FEQWRCZ05WSFE0RUZnUVV0NmxNVDU1THd3OTlUZTJKaWVlUVJZOVNlcW93SHdZRFZSMGpCQmd3CkZvQVVIKzZPL1pwcDA1UlRLTk44NWhtMTdMTWlTRnN3RFFZSktvWklodmNOQVFFTEJRQUrnZ0VCQUczYW9HcWEKVDdFZDAwL0szUXJ1OWZTUm1xRER4eXh6VTJYTWd2bnZEQzhuVUMycVorQmdGRzZzUktBQVVHMGVxLzk4ajJzNgpKMmZJU1pUZGFIc1FoQmVQQWFqdElhS0E5YTByQlRmU3ZmbVZ0ZmhGdzAwK1FsNUJBU3U2bndVMTM3d3lCam9oCm81RDZ1K2J2Tk9Sd2NWa0g5MTc2T21CUnVDalY5Lzk2cFZCVUNiL0p6dDQ4NVg2SzkzOCttRW5JWDBLcExCdlcKL3JZdDJiVlQ3cFpTQXN0K2RaVzd2YzlqV0pUNVBma2V4bEliRzk4Tit1b2JhVk55S1J3K09WaHdWQ08wTGhuTQpleGdUU1gvcEhPNkxaK1lVRlpRSzJlVU9BeVJvMzVyY3g4TUJxMHh5dTlJeUZLS2xmd1hEdnZYOXVJN1Z0eG0xCkFyeHM5d29RdHNBNkx2UT0KLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQo= + client-key-data: LS0tLS1CRUdJTiBSU0EgUFJJVkFURSBLRVktLS0tLQpNSUlFb3dJQkFBS0NBUUVBbDU4bFlFTDA0VTdaY0hvaldvZVlpRER4MWtFcjNzT0pCeFRVRkd0cU5YTDIyZWtRCkJxZEthTnF1SFpYTmlXalZiajBHenEwbHhWRzdrM3YwVmpFU0ZHbnArQTdCK0hXamRza0RoMllxWDF6VkNRZzMKSUxkdHV3TDJZNzBIQjhpRnFrMk5OTmd6SDJuMWxjL3c5TXJ2OXh2VUpiaGlvdHEzTXA0Skl6RGhucVRnWTlhaQovQU85c1MrY2xXN1RqdEZIaVNIVjhBNE9JRWNaenZrK1hjKzl0TjlUcG9GbFNZdmJJYXp2R0N1ekJ0NkpXQ2ZJClMvM1hEcVlGNGR2MXpENVRTY0YwNTBtTTNHKy92U1dEeWdwWlVBRmZodFkxRkV3Z2NMamxqR04yWjQ5WnRwdWkKZHI3V01DYTNab0xDZXhTeUp0OG84QXRFemdYZlJ4bXozRUJZMFFJREFRQUJBb0lCQVFDRUZYdjE4OTVvT014cgprN3Nncm1kT25YVFA5VTVHYllqOXhrTksxcGhibjU4MERqaUwwMGliTjRYZStCVnAwdzI3VHlhUy9YdWQvYW11CnZaa0pUUTQzQWwxMFgwYlRMNGdMZnVtNEZtUnJWdSt2UXB6anYyZTBOc3gxN3NJbElhWnZ5Y2R0ZGJwemIxY2wKLzFRbHJIU0hqSkt2bVlVejRkMGVGMVpXZGNyVzYrdlBUZFYxNUtaaHpONVV6Tm9maHhzUEZSZEEySTdtS1RxOApadG92NXFaRVltWWZkQjMwK2NyQ1VCR1ZoaGJiaGt1LytqMEJJWXJST0RmellnTE5MNEpTOVpXNk9CUE5rVldJClUzZmxQaEZMTHI5NmE1K05Ua29HcWlMbktIZzh2TUJQcmhFS0puWVB6SnVSWEdHd1FvNXhzTFVVVW9uU3R6cTUKSXBiRzM5VFJBb0dCQU1IRXRRTlJ4c010S0tGZFd6a2J3c1k4MGdzaHhJRFhWenVFYjFPNnpxM3JFVWg5MllkbQpEYVBZcm9GNDBKdkdkNjNuNWl0MkhDNU1ESk13Y3cvc1p1OEY5NWpuVU1SaTcydStrV24xeXrGaUZLZUJSWG1DClFpSzJiWG5MRmdCQi9WM0pyNUVhbVJqZFFMMVZLKzFOaVNqUTVHZDIyajloRUxJK1JFRmxuWW83QW9HQkFNaFIKTmN4WVBsS1NBTFFCZTdESEs3cWx3ZlpLdGI0bDhYOFpBcXJ6by9iY2xMRHFLQ053ZlIrQVp6OFc1b1gyaVV3bgo1TW9sQU9kbDZTSGJmeVdNOTRSbEhTczVVcXRKRWE5b0YxK0xBYitHZUVqWmNtbDl4L1F6RG9WemxzQWxKejRTClJhZWJ5VlVmcVVqTU8yNUxXb0ZmQmVaRi9HeGZWdkE2M29YcTJXeGpBb0dBWG1EaVRlQ1o4RnpoaWw4L1hIeVMKRFI1NHJDVmhZZVFCUUNNTVduc0Z5aDVSeDc1TW9xOXBlMkhCOVp3VDk1dmVsUno3dGpXTUdseStUejdzL0ZlSAo5Mm92cEJFZS9OaTNod0pHTDVjaGw0U3ZUTHNoVE1MT1Zid0hiS2duYWk2Nkt1RmVtMDJhUGtzZUNsb2UwREhRCjJjbU5SbnZVWjhSdWJuTDNxZWJGcWhzQ2dZQkZHd2NWUE9nYk1qVTk1RGtZcmsxZXNhcHRYaTYrcjNaVm8zb3gKSWFaU0ZwelJQNmFqT3o1ZkxMdnhudVBlR1VRYVdyVHFLOFBaRUdaU0FOZ25TeTlrcEVGZzFRQzVDSmNxVFIycgpIMWgyQzF6WnZQSmtoRGtEL00wb3FzeTU4dGRMNlovUUI4VjRNVmtFUFRqUGZ2MTFIaVA1NGZFSUxnZmZEbUFRCkVRbjdBd0tCZ0dHcVVBejFyYXdXTDNQbTMvVFh1OHRZS0w3NE9vVHNwaEpJTzlwOFdSazZDc3ZwZmtPMVI4cHAKWE83RjFKQ2V5ZHB5S3NadTZIT1FNN2hJUEVrUjBNMGVDL1l5eDNlVEMrSzhleDFrczlUSmI3eWk0aE54dndrQQpjbDVZNmhVaG45bzE3WW0rMGlPRDUzb0hiNmxpMll2OWdXazBxWUVzVHBEQ1FoRjdwd25sCi0tLS0tRU5EIFJTQSBQUklWQVRFIEtFWS0tLS0tCg== +- name: system:admin/api-cormorant-wpc-test:6443 + user: + client-certificate-data: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURaekNDQWsrZ0F3SUJBZ0lJYXA2Q1BYdUFud2N3RFFZSktvWklodmNOQVFFTEJRQXdOakVTTUJBR0ExVUUKQ3hNSmIzQmxibk5vYVdaME1TQXdIZ1lEVlFRREV4ZGhaRzFwYmkxcmRXSmxZMjl1Wm1sbkxYTnBaMjVsY2pBZQpGdzB5TXpBeE1qa3hNalE1TkROYUZ3MHpNekF4TWpZeE1qUTVORE5hTURBeEZ6QVZCZ05WQkFvVERuTjVjM1JsCmJUcHRZWE4wWlhKek1SVXdFd1lEVlFRREV3eHplWE4wWlcwNllXUnRhVzR3Z2dFaU1BMEdDU3FHU0liM0RRRUIKQVFVQUE0SUJEd0F3Z2dFS0FvSUJBUUNYbnlWZ1F2VGhUdGx3ZWlOYWg1aUlNUEhXUVN2ZXc0a0hGTlFVYTJvMQpjdmJaNlJBR3AwcG8ycTRkbGMySmFOVnVQUWJPclNYRlVidVRlL1JXTVJJVWFlbjREc0g0ZGFOMnlRT0haaXBmClhOVUpDRGNndDIyN0F2Wmp2UWNIeUlXcVRZMDAyRE1mYWZXVnovRDB5dS8zRzlRbHVHS2kycmN5bmdrak1PR2UKcE9CajFxTDhBNzJ4TDV5VmJ0T08wVWVKSWRYd0RnNGdSeG5PK1Q1ZHo3MjAzMU9tZ1dWSmk5c2hyTzhZSzdNRwozb2xZSjhoTC9kY09wZ1hoMi9YTVBsTkp3WFRuU1l6Y2I3KzlKWVBLQ2xsUUFWK0cxalVVVENCd3VPV01ZM1puCmoxbTJtNkoydnRZd0pyZG1nc0o3RkxJbTN5andDMFRPQmQ5SEdiUGNRRmpSQWdNQkFBR2pmekI5TUE0R0ExVWQKRHdFQi93UUVBd0lGb0RBZEJnTlZIU1VFRmpBVUJnZ3JCZ0VGQlFjREFRWUlLd1lCQlFVSEF3SXdEQVlEVlIwVApBUUgvQkFJd0FEQWRCZ05WSFE0RUZnUVV0NmxNVDU1THd3OTlUZTJKaWVlUVJZOVNlcW93SHdZRFZSMGpCQmd3CkZvQVVIKzZPL1pwcDA1UlRLTk44NWhtMTdMTWlTRnN3RFFZSktvWklodmNOQVFFTEJRQURnZ0VCQUczYW9HcWEKVDdFZDAwL0szUXJ1OWZTUm1xRER4eXh6VTJYTWd2bnZEQzhuVUMycVorQmdGRzZzUktBQVVHMGVxLzk4ajJzNgpKMmZJU1pUZGFIc1FoQmVQQWFqdElhS0E5YTByQlRmU3ZmbVZ0ZmhGdzAwK1FsNUJBU3U2bndVMTM3d3lCam9oCm81RDZ1K2J2Tk9Sd2NWa0g5MTc2T21CUnVDalY5Lzk2cFZCVUNiL0p6dDQ4NVg2SzkzOCttRW5JWDBLcExCdlcKL3JZdDJiVlQ3cFpTQXN0K2RaVzd2YzlqV0pUNVBma2V4bEliRzk4Tit1b2JhVk55S1J3K09WaHdWQ08wTGhuTQpleGdUU1gvcEhPNkxaK1lVRlpRSzJlVU9BeVJvMzVyY3g4TUJxMHh5dTlJeUZLS2xmd1hEdnZYOXVJN1Z0eG0xCkFyeHM5d29RdHNBNkx2UT0KLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQo= + client-key-data: LS0tLS1CRUdJTiBSU0EgUFJJVkFURSBLRVktLS0tLQpNSUlFb3dJQkFBS0NBUUVBbDU4bFlFTDA0VTdaY0hvaldvZVlpRER4MWtFcjNzT0pCeFRVRkd0cU5YTDIyZWtRCkJxZEthTnF1SFpYTmlXalZiajBHenEwbHhWRzdrM3YwVmpFU0ZHbnArQTdCK0hXamRza0RoMllxWDF6VkNRZzMKSUxkdHV3TDJZNzBIQjhpRnFrMk5OTmd6SDJuMWxjL3c5TXJ2OXh2VUpiaGlvdHEzTXA0Skl6RGhucVRnWTlhaQovQU85c1MrY2xXN1RqdEZIaVNIVjhBNE9JRWNaenZrK1hjKzl0TjlUcG9GbFNZdmJJYXp2R0N1ekJ0NkpXQ2ZJClMvM1hEcVlGNGR2MXpENVRTY0YwNTBtTTNHKy92U1dEeWdwWlVBRmZodFkxRkV3Z2NMamxqR04yWjQ5WnRwdWkKZHI3V01DYTNab0xDZXhTeUp0OG84QXRFemdYZlJ4bXozRUJZMFFJREFRQUJBb0lCQVFDRUZYdjE4OTVvT014cgprN3Nncm1kT25YVFA5VTVHYllqOXhrTksxcGhibjU4MERqaUwwMGliTjRYZStCVnAwdzI3VHlhUy9YdWQvYW11CnZaa0pUUTQzQWwxMFgwYlRMNGdMZnVtNEZtUnJWdSt2UXB6anYyZTBOc3gxN3NJbElhWnZ5Y2R0ZGJwemIxY2wKLzFRbHJIU0hqSkt2bVlVejRkMGVGMVpXZGNyVzYrdlBUZFYxNUtaaHpONVV6Tm9maHhzUEZSZEEySTdtS1RxOApadG92NXFaRVltWWZkQjMwK2NyQ1VCR1ZoaGJiaGt1LytqMEJJWXJST0RmellnTE5MNEpTOVpXNk9CUE5rVldJClUzZmxQaEZMTHI5NmE1K05Ua29HcWlMbktIZzh2TUJQcmhFS0puWVB6SnVSWEdHd1FvNXhzTFVVVW9uU3R6cTUKSXBiRzM5VFJBb0dCQU1IRXRRTlJ4c010S0tGZFd6a2J3c1k4MGdzaHhJRFhWenVFYjFPNnpxM3JFVWg5MllkbQpEYVBZcm9GNDBKdkdkNjNuNWl0MkhDNU1ESk13Y3cvc1p1OEY5NWpuVU1SaTcydStrV24xeXRGaUZLZUJSWG1DClFpSzJiWG5MRmdCQi9WM0pyNUVhbVJqZFFMMVZLKzFOaVNqUTVHZDIyajloRUxJK1JFRmxuWW83QW9HQkFNaFIKTmN4WVBsS1NBTFFCZTdESEs3cWx3ZlpLdGI0bDhYOFpBcXJ6by9iY2xMRHFLQ053ZlIrQVp6OFc1b1gyaVV3bgo1TW9sQU9kbDZTSGJmeVdNOTRSbEhTczVVcXRKRWE5b0YxK0xBYitHZUVqWmNtbDl4L1F6RG9WemxzQWxKejRTClJhZWJ5VlVmcVVqTU8yNUxXb0ZmQmVaRi9HeGZWdkE2M29YcTJXeGpBb0dBWG1EaVRlQ1o4RnpoaWw4L1hIeVMKRFI1NHJDVmhZZVFCUUNNTVduc0Z5aDVSeDc1TW9xOXBlMkhCOVp3VDk1dmVsUno3dGpXTUdseStUejdzL0ZlSAo5Mm92cEJFZS9OaTNod0pHTDVjaGw0U3ZUTHNoVE1MT1Zid0hiS2duYWk2Nkt1RmVtMDJhUGtzZUNsb2UwREhRCjJjbU5SbnZVWjhSdWJuTDNxZWJGcWhzQ2dZQkZHd2NWUE9nYk1qVTk1RGtZcmsxZXNhcHRYaTYrcjNaVm8zb3gKSWFaU0ZwelJQNmFqT3o1ZkxMdnhudVBlR1VRYVdyVHFLOFBaRUdaU0FOZ25TeTlrcEVGZzFRQzVDSmNxVFIycgpIMWgyQzF6WnZQSmtoRGtEL00wb3FzeTU4dGRMNlovUUI4VjRNVmtFUFRqUGZ2MTFIaVA1NGZFSUxnZmZEbUFRCkVRbjdBd0tCZ0dHcVVBejFyYXdXTDNQbTMvVFh1OHRZS0w3NE9vVHNwaEpJTzlwOFdSazZDc3ZwZmtPMVI4cHAKWE83RjFKQ2V5ZHB5S3NadTZIT1FNN2hJUEVrUjBNMGVDL1l5eDNlVEMrSzhleDFrczlUSmI3eWk0aE54dndrQQpjbDVZNmhVaG45bzE3WW0rMGlPRDUzb0hiNmxpMll2OWdXazBxWUVzVHBEQ1FoRjdwd25sCi0tLS0tRU5EIFJTQSBQUklWQVRFIEtFWS0tLS0tCg== diff --git a/collector-framework/pkg/collectors/collector.go b/collector-framework/pkg/collectors/collector.go new file mode 100644 index 00000000..14f73e8b --- /dev/null +++ b/collector-framework/pkg/collectors/collector.go @@ -0,0 +1,165 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + +package collectors + +import ( + "sync" + "time" + + "github.com/redhat-partner-solutions/vse-sync-collection-tools/collector-framework/pkg/callbacks" + "github.com/redhat-partner-solutions/vse-sync-collection-tools/collector-framework/pkg/clients" + "github.com/redhat-partner-solutions/vse-sync-collection-tools/collector-framework/pkg/utils" +) + +type Collector interface { + Start() error // Setups any internal state required for collection to happen + Poll(chan PollResult, *utils.WaitGroupCount) // Poll for collectables + CleanUp() error // Stops the collector and cleans up any internal state. It should result in a state that can be started again + GetPollInterval() time.Duration // Returns the collectors polling interval + IsAnnouncer() bool + ScalePollInterval(float64) + ResetPollInterval() +} + +// A union of all values required to be passed into all constructions +type CollectionConstructor struct { + Callback callbacks.Callback + Clientset *clients.Clientset + ErroredPolls chan PollResult + CollectorArgs map[string]map[string]any + PollInterval int + DevInfoAnnouceInterval int +} + +type PollResult struct { + CollectorName string + Errors []error +} + +type baseCollector struct { + Callback callbacks.Callback + pollInterval *LockedInterval + isAnnouncer bool + running bool +} + +func (base *baseCollector) GetPollInterval() time.Duration { + return base.pollInterval.interval() +} + +func (base *baseCollector) ScalePollInterval(factor float64) { + base.pollInterval.scale(factor) +} + +func (base *baseCollector) ResetPollInterval() { + base.pollInterval.reset() +} + +func (base *baseCollector) IsAnnouncer() bool { + return base.isAnnouncer +} + +func (base *baseCollector) Start() error { + base.running = true + return nil +} + +func (base *baseCollector) CleanUp() error { + base.running = false + return nil +} + +func NewBaseCollector( + pollInterval int, + isAnnouncer bool, + callback callbacks.Callback, +) *baseCollector { + return &baseCollector{ + Callback: callback, + isAnnouncer: isAnnouncer, + running: false, + pollInterval: NewLockedInterval(pollInterval), + } +} + +type ExecCollector struct { + *baseCollector + ctx clients.ExecContext +} + +func NewExecCollector( + pollInterval int, + isAnnouncer bool, + callback callbacks.Callback, + ctx clients.ExecContext, +) *ExecCollector { + execCollector := ExecCollector{ + baseCollector: NewBaseCollector( + pollInterval, + isAnnouncer, + callback, + ), + ctx: ctx, + } + return &execCollector +} + +func (col *ExecCollector) GetContext() clients.ExecContext { + return col.ctx +} + +type APICollector struct { + *baseCollector + ctx clients.APIContext +} + +func NewAPICollector( + pollInterval int, + isAnnouncer bool, + callback callbacks.Callback, + ctx clients.APIContext, +) *APICollector { + return &APICollector{ + baseCollector: NewBaseCollector( + pollInterval, + isAnnouncer, + callback, + ), + ctx: ctx, + } +} + +func (col *APICollector) GetContext() clients.APIContext { + return col.ctx +} + +type LockedInterval struct { + current time.Duration + base time.Duration + lock sync.RWMutex +} + +func (li *LockedInterval) interval() time.Duration { + li.lock.RLock() + defer li.lock.RUnlock() + return li.current +} + +func (li *LockedInterval) scale(factor float64) { + li.lock.Lock() + li.current = time.Duration(factor * li.current.Seconds() * float64(time.Second)) + li.lock.Unlock() +} + +func (li *LockedInterval) reset() { + li.lock.Lock() + li.current = li.base + li.lock.Unlock() +} + +func NewLockedInterval(seconds int) *LockedInterval { + return &LockedInterval{ + current: time.Duration(seconds) * time.Second, + base: time.Duration(seconds) * time.Second, + } +} diff --git a/collector-framework/pkg/collectors/log_follower.go b/collector-framework/pkg/collectors/log_follower.go new file mode 100644 index 00000000..5681deef --- /dev/null +++ b/collector-framework/pkg/collectors/log_follower.go @@ -0,0 +1,343 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + +package collectors + +import ( + "bufio" + "context" + "errors" + "fmt" + "io" + "os" + "strings" + "sync" + "time" + "unicode" + + log "github.com/sirupsen/logrus" + v1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + + "github.com/redhat-partner-solutions/vse-sync-collection-tools/collector-framework/pkg/clients" + "github.com/redhat-partner-solutions/vse-sync-collection-tools/collector-framework/pkg/loglines" + "github.com/redhat-partner-solutions/vse-sync-collection-tools/collector-framework/pkg/utils" +) + +const ( + lineSliceChanLength = 100 + lineChanLength = 1000 + lineDelim = '\n' + streamingBufferSize = 2000 + logPollInterval = 2 + logFilePermissions = 0666 + keepGenerations = 5 +) + +var ( + followDuration = logPollInterval * time.Second + followTimeout = 30 * followDuration +) + +// LogsCollector collects logs from repeated calls to the kubeapi with overlapping query times, +// the lines are then fed into a channel, in another goroutine they are de-duplicated and written to an output file. +// +// Overlap: +// cmd followDuration +// |---------------| +// since cmd followDuration +// |---------------|---------------| +// .............. since cmd followDuration +// .............. |---------------|---------------| +// +// This was done because oc logs and the kubeapi endpoint which it uses does not look back +// over a log rotation event, nor does it continue to follow. +// +// Log aggregators would be preferred over this method however this requires extra infra +// which might not be present in the environment. +type LogsCollector struct { + *APICollector + generations loglines.Generations + writeQuit chan os.Signal + lines chan *loglines.ProcessedLine + slices chan *loglines.LineSlice + sliceQuit chan os.Signal + logsOutputFileName string + lastPoll loglines.GenerationalLockedTime + wg sync.WaitGroup + withTimeStamps bool + pruned bool +} + +const ( + LogsCollectorName = "Logs" + LogsInfo = "log-line" +) + +func (logs *LogsCollector) SetLastPoll(pollTime time.Time) { + logs.lastPoll.Update(pollTime) +} + +// Start sets up the collector so it is ready to be polled +func (logs *LogsCollector) Start() error { + go logs.processSlices() + go logs.writeToLogFile() + logs.generations.Dumper.Start() + logs.running = true + return nil +} + +func (logs *LogsCollector) writeLine(line *loglines.ProcessedLine, writer io.StringWriter) { + var err error + if logs.withTimeStamps { + _, err = writer.WriteString(line.Full + "\n") + } else { + _, err = writer.WriteString(line.Content + "\n") + } + if err != nil { + log.Error("failed to write log output to file") + } +} + +//nolint:cyclop // allow this to be a little complicated +func (logs *LogsCollector) processSlices() { + logs.wg.Add(1) + defer logs.wg.Done() + for { + select { + case sig := <-logs.sliceQuit: + log.Debug("Clearing slices") + for len(logs.slices) > 0 { + lineSlice := <-logs.slices + logs.generations.Add(lineSlice) + } + log.Debug("Flushing remaining generations") + deduplicated := logs.generations.FlushAll() + for _, line := range deduplicated.Lines { + logs.lines <- line + } + log.Debug("Sending Signal to writer") + logs.writeQuit <- sig + return + case lineSlice := <-logs.slices: + logs.generations.Add(lineSlice) + default: + if logs.generations.ShouldFlush() { + deduplicated := logs.generations.Flush() + for _, line := range deduplicated.Lines { + logs.lines <- line + } + } + time.Sleep(time.Nanosecond) + } + } +} + +func (logs *LogsCollector) writeToLogFile() { + logs.wg.Add(1) + defer logs.wg.Done() + + fileHandle, err := os.OpenFile(logs.logsOutputFileName, os.O_CREATE|os.O_WRONLY, logFilePermissions) + utils.IfErrorExitOrPanic(err) + defer fileHandle.Close() + for { + select { + case <-logs.writeQuit: + // Consume the rest of the lines so we don't miss lines + for len(logs.lines) > 0 { + line := <-logs.lines + logs.writeLine(line, fileHandle) + } + return + case line := <-logs.lines: + logs.writeLine(line, fileHandle) + default: + time.Sleep(time.Nanosecond) + } + } +} + +func processLine(line string) (*loglines.ProcessedLine, error) { + splitLine := strings.SplitN(line, " ", 2) //nolint:gomnd // moving this to a var would make the code less clear + if len(splitLine) < 2 { //nolint:gomnd // moving this to a var would make the code less clear + return nil, fmt.Errorf("failed to split line %s", line) + } + timestampPart := splitLine[0] + lineContent := splitLine[1] + timestamp, err := time.Parse(time.RFC3339, timestampPart) + if err != nil { + // This is not a value line something went wrong + return nil, fmt.Errorf("failed to process timestamp from line: '%s'", line) + } + processed := &loglines.ProcessedLine{ + Timestamp: timestamp, + Content: strings.TrimRightFunc(lineContent, unicode.IsSpace), + Full: strings.TrimRightFunc(line, unicode.IsSpace), + } + return processed, nil +} + +//nolint:funlen // allow long function +func processStream(stream io.ReadCloser, expectedEndtime time.Time) ([]*loglines.ProcessedLine, error) { + scanner := bufio.NewScanner(stream) + segment := make([]*loglines.ProcessedLine, 0) + for scanner.Scan() { + if err := scanner.Err(); err != nil { + return segment, fmt.Errorf("error while reading logs stream %w", err) + } + pline, err := processLine(scanner.Text()) + if err != nil { + log.Warning("failed to process line: ", err) + continue + } + segment = append(segment, pline) + if expectedEndtime.Sub(pline.Timestamp) < 0 { + // Were past our expected end time lets finish there + break + } + } + return segment, nil +} + +func (logs *LogsCollector) poll() error { + podName := logs.ctx.GetPodName() + podLogOptions := v1.PodLogOptions{ + SinceTime: &metav1.Time{Time: logs.lastPoll.Time()}, + Container: logs.ctx.GetContainerName(), + Follow: true, + Previous: false, + Timestamps: true, + } + podLogRequest := logs.ctx.GetClientset().K8sClient.CoreV1(). + Pods(logs.ctx.GetNamespace()). + GetLogs(podName, &podLogOptions). + Timeout(followTimeout) + stream, err := podLogRequest.Stream(context.TODO()) + if err != nil { + return fmt.Errorf("failed to poll when r: %w", err) + } + defer stream.Close() + + start := time.Now() + generation := logs.lastPoll.Generation() + lines, err := processStream(stream, time.Now().Add(logs.GetPollInterval())) + if err != nil { + return err + } + if len(lines) > 0 { + lineSlice := loglines.MakeSliceFromLines(lines, generation) + logs.slices <- lineSlice + logs.SetLastPoll(start) + } + return nil +} + +// Poll collects log lines +func (logs *LogsCollector) Poll(resultsChan chan PollResult, wg *utils.WaitGroupCount) { + defer func() { + wg.Done() + }() + errorsToReturn := make([]error, 0) + err := logs.poll() + if err != nil { + errorsToReturn = append(errorsToReturn, err) + } + resultsChan <- PollResult{ + CollectorName: LogsCollectorName, + Errors: errorsToReturn, + } +} + +// CleanUp stops a running collector +func (logs *LogsCollector) CleanUp() error { + logs.running = false + logs.sliceQuit <- os.Kill + log.Debug("waiting for logs to complete") + logs.wg.Wait() + logs.generations.Dumper.Stop() + return nil +} + +//nolint:varnamelen,funlen // ok is the standard name for these checks, +func getArgsFromCollectorArgs(constructor *CollectionConstructor) ( + includeLogTimestamps bool, + logsOutputFile string, + tempDir string, + keepDebugFiles bool, + err error, +) { + logArgs, ok := constructor.CollectorArgs["Logs"] + if !ok { + return false, "", "", false, errors.New("no Logs args in collector args") + } + logsOutputFileRaw, ok := logArgs["logsOutputFile"] + if !ok { + return false, "", "", false, errors.New("no logsOutputFile in Log collector args") + } + + logsOutputFile, ok = logsOutputFileRaw.(string) + if !ok { + return false, "", "", false, errors.New("logsOutputFile is not a string") + } + + includeLogTimestampsRaw, ok := logArgs["includeLogTimestamps"] + if !ok { + return false, "", "", false, errors.New("no logsOutputFile in Log collector args") + } + + includeLogTimestamps, ok = includeLogTimestampsRaw.(bool) + if !ok { + return false, "", "", false, errors.New("logsOutputFile is not a bool") + } + + tempDirRaw, ok := logArgs["tempDir"] + if !ok { + return false, "", "", false, errors.New("no tempDir in Log collector args") + } + + tempDir, ok = tempDirRaw.(string) + if !ok { + return false, "", "", false, errors.New("tempDir is not a string") + } + + keepDebugFilesRaw, ok := logArgs["keepDebugFiles"] + if !ok { + return false, "", "", false, errors.New("no keepDebugFiles in Log collector args") + } + + keepDebugFiles, ok = keepDebugFilesRaw.(bool) + if !ok { + return false, "", "", false, errors.New("keepDebugFiles is not a string") + } + + return includeLogTimestamps, logsOutputFile, tempDir, keepDebugFiles, nil +} + +// Returns a new LogsCollector from the CollectionConstuctor Factory +func NewLogsCollector(constructor *CollectionConstructor, ctx *clients.ContainerExecContext) (Collector, error) { + includeLogTimestamps, logsOutputFile, tempDir, keepDebugFiles, err := getArgsFromCollectorArgs(constructor) + if err != nil { + return &LogsCollector{}, err + } + + collector := LogsCollector{ + APICollector: NewAPICollector( + logPollInterval, + false, + constructor.Callback, + ctx, + ), + sliceQuit: make(chan os.Signal), + writeQuit: make(chan os.Signal), + pruned: true, + slices: make(chan *loglines.LineSlice, lineSliceChanLength), + lines: make(chan *loglines.ProcessedLine, lineChanLength), + lastPoll: loglines.NewGenerationalLockedTime(time.Now().Add(-time.Second)), // Stop initial since seconds from being 0 as its invalid + withTimeStamps: includeLogTimestamps, + logsOutputFileName: logsOutputFile, + generations: loglines.Generations{ + Store: make(map[uint32][]*loglines.LineSlice), + Dumper: loglines.NewGenerationDumper(tempDir, keepDebugFiles), + }, + } + return &collector, nil +} diff --git a/collector-framework/pkg/collectors/registry.go b/collector-framework/pkg/collectors/registry.go new file mode 100644 index 00000000..96cf1203 --- /dev/null +++ b/collector-framework/pkg/collectors/registry.go @@ -0,0 +1,71 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + +package collectors + +import ( + "fmt" + "log" +) + +type collectonBuilderFunc func(*CollectionConstructor) (Collector, error) +type collectorInclusionType int + +const ( + Required collectorInclusionType = iota + Optional +) + +type CollectorRegistry struct { + registry map[string]collectonBuilderFunc + required []string + optional []string +} + +var registry *CollectorRegistry + +func GetRegistry() *CollectorRegistry { + return registry +} + +func (reg *CollectorRegistry) register( + collectorName string, + builderFunc collectonBuilderFunc, + inclusionType collectorInclusionType, +) { + reg.registry[collectorName] = builderFunc + switch inclusionType { + case Required: + reg.required = append(reg.required, collectorName) + case Optional: + reg.optional = append(reg.optional, collectorName) + default: + log.Panic("Incorrect collector inclusion type") + } +} + +func (reg *CollectorRegistry) GetBuilderFunc(collectorName string) (collectonBuilderFunc, error) { + builderFunc, ok := reg.registry[collectorName] + if !ok { + return nil, fmt.Errorf("not index in registry for collector named %s", collectorName) + } + return builderFunc, nil +} + +func (reg *CollectorRegistry) GetRequiredNames() []string { + return reg.required +} + +func (reg *CollectorRegistry) GetOptionalNames() []string { + return reg.optional +} + +func RegisterCollector(collectorName string, builderFunc collectonBuilderFunc, inclusionType collectorInclusionType) { + if registry == nil { + registry = &CollectorRegistry{ + registry: make(map[string]collectonBuilderFunc, 0), + required: make([]string, 0), + optional: make([]string, 0), + } + } + registry.register(collectorName, builderFunc, inclusionType) +} diff --git a/collector-framework/pkg/fetcher/builder.go b/collector-framework/pkg/fetcher/builder.go new file mode 100644 index 00000000..ff616bfe --- /dev/null +++ b/collector-framework/pkg/fetcher/builder.go @@ -0,0 +1,31 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + +package fetcher + +import ( + "fmt" + + "github.com/redhat-partner-solutions/vse-sync-collection-tools/collector-framework/pkg/clients" +) + +type AddCommandArgs struct { + Key string + Command string + Trim bool +} + +func FetcherFactory(commands []*clients.Cmd, addCommands []AddCommandArgs) (*Fetcher, error) { + fetcherInst := NewFetcher() + for _, cmdInst := range commands { + fetcherInst.AddCommand(cmdInst) + } + + for _, addCmd := range addCommands { + err := fetcherInst.AddNewCommand(addCmd.Key, addCmd.Command, addCmd.Trim) + if err != nil { + return fetcherInst, fmt.Errorf("failed to add command %s: %w", addCmd.Key, err) + } + } + + return fetcherInst, nil +} diff --git a/collector-framework/pkg/fetcher/fetcher.go b/collector-framework/pkg/fetcher/fetcher.go new file mode 100644 index 00000000..b31c4b15 --- /dev/null +++ b/collector-framework/pkg/fetcher/fetcher.go @@ -0,0 +1,105 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + +package fetcher + +import ( + "bytes" + "fmt" + "strings" + + log "github.com/sirupsen/logrus" + + "github.com/redhat-partner-solutions/vse-sync-collection-tools/collector-framework/pkg/clients" +) + +type PostProcessFuncType func(map[string]string) (map[string]any, error) + +type Fetcher struct { + cmdGrp *clients.CmdGroup + postProcessor PostProcessFuncType +} + +func NewFetcher() *Fetcher { + return &Fetcher{ + cmdGrp: &clients.CmdGroup{}, + } +} + +func TrimSpace(s string) (string, error) { + return strings.TrimSpace(s), nil +} + +func (inst *Fetcher) SetPostProcessor(ppFunc PostProcessFuncType) { + inst.postProcessor = ppFunc +} + +// AddNewCommand creates a new command from a string +// then adds it to the fetcher +func (inst *Fetcher) AddNewCommand(key, cmd string, trim bool) error { + cmdInst, err := clients.NewCmd(key, cmd) + if err != nil { + return fmt.Errorf("add fetcher cmd failed %w", err) + } + if trim { + cmdInst.SetOutputProcessor(TrimSpace) + } + inst.cmdGrp.AddCommand(cmdInst) + return nil +} + +// AddCommand takes a command instance and adds it the fetcher +func (inst *Fetcher) AddCommand(cmdInst *clients.Cmd) { + inst.cmdGrp.AddCommand(cmdInst) +} + +// Fetch executes the commands on the container passed as the ctx and +// use the results to populate pack +func (inst *Fetcher) Fetch(ctx clients.ExecContext, pack any) error { + runResult, err := runCommands(ctx, inst.cmdGrp) + if err != nil { + return err + } + result := make(map[string]any) + for key, value := range runResult { + result[key] = value + } + if inst.postProcessor != nil { + updatedResults, ppErr := inst.postProcessor(runResult) + if ppErr != nil { + return fmt.Errorf("feching failed post process the data %w", ppErr) + } + for key, value := range updatedResults { + result[key] = value + } + } + err = unmarshal(result, pack) + if err != nil { + return fmt.Errorf("feching failed to unpack data %w", err) + } + return nil +} + +// runCommands executes the commands on the container passed as the ctx +// and extracts the results from the stdout +func runCommands(ctx clients.ExecContext, cmdGrp clients.Cmder) (result map[string]string, err error) { //nolint:lll // allow slightly long function definition + cmd := cmdGrp.GetCommand() + command := []string{"/usr/bin/sh"} + var buffIn bytes.Buffer + buffIn.WriteString(cmd) + + stdout, _, err := ctx.ExecCommandStdIn(command, buffIn) + if err != nil { + log.Debugf( + "command in container failed unexpectedly:\n\tcontext: %v\n\tcommand: %v\n\terror: %v", + ctx, command, err, + ) + return result, fmt.Errorf("runCommands failed %w", err) + } + result, err = cmdGrp.ExtractResult(stdout) + if err != nil { + log.Debugf("extraction failed %s", err.Error()) + log.Debugf("output was %s", stdout) + return result, fmt.Errorf("runCommands failed %w", err) + } + return result, nil +} diff --git a/collector-framework/pkg/fetcher/unmarshal.go b/collector-framework/pkg/fetcher/unmarshal.go new file mode 100644 index 00000000..d8ed3151 --- /dev/null +++ b/collector-framework/pkg/fetcher/unmarshal.go @@ -0,0 +1,43 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + +package fetcher + +import ( + "fmt" + "reflect" +) + +func setValueOnField(fieldVal reflect.Value, value any) error { + if valueType := reflect.TypeOf(value); valueType != fieldVal.Type() { + return fmt.Errorf( + "incoming value %v with type %s not of expected type %s", + value, + valueType, + fieldVal.Type().String(), + ) + } + fieldVal.Set(reflect.ValueOf(value)) + return nil +} + +// unmarshal will populate the fields in `target` with the values from `result` according to the fields`fetcherKey` tag. +// fields with no `fetcherKey` tag will not be touched, and elements in `result` without a matched field will be ignored. +func unmarshal(result map[string]any, target any) error { + val := reflect.ValueOf(target) + typ := reflect.TypeOf(target) + + for i := 0; i < val.Elem().NumField(); i++ { + field := typ.Elem().Field(i) + resultName := field.Tag.Get("fetcherKey") + if resultName != "" { + fieldVal := val.Elem().FieldByIndex(field.Index) + if res, ok := result[resultName]; ok { + err := setValueOnField(fieldVal, res) + if err != nil { + return fmt.Errorf("failed to set value on field %s: %w", resultName, err) + } + } + } + } + return nil +} diff --git a/collector-framework/pkg/fetcher/unmarshal_test.go b/collector-framework/pkg/fetcher/unmarshal_test.go new file mode 100644 index 00000000..e931651a --- /dev/null +++ b/collector-framework/pkg/fetcher/unmarshal_test.go @@ -0,0 +1,124 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + +package fetcher //nolint:testpackage // testing internal functions + +import ( + "reflect" + "testing" + "time" + + . "github.com/onsi/ginkgo/v2" + . "github.com/onsi/gomega" +) + +type testStruct struct { //nolint:govet // changing the order would break the tests as it relies on the ordering + TestString string `fetcherKey:"str"` + TestSlice []int `fetcherKey:"slice"` + TestDuration time.Duration `fetcherKey:"duration"` + TestStuct nestedStuct `fetcherKey:"struct"` +} + +type nestedStuct struct { + Value string +} + +var _ = Describe("setValueOnField", func() { + When("calling setValueOnField with the correct type", func() { + It("should populate the field", func() { + target := &testStruct{} + testStrValue := "I am a test string" + strField := reflect.TypeOf(target).Elem().Field(0) + strFieldVal := reflect.ValueOf(target).Elem().FieldByIndex(strField.Index) + err := setValueOnField(strFieldVal, testStrValue) + Expect(err).NotTo(HaveOccurred()) + Expect(target.TestString).To(Equal(testStrValue)) + + testSliceValue := []int{12, 15, 18} + sliceField := reflect.TypeOf(target).Elem().Field(1) + sliceFieldVal := reflect.ValueOf(target).Elem().FieldByIndex(sliceField.Index) + err = setValueOnField(sliceFieldVal, testSliceValue) + Expect(err).NotTo(HaveOccurred()) + Expect(target.TestSlice).To(Equal(testSliceValue)) + + }) + }) + When("calling setValueOnField with a non trivial type", func() { + It("should populate the field", func() { + target := &testStruct{} + testDuration := 10 * time.Second + sliceField := reflect.TypeOf(target).Elem().Field(2) + sliceFieldVal := reflect.ValueOf(target).Elem().FieldByIndex(sliceField.Index) + err := setValueOnField(sliceFieldVal, testDuration) + Expect(err).NotTo(HaveOccurred()) + Expect(target.TestDuration).To(Equal(testDuration)) + + }) + }) + When("calling setValueOnField with a struct type", func() { + It("should populate the field", func() { + target := &testStruct{} + toNest := nestedStuct{Value: "I am nested"} + sliceField := reflect.TypeOf(target).Elem().Field(3) + sliceFieldVal := reflect.ValueOf(target).Elem().FieldByIndex(sliceField.Index) + err := setValueOnField(sliceFieldVal, toNest) + Expect(err).NotTo(HaveOccurred()) + Expect(target.TestStuct).To(Equal(toNest)) + }) + }) + When("calling setValueOnField with the incorrect type", func() { + It("should return an error", func() { + target := &testStruct{} + testNonStrValue := 12 + strField := reflect.TypeOf(target).Elem().Field(0) + strFieldVal := reflect.ValueOf(target).Elem().FieldByIndex(strField.Index) + err := setValueOnField(strFieldVal, testNonStrValue) + Expect(err).To(HaveOccurred()) + + testBadSliceValue := []string{"12", "15", "18"} + sliceField := reflect.TypeOf(target).Elem().Field(1) + sliceFieldVal := reflect.ValueOf(target).Elem().FieldByIndex(sliceField.Index) + err = setValueOnField(sliceFieldVal, testBadSliceValue) + Expect(err).To(HaveOccurred()) + }) + }) +}) + +var _ = Describe("unmarshal", func() { + When("calling unmarshal with the correct types", func() { + It("should populate the target", func() { + target := &testStruct{} + values := make(map[string]any) + values["str"] = "I am a test string" + values["slice"] = []int{1, 2, 3, 4} + err := unmarshal(values, target) + Expect(err).NotTo(HaveOccurred()) + Expect(target.TestString).To(Equal(values["str"])) + Expect(target.TestSlice).To(Equal(values["slice"])) + }) + }) + When("calling unmarshal with the incorrect str type", func() { + It("should return an err", func() { + target := &testStruct{} + values := make(map[string]any) + values["str"] = 12 + values["slice"] = []int{1, 2, 3, 4} + err := unmarshal(values, target) + Expect(err).To(HaveOccurred()) + }) + }) + When("calling unmarshal with the incorrect slice type", func() { + It("should return an err", func() { + target := &testStruct{} + values := make(map[string]any) + values["str"] = "I am a test string" + values["slice"] = []string{"1", "2", "3", "4"} + err := unmarshal(values, target) + Expect(err).To(HaveOccurred()) + }) + }) +}) + +func TestFetcher(t *testing.T) { + RegisterFailHandler(Fail) + RunSpecs(t, "Fetcher Suite") +} diff --git a/collector-framework/pkg/logging/logging.go b/collector-framework/pkg/logging/logging.go new file mode 100644 index 00000000..1685ffca --- /dev/null +++ b/collector-framework/pkg/logging/logging.go @@ -0,0 +1,20 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + +package logging + +import ( + "io" + + log "github.com/sirupsen/logrus" + + "github.com/redhat-partner-solutions/vse-sync-collection-tools/collector-framework/pkg/utils" +) + +// SetupLogging will configure the output stream and the level +// of the logrus logger +func SetupLogging(logLevel string, out io.Writer) { + log.SetOutput(out) + level, err := log.ParseLevel(logLevel) + utils.IfErrorExitOrPanic(err) + log.SetLevel(level) +} diff --git a/collector-framework/pkg/loglines/dedup.go b/collector-framework/pkg/loglines/dedup.go new file mode 100644 index 00000000..82778091 --- /dev/null +++ b/collector-framework/pkg/loglines/dedup.go @@ -0,0 +1,223 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + +package loglines + +import ( + "fmt" + "os" + "sort" + + log "github.com/sirupsen/logrus" +) + +const ( + keepGenerations = 5 +) + +func dedupGeneration(lineSlices []*LineSlice) *LineSlice { + ls1, ls2 := DedupLineSlices(lineSlices) + output := MakeSliceFromLines(MakeNewCombinedSlice(ls1.Lines, ls2.Lines), ls2.Generation) + return output +} + +// findLineIndex will find the index of a line in a slice of lines +// and will return -1 if it is not found +func findLineIndex(needle *ProcessedLine, list []*ProcessedLine) int { + checkLine := needle.Full + for i, hay := range list { + if hay.Full == checkLine { + return i + } + } + return -1 +} + +// looks for a line that exists in x without being present at the same index in y. +// +//nolint:varnamelen // x and y are just two sets of lines +func findFirstIssueIndex(x, y []*ProcessedLine) int { + for index, line := range x { + if index >= len(y) { + // we've reached the end of y so no bad lines found + break + } + if line.Full != y[index].Full { + return index + } + } + return -1 +} + +func findNextMatching(a, b []*ProcessedLine) (offset, index int) { + index = findLineIndex(a[offset], b) + if index == -1 { + // Can't find X in Y, Search for next line which is in Y + for offset = 1; offset < len(a); offset++ { + index = findLineIndex(a[offset], b) + if index != -1 { + break + } + } + } + return offset, index +} + +// fixLines will insert sequental lines missing in either x or y when stich them into the other. +// This is only done for the first issue found so you will need to call this iteratively. +// It will return the fixed slices and a flag which tells you if anything changed. +// If the lines at issueIndex are the same it will return the input slices. +// +//nolint:gocritic,varnamelen // don't want to name the return values as they should be built later, I think x, y are expressive enough names +func fixLines(x, y []*ProcessedLine, issueIndex int) ([]*ProcessedLine, []*ProcessedLine, bool) { + // confirm x[i] != y[i] + if x[issueIndex].Full == y[issueIndex].Full { + // No issue here... + return x, y, false + } + + // Check if its the y value missing in x + if findLineIndex(y[issueIndex], x[issueIndex:]) == -1 { + // lets add missing y values into x + yOffset, xIndex := findNextMatching(y[issueIndex:], x[issueIndex:]) + newX := make([]*ProcessedLine, 0, len(x)+yOffset) + newX = append(newX, x[:issueIndex]...) + newX = append(newX, y[issueIndex:issueIndex+yOffset]...) + newX = append(newX, x[issueIndex+xIndex:]...) + return newX, y, true + } + + if findLineIndex(x[issueIndex], y[issueIndex:]) == -1 { + xOffset, yIndex := findNextMatching(x[issueIndex:], y[issueIndex:]) + newY := make([]*ProcessedLine, 0, len(y)+xOffset) + newY = append(newY, y[:issueIndex]...) + newY = append(newY, x[issueIndex:issueIndex+xOffset]...) + newY = append(newY, y[issueIndex+yIndex:]...) + return x, newY, true + } + return x, y, false +} + +// processOverlap checks for incompatible lines if they are found it attempts to fix the issue +// and then if it fixes it then it dedups the fixed sets +// +//nolint:gocritic,varnamelen // don't want to name the return values as they should be built later, I think x, y are expressive enough names +func processOverlap(x, y []*ProcessedLine) ([]*ProcessedLine, []*ProcessedLine, error) { + newX := x + newY := y + issueIndex := findFirstIssueIndex(newX, newY) + if issueIndex == -1 { + return newX, newY, nil + } + var changed bool + for issueIndex != -1 { + newX, newY, changed = fixLines(newX, newY, issueIndex) + issueIndex = findFirstIssueIndex(newX, newY) + if !changed && issueIndex != -1 { + return newX, newY, fmt.Errorf("failed to resolve overlap") + } + } + // Now its been fixed lets just dedup it completely again. + dx, dy := DedupAB(newX, newY) + return dx, dy, nil +} + +//nolint:gocritic,varnamelen // don't want to name the return values as they should be built later, I think a, b are expressive enough names +func handleIncompleteOverlap(a, b []*ProcessedLine) ([]*ProcessedLine, []*ProcessedLine) { + newA, newB, err := processOverlap(a, b) + if err != nil { + issueIndex := findFirstIssueIndex(newA, newB) + log.Warning("Failed to fix issues gonna just split at the issue and retry this might lose some data") + return DedupAB(newA[:issueIndex], newB[issueIndex:]) + } + return newA, newB +} + +//nolint:gocritic,varnamelen // don't want to name the return values as they should be built later, I think a, b are expressive enough names +func DedupAB(a, b []*ProcessedLine) ([]*ProcessedLine, []*ProcessedLine) { + bFirstLineIndex := findLineIndex(b[0], a) + log.Debug("line index: ", bFirstLineIndex) + if bFirstLineIndex == -1 { + log.Debug("didn't to find first line of b") + lastLineIndex := findLineIndex(a[len(a)-1], b) + if lastLineIndex == -1 { + log.Debug("didn't to find last line of a; assuming no overlap") + return a, b + } + + // we have the index of the last line of a in b + // so b[:lastLineIndex+1] contains some of a + // lets try + return handleIncompleteOverlap(a, b) + } + + index := findFirstIssueIndex(a[bFirstLineIndex:], b) + if index >= 0 { + return handleIncompleteOverlap(a, b) + } + return a[:bFirstLineIndex], b +} + +func MakeNewCombinedSlice(x, y []*ProcessedLine) []*ProcessedLine { + r := make([]*ProcessedLine, 0, len(x)+len(y)) + r = append(r, x...) + r = append(r, y...) + return r +} + +//nolint:gocritic // don't want to name the return values as they should be built later +func DedupLineSlices(lineSlices []*LineSlice) (*LineSlice, *LineSlice) { + sort.Slice(lineSlices, func(i, j int) bool { + sdif := lineSlices[i].start.Sub(lineSlices[j].start) + if sdif == 0 { + // If start is the same then lets put the earlist end time first + return lineSlices[i].end.Sub(lineSlices[j].end) < 0 + } + return sdif < 0 + }) + + if len(lineSlices) == 1 { + return &LineSlice{}, lineSlices[0] + } + + lastLineSlice := lineSlices[len(lineSlices)-1] + lastButOneLineSlice := lineSlices[len(lineSlices)-2] + + // work backwards thought the slices + // dedupling the earlier one along the way + dedupedLines, lastLines := DedupAB(lastButOneLineSlice.Lines, lastLineSlice.Lines) + + if len(lineSlices) == 2 { //nolint:gomnd // it would obscure that its just a length of 2 + if len(dedupedLines) == 0 { + return &LineSlice{Generation: lastButOneLineSlice.Generation}, + MakeSliceFromLines(lastLines, lastLineSlice.Generation) + } + return MakeSliceFromLines(dedupedLines, lastButOneLineSlice.Generation), + MakeSliceFromLines(lastLines, lastLineSlice.Generation) + } + + resLines := dedupedLines + reference := MakeNewCombinedSlice(dedupedLines, lastLines) + for index := len(lineSlices) - 3; index >= 0; index-- { + aLines, bLines := DedupAB(lineSlices[index].Lines, reference) + resLines = MakeNewCombinedSlice(aLines, resLines) + reference = MakeNewCombinedSlice(aLines, bLines) + } + return MakeSliceFromLines(resLines, lastButOneLineSlice.Generation), + MakeSliceFromLines(lastLines, lastLineSlice.Generation) +} + +func WriteOverlap(lines []*ProcessedLine, name string) error { + logFile, err := os.Create(name) + if err != nil { + return fmt.Errorf("failed %w", err) + } + defer logFile.Close() + + for _, line := range lines { + _, err := logFile.WriteString(line.Full + "\n") + if err != nil { + log.Error(err) + } + } + return nil +} diff --git a/collector-framework/pkg/loglines/dedup_test.go b/collector-framework/pkg/loglines/dedup_test.go new file mode 100644 index 00000000..d6fa4a8f --- /dev/null +++ b/collector-framework/pkg/loglines/dedup_test.go @@ -0,0 +1,149 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + +package loglines_test + +import ( + "bufio" + "fmt" + "os" + "testing" + + . "github.com/onsi/ginkgo/v2" + . "github.com/onsi/gomega" + + "github.com/redhat-partner-solutions/vse-sync-collection-tools/collector-framework/pkg/loglines" +) + +//nolint:unparam // its only one param for now but we might want more later +func loadLinesFromFile(path string, generation uint32) (*loglines.LineSlice, error) { + reader, err := os.Open(path) + if err != nil { + return &loglines.LineSlice{}, fmt.Errorf("failed to open file %s %w", path, err) + } + defer reader.Close() + scanner := bufio.NewScanner(reader) + + lines := make([]*loglines.ProcessedLine, 0) + for scanner.Scan() { + if err := scanner.Err(); err != nil { + return &loglines.LineSlice{}, fmt.Errorf("failed to read line from %s %w", path, err) + } + line, err := loglines.ProcessLine(scanner.Text()) + if err != nil { + return &loglines.LineSlice{}, fmt.Errorf("failed to process line from %s %w", path, err) + } + lines = append(lines, line) + } + return loglines.MakeSliceFromLines(lines, generation), nil +} + +var _ = Describe("Dedup AB tests", func() { + When("DedupAB is called on two line slices with complete overlap", func() { //nolint:dupl // don't want to dupl tests + It("should return an empty list and a complete set of the lines", func() { + lineSlice, err := loadLinesFromFile("test_files/all.log", 0) + if err != nil { + Panic() + } + dl1, dl2 := loglines.DedupAB(lineSlice.Lines, lineSlice.Lines) + Expect(dl1).To(BeEmpty()) + Expect(dl2).To(Equal(lineSlice.Lines)) + }) + }) + When("DedupAB is called on two line slices with no overlap", func() { //nolint:dupl // don't want to dupl tests + It("should return a both sets of the lines", func() { + lineSlice, err := loadLinesFromFile("test_files/all.log", 0) + if err != nil { + Panic() + } + dl1, dl2 := loglines.DedupAB(lineSlice.Lines[:100], lineSlice.Lines[200:300]) + Expect(dl1).To(Equal(lineSlice.Lines[:100])) + Expect(dl2).To(Equal(lineSlice.Lines[200:300])) + }) + }) + When("DedupAB is called on two line slices with some overlap", func() { //nolint:dupl // don't want to dupl tests + It("should return the first slice without the overlap and the second set of lines", func() { + lineSlice, err := loadLinesFromFile("test_files/all.log", 0) + if err != nil { + Panic() + } + dl1, dl2 := loglines.DedupAB(lineSlice.Lines[:200], lineSlice.Lines[100:300]) + Expect(dl1).To(Equal(lineSlice.Lines[:100])) + Expect(dl2).To(Equal(lineSlice.Lines[100:300])) + }) + }) + When("DedupAB is called on two line slices when second is an extension of the first", func() { //nolint:dupl // don't want to dupl tests + It("should return a empty set and a complete set", func() { + lineSlice, err := loadLinesFromFile("test_files/all.log", 0) + if err != nil { + Panic() + } + dl1, dl2 := loglines.DedupAB(lineSlice.Lines[:200], lineSlice.Lines[:300]) + Expect(dl1).To(BeEmpty()) + Expect(dl2).To(Equal(lineSlice.Lines[:300])) + }) + }) + When("cDedupAB is called on two line slices with when the second is an extension of the first, "+ + "but the first is missing the first line", func() { //nolint:dupl // don't want to dupl tests + It("should return a empty set and a complete set", func() { + lineSlice, err := loadLinesFromFile("test_files/all.log", 0) + if err != nil { + Panic() + } + dl1, dl2 := loglines.DedupAB(lineSlice.Lines[1:200], lineSlice.Lines[:300]) + Expect(dl1).To(BeEmpty()) + Expect(dl2).To(Equal(lineSlice.Lines[:300])) + }) + }) + When("DedupAB is called on two line slices with first slice is missing every 3rd line", func() { //nolint:dupl // don't want to dupl tests + It("should return an empty set and a complete set", func() { + lineSlice, err := loadLinesFromFile("test_files/all.log", 0) + if err != nil { + Panic() + } + firstSet := make([]*loglines.ProcessedLine, 0) + for i, line := range lineSlice.Lines[:200] { + if i%3 == 0 { + continue + } + firstSet = append(firstSet, line) + } + dl1, dl2 := loglines.DedupAB(firstSet, lineSlice.Lines[:300]) + Expect(dl1).To(BeEmpty()) + Expect(dl2).To(Equal(lineSlice.Lines[:300])) + }) + }) + When("DedupAB is called on two line slices with second slice is missing every 3rd line", func() { //nolint:dupl // don't want to dupl tests + It("should return an empty set and a complete set", func() { + lineSlice, err := loadLinesFromFile("test_files/all.log", 0) + if err != nil { + Panic() + } + secondSet := make([]*loglines.ProcessedLine, 0) + for i, line := range lineSlice.Lines[:300] { + if i%3 == 0 { + continue + } + secondSet = append(secondSet, line) + } + dl1, dl2 := loglines.DedupAB(secondSet, lineSlice.Lines[:300]) + Expect(dl1).To(BeEmpty()) + Expect(dl2).To(Equal(lineSlice.Lines[:300])) + }) + }) + When("DedupAB is called on two line slices with second slice is overlapping but longer", func() { //nolint:dupl // don't want to dupl tests + It("should return an empty list and a complete set of the lines", func() { + lineSlice, err := loadLinesFromFile("test_files/all.log", 0) + if err != nil { + Panic() + } + dl1, dl2 := loglines.DedupAB(lineSlice.Lines[:100], lineSlice.Lines) + Expect(dl1).To(BeEmpty()) + Expect(dl2).To(Equal(lineSlice.Lines)) + }) + }) +}) + +func TestCommand(t *testing.T) { + RegisterFailHandler(Fail) + RunSpecs(t, "Loglines") +} diff --git a/collector-framework/pkg/loglines/lines.go b/collector-framework/pkg/loglines/lines.go new file mode 100644 index 00000000..08d09c4c --- /dev/null +++ b/collector-framework/pkg/loglines/lines.go @@ -0,0 +1,256 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + +package loglines + +import ( + "fmt" + "os" + "path/filepath" + "sort" + "strings" + "sync" + "time" + "unicode" + + log "github.com/sirupsen/logrus" + + "github.com/redhat-partner-solutions/vse-sync-collection-tools/collector-framework/pkg/utils" +) + +const ( + dumpChannelSize = 100 +) + +type ProcessedLine struct { + Timestamp time.Time + Full string + Content string + Generation uint32 +} + +func ProcessLine(line string) (*ProcessedLine, error) { + splitLine := strings.SplitN(line, " ", 2) //nolint:gomnd // moving this to a var would make the code less clear + if len(splitLine) < 2 { //nolint:gomnd // moving this to a var would make the code less clear + return nil, fmt.Errorf("failed to split line %s", line) + } + timestampPart := splitLine[0] + lineContent := splitLine[1] + timestamp, err := time.Parse(time.RFC3339, timestampPart) + if err != nil { + // This is not a value line something went wrong + return nil, fmt.Errorf("failed to process timestamp from line: '%s'", line) + } + processed := &ProcessedLine{ + Timestamp: timestamp, + Content: strings.TrimRightFunc(lineContent, unicode.IsSpace), + Full: strings.TrimRightFunc(line, unicode.IsSpace), + } + return processed, nil +} + +func NewGenerationalLockedTime(initialTime time.Time) GenerationalLockedTime { + return GenerationalLockedTime{time: initialTime} +} + +type GenerationalLockedTime struct { + time time.Time + lock sync.RWMutex + generation uint32 +} + +func (lt *GenerationalLockedTime) Time() time.Time { + lt.lock.RLock() + defer lt.lock.RUnlock() + return lt.time +} + +func (lt *GenerationalLockedTime) Generation() uint32 { + lt.lock.RLock() + defer lt.lock.RUnlock() + return lt.generation +} + +func (lt *GenerationalLockedTime) Update(update time.Time) { + lt.lock.Lock() + defer lt.lock.Unlock() + if update.Sub(lt.time) > 0 { + lt.time = update + lt.generation += 1 + } +} + +type LineSlice struct { + start time.Time + end time.Time + Lines []*ProcessedLine + Generation uint32 +} + +type Generations struct { + Store map[uint32][]*LineSlice + Dumper *GenerationDumper + Latest uint32 + Oldest uint32 +} + +type Dump struct { + slice *LineSlice + numberInGen int +} + +func NewGenerationDumper(dir string, keepLogs bool) *GenerationDumper { + return &GenerationDumper{ + dir: dir, + toDump: make(chan *Dump, dumpChannelSize), + quit: make(chan *os.Signal), + filenames: make([]string, 0), + keepLogs: keepLogs, + } +} + +type GenerationDumper struct { + dir string + toDump chan *Dump + quit chan *os.Signal + filenames []string + keepLogs bool + wg sync.WaitGroup +} + +func (dump *GenerationDumper) Start() { + dump.wg.Add(1) + go dump.dumpProcessor() +} + +func (dump *GenerationDumper) DumpLines(ls *LineSlice, numberInGen int) { + dump.toDump <- &Dump{slice: ls, numberInGen: numberInGen} +} + +func (dump *GenerationDumper) writeToFile(toDump *Dump) { + fname := filepath.Join( + dump.dir, + fmt.Sprintf("generation-%d-%d.log", toDump.slice.Generation, toDump.numberInGen), + ) + dump.filenames = append(dump.filenames, fname) + err := WriteOverlap(toDump.slice.Lines, fname) + if err != nil { + log.Errorf("failed to write generation dump file: %s", err.Error()) + } +} + +func (dump *GenerationDumper) dumpProcessor() { + defer dump.wg.Done() + for { + select { + case <-dump.quit: + log.Info("Dumping slices") + for len(dump.toDump) > 0 { + toDump := <-dump.toDump + dump.writeToFile(toDump) + } + return + case toDump := <-dump.toDump: + dump.writeToFile(toDump) + default: + time.Sleep(time.Nanosecond) + } + } +} + +func (dump *GenerationDumper) Stop() { + dump.quit <- &os.Kill + log.Debug("waiting for generation dumping to complete") + dump.wg.Wait() + + if !dump.keepLogs { + log.Debug("removing generation dump files") + utils.RemoveTempFiles(dump.dir, dump.filenames) + } +} + +func (gens *Generations) Add(lineSlice *LineSlice) { + genSlice, ok := gens.Store[lineSlice.Generation] + if !ok { + genSlice = make([]*LineSlice, 0) + } + numberInGen := len(genSlice) + gens.Store[lineSlice.Generation] = append(genSlice, lineSlice) + gens.Dumper.DumpLines(lineSlice, numberInGen) + + log.Debug("Logs: all generations: ", gens.Store) + + if gens.Latest < lineSlice.Generation { + gens.Latest = lineSlice.Generation + log.Debug("Logs: lastest updated ", gens.Latest) + log.Debug("Logs: should flush ", gens.ShouldFlush()) + } +} + +func (gens *Generations) removeOlderThan(keepGen uint32) { + log.Debug("Removing geners <", keepGen) + for g := range gens.Store { + if g < keepGen { + delete(gens.Store, g) + } + } + gens.Oldest = keepGen +} + +func (gens *Generations) ShouldFlush() bool { + return (gens.Latest-gens.Oldest > keepGenerations && + len(gens.Store) > keepGenerations) +} + +func (gens *Generations) Flush() *LineSlice { + lastGen := gens.Oldest + keepGenerations + log.Debug("Flushing generations <=", lastGen) + + gensToFlush := make([][]*LineSlice, 0) + for index, value := range gens.Store { + if index <= lastGen { + gensToFlush = append(gensToFlush, value) + } + } + result, lastSlice := gens.flush(gensToFlush) + gens.removeOlderThan(lastSlice.Generation) + gens.Store[lastSlice.Generation] = []*LineSlice{lastSlice} + return result +} + +func (gens *Generations) FlushAll() *LineSlice { + log.Debug("Flushing all generations") + gensToFlush := make([][]*LineSlice, 0) + for _, value := range gens.Store { + gensToFlush = append(gensToFlush, value) + } + if len(gensToFlush) == 0 { + return &LineSlice{} + } + result, lastSlice := gens.flush(gensToFlush) + return MakeSliceFromLines(MakeNewCombinedSlice(result.Lines, lastSlice.Lines), lastSlice.Generation) +} + +//nolint:gocritic // don't want to name the return values as they should be built later +func (gens *Generations) flush(generations [][]*LineSlice) (*LineSlice, *LineSlice) { + log.Debug("genrations: ", generations) + sort.Slice(generations, func(i, j int) bool { + return generations[i][0].Generation < generations[j][0].Generation + }) + dedupGen := make([]*LineSlice, len(generations)) + for index, gen := range generations { + dedupGen[index] = dedupGeneration(gen) + } + return DedupLineSlices(dedupGen) +} + +func MakeSliceFromLines(lines []*ProcessedLine, generation uint32) *LineSlice { + if len(lines) == 0 { + return &LineSlice{Generation: generation} + } + return &LineSlice{ + Lines: lines, + start: lines[0].Timestamp, + end: lines[len(lines)-1].Timestamp, + Generation: generation, + } +} diff --git a/collector-framework/pkg/loglines/test_files/all.log b/collector-framework/pkg/loglines/test_files/all.log new file mode 100644 index 00000000..0ec52533 --- /dev/null +++ b/collector-framework/pkg/loglines/test_files/all.log @@ -0,0 +1,1000 @@ +2023-09-12T20:45:30.577901600Z phc2sys[357138.013]: [ptp4l.0.config] CLOCK_REALTIME phc offset -7 s2 freq -10108 delay 505 +2023-09-12T20:45:30.640458927Z phc2sys[357138.075]: [ptp4l.0.config] CLOCK_REALTIME phc offset 0 s2 freq -10103 delay 502 +2023-09-12T20:45:30.703071157Z phc2sys[357138.138]: [ptp4l.0.config] CLOCK_REALTIME phc offset -1 s2 freq -10104 delay 514 +2023-09-12T20:45:30.765716846Z phc2sys[357138.200]: [ptp4l.0.config] CLOCK_REALTIME phc offset -6 s2 freq -10109 delay 503 +2023-09-12T20:45:30.828263160Z phc2sys[357138.263]: [ptp4l.0.config] CLOCK_REALTIME phc offset -1 s2 freq -10106 delay 500 +2023-09-12T20:45:30.890861110Z phc2sys[357138.326]: [ptp4l.0.config] CLOCK_REALTIME phc offset 0 s2 freq -10106 delay 508 +2023-09-12T20:45:30.953432438Z phc2sys[357138.388]: [ptp4l.0.config] CLOCK_REALTIME phc offset -4 s2 freq -10110 delay 503 +2023-09-12T20:45:31.000120915Z ts2phc[357138.435]: [ts2phc.0.config] nmea delay: 120642630 ns +2023-09-12T20:45:31.000120915Z ts2phc[357138.435]: [ts2phc.0.config] ens6f0 extts index 0 at 1694551568.000000000 corr 0 src 1694551568.879384013 diff 0 +2023-09-12T20:45:31.000120915Z ts2phc[357138.435]: [ts2phc.0.config] ens6f0 master offset 0 s2 freq +0 +2023-09-12T20:45:31.000182560Z I0912 20:45:31.000148 161357 event.go:362] dpll State s2, gnss State s2, ts2phc state s2, gm state s2, +2023-09-12T20:45:31.016020965Z phc2sys[357138.451]: [ptp4l.0.config] CLOCK_REALTIME phc offset -4 s2 freq -10111 delay 508 +2023-09-12T20:45:31.078611092Z phc2sys[357138.513]: [ptp4l.0.config] CLOCK_REALTIME phc offset -23 s2 freq -10131 delay 494 +2023-09-12T20:45:31.125529786Z ts2phc[357138.560]: [ts2phc.0.config] nmea sentence: GNRMC,204531.00,A,4233.01593,N,07112.87859,W,0.016,,120923,,,A,V +2023-09-12T20:45:31.125945263Z ts2phc[357138.561]: [ts2phc.0.config] nmea sentence: GNGGA,204531.00,4233.01593,N,07112.87859,W,1,05,1.98,60.2,M,-33.0,M,, +2023-09-12T20:45:31.125945263Z ts2phc[357138.561]: [ts2phc.0.config] nmea sentence: GNGSA,A,3,10,12,23,28,32,,,,,,,,4.25,1.98,3.76,1 +2023-09-12T20:45:31.125945263Z ts2phc[357138.561]: [ts2phc.0.config] nmea sentence: GNGSA,A,3,,,,,,,,,,,,,4.25,1.98,3.76,5 +2023-09-12T20:45:31.125945263Z ts2phc[357138.561]: [ts2phc.0.config] nmea sentence: GPGSV,3,1,10,02,19,296,22,10,63,173,27,12,33,066,22,21,20,287,18,1 +2023-09-12T20:45:31.125945263Z ts2phc[357138.561]: [ts2phc.0.config] nmea sentence: GPGSV,3,2,10,23,26,153,21,24,09,056,17,25,44,120,23,28,49,236,23,1 +2023-09-12T20:45:31.126296251Z ts2phc[357138.561]: [ts2phc.0.config] nmea sentence: GPGSV,3,3,10,31,20,231,21,32,69,326,23,1 +2023-09-12T20:45:31.126296251Z ts2phc[357138.561]: [ts2phc.0.config] nmea sentence: GNGST,204531.00,41,14,11,122,4.9,5.5,11 +2023-09-12T20:45:31.126296251Z ts2phc[357138.561]: [ts2phc.0.config] nmea sentence: GNZDA,204531.00,12,09,2023,00,00 +2023-09-12T20:45:31.126296251Z ts2phc[357138.561]: [ts2phc.0.config] nmea sentence: GNGBS,204531.00,4.9,5.5,10.8,,,,,, +2023-09-12T20:45:31.134443813Z gnss[1694551531]:[ts2phc.0.config] ens6f0 gnss_status 3 offset 5 s2 +2023-09-12T20:45:31.141184660Z phc2sys[357138.576]: [ptp4l.0.config] CLOCK_REALTIME phc offset 3 s2 freq -10112 delay 503 +2023-09-12T20:45:31.171022714Z I0912 20:45:31.171003 161357 dpll.go:467] dpll decision: Status 3, Offset 0, In spec true, Source lost false, On holdover false +2023-09-12T20:45:31.171022714Z I0912 20:45:31.171017 161357 dpll.go:494] dpll is locked, source is not lost, offset is in range, state is DPLL_LOCKED_HO_ACQ or DPLL_HOLDOVER +2023-09-12T20:45:31.171041863Z I0912 20:45:31.171023 161357 dpll.go:540] dpll event sent +2023-09-12T20:45:31.176150794Z dpll[1694551531]:[ts2phc.0.config] ens6f0 frequency_status 3 offset -1 phase_status 3 s2 +2023-09-12T20:45:31.203770247Z phc2sys[357138.639]: [ptp4l.0.config] CLOCK_REALTIME phc offset 5 s2 freq -10109 delay 502 +2023-09-12T20:45:31.266370278Z phc2sys[357138.701]: [ptp4l.0.config] CLOCK_REALTIME phc offset 2 s2 freq -10110 delay 503 +2023-09-12T20:45:31.328940931Z phc2sys[357138.764]: [ptp4l.0.config] CLOCK_REALTIME phc offset 1 s2 freq -10111 delay 503 +2023-09-12T20:45:31.391509847Z phc2sys[357138.826]: [ptp4l.0.config] CLOCK_REALTIME phc offset 3 s2 freq -10109 delay 503 +2023-09-12T20:45:31.454099121Z phc2sys[357138.889]: [ptp4l.0.config] CLOCK_REALTIME phc offset 8 s2 freq -10103 delay 495 +2023-09-12T20:45:31.516671480Z phc2sys[357138.951]: [ptp4l.0.config] CLOCK_REALTIME phc offset 7 s2 freq -10101 delay 502 +2023-09-12T20:45:31.579257823Z phc2sys[357139.014]: [ptp4l.0.config] CLOCK_REALTIME phc offset 7 s2 freq -10099 delay 515 +2023-09-12T20:45:31.641865759Z phc2sys[357139.077]: [ptp4l.0.config] CLOCK_REALTIME phc offset 4 s2 freq -10100 delay 503 +2023-09-12T20:45:31.704457431Z phc2sys[357139.139]: [ptp4l.0.config] CLOCK_REALTIME phc offset 11 s2 freq -10092 delay 503 +2023-09-12T20:45:31.767075268Z phc2sys[357139.202]: [ptp4l.0.config] CLOCK_REALTIME phc offset 8 s2 freq -10092 delay 502 +2023-09-12T20:45:31.829642022Z phc2sys[357139.264]: [ptp4l.0.config] CLOCK_REALTIME phc offset 10 s2 freq -10087 delay 504 +2023-09-12T20:45:31.892289456Z phc2sys[357139.327]: [ptp4l.0.config] CLOCK_REALTIME phc offset 7 s2 freq -10087 delay 509 +2023-09-12T20:45:31.954811569Z phc2sys[357139.390]: [ptp4l.0.config] CLOCK_REALTIME phc offset 5 s2 freq -10087 delay 502 +2023-09-12T20:45:32.000069705Z ts2phc[357139.435]: [ts2phc.0.config] nmea delay: 125470684 ns +2023-09-12T20:45:32.000069705Z ts2phc[357139.435]: [ts2phc.0.config] ens6f0 extts index 0 at 1694551569.000000000 corr 0 src 1694551569.874553125 diff 0 +2023-09-12T20:45:32.000069705Z ts2phc[357139.435]: [ts2phc.0.config] ens6f0 master offset 0 s2 freq +0 +2023-09-12T20:45:32.010207128Z I0912 20:45:32.010186 161357 event.go:362] dpll State s2, gnss State s2, ts2phc state s2, gm state s2, +2023-09-12T20:45:32.017384131Z phc2sys[357139.452]: [ptp4l.0.config] CLOCK_REALTIME phc offset 8 s2 freq -10083 delay 502 +2023-09-12T20:45:32.079960898Z phc2sys[357139.515]: [ptp4l.0.config] CLOCK_REALTIME phc offset 4 s2 freq -10084 delay 509 +2023-09-12T20:45:32.110307879Z ts2phc[357139.545]: [ts2phc.0.config] nmea sentence: GNRMC,204532.00,A,4233.01593,N,07112.87859,W,0.016,,120923,,,A,V +2023-09-12T20:45:32.110307879Z ts2phc[357139.545]: [ts2phc.0.config] nmea sentence: GNGGA,204532.00,4233.01593,N,07112.87859,W,1,05,1.98,60.1,M,-33.0,M,, +2023-09-12T20:45:32.110307879Z ts2phc[357139.545]: [ts2phc.0.config] nmea sentence: GNGSA,A,3,10,12,23,28,32,,,,,,,,4.25,1.98,3.76,1 +2023-09-12T20:45:32.110307879Z ts2phc[357139.545]: [ts2phc.0.config] nmea sentence: GNGSA,A,3,,,,,,,,,,,,,4.25,1.98,3.76,5 +2023-09-12T20:45:32.110350123Z ts2phc[357139.545]: [ts2phc.0.config] nmea sentence: GPGSV,3,1,10,02,19,296,22,10,63,173,26,12,33,066,22,21,20,287,18,1 +2023-09-12T20:45:32.110350123Z ts2phc[357139.545]: [ts2phc.0.config] nmea sentence: GPGSV,3,2,10,23,26,153,20,24,09,056,17,25,44,120,23,28,49,236,23,1 +2023-09-12T20:45:32.110350123Z ts2phc[357139.545]: [ts2phc.0.config] nmea sentence: GPGSV,3,3,10,31,20,231,22,32,69,326,23,1 +2023-09-12T20:45:32.110350123Z ts2phc[357139.545]: [ts2phc.0.config] nmea sentence: GNGST,204532.00,42,14,11,122,4.9,5.5,11 +2023-09-12T20:45:32.110350123Z ts2phc[357139.545]: [ts2phc.0.config] nmea sentence: GNZDA,204532.00,12,09,2023,00,00 +2023-09-12T20:45:32.110444476Z ts2phc[357139.545]: [ts2phc.0.config] nmea sentence: GNGBS,204532.00,4.9,5.5,10.9,,,,,, +2023-09-12T20:45:32.113613408Z gnss[1694551532]:[ts2phc.0.config] ens6f0 gnss_status 3 offset 5 s2 +2023-09-12T20:45:32.142543591Z phc2sys[357139.577]: [ptp4l.0.config] CLOCK_REALTIME phc offset 4 s2 freq -10083 delay 503 +2023-09-12T20:45:32.171600541Z I0912 20:45:32.171580 161357 dpll.go:467] dpll decision: Status 3, Offset 0, In spec true, Source lost false, On holdover false +2023-09-12T20:45:32.171600541Z I0912 20:45:32.171593 161357 dpll.go:494] dpll is locked, source is not lost, offset is in range, state is DPLL_LOCKED_HO_ACQ or DPLL_HOLDOVER +2023-09-12T20:45:32.171627693Z I0912 20:45:32.171599 161357 dpll.go:540] dpll event sent +2023-09-12T20:45:32.175738420Z dpll[1694551532]:[ts2phc.0.config] ens6f0 frequency_status 3 offset -2 phase_status 3 s2 +2023-09-12T20:45:32.205133395Z phc2sys[357139.640]: [ptp4l.0.config] CLOCK_REALTIME phc offset -1 s2 freq -10087 delay 508 +2023-09-12T20:45:32.267705176Z phc2sys[357139.703]: [ptp4l.0.config] CLOCK_REALTIME phc offset 6 s2 freq -10080 delay 501 +2023-09-12T20:45:32.330293761Z phc2sys[357139.765]: [ptp4l.0.config] CLOCK_REALTIME phc offset 2 s2 freq -10082 delay 502 +2023-09-12T20:45:32.392863087Z phc2sys[357139.828]: [ptp4l.0.config] CLOCK_REALTIME phc offset 0 s2 freq -10084 delay 502 +2023-09-12T20:45:32.455435186Z phc2sys[357139.890]: [ptp4l.0.config] CLOCK_REALTIME phc offset -1 s2 freq -10085 delay 503 +2023-09-12T20:45:32.518021421Z phc2sys[357139.953]: [ptp4l.0.config] CLOCK_REALTIME phc offset -4 s2 freq -10088 delay 503 +2023-09-12T20:45:32.580587753Z phc2sys[357140.015]: [ptp4l.0.config] CLOCK_REALTIME phc offset 1 s2 freq -10084 delay 501 +2023-09-12T20:45:32.643158591Z phc2sys[357140.078]: [ptp4l.0.config] CLOCK_REALTIME phc offset -2 s2 freq -10087 delay 503 +2023-09-12T20:45:32.705762952Z phc2sys[357140.141]: [ptp4l.0.config] CLOCK_REALTIME phc offset -4 s2 freq -10089 delay 501 +2023-09-12T20:45:32.768358201Z phc2sys[357140.203]: [ptp4l.0.config] CLOCK_REALTIME phc offset -3 s2 freq -10090 delay 500 +2023-09-12T20:45:32.830948183Z phc2sys[357140.266]: [ptp4l.0.config] CLOCK_REALTIME phc offset -2 s2 freq -10090 delay 504 +2023-09-12T20:45:32.893517560Z phc2sys[357140.328]: [ptp4l.0.config] CLOCK_REALTIME phc offset -5 s2 freq -10093 delay 498 +2023-09-12T20:45:32.956090062Z phc2sys[357140.391]: [ptp4l.0.config] CLOCK_REALTIME phc offset -3 s2 freq -10093 delay 503 +2023-09-12T20:45:33.000066773Z ts2phc[357140.435]: [ts2phc.0.config] nmea delay: 109923033 ns +2023-09-12T20:45:33.000066773Z ts2phc[357140.435]: [ts2phc.0.config] ens6f0 extts index 0 at 1694551570.000000000 corr 0 src 1694551570.890101077 diff 0 +2023-09-12T20:45:33.000117021Z ts2phc[357140.435]: [ts2phc.0.config] ens6f0 master offset 0 s2 freq +0 +2023-09-12T20:45:33.006273907Z I0912 20:45:33.006254 161357 event.go:362] dpll State s2, gnss State s2, ts2phc state s2, gm state s2, +2023-09-12T20:45:33.018661166Z phc2sys[357140.453]: [ptp4l.0.config] CLOCK_REALTIME phc offset -2 s2 freq -10093 delay 503 +2023-09-12T20:45:33.081397193Z phc2sys[357140.516]: [ptp4l.0.config] CLOCK_REALTIME phc offset -9 s2 freq -10100 delay 505 +2023-09-12T20:45:33.135543428Z ts2phc[357140.570]: [ts2phc.0.config] nmea sentence: GNRMC,204533.00,A,4233.01594,N,07112.87859,W,0.016,,120923,,,A,V +2023-09-12T20:45:33.136129930Z ts2phc[357140.571]: [ts2phc.0.config] nmea sentence: GNGGA,204533.00,4233.01594,N,07112.87859,W,1,05,1.98,60.1,M,-33.0,M,, +2023-09-12T20:45:33.136129930Z ts2phc[357140.571]: [ts2phc.0.config] nmea sentence: GNGSA,A,3,10,12,23,28,32,,,,,,,,4.25,1.98,3.76,1 +2023-09-12T20:45:33.136155932Z ts2phc[357140.571]: [ts2phc.0.config] nmea sentence: GNGSA,A,3,,,,,,,,,,,,,4.25,1.98,3.76,5 +2023-09-12T20:45:33.136155932Z ts2phc[357140.571]: [ts2phc.0.config] nmea sentence: GPGSV,3,1,10,02,19,296,22,10,63,173,26,12,33,066,22,21,20,287,18,1 +2023-09-12T20:45:33.136155932Z ts2phc[357140.571]: [ts2phc.0.config] nmea sentence: GPGSV,3,2,10,23,26,153,20,24,09,056,16,25,44,120,22,28,49,236,23,1 +2023-09-12T20:45:33.136155932Z ts2phc[357140.571]: [ts2phc.0.config] nmea sentence: GPGSV,3,3,10,31,20,231,21,32,69,326,24,1 +2023-09-12T20:45:33.136155932Z ts2phc[357140.571]: [ts2phc.0.config] nmea sentence: GNGST,204533.00,41,14,11,122,4.9,5.5,11 +2023-09-12T20:45:33.136155932Z ts2phc[357140.571]: [ts2phc.0.config] nmea sentence: GNZDA,204533.00,12,09,2023,00,00 +2023-09-12T20:45:33.136155932Z ts2phc[357140.571]: [ts2phc.0.config] nmea sentence: GNGBS,204533.00,4.9,5.5,10.9,,,,,, +2023-09-12T20:45:33.140295785Z gnss[1694551533]:[ts2phc.0.config] ens6f0 gnss_status 3 offset 5 s2 +2023-09-12T20:45:33.143842376Z phc2sys[357140.579]: [ptp4l.0.config] CLOCK_REALTIME phc offset -9 s2 freq -10103 delay 503 +2023-09-12T20:45:33.171769600Z I0912 20:45:33.171745 161357 dpll.go:467] dpll decision: Status 3, Offset 0, In spec true, Source lost false, On holdover false +2023-09-12T20:45:33.171769600Z I0912 20:45:33.171761 161357 dpll.go:494] dpll is locked, source is not lost, offset is in range, state is DPLL_LOCKED_HO_ACQ or DPLL_HOLDOVER +2023-09-12T20:45:33.171801265Z I0912 20:45:33.171769 161357 dpll.go:540] dpll event sent +2023-09-12T20:45:33.182006993Z dpll[1694551533]:[ts2phc.0.config] ens6f0 frequency_status 3 offset 2 phase_status 3 s2 +2023-09-12T20:45:33.206420896Z phc2sys[357140.641]: [ptp4l.0.config] CLOCK_REALTIME phc offset -4 s2 freq -10101 delay 498 +2023-09-12T20:45:33.269019066Z phc2sys[357140.704]: [ptp4l.0.config] CLOCK_REALTIME phc offset -8 s2 freq -10106 delay 503 +2023-09-12T20:45:33.331608834Z phc2sys[357140.766]: [ptp4l.0.config] CLOCK_REALTIME phc offset -6 s2 freq -10106 delay 511 +2023-09-12T20:45:33.394206626Z phc2sys[357140.829]: [ptp4l.0.config] CLOCK_REALTIME phc offset -6 s2 freq -10108 delay 504 +2023-09-12T20:45:33.456767387Z phc2sys[357140.892]: [ptp4l.0.config] CLOCK_REALTIME phc offset 1 s2 freq -10103 delay 502 +2023-09-12T20:45:33.519342034Z phc2sys[357140.954]: [ptp4l.0.config] CLOCK_REALTIME phc offset -2 s2 freq -10105 delay 503 +2023-09-12T20:45:33.582005534Z phc2sys[357141.017]: [ptp4l.0.config] CLOCK_REALTIME phc offset -3 s2 freq -10107 delay 507 +2023-09-12T20:45:33.644532313Z phc2sys[357141.079]: [ptp4l.0.config] CLOCK_REALTIME phc offset -5 s2 freq -10110 delay 514 +2023-09-12T20:45:33.707136459Z phc2sys[357141.142]: [ptp4l.0.config] CLOCK_REALTIME phc offset -4 s2 freq -10110 delay 504 +2023-09-12T20:45:33.769706208Z phc2sys[357141.204]: [ptp4l.0.config] CLOCK_REALTIME phc offset 2 s2 freq -10106 delay 503 +2023-09-12T20:45:33.832297265Z phc2sys[357141.267]: [ptp4l.0.config] CLOCK_REALTIME phc offset 3 s2 freq -10104 delay 502 +2023-09-12T20:45:33.894884259Z phc2sys[357141.330]: [ptp4l.0.config] CLOCK_REALTIME phc offset 13 s2 freq -10093 delay 473 +2023-09-12T20:45:33.957464312Z phc2sys[357141.392]: [ptp4l.0.config] CLOCK_REALTIME phc offset -2 s2 freq -10104 delay 502 +2023-09-12T20:45:34.000090010Z ts2phc[357141.435]: [ts2phc.0.config] nmea delay: 135358057 ns +2023-09-12T20:45:34.000121440Z ts2phc[357141.435]: [ts2phc.0.config] ens6f0 extts index 0 at 1694551571.000000000 corr 0 src 1694551571.864665739 diff 0 +2023-09-12T20:45:34.000121440Z ts2phc[357141.435]: [ts2phc.0.config] ens6f0 master offset 0 s2 freq +0 +2023-09-12T20:45:34.003349720Z I0912 20:45:34.003330 161357 event.go:362] dpll State s2, gnss State s2, ts2phc state s2, gm state s2, +2023-09-12T20:45:34.020041367Z phc2sys[357141.455]: [ptp4l.0.config] CLOCK_REALTIME phc offset -3 s2 freq -10106 delay 502 +2023-09-12T20:45:34.082613037Z phc2sys[357141.517]: [ptp4l.0.config] CLOCK_REALTIME phc offset 0 s2 freq -10104 delay 503 +2023-09-12T20:45:34.145202981Z phc2sys[357141.580]: [ptp4l.0.config] CLOCK_REALTIME phc offset -3 s2 freq -10107 delay 512 +2023-09-12T20:45:34.169154998Z ts2phc[357141.604]: [ts2phc.0.config] nmea sentence: GNRMC,204534.00,A,4233.01594,N,07112.87860,W,0.016,,120923,,,A,V +2023-09-12T20:45:34.169477845Z ts2phc[357141.604]: [ts2phc.0.config] nmea sentence: GNGGA,204534.00,4233.01594,N,07112.87860,W,1,05,1.98,60.1,M,-33.0,M,, +2023-09-12T20:45:34.169517522Z ts2phc[357141.604]: [ts2phc.0.config] nmea sentence: GNGSA,A,3,10,12,23,28,32,,,,,,,,4.25,1.98,3.76,1 +2023-09-12T20:45:34.169562899Z ts2phc[357141.604]: [ts2phc.0.config] nmea sentence: GNGSA,A,3,,,,,,,,,,,,,4.25,1.98,3.76,5 +2023-09-12T20:45:34.169588682Z ts2phc[357141.604]: [ts2phc.0.config] nmea sentence: GPGSV,3,1,10,02,19,296,22,10,63,173,26,12,33,066,22,21,20,287,17,1 +2023-09-12T20:45:34.169613558Z ts2phc[357141.604]: [ts2phc.0.config] nmea sentence: GPGSV,3,2,10,23,26,153,20,24,09,056,16,25,44,120,22,28,49,236,23,1 +2023-09-12T20:45:34.169660915Z ts2phc[357141.604]: [ts2phc.0.config] nmea sentence: GPGSV,3,3,10,31,20,231,22,32,69,326,23,1 +2023-09-12T20:45:34.169697712Z ts2phc[357141.604]: [ts2phc.0.config] nmea sentence: GNGST,204534.00,42,14,11,122,4.9,5.5,11 +2023-09-12T20:45:34.169750280Z ts2phc[357141.604]: [ts2phc.0.config] nmea sentence: GNZDA,204534.00,12,09,2023,00,00 +2023-09-12T20:45:34.169773514Z ts2phc[357141.604]: [ts2phc.0.config] nmea sentence: GNGBS,204534.00,4.9,5.5,10.9,,,,,, +2023-09-12T20:45:34.171809787Z I0912 20:45:34.171791 161357 dpll.go:467] dpll decision: Status 3, Offset 0, In spec true, Source lost false, On holdover false +2023-09-12T20:45:34.171809787Z I0912 20:45:34.171804 161357 dpll.go:494] dpll is locked, source is not lost, offset is in range, state is DPLL_LOCKED_HO_ACQ or DPLL_HOLDOVER +2023-09-12T20:45:34.171832354Z I0912 20:45:34.171810 161357 dpll.go:540] dpll event sent +2023-09-12T20:45:34.177957620Z gnss[1694551534]:[ts2phc.0.config] ens6f0 gnss_status 3 offset 5 s2 +2023-09-12T20:45:34.178011307Z dpll[1694551534]:[ts2phc.0.config] ens6f0 frequency_status 3 offset 1 phase_status 3 s2 +2023-09-12T20:45:34.207782660Z phc2sys[357141.643]: [ptp4l.0.config] CLOCK_REALTIME phc offset 0 s2 freq -10105 delay 499 +2023-09-12T20:45:34.270376859Z phc2sys[357141.705]: [ptp4l.0.config] CLOCK_REALTIME phc offset -3 s2 freq -10108 delay 502 +2023-09-12T20:45:34.332942014Z phc2sys[357141.768]: [ptp4l.0.config] CLOCK_REALTIME phc offset 2 s2 freq -10104 delay 502 +2023-09-12T20:45:34.395557153Z phc2sys[357141.830]: [ptp4l.0.config] CLOCK_REALTIME phc offset -1 s2 freq -10106 delay 503 +2023-09-12T20:45:34.458130419Z phc2sys[357141.893]: [ptp4l.0.config] CLOCK_REALTIME phc offset 2 s2 freq -10103 delay 503 +2023-09-12T20:45:34.520723811Z phc2sys[357141.956]: [ptp4l.0.config] CLOCK_REALTIME phc offset 1 s2 freq -10104 delay 497 +2023-09-12T20:45:34.583291578Z phc2sys[357142.018]: [ptp4l.0.config] CLOCK_REALTIME phc offset -1 s2 freq -10105 delay 503 +2023-09-12T20:45:34.645869330Z phc2sys[357142.081]: [ptp4l.0.config] CLOCK_REALTIME phc offset 5 s2 freq -10100 delay 503 +2023-09-12T20:45:34.708436564Z phc2sys[357142.143]: [ptp4l.0.config] CLOCK_REALTIME phc offset 0 s2 freq -10103 delay 503 +2023-09-12T20:45:34.771032444Z phc2sys[357142.206]: [ptp4l.0.config] CLOCK_REALTIME phc offset 2 s2 freq -10101 delay 508 +2023-09-12T20:45:34.833607345Z phc2sys[357142.268]: [ptp4l.0.config] CLOCK_REALTIME phc offset 6 s2 freq -10097 delay 502 +2023-09-12T20:45:34.896191738Z phc2sys[357142.331]: [ptp4l.0.config] CLOCK_REALTIME phc offset 2 s2 freq -10099 delay 501 +2023-09-12T20:45:34.958764463Z phc2sys[357142.394]: [ptp4l.0.config] CLOCK_REALTIME phc offset 1 s2 freq -10099 delay 510 +2023-09-12T20:45:35.000080178Z ts2phc[357142.435]: [ts2phc.0.config] nmea delay: 168953517 ns +2023-09-12T20:45:35.000080178Z ts2phc[357142.435]: [ts2phc.0.config] ens6f0 extts index 0 at 1694551572.000000000 corr 0 src 1694551572.831080776 diff 0 +2023-09-12T20:45:35.000131003Z ts2phc[357142.435]: [ts2phc.0.config] ens6f0 master offset 0 s2 freq +0 +2023-09-12T20:45:35.009294566Z I0912 20:45:35.009272 161357 event.go:362] dpll State s2, gnss State s2, ts2phc state s2, gm state s2, +2023-09-12T20:45:35.021354636Z phc2sys[357142.456]: [ptp4l.0.config] CLOCK_REALTIME phc offset 1 s2 freq -10099 delay 509 +2023-09-12T20:45:35.083991190Z phc2sys[357142.519]: [ptp4l.0.config] CLOCK_REALTIME phc offset 1 s2 freq -10099 delay 512 +2023-09-12T20:45:35.118756314Z ts2phc[357142.553]: [ts2phc.0.config] nmea sentence: GNRMC,204535.00,A,4233.01593,N,07112.87861,W,0.016,,120923,,,A,V +2023-09-12T20:45:35.119280658Z ts2phc[357142.554]: [ts2phc.0.config] nmea sentence: GNGGA,204535.00,4233.01593,N,07112.87861,W,1,05,1.98,60.1,M,-33.0,M,, +2023-09-12T20:45:35.119336499Z ts2phc[357142.554]: [ts2phc.0.config] nmea sentence: GNGSA,A,3,10,12,23,28,32,,,,,,,,4.25,1.98,3.76,1 +2023-09-12T20:45:35.119374475Z ts2phc[357142.554]: [ts2phc.0.config] nmea sentence: GNGSA,A,3,,,,,,,,,,,,,4.25,1.98,3.76,5 +2023-09-12T20:45:35.119401712Z ts2phc[357142.554]: [ts2phc.0.config] nmea sentence: GPGSV,3,1,10,02,19,296,22,10,63,173,26,12,33,066,22,21,20,287,18,1 +2023-09-12T20:45:35.119428485Z ts2phc[357142.554]: [ts2phc.0.config] nmea sentence: GPGSV,3,2,10,23,25,153,20,24,09,056,16,25,44,120,22,28,49,236,23,1 +2023-09-12T20:45:35.119453466Z ts2phc[357142.554]: [ts2phc.0.config] nmea sentence: GPGSV,3,3,10,31,20,231,21,32,69,326,23,1 +2023-09-12T20:45:35.119478714Z ts2phc[357142.554]: [ts2phc.0.config] nmea sentence: GNGST,204535.00,42,14,11,122,4.9,5.5,11 +2023-09-12T20:45:35.119505502Z ts2phc[357142.554]: [ts2phc.0.config] nmea sentence: GNZDA,204535.00,12,09,2023,00,00 +2023-09-12T20:45:35.119538254Z ts2phc[357142.554]: [ts2phc.0.config] nmea sentence: GNGBS,204535.00,4.9,5.5,10.9,,,,,, +2023-09-12T20:45:35.121653241Z gnss[1694551535]:[ts2phc.0.config] ens6f0 gnss_status 3 offset 5 s2 +2023-09-12T20:45:35.146602065Z phc2sys[357142.581]: [ptp4l.0.config] CLOCK_REALTIME phc offset 1 s2 freq -10098 delay 506 +2023-09-12T20:45:35.171473219Z I0912 20:45:35.171442 161357 dpll.go:467] dpll decision: Status 3, Offset 0, In spec true, Source lost false, On holdover false +2023-09-12T20:45:35.172176209Z I0912 20:45:35.171825 161357 dpll.go:494] dpll is locked, source is not lost, offset is in range, state is DPLL_LOCKED_HO_ACQ or DPLL_HOLDOVER +2023-09-12T20:45:35.172176209Z I0912 20:45:35.171837 161357 dpll.go:540] dpll event sent +2023-09-12T20:45:35.175044031Z dpll[1694551535]:[ts2phc.0.config] ens6f0 frequency_status 3 offset 1 phase_status 3 s2 +2023-09-12T20:45:35.209177846Z phc2sys[357142.644]: [ptp4l.0.config] CLOCK_REALTIME phc offset 1 s2 freq -10098 delay 500 +2023-09-12T20:45:35.271761470Z phc2sys[357142.707]: [ptp4l.0.config] CLOCK_REALTIME phc offset -3 s2 freq -10102 delay 503 +2023-09-12T20:45:35.334346274Z phc2sys[357142.769]: [ptp4l.0.config] CLOCK_REALTIME phc offset 1 s2 freq -10099 delay 497 +2023-09-12T20:45:35.396915142Z phc2sys[357142.832]: [ptp4l.0.config] CLOCK_REALTIME phc offset 0 s2 freq -10099 delay 499 +2023-09-12T20:45:35.459494833Z phc2sys[357142.894]: [ptp4l.0.config] CLOCK_REALTIME phc offset 3 s2 freq -10096 delay 504 +2023-09-12T20:45:35.522077931Z phc2sys[357142.957]: [ptp4l.0.config] CLOCK_REALTIME phc offset 2 s2 freq -10096 delay 506 +2023-09-12T20:45:35.584725802Z phc2sys[357143.019]: [ptp4l.0.config] CLOCK_REALTIME phc offset 0 s2 freq -10098 delay 507 +2023-09-12T20:45:35.647372311Z phc2sys[357143.082]: [ptp4l.0.config] CLOCK_REALTIME phc offset 2 s2 freq -10096 delay 510 +2023-09-12T20:45:35.709913243Z phc2sys[357143.145]: [ptp4l.0.config] CLOCK_REALTIME phc offset 0 s2 freq -10097 delay 502 +2023-09-12T20:45:35.772483372Z phc2sys[357143.207]: [ptp4l.0.config] CLOCK_REALTIME phc offset 17 s2 freq -10080 delay 485 +2023-09-12T20:45:35.835066895Z phc2sys[357143.270]: [ptp4l.0.config] CLOCK_REALTIME phc offset -4 s2 freq -10096 delay 503 +2023-09-12T20:45:35.897636519Z phc2sys[357143.332]: [ptp4l.0.config] CLOCK_REALTIME phc offset -3 s2 freq -10096 delay 502 +2023-09-12T20:45:35.960209495Z phc2sys[357143.395]: [ptp4l.0.config] CLOCK_REALTIME phc offset -4 s2 freq -10098 delay 503 +2023-09-12T20:45:36.000167253Z ts2phc[357143.435]: [ts2phc.0.config] nmea delay: 118635224 ns +2023-09-12T20:45:36.000167253Z ts2phc[357143.435]: [ts2phc.0.config] ens6f0 extts index 0 at 1694551573.000000000 corr 0 src 1694551573.881389766 diff 0 +2023-09-12T20:45:36.000227050Z ts2phc[357143.435]: [ts2phc.0.config] ens6f0 master offset 0 s2 freq +0 +2023-09-12T20:45:36.000335284Z I0912 20:45:36.000313 161357 event.go:362] dpll State s2, gnss State s2, ts2phc state s2, gm state s2, +2023-09-12T20:45:36.022786353Z phc2sys[357143.458]: [ptp4l.0.config] CLOCK_REALTIME phc offset 1 s2 freq -10094 delay 501 +2023-09-12T20:45:36.085369983Z phc2sys[357143.520]: [ptp4l.0.config] CLOCK_REALTIME phc offset 5 s2 freq -10090 delay 502 +2023-09-12T20:45:36.109479963Z ts2phc[357143.544]: [ts2phc.0.config] nmea sentence: GNRMC,204536.00,A,4233.01594,N,07112.87862,W,0.016,,120923,,,A,V +2023-09-12T20:45:36.109970965Z ts2phc[357143.545]: [ts2phc.0.config] nmea sentence: GNGGA,204536.00,4233.01594,N,07112.87862,W,1,05,1.98,60.1,M,-33.0,M,, +2023-09-12T20:45:36.110021129Z ts2phc[357143.545]: [ts2phc.0.config] nmea sentence: GNGSA,A,3,10,12,23,28,32,,,,,,,,4.25,1.98,3.76,1 +2023-09-12T20:45:36.110064001Z ts2phc[357143.545]: [ts2phc.0.config] nmea sentence: GNGSA,A,3,,,,,,,,,,,,,4.25,1.98,3.76,5 +2023-09-12T20:45:36.110091689Z ts2phc[357143.545]: [ts2phc.0.config] nmea sentence: GPGSV,3,1,10,02,19,296,22,10,63,173,26,12,33,066,22,21,20,287,18,1 +2023-09-12T20:45:36.110122253Z ts2phc[357143.545]: [ts2phc.0.config] nmea sentence: GPGSV,3,2,10,23,25,153,20,24,09,056,17,25,44,120,22,28,49,236,23,1 +2023-09-12T20:45:36.110122253Z ts2phc[357143.545]: [ts2phc.0.config] nmea sentence: GPGSV,3,3,10,31,20,231,21,32,69,326,23,1 +2023-09-12T20:45:36.110122253Z ts2phc[357143.545]: [ts2phc.0.config] nmea sentence: GNGST,204536.00,42,14,11,122,4.9,5.5,11 +2023-09-12T20:45:36.110122253Z ts2phc[357143.545]: [ts2phc.0.config] nmea sentence: GNZDA,204536.00,12,09,2023,00,00 +2023-09-12T20:45:36.110122253Z ts2phc[357143.545]: [ts2phc.0.config] nmea sentence: GNGBS,204536.00,4.9,5.5,10.9,,,,,, +2023-09-12T20:45:36.113227594Z gnss[1694551536]:[ts2phc.0.config] ens6f0 gnss_status 3 offset 5 s2 +2023-09-12T20:45:36.147947026Z phc2sys[357143.583]: [ptp4l.0.config] CLOCK_REALTIME phc offset 1 s2 freq -10093 delay 496 +2023-09-12T20:45:36.171617494Z I0912 20:45:36.171597 161357 dpll.go:467] dpll decision: Status 3, Offset 0, In spec true, Source lost false, On holdover false +2023-09-12T20:45:36.171617494Z I0912 20:45:36.171612 161357 dpll.go:494] dpll is locked, source is not lost, offset is in range, state is DPLL_LOCKED_HO_ACQ or DPLL_HOLDOVER +2023-09-12T20:45:36.171645729Z I0912 20:45:36.171619 161357 dpll.go:540] dpll event sent +2023-09-12T20:45:36.174756847Z dpll[1694551536]:[ts2phc.0.config] ens6f0 frequency_status 3 offset 0 phase_status 3 s2 +2023-09-12T20:45:36.210542813Z phc2sys[357143.645]: [ptp4l.0.config] CLOCK_REALTIME phc offset -4 s2 freq -10097 delay 503 +2023-09-12T20:45:36.273159360Z phc2sys[357143.708]: [ptp4l.0.config] CLOCK_REALTIME phc offset -4 s2 freq -10098 delay 502 +2023-09-12T20:45:36.335719267Z phc2sys[357143.771]: [ptp4l.0.config] CLOCK_REALTIME phc offset 2 s2 freq -10094 delay 500 +2023-09-12T20:45:36.398288003Z phc2sys[357143.833]: [ptp4l.0.config] CLOCK_REALTIME phc offset 1 s2 freq -10094 delay 503 +2023-09-12T20:45:36.460876865Z phc2sys[357143.896]: [ptp4l.0.config] CLOCK_REALTIME phc offset -5 s2 freq -10100 delay 503 +2023-09-12T20:45:36.523446339Z phc2sys[357143.958]: [ptp4l.0.config] CLOCK_REALTIME phc offset 1 s2 freq -10095 delay 503 +2023-09-12T20:45:36.586025794Z phc2sys[357144.021]: [ptp4l.0.config] CLOCK_REALTIME phc offset 4 s2 freq -10092 delay 503 +2023-09-12T20:45:36.649121533Z phc2sys[357144.083]: [ptp4l.0.config] CLOCK_REALTIME phc offset -1 s2 freq -10096 delay 507 +2023-09-12T20:45:36.711737535Z phc2sys[357144.146]: [ptp4l.0.config] CLOCK_REALTIME phc offset -3 s2 freq -10098 delay 504 +2023-09-12T20:45:36.773885533Z phc2sys[357144.209]: [ptp4l.0.config] CLOCK_REALTIME phc offset -2 s2 freq -10098 delay 502 +2023-09-12T20:45:36.836557741Z phc2sys[357144.271]: [ptp4l.0.config] CLOCK_REALTIME phc offset -3 s2 freq -10100 delay 509 +2023-09-12T20:45:36.899100958Z phc2sys[357144.334]: [ptp4l.0.config] CLOCK_REALTIME phc offset -7 s2 freq -10104 delay 503 +2023-09-12T20:45:36.961699539Z phc2sys[357144.396]: [ptp4l.0.config] CLOCK_REALTIME phc offset 1 s2 freq -10099 delay 502 +2023-09-12T20:45:37.000080615Z ts2phc[357144.435]: [ts2phc.0.config] nmea delay: 109429817 ns +2023-09-12T20:45:37.000080615Z ts2phc[357144.435]: [ts2phc.0.config] ens6f0 extts index 0 at 1694551574.000000000 corr 0 src 1694551574.890597428 diff 0 +2023-09-12T20:45:37.000080615Z ts2phc[357144.435]: [ts2phc.0.config] ens6f0 master offset 0 s2 freq +0 +2023-09-12T20:45:37.008282923Z I0912 20:45:37.008260 161357 event.go:362] dpll State s2, gnss State s2, ts2phc state s2, gm state s2, +2023-09-12T20:45:37.024281809Z phc2sys[357144.459]: [ptp4l.0.config] CLOCK_REALTIME phc offset -3 s2 freq -10102 delay 508 +2023-09-12T20:45:37.086889064Z phc2sys[357144.522]: [ptp4l.0.config] CLOCK_REALTIME phc offset -1 s2 freq -10101 delay 494 +2023-09-12T20:45:37.132241966Z ts2phc[357144.567]: [ts2phc.0.config] nmea sentence: GNRMC,204537.00,A,4233.01595,N,07112.87862,W,0.016,,120923,,,A,V +2023-09-12T20:45:37.132526493Z ts2phc[357144.567]: [ts2phc.0.config] nmea sentence: GNGGA,204537.00,4233.01595,N,07112.87862,W,1,05,1.98,60.1,M,-33.0,M,, +2023-09-12T20:45:37.132526493Z ts2phc[357144.567]: [ts2phc.0.config] nmea sentence: GNGSA,A,3,10,12,23,28,32,,,,,,,,4.25,1.98,3.76,1 +2023-09-12T20:45:37.132539884Z ts2phc[357144.567]: [ts2phc.0.config] nmea sentence: GNGSA,A,3,,,,,,,,,,,,,4.25,1.98,3.76,5 +2023-09-12T20:45:37.132539884Z ts2phc[357144.567]: [ts2phc.0.config] nmea sentence: GPGSV,3,1,10,02,19,296,22,10,63,173,26,12,33,066,22,21,20,287,18,1 +2023-09-12T20:45:37.132539884Z ts2phc[357144.567]: [ts2phc.0.config] nmea sentence: GPGSV,3,2,10,23,25,153,21,24,09,056,17,25,45,120,22,28,49,236,23,1 +2023-09-12T20:45:37.132539884Z ts2phc[357144.567]: [ts2phc.0.config] nmea sentence: GPGSV,3,3,10,31,20,231,21,32,69,326,23,1 +2023-09-12T20:45:37.132613130Z ts2phc[357144.567]: [ts2phc.0.config] nmea sentence: GNGST,204537.00,41,14,11,122,4.9,5.5,11 +2023-09-12T20:45:37.132623547Z ts2phc[357144.567]: [ts2phc.0.config] nmea sentence: GNZDA,204537.00,12,09,2023,00,00 +2023-09-12T20:45:37.132706366Z ts2phc[357144.567]: [ts2phc.0.config] nmea sentence: GNGBS,204537.00,4.9,5.5,10.9,,,,,, +2023-09-12T20:45:37.141894002Z gnss[1694551537]:[ts2phc.0.config] ens6f0 gnss_status 3 offset 5 s2 +2023-09-12T20:45:37.149513013Z phc2sys[357144.584]: [ptp4l.0.config] CLOCK_REALTIME phc offset -1 s2 freq -10101 delay 503 +2023-09-12T20:45:37.171495948Z I0912 20:45:37.171475 161357 dpll.go:467] dpll decision: Status 3, Offset 0, In spec true, Source lost false, On holdover false +2023-09-12T20:45:37.171495948Z I0912 20:45:37.171490 161357 dpll.go:494] dpll is locked, source is not lost, offset is in range, state is DPLL_LOCKED_HO_ACQ or DPLL_HOLDOVER +2023-09-12T20:45:37.171522570Z I0912 20:45:37.171496 161357 dpll.go:540] dpll event sent +2023-09-12T20:45:37.173619017Z dpll[1694551537]:[ts2phc.0.config] ens6f0 frequency_status 3 offset -2 phase_status 3 s2 +2023-09-12T20:45:37.212089603Z phc2sys[357144.647]: [ptp4l.0.config] CLOCK_REALTIME phc offset 0 s2 freq -10101 delay 503 +2023-09-12T20:45:37.274643473Z phc2sys[357144.709]: [ptp4l.0.config] CLOCK_REALTIME phc offset -2 s2 freq -10103 delay 502 +2023-09-12T20:45:37.337220863Z phc2sys[357144.772]: [ptp4l.0.config] CLOCK_REALTIME phc offset -6 s2 freq -10107 delay 503 +2023-09-12T20:45:37.399802161Z phc2sys[357144.835]: [ptp4l.0.config] CLOCK_REALTIME phc offset -1 s2 freq -10104 delay 503 +2023-09-12T20:45:37.462371616Z phc2sys[357144.897]: [ptp4l.0.config] CLOCK_REALTIME phc offset -2 s2 freq -10105 delay 503 +2023-09-12T20:45:37.525006437Z phc2sys[357144.960]: [ptp4l.0.config] CLOCK_REALTIME phc offset -4 s2 freq -10108 delay 506 +2023-09-12T20:45:37.587548191Z phc2sys[357145.022]: [ptp4l.0.config] CLOCK_REALTIME phc offset 2 s2 freq -10103 delay 502 +2023-09-12T20:45:37.650226268Z phc2sys[357145.085]: [ptp4l.0.config] CLOCK_REALTIME phc offset 1 s2 freq -10104 delay 510 +2023-09-12T20:45:37.712784760Z phc2sys[357145.148]: [ptp4l.0.config] CLOCK_REALTIME phc offset 0 s2 freq -10104 delay 509 +2023-09-12T20:45:37.775388214Z phc2sys[357145.210]: [ptp4l.0.config] CLOCK_REALTIME phc offset -3 s2 freq -10107 delay 503 +2023-09-12T20:45:37.837974109Z phc2sys[357145.273]: [ptp4l.0.config] CLOCK_REALTIME phc offset -1 s2 freq -10106 delay 503 +2023-09-12T20:45:37.900544681Z phc2sys[357145.335]: [ptp4l.0.config] CLOCK_REALTIME phc offset -2 s2 freq -10108 delay 503 +2023-09-12T20:45:37.963182916Z phc2sys[357145.398]: [ptp4l.0.config] CLOCK_REALTIME phc offset -1 s2 freq -10107 delay 502 +2023-09-12T20:45:38.000072139Z ts2phc[357145.435]: [ts2phc.0.config] nmea delay: 132195182 ns +2023-09-12T20:45:38.000129282Z ts2phc[357145.435]: [ts2phc.0.config] ens6f0 extts index 0 at 1694551575.000000000 corr 0 src 1694551575.867828231 diff 0 +2023-09-12T20:45:38.000158486Z ts2phc[357145.435]: [ts2phc.0.config] ens6f0 master offset 0 s2 freq +0 +2023-09-12T20:45:38.006330602Z I0912 20:45:38.006286 161357 event.go:362] dpll State s2, gnss State s2, ts2phc state s2, gm state s2, +2023-09-12T20:45:38.025738317Z phc2sys[357145.461]: [ptp4l.0.config] CLOCK_REALTIME phc offset 6 s2 freq -10100 delay 502 +2023-09-12T20:45:38.088382717Z phc2sys[357145.523]: [ptp4l.0.config] CLOCK_REALTIME phc offset 4 s2 freq -10101 delay 507 +2023-09-12T20:45:38.110200684Z ts2phc[357145.545]: [ts2phc.0.config] nmea sentence: GNRMC,204538.00,A,4233.01594,N,07112.87864,W,0.016,,120923,,,A,V +2023-09-12T20:45:38.110555418Z ts2phc[357145.545]: [ts2phc.0.config] nmea sentence: GNGGA,204538.00,4233.01594,N,07112.87864,W,1,05,1.98,60.0,M,-33.0,M,, +2023-09-12T20:45:38.110593995Z ts2phc[357145.545]: [ts2phc.0.config] nmea sentence: GNGSA,A,3,10,12,23,28,32,,,,,,,,4.25,1.98,3.76,1 +2023-09-12T20:45:38.110634754Z ts2phc[357145.545]: [ts2phc.0.config] nmea sentence: GNGSA,A,3,,,,,,,,,,,,,4.25,1.98,3.76,5 +2023-09-12T20:45:38.110677673Z ts2phc[357145.545]: [ts2phc.0.config] nmea sentence: GPGSV,3,1,10,02,19,296,21,10,63,173,27,12,33,066,22,21,20,287,19,1 +2023-09-12T20:45:38.110720368Z ts2phc[357145.545]: [ts2phc.0.config] nmea sentence: GPGSV,3,2,10,23,25,153,20,24,09,056,17,25,45,120,22,28,49,236,22,1 +2023-09-12T20:45:38.110783259Z ts2phc[357145.545]: [ts2phc.0.config] nmea sentence: GPGSV,3,3,10,31,20,231,21,32,69,326,24,1 +2023-09-12T20:45:38.110811358Z ts2phc[357145.545]: [ts2phc.0.config] nmea sentence: GNGST,204538.00,41,14,11,122,4.9,5.5,11 +2023-09-12T20:45:38.110842017Z ts2phc[357145.545]: [ts2phc.0.config] nmea sentence: GNZDA,204538.00,12,09,2023,00,00 +2023-09-12T20:45:38.110871241Z ts2phc[357145.546]: [ts2phc.0.config] nmea sentence: GNGBS,204538.00,4.9,5.5,10.9,,,,,, +2023-09-12T20:45:38.119070599Z gnss[1694551538]:[ts2phc.0.config] ens6f0 gnss_status 3 offset 5 s2 +2023-09-12T20:45:38.150878907Z phc2sys[357145.586]: [ptp4l.0.config] CLOCK_REALTIME phc offset 18 s2 freq -10085 delay 474 +2023-09-12T20:45:38.171561827Z I0912 20:45:38.171542 161357 dpll.go:467] dpll decision: Status 3, Offset 0, In spec true, Source lost false, On holdover false +2023-09-12T20:45:38.171561827Z I0912 20:45:38.171556 161357 dpll.go:494] dpll is locked, source is not lost, offset is in range, state is DPLL_LOCKED_HO_ACQ or DPLL_HOLDOVER +2023-09-12T20:45:38.171587136Z I0912 20:45:38.171561 161357 dpll.go:540] dpll event sent +2023-09-12T20:45:38.180798911Z dpll[1694551538]:[ts2phc.0.config] ens6f0 frequency_status 3 offset -3 phase_status 3 s2 +2023-09-12T20:45:38.213458729Z phc2sys[357145.648]: [ptp4l.0.config] CLOCK_REALTIME phc offset 4 s2 freq -10094 delay 514 +2023-09-12T20:45:38.276038443Z phc2sys[357145.711]: [ptp4l.0.config] CLOCK_REALTIME phc offset 2 s2 freq -10095 delay 501 +2023-09-12T20:45:38.338658515Z phc2sys[357145.773]: [ptp4l.0.config] CLOCK_REALTIME phc offset 5 s2 freq -10091 delay 504 +2023-09-12T20:45:38.401242480Z phc2sys[357145.836]: [ptp4l.0.config] CLOCK_REALTIME phc offset 0 s2 freq -10095 delay 502 +2023-09-12T20:45:38.463821581Z phc2sys[357145.899]: [ptp4l.0.config] CLOCK_REALTIME phc offset 1 s2 freq -10094 delay 504 +2023-09-12T20:45:38.526397624Z phc2sys[357145.961]: [ptp4l.0.config] CLOCK_REALTIME phc offset -2 s2 freq -10096 delay 503 +2023-09-12T20:45:38.589000355Z phc2sys[357146.024]: [ptp4l.0.config] CLOCK_REALTIME phc offset 4 s2 freq -10091 delay 500 +2023-09-12T20:45:38.651599629Z phc2sys[357146.086]: [ptp4l.0.config] CLOCK_REALTIME phc offset 2 s2 freq -10092 delay 507 +2023-09-12T20:45:38.714160664Z phc2sys[357146.149]: [ptp4l.0.config] CLOCK_REALTIME phc offset 6 s2 freq -10087 delay 503 +2023-09-12T20:45:38.776774925Z phc2sys[357146.212]: [ptp4l.0.config] CLOCK_REALTIME phc offset 7 s2 freq -10084 delay 502 +2023-09-12T20:45:38.839325036Z phc2sys[357146.274]: [ptp4l.0.config] CLOCK_REALTIME phc offset 0 s2 freq -10089 delay 502 +2023-09-12T20:45:38.901903833Z phc2sys[357146.337]: [ptp4l.0.config] CLOCK_REALTIME phc offset 5 s2 freq -10084 delay 503 +2023-09-12T20:45:38.964486471Z phc2sys[357146.399]: [ptp4l.0.config] CLOCK_REALTIME phc offset 22 s2 freq -10066 delay 477 +2023-09-12T20:45:39.000060969Z ts2phc[357146.435]: [ts2phc.0.config] nmea delay: 110101427 ns +2023-09-12T20:45:39.000060969Z ts2phc[357146.435]: [ts2phc.0.config] ens6f0 extts index 0 at 1694551576.000000000 corr 0 src 1694551576.889920902 diff 0 +2023-09-12T20:45:39.000138791Z ts2phc[357146.435]: [ts2phc.0.config] ens6f0 master offset 0 s2 freq +0 +2023-09-12T20:45:39.001207652Z I0912 20:45:39.001189 161357 event.go:362] dpll State s2, gnss State s2, ts2phc state s2, gm state s2, +2023-09-12T20:45:39.027086615Z phc2sys[357146.462]: [ptp4l.0.config] CLOCK_REALTIME phc offset -4 s2 freq -10085 delay 508 +2023-09-12T20:45:39.089655193Z phc2sys[357146.524]: [ptp4l.0.config] CLOCK_REALTIME phc offset -4 s2 freq -10086 delay 503 +2023-09-12T20:45:39.121929162Z ts2phc[357146.557]: [ts2phc.0.config] nmea sentence: GNRMC,204539.00,A,4233.01593,N,07112.87866,W,0.016,,120923,,,A,V +2023-09-12T20:45:39.122401547Z ts2phc[357146.557]: [ts2phc.0.config] nmea sentence: GNGGA,204539.00,4233.01593,N,07112.87866,W,1,05,1.98,60.0,M,-33.0,M,, +2023-09-12T20:45:39.122445783Z ts2phc[357146.557]: [ts2phc.0.config] nmea sentence: GNGSA,A,3,10,12,23,28,32,,,,,,,,4.25,1.98,3.77,1 +2023-09-12T20:45:39.122488350Z ts2phc[357146.557]: [ts2phc.0.config] nmea sentence: GNGSA,A,3,,,,,,,,,,,,,4.25,1.98,3.77,5 +2023-09-12T20:45:39.122513106Z ts2phc[357146.557]: [ts2phc.0.config] nmea sentence: GPGSV,3,1,10,02,19,296,21,10,63,173,26,12,33,066,23,21,20,287,19,1 +2023-09-12T20:45:39.122539217Z ts2phc[357146.557]: [ts2phc.0.config] nmea sentence: GPGSV,3,2,10,23,25,153,20,24,09,056,17,25,45,120,23,28,49,236,23,1 +2023-09-12T20:45:39.122572399Z ts2phc[357146.557]: [ts2phc.0.config] nmea sentence: GPGSV,3,3,10,31,20,231,21,32,69,326,24,1 +2023-09-12T20:45:39.122572399Z ts2phc[357146.557]: [ts2phc.0.config] nmea sentence: GNGST,204539.00,41,14,11,122,4.9,5.5,11 +2023-09-12T20:45:39.122572399Z ts2phc[357146.557]: [ts2phc.0.config] nmea sentence: GNZDA,204539.00,12,09,2023,00,00 +2023-09-12T20:45:39.122572399Z ts2phc[357146.557]: [ts2phc.0.config] nmea sentence: GNGBS,204539.00,4.9,5.5,10.9,,,,,, +2023-09-12T20:45:39.124644986Z gnss[1694551539]:[ts2phc.0.config] ens6f0 gnss_status 3 offset 5 s2 +2023-09-12T20:45:39.152356565Z phc2sys[357146.587]: [ptp4l.0.config] CLOCK_REALTIME phc offset -5 s2 freq -10089 delay 514 +2023-09-12T20:45:39.171214746Z I0912 20:45:39.171196 161357 dpll.go:467] dpll decision: Status 3, Offset 0, In spec true, Source lost false, On holdover false +2023-09-12T20:45:39.171214746Z I0912 20:45:39.171209 161357 dpll.go:494] dpll is locked, source is not lost, offset is in range, state is DPLL_LOCKED_HO_ACQ or DPLL_HOLDOVER +2023-09-12T20:45:39.171239433Z I0912 20:45:39.171215 161357 dpll.go:540] dpll event sent +2023-09-12T20:45:39.176309469Z dpll[1694551539]:[ts2phc.0.config] ens6f0 frequency_status 3 offset 2 phase_status 3 s2 +2023-09-12T20:45:39.214823102Z phc2sys[357146.650]: [ptp4l.0.config] CLOCK_REALTIME phc offset -5 s2 freq -10090 delay 503 +2023-09-12T20:45:39.277391329Z phc2sys[357146.712]: [ptp4l.0.config] CLOCK_REALTIME phc offset -1 s2 freq -10088 delay 502 +2023-09-12T20:45:39.339972118Z phc2sys[357146.775]: [ptp4l.0.config] CLOCK_REALTIME phc offset -5 s2 freq -10092 delay 513 +2023-09-12T20:45:39.402551743Z phc2sys[357146.837]: [ptp4l.0.config] CLOCK_REALTIME phc offset -8 s2 freq -10096 delay 503 +2023-09-12T20:45:39.465123485Z phc2sys[357146.900]: [ptp4l.0.config] CLOCK_REALTIME phc offset -2 s2 freq -10093 delay 503 +2023-09-12T20:45:39.527695072Z phc2sys[357146.962]: [ptp4l.0.config] CLOCK_REALTIME phc offset -7 s2 freq -10098 delay 504 +2023-09-12T20:45:39.590317105Z phc2sys[357147.025]: [ptp4l.0.config] CLOCK_REALTIME phc offset -6 s2 freq -10100 delay 508 +2023-09-12T20:45:39.652908785Z phc2sys[357147.088]: [ptp4l.0.config] CLOCK_REALTIME phc offset -8 s2 freq -10103 delay 503 +2023-09-12T20:45:39.715494393Z phc2sys[357147.150]: [ptp4l.0.config] CLOCK_REALTIME phc offset -8 s2 freq -10106 delay 503 +2023-09-12T20:45:39.778092086Z phc2sys[357147.213]: [ptp4l.0.config] CLOCK_REALTIME phc offset -2 s2 freq -10102 delay 502 +2023-09-12T20:45:39.840643337Z phc2sys[357147.275]: [ptp4l.0.config] CLOCK_REALTIME phc offset -3 s2 freq -10104 delay 503 +2023-09-12T20:45:39.903209820Z phc2sys[357147.338]: [ptp4l.0.config] CLOCK_REALTIME phc offset -3 s2 freq -10105 delay 503 +2023-09-12T20:45:39.965792862Z phc2sys[357147.401]: [ptp4l.0.config] CLOCK_REALTIME phc offset -2 s2 freq -10105 delay 503 +2023-09-12T20:45:40.000070843Z ts2phc[357147.435]: [ts2phc.0.config] nmea delay: 121843376 ns +2023-09-12T20:45:40.000070843Z ts2phc[357147.435]: [ts2phc.0.config] ens6f0 extts index 0 at 1694551577.000000000 corr 0 src 1694551577.878179855 diff 0 +2023-09-12T20:45:40.000070843Z ts2phc[357147.435]: [ts2phc.0.config] ens6f0 master offset 0 s2 freq +0 +2023-09-12T20:45:40.007255983Z I0912 20:45:40.007226 161357 event.go:362] dpll State s2, gnss State s2, ts2phc state s2, gm state s2, +2023-09-12T20:45:40.028369712Z phc2sys[357147.463]: [ptp4l.0.config] CLOCK_REALTIME phc offset 0 s2 freq -10103 delay 503 +2023-09-12T20:45:40.090961365Z phc2sys[357147.526]: [ptp4l.0.config] CLOCK_REALTIME phc offset -4 s2 freq -10107 delay 497 +2023-09-12T20:45:40.111858783Z ts2phc[357147.547]: [ts2phc.0.config] nmea sentence: GNRMC,204540.00,A,4233.01594,N,07112.87868,W,0.016,,120923,,,A,V +2023-09-12T20:45:40.112317571Z ts2phc[357147.547]: [ts2phc.0.config] nmea sentence: GNGGA,204540.00,4233.01594,N,07112.87868,W,1,05,1.98,59.9,M,-33.0,M,, +2023-09-12T20:45:40.112368575Z ts2phc[357147.547]: [ts2phc.0.config] nmea sentence: GNGSA,A,3,10,12,23,28,32,,,,,,,,4.25,1.98,3.77,1 +2023-09-12T20:45:40.112412260Z ts2phc[357147.547]: [ts2phc.0.config] nmea sentence: GNGSA,A,3,,,,,,,,,,,,,4.25,1.98,3.77,5 +2023-09-12T20:45:40.112438223Z ts2phc[357147.547]: [ts2phc.0.config] nmea sentence: GPGSV,3,1,10,02,19,296,21,10,63,173,27,12,33,066,22,21,20,287,20,1 +2023-09-12T20:45:40.112465938Z ts2phc[357147.547]: [ts2phc.0.config] nmea sentence: GPGSV,3,2,10,23,25,153,20,24,09,056,17,25,45,120,23,28,50,237,23,1 +2023-09-12T20:45:40.112465938Z ts2phc[357147.547]: [ts2phc.0.config] nmea sentence: GPGSV,3,3,10,31,20,231,22,32,69,326,25,1 +2023-09-12T20:45:40.112465938Z ts2phc[357147.547]: [ts2phc.0.config] nmea sentence: GNGST,204540.00,40,14,11,122,4.9,5.5,11 +2023-09-12T20:45:40.112465938Z ts2phc[357147.547]: [ts2phc.0.config] nmea sentence: GNZDA,204540.00,12,09,2023,00,00 +2023-09-12T20:45:40.112465938Z ts2phc[357147.547]: [ts2phc.0.config] nmea sentence: GNGBS,204540.00,4.9,5.5,10.9,,,,,, +2023-09-12T20:45:40.121224214Z gnss[1694551540]:[ts2phc.0.config] ens6f0 gnss_status 3 offset 5 s2 +2023-09-12T20:45:40.153557244Z phc2sys[357147.588]: [ptp4l.0.config] CLOCK_REALTIME phc offset -2 s2 freq -10106 delay 501 +2023-09-12T20:45:40.171097894Z I0912 20:45:40.171077 161357 dpll.go:467] dpll decision: Status 3, Offset 0, In spec true, Source lost false, On holdover false +2023-09-12T20:45:40.171097894Z I0912 20:45:40.171093 161357 dpll.go:494] dpll is locked, source is not lost, offset is in range, state is DPLL_LOCKED_HO_ACQ or DPLL_HOLDOVER +2023-09-12T20:45:40.171122164Z I0912 20:45:40.171099 161357 dpll.go:540] dpll event sent +2023-09-12T20:45:40.172158035Z dpll[1694551540]:[ts2phc.0.config] ens6f0 frequency_status 3 offset 0 phase_status 3 s2 +2023-09-12T20:45:40.216106079Z phc2sys[357147.651]: [ptp4l.0.config] CLOCK_REALTIME phc offset -6 s2 freq -10111 delay 503 +2023-09-12T20:45:40.278743207Z phc2sys[357147.713]: [ptp4l.0.config] CLOCK_REALTIME phc offset -2 s2 freq -10109 delay 499 +2023-09-12T20:45:40.341285079Z phc2sys[357147.776]: [ptp4l.0.config] CLOCK_REALTIME phc offset -2 s2 freq -10109 delay 503 +2023-09-12T20:45:40.403855152Z phc2sys[357147.839]: [ptp4l.0.config] CLOCK_REALTIME phc offset -2 s2 freq -10110 delay 502 +2023-09-12T20:45:40.466442221Z phc2sys[357147.901]: [ptp4l.0.config] CLOCK_REALTIME phc offset -2 s2 freq -10111 delay 503 +2023-09-12T20:45:40.529090408Z phc2sys[357147.964]: [ptp4l.0.config] CLOCK_REALTIME phc offset 4 s2 freq -10105 delay 503 +2023-09-12T20:45:40.591615377Z phc2sys[357148.026]: [ptp4l.0.config] CLOCK_REALTIME phc offset 1 s2 freq -10107 delay 504 +2023-09-12T20:45:40.654212840Z phc2sys[357148.089]: [ptp4l.0.config] CLOCK_REALTIME phc offset 0 s2 freq -10108 delay 502 +2023-09-12T20:45:40.716806868Z phc2sys[357148.152]: [ptp4l.0.config] CLOCK_REALTIME phc offset 2 s2 freq -10106 delay 502 +2023-09-12T20:45:40.779417559Z phc2sys[357148.214]: [ptp4l.0.config] CLOCK_REALTIME phc offset 0 s2 freq -10107 delay 502 +2023-09-12T20:45:40.842016543Z phc2sys[357148.277]: [ptp4l.0.config] CLOCK_REALTIME phc offset 0 s2 freq -10107 delay 503 +2023-09-12T20:45:40.904587202Z phc2sys[357148.339]: [ptp4l.0.config] CLOCK_REALTIME phc offset -1 s2 freq -10108 delay 503 +2023-09-12T20:45:40.967187166Z phc2sys[357148.402]: [ptp4l.0.config] CLOCK_REALTIME phc offset 5 s2 freq -10102 delay 503 +2023-09-12T20:45:41.000110394Z ts2phc[357148.435]: [ts2phc.0.config] nmea delay: 111809969 ns +2023-09-12T20:45:41.000110394Z ts2phc[357148.435]: [ts2phc.0.config] ens6f0 extts index 0 at 1694551578.000000000 corr 0 src 1694551578.888216267 diff 0 +2023-09-12T20:45:41.000110394Z ts2phc[357148.435]: [ts2phc.0.config] ens6f0 master offset 0 s2 freq +0 +2023-09-12T20:45:41.006430566Z I0912 20:45:41.006410 161357 event.go:362] dpll State s2, gnss State s2, ts2phc state s2, gm state s2, +2023-09-12T20:45:41.029831421Z phc2sys[357148.465]: [ptp4l.0.config] CLOCK_REALTIME phc offset 3 s2 freq -10103 delay 505 +2023-09-12T20:45:41.092362581Z phc2sys[357148.527]: [ptp4l.0.config] CLOCK_REALTIME phc offset 2 s2 freq -10103 delay 503 +2023-09-12T20:45:41.109207765Z ts2phc[357148.543]: [ts2phc.0.config] nmea sentence: GNRMC,204541.00,A,4233.01593,N,07112.87870,W,0.016,,120923,,,A,V +2023-09-12T20:45:41.109207765Z ts2phc[357148.544]: [ts2phc.0.config] nmea sentence: GNGGA,204541.00,4233.01593,N,07112.87870,W,1,05,1.98,59.9,M,-33.0,M,, +2023-09-12T20:45:41.109207765Z ts2phc[357148.544]: [ts2phc.0.config] nmea sentence: GNGSA,A,3,10,12,23,28,32,,,,,,,,4.25,1.98,3.77,1 +2023-09-12T20:45:41.109207765Z ts2phc[357148.544]: [ts2phc.0.config] nmea sentence: GNGSA,A,3,,,,,,,,,,,,,4.25,1.98,3.77,5 +2023-09-12T20:45:41.109207765Z ts2phc[357148.544]: [ts2phc.0.config] nmea sentence: GPGSV,3,1,10,02,19,296,21,10,63,173,27,12,33,066,22,21,20,287,19,1 +2023-09-12T20:45:41.109207765Z ts2phc[357148.544]: [ts2phc.0.config] nmea sentence: GPGSV,3,2,10,23,25,153,19,24,09,056,16,25,45,120,22,28,50,237,23,1 +2023-09-12T20:45:41.109207765Z ts2phc[357148.544]: [ts2phc.0.config] nmea sentence: GPGSV,3,3,10,31,20,231,22,32,69,326,25,1 +2023-09-12T20:45:41.109207765Z ts2phc[357148.544]: [ts2phc.0.config] nmea sentence: GNGST,204541.00,41,14,11,122,4.9,5.5,11 +2023-09-12T20:45:41.109207765Z ts2phc[357148.544]: [ts2phc.0.config] nmea sentence: GNZDA,204541.00,12,09,2023,00,00 +2023-09-12T20:45:41.109259235Z ts2phc[357148.544]: [ts2phc.0.config] nmea sentence: GNGBS,204541.00,4.9,5.5,10.9,,,,,, +2023-09-12T20:45:41.119413393Z gnss[1694551541]:[ts2phc.0.config] ens6f0 gnss_status 3 offset 5 s2 +2023-09-12T20:45:41.154970653Z phc2sys[357148.590]: [ptp4l.0.config] CLOCK_REALTIME phc offset 10 s2 freq -10094 delay 503 +2023-09-12T20:45:41.171542573Z I0912 20:45:41.171522 161357 dpll.go:467] dpll decision: Status 3, Offset 0, In spec true, Source lost false, On holdover false +2023-09-12T20:45:41.171542573Z I0912 20:45:41.171536 161357 dpll.go:494] dpll is locked, source is not lost, offset is in range, state is DPLL_LOCKED_HO_ACQ or DPLL_HOLDOVER +2023-09-12T20:45:41.171578579Z I0912 20:45:41.171543 161357 dpll.go:540] dpll event sent +2023-09-12T20:45:41.180678036Z dpll[1694551541]:[ts2phc.0.config] ens6f0 frequency_status 3 offset -2 phase_status 3 s2 +2023-09-12T20:45:41.217526389Z phc2sys[357148.652]: [ptp4l.0.config] CLOCK_REALTIME phc offset 2 s2 freq -10099 delay 502 +2023-09-12T20:45:41.280154785Z phc2sys[357148.715]: [ptp4l.0.config] CLOCK_REALTIME phc offset 3 s2 freq -10098 delay 504 +2023-09-12T20:45:41.342715603Z phc2sys[357148.777]: [ptp4l.0.config] CLOCK_REALTIME phc offset 4 s2 freq -10096 delay 501 +2023-09-12T20:45:41.405281707Z phc2sys[357148.840]: [ptp4l.0.config] CLOCK_REALTIME phc offset 18 s2 freq -10081 delay 473 +2023-09-12T20:45:41.467858285Z phc2sys[357148.903]: [ptp4l.0.config] CLOCK_REALTIME phc offset 5 s2 freq -10088 delay 502 +2023-09-12T20:45:41.530437326Z phc2sys[357148.965]: [ptp4l.0.config] CLOCK_REALTIME phc offset 3 s2 freq -10089 delay 497 +2023-09-12T20:45:41.593091860Z phc2sys[357149.028]: [ptp4l.0.config] CLOCK_REALTIME phc offset -1 s2 freq -10092 delay 502 +2023-09-12T20:45:41.655648901Z phc2sys[357149.090]: [ptp4l.0.config] CLOCK_REALTIME phc offset -2 s2 freq -10093 delay 502 +2023-09-12T20:45:41.718239286Z phc2sys[357149.153]: [ptp4l.0.config] CLOCK_REALTIME phc offset 2 s2 freq -10090 delay 496 +2023-09-12T20:45:41.780806944Z phc2sys[357149.216]: [ptp4l.0.config] CLOCK_REALTIME phc offset -2 s2 freq -10093 delay 503 +2023-09-12T20:45:41.843377325Z phc2sys[357149.278]: [ptp4l.0.config] CLOCK_REALTIME phc offset 1 s2 freq -10091 delay 503 +2023-09-12T20:45:41.905968938Z phc2sys[357149.341]: [ptp4l.0.config] CLOCK_REALTIME phc offset 1 s2 freq -10090 delay 511 +2023-09-12T20:45:41.968587830Z phc2sys[357149.403]: [ptp4l.0.config] CLOCK_REALTIME phc offset 1 s2 freq -10090 delay 515 +2023-09-12T20:45:42.000063180Z ts2phc[357149.435]: [ts2phc.0.config] nmea delay: 108641588 ns +2023-09-12T20:45:42.000063180Z ts2phc[357149.435]: [ts2phc.0.config] ens6f0 extts index 0 at 1694551579.000000000 corr 0 src 1694551579.891380473 diff 0 +2023-09-12T20:45:42.000097728Z ts2phc[357149.435]: [ts2phc.0.config] ens6f0 master offset 0 s2 freq +0 +2023-09-12T20:45:42.001216077Z I0912 20:45:42.001197 161357 event.go:362] dpll State s2, gnss State s2, ts2phc state s2, gm state s2, +2023-09-12T20:45:42.031147596Z phc2sys[357149.466]: [ptp4l.0.config] CLOCK_REALTIME phc offset 3 s2 freq -10088 delay 503 +2023-09-12T20:45:42.093730262Z phc2sys[357149.529]: [ptp4l.0.config] CLOCK_REALTIME phc offset 0 s2 freq -10090 delay 502 +2023-09-12T20:45:42.138904956Z ts2phc[357149.574]: [ts2phc.0.config] nmea sentence: GNRMC,204542.00,A,4233.01594,N,07112.87872,W,0.016,,120923,,,A,V +2023-09-12T20:45:42.139165267Z ts2phc[357149.574]: [ts2phc.0.config] nmea sentence: GNGGA,204542.00,4233.01594,N,07112.87872,W,1,05,1.98,59.8,M,-33.0,M,, +2023-09-12T20:45:42.139165267Z ts2phc[357149.574]: [ts2phc.0.config] nmea sentence: GNGSA,A,3,10,12,23,28,32,,,,,,,,4.25,1.98,3.77,1 +2023-09-12T20:45:42.139184643Z ts2phc[357149.574]: [ts2phc.0.config] nmea sentence: GNGSA,A,3,,,,,,,,,,,,,4.25,1.98,3.77,5 +2023-09-12T20:45:42.139184643Z ts2phc[357149.574]: [ts2phc.0.config] nmea sentence: GPGSV,3,1,10,02,19,296,21,10,63,173,27,12,33,066,22,21,20,287,19,1 +2023-09-12T20:45:42.139184643Z ts2phc[357149.574]: [ts2phc.0.config] nmea sentence: GPGSV,3,2,10,23,25,153,19,24,09,056,16,25,45,120,22,28,50,237,23,1 +2023-09-12T20:45:42.139203048Z ts2phc[357149.574]: [ts2phc.0.config] nmea sentence: GPGSV,3,3,10,31,20,231,21,32,69,326,25,1 +2023-09-12T20:45:42.139311621Z ts2phc[357149.574]: [ts2phc.0.config] nmea sentence: GNGST,204542.00,41,14,11,122,4.8,5.5,11 +2023-09-12T20:45:42.139357944Z ts2phc[357149.574]: [ts2phc.0.config] nmea sentence: GNZDA,204542.00,12,09,2023,00,00 +2023-09-12T20:45:42.139481095Z ts2phc[357149.574]: [ts2phc.0.config] nmea sentence: GNGBS,204542.00,4.8,5.5,10.9,,,,,, +2023-09-12T20:45:42.144600227Z gnss[1694551542]:[ts2phc.0.config] ens6f0 gnss_status 3 offset 5 s2 +2023-09-12T20:45:42.156305653Z phc2sys[357149.591]: [ptp4l.0.config] CLOCK_REALTIME phc offset 0 s2 freq -10090 delay 502 +2023-09-12T20:45:42.171006844Z I0912 20:45:42.170978 161357 dpll.go:467] dpll decision: Status 3, Offset 0, In spec true, Source lost false, On holdover false +2023-09-12T20:45:42.171057565Z I0912 20:45:42.171039 161357 dpll.go:494] dpll is locked, source is not lost, offset is in range, state is DPLL_LOCKED_HO_ACQ or DPLL_HOLDOVER +2023-09-12T20:45:42.171100194Z I0912 20:45:42.171081 161357 dpll.go:540] dpll event sent +2023-09-12T20:45:42.176086918Z dpll[1694551542]:[ts2phc.0.config] ens6f0 frequency_status 3 offset -4 phase_status 3 s2 +2023-09-12T20:45:42.218881802Z phc2sys[357149.654]: [ptp4l.0.config] CLOCK_REALTIME phc offset 11 s2 freq -10079 delay 473 +2023-09-12T20:45:42.281476551Z phc2sys[357149.716]: [ptp4l.0.config] CLOCK_REALTIME phc offset -6 s2 freq -10093 delay 501 +2023-09-12T20:45:42.344078353Z phc2sys[357149.779]: [ptp4l.0.config] CLOCK_REALTIME phc offset -6 s2 freq -10094 delay 509 +2023-09-12T20:45:42.406646467Z phc2sys[357149.841]: [ptp4l.0.config] CLOCK_REALTIME phc offset -2 s2 freq -10092 delay 502 +2023-09-12T20:45:42.469219902Z phc2sys[357149.904]: [ptp4l.0.config] CLOCK_REALTIME phc offset -2 s2 freq -10093 delay 504 +2023-09-12T20:45:42.531826409Z phc2sys[357149.967]: [ptp4l.0.config] CLOCK_REALTIME phc offset -6 s2 freq -10097 delay 501 +2023-09-12T20:45:42.594404176Z phc2sys[357150.029]: [ptp4l.0.config] CLOCK_REALTIME phc offset -5 s2 freq -10098 delay 502 +2023-09-12T20:45:42.657025073Z phc2sys[357150.092]: [ptp4l.0.config] CLOCK_REALTIME phc offset -2 s2 freq -10097 delay 503 +2023-09-12T20:45:42.719561696Z phc2sys[357150.154]: [ptp4l.0.config] CLOCK_REALTIME phc offset -6 s2 freq -10101 delay 501 +2023-09-12T20:45:42.782164102Z phc2sys[357150.217]: [ptp4l.0.config] CLOCK_REALTIME phc offset -2 s2 freq -10099 delay 502 +2023-09-12T20:45:42.844766366Z phc2sys[357150.280]: [ptp4l.0.config] CLOCK_REALTIME phc offset -6 s2 freq -10104 delay 501 +2023-09-12T20:45:42.907374116Z phc2sys[357150.342]: [ptp4l.0.config] CLOCK_REALTIME phc offset 0 s2 freq -10100 delay 506 +2023-09-12T20:45:42.972031615Z phc2sys[357150.405]: [ptp4l.0.config] CLOCK_REALTIME phc offset -9 s2 freq -10109 delay 513 +2023-09-12T20:45:43.000116184Z ts2phc[357150.435]: [ts2phc.0.config] nmea delay: 138856930 ns +2023-09-12T20:45:43.000260947Z ts2phc[357150.435]: [ts2phc.0.config] ens6f0 extts index 0 at 1694551580.000000000 corr 0 src 1694551580.861170530 diff 0 +2023-09-12T20:45:43.000260947Z ts2phc[357150.435]: [ts2phc.0.config] ens6f0 master offset 0 s2 freq +0 +2023-09-12T20:45:43.007439273Z I0912 20:45:43.007336 161357 event.go:362] dpll State s2, gnss State s2, ts2phc state s2, gm state s2, +2023-09-12T20:45:43.032534840Z phc2sys[357150.467]: [ptp4l.0.config] CLOCK_REALTIME phc offset -3 s2 freq -10105 delay 497 +2023-09-12T20:45:43.095206654Z phc2sys[357150.530]: [ptp4l.0.config] CLOCK_REALTIME phc offset -4 s2 freq -10107 delay 506 +2023-09-12T20:45:43.157763642Z phc2sys[357150.593]: [ptp4l.0.config] CLOCK_REALTIME phc offset 0 s2 freq -10104 delay 507 +2023-09-12T20:45:43.169087775Z ts2phc[357150.603]: [ts2phc.0.config] nmea sentence: GNRMC,204543.00,A,4233.01594,N,07112.87873,W,0.016,,120923,,,A,V +2023-09-12T20:45:43.169154944Z ts2phc[357150.604]: [ts2phc.0.config] nmea sentence: GNGGA,204543.00,4233.01594,N,07112.87873,W,1,05,1.98,59.7,M,-33.0,M,, +2023-09-12T20:45:43.169184594Z ts2phc[357150.604]: [ts2phc.0.config] nmea sentence: GNGSA,A,3,10,12,23,28,32,,,,,,,,4.25,1.98,3.77,1 +2023-09-12T20:45:43.169209036Z ts2phc[357150.604]: [ts2phc.0.config] nmea sentence: GNGSA,A,3,,,,,,,,,,,,,4.25,1.98,3.77,5 +2023-09-12T20:45:43.169241291Z ts2phc[357150.604]: [ts2phc.0.config] nmea sentence: GPGSV,3,1,10,02,19,296,22,10,63,173,27,12,33,066,22,21,20,287,18,1 +2023-09-12T20:45:43.169329543Z ts2phc[357150.604]: [ts2phc.0.config] nmea sentence: GPGSV,3,2,10,23,25,153,20,24,09,056,17,25,45,120,22,28,50,237,23,1 +2023-09-12T20:45:43.169384531Z ts2phc[357150.604]: [ts2phc.0.config] nmea sentence: GPGSV,3,3,10,31,20,232,21,32,69,326,25,1 +2023-09-12T20:45:43.169384531Z ts2phc[357150.604]: [ts2phc.0.config] nmea sentence: GNGST,204543.00,40,14,11,122,4.8,5.5,11 +2023-09-12T20:45:43.169384531Z ts2phc[357150.604]: [ts2phc.0.config] nmea sentence: GNZDA,204543.00,12,09,2023,00,00 +2023-09-12T20:45:43.169384531Z ts2phc[357150.604]: [ts2phc.0.config] nmea sentence: GNGBS,204543.00,4.8,5.5,10.9,,,,,, +2023-09-12T20:45:43.171374867Z I0912 20:45:43.171355 161357 dpll.go:467] dpll decision: Status 3, Offset 0, In spec true, Source lost false, On holdover false +2023-09-12T20:45:43.171374867Z I0912 20:45:43.171370 161357 dpll.go:494] dpll is locked, source is not lost, offset is in range, state is DPLL_LOCKED_HO_ACQ or DPLL_HOLDOVER +2023-09-12T20:45:43.171407841Z I0912 20:45:43.171377 161357 dpll.go:540] dpll event sent +2023-09-12T20:45:43.172451450Z gnss[1694551543]:[ts2phc.0.config] ens6f0 gnss_status 3 offset 5 s2 +2023-09-12T20:45:43.172474223Z dpll[1694551543]:[ts2phc.0.config] ens6f0 frequency_status 3 offset 3 phase_status 3 s2 +2023-09-12T20:45:43.220334415Z phc2sys[357150.655]: [ptp4l.0.config] CLOCK_REALTIME phc offset -4 s2 freq -10108 delay 509 +2023-09-12T20:45:43.282922300Z phc2sys[357150.718]: [ptp4l.0.config] CLOCK_REALTIME phc offset -4 s2 freq -10110 delay 503 +2023-09-12T20:45:43.345498545Z phc2sys[357150.780]: [ptp4l.0.config] CLOCK_REALTIME phc offset 0 s2 freq -10107 delay 501 +2023-09-12T20:45:43.408073203Z phc2sys[357150.843]: [ptp4l.0.config] CLOCK_REALTIME phc offset -2 s2 freq -10109 delay 502 +2023-09-12T20:45:43.470651484Z phc2sys[357150.905]: [ptp4l.0.config] CLOCK_REALTIME phc offset -1 s2 freq -10108 delay 501 +2023-09-12T20:45:43.533231275Z phc2sys[357150.968]: [ptp4l.0.config] CLOCK_REALTIME phc offset 2 s2 freq -10106 delay 501 +2023-09-12T20:45:43.595922789Z phc2sys[357151.031]: [ptp4l.0.config] CLOCK_REALTIME phc offset 6 s2 freq -10101 delay 511 +2023-09-12T20:45:43.658542424Z phc2sys[357151.093]: [ptp4l.0.config] CLOCK_REALTIME phc offset 7 s2 freq -10098 delay 509 +2023-09-12T20:45:43.721114074Z phc2sys[357151.156]: [ptp4l.0.config] CLOCK_REALTIME phc offset 5 s2 freq -10098 delay 501 +2023-09-12T20:45:43.783673467Z phc2sys[357151.218]: [ptp4l.0.config] CLOCK_REALTIME phc offset 7 s2 freq -10095 delay 504 +2023-09-12T20:45:43.846267783Z phc2sys[357151.281]: [ptp4l.0.config] CLOCK_REALTIME phc offset 7 s2 freq -10093 delay 499 +2023-09-12T20:45:43.908851774Z phc2sys[357151.344]: [ptp4l.0.config] CLOCK_REALTIME phc offset 5 s2 freq -10092 delay 503 +2023-09-12T20:45:43.971424124Z phc2sys[357151.406]: [ptp4l.0.config] CLOCK_REALTIME phc offset 9 s2 freq -10087 delay 502 +2023-09-12T20:45:44.000067116Z ts2phc[357151.435]: [ts2phc.0.config] nmea delay: 168422384 ns +2023-09-12T20:45:44.000097247Z ts2phc[357151.435]: [ts2phc.0.config] ens6f0 extts index 0 at 1694551581.000000000 corr 0 src 1694551581.831600433 diff 0 +2023-09-12T20:45:44.000097247Z ts2phc[357151.435]: [ts2phc.0.config] ens6f0 master offset 0 s2 freq +0 +2023-09-12T20:45:44.003277388Z I0912 20:45:44.003259 161357 event.go:362] dpll State s2, gnss State s2, ts2phc state s2, gm state s2, +2023-09-12T20:45:44.033998262Z phc2sys[357151.469]: [ptp4l.0.config] CLOCK_REALTIME phc offset 5 s2 freq -10088 delay 502 +2023-09-12T20:45:44.096582101Z phc2sys[357151.531]: [ptp4l.0.config] CLOCK_REALTIME phc offset 3 s2 freq -10089 delay 506 +2023-09-12T20:45:44.121910169Z ts2phc[357151.557]: [ts2phc.0.config] nmea sentence: GNRMC,204544.00,A,4233.01594,N,07112.87874,W,0.016,,120923,,,A,V +2023-09-12T20:45:44.122530062Z ts2phc[357151.557]: [ts2phc.0.config] nmea sentence: GNGGA,204544.00,4233.01594,N,07112.87874,W,1,05,1.98,59.7,M,-33.0,M,, +2023-09-12T20:45:44.122530062Z ts2phc[357151.557]: [ts2phc.0.config] nmea sentence: GNGSA,A,3,10,12,23,28,32,,,,,,,,4.25,1.98,3.77,1 +2023-09-12T20:45:44.122530062Z ts2phc[357151.557]: [ts2phc.0.config] nmea sentence: GNGSA,A,3,,,,,,,,,,,,,4.25,1.98,3.77,5 +2023-09-12T20:45:44.122530062Z ts2phc[357151.557]: [ts2phc.0.config] nmea sentence: GPGSV,3,1,10,02,19,296,21,10,63,173,27,12,33,066,22,21,20,287,19,1 +2023-09-12T20:45:44.122562059Z ts2phc[357151.557]: [ts2phc.0.config] nmea sentence: GPGSV,3,2,10,23,25,153,20,24,09,056,16,25,45,120,23,28,50,237,23,1 +2023-09-12T20:45:44.122562059Z ts2phc[357151.557]: [ts2phc.0.config] nmea sentence: GPGSV,3,3,10,31,20,232,22,32,69,327,25,1 +2023-09-12T20:45:44.122562059Z ts2phc[357151.557]: [ts2phc.0.config] nmea sentence: GNGST,204544.00,40,14,11,122,4.8,5.5,11 +2023-09-12T20:45:44.122562059Z ts2phc[357151.557]: [ts2phc.0.config] nmea sentence: GNZDA,204544.00,12,09,2023,00,00 +2023-09-12T20:45:44.122562059Z ts2phc[357151.557]: [ts2phc.0.config] nmea sentence: GNGBS,204544.00,4.8,5.5,10.9,,,,,, +2023-09-12T20:45:44.126658763Z gnss[1694551544]:[ts2phc.0.config] ens6f0 gnss_status 3 offset 5 s2 +2023-09-12T20:45:44.159200390Z phc2sys[357151.594]: [ptp4l.0.config] CLOCK_REALTIME phc offset 7 s2 freq -10084 delay 503 +2023-09-12T20:45:44.171805105Z I0912 20:45:44.171782 161357 dpll.go:467] dpll decision: Status 3, Offset 0, In spec true, Source lost false, On holdover false +2023-09-12T20:45:44.171805105Z I0912 20:45:44.171800 161357 dpll.go:494] dpll is locked, source is not lost, offset is in range, state is DPLL_LOCKED_HO_ACQ or DPLL_HOLDOVER +2023-09-12T20:45:44.171831938Z I0912 20:45:44.171806 161357 dpll.go:540] dpll event sent +2023-09-12T20:45:44.177931324Z dpll[1694551544]:[ts2phc.0.config] ens6f0 frequency_status 3 offset 3 phase_status 3 s2 +2023-09-12T20:45:44.221764907Z phc2sys[357151.657]: [ptp4l.0.config] CLOCK_REALTIME phc offset 8 s2 freq -10081 delay 503 +2023-09-12T20:45:44.284354322Z phc2sys[357151.719]: [ptp4l.0.config] CLOCK_REALTIME phc offset 3 s2 freq -10083 delay 503 +2023-09-12T20:45:44.346939861Z phc2sys[357151.782]: [ptp4l.0.config] CLOCK_REALTIME phc offset 0 s2 freq -10085 delay 503 +2023-09-12T20:45:44.409511541Z phc2sys[357151.844]: [ptp4l.0.config] CLOCK_REALTIME phc offset -2 s2 freq -10087 delay 503 +2023-09-12T20:45:44.472083211Z phc2sys[357151.907]: [ptp4l.0.config] CLOCK_REALTIME phc offset 2 s2 freq -10084 delay 503 +2023-09-12T20:45:44.534755582Z phc2sys[357151.969]: [ptp4l.0.config] CLOCK_REALTIME phc offset -1 s2 freq -10086 delay 509 +2023-09-12T20:45:44.597983121Z phc2sys[357152.032]: [ptp4l.0.config] CLOCK_REALTIME phc offset -3 s2 freq -10089 delay 508 +2023-09-12T20:45:44.659912529Z phc2sys[357152.095]: [ptp4l.0.config] CLOCK_REALTIME phc offset -16 s2 freq -10103 delay 483 +2023-09-12T20:45:44.722537002Z phc2sys[357152.157]: [ptp4l.0.config] CLOCK_REALTIME phc offset -5 s2 freq -10096 delay 511 +2023-09-12T20:45:44.785133731Z phc2sys[357152.220]: [ptp4l.0.config] CLOCK_REALTIME phc offset 0 s2 freq -10093 delay 511 +2023-09-12T20:45:44.847737907Z phc2sys[357152.283]: [ptp4l.0.config] CLOCK_REALTIME phc offset 0 s2 freq -10093 delay 500 +2023-09-12T20:45:44.910337573Z phc2sys[357152.345]: [ptp4l.0.config] CLOCK_REALTIME phc offset -4 s2 freq -10097 delay 502 +2023-09-12T20:45:44.972926650Z phc2sys[357152.408]: [ptp4l.0.config] CLOCK_REALTIME phc offset -6 s2 freq -10100 delay 503 +2023-09-12T20:45:45.000118567Z ts2phc[357152.435]: [ts2phc.0.config] nmea delay: 121817530 ns +2023-09-12T20:45:45.000118567Z ts2phc[357152.435]: [ts2phc.0.config] ens6f0 extts index 0 at 1694551582.000000000 corr 0 src 1694551582.878206386 diff 0 +2023-09-12T20:45:45.000118567Z ts2phc[357152.435]: [ts2phc.0.config] ens6f0 master offset 0 s2 freq +0 +2023-09-12T20:45:45.010359974Z I0912 20:45:45.010336 161357 event.go:362] dpll State s2, gnss State s2, ts2phc state s2, gm state s2, +2023-09-12T20:45:45.035505752Z phc2sys[357152.470]: [ptp4l.0.config] CLOCK_REALTIME phc offset 2 s2 freq -10094 delay 503 +2023-09-12T20:45:45.098098114Z phc2sys[357152.533]: [ptp4l.0.config] CLOCK_REALTIME phc offset 2 s2 freq -10093 delay 504 +2023-09-12T20:45:45.114893434Z ts2phc[357152.550]: [ts2phc.0.config] nmea sentence: GNRMC,204545.00,A,4233.01594,N,07112.87874,W,0.016,,120923,,,A,V +2023-09-12T20:45:45.115487306Z ts2phc[357152.550]: [ts2phc.0.config] nmea sentence: GNGGA,204545.00,4233.01594,N,07112.87874,W,1,05,1.98,59.6,M,-33.0,M,, +2023-09-12T20:45:45.115487306Z ts2phc[357152.550]: [ts2phc.0.config] nmea sentence: GNGSA,A,3,10,12,23,28,32,,,,,,,,4.25,1.98,3.77,1 +2023-09-12T20:45:45.115487306Z ts2phc[357152.550]: [ts2phc.0.config] nmea sentence: GNGSA,A,3,,,,,,,,,,,,,4.25,1.98,3.77,5 +2023-09-12T20:45:45.115487306Z ts2phc[357152.550]: [ts2phc.0.config] nmea sentence: GPGSV,3,1,10,02,19,296,21,10,63,173,26,12,33,066,21,21,20,287,19,1 +2023-09-12T20:45:45.115512480Z ts2phc[357152.550]: [ts2phc.0.config] nmea sentence: GPGSV,3,2,10,23,25,153,20,24,09,056,16,25,45,120,23,28,50,237,23,1 +2023-09-12T20:45:45.115512480Z ts2phc[357152.550]: [ts2phc.0.config] nmea sentence: GPGSV,3,3,10,31,20,232,22,32,69,327,24,1 +2023-09-12T20:45:45.115512480Z ts2phc[357152.550]: [ts2phc.0.config] nmea sentence: GNGST,204545.00,42,14,11,122,4.8,5.5,11 +2023-09-12T20:45:45.115512480Z ts2phc[357152.550]: [ts2phc.0.config] nmea sentence: GNZDA,204545.00,12,09,2023,00,00 +2023-09-12T20:45:45.115512480Z ts2phc[357152.550]: [ts2phc.0.config] nmea sentence: GNGBS,204545.00,4.8,5.5,10.9,,,,,, +2023-09-12T20:45:45.123814891Z gnss[1694551545]:[ts2phc.0.config] ens6f0 gnss_status 3 offset 5 s2 +2023-09-12T20:45:45.160676035Z phc2sys[357152.595]: [ptp4l.0.config] CLOCK_REALTIME phc offset 1 s2 freq -10094 delay 503 +2023-09-12T20:45:45.171202632Z I0912 20:45:45.171181 161357 dpll.go:467] dpll decision: Status 3, Offset 0, In spec true, Source lost false, On holdover false +2023-09-12T20:45:45.171202632Z I0912 20:45:45.171195 161357 dpll.go:494] dpll is locked, source is not lost, offset is in range, state is DPLL_LOCKED_HO_ACQ or DPLL_HOLDOVER +2023-09-12T20:45:45.171228280Z I0912 20:45:45.171201 161357 dpll.go:540] dpll event sent +2023-09-12T20:45:45.175333466Z dpll[1694551545]:[ts2phc.0.config] ens6f0 frequency_status 3 offset 0 phase_status 3 s2 +2023-09-12T20:45:45.223259747Z phc2sys[357152.658]: [ptp4l.0.config] CLOCK_REALTIME phc offset 3 s2 freq -10091 delay 500 +2023-09-12T20:45:45.285844945Z phc2sys[357152.721]: [ptp4l.0.config] CLOCK_REALTIME phc offset -2 s2 freq -10096 delay 502 +2023-09-12T20:45:45.348409764Z phc2sys[357152.783]: [ptp4l.0.config] CLOCK_REALTIME phc offset -1 s2 freq -10095 delay 503 +2023-09-12T20:45:45.411005316Z phc2sys[357152.846]: [ptp4l.0.config] CLOCK_REALTIME phc offset -6 s2 freq -10100 delay 503 +2023-09-12T20:45:45.473582376Z phc2sys[357152.908]: [ptp4l.0.config] CLOCK_REALTIME phc offset 1 s2 freq -10095 delay 503 +2023-09-12T20:45:45.536161854Z phc2sys[357152.971]: [ptp4l.0.config] CLOCK_REALTIME phc offset -1 s2 freq -10097 delay 503 +2023-09-12T20:45:45.598792088Z phc2sys[357153.034]: [ptp4l.0.config] CLOCK_REALTIME phc offset -3 s2 freq -10099 delay 508 +2023-09-12T20:45:45.661460639Z phc2sys[357153.096]: [ptp4l.0.config] CLOCK_REALTIME phc offset 0 s2 freq -10097 delay 501 +2023-09-12T20:45:45.724001683Z phc2sys[357153.159]: [ptp4l.0.config] CLOCK_REALTIME phc offset -1 s2 freq -10098 delay 510 +2023-09-12T20:45:45.786589285Z phc2sys[357153.221]: [ptp4l.0.config] CLOCK_REALTIME phc offset 1 s2 freq -10096 delay 503 +2023-09-12T20:45:45.849167658Z phc2sys[357153.284]: [ptp4l.0.config] CLOCK_REALTIME phc offset -2 s2 freq -10099 delay 503 +2023-09-12T20:45:45.911872099Z phc2sys[357153.347]: [ptp4l.0.config] CLOCK_REALTIME phc offset -3 s2 freq -10101 delay 505 +2023-09-12T20:45:45.974390586Z phc2sys[357153.409]: [ptp4l.0.config] CLOCK_REALTIME phc offset 5 s2 freq -10094 delay 503 +2023-09-12T20:45:46.000077318Z ts2phc[357153.435]: [ts2phc.0.config] nmea delay: 114836171 ns +2023-09-12T20:45:46.000110973Z ts2phc[357153.435]: [ts2phc.0.config] ens6f0 extts index 0 at 1694551583.000000000 corr 0 src 1694551583.885187285 diff 0 +2023-09-12T20:45:46.000121713Z ts2phc[357153.435]: [ts2phc.0.config] ens6f0 master offset 0 s2 freq +0 +2023-09-12T20:45:46.009470926Z I0912 20:45:46.009447 161357 event.go:362] dpll State s2, gnss State s2, ts2phc state s2, gm state s2, +2023-09-12T20:45:46.036960559Z phc2sys[357153.472]: [ptp4l.0.config] CLOCK_REALTIME phc offset 1 s2 freq -10096 delay 503 +2023-09-12T20:45:46.099547538Z phc2sys[357153.534]: [ptp4l.0.config] CLOCK_REALTIME phc offset 5 s2 freq -10092 delay 498 +2023-09-12T20:45:46.116927061Z ts2phc[357153.552]: [ts2phc.0.config] nmea sentence: GNRMC,204546.00,A,4233.01594,N,07112.87876,W,0.016,,120923,,,A,V +2023-09-12T20:45:46.117393443Z ts2phc[357153.552]: [ts2phc.0.config] nmea sentence: GNGGA,204546.00,4233.01594,N,07112.87876,W,1,05,1.98,59.6,M,-33.0,M,, +2023-09-12T20:45:46.117393443Z ts2phc[357153.552]: [ts2phc.0.config] nmea sentence: GNGSA,A,3,10,12,23,28,32,,,,,,,,4.26,1.98,3.77,1 +2023-09-12T20:45:46.117393443Z ts2phc[357153.552]: [ts2phc.0.config] nmea sentence: GNGSA,A,3,,,,,,,,,,,,,4.26,1.98,3.77,5 +2023-09-12T20:45:46.117393443Z ts2phc[357153.552]: [ts2phc.0.config] nmea sentence: GPGSV,3,1,10,02,19,296,21,10,63,173,27,12,33,066,22,21,20,287,19,1 +2023-09-12T20:45:46.117424538Z ts2phc[357153.552]: [ts2phc.0.config] nmea sentence: GPGSV,3,2,10,23,25,153,20,24,09,056,16,25,45,120,23,28,50,237,23,1 +2023-09-12T20:45:46.117424538Z ts2phc[357153.552]: [ts2phc.0.config] nmea sentence: GPGSV,3,3,10,31,20,232,22,32,69,327,24,1 +2023-09-12T20:45:46.117424538Z ts2phc[357153.552]: [ts2phc.0.config] nmea sentence: GNGST,204546.00,41,14,11,122,4.8,5.5,11 +2023-09-12T20:45:46.117424538Z ts2phc[357153.552]: [ts2phc.0.config] nmea sentence: GNZDA,204546.00,12,09,2023,00,00 +2023-09-12T20:45:46.117542070Z ts2phc[357153.552]: [ts2phc.0.config] nmea sentence: GNGBS,204546.00,4.8,5.5,10.9,,,,,, +2023-09-12T20:45:46.122753428Z gnss[1694551546]:[ts2phc.0.config] ens6f0 gnss_status 3 offset 5 s2 +2023-09-12T20:45:46.162126932Z phc2sys[357153.597]: [ptp4l.0.config] CLOCK_REALTIME phc offset 6 s2 freq -10089 delay 502 +2023-09-12T20:45:46.171591981Z I0912 20:45:46.171570 161357 dpll.go:467] dpll decision: Status 3, Offset 0, In spec true, Source lost false, On holdover false +2023-09-12T20:45:46.171591981Z I0912 20:45:46.171585 161357 dpll.go:494] dpll is locked, source is not lost, offset is in range, state is DPLL_LOCKED_HO_ACQ or DPLL_HOLDOVER +2023-09-12T20:45:46.171619667Z I0912 20:45:46.171592 161357 dpll.go:540] dpll event sent +2023-09-12T20:45:46.174732642Z dpll[1694551546]:[ts2phc.0.config] ens6f0 frequency_status 3 offset 0 phase_status 3 s2 +2023-09-12T20:45:46.224733947Z phc2sys[357153.659]: [ptp4l.0.config] CLOCK_REALTIME phc offset 0 s2 freq -10094 delay 502 +2023-09-12T20:45:46.287299364Z phc2sys[357153.722]: [ptp4l.0.config] CLOCK_REALTIME phc offset -2 s2 freq -10096 delay 503 +2023-09-12T20:45:46.349995685Z phc2sys[357153.785]: [ptp4l.0.config] CLOCK_REALTIME phc offset 5 s2 freq -10089 delay 503 +2023-09-12T20:45:46.412462052Z phc2sys[357153.847]: [ptp4l.0.config] CLOCK_REALTIME phc offset 2 s2 freq -10091 delay 503 +2023-09-12T20:45:46.475040478Z phc2sys[357153.910]: [ptp4l.0.config] CLOCK_REALTIME phc offset 0 s2 freq -10092 delay 501 +2023-09-12T20:45:46.537695502Z phc2sys[357153.972]: [ptp4l.0.config] CLOCK_REALTIME phc offset -2 s2 freq -10094 delay 508 +2023-09-12T20:45:46.600248112Z phc2sys[357154.035]: [ptp4l.0.config] CLOCK_REALTIME phc offset 2 s2 freq -10091 delay 495 +2023-09-12T20:45:46.662822586Z phc2sys[357154.098]: [ptp4l.0.config] CLOCK_REALTIME phc offset 0 s2 freq -10092 delay 503 +2023-09-12T20:45:46.725419964Z phc2sys[357154.160]: [ptp4l.0.config] CLOCK_REALTIME phc offset 4 s2 freq -10088 delay 498 +2023-09-12T20:45:46.788004022Z phc2sys[357154.223]: [ptp4l.0.config] CLOCK_REALTIME phc offset 1 s2 freq -10090 delay 501 +2023-09-12T20:45:46.850605600Z phc2sys[357154.285]: [ptp4l.0.config] CLOCK_REALTIME phc offset -6 s2 freq -10097 delay 512 +2023-09-12T20:45:46.913201651Z phc2sys[357154.348]: [ptp4l.0.config] CLOCK_REALTIME phc offset -3 s2 freq -10095 delay 500 +2023-09-12T20:45:46.975783386Z phc2sys[357154.411]: [ptp4l.0.config] CLOCK_REALTIME phc offset 0 s2 freq -10093 delay 503 +2023-09-12T20:45:47.000064114Z ts2phc[357154.435]: [ts2phc.0.config] nmea delay: 116873321 ns +2023-09-12T20:45:47.000064114Z ts2phc[357154.435]: [ts2phc.0.config] ens6f0 extts index 0 at 1694551584.000000000 corr 0 src 1694551584.883148424 diff 0 +2023-09-12T20:45:47.000095782Z ts2phc[357154.435]: [ts2phc.0.config] ens6f0 master offset 0 s2 freq +0 +2023-09-12T20:45:47.006303183Z I0912 20:45:47.006285 161357 event.go:362] dpll State s2, gnss State s2, ts2phc state s2, gm state s2, +2023-09-12T20:45:47.038375746Z phc2sys[357154.473]: [ptp4l.0.config] CLOCK_REALTIME phc offset 1 s2 freq -10092 delay 503 +2023-09-12T20:45:47.100955003Z phc2sys[357154.536]: [ptp4l.0.config] CLOCK_REALTIME phc offset 3 s2 freq -10090 delay 502 +2023-09-12T20:45:47.110014657Z ts2phc[357154.545]: [ts2phc.0.config] nmea sentence: GNRMC,204547.00,A,4233.01593,N,07112.87878,W,0.016,,120923,,,A,V +2023-09-12T20:45:47.110625041Z ts2phc[357154.545]: [ts2phc.0.config] nmea sentence: GNGGA,204547.00,4233.01593,N,07112.87878,W,1,05,1.98,59.5,M,-33.0,M,, +2023-09-12T20:45:47.110625041Z ts2phc[357154.545]: [ts2phc.0.config] nmea sentence: GNGSA,A,3,10,12,23,28,32,,,,,,,,4.26,1.98,3.77,1 +2023-09-12T20:45:47.110625041Z ts2phc[357154.545]: [ts2phc.0.config] nmea sentence: GNGSA,A,3,,,,,,,,,,,,,4.26,1.98,3.77,5 +2023-09-12T20:45:47.110625041Z ts2phc[357154.545]: [ts2phc.0.config] nmea sentence: GPGSV,3,1,10,02,19,296,21,10,63,173,27,12,33,066,22,21,20,287,19,1 +2023-09-12T20:45:47.110625041Z ts2phc[357154.545]: [ts2phc.0.config] nmea sentence: GPGSV,3,2,10,23,25,153,20,24,09,056,16,25,45,120,22,28,50,237,24,1 +2023-09-12T20:45:47.110625041Z ts2phc[357154.545]: [ts2phc.0.config] nmea sentence: GPGSV,3,3,10,31,20,232,21,32,69,327,24,1 +2023-09-12T20:45:47.110625041Z ts2phc[357154.545]: [ts2phc.0.config] nmea sentence: GNGST,204547.00,40,14,11,122,4.8,5.5,11 +2023-09-12T20:45:47.110625041Z ts2phc[357154.545]: [ts2phc.0.config] nmea sentence: GNZDA,204547.00,12,09,2023,00,00 +2023-09-12T20:45:47.110656620Z ts2phc[357154.545]: [ts2phc.0.config] nmea sentence: GNGBS,204547.00,4.8,5.5,10.9,,,,,, +2023-09-12T20:45:47.119987064Z gnss[1694551547]:[ts2phc.0.config] ens6f0 gnss_status 3 offset 5 s2 +2023-09-12T20:45:47.163568885Z phc2sys[357154.598]: [ptp4l.0.config] CLOCK_REALTIME phc offset -3 s2 freq -10095 delay 505 +2023-09-12T20:45:47.171135783Z I0912 20:45:47.171116 161357 dpll.go:467] dpll decision: Status 3, Offset 0, In spec true, Source lost false, On holdover false +2023-09-12T20:45:47.171135783Z I0912 20:45:47.171129 161357 dpll.go:494] dpll is locked, source is not lost, offset is in range, state is DPLL_LOCKED_HO_ACQ or DPLL_HOLDOVER +2023-09-12T20:45:47.171163501Z I0912 20:45:47.171134 161357 dpll.go:540] dpll event sent +2023-09-12T20:45:47.181264902Z dpll[1694551547]:[ts2phc.0.config] ens6f0 frequency_status 3 offset -2 phase_status 3 s2 +2023-09-12T20:45:47.226121792Z phc2sys[357154.661]: [ptp4l.0.config] CLOCK_REALTIME phc offset -1 s2 freq -10094 delay 502 +2023-09-12T20:45:47.288743902Z phc2sys[357154.724]: [ptp4l.0.config] CLOCK_REALTIME phc offset -1 s2 freq -10094 delay 502 +2023-09-12T20:45:47.351301903Z phc2sys[357154.786]: [ptp4l.0.config] CLOCK_REALTIME phc offset 0 s2 freq -10094 delay 503 +2023-09-12T20:45:47.413881157Z phc2sys[357154.849]: [ptp4l.0.config] CLOCK_REALTIME phc offset -3 s2 freq -10097 delay 502 +2023-09-12T20:45:47.476453658Z phc2sys[357154.911]: [ptp4l.0.config] CLOCK_REALTIME phc offset -1 s2 freq -10095 delay 503 +2023-09-12T20:45:47.539039689Z phc2sys[357154.974]: [ptp4l.0.config] CLOCK_REALTIME phc offset -8 s2 freq -10103 delay 503 +2023-09-12T20:45:47.601623959Z phc2sys[357155.036]: [ptp4l.0.config] CLOCK_REALTIME phc offset -6 s2 freq -10103 delay 506 +2023-09-12T20:45:47.664308169Z phc2sys[357155.099]: [ptp4l.0.config] CLOCK_REALTIME phc offset -3 s2 freq -10102 delay 508 +2023-09-12T20:45:47.726826387Z phc2sys[357155.162]: [ptp4l.0.config] CLOCK_REALTIME phc offset -3 s2 freq -10103 delay 502 +2023-09-12T20:45:47.789406282Z phc2sys[357155.224]: [ptp4l.0.config] CLOCK_REALTIME phc offset -1 s2 freq -10102 delay 503 +2023-09-12T20:45:47.852003445Z phc2sys[357155.287]: [ptp4l.0.config] CLOCK_REALTIME phc offset -8 s2 freq -10109 delay 503 +2023-09-12T20:45:47.914584603Z phc2sys[357155.349]: [ptp4l.0.config] CLOCK_REALTIME phc offset -4 s2 freq -10107 delay 502 +2023-09-12T20:45:47.977169023Z phc2sys[357155.412]: [ptp4l.0.config] CLOCK_REALTIME phc offset 0 s2 freq -10105 delay 502 +2023-09-12T20:45:48.000063778Z ts2phc[357155.435]: [ts2phc.0.config] nmea delay: 109957909 ns +2023-09-12T20:45:48.000063778Z ts2phc[357155.435]: [ts2phc.0.config] ens6f0 extts index 0 at 1694551585.000000000 corr 0 src 1694551585.890064841 diff 0 +2023-09-12T20:45:48.000096516Z ts2phc[357155.435]: [ts2phc.0.config] ens6f0 master offset 0 s2 freq +0 +2023-09-12T20:45:48.002233246Z I0912 20:45:48.002215 161357 event.go:362] dpll State s2, gnss State s2, ts2phc state s2, gm state s2, +2023-09-12T20:45:48.039754479Z phc2sys[357155.475]: [ptp4l.0.config] CLOCK_REALTIME phc offset -4 s2 freq -10109 delay 502 +2023-09-12T20:45:48.102332753Z phc2sys[357155.537]: [ptp4l.0.config] CLOCK_REALTIME phc offset 0 s2 freq -10106 delay 503 +2023-09-12T20:45:48.121874478Z ts2phc[357155.557]: [ts2phc.0.config] nmea sentence: GNRMC,204548.00,A,4233.01593,N,07112.87880,W,0.016,,120923,,,A,V +2023-09-12T20:45:48.122540400Z ts2phc[357155.557]: [ts2phc.0.config] nmea sentence: GNGGA,204548.00,4233.01593,N,07112.87880,W,1,05,1.98,59.5,M,-33.0,M,, +2023-09-12T20:45:48.122589260Z ts2phc[357155.557]: [ts2phc.0.config] nmea sentence: GNGSA,A,3,10,12,23,28,32,,,,,,,,4.26,1.98,3.77,1 +2023-09-12T20:45:48.122622001Z ts2phc[357155.557]: [ts2phc.0.config] nmea sentence: GNGSA,A,3,,,,,,,,,,,,,4.26,1.98,3.77,5 +2023-09-12T20:45:48.122622001Z ts2phc[357155.557]: [ts2phc.0.config] nmea sentence: GPGSV,3,1,10,02,19,296,21,10,63,173,26,12,33,066,22,21,20,287,20,1 +2023-09-12T20:45:48.122622001Z ts2phc[357155.557]: [ts2phc.0.config] nmea sentence: GPGSV,3,2,10,23,25,153,20,24,09,056,16,25,45,120,23,28,50,237,23,1 +2023-09-12T20:45:48.122655457Z ts2phc[357155.557]: [ts2phc.0.config] nmea sentence: GPGSV,3,3,10,31,20,232,21,32,69,327,24,1 +2023-09-12T20:45:48.122655457Z ts2phc[357155.557]: [ts2phc.0.config] nmea sentence: GNGST,204548.00,41,14,11,122,4.8,5.5,11 +2023-09-12T20:45:48.122655457Z ts2phc[357155.557]: [ts2phc.0.config] nmea sentence: GNZDA,204548.00,12,09,2023,00,00 +2023-09-12T20:45:48.122655457Z ts2phc[357155.557]: [ts2phc.0.config] nmea sentence: GNGBS,204548.00,4.8,5.5,10.9,,,,,, +2023-09-12T20:45:48.124705797Z gnss[1694551548]:[ts2phc.0.config] ens6f0 gnss_status 3 offset 5 s2 +2023-09-12T20:45:48.164911442Z phc2sys[357155.600]: [ptp4l.0.config] CLOCK_REALTIME phc offset 1 s2 freq -10105 delay 503 +2023-09-12T20:45:48.171290311Z I0912 20:45:48.171269 161357 dpll.go:467] dpll decision: Status 3, Offset 0, In spec true, Source lost false, On holdover false +2023-09-12T20:45:48.171290311Z I0912 20:45:48.171284 161357 dpll.go:494] dpll is locked, source is not lost, offset is in range, state is DPLL_LOCKED_HO_ACQ or DPLL_HOLDOVER +2023-09-12T20:45:48.171316303Z I0912 20:45:48.171289 161357 dpll.go:540] dpll event sent +2023-09-12T20:45:48.176426873Z dpll[1694551548]:[ts2phc.0.config] ens6f0 frequency_status 3 offset -3 phase_status 3 s2 +2023-09-12T20:45:48.227493856Z phc2sys[357155.662]: [ptp4l.0.config] CLOCK_REALTIME phc offset 1 s2 freq -10105 delay 503 +2023-09-12T20:45:48.290068203Z phc2sys[357155.725]: [ptp4l.0.config] CLOCK_REALTIME phc offset 3 s2 freq -10102 delay 502 +2023-09-12T20:45:48.352648600Z phc2sys[357155.787]: [ptp4l.0.config] CLOCK_REALTIME phc offset -3 s2 freq -10107 delay 503 +2023-09-12T20:45:48.415224488Z phc2sys[357155.850]: [ptp4l.0.config] CLOCK_REALTIME phc offset -1 s2 freq -10106 delay 508 +2023-09-12T20:45:48.477815410Z phc2sys[357155.913]: [ptp4l.0.config] CLOCK_REALTIME phc offset 4 s2 freq -10102 delay 503 +2023-09-12T20:45:48.540399210Z phc2sys[357155.975]: [ptp4l.0.config] CLOCK_REALTIME phc offset -2 s2 freq -10106 delay 504 +2023-09-12T20:45:48.602990302Z phc2sys[357156.038]: [ptp4l.0.config] CLOCK_REALTIME phc offset 3 s2 freq -10102 delay 504 +2023-09-12T20:45:48.665567227Z phc2sys[357156.100]: [ptp4l.0.config] CLOCK_REALTIME phc offset 2 s2 freq -10102 delay 508 +2023-09-12T20:45:48.728145841Z phc2sys[357156.163]: [ptp4l.0.config] CLOCK_REALTIME phc offset -3 s2 freq -10106 delay 502 +2023-09-12T20:45:48.790731949Z phc2sys[357156.226]: [ptp4l.0.config] CLOCK_REALTIME phc offset 3 s2 freq -10101 delay 503 +2023-09-12T20:45:48.853292064Z phc2sys[357156.288]: [ptp4l.0.config] CLOCK_REALTIME phc offset 6 s2 freq -10097 delay 503 +2023-09-12T20:45:48.915866837Z phc2sys[357156.351]: [ptp4l.0.config] CLOCK_REALTIME phc offset -1 s2 freq -10103 delay 502 +2023-09-12T20:45:48.978449589Z phc2sys[357156.413]: [ptp4l.0.config] CLOCK_REALTIME phc offset 5 s2 freq -10097 delay 502 +2023-09-12T20:45:49.000100387Z ts2phc[357156.435]: [ts2phc.0.config] nmea delay: 121820476 ns +2023-09-12T20:45:49.000139771Z ts2phc[357156.435]: [ts2phc.0.config] ens6f0 extts index 0 at 1694551586.000000000 corr 0 src 1694551586.878205556 diff 0 +2023-09-12T20:45:49.000139771Z ts2phc[357156.435]: [ts2phc.0.config] ens6f0 master offset 0 s2 freq +0 +2023-09-12T20:45:49.007341840Z I0912 20:45:49.007323 161357 event.go:362] dpll State s2, gnss State s2, ts2phc state s2, gm state s2, +2023-09-12T20:45:49.041053052Z phc2sys[357156.476]: [ptp4l.0.config] CLOCK_REALTIME phc offset 2 s2 freq -10098 delay 508 +2023-09-12T20:45:49.103662061Z phc2sys[357156.538]: [ptp4l.0.config] CLOCK_REALTIME phc offset 1 s2 freq -10099 delay 499 +2023-09-12T20:45:49.112865990Z ts2phc[357156.547]: [ts2phc.0.config] nmea sentence: GNRMC,204549.00,A,4233.01592,N,07112.87882,W,0.016,,120923,,,A,V +2023-09-12T20:45:49.113143292Z ts2phc[357156.548]: [ts2phc.0.config] nmea sentence: GNGGA,204549.00,4233.01592,N,07112.87882,W,1,05,1.98,59.4,M,-33.0,M,, +2023-09-12T20:45:49.113208032Z ts2phc[357156.548]: [ts2phc.0.config] nmea sentence: GNGSA,A,3,10,12,23,28,32,,,,,,,,4.26,1.98,3.77,1 +2023-09-12T20:45:49.113239864Z ts2phc[357156.548]: [ts2phc.0.config] nmea sentence: GNGSA,A,3,,,,,,,,,,,,,4.26,1.98,3.77,5 +2023-09-12T20:45:49.113264861Z ts2phc[357156.548]: [ts2phc.0.config] nmea sentence: GPGSV,3,1,10,02,19,296,21,10,63,173,26,12,33,066,22,21,20,287,19,1 +2023-09-12T20:45:49.113303450Z ts2phc[357156.548]: [ts2phc.0.config] nmea sentence: GPGSV,3,2,10,23,25,153,20,24,09,056,15,25,45,120,23,28,50,237,23,1 +2023-09-12T20:45:49.113332226Z ts2phc[357156.548]: [ts2phc.0.config] nmea sentence: GPGSV,3,3,10,31,20,232,21,32,69,327,24,1 +2023-09-12T20:45:49.113332226Z ts2phc[357156.548]: [ts2phc.0.config] nmea sentence: GNGST,204549.00,41,14,11,122,4.8,5.5,11 +2023-09-12T20:45:49.113332226Z ts2phc[357156.548]: [ts2phc.0.config] nmea sentence: GNZDA,204549.00,12,09,2023,00,00 +2023-09-12T20:45:49.113332226Z ts2phc[357156.548]: [ts2phc.0.config] nmea sentence: GNGBS,204549.00,4.8,5.5,10.9,,,,,, +2023-09-12T20:45:49.120164779Z gnss[1694551549]:[ts2phc.0.config] ens6f0 gnss_status 3 offset 5 s2 +2023-09-12T20:45:49.166224096Z phc2sys[357156.601]: [ptp4l.0.config] CLOCK_REALTIME phc offset 0 s2 freq -10100 delay 502 +2023-09-12T20:45:49.171627998Z I0912 20:45:49.171606 161357 dpll.go:467] dpll decision: Status 3, Offset 0, In spec true, Source lost false, On holdover false +2023-09-12T20:45:49.171627998Z I0912 20:45:49.171623 161357 dpll.go:494] dpll is locked, source is not lost, offset is in range, state is DPLL_LOCKED_HO_ACQ or DPLL_HOLDOVER +2023-09-12T20:45:49.171673735Z I0912 20:45:49.171630 161357 dpll.go:540] dpll event sent +2023-09-12T20:45:49.181768932Z dpll[1694551549]:[ts2phc.0.config] ens6f0 frequency_status 3 offset 4 phase_status 3 s2 +2023-09-12T20:45:49.228828168Z phc2sys[357156.664]: [ptp4l.0.config] CLOCK_REALTIME phc offset -3 s2 freq -10103 delay 503 +2023-09-12T20:45:49.291501772Z phc2sys[357156.726]: [ptp4l.0.config] CLOCK_REALTIME phc offset 1 s2 freq -10099 delay 507 +2023-09-12T20:45:49.354062181Z phc2sys[357156.789]: [ptp4l.0.config] CLOCK_REALTIME phc offset -4 s2 freq -10104 delay 504 +2023-09-12T20:45:49.416663471Z phc2sys[357156.851]: [ptp4l.0.config] CLOCK_REALTIME phc offset 0 s2 freq -10101 delay 497 +2023-09-12T20:45:49.479252968Z phc2sys[357156.914]: [ptp4l.0.config] CLOCK_REALTIME phc offset -1 s2 freq -10102 delay 502 +2023-09-12T20:45:49.541828791Z phc2sys[357156.977]: [ptp4l.0.config] CLOCK_REALTIME phc offset 4 s2 freq -10098 delay 508 +2023-09-12T20:45:49.607725569Z phc2sys[357157.039]: [ptp4l.0.config] CLOCK_REALTIME phc offset -5 s2 freq -10105 delay 507 +2023-09-12T20:45:49.667077385Z phc2sys[357157.102]: [ptp4l.0.config] CLOCK_REALTIME phc offset 2 s2 freq -10100 delay 503 +2023-09-12T20:45:49.729641789Z phc2sys[357157.164]: [ptp4l.0.config] CLOCK_REALTIME phc offset 3 s2 freq -10098 delay 503 +2023-09-12T20:45:49.792219135Z phc2sys[357157.227]: [ptp4l.0.config] CLOCK_REALTIME phc offset 4 s2 freq -10096 delay 502 +2023-09-12T20:45:49.854821619Z phc2sys[357157.290]: [ptp4l.0.config] CLOCK_REALTIME phc offset -1 s2 freq -10100 delay 509 +2023-09-12T20:45:49.917406528Z phc2sys[357157.352]: [ptp4l.0.config] CLOCK_REALTIME phc offset 1 s2 freq -10099 delay 503 +2023-09-12T20:45:49.980001611Z phc2sys[357157.415]: [ptp4l.0.config] CLOCK_REALTIME phc offset -2 s2 freq -10101 delay 503 +2023-09-12T20:45:50.000062986Z ts2phc[357157.435]: [ts2phc.0.config] nmea delay: 112404091 ns +2023-09-12T20:45:50.000062986Z ts2phc[357157.435]: [ts2phc.0.config] ens6f0 extts index 0 at 1694551587.000000000 corr 0 src 1694551587.887619890 diff 0 +2023-09-12T20:45:50.000062986Z ts2phc[357157.435]: [ts2phc.0.config] ens6f0 master offset 0 s2 freq +0 +2023-09-12T20:45:50.008266938Z I0912 20:45:50.008248 161357 event.go:362] dpll State s2, gnss State s2, ts2phc state s2, gm state s2, +2023-09-12T20:45:50.042579131Z phc2sys[357157.477]: [ptp4l.0.config] CLOCK_REALTIME phc offset -1 s2 freq -10101 delay 504 +2023-09-12T20:45:50.105154664Z phc2sys[357157.540]: [ptp4l.0.config] CLOCK_REALTIME phc offset -1 s2 freq -10101 delay 503 +2023-09-12T20:45:50.121851730Z ts2phc[357157.557]: [ts2phc.0.config] nmea sentence: GNRMC,204550.00,A,4233.01591,N,07112.87883,W,0.016,,120923,,,A,V +2023-09-12T20:45:50.122394453Z ts2phc[357157.557]: [ts2phc.0.config] nmea sentence: GNGGA,204550.00,4233.01591,N,07112.87883,W,1,05,1.98,59.4,M,-33.0,M,, +2023-09-12T20:45:50.122394453Z ts2phc[357157.557]: [ts2phc.0.config] nmea sentence: GNGSA,A,3,10,12,23,28,32,,,,,,,,4.26,1.98,3.77,1 +2023-09-12T20:45:50.122394453Z ts2phc[357157.557]: [ts2phc.0.config] nmea sentence: GNGSA,A,3,,,,,,,,,,,,,4.26,1.98,3.77,5 +2023-09-12T20:45:50.122394453Z ts2phc[357157.557]: [ts2phc.0.config] nmea sentence: GPGSV,3,1,10,02,19,296,22,10,63,173,27,12,33,066,22,21,20,287,19,1 +2023-09-12T20:45:50.122394453Z ts2phc[357157.557]: [ts2phc.0.config] nmea sentence: GPGSV,3,2,10,23,25,153,20,24,09,056,16,25,45,120,23,28,50,237,23,1 +2023-09-12T20:45:50.122394453Z ts2phc[357157.557]: [ts2phc.0.config] nmea sentence: GPGSV,3,3,10,31,20,232,22,32,69,327,24,1 +2023-09-12T20:45:50.122394453Z ts2phc[357157.557]: [ts2phc.0.config] nmea sentence: GNGST,204550.00,41,14,11,122,4.8,5.5,11 +2023-09-12T20:45:50.122454864Z ts2phc[357157.557]: [ts2phc.0.config] nmea sentence: GNZDA,204550.00,12,09,2023,00,00 +2023-09-12T20:45:50.122545834Z ts2phc[357157.557]: [ts2phc.0.config] nmea sentence: GNGBS,204550.00,4.8,5.5,10.9,,,,,, +2023-09-12T20:45:50.130731327Z gnss[1694551550]:[ts2phc.0.config] ens6f0 gnss_status 3 offset 5 s2 +2023-09-12T20:45:50.167752851Z phc2sys[357157.603]: [ptp4l.0.config] CLOCK_REALTIME phc offset 0 s2 freq -10100 delay 497 +2023-09-12T20:45:50.171544501Z I0912 20:45:50.171507 161357 dpll.go:467] dpll decision: Status 3, Offset 0, In spec true, Source lost false, On holdover false +2023-09-12T20:45:50.172387378Z I0912 20:45:50.172367 161357 dpll.go:494] dpll is locked, source is not lost, offset is in range, state is DPLL_LOCKED_HO_ACQ or DPLL_HOLDOVER +2023-09-12T20:45:50.173240373Z I0912 20:45:50.172919 161357 dpll.go:540] dpll event sent +2023-09-12T20:45:50.182510255Z dpll[1694551550]:[ts2phc.0.config] ens6f0 frequency_status 3 offset 0 phase_status 3 s2 +2023-09-12T20:45:50.230329130Z phc2sys[357157.665]: [ptp4l.0.config] CLOCK_REALTIME phc offset -3 s2 freq -10103 delay 503 +2023-09-12T20:45:50.292925410Z phc2sys[357157.728]: [ptp4l.0.config] CLOCK_REALTIME phc offset -3 s2 freq -10104 delay 503 +2023-09-12T20:45:50.355498750Z phc2sys[357157.790]: [ptp4l.0.config] CLOCK_REALTIME phc offset 2 s2 freq -10100 delay 503 +2023-09-12T20:45:50.418082226Z phc2sys[357157.853]: [ptp4l.0.config] CLOCK_REALTIME phc offset 22 s2 freq -10080 delay 473 +2023-09-12T20:45:50.480660884Z phc2sys[357157.915]: [ptp4l.0.config] CLOCK_REALTIME phc offset -1 s2 freq -10096 delay 503 +2023-09-12T20:45:50.543252692Z phc2sys[357157.978]: [ptp4l.0.config] CLOCK_REALTIME phc offset 1 s2 freq -10094 delay 502 +2023-09-12T20:45:50.605935922Z phc2sys[357158.041]: [ptp4l.0.config] CLOCK_REALTIME phc offset 2 s2 freq -10093 delay 508 +2023-09-12T20:45:50.668413764Z phc2sys[357158.103]: [ptp4l.0.config] CLOCK_REALTIME phc offset 5 s2 freq -10089 delay 502 +2023-09-12T20:45:50.731001171Z phc2sys[357158.166]: [ptp4l.0.config] CLOCK_REALTIME phc offset -3 s2 freq -10096 delay 503 +2023-09-12T20:45:50.793589761Z phc2sys[357158.228]: [ptp4l.0.config] CLOCK_REALTIME phc offset 0 s2 freq -10094 delay 503 +2023-09-12T20:45:50.856185896Z phc2sys[357158.291]: [ptp4l.0.config] CLOCK_REALTIME phc offset -3 s2 freq -10097 delay 516 +2023-09-12T20:45:50.918764847Z phc2sys[357158.354]: [ptp4l.0.config] CLOCK_REALTIME phc offset 5 s2 freq -10090 delay 502 +2023-09-12T20:45:50.981334928Z phc2sys[357158.416]: [ptp4l.0.config] CLOCK_REALTIME phc offset 1 s2 freq -10092 delay 502 +2023-09-12T20:45:51.000076517Z ts2phc[357158.435]: [ts2phc.0.config] nmea delay: 121795513 ns +2023-09-12T20:45:51.000135371Z ts2phc[357158.435]: [ts2phc.0.config] ens6f0 extts index 0 at 1694551588.000000000 corr 0 src 1694551588.878229417 diff 0 +2023-09-12T20:45:51.000194720Z ts2phc[357158.435]: [ts2phc.0.config] ens6f0 master offset 0 s2 freq +0 +2023-09-12T20:45:51.003351258Z I0912 20:45:51.003333 161357 event.go:362] dpll State s2, gnss State s2, ts2phc state s2, gm state s2, +2023-09-12T20:45:51.043467141Z ts2phc[357158.478]: [ts2phc.0.config] nmea sentence: GNRMC,204551.00,A,4233.01591,N,07112.87883,W,0.016,,120923,,,A,V +2023-09-12T20:45:51.043967265Z phc2sys[357158.479]: [ptp4l.0.config] CLOCK_REALTIME phc offset 0 s2 freq -10093 delay 503 +2023-09-12T20:45:51.106506744Z phc2sys[357158.541]: [ptp4l.0.config] CLOCK_REALTIME phc offset 3 s2 freq -10090 delay 502 +2023-09-12T20:45:51.169114060Z phc2sys[357158.604]: [ptp4l.0.config] CLOCK_REALTIME phc offset 2 s2 freq -10090 delay 503 +2023-09-12T20:45:51.171575417Z I0912 20:45:51.171537 161357 dpll.go:467] dpll decision: Status 3, Offset 0, In spec true, Source lost false, On holdover false +2023-09-12T20:45:51.171602292Z I0912 20:45:51.171571 161357 dpll.go:494] dpll is locked, source is not lost, offset is in range, state is DPLL_LOCKED_HO_ACQ or DPLL_HOLDOVER +2023-09-12T20:45:51.171602292Z I0912 20:45:51.171586 161357 dpll.go:540] dpll event sent +2023-09-12T20:45:51.178694575Z dpll[1694551551]:[ts2phc.0.config] ens6f0 frequency_status 3 offset -2 phase_status 3 s2 +2023-09-12T20:45:51.211445030Z ts2phc[357158.646]: [ts2phc.0.config] nmea sentence: GNGGA,204551.00,4233.01591,N,07112.87883,W,1,05,1.98,59.3,M,-33.0,M,, +2023-09-12T20:45:51.211445030Z ts2phc[357158.646]: [ts2phc.0.config] nmea sentence: GNGSA,A,3,10,12,23,28,32,,,,,,,,4.26,1.98,3.77,1 +2023-09-12T20:45:51.211445030Z ts2phc[357158.646]: [ts2phc.0.config] nmea sentence: GNGSA,A,3,,,,,,,,,,,,,4.26,1.98,3.77,5 +2023-09-12T20:45:51.211502659Z ts2phc[357158.646]: [ts2phc.0.config] nmea sentence: GPGSV,3,1,10,02,19,296,22,10,63,173,27,12,33,066,21,21,20,287,18,1 +2023-09-12T20:45:51.211502659Z ts2phc[357158.646]: [ts2phc.0.config] nmea sentence: GPGSV,3,2,10,23,25,153,21,24,09,056,16,25,45,120,23,28,50,237,23,1 +2023-09-12T20:45:51.211709047Z ts2phc[357158.646]: [ts2phc.0.config] nmea sentence: GPGSV,3,3,10,31,20,232,22,32,69,327,24,1 +2023-09-12T20:45:51.211731496Z ts2phc[357158.647]: [ts2phc.0.config] nmea sentence: GNGST,204551.00,41,14,11,122,4.8,5.5,11 +2023-09-12T20:45:51.211731496Z ts2phc[357158.647]: [ts2phc.0.config] nmea sentence: GNZDA,204551.00,12,09,2023,00,00 +2023-09-12T20:45:51.211916444Z ts2phc[357158.647]: [ts2phc.0.config] nmea sentence: GNGBS,204551.00,4.8,5.5,10.9,,,,,, +2023-09-12T20:45:51.220063027Z gnss[1694551551]:[ts2phc.0.config] ens6f0 gnss_status 3 offset 5 s2 +2023-09-12T20:45:51.231693986Z phc2sys[357158.666]: [ptp4l.0.config] CLOCK_REALTIME phc offset -3 s2 freq -10094 delay 503 +2023-09-12T20:45:51.294320671Z phc2sys[357158.729]: [ptp4l.0.config] CLOCK_REALTIME phc offset 0 s2 freq -10092 delay 504 +2023-09-12T20:45:51.356879270Z phc2sys[357158.792]: [ptp4l.0.config] CLOCK_REALTIME phc offset 2 s2 freq -10090 delay 504 +2023-09-12T20:45:51.419454248Z phc2sys[357158.854]: [ptp4l.0.config] CLOCK_REALTIME phc offset 0 s2 freq -10092 delay 503 +2023-09-12T20:45:51.482033838Z phc2sys[357158.917]: [ptp4l.0.config] CLOCK_REALTIME phc offset 1 s2 freq -10091 delay 503 +2023-09-12T20:45:51.544624953Z phc2sys[357158.979]: [ptp4l.0.config] CLOCK_REALTIME phc offset -2 s2 freq -10093 delay 511 +2023-09-12T20:45:51.607255549Z phc2sys[357159.042]: [ptp4l.0.config] CLOCK_REALTIME phc offset -1 s2 freq -10093 delay 514 +2023-09-12T20:45:51.669849712Z phc2sys[357159.105]: [ptp4l.0.config] CLOCK_REALTIME phc offset -2 s2 freq -10094 delay 503 +2023-09-12T20:45:51.732440674Z phc2sys[357159.167]: [ptp4l.0.config] CLOCK_REALTIME phc offset 1 s2 freq -10092 delay 503 +2023-09-12T20:45:51.795034780Z phc2sys[357159.230]: [ptp4l.0.config] CLOCK_REALTIME phc offset -12 s2 freq -10105 delay 515 +2023-09-12T20:45:51.857629391Z phc2sys[357159.292]: [ptp4l.0.config] CLOCK_REALTIME phc offset -4 s2 freq -10100 delay 502 +2023-09-12T20:45:51.920198990Z phc2sys[357159.355]: [ptp4l.0.config] CLOCK_REALTIME phc offset -6 s2 freq -10103 delay 501 +2023-09-12T20:45:51.982810512Z phc2sys[357159.418]: [ptp4l.0.config] CLOCK_REALTIME phc offset -7 s2 freq -10106 delay 503 +2023-09-12T20:45:52.000084168Z ts2phc[357159.435]: [ts2phc.0.config] nmea delay: 43415441 ns +2023-09-12T20:45:52.000140568Z ts2phc[357159.435]: [ts2phc.0.config] ens6f0 extts index 0 at 1694551589.000000000 corr 0 src 1694551589.956607315 diff 0 +2023-09-12T20:45:52.000168271Z ts2phc[357159.435]: [ts2phc.0.config] ens6f0 master offset 0 s2 freq +0 +2023-09-12T20:45:52.000287782Z I0912 20:45:52.000267 161357 event.go:362] dpll State s2, gnss State s2, ts2phc state s2, gm state s2, +2023-09-12T20:45:52.045392079Z phc2sys[357159.480]: [ptp4l.0.config] CLOCK_REALTIME phc offset -6 s2 freq -10107 delay 503 +2023-09-12T20:45:52.068887138Z I0912 20:45:52.068857 161357 main.go:140] ticker pull +2023-09-12T20:45:52.107985718Z phc2sys[357159.543]: [ptp4l.0.config] CLOCK_REALTIME phc offset 0 s2 freq -10103 delay 513 +2023-09-12T20:45:52.121907579Z ts2phc[357159.557]: [ts2phc.0.config] nmea sentence: GNRMC,204552.00,A,4233.01590,N,07112.87883,W,0.016,,120923,,,A,V +2023-09-12T20:45:52.122366018Z ts2phc[357159.557]: [ts2phc.0.config] nmea sentence: GNGGA,204552.00,4233.01590,N,07112.87883,W,1,05,1.98,59.3,M,-33.0,M,, +2023-09-12T20:45:52.122406859Z ts2phc[357159.557]: [ts2phc.0.config] nmea sentence: GNGSA,A,3,10,12,23,28,32,,,,,,,,4.26,1.98,3.77,1 +2023-09-12T20:45:52.122475281Z ts2phc[357159.557]: [ts2phc.0.config] nmea sentence: GNGSA,A,3,,,,,,,,,,,,,4.26,1.98,3.77,5 +2023-09-12T20:45:52.122625653Z ts2phc[357159.557]: [ts2phc.0.config] nmea sentence: GPGSV,3,1,10,02,19,296,21,10,63,173,26,12,33,066,22,21,20,287,18,1 +2023-09-12T20:45:52.122625653Z ts2phc[357159.557]: [ts2phc.0.config] nmea sentence: GPGSV,3,2,10,23,25,153,21,24,09,056,15,25,45,120,23,28,50,237,23,1 +2023-09-12T20:45:52.122625653Z ts2phc[357159.557]: [ts2phc.0.config] nmea sentence: GPGSV,3,3,10,31,20,232,22,32,69,327,24,1 +2023-09-12T20:45:52.122625653Z ts2phc[357159.557]: [ts2phc.0.config] nmea sentence: GNGST,204552.00,41,14,11,122,4.8,5.5,11 +2023-09-12T20:45:52.122625653Z ts2phc[357159.557]: [ts2phc.0.config] nmea sentence: GNZDA,204552.00,12,09,2023,00,00 +2023-09-12T20:45:52.122625653Z ts2phc[357159.557]: [ts2phc.0.config] nmea sentence: GNGBS,204552.00,4.8,5.5,10.9,,,,,, +2023-09-12T20:45:52.123623422Z gnss[1694551552]:[ts2phc.0.config] ens6f0 gnss_status 3 offset 5 s2 +2023-09-12T20:45:52.170592703Z phc2sys[357159.605]: [ptp4l.0.config] CLOCK_REALTIME phc offset 0 s2 freq -10103 delay 503 +2023-09-12T20:45:52.170898248Z I0912 20:45:52.170860 161357 dpll.go:467] dpll decision: Status 3, Offset 0, In spec true, Source lost false, On holdover false +2023-09-12T20:45:52.170946225Z I0912 20:45:52.170932 161357 dpll.go:494] dpll is locked, source is not lost, offset is in range, state is DPLL_LOCKED_HO_ACQ or DPLL_HOLDOVER +2023-09-12T20:45:52.170974736Z I0912 20:45:52.170963 161357 dpll.go:540] dpll event sent +2023-09-12T20:45:52.174984489Z dpll[1694551552]:[ts2phc.0.config] ens6f0 frequency_status 3 offset -4 phase_status 3 s2 +2023-09-12T20:45:52.233453026Z phc2sys[357159.668]: [ptp4l.0.config] CLOCK_REALTIME phc offset -5 s2 freq -10108 delay 509 +2023-09-12T20:45:52.295996690Z phc2sys[357159.731]: [ptp4l.0.config] CLOCK_REALTIME phc offset 2 s2 freq -10103 delay 508 +2023-09-12T20:45:52.358631536Z phc2sys[357159.793]: [ptp4l.0.config] CLOCK_REALTIME phc offset 0 s2 freq -10104 delay 508 +2023-09-12T20:45:52.421191911Z phc2sys[357159.856]: [ptp4l.0.config] CLOCK_REALTIME phc offset 0 s2 freq -10104 delay 502 +2023-09-12T20:45:52.483845942Z phc2sys[357159.919]: [ptp4l.0.config] CLOCK_REALTIME phc offset 16 s2 freq -10088 delay 423 +2023-09-12T20:45:52.546382678Z phc2sys[357159.981]: [ptp4l.0.config] CLOCK_REALTIME phc offset 0 s2 freq -10099 delay 503 +2023-09-12T20:45:52.608967247Z phc2sys[357160.044]: [ptp4l.0.config] CLOCK_REALTIME phc offset 1 s2 freq -10098 delay 492 +2023-09-12T20:45:52.671618669Z phc2sys[357160.106]: [ptp4l.0.config] CLOCK_REALTIME phc offset 5 s2 freq -10094 delay 503 +2023-09-12T20:45:52.734185149Z phc2sys[357160.169]: [ptp4l.0.config] CLOCK_REALTIME phc offset 19 s2 freq -10078 delay 457 +2023-09-12T20:45:52.796779988Z phc2sys[357160.232]: [ptp4l.0.config] CLOCK_REALTIME phc offset 0 s2 freq -10092 delay 498 +2023-09-12T20:45:52.859373942Z phc2sys[357160.294]: [ptp4l.0.config] CLOCK_REALTIME phc offset 2 s2 freq -10090 delay 502 +2023-09-12T20:45:52.921957891Z phc2sys[357160.357]: [ptp4l.0.config] CLOCK_REALTIME phc offset 1 s2 freq -10090 delay 502 +2023-09-12T20:45:52.984574823Z phc2sys[357160.419]: [ptp4l.0.config] CLOCK_REALTIME phc offset -6 s2 freq -10097 delay 503 +2023-09-12T20:45:53.000084378Z ts2phc[357160.435]: [ts2phc.0.config] nmea delay: 121846077 ns +2023-09-12T20:45:53.000112512Z ts2phc[357160.435]: [ts2phc.0.config] ens6f0 extts index 0 at 1694551590.000000000 corr 0 src 1694551590.878183172 diff 0 +2023-09-12T20:45:53.000112512Z ts2phc[357160.435]: [ts2phc.0.config] ens6f0 master offset 0 s2 freq +0 +2023-09-12T20:45:53.005295241Z I0912 20:45:53.005276 161357 event.go:362] dpll State s2, gnss State s2, ts2phc state s2, gm state s2, +2023-09-12T20:45:53.047164381Z phc2sys[357160.482]: [ptp4l.0.config] CLOCK_REALTIME phc offset -2 s2 freq -10095 delay 499 +2023-09-12T20:45:53.109779230Z phc2sys[357160.545]: [ptp4l.0.config] CLOCK_REALTIME phc offset -1 s2 freq -10094 delay 503 +2023-09-12T20:45:53.122002735Z ts2phc[357160.557]: [ts2phc.0.config] nmea sentence: GNRMC,204553.00,A,4233.01589,N,07112.87882,W,0.016,,120923,,,A,V +2023-09-12T20:45:53.122651379Z ts2phc[357160.557]: [ts2phc.0.config] nmea sentence: GNGGA,204553.00,4233.01589,N,07112.87882,W,1,05,1.98,59.3,M,-33.0,M,, +2023-09-12T20:45:53.122651379Z ts2phc[357160.557]: [ts2phc.0.config] nmea sentence: GNGSA,A,3,10,12,23,28,32,,,,,,,,4.26,1.98,3.77,1 +2023-09-12T20:45:53.122651379Z ts2phc[357160.557]: [ts2phc.0.config] nmea sentence: GNGSA,A,3,,,,,,,,,,,,,4.26,1.98,3.77,5 +2023-09-12T20:45:53.122651379Z ts2phc[357160.557]: [ts2phc.0.config] nmea sentence: GPGSV,3,1,10,02,19,296,21,10,63,173,26,12,33,066,22,21,20,287,18,1 +2023-09-12T20:45:53.122673797Z ts2phc[357160.557]: [ts2phc.0.config] nmea sentence: GPGSV,3,2,10,23,25,153,21,24,09,056,15,25,45,120,23,28,50,237,23,1 +2023-09-12T20:45:53.122673797Z ts2phc[357160.557]: [ts2phc.0.config] nmea sentence: GPGSV,3,3,10,31,20,232,22,32,69,327,24,1 +2023-09-12T20:45:53.122673797Z ts2phc[357160.557]: [ts2phc.0.config] nmea sentence: GNGST,204553.00,41,14,11,122,4.8,5.5,11 +2023-09-12T20:45:53.122673797Z ts2phc[357160.557]: [ts2phc.0.config] nmea sentence: GNZDA,204553.00,12,09,2023,00,00 +2023-09-12T20:45:53.122673797Z ts2phc[357160.557]: [ts2phc.0.config] nmea sentence: GNGBS,204553.00,4.8,5.5,10.9,,,,,, +2023-09-12T20:45:53.128698724Z gnss[1694551553]:[ts2phc.0.config] ens6f0 gnss_status 3 offset 5 s2 +2023-09-12T20:45:53.170783874Z I0912 20:45:53.170765 161357 dpll.go:467] dpll decision: Status 3, Offset 0, In spec true, Source lost false, On holdover false +2023-09-12T20:45:53.170783874Z I0912 20:45:53.170778 161357 dpll.go:494] dpll is locked, source is not lost, offset is in range, state is DPLL_LOCKED_HO_ACQ or DPLL_HOLDOVER +2023-09-12T20:45:53.170819611Z I0912 20:45:53.170784 161357 dpll.go:540] dpll event sent +2023-09-12T20:45:53.172344241Z phc2sys[357160.607]: [ptp4l.0.config] CLOCK_REALTIME phc offset 28 s2 freq -10066 delay 451 +2023-09-12T20:45:53.180608100Z dpll[1694551553]:[ts2phc.0.config] ens6f0 frequency_status 3 offset -4 phase_status 3 s2 +2023-09-12T20:45:53.234941408Z phc2sys[357160.670]: [ptp4l.0.config] CLOCK_REALTIME phc offset 5 s2 freq -10080 delay 412 +2023-09-12T20:45:53.297507471Z phc2sys[357160.732]: [ptp4l.0.config] CLOCK_REALTIME phc offset 11 s2 freq -10073 delay 423 +2023-09-12T20:45:53.360316132Z phc2sys[357160.795]: [ptp4l.0.config] CLOCK_REALTIME phc offset -11 s2 freq -10091 delay 515 +2023-09-12T20:45:53.422705493Z phc2sys[357160.857]: [ptp4l.0.config] CLOCK_REALTIME phc offset -14 s2 freq -10098 delay 515 +2023-09-12T20:45:53.485317546Z phc2sys[357160.920]: [ptp4l.0.config] CLOCK_REALTIME phc offset 9 s2 freq -10079 delay 414 +2023-09-12T20:45:53.547917020Z phc2sys[357160.983]: [ptp4l.0.config] CLOCK_REALTIME phc offset -10 s2 freq -10095 delay 504 +2023-09-12T20:45:53.610535713Z phc2sys[357161.045]: [ptp4l.0.config] CLOCK_REALTIME phc offset -7 s2 freq -10095 delay 501 +2023-09-12T20:45:53.673136283Z phc2sys[357161.108]: [ptp4l.0.config] CLOCK_REALTIME phc offset -14 s2 freq -10104 delay 503 +2023-09-12T20:45:53.735767049Z phc2sys[357161.171]: [ptp4l.0.config] CLOCK_REALTIME phc offset 3 s2 freq -10091 delay 457 +2023-09-12T20:45:53.798358061Z phc2sys[357161.233]: [ptp4l.0.config] CLOCK_REALTIME phc offset -13 s2 freq -10107 delay 510 +2023-09-12T20:45:53.860938607Z phc2sys[357161.296]: [ptp4l.0.config] CLOCK_REALTIME phc offset 7 s2 freq -10090 delay 469 +2023-09-12T20:45:53.923579665Z phc2sys[357161.358]: [ptp4l.0.config] CLOCK_REALTIME phc offset -14 s2 freq -10109 delay 506 +2023-09-12T20:45:53.986104812Z phc2sys[357161.421]: [ptp4l.0.config] CLOCK_REALTIME phc offset -13 s2 freq -10113 delay 499 +2023-09-12T20:45:54.000073887Z ts2phc[357161.435]: [ts2phc.0.config] nmea delay: 121790902 ns +2023-09-12T20:45:54.000106970Z ts2phc[357161.435]: [ts2phc.0.config] ens6f0 extts index 0 at 1694551591.000000000 corr 0 src 1694551591.878232372 diff 0 +2023-09-12T20:45:54.000106970Z ts2phc[357161.435]: [ts2phc.0.config] ens6f0 master offset 0 s2 freq +0 +2023-09-12T20:45:54.001239765Z I0912 20:45:54.001221 161357 event.go:362] dpll State s2, gnss State s2, ts2phc state s2, gm state s2, +2023-09-12T20:45:54.048681807Z phc2sys[357161.483]: [ptp4l.0.config] CLOCK_REALTIME phc offset -11 s2 freq -10114 delay 509 +2023-09-12T20:45:54.111258753Z phc2sys[357161.546]: [ptp4l.0.config] CLOCK_REALTIME phc offset -25 s2 freq -10132 delay 471 +2023-09-12T20:45:54.121881466Z ts2phc[357161.557]: [ts2phc.0.config] nmea sentence: GNRMC,204554.00,A,4233.01588,N,07112.87882,W,0.016,,120923,,,A,V +2023-09-12T20:45:54.122682505Z ts2phc[357161.557]: [ts2phc.0.config] nmea sentence: GNGGA,204554.00,4233.01588,N,07112.87882,W,1,05,1.98,59.2,M,-33.0,M,, +2023-09-12T20:45:54.122738140Z ts2phc[357161.557]: [ts2phc.0.config] nmea sentence: GNGSA,A,3,10,12,23,28,32,,,,,,,,4.26,1.98,3.77,1 +2023-09-12T20:45:54.122782755Z ts2phc[357161.557]: [ts2phc.0.config] nmea sentence: GNGSA,A,3,,,,,,,,,,,,,4.26,1.98,3.77,5 +2023-09-12T20:45:54.122815816Z ts2phc[357161.557]: [ts2phc.0.config] nmea sentence: GPGSV,3,1,10,02,19,296,21,10,63,173,26,12,33,066,22,21,20,287,18,1 +2023-09-12T20:45:54.122815816Z ts2phc[357161.557]: [ts2phc.0.config] nmea sentence: GPGSV,3,2,10,23,25,153,21,24,09,056,14,25,45,120,23,28,50,237,23,1 +2023-09-12T20:45:54.122815816Z ts2phc[357161.557]: [ts2phc.0.config] nmea sentence: GPGSV,3,3,10,31,20,232,22,32,69,327,24,1 +2023-09-12T20:45:54.122815816Z ts2phc[357161.557]: [ts2phc.0.config] nmea sentence: GNGST,204554.00,41,14,11,122,4.8,5.5,11 +2023-09-12T20:45:54.122815816Z ts2phc[357161.557]: [ts2phc.0.config] nmea sentence: GNZDA,204554.00,12,09,2023,00,00 +2023-09-12T20:45:54.122815816Z ts2phc[357161.557]: [ts2phc.0.config] nmea sentence: GNGBS,204554.00,4.8,5.5,10.9,,,,,, +2023-09-12T20:45:54.124891772Z gnss[1694551554]:[ts2phc.0.config] ens6f0 gnss_status 3 offset 5 s2 +2023-09-12T20:45:54.170915655Z I0912 20:45:54.170892 161357 dpll.go:467] dpll decision: Status 3, Offset 0, In spec true, Source lost false, On holdover false +2023-09-12T20:45:54.170915655Z I0912 20:45:54.170910 161357 dpll.go:494] dpll is locked, source is not lost, offset is in range, state is DPLL_LOCKED_HO_ACQ or DPLL_HOLDOVER +2023-09-12T20:45:54.170943299Z I0912 20:45:54.170918 161357 dpll.go:540] dpll event sent +2023-09-12T20:45:54.173845545Z phc2sys[357161.609]: [ptp4l.0.config] CLOCK_REALTIME phc offset -10 s2 freq -10124 delay 515 +2023-09-12T20:45:54.176066181Z dpll[1694551554]:[ts2phc.0.config] ens6f0 frequency_status 3 offset 1 phase_status 3 s2 +2023-09-12T20:45:54.236434482Z phc2sys[357161.671]: [ptp4l.0.config] CLOCK_REALTIME phc offset -1 s2 freq -10118 delay 503 +2023-09-12T20:45:54.299054933Z phc2sys[357161.734]: [ptp4l.0.config] CLOCK_REALTIME phc offset -5 s2 freq -10123 delay 502 +2023-09-12T20:45:54.361626335Z phc2sys[357161.796]: [ptp4l.0.config] CLOCK_REALTIME phc offset 4 s2 freq -10115 delay 502 +2023-09-12T20:45:54.424203771Z phc2sys[357161.859]: [ptp4l.0.config] CLOCK_REALTIME phc offset 2 s2 freq -10116 delay 503 +2023-09-12T20:45:54.486775848Z phc2sys[357161.922]: [ptp4l.0.config] CLOCK_REALTIME phc offset 6 s2 freq -10111 delay 503 +2023-09-12T20:45:54.549358420Z phc2sys[357161.984]: [ptp4l.0.config] CLOCK_REALTIME phc offset 1 s2 freq -10114 delay 503 +2023-09-12T20:45:54.611918856Z phc2sys[357162.047]: [ptp4l.0.config] CLOCK_REALTIME phc offset 6 s2 freq -10109 delay 499 +2023-09-12T20:45:54.674493875Z phc2sys[357162.109]: [ptp4l.0.config] CLOCK_REALTIME phc offset 8 s2 freq -10105 delay 503 +2023-09-12T20:45:54.737073597Z phc2sys[357162.172]: [ptp4l.0.config] CLOCK_REALTIME phc offset 6 s2 freq -10105 delay 500 +2023-09-12T20:45:54.799654298Z phc2sys[357162.234]: [ptp4l.0.config] CLOCK_REALTIME phc offset 2 s2 freq -10107 delay 503 +2023-09-12T20:45:54.862220152Z phc2sys[357162.297]: [ptp4l.0.config] CLOCK_REALTIME phc offset 5 s2 freq -10104 delay 501 +2023-09-12T20:45:54.924803353Z phc2sys[357162.360]: [ptp4l.0.config] CLOCK_REALTIME phc offset 6 s2 freq -10101 delay 510 +2023-09-12T20:45:54.987440609Z phc2sys[357162.422]: [ptp4l.0.config] CLOCK_REALTIME phc offset 8 s2 freq -10097 delay 506 +2023-09-12T20:45:55.000088102Z ts2phc[357162.435]: [ts2phc.0.config] nmea delay: 121831591 ns +2023-09-12T20:45:55.000144757Z ts2phc[357162.435]: [ts2phc.0.config] ens6f0 extts index 0 at 1694551592.000000000 corr 0 src 1694551592.878195081 diff 0 +2023-09-12T20:45:55.000197576Z ts2phc[357162.435]: [ts2phc.0.config] ens6f0 master offset 0 s2 freq +0 +2023-09-12T20:45:55.007413153Z I0912 20:45:55.007388 161357 event.go:362] dpll State s2, gnss State s2, ts2phc state s2, gm state s2, +2023-09-12T20:45:55.050025097Z phc2sys[357162.485]: [ptp4l.0.config] CLOCK_REALTIME phc offset 8 s2 freq -10095 delay 500 +2023-09-12T20:45:55.112615688Z phc2sys[357162.547]: [ptp4l.0.config] CLOCK_REALTIME phc offset 7 s2 freq -10093 delay 500 +2023-09-12T20:45:55.116994336Z ts2phc[357162.552]: [ts2phc.0.config] nmea sentence: GNRMC,204555.00,A,4233.01588,N,07112.87881,W,0.015,,120923,,,A,V +2023-09-12T20:45:55.117451620Z ts2phc[357162.552]: [ts2phc.0.config] nmea sentence: GNGGA,204555.00,4233.01588,N,07112.87881,W,1,05,1.98,59.2,M,-33.0,M,, +2023-09-12T20:45:55.117624639Z ts2phc[357162.552]: [ts2phc.0.config] nmea sentence: GNGSA,A,3,10,12,23,28,32,,,,,,,,4.26,1.98,3.77,1 +2023-09-12T20:45:55.117624639Z ts2phc[357162.552]: [ts2phc.0.config] nmea sentence: GNGSA,A,3,,,,,,,,,,,,,4.26,1.98,3.77,5 +2023-09-12T20:45:55.117624639Z ts2phc[357162.552]: [ts2phc.0.config] nmea sentence: GPGSV,3,1,10,02,19,296,21,10,63,173,26,12,33,066,22,21,20,287,18,1 +2023-09-12T20:45:55.117624639Z ts2phc[357162.552]: [ts2phc.0.config] nmea sentence: GPGSV,3,2,10,23,25,153,21,24,09,056,15,25,45,120,23,28,50,237,24,1 +2023-09-12T20:45:55.117624639Z ts2phc[357162.552]: [ts2phc.0.config] nmea sentence: GPGSV,3,3,10,31,20,232,22,32,69,327,24,1 +2023-09-12T20:45:55.117624639Z ts2phc[357162.552]: [ts2phc.0.config] nmea sentence: GNGST,204555.00,40,14,11,122,4.8,5.5,11 +2023-09-12T20:45:55.117624639Z ts2phc[357162.552]: [ts2phc.0.config] nmea sentence: GNZDA,204555.00,12,09,2023,00,00 +2023-09-12T20:45:55.117624639Z ts2phc[357162.552]: [ts2phc.0.config] nmea sentence: GNGBS,204555.00,4.8,5.5,10.9,,,,,, +2023-09-12T20:45:55.119739635Z gnss[1694551555]:[ts2phc.0.config] ens6f0 gnss_status 3 offset 5 s2 +2023-09-12T20:45:55.171070925Z I0912 20:45:55.171038 161357 dpll.go:467] dpll decision: Status 3, Offset 0, In spec true, Source lost false, On holdover false +2023-09-12T20:45:55.171129347Z I0912 20:45:55.171113 161357 dpll.go:494] dpll is locked, source is not lost, offset is in range, state is DPLL_LOCKED_HO_ACQ or DPLL_HOLDOVER +2023-09-12T20:45:55.171164956Z I0912 20:45:55.171150 161357 dpll.go:540] dpll event sent +2023-09-12T20:45:55.172112841Z dpll[1694551555]:[ts2phc.0.config] ens6f0 frequency_status 3 offset 0 phase_status 3 s2 +2023-09-12T20:45:55.175249089Z phc2sys[357162.610]: [ptp4l.0.config] CLOCK_REALTIME phc offset 5 s2 freq -10093 delay 508 +2023-09-12T20:45:55.237826663Z phc2sys[357162.673]: [ptp4l.0.config] CLOCK_REALTIME phc offset 6 s2 freq -10091 delay 502 +2023-09-12T20:45:55.300420995Z phc2sys[357162.735]: [ptp4l.0.config] CLOCK_REALTIME phc offset 3 s2 freq -10092 delay 505 +2023-09-12T20:45:55.363014792Z phc2sys[357162.798]: [ptp4l.0.config] CLOCK_REALTIME phc offset 5 s2 freq -10089 delay 503 +2023-09-12T20:45:55.425585997Z phc2sys[357162.860]: [ptp4l.0.config] CLOCK_REALTIME phc offset 2 s2 freq -10091 delay 499 +2023-09-12T20:45:55.488176389Z phc2sys[357162.923]: [ptp4l.0.config] CLOCK_REALTIME phc offset 2 s2 freq -10090 delay 503 +2023-09-12T20:45:55.550788741Z phc2sys[357162.986]: [ptp4l.0.config] CLOCK_REALTIME phc offset -13 s2 freq -10104 delay 493 +2023-09-12T20:45:55.613439504Z phc2sys[357163.048]: [ptp4l.0.config] CLOCK_REALTIME phc offset -2 s2 freq -10097 delay 516 +2023-09-12T20:45:55.676050538Z phc2sys[357163.111]: [ptp4l.0.config] CLOCK_REALTIME phc offset -1 s2 freq -10097 delay 506 +2023-09-12T20:45:55.738706168Z phc2sys[357163.173]: [ptp4l.0.config] CLOCK_REALTIME phc offset -2 s2 freq -10098 delay 515 +2023-09-12T20:45:55.801281124Z phc2sys[357163.236]: [ptp4l.0.config] CLOCK_REALTIME phc offset 3 s2 freq -10094 delay 503 +2023-09-12T20:45:55.863880901Z phc2sys[357163.299]: [ptp4l.0.config] CLOCK_REALTIME phc offset 2 s2 freq -10094 delay 503 +2023-09-12T20:45:55.926467007Z phc2sys[357163.361]: [ptp4l.0.config] CLOCK_REALTIME phc offset -3 s2 freq -10098 delay 502 +2023-09-12T20:45:55.989058670Z phc2sys[357163.424]: [ptp4l.0.config] CLOCK_REALTIME phc offset -2 s2 freq -10098 delay 503 +2023-09-12T20:45:56.000068240Z ts2phc[357163.435]: [ts2phc.0.config] nmea delay: 116900440 ns +2023-09-12T20:45:56.000068240Z ts2phc[357163.435]: [ts2phc.0.config] ens6f0 extts index 0 at 1694551593.000000000 corr 0 src 1694551593.883123599 diff 0 +2023-09-12T20:45:56.000100691Z ts2phc[357163.435]: [ts2phc.0.config] ens6f0 master offset 0 s2 freq +0 +2023-09-12T20:45:56.004284319Z I0912 20:45:56.004265 161357 event.go:362] dpll State s2, gnss State s2, ts2phc state s2, gm state s2, +2023-09-12T20:45:56.051655369Z phc2sys[357163.486]: [ptp4l.0.config] CLOCK_REALTIME phc offset 1 s2 freq -10096 delay 502 +2023-09-12T20:45:56.114249287Z phc2sys[357163.549]: [ptp4l.0.config] CLOCK_REALTIME phc offset 2 s2 freq -10095 delay 503 +2023-09-12T20:45:56.114906065Z ts2phc[357163.550]: [ts2phc.0.config] nmea sentence: GNRMC,204556.00,A,4233.01587,N,07112.87880,W,0.015,,120923,,,A,V +2023-09-12T20:45:56.115361703Z ts2phc[357163.550]: [ts2phc.0.config] nmea sentence: GNGGA,204556.00,4233.01587,N,07112.87880,W,1,05,1.98,59.1,M,-33.0,M,, +2023-09-12T20:45:56.115361703Z ts2phc[357163.550]: [ts2phc.0.config] nmea sentence: GNGSA,A,3,10,12,23,28,32,,,,,,,,4.26,1.98,3.77,1 +2023-09-12T20:45:56.115361703Z ts2phc[357163.550]: [ts2phc.0.config] nmea sentence: GNGSA,A,3,,,,,,,,,,,,,4.26,1.98,3.77,5 +2023-09-12T20:45:56.115361703Z ts2phc[357163.550]: [ts2phc.0.config] nmea sentence: GPGSV,3,1,10,02,19,296,21,10,63,173,26,12,33,066,22,21,20,287,18,1 +2023-09-12T20:45:56.115361703Z ts2phc[357163.550]: [ts2phc.0.config] nmea sentence: GPGSV,3,2,10,23,25,153,21,24,09,056,14,25,45,120,23,28,50,237,23,1 +2023-09-12T20:45:56.115361703Z ts2phc[357163.550]: [ts2phc.0.config] nmea sentence: GPGSV,3,3,10,31,20,232,22,32,69,327,24,1 +2023-09-12T20:45:56.115385238Z ts2phc[357163.550]: [ts2phc.0.config] nmea sentence: GNGST,204556.00,41,14,11,122,4.8,5.5,11 +2023-09-12T20:45:56.115385238Z ts2phc[357163.550]: [ts2phc.0.config] nmea sentence: GNZDA,204556.00,12,09,2023,00,00 +2023-09-12T20:45:56.115487737Z ts2phc[357163.550]: [ts2phc.0.config] nmea sentence: GNGBS,204556.00,4.8,5.5,11.0,,,,,, +2023-09-12T20:45:56.117659243Z gnss[1694551556]:[ts2phc.0.config] ens6f0 gnss_status 3 offset 5 s2 +2023-09-12T20:45:56.170925432Z I0912 20:45:56.170906 161357 dpll.go:467] dpll decision: Status 3, Offset 0, In spec true, Source lost false, On holdover false +2023-09-12T20:45:56.170925432Z I0912 20:45:56.170919 161357 dpll.go:494] dpll is locked, source is not lost, offset is in range, state is DPLL_LOCKED_HO_ACQ or DPLL_HOLDOVER +2023-09-12T20:45:56.170975796Z I0912 20:45:56.170924 161357 dpll.go:540] dpll event sent +2023-09-12T20:45:56.176827652Z phc2sys[357163.612]: [ptp4l.0.config] CLOCK_REALTIME phc offset 1 s2 freq -10095 delay 503 +2023-09-12T20:45:56.179028905Z dpll[1694551556]:[ts2phc.0.config] ens6f0 frequency_status 3 offset -3 phase_status 3 s2 +2023-09-12T20:45:56.239408431Z phc2sys[357163.674]: [ptp4l.0.config] CLOCK_REALTIME phc offset -3 s2 freq -10099 delay 503 +2023-09-12T20:45:56.301998621Z phc2sys[357163.737]: [ptp4l.0.config] CLOCK_REALTIME phc offset -1 s2 freq -10098 delay 502 +2023-09-12T20:45:56.364559300Z phc2sys[357163.799]: [ptp4l.0.config] CLOCK_REALTIME phc offset 4 s2 freq -10093 delay 504 +2023-09-12T20:45:56.427132773Z phc2sys[357163.862]: [ptp4l.0.config] CLOCK_REALTIME phc offset 5 s2 freq -10091 delay 503 +2023-09-12T20:45:56.489749735Z phc2sys[357163.925]: [ptp4l.0.config] CLOCK_REALTIME phc offset -1 s2 freq -10095 delay 503 +2023-09-12T20:45:56.552330289Z phc2sys[357163.987]: [ptp4l.0.config] CLOCK_REALTIME phc offset 6 s2 freq -10088 delay 502 +2023-09-12T20:45:56.614907166Z phc2sys[357164.050]: [ptp4l.0.config] CLOCK_REALTIME phc offset -2 s2 freq -10095 delay 503 +2023-09-12T20:45:56.677494909Z phc2sys[357164.112]: [ptp4l.0.config] CLOCK_REALTIME phc offset 1 s2 freq -10092 delay 502 +2023-09-12T20:45:56.740090387Z phc2sys[357164.175]: [ptp4l.0.config] CLOCK_REALTIME phc offset 0 s2 freq -10093 delay 498 +2023-09-12T20:45:56.802660171Z phc2sys[357164.237]: [ptp4l.0.config] CLOCK_REALTIME phc offset -2 s2 freq -10095 delay 505 +2023-09-12T20:45:56.865303595Z phc2sys[357164.300]: [ptp4l.0.config] CLOCK_REALTIME phc offset -1 s2 freq -10095 delay 509 +2023-09-12T20:45:56.927828316Z phc2sys[357164.363]: [ptp4l.0.config] CLOCK_REALTIME phc offset -3 s2 freq -10097 delay 504 +2023-09-12T20:45:56.990435640Z phc2sys[357164.425]: [ptp4l.0.config] CLOCK_REALTIME phc offset 3 s2 freq -10092 delay 502 +2023-09-12T20:45:57.000091107Z ts2phc[357164.435]: [ts2phc.0.config] nmea delay: 114829942 ns +2023-09-12T20:45:57.000123383Z ts2phc[357164.435]: [ts2phc.0.config] ens6f0 extts index 0 at 1694551594.000000000 corr 0 src 1694551594.885193460 diff 0 +2023-09-12T20:45:57.000123383Z ts2phc[357164.435]: [ts2phc.0.config] ens6f0 master offset 0 s2 freq +0 +2023-09-12T20:45:57.010321587Z I0912 20:45:57.010302 161357 event.go:362] dpll State s2, gnss State s2, ts2phc state s2, gm state s2, +2023-09-12T20:45:57.052995539Z phc2sys[357164.488]: [ptp4l.0.config] CLOCK_REALTIME phc offset 3 s2 freq -10091 delay 503 +2023-09-12T20:45:57.109584161Z ts2phc[357164.544]: [ts2phc.0.config] nmea sentence: GNRMC,204557.00,A,4233.01586,N,07112.87878,W,0.015,,120923,,,A,V +2023-09-12T20:45:57.110097110Z ts2phc[357164.545]: [ts2phc.0.config] nmea sentence: GNGGA,204557.00,4233.01586,N,07112.87878,W,1,05,1.99,59.1,M,-33.0,M,, +2023-09-12T20:45:57.110148848Z ts2phc[357164.545]: [ts2phc.0.config] nmea sentence: GNGSA,A,3,10,12,23,28,32,,,,,,,,4.26,1.99,3.77,1 +2023-09-12T20:45:57.110148848Z ts2phc[357164.545]: [ts2phc.0.config] nmea sentence: GNGSA,A,3,,,,,,,,,,,,,4.26,1.99,3.77,5 +2023-09-12T20:45:57.110205144Z ts2phc[357164.545]: [ts2phc.0.config] nmea sentence: GPGSV,3,1,10,02,19,296,21,10,63,173,27,12,33,066,22,21,20,287,18,1 +2023-09-12T20:45:57.110238428Z ts2phc[357164.545]: [ts2phc.0.config] nmea sentence: GPGSV,3,2,10,23,25,153,21,24,09,056,14,25,45,120,23,28,50,237,23,1 +2023-09-12T20:45:57.110264335Z ts2phc[357164.545]: [ts2phc.0.config] nmea sentence: GPGSV,3,3,10,31,20,232,22,32,69,327,24,1 +2023-09-12T20:45:57.110298877Z ts2phc[357164.545]: [ts2phc.0.config] nmea sentence: GNGST,204557.00,40,14,11,122,4.8,5.5,11 +2023-09-12T20:45:57.110298877Z ts2phc[357164.545]: [ts2phc.0.config] nmea sentence: GNZDA,204557.00,12,09,2023,00,00 +2023-09-12T20:45:57.110298877Z ts2phc[357164.545]: [ts2phc.0.config] nmea sentence: GNGBS,204557.00,4.8,5.5,11.0,,,,,, +2023-09-12T20:45:57.112272875Z gnss[1694551557]:[ts2phc.0.config] ens6f0 gnss_status 3 offset 5 s2 +2023-09-12T20:45:57.115572988Z phc2sys[357164.550]: [ptp4l.0.config] CLOCK_REALTIME phc offset 3 s2 freq -10090 delay 503 +2023-09-12T20:45:57.170963483Z I0912 20:45:57.170927 161357 dpll.go:467] dpll decision: Status 3, Offset 0, In spec true, Source lost false, On holdover false +2023-09-12T20:45:57.170963483Z I0912 20:45:57.170946 161357 dpll.go:494] dpll is locked, source is not lost, offset is in range, state is DPLL_LOCKED_HO_ACQ or DPLL_HOLDOVER +2023-09-12T20:45:57.171042402Z I0912 20:45:57.171016 161357 dpll.go:540] dpll event sent +2023-09-12T20:45:57.174195197Z dpll[1694551557]:[ts2phc.0.config] ens6f0 frequency_status 3 offset 3 phase_status 3 s2 +2023-09-12T20:45:57.178188608Z phc2sys[357164.613]: [ptp4l.0.config] CLOCK_REALTIME phc offset -4 s2 freq -10096 delay 503 +2023-09-12T20:45:57.240747204Z phc2sys[357164.676]: [ptp4l.0.config] CLOCK_REALTIME phc offset -6 s2 freq -10099 delay 502 +2023-09-12T20:45:57.303328248Z phc2sys[357164.738]: [ptp4l.0.config] CLOCK_REALTIME phc offset 1 s2 freq -10094 delay 503 +2023-09-12T20:45:57.365916042Z phc2sys[357164.801]: [ptp4l.0.config] CLOCK_REALTIME phc offset -2 s2 freq -10097 delay 503 +2023-09-12T20:45:57.428509066Z phc2sys[357164.863]: [ptp4l.0.config] CLOCK_REALTIME phc offset 11 s2 freq -10084 delay 483 +2023-09-12T20:45:57.491107890Z phc2sys[357164.926]: [ptp4l.0.config] CLOCK_REALTIME phc offset -6 s2 freq -10098 delay 504 +2023-09-12T20:45:57.553677322Z phc2sys[357164.988]: [ptp4l.0.config] CLOCK_REALTIME phc offset -2 s2 freq -10096 delay 502 +2023-09-12T20:45:57.616285105Z phc2sys[357165.051]: [ptp4l.0.config] CLOCK_REALTIME phc offset -2 s2 freq -10096 delay 509 +2023-09-12T20:45:57.678890957Z phc2sys[357165.114]: [ptp4l.0.config] CLOCK_REALTIME phc offset -6 s2 freq -10101 delay 504 +2023-09-12T20:45:57.741449984Z phc2sys[357165.176]: [ptp4l.0.config] CLOCK_REALTIME phc offset -3 s2 freq -10100 delay 503 +2023-09-12T20:45:57.804036839Z phc2sys[357165.239]: [ptp4l.0.config] CLOCK_REALTIME phc offset -6 s2 freq -10104 delay 503 +2023-09-12T20:45:57.866645168Z phc2sys[357165.301]: [ptp4l.0.config] CLOCK_REALTIME phc offset -5 s2 freq -10105 delay 508 +2023-09-12T20:45:57.929235217Z phc2sys[357165.364]: [ptp4l.0.config] CLOCK_REALTIME phc offset -5 s2 freq -10106 delay 503 +2023-09-12T20:45:57.991796006Z phc2sys[357165.427]: [ptp4l.0.config] CLOCK_REALTIME phc offset -3 s2 freq -10106 delay 503 +2023-09-12T20:45:58.000073997Z ts2phc[357165.435]: [ts2phc.0.config] nmea delay: 109527177 ns +2023-09-12T20:45:58.000073997Z ts2phc[357165.435]: [ts2phc.0.config] ens6f0 extts index 0 at 1694551595.000000000 corr 0 src 1694551595.890495868 diff 0 +2023-09-12T20:45:58.000104488Z ts2phc[357165.435]: [ts2phc.0.config] ens6f0 master offset 0 s2 freq +0 +2023-09-12T20:45:58.005271519Z I0912 20:45:58.005251 161357 event.go:362] dpll State s2, gnss State s2, ts2phc state s2, gm state s2, +2023-09-12T20:45:58.054503429Z phc2sys[357165.489]: [ptp4l.0.config] CLOCK_REALTIME phc offset -1 s2 freq -10104 delay 507 +2023-09-12T20:45:58.109073510Z ts2phc[357165.544]: [ts2phc.0.config] nmea sentence: GNRMC,204558.00,A,4233.01584,N,07112.87876,W,0.015,,120923,,,A,V +2023-09-12T20:45:58.109686971Z ts2phc[357165.544]: [ts2phc.0.config] nmea sentence: GNGGA,204558.00,4233.01584,N,07112.87876,W,1,05,1.99,59.1,M,-33.0,M,, +2023-09-12T20:45:58.109776540Z ts2phc[357165.544]: [ts2phc.0.config] nmea sentence: GNGSA,A,3,10,12,23,28,32,,,,,,,,4.26,1.99,3.77,1 +2023-09-12T20:45:58.109776540Z ts2phc[357165.544]: [ts2phc.0.config] nmea sentence: GNGSA,A,3,,,,,,,,,,,,,4.26,1.99,3.77,5 +2023-09-12T20:45:58.109776540Z ts2phc[357165.544]: [ts2phc.0.config] nmea sentence: GPGSV,3,1,10,02,19,295,21,10,63,173,27,12,33,066,22,21,20,287,18,1 +2023-09-12T20:45:58.109776540Z ts2phc[357165.544]: [ts2phc.0.config] nmea sentence: GPGSV,3,2,10,23,25,153,21,24,09,056,15,25,45,120,23,28,50,237,23,1 +2023-09-12T20:45:58.109776540Z ts2phc[357165.544]: [ts2phc.0.config] nmea sentence: GPGSV,3,3,10,31,20,232,21,32,69,327,25,1 +2023-09-12T20:45:58.109776540Z ts2phc[357165.544]: [ts2phc.0.config] nmea sentence: GNGST,204558.00,40,14,11,122,4.8,5.5,11 +2023-09-12T20:45:58.109776540Z ts2phc[357165.544]: [ts2phc.0.config] nmea sentence: GNZDA,204558.00,12,09,2023,00,00 +2023-09-12T20:45:58.109776540Z ts2phc[357165.544]: [ts2phc.0.config] nmea sentence: GNGBS,204558.00,4.8,5.5,11.0,,,,,, +2023-09-12T20:45:58.116961942Z phc2sys[357165.552]: [ptp4l.0.config] CLOCK_REALTIME phc offset -3 s2 freq -10107 delay 503 +2023-09-12T20:45:58.118130666Z gnss[1694551558]:[ts2phc.0.config] ens6f0 gnss_status 3 offset 5 s2 +2023-09-12T20:45:58.171658325Z I0912 20:45:58.171632 161357 dpll.go:467] dpll decision: Status 3, Offset 0, In spec true, Source lost false, On holdover false +2023-09-12T20:45:58.171658325Z I0912 20:45:58.171647 161357 dpll.go:494] dpll is locked, source is not lost, offset is in range, state is DPLL_LOCKED_HO_ACQ or DPLL_HOLDOVER +2023-09-12T20:45:58.171658325Z I0912 20:45:58.171653 161357 dpll.go:540] dpll event sent +2023-09-12T20:45:58.179519445Z phc2sys[357165.614]: [ptp4l.0.config] CLOCK_REALTIME phc offset -5 s2 freq -10110 delay 504 +2023-09-12T20:45:58.179597537Z dpll[1694551558]:[ts2phc.0.config] ens6f0 frequency_status 3 offset 1 phase_status 3 s2 +2023-09-12T20:45:58.242089940Z phc2sys[357165.677]: [ptp4l.0.config] CLOCK_REALTIME phc offset -6 s2 freq -10112 delay 504 +2023-09-12T20:45:58.304678263Z phc2sys[357165.739]: [ptp4l.0.config] CLOCK_REALTIME phc offset -2 s2 freq -10110 delay 503 +2023-09-12T20:45:58.367267911Z phc2sys[357165.802]: [ptp4l.0.config] CLOCK_REALTIME phc offset 0 s2 freq -10109 delay 503 +2023-09-12T20:45:58.429891364Z phc2sys[357165.865]: [ptp4l.0.config] CLOCK_REALTIME phc offset -7 s2 freq -10116 delay 511 +2023-09-12T20:45:58.492423485Z phc2sys[357165.927]: [ptp4l.0.config] CLOCK_REALTIME phc offset 0 s2 freq -10111 delay 502 +2023-09-12T20:45:58.555103303Z phc2sys[357165.990]: [ptp4l.0.config] CLOCK_REALTIME phc offset 2 s2 freq -10109 delay 499 +2023-09-12T20:45:58.617627746Z phc2sys[357166.052]: [ptp4l.0.config] CLOCK_REALTIME phc offset 3 s2 freq -10107 delay 503 +2023-09-12T20:45:58.680267543Z phc2sys[357166.115]: [ptp4l.0.config] CLOCK_REALTIME phc offset -1 s2 freq -10110 delay 503 +2023-09-12T20:45:58.742808789Z phc2sys[357166.178]: [ptp4l.0.config] CLOCK_REALTIME phc offset -2 s2 freq -10111 delay 503 +2023-09-12T20:45:58.805369054Z phc2sys[357166.240]: [ptp4l.0.config] CLOCK_REALTIME phc offset 5 s2 freq -10105 delay 503 +2023-09-12T20:45:58.867946867Z phc2sys[357166.303]: [ptp4l.0.config] CLOCK_REALTIME phc offset -1 s2 freq -10110 delay 503 +2023-09-12T20:45:58.930565573Z phc2sys[357166.365]: [ptp4l.0.config] CLOCK_REALTIME phc offset -3 s2 freq -10112 delay 506 +2023-09-12T20:45:58.993760978Z phc2sys[357166.428]: [ptp4l.0.config] CLOCK_REALTIME phc offset -4 s2 freq -10114 delay 512 +2023-09-12T20:45:59.000066163Z ts2phc[357166.435]: [ts2phc.0.config] nmea delay: 109019555 ns +2023-09-12T20:45:59.000066163Z ts2phc[357166.435]: [ts2phc.0.config] ens6f0 extts index 0 at 1694551596.000000000 corr 0 src 1694551596.891002258 diff 0 +2023-09-12T20:45:59.000066163Z ts2phc[357166.435]: [ts2phc.0.config] ens6f0 master offset 0 s2 freq +0 +2023-09-12T20:45:59.009317496Z I0912 20:45:59.009297 161357 event.go:362] dpll State s2, gnss State s2, ts2phc state s2, gm state s2, +2023-09-12T20:45:59.055744298Z phc2sys[357166.491]: [ptp4l.0.config] CLOCK_REALTIME phc offset 5 s2 freq -10106 delay 498 +2023-09-12T20:45:59.118307993Z phc2sys[357166.553]: [ptp4l.0.config] CLOCK_REALTIME phc offset 0 s2 freq -10109 delay 507 +2023-09-12T20:45:59.119575899Z ts2phc[357166.554]: [ts2phc.0.config] nmea sentence: GNRMC,204559.00,A,4233.01583,N,07112.87872,W,0.014,,120923,,,A,V +2023-09-12T20:45:59.120114023Z ts2phc[357166.555]: [ts2phc.0.config] nmea sentence: GNGGA,204559.00,4233.01583,N,07112.87872,W,1,05,1.99,59.1,M,-33.0,M,, +2023-09-12T20:45:59.120114023Z ts2phc[357166.555]: [ts2phc.0.config] nmea sentence: GNGSA,A,3,10,12,23,28,32,,,,,,,,4.26,1.99,3.77,1 +2023-09-12T20:45:59.120114023Z ts2phc[357166.555]: [ts2phc.0.config] nmea sentence: GNGSA,A,3,,,,,,,,,,,,,4.26,1.99,3.77,5 +2023-09-12T20:45:59.120114023Z ts2phc[357166.555]: [ts2phc.0.config] nmea sentence: GPGSV,3,1,10,02,19,295,22,10,63,173,27,12,33,066,22,21,20,287,18,1 +2023-09-12T20:45:59.120114023Z ts2phc[357166.555]: [ts2phc.0.config] nmea sentence: GPGSV,3,2,10,23,25,153,20,24,09,056,15,25,45,120,23,28,50,237,23,1 diff --git a/collector-framework/pkg/runner/collector_selector.go b/collector-framework/pkg/runner/collector_selector.go new file mode 100644 index 00000000..3e4f4f21 --- /dev/null +++ b/collector-framework/pkg/runner/collector_selector.go @@ -0,0 +1,66 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + +package runner + +import ( + "strings" + + log "github.com/sirupsen/logrus" + + "github.com/redhat-partner-solutions/vse-sync-collection-tools/collector-framework/pkg/collectors" +) + +var ( + OptionalCollectorNames []string + RequiredCollectorNames []string + All string = "all" +) + +func init() { + registry := collectors.GetRegistry() + OptionalCollectorNames = registry.GetOptionalNames() + RequiredCollectorNames = registry.GetRequiredNames() +} + +func isIn(name string, arr []string) bool { + for _, arrVal := range arr { + if name == arrVal { + return true + } + } + return false +} + +func removeDuplicates(arr []string) []string { + res := make([]string, 0) + for _, name := range arr { + if !isIn(name, res) { + res = append(res, name) + } + } + return res +} + +// GetCollectorsToRun returns a slice containing the names of the +// collectors to be run it will enfore that required colletors +// are returned +func GetCollectorsToRun(selectedCollectors []string) []string { + collectorNames := make([]string, 0) + collectorNames = append(collectorNames, RequiredCollectorNames...) + for _, name := range selectedCollectors { + switch { + case strings.EqualFold(name, "all"): + collectorNames = append(collectorNames, OptionalCollectorNames...) + case strings.EqualFold(name, "defaults"): + collectorNames = append(collectorNames, OptionalCollectorNames...) + case isIn(name, collectorNames): + continue + case isIn(name, OptionalCollectorNames): + collectorNames = append(collectorNames, name) + default: + log.Errorf("Unknown collector %s. Ignored", name) + } + } + collectorNames = removeDuplicates(collectorNames) + return collectorNames +} diff --git a/collector-framework/pkg/runner/runner.go b/collector-framework/pkg/runner/runner.go new file mode 100644 index 00000000..e2cb20f1 --- /dev/null +++ b/collector-framework/pkg/runner/runner.go @@ -0,0 +1,272 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + +package runner + +import ( + "errors" + "os" + "os/signal" + "syscall" + "time" + + log "github.com/sirupsen/logrus" + + "github.com/redhat-partner-solutions/vse-sync-collection-tools/collector-framework/pkg/callbacks" + "github.com/redhat-partner-solutions/vse-sync-collection-tools/collector-framework/pkg/clients" + "github.com/redhat-partner-solutions/vse-sync-collection-tools/collector-framework/pkg/collectors" + "github.com/redhat-partner-solutions/vse-sync-collection-tools/collector-framework/pkg/utils" +) + +const ( + maxRunningPolls = 3 + pollResultsQueueSize = 10 +) + +// getQuitChannel creates and returns a channel for notifying +// that a exit signal has been received +func getQuitChannel() chan os.Signal { + // Allow ourselves to handle shut down gracefully + quit := make(chan os.Signal, 1) + signal.Notify(quit, syscall.SIGINT, syscall.SIGTERM) + return quit +} + +type CollectorRunner struct { + endTime time.Time + quit chan os.Signal + collectorQuitChannel map[string]chan os.Signal + pollResults chan collectors.PollResult + erroredPolls chan collectors.PollResult + collectorInstances map[string]collectors.Collector + collectorNames []string + runningCollectorsWG utils.WaitGroupCount + runningAnnouncersWG utils.WaitGroupCount + pollInterval int + devInfoAnnouceInterval int + onlyAnnouncers bool +} + +func NewCollectorRunner(selectedCollectors []string) *CollectorRunner { + return &CollectorRunner{ + collectorInstances: make(map[string]collectors.Collector), + collectorNames: GetCollectorsToRun(selectedCollectors), + quit: getQuitChannel(), + pollResults: make(chan collectors.PollResult, pollResultsQueueSize), + erroredPolls: make(chan collectors.PollResult, pollResultsQueueSize), + collectorQuitChannel: make(map[string]chan os.Signal, 1), + onlyAnnouncers: false, + } +} + +// initialise will call theconstructor for each +// value in collector name, it will panic if a collector name is not known. +func (runner *CollectorRunner) initialise( //nolint:funlen // allow a slightly long function + callback callbacks.Callback, + clientset *clients.Clientset, + pollInterval int, + requestedDuration time.Duration, + devInfoAnnouceInterval int, + collectorArgs map[string]map[string]any, +) { + runner.pollInterval = pollInterval + runner.endTime = time.Now().Add(requestedDuration) + runner.devInfoAnnouceInterval = devInfoAnnouceInterval + + constructor := &collectors.CollectionConstructor{ + Callback: callback, + CollectorArgs: collectorArgs, + Clientset: clientset, + PollInterval: pollInterval, + DevInfoAnnouceInterval: devInfoAnnouceInterval, + ErroredPolls: runner.erroredPolls, + } + + registry := collectors.GetRegistry() + + for _, collectorName := range runner.collectorNames { + builderFunc, err := registry.GetBuilderFunc(collectorName) + if err != nil { + log.Error(err) + continue + } + + newCollector, err := builderFunc(constructor) + var missingRequirements *utils.RequirementsNotMetError + if errors.As(err, &missingRequirements) { + // Requirements are missing so don't add the collector to collectorInstance + // so that it doesn't get ran + log.Warning(err.Error()) + } else { + utils.IfErrorExitOrPanic(err) + runner.collectorInstances[collectorName] = newCollector + log.Debugf("Added collector %T, %v", newCollector, newCollector) + } + } + log.Debugf("Collectors %v", runner.collectorInstances) + runner.setOnlyAnnouncers() +} + +func (runner *CollectorRunner) setOnlyAnnouncers() { + onlyAnnouncers := true + for _, collector := range runner.collectorInstances { + if !collector.IsAnnouncer() { + onlyAnnouncers = false + break + } + } + runner.onlyAnnouncers = onlyAnnouncers +} + +func (runner *CollectorRunner) shouldKeepPolling( + collector collectors.Collector, +) bool { + if collector.IsAnnouncer() && !runner.onlyAnnouncers { + return runner.runningCollectorsWG.GetCount() > 0 + } else { + return time.Since(runner.endTime) <= 0 + } +} + +func (runner *CollectorRunner) poller( + collectorName string, + collector collectors.Collector, + quit chan os.Signal, + wg *utils.WaitGroupCount, +) { + defer wg.Done() + var lastPoll time.Time + pollInterval := collector.GetPollInterval() + runningPolls := utils.WaitGroupCount{} + log.Debugf("Collector with poll interval %fs", pollInterval.Seconds()) + for runner.shouldKeepPolling(collector) { + // If pollResults were to block we do not want to keep spawning polls + // so we shouldn't allow too many polls to be running simultaneously + if runningPolls.GetCount() >= maxRunningPolls { + runningPolls.Wait() + } + log.Debugf("Collector GoRoutine: %s", collectorName) + select { + case <-quit: + log.Infof("Killed shutting down collector %s waiting for running polls to finish", collectorName) + runningPolls.Wait() + return + default: + pollInterval = collector.GetPollInterval() + log.Debug( + "Collector GoRoutine:", + collectorName, + lastPoll, pollInterval, + lastPoll.IsZero(), + time.Since(lastPoll), + time.Since(lastPoll) > pollInterval, + lastPoll.IsZero() || time.Since(lastPoll) > pollInterval, + ) + if lastPoll.IsZero() || time.Since(lastPoll) > pollInterval { + lastPoll = time.Now() + log.Debugf("poll %s", collectorName) + runningPolls.Add(1) + go collector.Poll(runner.pollResults, &runningPolls) + } + time.Sleep(time.Microsecond) + } + } + runningPolls.Wait() + log.Debugf("Collector finished %s", collectorName) +} + +// start configures all collectors to start collecting all their data keys +func (runner *CollectorRunner) start() { + for collectorName, collector := range runner.collectorInstances { + log.Debugf("start collector %v", collector) + err := collector.Start() + utils.IfErrorExitOrPanic(err) + + log.Debugf("Spawning collector: %v", collector) + collectorName := collectorName + collector := collector + quit := make(chan os.Signal, 1) + if collector.IsAnnouncer() { + runner.collectorQuitChannel[collectorName] = quit + runner.runningAnnouncersWG.Add(1) + go runner.poller(collectorName, collector, quit, &runner.runningAnnouncersWG) + } else { + runner.collectorQuitChannel[collectorName] = quit + runner.runningCollectorsWG.Add(1) + go runner.poller(collectorName, collector, quit, &runner.runningCollectorsWG) + } + } +} + +// cleanup calls cleanup on each collector +func (runner *CollectorRunner) cleanUpAll() { + for collectorName, collector := range runner.collectorInstances { + log.Debugf("cleanup %s", collectorName) + err := collector.CleanUp() + utils.IfErrorExitOrPanic(err) + } +} + +// Run manages set of collectors. +// It first initialises them, +// then polls them on the correct cadence and +// finally cleans up the collectors when exiting +func (runner *CollectorRunner) Run( //nolint:funlen // allow a slightly long function + kubeConfig string, + outputFile string, + requestedDuration time.Duration, + pollInterval int, + devInfoAnnouceInterval int, + useAnalyserJSON bool, + collectorArgs map[string]map[string]any, +) { + clientset, err := clients.GetClientset(kubeConfig) + utils.IfErrorExitOrPanic(err) + + outputFormat := callbacks.Raw + if useAnalyserJSON { + outputFormat = callbacks.AnalyserJSON + } + + callback, err := callbacks.SetupCallback(outputFile, outputFormat) + utils.IfErrorExitOrPanic(err) + runner.initialise( + callback, + clientset, + pollInterval, + requestedDuration, + devInfoAnnouceInterval, + collectorArgs, + ) + runner.start() + + // Use wg count to know if any collectors are running. + for (runner.runningCollectorsWG.GetCount() + runner.runningAnnouncersWG.GetCount()) > 0 { + log.Debugf("Main Loop ") + select { + case sig := <-runner.quit: + log.Info("Killed shutting down") + // Forward signal to collector QuitChannels + for collectorName, quit := range runner.collectorQuitChannel { + log.Infof("Killed shutting down: %s", collectorName) + quit <- sig + } + runner.runningCollectorsWG.Wait() + runner.runningAnnouncersWG.Wait() + case pollRes := <-runner.pollResults: + log.Infof("Received %v", pollRes) + if len(pollRes.Errors) > 0 { + log.Warnf("Poll %s had issues: %v. Will retry next poll", pollRes.CollectorName, pollRes.Errors) + // If erroredPolls blocks it could cause pollResults to fill and + // block the execution of the collectors. + runner.erroredPolls <- pollRes + } + default: + log.Debug("Sleeping main func") + time.Sleep(time.Millisecond) + } + } + log.Info("Doing Cleanup") + runner.cleanUpAll() + err = callback.CleanUp() + utils.IfErrorExitOrPanic(err) +} diff --git a/collector-framework/pkg/utils/errors.go b/collector-framework/pkg/utils/errors.go new file mode 100644 index 00000000..3a185b5a --- /dev/null +++ b/collector-framework/pkg/utils/errors.go @@ -0,0 +1,97 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + +package utils + +import ( + "errors" + "fmt" + "strings" +) + +type exitCode int + +const ( + // Exitcodes + Success exitCode = iota + InvalidEnv + MissingInput + NotHandled +) + +type InvalidEnvError struct { + err error +} + +func (err InvalidEnvError) Error() string { + return err.err.Error() +} +func (err InvalidEnvError) Unwrap() error { + return err.err +} + +func NewInvalidEnvError(err error) *InvalidEnvError { + return &InvalidEnvError{err: err} +} + +type MissingInputError struct { + err error +} + +func (err MissingInputError) Error() string { + return err.err.Error() +} +func (err MissingInputError) Unwrap() error { + return err.err +} + +func NewMissingInputError(err error) *MissingInputError { + return &MissingInputError{err: err} +} + +type RequirementsNotMetError struct { + err error +} + +func (err RequirementsNotMetError) Error() string { + return err.err.Error() +} +func (err RequirementsNotMetError) Unwrap() error { + return err.err +} + +func NewRequirementsNotMetError(err error) *RequirementsNotMetError { + return &RequirementsNotMetError{err: err} +} + +func checkError(err error) (exitCode, bool) { + var invalidEnv *InvalidEnvError + if errors.As(err, &invalidEnv) { + return InvalidEnv, true + } + + var missingInput *MissingInputError + if errors.As(err, &missingInput) { + return MissingInput, true + } + + return NotHandled, false +} + +func MakeCompositeError(prefix string, errSlice []error) error { + pattern := strings.Repeat("\t%s\n", len(errSlice)) + + values := make([]any, 0) + for _, err := range errSlice { + values = append(values, err.Error()) + } + if len(prefix) > 0 { + return fmt.Errorf(prefix+":\n"+pattern, values...) + } + return fmt.Errorf(pattern, values...) +} + +func MakeCompositeInvalidEnvError(errSlice []error) error { + return NewInvalidEnvError( + MakeCompositeError("The following issues where found", errSlice), + ) +} diff --git a/collector-framework/pkg/utils/utils.go b/collector-framework/pkg/utils/utils.go new file mode 100644 index 00000000..761ce793 --- /dev/null +++ b/collector-framework/pkg/utils/utils.go @@ -0,0 +1,81 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + +package utils + +import ( + "errors" + "fmt" + "io/fs" + "os" + "path/filepath" + "strings" + "sync" + "sync/atomic" + "time" + + log "github.com/sirupsen/logrus" +) + +var ( + Epoch = time.Unix(0, 0) +) + +func IfErrorExitOrPanic(err error) { + if err == nil { + return + } + + if exitCode, matched := checkError(err); matched { + log.Error(err) + os.Exit(int(exitCode)) + } else { + log.Panic(err) + } +} + +// The standard sync.WaitGroup doesn't expose the +// count of members as this is considered internal state +// however this value is very useful. +type WaitGroupCount struct { + sync.WaitGroup + count int64 +} + +func (wg *WaitGroupCount) Add(delta int) { + atomic.AddInt64(&wg.count, int64(delta)) + wg.WaitGroup.Add(delta) +} + +func (wg *WaitGroupCount) Done() { + atomic.AddInt64(&wg.count, -1) + wg.WaitGroup.Done() +} + +func (wg *WaitGroupCount) GetCount() int { + return int(atomic.LoadInt64(&wg.count)) +} + +// ParseTimestamp converts an input number of seconds (including a decimal fraction) into a time.Time +func ParseTimestamp(timestamp string) (time.Time, error) { + duration, err := time.ParseDuration(fmt.Sprintf("%ss", timestamp)) + if err != nil { + return time.Time{}, fmt.Errorf("failed to parse timestamp as a duration %w", err) + } + return Epoch.Add(duration).UTC(), nil +} + +func RemoveTempFiles(dir string, filenames []string) { + dir = filepath.Clean(dir) + for _, fname := range filenames { + log.Info() + if !strings.HasPrefix(fname, dir) { + fname = filepath.Join(dir, fname) + } + err := os.Remove(fname) + if err != nil && errors.Is(err, fs.ErrNotExist) { + log.Errorf("Failed to remove temp file %s: %s", fname, err.Error()) + } + } + // os.Remove will not remove a director if has files so its safe to call on the Dir + os.Remove(dir) +} diff --git a/collector-framework/pkg/validations/validation.go b/collector-framework/pkg/validations/validation.go new file mode 100644 index 00000000..71b06f34 --- /dev/null +++ b/collector-framework/pkg/validations/validation.go @@ -0,0 +1,140 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + +package validations + +import ( + "encoding/json" + "fmt" + "strings" + + "golang.org/x/mod/semver" + + "github.com/redhat-partner-solutions/vse-sync-collection-tools/collector-framework/pkg/utils" +) + +type Validation interface { + Verify() error + GetID() string + GetDescription() string + GetData() any + GetOrder() int +} + +//nolint:varnamelen // id is fine this seems like a bug in varnamelen +func NewVersionCheck( + id string, + version string, + checkVersion string, + minVersion string, + description string, + order int, +) *VersionCheck { + return &VersionCheck{ + id: id, + Version: version, + checkVersion: checkVersion, + MinVersion: minVersion, + description: description, + order: order, + } +} + +type VersionCheck struct { + id string `json:"-"` + Version string `json:"version"` + checkVersion string `json:"-"` + MinVersion string `json:"expected"` + description string `json:"-"` + order int `json:"-"` +} + +func (verCheck *VersionCheck) Verify() error { + ver := fmt.Sprintf("v%s", strings.ReplaceAll(verCheck.checkVersion, "_", "-")) + if !semver.IsValid(ver) { + return fmt.Errorf("could not parse version %s", ver) + } + if semver.Compare(ver, fmt.Sprintf("v%s", verCheck.MinVersion)) < 0 { + return utils.NewInvalidEnvError( + fmt.Errorf("unexpected version: %s < %s", verCheck.checkVersion, verCheck.MinVersion), + ) + } + return nil +} + +func (verCheck *VersionCheck) GetID() string { + return verCheck.id +} + +func (verCheck *VersionCheck) GetDescription() string { + return verCheck.description +} + +func (verCheck *VersionCheck) GetData() any { //nolint:ireturn // data will vary for each validation + return verCheck +} + +func (verCheck *VersionCheck) GetOrder() int { + return verCheck.order +} + +//nolint:varnamelen // id is fine this seems like a bug in varnamelen +func NewVersionCheckWithError( + id string, + version string, + checkVersion string, + minVersion string, + description string, + order int, + err error, +) *VersionWithErrorCheck { + return &VersionWithErrorCheck{ + VersionCheck: &VersionCheck{ + id: id, + Version: version, + checkVersion: checkVersion, + MinVersion: minVersion, + description: description, + order: order, + }, + Error: err, + } +} + +type VersionWithError struct { + Error error `json:"fetchError"` + Version string `json:"version"` +} + +func MarshalVersionAndError(ver *VersionWithError) ([]byte, error) { + var err any + if ver.Error != nil { + err = ver.Error.Error() + } + marsh, marshalErr := json.Marshal(&struct { + Error any `json:"fetchError"` + Version string `json:"version"` + }{ + Version: ver.Version, + Error: err, + }) + return marsh, fmt.Errorf("failed to marshal VersionWithError %w", marshalErr) +} + +type VersionWithErrorCheck struct { + *VersionCheck + Error error +} + +func (verCheck *VersionWithErrorCheck) MarshalJSON() ([]byte, error) { + return MarshalVersionAndError(&VersionWithError{ + Version: verCheck.Version, + Error: verCheck.Error, + }) +} + +func (verCheck *VersionWithErrorCheck) Verify() error { + if verCheck.Error != nil { + return verCheck.Error + } + return verCheck.VersionCheck.Verify() +} diff --git a/collector-framework/testutils/fake_executor.go b/collector-framework/testutils/fake_executor.go new file mode 100644 index 00000000..d8d0d3c1 --- /dev/null +++ b/collector-framework/testutils/fake_executor.go @@ -0,0 +1,54 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + +package testutils + +import ( + "context" + "fmt" + "net/url" + + "k8s.io/client-go/rest" + "k8s.io/client-go/tools/remotecommand" +) + +// Return a SPDYExectuor with stdout, stderr and an error embedded +func NewFakeNewSPDYExecutor( + responder func(method string, url *url.URL, options remotecommand.StreamOptions) ([]byte, []byte, error), + execCreationErr error, +) func(config *rest.Config, method string, url *url.URL) (remotecommand.Executor, error) { + return func(config *rest.Config, method string, url *url.URL) (remotecommand.Executor, error) { + return &fakeExecutor{method: method, url: url, responder: responder}, execCreationErr + } +} + +type fakeExecutor struct { + url *url.URL + responder func(method string, url *url.URL, options remotecommand.StreamOptions) ([]byte, []byte, error) + method string +} + +func (f *fakeExecutor) Stream(options remotecommand.StreamOptions) error { + stdout, stderr, responseErr := f.responder(f.method, f.url, options) + _, err := options.Stdout.Write(stdout) + if err != nil { + return fmt.Errorf("failed to write stdout Error: %w", err) + } + _, err = options.Stderr.Write(stderr) + if err != nil { + return fmt.Errorf("failed to write stderr Error: %w", err) + } + return responseErr +} + +func (f *fakeExecutor) StreamWithContext(ctx context.Context, options remotecommand.StreamOptions) error { + stdout, stderr, reponseErr := f.responder(f.method, f.url, options) + _, err := options.Stdout.Write(stdout) + if err != nil { + return fmt.Errorf("failed to write stdout Error: %w", err) + } + _, err = options.Stderr.Write(stderr) + if err != nil { + return fmt.Errorf("failed to write stderr Error: %w", err) + } + return reponseErr +} diff --git a/collector-framework/testutils/mocked_clientset.go b/collector-framework/testutils/mocked_clientset.go new file mode 100644 index 00000000..58dab7ea --- /dev/null +++ b/collector-framework/testutils/mocked_clientset.go @@ -0,0 +1,37 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + +package testutils + +import ( + "net/url" + + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" + fakeK8s "k8s.io/client-go/kubernetes/fake" + "k8s.io/client-go/rest" + + "github.com/redhat-partner-solutions/vse-sync-collection-tools/collector-framework/pkg/clients" +) + +const kubeconfigPath string = "test_files/kubeconfig" + +// Returns a clientset where K8sClient and K8sRestClient are faked +func GetMockedClientSet(k8APIObjects ...runtime.Object) *clients.Clientset { + clients.ClearClientSet() + clientset, err := clients.GetClientset(kubeconfigPath) + if err != nil { + panic("Failed to get clientset") + } + fakeK8sClient := fakeK8s.NewSimpleClientset(k8APIObjects...) + + config := rest.ClientContentConfig{ + GroupVersion: schema.GroupVersion{Version: "v1"}, + } + fakeRestClient, err := rest.NewRESTClient(&url.URL{}, "", config, nil, nil) + if err != nil { + panic("Failed to create rest client") + } + clientset.K8sClient = fakeK8sClient + clientset.K8sRestClient = fakeRestClient + return clientset +} diff --git a/go.work b/go.work index 141ee7e5..ec35c0ae 100644 --- a/go.work +++ b/go.work @@ -1,3 +1,6 @@ go 1.20 -use ./tgm-collector/ +use ( + ./collector-framework + ./tgm-collector/ +) diff --git a/tgm-collector/doc/implementing_a_collector.md b/tgm-collector/doc/implementing_a_collector.md index 7e4fcd73..cd016eb7 100644 --- a/tgm-collector/doc/implementing_a_collector.md +++ b/tgm-collector/doc/implementing_a_collector.md @@ -75,7 +75,7 @@ package collectors import ( "fmt" - "github.com/redhat-partner-solutions/vse-sync-collection-tools/pkg/callbacks" + "github.com/redhat-partner-solutions/vse-sync-collection-tools/tgm-collector/pkg/callbacks" ) const ( AnnouncementCollectorName = "MyCustomerAnouncer" diff --git a/tgm-collector/go.mod b/tgm-collector/go.mod index 4cc5102f..f9290092 100644 --- a/tgm-collector/go.mod +++ b/tgm-collector/go.mod @@ -1,4 +1,4 @@ -module github.com/redhat-partner-solutions/vse-sync-collection-tools +module github.com/redhat-partner-solutions/vse-sync-collection-tools/tgm-collector go 1.18 diff --git a/tgm-collector/main.go b/tgm-collector/main.go index 2ee5ec5a..3d8d9e60 100644 --- a/tgm-collector/main.go +++ b/tgm-collector/main.go @@ -3,7 +3,7 @@ package main import ( - "github.com/redhat-partner-solutions/vse-sync-collection-tools/pkg/cmd" + "github.com/redhat-partner-solutions/vse-sync-collection-tools/tgm-collector/pkg/cmd" ) func main() { diff --git a/tgm-collector/pkg/callbacks/callbacks_test.go b/tgm-collector/pkg/callbacks/callbacks_test.go index 45604827..66578c09 100644 --- a/tgm-collector/pkg/callbacks/callbacks_test.go +++ b/tgm-collector/pkg/callbacks/callbacks_test.go @@ -10,7 +10,7 @@ import ( . "github.com/onsi/ginkgo/v2" . "github.com/onsi/gomega" - "github.com/redhat-partner-solutions/vse-sync-collection-tools/pkg/callbacks" + "github.com/redhat-partner-solutions/vse-sync-collection-tools/tgm-collector/pkg/callbacks" ) func NewTestFile() *testFile { diff --git a/tgm-collector/pkg/clients/clients_test.go b/tgm-collector/pkg/clients/clients_test.go index 1e806b51..d9d73677 100644 --- a/tgm-collector/pkg/clients/clients_test.go +++ b/tgm-collector/pkg/clients/clients_test.go @@ -8,7 +8,7 @@ import ( . "github.com/onsi/ginkgo/v2" . "github.com/onsi/gomega" - "github.com/redhat-partner-solutions/vse-sync-collection-tools/pkg/clients" + "github.com/redhat-partner-solutions/vse-sync-collection-tools/tgm-collector/pkg/clients" ) const ( diff --git a/tgm-collector/pkg/clients/clientset.go b/tgm-collector/pkg/clients/clientset.go index 1e0bc48b..1af6960e 100644 --- a/tgm-collector/pkg/clients/clientset.go +++ b/tgm-collector/pkg/clients/clientset.go @@ -16,7 +16,7 @@ import ( "k8s.io/client-go/rest" "k8s.io/client-go/tools/clientcmd" - "github.com/redhat-partner-solutions/vse-sync-collection-tools/pkg/utils" + "github.com/redhat-partner-solutions/vse-sync-collection-tools/tgm-collector/pkg/utils" ) // A Clientset contains clients for the different k8s API groups in one place diff --git a/tgm-collector/pkg/clients/command_test.go b/tgm-collector/pkg/clients/command_test.go index a5eacf17..e6611fc9 100644 --- a/tgm-collector/pkg/clients/command_test.go +++ b/tgm-collector/pkg/clients/command_test.go @@ -8,7 +8,7 @@ import ( . "github.com/onsi/ginkgo/v2" . "github.com/onsi/gomega" - "github.com/redhat-partner-solutions/vse-sync-collection-tools/pkg/clients" + "github.com/redhat-partner-solutions/vse-sync-collection-tools/tgm-collector/pkg/clients" ) var _ = Describe("Cmd", func() { diff --git a/tgm-collector/pkg/clients/exec_command_test.go b/tgm-collector/pkg/clients/exec_command_test.go index 4eb012ce..28ed79fc 100644 --- a/tgm-collector/pkg/clients/exec_command_test.go +++ b/tgm-collector/pkg/clients/exec_command_test.go @@ -14,8 +14,8 @@ import ( fakeK8s "k8s.io/client-go/kubernetes/fake" "k8s.io/client-go/tools/remotecommand" - "github.com/redhat-partner-solutions/vse-sync-collection-tools/pkg/clients" - "github.com/redhat-partner-solutions/vse-sync-collection-tools/testutils" + "github.com/redhat-partner-solutions/vse-sync-collection-tools/tgm-collector/pkg/clients" + "github.com/redhat-partner-solutions/vse-sync-collection-tools/tgm-collector/testutils" ) var notATestPod = &v1.Pod{ diff --git a/tgm-collector/pkg/cmd/collect.go b/tgm-collector/pkg/cmd/collect.go index 3a1babd9..2bfc2343 100644 --- a/tgm-collector/pkg/cmd/collect.go +++ b/tgm-collector/pkg/cmd/collect.go @@ -14,9 +14,9 @@ import ( log "github.com/sirupsen/logrus" "github.com/spf13/cobra" - "github.com/redhat-partner-solutions/vse-sync-collection-tools/pkg/collectors" - "github.com/redhat-partner-solutions/vse-sync-collection-tools/pkg/runner" - "github.com/redhat-partner-solutions/vse-sync-collection-tools/pkg/utils" + "github.com/redhat-partner-solutions/vse-sync-collection-tools/tgm-collector/pkg/collectors" + "github.com/redhat-partner-solutions/vse-sync-collection-tools/tgm-collector/pkg/runner" + "github.com/redhat-partner-solutions/vse-sync-collection-tools/tgm-collector/pkg/utils" ) const ( diff --git a/tgm-collector/pkg/cmd/common.go b/tgm-collector/pkg/cmd/common.go index 81fe50d2..e89c139a 100644 --- a/tgm-collector/pkg/cmd/common.go +++ b/tgm-collector/pkg/cmd/common.go @@ -5,7 +5,7 @@ package cmd import ( "github.com/spf13/cobra" - "github.com/redhat-partner-solutions/vse-sync-collection-tools/pkg/utils" + "github.com/redhat-partner-solutions/vse-sync-collection-tools/tgm-collector/pkg/utils" ) var ( diff --git a/tgm-collector/pkg/cmd/root.go b/tgm-collector/pkg/cmd/root.go index 6c915ed5..07cc57f1 100644 --- a/tgm-collector/pkg/cmd/root.go +++ b/tgm-collector/pkg/cmd/root.go @@ -8,7 +8,7 @@ import ( log "github.com/sirupsen/logrus" "github.com/spf13/cobra" - "github.com/redhat-partner-solutions/vse-sync-collection-tools/pkg/logging" + "github.com/redhat-partner-solutions/vse-sync-collection-tools/tgm-collector/pkg/logging" ) var ( diff --git a/tgm-collector/pkg/cmd/verifyEnv.go b/tgm-collector/pkg/cmd/verifyEnv.go index ca7ecc36..49480c2a 100644 --- a/tgm-collector/pkg/cmd/verifyEnv.go +++ b/tgm-collector/pkg/cmd/verifyEnv.go @@ -5,7 +5,7 @@ package cmd import ( "github.com/spf13/cobra" - "github.com/redhat-partner-solutions/vse-sync-collection-tools/pkg/verify" + "github.com/redhat-partner-solutions/vse-sync-collection-tools/tgm-collector/pkg/verify" ) var envCmd = &cobra.Command{ diff --git a/tgm-collector/pkg/collectors/collector.go b/tgm-collector/pkg/collectors/collector.go index d2c5b1bd..40c98a7b 100644 --- a/tgm-collector/pkg/collectors/collector.go +++ b/tgm-collector/pkg/collectors/collector.go @@ -5,9 +5,9 @@ package collectors import ( "time" - "github.com/redhat-partner-solutions/vse-sync-collection-tools/pkg/callbacks" - "github.com/redhat-partner-solutions/vse-sync-collection-tools/pkg/clients" - "github.com/redhat-partner-solutions/vse-sync-collection-tools/pkg/utils" + "github.com/redhat-partner-solutions/vse-sync-collection-tools/tgm-collector/pkg/callbacks" + "github.com/redhat-partner-solutions/vse-sync-collection-tools/tgm-collector/pkg/clients" + "github.com/redhat-partner-solutions/vse-sync-collection-tools/tgm-collector/pkg/utils" ) type Collector interface { diff --git a/tgm-collector/pkg/collectors/contexts/contexts.go b/tgm-collector/pkg/collectors/contexts/contexts.go index 8bda10ea..2c6aa947 100644 --- a/tgm-collector/pkg/collectors/contexts/contexts.go +++ b/tgm-collector/pkg/collectors/contexts/contexts.go @@ -7,7 +7,7 @@ import ( corev1 "k8s.io/api/core/v1" - "github.com/redhat-partner-solutions/vse-sync-collection-tools/pkg/clients" + "github.com/redhat-partner-solutions/vse-sync-collection-tools/tgm-collector/pkg/clients" ) const ( diff --git a/tgm-collector/pkg/collectors/dev_info_collector.go b/tgm-collector/pkg/collectors/dev_info_collector.go index f3210d63..a16baf9e 100644 --- a/tgm-collector/pkg/collectors/dev_info_collector.go +++ b/tgm-collector/pkg/collectors/dev_info_collector.go @@ -11,11 +11,11 @@ import ( log "github.com/sirupsen/logrus" - "github.com/redhat-partner-solutions/vse-sync-collection-tools/pkg/clients" - "github.com/redhat-partner-solutions/vse-sync-collection-tools/pkg/collectors/contexts" - "github.com/redhat-partner-solutions/vse-sync-collection-tools/pkg/collectors/devices" - "github.com/redhat-partner-solutions/vse-sync-collection-tools/pkg/utils" - "github.com/redhat-partner-solutions/vse-sync-collection-tools/pkg/validations" + "github.com/redhat-partner-solutions/vse-sync-collection-tools/tgm-collector/pkg/clients" + "github.com/redhat-partner-solutions/vse-sync-collection-tools/tgm-collector/pkg/collectors/contexts" + "github.com/redhat-partner-solutions/vse-sync-collection-tools/tgm-collector/pkg/collectors/devices" + "github.com/redhat-partner-solutions/vse-sync-collection-tools/tgm-collector/pkg/utils" + "github.com/redhat-partner-solutions/vse-sync-collection-tools/tgm-collector/pkg/validations" ) type DevInfoCollector struct { diff --git a/tgm-collector/pkg/collectors/devices/common.go b/tgm-collector/pkg/collectors/devices/common.go index 42009e50..8a7f18e4 100644 --- a/tgm-collector/pkg/collectors/devices/common.go +++ b/tgm-collector/pkg/collectors/devices/common.go @@ -7,8 +7,8 @@ import ( "strings" "time" - "github.com/redhat-partner-solutions/vse-sync-collection-tools/pkg/clients" - "github.com/redhat-partner-solutions/vse-sync-collection-tools/pkg/utils" + "github.com/redhat-partner-solutions/vse-sync-collection-tools/tgm-collector/pkg/clients" + "github.com/redhat-partner-solutions/vse-sync-collection-tools/tgm-collector/pkg/utils" ) var dateCmd *clients.Cmd diff --git a/tgm-collector/pkg/collectors/devices/device_info.go b/tgm-collector/pkg/collectors/devices/device_info.go index 9ffbf96c..990d8233 100644 --- a/tgm-collector/pkg/collectors/devices/device_info.go +++ b/tgm-collector/pkg/collectors/devices/device_info.go @@ -11,9 +11,9 @@ import ( log "github.com/sirupsen/logrus" - "github.com/redhat-partner-solutions/vse-sync-collection-tools/pkg/callbacks" - "github.com/redhat-partner-solutions/vse-sync-collection-tools/pkg/clients" - "github.com/redhat-partner-solutions/vse-sync-collection-tools/pkg/fetcher" + "github.com/redhat-partner-solutions/vse-sync-collection-tools/tgm-collector/pkg/callbacks" + "github.com/redhat-partner-solutions/vse-sync-collection-tools/tgm-collector/pkg/clients" + "github.com/redhat-partner-solutions/vse-sync-collection-tools/tgm-collector/pkg/fetcher" ) type PTPDeviceInfo struct { diff --git a/tgm-collector/pkg/collectors/devices/device_info_test.go b/tgm-collector/pkg/collectors/devices/device_info_test.go index 16dbbe71..9d56dfdc 100644 --- a/tgm-collector/pkg/collectors/devices/device_info_test.go +++ b/tgm-collector/pkg/collectors/devices/device_info_test.go @@ -15,9 +15,9 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/client-go/tools/remotecommand" - "github.com/redhat-partner-solutions/vse-sync-collection-tools/pkg/clients" - "github.com/redhat-partner-solutions/vse-sync-collection-tools/pkg/collectors/devices" - "github.com/redhat-partner-solutions/vse-sync-collection-tools/testutils" + "github.com/redhat-partner-solutions/vse-sync-collection-tools/tgm-collector/pkg/clients" + "github.com/redhat-partner-solutions/vse-sync-collection-tools/tgm-collector/pkg/collectors/devices" + "github.com/redhat-partner-solutions/vse-sync-collection-tools/tgm-collector/testutils" ) const ethtoolOutput = ` diff --git a/tgm-collector/pkg/collectors/devices/dpll_fs.go b/tgm-collector/pkg/collectors/devices/dpll_fs.go index 4c7695dd..3355a31d 100644 --- a/tgm-collector/pkg/collectors/devices/dpll_fs.go +++ b/tgm-collector/pkg/collectors/devices/dpll_fs.go @@ -10,9 +10,9 @@ import ( log "github.com/sirupsen/logrus" - "github.com/redhat-partner-solutions/vse-sync-collection-tools/pkg/callbacks" - "github.com/redhat-partner-solutions/vse-sync-collection-tools/pkg/clients" - "github.com/redhat-partner-solutions/vse-sync-collection-tools/pkg/fetcher" + "github.com/redhat-partner-solutions/vse-sync-collection-tools/tgm-collector/pkg/callbacks" + "github.com/redhat-partner-solutions/vse-sync-collection-tools/tgm-collector/pkg/clients" + "github.com/redhat-partner-solutions/vse-sync-collection-tools/tgm-collector/pkg/fetcher" ) const ( diff --git a/tgm-collector/pkg/collectors/devices/dpll_fs_test.go b/tgm-collector/pkg/collectors/devices/dpll_fs_test.go index 9215a72e..6b7a7fdb 100644 --- a/tgm-collector/pkg/collectors/devices/dpll_fs_test.go +++ b/tgm-collector/pkg/collectors/devices/dpll_fs_test.go @@ -12,9 +12,9 @@ import ( "k8s.io/client-go/tools/remotecommand" - "github.com/redhat-partner-solutions/vse-sync-collection-tools/pkg/clients" - "github.com/redhat-partner-solutions/vse-sync-collection-tools/pkg/collectors/devices" - "github.com/redhat-partner-solutions/vse-sync-collection-tools/testutils" + "github.com/redhat-partner-solutions/vse-sync-collection-tools/tgm-collector/pkg/clients" + "github.com/redhat-partner-solutions/vse-sync-collection-tools/tgm-collector/pkg/collectors/devices" + "github.com/redhat-partner-solutions/vse-sync-collection-tools/tgm-collector/testutils" ) var _ = Describe("NewContainerContext", func() { diff --git a/tgm-collector/pkg/collectors/devices/dpll_netlink.go b/tgm-collector/pkg/collectors/devices/dpll_netlink.go index 7d4675d8..7113cd53 100644 --- a/tgm-collector/pkg/collectors/devices/dpll_netlink.go +++ b/tgm-collector/pkg/collectors/devices/dpll_netlink.go @@ -11,9 +11,9 @@ import ( log "github.com/sirupsen/logrus" - "github.com/redhat-partner-solutions/vse-sync-collection-tools/pkg/callbacks" - "github.com/redhat-partner-solutions/vse-sync-collection-tools/pkg/clients" - "github.com/redhat-partner-solutions/vse-sync-collection-tools/pkg/fetcher" + "github.com/redhat-partner-solutions/vse-sync-collection-tools/tgm-collector/pkg/callbacks" + "github.com/redhat-partner-solutions/vse-sync-collection-tools/tgm-collector/pkg/clients" + "github.com/redhat-partner-solutions/vse-sync-collection-tools/tgm-collector/pkg/fetcher" ) var states = map[string]string{ diff --git a/tgm-collector/pkg/collectors/devices/gps_ubx.go b/tgm-collector/pkg/collectors/devices/gps_ubx.go index 6e47d247..1d604012 100644 --- a/tgm-collector/pkg/collectors/devices/gps_ubx.go +++ b/tgm-collector/pkg/collectors/devices/gps_ubx.go @@ -10,10 +10,10 @@ import ( log "github.com/sirupsen/logrus" - "github.com/redhat-partner-solutions/vse-sync-collection-tools/pkg/callbacks" - "github.com/redhat-partner-solutions/vse-sync-collection-tools/pkg/clients" - "github.com/redhat-partner-solutions/vse-sync-collection-tools/pkg/fetcher" - "github.com/redhat-partner-solutions/vse-sync-collection-tools/pkg/utils" + "github.com/redhat-partner-solutions/vse-sync-collection-tools/tgm-collector/pkg/callbacks" + "github.com/redhat-partner-solutions/vse-sync-collection-tools/tgm-collector/pkg/clients" + "github.com/redhat-partner-solutions/vse-sync-collection-tools/tgm-collector/pkg/fetcher" + "github.com/redhat-partner-solutions/vse-sync-collection-tools/tgm-collector/pkg/utils" ) type GPSDetails struct { diff --git a/tgm-collector/pkg/collectors/devices/gps_ubx_test.go b/tgm-collector/pkg/collectors/devices/gps_ubx_test.go index 547c7f8a..143e5ce8 100644 --- a/tgm-collector/pkg/collectors/devices/gps_ubx_test.go +++ b/tgm-collector/pkg/collectors/devices/gps_ubx_test.go @@ -12,9 +12,9 @@ import ( "k8s.io/client-go/tools/remotecommand" - "github.com/redhat-partner-solutions/vse-sync-collection-tools/pkg/clients" - "github.com/redhat-partner-solutions/vse-sync-collection-tools/pkg/collectors/devices" - "github.com/redhat-partner-solutions/vse-sync-collection-tools/testutils" + "github.com/redhat-partner-solutions/vse-sync-collection-tools/tgm-collector/pkg/clients" + "github.com/redhat-partner-solutions/vse-sync-collection-tools/tgm-collector/pkg/collectors/devices" + "github.com/redhat-partner-solutions/vse-sync-collection-tools/tgm-collector/testutils" ) var _ = Describe("GetGPSNav", func() { diff --git a/tgm-collector/pkg/collectors/devices/gps_ubx_ver.go b/tgm-collector/pkg/collectors/devices/gps_ubx_ver.go index 0dfda78c..81c88a81 100644 --- a/tgm-collector/pkg/collectors/devices/gps_ubx_ver.go +++ b/tgm-collector/pkg/collectors/devices/gps_ubx_ver.go @@ -10,10 +10,10 @@ import ( log "github.com/sirupsen/logrus" - "github.com/redhat-partner-solutions/vse-sync-collection-tools/pkg/callbacks" - "github.com/redhat-partner-solutions/vse-sync-collection-tools/pkg/clients" - "github.com/redhat-partner-solutions/vse-sync-collection-tools/pkg/fetcher" - "github.com/redhat-partner-solutions/vse-sync-collection-tools/pkg/utils" + "github.com/redhat-partner-solutions/vse-sync-collection-tools/tgm-collector/pkg/callbacks" + "github.com/redhat-partner-solutions/vse-sync-collection-tools/tgm-collector/pkg/clients" + "github.com/redhat-partner-solutions/vse-sync-collection-tools/tgm-collector/pkg/fetcher" + "github.com/redhat-partner-solutions/vse-sync-collection-tools/tgm-collector/pkg/utils" ) type GPSVersions struct { diff --git a/tgm-collector/pkg/collectors/devices/gps_ubx_ver_test.go b/tgm-collector/pkg/collectors/devices/gps_ubx_ver_test.go index 913712d1..4bb6af5b 100644 --- a/tgm-collector/pkg/collectors/devices/gps_ubx_ver_test.go +++ b/tgm-collector/pkg/collectors/devices/gps_ubx_ver_test.go @@ -12,9 +12,9 @@ import ( "k8s.io/client-go/tools/remotecommand" - "github.com/redhat-partner-solutions/vse-sync-collection-tools/pkg/clients" - "github.com/redhat-partner-solutions/vse-sync-collection-tools/pkg/collectors/devices" - "github.com/redhat-partner-solutions/vse-sync-collection-tools/testutils" + "github.com/redhat-partner-solutions/vse-sync-collection-tools/tgm-collector/pkg/clients" + "github.com/redhat-partner-solutions/vse-sync-collection-tools/tgm-collector/pkg/collectors/devices" + "github.com/redhat-partner-solutions/vse-sync-collection-tools/tgm-collector/testutils" ) var _ = Describe("GetGPSNav", func() { diff --git a/tgm-collector/pkg/collectors/devices/pmc.go b/tgm-collector/pkg/collectors/devices/pmc.go index f83e9336..d96b2fc9 100644 --- a/tgm-collector/pkg/collectors/devices/pmc.go +++ b/tgm-collector/pkg/collectors/devices/pmc.go @@ -9,9 +9,9 @@ import ( log "github.com/sirupsen/logrus" - "github.com/redhat-partner-solutions/vse-sync-collection-tools/pkg/callbacks" - "github.com/redhat-partner-solutions/vse-sync-collection-tools/pkg/clients" - "github.com/redhat-partner-solutions/vse-sync-collection-tools/pkg/fetcher" + "github.com/redhat-partner-solutions/vse-sync-collection-tools/tgm-collector/pkg/callbacks" + "github.com/redhat-partner-solutions/vse-sync-collection-tools/tgm-collector/pkg/clients" + "github.com/redhat-partner-solutions/vse-sync-collection-tools/tgm-collector/pkg/fetcher" ) type PMCInfo struct { diff --git a/tgm-collector/pkg/collectors/devices/pmc_test.go b/tgm-collector/pkg/collectors/devices/pmc_test.go index 516b759f..92011ffe 100644 --- a/tgm-collector/pkg/collectors/devices/pmc_test.go +++ b/tgm-collector/pkg/collectors/devices/pmc_test.go @@ -12,9 +12,9 @@ import ( "k8s.io/client-go/tools/remotecommand" - "github.com/redhat-partner-solutions/vse-sync-collection-tools/pkg/clients" - "github.com/redhat-partner-solutions/vse-sync-collection-tools/pkg/collectors/devices" - "github.com/redhat-partner-solutions/vse-sync-collection-tools/testutils" + "github.com/redhat-partner-solutions/vse-sync-collection-tools/tgm-collector/pkg/clients" + "github.com/redhat-partner-solutions/vse-sync-collection-tools/tgm-collector/pkg/collectors/devices" + "github.com/redhat-partner-solutions/vse-sync-collection-tools/tgm-collector/testutils" ) var _ = Describe("GetPMC", func() { diff --git a/tgm-collector/pkg/collectors/dpll_collector.go b/tgm-collector/pkg/collectors/dpll_collector.go index 1503ea44..62c5b3f6 100644 --- a/tgm-collector/pkg/collectors/dpll_collector.go +++ b/tgm-collector/pkg/collectors/dpll_collector.go @@ -7,8 +7,8 @@ import ( log "github.com/sirupsen/logrus" - "github.com/redhat-partner-solutions/vse-sync-collection-tools/pkg/collectors/contexts" - "github.com/redhat-partner-solutions/vse-sync-collection-tools/pkg/collectors/devices" + "github.com/redhat-partner-solutions/vse-sync-collection-tools/tgm-collector/pkg/collectors/contexts" + "github.com/redhat-partner-solutions/vse-sync-collection-tools/tgm-collector/pkg/collectors/devices" ) const ( diff --git a/tgm-collector/pkg/collectors/dpll_collector_fs.go b/tgm-collector/pkg/collectors/dpll_collector_fs.go index c36d83ec..23e3b068 100644 --- a/tgm-collector/pkg/collectors/dpll_collector_fs.go +++ b/tgm-collector/pkg/collectors/dpll_collector_fs.go @@ -5,10 +5,10 @@ package collectors import ( "fmt" - "github.com/redhat-partner-solutions/vse-sync-collection-tools/pkg/clients" - "github.com/redhat-partner-solutions/vse-sync-collection-tools/pkg/collectors/contexts" - "github.com/redhat-partner-solutions/vse-sync-collection-tools/pkg/collectors/devices" - "github.com/redhat-partner-solutions/vse-sync-collection-tools/pkg/utils" + "github.com/redhat-partner-solutions/vse-sync-collection-tools/tgm-collector/pkg/clients" + "github.com/redhat-partner-solutions/vse-sync-collection-tools/tgm-collector/pkg/collectors/contexts" + "github.com/redhat-partner-solutions/vse-sync-collection-tools/tgm-collector/pkg/collectors/devices" + "github.com/redhat-partner-solutions/vse-sync-collection-tools/tgm-collector/pkg/utils" ) type DPLLFilesystemCollector struct { diff --git a/tgm-collector/pkg/collectors/dpll_collector_netlink.go b/tgm-collector/pkg/collectors/dpll_collector_netlink.go index d53b9c92..743c00d0 100644 --- a/tgm-collector/pkg/collectors/dpll_collector_netlink.go +++ b/tgm-collector/pkg/collectors/dpll_collector_netlink.go @@ -7,10 +7,10 @@ import ( log "github.com/sirupsen/logrus" - "github.com/redhat-partner-solutions/vse-sync-collection-tools/pkg/clients" - "github.com/redhat-partner-solutions/vse-sync-collection-tools/pkg/collectors/contexts" - "github.com/redhat-partner-solutions/vse-sync-collection-tools/pkg/collectors/devices" - "github.com/redhat-partner-solutions/vse-sync-collection-tools/pkg/utils" + "github.com/redhat-partner-solutions/vse-sync-collection-tools/tgm-collector/pkg/clients" + "github.com/redhat-partner-solutions/vse-sync-collection-tools/tgm-collector/pkg/collectors/contexts" + "github.com/redhat-partner-solutions/vse-sync-collection-tools/tgm-collector/pkg/collectors/devices" + "github.com/redhat-partner-solutions/vse-sync-collection-tools/tgm-collector/pkg/utils" ) type DPLLNetlinkCollector struct { diff --git a/tgm-collector/pkg/collectors/gps_ubx_collector.go b/tgm-collector/pkg/collectors/gps_ubx_collector.go index 8086dbc1..d923c64c 100644 --- a/tgm-collector/pkg/collectors/gps_ubx_collector.go +++ b/tgm-collector/pkg/collectors/gps_ubx_collector.go @@ -5,10 +5,10 @@ package collectors //nolint:dupl // new collector import ( "fmt" - "github.com/redhat-partner-solutions/vse-sync-collection-tools/pkg/clients" - "github.com/redhat-partner-solutions/vse-sync-collection-tools/pkg/collectors/contexts" - "github.com/redhat-partner-solutions/vse-sync-collection-tools/pkg/collectors/devices" - "github.com/redhat-partner-solutions/vse-sync-collection-tools/pkg/utils" + "github.com/redhat-partner-solutions/vse-sync-collection-tools/tgm-collector/pkg/clients" + "github.com/redhat-partner-solutions/vse-sync-collection-tools/tgm-collector/pkg/collectors/contexts" + "github.com/redhat-partner-solutions/vse-sync-collection-tools/tgm-collector/pkg/collectors/devices" + "github.com/redhat-partner-solutions/vse-sync-collection-tools/tgm-collector/pkg/utils" ) var ( diff --git a/tgm-collector/pkg/collectors/log_follower.go b/tgm-collector/pkg/collectors/log_follower.go index 16db7a9b..8d088962 100644 --- a/tgm-collector/pkg/collectors/log_follower.go +++ b/tgm-collector/pkg/collectors/log_follower.go @@ -17,10 +17,10 @@ import ( v1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "github.com/redhat-partner-solutions/vse-sync-collection-tools/pkg/clients" - "github.com/redhat-partner-solutions/vse-sync-collection-tools/pkg/collectors/contexts" - "github.com/redhat-partner-solutions/vse-sync-collection-tools/pkg/loglines" - "github.com/redhat-partner-solutions/vse-sync-collection-tools/pkg/utils" + "github.com/redhat-partner-solutions/vse-sync-collection-tools/tgm-collector/pkg/clients" + "github.com/redhat-partner-solutions/vse-sync-collection-tools/tgm-collector/pkg/collectors/contexts" + "github.com/redhat-partner-solutions/vse-sync-collection-tools/tgm-collector/pkg/loglines" + "github.com/redhat-partner-solutions/vse-sync-collection-tools/tgm-collector/pkg/utils" ) const ( diff --git a/tgm-collector/pkg/collectors/pmc_collector.go b/tgm-collector/pkg/collectors/pmc_collector.go index e9e33c10..51c189ef 100644 --- a/tgm-collector/pkg/collectors/pmc_collector.go +++ b/tgm-collector/pkg/collectors/pmc_collector.go @@ -5,10 +5,10 @@ package collectors //nolint:dupl // new collector import ( "fmt" - "github.com/redhat-partner-solutions/vse-sync-collection-tools/pkg/clients" - "github.com/redhat-partner-solutions/vse-sync-collection-tools/pkg/collectors/contexts" - "github.com/redhat-partner-solutions/vse-sync-collection-tools/pkg/collectors/devices" - "github.com/redhat-partner-solutions/vse-sync-collection-tools/pkg/utils" + "github.com/redhat-partner-solutions/vse-sync-collection-tools/tgm-collector/pkg/clients" + "github.com/redhat-partner-solutions/vse-sync-collection-tools/tgm-collector/pkg/collectors/contexts" + "github.com/redhat-partner-solutions/vse-sync-collection-tools/tgm-collector/pkg/collectors/devices" + "github.com/redhat-partner-solutions/vse-sync-collection-tools/tgm-collector/pkg/utils" ) const ( diff --git a/tgm-collector/pkg/fetcher/builder.go b/tgm-collector/pkg/fetcher/builder.go index bce4ee59..793a3297 100644 --- a/tgm-collector/pkg/fetcher/builder.go +++ b/tgm-collector/pkg/fetcher/builder.go @@ -5,7 +5,7 @@ package fetcher import ( "fmt" - "github.com/redhat-partner-solutions/vse-sync-collection-tools/pkg/clients" + "github.com/redhat-partner-solutions/vse-sync-collection-tools/tgm-collector/pkg/clients" ) type AddCommandArgs struct { diff --git a/tgm-collector/pkg/fetcher/fetcher.go b/tgm-collector/pkg/fetcher/fetcher.go index 9f47a4a1..2a55f860 100644 --- a/tgm-collector/pkg/fetcher/fetcher.go +++ b/tgm-collector/pkg/fetcher/fetcher.go @@ -9,7 +9,7 @@ import ( log "github.com/sirupsen/logrus" - "github.com/redhat-partner-solutions/vse-sync-collection-tools/pkg/clients" + "github.com/redhat-partner-solutions/vse-sync-collection-tools/tgm-collector/pkg/clients" ) type PostProcessFuncType func(map[string]string) (map[string]any, error) diff --git a/tgm-collector/pkg/logging/logging.go b/tgm-collector/pkg/logging/logging.go index 1db41f5f..b3510419 100644 --- a/tgm-collector/pkg/logging/logging.go +++ b/tgm-collector/pkg/logging/logging.go @@ -7,7 +7,7 @@ import ( log "github.com/sirupsen/logrus" - "github.com/redhat-partner-solutions/vse-sync-collection-tools/pkg/utils" + "github.com/redhat-partner-solutions/vse-sync-collection-tools/tgm-collector/pkg/utils" ) // SetupLogging will configure the output stream and the level diff --git a/tgm-collector/pkg/loglines/dedup_test.go b/tgm-collector/pkg/loglines/dedup_test.go index e78d9ec5..ecb12d22 100644 --- a/tgm-collector/pkg/loglines/dedup_test.go +++ b/tgm-collector/pkg/loglines/dedup_test.go @@ -11,7 +11,7 @@ import ( . "github.com/onsi/ginkgo/v2" . "github.com/onsi/gomega" - "github.com/redhat-partner-solutions/vse-sync-collection-tools/pkg/loglines" + "github.com/redhat-partner-solutions/vse-sync-collection-tools/tgm-collector/pkg/loglines" ) //nolint:unparam // its only one param for now but we might want more later diff --git a/tgm-collector/pkg/loglines/lines.go b/tgm-collector/pkg/loglines/lines.go index 58b0a2c8..4e870ffa 100644 --- a/tgm-collector/pkg/loglines/lines.go +++ b/tgm-collector/pkg/loglines/lines.go @@ -14,7 +14,7 @@ import ( log "github.com/sirupsen/logrus" - "github.com/redhat-partner-solutions/vse-sync-collection-tools/pkg/utils" + "github.com/redhat-partner-solutions/vse-sync-collection-tools/tgm-collector/pkg/utils" ) const ( diff --git a/tgm-collector/pkg/runner/collector_selector.go b/tgm-collector/pkg/runner/collector_selector.go index 4b2e6b60..378dc7e6 100644 --- a/tgm-collector/pkg/runner/collector_selector.go +++ b/tgm-collector/pkg/runner/collector_selector.go @@ -7,7 +7,7 @@ import ( log "github.com/sirupsen/logrus" - "github.com/redhat-partner-solutions/vse-sync-collection-tools/pkg/collectors" + "github.com/redhat-partner-solutions/vse-sync-collection-tools/tgm-collector/pkg/collectors" ) var ( diff --git a/tgm-collector/pkg/runner/runner.go b/tgm-collector/pkg/runner/runner.go index cc5d8e9a..a00cbcd8 100644 --- a/tgm-collector/pkg/runner/runner.go +++ b/tgm-collector/pkg/runner/runner.go @@ -11,10 +11,10 @@ import ( log "github.com/sirupsen/logrus" - "github.com/redhat-partner-solutions/vse-sync-collection-tools/pkg/callbacks" - "github.com/redhat-partner-solutions/vse-sync-collection-tools/pkg/clients" - "github.com/redhat-partner-solutions/vse-sync-collection-tools/pkg/collectors" - "github.com/redhat-partner-solutions/vse-sync-collection-tools/pkg/utils" + "github.com/redhat-partner-solutions/vse-sync-collection-tools/tgm-collector/pkg/callbacks" + "github.com/redhat-partner-solutions/vse-sync-collection-tools/tgm-collector/pkg/clients" + "github.com/redhat-partner-solutions/vse-sync-collection-tools/tgm-collector/pkg/collectors" + "github.com/redhat-partner-solutions/vse-sync-collection-tools/tgm-collector/pkg/utils" ) const ( diff --git a/tgm-collector/pkg/validations/cluster_version.go b/tgm-collector/pkg/validations/cluster_version.go index c2b6d43a..884f9368 100644 --- a/tgm-collector/pkg/validations/cluster_version.go +++ b/tgm-collector/pkg/validations/cluster_version.go @@ -13,7 +13,7 @@ import ( "k8s.io/apimachinery/pkg/runtime/schema" "k8s.io/client-go/dynamic" - "github.com/redhat-partner-solutions/vse-sync-collection-tools/pkg/clients" + "github.com/redhat-partner-solutions/vse-sync-collection-tools/tgm-collector/pkg/clients" ) const ( diff --git a/tgm-collector/pkg/validations/common.go b/tgm-collector/pkg/validations/common.go index 747f04aa..5f471761 100644 --- a/tgm-collector/pkg/validations/common.go +++ b/tgm-collector/pkg/validations/common.go @@ -9,7 +9,7 @@ import ( "golang.org/x/mod/semver" - "github.com/redhat-partner-solutions/vse-sync-collection-tools/pkg/utils" + "github.com/redhat-partner-solutions/vse-sync-collection-tools/tgm-collector/pkg/utils" ) const ( diff --git a/tgm-collector/pkg/validations/device.go b/tgm-collector/pkg/validations/device.go index 2fe54e2a..2f271686 100644 --- a/tgm-collector/pkg/validations/device.go +++ b/tgm-collector/pkg/validations/device.go @@ -5,8 +5,8 @@ package validations import ( "fmt" - "github.com/redhat-partner-solutions/vse-sync-collection-tools/pkg/collectors/devices" - "github.com/redhat-partner-solutions/vse-sync-collection-tools/pkg/utils" + "github.com/redhat-partner-solutions/vse-sync-collection-tools/tgm-collector/pkg/collectors/devices" + "github.com/redhat-partner-solutions/vse-sync-collection-tools/tgm-collector/pkg/utils" ) const ( diff --git a/tgm-collector/pkg/validations/device_driver.go b/tgm-collector/pkg/validations/device_driver.go index 7bdcafe0..c3d41e5a 100644 --- a/tgm-collector/pkg/validations/device_driver.go +++ b/tgm-collector/pkg/validations/device_driver.go @@ -8,7 +8,7 @@ import ( "golang.org/x/mod/semver" - "github.com/redhat-partner-solutions/vse-sync-collection-tools/pkg/collectors/devices" + "github.com/redhat-partner-solutions/vse-sync-collection-tools/tgm-collector/pkg/collectors/devices" ) const ( diff --git a/tgm-collector/pkg/validations/device_firmware.go b/tgm-collector/pkg/validations/device_firmware.go index 7f399426..a21ef08b 100644 --- a/tgm-collector/pkg/validations/device_firmware.go +++ b/tgm-collector/pkg/validations/device_firmware.go @@ -5,7 +5,7 @@ package validations import ( "strings" - "github.com/redhat-partner-solutions/vse-sync-collection-tools/pkg/collectors/devices" + "github.com/redhat-partner-solutions/vse-sync-collection-tools/tgm-collector/pkg/collectors/devices" ) const ( diff --git a/tgm-collector/pkg/validations/gnss_ant_power_status.go b/tgm-collector/pkg/validations/gnss_ant_power_status.go index d64f63c0..26126505 100644 --- a/tgm-collector/pkg/validations/gnss_ant_power_status.go +++ b/tgm-collector/pkg/validations/gnss_ant_power_status.go @@ -5,8 +5,8 @@ package validations import ( "errors" - "github.com/redhat-partner-solutions/vse-sync-collection-tools/pkg/collectors/devices" - "github.com/redhat-partner-solutions/vse-sync-collection-tools/pkg/utils" + "github.com/redhat-partner-solutions/vse-sync-collection-tools/tgm-collector/pkg/collectors/devices" + "github.com/redhat-partner-solutions/vse-sync-collection-tools/tgm-collector/pkg/utils" ) const ( diff --git a/tgm-collector/pkg/validations/gnss_devices.go b/tgm-collector/pkg/validations/gnss_devices.go index 0c9b4566..69ddf3cc 100644 --- a/tgm-collector/pkg/validations/gnss_devices.go +++ b/tgm-collector/pkg/validations/gnss_devices.go @@ -5,8 +5,8 @@ package validations import ( "errors" - "github.com/redhat-partner-solutions/vse-sync-collection-tools/pkg/collectors/devices" - "github.com/redhat-partner-solutions/vse-sync-collection-tools/pkg/utils" + "github.com/redhat-partner-solutions/vse-sync-collection-tools/tgm-collector/pkg/collectors/devices" + "github.com/redhat-partner-solutions/vse-sync-collection-tools/tgm-collector/pkg/utils" ) const ( diff --git a/tgm-collector/pkg/validations/gnss_firmware_version.go b/tgm-collector/pkg/validations/gnss_firmware_version.go index cdaa9e37..2cfda729 100644 --- a/tgm-collector/pkg/validations/gnss_firmware_version.go +++ b/tgm-collector/pkg/validations/gnss_firmware_version.go @@ -5,7 +5,7 @@ package validations import ( "strings" - "github.com/redhat-partner-solutions/vse-sync-collection-tools/pkg/collectors/devices" + "github.com/redhat-partner-solutions/vse-sync-collection-tools/tgm-collector/pkg/collectors/devices" ) const ( diff --git a/tgm-collector/pkg/validations/gnss_module.go b/tgm-collector/pkg/validations/gnss_module.go index 7d0a6496..6f681118 100644 --- a/tgm-collector/pkg/validations/gnss_module.go +++ b/tgm-collector/pkg/validations/gnss_module.go @@ -5,8 +5,8 @@ package validations import ( "fmt" - "github.com/redhat-partner-solutions/vse-sync-collection-tools/pkg/collectors/devices" - "github.com/redhat-partner-solutions/vse-sync-collection-tools/pkg/utils" + "github.com/redhat-partner-solutions/vse-sync-collection-tools/tgm-collector/pkg/collectors/devices" + "github.com/redhat-partner-solutions/vse-sync-collection-tools/tgm-collector/pkg/utils" ) const ( diff --git a/tgm-collector/pkg/validations/gnss_protocol_version.go b/tgm-collector/pkg/validations/gnss_protocol_version.go index c79b0adc..617b2b29 100644 --- a/tgm-collector/pkg/validations/gnss_protocol_version.go +++ b/tgm-collector/pkg/validations/gnss_protocol_version.go @@ -3,7 +3,7 @@ package validations import ( - "github.com/redhat-partner-solutions/vse-sync-collection-tools/pkg/collectors/devices" + "github.com/redhat-partner-solutions/vse-sync-collection-tools/tgm-collector/pkg/collectors/devices" ) const ( diff --git a/tgm-collector/pkg/validations/gnss_receiving_data.go b/tgm-collector/pkg/validations/gnss_receiving_data.go index 5b331ecc..6b142323 100644 --- a/tgm-collector/pkg/validations/gnss_receiving_data.go +++ b/tgm-collector/pkg/validations/gnss_receiving_data.go @@ -5,8 +5,8 @@ package validations import ( "errors" - "github.com/redhat-partner-solutions/vse-sync-collection-tools/pkg/collectors/devices" - "github.com/redhat-partner-solutions/vse-sync-collection-tools/pkg/utils" + "github.com/redhat-partner-solutions/vse-sync-collection-tools/tgm-collector/pkg/collectors/devices" + "github.com/redhat-partner-solutions/vse-sync-collection-tools/tgm-collector/pkg/utils" ) const ( diff --git a/tgm-collector/pkg/validations/gpsd_version.go b/tgm-collector/pkg/validations/gpsd_version.go index 24b7b8c1..75f07a72 100644 --- a/tgm-collector/pkg/validations/gpsd_version.go +++ b/tgm-collector/pkg/validations/gpsd_version.go @@ -5,7 +5,7 @@ package validations import ( "strings" - "github.com/redhat-partner-solutions/vse-sync-collection-tools/pkg/collectors/devices" + "github.com/redhat-partner-solutions/vse-sync-collection-tools/tgm-collector/pkg/collectors/devices" ) const ( diff --git a/tgm-collector/pkg/validations/grand_master.go b/tgm-collector/pkg/validations/grand_master.go index 96f9e079..456a9b02 100644 --- a/tgm-collector/pkg/validations/grand_master.go +++ b/tgm-collector/pkg/validations/grand_master.go @@ -9,8 +9,8 @@ import ( "fmt" "strings" - "github.com/redhat-partner-solutions/vse-sync-collection-tools/pkg/clients" - "github.com/redhat-partner-solutions/vse-sync-collection-tools/pkg/utils" + "github.com/redhat-partner-solutions/vse-sync-collection-tools/tgm-collector/pkg/clients" + "github.com/redhat-partner-solutions/vse-sync-collection-tools/tgm-collector/pkg/utils" ) const ( diff --git a/tgm-collector/pkg/validations/operator_version.go b/tgm-collector/pkg/validations/operator_version.go index 094808c0..5c7d5fe1 100644 --- a/tgm-collector/pkg/validations/operator_version.go +++ b/tgm-collector/pkg/validations/operator_version.go @@ -13,7 +13,7 @@ import ( "k8s.io/apimachinery/pkg/runtime/schema" "k8s.io/client-go/dynamic" - "github.com/redhat-partner-solutions/vse-sync-collection-tools/pkg/clients" + "github.com/redhat-partner-solutions/vse-sync-collection-tools/tgm-collector/pkg/clients" ) const ( diff --git a/tgm-collector/pkg/verify/result.go b/tgm-collector/pkg/verify/result.go index 65a54592..5ad2c881 100644 --- a/tgm-collector/pkg/verify/result.go +++ b/tgm-collector/pkg/verify/result.go @@ -6,9 +6,9 @@ import ( "errors" "fmt" - "github.com/redhat-partner-solutions/vse-sync-collection-tools/pkg/callbacks" - "github.com/redhat-partner-solutions/vse-sync-collection-tools/pkg/utils" - "github.com/redhat-partner-solutions/vse-sync-collection-tools/pkg/validations" + "github.com/redhat-partner-solutions/vse-sync-collection-tools/tgm-collector/pkg/callbacks" + "github.com/redhat-partner-solutions/vse-sync-collection-tools/tgm-collector/pkg/utils" + "github.com/redhat-partner-solutions/vse-sync-collection-tools/tgm-collector/pkg/validations" ) type resType int diff --git a/tgm-collector/pkg/verify/verify.go b/tgm-collector/pkg/verify/verify.go index 4d61d7dd..1fdae52b 100644 --- a/tgm-collector/pkg/verify/verify.go +++ b/tgm-collector/pkg/verify/verify.go @@ -10,12 +10,12 @@ import ( log "github.com/sirupsen/logrus" - "github.com/redhat-partner-solutions/vse-sync-collection-tools/pkg/callbacks" - "github.com/redhat-partner-solutions/vse-sync-collection-tools/pkg/clients" - "github.com/redhat-partner-solutions/vse-sync-collection-tools/pkg/collectors/contexts" - "github.com/redhat-partner-solutions/vse-sync-collection-tools/pkg/collectors/devices" - "github.com/redhat-partner-solutions/vse-sync-collection-tools/pkg/utils" - "github.com/redhat-partner-solutions/vse-sync-collection-tools/pkg/validations" + "github.com/redhat-partner-solutions/vse-sync-collection-tools/tgm-collector/pkg/callbacks" + "github.com/redhat-partner-solutions/vse-sync-collection-tools/tgm-collector/pkg/clients" + "github.com/redhat-partner-solutions/vse-sync-collection-tools/tgm-collector/pkg/collectors/contexts" + "github.com/redhat-partner-solutions/vse-sync-collection-tools/tgm-collector/pkg/collectors/devices" + "github.com/redhat-partner-solutions/vse-sync-collection-tools/tgm-collector/pkg/utils" + "github.com/redhat-partner-solutions/vse-sync-collection-tools/tgm-collector/pkg/validations" ) const ( diff --git a/tgm-collector/testutils/mocked_clientset.go b/tgm-collector/testutils/mocked_clientset.go index 008987c9..94e07134 100644 --- a/tgm-collector/testutils/mocked_clientset.go +++ b/tgm-collector/testutils/mocked_clientset.go @@ -10,7 +10,7 @@ import ( fakeK8s "k8s.io/client-go/kubernetes/fake" "k8s.io/client-go/rest" - "github.com/redhat-partner-solutions/vse-sync-collection-tools/pkg/clients" + "github.com/redhat-partner-solutions/vse-sync-collection-tools/tgm-collector/pkg/clients" ) const kubeconfigPath string = "test_files/kubeconfig"