Compare commits

...

67 Commits

Author SHA1 Message Date
Itxaka
99c1c93d26 Sign uki tpm stuff with a policy (#39) 2023-12-15 16:47:56 +01:00
renovate[bot]
12a8d5d33c Update module github.com/kairos-io/kairos-sdk to v0.0.18 2023-12-06 23:19:13 +00:00
renovate[bot]
ce877a2a7f Update module github.com/kairos-io/kairos-sdk to v0.0.16 2023-11-30 22:29:59 +00:00
Itxaka
554e350fb7 Fix issue when closing the device (#34) 2023-11-30 18:10:15 +01:00
renovate[bot]
e86d8e5595 Update module github.com/urfave/cli to v1.22.14 2023-11-30 13:45:11 +00:00
Itxaka
42e451494d Merge pull request #33 from Itxaka/public_functions 2023-11-30 14:41:36 +01:00
Itxaka
94af8c8dd3 Also unlock with TPM
so we can use the same functions everywhere just with a flag

Signed-off-by: Itxaka <itxaka@kairos.io>
2023-11-30 11:39:21 +01:00
Itxaka
e73e33b26d cryptenroll needs the actual password
Also remove password from the luksdevice once we are finished

Signed-off-by: Itxaka <itxaka@kairos.io>
2023-11-30 11:29:20 +01:00
Itxaka
e43da08f2d Allow passing flags to luksify
flags for luks version and use tpm

Signed-off-by: Itxaka <itxaka@kairos.io>
2023-11-30 11:01:39 +01:00
Itxaka
365f16e8f1 Move all functions under pkg
Signed-off-by: Itxaka <itxaka@kairos.io>
2023-11-30 10:24:55 +01:00
renovate[bot]
4ec8386ac8 Update module github.com/kairos-io/kairos-sdk to v0.0.15 2023-10-29 02:43:40 +00:00
Mauro Morales
20547f93a2 Configure automerge for patch updtes 2023-10-04 17:04:33 +02:00
Itxaka
864ff80b53 Merge pull request #20 from kairos-io/bump_sdk 2023-06-14 16:18:40 +02:00
Itxaka
bdde2df13a Merge branch 'main' into bump_sdk 2023-06-14 15:23:37 +02:00
Itxaka
166b8802ea Drop kairos lib and use sdk instead
Signed-off-by: Itxaka <itxaka.garcia@spectrocloud.com>
2023-06-14 15:03:31 +02:00
Itxaka
3a0c3f0bae Merge pull request #2 from kairos-io/renovate/configure 2023-06-14 14:36:52 +02:00
Itxaka
16ec663748 Merge branch 'main' into renovate/configure 2023-06-14 14:36:47 +02:00
Mauro Morales
59ed3da68d Update issue templates
relates to https://github.com/kairos-io/kairos/issues/1483
2023-06-13 12:18:46 +02:00
Itxaka
c08c563658 Merge pull request #19 from kairos-io/debug 2023-05-05 10:18:17 +02:00
Itxaka
47e7f67e04 Fix label
Signed-off-by: Itxaka <itxaka.garcia@spectrocloud.com>
2023-05-05 09:19:46 +02:00
Itxaka
f5dc23f554 Merge pull request #18 from kairos-io/rework_dracut 2023-05-04 14:10:15 +02:00
Itxaka
2889a52eab Merge branch 'main' into rework_dracut 2023-05-04 12:41:55 +02:00
Itxaka
18eab4843d Merge pull request #17 from kairos-io/uuid_partition_identify 2023-05-04 12:38:29 +02:00
Itxaka
3e25056dd0 Merge branch 'main' into uuid_partition_identify 2023-05-04 12:07:39 +02:00
Itxaka
36f861fd0c Use reproducible UUIDs for partition identification
Signed-off-by: Itxaka <itxaka.garcia@spectrocloud.com>
2023-05-04 12:07:21 +02:00
Itxaka
5f52d1f2f9 Store dracut artifacts in its own target
So its easier to access them from other places.
Alos stores the dracut.conf file for kcryt under the dracut dir and
renames it to its proper final name

Signed-off-by: Itxaka <itxaka.garcia@spectrocloud.com>
2023-05-03 21:52:44 +02:00
Itxaka
7a8210d26c Merge pull request #16 from kairos-io/more_public_functions
🌱 Make some functions public
2023-04-19 17:27:20 +02:00
Itxaka
6d6dfd00a1 🌱 Make some functions public
So they can be imported from different places as lib and re-used

Signed-off-by: Itxaka <itxaka.garcia@spectrocloud.com>
2023-04-19 14:44:33 +02:00
renovate[bot]
a312a2ecd8 Add renovate.json 2023-03-30 19:51:44 +00:00
Mauro Morales
92c79f4e75 Merge pull request #15 from kairos-io/bump-go-version-to-1.20.2
⬆️ bump go version to 1.20.2
2023-03-30 09:10:18 +02:00
Mauro Morales
a254871c22 Remove something left from the merge conflict
Signed-off-by: Mauro Morales <mauro.morales@spectrocloud.com>
2023-03-30 09:06:11 +02:00
Mauro Morales
7e6a31f38b Add lint workflow
Signed-off-by: Mauro Morales <mauro.morales@spectrocloud.com>
2023-03-29 17:05:53 +02:00
Mauro Morales
0f3eee7851 Add golint
Signed-off-by: Mauro Morales <mauro.morales@spectrocloud.com>
2023-03-29 17:05:51 +02:00
Mauro Morales
15cc284978 Part of previous commit
Signed-off-by: Mauro Morales <mauro.morales@spectrocloud.com>
2023-03-29 17:00:06 +02:00
Mauro Morales
b7352829ff Add yamllint
Signed-off-by: Mauro Morales <mauro.morales@spectrocloud.com>
2023-03-29 17:00:06 +02:00
Mauro Morales
57aef89b02 ⬆️ bump go version to 1.20.2
Signed-off-by: Mauro Morales <mauro.morales@spectrocloud.com>
2023-03-29 16:59:56 +02:00
Dimitris Karakasilis
2dbd13c984 Merge pull request #14 from kairos-io/use-collector-insted-of-config
 Switch to using new collector pkg
2023-03-29 17:38:49 +03:00
Dimitris Karakasilis
ff42570ec7 Fix go.sum/go.mod with go mod tidy
Signed-off-by: Dimitris Karakasilis <dimitris@karakasilis.me>
2023-03-29 17:29:41 +03:00
Mauro Morales
36fafa38cf Add test for header when writing mappings
Signed-off-by: Mauro Morales <mauro.morales@spectrocloud.com>
2023-03-29 17:27:55 +03:00
Mauro Morales
f977f72e8d Switch to using new collector pkg
Signed-off-by: Mauro Morales <mauro.morales@spectrocloud.com>
2023-03-29 17:27:55 +03:00
Itxaka
608b465afc Merge pull request #13 from kairos-io/move_to_immucore 2023-03-15 10:37:10 +01:00
Itxaka
79fbcc2f73 Merge branch 'main' into move_to_immucore 2023-03-09 23:55:05 +01:00
Itxaka
7298e9c0dd Merge pull request #12 from kairos-io/Itxaka-patch-1 2023-03-09 23:54:36 +01:00
Itxaka
94cfbcfe88 Update dracut/29kcrypt/generator.sh
Co-authored-by: Mauro Morales <contact@mauromorales.com>
2023-03-01 16:58:08 +01:00
Itxaka
1296f284cb Update dracut/29kcrypt/generator.sh
Co-authored-by: Mauro Morales <contact@mauromorales.com>
2023-03-01 16:58:01 +01:00
Itxaka
4cff0323af Depend on immucore-service
Signed-off-by: Itxaka <itxaka.garcia@spectrocloud.com>
2023-03-01 12:45:19 +01:00
Itxaka
9c7c27af89 Skip kcrypt on non-immmutable systems
Disable the module creating any services if the inmutability layer is not gonna run as it makes no sense to load kcrypt if we are not mounting our stuff.

Fixes https://github.com/kairos-io/kairos/issues/642

Signed-off-by: Itxaka <itxaka.garcia@spectrocloud.com>
2023-03-01 12:44:08 +01:00
Dimitris Karakasilis
fa9eb79998 Merge pull request #11 from kairos-io/bump-go-pluggable
Bump go-pluggable to show output from kcrypt-challenger when somethin…
2023-02-08 16:28:12 +02:00
Dimitris Karakasilis
11bfa53dc1 Bump go-pluggable to show output from kcrypt-challenger when something fails
Signed-off-by: Dimitris Karakasilis <dimitris@karakasilis.me>
2023-02-08 16:15:05 +02:00
Ettore Di Giacinto
930d7433ae 📖 Create README 2023-02-07 12:32:55 +01:00
Dimitris Karakasilis
845f5984b1 Merge pull request #10 from kairos-io/no_challenger
🌱 Remove challenger traces from here
2023-01-19 15:25:40 +02:00
mudler
71506ff020 🌱 Remove challenger traces from here
The challenger has no business logic in here, and kcrypt should just
read what it needs. This goes in parallel with https://github.com/kairos-io/kcrypt-challenger/pull/10
Not blocking each other.

Signed-off-by: mudler <mudler@c3os.io>
2023-01-19 12:28:46 +01:00
Dimitris Karakasilis
27183fbce7 Merge pull request #9 from kairos-io/399-kcrypt-configuration
Move from partition_info to config package
2023-01-18 14:59:49 +02:00
Dimitris Karakasilis
018322ff00 Move from partition_info to config package
Now the kcrypt configuration will be just a block (`kcrypt`) in the regular
kairos configuration files.

We will use the config mechanism of looking up in multiple directories
becase the old code was only looking at `/oem` but at boot time
(initramfs) the configuration was present in `/sysroot/oem`.

The reason it "worked" was that we had a bug and a sealedvolume was
matching our request simply because we sent an empty UUID/Label/Name
and the sealedvolume had and empty UUID (empty matches empty, right?)

With that fixed on the challenger server side, it became obvious that we
never actually read the partition_info file because we were looking for
it at the wrong place.

Signed-off-by: Dimitris Karakasilis <dimitris@karakasilis.me>
2023-01-18 14:55:25 +02:00
Ettore Di Giacinto
361e1ab817 Merge pull request #7 from kairos-io/fix/umount
Do not umount oem if we have found it out
2022-11-23 16:25:16 +01:00
Ettore Di Giacinto
4234ae7034 Incorporating feedback review 2022-11-23 15:11:48 +00:00
Ettore Di Giacinto
193a7da9ee Update main.go
Co-authored-by: Dimitris Karakasilis <jimmykarily@gmail.com>
2022-11-23 16:05:44 +01:00
Ettore Di Giacinto
e0316ade0a Add earthly.sh 2022-11-23 15:16:04 +01:00
Ettore Di Giacinto
1c3a3ac510 Do not fail if we can't find a partition file 2022-11-23 14:09:44 +01:00
Ettore Di Giacinto
641fc6ffa7 Try to run kcrypt directly 2022-11-23 14:01:46 +01:00
Ettore Di Giacinto
214ae51333 Bind it to sysroot 2022-11-23 14:01:46 +01:00
Ettore Di Giacinto
7f397a3459 Try to wait for oem mount instead 2022-11-23 14:01:46 +01:00
Ettore Di Giacinto
b3d7b86591 Do not umount oem if we have found it out
Signed-off-by: Ettore Di Giacinto <mudler@users.noreply.github.com>
2022-11-23 14:01:46 +01:00
Ettore Di Giacinto
24240b6421 Merge pull request #8 from kairos-io/dont-hide-errors
Don't hide there error when it's not about file not existing
2022-11-23 14:00:57 +01:00
Dimitris Karakasilis
bb144f204a Don't hide there error when it's not about file not existing
Signed-off-by: Dimitris Karakasilis <dimitris@karakasilis.me>
2022-11-23 14:53:02 +02:00
Dimitris Karakasilis
7d077c9353 Merge pull request #6 from kairos-io/dont-let-mapping-be-nil
Don't let the mapping be nil when reading an empty file
2022-11-16 09:30:31 +02:00
Dimitris Karakasilis
0e278a89f0 Don't let the mapping be nil when reading an empty file
e.g. when we first create it

because it throws this error:

```
panic: assignment to entry in nil map

goroutine 1 [running]:
github.com/kairos-io/kcrypt/pkg/partition_info.PartitionInfo.UpdateMapping({{0xa60325?, 0x18?}, 0x0?}, {0xc000302000?, 0x1?})
	/go/pkg/mod/github.com/kairos-io/kcrypt@v0.4.2/pkg/partition_info/partition_info.go:69 +0x99

```

Signed-off-by: Dimitris Karakasilis <dimitris@karakasilis.me>
2022-11-15 19:45:44 +02:00
26 changed files with 1455 additions and 756 deletions

View File

@@ -0,0 +1,12 @@
---
name: File issues on main Kairos repo
about: Tell users to file their issues on the main Kairos repo
title: ''
labels: ''
assignees: ''
---
:warning: All Kairos issues are tracked in our main repo, please file your issue there, thanks! :warning:
https://github.com/kairos-io/kairos/issues

28
.github/workflows/lint.yaml vendored Normal file
View File

@@ -0,0 +1,28 @@
name: Lint
on:
push:
branches:
- main
pull_request:
paths:
- '**'
env:
FORCE_COLOR: 1
jobs:
lint:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v3
with:
fetch-depth: 0
- name: Install Go
uses: actions/setup-go@v4
- name: Install earthly
uses: Luet-lab/luet-install-action@v1
with:
repository: quay.io/kairos/packages
packages: utils/earthly
- name: Run Lint checks
run: |
earthly +lint

View File

@@ -1,9 +1,9 @@
name: Unit tests name: Unit tests
on: on:
push: push:
branches: branches:
- master - master
pull_request: pull_request:
jobs: jobs:
unit-tests: unit-tests:
@@ -16,7 +16,7 @@ jobs:
- name: Install Go - name: Install Go
uses: actions/setup-go@v3 uses: actions/setup-go@v3
with: with:
go-version: '^1.18' go-version: '^1.20'
- name: Install Ginkgo - name: Install Ginkgo
run: go install github.com/onsi/ginkgo/v2/ginkgo@v2.5.0 run: go install github.com/onsi/ginkgo/v2/ginkgo@v2.5.0

21
.yamllint Normal file
View File

@@ -0,0 +1,21 @@
extends: default
rules:
# 80 chars should be enough, but don't fail if a line is longer
line-length:
max: 150
level: warning
# accept both key:
# - item
#
# and key:
# - item
indentation:
indent-sequences: whatever
truthy:
check-keys: false
document-start:
present: false

View File

@@ -3,6 +3,9 @@ VERSION 0.6
# TODO: This needs to come from pre-built kernels in c3os repos, kcrypt included. # TODO: This needs to come from pre-built kernels in c3os repos, kcrypt included.
# Framework images should use our initrd # Framework images should use our initrd
ARG BASE_IMAGE=quay.io/kairos/core-opensuse ARG BASE_IMAGE=quay.io/kairos/core-opensuse
# renovate: datasource=docker depName=golang
ARG GO_VERSION=1.20.2
ARG GOLINT_VERSION=1.52.2
build-kcrypt: build-kcrypt:
FROM golang:alpine FROM golang:alpine
@@ -11,15 +14,22 @@ build-kcrypt:
WORKDIR /work WORKDIR /work
ARG VERSION="$(git describe --tags)" ARG VERSION="$(git describe --tags)"
RUN CGO_ENABLED=0 go build -o kcrypt -ldflags "-X main.Version=$VERSION" RUN CGO_ENABLED=0 go build -o kcrypt -ldflags "-X main.Version=$VERSION"
SAVE ARTIFACT /work/kcrypt AS LOCAL kcrypt SAVE ARTIFACT /work/kcrypt kcrypt AS LOCAL kcrypt
dracut-artifacts:
FROM $BASE_IMAGE
WORKDIR /build
COPY --dir dracut/29kcrypt .
COPY dracut/10-kcrypt.conf .
SAVE ARTIFACT 29kcrypt 29kcrypt
SAVE ARTIFACT 10-kcrypt.conf 10-kcrypt.conf
build-dracut: build-dracut:
FROM $BASE_IMAGE FROM $BASE_IMAGE
COPY . /work
COPY +build-kcrypt/kcrypt /usr/bin/kcrypt
WORKDIR /work WORKDIR /work
RUN cp -r dracut/* /usr/lib/dracut/modules.d COPY +build-kcrypt/kcrypt /usr/bin/kcrypt
RUN cp dracut.conf /etc/dracut.conf.d/10-kcrypt.conf COPY +dracut-artifacts/29kcrypt /usr/lib/dracut/modules.d/29kcrypt
COPY +dracut-artifacts/10-kcrypt.conf /etc/dracut.conf.d/10-kcrypt.conf
RUN kernel=$(ls /lib/modules | head -n1) && \ RUN kernel=$(ls /lib/modules | head -n1) && \
dracut -f "/boot/initrd-${kernel}" "${kernel}" && \ dracut -f "/boot/initrd-${kernel}" "${kernel}" && \
ln -sf "initrd-${kernel}" /boot/initrd ln -sf "initrd-${kernel}" /boot/initrd
@@ -63,3 +73,21 @@ iso:
RUN sha256sum $ISO_NAME.iso > $ISO_NAME.iso.sha256 RUN sha256sum $ISO_NAME.iso > $ISO_NAME.iso.sha256
SAVE ARTIFACT /build/$ISO_NAME.iso iso AS LOCAL build/$ISO_NAME.iso SAVE ARTIFACT /build/$ISO_NAME.iso iso AS LOCAL build/$ISO_NAME.iso
SAVE ARTIFACT /build/$ISO_NAME.iso.sha256 sha256 AS LOCAL build/$ISO_NAME.iso.sha256 SAVE ARTIFACT /build/$ISO_NAME.iso.sha256 sha256 AS LOCAL build/$ISO_NAME.iso.sha256
lint:
BUILD +golint
BUILD +yamllint
golint:
ARG GO_VERSION
FROM golang:$GO_VERSION
ARG GOLINT_VERSION
RUN wget -O- -nv https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s v$GOLINT_VERSION
WORKDIR /build
COPY . .
RUN golangci-lint run
yamllint:
FROM cytopia/yamllint
COPY . .
RUN yamllint .github/workflows/

64
README.md Normal file
View File

@@ -0,0 +1,64 @@
<h1 align="center">
<br>
<img width="184" alt="kairos-white-column 5bc2fe34" src="https://user-images.githubusercontent.com/2420543/193010398-72d4ba6e-7efe-4c2e-b7ba-d3a826a55b7d.png"><br>
Kcrypt
<br>
</h1>
<h3 align="center">Cloud native guardian for persistent data in the edge</h3>
<p align="center">
<a href="https://opensource.org/licenses/">
<img src="https://img.shields.io/badge/licence-APL2-brightgreen"
alt="license">
</a>
<a href="https://github.com/kairos-io/kcrypt/issues"><img src="https://img.shields.io/github/issues/kairos-io/kcrypt"></a>
<a href="https://kairos.io/docs/" target=_blank> <img src="https://img.shields.io/badge/Documentation-blue"
alt="docs"></a>
<img src="https://img.shields.io/badge/made%20with-Go-blue">
<img src="https://goreportcard.com/badge/github.com/kairos-io/kcrypt" alt="go report card" />
</p>
With Kairos you can build immutable, bootable Kubernetes and OS images for your edge devices as easily as writing a Dockerfile. Optional P2P mesh with distributed ledger automates node bootstrapping and coordination. Updating nodes is as easy as CI/CD: push a new image to your container registry and let secure, risk-free A/B atomic upgrades do the rest.
<table>
<tr>
<th align="center">
<img width="640" height="1px">
<p>
<small>
Documentation
</small>
</p>
</th>
<th align="center">
<img width="640" height="1">
<p>
<small>
Contribute
</small>
</p>
</th>
</tr>
<tr>
<td>
📚 [Getting started with Kairos](https://kairos.io/docs/getting-started) <br> :bulb: [Examples](https://kairos.io/docs/examples) <br> :movie_camera: [Video](https://kairos.io/docs/media/) <br> :open_hands:[Engage with the Community](https://kairos.io/community/)
</td>
<td>
🙌[ CONTRIBUTING.md ]( https://github.com/kairos-io/kairos/blob/master/CONTRIBUTING.md ) <br> :raising_hand: [ GOVERNANCE ]( https://github.com/kairos-io/kairos/blob/master/GOVERNANCE.md ) <br>:construction_worker:[Code of conduct](https://github.com/kairos-io/kairos/blob/master/CODE_OF_CONDUCT.md)
</td>
</tr>
</table>
## Description
This is the Kairos internal component which delegates encryption and decryption of partitions in a Kairos system.
## Usage
See the documentation in our website: https://kairos.io/docs/advanced/partition_encryption/.

View File

@@ -7,34 +7,46 @@ GENERATOR_DIR="$2"
[ -z "$GENERATOR_DIR" ] && exit 1 [ -z "$GENERATOR_DIR" ] && exit 1
[ -d "$GENERATOR_DIR" ] || mkdir "$GENERATOR_DIR" [ -d "$GENERATOR_DIR" ] || mkdir "$GENERATOR_DIR"
if getargbool 0 rd.neednet; then oem_label=$(getarg rd.cos.oemlabel=)
{
echo "[Unit]" ## Several things indicate booting from a different media so we should not do anything
echo "DefaultDependencies=no" ## rd.cos.disable is set on LIVECD and disables mounting of any type
echo "Description=kcrypt online mount" if getargbool 0 rd.cos.disable; then
echo "Before=cos-immutable-rootfs.service" exit 0
echo "After=network-online.target"
echo "Wants=network-online.target"
echo "[Service]"
echo "Type=oneshot"
echo "RemainAfterExit=no"
echo "ExecStart=/sbin/kcrypt-mount-local"
} > "$GENERATOR_DIR"/kcrypt.service
else
{
echo "[Unit]"
echo "DefaultDependencies=no"
echo "Description=kcrypt mount"
echo "Before=cos-immutable-rootfs.service"
echo "[Service]"
echo "Type=oneshot"
echo "RemainAfterExit=no"
echo "ExecStart=/sbin/kcrypt-mount-local"
} > "$GENERATOR_DIR"/kcrypt.service
fi fi
## Netboot is set on...well, netboot obiously
if getargbool 0 netboot; then
exit 0
fi
# See https://github.com/kairos-io/packages/blob/d12b12b043a71d8471454f7b4fc84c3181d2bf60/packages/system/dracut/immutable-rootfs/30cos-immutable-rootfs/cos-generator.sh#L29
{
echo "[Unit]"
echo "DefaultDependencies=no"
echo "Before=immucore.service"
echo "Conflicts=initrd-switch-root.target"
if getargbool 0 rd.neednet; then
echo "Wants=network-online.target"
echo "After=network-online.target"
echo "Description=kcrypt online mount"
else
echo "Description=kcrypt mount"
fi
# OEM is special as kcrypt plugins might need that in order to unlock other partitions and plugins can reside in /oem as well and kcrypt needs to find them
if [ -n "${oem_label}" ]; then
echo "After=oem.mount"
fi
echo "After=sysroot.mount"
echo "[Service]"
echo "Type=oneshot"
echo "RemainAfterExit=no"
echo "ExecStart=/usr/bin/kcrypt unlock-all"
} > "$GENERATOR_DIR"/kcrypt.service
if [ ! -e "$GENERATOR_DIR/initrd-fs.target.requires/kcrypt.service" ]; then if [ ! -e "$GENERATOR_DIR/initrd-fs.target.requires/kcrypt.service" ]; then
mkdir -p "$GENERATOR_DIR"/initrd-fs.target.requires mkdir -p "$GENERATOR_DIR"/initrd-fs.target.requires
ln -s "$GENERATOR_DIR"/kcrypt.service \ ln -s "$GENERATOR_DIR"/kcrypt.service \
"$GENERATOR_DIR"/initrd-fs.target.requires/kcrypt.service "$GENERATOR_DIR"/initrd-fs.target.requires/kcrypt.service
fi fi

View File

@@ -27,8 +27,7 @@ install() {
inst_multiple \ inst_multiple \
kcrypt kcrypt
inst_script "${moddir}/mount-local.sh" "/sbin/kcrypt-mount-local"
#inst_hook pre-trigger 10 "$moddir/mount-local.sh"
inst_script "${moddir}/generator.sh" \ inst_script "${moddir}/generator.sh" \
"${systemdutildir}/system-generators/dracut-kcrypt-generator" "${systemdutildir}/system-generators/dracut-kcrypt-generator"

View File

@@ -1,19 +0,0 @@
#!/bin/sh
# -*- mode: shell-script; indent-tabs-mode: nil; sh-basic-offset: 4; -*-
# ex: ts=8 sw=4 sts=4 et filetype=sh
type getarg > /dev/null 2>&1 || . /lib/dracut-lib.sh
PATH=/usr/sbin:/usr/bin:/sbin:/bin
OEM=$(blkid -L COS_OEM)
if [ "$OEM" != "" ]; then
mkdir /oem
mount $OEM /oem
fi
kcrypt unlock-all
if [ "$OEM" != "" ]; then
umount /oem
fi

3
earthly.sh Executable file
View File

@@ -0,0 +1,3 @@
#!/bin/bash
docker run --privileged -v /var/run/docker.sock:/var/run/docker.sock --rm -t -v $(pwd):/workspace -v earthly-tmp:/tmp/earthly:rw earthly/earthly:v0.6.21 --allow-privileged $@

98
go.mod
View File

@@ -1,38 +1,96 @@
module github.com/kairos-io/kcrypt module github.com/kairos-io/kcrypt
go 1.18 go 1.20
require ( require (
github.com/anatol/luks.go v0.0.0-20220803222236-155595903818 github.com/anatol/luks.go v0.0.0-20230125211543-ada2562d4206
github.com/hashicorp/go-multierror v1.1.1 github.com/gofrs/uuid v4.4.0+incompatible
github.com/jaypipes/ghw v0.9.0 github.com/jaypipes/ghw v0.10.0
github.com/mudler/go-pluggable v0.0.0-20220716112424-189d463e3ff3 github.com/kairos-io/kairos-sdk v0.0.18
github.com/onsi/ginkgo/v2 v2.5.0 github.com/mudler/go-pluggable v0.0.0-20230126220627-7710299a0ae5
github.com/onsi/gomega v1.24.0 github.com/onsi/ginkgo/v2 v2.11.0
github.com/otiai10/copy v1.7.0 github.com/onsi/gomega v1.27.8
github.com/otiai10/copy v1.9.0
github.com/pkg/errors v0.9.1 github.com/pkg/errors v0.9.1
github.com/urfave/cli v1.22.9 github.com/urfave/cli v1.22.14
gopkg.in/yaml.v3 v3.0.1 gopkg.in/yaml.v1 v1.0.0-20140924161607-9f9df34309c0
k8s.io/apimachinery v0.26.2
) )
require ( require (
atomicgo.dev/cursor v0.1.3 // indirect
atomicgo.dev/keyboard v0.2.9 // indirect
atomicgo.dev/schedule v0.0.2 // indirect
github.com/Microsoft/go-winio v0.6.1 // indirect
github.com/Microsoft/hcsshim v0.11.1 // indirect
github.com/StackExchange/wmi v1.2.1 // indirect github.com/StackExchange/wmi v1.2.1 // indirect
github.com/anatol/devmapper.go v0.0.0-20220716012224-693a1447fc15 // indirect github.com/anatol/devmapper.go v0.0.0-20220907161421-ba4de5fc0fd1 // indirect
github.com/avast/retry-go v3.0.0+incompatible // indirect
github.com/aybabtme/rgbterm v0.0.0-20170906152045-cc83f3b3ce59 // indirect
github.com/chuckpreslar/emission v0.0.0-20170206194824-a7ddd980baf9 // indirect github.com/chuckpreslar/emission v0.0.0-20170206194824-a7ddd980baf9 // indirect
github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d // indirect github.com/containerd/cgroups v1.1.0 // indirect
github.com/containerd/console v1.0.3 // indirect
github.com/containerd/containerd v1.7.7 // indirect
github.com/containerd/continuity v0.4.2 // indirect
github.com/containerd/log v0.1.0 // indirect
github.com/containerd/stargz-snapshotter/estargz v0.14.3 // indirect
github.com/cpuguy83/go-md2man/v2 v2.0.2 // indirect
github.com/denisbrodbeck/machineid v1.0.1 // indirect
github.com/dgryski/go-camellia v0.0.0-20191119043421-69a8a13fb23d // indirect
github.com/docker/cli v23.0.5+incompatible // indirect
github.com/docker/distribution v2.8.1+incompatible // indirect
github.com/docker/docker v23.0.5+incompatible // indirect
github.com/docker/docker-credential-helpers v0.7.0 // indirect
github.com/docker/go-connections v0.4.0 // indirect
github.com/docker/go-units v0.5.0 // indirect
github.com/ghodss/yaml v1.0.0 // indirect github.com/ghodss/yaml v1.0.0 // indirect
github.com/go-logr/logr v1.2.3 // indirect github.com/go-logr/logr v1.2.4 // indirect
github.com/go-ole/go-ole v1.2.6 // indirect github.com/go-ole/go-ole v1.2.6 // indirect
github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 // indirect
github.com/gogo/protobuf v1.3.2 // indirect
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect
github.com/golang/protobuf v1.5.3 // indirect
github.com/google/go-cmp v0.5.9 // indirect github.com/google/go-cmp v0.5.9 // indirect
github.com/hashicorp/errwrap v1.0.0 // indirect github.com/google/go-containerregistry v0.15.2 // indirect
github.com/google/pprof v0.0.0-20230228050547-1710fef4ab10 // indirect
github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 // indirect
github.com/gookit/color v1.5.3 // indirect
github.com/hashicorp/errwrap v1.1.0 // indirect
github.com/hashicorp/go-multierror v1.1.1 // indirect
github.com/itchyny/gojq v0.12.13 // indirect
github.com/itchyny/timefmt-go v0.1.5 // indirect
github.com/jaypipes/pcidb v1.0.0 // indirect github.com/jaypipes/pcidb v1.0.0 // indirect
github.com/joho/godotenv v1.5.1 // indirect
github.com/klauspost/compress v1.16.5 // indirect
github.com/lithammer/fuzzysearch v1.1.8 // indirect
github.com/mattn/go-isatty v0.0.19 // indirect
github.com/mattn/go-runewidth v0.0.14 // indirect
github.com/mitchellh/go-homedir v1.1.0 // indirect github.com/mitchellh/go-homedir v1.1.0 // indirect
github.com/russross/blackfriday/v2 v2.0.1 // indirect github.com/moby/sys/sequential v0.5.0 // indirect
github.com/shurcooL/sanitized_anchor_name v1.0.0 // indirect github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646 // indirect
golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa // indirect github.com/opencontainers/go-digest v1.0.0 // indirect
golang.org/x/net v0.1.0 // indirect github.com/opencontainers/image-spec v1.1.0-rc3 // indirect
golang.org/x/sys v0.1.0 // indirect github.com/pterm/pterm v0.12.63 // indirect
golang.org/x/text v0.4.0 // indirect github.com/qeesung/image2ascii v1.0.1 // indirect
github.com/rivo/uniseg v0.4.4 // indirect
github.com/russross/blackfriday/v2 v2.1.0 // indirect
github.com/sirupsen/logrus v1.9.3 // indirect
github.com/vbatts/tar-split v0.11.3 // indirect
github.com/wayneashleyberry/terminal-dimensions v1.1.0 // indirect
github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e // indirect
go.opencensus.io v0.24.0 // indirect
golang.org/x/crypto v0.11.0 // indirect
golang.org/x/mod v0.10.0 // indirect
golang.org/x/net v0.13.0 // indirect
golang.org/x/sync v0.2.0 // indirect
golang.org/x/sys v0.10.0 // indirect
golang.org/x/term v0.10.0 // indirect
golang.org/x/text v0.11.0 // indirect
golang.org/x/tools v0.9.3 // indirect
google.golang.org/genproto v0.0.0-20230306155012-7f2fa6fef1f4 // indirect
google.golang.org/grpc v1.53.0 // indirect
google.golang.org/protobuf v1.30.0 // indirect
gopkg.in/yaml.v2 v2.4.0 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
howett.net/plist v1.0.0 // indirect howett.net/plist v1.0.0 // indirect
) )

400
go.sum
View File

@@ -1,106 +1,341 @@
atomicgo.dev/assert v0.0.2 h1:FiKeMiZSgRrZsPo9qn/7vmr7mCsh5SZyXY4YGYiYwrg=
atomicgo.dev/cursor v0.1.1 h1:0t9sxQomCTRh5ug+hAMCs59x/UmC9QL6Ci5uosINKD4=
atomicgo.dev/cursor v0.1.1/go.mod h1:Lr4ZJB3U7DfPPOkbH7/6TOtJ4vFGHlgj1nc+n900IpU=
atomicgo.dev/cursor v0.1.3 h1:w8GcylMdZRyFzvDiGm3wy3fhZYYT7BwaqNjUFHxo0NU=
atomicgo.dev/cursor v0.1.3/go.mod h1:Lr4ZJB3U7DfPPOkbH7/6TOtJ4vFGHlgj1nc+n900IpU=
atomicgo.dev/keyboard v0.2.9 h1:tOsIid3nlPLZ3lwgG8KZMp/SFmr7P0ssEN5JUsm78K8=
atomicgo.dev/keyboard v0.2.9/go.mod h1:BC4w9g00XkxH/f1HXhW2sXmJFOCWbKn9xrOunSFtExQ=
atomicgo.dev/schedule v0.0.2 h1:2e/4KY6t3wokja01Cyty6qgkQM8MotJzjtqCH70oX2Q=
atomicgo.dev/schedule v0.0.2/go.mod h1:xeUa3oAkiuHYh8bKiQBRojqAMq3PXXbJujjb0hw8pEU=
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161 h1:L/gRVlceqvL25UVaW/CKtUDjefjrs0SPonmDGUVOYP0=
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
github.com/BurntSushi/toml v1.2.1/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ=
github.com/BurntSushi/toml v1.3.2/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ=
github.com/MarvinJWendt/testza v0.1.0/go.mod h1:7AxNvlfeHP7Z/hDQ5JtE3OKYT3XFUeLCDE2DQninSqs=
github.com/MarvinJWendt/testza v0.2.1/go.mod h1:God7bhG8n6uQxwdScay+gjm9/LnO4D3kkcZX4hv9Rp8=
github.com/MarvinJWendt/testza v0.2.8/go.mod h1:nwIcjmr0Zz+Rcwfh3/4UhBp7ePKVhuBExvZqnKYWlII=
github.com/MarvinJWendt/testza v0.2.10/go.mod h1:pd+VWsoGUiFtq+hRKSU1Bktnn+DMCSrDrXDpX2bG66k=
github.com/MarvinJWendt/testza v0.2.12/go.mod h1:JOIegYyV7rX+7VZ9r77L/eH6CfJHHzXjB69adAhzZkI=
github.com/MarvinJWendt/testza v0.3.0/go.mod h1:eFcL4I0idjtIx8P9C6KkAuLgATNKpX4/2oUqKc6bF2c=
github.com/MarvinJWendt/testza v0.4.2/go.mod h1:mSdhXiKH8sg/gQehJ63bINcCKp7RtYewEjXsvsVUPbE=
github.com/MarvinJWendt/testza v0.5.2 h1:53KDo64C1z/h/d/stCYCPY69bt/OSwjq5KpFNwi+zB4=
github.com/Microsoft/go-winio v0.6.1 h1:9/kr64B9VUZrLm5YYwbGtUJnMgqWVOdUAXu6Migciow=
github.com/Microsoft/go-winio v0.6.1/go.mod h1:LRdKpFKfdobln8UmuiYcKPot9D2v6svN5+sAH+4kjUM=
github.com/Microsoft/hcsshim v0.10.0-rc.8 h1:YSZVvlIIDD1UxQpJp0h+dnpLUw+TrY0cx8obKsp3bek=
github.com/Microsoft/hcsshim v0.10.0-rc.8/go.mod h1:OEthFdQv/AD2RAdzR6Mm1N1KPCztGKDurW1Z8b8VGMM=
github.com/Microsoft/hcsshim v0.11.1 h1:hJ3s7GbWlGK4YVV92sO88BQSyF4ZLVy7/awqOlPxFbA=
github.com/Microsoft/hcsshim v0.11.1/go.mod h1:nFJmaO4Zr5Y7eADdFOpYswDDlNVbvcIJJNJLECr5JQg=
github.com/StackExchange/wmi v1.2.1 h1:VIkavFPXSjcnS+O8yTq7NI32k0R5Aj+v39y29VYDOSA= github.com/StackExchange/wmi v1.2.1 h1:VIkavFPXSjcnS+O8yTq7NI32k0R5Aj+v39y29VYDOSA=
github.com/StackExchange/wmi v1.2.1/go.mod h1:rcmrprowKIVzvc+NUiLncP2uuArMWLCbu9SBzvHz7e8= github.com/StackExchange/wmi v1.2.1/go.mod h1:rcmrprowKIVzvc+NUiLncP2uuArMWLCbu9SBzvHz7e8=
github.com/anatol/devmapper.go v0.0.0-20220716012224-693a1447fc15 h1:741Z9HQjbLXe4SnZ6liQTYINeD559oFl/vOtzA21KM0= github.com/anatol/devmapper.go v0.0.0-20220907161421-ba4de5fc0fd1 h1:6ok4FQsJFooNYKiSmrVUv476cG/NYmbM0LxazuL4sZU=
github.com/anatol/devmapper.go v0.0.0-20220716012224-693a1447fc15/go.mod h1:Ow7/kdG1m4K6UDTOwJeYJv9bkSLoL44qSu7S/Bxxi4Y= github.com/anatol/devmapper.go v0.0.0-20220907161421-ba4de5fc0fd1/go.mod h1:k5R4Ie9eQbP4muJljLeun3f1onpMKRSqG/aXMFdCWm4=
github.com/anatol/luks.go v0.0.0-20220803222236-155595903818 h1:IyYgXFMhnSIbkDnDrTnMrPDYlc/uYhG5UcGX6NVkO58= github.com/anatol/luks.go v0.0.0-20230125211543-ada2562d4206 h1:9kfvAJRm75SuSR185WrbYOco0cKFo9IglQfiFyRNvK0=
github.com/anatol/luks.go v0.0.0-20220803222236-155595903818/go.mod h1:1lE8PgTi0cS+3YsxbWcpfvGfjiPrRdcKJZc9j70OOTs= github.com/anatol/luks.go v0.0.0-20230125211543-ada2562d4206/go.mod h1:XwLorksvNshI9TH9UOO/WfX7kYIdlljCQi5WPkN7K0c=
github.com/anatol/vmtest v0.0.0-20220413190228-7a42f1f6d7b8 h1:t4JGeY9oaF5LB4Rdx9e2wARRRPAYt8Ow4eCf5SwO3fA= github.com/anatol/vmtest v0.0.0-20220413190228-7a42f1f6d7b8 h1:t4JGeY9oaF5LB4Rdx9e2wARRRPAYt8Ow4eCf5SwO3fA=
github.com/atomicgo/cursor v0.0.1/go.mod h1:cBON2QmmrysudxNBFthvMtN32r3jxVRIvzkUiF/RuIk=
github.com/avast/retry-go v3.0.0+incompatible h1:4SOWQ7Qs+oroOTQOYnAHqelpCO0biHSxpiH9JdtuBj0=
github.com/avast/retry-go v3.0.0+incompatible/go.mod h1:XtSnn+n/sHqQIpZ10K1qAevBhOOCWBLXXy3hyiqqBrY=
github.com/aybabtme/rgbterm v0.0.0-20170906152045-cc83f3b3ce59 h1:WWB576BN5zNSZc/M9d/10pqEx5VHNhaQ/yOVAkmj5Yo=
github.com/aybabtme/rgbterm v0.0.0-20170906152045-cc83f3b3ce59/go.mod h1:q/89r3U2H7sSsE2t6Kca0lfwTK8JdoNGS/yzM/4iH5I=
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
github.com/chuckpreslar/emission v0.0.0-20170206194824-a7ddd980baf9 h1:xz6Nv3zcwO2Lila35hcb0QloCQsc38Al13RNEzWRpX4= github.com/chuckpreslar/emission v0.0.0-20170206194824-a7ddd980baf9 h1:xz6Nv3zcwO2Lila35hcb0QloCQsc38Al13RNEzWRpX4=
github.com/chuckpreslar/emission v0.0.0-20170206194824-a7ddd980baf9/go.mod h1:2wSM9zJkl1UQEFZgSd68NfCgRz1VL1jzy/RjCg+ULrs= github.com/chuckpreslar/emission v0.0.0-20170206194824-a7ddd980baf9/go.mod h1:2wSM9zJkl1UQEFZgSd68NfCgRz1VL1jzy/RjCg+ULrs=
github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d h1:U+s90UTSYgptZMwQh2aRr3LuazLJIa+Pg3Kc1ylSYVY= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=
github.com/containerd/cgroups v1.1.0 h1:v8rEWFl6EoqHB+swVNjVoCJE8o3jX7e8nqBGPLaDFBM=
github.com/containerd/cgroups v1.1.0/go.mod h1:6ppBcbh/NOOUU+dMKrykgaBnK9lCIBxHqJDGwsa1mIw=
github.com/containerd/console v1.0.3 h1:lIr7SlA5PxZyMV30bDW0MGbiOPXwc63yRuCP0ARubLw=
github.com/containerd/console v1.0.3/go.mod h1:7LqA/THxQ86k76b8c/EMSiaJ3h1eZkMkXar0TQ1gf3U=
github.com/containerd/containerd v1.7.1 h1:k8DbDkSOwt5rgxQ3uCI4WMKIJxIndSCBUaGm5oRn+Go=
github.com/containerd/containerd v1.7.1/go.mod h1:gA+nJUADRBm98QS5j5RPROnt0POQSMK+r7P7EGMC/Qc=
github.com/containerd/containerd v1.7.7 h1:QOC2K4A42RQpcrZyptP6z9EJZnlHfHJUfZrAAHe15q4=
github.com/containerd/containerd v1.7.7/go.mod h1:3c4XZv6VeT9qgf9GMTxNTMFxGJrGpI2vz1yk4ye+YY8=
github.com/containerd/continuity v0.3.0 h1:nisirsYROK15TAMVukJOUyGJjz4BNQJBVsNvAXZJ/eg=
github.com/containerd/continuity v0.3.0/go.mod h1:wJEAIwKOm/pBZuBd0JmeTvnLquTB1Ag8espWhkykbPM=
github.com/containerd/continuity v0.4.2 h1:v3y/4Yz5jwnvqPKJJ+7Wf93fyWoCB3F5EclWG023MDM=
github.com/containerd/continuity v0.4.2/go.mod h1:F6PTNCKepoxEaXLQp3wDAjygEnImnZ/7o4JzpodfroQ=
github.com/containerd/log v0.1.0 h1:TCJt7ioM2cr/tfR8GPbGf9/VRAX8D2B4PjzCpfX540I=
github.com/containerd/log v0.1.0/go.mod h1:VRRf09a7mHDIRezVKTRCrOq78v577GXq3bSa3EhrzVo=
github.com/containerd/stargz-snapshotter/estargz v0.14.3 h1:OqlDCK3ZVUO6C3B/5FSkDwbkEETK84kQgEeFwDC+62k=
github.com/containerd/stargz-snapshotter/estargz v0.14.3/go.mod h1:KY//uOCIkSuNAHhJogcZtrNHdKrA99/FCCRjE3HD36o=
github.com/cpuguy83/go-md2man/v2 v2.0.2 h1:p1EgwI/C7NhT0JmVkwCD2ZBK8j4aeHQX2pMHHBfMQ6w=
github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
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 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/denisbrodbeck/machineid v1.0.1 h1:geKr9qtkB876mXguW2X6TU4ZynleN6ezuMSRhl4D7AQ=
github.com/denisbrodbeck/machineid v1.0.1/go.mod h1:dJUwb7PTidGDeYyUBmXZ2GphQBbjJCrnectwCyxcUSI=
github.com/dgryski/go-camellia v0.0.0-20191119043421-69a8a13fb23d h1:CPqTNIigGweVPT4CYb+OO2E6XyRKFOmvTHwWRLgCAlE=
github.com/dgryski/go-camellia v0.0.0-20191119043421-69a8a13fb23d/go.mod h1:QX5ZVULjAfZJux/W62Y91HvCh9hyW6enAwcrrv/sLj0=
github.com/docker/cli v23.0.5+incompatible h1:ufWmAOuD3Vmr7JP2G5K3cyuNC4YZWiAsuDEvFVVDafE=
github.com/docker/cli v23.0.5+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8=
github.com/docker/distribution v2.8.1+incompatible h1:Q50tZOPR6T/hjNsyc9g8/syEs6bk8XXApsHjKukMl68=
github.com/docker/distribution v2.8.1+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w=
github.com/docker/docker v23.0.5+incompatible h1:DaxtlTJjFSnLOXVNUBU1+6kXGz2lpDoEAH6QoxaSg8k=
github.com/docker/docker v23.0.5+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
github.com/docker/docker-credential-helpers v0.7.0 h1:xtCHsjxogADNZcdv1pKUHXryefjlVRqWqIhk/uXJp0A=
github.com/docker/docker-credential-helpers v0.7.0/go.mod h1:rETQfLdHNT3foU5kuNkFR1R1V12OJRRO5lzt2D1b5X0=
github.com/docker/go-connections v0.4.0 h1:El9xVISelRB7BuFusrZozjnkIM5YnzCViNKohAFqRJQ=
github.com/docker/go-connections v0.4.0/go.mod h1:Gbd7IOopHjR8Iph03tsViu4nIes5XhDvyHbTtUxmeec=
github.com/docker/go-units v0.5.0 h1:69rxXcBk27SvSaaxTtLh/8llcHD8vYHT7WSdRZ/jvr4=
github.com/docker/go-units v0.5.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk=
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/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4=
github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ=
github.com/fsnotify/fsnotify v1.6.0 h1:n+5WquG0fcWoWp6xPWfHdbskMCQaFnG6PfBrh1Ky4HY=
github.com/ghodss/yaml v1.0.0 h1:wQHKEahhL6wmXdzwWG11gIVCkOv05bNOh+Rxn0yngAk= github.com/ghodss/yaml v1.0.0 h1:wQHKEahhL6wmXdzwWG11gIVCkOv05bNOh+Rxn0yngAk=
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
github.com/go-logr/logr v1.2.3 h1:2DntVwHkVopvECVRSlL5PSo9eG+cAkDCuckLubN+rq0= github.com/go-logr/logr v1.2.4 h1:g01GSCwiDw2xSZfjJ2/T9M+S6pFdcNtFYsp+Y43HYDQ=
github.com/go-logr/logr v1.2.3/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= github.com/go-logr/logr v1.2.4/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
github.com/go-ole/go-ole v1.2.5/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0= github.com/go-ole/go-ole v1.2.5/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0=
github.com/go-ole/go-ole v1.2.6 h1:/Fpf6oFPoeFik9ty7siob0G6Ke8QvQEuVcuChpwXzpY= github.com/go-ole/go-ole v1.2.6 h1:/Fpf6oFPoeFik9ty7siob0G6Ke8QvQEuVcuChpwXzpY=
github.com/go-ole/go-ole v1.2.6/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0= github.com/go-ole/go-ole v1.2.6/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0=
github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 h1:tfuBGBXKqDEevZMzYi5KSi8KkcZtzBcTgAUUtapy0OI=
github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572/go.mod h1:9Pwr4B2jHnOSGXyyzV8ROjYa2ojvAY6HCGYYfMoC3Ls=
github.com/gofrs/uuid v4.4.0+incompatible h1:3qXRTX8/NbyulANqlc0lchS1gqAVxRgsuW1YrTJupqA=
github.com/gofrs/uuid v4.4.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM=
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/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da h1:oI5xCqsCo564l8iNU+DwB5epxmsaqB+rhGL0m5jtYqE=
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
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.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= 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.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.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-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.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.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw= 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.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg=
github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
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.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.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.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.3/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 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/hashicorp/errwrap v1.0.0 h1:hLrqtEDnRye3+sgx6z4qVLNuviH3MR5aQ0ykNJa/UYA= github.com/google/go-containerregistry v0.15.2 h1:MMkSh+tjSdnmJZO7ljvEqV1DjfekB6VUEAZgy3a+TQE=
github.com/google/go-containerregistry v0.15.2/go.mod h1:wWK+LnOv4jXMM23IT/F1wdYftGWGr47Is8CG+pmHK1Q=
github.com/google/pprof v0.0.0-20230228050547-1710fef4ab10 h1:CqYfpuYIjnlNxM3msdyPRKabhXZWbKjf3Q8BWROFBso=
github.com/google/pprof v0.0.0-20230228050547-1710fef4ab10/go.mod h1:79YE0hCXdHag9sBkw2o+N/YnZtTkXi0UT9Nnixa5eYk=
github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 h1:El6M4kTTCOh6aBiKaUGG7oYTSPP8MxqL4YI3kZKwcP4=
github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510/go.mod h1:pupxD2MaaD3pAXIBCelhxNneeOaAeabZDe5s4K6zSpQ=
github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/gookit/color v1.4.2/go.mod h1:fqRyamkC1W8uxl+lxCQxOT09l/vYfZ+QeiX3rKQHCoQ=
github.com/gookit/color v1.5.0/go.mod h1:43aQb+Zerm/BWh2GnrgOQm7ffz7tvQXEKV6BFMl7wAo=
github.com/gookit/color v1.5.3 h1:twfIhZs4QLCtimkP7MOxlF3A0U/5cDPseRT9M/+2SCE=
github.com/gookit/color v1.5.3/go.mod h1:NUzwzeehUfl7GIb36pqId+UGmRfQcU/WiiyTTeNjHtE=
github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
github.com/hashicorp/errwrap v1.1.0 h1:OxrOeh75EUXMY8TBjag2fzXGZ40LB6IKw45YeGUDY2I=
github.com/hashicorp/errwrap v1.1.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
github.com/hashicorp/go-multierror v1.1.1 h1:H5DkEtf6CXdFp0N0Em5UCwQpXMWke8IA0+lD48awMYo= github.com/hashicorp/go-multierror v1.1.1 h1:H5DkEtf6CXdFp0N0Em5UCwQpXMWke8IA0+lD48awMYo=
github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9/fmwbPZ6JB6eMoM= github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9/fmwbPZ6JB6eMoM=
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= github.com/itchyny/gojq v0.12.12 h1:x+xGI9BXqKoJQZkr95ibpe3cdrTbY8D9lonrK433rcA=
github.com/jaypipes/ghw v0.9.0 h1:TWF4wNIGtZcgDJaiNcFgby5BR8s2ixcUe0ydxNO2McY= github.com/itchyny/gojq v0.12.12/go.mod h1:j+3sVkjxwd7A7Z5jrbKibgOLn0ZfLWkV+Awxr/pyzJE=
github.com/jaypipes/ghw v0.9.0/go.mod h1:dXMo19735vXOjpIBDyDYSp31sB2u4hrtRCMxInqQ64k= github.com/itchyny/gojq v0.12.13 h1:IxyYlHYIlspQHHTE0f3cJF0NKDMfajxViuhBLnHd/QU=
github.com/itchyny/gojq v0.12.13/go.mod h1:JzwzAqenfhrPUuwbmEz3nu3JQmFLlQTQMUcOdnu/Sf4=
github.com/itchyny/timefmt-go v0.1.5 h1:G0INE2la8S6ru/ZI5JecgyzbbJNs5lG1RcBqa7Jm6GE=
github.com/itchyny/timefmt-go v0.1.5/go.mod h1:nEP7L+2YmAbT2kZ2HfSs1d8Xtw9LY8D2stDBckWakZ8=
github.com/jaypipes/ghw v0.10.0 h1:UHu9UX08Py315iPojADFPOkmjTsNzHj4g4adsNKKteY=
github.com/jaypipes/ghw v0.10.0/go.mod h1:jeJGbkRB2lL3/gxYzNYzEDETV1ZJ56OKr+CSeSEym+g=
github.com/jaypipes/pcidb v1.0.0 h1:vtZIfkiCUE42oYbJS0TAq9XSfSmcsgo9IdxSm9qzYU8= github.com/jaypipes/pcidb v1.0.0 h1:vtZIfkiCUE42oYbJS0TAq9XSfSmcsgo9IdxSm9qzYU8=
github.com/jaypipes/pcidb v1.0.0/go.mod h1:TnYUvqhPBzCKnH34KrIX22kAeEbDCSRJ9cqLRCuNDfk= github.com/jaypipes/pcidb v1.0.0/go.mod h1:TnYUvqhPBzCKnH34KrIX22kAeEbDCSRJ9cqLRCuNDfk=
github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI=
github.com/joho/godotenv v1.5.1 h1:7eLL/+HRGLY0ldzfGMeQkb7vMd0as4CfYvUVzLqw0N0=
github.com/joho/godotenv v1.5.1/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4=
github.com/kairos-io/kairos-sdk v0.0.8 h1:3yfxdmUuJoN7ePg+ogpH1PJvuMsLmLcxEXuWoiGdIrg=
github.com/kairos-io/kairos-sdk v0.0.8/go.mod h1:Z+1CLqMZq97bzwX2XSIArr8EoniMth3mMYkOOb8L3QY=
github.com/kairos-io/kairos-sdk v0.0.15 h1:1hcnRfKlBzDWcZ8z7UrUqJ2v6GafCHZknPqm90iTZdU=
github.com/kairos-io/kairos-sdk v0.0.15/go.mod h1:Ew3NKFuXByu3Y3yGu8Q92M3oMqsXrg2VilouubdhYqA=
github.com/kairos-io/kairos-sdk v0.0.16 h1:Zq+ALQTpv6T8wghkNpFGWzeeGvzcAf/i5m89Vlo+4vA=
github.com/kairos-io/kairos-sdk v0.0.16/go.mod h1:6Y9RGvKU/B99euFE32OYrabLLsSVjjemCfyRgiEHuKE=
github.com/kairos-io/kairos-sdk v0.0.18 h1:eV4pf91MTG1Kho1AiA+9C4JnV9g/yvpyLy1g4JRtOEI=
github.com/kairos-io/kairos-sdk v0.0.18/go.mod h1:17dpFG2d3Q/TcT86DlLK5nNXEjlSrkYl7bsvO2cpYGE=
github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 h1:Z9n2FFNUXsshfwJMBgNA0RU6/i7WVaAegv3PtuIHPMs= github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 h1:Z9n2FFNUXsshfwJMBgNA0RU6/i7WVaAegv3PtuIHPMs=
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/klauspost/compress v1.16.5 h1:IFV2oUNUzZaz+XyusxpLzpzS8Pt5rh0Z16For/djlyI=
github.com/klauspost/compress v1.16.5/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE=
github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg=
github.com/klauspost/cpuid/v2 v2.0.10/go.mod h1:g2LTdtYhdyuGPqyWyv7qRAmj1WBqxuObKfj5c0PQa7c=
github.com/klauspost/cpuid/v2 v2.0.12/go.mod h1:g2LTdtYhdyuGPqyWyv7qRAmj1WBqxuObKfj5c0PQa7c=
github.com/klauspost/cpuid/v2 v2.2.3 h1:sxCkb+qR91z4vsqw4vGGZlDgPz3G7gjaLyK3V8y70BU=
github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI= github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI=
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/mitchellh/go-homedir v1.0.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
github.com/lithammer/fuzzysearch v1.1.7 h1:q8rZNmBIUkqxsxb/IlwsXVbCoPIH/0juxjFHY0UIwhU=
github.com/lithammer/fuzzysearch v1.1.7/go.mod h1:ZhIlfRGxnD8qa9car/yplC6GmnM14CS07BYAKJJBK2I=
github.com/lithammer/fuzzysearch v1.1.8 h1:/HIuJnjHuXS8bKaiTMeeDlW2/AyIWk2brx1V8LFgLN4=
github.com/lithammer/fuzzysearch v1.1.8/go.mod h1:IdqeyBClc3FFqSzYq/MXESsS4S0FsZ5ajtkr5xPLts4=
github.com/mattn/go-isatty v0.0.17 h1:BTarxUcIeDqL27Mc+vyvdWYSL28zpIhv3RoTdsLMPng=
github.com/mattn/go-isatty v0.0.17/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
github.com/mattn/go-isatty v0.0.19 h1:JITubQf0MOLdlGRuRq+jtsDlekdYPia9ZFsB8h/APPA=
github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
github.com/mattn/go-runewidth v0.0.13/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w=
github.com/mattn/go-runewidth v0.0.14 h1:+xnbZSEeDbOIg5/mE6JF0w6n9duR1l3/WmbinWVwUuU=
github.com/mattn/go-runewidth v0.0.14/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w=
github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y= github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y=
github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
github.com/mudler/go-pluggable v0.0.0-20220716112424-189d463e3ff3 h1:t4X6t8WisUy5mExfS58RBOkzaEGmuor5kOUMQS8lT2g= github.com/moby/sys/mountinfo v0.6.2 h1:BzJjoreD5BMFNmD9Rus6gdd1pLuecOFPt8wC+Vygl78=
github.com/mudler/go-pluggable v0.0.0-20220716112424-189d463e3ff3/go.mod h1:WmKcT8ONmhDQIqQ+HxU+tkGWjzBEyY/KFO8LTGCu4AI= github.com/moby/sys/sequential v0.5.0 h1:OPvI35Lzn9K04PBbCLW0g4LcFAJgHsvXsRyewg5lXtc=
github.com/moby/sys/sequential v0.5.0/go.mod h1:tH2cOOs5V9MlPiXcQzRC+eEyab644PWKGRYaaV5ZZlo=
github.com/moby/term v0.0.0-20221205130635-1aeaba878587 h1:HfkjXDfhgVaN5rmueG8cL8KKeFNecRCXFhaJ2qZ5SKA=
github.com/morikuni/aec v1.0.0 h1:nP9CBfwrvYnBRgY6qfDQkygYDmYwOilePFkwzv4dU8A=
github.com/mudler/go-pluggable v0.0.0-20230126220627-7710299a0ae5 h1:FaZD86+A9mVt7lh9glAryzQblMsbJYU2VnrdZ8yHlTs=
github.com/mudler/go-pluggable v0.0.0-20230126220627-7710299a0ae5/go.mod h1:WmKcT8ONmhDQIqQ+HxU+tkGWjzBEyY/KFO8LTGCu4AI=
github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646 h1:zYyBkD/k9seD2A7fsi6Oo2LfFZAehjjQMERAvZLEDnQ=
github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646/go.mod h1:jpp1/29i3P1S/RLdc7JQKbRpFeM1dOBd8T9ki5s+AY8=
github.com/nxadm/tail v1.4.4 h1:DQuhQpB1tVlglWS2hLQ5OV6B5r8aGxSrPc5Qo6uTN78= github.com/nxadm/tail v1.4.4 h1:DQuhQpB1tVlglWS2hLQ5OV6B5r8aGxSrPc5Qo6uTN78=
github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A=
github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk= github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk=
github.com/onsi/ginkgo v1.14.2 h1:8mVmC9kjFFmA8H4pKMUhcblgifdkOIXPvbhN1T36q1M= github.com/onsi/ginkgo v1.14.2 h1:8mVmC9kjFFmA8H4pKMUhcblgifdkOIXPvbhN1T36q1M=
github.com/onsi/ginkgo v1.14.2/go.mod h1:iSB4RoI2tjJc9BBv4NKIKWKya62Rps+oPG/Lv9klQyY= github.com/onsi/ginkgo v1.14.2/go.mod h1:iSB4RoI2tjJc9BBv4NKIKWKya62Rps+oPG/Lv9klQyY=
github.com/onsi/ginkgo/v2 v2.5.0 h1:TRtrvv2vdQqzkwrQ1ke6vtXf7IK34RBUJafIy1wMwls= github.com/onsi/ginkgo/v2 v2.9.5 h1:+6Hr4uxzP4XIUyAkg61dWBw8lb/gc4/X5luuxN/EC+Q=
github.com/onsi/ginkgo/v2 v2.5.0/go.mod h1:Luc4sArBICYCS8THh8v3i3i5CuSZO+RaQRaJoeNwomw= github.com/onsi/ginkgo/v2 v2.9.5/go.mod h1:tvAoo1QUJwNEU2ITftXTpR7R1RbCzoZUOs3RonqW57k=
github.com/onsi/ginkgo/v2 v2.11.0 h1:WgqUCUt/lT6yXoQ8Wef0fsNn5cAuMK7+KT9UFRz2tcU=
github.com/onsi/ginkgo/v2 v2.11.0/go.mod h1:ZhrRA5XmEE3x3rhlzamx/JJvujdZoJ2uvgI7kR0iZvM=
github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY=
github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo=
github.com/onsi/gomega v1.10.3/go.mod h1:V9xEwhxec5O8UDM77eCW8vLymOMltsqPVYWrpDsH8xc= github.com/onsi/gomega v1.10.3/go.mod h1:V9xEwhxec5O8UDM77eCW8vLymOMltsqPVYWrpDsH8xc=
github.com/onsi/gomega v1.24.0 h1:+0glovB9Jd6z3VR+ScSwQqXVTIfJcGA9UBM8yzQxhqg= github.com/onsi/gomega v1.27.7 h1:fVih9JD6ogIiHUN6ePK7HJidyEDpWGVB5mzM7cWNXoU=
github.com/onsi/gomega v1.24.0/go.mod h1:Z/NWtiqwBrwUt4/2loMmHL63EDLnYHmVbuBpDr2vQAg= github.com/onsi/gomega v1.27.7/go.mod h1:1p8OOlwo2iUUDsHnOrjE5UKYJ+e3W8eQ3qSlRahPmr4=
github.com/otiai10/copy v1.7.0 h1:hVoPiN+t+7d2nzzwMiDHPSOogsWAStewq3TwU05+clE= github.com/onsi/gomega v1.27.8 h1:gegWiwZjBsf2DgiSbf5hpokZ98JVDMcWkUiigk6/KXc=
github.com/otiai10/copy v1.7.0/go.mod h1:rmRl6QPdJj6EiUqXQ/4Nn2lLXoNQjFCQbbNrxgc/t3U= github.com/onsi/gomega v1.27.8/go.mod h1:2J8vzI/s+2shY9XHRApDkdgPo1TKT7P2u6fXeJKFnNQ=
github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U=
github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM=
github.com/opencontainers/image-spec v1.1.0-rc3 h1:fzg1mXZFj8YdPeNkRXMg+zb88BFV0Ys52cJydRwBkb8=
github.com/opencontainers/image-spec v1.1.0-rc3/go.mod h1:X4pATf0uXsnn3g5aiGIsVnJBR4mxhKzfwmvK/B2NTm8=
github.com/otiai10/copy v1.9.0 h1:7KFNiCgZ91Ru4qW4CWPf/7jqtxLagGRmIxWldPP9VY4=
github.com/otiai10/copy v1.9.0/go.mod h1:hsfX19wcn0UWIHUQ3/4fHuehhk2UyArQ9dVFAn3FczI=
github.com/otiai10/curr v0.0.0-20150429015615-9b4961190c95/go.mod h1:9qAhocn7zKJG+0mI8eUu6xqkFDYS2kb2saOteoSB3cE= github.com/otiai10/curr v0.0.0-20150429015615-9b4961190c95/go.mod h1:9qAhocn7zKJG+0mI8eUu6xqkFDYS2kb2saOteoSB3cE=
github.com/otiai10/curr v1.0.0/go.mod h1:LskTG5wDwr8Rs+nNQ+1LlxRjAtTZZjtJW4rMXl6j4vs= github.com/otiai10/curr v1.0.0/go.mod h1:LskTG5wDwr8Rs+nNQ+1LlxRjAtTZZjtJW4rMXl6j4vs=
github.com/otiai10/mint v1.3.0/go.mod h1:F5AjcsTsWUqX+Na9fpHb52P8pcRX2CI6A3ctIT91xUo= github.com/otiai10/mint v1.3.0/go.mod h1:F5AjcsTsWUqX+Na9fpHb52P8pcRX2CI6A3ctIT91xUo=
github.com/otiai10/mint v1.3.3 h1:7JgpsBaN0uMkyju4tbYHu0mnM55hNKVYLsXmwr15NQI= github.com/otiai10/mint v1.4.0 h1:umwcf7gbpEwf7WFzqmWwSv0CzbeMsae2u9ZvpP8j2q4=
github.com/otiai10/mint v1.3.3/go.mod h1:/yxELlJQ0ufhjUwhshSj+wFjZ78CnZ48/1wtmBH1OTc= github.com/otiai10/mint v1.4.0/go.mod h1:gifjb2MYOoULtKLqUAEILUG/9KONW6f7YsJ6vQLTlFI=
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= 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 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/russross/blackfriday/v2 v2.0.1 h1:lPqVAte+HuHNfhJ/0LC98ESWRz8afy9tM/0RK8m9o+Q= github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/pterm/pterm v0.12.27/go.mod h1:PhQ89w4i95rhgE+xedAoqous6K9X+r6aSOI2eFF7DZI=
github.com/shurcooL/sanitized_anchor_name v1.0.0 h1:PdmoCO6wvbs+7yrJyMORt4/BmY5IYyJwS/kOiWx8mHo= github.com/pterm/pterm v0.12.29/go.mod h1:WI3qxgvoQFFGKGjGnJR849gU0TsEOvKn5Q8LlY1U7lg=
github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= github.com/pterm/pterm v0.12.30/go.mod h1:MOqLIyMOgmTDz9yorcYbcw+HsgoZo3BQfg2wtl3HEFE=
github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ= github.com/pterm/pterm v0.12.31/go.mod h1:32ZAWZVXD7ZfG0s8qqHXePte42kdz8ECtRyEejaWgXU=
github.com/spf13/pflag v1.0.2/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= github.com/pterm/pterm v0.12.33/go.mod h1:x+h2uL+n7CP/rel9+bImHD5lF3nM9vJj80k9ybiiTTE=
github.com/stretchr/testify v1.8.0 h1:pSgiaMZlXftHpm5L7V1+rVB+AZJydKsMxsQBIJw4PKk= github.com/pterm/pterm v0.12.36/go.mod h1:NjiL09hFhT/vWjQHSj1athJpx6H8cjpHXNAK5bUw8T8=
github.com/pterm/pterm v0.12.40/go.mod h1:ffwPLwlbXxP+rxT0GsgDTzS3y3rmpAO1NMjUkGTYf8s=
github.com/pterm/pterm v0.12.61 h1:cZFweZ0C4zbBsusyThfgqg0KU0PTnq5xupnGN3Ytxzc=
github.com/pterm/pterm v0.12.61/go.mod h1:07yyGZKQr8BpKKBaOZI1qKzzngqUisHdSYR4fQ9Nb4g=
github.com/pterm/pterm v0.12.63 h1:fHlrpFiI9qLtEU0TWDWMU+tAt4qKJ/s157BEAPtGm8w=
github.com/pterm/pterm v0.12.63/go.mod h1:Bq1eoUJ6BhUzzXG8WxA4l7T3s7d3Ogwg7v9VXlsVat0=
github.com/qeesung/image2ascii v1.0.1 h1:Fe5zTnX/v/qNC3OC4P/cfASOXS501Xyw2UUcgrLgtp4=
github.com/qeesung/image2ascii v1.0.1/go.mod h1:kZKhyX0h2g/YXa/zdJR3JnLnJ8avHjZ3LrvEKSYyAyU=
github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
github.com/rivo/uniseg v0.4.4 h1:8TfxU8dW6PdqD27gjM8MVNuicgxIjxpm4K7x4jp8sis=
github.com/rivo/uniseg v0.4.4/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88=
github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk=
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
github.com/sergi/go-diff v1.2.0 h1:XU+rvMAioB0UC3q1MFrIQy4Vo5/4VsRDQQXHsEya6xQ=
github.com/sergi/go-diff v1.2.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM=
github.com/sirupsen/logrus v1.9.0 h1:trlNQbNUG3OdDrDil03MCb1H2o9nJ1x4/5LYw7byDE0=
github.com/sirupsen/logrus v1.9.0/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=
github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ=
github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=
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 h1:1zr/of2m5FGMsad5YfcqgdqdWrIhu+EBEJRhR1U7z/c=
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
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/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
github.com/stretchr/testify v1.8.2 h1:+h33VjcLVPDHtOdpUCuF+7gSuG3yGIftsP1YvFihtJ8=
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
github.com/tmc/scp v0.0.0-20170824174625-f7b48647feef h1:7D6Nm4D6f0ci9yttWaKjM1TMAXrH5Su72dojqYGntFY= github.com/tmc/scp v0.0.0-20170824174625-f7b48647feef h1:7D6Nm4D6f0ci9yttWaKjM1TMAXrH5Su72dojqYGntFY=
github.com/urfave/cli v1.22.9 h1:cv3/KhXGBGjEXLC4bH0sLuJ9BewaAbpk5oyMOveu4pw= github.com/urfave/cli v1.22.12 h1:igJgVw1JdKH+trcLWLeLwZjU9fEfPesQ+9/e4MQ44S8=
github.com/urfave/cli v1.22.9/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= github.com/urfave/cli v1.22.12/go.mod h1:sSBEIC79qR6OvcmsD4U3KABeOTxDqQtdDnaFuUN30b8=
github.com/urfave/cli v1.22.14 h1:ebbhrRiGK2i4naQJr+1Xj92HXZCrK7MsyTS/ob3HnAk=
github.com/urfave/cli v1.22.14/go.mod h1:X0eDS6pD6Exaclxm99NJ3FiCDRED7vIHpx2mDOHLvkA=
github.com/vbatts/tar-split v0.11.3 h1:hLFqsOLQ1SsppQNTMpkpPXClLDfC2A3Zgy9OUU+RVck=
github.com/vbatts/tar-split v0.11.3/go.mod h1:9QlHN18E+fEH7RdG+QAJJcuya3rqT7eXSTY7wGrAokY=
github.com/wayneashleyberry/terminal-dimensions v1.1.0 h1:EB7cIzBdsOzAgmhTUtTTQXBByuPheP/Zv1zL2BRPY6g=
github.com/wayneashleyberry/terminal-dimensions v1.1.0/go.mod h1:2lc/0eWCObmhRczn2SdGSQtgBooLUzIotkkEGXqghyg=
github.com/xo/terminfo v0.0.0-20210125001918-ca9a967f8778/go.mod h1:2MuV+tbUrU1zIOPMxZ5EncGwgmMJsa+9ucAQZXxsObs=
github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e h1:JVG44RsyaB9T2KIHavMF/ppJZNG9ZpyihvCd0w101no=
github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e/go.mod h1:RbqR21r5mrJuqunuUZ/Dhy/avygyECGrLceyNeo4LiM=
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
go.opencensus.io v0.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0=
go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= 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/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa h1:zuSxTR4o9y82ebqCUJYNGJbGPo6sKVl54f/TVDObg1c= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/crypto v0.7.0 h1:AvwMYaRytfdeVt3u6mLaxYtErKYjxA2OXjJ1HHq6t3A=
golang.org/x/crypto v0.7.0/go.mod h1:pYwdfH91IfpZVANVyUOhSIPZaFoJGxTFbZhFTx+dXZU=
golang.org/x/crypto v0.11.0 h1:6Ewdq3tDic1mg5xRO4milcWCfMVQhI4NkqWWvqejpuA=
golang.org/x/crypto v0.11.0/go.mod h1:xgJhtzW8F9jGdVFWZESrid1U1bjeNy4zgy5cRr/CIio=
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20220916125017-b168a2c6b86b h1:SCE/18RnFsLrjydh/R/s5EVvHoZprqEQUuoxK8q2Pc4=
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.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
golang.org/x/mod v0.10.0 h1:lFO9qtOdlre5W1jxS3r/4szv2/6iXxScdzjoBMXNhYk=
golang.org/x/mod v0.10.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-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/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-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
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-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
golang.org/x/net v0.0.0-20201006153459-a7d1128ccaa0/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20201006153459-a7d1128ccaa0/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
golang.org/x/net v0.1.0 h1:hZ/3BUoy5aId7sCpA/Tc5lt8DkFgdVS2onTpJsZ/fl0= golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
golang.org/x/net v0.1.0/go.mod h1:Cx3nUiGt4eDBEyega/BKRp+/AlGL8hYe7U9odMt2Cco= golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
golang.org/x/net v0.10.0 h1:X2//UzNDwYmtCLn7To6G58Wr6f5ahEAQgKNzv9Y951M=
golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg=
golang.org/x/net v0.13.0 h1:Nvo8UFsZ8X3BhAC9699Z1j7XQ3rsZnUUm7jfBEk1ueY=
golang.org/x/net v0.13.0/go.mod h1:zEVYFnQC7m/vmpQFELhcD1EWkZlX69l4oqgmer6hfKA=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= 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-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/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.2.0 h1:PUR+T4wwASmuSTYdKjYHI5TD22Wy5ogLU5qZCOLxBrI=
golang.org/x/sync v0.2.0/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-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/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-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-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
@@ -111,36 +346,109 @@ golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7w
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200519105757-fe76b779f299/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200519105757-fe76b779f299/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/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-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20211013075003-97ac67df715c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220319134239-a9b59b0215f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220319134239-a9b59b0215f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.1.0 h1:kunALQeHf1/185U1i0GOB/fy1IPRDDpuoOOqRReG57U= golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220906165534-d0df966e6959/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.8.0 h1:EBmGv8NaZBZTWvrbjNoL6HVt+IVy3QDQpJs7VRIw3tU=
golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.10.0 h1:SqMFp9UcQJZa+pmYuAKjd9xq1f0j5rLcDIk0mj4qAsA=
golang.org/x/sys v0.10.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.0.0-20210220032956-6a3ed077a48d/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.0.0-20210615171337-6886f2dfbf5b/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
golang.org/x/term v0.8.0 h1:n5xxQn2i3PC0yLAbjTpNT85q/Kgzcr2gIoX9OrJUols=
golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo=
golang.org/x/term v0.10.0 h1:3R7pNqamzBraeqj/Tj8qt1aQ2HpmlC+Cx/qL/7hn4/c=
golang.org/x/term v0.10.0/go.mod h1:lpqdcUyK/oCiQxvxVrppt5ggO2KCZ5QblwqPnfZ6d5o=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= 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.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.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.4.0 h1:BrVqGRd7+k1DiOgtnFvAkoQEWQvBc25ouMJM6429SFg= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
golang.org/x/text v0.9.0 h1:2sjJmO8cDvYveuX97RDLsxlyUxLl+GHoLxBiRdHllBE=
golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
golang.org/x/text v0.11.0 h1:LAntKIrcmeSKERyiOh0XMV39LXS8IE9UL2yP7+f5ij4=
golang.org/x/text v0.11.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
golang.org/x/time v0.0.0-20220210224613-90d013bbcef8 h1:vVKdlvoWBphwdxWKrFZEuM0kGgGLxUOYcY4U/2Vjg44=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= 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.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=
golang.org/x/tools v0.9.1 h1:8WMNJAz3zrtPmnYC7ISf5dEn3MT0gY7jBJfw27yrrLo=
golang.org/x/tools v0.9.1/go.mod h1:owI94Op576fPu3cIGQeHs3joujW/2Oc6MtlxbF5dfNc=
golang.org/x/tools v0.9.3 h1:Gn1I8+64MsuTb/HpH+LmQtNas23LhUVr3rYZ0eKuaMM=
golang.org/x/tools v0.9.3/go.mod h1:owI94Op576fPu3cIGQeHs3joujW/2Oc6MtlxbF5dfNc=
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-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/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-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo=
google.golang.org/genproto v0.0.0-20230306155012-7f2fa6fef1f4 h1:DdoeryqhaXp1LtT/emMP1BRJPHHKFi5akj/nbx/zNTA=
google.golang.org/genproto v0.0.0-20230306155012-7f2fa6fef1f4/go.mod h1:NWraEVixdDnqcqQ30jipen1STv2r/n24Wb7twVTGR4s=
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.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc=
google.golang.org/grpc v1.53.0 h1:LAv2ds7cmFV/XTS3XG1NneeENYrXGmorPxsBbptIjNc=
google.golang.org/grpc v1.53.0/go.mod h1:OnIrk0ipVdj4N5d9IUoFUx72/VlD7+jUsHwZgwSMQpw=
google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= 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-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 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.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.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.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
google.golang.org/protobuf v1.28.0 h1:w43yiav+6bVFTBQFZX0r7ipe9JQ1QsbMgHwbBziscLw= 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.30.0 h1:kPPoIgf3TsEvrm0PFe15JQ+570QVxYzEvvHqChK+cng=
google.golang.org/protobuf v1.30.0/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 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ=
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
gopkg.in/yaml.v1 v1.0.0-20140924161607-9f9df34309c0 h1:POO/ycCATvegFmVuPpQzZFJ+pGZeX22Ufu6fibxDVjU=
gopkg.in/yaml.v1 v1.0.0-20140924161607-9f9df34309c0/go.mod h1:WDnlLJ4WF5VGsH/HVa3CI79GS0ol3YnhVnKP89i0kNg= gopkg.in/yaml.v1 v1.0.0-20140924161607-9f9df34309c0/go.mod h1:WDnlLJ4WF5VGsH/HVa3CI79GS0ol3YnhVnKP89i0kNg=
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= 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.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-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gotest.tools/v3 v3.0.3 h1:4AuOwCGf4lLR9u3YOe2awrHygurzhO/HeQ6laiA6Sx0=
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=
howett.net/plist v1.0.0 h1:7CrbWYbPPO/PyNy38b2EB/+gYbjCe2DXBxgtOOZbSQM= howett.net/plist v1.0.0 h1:7CrbWYbPPO/PyNy38b2EB/+gYbjCe2DXBxgtOOZbSQM=
howett.net/plist v1.0.0/go.mod h1:lqaXoTrLY4hg8tnEzNru53gicrbv7rrk+2xJA/7hw9g= howett.net/plist v1.0.0/go.mod h1:lqaXoTrLY4hg8tnEzNru53gicrbv7rrk+2xJA/7hw9g=
k8s.io/apimachinery v0.26.2 h1:da1u3D5wfR5u2RpLhE/ZtZS2P7QvDgLZTi9wrNZl/tQ=
k8s.io/apimachinery v0.26.2/go.mod h1:ats7nN1LExKHvJ9TmwootT00Yz05MuYqPXEXaVeOy5I=

370
main.go
View File

@@ -2,309 +2,14 @@ package main
import ( import (
"fmt" "fmt"
"io/ioutil"
"os" "os"
"os/exec"
"path/filepath"
"strings"
"time"
luks "github.com/anatol/luks.go" "github.com/kairos-io/kcrypt/pkg/lib"
multierror "github.com/hashicorp/go-multierror"
"github.com/jaypipes/ghw"
"github.com/jaypipes/ghw/pkg/block"
"github.com/kairos-io/kcrypt/pkg/bus"
"github.com/mudler/go-pluggable"
cp "github.com/otiai10/copy"
"github.com/urfave/cli" "github.com/urfave/cli"
pi "github.com/kairos-io/kcrypt/pkg/partition_info"
) )
var Version = "v0.0.0-dev" var Version = "v0.0.0-dev"
func waitdevice(device string, attempts int) error {
for tries := 0; tries < attempts; tries++ {
sh("udevadm settle")
_, err := os.Lstat(device)
if !os.IsNotExist(err) {
return nil
}
time.Sleep(1 * time.Second)
}
return fmt.Errorf("no device found")
}
// TODO: Ask to discovery a pass to unlock. keep waiting until we get it and a timeout is exhausted with retrials (exp backoff)
func getPassword(b *block.Partition) (password string, err error) {
bus.Reload()
bus.Manager.Response(bus.EventDiscoveryPassword, func(p *pluggable.Plugin, r *pluggable.EventResponse) {
password = r.Data
if r.Errored() {
err = fmt.Errorf("failed discovery: %s", r.Error)
}
})
bus.Manager.Publish(bus.EventDiscoveryPassword, b)
if password == "" {
return password, fmt.Errorf("received empty password")
}
return
}
func luksUnlock(device, mapper, password string) error {
dev, err := luks.Open(device)
if err != nil {
// handle error
return err
}
defer dev.Close()
err = dev.Unlock(0, []byte(password), mapper)
if err != nil {
return err
}
return nil
}
func unlockDisk(b *block.Partition) error {
pass, err := getPassword(b)
if err != nil {
return fmt.Errorf("error retreiving password remotely: %w", err)
}
return luksUnlock(fmt.Sprintf("/dev/%s", b.Name), b.Name, pass)
}
func createLuks(dev, password, version string, cryptsetupArgs ...string) error {
if version == "" {
version = "luks2"
}
args := []string{"luksFormat", "--type", version, "--iter-time", "5", "-q", dev}
args = append(args, cryptsetupArgs...)
cmd := exec.Command("cryptsetup", args...)
cmd.Stdin = strings.NewReader(password)
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
if err := cmd.Run(); err != nil {
return err
}
return nil
}
func createDiskImage() (*os.File, error) {
disk, err := ioutil.TempFile("", "luksv2.go.disk")
if err != nil {
return nil, err
}
if err := disk.Truncate(24 * 1024 * 1024); err != nil {
return nil, err
}
return disk, err
}
// TODO: A crypt disk utility to call after install, that with discovery discoveries the password that should be used
// this function should delete COS_PERSISTENT. delete the partition and create a luks+type in place.
// Take a part label, and recreates it with LUKS. IT OVERWRITES DATA!
// On success, it returns a machine parseable string with the partition information
// (label:name:uuid) so that it can be stored by the caller for later use.
// This is because the label of the encrypted partition is not accessible unless
// the partition is decrypted first and the uuid changed after encryption so
// any stored information needs to be updated (by the caller).
func luksify(label string) (string, error) {
// blkid
persistent, b, err := findPartition(label)
if err != nil {
return "", err
}
pass, err := getPassword(b)
if err != nil {
return "", err
}
persistent = fmt.Sprintf("/dev/%s", persistent)
devMapper := fmt.Sprintf("/dev/mapper/%s", b.Name)
if err := createLuks(persistent, pass, "luks1"); err != nil {
return "", err
}
if err := luksUnlock(persistent, b.Name, pass); err != nil {
return "", err
}
if err := waitdevice(devMapper, 10); err != nil {
return "", err
}
out, err := sh(fmt.Sprintf("mkfs.ext4 -L %s %s", label, devMapper))
if err != nil {
return "", fmt.Errorf("err: %w, out: %s", err, out)
}
out2, err := sh(fmt.Sprintf("cryptsetup close %s", b.Name))
if err != nil {
return "", fmt.Errorf("err: %w, out: %s", err, out2)
}
return pi.PartitionToString(b), nil
}
func findPartition(label string) (string, *block.Partition, error) {
block, err := ghw.Block()
if err == nil {
for _, disk := range block.Disks {
for _, p := range disk.Partitions {
if p.Label == label {
return p.Name, p, nil
}
}
}
} else {
return "", nil, err
}
return "", nil, fmt.Errorf("not found")
}
func sh(c string) (string, error) {
o, err := exec.Command("/bin/sh", "-c", c).CombinedOutput()
return string(o), err
}
const (
GZType = "gz"
XZType = "xz"
LZMAType = "lzma"
)
// TODO: replace with golang native code
func detect(archive string) (string, error) {
out, err := sh(fmt.Sprintf("file %s", archive))
if err != nil {
return "", err
}
out = strings.ToLower(out)
if strings.Contains(out, "xz") {
return XZType, nil
} else if strings.Contains(out, "lzma") {
return LZMAType, nil
} else if strings.Contains(out, "gz") {
return GZType, nil
}
return "", fmt.Errorf("Unknown")
}
// TODO: replace with golang native code
func extractInitrd(initrd string, dst string) error {
os.MkdirAll(dst, os.ModePerm)
var out string
var err error
format, err := detect(initrd)
if err != nil {
return err
}
if format == XZType || format == LZMAType {
out, err = sh(fmt.Sprintf("cd %s && xz -dc < %s | cpio -idmv", dst, initrd))
} else if format == GZType {
out, err = sh(fmt.Sprintf("cd %s && zcat %s | cpio -idmv", dst, initrd))
}
fmt.Println(out)
return err
}
func createInitrd(initrd string, src string, format string) error {
fmt.Printf("Creating '%s' from '%s' as '%s'\n", initrd, src, format)
if _, err := os.Stat(src); err != nil {
return err
}
var err error
var out string
if format == XZType {
out, err = sh(fmt.Sprintf("cd %s && find . 2>/dev/null | cpio -H newc --quiet --null -o -R root:root | xz -0 --check=crc32 > %s", src, initrd))
} else if format == GZType {
out, err = sh(fmt.Sprintf("cd %s && find . | cpio -H newc -o -R root:root | gzip -9 > %s", src, initrd))
} else if format == LZMAType {
out, err = sh(fmt.Sprintf("cd %s && find . 2>/dev/null | cpio -H newc -o -R root:root | xz -9 --format=lzma > %s", src, initrd))
}
fmt.Println(out)
return err
}
// TODO: A inject initramfs command to add the discovery e.g. to use inside Dockerfiles
func injectInitrd(initrd string, file, dst string) error {
fmt.Printf("Injecting '%s' as '%s' into '%s'\n", file, dst, initrd)
format, err := detect(initrd)
if err != nil {
return err
}
tmp, err := ioutil.TempDir("", "kcrypt")
if err != nil {
return fmt.Errorf("cannot create tempdir, %s", err)
}
defer os.RemoveAll(tmp)
fmt.Printf("Extracting '%s' in '%s' ...\n", initrd, tmp)
if err := extractInitrd(initrd, tmp); err != nil {
return fmt.Errorf("cannot extract initrd, %s", err)
}
d := filepath.Join(tmp, dst)
fmt.Printf("Copying '%s' in '%s' ...\n", file, d)
if err := cp.Copy(file, d); err != nil {
return fmt.Errorf("cannot copy file, %s", err)
}
return createInitrd(initrd, tmp, format)
}
// TODO: a custom toolkit version, to build out initrd pre-built with this component
func unlockAll() error {
bus.Manager.Initialize()
partitionInfo, _, err := pi.NewPartitionInfoFromFile(pi.DefaultPartitionInfoFile)
if err != nil {
return err
}
block, err := ghw.Block()
if err == nil {
for _, disk := range block.Disks {
for _, p := range disk.Partitions {
if p.Type == "crypto_LUKS" {
p.Label = partitionInfo.LookupLabelForUUID(p.UUID)
fmt.Printf("Unmounted Luks found at '%s' LABEL '%s' \n", p.Name, p.Label)
err = multierror.Append(err, unlockDisk(p))
if err != nil {
fmt.Printf("Unlocking failed: '%s'\n", err.Error())
}
time.Sleep(10 * time.Second)
}
}
}
}
return err
}
func main() { func main() {
app := &cli.App{ app := &cli.App{
Name: "kairos-kcrypt", Name: "kairos-kcrypt",
@@ -315,25 +20,28 @@ func main() {
UsageText: ``, UsageText: ``,
Copyright: "Ettore Di Giacinto", Copyright: "Ettore Di Giacinto",
Commands: []cli.Command{ Commands: []cli.Command{
{
Name: "extract-initrd",
Action: func(c *cli.Context) error {
if c.NArg() != 2 {
return fmt.Errorf("requires 3 args. initrd,, dst")
}
return extractInitrd(c.Args()[0], c.Args()[1])
},
},
{ {
Name: "encrypt", Name: "encrypt",
Description: "Encrypts a partition", Description: "Encrypts a partition",
Usage: "Encrypts a partition",
ArgsUsage: "kcrypt [--version VERSION] [--tpm] LABEL",
Flags: []cli.Flag{
&cli.StringFlag{
Name: "version",
Value: "luks1",
Usage: "luks version to use",
},
&cli.BoolFlag{
Name: "tpm",
Usage: "Use TPM to lock the partition",
},
},
Action: func(c *cli.Context) error { Action: func(c *cli.Context) error {
if c.NArg() != 1 { if c.NArg() != 1 {
return fmt.Errorf("requires 1 arg, the partition label") return fmt.Errorf("requires 1 arg, the partition label")
} }
out, err := luksify(c.Args().First()) out, err := lib.Luksify(c.Args().First(), c.String("version"), c.Bool("tpm"))
if err != nil { if err != nil {
return err return err
} }
@@ -341,30 +49,42 @@ func main() {
return nil return nil
}, },
}, },
{
Name: "unlock-all",
UsageText: "unlock-all",
Usage: "Try to unlock all LUKS partitions",
Description: "Typically run during initrd to unlock all the LUKS partitions found",
ArgsUsage: "kcrypt [--tpm] unlock-all",
Flags: []cli.Flag{
&cli.BoolFlag{
Name: "tpm",
Usage: "Use TPM to unlock the partition",
},
},
Action: func(c *cli.Context) error {
return lib.UnlockAll(c.Bool("tpm"))
},
},
{ {
Name: "inject-initrd", Name: "extract-initrd",
Hidden: true,
Action: func(c *cli.Context) error {
if c.NArg() != 2 {
return fmt.Errorf("requires 3 args. initrd,, dst")
}
return lib.ExtractInitrd(c.Args()[0], c.Args()[1])
},
},
{
Name: "inject-initrd",
Hidden: true,
Action: func(c *cli.Context) error { Action: func(c *cli.Context) error {
if c.NArg() != 3 { if c.NArg() != 3 {
return fmt.Errorf("requires 3 args. initrd, srcfile, dst") return fmt.Errorf("requires 3 args. initrd, srcfile, dst")
} }
return injectInitrd(c.Args()[0], c.Args()[1], c.Args()[2]) return lib.InjectInitrd(c.Args()[0], c.Args()[1], c.Args()[2])
},
},
{
Name: "unlock-all",
UsageText: "unlock-all",
Usage: "Try to unlock all LUKS partitions",
Description: `
Typically run during initrd to unlock all the LUKS partitions found
`,
ArgsUsage: "kcrypt unlock-all",
Flags: []cli.Flag{
&cli.StringFlag{},
},
Action: func(c *cli.Context) error {
return unlockAll()
}, },
}, },
}, },

View File

@@ -28,7 +28,7 @@ type Bus struct {
func (b *Bus) LoadProviders() { func (b *Bus) LoadProviders() {
wd, _ := os.Getwd() wd, _ := os.Getwd()
b.Manager.Autoload("kcrypt-discovery", "/system/discovery", "/oem/kcrypt", "/oem/system/discovery", wd).Register() b.Manager.Autoload("kcrypt-discovery", "/sysroot/system/discovery", "/system/discovery", "/oem/kcrypt", "/oem/system/discovery", wd).Register()
} }
func (b *Bus) Initialize() { func (b *Bus) Initialize() {

145
pkg/config/config.go Normal file
View File

@@ -0,0 +1,145 @@
// package config contains all the logic around kcrypt config
// This config includes everything below `kcrypt:` in the kairos config yaml
package config
import (
"fmt"
"os"
"strings"
"github.com/gofrs/uuid"
"github.com/jaypipes/ghw/pkg/block"
"github.com/kairos-io/kairos-sdk/collector"
"github.com/pkg/errors"
"gopkg.in/yaml.v1"
)
// There are the directories under which we expect to find kairos configuration.
// When we are booted from an iso (during installation), configuration is expected
// under `/oem`. When we are booting an installed system (in initramfs phase),
// the path is `/sysroot/oem`.
var ConfigScanDirs = []string{"/oem", "/sysroot/oem"}
// This file is "hardcoded" to `/oem` because we only use this at install time
// in which case the config is in `/oem`.
var MappingsFile = "/oem/91-kcrypt-mappings.yaml"
type Config struct {
Kcrypt struct {
UUIDLabelMappings map[string]string `yaml:"uuid_label_mappings,omitempty"`
}
}
func PartitionToString(p *block.Partition) string {
return fmt.Sprintf("%s:%s:%s", p.FilesystemLabel, p.Name, p.UUID)
}
// Takes a partition info string (as returned by PartitionToString) and return
// the partition label and the UUID
func partitionDataFromString(partitionStr string) (string, string, error) {
parts := strings.Split(partitionStr, ":")
if len(parts) != 3 {
return "", "", errors.New("partition string not valid")
}
return strings.TrimSpace(parts[0]), strings.TrimSpace(parts[2]), nil
}
func GetConfiguration(configDirs []string) (Config, error) {
var result Config
o := &collector.Options{MergeBootCMDLine: false}
if err := o.Apply(collector.Directories(configDirs...), collector.NoLogs); err != nil {
return result, err
}
c, err := collector.Scan(o, func(d []byte) ([]byte, error) {
return d, nil
})
if err != nil {
return result, err
}
configStr, err := c.String()
if err != nil {
return result, err
}
if err = yaml.Unmarshal([]byte(configStr), &result); err != nil {
return result, err
}
return result, nil
}
// SetMapping updates the Config with partition information for
// one partition. This doesn't persist on the file. WriteMappings needs to
// be called after all mapping are in the Config (possibly with multiple calls
// to this function).
func (c *Config) SetMapping(partitionInfo string) error {
label, uuid, err := partitionDataFromString(partitionInfo)
if err != nil {
return err
}
// Initialize map
if c.Kcrypt.UUIDLabelMappings == nil {
c.Kcrypt.UUIDLabelMappings = map[string]string{}
}
c.Kcrypt.UUIDLabelMappings[label] = uuid
return nil
}
// WriteMappings will create or replace the MappingsFile
// It's called by kairos agent, at installation time, after the partitions
// have been created (and we have the UUIDs available).
func (c *Config) WriteMappings(fileName string) error {
data, err := yaml.Marshal(&c)
if err != nil {
return errors.Wrap(err, "marshalling the kcrypt configuration to yaml")
}
data = append([]byte(collector.DefaultHeader+"\n"), data...)
err = os.WriteFile(fileName, data, 0744)
if err != nil {
return errors.Wrap(err, "writing the kcrypt configuration file")
}
return nil
}
func (c Config) LookupUUIDForLabel(l string) string {
return c.Kcrypt.UUIDLabelMappings[l]
}
func (c Config) LookupLabelForUUID(uuid string) string {
for k, v := range c.Kcrypt.UUIDLabelMappings {
if v == uuid {
return k
}
}
return ""
}
// GetLabelForUUID returns the partition label for a known UUID
// UUIDS are generated on luksify method
// They are generated by setting the namespace to DNS and the name to the fs label, so they are always the same
func (c Config) GetLabelForUUID(uuidCheck string) (string, error) {
persistent := uuid.NewV5(uuid.NamespaceURL, "COS_PERSISTENT")
oem := uuid.NewV5(uuid.NamespaceURL, "COS_OEM")
fmt.Printf("Checking uuid: %s\n", uuidCheck)
parsedUUID, err := uuid.FromString(uuidCheck)
if err != nil {
return "", err
}
switch parsedUUID {
case persistent:
return "COS_PERSISTENT", nil
case oem:
return "COS_OEM", nil
default:
return "", errors.New("no partition found with that uuid")
}
}

216
pkg/config/config_test.go Normal file
View File

@@ -0,0 +1,216 @@
package config_test
import (
"os"
. "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega"
"github.com/kairos-io/kairos-sdk/collector"
configpkg "github.com/kairos-io/kcrypt/pkg/config"
)
var _ = Describe("Config", func() {
var tmpDir string
var err error
BeforeEach(func() {
tmpDir, err = os.MkdirTemp("", "kcrypt-configuration-*")
Expect(err).ToNot(HaveOccurred())
})
AfterEach(func() {
os.RemoveAll(tmpDir)
})
Describe("GetConfiguration", func() {
When("the no relevant block exists", func() {
It("returns empty Config", func() {
c, err := configpkg.GetConfiguration([]string{tmpDir})
Expect(err).ToNot(HaveOccurred())
Expect(c.Kcrypt.UUIDLabelMappings).To(BeEmpty())
})
})
When("a kcrypt block exists", func() {
var tmpFile *os.File
BeforeEach(func() {
tmpFile, err = os.CreateTemp(tmpDir, "config-*.yaml")
Expect(err).ToNot(HaveOccurred())
data := []byte(`#cloud-config
kcrypt:
uuid_label_mappings:
COS_PERSISTENT: some_uuid_here
`)
err := os.WriteFile(tmpFile.Name(), data, 0744)
Expect(err).ToNot(HaveOccurred())
})
It("returns the Config", func() {
c, err := configpkg.GetConfiguration([]string{tmpDir})
Expect(err).ToNot(HaveOccurred())
Expect(c.Kcrypt.UUIDLabelMappings["COS_PERSISTENT"]).To(Equal("some_uuid_here"))
})
})
When("multiple kcrypt block exist", func() {
var tmpFile1, tmpFile2 *os.File
BeforeEach(func() {
tmpFile1, err = os.CreateTemp(tmpDir, "config-*.yaml")
Expect(err).ToNot(HaveOccurred())
data := []byte(`#cloud-config
kcrypt:
challenger_server: http://test.org:8082
`)
err := os.WriteFile(tmpFile1.Name(), data, 0744)
Expect(err).ToNot(HaveOccurred())
tmpFile2, err = os.CreateTemp(tmpDir, "config-*.yaml")
Expect(err).ToNot(HaveOccurred())
data = []byte(`#cloud-config
kcrypt:
uuid_label_mappings:
COS_PERSISTENT: some_uuid_here
`)
err = os.WriteFile(tmpFile2.Name(), data, 0744)
Expect(err).ToNot(HaveOccurred())
})
It("returns the merged Config", func() {
c, err := configpkg.GetConfiguration([]string{tmpDir})
Expect(err).ToNot(HaveOccurred())
Expect(c.Kcrypt.UUIDLabelMappings["COS_PERSISTENT"]).To(Equal("some_uuid_here"))
})
})
})
Describe("SetMapping", func() {
var c configpkg.Config
BeforeEach(func() {
c, err = configpkg.GetConfiguration([]string{tmpDir})
Expect(err).ToNot(HaveOccurred())
})
It("adds partition information when empty and appends when not", func() {
Expect(c.Kcrypt.UUIDLabelMappings).To(BeNil())
err := c.SetMapping("some_label:some_name:some_uuid")
Expect(err).ToNot(HaveOccurred())
Expect(c.Kcrypt.UUIDLabelMappings["some_label"]).To(Equal("some_uuid"))
err = c.SetMapping("some_other_label:some_name:some_other_uuid")
Expect(err).ToNot(HaveOccurred())
Expect(c.Kcrypt.UUIDLabelMappings["some_label"]).To(Equal("some_uuid"))
Expect(c.Kcrypt.UUIDLabelMappings["some_other_label"]).To(Equal("some_other_uuid"))
})
})
Describe("WriteMappings", func() {
var tmpFile *os.File
var c configpkg.Config
When("mappings config file already exists", func() {
BeforeEach(func() {
tmpFile, err = os.CreateTemp(tmpDir, "config-*.yaml")
Expect(err).ToNot(HaveOccurred())
data := []byte(`kcrypt:
uuid_label_mappings:
COS_PERSISTENT: some_uuid_here
`)
err := os.WriteFile(tmpFile.Name(), data, 0744)
Expect(err).ToNot(HaveOccurred())
})
It("replaces the file contents", func() {
err := c.SetMapping("COS_PERSISTENT:the_new_name:the_new_uuid")
Expect(err).ToNot(HaveOccurred())
err = c.WriteMappings(tmpFile.Name())
Expect(err).ToNot(HaveOccurred())
data, err := os.ReadFile(tmpFile.Name())
Expect(err).ToNot(HaveOccurred())
Expect(collector.HasValidHeader(string(data))).To(BeTrue())
newConfig, err := configpkg.GetConfiguration([]string{tmpDir})
Expect(err).ToNot(HaveOccurred())
Expect(newConfig.Kcrypt.UUIDLabelMappings["COS_PERSISTENT"]).To(Equal("the_new_uuid"))
})
})
When("a mappings configuration file doesn't exist", func() {
BeforeEach(func() {
tmpFile, err = os.CreateTemp(tmpDir, "config-*.yaml")
Expect(err).ToNot(HaveOccurred())
// We will reuse the same name but we make sure the file doesn't exist.
os.RemoveAll(tmpFile.Name())
})
It("creates the file with the given mappings", func() {
err := c.SetMapping("COS_PERSISTENT:the_new_name:the_new_uuid")
Expect(err).ToNot(HaveOccurred())
err = c.WriteMappings(tmpFile.Name())
Expect(err).ToNot(HaveOccurred())
newConfig, err := configpkg.GetConfiguration([]string{tmpDir})
Expect(err).ToNot(HaveOccurred())
Expect(newConfig.Kcrypt.UUIDLabelMappings["COS_PERSISTENT"]).To(Equal("the_new_uuid"))
})
})
})
Describe("LookupUUIDForLabel", func() {
var tmpFile *os.File
var c configpkg.Config
BeforeEach(func() {
tmpFile, err = os.CreateTemp(tmpDir, "config-*.yaml")
Expect(err).ToNot(HaveOccurred())
// Should trim the whitespace
err = c.SetMapping("COS_PERSISTENT:the_new_name:some_uuid_1\n")
Expect(err).ToNot(HaveOccurred())
err = c.WriteMappings(tmpFile.Name())
Expect(err).ToNot(HaveOccurred())
})
It("returns the correct UUID", func() {
uuid := c.LookupUUIDForLabel("COS_PERSISTENT")
Expect(uuid).To(Equal("some_uuid_1"))
})
It("returns an empty UUID when the label is not found", func() {
uuid := c.LookupUUIDForLabel("DOESNT_EXIST")
Expect(uuid).To(Equal(""))
})
It("returns an empty UUID when the UUIDLabelMappings is nil", func() {
c.Kcrypt.UUIDLabelMappings = nil
uuid := c.LookupUUIDForLabel("COS_PERSISTENT")
Expect(uuid).To(Equal(""))
})
})
Describe("LookupLabelForUUID", func() {
var tmpFile *os.File
var c configpkg.Config
BeforeEach(func() {
tmpFile, err = os.CreateTemp(tmpDir, "config-*.yaml")
Expect(err).ToNot(HaveOccurred())
err = c.SetMapping("COS_PERSISTENT:the_new_name:some_uuid_1")
Expect(err).ToNot(HaveOccurred())
err = c.WriteMappings(tmpFile.Name())
Expect(err).ToNot(HaveOccurred())
})
It("returns the correct label", func() {
uuid := c.LookupLabelForUUID("some_uuid_1")
Expect(uuid).To(Equal("COS_PERSISTENT"))
})
It("returns an empty label when UUID doesn't exist", func() {
uuid := c.LookupLabelForUUID("doesnt_exist")
Expect(uuid).To(Equal(""))
})
})
})

View File

@@ -1,4 +1,4 @@
package partition_info package config
import ( import (
"testing" "testing"
@@ -9,5 +9,5 @@ import (
func TestPartitionINfo(t *testing.T) { func TestPartitionINfo(t *testing.T) {
RegisterFailHandler(Fail) RegisterFailHandler(Fail)
RunSpecs(t, "PartitionInfo file parser test suite") RunSpecs(t, "Kcrypt config test suite")
} }

104
pkg/lib/initrd.go Normal file
View File

@@ -0,0 +1,104 @@
package lib
import (
"fmt"
"os"
"path/filepath"
"strings"
cp "github.com/otiai10/copy"
)
const (
GZType = "gz"
XZType = "xz"
LZMAType = "lzma"
)
func createInitrd(initrd string, src string, format string) error {
fmt.Printf("Creating '%s' from '%s' as '%s'\n", initrd, src, format)
if _, err := os.Stat(src); err != nil {
return err
}
var err error
var out string
if format == XZType {
out, err = SH(fmt.Sprintf("cd %s && find . 2>/dev/null | cpio -H newc --quiet --null -o -R root:root | xz -0 --check=crc32 > %s", src, initrd))
} else if format == GZType {
out, err = SH(fmt.Sprintf("cd %s && find . | cpio -H newc -o -R root:root | gzip -9 > %s", src, initrd))
} else if format == LZMAType {
out, err = SH(fmt.Sprintf("cd %s && find . 2>/dev/null | cpio -H newc -o -R root:root | xz -9 --format=lzma > %s", src, initrd))
}
fmt.Println(out)
return err
}
func InjectInitrd(initrd string, file, dst string) error {
fmt.Printf("Injecting '%s' as '%s' into '%s'\n", file, dst, initrd)
format, err := detect(initrd)
if err != nil {
return err
}
tmp, err := os.MkdirTemp("", "kcrypt")
if err != nil {
return fmt.Errorf("cannot create tempdir, %s", err)
}
defer os.RemoveAll(tmp)
fmt.Printf("Extracting '%s' in '%s' ...\n", initrd, tmp)
if err := ExtractInitrd(initrd, tmp); err != nil {
return fmt.Errorf("cannot extract initrd, %s", err)
}
d := filepath.Join(tmp, dst)
fmt.Printf("Copying '%s' in '%s' ...\n", file, d)
if err := cp.Copy(file, d); err != nil {
return fmt.Errorf("cannot copy file, %s", err)
}
return createInitrd(initrd, tmp, format)
}
func ExtractInitrd(initrd string, dst string) error {
var out string
var err error
err = os.MkdirAll(dst, os.ModePerm)
if err != nil {
return err
}
format, err := detect(initrd)
if err != nil {
return err
}
if format == XZType || format == LZMAType {
out, err = SH(fmt.Sprintf("cd %s && xz -dc < %s | cpio -idmv", dst, initrd))
} else if format == GZType {
out, err = SH(fmt.Sprintf("cd %s && zcat %s | cpio -idmv", dst, initrd))
}
fmt.Println(out)
return err
}
func detect(archive string) (string, error) {
out, err := SH(fmt.Sprintf("file %s", archive))
if err != nil {
return "", err
}
out = strings.ToLower(out)
if strings.Contains(out, "xz") {
return XZType, nil
} else if strings.Contains(out, "lzma") {
return LZMAType, nil
} else if strings.Contains(out, "gz") {
return GZType, nil
}
return "", fmt.Errorf("Unknown")
}

137
pkg/lib/lock.go Normal file
View File

@@ -0,0 +1,137 @@
package lib
import (
"fmt"
"github.com/gofrs/uuid"
"github.com/jaypipes/ghw"
"github.com/jaypipes/ghw/pkg/block"
configpkg "github.com/kairos-io/kcrypt/pkg/config"
"k8s.io/apimachinery/pkg/util/rand"
"os"
"os/exec"
"strings"
)
func CreateLuks(dev, password, version string, cryptsetupArgs ...string) error {
if version == "" {
version = "luks2"
}
args := []string{"luksFormat", "--type", version, "--iter-time", "5", "-q", dev}
args = append(args, cryptsetupArgs...)
cmd := exec.Command("cryptsetup", args...)
cmd.Stdin = strings.NewReader(password)
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
err := cmd.Run()
if err != nil {
return err
}
return nil
}
// Luksify Take a part label, and recreates it with LUKS. IT OVERWRITES DATA!
// On success, it returns a machine parseable string with the partition information
// (label:name:uuid) so that it can be stored by the caller for later use.
// This is because the label of the encrypted partition is not accessible unless
// the partition is decrypted first and the uuid changed after encryption so
// any stored information needs to be updated (by the caller).
func Luksify(label, version string, tpm bool) (string, error) {
var pass string
if version == "" {
version = "luks1"
}
if version != "luks1" && version != "luks2" {
return "", fmt.Errorf("version must be luks1 or luks2")
}
part, b, err := FindPartition(label)
if err != nil {
return "", err
}
if tpm {
// On TPM locking we generate a random password that will only be used here then discarded.
// only unlocking method will be PCR values
pass = rand.String(32)
} else {
pass, err = GetPassword(b)
if err != nil {
return "", err
}
}
part = fmt.Sprintf("/dev/%s", part)
devMapper := fmt.Sprintf("/dev/mapper/%s", b.Name)
partUUID := uuid.NewV5(uuid.NamespaceURL, label)
extraArgs := []string{"--uuid", partUUID.String()}
if err := CreateLuks(part, pass, version, extraArgs...); err != nil {
return "", err
}
if tpm {
// Enroll PCR policy as a keyslot
// We pass the current signature of the booted system to confirm that we would be able to unlock with the current booted system
// That checks the policy against the signatures and fails if a UKI with those signatures wont be able to unlock the device
// Files are generated by systemd automatically and are extracted from the UKI binary directly
// public pem cert -> .pcrpkey section fo the elf file
// signatures -> .pcrsig section of the elf file
args := []string{"--tpm2-public-key=/run/systemd/tpm2-pcr-public-key.pem", "--tpm2-signature=/run/systemd/tpm2-pcr-signature.json", "--tpm2-device=auto", part}
cmd := exec.Command("systemd-cryptenroll", args...)
cmd.Env = append(cmd.Env, fmt.Sprintf("PASSWORD=%s", pass)) // cannot pass it via stdin
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
err := cmd.Run()
if err != nil {
return "", err
}
}
if err := LuksUnlock(part, b.Name, pass); err != nil {
return "", fmt.Errorf("unlock err: %w", err)
}
if err := Waitdevice(devMapper, 10); err != nil {
return "", fmt.Errorf("waitdevice err: %w", err)
}
cmd := fmt.Sprintf("mkfs.ext4 -L %s %s", label, devMapper)
out, err := SH(cmd)
if err != nil {
return "", fmt.Errorf("mkfs err: %w, out: %s", err, out)
}
out, err = SH(fmt.Sprintf("cryptsetup close %s", b.Name))
if err != nil {
return "", fmt.Errorf("lock err: %w, out: %s", err, out)
}
if tpm {
// Delete password slot from luks device
out, err := SH(fmt.Sprintf("systemd-cryptenroll --wipe-slot=password %s", part))
if err != nil {
return "", fmt.Errorf("err: %w, out: %s", err, out)
}
}
return configpkg.PartitionToString(b), nil
}
func FindPartition(label string) (string, *block.Partition, error) {
b, err := ghw.Block()
if err == nil {
for _, disk := range b.Disks {
for _, p := range disk.Partitions {
if p.FilesystemLabel == label {
return p.Name, p, nil
}
}
}
} else {
return "", nil, err
}
return "", nil, fmt.Errorf("not found")
}

123
pkg/lib/unlock.go Normal file
View File

@@ -0,0 +1,123 @@
package lib
import (
"fmt"
"path/filepath"
"strings"
"github.com/anatol/luks.go"
"github.com/jaypipes/ghw"
"github.com/jaypipes/ghw/pkg/block"
"github.com/kairos-io/kairos-sdk/utils"
"github.com/kairos-io/kcrypt/pkg/bus"
configpkg "github.com/kairos-io/kcrypt/pkg/config"
"github.com/mudler/go-pluggable"
)
// UnlockAll Unlocks all encrypted devices found in the system
func UnlockAll(tpm bool) error {
bus.Manager.Initialize()
config, err := configpkg.GetConfiguration(configpkg.ConfigScanDirs)
if err != nil {
fmt.Printf("Warning: Could not read kcrypt configuration '%s'\n", err.Error())
}
blk, err := ghw.Block()
if err != nil {
fmt.Printf("Warning: Error reading partitions '%s \n", err.Error())
return nil
}
for _, disk := range blk.Disks {
for _, p := range disk.Partitions {
if p.Type == "crypto_LUKS" {
// Get the luks UUID directly from cryptsetup
volumeUUID, err := utils.SH(fmt.Sprintf("cryptsetup luksUUID %s", filepath.Join("/dev", p.Name)))
fmt.Printf("Got luks UUID %s for partition %s\n", volumeUUID, p.Name)
if err != nil {
return err
}
volumeUUID = strings.TrimSpace(volumeUUID)
if volumeUUID == "" {
fmt.Printf("No uuid for %s, skipping\n", p.Name)
continue
}
p.FilesystemLabel, err = config.GetLabelForUUID(volumeUUID)
if err != nil {
return err
}
// Check if device is already mounted
// We mount it under /dev/mapper/DEVICE, so It's pretty easy to check
if !utils.Exists(filepath.Join("/dev", "mapper", p.Name)) {
fmt.Printf("Unmounted Luks found at '%s' LABEL '%s' \n", filepath.Join("/dev", p.Name), p.FilesystemLabel)
if tpm {
out, err := utils.SH(fmt.Sprintf("/usr/lib/systemd/systemd-cryptsetup attach %s %s - tpm2-device=auto", p.Name, filepath.Join("/dev", p.Name)))
if err != nil {
fmt.Printf("Unlocking failed: '%s'\n", err.Error())
fmt.Printf("Unlocking failed, command output: '%s'\n", out)
}
} else {
err = UnlockDisk(p)
if err != nil {
fmt.Printf("Unlocking failed: '%s'\n", err.Error())
}
}
} else {
fmt.Printf("Device %s seems to be mounted at %s, skipping\n", filepath.Join("/dev", p.Name), filepath.Join("/dev", "mapper", p.Name))
}
}
}
}
return nil
}
// UnlockDisk unlocks a single block.Partition
func UnlockDisk(b *block.Partition) error {
pass, err := GetPassword(b)
if err != nil {
return fmt.Errorf("error retreiving password remotely: %w", err)
}
return LuksUnlock(filepath.Join("/dev", b.Name), b.Name, pass)
}
// GetPassword gets the password for a block.Partition
// TODO: Ask to discovery a pass to unlock. keep waiting until we get it and a timeout is exhausted with retrials (exp backoff)
func GetPassword(b *block.Partition) (password string, err error) {
bus.Reload()
bus.Manager.Response(bus.EventDiscoveryPassword, func(p *pluggable.Plugin, r *pluggable.EventResponse) {
password = r.Data
if r.Errored() {
err = fmt.Errorf("failed discovery: %s", r.Error)
}
})
_, err = bus.Manager.Publish(bus.EventDiscoveryPassword, b)
if err != nil {
return password, err
}
if password == "" {
return password, fmt.Errorf("received empty password")
}
return
}
func LuksUnlock(device, mapper, password string) error {
dev, err := luks.Open(device)
if err != nil {
// handle error
return err
}
defer dev.Close()
err = dev.Unlock(0, []byte(password), mapper)
if err != nil {
return err
}
return nil
}

28
pkg/lib/utils.go Normal file
View File

@@ -0,0 +1,28 @@
package lib
import (
"fmt"
"os"
"os/exec"
"time"
)
func SH(c string) (string, error) {
o, err := exec.Command("/bin/sh", "-c", c).CombinedOutput()
return string(o), err
}
func Waitdevice(device string, attempts int) error {
for tries := 0; tries < attempts; tries++ {
_, err := SH("udevadm settle")
if err != nil {
return err
}
_, err = os.Lstat(device)
if !os.IsNotExist(err) {
return nil
}
time.Sleep(1 * time.Second)
}
return fmt.Errorf("no device found")
}

View File

@@ -1,125 +0,0 @@
package partition_info
import (
"fmt"
"io/ioutil"
"os"
"strings"
"github.com/jaypipes/ghw/pkg/block"
"github.com/pkg/errors"
"gopkg.in/yaml.v3"
)
const DefaultPartitionInfoFile = "/oem/partition_info.yaml"
// PartitionInfo maps a partition label to a partition UUID.
// It's used in order to be able to ask the kcrypt-challenger for the passphrase
// using the partition label, even when the label is not accessible (e.g. before
// decrypting the partition). The UUID can be used to lookup the partition label
// and make the request.
type PartitionInfo struct {
file string
mapping map[string]string
}
// NewPartitionInfoFromFile reads the given partition info file (if one exists)
// and returns a pointer to a PartitionInfo object.
// If a file doesn't exist, the function will create one and return an "empty"
// PartitionInfo object.
// The boolean return value indicates whether a file existed or not (true means,
// a file existed already).
func NewPartitionInfoFromFile(file string) (*PartitionInfo, bool, error) {
existed, err := createInfoFileIfNotExists(file)
if err != nil {
return nil, existed, err
}
mapping, err := ParsePartitionInfoFile(file)
if err != nil {
return nil, existed, err
}
return &PartitionInfo{
file: file,
mapping: mapping,
}, existed, nil
}
func (pi PartitionInfo) LookupUUIDForLabel(l string) string {
return pi.mapping[l]
}
func (pi PartitionInfo) LookupLabelForUUID(uuid string) string {
for k, v := range pi.mapping {
if v == uuid {
return k
}
}
return ""
}
// UpdatePartitionLabelMapping takes partition information as a string argument
// the the form: `label:name:uuid` (that's what the `kcrypt encrypt` command returns
// on success. This function stores it in the PartitionInfoFile yaml file for
// later use.
func (pi PartitionInfo) UpdateMapping(partitionData string) error {
label, uuid := PartitionDataFromString(partitionData)
pi.mapping[label] = uuid
return pi.save()
}
func (pi PartitionInfo) save() error {
data, err := yaml.Marshal(&pi.mapping)
if err != nil {
return errors.Wrap(err, "marshalling the new partition info to yaml")
}
err = ioutil.WriteFile(pi.file, data, 0)
if err != nil {
return errors.Wrap(err, "writing back the partition info file")
}
return nil
}
func PartitionToString(p *block.Partition) string {
return fmt.Sprintf("%s:%s:%s", p.Label, p.Name, p.UUID)
}
// Takes a partition info string (as returned by PartitionToString) and return
// the partition label and the UUID
func PartitionDataFromString(partitionStr string) (string, string) {
parts := strings.Split(partitionStr, ":")
return parts[0], parts[2]
}
func ParsePartitionInfoFile(file string) (map[string]string, error) {
var result map[string]string
yamlFile, err := ioutil.ReadFile(file)
if err != nil {
return result, errors.Wrap(err, "reading the partition info file")
}
err = yaml.Unmarshal(yamlFile, &result)
if err != nil {
return result, errors.Wrap(err, "unmarshalling partition info file")
}
return result, nil
}
// createInfoFileIfNotExists returns true if file already exists or creates the
// the file if it doesn't exist and returns false.
func createInfoFileIfNotExists(fileName string) (bool, error) {
_, err := os.Stat(fileName)
if errors.Is(err, os.ErrNotExist) {
if _, err := os.Create(fileName); err != nil {
return false, err
}
return false, nil
}
return true, nil
}

View File

@@ -1,179 +0,0 @@
package partition_info_test
import (
"fmt"
"io/ioutil"
"os"
"path"
"time"
"github.com/jaypipes/ghw/pkg/block"
. "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega"
pi "github.com/kairos-io/kcrypt/pkg/partition_info"
)
var _ = Describe("Partition Info file parsing", func() {
Describe("NewPartitionInfoFromFile", func() {
var file string
BeforeEach(func() {
file = "../../tests/assets/partition_info.yaml"
})
When("the files exists already", func() {
It("returns 'true' and a PartitionInfo object", func() {
result, existed, err := pi.NewPartitionInfoFromFile(file)
Expect(err).ToNot(HaveOccurred())
Expect(result).ToNot(BeNil())
Expect(existed).To(BeTrue())
})
})
When("a file doesn't exist", func() {
var fileName string
BeforeEach(func() {
fileName = path.Join(
os.TempDir(),
fmt.Sprintf("partition-info-%d.yaml", time.Now().UnixNano()))
})
It("creates the file and returns 'false' and an (empty) mapping", func() {
result, existed, err := pi.NewPartitionInfoFromFile(fileName)
Expect(err).ToNot(HaveOccurred())
Expect(result).ToNot(BeNil())
Expect(existed).To(BeFalse())
_, err = os.Stat(fileName)
Expect(err).ToNot(HaveOccurred())
})
})
})
Describe("ParsePartitionInfoFile", func() {
var file string
BeforeEach(func() {
file = "../../tests/assets/partition_info.yaml"
})
It("parses the file correctly", func() {
info, err := pi.ParsePartitionInfoFile(file)
Expect(err).ToNot(HaveOccurred())
Expect(len(info)).To(Equal(2))
Expect(info["COS_PERSISTENT"]).To(Equal("some_uuid_1"))
Expect(info["COS_OTHER"]).To(Equal("some_uuid_2"))
})
})
Describe("PartitionToString", func() {
var partition *block.Partition
BeforeEach(func() {
partition = &block.Partition{
Disk: nil,
Name: "sda1",
Label: "COS_PERSISTENT",
MountPoint: "/mnt/sda1",
UUID: "some_uuid_here",
}
})
It("returns a string representation of the partition data", func() {
Expect(pi.PartitionToString(partition)).To(Equal("COS_PERSISTENT:sda1:some_uuid_here"))
})
})
Describe("PartitionDataFromString", func() {
var partitionData string
BeforeEach(func() {
partitionData = "THE_LABEL:the_name:the_uuid"
})
It("returns the label and the uuid", func() {
label, uuid := pi.PartitionDataFromString(partitionData)
Expect(label).To(Equal("THE_LABEL"))
Expect(uuid).To(Equal("the_uuid"))
})
})
Describe("UpdateMapping", func() {
var file *os.File
var err error
var partitionInfo *pi.PartitionInfo
BeforeEach(func() {
file, err = ioutil.TempFile("", "partition-info.*.yaml")
Expect(err).ToNot(HaveOccurred())
_, err = file.Write([]byte("TO_KEEP: old_uuid_1"))
Expect(err).ToNot(HaveOccurred())
partitionInfo, _, err = pi.NewPartitionInfoFromFile(file.Name())
Expect(err).ToNot(HaveOccurred())
})
AfterEach(func() {
os.Remove(file.Name())
})
It("Updates the file correctly from a `kcrypt encrypt` return value", func() {
partitionData := "TO_BE_ADDED:some_name:new_uuid"
err = partitionInfo.UpdateMapping(partitionData)
Expect(err).ToNot(HaveOccurred())
dat, err := os.ReadFile(file.Name())
Expect(err).ToNot(HaveOccurred())
expectedContent := `TO_BE_ADDED: new_uuid
TO_KEEP: old_uuid_1
`
Expect(string(dat)).To(Equal(expectedContent))
})
})
Describe("LookupUUIDForLabel", func() {
var file string
var partitionInfo *pi.PartitionInfo
var err error
BeforeEach(func() {
file = "../../tests/assets/partition_info.yaml"
partitionInfo, _, err = pi.NewPartitionInfoFromFile(file)
Expect(err).ToNot(HaveOccurred())
})
It("returns the correct UUID", func() {
uuid := partitionInfo.LookupUUIDForLabel("COS_PERSISTENT")
Expect(uuid).To(Equal("some_uuid_1"))
})
It("returns an empty UUID when the label is not found", func() {
uuid := partitionInfo.LookupUUIDForLabel("DOESNT_EXIST")
Expect(uuid).To(Equal(""))
})
})
Describe("LookupLabelForUUID", func() {
var file string
var partitionInfo *pi.PartitionInfo
var err error
BeforeEach(func() {
file = "../../tests/assets/partition_info.yaml"
partitionInfo, _, err = pi.NewPartitionInfoFromFile(file)
Expect(err).ToNot(HaveOccurred())
})
It("returns the correct label", func() {
uuid := partitionInfo.LookupLabelForUUID("some_uuid_1")
Expect(uuid).To(Equal("COS_PERSISTENT"))
})
It("returns an empty label when UUID doesn't exist", func() {
uuid := partitionInfo.LookupLabelForUUID("doesnt_exist")
Expect(uuid).To(Equal(""))
})
})
})

18
renovate.json Normal file
View File

@@ -0,0 +1,18 @@
{
"$schema": "https://docs.renovatebot.com/renovate-schema.json",
"extends": [
"config:base"
],
"schedule": [
"after 11pm every weekday",
"before 7am every weekday",
"every weekend"
],
"timezone": "Europe/Brussels",
"packageRules": [
{
"matchUpdateTypes": ["patch"],
"automerge": true
}
]
}

View File

@@ -1,2 +0,0 @@
COS_PERSISTENT: some_uuid_1
COS_OTHER: some_uuid_2