mirror of
https://github.com/kata-containers/kata-containers.git
synced 2026-03-05 20:32:19 +00:00
Compare commits
56 Commits
2.2.0-alph
...
2.1.1
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
0e2be438bd | ||
|
|
55dede1bce | ||
|
|
4d514ba1fb | ||
|
|
492729f443 | ||
|
|
645e950b8e | ||
|
|
db8d853b99 | ||
|
|
3fad527734 | ||
|
|
175970c93a | ||
|
|
6cea1b146c | ||
|
|
1cc2ad3f34 | ||
|
|
ac34f6dfd9 | ||
|
|
ff206cf6cf | ||
|
|
57f7ffbe39 | ||
|
|
915fea7b1f | ||
|
|
a05e137710 | ||
|
|
8019f7322d | ||
|
|
e48c9d426d | ||
|
|
6a7e6a8d0a | ||
|
|
7874ab33d4 | ||
|
|
536634e909 | ||
|
|
c51891fee7 | ||
|
|
b137c7ac33 | ||
|
|
a407e53b94 | ||
|
|
68a77a7dec | ||
|
|
169cf133c9 | ||
|
|
550269ff89 | ||
|
|
d6d16dc597 | ||
|
|
1ea0dc9804 | ||
|
|
0f82291926 | ||
|
|
5d3610e25f | ||
|
|
ed01ac3e0c | ||
|
|
9266c2460a | ||
|
|
7086f91e1f | ||
|
|
0a7befa645 | ||
|
|
eff70d2eea | ||
|
|
dd26aa5838 | ||
|
|
260f59df38 | ||
|
|
9a32a3e16d | ||
|
|
123f7d53cb | ||
|
|
aa213fdc28 | ||
|
|
c0bdba2350 | ||
|
|
1b3cf2fb7d | ||
|
|
59b9e5d0f8 | ||
|
|
828a304883 | ||
|
|
70734dfa17 | ||
|
|
f170df6201 | ||
|
|
d3690952e6 | ||
|
|
7f7c794da4 | ||
|
|
3f1b7c9127 | ||
|
|
68cad37720 | ||
|
|
7c9067cc9d | ||
|
|
dba86ef31a | ||
|
|
0e2df80bda | ||
|
|
8c4e187049 | ||
|
|
3bcdc26008 | ||
|
|
3212c7ae00 |
@@ -6,15 +6,15 @@
|
||||
name: Ensure PR has required porting labels
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
branches:
|
||||
- main
|
||||
pull_request_target:
|
||||
types:
|
||||
- opened
|
||||
- reopened
|
||||
- labeled
|
||||
- unlabeled
|
||||
pull_request:
|
||||
branches:
|
||||
- main
|
||||
|
||||
jobs:
|
||||
check-pr-porting-labels:
|
||||
|
||||
@@ -37,7 +37,6 @@
|
||||
- [Set up a debug console](#set-up-a-debug-console)
|
||||
- [Simple debug console setup](#simple-debug-console-setup)
|
||||
- [Enable agent debug console](#enable-agent-debug-console)
|
||||
- [Start `kata-monitor` - ONLY NEEDED FOR 2.0.x](#start-kata-monitor---only-needed-for-20x)
|
||||
- [Connect to debug console](#connect-to-debug-console)
|
||||
- [Traditional debug console setup](#traditional-debug-console-setup)
|
||||
- [Create a custom image containing a shell](#create-a-custom-image-containing-a-shell)
|
||||
@@ -305,7 +304,7 @@ You MUST choose one of `alpine`, `centos`, `clearlinux`, `debian`, `euleros`, `f
|
||||
> - You should only do this step if you are testing with the latest version of the agent.
|
||||
|
||||
```
|
||||
$ sudo install -o root -g root -m 0550 -t ${ROOTFS_DIR}/usr/bin ../../../src/agent/target/x86_64-unknown-linux-musl/release/kata-agent
|
||||
$ sudo install -o root -g root -m 0550 -t ${ROOTFS_DIR}/bin ../../../src/agent/target/x86_64-unknown-linux-musl/release/kata-agent
|
||||
$ sudo install -o root -g root -m 0440 ../../../src/agent/kata-agent.service ${ROOTFS_DIR}/usr/lib/systemd/system/
|
||||
$ sudo install -o root -g root -m 0440 ../../../src/agent/kata-containers.target ${ROOTFS_DIR}/usr/lib/systemd/system/
|
||||
```
|
||||
@@ -394,40 +393,14 @@ You may choose to manually build your VMM/hypervisor.
|
||||
Kata Containers makes use of upstream QEMU branch. The exact version
|
||||
and repository utilized can be found by looking at the [versions file](../versions.yaml).
|
||||
|
||||
Find the correct version of QEMU from the versions file:
|
||||
```
|
||||
$ source ${GOPATH}/src/github.com/kata-containers/kata-containers/tools/packaging/scripts/lib.sh
|
||||
$ qemu_version=$(get_from_kata_deps "assets.hypervisor.qemu.version")
|
||||
$ echo ${qemu_version}
|
||||
```
|
||||
Get source from the matching branch of QEMU:
|
||||
```
|
||||
$ go get -d github.com/qemu/qemu
|
||||
$ cd ${GOPATH}/src/github.com/qemu/qemu
|
||||
$ git checkout ${qemu_version}
|
||||
$ your_qemu_directory=${GOPATH}/src/github.com/qemu/qemu
|
||||
```
|
||||
|
||||
There are scripts to manage the build and packaging of QEMU. For the examples below, set your
|
||||
environment as:
|
||||
```
|
||||
$ go get -d github.com/kata-containers/kata-containers
|
||||
$ packaging_dir="${GOPATH}/src/github.com/kata-containers/kata-containers/tools/packaging"
|
||||
```
|
||||
|
||||
Kata often utilizes patches for not-yet-upstream and/or backported fixes for components,
|
||||
including QEMU. These can be found in the [packaging/QEMU directory](../tools/packaging/qemu/patches),
|
||||
and it's *recommended* that you apply them. For example, suppose that you are going to build QEMU
|
||||
version 5.2.0, do:
|
||||
```
|
||||
$ cd $your_qemu_directory
|
||||
$ $packaging_dir/scripts/apply_patches.sh $packaging_dir/qemu/patches/5.2.x/
|
||||
```
|
||||
Kata often utilizes patches for not-yet-upstream fixes for components,
|
||||
including QEMU. These can be found in the [packaging/QEMU directory](../tools/packaging/qemu/patches)
|
||||
|
||||
To build utilizing the same options as Kata, you should make use of the `configure-hypervisor.sh` script. For example:
|
||||
```
|
||||
$ go get -d github.com/kata-containers/kata-containers/tools/packaging
|
||||
$ cd $your_qemu_directory
|
||||
$ $packaging_dir/scripts/configure-hypervisor.sh kata-qemu > kata.cfg
|
||||
$ ${GOPATH}/src/github.com/kata-containers/kata-containers/tools/packaging/scripts/configure-hypervisor.sh kata-qemu > kata.cfg
|
||||
$ eval ./configure "$(cat kata.cfg)"
|
||||
$ make -j $(nproc)
|
||||
$ sudo -E make install
|
||||
@@ -502,16 +475,6 @@ debug_console_enabled = true
|
||||
|
||||
This will pass `agent.debug_console agent.debug_console_vport=1026` to agent as kernel parameters, and sandboxes created using this parameters will start a shell in guest if new connection is accept from VSOCK.
|
||||
|
||||
#### Start `kata-monitor` - ONLY NEEDED FOR 2.0.x
|
||||
|
||||
For Kata Containers `2.0.x` releases, the `kata-runtime exec` command depends on the`kata-monitor` running, in order to get the sandbox's `vsock` address to connect to. Thus, first start the `kata-monitor` process.
|
||||
|
||||
```
|
||||
$ sudo kata-monitor
|
||||
```
|
||||
|
||||
`kata-monitor` will serve at `localhost:8090` by default.
|
||||
|
||||
#### Connect to debug console
|
||||
|
||||
Command `kata-runtime exec` is used to connect to the debug console.
|
||||
|
||||
@@ -29,7 +29,6 @@
|
||||
|
||||
## Release Process
|
||||
|
||||
|
||||
### Bump all Kata repositories
|
||||
|
||||
Bump the repositories using a script in the Kata packaging repo, where:
|
||||
@@ -42,23 +41,6 @@
|
||||
$ ./update-repository-version.sh -p "$NEW_VERSION" "$BRANCH"
|
||||
```
|
||||
|
||||
### Point tests repository to stable branch
|
||||
|
||||
If you create a new stable branch, i.e. if your release changes a major or minor version number (not a patch release), then
|
||||
you should modify the `tests` repository to point to that newly created stable branch and not the `main` branch.
|
||||
The objective is that changes in the CI on the main branch will not impact the stable branch.
|
||||
|
||||
In the test directory, change references the main branch in:
|
||||
* `README.md`
|
||||
* `versions.yaml`
|
||||
* `cmd/github-labels/labels.yaml.in`
|
||||
* `cmd/pmemctl/pmemctl.sh`
|
||||
* `.ci/lib.sh`
|
||||
* `.ci/static-checks.sh`
|
||||
|
||||
See the commits in [the corresponding PR for stable-2.1](https://github.com/kata-containers/tests/pull/3504) for an example of the changes.
|
||||
|
||||
|
||||
### Merge all bump version Pull requests
|
||||
|
||||
- The above step will create a GitHub pull request in the Kata projects. Trigger the CI using `/test` command on each bump Pull request.
|
||||
@@ -68,7 +50,7 @@
|
||||
### Tag all Kata repositories
|
||||
|
||||
Once all the pull requests to bump versions in all Kata repositories are merged,
|
||||
tag all the repositories as shown below.
|
||||
tag all the repositories as shown below.
|
||||
```
|
||||
$ cd ${GOPATH}/src/github.com/kata-containers/kata-containers/tools/packaging/release
|
||||
$ git checkout <kata-branch-to-release>
|
||||
|
||||
@@ -32,16 +32,16 @@ provides additional information regarding release `99.123.77` in the previous ex
|
||||
changing the existing behavior*.
|
||||
|
||||
- When `MAJOR` increases, the new release adds **new features, bug fixes, or
|
||||
both** and which **changes the behavior from the previous release** (incompatible with previous releases).
|
||||
both** and which *changes the behavior from the previous release* (incompatible with previous releases).
|
||||
|
||||
A major release will also likely require a change of the container manager version used,
|
||||
for example Containerd or CRI-O. Please refer to the release notes for further details.
|
||||
for example Docker\*. Please refer to the release notes for further details.
|
||||
|
||||
## Release Strategy
|
||||
|
||||
Any new features added since the last release will be available in the next minor
|
||||
release. These will include bug fixes as well. To facilitate a stable user environment,
|
||||
Kata provides stable branch-based releases and a main branch release.
|
||||
Kata provides stable branch-based releases and a master branch release.
|
||||
|
||||
## Stable branch patch criteria
|
||||
|
||||
@@ -49,10 +49,9 @@ No new features should be introduced to stable branches. This is intended to li
|
||||
providing only bug and security fixes.
|
||||
|
||||
## Branch Management
|
||||
Kata Containers will maintain **one** stable release branch, in addition to the main branch, for
|
||||
each active major release.
|
||||
Once a new MAJOR or MINOR release is created from main, a new stable branch is created for
|
||||
the prior MAJOR or MINOR release and the previous stable branch is no longer maintained. End of
|
||||
Kata Containers will maintain two stable release branches in addition to the master branch.
|
||||
Once a new MAJOR or MINOR release is created from master, a new stable branch is created for
|
||||
the prior MAJOR or MINOR release and the older stable branch is no longer maintained. End of
|
||||
maintenance for a branch is announced on the Kata Containers mailing list. Users can determine
|
||||
the version currently installed by running `kata-runtime kata-env`. It is recommended to use the
|
||||
latest stable branch available.
|
||||
@@ -62,59 +61,59 @@ A couple of examples follow to help clarify this process.
|
||||
### New bug fix introduced
|
||||
|
||||
A bug fix is submitted against the runtime which does not introduce new inter-component dependencies.
|
||||
This fix is applied to both the main and stable branches, and there is no need to create a new
|
||||
This fix is applied to both the master and stable branches, and there is no need to create a new
|
||||
stable branch.
|
||||
|
||||
| Branch | Original version | New version |
|
||||
|--|--|--|
|
||||
| `main` | `2.3.0-rc0` | `2.3.0-rc1` |
|
||||
| `stable-2.2` | `2.2.0` | `2.2.1` |
|
||||
| `stable-2.1` | (unmaintained) | (unmaintained) |
|
||||
| `master` | `1.3.0-rc0` | `1.3.0-rc1` |
|
||||
| `stable-1.2` | `1.2.0` | `1.2.1` |
|
||||
| `stable-1.1` | `1.1.2` | `1.1.3` |
|
||||
|
||||
|
||||
### New release made feature or change adding new inter-component dependency
|
||||
|
||||
A new feature is introduced, which adds a new inter-component dependency. In this case a new stable
|
||||
branch is created (stable-2.3) starting from main and the previous stable branch (stable-2.2)
|
||||
branch is created (stable-1.3) starting from master and the older stable branch (stable-1.1)
|
||||
is dropped from maintenance.
|
||||
|
||||
|
||||
| Branch | Original version | New version |
|
||||
|--|--|--|
|
||||
| `main` | `2.3.0-rc1` | `2.3.0` |
|
||||
| `stable-2.3` | N/A| `2.3.0` |
|
||||
| `stable-2.2` | `2.2.1` | (unmaintained) |
|
||||
| `stable-2.1` | (unmaintained) | (unmaintained) |
|
||||
| `master` | `1.3.0-rc1` | `1.3.0` |
|
||||
| `stable-1.3` | N/A| `1.3.0` |
|
||||
| `stable-1.2` | `1.2.1` | `1.2.2` |
|
||||
| `stable-1.1` | `1.1.3` | (unmaintained) |
|
||||
|
||||
Note, the stable-2.2 branch will still exist with tag 2.2.1, but under current plans it is
|
||||
not maintained further. The next tag applied to main will be 2.4.0-alpha0. We would then
|
||||
Note, the stable-1.1 branch will still exist with tag 1.1.3, but under current plans it is
|
||||
not maintained further. The next tag applied to master will be 1.4.0-alpha0. We would then
|
||||
create a couple of alpha releases gathering features targeted for that particular release (in
|
||||
this case 2.4.0), followed by a release candidate. The release candidate marks a feature freeze.
|
||||
this case 1.4.0), followed by a release candidate. The release candidate marks a feature freeze.
|
||||
A new stable branch is created for the release candidate. Only bug fixes and any security issues
|
||||
are added to the branch going forward until release 2.4.0 is made.
|
||||
are added to the branch going forward until release 1.4.0 is made.
|
||||
|
||||
## Backporting Process
|
||||
|
||||
Development that occurs against the main branch and applicable code commits should also be submitted
|
||||
Development that occurs against the master branch and applicable code commits should also be submitted
|
||||
against the stable branches. Some guidelines for this process follow::
|
||||
1. Only bug and security fixes which do not introduce inter-component dependencies are
|
||||
candidates for stable branches. These PRs should be marked with "bug" in GitHub.
|
||||
2. Once a PR is created against main which meets requirement of (1), a comparable one
|
||||
2. Once a PR is created against master which meets requirement of (1), a comparable one
|
||||
should also be submitted against the stable branches. It is the responsibility of the submitter
|
||||
to apply their pull request against stable, and it is the responsibility of the
|
||||
reviewers to help identify stable-candidate pull requests.
|
||||
|
||||
## Continuous Integration Testing
|
||||
|
||||
The test repository is forked to create stable branches from main. Full CI
|
||||
runs on each stable and main PR using its respective tests repository branch.
|
||||
The test repository is forked to create stable branches from master. Full CI
|
||||
runs on each stable and master PR using its respective tests repository branch.
|
||||
|
||||
### An alternative method for CI testing:
|
||||
|
||||
Ideally, the continuous integration infrastructure will run the same test suite on both main
|
||||
Ideally, the continuous integration infrastructure will run the same test suite on both master
|
||||
and the stable branches. When tests are modified or new feature tests are introduced, explicit
|
||||
logic should exist within the testing CI to make sure only applicable tests are executed against
|
||||
stable and main. While this is not in place currently, it should be considered in the long term.
|
||||
stable and master. While this is not in place currently, it should be considered in the long term.
|
||||
|
||||
## Release Management
|
||||
|
||||
@@ -122,7 +121,7 @@ stable and main. While this is not in place currently, it should be considered i
|
||||
|
||||
Releases are made every three weeks, which include a GitHub release as
|
||||
well as binary packages. These patch releases are made for both stable branches, and a "release candidate"
|
||||
for the next `MAJOR` or `MINOR` is created from main. If there are no changes across all the repositories, no
|
||||
for the next `MAJOR` or `MINOR` is created from master. If there are no changes across all the repositories, no
|
||||
release is created and an announcement is made on the developer mailing list to highlight this.
|
||||
If a release is being made, each repository is tagged for this release, regardless
|
||||
of whether changes are introduced. The release schedule can be seen on the
|
||||
@@ -143,10 +142,10 @@ maturity, we have increased the cadence from six weeks to twelve weeks. The rele
|
||||
### Compatibility
|
||||
Kata guarantees compatibility between components that are within one minor release of each other.
|
||||
|
||||
This is critical for dependencies which cross between host (shimv2 runtime) and
|
||||
This is critical for dependencies which cross between host (runtime, shim, proxy) and
|
||||
the guest (hypervisor, rootfs and agent). For example, consider a cluster with a long-running
|
||||
deployment, workload-never-dies, all on Kata version 2.1.3 components. If the operator updates
|
||||
the Kata components to the next new minor release (i.e. 2.2.0), we need to guarantee that the 2.2.0
|
||||
shimv2 runtime still communicates with 2.1.3 agent within workload-never-dies.
|
||||
deployment, workload-never-dies, all on Kata version 1.1.3 components. If the operator updates
|
||||
the Kata components to the next new minor release (i.e. 1.2.0), we need to guarantee that the 1.2.0
|
||||
runtime still communicates with 1.1.3 agent within workload-never-dies.
|
||||
|
||||
Handling live-update is out of the scope of this document. See this [`kata-runtime` issue](https://github.com/kata-containers/runtime/issues/492) for details.
|
||||
|
||||
@@ -37,4 +37,3 @@
|
||||
- [How to use Kata Containers with `virtio-mem`](how-to-use-virtio-mem-with-kata.md)
|
||||
- [How to set sandbox Kata Containers configurations with pod annotations](how-to-set-sandbox-config-kata.md)
|
||||
- [How to monitor Kata Containers in K8s](how-to-set-prometheus-in-k8s.md)
|
||||
- [How to use hotplug memory on arm64 in Kata Containers](how-to-hotplug-memory-arm64.md)
|
||||
|
||||
@@ -1,32 +0,0 @@
|
||||
# How to use memory hotplug feature in Kata Containers on arm64
|
||||
|
||||
- [Introduction](#introduction)
|
||||
- [Install UEFI ROM](#install-uefi-rom)
|
||||
- [Run for test](#run-for-test)
|
||||
|
||||
## Introduction
|
||||
|
||||
Memory hotplug is a key feature for containers to allocate memory dynamically in deployment.
|
||||
As Kata Container bases on VM, this feature needs support both from VMM and guest kernel. Luckily, it has been fully supported for the current default version of QEMU and guest kernel used by Kata on arm64. For other VMMs, e.g, Cloud Hypervisor, the enablement work is on the road. Apart from VMM and guest kernel, memory hotplug also depends on ACPI which depends on firmware either. On x86, you can boot a VM using QEMU with ACPI enabled directly, because it boots up with firmware implicitly. For arm64, however, you need specify firmware explicitly. That is to say, if you are ready to run a normal Kata Container on arm64, what you need extra to do is to install the UEFI ROM before use the memory hotplug feature.
|
||||
|
||||
## Install UEFI ROM
|
||||
|
||||
We have offered a helper script for you to install the UEFI ROM. If you have installed Kata normally on your host, you just need to run the script as fellows:
|
||||
|
||||
```bash
|
||||
$ pushd $GOPATH/src/github.com/kata-containers/tests
|
||||
$ sudo .ci/aarch64/install_rom_aarch64.sh
|
||||
$ popd
|
||||
```
|
||||
|
||||
## Run for test
|
||||
|
||||
Let's test if the memory hotplug is ready for Kata after install the UEFI ROM. Make sure containerd is ready to run Kata before test.
|
||||
|
||||
```bash
|
||||
$ sudo ctr image pull docker.io/library/ubuntu:latest
|
||||
$ sudo ctr run --runtime io.containerd.run.kata.v2 -t --rm docker.io/library/ubuntu:latest hello sh -c "free -h"
|
||||
$ sudo ctr run --runtime io.containerd.run.kata.v2 -t --memory-limit 536870912 --rm docker.io/library/ubuntu:latest hello sh -c "free -h"
|
||||
```
|
||||
|
||||
Compare the results between the two tests. If the latter is 0.5G larger than the former, you have done what you want, and congratulation!
|
||||
@@ -171,10 +171,10 @@ $ sudo systemctl daemon-reload
|
||||
$ sudo systemctl restart kubelet
|
||||
|
||||
# If using CRI-O
|
||||
$ sudo kubeadm init --ignore-preflight-errors=all --cri-socket /var/run/crio/crio.sock --pod-network-cidr=10.244.0.0/16
|
||||
$ sudo kubeadm init --skip-preflight-checks --cri-socket /var/run/crio/crio.sock --pod-network-cidr=10.244.0.0/16
|
||||
|
||||
# If using CRI-containerd
|
||||
$ sudo kubeadm init --ignore-preflight-errors=all --cri-socket /run/containerd/containerd.sock --pod-network-cidr=10.244.0.0/16
|
||||
$ sudo kubeadm init --skip-preflight-checks --cri-socket /run/containerd/containerd.sock --pod-network-cidr=10.244.0.0/16
|
||||
|
||||
$ export KUBECONFIG=/etc/kubernetes/admin.conf
|
||||
```
|
||||
|
||||
734
src/agent/Cargo.lock
generated
734
src/agent/Cargo.lock
generated
File diff suppressed because it is too large
Load Diff
@@ -13,8 +13,8 @@ lazy_static = "1.3.0"
|
||||
ttrpc = { version = "0.5.0", features = ["async", "protobuf-codec"], default-features = false }
|
||||
protobuf = "=2.14.0"
|
||||
libc = "0.2.58"
|
||||
nix = "0.21.0"
|
||||
capctl = "0.2.0"
|
||||
nix = "0.17.0"
|
||||
prctl = "1.0.0"
|
||||
serde_json = "1.0.39"
|
||||
scan_fmt = "0.2.3"
|
||||
scopeguard = "1.0.0"
|
||||
@@ -43,21 +43,13 @@ slog-scope = "4.1.2"
|
||||
slog-stdlog = "4.0.0"
|
||||
log = "0.4.11"
|
||||
|
||||
# for testing
|
||||
tempfile = "3.1.0"
|
||||
prometheus = { version = "0.9.0", features = ["process"] }
|
||||
procfs = "0.7.9"
|
||||
anyhow = "1.0.32"
|
||||
cgroups = { package = "cgroups-rs", version = "0.2.5" }
|
||||
|
||||
# Tracing
|
||||
tracing = "0.1.26"
|
||||
tracing-subscriber = "0.2.18"
|
||||
tracing-opentelemetry = "0.13.0"
|
||||
opentelemetry = "0.14.0"
|
||||
vsock-exporter = { path = "vsock-exporter" }
|
||||
|
||||
[dev-dependencies]
|
||||
tempfile = "3.1.0"
|
||||
|
||||
[workspace]
|
||||
members = [
|
||||
"oci",
|
||||
|
||||
@@ -11,9 +11,9 @@ serde_derive = "1.0.91"
|
||||
oci = { path = "../oci" }
|
||||
protocols = { path ="../protocols" }
|
||||
caps = "0.5.0"
|
||||
nix = "0.21.0"
|
||||
nix = "0.17.0"
|
||||
scopeguard = "1.0.0"
|
||||
capctl = "0.2.0"
|
||||
prctl = "1.0.0"
|
||||
lazy_static = "1.3.0"
|
||||
libc = "0.2.58"
|
||||
protobuf = "=2.14.0"
|
||||
@@ -24,6 +24,7 @@ regex = "1.1"
|
||||
path-absolutize = "1.2.0"
|
||||
anyhow = "1.0.32"
|
||||
cgroups = { package = "cgroups-rs", version = "0.2.5" }
|
||||
tempfile = "3.1.0"
|
||||
rlimit = "0.5.3"
|
||||
|
||||
tokio = { version = "1.2.0", features = ["sync", "io-util", "process", "time", "macros"] }
|
||||
@@ -33,4 +34,3 @@ inotify = "0.9.2"
|
||||
|
||||
[dev-dependencies]
|
||||
serial_test = "0.5.0"
|
||||
tempfile = "3.1.0"
|
||||
|
||||
56
src/agent/rustjail/src/configs/device.rs
Normal file
56
src/agent/rustjail/src/configs/device.rs
Normal file
@@ -0,0 +1,56 @@
|
||||
// Copyright (c) 2019 Ant Financial
|
||||
//
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
//
|
||||
|
||||
use libc::*;
|
||||
use serde;
|
||||
#[macro_use]
|
||||
use serde_derive;
|
||||
use serde_json;
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug)]
|
||||
pub struct Device {
|
||||
#[serde(default)]
|
||||
r#type: char,
|
||||
#[serde(default)]
|
||||
path: String,
|
||||
#[serde(default)]
|
||||
major: i64,
|
||||
#[serde(default)]
|
||||
minor: i64,
|
||||
#[serde(default)]
|
||||
permissions: String,
|
||||
#[serde(default)]
|
||||
file_mode: mode_t,
|
||||
#[serde(default)]
|
||||
uid: i32,
|
||||
#[serde(default)]
|
||||
gid: i32,
|
||||
#[serde(default)]
|
||||
allow: bool,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug)]
|
||||
pub struct BlockIODevice {
|
||||
#[serde(default)]
|
||||
major: i64,
|
||||
#[serde(default)]
|
||||
minor: i64,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug)]
|
||||
pub struct WeightDevice {
|
||||
block: BlockIODevice,
|
||||
#[serde(default)]
|
||||
weight: u16,
|
||||
#[serde(default, rename = "leafWeight")]
|
||||
leaf_weight: u16,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug)]
|
||||
pub struct ThrottleDevice {
|
||||
block: BlockIODevice,
|
||||
#[serde(default)]
|
||||
rate: u64,
|
||||
}
|
||||
372
src/agent/rustjail/src/configs/mod.rs
Normal file
372
src/agent/rustjail/src/configs/mod.rs
Normal file
@@ -0,0 +1,372 @@
|
||||
// Copyright (c) 2019 Ant Financial
|
||||
//
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
//
|
||||
|
||||
use serde;
|
||||
#[macro_use]
|
||||
use serde_derive;
|
||||
use serde_json;
|
||||
|
||||
use protocols::oci::State as OCIState;
|
||||
|
||||
use std::collections::HashMap;
|
||||
use std::fmt;
|
||||
use std::path::PathBuf;
|
||||
use std::time::Duration;
|
||||
|
||||
use nix::unistd;
|
||||
|
||||
use self::device::{Device, ThrottleDevice, WeightDevice};
|
||||
use self::namespaces::Namespaces;
|
||||
use crate::specconv::CreateOpts;
|
||||
|
||||
pub mod device;
|
||||
pub mod namespaces;
|
||||
pub mod validator;
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug)]
|
||||
pub struct Rlimit {
|
||||
#[serde(default)]
|
||||
r#type: i32,
|
||||
#[serde(default)]
|
||||
hard: i32,
|
||||
#[serde(default)]
|
||||
soft: i32,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug)]
|
||||
pub struct IDMap {
|
||||
#[serde(default)]
|
||||
container_id: i32,
|
||||
#[serde(default)]
|
||||
host_id: i32,
|
||||
#[serde(default)]
|
||||
size: i32,
|
||||
}
|
||||
|
||||
type Action = i32;
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug)]
|
||||
pub struct Seccomp {
|
||||
#[serde(default)]
|
||||
default_action: Action,
|
||||
#[serde(default)]
|
||||
architectures: Vec<String>,
|
||||
#[serde(default)]
|
||||
flags: Vec<String>,
|
||||
#[serde(default)]
|
||||
syscalls: Vec<Syscall>,
|
||||
}
|
||||
|
||||
type Operator = i32;
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug)]
|
||||
pub struct Arg {
|
||||
#[serde(default)]
|
||||
index: u32,
|
||||
#[serde(default)]
|
||||
value: u64,
|
||||
#[serde(default)]
|
||||
value_two: u64,
|
||||
#[serde(default)]
|
||||
op: Operator,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug)]
|
||||
pub struct Syscall {
|
||||
#[serde(default, skip_serializing_if = "String::is_empty")]
|
||||
names: String,
|
||||
#[serde(default)]
|
||||
action: Action,
|
||||
#[serde(default, rename = "errnoRet")]
|
||||
errno_ret: u32,
|
||||
#[serde(default, skip_serializing_if = "Vec::is_empty")]
|
||||
args: Vec<Arg>,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug)]
|
||||
pub struct Config<'a> {
|
||||
#[serde(default)]
|
||||
no_pivot_root: bool,
|
||||
#[serde(default)]
|
||||
parent_death_signal: i32,
|
||||
#[serde(default)]
|
||||
rootfs: String,
|
||||
#[serde(default)]
|
||||
readonlyfs: bool,
|
||||
#[serde(default, rename = "rootPropagation")]
|
||||
root_propagation: i32,
|
||||
#[serde(default)]
|
||||
mounts: Vec<Mount>,
|
||||
#[serde(default)]
|
||||
devices: Vec<Device>,
|
||||
#[serde(default)]
|
||||
mount_label: String,
|
||||
#[serde(default)]
|
||||
hostname: String,
|
||||
#[serde(default)]
|
||||
namespaces: Namespaces,
|
||||
#[serde(default)]
|
||||
capabilities: Option<Capabilities>,
|
||||
#[serde(default)]
|
||||
networks: Vec<Network>,
|
||||
#[serde(default)]
|
||||
routes: Vec<Route>,
|
||||
#[serde(default)]
|
||||
cgroups: Option<Cgroup<'a>>,
|
||||
#[serde(default, skip_serializing_if = "String::is_empty")]
|
||||
apparmor_profile: String,
|
||||
#[serde(default, skip_serializing_if = "String::is_empty")]
|
||||
process_label: String,
|
||||
#[serde(default, skip_serializing_if = "Vec::is_empty")]
|
||||
rlimits: Vec<Rlimit>,
|
||||
#[serde(default)]
|
||||
oom_score_adj: Option<i32>,
|
||||
#[serde(default)]
|
||||
uid_mappings: Vec<IDMap>,
|
||||
#[serde(default)]
|
||||
gid_mappings: Vec<IDMap>,
|
||||
#[serde(default)]
|
||||
mask_paths: Vec<String>,
|
||||
#[serde(default)]
|
||||
readonly_paths: Vec<String>,
|
||||
#[serde(default)]
|
||||
sysctl: HashMap<String, String>,
|
||||
#[serde(default)]
|
||||
seccomp: Option<Seccomp>,
|
||||
#[serde(default)]
|
||||
no_new_privileges: bool,
|
||||
hooks: Option<Hooks>,
|
||||
#[serde(default)]
|
||||
version: String,
|
||||
#[serde(default)]
|
||||
labels: Vec<String>,
|
||||
#[serde(default)]
|
||||
no_new_keyring: bool,
|
||||
#[serde(default)]
|
||||
intel_rdt: Option<IntelRdt>,
|
||||
#[serde(default)]
|
||||
rootless_euid: bool,
|
||||
#[serde(default)]
|
||||
rootless_cgroups: bool,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug)]
|
||||
pub struct Hooks {
|
||||
prestart: Vec<Box<Hook>>,
|
||||
poststart: Vec<Box<Hook>>,
|
||||
poststop: Vec<Box<Hook>>,
|
||||
}
|
||||
#[derive(Serialize, Deserialize, Debug)]
|
||||
pub struct Capabilities {
|
||||
bounding: Vec<String>,
|
||||
effective: Vec<String>,
|
||||
inheritable: Vec<String>,
|
||||
permitted: Vec<String>,
|
||||
ambient: Vec<String>,
|
||||
}
|
||||
|
||||
pub trait Hook {
|
||||
fn run(&self, state: &OCIState) -> Result<()>;
|
||||
}
|
||||
|
||||
pub struct FuncHook {
|
||||
// run: fn(&OCIState) -> Result<()>,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug)]
|
||||
pub struct Command {
|
||||
#[serde(default)]
|
||||
path: String,
|
||||
#[serde(default)]
|
||||
args: Vec<String>,
|
||||
#[serde(default)]
|
||||
env: Vec<String>,
|
||||
#[serde(default)]
|
||||
dir: String,
|
||||
#[serde(default)]
|
||||
timeout: Duration,
|
||||
}
|
||||
|
||||
pub struct CommandHook {
|
||||
command: Command,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug)]
|
||||
pub struct Mount {
|
||||
#[serde(default)]
|
||||
source: String,
|
||||
#[serde(default)]
|
||||
destination: String,
|
||||
#[serde(default)]
|
||||
device: String,
|
||||
#[serde(default)]
|
||||
flags: i32,
|
||||
#[serde(default)]
|
||||
propagation_flags: Vec<i32>,
|
||||
#[serde(default)]
|
||||
data: String,
|
||||
#[serde(default)]
|
||||
relabel: String,
|
||||
#[serde(default)]
|
||||
extensions: i32,
|
||||
#[serde(default)]
|
||||
premount_cmds: Vec<Command>,
|
||||
#[serde(default)]
|
||||
postmount_cmds: Vec<Command>,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug)]
|
||||
pub struct HugepageLimit {
|
||||
#[serde(default)]
|
||||
page_size: String,
|
||||
#[serde(default)]
|
||||
limit: u64,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug)]
|
||||
pub struct IntelRdt {
|
||||
#[serde(default, skip_serializing_if = "String::is_empty")]
|
||||
l3_cache_schema: String,
|
||||
#[serde(
|
||||
default,
|
||||
rename = "memBwSchema",
|
||||
skip_serializing_if = "String::is_empty"
|
||||
)]
|
||||
mem_bw_schema: String,
|
||||
}
|
||||
|
||||
pub type FreezerState = String;
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug)]
|
||||
pub struct Cgroup<'a> {
|
||||
#[serde(default, skip_serializing_if = "String::is_empty")]
|
||||
name: String,
|
||||
#[serde(default, skip_serializing_if = "String::is_empty")]
|
||||
parent: String,
|
||||
#[serde(default)]
|
||||
path: String,
|
||||
#[serde(default)]
|
||||
scope_prefix: String,
|
||||
paths: HashMap<String, String>,
|
||||
resource: &'a Resources<'a>,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug)]
|
||||
pub struct Resources<'a> {
|
||||
#[serde(default)]
|
||||
allow_all_devices: bool,
|
||||
#[serde(default, skip_serializing_if = "Vec::is_empty")]
|
||||
allowed_devices: Vec<&'a Device>,
|
||||
#[serde(default, skip_serializing_if = "Vec::is_empty")]
|
||||
denied_devices: Vec<&'a Device>,
|
||||
#[serde(default)]
|
||||
devices: Vec<&'a Device>,
|
||||
#[serde(default)]
|
||||
memory: i64,
|
||||
#[serde(default)]
|
||||
memory_reservation: i64,
|
||||
#[serde(default)]
|
||||
memory_swap: i64,
|
||||
#[serde(default)]
|
||||
kernel_memory: i64,
|
||||
#[serde(default)]
|
||||
kernel_memory_tcp: i64,
|
||||
#[serde(default)]
|
||||
cpu_shares: u64,
|
||||
#[serde(default)]
|
||||
cpu_quota: i64,
|
||||
#[serde(default)]
|
||||
cpu_period: u64,
|
||||
#[serde(default)]
|
||||
cpu_rt_quota: i64,
|
||||
#[serde(default)]
|
||||
cpu_rt_period: u64,
|
||||
#[serde(default)]
|
||||
cpuset_cpus: String,
|
||||
#[serde(default)]
|
||||
cpuset_mems: String,
|
||||
#[serde(default)]
|
||||
pids_limit: i64,
|
||||
#[serde(default)]
|
||||
blkio_weight: u64,
|
||||
#[serde(default)]
|
||||
blkio_leaf_weight: u64,
|
||||
#[serde(default)]
|
||||
blkio_weight_device: Vec<&'a WeightDevice>,
|
||||
#[serde(default)]
|
||||
blkio_throttle_read_bps_device: Vec<&'a ThrottleDevice>,
|
||||
#[serde(default)]
|
||||
blkio_throttle_write_bps_device: Vec<&'a ThrottleDevice>,
|
||||
#[serde(default)]
|
||||
blkio_throttle_read_iops_device: Vec<&'a ThrottleDevice>,
|
||||
#[serde(default)]
|
||||
blkio_throttle_write_iops_device: Vec<&'a ThrottleDevice>,
|
||||
#[serde(default)]
|
||||
freezer: FreezerState,
|
||||
#[serde(default)]
|
||||
hugetlb_limit: Vec<&'a HugepageLimit>,
|
||||
#[serde(default)]
|
||||
oom_kill_disable: bool,
|
||||
#[serde(default)]
|
||||
memory_swapiness: u64,
|
||||
#[serde(default)]
|
||||
net_prio_ifpriomap: Vec<&'a IfPrioMap>,
|
||||
#[serde(default)]
|
||||
net_cls_classid_u: u32,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug)]
|
||||
pub struct Network {
|
||||
#[serde(default)]
|
||||
r#type: String,
|
||||
#[serde(default)]
|
||||
name: String,
|
||||
#[serde(default)]
|
||||
bridge: String,
|
||||
#[serde(default)]
|
||||
mac_address: String,
|
||||
#[serde(default)]
|
||||
address: String,
|
||||
#[serde(default)]
|
||||
gateway: String,
|
||||
#[serde(default)]
|
||||
ipv6_address: String,
|
||||
#[serde(default)]
|
||||
ipv6_gateway: String,
|
||||
#[serde(default)]
|
||||
mtu: i32,
|
||||
#[serde(default)]
|
||||
txqueuelen: i32,
|
||||
#[serde(default)]
|
||||
host_interface_name: String,
|
||||
#[serde(default)]
|
||||
hairpin_mode: bool,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug)]
|
||||
pub struct Route {
|
||||
#[serde(default)]
|
||||
destination: String,
|
||||
#[serde(default)]
|
||||
source: String,
|
||||
#[serde(default)]
|
||||
gateway: String,
|
||||
#[serde(default)]
|
||||
interface_name: String,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug)]
|
||||
pub struct IfPrioMap {
|
||||
#[serde(default)]
|
||||
interface: String,
|
||||
#[serde(default)]
|
||||
priority: i32,
|
||||
}
|
||||
|
||||
impl IfPrioMap {
|
||||
fn cgroup_string(&self) -> String {
|
||||
format!("{} {}", self.interface, self.priority)
|
||||
}
|
||||
}
|
||||
46
src/agent/rustjail/src/configs/namespaces.rs
Normal file
46
src/agent/rustjail/src/configs/namespaces.rs
Normal file
@@ -0,0 +1,46 @@
|
||||
// Copyright (c) 2019 Ant Financial
|
||||
//
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
//
|
||||
|
||||
use serde;
|
||||
#[macro_use]
|
||||
use serde_derive;
|
||||
use serde_json;
|
||||
|
||||
use std::collections::HashMap;
|
||||
#[macro_use]
|
||||
use lazy_static;
|
||||
|
||||
pub type NamespaceType = String;
|
||||
pub type Namespaces = Vec<Namespace>;
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug)]
|
||||
pub struct Namespace {
|
||||
#[serde(default)]
|
||||
r#type: NamespaceType,
|
||||
#[serde(default)]
|
||||
path: String,
|
||||
}
|
||||
|
||||
pub const NEWNET: &'static str = "NEWNET";
|
||||
pub const NEWPID: &'static str = "NEWPID";
|
||||
pub const NEWNS: &'static str = "NEWNS";
|
||||
pub const NEWUTS: &'static str = "NEWUTS";
|
||||
pub const NEWUSER: &'static str = "NEWUSER";
|
||||
pub const NEWCGROUP: &'static str = "NEWCGROUP";
|
||||
pub const NEWIPC: &'static str = "NEWIPC";
|
||||
|
||||
lazy_static! {
|
||||
static ref TYPETONAME: HashMap<&'static str, &'static str> = {
|
||||
let mut m = HashMap::new();
|
||||
m.insert("pid", "pid");
|
||||
m.insert("network", "net");
|
||||
m.insert("mount", "mnt");
|
||||
m.insert("user", "user");
|
||||
m.insert("uts", "uts");
|
||||
m.insert("ipc", "ipc");
|
||||
m.insert("cgroup", "cgroup");
|
||||
m
|
||||
};
|
||||
}
|
||||
23
src/agent/rustjail/src/configs/validator.rs
Normal file
23
src/agent/rustjail/src/configs/validator.rs
Normal file
@@ -0,0 +1,23 @@
|
||||
// Copyright (c) 2019 Ant Financial
|
||||
//
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
//
|
||||
|
||||
use crate::configs::Config;
|
||||
use std::io::Result;
|
||||
|
||||
pub trait Validator {
|
||||
fn validate(&self, config: &Config) -> Result<()> {
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
pub struct ConfigValidator {}
|
||||
|
||||
impl Validator for ConfigValidator {}
|
||||
|
||||
impl ConfigValidator {
|
||||
fn new() -> Self {
|
||||
ConfigValidator {}
|
||||
}
|
||||
}
|
||||
@@ -8,7 +8,7 @@ use libc::pid_t;
|
||||
use oci::{ContainerState, LinuxDevice, LinuxIdMapping};
|
||||
use oci::{Hook, Linux, LinuxNamespace, LinuxResources, Spec};
|
||||
use std::clone::Clone;
|
||||
use std::ffi::CString;
|
||||
use std::ffi::{CStr, CString};
|
||||
use std::fmt::Display;
|
||||
use std::fs;
|
||||
use std::os::unix::io::RawFd;
|
||||
@@ -346,7 +346,7 @@ fn do_init_child(cwfd: RawFd) -> Result<()> {
|
||||
Err(_e) => sched::unshare(CloneFlags::CLONE_NEWPID)?,
|
||||
}
|
||||
|
||||
match unsafe { fork() } {
|
||||
match fork() {
|
||||
Ok(ForkResult::Parent { child, .. }) => {
|
||||
log_child!(
|
||||
cfd_log,
|
||||
@@ -469,7 +469,7 @@ fn do_init_child(cwfd: RawFd) -> Result<()> {
|
||||
// Ref: https://github.com/opencontainers/runc/commit/50a19c6ff828c58e5dab13830bd3dacde268afe5
|
||||
//
|
||||
if !nses.is_empty() {
|
||||
capctl::prctl::set_dumpable(false)
|
||||
prctl::set_dumpable(false)
|
||||
.map_err(|e| anyhow!(e).context("set process non-dumpable failed"))?;
|
||||
}
|
||||
|
||||
@@ -545,7 +545,7 @@ fn do_init_child(cwfd: RawFd) -> Result<()> {
|
||||
// notify parent to run prestart hooks
|
||||
write_sync(cwfd, SYNC_SUCCESS, "")?;
|
||||
// wait parent run prestart hooks
|
||||
read_sync(crfd)?;
|
||||
let _ = read_sync(crfd)?;
|
||||
}
|
||||
|
||||
if mount_fd != -1 {
|
||||
@@ -602,7 +602,7 @@ fn do_init_child(cwfd: RawFd) -> Result<()> {
|
||||
|
||||
// NoNewPeiviledges, Drop capabilities
|
||||
if oci_process.no_new_privileges {
|
||||
capctl::prctl::set_no_new_privs().map_err(|_| anyhow!("cannot set no new privileges"))?;
|
||||
prctl::set_no_new_privileges(true).map_err(|_| anyhow!("cannot set no new privileges"))?;
|
||||
}
|
||||
|
||||
if oci_process.capabilities.is_some() {
|
||||
@@ -612,6 +612,8 @@ fn do_init_child(cwfd: RawFd) -> Result<()> {
|
||||
|
||||
if init {
|
||||
// notify parent to run poststart hooks
|
||||
// cfd is closed when return from join_namespaces
|
||||
// should retunr cfile instead of cfd?
|
||||
write_sync(cwfd, SYNC_SUCCESS, "")?;
|
||||
}
|
||||
|
||||
@@ -1079,8 +1081,9 @@ fn do_exec(args: &[String]) -> ! {
|
||||
.iter()
|
||||
.map(|s| CString::new(s.to_string()).unwrap_or_default())
|
||||
.collect();
|
||||
let a: Vec<&CStr> = sa.iter().map(|s| s.as_c_str()).collect();
|
||||
|
||||
let _ = unistd::execvp(p.as_c_str(), &sa).map_err(|e| match e {
|
||||
let _ = unistd::execvp(p.as_c_str(), a.as_slice()).map_err(|e| match e {
|
||||
nix::Error::Sys(errno) => {
|
||||
std::process::exit(errno as i32);
|
||||
}
|
||||
@@ -1253,7 +1256,7 @@ async fn join_namespaces(
|
||||
|
||||
if p.init {
|
||||
info!(logger, "notify child parent ready to run prestart hook!");
|
||||
read_async(pipe_r).await?;
|
||||
let _ = read_async(pipe_r).await?;
|
||||
|
||||
info!(logger, "get ready to run prestart hook!");
|
||||
|
||||
@@ -1313,7 +1316,7 @@ fn write_mappings(logger: &Logger, path: &str, maps: &[LinuxIdMapping]) -> Resul
|
||||
|
||||
fn setid(uid: Uid, gid: Gid) -> Result<()> {
|
||||
// set uid/gid
|
||||
capctl::prctl::set_keepcaps(true)
|
||||
prctl::set_keep_capabilities(true)
|
||||
.map_err(|e| anyhow!(e).context("set keep capabilities returned"))?;
|
||||
|
||||
{
|
||||
@@ -1327,7 +1330,7 @@ fn setid(uid: Uid, gid: Gid) -> Result<()> {
|
||||
capabilities::reset_effective()?;
|
||||
}
|
||||
|
||||
capctl::prctl::set_keepcaps(false)
|
||||
prctl::set_keep_capabilities(false)
|
||||
.map_err(|e| anyhow!(e).context("set keep capabilities returned"))?;
|
||||
|
||||
Ok(())
|
||||
|
||||
@@ -23,7 +23,7 @@ extern crate caps;
|
||||
extern crate protocols;
|
||||
#[macro_use]
|
||||
extern crate scopeguard;
|
||||
extern crate capctl;
|
||||
extern crate prctl;
|
||||
#[macro_use]
|
||||
extern crate lazy_static;
|
||||
extern crate libc;
|
||||
@@ -47,6 +47,16 @@ pub mod sync;
|
||||
pub mod sync_with_async;
|
||||
pub mod utils;
|
||||
pub mod validator;
|
||||
// pub mod factory;
|
||||
//pub mod configs;
|
||||
// pub mod devices;
|
||||
// pub mod init;
|
||||
// pub mod rootfs;
|
||||
// pub mod capabilities;
|
||||
// pub mod console;
|
||||
// pub mod stats;
|
||||
// pub mod user;
|
||||
//pub mod intelrdt;
|
||||
|
||||
use std::collections::HashMap;
|
||||
|
||||
|
||||
@@ -28,6 +28,16 @@ fn contain_namespace(nses: &[LinuxNamespace], key: &str) -> bool {
|
||||
false
|
||||
}
|
||||
|
||||
fn get_namespace_path(nses: &[LinuxNamespace], key: &str) -> Result<String> {
|
||||
for ns in nses {
|
||||
if ns.r#type.as_str() == key {
|
||||
return Ok(ns.path.clone());
|
||||
}
|
||||
}
|
||||
|
||||
Err(einval())
|
||||
}
|
||||
|
||||
fn rootfs(root: &str) -> Result<()> {
|
||||
let path = PathBuf::from(root);
|
||||
// not absolute path or not exists
|
||||
@@ -156,6 +166,31 @@ lazy_static! {
|
||||
};
|
||||
}
|
||||
|
||||
fn check_host_ns(path: &str) -> Result<()> {
|
||||
let cpath = PathBuf::from(path);
|
||||
let hpath = PathBuf::from("/proc/self/ns/net");
|
||||
|
||||
let real_hpath = hpath
|
||||
.read_link()
|
||||
.context(format!("read link {:?}", hpath))?;
|
||||
let meta = cpath
|
||||
.symlink_metadata()
|
||||
.context(format!("symlink metadata {:?}", cpath))?;
|
||||
let file_type = meta.file_type();
|
||||
|
||||
if !file_type.is_symlink() {
|
||||
return Ok(());
|
||||
}
|
||||
let real_cpath = cpath
|
||||
.read_link()
|
||||
.context(format!("read link {:?}", cpath))?;
|
||||
if real_cpath == real_hpath {
|
||||
return Err(einval());
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn sysctl(oci: &Spec) -> Result<()> {
|
||||
let linux = get_linux(oci)?;
|
||||
|
||||
@@ -299,6 +334,19 @@ mod tests {
|
||||
assert_eq!(contain_namespace(&namespaces, ""), false);
|
||||
assert_eq!(contain_namespace(&namespaces, "Net"), false);
|
||||
assert_eq!(contain_namespace(&namespaces, "ipc"), false);
|
||||
|
||||
assert_eq!(
|
||||
get_namespace_path(&namespaces, "net").unwrap(),
|
||||
"/sys/cgroups/net"
|
||||
);
|
||||
assert_eq!(
|
||||
get_namespace_path(&namespaces, "uts").unwrap(),
|
||||
"/sys/cgroups/uts"
|
||||
);
|
||||
|
||||
get_namespace_path(&namespaces, "").unwrap_err();
|
||||
get_namespace_path(&namespaces, "Uts").unwrap_err();
|
||||
get_namespace_path(&namespaces, "ipc").unwrap_err();
|
||||
}
|
||||
|
||||
#[test]
|
||||
@@ -480,6 +528,12 @@ mod tests {
|
||||
rootless_euid(&spec).unwrap();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_check_host_ns() {
|
||||
check_host_ns("/proc/self/ns/net").unwrap_err();
|
||||
check_host_ns("/proc/sys/net/ipv4/tcp_sack").unwrap();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_sysctl() {
|
||||
let mut spec = Spec::default();
|
||||
|
||||
@@ -2,16 +2,13 @@
|
||||
//
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
//
|
||||
use crate::tracer;
|
||||
use anyhow::{anyhow, Result};
|
||||
use std::env;
|
||||
use std::fs;
|
||||
use std::time;
|
||||
use tracing::instrument;
|
||||
|
||||
const DEBUG_CONSOLE_FLAG: &str = "agent.debug_console";
|
||||
const DEV_MODE_FLAG: &str = "agent.devmode";
|
||||
const TRACE_MODE_OPTION: &str = "agent.trace";
|
||||
const LOG_LEVEL_OPTION: &str = "agent.log";
|
||||
const SERVER_ADDR_OPTION: &str = "agent.server_addr";
|
||||
const HOTPLUG_TIMOUT_OPTION: &str = "agent.hotplug_timeout";
|
||||
@@ -29,7 +26,6 @@ const VSOCK_PORT: u16 = 1024;
|
||||
// Environment variables used for development and testing
|
||||
const SERVER_ADDR_ENV_VAR: &str = "KATA_AGENT_SERVER_ADDR";
|
||||
const LOG_LEVEL_ENV_VAR: &str = "KATA_AGENT_LOG_LEVEL";
|
||||
const TRACE_TYPE_ENV_VAR: &str = "KATA_AGENT_TRACE_TYPE";
|
||||
|
||||
const ERR_INVALID_LOG_LEVEL: &str = "invalid log level";
|
||||
const ERR_INVALID_LOG_LEVEL_PARAM: &str = "invalid log level parameter";
|
||||
@@ -58,7 +54,6 @@ pub struct AgentConfig {
|
||||
pub container_pipe_size: i32,
|
||||
pub server_addr: String,
|
||||
pub unified_cgroup_hierarchy: bool,
|
||||
pub tracing: tracer::TraceType,
|
||||
}
|
||||
|
||||
// parse_cmdline_param parse commandline parameters.
|
||||
@@ -103,11 +98,9 @@ impl AgentConfig {
|
||||
container_pipe_size: DEFAULT_CONTAINER_PIPE_SIZE,
|
||||
server_addr: format!("{}:{}", VSOCK_ADDR, VSOCK_PORT),
|
||||
unified_cgroup_hierarchy: false,
|
||||
tracing: tracer::TraceType::Disabled,
|
||||
}
|
||||
}
|
||||
|
||||
#[instrument]
|
||||
pub fn parse_cmdline(&mut self, file: &str) -> Result<()> {
|
||||
let cmdline = fs::read_to_string(file)?;
|
||||
let params: Vec<&str> = cmdline.split_ascii_whitespace().collect();
|
||||
@@ -116,15 +109,6 @@ impl AgentConfig {
|
||||
parse_cmdline_param!(param, DEBUG_CONSOLE_FLAG, self.debug_console);
|
||||
parse_cmdline_param!(param, DEV_MODE_FLAG, self.dev_mode);
|
||||
|
||||
// Support "bare" tracing option for backwards compatibility with
|
||||
// Kata 1.x.
|
||||
if param == &TRACE_MODE_OPTION {
|
||||
self.tracing = tracer::TraceType::Isolated;
|
||||
continue;
|
||||
}
|
||||
|
||||
parse_cmdline_param!(param, TRACE_MODE_OPTION, self.tracing, get_trace_type);
|
||||
|
||||
// parse cmdline options
|
||||
parse_cmdline_param!(param, LOG_LEVEL_OPTION, self.log_level, get_log_level);
|
||||
parse_cmdline_param!(
|
||||
@@ -183,17 +167,10 @@ impl AgentConfig {
|
||||
}
|
||||
}
|
||||
|
||||
if let Ok(value) = env::var(TRACE_TYPE_ENV_VAR) {
|
||||
if let Ok(result) = value.parse::<tracer::TraceType>() {
|
||||
self.tracing = result;
|
||||
}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
#[instrument]
|
||||
fn get_vsock_port(p: &str) -> Result<i32> {
|
||||
let fields: Vec<&str> = p.split('=').collect();
|
||||
if fields.len() != 2 {
|
||||
@@ -208,7 +185,6 @@ fn get_vsock_port(p: &str) -> Result<i32> {
|
||||
//
|
||||
// Note: Logrus names are used for compatability with the previous
|
||||
// golang-based agent.
|
||||
#[instrument]
|
||||
fn logrus_to_slog_level(logrus_level: &str) -> Result<slog::Level> {
|
||||
let level = match logrus_level {
|
||||
// Note: different semantics to logrus: log, but don't panic.
|
||||
@@ -231,7 +207,6 @@ fn logrus_to_slog_level(logrus_level: &str) -> Result<slog::Level> {
|
||||
Ok(level)
|
||||
}
|
||||
|
||||
#[instrument]
|
||||
fn get_log_level(param: &str) -> Result<slog::Level> {
|
||||
let fields: Vec<&str> = param.split('=').collect();
|
||||
|
||||
@@ -246,28 +221,6 @@ fn get_log_level(param: &str) -> Result<slog::Level> {
|
||||
}
|
||||
}
|
||||
|
||||
#[instrument]
|
||||
fn get_trace_type(param: &str) -> Result<tracer::TraceType> {
|
||||
if param.is_empty() {
|
||||
return Err(anyhow!("invalid trace type parameter"));
|
||||
}
|
||||
|
||||
let fields: Vec<&str> = param.split('=').collect();
|
||||
|
||||
if fields[0] != TRACE_MODE_OPTION {
|
||||
return Err(anyhow!("invalid trace type key name"));
|
||||
}
|
||||
|
||||
if fields.len() == 1 {
|
||||
return Ok(tracer::TraceType::Isolated);
|
||||
}
|
||||
|
||||
let result = fields[1].parse::<tracer::TraceType>()?;
|
||||
|
||||
Ok(result)
|
||||
}
|
||||
|
||||
#[instrument]
|
||||
fn get_hotplug_timeout(param: &str) -> Result<time::Duration> {
|
||||
let fields: Vec<&str> = param.split('=').collect();
|
||||
|
||||
@@ -288,7 +241,6 @@ fn get_hotplug_timeout(param: &str) -> Result<time::Duration> {
|
||||
Ok(time::Duration::from_secs(value.unwrap()))
|
||||
}
|
||||
|
||||
#[instrument]
|
||||
fn get_bool_value(param: &str) -> Result<bool> {
|
||||
let fields: Vec<&str> = param.split('=').collect();
|
||||
|
||||
@@ -313,7 +265,6 @@ fn get_bool_value(param: &str) -> Result<bool> {
|
||||
// - A value can contain any number of equal signs.
|
||||
// - We could/should maybe check if the name is pure whitespace
|
||||
// since this is considered to be invalid.
|
||||
#[instrument]
|
||||
fn get_string_value(param: &str) -> Result<String> {
|
||||
let fields: Vec<&str> = param.split('=').collect();
|
||||
|
||||
@@ -334,7 +285,6 @@ fn get_string_value(param: &str) -> Result<String> {
|
||||
Ok(value)
|
||||
}
|
||||
|
||||
#[instrument]
|
||||
fn get_container_pipe_size(param: &str) -> Result<i32> {
|
||||
let fields: Vec<&str> = param.split('=').collect();
|
||||
|
||||
@@ -369,10 +319,6 @@ mod tests {
|
||||
use std::time;
|
||||
use tempfile::tempdir;
|
||||
|
||||
const ERR_INVALID_TRACE_TYPE_PARAM: &str = "invalid trace type parameter";
|
||||
const ERR_INVALID_TRACE_TYPE: &str = "invalid trace type";
|
||||
const ERR_INVALID_TRACE_TYPE_KEY: &str = "invalid trace type key name";
|
||||
|
||||
// helper function to make errors less crazy-long
|
||||
fn make_err(desc: &str) -> Error {
|
||||
anyhow!(desc.to_string())
|
||||
@@ -428,7 +374,6 @@ mod tests {
|
||||
container_pipe_size: i32,
|
||||
server_addr: &'a str,
|
||||
unified_cgroup_hierarchy: bool,
|
||||
tracing: tracer::TraceType,
|
||||
}
|
||||
|
||||
let tests = &[
|
||||
@@ -442,7 +387,6 @@ mod tests {
|
||||
container_pipe_size: DEFAULT_CONTAINER_PIPE_SIZE,
|
||||
server_addr: TEST_SERVER_ADDR,
|
||||
unified_cgroup_hierarchy: false,
|
||||
tracing: tracer::TraceType::Disabled,
|
||||
},
|
||||
TestData {
|
||||
contents: "agent.debug_console agent.devmodex",
|
||||
@@ -454,7 +398,6 @@ mod tests {
|
||||
container_pipe_size: DEFAULT_CONTAINER_PIPE_SIZE,
|
||||
server_addr: TEST_SERVER_ADDR,
|
||||
unified_cgroup_hierarchy: false,
|
||||
tracing: tracer::TraceType::Disabled,
|
||||
},
|
||||
TestData {
|
||||
contents: "agent.logx=debug",
|
||||
@@ -466,7 +409,6 @@ mod tests {
|
||||
container_pipe_size: DEFAULT_CONTAINER_PIPE_SIZE,
|
||||
server_addr: TEST_SERVER_ADDR,
|
||||
unified_cgroup_hierarchy: false,
|
||||
tracing: tracer::TraceType::Disabled,
|
||||
},
|
||||
TestData {
|
||||
contents: "agent.log=debug",
|
||||
@@ -478,7 +420,6 @@ mod tests {
|
||||
container_pipe_size: DEFAULT_CONTAINER_PIPE_SIZE,
|
||||
server_addr: TEST_SERVER_ADDR,
|
||||
unified_cgroup_hierarchy: false,
|
||||
tracing: tracer::TraceType::Disabled,
|
||||
},
|
||||
TestData {
|
||||
contents: "agent.log=debug",
|
||||
@@ -490,7 +431,6 @@ mod tests {
|
||||
container_pipe_size: DEFAULT_CONTAINER_PIPE_SIZE,
|
||||
server_addr: TEST_SERVER_ADDR,
|
||||
unified_cgroup_hierarchy: false,
|
||||
tracing: tracer::TraceType::Disabled,
|
||||
},
|
||||
TestData {
|
||||
contents: "",
|
||||
@@ -502,7 +442,6 @@ mod tests {
|
||||
container_pipe_size: DEFAULT_CONTAINER_PIPE_SIZE,
|
||||
server_addr: TEST_SERVER_ADDR,
|
||||
unified_cgroup_hierarchy: false,
|
||||
tracing: tracer::TraceType::Disabled,
|
||||
},
|
||||
TestData {
|
||||
contents: "foo",
|
||||
@@ -514,7 +453,6 @@ mod tests {
|
||||
container_pipe_size: DEFAULT_CONTAINER_PIPE_SIZE,
|
||||
server_addr: TEST_SERVER_ADDR,
|
||||
unified_cgroup_hierarchy: false,
|
||||
tracing: tracer::TraceType::Disabled,
|
||||
},
|
||||
TestData {
|
||||
contents: "foo bar",
|
||||
@@ -526,7 +464,6 @@ mod tests {
|
||||
container_pipe_size: DEFAULT_CONTAINER_PIPE_SIZE,
|
||||
server_addr: TEST_SERVER_ADDR,
|
||||
unified_cgroup_hierarchy: false,
|
||||
tracing: tracer::TraceType::Disabled,
|
||||
},
|
||||
TestData {
|
||||
contents: "foo bar",
|
||||
@@ -538,7 +475,6 @@ mod tests {
|
||||
container_pipe_size: DEFAULT_CONTAINER_PIPE_SIZE,
|
||||
server_addr: TEST_SERVER_ADDR,
|
||||
unified_cgroup_hierarchy: false,
|
||||
tracing: tracer::TraceType::Disabled,
|
||||
},
|
||||
TestData {
|
||||
contents: "foo agent bar",
|
||||
@@ -550,7 +486,6 @@ mod tests {
|
||||
container_pipe_size: DEFAULT_CONTAINER_PIPE_SIZE,
|
||||
server_addr: TEST_SERVER_ADDR,
|
||||
unified_cgroup_hierarchy: false,
|
||||
tracing: tracer::TraceType::Disabled,
|
||||
},
|
||||
TestData {
|
||||
contents: "foo debug_console agent bar devmode",
|
||||
@@ -562,7 +497,6 @@ mod tests {
|
||||
container_pipe_size: DEFAULT_CONTAINER_PIPE_SIZE,
|
||||
server_addr: TEST_SERVER_ADDR,
|
||||
unified_cgroup_hierarchy: false,
|
||||
tracing: tracer::TraceType::Disabled,
|
||||
},
|
||||
TestData {
|
||||
contents: "agent.debug_console",
|
||||
@@ -574,7 +508,6 @@ mod tests {
|
||||
container_pipe_size: DEFAULT_CONTAINER_PIPE_SIZE,
|
||||
server_addr: TEST_SERVER_ADDR,
|
||||
unified_cgroup_hierarchy: false,
|
||||
tracing: tracer::TraceType::Disabled,
|
||||
},
|
||||
TestData {
|
||||
contents: " agent.debug_console ",
|
||||
@@ -586,7 +519,6 @@ mod tests {
|
||||
container_pipe_size: DEFAULT_CONTAINER_PIPE_SIZE,
|
||||
server_addr: TEST_SERVER_ADDR,
|
||||
unified_cgroup_hierarchy: false,
|
||||
tracing: tracer::TraceType::Disabled,
|
||||
},
|
||||
TestData {
|
||||
contents: "agent.debug_console foo",
|
||||
@@ -598,7 +530,6 @@ mod tests {
|
||||
container_pipe_size: DEFAULT_CONTAINER_PIPE_SIZE,
|
||||
server_addr: TEST_SERVER_ADDR,
|
||||
unified_cgroup_hierarchy: false,
|
||||
tracing: tracer::TraceType::Disabled,
|
||||
},
|
||||
TestData {
|
||||
contents: " agent.debug_console foo",
|
||||
@@ -610,7 +541,6 @@ mod tests {
|
||||
container_pipe_size: DEFAULT_CONTAINER_PIPE_SIZE,
|
||||
server_addr: TEST_SERVER_ADDR,
|
||||
unified_cgroup_hierarchy: false,
|
||||
tracing: tracer::TraceType::Disabled,
|
||||
},
|
||||
TestData {
|
||||
contents: "foo agent.debug_console bar",
|
||||
@@ -622,7 +552,6 @@ mod tests {
|
||||
container_pipe_size: DEFAULT_CONTAINER_PIPE_SIZE,
|
||||
server_addr: TEST_SERVER_ADDR,
|
||||
unified_cgroup_hierarchy: false,
|
||||
tracing: tracer::TraceType::Disabled,
|
||||
},
|
||||
TestData {
|
||||
contents: "foo agent.debug_console",
|
||||
@@ -634,7 +563,6 @@ mod tests {
|
||||
container_pipe_size: DEFAULT_CONTAINER_PIPE_SIZE,
|
||||
server_addr: TEST_SERVER_ADDR,
|
||||
unified_cgroup_hierarchy: false,
|
||||
tracing: tracer::TraceType::Disabled,
|
||||
},
|
||||
TestData {
|
||||
contents: "foo agent.debug_console ",
|
||||
@@ -646,7 +574,6 @@ mod tests {
|
||||
container_pipe_size: DEFAULT_CONTAINER_PIPE_SIZE,
|
||||
server_addr: TEST_SERVER_ADDR,
|
||||
unified_cgroup_hierarchy: false,
|
||||
tracing: tracer::TraceType::Disabled,
|
||||
},
|
||||
TestData {
|
||||
contents: "agent.devmode",
|
||||
@@ -658,7 +585,6 @@ mod tests {
|
||||
container_pipe_size: DEFAULT_CONTAINER_PIPE_SIZE,
|
||||
server_addr: TEST_SERVER_ADDR,
|
||||
unified_cgroup_hierarchy: false,
|
||||
tracing: tracer::TraceType::Disabled,
|
||||
},
|
||||
TestData {
|
||||
contents: " agent.devmode ",
|
||||
@@ -670,7 +596,6 @@ mod tests {
|
||||
container_pipe_size: DEFAULT_CONTAINER_PIPE_SIZE,
|
||||
server_addr: TEST_SERVER_ADDR,
|
||||
unified_cgroup_hierarchy: false,
|
||||
tracing: tracer::TraceType::Disabled,
|
||||
},
|
||||
TestData {
|
||||
contents: "agent.devmode foo",
|
||||
@@ -682,7 +607,6 @@ mod tests {
|
||||
container_pipe_size: DEFAULT_CONTAINER_PIPE_SIZE,
|
||||
server_addr: TEST_SERVER_ADDR,
|
||||
unified_cgroup_hierarchy: false,
|
||||
tracing: tracer::TraceType::Disabled,
|
||||
},
|
||||
TestData {
|
||||
contents: " agent.devmode foo",
|
||||
@@ -694,7 +618,6 @@ mod tests {
|
||||
container_pipe_size: DEFAULT_CONTAINER_PIPE_SIZE,
|
||||
server_addr: TEST_SERVER_ADDR,
|
||||
unified_cgroup_hierarchy: false,
|
||||
tracing: tracer::TraceType::Disabled,
|
||||
},
|
||||
TestData {
|
||||
contents: "foo agent.devmode bar",
|
||||
@@ -706,7 +629,6 @@ mod tests {
|
||||
container_pipe_size: DEFAULT_CONTAINER_PIPE_SIZE,
|
||||
server_addr: TEST_SERVER_ADDR,
|
||||
unified_cgroup_hierarchy: false,
|
||||
tracing: tracer::TraceType::Disabled,
|
||||
},
|
||||
TestData {
|
||||
contents: "foo agent.devmode",
|
||||
@@ -718,7 +640,6 @@ mod tests {
|
||||
container_pipe_size: DEFAULT_CONTAINER_PIPE_SIZE,
|
||||
server_addr: TEST_SERVER_ADDR,
|
||||
unified_cgroup_hierarchy: false,
|
||||
tracing: tracer::TraceType::Disabled,
|
||||
},
|
||||
TestData {
|
||||
contents: "foo agent.devmode ",
|
||||
@@ -730,7 +651,6 @@ mod tests {
|
||||
container_pipe_size: DEFAULT_CONTAINER_PIPE_SIZE,
|
||||
server_addr: TEST_SERVER_ADDR,
|
||||
unified_cgroup_hierarchy: false,
|
||||
tracing: tracer::TraceType::Disabled,
|
||||
},
|
||||
TestData {
|
||||
contents: "agent.devmode agent.debug_console",
|
||||
@@ -742,7 +662,6 @@ mod tests {
|
||||
container_pipe_size: DEFAULT_CONTAINER_PIPE_SIZE,
|
||||
server_addr: TEST_SERVER_ADDR,
|
||||
unified_cgroup_hierarchy: false,
|
||||
tracing: tracer::TraceType::Disabled,
|
||||
},
|
||||
TestData {
|
||||
contents: "agent.devmode agent.debug_console agent.hotplug_timeout=100 agent.unified_cgroup_hierarchy=a",
|
||||
@@ -754,7 +673,6 @@ mod tests {
|
||||
container_pipe_size: DEFAULT_CONTAINER_PIPE_SIZE,
|
||||
server_addr: TEST_SERVER_ADDR,
|
||||
unified_cgroup_hierarchy: false,
|
||||
tracing: tracer::TraceType::Disabled,
|
||||
},
|
||||
TestData {
|
||||
contents: "agent.devmode agent.debug_console agent.hotplug_timeout=0 agent.unified_cgroup_hierarchy=11",
|
||||
@@ -766,7 +684,6 @@ mod tests {
|
||||
container_pipe_size: DEFAULT_CONTAINER_PIPE_SIZE,
|
||||
server_addr: TEST_SERVER_ADDR,
|
||||
unified_cgroup_hierarchy: true,
|
||||
tracing: tracer::TraceType::Disabled,
|
||||
},
|
||||
TestData {
|
||||
contents: "agent.devmode agent.debug_console agent.container_pipe_size=2097152 agent.unified_cgroup_hierarchy=false",
|
||||
@@ -778,7 +695,6 @@ mod tests {
|
||||
container_pipe_size: 2097152,
|
||||
server_addr: TEST_SERVER_ADDR,
|
||||
unified_cgroup_hierarchy: false,
|
||||
tracing: tracer::TraceType::Disabled,
|
||||
},
|
||||
TestData {
|
||||
contents: "agent.devmode agent.debug_console agent.container_pipe_size=100 agent.unified_cgroup_hierarchy=true",
|
||||
@@ -790,7 +706,6 @@ mod tests {
|
||||
container_pipe_size: 100,
|
||||
server_addr: TEST_SERVER_ADDR,
|
||||
unified_cgroup_hierarchy: true,
|
||||
tracing: tracer::TraceType::Disabled,
|
||||
},
|
||||
TestData {
|
||||
contents: "agent.devmode agent.debug_console agent.container_pipe_size=0 agent.unified_cgroup_hierarchy=0",
|
||||
@@ -802,7 +717,6 @@ mod tests {
|
||||
container_pipe_size: DEFAULT_CONTAINER_PIPE_SIZE,
|
||||
server_addr: TEST_SERVER_ADDR,
|
||||
unified_cgroup_hierarchy: false,
|
||||
tracing: tracer::TraceType::Disabled,
|
||||
},
|
||||
TestData {
|
||||
contents: "agent.devmode agent.debug_console agent.container_pip_siz=100 agent.unified_cgroup_hierarchy=1",
|
||||
@@ -814,7 +728,6 @@ mod tests {
|
||||
container_pipe_size: DEFAULT_CONTAINER_PIPE_SIZE,
|
||||
server_addr: TEST_SERVER_ADDR,
|
||||
unified_cgroup_hierarchy: true,
|
||||
tracing: tracer::TraceType::Disabled,
|
||||
},
|
||||
TestData {
|
||||
contents: "",
|
||||
@@ -826,7 +739,6 @@ mod tests {
|
||||
container_pipe_size: DEFAULT_CONTAINER_PIPE_SIZE,
|
||||
server_addr: TEST_SERVER_ADDR,
|
||||
unified_cgroup_hierarchy: false,
|
||||
tracing: tracer::TraceType::Disabled,
|
||||
},
|
||||
TestData {
|
||||
contents: "",
|
||||
@@ -838,7 +750,6 @@ mod tests {
|
||||
container_pipe_size: DEFAULT_CONTAINER_PIPE_SIZE,
|
||||
server_addr: "foo",
|
||||
unified_cgroup_hierarchy: false,
|
||||
tracing: tracer::TraceType::Disabled,
|
||||
},
|
||||
TestData {
|
||||
contents: "",
|
||||
@@ -850,7 +761,6 @@ mod tests {
|
||||
container_pipe_size: DEFAULT_CONTAINER_PIPE_SIZE,
|
||||
server_addr: "=",
|
||||
unified_cgroup_hierarchy: false,
|
||||
tracing: tracer::TraceType::Disabled,
|
||||
},
|
||||
TestData {
|
||||
contents: "",
|
||||
@@ -862,7 +772,6 @@ mod tests {
|
||||
container_pipe_size: DEFAULT_CONTAINER_PIPE_SIZE,
|
||||
server_addr: "=foo",
|
||||
unified_cgroup_hierarchy: false,
|
||||
tracing: tracer::TraceType::Disabled,
|
||||
},
|
||||
TestData {
|
||||
contents: "",
|
||||
@@ -874,7 +783,6 @@ mod tests {
|
||||
container_pipe_size: DEFAULT_CONTAINER_PIPE_SIZE,
|
||||
server_addr: "foo=bar=baz=",
|
||||
unified_cgroup_hierarchy: false,
|
||||
tracing: tracer::TraceType::Disabled,
|
||||
},
|
||||
TestData {
|
||||
contents: "",
|
||||
@@ -886,7 +794,6 @@ mod tests {
|
||||
container_pipe_size: DEFAULT_CONTAINER_PIPE_SIZE,
|
||||
server_addr: "unix:///tmp/foo.socket",
|
||||
unified_cgroup_hierarchy: false,
|
||||
tracing: tracer::TraceType::Disabled,
|
||||
},
|
||||
TestData {
|
||||
contents: "",
|
||||
@@ -898,7 +805,6 @@ mod tests {
|
||||
container_pipe_size: DEFAULT_CONTAINER_PIPE_SIZE,
|
||||
server_addr: "unix://@/tmp/foo.socket",
|
||||
unified_cgroup_hierarchy: false,
|
||||
tracing: tracer::TraceType::Disabled,
|
||||
},
|
||||
TestData {
|
||||
contents: "",
|
||||
@@ -910,7 +816,6 @@ mod tests {
|
||||
container_pipe_size: DEFAULT_CONTAINER_PIPE_SIZE,
|
||||
server_addr: TEST_SERVER_ADDR,
|
||||
unified_cgroup_hierarchy: false,
|
||||
tracing: tracer::TraceType::Disabled,
|
||||
},
|
||||
TestData {
|
||||
contents: "",
|
||||
@@ -922,7 +827,6 @@ mod tests {
|
||||
container_pipe_size: DEFAULT_CONTAINER_PIPE_SIZE,
|
||||
server_addr: TEST_SERVER_ADDR,
|
||||
unified_cgroup_hierarchy: false,
|
||||
tracing: tracer::TraceType::Disabled,
|
||||
},
|
||||
TestData {
|
||||
contents: "",
|
||||
@@ -934,7 +838,6 @@ mod tests {
|
||||
container_pipe_size: DEFAULT_CONTAINER_PIPE_SIZE,
|
||||
server_addr: TEST_SERVER_ADDR,
|
||||
unified_cgroup_hierarchy: false,
|
||||
tracing: tracer::TraceType::Disabled,
|
||||
},
|
||||
TestData {
|
||||
contents: "",
|
||||
@@ -946,7 +849,6 @@ mod tests {
|
||||
container_pipe_size: DEFAULT_CONTAINER_PIPE_SIZE,
|
||||
server_addr: TEST_SERVER_ADDR,
|
||||
unified_cgroup_hierarchy: false,
|
||||
tracing: tracer::TraceType::Disabled,
|
||||
},
|
||||
TestData {
|
||||
contents: "server_addr=unix:///tmp/foo.socket",
|
||||
@@ -958,7 +860,6 @@ mod tests {
|
||||
container_pipe_size: DEFAULT_CONTAINER_PIPE_SIZE,
|
||||
server_addr: TEST_SERVER_ADDR,
|
||||
unified_cgroup_hierarchy: false,
|
||||
tracing: tracer::TraceType::Disabled,
|
||||
},
|
||||
TestData {
|
||||
contents: "agent.server_address=unix:///tmp/foo.socket",
|
||||
@@ -970,7 +871,6 @@ mod tests {
|
||||
container_pipe_size: DEFAULT_CONTAINER_PIPE_SIZE,
|
||||
server_addr: TEST_SERVER_ADDR,
|
||||
unified_cgroup_hierarchy: false,
|
||||
tracing: tracer::TraceType::Disabled,
|
||||
},
|
||||
TestData {
|
||||
contents: "agent.server_addr=unix:///tmp/foo.socket",
|
||||
@@ -982,7 +882,6 @@ mod tests {
|
||||
container_pipe_size: DEFAULT_CONTAINER_PIPE_SIZE,
|
||||
server_addr: "unix:///tmp/foo.socket",
|
||||
unified_cgroup_hierarchy: false,
|
||||
tracing: tracer::TraceType::Disabled,
|
||||
},
|
||||
TestData {
|
||||
contents: " agent.server_addr=unix:///tmp/foo.socket",
|
||||
@@ -994,7 +893,6 @@ mod tests {
|
||||
container_pipe_size: DEFAULT_CONTAINER_PIPE_SIZE,
|
||||
server_addr: "unix:///tmp/foo.socket",
|
||||
unified_cgroup_hierarchy: false,
|
||||
tracing: tracer::TraceType::Disabled,
|
||||
},
|
||||
TestData {
|
||||
contents: " agent.server_addr=unix:///tmp/foo.socket a",
|
||||
@@ -1006,115 +904,6 @@ mod tests {
|
||||
container_pipe_size: DEFAULT_CONTAINER_PIPE_SIZE,
|
||||
server_addr: "unix:///tmp/foo.socket",
|
||||
unified_cgroup_hierarchy: false,
|
||||
tracing: tracer::TraceType::Disabled,
|
||||
},
|
||||
TestData {
|
||||
contents: "trace",
|
||||
env_vars: Vec::new(),
|
||||
debug_console: false,
|
||||
dev_mode: false,
|
||||
log_level: DEFAULT_LOG_LEVEL,
|
||||
hotplug_timeout: DEFAULT_HOTPLUG_TIMEOUT,
|
||||
container_pipe_size: DEFAULT_CONTAINER_PIPE_SIZE,
|
||||
server_addr: TEST_SERVER_ADDR,
|
||||
unified_cgroup_hierarchy: false,
|
||||
tracing: tracer::TraceType::Disabled,
|
||||
},
|
||||
TestData {
|
||||
contents: ".trace",
|
||||
env_vars: Vec::new(),
|
||||
debug_console: false,
|
||||
dev_mode: false,
|
||||
log_level: DEFAULT_LOG_LEVEL,
|
||||
hotplug_timeout: DEFAULT_HOTPLUG_TIMEOUT,
|
||||
container_pipe_size: DEFAULT_CONTAINER_PIPE_SIZE,
|
||||
server_addr: TEST_SERVER_ADDR,
|
||||
unified_cgroup_hierarchy: false,
|
||||
tracing: tracer::TraceType::Disabled,
|
||||
},
|
||||
TestData {
|
||||
contents: "agent.tracer",
|
||||
env_vars: Vec::new(),
|
||||
debug_console: false,
|
||||
dev_mode: false,
|
||||
log_level: DEFAULT_LOG_LEVEL,
|
||||
hotplug_timeout: DEFAULT_HOTPLUG_TIMEOUT,
|
||||
container_pipe_size: DEFAULT_CONTAINER_PIPE_SIZE,
|
||||
server_addr: TEST_SERVER_ADDR,
|
||||
unified_cgroup_hierarchy: false,
|
||||
tracing: tracer::TraceType::Disabled,
|
||||
},
|
||||
TestData {
|
||||
contents: "agent.trac",
|
||||
env_vars: Vec::new(),
|
||||
debug_console: false,
|
||||
dev_mode: false,
|
||||
log_level: DEFAULT_LOG_LEVEL,
|
||||
hotplug_timeout: DEFAULT_HOTPLUG_TIMEOUT,
|
||||
container_pipe_size: DEFAULT_CONTAINER_PIPE_SIZE,
|
||||
server_addr: TEST_SERVER_ADDR,
|
||||
unified_cgroup_hierarchy: false,
|
||||
tracing: tracer::TraceType::Disabled,
|
||||
},
|
||||
TestData {
|
||||
contents: "agent.trace",
|
||||
env_vars: Vec::new(),
|
||||
debug_console: false,
|
||||
dev_mode: false,
|
||||
log_level: DEFAULT_LOG_LEVEL,
|
||||
hotplug_timeout: DEFAULT_HOTPLUG_TIMEOUT,
|
||||
container_pipe_size: DEFAULT_CONTAINER_PIPE_SIZE,
|
||||
server_addr: TEST_SERVER_ADDR,
|
||||
unified_cgroup_hierarchy: false,
|
||||
tracing: tracer::TraceType::Isolated,
|
||||
},
|
||||
TestData {
|
||||
contents: "agent.trace=isolated",
|
||||
env_vars: Vec::new(),
|
||||
debug_console: false,
|
||||
dev_mode: false,
|
||||
log_level: DEFAULT_LOG_LEVEL,
|
||||
hotplug_timeout: DEFAULT_HOTPLUG_TIMEOUT,
|
||||
container_pipe_size: DEFAULT_CONTAINER_PIPE_SIZE,
|
||||
server_addr: TEST_SERVER_ADDR,
|
||||
unified_cgroup_hierarchy: false,
|
||||
tracing: tracer::TraceType::Isolated,
|
||||
},
|
||||
TestData {
|
||||
contents: "agent.trace=disabled",
|
||||
env_vars: Vec::new(),
|
||||
debug_console: false,
|
||||
dev_mode: false,
|
||||
log_level: DEFAULT_LOG_LEVEL,
|
||||
hotplug_timeout: DEFAULT_HOTPLUG_TIMEOUT,
|
||||
container_pipe_size: DEFAULT_CONTAINER_PIPE_SIZE,
|
||||
server_addr: TEST_SERVER_ADDR,
|
||||
unified_cgroup_hierarchy: false,
|
||||
tracing: tracer::TraceType::Disabled,
|
||||
},
|
||||
TestData {
|
||||
contents: "",
|
||||
env_vars: vec!["KATA_AGENT_TRACE_TYPE=isolated"],
|
||||
debug_console: false,
|
||||
dev_mode: false,
|
||||
log_level: DEFAULT_LOG_LEVEL,
|
||||
hotplug_timeout: DEFAULT_HOTPLUG_TIMEOUT,
|
||||
container_pipe_size: DEFAULT_CONTAINER_PIPE_SIZE,
|
||||
server_addr: TEST_SERVER_ADDR,
|
||||
unified_cgroup_hierarchy: false,
|
||||
tracing: tracer::TraceType::Isolated,
|
||||
},
|
||||
TestData {
|
||||
contents: "",
|
||||
env_vars: vec!["KATA_AGENT_TRACE_TYPE=disabled"],
|
||||
debug_console: false,
|
||||
dev_mode: false,
|
||||
log_level: DEFAULT_LOG_LEVEL,
|
||||
hotplug_timeout: DEFAULT_HOTPLUG_TIMEOUT,
|
||||
container_pipe_size: DEFAULT_CONTAINER_PIPE_SIZE,
|
||||
server_addr: TEST_SERVER_ADDR,
|
||||
unified_cgroup_hierarchy: false,
|
||||
tracing: tracer::TraceType::Disabled,
|
||||
},
|
||||
];
|
||||
|
||||
@@ -1169,7 +958,6 @@ mod tests {
|
||||
);
|
||||
assert_eq!(config.container_pipe_size, 0, "{}", msg);
|
||||
assert_eq!(config.server_addr, TEST_SERVER_ADDR, "{}", msg);
|
||||
assert_eq!(config.tracing, tracer::TraceType::Disabled, "{}", msg);
|
||||
|
||||
let result = config.parse_cmdline(filename);
|
||||
assert!(result.is_ok(), "{}", msg);
|
||||
@@ -1185,7 +973,6 @@ mod tests {
|
||||
assert_eq!(d.hotplug_timeout, config.hotplug_timeout, "{}", msg);
|
||||
assert_eq!(d.container_pipe_size, config.container_pipe_size, "{}", msg);
|
||||
assert_eq!(d.server_addr, config.server_addr, "{}", msg);
|
||||
assert_eq!(d.tracing, config.tracing, "{}", msg);
|
||||
|
||||
for v in vars_to_unset {
|
||||
env::remove_var(v);
|
||||
@@ -1582,62 +1369,4 @@ mod tests {
|
||||
assert_result!(d.result, result, msg);
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_get_trace_type() {
|
||||
#[derive(Debug)]
|
||||
struct TestData<'a> {
|
||||
param: &'a str,
|
||||
result: Result<tracer::TraceType>,
|
||||
}
|
||||
|
||||
let tests = &[
|
||||
TestData {
|
||||
param: "",
|
||||
result: Err(make_err(ERR_INVALID_TRACE_TYPE_PARAM)),
|
||||
},
|
||||
TestData {
|
||||
param: "agent.tracer",
|
||||
result: Err(make_err(ERR_INVALID_TRACE_TYPE_KEY)),
|
||||
},
|
||||
TestData {
|
||||
param: "agent.trac",
|
||||
result: Err(make_err(ERR_INVALID_TRACE_TYPE_KEY)),
|
||||
},
|
||||
TestData {
|
||||
param: "agent.trace=",
|
||||
result: Err(make_err(ERR_INVALID_TRACE_TYPE)),
|
||||
},
|
||||
TestData {
|
||||
param: "agent.trace==",
|
||||
result: Err(make_err(ERR_INVALID_TRACE_TYPE)),
|
||||
},
|
||||
TestData {
|
||||
param: "agent.trace=foo",
|
||||
result: Err(make_err(ERR_INVALID_TRACE_TYPE)),
|
||||
},
|
||||
TestData {
|
||||
param: "agent.trace",
|
||||
result: Ok(tracer::TraceType::Isolated),
|
||||
},
|
||||
TestData {
|
||||
param: "agent.trace=isolated",
|
||||
result: Ok(tracer::TraceType::Isolated),
|
||||
},
|
||||
TestData {
|
||||
param: "agent.trace=disabled",
|
||||
result: Ok(tracer::TraceType::Disabled),
|
||||
},
|
||||
];
|
||||
|
||||
for (i, d) in tests.iter().enumerate() {
|
||||
let msg = format!("test[{}]: {:?}", i, d);
|
||||
|
||||
let result = get_trace_type(d.param);
|
||||
|
||||
let msg = format!("{}: result: {:?}", msg, result);
|
||||
|
||||
assert_result!(d.result, result, msg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -145,10 +145,9 @@ fn run_in_child(slave_fd: libc::c_int, shell: String) -> Result<()> {
|
||||
}
|
||||
|
||||
let cmd = CString::new(shell).unwrap();
|
||||
let args: Vec<CString> = Vec::new();
|
||||
|
||||
// run shell
|
||||
let _ = unistd::execvp(cmd.as_c_str(), &args).map_err(|e| match e {
|
||||
let _ = unistd::execvp(cmd.as_c_str(), &[]).map_err(|e| match e {
|
||||
nix::Error::Sys(errno) => {
|
||||
std::process::exit(errno as i32);
|
||||
}
|
||||
@@ -206,7 +205,7 @@ async fn run_debug_console_vsock<T: AsyncRead + AsyncWrite>(
|
||||
|
||||
let slave_fd = pseudo.slave;
|
||||
|
||||
match unsafe { fork() } {
|
||||
match fork() {
|
||||
Ok(ForkResult::Child) => run_in_child(slave_fd, shell),
|
||||
Ok(ForkResult::Parent { child: child_pid }) => {
|
||||
run_in_parent(logger.clone(), stream, pseudo, child_pid).await
|
||||
|
||||
@@ -22,7 +22,6 @@ use crate::uevent::{wait_for_uevent, Uevent, UeventMatcher};
|
||||
use anyhow::{anyhow, Result};
|
||||
use oci::{LinuxDeviceCgroup, LinuxResources, Spec};
|
||||
use protocols::agent::Device;
|
||||
use tracing::instrument;
|
||||
|
||||
// Convenience macro to obtain the scope logger
|
||||
macro_rules! sl {
|
||||
@@ -33,21 +32,17 @@ macro_rules! sl {
|
||||
|
||||
const VM_ROOTFS: &str = "/";
|
||||
|
||||
#[derive(Debug)]
|
||||
struct DevIndexEntry {
|
||||
idx: usize,
|
||||
residx: Vec<usize>,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
struct DevIndex(HashMap<String, DevIndexEntry>);
|
||||
|
||||
#[instrument]
|
||||
pub fn rescan_pci_bus() -> Result<()> {
|
||||
online_device(SYSFS_PCI_BUS_RESCAN_FILE)
|
||||
}
|
||||
|
||||
#[instrument]
|
||||
pub fn online_device(path: &str) -> Result<()> {
|
||||
fs::write(path, "1")?;
|
||||
Ok(())
|
||||
@@ -56,7 +51,6 @@ pub fn online_device(path: &str) -> Result<()> {
|
||||
// pcipath_to_sysfs fetches the sysfs path for a PCI path, relative to
|
||||
// the sysfs path for the PCI host bridge, based on the PCI path
|
||||
// provided.
|
||||
#[instrument]
|
||||
fn pcipath_to_sysfs(root_bus_sysfs: &str, pcipath: &pci::Path) -> Result<String> {
|
||||
let mut bus = "0000:00".to_string();
|
||||
let mut relpath = String::new();
|
||||
@@ -115,7 +109,6 @@ impl UeventMatcher for ScsiBlockMatcher {
|
||||
}
|
||||
}
|
||||
|
||||
#[instrument]
|
||||
pub async fn get_scsi_device_name(
|
||||
sandbox: &Arc<Mutex<Sandbox>>,
|
||||
scsi_addr: &str,
|
||||
@@ -148,7 +141,6 @@ impl UeventMatcher for VirtioBlkPciMatcher {
|
||||
}
|
||||
}
|
||||
|
||||
#[instrument]
|
||||
pub async fn get_virtio_blk_pci_device_name(
|
||||
sandbox: &Arc<Mutex<Sandbox>>,
|
||||
pcipath: &pci::Path,
|
||||
@@ -185,7 +177,6 @@ impl UeventMatcher for PmemBlockMatcher {
|
||||
}
|
||||
}
|
||||
|
||||
#[instrument]
|
||||
pub async fn wait_for_pmem_device(sandbox: &Arc<Mutex<Sandbox>>, devpath: &str) -> Result<()> {
|
||||
let devname = match devpath.strip_prefix("/dev/") {
|
||||
Some(dev) => dev,
|
||||
@@ -210,7 +201,6 @@ pub async fn wait_for_pmem_device(sandbox: &Arc<Mutex<Sandbox>>, devpath: &str)
|
||||
}
|
||||
|
||||
/// Scan SCSI bus for the given SCSI address(SCSI-Id and LUN)
|
||||
#[instrument]
|
||||
fn scan_scsi_bus(scsi_addr: &str) -> Result<()> {
|
||||
let tokens: Vec<&str> = scsi_addr.split(':').collect();
|
||||
if tokens.len() != 2 {
|
||||
@@ -245,7 +235,6 @@ fn scan_scsi_bus(scsi_addr: &str) -> Result<()> {
|
||||
// the same device in the list of devices provided through the OCI spec.
|
||||
// This is needed to update information about minor/major numbers that cannot
|
||||
// be predicted from the caller.
|
||||
#[instrument]
|
||||
fn update_spec_device_list(device: &Device, spec: &mut Spec, devidx: &DevIndex) -> Result<()> {
|
||||
let major_id: c_uint;
|
||||
let minor_id: c_uint;
|
||||
@@ -322,7 +311,6 @@ fn update_spec_device_list(device: &Device, spec: &mut Spec, devidx: &DevIndex)
|
||||
|
||||
// device.Id should be the predicted device name (vda, vdb, ...)
|
||||
// device.VmPath already provides a way to send it in
|
||||
#[instrument]
|
||||
async fn virtiommio_blk_device_handler(
|
||||
device: &Device,
|
||||
spec: &mut Spec,
|
||||
@@ -337,7 +325,6 @@ async fn virtiommio_blk_device_handler(
|
||||
}
|
||||
|
||||
// device.Id should be a PCI path string
|
||||
#[instrument]
|
||||
async fn virtio_blk_device_handler(
|
||||
device: &Device,
|
||||
spec: &mut Spec,
|
||||
@@ -353,7 +340,6 @@ async fn virtio_blk_device_handler(
|
||||
}
|
||||
|
||||
// device.Id should be the SCSI address of the disk in the format "scsiID:lunID"
|
||||
#[instrument]
|
||||
async fn virtio_scsi_device_handler(
|
||||
device: &Device,
|
||||
spec: &mut Spec,
|
||||
@@ -365,7 +351,6 @@ async fn virtio_scsi_device_handler(
|
||||
update_spec_device_list(&dev, spec, devidx)
|
||||
}
|
||||
|
||||
#[instrument]
|
||||
async fn virtio_nvdimm_device_handler(
|
||||
device: &Device,
|
||||
spec: &mut Spec,
|
||||
@@ -404,7 +389,6 @@ impl DevIndex {
|
||||
}
|
||||
}
|
||||
|
||||
#[instrument]
|
||||
pub async fn add_devices(
|
||||
devices: &[Device],
|
||||
spec: &mut Spec,
|
||||
@@ -419,7 +403,6 @@ pub async fn add_devices(
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[instrument]
|
||||
async fn add_device(
|
||||
device: &Device,
|
||||
spec: &mut Spec,
|
||||
@@ -454,7 +437,6 @@ async fn add_device(
|
||||
// update_device_cgroup update the device cgroup for container
|
||||
// to not allow access to the guest root partition. This prevents
|
||||
// the container from being able to access the VM rootfs.
|
||||
#[instrument]
|
||||
pub fn update_device_cgroup(spec: &mut Spec) -> Result<()> {
|
||||
let meta = fs::metadata(VM_ROOTFS)?;
|
||||
let rdev = meta.dev();
|
||||
|
||||
@@ -5,8 +5,8 @@
|
||||
|
||||
#[macro_use]
|
||||
extern crate lazy_static;
|
||||
extern crate capctl;
|
||||
extern crate oci;
|
||||
extern crate prctl;
|
||||
extern crate prometheus;
|
||||
extern crate protocols;
|
||||
extern crate regex;
|
||||
@@ -32,7 +32,6 @@ use std::os::unix::io::AsRawFd;
|
||||
use std::path::Path;
|
||||
use std::process::exit;
|
||||
use std::sync::Arc;
|
||||
use tracing::{instrument, span};
|
||||
|
||||
mod config;
|
||||
mod console;
|
||||
@@ -56,7 +55,7 @@ mod version;
|
||||
use mount::{cgroups_mount, general_mount};
|
||||
use sandbox::Sandbox;
|
||||
use signal::setup_signal_handler;
|
||||
use slog::{error, info, o, warn, Logger};
|
||||
use slog::Logger;
|
||||
use uevent::watch_uevents;
|
||||
|
||||
use futures::future::join_all;
|
||||
@@ -71,7 +70,6 @@ use tokio::{
|
||||
};
|
||||
|
||||
mod rpc;
|
||||
mod tracer;
|
||||
|
||||
const NAME: &str = "kata-agent";
|
||||
const KERNEL_CMDLINE_FILE: &str = "/proc/cmdline";
|
||||
@@ -81,7 +79,6 @@ lazy_static! {
|
||||
Arc::new(RwLock::new(config::AgentConfig::new()));
|
||||
}
|
||||
|
||||
#[instrument]
|
||||
fn announce(logger: &Logger, config: &AgentConfig) {
|
||||
info!(logger, "announce";
|
||||
"agent-commit" => version::VERSION_COMMIT,
|
||||
@@ -202,17 +199,6 @@ async fn real_main() -> std::result::Result<(), Box<dyn std::error::Error>> {
|
||||
ttrpc_log_guard = Ok(slog_stdlog::init().map_err(|e| e)?);
|
||||
}
|
||||
|
||||
if config.tracing != tracer::TraceType::Disabled {
|
||||
let _ = tracer::setup_tracing(NAME, &logger, &config)?;
|
||||
}
|
||||
|
||||
let root = span!(tracing::Level::TRACE, "root-span", work_units = 2);
|
||||
|
||||
// XXX: Start the root trace transaction.
|
||||
//
|
||||
// XXX: Note that *ALL* spans needs to start after this point!!
|
||||
let _enter = root.enter();
|
||||
|
||||
// Start the sandbox and wait for its ttRPC server to end
|
||||
start_sandbox(&logger, &config, init_mode, &mut tasks, shutdown_rx.clone()).await?;
|
||||
|
||||
@@ -241,10 +227,6 @@ async fn real_main() -> std::result::Result<(), Box<dyn std::error::Error>> {
|
||||
}
|
||||
}
|
||||
|
||||
if config.tracing != tracer::TraceType::Disabled {
|
||||
tracer::end_tracing();
|
||||
}
|
||||
|
||||
eprintln!("{} shutdown complete", NAME);
|
||||
|
||||
Ok(())
|
||||
@@ -278,7 +260,6 @@ fn main() -> std::result::Result<(), Box<dyn std::error::Error>> {
|
||||
rt.block_on(real_main())
|
||||
}
|
||||
|
||||
#[instrument]
|
||||
async fn start_sandbox(
|
||||
logger: &Logger,
|
||||
config: &AgentConfig,
|
||||
@@ -325,7 +306,7 @@ async fn start_sandbox(
|
||||
let mut server = rpc::start(sandbox.clone(), config.server_addr.as_str());
|
||||
server.start().await?;
|
||||
|
||||
rx.await?;
|
||||
let _ = rx.await?;
|
||||
server.shutdown().await?;
|
||||
|
||||
Ok(())
|
||||
@@ -365,7 +346,6 @@ fn init_agent_as_init(logger: &Logger, unified_cgroup_hierarchy: bool) -> Result
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[instrument]
|
||||
fn sethostname(hostname: &OsStr) -> Result<()> {
|
||||
let size = hostname.len() as usize;
|
||||
|
||||
|
||||
@@ -8,7 +8,6 @@ extern crate procfs;
|
||||
use prometheus::{Encoder, Gauge, GaugeVec, IntCounter, TextEncoder};
|
||||
|
||||
use anyhow::Result;
|
||||
use tracing::instrument;
|
||||
|
||||
const NAMESPACE_KATA_AGENT: &str = "kata_agent";
|
||||
const NAMESPACE_KATA_GUEST: &str = "kata_guest";
|
||||
@@ -69,7 +68,6 @@ lazy_static! {
|
||||
prometheus::register_gauge_vec!(format!("{}_{}",NAMESPACE_KATA_GUEST,"meminfo").as_ref() , "Statistics about memory usage in the system.", &["item"]).unwrap();
|
||||
}
|
||||
|
||||
#[instrument]
|
||||
pub fn get_metrics(_: &protocols::agent::GetMetricsRequest) -> Result<String> {
|
||||
AGENT_SCRAPE_COUNT.inc();
|
||||
|
||||
@@ -89,7 +87,6 @@ pub fn get_metrics(_: &protocols::agent::GetMetricsRequest) -> Result<String> {
|
||||
Ok(String::from_utf8(buffer).unwrap())
|
||||
}
|
||||
|
||||
#[instrument]
|
||||
fn update_agent_metrics() {
|
||||
let me = procfs::process::Process::myself();
|
||||
|
||||
@@ -139,7 +136,6 @@ fn update_agent_metrics() {
|
||||
}
|
||||
}
|
||||
|
||||
#[instrument]
|
||||
fn update_guest_metrics() {
|
||||
// try get load and task info
|
||||
match procfs::LoadAverage::new() {
|
||||
@@ -222,7 +218,6 @@ fn update_guest_metrics() {
|
||||
}
|
||||
}
|
||||
|
||||
#[instrument]
|
||||
fn set_gauge_vec_meminfo(gv: &prometheus::GaugeVec, meminfo: &procfs::Meminfo) {
|
||||
gv.with_label_values(&["mem_total"])
|
||||
.set(meminfo.mem_total as f64);
|
||||
@@ -337,7 +332,6 @@ fn set_gauge_vec_meminfo(gv: &prometheus::GaugeVec, meminfo: &procfs::Meminfo) {
|
||||
.set(meminfo.k_reclaimable.unwrap_or(0) as f64);
|
||||
}
|
||||
|
||||
#[instrument]
|
||||
fn set_gauge_vec_cpu_time(gv: &prometheus::GaugeVec, cpu: &str, cpu_time: &procfs::CpuTime) {
|
||||
gv.with_label_values(&[cpu, "user"])
|
||||
.set(cpu_time.user as f64);
|
||||
@@ -361,7 +355,6 @@ fn set_gauge_vec_cpu_time(gv: &prometheus::GaugeVec, cpu: &str, cpu_time: &procf
|
||||
.set(cpu_time.guest_nice.unwrap_or(0.0) as f64);
|
||||
}
|
||||
|
||||
#[instrument]
|
||||
fn set_gauge_vec_diskstat(gv: &prometheus::GaugeVec, diskstat: &procfs::DiskStat) {
|
||||
gv.with_label_values(&[diskstat.name.as_str(), "reads"])
|
||||
.set(diskstat.reads as f64);
|
||||
@@ -400,7 +393,6 @@ fn set_gauge_vec_diskstat(gv: &prometheus::GaugeVec, diskstat: &procfs::DiskStat
|
||||
}
|
||||
|
||||
// set_gauge_vec_netdev set gauge for NetDevLine
|
||||
#[instrument]
|
||||
fn set_gauge_vec_netdev(gv: &prometheus::GaugeVec, status: &procfs::net::DeviceStatus) {
|
||||
gv.with_label_values(&[status.name.as_str(), "recv_bytes"])
|
||||
.set(status.recv_bytes as f64);
|
||||
@@ -437,7 +429,6 @@ fn set_gauge_vec_netdev(gv: &prometheus::GaugeVec, status: &procfs::net::DeviceS
|
||||
}
|
||||
|
||||
// set_gauge_vec_proc_status set gauge for ProcStatus
|
||||
#[instrument]
|
||||
fn set_gauge_vec_proc_status(gv: &prometheus::GaugeVec, status: &procfs::process::Status) {
|
||||
gv.with_label_values(&["vmpeak"])
|
||||
.set(status.vmpeak.unwrap_or(0) as f64);
|
||||
@@ -478,7 +469,6 @@ fn set_gauge_vec_proc_status(gv: &prometheus::GaugeVec, status: &procfs::process
|
||||
}
|
||||
|
||||
// set_gauge_vec_proc_io set gauge for ProcIO
|
||||
#[instrument]
|
||||
fn set_gauge_vec_proc_io(gv: &prometheus::GaugeVec, io_stat: &procfs::process::Io) {
|
||||
gv.with_label_values(&["rchar"]).set(io_stat.rchar as f64);
|
||||
gv.with_label_values(&["wchar"]).set(io_stat.wchar as f64);
|
||||
@@ -493,7 +483,6 @@ fn set_gauge_vec_proc_io(gv: &prometheus::GaugeVec, io_stat: &procfs::process::I
|
||||
}
|
||||
|
||||
// set_gauge_vec_proc_stat set gauge for ProcStat
|
||||
#[instrument]
|
||||
fn set_gauge_vec_proc_stat(gv: &prometheus::GaugeVec, stat: &procfs::process::Stat) {
|
||||
gv.with_label_values(&["utime"]).set(stat.utime as f64);
|
||||
gv.with_label_values(&["stime"]).set(stat.stime as f64);
|
||||
|
||||
@@ -32,7 +32,6 @@ use crate::protocols::agent::Storage;
|
||||
use crate::Sandbox;
|
||||
use anyhow::{anyhow, Context, Result};
|
||||
use slog::Logger;
|
||||
use tracing::instrument;
|
||||
|
||||
pub const DRIVER_9P_TYPE: &str = "9p";
|
||||
pub const DRIVER_VIRTIOFS_TYPE: &str = "virtio-fs";
|
||||
@@ -157,7 +156,6 @@ pub struct BareMount<'a> {
|
||||
// * evaluate all symlinks
|
||||
// * ensure the source exists
|
||||
impl<'a> BareMount<'a> {
|
||||
#[instrument]
|
||||
pub fn new(
|
||||
s: &'a str,
|
||||
d: &'a str,
|
||||
@@ -176,7 +174,6 @@ impl<'a> BareMount<'a> {
|
||||
}
|
||||
}
|
||||
|
||||
#[instrument]
|
||||
pub fn mount(&self) -> Result<()> {
|
||||
let source;
|
||||
let dest;
|
||||
@@ -235,7 +232,6 @@ impl<'a> BareMount<'a> {
|
||||
}
|
||||
}
|
||||
|
||||
#[instrument]
|
||||
async fn ephemeral_storage_handler(
|
||||
logger: &Logger,
|
||||
storage: &Storage,
|
||||
@@ -282,7 +278,6 @@ async fn ephemeral_storage_handler(
|
||||
Ok("".to_string())
|
||||
}
|
||||
|
||||
#[instrument]
|
||||
async fn local_storage_handler(
|
||||
_logger: &Logger,
|
||||
storage: &Storage,
|
||||
@@ -329,7 +324,6 @@ async fn local_storage_handler(
|
||||
Ok("".to_string())
|
||||
}
|
||||
|
||||
#[instrument]
|
||||
async fn virtio9p_storage_handler(
|
||||
logger: &Logger,
|
||||
storage: &Storage,
|
||||
@@ -339,7 +333,6 @@ async fn virtio9p_storage_handler(
|
||||
}
|
||||
|
||||
// virtiommio_blk_storage_handler handles the storage for mmio blk driver.
|
||||
#[instrument]
|
||||
async fn virtiommio_blk_storage_handler(
|
||||
logger: &Logger,
|
||||
storage: &Storage,
|
||||
@@ -350,7 +343,6 @@ async fn virtiommio_blk_storage_handler(
|
||||
}
|
||||
|
||||
// virtiofs_storage_handler handles the storage for virtio-fs.
|
||||
#[instrument]
|
||||
async fn virtiofs_storage_handler(
|
||||
logger: &Logger,
|
||||
storage: &Storage,
|
||||
@@ -360,7 +352,6 @@ async fn virtiofs_storage_handler(
|
||||
}
|
||||
|
||||
// virtio_blk_storage_handler handles the storage for blk driver.
|
||||
#[instrument]
|
||||
async fn virtio_blk_storage_handler(
|
||||
logger: &Logger,
|
||||
storage: &Storage,
|
||||
@@ -386,8 +377,7 @@ async fn virtio_blk_storage_handler(
|
||||
common_storage_handler(logger, &storage)
|
||||
}
|
||||
|
||||
// virtio_scsi_storage_handler handles the storage for scsi driver.
|
||||
#[instrument]
|
||||
// virtio_scsi_storage_handler handles the storage for scsi driver.
|
||||
async fn virtio_scsi_storage_handler(
|
||||
logger: &Logger,
|
||||
storage: &Storage,
|
||||
@@ -402,7 +392,6 @@ async fn virtio_scsi_storage_handler(
|
||||
common_storage_handler(logger, &storage)
|
||||
}
|
||||
|
||||
#[instrument]
|
||||
fn common_storage_handler(logger: &Logger, storage: &Storage) -> Result<String> {
|
||||
// Mount the storage device.
|
||||
let mount_point = storage.mount_point.to_string();
|
||||
@@ -411,7 +400,6 @@ fn common_storage_handler(logger: &Logger, storage: &Storage) -> Result<String>
|
||||
}
|
||||
|
||||
// nvdimm_storage_handler handles the storage for NVDIMM driver.
|
||||
#[instrument]
|
||||
async fn nvdimm_storage_handler(
|
||||
logger: &Logger,
|
||||
storage: &Storage,
|
||||
@@ -426,7 +414,6 @@ async fn nvdimm_storage_handler(
|
||||
}
|
||||
|
||||
// mount_storage performs the mount described by the storage structure.
|
||||
#[instrument]
|
||||
fn mount_storage(logger: &Logger, storage: &Storage) -> Result<()> {
|
||||
let logger = logger.new(o!("subsystem" => "mount"));
|
||||
|
||||
@@ -477,7 +464,6 @@ fn mount_storage(logger: &Logger, storage: &Storage) -> Result<()> {
|
||||
}
|
||||
|
||||
/// Looks for `mount_point` entry in the /proc/mounts.
|
||||
#[instrument]
|
||||
fn is_mounted(mount_point: &str) -> Result<bool> {
|
||||
let mount_point = mount_point.trim_end_matches('/');
|
||||
let found = fs::metadata(mount_point).is_ok()
|
||||
@@ -495,7 +481,6 @@ fn is_mounted(mount_point: &str) -> Result<bool> {
|
||||
Ok(found)
|
||||
}
|
||||
|
||||
#[instrument]
|
||||
fn parse_mount_flags_and_options(options_vec: Vec<&str>) -> (MsFlags, String) {
|
||||
let mut flags = MsFlags::empty();
|
||||
let mut options: String = "".to_string();
|
||||
@@ -524,7 +509,6 @@ fn parse_mount_flags_and_options(options_vec: Vec<&str>) -> (MsFlags, String) {
|
||||
// associated operations such as waiting for the device to show up, and mount
|
||||
// it to a specific location, according to the type of handler chosen, and for
|
||||
// each storage.
|
||||
#[instrument]
|
||||
pub async fn add_storages(
|
||||
logger: Logger,
|
||||
storages: Vec<Storage>,
|
||||
@@ -574,7 +558,6 @@ pub async fn add_storages(
|
||||
Ok(mount_list)
|
||||
}
|
||||
|
||||
#[instrument]
|
||||
fn mount_to_rootfs(logger: &Logger, m: &InitMount) -> Result<()> {
|
||||
let options_vec: Vec<&str> = m.options.clone();
|
||||
|
||||
@@ -600,7 +583,6 @@ fn mount_to_rootfs(logger: &Logger, m: &InitMount) -> Result<()> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[instrument]
|
||||
pub fn general_mount(logger: &Logger) -> Result<()> {
|
||||
let logger = logger.new(o!("subsystem" => "mount"));
|
||||
|
||||
@@ -618,7 +600,6 @@ pub fn get_mount_fs_type(mount_point: &str) -> Result<String> {
|
||||
|
||||
// get_mount_fs_type_from_file returns the FS type corresponding to the passed mount point and
|
||||
// any error ecountered.
|
||||
#[instrument]
|
||||
pub fn get_mount_fs_type_from_file(mount_file: &str, mount_point: &str) -> Result<String> {
|
||||
if mount_point.is_empty() {
|
||||
return Err(anyhow!("Invalid mount point {}", mount_point));
|
||||
@@ -649,7 +630,6 @@ pub fn get_mount_fs_type_from_file(mount_file: &str, mount_point: &str) -> Resul
|
||||
))
|
||||
}
|
||||
|
||||
#[instrument]
|
||||
pub fn get_cgroup_mounts(
|
||||
logger: &Logger,
|
||||
cg_path: &str,
|
||||
@@ -740,7 +720,6 @@ pub fn get_cgroup_mounts(
|
||||
Ok(cg_mounts)
|
||||
}
|
||||
|
||||
#[instrument]
|
||||
pub fn cgroups_mount(logger: &Logger, unified_cgroup_hierarchy: bool) -> Result<()> {
|
||||
let logger = logger.new(o!("subsystem" => "mount"));
|
||||
|
||||
@@ -756,7 +735,6 @@ pub fn cgroups_mount(logger: &Logger, unified_cgroup_hierarchy: bool) -> Result<
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[instrument]
|
||||
pub fn remove_mounts(mounts: &[String]) -> Result<()> {
|
||||
for m in mounts.iter() {
|
||||
mount::umount(m.as_str()).context(format!("failed to umount {:?}", m))?;
|
||||
@@ -766,7 +744,6 @@ pub fn remove_mounts(mounts: &[String]) -> Result<()> {
|
||||
|
||||
// ensure_destination_exists will recursively create a given mountpoint. If directories
|
||||
// are created, their permissions are initialized to mountPerm(0755)
|
||||
#[instrument]
|
||||
fn ensure_destination_exists(destination: &str, fs_type: &str) -> Result<()> {
|
||||
let d = Path::new(destination);
|
||||
if !d.exists() {
|
||||
@@ -787,7 +764,6 @@ fn ensure_destination_exists(destination: &str, fs_type: &str) -> Result<()> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[instrument]
|
||||
fn parse_options(option_list: Vec<String>) -> HashMap<String, String> {
|
||||
let mut options = HashMap::new();
|
||||
for opt in option_list.iter() {
|
||||
|
||||
@@ -11,7 +11,6 @@ use std::fmt;
|
||||
use std::fs;
|
||||
use std::fs::File;
|
||||
use std::path::{Path, PathBuf};
|
||||
use tracing::instrument;
|
||||
|
||||
use crate::mount::{BareMount, FLAGS};
|
||||
use slog::Logger;
|
||||
@@ -21,7 +20,6 @@ pub const NSTYPEIPC: &str = "ipc";
|
||||
pub const NSTYPEUTS: &str = "uts";
|
||||
pub const NSTYPEPID: &str = "pid";
|
||||
|
||||
#[instrument]
|
||||
pub fn get_current_thread_ns_path(ns_type: &str) -> String {
|
||||
format!(
|
||||
"/proc/{}/task/{}/ns/{}",
|
||||
@@ -42,7 +40,6 @@ pub struct Namespace {
|
||||
}
|
||||
|
||||
impl Namespace {
|
||||
#[instrument]
|
||||
pub fn new(logger: &Logger) -> Self {
|
||||
Namespace {
|
||||
logger: logger.clone(),
|
||||
@@ -53,13 +50,11 @@ impl Namespace {
|
||||
}
|
||||
}
|
||||
|
||||
#[instrument]
|
||||
pub fn get_ipc(mut self) -> Self {
|
||||
self.ns_type = NamespaceType::Ipc;
|
||||
self
|
||||
}
|
||||
|
||||
#[instrument]
|
||||
pub fn get_uts(mut self, hostname: &str) -> Self {
|
||||
self.ns_type = NamespaceType::Uts;
|
||||
if !hostname.is_empty() {
|
||||
@@ -68,7 +63,6 @@ impl Namespace {
|
||||
self
|
||||
}
|
||||
|
||||
#[instrument]
|
||||
pub fn get_pid(mut self) -> Self {
|
||||
self.ns_type = NamespaceType::Pid;
|
||||
self
|
||||
@@ -82,7 +76,6 @@ impl Namespace {
|
||||
|
||||
// setup creates persistent namespace without switching to it.
|
||||
// Note, pid namespaces cannot be persisted.
|
||||
#[instrument]
|
||||
pub async fn setup(mut self) -> Result<Self> {
|
||||
fs::create_dir_all(&self.persistent_ns_dir)?;
|
||||
|
||||
|
||||
@@ -9,7 +9,6 @@ use nix::fcntl::{self, OFlag};
|
||||
use nix::sys::stat::Mode;
|
||||
use std::fs;
|
||||
use std::os::unix::io::{AsRawFd, FromRawFd};
|
||||
use tracing::instrument;
|
||||
|
||||
pub const RNGDEV: &str = "/dev/random";
|
||||
pub const RNDADDTOENTCNT: libc::c_int = 0x40045201;
|
||||
@@ -21,7 +20,6 @@ type IoctlRequestType = libc::c_int;
|
||||
#[cfg(target_env = "gnu")]
|
||||
type IoctlRequestType = libc::c_ulong;
|
||||
|
||||
#[instrument]
|
||||
pub fn reseed_rng(data: &[u8]) -> Result<()> {
|
||||
let len = data.len() as libc::c_long;
|
||||
fs::write(RNGDEV, data)?;
|
||||
@@ -39,10 +37,10 @@ pub fn reseed_rng(data: &[u8]) -> Result<()> {
|
||||
&len as *const libc::c_long,
|
||||
)
|
||||
};
|
||||
Errno::result(ret).map(drop)?;
|
||||
let _ = Errno::result(ret).map(drop)?;
|
||||
|
||||
let ret = unsafe { libc::ioctl(f.as_raw_fd(), RNDRESEEDRNG as IoctlRequestType, 0) };
|
||||
Errno::result(ret).map(drop)?;
|
||||
let _ = Errno::result(ret).map(drop)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@@ -103,7 +103,7 @@ impl AgentService {
|
||||
) -> Result<()> {
|
||||
let cid = req.container_id.clone();
|
||||
|
||||
verify_cid(&cid)?;
|
||||
let _ = verify_cid(&cid)?;
|
||||
|
||||
let mut oci_spec = req.OCI.clone();
|
||||
let use_sandbox_pidns = req.get_sandbox_pidns();
|
||||
@@ -926,7 +926,7 @@ impl protocols::agent_ttrpc::AgentService for AgentService {
|
||||
}
|
||||
|
||||
for m in req.kernel_modules.iter() {
|
||||
load_kernel_module(m)
|
||||
let _ = load_kernel_module(m)
|
||||
.map_err(|e| ttrpc_error(ttrpc::Code::INTERNAL, e.to_string()))?;
|
||||
}
|
||||
|
||||
@@ -1529,22 +1529,22 @@ fn setup_bundle(cid: &str, spec: &mut Spec) -> Result<PathBuf> {
|
||||
fn cleanup_process(p: &mut Process) -> Result<()> {
|
||||
if p.parent_stdin.is_some() {
|
||||
p.close_stream(StreamType::ParentStdin);
|
||||
unistd::close(p.parent_stdin.unwrap())?;
|
||||
let _ = unistd::close(p.parent_stdin.unwrap())?;
|
||||
}
|
||||
|
||||
if p.parent_stdout.is_some() {
|
||||
p.close_stream(StreamType::ParentStdout);
|
||||
unistd::close(p.parent_stdout.unwrap())?;
|
||||
let _ = unistd::close(p.parent_stdout.unwrap())?;
|
||||
}
|
||||
|
||||
if p.parent_stderr.is_some() {
|
||||
p.close_stream(StreamType::ParentStderr);
|
||||
unistd::close(p.parent_stderr.unwrap())?;
|
||||
let _ = unistd::close(p.parent_stderr.unwrap())?;
|
||||
}
|
||||
|
||||
if p.term_master.is_some() {
|
||||
p.close_stream(StreamType::TermMaster);
|
||||
unistd::close(p.term_master.unwrap())?;
|
||||
let _ = unistd::close(p.term_master.unwrap())?;
|
||||
}
|
||||
|
||||
p.notify_term_close();
|
||||
|
||||
@@ -28,7 +28,6 @@ use std::{thread, time};
|
||||
use tokio::sync::mpsc::{channel, Receiver, Sender};
|
||||
use tokio::sync::oneshot;
|
||||
use tokio::sync::Mutex;
|
||||
use tracing::instrument;
|
||||
|
||||
type UeventWatcher = (Box<dyn UeventMatcher>, oneshot::Sender<Uevent>);
|
||||
|
||||
@@ -57,7 +56,6 @@ pub struct Sandbox {
|
||||
}
|
||||
|
||||
impl Sandbox {
|
||||
#[instrument]
|
||||
pub fn new(logger: &Logger) -> Result<Self> {
|
||||
let fs_type = get_mount_fs_type("/")?;
|
||||
let logger = logger.new(o!("subsystem" => "sandbox"));
|
||||
@@ -96,7 +94,6 @@ impl Sandbox {
|
||||
//
|
||||
// It's assumed that caller is calling this method after
|
||||
// acquiring a lock on sandbox.
|
||||
#[instrument]
|
||||
pub fn set_sandbox_storage(&mut self, path: &str) -> bool {
|
||||
match self.storages.get_mut(path) {
|
||||
None => {
|
||||
@@ -119,7 +116,6 @@ impl Sandbox {
|
||||
//
|
||||
// It's assumed that caller is calling this method after
|
||||
// acquiring a lock on sandbox.
|
||||
#[instrument]
|
||||
pub fn unset_sandbox_storage(&mut self, path: &str) -> Result<bool> {
|
||||
match self.storages.get_mut(path) {
|
||||
None => Err(anyhow!("Sandbox storage with path {} not found", path)),
|
||||
@@ -139,7 +135,6 @@ impl Sandbox {
|
||||
//
|
||||
// It's assumed that caller is calling this method after
|
||||
// acquiring a lock on sandbox.
|
||||
#[instrument]
|
||||
pub fn remove_sandbox_storage(&self, path: &str) -> Result<()> {
|
||||
let mounts = vec![path.to_string()];
|
||||
remove_mounts(&mounts)?;
|
||||
@@ -153,7 +148,6 @@ impl Sandbox {
|
||||
//
|
||||
// It's assumed that caller is calling this method after
|
||||
// acquiring a lock on sandbox.
|
||||
#[instrument]
|
||||
pub fn unset_and_remove_sandbox_storage(&mut self, path: &str) -> Result<()> {
|
||||
if self.unset_sandbox_storage(path)? {
|
||||
return self.remove_sandbox_storage(path);
|
||||
@@ -162,7 +156,6 @@ impl Sandbox {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[instrument]
|
||||
pub async fn setup_shared_namespaces(&mut self) -> Result<bool> {
|
||||
// Set up shared IPC namespace
|
||||
self.shared_ipcns = Namespace::new(&self.logger)
|
||||
@@ -181,12 +174,10 @@ impl Sandbox {
|
||||
Ok(true)
|
||||
}
|
||||
|
||||
#[instrument]
|
||||
pub fn add_container(&mut self, c: LinuxContainer) {
|
||||
self.containers.insert(c.id.clone(), c);
|
||||
}
|
||||
|
||||
#[instrument]
|
||||
pub fn update_shared_pidns(&mut self, c: &LinuxContainer) -> Result<()> {
|
||||
// Populate the shared pid path only if this is an infra container and
|
||||
// sandbox_pidns has not been passed in the create_sandbox request.
|
||||
@@ -210,12 +201,10 @@ impl Sandbox {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[instrument]
|
||||
pub fn get_container(&mut self, id: &str) -> Option<&mut LinuxContainer> {
|
||||
self.containers.get_mut(id)
|
||||
}
|
||||
|
||||
#[instrument]
|
||||
pub fn find_process(&mut self, pid: pid_t) -> Option<&mut Process> {
|
||||
for (_, c) in self.containers.iter_mut() {
|
||||
if c.processes.get(&pid).is_some() {
|
||||
@@ -226,7 +215,6 @@ impl Sandbox {
|
||||
None
|
||||
}
|
||||
|
||||
#[instrument]
|
||||
pub async fn destroy(&mut self) -> Result<()> {
|
||||
for ctr in self.containers.values_mut() {
|
||||
ctr.destroy().await?;
|
||||
@@ -234,7 +222,6 @@ impl Sandbox {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[instrument]
|
||||
pub fn online_cpu_memory(&self, req: &OnlineCPUMemRequest) -> Result<()> {
|
||||
if req.nb_cpus > 0 {
|
||||
// online cpus
|
||||
@@ -278,7 +265,6 @@ impl Sandbox {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[instrument]
|
||||
pub fn add_hooks(&mut self, dir: &str) -> Result<()> {
|
||||
let mut hooks = Hooks::default();
|
||||
if let Ok(hook) = self.find_hooks(dir, "prestart") {
|
||||
@@ -294,7 +280,6 @@ impl Sandbox {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[instrument]
|
||||
fn find_hooks(&self, hook_path: &str, hook_type: &str) -> Result<Vec<Hook>> {
|
||||
let mut hooks = Vec::new();
|
||||
for entry in fs::read_dir(Path::new(hook_path).join(hook_type))? {
|
||||
@@ -331,7 +316,6 @@ impl Sandbox {
|
||||
Ok(hooks)
|
||||
}
|
||||
|
||||
#[instrument]
|
||||
pub async fn run_oom_event_monitor(&self, mut rx: Receiver<String>, container_id: String) {
|
||||
let logger = self.logger.clone();
|
||||
|
||||
@@ -364,7 +348,6 @@ impl Sandbox {
|
||||
}
|
||||
}
|
||||
|
||||
#[instrument]
|
||||
fn online_resources(logger: &Logger, path: &str, pattern: &str, num: i32) -> Result<i32> {
|
||||
let mut count = 0;
|
||||
let re = Regex::new(pattern)?;
|
||||
@@ -410,7 +393,6 @@ fn online_resources(logger: &Logger, path: &str, pattern: &str, num: i32) -> Res
|
||||
const ONLINE_CPUMEM_WATI_MILLIS: u64 = 50;
|
||||
const ONLINE_CPUMEM_MAX_RETRIES: u32 = 100;
|
||||
|
||||
#[instrument]
|
||||
fn online_cpus(logger: &Logger, num: i32) -> Result<i32> {
|
||||
let mut onlined_count: i32 = 0;
|
||||
|
||||
@@ -440,7 +422,6 @@ fn online_cpus(logger: &Logger, num: i32) -> Result<i32> {
|
||||
))
|
||||
}
|
||||
|
||||
#[instrument]
|
||||
fn online_memory(logger: &Logger) -> Result<()> {
|
||||
online_resources(logger, SYSFS_MEMORY_ONLINE_PATH, r"memory[0-9]+", -1)?;
|
||||
Ok(())
|
||||
|
||||
@@ -6,10 +6,10 @@
|
||||
|
||||
use crate::sandbox::Sandbox;
|
||||
use anyhow::{anyhow, Result};
|
||||
use capctl::prctl::set_subreaper;
|
||||
use nix::sys::wait::WaitPidFlag;
|
||||
use nix::sys::wait::{self, WaitStatus};
|
||||
use nix::unistd;
|
||||
use prctl::set_child_subreaper;
|
||||
use slog::{error, info, o, Logger};
|
||||
use std::sync::Arc;
|
||||
use tokio::select;
|
||||
@@ -88,7 +88,7 @@ pub async fn setup_signal_handler(
|
||||
) -> Result<()> {
|
||||
let logger = logger.new(o!("subsystem" => "signals"));
|
||||
|
||||
set_subreaper(true)
|
||||
set_child_subreaper(true)
|
||||
.map_err(|err| anyhow!(err).context("failed to setup agent as a child subreaper"))?;
|
||||
|
||||
let mut sigchild_stream = signal(SignalKind::child())?;
|
||||
|
||||
@@ -1,91 +0,0 @@
|
||||
// Copyright (c) 2020-2021 Intel Corporation
|
||||
//
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
//
|
||||
|
||||
use crate::config::AgentConfig;
|
||||
use anyhow::Result;
|
||||
use opentelemetry::{global, sdk::trace::Config, trace::TracerProvider};
|
||||
use slog::{info, o, Logger};
|
||||
use std::error::Error;
|
||||
use std::fmt;
|
||||
use std::str::FromStr;
|
||||
use tracing_opentelemetry::OpenTelemetryLayer;
|
||||
use tracing_subscriber::layer::SubscriberExt;
|
||||
use tracing_subscriber::Registry;
|
||||
|
||||
#[derive(Debug, PartialEq)]
|
||||
pub enum TraceType {
|
||||
Disabled,
|
||||
Isolated,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct TraceTypeError {
|
||||
details: String,
|
||||
}
|
||||
|
||||
impl TraceTypeError {
|
||||
fn new(msg: &str) -> TraceTypeError {
|
||||
TraceTypeError {
|
||||
details: msg.into(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Error for TraceTypeError {}
|
||||
|
||||
impl fmt::Display for TraceTypeError {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(f, "{}", self.details)
|
||||
}
|
||||
}
|
||||
|
||||
impl FromStr for TraceType {
|
||||
type Err = TraceTypeError;
|
||||
|
||||
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
||||
match s {
|
||||
"isolated" => Ok(TraceType::Isolated),
|
||||
"disabled" => Ok(TraceType::Disabled),
|
||||
_ => Err(TraceTypeError::new("invalid trace type")),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn setup_tracing(name: &'static str, logger: &Logger, _agent_cfg: &AgentConfig) -> Result<()> {
|
||||
let logger = logger.new(o!("subsystem" => "vsock-tracer"));
|
||||
|
||||
let exporter = vsock_exporter::Exporter::builder()
|
||||
.with_logger(&logger)
|
||||
.init();
|
||||
|
||||
let config = Config::default();
|
||||
|
||||
let builder = opentelemetry::sdk::trace::TracerProvider::builder()
|
||||
.with_simple_exporter(exporter)
|
||||
.with_config(config);
|
||||
|
||||
let provider = builder.build();
|
||||
|
||||
// We don't need a versioned tracer.
|
||||
let version = None;
|
||||
|
||||
let tracer = provider.get_tracer(name, version);
|
||||
|
||||
let _global_provider = global::set_tracer_provider(provider);
|
||||
|
||||
let layer = OpenTelemetryLayer::new(tracer);
|
||||
|
||||
let subscriber = Registry::default().with(layer);
|
||||
|
||||
tracing::subscriber::set_global_default(subscriber)?;
|
||||
|
||||
info!(logger, "tracing setup");
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn end_tracing() {
|
||||
global::shutdown_tracer_provider();
|
||||
}
|
||||
@@ -18,7 +18,6 @@ use std::sync::Arc;
|
||||
use tokio::select;
|
||||
use tokio::sync::watch::Receiver;
|
||||
use tokio::sync::Mutex;
|
||||
use tracing::instrument;
|
||||
|
||||
// Convenience macro to obtain the scope logger
|
||||
macro_rules! sl {
|
||||
@@ -65,7 +64,6 @@ impl Uevent {
|
||||
event
|
||||
}
|
||||
|
||||
#[instrument]
|
||||
async fn process_add(&self, logger: &Logger, sandbox: &Arc<Mutex<Sandbox>>) {
|
||||
// Special case for memory hot-adds first
|
||||
let online_path = format!("{}/{}/online", SYSFS_DIR, &self.devpath);
|
||||
@@ -97,7 +95,6 @@ impl Uevent {
|
||||
}
|
||||
}
|
||||
|
||||
#[instrument]
|
||||
async fn process(&self, logger: &Logger, sandbox: &Arc<Mutex<Sandbox>>) {
|
||||
if self.action == U_EVENT_ACTION_ADD {
|
||||
return self.process_add(logger, sandbox).await;
|
||||
@@ -106,7 +103,6 @@ impl Uevent {
|
||||
}
|
||||
}
|
||||
|
||||
#[instrument]
|
||||
pub async fn wait_for_uevent(
|
||||
sandbox: &Arc<Mutex<Sandbox>>,
|
||||
matcher: impl UeventMatcher,
|
||||
@@ -149,7 +145,6 @@ pub async fn wait_for_uevent(
|
||||
Ok(uev)
|
||||
}
|
||||
|
||||
#[instrument]
|
||||
pub async fn watch_uevents(
|
||||
sandbox: Arc<Mutex<Sandbox>>,
|
||||
mut shutdown: Receiver<bool>,
|
||||
|
||||
@@ -11,7 +11,6 @@ use std::os::unix::io::{FromRawFd, RawFd};
|
||||
use tokio::io::{AsyncReadExt, AsyncWriteExt};
|
||||
use tokio::sync::watch::Receiver;
|
||||
use tokio_vsock::{Incoming, VsockListener, VsockStream};
|
||||
use tracing::instrument;
|
||||
|
||||
// Size of I/O read buffer
|
||||
const BUF_SIZE: usize = 8192;
|
||||
@@ -57,12 +56,10 @@ where
|
||||
Ok(total_bytes)
|
||||
}
|
||||
|
||||
#[instrument]
|
||||
pub fn get_vsock_incoming(fd: RawFd) -> Incoming {
|
||||
unsafe { VsockListener::from_raw_fd(fd).incoming() }
|
||||
}
|
||||
|
||||
#[instrument]
|
||||
pub async fn get_vsock_stream(fd: RawFd) -> Result<VsockStream> {
|
||||
let stream = get_vsock_incoming(fd).next().await.unwrap()?;
|
||||
Ok(stream)
|
||||
|
||||
@@ -1,19 +0,0 @@
|
||||
[package]
|
||||
name = "vsock-exporter"
|
||||
version = "0.1.0"
|
||||
authors = ["James O. D. Hunt <james.o.hunt@intel.com>"]
|
||||
edition = "2018"
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
||||
nix = "0.20.0"
|
||||
libc = "0.2.94"
|
||||
thiserror = "1.0.24"
|
||||
opentelemetry = { version = "0.14.0", features=["serialize"] }
|
||||
serde = { version = "1.0.126", features = ["derive"] }
|
||||
vsock = "0.2.3"
|
||||
bincode = "1.3.3"
|
||||
byteorder = "1.4.3"
|
||||
slog = { version = "2.5.2", features = ["dynamic-keys", "max_level_trace", "release_max_level_info"] }
|
||||
async-trait = "0.1.50"
|
||||
@@ -1,196 +0,0 @@
|
||||
// Copyright (c) 2020-2021 Intel Corporation
|
||||
//
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
//
|
||||
|
||||
// The VSOCK Exporter sends trace spans "out" to the forwarder running on the
|
||||
// host (which then forwards them on to a trace collector). The data is sent
|
||||
// via a VSOCK socket that the forwarder process is listening on. To allow the
|
||||
// forwarder to know how much data to each for each trace span the simplest
|
||||
// protocol is employed which uses a header packet and the payload (trace
|
||||
// span) data. The header packet is a simple count of the number of bytes in the
|
||||
// payload, which allows the forwarder to know how many bytes it must read to
|
||||
// consume the trace span. The payload is a serialised version of the trace span.
|
||||
|
||||
use async_trait::async_trait;
|
||||
use byteorder::{ByteOrder, NetworkEndian};
|
||||
use opentelemetry::sdk::export::trace::{ExportResult, SpanData, SpanExporter};
|
||||
use opentelemetry::sdk::export::ExportError;
|
||||
use slog::{error, o, Logger};
|
||||
use std::io::{ErrorKind, Write};
|
||||
use std::net::Shutdown;
|
||||
use std::sync::Mutex;
|
||||
use vsock::{SockAddr, VsockStream};
|
||||
|
||||
const ANY_CID: &str = "any";
|
||||
|
||||
// Must match the value of the variable of the same name in the trace forwarder.
|
||||
const HEADER_SIZE_BYTES: u64 = std::mem::size_of::<u64>() as u64;
|
||||
|
||||
// By default, the VSOCK exporter should talk "out" to the host where the
|
||||
// forwarder is running.
|
||||
const DEFAULT_CID: u32 = libc::VMADDR_CID_HOST;
|
||||
|
||||
// The VSOCK port the forwarders listens on by default
|
||||
const DEFAULT_PORT: u32 = 10240;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct Exporter {
|
||||
port: u32,
|
||||
cid: u32,
|
||||
conn: Mutex<VsockStream>,
|
||||
logger: Logger,
|
||||
}
|
||||
|
||||
impl Exporter {
|
||||
/// Create a new exporter builder.
|
||||
pub fn builder() -> Builder {
|
||||
Builder::default()
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(thiserror::Error, Debug)]
|
||||
pub enum Error {
|
||||
#[error("connection error: {0}")]
|
||||
ConnectionError(String),
|
||||
#[error("serialisation error: {0}")]
|
||||
SerialisationError(#[from] bincode::Error),
|
||||
#[error("I/O error: {0}")]
|
||||
IOError(#[from] std::io::Error),
|
||||
}
|
||||
|
||||
impl ExportError for Error {
|
||||
fn exporter_name(&self) -> &'static str {
|
||||
"vsock-exporter"
|
||||
}
|
||||
}
|
||||
|
||||
fn make_io_error(desc: String) -> std::io::Error {
|
||||
std::io::Error::new(ErrorKind::Other, desc)
|
||||
}
|
||||
|
||||
// Send a trace span to the forwarder running on the host.
|
||||
fn write_span(writer: &mut dyn Write, span: &SpanData) -> Result<(), std::io::Error> {
|
||||
let encoded_payload: Vec<u8> =
|
||||
bincode::serialize(&span).map_err(|e| make_io_error(e.to_string()))?;
|
||||
|
||||
let payload_len: u64 = encoded_payload.len() as u64;
|
||||
|
||||
let mut payload_len_as_bytes: [u8; HEADER_SIZE_BYTES as usize] =
|
||||
[0; HEADER_SIZE_BYTES as usize];
|
||||
|
||||
// Encode the header
|
||||
NetworkEndian::write_u64(&mut payload_len_as_bytes, payload_len);
|
||||
|
||||
// Send the header
|
||||
writer
|
||||
.write_all(&payload_len_as_bytes)
|
||||
.map_err(|e| make_io_error(format!("failed to write trace header: {:?}", e)))?;
|
||||
|
||||
writer
|
||||
.write_all(&encoded_payload)
|
||||
.map_err(|e| make_io_error(format!("failed to write trace payload: {:?}", e)))
|
||||
}
|
||||
|
||||
fn handle_batch(writer: &mut dyn Write, batch: Vec<SpanData>) -> ExportResult {
|
||||
for span_data in batch {
|
||||
write_span(writer, &span_data).map_err(Error::IOError)?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[async_trait]
|
||||
impl SpanExporter for Exporter {
|
||||
async fn export(&mut self, batch: Vec<SpanData>) -> ExportResult {
|
||||
let conn = self.conn.lock();
|
||||
|
||||
match conn {
|
||||
Ok(mut c) => handle_batch(&mut *c, batch),
|
||||
Err(e) => {
|
||||
error!(self.logger, "failed to obtain connection";
|
||||
"error" => format!("{}", e));
|
||||
|
||||
return Err(Error::ConnectionError(e.to_string()).into());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn shutdown(&mut self) {
|
||||
let conn = match self.conn.lock() {
|
||||
Ok(conn) => conn,
|
||||
Err(e) => {
|
||||
error!(self.logger, "failed to obtain connection";
|
||||
"error" => format!("{}", e));
|
||||
return;
|
||||
}
|
||||
};
|
||||
|
||||
conn.shutdown(Shutdown::Write)
|
||||
.expect("failed to shutdown VSOCK connection");
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct Builder {
|
||||
port: u32,
|
||||
cid: u32,
|
||||
logger: Logger,
|
||||
}
|
||||
|
||||
impl Default for Builder {
|
||||
fn default() -> Self {
|
||||
let logger = Logger::root(slog::Discard, o!());
|
||||
|
||||
Builder {
|
||||
cid: DEFAULT_CID,
|
||||
port: DEFAULT_PORT,
|
||||
logger,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Builder {
|
||||
pub fn with_cid(self, cid: u32) -> Self {
|
||||
Builder { cid, ..self }
|
||||
}
|
||||
|
||||
pub fn with_port(self, port: u32) -> Self {
|
||||
Builder { port, ..self }
|
||||
}
|
||||
|
||||
pub fn with_logger(self, logger: &Logger) -> Self {
|
||||
Builder {
|
||||
logger: logger.new(o!()),
|
||||
..self
|
||||
}
|
||||
}
|
||||
|
||||
pub fn init(self) -> Exporter {
|
||||
let Builder { port, cid, logger } = self;
|
||||
|
||||
let sock_addr = SockAddr::new_vsock(self.cid, self.port);
|
||||
|
||||
let cid_str: String;
|
||||
|
||||
if self.cid == libc::VMADDR_CID_ANY {
|
||||
cid_str = ANY_CID.to_string();
|
||||
} else {
|
||||
cid_str = format!("{}", self.cid);
|
||||
}
|
||||
|
||||
let msg = format!(
|
||||
"failed to connect to VSOCK server (port: {}, cid: {}) - {}",
|
||||
self.port, cid_str, "ensure trace forwarder is running on host"
|
||||
);
|
||||
|
||||
let conn = VsockStream::connect(&sock_addr).expect(&msg);
|
||||
|
||||
Exporter {
|
||||
port,
|
||||
cid,
|
||||
conn: Mutex::new(conn),
|
||||
logger: logger.new(o!("cid" => cid_str, "port" => port)),
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -11,10 +11,3 @@ MACHINEACCELERATORS :=
|
||||
CPUFEATURES :=
|
||||
|
||||
QEMUCMD := qemu-system-s390x
|
||||
|
||||
# See https://github.com/kata-containers/osbuilder/issues/217
|
||||
FEDORA_LIKE = $(shell grep -E "\<fedora\>" /etc/os-release 2> /dev/null)
|
||||
ifneq (,$(FEDORA_LIKE))
|
||||
CC := gcc
|
||||
export CC
|
||||
endif
|
||||
|
||||
@@ -16,14 +16,6 @@ kernel = "@KERNELPATH@"
|
||||
image = "@IMAGEPATH@"
|
||||
machine_type = "@MACHINETYPE@"
|
||||
|
||||
# Enable confidential guest support.
|
||||
# Toggling that setting may trigger different hardware features, ranging
|
||||
# from memory encryption to both memory and CPU-state encryption and integrity.
|
||||
# The Kata Containers runtime dynamically detects the available feature set and
|
||||
# aims at enabling the largest possible one.
|
||||
# Default false
|
||||
# confidential_guest = true
|
||||
|
||||
# List of valid annotation names for the hypervisor
|
||||
# Each member of the list is a regular expression, which is the base name
|
||||
# of the annotation, e.g. "path" for io.katacontainers.config.hypervisor.path"
|
||||
@@ -544,30 +536,3 @@ experimental=@DEFAULTEXPFEATURES@
|
||||
# If enabled, user can run pprof tools with shim v2 process through kata-monitor.
|
||||
# (default: false)
|
||||
# enable_pprof = true
|
||||
|
||||
# WARNING: All the options in the following section have not been implemented yet.
|
||||
# This section was added as a placeholder. DO NOT USE IT!
|
||||
[image]
|
||||
# Container image service.
|
||||
#
|
||||
# Offload the CRI image management service to the Kata agent.
|
||||
# (default: false)
|
||||
#service_offload = true
|
||||
|
||||
# Container image decryption keys provisioning.
|
||||
# Applies only if service_offload is true.
|
||||
# Keys can be provisioned locally (e.g. through a special command or
|
||||
# a local file) or remotely (usually after the guest is remotely attested).
|
||||
# The provision setting is a complete URL that lets the Kata agent decide
|
||||
# which method to use in order to fetch the keys.
|
||||
#
|
||||
# Keys can be stored in a local file, in a measured and attested initrd:
|
||||
#provision=data:///local/key/file
|
||||
#
|
||||
# Keys could be fetched through a special command or binary from the
|
||||
# initrd (guest) image, e.g. a firmware call:
|
||||
#provision=file:///path/to/bin/fetcher/in/guest
|
||||
#
|
||||
# Keys can be remotely provisioned. The Kata agent fetches them from e.g.
|
||||
# a HTTPS URL:
|
||||
#provision=https://my-key-broker.foo/tenant/<tenant-id>
|
||||
|
||||
@@ -22,7 +22,6 @@ import (
|
||||
vc "github.com/kata-containers/kata-containers/src/runtime/virtcontainers"
|
||||
exp "github.com/kata-containers/kata-containers/src/runtime/virtcontainers/experimental"
|
||||
vf "github.com/kata-containers/kata-containers/src/runtime/virtcontainers/factory"
|
||||
tl "github.com/kata-containers/kata-containers/src/runtime/virtcontainers/factory/template"
|
||||
"github.com/kata-containers/kata-containers/src/runtime/virtcontainers/pkg/oci"
|
||||
"github.com/kata-containers/kata-containers/src/runtime/virtcontainers/pkg/rootless"
|
||||
specs "github.com/opencontainers/runtime-spec/specs-go"
|
||||
@@ -202,9 +201,6 @@ func setExternalLoggers(ctx context.Context, logger *logrus.Entry) {
|
||||
// Set vm factory logger.
|
||||
vf.SetLogger(ctx, logger)
|
||||
|
||||
// Set vm factory template logger.
|
||||
tl.SetLogger(ctx, logger)
|
||||
|
||||
// Set the OCI package logger.
|
||||
oci.SetLogger(ctx, logger)
|
||||
|
||||
|
||||
@@ -294,7 +294,8 @@ func trace(ctx context.Context, name string) (otelTrace.Span, context.Context) {
|
||||
ctx = context.Background()
|
||||
}
|
||||
tracer := otel.Tracer("kata")
|
||||
ctx, span := tracer.Start(ctx, name, otelTrace.WithAttributes(label.String("source", "runtime"), label.String("package", "containerdshim")))
|
||||
ctx, span := tracer.Start(ctx, name)
|
||||
span.SetAttributes([]label.KeyValue{label.Key("source").String("runtime"), label.Key("package").String("containerdshim")}...)
|
||||
|
||||
return span, ctx
|
||||
}
|
||||
|
||||
@@ -14,7 +14,7 @@ import (
|
||||
)
|
||||
|
||||
func startContainer(ctx context.Context, s *service, c *container) error {
|
||||
// start a container
|
||||
//start a container
|
||||
if c.cType == "" {
|
||||
err := fmt.Errorf("Bug, the container %s type is empty", c.id)
|
||||
return err
|
||||
@@ -37,8 +37,8 @@ func startContainer(ctx context.Context, s *service, c *container) error {
|
||||
}
|
||||
go watchSandbox(ctx, s)
|
||||
|
||||
// We use s.ctx(`ctx` derived from `s.ctx`) to check for cancellation of the
|
||||
// shim context and the context passed to startContainer for tracing.
|
||||
// We don't rely on the context passed to startContainer as it can be cancelled after
|
||||
// this rpc call.
|
||||
go watchOOMEvents(ctx, s)
|
||||
} else {
|
||||
_, err := s.sandbox.StartContainer(ctx, c.id)
|
||||
@@ -74,10 +74,10 @@ func startContainer(ctx context.Context, s *service, c *container) error {
|
||||
c.ttyio = tty
|
||||
go ioCopy(c.exitIOch, c.stdinCloser, tty, stdin, stdout, stderr)
|
||||
} else {
|
||||
// close the io exit channel, since there is no io for this container,
|
||||
// otherwise the following wait goroutine will hang on this channel.
|
||||
//close the io exit channel, since there is no io for this container,
|
||||
//otherwise the following wait goroutine will hang on this channel.
|
||||
close(c.exitIOch)
|
||||
// close the stdin closer channel to notify that it's safe to close process's
|
||||
//close the stdin closer channel to notify that it's safe to close process's
|
||||
// io.
|
||||
close(c.stdinCloser)
|
||||
}
|
||||
@@ -88,7 +88,7 @@ func startContainer(ctx context.Context, s *service, c *container) error {
|
||||
}
|
||||
|
||||
func startExec(ctx context.Context, s *service, containerID, execID string) (*exec, error) {
|
||||
// start an exec
|
||||
//start an exec
|
||||
c, err := s.getContainer(containerID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
||||
@@ -30,7 +30,7 @@ require (
|
||||
github.com/gogo/googleapis v1.4.0 // indirect
|
||||
github.com/gogo/protobuf v1.3.1
|
||||
github.com/hashicorp/go-multierror v1.0.0
|
||||
github.com/kata-containers/govmm v0.0.0-20210520142420-eb57f004d89f
|
||||
github.com/kata-containers/govmm v0.0.0-20210428163604-f0e9a35308ee
|
||||
github.com/mdlayher/vsock v0.0.0-20191108225356-d9c65923cb8f
|
||||
github.com/opencontainers/image-spec v1.0.1 // indirect
|
||||
github.com/opencontainers/runc v1.0.0-rc9.0.20200102164712-2b52db75279c
|
||||
|
||||
@@ -270,8 +270,6 @@ github.com/juju/testing v0.0.0-20190613124551-e81189438503/go.mod h1:63prj8cnj0t
|
||||
github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w=
|
||||
github.com/kata-containers/govmm v0.0.0-20210428163604-f0e9a35308ee h1:M4N7AdSHgWz/ubV5AZQdeqmK+9Ztpea6oqeXgk8GCHk=
|
||||
github.com/kata-containers/govmm v0.0.0-20210428163604-f0e9a35308ee/go.mod h1:VmAHbsL5lLfzHW/MNL96NVLF840DNEV5i683kISgFKk=
|
||||
github.com/kata-containers/govmm v0.0.0-20210520142420-eb57f004d89f h1:jXMZY7GIz5kSv3/Rdiesg1WMvgXJKNOk3KxwxgNWAVk=
|
||||
github.com/kata-containers/govmm v0.0.0-20210520142420-eb57f004d89f/go.mod h1:VmAHbsL5lLfzHW/MNL96NVLF840DNEV5i683kISgFKk=
|
||||
github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00=
|
||||
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
|
||||
github.com/konsorten/go-windows-terminal-sequences v1.0.1 h1:mweAR1A6xJ3oS2pRaGiHgQ4OO8tzTaLawm8vnODuwDk=
|
||||
|
||||
@@ -54,7 +54,6 @@ const defaultDisableImageNvdimm = false
|
||||
const defaultVhostUserStorePath string = "/var/run/kata-containers/vhost-user/"
|
||||
const defaultRxRateLimiterMaxRate = uint64(0)
|
||||
const defaultTxRateLimiterMaxRate = uint64(0)
|
||||
const defaultConfidentialGuest = false
|
||||
|
||||
var defaultSGXEPCSize = int64(0)
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright (c) 2018-2021 Intel Corporation
|
||||
// Copyright (c) 2018 Intel Corporation
|
||||
// Copyright (c) 2018 HyperHQ Inc.
|
||||
//
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
@@ -61,12 +61,6 @@ type tomlConfig struct {
|
||||
Runtime runtime
|
||||
Factory factory
|
||||
Netmon netmon
|
||||
Image image
|
||||
}
|
||||
|
||||
type image struct {
|
||||
ServiceOffload bool `toml:"service_offload"`
|
||||
Provision string `toml:"provision"`
|
||||
}
|
||||
|
||||
type factory struct {
|
||||
@@ -136,7 +130,6 @@ type hypervisor struct {
|
||||
HotplugVFIOOnRootBus bool `toml:"hotplug_vfio_on_root_bus"`
|
||||
DisableVhostNet bool `toml:"disable_vhost_net"`
|
||||
GuestMemoryDumpPaging bool `toml:"guest_memory_dump_paging"`
|
||||
ConfidentialGuest bool `toml:"confidential_guest"`
|
||||
}
|
||||
|
||||
type runtime struct {
|
||||
@@ -714,7 +707,6 @@ func newQemuHypervisorConfig(h hypervisor) (vc.HypervisorConfig, error) {
|
||||
EnableAnnotations: h.EnableAnnotations,
|
||||
GuestMemoryDumpPath: h.GuestMemoryDumpPath,
|
||||
GuestMemoryDumpPaging: h.GuestMemoryDumpPaging,
|
||||
ConfidentialGuest: h.ConfidentialGuest,
|
||||
}, nil
|
||||
}
|
||||
|
||||
@@ -1069,7 +1061,6 @@ func GetDefaultHypervisorConfig() vc.HypervisorConfig {
|
||||
RxRateLimiterMaxRate: defaultRxRateLimiterMaxRate,
|
||||
TxRateLimiterMaxRate: defaultTxRateLimiterMaxRate,
|
||||
SGXEPCSize: defaultSGXEPCSize,
|
||||
ConfidentialGuest: defaultConfidentialGuest,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -104,7 +104,7 @@ func SetEphemeralStorageType(ociSpec specs.Spec) specs.Spec {
|
||||
// CreateSandbox create a sandbox container
|
||||
func CreateSandbox(ctx context.Context, vci vc.VC, ociSpec specs.Spec, runtimeConfig oci.RuntimeConfig, rootFs vc.RootFs,
|
||||
containerID, bundlePath, console string, disableOutput, systemdCgroup bool) (_ vc.VCSandbox, _ vc.Process, err error) {
|
||||
span, ctx := Trace(ctx, "CreateSandbox", []label.KeyValue{label.Key("source").String("runtime"), label.Key("package").String("katautils"), label.Key("subsystem").String("sandbox"), label.Key("container_id").String(containerID)}...)
|
||||
span, ctx := Trace(ctx, "createSandbox")
|
||||
defer span.End()
|
||||
|
||||
sandboxConfig, err := oci.SandboxConfig(ociSpec, runtimeConfig, bundlePath, containerID, console, disableOutput, systemdCgroup)
|
||||
@@ -159,7 +159,7 @@ func CreateSandbox(ctx context.Context, vci vc.VC, ociSpec specs.Spec, runtimeCo
|
||||
|
||||
sid := sandbox.ID()
|
||||
kataUtilsLogger = kataUtilsLogger.WithField("sandbox", sid)
|
||||
span.SetAttributes(label.Key("sandbox_id").String(sid))
|
||||
span.SetAttributes(label.Key("sandbox").String(sid))
|
||||
|
||||
containers := sandbox.GetAllContainers()
|
||||
if len(containers) != 1 {
|
||||
@@ -202,7 +202,7 @@ func checkForFIPS(sandboxConfig *vc.SandboxConfig) error {
|
||||
func CreateContainer(ctx context.Context, sandbox vc.VCSandbox, ociSpec specs.Spec, rootFs vc.RootFs, containerID, bundlePath, console string, disableOutput bool) (vc.Process, error) {
|
||||
var c vc.VCContainer
|
||||
|
||||
span, ctx := Trace(ctx, "CreateContainer", []label.KeyValue{label.Key("source").String("runtime"), label.Key("package").String("katautils"), label.Key("subsystem").String("sandbox"), label.Key("container_id").String(containerID)}...)
|
||||
span, ctx := Trace(ctx, "createContainer")
|
||||
defer span.End()
|
||||
|
||||
ociSpec = SetEphemeralStorageType(ociSpec)
|
||||
@@ -228,7 +228,7 @@ func CreateContainer(ctx context.Context, sandbox vc.VCSandbox, ociSpec specs.Sp
|
||||
return vc.Process{}, err
|
||||
}
|
||||
|
||||
span.SetAttributes(label.Key("sandbox_id").String(sandboxID))
|
||||
span.SetAttributes(label.Key("sandbox").String(sandboxID))
|
||||
|
||||
c, err = sandbox.CreateContainer(ctx, contConfig)
|
||||
if err != nil {
|
||||
|
||||
@@ -26,9 +26,11 @@ func hookLogger() *logrus.Entry {
|
||||
}
|
||||
|
||||
func runHook(ctx context.Context, hook specs.Hook, cid, bundlePath string) error {
|
||||
span, _ := Trace(ctx, "runHook", []label.KeyValue{label.Key("source").String("runtime"), label.Key("package").String("katautils"), label.Key("subsystem").String("hook")}...)
|
||||
span, _ := Trace(ctx, "hook")
|
||||
defer span.End()
|
||||
|
||||
span.SetAttributes(label.Key("subsystem").String("runHook"))
|
||||
|
||||
// FIXME
|
||||
// span.LogFields(
|
||||
// log.String("hook-name", hook.Path),
|
||||
@@ -88,9 +90,11 @@ func runHook(ctx context.Context, hook specs.Hook, cid, bundlePath string) error
|
||||
}
|
||||
|
||||
func runHooks(ctx context.Context, hooks []specs.Hook, cid, bundlePath, hookType string) error {
|
||||
span, _ := Trace(ctx, "runHooks", []label.KeyValue{label.Key("source").String("runtime"), label.Key("package").String("katautils"), label.Key("subsystem").String("hook"), label.Key("type").String(hookType)}...)
|
||||
span, _ := Trace(ctx, "hooks")
|
||||
defer span.End()
|
||||
|
||||
span.SetAttributes(label.Key("subsystem").String(hookType))
|
||||
|
||||
for _, hook := range hooks {
|
||||
if err := runHook(ctx, hook, cid, bundlePath); err != nil {
|
||||
hookLogger().WithFields(logrus.Fields{
|
||||
|
||||
@@ -110,11 +110,12 @@ func StopTracing(ctx context.Context) {
|
||||
}
|
||||
|
||||
// Trace creates a new tracing span based on the specified name and parent
|
||||
// context and an opentelemetry label.KeyValue slice for span attributes.
|
||||
func Trace(parent context.Context, name string, tags ...label.KeyValue) (otelTrace.Span, context.Context) {
|
||||
// context.
|
||||
func Trace(parent context.Context, name string) (otelTrace.Span, context.Context) {
|
||||
|
||||
tracer := otel.Tracer("kata")
|
||||
ctx, span := tracer.Start(parent, name, otelTrace.WithAttributes(tags...))
|
||||
ctx, span := tracer.Start(parent, name)
|
||||
span.SetAttributes(label.Key("source").String("runtime"))
|
||||
|
||||
// This is slightly confusing: when tracing is disabled, trace spans
|
||||
// are still created - but the tracer used is a NOP. Therefore, only
|
||||
|
||||
80
src/runtime/vendor/github.com/kata-containers/govmm/qemu/qemu.go
generated
vendored
80
src/runtime/vendor/github.com/kata-containers/govmm/qemu/qemu.go
generated
vendored
@@ -134,9 +134,6 @@ const (
|
||||
|
||||
// Loader is the Loader device driver.
|
||||
Loader DeviceDriver = "loader"
|
||||
|
||||
// SpaprTPMProxy is used for enabling guest to run in secure mode on ppc64le.
|
||||
SpaprTPMProxy DeviceDriver = "spapr-tpm-proxy"
|
||||
)
|
||||
|
||||
func isDimmSupported(config *Config) bool {
|
||||
@@ -233,14 +230,6 @@ const (
|
||||
|
||||
// TDXGuest represents a TDX object
|
||||
TDXGuest ObjectType = "tdx-guest"
|
||||
|
||||
// SEVGuest represents an SEV guest object
|
||||
SEVGuest ObjectType = "sev-guest"
|
||||
|
||||
// SecExecGuest represents an s390x Secure Execution (Protected Virtualization in QEMU) object
|
||||
SecExecGuest ObjectType = "s390-pv-guest"
|
||||
// PEFGuest represent ppc64le PEF(Protected Execution Facility) object.
|
||||
PEFGuest ObjectType = "pef-guest"
|
||||
)
|
||||
|
||||
// Object is a qemu object representation.
|
||||
@@ -269,42 +258,37 @@ type Object struct {
|
||||
|
||||
// File is the device file
|
||||
File string
|
||||
|
||||
// CBitPos is the location of the C-bit in a guest page table entry
|
||||
// This is only relevant for sev-guest objects
|
||||
CBitPos uint32
|
||||
|
||||
// ReducedPhysBits is the reduction in the guest physical address space
|
||||
// This is only relevant for sev-guest objects
|
||||
ReducedPhysBits uint32
|
||||
}
|
||||
|
||||
// Valid returns true if the Object structure is valid and complete.
|
||||
func (object Object) Valid() bool {
|
||||
switch object.Type {
|
||||
case MemoryBackendFile:
|
||||
return object.ID != "" && object.MemPath != "" && object.Size != 0
|
||||
if object.ID == "" || object.MemPath == "" || object.Size == 0 {
|
||||
return false
|
||||
}
|
||||
|
||||
case TDXGuest:
|
||||
return object.ID != "" && object.File != "" && object.DeviceID != ""
|
||||
case SEVGuest:
|
||||
return object.ID != "" && object.File != "" && object.CBitPos != 0 && object.ReducedPhysBits != 0
|
||||
case SecExecGuest:
|
||||
return object.ID != ""
|
||||
case PEFGuest:
|
||||
return object.ID != "" && object.File != ""
|
||||
if object.ID == "" || object.File == "" || object.DeviceID == "" {
|
||||
return false
|
||||
}
|
||||
|
||||
default:
|
||||
return false
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
// QemuParams returns the qemu parameters built out of this Object device.
|
||||
func (object Object) QemuParams(config *Config) []string {
|
||||
var objectParams []string
|
||||
var deviceParams []string
|
||||
var driveParams []string
|
||||
var qemuParams []string
|
||||
|
||||
deviceParams = append(deviceParams, string(object.Driver))
|
||||
deviceParams = append(deviceParams, fmt.Sprintf(",id=%s", object.DeviceID))
|
||||
|
||||
switch object.Type {
|
||||
case MemoryBackendFile:
|
||||
objectParams = append(objectParams, string(object.Type))
|
||||
@@ -312,8 +296,6 @@ func (object Object) QemuParams(config *Config) []string {
|
||||
objectParams = append(objectParams, fmt.Sprintf(",mem-path=%s", object.MemPath))
|
||||
objectParams = append(objectParams, fmt.Sprintf(",size=%d", object.Size))
|
||||
|
||||
deviceParams = append(deviceParams, string(object.Driver))
|
||||
deviceParams = append(deviceParams, fmt.Sprintf(",id=%s", object.DeviceID))
|
||||
deviceParams = append(deviceParams, fmt.Sprintf(",memdev=%s", object.ID))
|
||||
case TDXGuest:
|
||||
objectParams = append(objectParams, string(object.Type))
|
||||
@@ -321,44 +303,14 @@ func (object Object) QemuParams(config *Config) []string {
|
||||
if object.Debug {
|
||||
objectParams = append(objectParams, ",debug=on")
|
||||
}
|
||||
deviceParams = append(deviceParams, string(object.Driver))
|
||||
deviceParams = append(deviceParams, fmt.Sprintf(",id=%s", object.DeviceID))
|
||||
deviceParams = append(deviceParams, fmt.Sprintf(",file=%s", object.File))
|
||||
case SEVGuest:
|
||||
objectParams = append(objectParams, string(object.Type))
|
||||
objectParams = append(objectParams, fmt.Sprintf(",id=%s", object.ID))
|
||||
objectParams = append(objectParams, fmt.Sprintf(",cbitpos=%d", object.CBitPos))
|
||||
objectParams = append(objectParams, fmt.Sprintf(",reduced-phys-bits=%d", object.ReducedPhysBits))
|
||||
|
||||
driveParams = append(driveParams, "if=pflash,format=raw,readonly=on")
|
||||
driveParams = append(driveParams, fmt.Sprintf(",file=%s", object.File))
|
||||
case SecExecGuest:
|
||||
objectParams = append(objectParams, string(object.Type))
|
||||
objectParams = append(objectParams, fmt.Sprintf(",id=%s", object.ID))
|
||||
case PEFGuest:
|
||||
objectParams = append(objectParams, string(object.Type))
|
||||
objectParams = append(objectParams, fmt.Sprintf(",id=%s", object.ID))
|
||||
|
||||
deviceParams = append(deviceParams, string(object.Driver))
|
||||
deviceParams = append(deviceParams, fmt.Sprintf(",id=%s", object.DeviceID))
|
||||
deviceParams = append(deviceParams, fmt.Sprintf(",host-path=%s", object.File))
|
||||
|
||||
}
|
||||
|
||||
if len(deviceParams) > 0 {
|
||||
qemuParams = append(qemuParams, "-device")
|
||||
qemuParams = append(qemuParams, strings.Join(deviceParams, ""))
|
||||
}
|
||||
qemuParams = append(qemuParams, "-device")
|
||||
qemuParams = append(qemuParams, strings.Join(deviceParams, ""))
|
||||
|
||||
if len(objectParams) > 0 {
|
||||
qemuParams = append(qemuParams, "-object")
|
||||
qemuParams = append(qemuParams, strings.Join(objectParams, ""))
|
||||
}
|
||||
|
||||
if len(driveParams) > 0 {
|
||||
qemuParams = append(qemuParams, "-drive")
|
||||
qemuParams = append(qemuParams, strings.Join(driveParams, ""))
|
||||
}
|
||||
qemuParams = append(qemuParams, "-object")
|
||||
qemuParams = append(qemuParams, strings.Join(objectParams, ""))
|
||||
|
||||
return qemuParams
|
||||
}
|
||||
|
||||
2
src/runtime/vendor/modules.txt
vendored
2
src/runtime/vendor/modules.txt
vendored
@@ -221,7 +221,7 @@ github.com/hashicorp/errwrap
|
||||
# github.com/hashicorp/go-multierror v1.0.0
|
||||
## explicit
|
||||
github.com/hashicorp/go-multierror
|
||||
# github.com/kata-containers/govmm v0.0.0-20210520142420-eb57f004d89f
|
||||
# github.com/kata-containers/govmm v0.0.0-20210428163604-f0e9a35308ee
|
||||
## explicit
|
||||
github.com/kata-containers/govmm/qemu
|
||||
# github.com/konsorten/go-windows-terminal-sequences v1.0.1
|
||||
|
||||
@@ -214,7 +214,8 @@ func (a *Acrn) trace(parent context.Context, name string) (otelTrace.Span, conte
|
||||
}
|
||||
|
||||
tracer := otel.Tracer("kata")
|
||||
ctx, span := tracer.Start(parent, name, otelTrace.WithAttributes(label.String("source", "runtime"), label.String("package", "virtcontainers"), label.String("subsystem", "hypervisor"), label.String("type", "acrn"), label.String("sandbox_id", a.id)))
|
||||
ctx, span := tracer.Start(parent, name)
|
||||
span.SetAttributes([]label.KeyValue{label.Key("subsystem").String("hypervisor"), label.Key("type").String("acrn")}...)
|
||||
|
||||
return span, ctx
|
||||
}
|
||||
@@ -678,10 +679,6 @@ func (a *Acrn) getPids() []int {
|
||||
return []int{a.state.PID}
|
||||
}
|
||||
|
||||
func (a *Acrn) getVirtioFsPid() *int {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (a *Acrn) fromGrpc(ctx context.Context, hypervisorConfig *HypervisorConfig, j []byte) error {
|
||||
return errors.New("acrn is not supported by VM cache")
|
||||
}
|
||||
|
||||
@@ -30,7 +30,11 @@ var virtLog = logrus.WithField("source", "virtcontainers")
|
||||
// context.
|
||||
func trace(parent context.Context, name string) (otelTrace.Span, context.Context) {
|
||||
tracer := otel.Tracer("kata")
|
||||
ctx, span := tracer.Start(parent, name, otelTrace.WithAttributes(label.String("source", "runtime"), label.String("packages", "virtcontainers"), label.String("subsystem", "api")))
|
||||
ctx, span := tracer.Start(parent, name)
|
||||
span.SetAttributes([]label.KeyValue{
|
||||
label.Key("source").String("virtcontainers"),
|
||||
label.Key("component").String("virtcontainers"),
|
||||
label.Key("subsystem").String("api")}...)
|
||||
|
||||
return span, ctx
|
||||
}
|
||||
@@ -120,6 +124,11 @@ func createSandboxFromConfig(ctx context.Context, sandboxConfig SandboxConfig, f
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// The sandbox is completely created now, we can store it.
|
||||
if err = s.storeSandbox(ctx); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return s, nil
|
||||
}
|
||||
|
||||
|
||||
@@ -14,8 +14,6 @@ import (
|
||||
vcTypes "github.com/kata-containers/kata-containers/src/runtime/virtcontainers/pkg/types"
|
||||
)
|
||||
|
||||
var macvlanTrace = getNetworkTrace(BridgedMacvlanEndpointType)
|
||||
|
||||
// BridgedMacvlanEndpoint represents a macvlan endpoint that is bridged to the VM
|
||||
type BridgedMacvlanEndpoint struct {
|
||||
NetPair NetworkInterfacePair
|
||||
@@ -91,9 +89,6 @@ func (endpoint *BridgedMacvlanEndpoint) NetworkPair() *NetworkInterfacePair {
|
||||
// Attach for virtual endpoint bridges the network pair and adds the
|
||||
// tap interface of the network pair to the hypervisor.
|
||||
func (endpoint *BridgedMacvlanEndpoint) Attach(ctx context.Context, s *Sandbox) error {
|
||||
span, ctx := macvlanTrace(ctx, "Attach", endpoint)
|
||||
defer span.End()
|
||||
|
||||
h := s.hypervisor
|
||||
if err := xConnectVMNetwork(ctx, endpoint, h); err != nil {
|
||||
networkLogger().WithError(err).Error("Error bridging virtual ep")
|
||||
@@ -112,11 +107,8 @@ func (endpoint *BridgedMacvlanEndpoint) Detach(ctx context.Context, netNsCreated
|
||||
return nil
|
||||
}
|
||||
|
||||
span, ctx := macvlanTrace(ctx, "Detach", endpoint)
|
||||
defer span.End()
|
||||
|
||||
return doNetNS(netNsPath, func(_ ns.NetNS) error {
|
||||
return xDisconnectVMNetwork(ctx, endpoint)
|
||||
return xDisconnectVMNetwork(endpoint)
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
@@ -362,9 +362,7 @@ func (clh *cloudHypervisor) startSandbox(ctx context.Context, timeout int) error
|
||||
|
||||
if clh.config.SharedFS == config.VirtioFS {
|
||||
clh.Logger().WithField("function", "startSandbox").Info("Starting virtiofsd")
|
||||
pid, err := clh.virtiofsd.Start(ctx, func() {
|
||||
clh.stopSandbox(ctx, false)
|
||||
})
|
||||
pid, err := clh.virtiofsd.Start(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -714,10 +712,6 @@ func (clh *cloudHypervisor) getPids() []int {
|
||||
return pids
|
||||
}
|
||||
|
||||
func (clh *cloudHypervisor) getVirtioFsPid() *int {
|
||||
return &clh.state.VirtiofsdPID
|
||||
}
|
||||
|
||||
func (clh *cloudHypervisor) addDevice(ctx context.Context, devInfo interface{}, devType deviceType) error {
|
||||
span, _ := clh.trace(ctx, "addDevice")
|
||||
defer span.End()
|
||||
@@ -770,7 +764,8 @@ func (clh *cloudHypervisor) trace(parent context.Context, name string) (otelTrac
|
||||
}
|
||||
|
||||
tracer := otel.Tracer("kata")
|
||||
ctx, span := tracer.Start(parent, name, otelTrace.WithAttributes(otelLabel.String("source", "runtime"), otelLabel.String("package", "virtcontainers"), otelLabel.String("subsystem", "hypervisor"), otelLabel.String("type", "clh"), otelLabel.String("sandbox_id", clh.id)))
|
||||
ctx, span := tracer.Start(parent, name)
|
||||
span.SetAttributes([]otelLabel.KeyValue{otelLabel.Key("subsystem").String("hypervisor"), otelLabel.Key("type").String("clh")}...)
|
||||
|
||||
return span, ctx
|
||||
}
|
||||
|
||||
@@ -360,7 +360,8 @@ func (c *Container) trace(parent context.Context, name string) (otelTrace.Span,
|
||||
}
|
||||
|
||||
tracer := otel.Tracer("kata")
|
||||
ctx, span := tracer.Start(parent, name, otelTrace.WithAttributes(otelLabel.String("source", "runtime"), otelLabel.String("package", "virtcontainers"), otelLabel.String("subsystem", "container"), otelLabel.String("container_id", c.id)))
|
||||
ctx, span := tracer.Start(parent, name)
|
||||
span.SetAttributes(otelLabel.Key("subsystem").String("container"))
|
||||
|
||||
return span, ctx
|
||||
}
|
||||
|
||||
17
src/runtime/virtcontainers/doc.go
Normal file
17
src/runtime/virtcontainers/doc.go
Normal file
@@ -0,0 +1,17 @@
|
||||
// Copyright (c) 2016 Intel Corporation
|
||||
//
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
//
|
||||
|
||||
/*
|
||||
Package virtcontainers manages hardware virtualized containers.
|
||||
Each container belongs to a set of containers sharing the same networking
|
||||
namespace and storage, also known as a sandbox.
|
||||
|
||||
Virtcontainers sandboxes are hardware virtualized, i.e. they run on virtual machines.
|
||||
Virtcontainers will create one VM per sandbox, and containers will be created as
|
||||
processes within the sandbox VM.
|
||||
|
||||
The virtcontainers package manages both sandboxes and containers lifecycles.
|
||||
*/
|
||||
package virtcontainers
|
||||
@@ -42,7 +42,8 @@ type factory struct {
|
||||
|
||||
func trace(parent context.Context, name string) (otelTrace.Span, context.Context) {
|
||||
tracer := otel.Tracer("kata")
|
||||
ctx, span := tracer.Start(parent, name, otelTrace.WithAttributes(label.String("source", "runtime"), label.String("package", "factory"), label.String("subsystem", "factory")))
|
||||
ctx, span := tracer.Start(parent, name)
|
||||
span.SetAttributes(label.Key("subsystem").String("factory"))
|
||||
|
||||
return span, ctx
|
||||
}
|
||||
|
||||
@@ -16,7 +16,6 @@ import (
|
||||
pb "github.com/kata-containers/kata-containers/src/runtime/protocols/cache"
|
||||
vc "github.com/kata-containers/kata-containers/src/runtime/virtcontainers"
|
||||
"github.com/kata-containers/kata-containers/src/runtime/virtcontainers/factory/base"
|
||||
"github.com/sirupsen/logrus"
|
||||
)
|
||||
|
||||
type template struct {
|
||||
@@ -25,7 +24,6 @@ type template struct {
|
||||
}
|
||||
|
||||
var templateWaitForAgent = 2 * time.Second
|
||||
var templateLog = logrus.WithField("source", "virtcontainers/factory/template")
|
||||
|
||||
// Fetch finds and returns a pre-built template factory.
|
||||
// TODO: save template metadata and fetch from storage.
|
||||
@@ -88,13 +86,8 @@ func (t *template) GetVMStatus() []*pb.GrpcVMStatus {
|
||||
}
|
||||
|
||||
func (t *template) close() {
|
||||
if err := syscall.Unmount(t.statePath, syscall.MNT_DETACH); err != nil {
|
||||
t.Logger().WithError(err).Errorf("failed to unmount %s", t.statePath)
|
||||
}
|
||||
|
||||
if err := os.RemoveAll(t.statePath); err != nil {
|
||||
t.Logger().WithError(err).Errorf("failed to remove %s", t.statePath)
|
||||
}
|
||||
syscall.Unmount(t.statePath, 0)
|
||||
os.RemoveAll(t.statePath)
|
||||
}
|
||||
|
||||
func (t *template) prepareTemplateFiles() error {
|
||||
@@ -175,19 +168,3 @@ func (t *template) checkTemplateVM() error {
|
||||
_, err = os.Stat(t.statePath + "/state")
|
||||
return err
|
||||
}
|
||||
|
||||
// Logger returns a logrus logger appropriate for logging template messages
|
||||
func (t *template) Logger() *logrus.Entry {
|
||||
return templateLog.WithFields(logrus.Fields{
|
||||
"subsystem": "template",
|
||||
})
|
||||
}
|
||||
|
||||
// SetLogger sets the logger for the factory template.
|
||||
func SetLogger(ctx context.Context, logger logrus.FieldLogger) {
|
||||
fields := logrus.Fields{
|
||||
"source": "virtcontainers",
|
||||
}
|
||||
|
||||
templateLog = logger.WithFields(fields)
|
||||
}
|
||||
|
||||
@@ -121,14 +121,7 @@ func TestTemplateFactory(t *testing.T) {
|
||||
err = vm.Stop(ctx)
|
||||
assert.Nil(err)
|
||||
|
||||
// make tt.statePath is busy
|
||||
os.Chdir(tt.statePath)
|
||||
|
||||
// CloseFactory, there is no need to call tt.CloseFactory(ctx)
|
||||
// CloseFactory
|
||||
f.CloseFactory(ctx)
|
||||
|
||||
// expect tt.statePath not exist, if exist, it means this case failed.
|
||||
_, err = os.Stat(tt.statePath)
|
||||
assert.Error(err)
|
||||
assert.True(os.IsNotExist(err))
|
||||
tt.CloseFactory(ctx)
|
||||
}
|
||||
|
||||
@@ -175,7 +175,8 @@ func (fc *firecracker) trace(parent context.Context, name string) (otelTrace.Spa
|
||||
}
|
||||
|
||||
tracer := otel.Tracer("kata")
|
||||
ctx, span := tracer.Start(parent, name, otelTrace.WithAttributes(otelLabel.String("source", "runtime"), otelLabel.String("package", "virtcontainers"), otelLabel.String("subsystem", "hypervisor"), otelLabel.String("type", "firecracker"), otelLabel.String("sandbox_id", fc.id)))
|
||||
ctx, span := tracer.Start(parent, name)
|
||||
span.SetAttributes([]otelLabel.KeyValue{otelLabel.Key("subsystem").String("hypervisor"), otelLabel.Key("type").String("firecracker")}...)
|
||||
|
||||
return span, ctx
|
||||
}
|
||||
@@ -1180,10 +1181,6 @@ func (fc *firecracker) getPids() []int {
|
||||
return []int{fc.info.PID}
|
||||
}
|
||||
|
||||
func (fc *firecracker) getVirtioFsPid() *int {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (fc *firecracker) fromGrpc(ctx context.Context, hypervisorConfig *HypervisorConfig, j []byte) error {
|
||||
return errors.New("firecracker is not supported by VM cache")
|
||||
}
|
||||
|
||||
@@ -453,11 +453,6 @@ type HypervisorConfig struct {
|
||||
// GuestMemoryDumpPaging is used to indicate if enable paging
|
||||
// for QEMU dump-guest-memory command
|
||||
GuestMemoryDumpPaging bool
|
||||
|
||||
// Enable confidential guest support.
|
||||
// Enable or disable different hardware features, ranging
|
||||
// from memory encryption to both memory and CPU-state encryption and integrity.
|
||||
ConfidentialGuest bool
|
||||
}
|
||||
|
||||
// vcpu mapping from vcpu number to thread number
|
||||
@@ -722,61 +717,21 @@ func getHostMemorySizeKb(memInfoPath string) (uint64, error) {
|
||||
return 0, fmt.Errorf("unable get MemTotal from %s", memInfoPath)
|
||||
}
|
||||
|
||||
// CheckCmdline checks whether an option or parameter is present in the kernel command line.
|
||||
// Search is case-insensitive.
|
||||
// Takes path to file that contains the kernel command line, desired option, and permitted values
|
||||
// (empty values to check for options).
|
||||
func CheckCmdline(kernelCmdlinePath, searchParam string, searchValues []string) (bool, error) {
|
||||
f, err := os.Open(kernelCmdlinePath)
|
||||
// RunningOnVMM checks if the system is running inside a VM.
|
||||
func RunningOnVMM(cpuInfoPath string) (bool, error) {
|
||||
if runtime.GOARCH == "arm64" || runtime.GOARCH == "ppc64le" || runtime.GOARCH == "s390x" {
|
||||
virtLog.Info("Unable to know if the system is running inside a VM")
|
||||
return false, nil
|
||||
}
|
||||
|
||||
flagsField := "flags"
|
||||
|
||||
f, err := os.Open(cpuInfoPath)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
defer f.Close()
|
||||
|
||||
// Create check function -- either check for verbatim option
|
||||
// or check for parameter and permitted values
|
||||
var check func(string, string, []string) bool
|
||||
if len(searchValues) == 0 {
|
||||
check = func(option, searchParam string, _ []string) bool {
|
||||
return strings.EqualFold(option, searchParam)
|
||||
}
|
||||
} else {
|
||||
check = func(param, searchParam string, searchValues []string) bool {
|
||||
// split parameter and value
|
||||
split := strings.SplitN(param, "=", 2)
|
||||
if len(split) < 2 || split[0] != searchParam {
|
||||
return false
|
||||
}
|
||||
for _, value := range searchValues {
|
||||
if strings.EqualFold(value, split[1]) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
scanner := bufio.NewScanner(f)
|
||||
for scanner.Scan() {
|
||||
for _, field := range strings.Fields(scanner.Text()) {
|
||||
if check(field, searchParam, searchValues) {
|
||||
return true, nil
|
||||
}
|
||||
}
|
||||
}
|
||||
return false, err
|
||||
}
|
||||
|
||||
func CPUFlags(cpuInfoPath string) (map[string]bool, error) {
|
||||
flagsField := "flags"
|
||||
|
||||
f, err := os.Open(cpuInfoPath)
|
||||
if err != nil {
|
||||
return map[string]bool{}, err
|
||||
}
|
||||
defer f.Close()
|
||||
|
||||
flags := make(map[string]bool)
|
||||
scanner := bufio.NewScanner(f)
|
||||
for scanner.Scan() {
|
||||
// Expected format: ["flags", ":", ...] or ["flags:", ...]
|
||||
@@ -790,31 +745,23 @@ func CPUFlags(cpuInfoPath string) (map[string]bool, error) {
|
||||
}
|
||||
|
||||
for _, field := range fields[1:] {
|
||||
flags[field] = true
|
||||
if field == "hypervisor" {
|
||||
return true, nil
|
||||
}
|
||||
}
|
||||
|
||||
return flags, nil
|
||||
// As long as we have been able to analyze the fields from
|
||||
// "flags", there is no reason to check what comes next from
|
||||
// /proc/cpuinfo, because we already know we are not running
|
||||
// on a VMM.
|
||||
return false, nil
|
||||
}
|
||||
|
||||
if err := scanner.Err(); err != nil {
|
||||
return map[string]bool{}, err
|
||||
return false, err
|
||||
}
|
||||
|
||||
return map[string]bool{}, fmt.Errorf("Couldn't find %q from %q output", flagsField, cpuInfoPath)
|
||||
}
|
||||
|
||||
// RunningOnVMM checks if the system is running inside a VM.
|
||||
func RunningOnVMM(cpuInfoPath string) (bool, error) {
|
||||
if runtime.GOARCH == "amd64" {
|
||||
flags, err := CPUFlags(cpuInfoPath)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
return flags["hypervisor"], nil
|
||||
}
|
||||
|
||||
virtLog.WithField("arch", runtime.GOARCH).Info("Unable to know if the system is running inside a VM")
|
||||
return false, nil
|
||||
return false, fmt.Errorf("Couldn't find %q from %q output", flagsField, cpuInfoPath)
|
||||
}
|
||||
|
||||
func getHypervisorPid(h hypervisor) int {
|
||||
@@ -863,7 +810,6 @@ type hypervisor interface {
|
||||
// getPids returns a slice of hypervisor related process ids.
|
||||
// The hypervisor pid must be put at index 0.
|
||||
getPids() []int
|
||||
getVirtioFsPid() *int
|
||||
fromGrpc(ctx context.Context, hypervisorConfig *HypervisorConfig, j []byte) error
|
||||
toGrpc(ctx context.Context) ([]byte, error)
|
||||
check() error
|
||||
|
||||
@@ -1,25 +0,0 @@
|
||||
// Copyright (c) 2021 Intel Corporation
|
||||
//
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
//
|
||||
|
||||
package virtcontainers
|
||||
|
||||
import "os"
|
||||
|
||||
// Implementation of this function is architecture specific
|
||||
func availableGuestProtection() (guestProtection, error) {
|
||||
flags, err := CPUFlags(procCPUInfo)
|
||||
if err != nil {
|
||||
return noneProtection, err
|
||||
}
|
||||
|
||||
// TDX is supported and properly loaded when the firmware directory exists or `tdx` is part of the CPU flags
|
||||
if d, err := os.Stat(tdxSysFirmwareDir); (err == nil && d.IsDir()) || flags[tdxCPUFlag] {
|
||||
return tdxProtection, nil
|
||||
}
|
||||
|
||||
// TODO: Add support for other technologies: SEV
|
||||
|
||||
return noneProtection, nil
|
||||
}
|
||||
@@ -1,17 +0,0 @@
|
||||
// Copyright (c) 2021 IBM
|
||||
//
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package virtcontainers
|
||||
|
||||
import "os"
|
||||
|
||||
//Returns pefProtection if the firmware directory exists
|
||||
func availableGuestProtection() (guestProtection, error) {
|
||||
|
||||
if d, err := os.Stat(pefSysFirmwareDir); err == nil && d.IsDir() {
|
||||
return pefProtection, err
|
||||
}
|
||||
|
||||
return noneProtection, nil
|
||||
}
|
||||
@@ -1,99 +0,0 @@
|
||||
// Copyright (c) IBM Corp. 2021
|
||||
//
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
//
|
||||
|
||||
package virtcontainers
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"fmt"
|
||||
"os"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
const (
|
||||
// This is valid in other architectures, but varcheck will complain
|
||||
// when setting it in common code as it will be regarded unused
|
||||
procKernelCmdline = "/proc/cmdline"
|
||||
|
||||
// Secure Execution
|
||||
// https://www.kernel.org/doc/html/latest/virt/kvm/s390-pv.html
|
||||
seCPUFacilityBit = 158
|
||||
seCmdlineParam = "prot_virt"
|
||||
)
|
||||
|
||||
var seCmdlineValues = []string{
|
||||
"1", "on", "y", "yes",
|
||||
}
|
||||
|
||||
// CPUFacilities retrieves active CPU facilities according to "Facility Indications", Principles of Operation.
|
||||
// Takes cpuinfo path (such as /proc/cpuinfo), returns map of all active facility bits.
|
||||
func CPUFacilities(cpuInfoPath string) (map[int]bool, error) {
|
||||
facilitiesField := "facilities"
|
||||
|
||||
f, err := os.Open(cpuInfoPath)
|
||||
if err != nil {
|
||||
return map[int]bool{}, err
|
||||
}
|
||||
defer f.Close()
|
||||
|
||||
facilities := make(map[int]bool)
|
||||
scanner := bufio.NewScanner(f)
|
||||
for scanner.Scan() {
|
||||
// Expected format: ["facilities", ":", ...] or ["facilities:", ...]
|
||||
fields := strings.Fields(scanner.Text())
|
||||
if len(fields) < 2 {
|
||||
continue
|
||||
}
|
||||
|
||||
if !strings.HasPrefix(fields[0], facilitiesField) {
|
||||
continue
|
||||
}
|
||||
|
||||
start := 1
|
||||
if fields[1] == ":" {
|
||||
start = 2
|
||||
}
|
||||
for _, field := range fields[start:] {
|
||||
bit, err := strconv.Atoi(field)
|
||||
if err != nil {
|
||||
return map[int]bool{}, err
|
||||
}
|
||||
facilities[bit] = true
|
||||
}
|
||||
|
||||
return facilities, nil
|
||||
}
|
||||
|
||||
if err := scanner.Err(); err != nil {
|
||||
return map[int]bool{}, err
|
||||
}
|
||||
|
||||
return map[int]bool{}, fmt.Errorf("Couldn't find %q from %q output", facilitiesField, cpuInfoPath)
|
||||
}
|
||||
|
||||
// availableGuestProtection returns seProtection (Secure Execution) if available.
|
||||
// Checks that Secure Execution is available (CPU facilities) and enabled (kernel command line).
|
||||
func availableGuestProtection() (guestProtection, error) {
|
||||
facilities, err := CPUFacilities(procCPUInfo)
|
||||
if err != nil {
|
||||
return noneProtection, err
|
||||
}
|
||||
if !facilities[seCPUFacilityBit] {
|
||||
return noneProtection, fmt.Errorf("This CPU does not support Secure Execution")
|
||||
}
|
||||
|
||||
seCmdlinePresent, err := CheckCmdline(procKernelCmdline, seCmdlineParam, seCmdlineValues)
|
||||
if err != nil {
|
||||
return noneProtection, err
|
||||
}
|
||||
if !seCmdlinePresent {
|
||||
return noneProtection, fmt.Errorf("Protected Virtualization is not enabled on kernel command line! " +
|
||||
"Need %s=%s (or %s) to enable Secure Execution",
|
||||
seCmdlineParam, seCmdlineValues[0], strings.Join(seCmdlineValues[1:], ", "))
|
||||
}
|
||||
|
||||
return seProtection, nil
|
||||
}
|
||||
@@ -1,25 +0,0 @@
|
||||
// Copyright (c) IBM Corp. 2021
|
||||
//
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
//
|
||||
|
||||
package virtcontainers
|
||||
|
||||
import (
|
||||
"math"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestCPUFacilities(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
|
||||
facilities, err := CPUFacilities(procCPUInfo)
|
||||
assert.NoError(err)
|
||||
|
||||
// z/Architecture facility should always be active (introduced in 2000)
|
||||
assert.Equal(facilities[1], true)
|
||||
// facility bits should not be as high as MaxInt
|
||||
assert.Equal(facilities[math.MaxInt64], false)
|
||||
}
|
||||
@@ -401,21 +401,6 @@ func TestGetHostMemorySizeKb(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestCheckCmdline(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
|
||||
cmdlineFp, err := ioutil.TempFile("", "")
|
||||
assert.NoError(err)
|
||||
_, err = cmdlineFp.WriteString("quiet root=/dev/sda2")
|
||||
assert.NoError(err)
|
||||
cmdlinePath := cmdlineFp.Name()
|
||||
defer os.Remove(cmdlinePath)
|
||||
|
||||
assert.True(CheckCmdline(cmdlinePath, "quiet", []string{}))
|
||||
assert.True(CheckCmdline(cmdlinePath, "root", []string{"/dev/sda1", "/dev/sda2"}))
|
||||
assert.False(CheckCmdline(cmdlinePath, "ro", []string{}))
|
||||
}
|
||||
|
||||
// nolint: unused, deadcode
|
||||
type testNestedVMMData struct {
|
||||
content []byte
|
||||
|
||||
@@ -14,8 +14,6 @@ import (
|
||||
vcTypes "github.com/kata-containers/kata-containers/src/runtime/virtcontainers/pkg/types"
|
||||
)
|
||||
|
||||
var ipvlanTrace = getNetworkTrace(IPVlanEndpointType)
|
||||
|
||||
// IPVlanEndpoint represents a ipvlan endpoint that is bridged to the VM
|
||||
type IPVlanEndpoint struct {
|
||||
NetPair NetworkInterfacePair
|
||||
@@ -94,9 +92,6 @@ func (endpoint *IPVlanEndpoint) NetworkPair() *NetworkInterfacePair {
|
||||
// Attach for virtual endpoint bridges the network pair and adds the
|
||||
// tap interface of the network pair to the hypervisor.
|
||||
func (endpoint *IPVlanEndpoint) Attach(ctx context.Context, s *Sandbox) error {
|
||||
span, ctx := ipvlanTrace(ctx, "Attach", endpoint)
|
||||
defer span.End()
|
||||
|
||||
h := s.hypervisor
|
||||
if err := xConnectVMNetwork(ctx, endpoint, h); err != nil {
|
||||
networkLogger().WithError(err).Error("Error bridging virtual ep")
|
||||
@@ -115,11 +110,8 @@ func (endpoint *IPVlanEndpoint) Detach(ctx context.Context, netNsCreated bool, n
|
||||
return nil
|
||||
}
|
||||
|
||||
span, ctx := ipvlanTrace(ctx, "Detach", endpoint)
|
||||
defer span.End()
|
||||
|
||||
return doNetNS(netNsPath, func(_ ns.NetNS) error {
|
||||
return xDisconnectVMNetwork(ctx, endpoint)
|
||||
return xDisconnectVMNetwork(endpoint)
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
@@ -251,7 +251,8 @@ func (k *kataAgent) trace(parent context.Context, name string) (otelTrace.Span,
|
||||
}
|
||||
|
||||
tracer := otel.Tracer("kata")
|
||||
ctx, span := tracer.Start(parent, name, otelTrace.WithAttributes(label.String("source", "runtime"), label.String("package", "virtcontainers"), label.String("subsystem", "agent")))
|
||||
ctx, span := tracer.Start(parent, name)
|
||||
span.SetAttributes([]label.KeyValue{label.Key("subsystem").String("agent"), label.Key("type").String("kata")}...)
|
||||
|
||||
return span, ctx
|
||||
}
|
||||
@@ -811,8 +812,10 @@ func (k *kataAgent) startSandbox(ctx context.Context, sandbox *Sandbox) error {
|
||||
return err
|
||||
}
|
||||
|
||||
//
|
||||
// Setup network interfaces and routes
|
||||
interfaces, routes, neighs, err := generateVCNetworkStructures(ctx, sandbox.networkNS)
|
||||
//
|
||||
interfaces, routes, neighs, err := generateVCNetworkStructures(sandbox.networkNS)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -14,8 +14,6 @@ import (
|
||||
vcTypes "github.com/kata-containers/kata-containers/src/runtime/virtcontainers/pkg/types"
|
||||
)
|
||||
|
||||
var macvtapTrace = getNetworkTrace(MacvtapEndpointType)
|
||||
|
||||
// MacvtapEndpoint represents a macvtap endpoint
|
||||
type MacvtapEndpoint struct {
|
||||
EndpointProperties NetworkInfo
|
||||
@@ -64,9 +62,6 @@ func (endpoint *MacvtapEndpoint) SetProperties(properties NetworkInfo) {
|
||||
// Attach for macvtap endpoint passes macvtap device to the hypervisor.
|
||||
func (endpoint *MacvtapEndpoint) Attach(ctx context.Context, s *Sandbox) error {
|
||||
var err error
|
||||
span, ctx := macvtapTrace(ctx, "Attach", endpoint)
|
||||
defer span.End()
|
||||
|
||||
h := s.hypervisor
|
||||
|
||||
endpoint.VMFds, err = createMacvtapFds(endpoint.EndpointProperties.Iface.Index, int(h.hypervisorConfig().NumVCPUs))
|
||||
|
||||
@@ -109,10 +109,6 @@ func (m *mockHypervisor) getPids() []int {
|
||||
return []int{m.mockPid}
|
||||
}
|
||||
|
||||
func (m *mockHypervisor) getVirtioFsPid() *int {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *mockHypervisor) fromGrpc(ctx context.Context, hypervisorConfig *HypervisorConfig, j []byte) error {
|
||||
return errors.New("mockHypervisor is not supported by VM cache")
|
||||
}
|
||||
|
||||
@@ -19,6 +19,7 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/containernetworking/plugins/pkg/ns"
|
||||
"github.com/containernetworking/plugins/pkg/testutils"
|
||||
"github.com/sirupsen/logrus"
|
||||
"github.com/vishvananda/netlink"
|
||||
"github.com/vishvananda/netns"
|
||||
@@ -57,7 +58,7 @@ const (
|
||||
NetXConnectInvalidModel
|
||||
)
|
||||
|
||||
// IsValid checks if a model is valid
|
||||
//IsValid checks if a model is valid
|
||||
func (n NetInterworkingModel) IsValid() bool {
|
||||
return 0 <= int(n) && int(n) < int(NetXConnectInvalidModel)
|
||||
}
|
||||
@@ -72,21 +73,6 @@ const (
|
||||
noneNetModelStr = "none"
|
||||
)
|
||||
|
||||
//GetModel returns the string value of a NetInterworkingModel
|
||||
func (n *NetInterworkingModel) GetModel() string {
|
||||
switch *n {
|
||||
case DefaultNetInterworkingModel:
|
||||
return defaultNetModelStr
|
||||
case NetXConnectMacVtapModel:
|
||||
return macvtapNetModelStr
|
||||
case NetXConnectTCFilterModel:
|
||||
return tcFilterNetModelStr
|
||||
case NetXConnectNoneModel:
|
||||
return noneNetModelStr
|
||||
}
|
||||
return "unknown"
|
||||
}
|
||||
|
||||
//SetModel change the model string value
|
||||
func (n *NetInterworkingModel) SetModel(modelName string) error {
|
||||
switch modelName {
|
||||
@@ -421,11 +407,6 @@ func getLinkByName(netHandle *netlink.Handle, name string, expectedLink netlink.
|
||||
|
||||
// The endpoint type should dictate how the connection needs to happen.
|
||||
func xConnectVMNetwork(ctx context.Context, endpoint Endpoint, h hypervisor) error {
|
||||
var err error
|
||||
|
||||
span, ctx := networkTrace(ctx, "xConnectVMNetwork", endpoint)
|
||||
defer closeSpan(span, err)
|
||||
|
||||
netPair := endpoint.NetworkPair()
|
||||
|
||||
queues := 0
|
||||
@@ -447,24 +428,16 @@ func xConnectVMNetwork(ctx context.Context, endpoint Endpoint, h hypervisor) err
|
||||
|
||||
switch netPair.NetInterworkingModel {
|
||||
case NetXConnectMacVtapModel:
|
||||
networkLogger().Info("connect macvtap to VM network")
|
||||
err = tapNetworkPair(ctx, endpoint, queues, disableVhostNet)
|
||||
return tapNetworkPair(endpoint, queues, disableVhostNet)
|
||||
case NetXConnectTCFilterModel:
|
||||
networkLogger().Info("connect TCFilter to VM network")
|
||||
err = setupTCFiltering(ctx, endpoint, queues, disableVhostNet)
|
||||
return setupTCFiltering(endpoint, queues, disableVhostNet)
|
||||
default:
|
||||
err = fmt.Errorf("Invalid internetworking model")
|
||||
return fmt.Errorf("Invalid internetworking model")
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
// The endpoint type should dictate how the disconnection needs to happen.
|
||||
func xDisconnectVMNetwork(ctx context.Context, endpoint Endpoint) error {
|
||||
var err error
|
||||
|
||||
span, ctx := networkTrace(ctx, "xDisconnectVMNetwork", endpoint)
|
||||
defer closeSpan(span, err)
|
||||
|
||||
func xDisconnectVMNetwork(endpoint Endpoint) error {
|
||||
netPair := endpoint.NetworkPair()
|
||||
|
||||
if netPair.NetInterworkingModel == NetXConnectDefaultModel {
|
||||
@@ -473,13 +446,12 @@ func xDisconnectVMNetwork(ctx context.Context, endpoint Endpoint) error {
|
||||
|
||||
switch netPair.NetInterworkingModel {
|
||||
case NetXConnectMacVtapModel:
|
||||
err = untapNetworkPair(ctx, endpoint)
|
||||
return untapNetworkPair(endpoint)
|
||||
case NetXConnectTCFilterModel:
|
||||
err = removeTCFiltering(ctx, endpoint)
|
||||
return removeTCFiltering(endpoint)
|
||||
default:
|
||||
err = fmt.Errorf("Invalid internetworking model")
|
||||
return fmt.Errorf("Invalid internetworking model")
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
func createMacvtapFds(linkIndex int, queues int) ([]*os.File, error) {
|
||||
@@ -561,10 +533,7 @@ func setIPs(link netlink.Link, addrs []netlink.Addr) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func tapNetworkPair(ctx context.Context, endpoint Endpoint, queues int, disableVhostNet bool) error {
|
||||
span, _ := networkTrace(ctx, "tapNetworkPair", endpoint)
|
||||
defer span.End()
|
||||
|
||||
func tapNetworkPair(endpoint Endpoint, queues int, disableVhostNet bool) error {
|
||||
netHandle, err := netlink.NewHandle()
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -658,10 +627,7 @@ func tapNetworkPair(ctx context.Context, endpoint Endpoint, queues int, disableV
|
||||
return nil
|
||||
}
|
||||
|
||||
func setupTCFiltering(ctx context.Context, endpoint Endpoint, queues int, disableVhostNet bool) error {
|
||||
span, _ := networkTrace(ctx, "setupTCFiltering", endpoint)
|
||||
defer span.End()
|
||||
|
||||
func setupTCFiltering(endpoint Endpoint, queues int, disableVhostNet bool) error {
|
||||
netHandle, err := netlink.NewHandle()
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -730,7 +696,7 @@ func setupTCFiltering(ctx context.Context, endpoint Endpoint, queues int, disabl
|
||||
return nil
|
||||
}
|
||||
|
||||
// addQdiscIngress creates a new qdisc for network interface with the specified network index
|
||||
// addQdiscIngress creates a new qdisc for nwtwork interface with the specified network index
|
||||
// on "ingress". qdiscs normally don't work on ingress so this is really a special qdisc
|
||||
// that you can consider an "alternate root" for inbound packets.
|
||||
// Handle for ingress qdisc defaults to "ffff:"
|
||||
@@ -833,10 +799,7 @@ func removeQdiscIngress(link netlink.Link) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func untapNetworkPair(ctx context.Context, endpoint Endpoint) error {
|
||||
span, _ := networkTrace(ctx, "untapNetworkPair", endpoint)
|
||||
defer span.End()
|
||||
|
||||
func untapNetworkPair(endpoint Endpoint) error {
|
||||
netHandle, err := netlink.NewHandle()
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -877,10 +840,7 @@ func untapNetworkPair(ctx context.Context, endpoint Endpoint) error {
|
||||
return err
|
||||
}
|
||||
|
||||
func removeTCFiltering(ctx context.Context, endpoint Endpoint) error {
|
||||
span, _ := networkTrace(ctx, "removeTCFiltering", endpoint)
|
||||
defer span.End()
|
||||
|
||||
func removeTCFiltering(endpoint Endpoint) error {
|
||||
netHandle, err := netlink.NewHandle()
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -922,6 +882,15 @@ func removeTCFiltering(ctx context.Context, endpoint Endpoint) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func createNetNS() (string, error) {
|
||||
n, err := testutils.NewNS()
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
return n.Path(), nil
|
||||
}
|
||||
|
||||
// doNetNS is free from any call to a go routine, and it calls
|
||||
// into runtime.LockOSThread(), meaning it won't be executed in a
|
||||
// different thread than the one expected by the caller.
|
||||
@@ -976,18 +945,18 @@ func deleteNetNS(netNSPath string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func generateVCNetworkStructures(ctx context.Context, networkNS NetworkNamespace) ([]*pbTypes.Interface, []*pbTypes.Route, []*pbTypes.ARPNeighbor, error) {
|
||||
func generateVCNetworkStructures(networkNS NetworkNamespace) ([]*pbTypes.Interface, []*pbTypes.Route, []*pbTypes.ARPNeighbor, error) {
|
||||
|
||||
if networkNS.NetNsPath == "" {
|
||||
return nil, nil, nil, nil
|
||||
}
|
||||
span, _ := networkTrace(ctx, "generateVCNetworkStructures", nil)
|
||||
defer span.End()
|
||||
|
||||
var routes []*pbTypes.Route
|
||||
var ifaces []*pbTypes.Interface
|
||||
var neighs []*pbTypes.ARPNeighbor
|
||||
|
||||
for _, endpoint := range networkNS.Endpoints {
|
||||
|
||||
var ipAddresses []*pbTypes.IPAddress
|
||||
for _, addr := range endpoint.Properties().Addrs {
|
||||
// Skip localhost interface
|
||||
@@ -1072,7 +1041,6 @@ func generateVCNetworkStructures(ctx context.Context, networkNS NetworkNamespace
|
||||
neighs = append(neighs, &n)
|
||||
}
|
||||
}
|
||||
|
||||
return ifaces, routes, neighs, nil
|
||||
}
|
||||
|
||||
@@ -1270,10 +1238,8 @@ func createEndpoint(netInfo NetworkInfo, idx int, model NetInterworkingModel, li
|
||||
}
|
||||
}
|
||||
} else if netInfo.Iface.Type == "veth" {
|
||||
networkLogger().Info("veth interface found")
|
||||
endpoint, err = createVethNetworkEndpoint(idx, netInfo.Iface.Name, model)
|
||||
} else if netInfo.Iface.Type == "ipvlan" {
|
||||
networkLogger().Info("ipvlan interface found")
|
||||
endpoint, err = createIPVlanNetworkEndpoint(idx, netInfo.Iface.Name)
|
||||
} else {
|
||||
return nil, fmt.Errorf("Unsupported network interface: %s", netInfo.Iface.Type)
|
||||
@@ -1287,31 +1253,12 @@ func createEndpoint(netInfo NetworkInfo, idx int, model NetInterworkingModel, li
|
||||
type Network struct {
|
||||
}
|
||||
|
||||
var networkTrace = getNetworkTrace("")
|
||||
|
||||
func (n *Network) trace(ctx context.Context, name string) (otelTrace.Span, context.Context) {
|
||||
return networkTrace(ctx, name, nil)
|
||||
}
|
||||
tracer := otel.Tracer("kata")
|
||||
ctx, span := tracer.Start(ctx, name)
|
||||
span.SetAttributes([]otelLabel.KeyValue{otelLabel.Key("subsystem").String("network"), otelLabel.Key("type").String("default")}...)
|
||||
|
||||
func getNetworkTrace(networkType EndpointType) func(ctx context.Context, name string, endpoint interface{}) (otelTrace.Span, context.Context) {
|
||||
return func(ctx context.Context, name string, endpoint interface{}) (otelTrace.Span, context.Context) {
|
||||
tracer := otel.Tracer("kata")
|
||||
ctx, span := tracer.Start(ctx, name, otelTrace.WithAttributes(otelLabel.String("source", "runtime"), otelLabel.String("package", "virtcontainers"), otelLabel.String("subsystem", "network")))
|
||||
if networkType != "" {
|
||||
span.SetAttributes(otelLabel.Any("type", string(networkType)))
|
||||
}
|
||||
if endpoint != nil {
|
||||
span.SetAttributes(otelLabel.Any("endpoint", endpoint))
|
||||
}
|
||||
return span, ctx
|
||||
}
|
||||
}
|
||||
|
||||
func closeSpan(span otelTrace.Span, err error) {
|
||||
if err != nil {
|
||||
span.SetAttributes(otelLabel.Any("error", err))
|
||||
}
|
||||
span.End()
|
||||
return span, ctx
|
||||
}
|
||||
|
||||
// Run runs a callback in the specified network namespace.
|
||||
@@ -1327,15 +1274,12 @@ func (n *Network) Run(ctx context.Context, networkNSPath string, cb func() error
|
||||
// Add adds all needed interfaces inside the network namespace.
|
||||
func (n *Network) Add(ctx context.Context, config *NetworkConfig, s *Sandbox, hotplug bool) ([]Endpoint, error) {
|
||||
span, ctx := n.trace(ctx, "Add")
|
||||
span.SetAttributes(otelLabel.String("type", config.InterworkingModel.GetModel()))
|
||||
defer span.End()
|
||||
|
||||
endpoints, err := createEndpointsFromScan(config.NetNSPath, config)
|
||||
if err != nil {
|
||||
return endpoints, err
|
||||
}
|
||||
span.SetAttributes(otelLabel.Any("endpoints", endpoints))
|
||||
span.SetAttributes(otelLabel.Bool("hotplug", hotplug))
|
||||
|
||||
err = doNetNS(config.NetNSPath, func(_ ns.NetNS) error {
|
||||
for _, endpoint := range endpoints {
|
||||
@@ -1365,7 +1309,9 @@ func (n *Network) Add(ctx context.Context, config *NetworkConfig, s *Sandbox, ho
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return nil
|
||||
@@ -1597,7 +1543,7 @@ func addIFBRedirecting(sourceIndex int, ifbIndex int) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// addTxRateLimiter implements tx rate limiter to control network I/O outbound traffic
|
||||
// func addTxRateLmiter implements tx rate limiter to control network I/O outbound traffic
|
||||
// on VM level for hypervisors which don't implement rate limiter in itself, like qemu, etc.
|
||||
// We adopt different actions, based on different inter-networking models.
|
||||
// For tcfilters as inter-networking model, we simply apply htb qdisc discipline to the virtual netpair.
|
||||
|
||||
@@ -6,9 +6,9 @@
|
||||
package virtcontainers
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"net"
|
||||
"os"
|
||||
"reflect"
|
||||
"testing"
|
||||
|
||||
@@ -20,6 +20,23 @@ import (
|
||||
"github.com/vishvananda/netlink"
|
||||
)
|
||||
|
||||
func TestCreateDeleteNetNS(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
if tc.NotValid(ktu.NeedRoot()) {
|
||||
t.Skip(testDisabledAsNonRoot)
|
||||
}
|
||||
|
||||
netNSPath, err := createNetNS()
|
||||
assert.NoError(err)
|
||||
assert.NotEmpty(netNSPath)
|
||||
|
||||
_, err = os.Stat(netNSPath)
|
||||
assert.NoError(err)
|
||||
|
||||
err = deleteNetNS(netNSPath)
|
||||
assert.NoError(err)
|
||||
}
|
||||
|
||||
func TestGenerateInterfacesAndRoutes(t *testing.T) {
|
||||
//
|
||||
//Create a couple of addresses
|
||||
@@ -75,7 +92,7 @@ func TestGenerateInterfacesAndRoutes(t *testing.T) {
|
||||
|
||||
nns := NetworkNamespace{NetNsPath: "foobar", NetNsCreated: true, Endpoints: endpoints}
|
||||
|
||||
resInterfaces, resRoutes, resNeighs, err := generateVCNetworkStructures(context.Background(), nns)
|
||||
resInterfaces, resRoutes, resNeighs, err := generateVCNetworkStructures(nns)
|
||||
|
||||
//
|
||||
// Build expected results:
|
||||
@@ -276,10 +293,10 @@ func TestTcRedirectNetwork(t *testing.T) {
|
||||
err = netHandle.LinkSetUp(link)
|
||||
assert.NoError(err)
|
||||
|
||||
err = setupTCFiltering(context.Background(), endpoint, 1, true)
|
||||
err = setupTCFiltering(endpoint, 1, true)
|
||||
assert.NoError(err)
|
||||
|
||||
err = removeTCFiltering(context.Background(), endpoint)
|
||||
err = removeTCFiltering(endpoint)
|
||||
assert.NoError(err)
|
||||
|
||||
// Remove the veth created for testing.
|
||||
@@ -314,7 +331,7 @@ func TestRxRateLimiter(t *testing.T) {
|
||||
err = netHandle.LinkSetUp(link)
|
||||
assert.NoError(err)
|
||||
|
||||
err = setupTCFiltering(context.Background(), endpoint, 1, true)
|
||||
err = setupTCFiltering(endpoint, 1, true)
|
||||
assert.NoError(err)
|
||||
|
||||
// 10Mb
|
||||
@@ -328,7 +345,7 @@ func TestRxRateLimiter(t *testing.T) {
|
||||
err = removeRxRateLimiter(endpoint, currentNS.Path())
|
||||
assert.NoError(err)
|
||||
|
||||
err = removeTCFiltering(context.Background(), endpoint)
|
||||
err = removeTCFiltering(endpoint)
|
||||
assert.NoError(err)
|
||||
|
||||
// Remove the veth created for testing.
|
||||
@@ -363,7 +380,7 @@ func TestTxRateLimiter(t *testing.T) {
|
||||
err = netHandle.LinkSetUp(link)
|
||||
assert.NoError(err)
|
||||
|
||||
err = setupTCFiltering(context.Background(), endpoint, 1, true)
|
||||
err = setupTCFiltering(endpoint, 1, true)
|
||||
assert.NoError(err)
|
||||
|
||||
// 10Mb
|
||||
@@ -377,7 +394,7 @@ func TestTxRateLimiter(t *testing.T) {
|
||||
err = removeTxRateLimiter(endpoint, currentNS.Path())
|
||||
assert.NoError(err)
|
||||
|
||||
err = removeTCFiltering(context.Background(), endpoint)
|
||||
err = removeTCFiltering(endpoint)
|
||||
assert.NoError(err)
|
||||
|
||||
// Remove the veth created for testing.
|
||||
|
||||
@@ -34,6 +34,7 @@ type SandboxState struct {
|
||||
|
||||
// CgroupPath is the cgroup hierarchy where sandbox's processes
|
||||
// including the hypervisor are placed.
|
||||
// FIXME: sandbox can reuse "SandboxContainer"'s CgroupPath so we can remove this field.
|
||||
CgroupPath string
|
||||
|
||||
// CgroupPath is the cgroup hierarchy where sandbox's processes
|
||||
|
||||
@@ -21,8 +21,6 @@ import (
|
||||
"github.com/safchain/ethtool"
|
||||
)
|
||||
|
||||
var physicalTrace = getNetworkTrace(PhysicalEndpointType)
|
||||
|
||||
// PhysicalEndpoint gathers a physical network interface and its properties
|
||||
type PhysicalEndpoint struct {
|
||||
IfaceName string
|
||||
@@ -78,9 +76,6 @@ func (endpoint *PhysicalEndpoint) NetworkPair() *NetworkInterfacePair {
|
||||
// Attach for physical endpoint binds the physical network interface to
|
||||
// vfio-pci and adds device to the hypervisor with vfio-passthrough.
|
||||
func (endpoint *PhysicalEndpoint) Attach(ctx context.Context, s *Sandbox) error {
|
||||
span, ctx := physicalTrace(ctx, "Attach", endpoint)
|
||||
defer span.End()
|
||||
|
||||
// Unbind physical interface from host driver and bind to vfio
|
||||
// so that it can be passed to qemu.
|
||||
vfioPath, err := bindNICToVFIO(endpoint)
|
||||
@@ -108,9 +103,6 @@ func (endpoint *PhysicalEndpoint) Attach(ctx context.Context, s *Sandbox) error
|
||||
// Detach for physical endpoint unbinds the physical network interface from vfio-pci
|
||||
// and binds it back to the saved host driver.
|
||||
func (endpoint *PhysicalEndpoint) Detach(ctx context.Context, netNsCreated bool, netNsPath string) error {
|
||||
span, _ := physicalTrace(ctx, "Detach", endpoint)
|
||||
defer span.End()
|
||||
|
||||
// Bind back the physical network interface to host.
|
||||
// We need to do this even if a new network namespace has not
|
||||
// been created by virtcontainers.
|
||||
|
||||
@@ -13,7 +13,9 @@ import (
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"math"
|
||||
"net"
|
||||
"os"
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
"strconv"
|
||||
"strings"
|
||||
@@ -104,8 +106,6 @@ type qemu struct {
|
||||
|
||||
// if in memory dump progress
|
||||
memoryDumpFlag sync.Mutex
|
||||
|
||||
virtiofsd Virtiofsd
|
||||
}
|
||||
|
||||
const (
|
||||
@@ -219,7 +219,8 @@ func (q *qemu) trace(parent context.Context, name string) (otelTrace.Span, conte
|
||||
}
|
||||
|
||||
tracer := otel.Tracer("kata")
|
||||
ctx, span := tracer.Start(parent, name, otelTrace.WithAttributes(otelLabel.String("source", "runtime"), otelLabel.String("package", "virtcontainers"), otelLabel.String("subsystem", "hypervisor"), otelLabel.String("type", "qemu"), otelLabel.String("sandbox_id", q.id)))
|
||||
ctx, span := tracer.Start(parent, name)
|
||||
span.SetAttributes([]otelLabel.KeyValue{otelLabel.Key("subsystem").String("hypervisor"), otelLabel.Key("type").String("qemu")}...)
|
||||
|
||||
return span, ctx
|
||||
}
|
||||
@@ -604,11 +605,6 @@ func (q *qemu) createSandbox(ctx context.Context, id string, networkNS NetworkNa
|
||||
PidFile: filepath.Join(q.store.RunVMStoragePath(), q.id, "pid"),
|
||||
}
|
||||
|
||||
qemuConfig.Devices, qemuConfig.Bios, err = q.arch.appendProtectionDevice(qemuConfig.Devices, firmwarePath)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if ioThread != nil {
|
||||
qemuConfig.IOThreads = []govmmQemu.IOThread{*ioThread}
|
||||
}
|
||||
@@ -631,20 +627,6 @@ func (q *qemu) createSandbox(ctx context.Context, id string, networkNS NetworkNa
|
||||
|
||||
q.qemuConfig = qemuConfig
|
||||
|
||||
virtiofsdSocketPath, err := q.vhostFSSocketPath(q.id)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
q.virtiofsd = &virtiofsd{
|
||||
path: q.config.VirtioFSDaemon,
|
||||
sourcePath: filepath.Join(getSharePath(q.id)),
|
||||
socketPath: virtiofsdSocketPath,
|
||||
extraArgs: q.config.VirtioFSExtraArgs,
|
||||
debug: q.config.Debug,
|
||||
cache: q.config.VirtioFSCache,
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -652,29 +634,102 @@ func (q *qemu) vhostFSSocketPath(id string) (string, error) {
|
||||
return utils.BuildSocketPath(q.store.RunVMStoragePath(), id, vhostFSSocket)
|
||||
}
|
||||
|
||||
func (q *qemu) virtiofsdArgs(fd uintptr) []string {
|
||||
// The daemon will terminate when the vhost-user socket
|
||||
// connection with QEMU closes. Therefore we do not keep track
|
||||
// of this child process after returning from this function.
|
||||
sourcePath := filepath.Join(getSharePath(q.id))
|
||||
args := []string{
|
||||
fmt.Sprintf("--fd=%v", fd),
|
||||
"-o", "source=" + sourcePath,
|
||||
"-o", "cache=" + q.config.VirtioFSCache,
|
||||
"--syslog", "-o", "no_posix_lock"}
|
||||
if q.config.Debug {
|
||||
args = append(args, "-d")
|
||||
} else {
|
||||
args = append(args, "-f")
|
||||
}
|
||||
|
||||
if len(q.config.VirtioFSExtraArgs) != 0 {
|
||||
args = append(args, q.config.VirtioFSExtraArgs...)
|
||||
}
|
||||
return args
|
||||
}
|
||||
|
||||
func (q *qemu) setupVirtiofsd(ctx context.Context) (err error) {
|
||||
pid, err := q.virtiofsd.Start(ctx, func() {
|
||||
q.stopSandbox(ctx, false)
|
||||
var listener *net.UnixListener
|
||||
var fd *os.File
|
||||
|
||||
sockPath, err := q.vhostFSSocketPath(q.id)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
listener, err = net.ListenUnix("unix", &net.UnixAddr{
|
||||
Name: sockPath,
|
||||
Net: "unix",
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
q.state.VirtiofsdPid = pid
|
||||
listener.SetUnlinkOnClose(false)
|
||||
|
||||
return nil
|
||||
fd, err = listener.File()
|
||||
listener.Close() // no longer needed since fd is a dup
|
||||
listener = nil
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer fd.Close()
|
||||
|
||||
const sockFd = 3 // Cmd.ExtraFiles[] fds are numbered starting from 3
|
||||
cmd := exec.Command(q.config.VirtioFSDaemon, q.virtiofsdArgs(sockFd)...)
|
||||
cmd.ExtraFiles = append(cmd.ExtraFiles, fd)
|
||||
stderr, err := cmd.StderrPipe()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = cmd.Start()
|
||||
if err != nil {
|
||||
return fmt.Errorf("virtiofs daemon %v returned with error: %v", q.config.VirtioFSDaemon, err)
|
||||
}
|
||||
q.state.VirtiofsdPid = cmd.Process.Pid
|
||||
|
||||
// Monitor virtiofsd's stderr and stop sandbox if virtiofsd quits
|
||||
go func() {
|
||||
scanner := bufio.NewScanner(stderr)
|
||||
for scanner.Scan() {
|
||||
q.Logger().WithField("source", "virtiofsd").Info(scanner.Text())
|
||||
}
|
||||
q.Logger().Info("virtiofsd quits")
|
||||
// Wait to release resources of virtiofsd process
|
||||
cmd.Process.Wait()
|
||||
q.stopSandbox(ctx, false)
|
||||
}()
|
||||
return err
|
||||
}
|
||||
|
||||
func (q *qemu) stopVirtiofsd(ctx context.Context) (err error) {
|
||||
|
||||
// kill virtiofsd
|
||||
if q.state.VirtiofsdPid == 0 {
|
||||
return errors.New("invalid virtiofsd PID(0)")
|
||||
}
|
||||
|
||||
err = q.virtiofsd.Stop(ctx)
|
||||
err = syscall.Kill(q.state.VirtiofsdPid, syscall.SIGKILL)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
q.state.VirtiofsdPid = 0
|
||||
return nil
|
||||
|
||||
// remove virtiofsd socket
|
||||
sockPath, err := q.vhostFSSocketPath(q.id)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return os.Remove(sockPath)
|
||||
}
|
||||
|
||||
func (q *qemu) getMemArgs() (bool, string, string, error) {
|
||||
@@ -2196,6 +2251,7 @@ func calcHotplugMemMiBSize(mem uint32, memorySectionSizeMB uint32) (uint32, erro
|
||||
return mem, nil
|
||||
}
|
||||
|
||||
// TODO: hot add memory aligned to memory section should be more properly. See https://github.com/kata-containers/runtime/pull/624#issuecomment-419656853
|
||||
return uint32(math.Ceil(float64(mem)/float64(memorySectionSizeMB))) * memorySectionSizeMB, nil
|
||||
}
|
||||
|
||||
@@ -2268,10 +2324,6 @@ func (q *qemu) getPids() []int {
|
||||
return pids
|
||||
}
|
||||
|
||||
func (q *qemu) getVirtioFsPid() *int {
|
||||
return &q.state.VirtiofsdPid
|
||||
}
|
||||
|
||||
type qemuGrpc struct {
|
||||
ID string
|
||||
QmpChannelpath string
|
||||
|
||||
@@ -11,7 +11,6 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/kata-containers/kata-containers/src/runtime/virtcontainers/types"
|
||||
"github.com/sirupsen/logrus"
|
||||
|
||||
govmmQemu "github.com/kata-containers/govmm/qemu"
|
||||
)
|
||||
@@ -21,8 +20,6 @@ type qemuAmd64 struct {
|
||||
qemuArchBase
|
||||
|
||||
vmFactory bool
|
||||
|
||||
devLoadersCount uint32
|
||||
}
|
||||
|
||||
const (
|
||||
@@ -33,10 +30,6 @@ const (
|
||||
defaultQemuMachineOptions = "accel=kvm,kernel_irqchip"
|
||||
|
||||
qmpMigrationWaitTimeout = 5 * time.Second
|
||||
|
||||
tdxSysFirmwareDir = "/sys/firmware/tdx_seam/"
|
||||
|
||||
tdxCPUFlag = "tdx"
|
||||
)
|
||||
|
||||
var qemuPaths = map[string]string{
|
||||
@@ -113,17 +106,17 @@ func newQemuArch(config HypervisorConfig) (qemuArch, error) {
|
||||
factory = true
|
||||
}
|
||||
|
||||
// IOMMU and Guest Protection require a split IRQ controller for handling interrupts
|
||||
// otherwise QEMU won't be able to create the kernel irqchip
|
||||
if config.IOMMU || config.ConfidentialGuest {
|
||||
mp.Options = "accel=kvm,kernel_irqchip=split"
|
||||
}
|
||||
|
||||
if config.IOMMU {
|
||||
var q35QemuIOMMUOptions = "accel=kvm,kernel_irqchip=split"
|
||||
|
||||
kernelParams = append(kernelParams,
|
||||
Param{"intel_iommu", "on"})
|
||||
kernelParams = append(kernelParams,
|
||||
Param{"iommu", "pt"})
|
||||
|
||||
if mp.Type == QemuQ35 {
|
||||
mp.Options = q35QemuIOMMUOptions
|
||||
}
|
||||
}
|
||||
|
||||
q := &qemuAmd64{
|
||||
@@ -136,17 +129,10 @@ func newQemuArch(config HypervisorConfig) (qemuArch, error) {
|
||||
kernelParams: kernelParams,
|
||||
disableNvdimm: config.DisableImageNvdimm,
|
||||
dax: true,
|
||||
protection: noneProtection,
|
||||
},
|
||||
vmFactory: factory,
|
||||
}
|
||||
|
||||
if config.ConfidentialGuest {
|
||||
if err := q.enableProtection(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
q.handleImagePath(config)
|
||||
|
||||
return q, nil
|
||||
@@ -205,55 +191,3 @@ func (q *qemuAmd64) appendImage(ctx context.Context, devices []govmmQemu.Device,
|
||||
func (q *qemuAmd64) appendBridges(devices []govmmQemu.Device) []govmmQemu.Device {
|
||||
return genericAppendBridges(devices, q.Bridges, q.qemuMachine.Type)
|
||||
}
|
||||
|
||||
// enable protection
|
||||
func (q *qemuAmd64) enableProtection() error {
|
||||
var err error
|
||||
q.protection, err = availableGuestProtection()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
switch q.protection {
|
||||
case tdxProtection:
|
||||
if q.qemuMachine.Options != "" {
|
||||
q.qemuMachine.Options += ","
|
||||
}
|
||||
q.qemuMachine.Options += "kvm-type=tdx,confidential-guest-support=tdx"
|
||||
q.kernelParams = append(q.kernelParams, Param{"tdx_guest", ""})
|
||||
virtLog.WithFields(logrus.Fields{
|
||||
"subsystem": "qemuAmd64",
|
||||
"machine": q.qemuMachine,
|
||||
"kernel-params": q.kernelParameters}).
|
||||
Info("Enabling TDX guest protection")
|
||||
return nil
|
||||
|
||||
// TODO: Add support for other x86_64 technologies: SEV
|
||||
|
||||
default:
|
||||
return fmt.Errorf("This system doesn't support Confidential Computing (Guest Protection)")
|
||||
}
|
||||
}
|
||||
|
||||
// append protection device
|
||||
func (q *qemuAmd64) appendProtectionDevice(devices []govmmQemu.Device, firmware string) ([]govmmQemu.Device, string, error) {
|
||||
switch q.protection {
|
||||
case tdxProtection:
|
||||
id := q.devLoadersCount
|
||||
q.devLoadersCount += 1
|
||||
return append(devices,
|
||||
govmmQemu.Object{
|
||||
Driver: govmmQemu.Loader,
|
||||
Type: govmmQemu.TDXGuest,
|
||||
ID: "tdx",
|
||||
DeviceID: fmt.Sprintf("fd%d", id),
|
||||
Debug: false,
|
||||
File: firmware,
|
||||
}), "", nil
|
||||
case noneProtection:
|
||||
return devices, firmware, nil
|
||||
|
||||
default:
|
||||
return devices, "", fmt.Errorf("Unsupported guest protection technology: %v", q.protection)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -276,59 +276,3 @@ func TestQemuAmd64Microvm(t *testing.T) {
|
||||
|
||||
assert.False(amd64.supportGuestMemoryHotplug())
|
||||
}
|
||||
|
||||
func TestQemuAmd64AppendProtectionDevice(t *testing.T) {
|
||||
var devices []govmmQemu.Device
|
||||
assert := assert.New(t)
|
||||
|
||||
amd64 := newTestQemu(assert, QemuPC)
|
||||
|
||||
id := amd64.(*qemuAmd64).devLoadersCount
|
||||
firmware := "tdvf.fd"
|
||||
var bios string
|
||||
var err error
|
||||
devices, bios, err = amd64.appendProtectionDevice(devices, firmware)
|
||||
assert.NoError(err)
|
||||
|
||||
// non-protection
|
||||
assert.NotEmpty(bios)
|
||||
|
||||
// pef protection
|
||||
amd64.(*qemuAmd64).protection = pefProtection
|
||||
devices, bios, err = amd64.appendProtectionDevice(devices, firmware)
|
||||
assert.Error(err)
|
||||
assert.Empty(bios)
|
||||
|
||||
// Secure Execution protection
|
||||
amd64.(*qemuAmd64).protection = seProtection
|
||||
devices, bios, err = amd64.appendProtectionDevice(devices, firmware)
|
||||
assert.Error(err)
|
||||
assert.Empty(bios)
|
||||
|
||||
// sev protection
|
||||
// TODO: update once it's supported
|
||||
amd64.(*qemuAmd64).protection = sevProtection
|
||||
devices, bios, err = amd64.appendProtectionDevice(devices, firmware)
|
||||
assert.Error(err)
|
||||
assert.Empty(bios)
|
||||
|
||||
// tdxProtection
|
||||
amd64.(*qemuAmd64).protection = tdxProtection
|
||||
|
||||
devices, bios, err = amd64.appendProtectionDevice(devices, firmware)
|
||||
assert.NoError(err)
|
||||
assert.Empty(bios)
|
||||
|
||||
expectedOut := []govmmQemu.Device{
|
||||
govmmQemu.Object{
|
||||
Driver: govmmQemu.Loader,
|
||||
Type: govmmQemu.TDXGuest,
|
||||
ID: "tdx",
|
||||
DeviceID: fmt.Sprintf("fd%d", id),
|
||||
Debug: false,
|
||||
File: firmware,
|
||||
},
|
||||
}
|
||||
|
||||
assert.Equal(expectedOut, devices)
|
||||
}
|
||||
|
||||
@@ -11,7 +11,6 @@ import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"os"
|
||||
"runtime"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
@@ -143,37 +142,8 @@ type qemuArch interface {
|
||||
|
||||
// append pvpanic device
|
||||
appendPVPanicDevice(devices []govmmQemu.Device) ([]govmmQemu.Device, error)
|
||||
|
||||
// append protection device.
|
||||
// This implementation is architecture specific, some archs may need
|
||||
// a firmware, returns a string containing the path to the firmware that should
|
||||
// be used with the -bios option, ommit -bios option if the path is empty.
|
||||
appendProtectionDevice(devices []govmmQemu.Device, firmware string) ([]govmmQemu.Device, string, error)
|
||||
}
|
||||
|
||||
// Kind of guest protection
|
||||
type guestProtection uint8
|
||||
|
||||
const (
|
||||
noneProtection guestProtection = iota
|
||||
|
||||
//Intel Trust Domain Extensions
|
||||
//https://software.intel.com/content/www/us/en/develop/articles/intel-trust-domain-extensions.html
|
||||
tdxProtection
|
||||
|
||||
// AMD Secure Encrypted Virtualization
|
||||
// https://developer.amd.com/sev/
|
||||
sevProtection
|
||||
|
||||
// IBM POWER 9 Protected Execution Facility
|
||||
// https://www.kernel.org/doc/html/latest/powerpc/ultravisor.html
|
||||
pefProtection
|
||||
|
||||
// IBM Secure Execution (IBM Z & LinuxONE)
|
||||
// https://www.kernel.org/doc/html/latest/virt/kvm/s390-pv.html
|
||||
seProtection
|
||||
)
|
||||
|
||||
type qemuArchBase struct {
|
||||
qemuMachine govmmQemu.Machine
|
||||
qemuExePath string
|
||||
@@ -188,7 +158,6 @@ type qemuArchBase struct {
|
||||
kernelParams []Param
|
||||
Bridges []types.Bridge
|
||||
PFlash []string
|
||||
protection guestProtection
|
||||
}
|
||||
|
||||
const (
|
||||
@@ -844,9 +813,3 @@ func (q *qemuArchBase) getPFlash() ([]string, error) {
|
||||
func (q *qemuArchBase) setPFlash(p []string) {
|
||||
q.PFlash = p
|
||||
}
|
||||
|
||||
// append protection device
|
||||
func (q *qemuArchBase) appendProtectionDevice(devices []govmmQemu.Device, firmware string) ([]govmmQemu.Device, string, error) {
|
||||
virtLog.WithField("arch", runtime.GOARCH).Warnf("Confidential Computing has not been implemented for this architecture")
|
||||
return devices, firmware, nil
|
||||
}
|
||||
|
||||
@@ -27,14 +27,6 @@ const defaultQemuMachineOptions = "accel=kvm,usb=off"
|
||||
|
||||
const qmpMigrationWaitTimeout = 5 * time.Second
|
||||
|
||||
const pefSysFirmwareDir = "/sys/firmware/ultravisor/"
|
||||
|
||||
const pefID = "pef0"
|
||||
|
||||
const tpmID = "tpm0"
|
||||
|
||||
const tpmHostPath = "/dev/tpmrm0"
|
||||
|
||||
var kernelParams = []Param{
|
||||
{"rcupdate.rcu_expedited", "1"},
|
||||
{"reboot", "k"},
|
||||
@@ -51,7 +43,7 @@ var supportedQemuMachine = govmmQemu.Machine{
|
||||
|
||||
// Logger returns a logrus logger appropriate for logging qemu messages
|
||||
func (q *qemuPPC64le) Logger() *logrus.Entry {
|
||||
return virtLog.WithField("subsystem", "qemuPPC64le")
|
||||
return virtLog.WithField("subsystem", "qemu")
|
||||
}
|
||||
|
||||
// MaxQemuVCPUs returns the maximum number of vCPUs supported
|
||||
@@ -77,16 +69,9 @@ func newQemuArch(config HypervisorConfig) (qemuArch, error) {
|
||||
kernelParamsNonDebug: kernelParamsNonDebug,
|
||||
kernelParamsDebug: kernelParamsDebug,
|
||||
kernelParams: kernelParams,
|
||||
protection: noneProtection,
|
||||
},
|
||||
}
|
||||
|
||||
if config.ConfidentialGuest {
|
||||
if err := q.enableProtection(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
q.handleImagePath(config)
|
||||
|
||||
q.memoryOffset = config.MemOffset
|
||||
@@ -131,49 +116,3 @@ func (q *qemuPPC64le) appendBridges(devices []govmmQemu.Device) []govmmQemu.Devi
|
||||
func (q *qemuPPC64le) appendIOMMU(devices []govmmQemu.Device) ([]govmmQemu.Device, error) {
|
||||
return devices, fmt.Errorf("PPC64le does not support appending a vIOMMU")
|
||||
}
|
||||
|
||||
// Enables guest protection
|
||||
func (q *qemuPPC64le) enableProtection() error {
|
||||
var err error
|
||||
q.protection, err = availableGuestProtection()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
switch q.protection {
|
||||
case pefProtection:
|
||||
if q.qemuMachine.Options != "" {
|
||||
q.qemuMachine.Options += ","
|
||||
}
|
||||
q.qemuMachine.Options += fmt.Sprintf("confidential-guest-support=%s", pefID)
|
||||
virtLog.WithFields(logrus.Fields{
|
||||
"subsystem": "qemuPPC64le",
|
||||
"machine": q.qemuMachine,
|
||||
"kernel-params": q.kernelParams,
|
||||
}).Info("Enabling PEF protection")
|
||||
return nil
|
||||
|
||||
default:
|
||||
return fmt.Errorf("This system doesn't support Confidential Computing (Guest Protection)")
|
||||
}
|
||||
}
|
||||
|
||||
// append protection device
|
||||
func (q *qemuPPC64le) appendProtectionDevice(devices []govmmQemu.Device, firmware string) ([]govmmQemu.Device, string, error) {
|
||||
switch q.protection {
|
||||
case pefProtection:
|
||||
return append(devices,
|
||||
govmmQemu.Object{
|
||||
Driver: govmmQemu.SpaprTPMProxy,
|
||||
Type: govmmQemu.PEFGuest,
|
||||
ID: pefID,
|
||||
DeviceID: tpmID,
|
||||
File: tpmHostPath,
|
||||
}), firmware, nil
|
||||
case noneProtection:
|
||||
return devices, firmware, nil
|
||||
|
||||
default:
|
||||
return devices, "", fmt.Errorf("Unsupported guest protection technology: %v", q.protection)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,7 +14,6 @@ import (
|
||||
"github.com/kata-containers/kata-containers/src/runtime/virtcontainers/device/config"
|
||||
"github.com/kata-containers/kata-containers/src/runtime/virtcontainers/types"
|
||||
"github.com/kata-containers/kata-containers/src/runtime/virtcontainers/utils"
|
||||
"github.com/sirupsen/logrus"
|
||||
)
|
||||
|
||||
type qemuS390x struct {
|
||||
@@ -22,18 +21,15 @@ type qemuS390x struct {
|
||||
qemuArchBase
|
||||
}
|
||||
|
||||
const (
|
||||
defaultQemuPath = "/usr/bin/qemu-system-s390x"
|
||||
defaultQemuMachineType = QemuCCWVirtio
|
||||
defaultQemuMachineOptions = "accel=kvm"
|
||||
virtioSerialCCW = "virtio-serial-ccw"
|
||||
qmpMigrationWaitTimeout = 5 * time.Second
|
||||
logSubsystem = "qemuS390x"
|
||||
const defaultQemuPath = "/usr/bin/qemu-system-s390x"
|
||||
|
||||
// Secure Execution, also known as Protected Virtualization
|
||||
// https://qemu.readthedocs.io/en/latest/system/s390x/protvirt.html
|
||||
secExecID = "pv0"
|
||||
)
|
||||
const defaultQemuMachineType = QemuCCWVirtio
|
||||
|
||||
const defaultQemuMachineOptions = "accel=kvm"
|
||||
|
||||
const virtioSerialCCW = "virtio-serial-ccw"
|
||||
|
||||
const qmpMigrationWaitTimeout = 5 * time.Second
|
||||
|
||||
// Verify needed parameters
|
||||
var kernelParams = []Param{
|
||||
@@ -78,12 +74,6 @@ func newQemuArch(config HypervisorConfig) (qemuArch, error) {
|
||||
// Set first bridge type to CCW
|
||||
q.Bridges = append(q.Bridges, ccwbridge)
|
||||
|
||||
if config.ConfidentialGuest {
|
||||
if err := q.enableProtection(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
if config.ImagePath != "" {
|
||||
q.kernelParams = append(q.kernelParams, commonVirtioblkKernelRootParams...)
|
||||
q.kernelParamsNonDebug = append(q.kernelParamsNonDebug, kernelParamsSystemdNonDebug...)
|
||||
@@ -313,42 +303,3 @@ func (q *qemuS390x) addDeviceToBridge(ctx context.Context, ID string, t types.Ty
|
||||
|
||||
return fmt.Sprintf("%04x", addr), b, nil
|
||||
}
|
||||
|
||||
// enableProtection enables guest protection for QEMU's machine option.
|
||||
func (q *qemuS390x) enableProtection() error {
|
||||
protection, err := availableGuestProtection()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if protection != seProtection {
|
||||
return fmt.Errorf("Got unexpected protection %v, only seProtection (Secure Execution) is supported", protection)
|
||||
}
|
||||
|
||||
q.protection = protection
|
||||
if q.qemuMachine.Options != "" {
|
||||
q.qemuMachine.Options += ","
|
||||
}
|
||||
q.qemuMachine.Options += fmt.Sprintf("confidential-guest-support=%s", secExecID)
|
||||
virtLog.WithFields(logrus.Fields{
|
||||
"subsystem": logSubsystem,
|
||||
"machine": q.qemuMachine}).
|
||||
Info("Enabling guest protection with Secure Execution")
|
||||
return nil
|
||||
}
|
||||
|
||||
// appendProtectionDevice appends a QEMU object for Secure Execution.
|
||||
// Takes devices and returns updated version. Takes BIOS and returns it (no modification on s390x).
|
||||
func (q *qemuS390x) appendProtectionDevice(devices []govmmQemu.Device, firmware string) ([]govmmQemu.Device, string, error) {
|
||||
switch q.protection {
|
||||
case seProtection:
|
||||
return append(devices,
|
||||
govmmQemu.Object{
|
||||
Type: govmmQemu.SecExecGuest,
|
||||
ID: secExecID,
|
||||
}), firmware, nil
|
||||
case noneProtection:
|
||||
return devices, firmware, nil
|
||||
default:
|
||||
return devices, firmware, fmt.Errorf("Unsupported guest protection technology: %v", q.protection)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -101,50 +101,3 @@ func TestQemuS390xAppendVhostUserDevice(t *testing.T) {
|
||||
assert.NoError(err)
|
||||
assert.Equal(devices, expected)
|
||||
}
|
||||
|
||||
func TestQemuS390xAppendProtectionDevice(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
s390x := newTestQemu(assert, QemuCCWVirtio)
|
||||
|
||||
var devices []govmmQemu.Device
|
||||
var bios, firmware string
|
||||
var err error
|
||||
devices, bios, err = s390x.appendProtectionDevice(devices, firmware)
|
||||
assert.NoError(err)
|
||||
|
||||
// no protection
|
||||
assert.Empty(bios)
|
||||
|
||||
// PEF protection
|
||||
s390x.(*qemuS390x).protection = pefProtection
|
||||
devices, bios, err = s390x.appendProtectionDevice(devices, firmware)
|
||||
assert.Error(err)
|
||||
assert.Empty(bios)
|
||||
|
||||
// TDX protection
|
||||
s390x.(*qemuS390x).protection = tdxProtection
|
||||
devices, bios, err = s390x.appendProtectionDevice(devices, firmware)
|
||||
assert.Error(err)
|
||||
assert.Empty(bios)
|
||||
|
||||
// SEV protection
|
||||
s390x.(*qemuS390x).protection = sevProtection
|
||||
devices, bios, err = s390x.appendProtectionDevice(devices, firmware)
|
||||
assert.Error(err)
|
||||
assert.Empty(bios)
|
||||
|
||||
// Secure Execution protection
|
||||
s390x.(*qemuS390x).protection = seProtection
|
||||
|
||||
devices, bios, err = s390x.appendProtectionDevice(devices, firmware)
|
||||
assert.NoError(err)
|
||||
assert.Empty(bios)
|
||||
|
||||
expectedOut := []govmmQemu.Device{
|
||||
govmmQemu.Object{
|
||||
Type: govmmQemu.SecExecGuest,
|
||||
ID: secExecID,
|
||||
},
|
||||
}
|
||||
assert.Equal(expectedOut, devices)
|
||||
}
|
||||
|
||||
@@ -11,6 +11,7 @@ import (
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
govmmQemu "github.com/kata-containers/govmm/qemu"
|
||||
@@ -549,6 +550,35 @@ func createQemuSandboxConfig() (*Sandbox, error) {
|
||||
return &sandbox, nil
|
||||
}
|
||||
|
||||
func TestQemuVirtiofsdArgs(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
|
||||
q := &qemu{
|
||||
id: "foo",
|
||||
config: HypervisorConfig{
|
||||
VirtioFSCache: "none",
|
||||
Debug: true,
|
||||
},
|
||||
}
|
||||
|
||||
savedKataHostSharedDir := kataHostSharedDir
|
||||
kataHostSharedDir = func() string {
|
||||
return "test-share-dir"
|
||||
}
|
||||
defer func() {
|
||||
kataHostSharedDir = savedKataHostSharedDir
|
||||
}()
|
||||
|
||||
result := "--fd=123 -o source=test-share-dir/foo/shared -o cache=none --syslog -o no_posix_lock -d"
|
||||
args := q.virtiofsdArgs(123)
|
||||
assert.Equal(strings.Join(args, " "), result)
|
||||
|
||||
q.config.Debug = false
|
||||
result = "--fd=123 -o source=test-share-dir/foo/shared -o cache=none --syslog -o no_posix_lock -f"
|
||||
args = q.virtiofsdArgs(123)
|
||||
assert.Equal(strings.Join(args, " "), result)
|
||||
}
|
||||
|
||||
func TestQemuGetpids(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
|
||||
|
||||
@@ -134,7 +134,8 @@ func (s *Sandbox) trace(parent context.Context, name string) (otelTrace.Span, co
|
||||
}
|
||||
|
||||
tracer := otel.Tracer("kata")
|
||||
ctx, span := tracer.Start(parent, name, otelTrace.WithAttributes(otelLabel.String("source", "runtime"), otelLabel.String("package", "virtcontainers"), otelLabel.String("subsystem", "sandbox"), otelLabel.String("sandbox_id", s.id)))
|
||||
ctx, span := tracer.Start(parent, name)
|
||||
span.SetAttributes(otelLabel.Key("subsystem").String("sandbox"))
|
||||
|
||||
return span, ctx
|
||||
}
|
||||
@@ -394,7 +395,6 @@ func (s *Sandbox) IOStream(containerID, processID string) (io.WriteCloser, io.Re
|
||||
|
||||
func createAssets(ctx context.Context, sandboxConfig *SandboxConfig) error {
|
||||
span, _ := trace(ctx, "createAssets")
|
||||
span.SetAttributes(otelLabel.String("sandbox_id", sandboxConfig.ID), otelLabel.String("subsystem", "sandbox"))
|
||||
defer span.End()
|
||||
|
||||
for _, name := range types.AssetTypes() {
|
||||
@@ -445,7 +445,6 @@ func (s *Sandbox) getAndStoreGuestDetails(ctx context.Context) error {
|
||||
// be started.
|
||||
func createSandbox(ctx context.Context, sandboxConfig SandboxConfig, factory Factory) (*Sandbox, error) {
|
||||
span, ctx := trace(ctx, "createSandbox")
|
||||
span.SetAttributes(otelLabel.String("sandbox_id", sandboxConfig.ID), otelLabel.String("subsystem", "sandbox"))
|
||||
defer span.End()
|
||||
|
||||
if err := createAssets(ctx, &sandboxConfig); err != nil {
|
||||
@@ -484,7 +483,6 @@ func createSandbox(ctx context.Context, sandboxConfig SandboxConfig, factory Fac
|
||||
|
||||
func newSandbox(ctx context.Context, sandboxConfig SandboxConfig, factory Factory) (sb *Sandbox, retErr error) {
|
||||
span, ctx := trace(ctx, "newSandbox")
|
||||
span.SetAttributes(otelLabel.String("sandbox_id", sandboxConfig.ID), otelLabel.String("subsystem", "sandbox"))
|
||||
defer span.End()
|
||||
|
||||
if !sandboxConfig.valid() {
|
||||
@@ -760,9 +758,6 @@ func (s *Sandbox) createNetwork(ctx context.Context) error {
|
||||
NetNsCreated: s.config.NetworkConfig.NetNsCreated,
|
||||
}
|
||||
|
||||
span.SetAttributes(otelLabel.Any("networkNS", s.networkNS))
|
||||
span.SetAttributes(otelLabel.Any("NetworkConfig", s.config.NetworkConfig))
|
||||
|
||||
// In case there is a factory, network interfaces are hotplugged
|
||||
// after vm is started.
|
||||
if s.factory == nil {
|
||||
@@ -1276,6 +1271,7 @@ func (s *Sandbox) DeleteContainer(ctx context.Context, containerID string) (VCCo
|
||||
}
|
||||
|
||||
// StatusContainer gets the status of a container
|
||||
// TODO: update container status properly, see kata-containers/runtime#253
|
||||
func (s *Sandbox) StatusContainer(containerID string) (ContainerStatus, error) {
|
||||
if containerID == "" {
|
||||
return ContainerStatus{}, vcTypes.ErrNeedContainerID
|
||||
@@ -1533,7 +1529,7 @@ func (s *Sandbox) Stop(ctx context.Context, force bool) error {
|
||||
|
||||
// shutdown console watcher if exists
|
||||
if s.cw != nil {
|
||||
s.Logger().Debug("stop the console watcher")
|
||||
s.Logger().Debug("stop the sandbox")
|
||||
s.cw.stop()
|
||||
}
|
||||
|
||||
|
||||
@@ -16,10 +16,8 @@ import (
|
||||
|
||||
const namespaceHypervisor = "kata_hypervisor"
|
||||
const namespaceKatashim = "kata_shim"
|
||||
const namespaceVirtiofsd = "kata_virtiofsd"
|
||||
|
||||
var (
|
||||
// hypervisor
|
||||
hypervisorThreads = prometheus.NewGauge(prometheus.GaugeOpts{
|
||||
Namespace: namespaceHypervisor,
|
||||
Name: "threads",
|
||||
@@ -64,7 +62,6 @@ var (
|
||||
Help: "Open FDs for hypervisor.",
|
||||
})
|
||||
|
||||
// agent
|
||||
agentRPCDurationsHistogram = prometheus.NewHistogramVec(prometheus.HistogramOpts{
|
||||
Namespace: namespaceKatashim,
|
||||
Name: "agent_rpc_durations_histogram_milliseconds",
|
||||
@@ -73,61 +70,16 @@ var (
|
||||
},
|
||||
[]string{"action"},
|
||||
)
|
||||
|
||||
// virtiofsd
|
||||
virtiofsdThreads = prometheus.NewGauge(prometheus.GaugeOpts{
|
||||
Namespace: namespaceVirtiofsd,
|
||||
Name: "threads",
|
||||
Help: "Virtiofsd process threads.",
|
||||
})
|
||||
|
||||
virtiofsdProcStatus = prometheus.NewGaugeVec(prometheus.GaugeOpts{
|
||||
Namespace: namespaceVirtiofsd,
|
||||
Name: "proc_status",
|
||||
Help: "Virtiofsd process status.",
|
||||
},
|
||||
[]string{"item"},
|
||||
)
|
||||
|
||||
virtiofsdProcStat = prometheus.NewGaugeVec(prometheus.GaugeOpts{
|
||||
Namespace: namespaceVirtiofsd,
|
||||
Name: "proc_stat",
|
||||
Help: "Virtiofsd process statistics.",
|
||||
},
|
||||
[]string{"item"},
|
||||
)
|
||||
|
||||
virtiofsdIOStat = prometheus.NewGaugeVec(prometheus.GaugeOpts{
|
||||
Namespace: namespaceVirtiofsd,
|
||||
Name: "io_stat",
|
||||
Help: "Process IO statistics.",
|
||||
},
|
||||
[]string{"item"},
|
||||
)
|
||||
|
||||
virtiofsdOpenFDs = prometheus.NewGauge(prometheus.GaugeOpts{
|
||||
Namespace: namespaceVirtiofsd,
|
||||
Name: "fds",
|
||||
Help: "Open FDs for virtiofsd.",
|
||||
})
|
||||
)
|
||||
|
||||
func RegisterMetrics() {
|
||||
// hypervisor
|
||||
prometheus.MustRegister(hypervisorThreads)
|
||||
prometheus.MustRegister(hypervisorProcStatus)
|
||||
prometheus.MustRegister(hypervisorProcStat)
|
||||
prometheus.MustRegister(hypervisorNetdev)
|
||||
prometheus.MustRegister(hypervisorIOStat)
|
||||
prometheus.MustRegister(hypervisorOpenFDs)
|
||||
// agent
|
||||
prometheus.MustRegister(agentRPCDurationsHistogram)
|
||||
// virtiofsd
|
||||
prometheus.MustRegister(virtiofsdThreads)
|
||||
prometheus.MustRegister(virtiofsdProcStatus)
|
||||
prometheus.MustRegister(virtiofsdProcStat)
|
||||
prometheus.MustRegister(virtiofsdIOStat)
|
||||
prometheus.MustRegister(virtiofsdOpenFDs)
|
||||
}
|
||||
|
||||
// UpdateRuntimeMetrics update shim/hypervisor's metrics
|
||||
@@ -173,48 +125,6 @@ func (s *Sandbox) UpdateRuntimeMetrics() error {
|
||||
mutils.SetGaugeVecProcIO(hypervisorIOStat, ioStat)
|
||||
}
|
||||
|
||||
// virtiofs metrics
|
||||
err = s.UpdateVirtiofsdMetrics()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *Sandbox) UpdateVirtiofsdMetrics() error {
|
||||
vfsPid := s.hypervisor.getVirtioFsPid()
|
||||
if vfsPid == nil {
|
||||
// virtiofsd is not mandatory for a VMM.
|
||||
return nil
|
||||
}
|
||||
|
||||
proc, err := procfs.NewProc(*vfsPid)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// process FDs
|
||||
if fds, err := proc.FileDescriptorsLen(); err == nil {
|
||||
virtiofsdOpenFDs.Set(float64(fds))
|
||||
}
|
||||
|
||||
// process statistics
|
||||
if procStat, err := proc.Stat(); err == nil {
|
||||
virtiofsdThreads.Set(float64(procStat.NumThreads))
|
||||
mutils.SetGaugeVecProcStat(virtiofsdProcStat, procStat)
|
||||
}
|
||||
|
||||
// process status
|
||||
if procStatus, err := proc.NewStatus(); err == nil {
|
||||
mutils.SetGaugeVecProcStatus(virtiofsdProcStatus, procStatus)
|
||||
}
|
||||
|
||||
// process IO statistics
|
||||
if ioStat, err := proc.IO(); err == nil {
|
||||
mutils.SetGaugeVecProcIO(virtiofsdIOStat, ioStat)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
@@ -17,8 +17,6 @@ import (
|
||||
"github.com/kata-containers/kata-containers/src/runtime/virtcontainers/pkg/uuid"
|
||||
)
|
||||
|
||||
var tapTrace = getNetworkTrace(TapEndpointType)
|
||||
|
||||
// TapEndpoint represents just a tap endpoint
|
||||
type TapEndpoint struct {
|
||||
TapInterface TapInterface
|
||||
@@ -80,9 +78,6 @@ func (endpoint *TapEndpoint) Detach(ctx context.Context, netNsCreated bool, netN
|
||||
return nil
|
||||
}
|
||||
|
||||
span, _ := tapTrace(ctx, "Detach", endpoint)
|
||||
defer span.End()
|
||||
|
||||
networkLogger().WithField("endpoint-type", TapEndpointType).Info("Detaching endpoint")
|
||||
return doNetNS(netNsPath, func(_ ns.NetNS) error {
|
||||
return unTapNetwork(endpoint.TapInterface.TAPIface.Name)
|
||||
@@ -92,10 +87,6 @@ func (endpoint *TapEndpoint) Detach(ctx context.Context, netNsCreated bool, netN
|
||||
// HotAttach for the tap endpoint uses hot plug device
|
||||
func (endpoint *TapEndpoint) HotAttach(ctx context.Context, h hypervisor) error {
|
||||
networkLogger().Info("Hot attaching tap endpoint")
|
||||
|
||||
span, ctx := tapTrace(ctx, "HotAttach", endpoint)
|
||||
defer span.End()
|
||||
|
||||
if err := tapNetwork(endpoint, h.hypervisorConfig().NumVCPUs, h.hypervisorConfig().DisableVhostNet); err != nil {
|
||||
networkLogger().WithError(err).Error("Error bridging tap ep")
|
||||
return err
|
||||
@@ -111,10 +102,6 @@ func (endpoint *TapEndpoint) HotAttach(ctx context.Context, h hypervisor) error
|
||||
// HotDetach for the tap endpoint uses hot pull device
|
||||
func (endpoint *TapEndpoint) HotDetach(ctx context.Context, h hypervisor, netNsCreated bool, netNsPath string) error {
|
||||
networkLogger().Info("Hot detaching tap endpoint")
|
||||
|
||||
span, ctx := tapTrace(ctx, "HotDetach", endpoint)
|
||||
defer span.End()
|
||||
|
||||
if err := doNetNS(netNsPath, func(_ ns.NetNS) error {
|
||||
return unTapNetwork(endpoint.TapInterface.TAPIface.Name)
|
||||
}); err != nil {
|
||||
|
||||
@@ -18,8 +18,6 @@ import (
|
||||
vcTypes "github.com/kata-containers/kata-containers/src/runtime/virtcontainers/pkg/types"
|
||||
)
|
||||
|
||||
var tuntapTrace = getNetworkTrace(TuntapEndpointType)
|
||||
|
||||
// TuntapEndpoint represents just a tap endpoint
|
||||
type TuntapEndpoint struct {
|
||||
NetPair NetworkInterfacePair
|
||||
@@ -73,15 +71,11 @@ func (endpoint *TuntapEndpoint) SetProperties(properties NetworkInfo) {
|
||||
|
||||
// Attach for tap endpoint adds the tap interface to the hypervisor.
|
||||
func (endpoint *TuntapEndpoint) Attach(ctx context.Context, s *Sandbox) error {
|
||||
span, ctx := tuntapTrace(ctx, "Attach", endpoint)
|
||||
defer span.End()
|
||||
|
||||
h := s.hypervisor
|
||||
if err := xConnectVMNetwork(ctx, endpoint, h); err != nil {
|
||||
networkLogger().WithError(err).Error("Error bridging virtual endpoint")
|
||||
return err
|
||||
}
|
||||
|
||||
return h.addDevice(ctx, endpoint, netDev)
|
||||
}
|
||||
|
||||
@@ -91,9 +85,6 @@ func (endpoint *TuntapEndpoint) Detach(ctx context.Context, netNsCreated bool, n
|
||||
return nil
|
||||
}
|
||||
|
||||
span, _ := tuntapTrace(ctx, "Detach", endpoint)
|
||||
defer span.End()
|
||||
|
||||
networkLogger().WithField("endpoint-type", TuntapEndpointType).Info("Detaching endpoint")
|
||||
return doNetNS(netNsPath, func(_ ns.NetNS) error {
|
||||
return unTuntapNetwork(endpoint.TuntapInterface.TAPIface.Name)
|
||||
@@ -103,10 +94,6 @@ func (endpoint *TuntapEndpoint) Detach(ctx context.Context, netNsCreated bool, n
|
||||
// HotAttach for the tap endpoint uses hot plug device
|
||||
func (endpoint *TuntapEndpoint) HotAttach(ctx context.Context, h hypervisor) error {
|
||||
networkLogger().Info("Hot attaching tap endpoint")
|
||||
|
||||
span, ctx := tuntapTrace(ctx, "HotAttach", endpoint)
|
||||
defer span.End()
|
||||
|
||||
if err := tuntapNetwork(endpoint, h.hypervisorConfig().NumVCPUs, h.hypervisorConfig().DisableVhostNet); err != nil {
|
||||
networkLogger().WithError(err).Error("Error bridging tap ep")
|
||||
return err
|
||||
@@ -122,10 +109,6 @@ func (endpoint *TuntapEndpoint) HotAttach(ctx context.Context, h hypervisor) err
|
||||
// HotDetach for the tap endpoint uses hot pull device
|
||||
func (endpoint *TuntapEndpoint) HotDetach(ctx context.Context, h hypervisor, netNsCreated bool, netNsPath string) error {
|
||||
networkLogger().Info("Hot detaching tap endpoint")
|
||||
|
||||
span, ctx := tuntapTrace(ctx, "HotDetach", endpoint)
|
||||
defer span.End()
|
||||
|
||||
if err := doNetNS(netNsPath, func(_ ns.NetNS) error {
|
||||
return unTuntapNetwork(endpoint.TuntapInterface.TAPIface.Name)
|
||||
}); err != nil {
|
||||
|
||||
@@ -14,8 +14,6 @@ import (
|
||||
vcTypes "github.com/kata-containers/kata-containers/src/runtime/virtcontainers/pkg/types"
|
||||
)
|
||||
|
||||
var vethTrace = getNetworkTrace(VethEndpointType)
|
||||
|
||||
// VethEndpoint gathers a network pair and its properties.
|
||||
type VethEndpoint struct {
|
||||
NetPair NetworkInterfacePair
|
||||
@@ -94,9 +92,6 @@ func (endpoint *VethEndpoint) SetProperties(properties NetworkInfo) {
|
||||
// Attach for veth endpoint bridges the network pair and adds the
|
||||
// tap interface of the network pair to the hypervisor.
|
||||
func (endpoint *VethEndpoint) Attach(ctx context.Context, s *Sandbox) error {
|
||||
span, ctx := vethTrace(ctx, "Attach", endpoint)
|
||||
defer span.End()
|
||||
|
||||
h := s.hypervisor
|
||||
if err := xConnectVMNetwork(ctx, endpoint, h); err != nil {
|
||||
networkLogger().WithError(err).Error("Error bridging virtual endpoint")
|
||||
@@ -115,19 +110,13 @@ func (endpoint *VethEndpoint) Detach(ctx context.Context, netNsCreated bool, net
|
||||
return nil
|
||||
}
|
||||
|
||||
span, ctx := vethTrace(ctx, "Detach", endpoint)
|
||||
defer span.End()
|
||||
|
||||
return doNetNS(netNsPath, func(_ ns.NetNS) error {
|
||||
return xDisconnectVMNetwork(ctx, endpoint)
|
||||
return xDisconnectVMNetwork(endpoint)
|
||||
})
|
||||
}
|
||||
|
||||
// HotAttach for the veth endpoint uses hot plug device
|
||||
func (endpoint *VethEndpoint) HotAttach(ctx context.Context, h hypervisor) error {
|
||||
span, ctx := vethTrace(ctx, "HotAttach", endpoint)
|
||||
defer span.End()
|
||||
|
||||
if err := xConnectVMNetwork(ctx, endpoint, h); err != nil {
|
||||
networkLogger().WithError(err).Error("Error bridging virtual ep")
|
||||
return err
|
||||
@@ -146,11 +135,8 @@ func (endpoint *VethEndpoint) HotDetach(ctx context.Context, h hypervisor, netNs
|
||||
return nil
|
||||
}
|
||||
|
||||
span, ctx := vethTrace(ctx, "HotDetach", endpoint)
|
||||
defer span.End()
|
||||
|
||||
if err := doNetNS(netNsPath, func(_ ns.NetNS) error {
|
||||
return xDisconnectVMNetwork(ctx, endpoint)
|
||||
return xDisconnectVMNetwork(endpoint)
|
||||
}); err != nil {
|
||||
networkLogger().WithError(err).Warn("Error un-bridging virtual ep")
|
||||
}
|
||||
|
||||
@@ -23,8 +23,6 @@ import (
|
||||
// using this path.
|
||||
const hostSocketSearchPath = "/tmp/vhostuser_%s/vhu.sock"
|
||||
|
||||
var vhostuserTrace = getNetworkTrace(VhostUserEndpointType)
|
||||
|
||||
// VhostUserEndpoint represents a vhost-user socket based network interface
|
||||
type VhostUserEndpoint struct {
|
||||
// Path to the vhost-user socket on the host system
|
||||
@@ -79,9 +77,6 @@ func (endpoint *VhostUserEndpoint) NetworkPair() *NetworkInterfacePair {
|
||||
|
||||
// Attach for vhostuser endpoint
|
||||
func (endpoint *VhostUserEndpoint) Attach(ctx context.Context, s *Sandbox) error {
|
||||
span, ctx := vhostuserTrace(ctx, "Attach", endpoint)
|
||||
defer span.End()
|
||||
|
||||
// Generate a unique ID to be used for hypervisor commandline fields
|
||||
randBytes, err := utils.GenerateRandomBytes(8)
|
||||
if err != nil {
|
||||
|
||||
@@ -9,12 +9,14 @@ import (
|
||||
"bufio"
|
||||
"context"
|
||||
"fmt"
|
||||
"io"
|
||||
"net"
|
||||
"os"
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"syscall"
|
||||
"time"
|
||||
|
||||
"github.com/kata-containers/kata-containers/src/runtime/virtcontainers/utils"
|
||||
"github.com/pkg/errors"
|
||||
@@ -24,22 +26,20 @@ import (
|
||||
otelTrace "go.opentelemetry.io/otel/trace"
|
||||
)
|
||||
|
||||
var (
|
||||
errVirtiofsdDaemonPathEmpty = errors.New("virtiofsd daemon path is empty")
|
||||
errVirtiofsdSocketPathEmpty = errors.New("virtiofsd socket path is empty")
|
||||
errVirtiofsdSourcePathEmpty = errors.New("virtiofsd source path is empty")
|
||||
errVirtiofsdSourceNotAvailable = errors.New("virtiofsd source path not available")
|
||||
const (
|
||||
//Timeout to wait in secounds
|
||||
virtiofsdStartTimeout = 5
|
||||
)
|
||||
|
||||
type Virtiofsd interface {
|
||||
// Start virtiofsd, return pid of virtiofsd process
|
||||
Start(context.Context, onQuitFunc) (pid int, err error)
|
||||
Start(context.Context) (pid int, err error)
|
||||
// Stop virtiofsd process
|
||||
Stop(context.Context) error
|
||||
}
|
||||
|
||||
// Helper function to execute when virtiofsd quit
|
||||
type onQuitFunc func()
|
||||
// Helper function to check virtiofsd is serving
|
||||
type virtiofsdWaitFunc func(runningCmd *exec.Cmd, stderr io.ReadCloser, debug bool) error
|
||||
|
||||
type virtiofsd struct {
|
||||
// path to virtiofsd daemon
|
||||
@@ -58,6 +58,8 @@ type virtiofsd struct {
|
||||
PID int
|
||||
// Neded by tracing
|
||||
ctx context.Context
|
||||
// wait helper function to check if virtiofsd is serving
|
||||
wait virtiofsdWaitFunc
|
||||
}
|
||||
|
||||
// Open socket on behalf of virtiofsd
|
||||
@@ -83,7 +85,7 @@ func (v *virtiofsd) getSocketFD() (*os.File, error) {
|
||||
}
|
||||
|
||||
// Start the virtiofsd daemon
|
||||
func (v *virtiofsd) Start(ctx context.Context, onQuit onQuitFunc) (int, error) {
|
||||
func (v *virtiofsd) Start(ctx context.Context) (int, error) {
|
||||
span, _ := v.trace(ctx, "Start")
|
||||
defer span.End()
|
||||
pid := 0
|
||||
@@ -114,29 +116,21 @@ func (v *virtiofsd) Start(ctx context.Context, onQuit onQuitFunc) (int, error) {
|
||||
|
||||
v.Logger().WithField("path", v.path).Info()
|
||||
v.Logger().WithField("args", strings.Join(args, " ")).Info()
|
||||
stderr, err := cmd.StderrPipe()
|
||||
if err != nil {
|
||||
return pid, err
|
||||
}
|
||||
|
||||
if err = utils.StartCmd(cmd); err != nil {
|
||||
return pid, err
|
||||
}
|
||||
|
||||
// Monitor virtiofsd's stderr and stop sandbox if virtiofsd quits
|
||||
go func() {
|
||||
scanner := bufio.NewScanner(stderr)
|
||||
for scanner.Scan() {
|
||||
v.Logger().WithField("source", "virtiofsd").Info(scanner.Text())
|
||||
}
|
||||
v.Logger().Info("virtiofsd quits")
|
||||
// Wait to release resources of virtiofsd process
|
||||
cmd.Process.Wait()
|
||||
if onQuit != nil {
|
||||
onQuit()
|
||||
defer func() {
|
||||
if err != nil {
|
||||
cmd.Process.Kill()
|
||||
}
|
||||
}()
|
||||
|
||||
if v.wait == nil {
|
||||
v.wait = waitVirtiofsReady
|
||||
}
|
||||
|
||||
return cmd.Process.Pid, nil
|
||||
}
|
||||
|
||||
@@ -145,6 +139,10 @@ func (v *virtiofsd) Stop(ctx context.Context) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
if v.socketPath == "" {
|
||||
return errors.New("vitiofsd socket path is empty")
|
||||
}
|
||||
|
||||
err := os.Remove(v.socketPath)
|
||||
if err != nil {
|
||||
v.Logger().WithError(err).WithField("path", v.socketPath).Warn("removing virtiofsd socket failed")
|
||||
@@ -153,10 +151,19 @@ func (v *virtiofsd) Stop(ctx context.Context) error {
|
||||
}
|
||||
|
||||
func (v *virtiofsd) args(FdSocketNumber uint) ([]string, error) {
|
||||
if v.sourcePath == "" {
|
||||
return []string{}, errors.New("vitiofsd source path is empty")
|
||||
}
|
||||
|
||||
if _, err := os.Stat(v.sourcePath); os.IsNotExist(err) {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
args := []string{
|
||||
// Send logs to syslog
|
||||
"--syslog",
|
||||
// foreground operation
|
||||
"-f",
|
||||
// cache mode for virtiofsd
|
||||
"-o", "cache=" + v.cache,
|
||||
// disable posix locking in daemon: bunch of basic posix locks properties are broken
|
||||
@@ -169,11 +176,7 @@ func (v *virtiofsd) args(FdSocketNumber uint) ([]string, error) {
|
||||
}
|
||||
|
||||
if v.debug {
|
||||
// enable debug output (implies -f)
|
||||
args = append(args, "-d")
|
||||
} else {
|
||||
// foreground operation
|
||||
args = append(args, "-f")
|
||||
args = append(args, "-o", "debug")
|
||||
}
|
||||
|
||||
if len(v.extraArgs) != 0 {
|
||||
@@ -185,20 +188,18 @@ func (v *virtiofsd) args(FdSocketNumber uint) ([]string, error) {
|
||||
|
||||
func (v *virtiofsd) valid() error {
|
||||
if v.path == "" {
|
||||
return errVirtiofsdDaemonPathEmpty
|
||||
errors.New("virtiofsd path is empty")
|
||||
}
|
||||
|
||||
if v.socketPath == "" {
|
||||
return errVirtiofsdSocketPathEmpty
|
||||
errors.New("Virtiofsd socket path is empty")
|
||||
}
|
||||
|
||||
if v.sourcePath == "" {
|
||||
return errVirtiofsdSourcePathEmpty
|
||||
errors.New("virtiofsd source path is empty")
|
||||
|
||||
}
|
||||
|
||||
if _, err := os.Stat(v.sourcePath); err != nil {
|
||||
return errVirtiofsdSourceNotAvailable
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -212,11 +213,55 @@ func (v *virtiofsd) trace(parent context.Context, name string) (otelTrace.Span,
|
||||
}
|
||||
|
||||
tracer := otel.Tracer("kata")
|
||||
ctx, span := tracer.Start(parent, name, otelTrace.WithAttributes(label.String("source", "runtime"), label.String("package", "virtcontainers"), label.String("subsystem", "virtiofsd")))
|
||||
ctx, span := tracer.Start(parent, name)
|
||||
span.SetAttributes(label.Key("subsystem").String("virtiofds"))
|
||||
|
||||
return span, ctx
|
||||
}
|
||||
|
||||
func waitVirtiofsReady(cmd *exec.Cmd, stderr io.ReadCloser, debug bool) error {
|
||||
if cmd == nil {
|
||||
return errors.New("cmd is nil")
|
||||
}
|
||||
|
||||
sockReady := make(chan error, 1)
|
||||
go func() {
|
||||
scanner := bufio.NewScanner(stderr)
|
||||
var sent bool
|
||||
for scanner.Scan() {
|
||||
if debug {
|
||||
virtLog.WithField("source", "virtiofsd").Debug(scanner.Text())
|
||||
}
|
||||
if !sent && strings.Contains(scanner.Text(), "Waiting for vhost-user socket connection...") {
|
||||
sockReady <- nil
|
||||
sent = true
|
||||
}
|
||||
|
||||
}
|
||||
if !sent {
|
||||
if err := scanner.Err(); err != nil {
|
||||
sockReady <- err
|
||||
|
||||
} else {
|
||||
sockReady <- fmt.Errorf("virtiofsd did not announce socket connection")
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
// Wait to release resources of virtiofsd process
|
||||
cmd.Process.Wait()
|
||||
}()
|
||||
|
||||
var err error
|
||||
select {
|
||||
case err = <-sockReady:
|
||||
case <-time.After(virtiofsdStartTimeout * time.Second):
|
||||
err = fmt.Errorf("timed out waiting for vitiofsd ready mesage pid=%d", cmd.Process.Pid)
|
||||
}
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
func (v *virtiofsd) kill(ctx context.Context) (err error) {
|
||||
span, _ := v.trace(ctx, "kill")
|
||||
defer span.End()
|
||||
@@ -238,7 +283,7 @@ type virtiofsdMock struct {
|
||||
}
|
||||
|
||||
// Start the virtiofsd daemon
|
||||
func (v *virtiofsdMock) Start(ctx context.Context, onQuit onQuitFunc) (int, error) {
|
||||
func (v *virtiofsdMock) Start(ctx context.Context) (int, error) {
|
||||
return 9999999, nil
|
||||
}
|
||||
|
||||
|
||||
@@ -7,9 +7,10 @@ package virtcontainers
|
||||
|
||||
import (
|
||||
"context"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"strings"
|
||||
"os/exec"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
@@ -66,9 +67,13 @@ func TestVirtiofsdStart(t *testing.T) {
|
||||
debug: tt.fields.debug,
|
||||
PID: tt.fields.PID,
|
||||
ctx: tt.fields.ctx,
|
||||
//Mock wait function
|
||||
wait: func(runningCmd *exec.Cmd, stderr io.ReadCloser, debug bool) error {
|
||||
return nil
|
||||
},
|
||||
}
|
||||
var ctx context.Context
|
||||
_, err := v.Start(ctx, nil)
|
||||
_, err := v.Start(ctx)
|
||||
if (err != nil) != tt.wantErr {
|
||||
t.Errorf("virtiofsd.Start() error = %v, wantErr %v", err, tt.wantErr)
|
||||
return
|
||||
@@ -76,71 +81,3 @@ func TestVirtiofsdStart(t *testing.T) {
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestVirtiofsdArgs(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
|
||||
v := &virtiofsd{
|
||||
path: "/usr/bin/virtiofsd",
|
||||
sourcePath: "/run/kata-shared/foo",
|
||||
cache: "none",
|
||||
}
|
||||
|
||||
expected := "--syslog -o cache=none -o no_posix_lock -o source=/run/kata-shared/foo --fd=123 -f"
|
||||
args, err := v.args(123)
|
||||
assert.NoError(err)
|
||||
assert.Equal(expected, strings.Join(args, " "))
|
||||
|
||||
v.debug = false
|
||||
expected = "--syslog -o cache=none -o no_posix_lock -o source=/run/kata-shared/foo --fd=456 -f"
|
||||
args, err = v.args(456)
|
||||
assert.NoError(err)
|
||||
assert.Equal(expected, strings.Join(args, " "))
|
||||
}
|
||||
|
||||
func TestValid(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
|
||||
sourcePath, err := ioutil.TempDir("", "")
|
||||
assert.NoError(err)
|
||||
defer os.RemoveAll(sourcePath)
|
||||
|
||||
socketDir, err := ioutil.TempDir("", "")
|
||||
assert.NoError(err)
|
||||
defer os.RemoveAll(socketDir)
|
||||
|
||||
socketPath := socketDir + "socket.s"
|
||||
|
||||
newVirtiofsdFunc := func() *virtiofsd {
|
||||
return &virtiofsd{
|
||||
path: "/usr/bin/virtiofsd",
|
||||
sourcePath: sourcePath,
|
||||
socketPath: socketPath,
|
||||
}
|
||||
}
|
||||
|
||||
// valid case
|
||||
v := newVirtiofsdFunc()
|
||||
err = v.valid()
|
||||
assert.NoError(err)
|
||||
|
||||
v = newVirtiofsdFunc()
|
||||
v.path = ""
|
||||
err = v.valid()
|
||||
assert.Equal(errVirtiofsdDaemonPathEmpty, err)
|
||||
|
||||
v = newVirtiofsdFunc()
|
||||
v.sourcePath = ""
|
||||
err = v.valid()
|
||||
assert.Equal(errVirtiofsdSourcePathEmpty, err)
|
||||
|
||||
v = newVirtiofsdFunc()
|
||||
v.socketPath = ""
|
||||
err = v.valid()
|
||||
assert.Equal(errVirtiofsdSocketPathEmpty, err)
|
||||
|
||||
v = newVirtiofsdFunc()
|
||||
v.sourcePath = "/foo/bar"
|
||||
err = v.valid()
|
||||
assert.Equal(errVirtiofsdSourceNotAvailable, err)
|
||||
}
|
||||
|
||||
463
src/trace-forwarder/Cargo.lock
generated
463
src/trace-forwarder/Cargo.lock
generated
@@ -1,5 +1,14 @@
|
||||
# This file is automatically @generated by Cargo.
|
||||
# It is not intended for manual editing.
|
||||
[[package]]
|
||||
name = "aho-corasick"
|
||||
version = "0.7.13"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "043164d8ba5c4c3035fec9bbee8647c0261d788f3474306f93bb65901cae0e86"
|
||||
dependencies = [
|
||||
"memchr",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ansi_term"
|
||||
version = "0.11.0"
|
||||
@@ -9,15 +18,6 @@ dependencies = [
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ansi_term"
|
||||
version = "0.12.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d52a9bb7ec0cf484c551830a7ce27bd20d67eac647e1befb56b0be4ee39a55d2"
|
||||
dependencies = [
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "anyhow"
|
||||
version = "1.0.31"
|
||||
@@ -30,17 +30,6 @@ version = "0.4.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4d25d88fd6b8041580a654f9d0c581a047baee2b3efee13275f2fc392fc75034"
|
||||
|
||||
[[package]]
|
||||
name = "async-trait"
|
||||
version = "0.1.50"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0b98e84bbb4cbcdd97da190ba0c58a1bb0de2c1fdf67d159e192ed766aeca722"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "atty"
|
||||
version = "0.2.14"
|
||||
@@ -60,10 +49,11 @@ checksum = "f8aac770f1885fd7e387acedd76065302551364496e46b3dd00860b2f8359b9d"
|
||||
|
||||
[[package]]
|
||||
name = "bincode"
|
||||
version = "1.3.3"
|
||||
version = "1.3.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b1f45e9417d87227c7a56d22e471c6206462cba514c7590c09aff4cf6d1ddcad"
|
||||
checksum = "f30d3a39baa26f9651f17b375061f3233dde33424a8b72b0dbe93a68a0bc896d"
|
||||
dependencies = [
|
||||
"byteorder",
|
||||
"serde",
|
||||
]
|
||||
|
||||
@@ -73,17 +63,11 @@ version = "1.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693"
|
||||
|
||||
[[package]]
|
||||
name = "bumpalo"
|
||||
version = "3.6.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "63396b8a4b9de3f4fdfb320ab6080762242f66a8ef174c49d8e19b674db4cdbe"
|
||||
|
||||
[[package]]
|
||||
name = "byteorder"
|
||||
version = "1.4.3"
|
||||
version = "1.3.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610"
|
||||
checksum = "08c48aae112d48ed9f069b33538ea9e3e90aa263cfa3d1c24309612b1f7472de"
|
||||
|
||||
[[package]]
|
||||
name = "cc"
|
||||
@@ -97,23 +81,15 @@ version = "0.1.10"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822"
|
||||
|
||||
[[package]]
|
||||
name = "cfg-if"
|
||||
version = "1.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
|
||||
|
||||
[[package]]
|
||||
name = "chrono"
|
||||
version = "0.4.19"
|
||||
version = "0.4.11"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "670ad68c9088c2a963aaa298cb369688cf3f9465ce5e2d4ca10e6e0098a1ce73"
|
||||
checksum = "80094f509cf8b5ae86a4966a39b3ff66cd7e2a3e594accec3743ff3fabeab5b2"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"num-integer",
|
||||
"num-traits",
|
||||
"time",
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -122,7 +98,7 @@ version = "2.33.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bdfa80d47f954d53a35a64987ca1422f495b8d6483c0fe9f7117b36c2a792129"
|
||||
dependencies = [
|
||||
"ansi_term 0.11.0",
|
||||
"ansi_term",
|
||||
"atty",
|
||||
"bitflags",
|
||||
"strsim",
|
||||
@@ -137,20 +113,10 @@ version = "0.4.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cced8691919c02aac3cb0a1bc2e9b73d89e832bf9a06fc579d4e71b68a2da061"
|
||||
dependencies = [
|
||||
"crossbeam-utils 0.7.2",
|
||||
"crossbeam-utils",
|
||||
"maybe-uninit",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "crossbeam-channel"
|
||||
version = "0.5.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "06ed27e177f16d65f0f0c22a213e17c696ace5dd64b14258b52f9417ccb52db4"
|
||||
dependencies = [
|
||||
"cfg-if 1.0.0",
|
||||
"crossbeam-utils 0.8.4",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "crossbeam-utils"
|
||||
version = "0.7.2"
|
||||
@@ -158,26 +124,21 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c3c7c73a2d1e9fc0886a08b93e98eb643461230d5f1925e4036204d5f2e261a8"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
"cfg-if 0.1.10",
|
||||
"cfg-if",
|
||||
"lazy_static",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "crossbeam-utils"
|
||||
version = "0.8.4"
|
||||
name = "fnv"
|
||||
version = "1.0.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4feb231f0d4d6af81aed15928e58ecf5816aa62a2393e2c82f46973e92a9a278"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
"cfg-if 1.0.0",
|
||||
"lazy_static",
|
||||
]
|
||||
checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1"
|
||||
|
||||
[[package]]
|
||||
name = "futures"
|
||||
version = "0.3.15"
|
||||
version = "0.3.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0e7e43a803dae2fa37c1f6a8fe121e1f7bf9548b4dfc0522a42f34145dadfc27"
|
||||
checksum = "1e05b85ec287aac0dc34db7d4a569323df697f9c55b99b15d6b4ef8cde49f613"
|
||||
dependencies = [
|
||||
"futures-channel",
|
||||
"futures-core",
|
||||
@@ -190,9 +151,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "futures-channel"
|
||||
version = "0.3.15"
|
||||
version = "0.3.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e682a68b29a882df0545c143dc3646daefe80ba479bcdede94d5a703de2871e2"
|
||||
checksum = "f366ad74c28cca6ba456d95e6422883cfb4b252a83bed929c83abfdbbf2967d5"
|
||||
dependencies = [
|
||||
"futures-core",
|
||||
"futures-sink",
|
||||
@@ -200,15 +161,15 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "futures-core"
|
||||
version = "0.3.15"
|
||||
version = "0.3.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0402f765d8a89a26043b889b26ce3c4679d268fa6bb22cd7c6aad98340e179d1"
|
||||
checksum = "59f5fff90fd5d971f936ad674802482ba441b6f09ba5e15fd8b39145582ca399"
|
||||
|
||||
[[package]]
|
||||
name = "futures-executor"
|
||||
version = "0.3.15"
|
||||
version = "0.3.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "badaa6a909fac9e7236d0620a2f57f7664640c56575b71a7552fbd68deafab79"
|
||||
checksum = "10d6bb888be1153d3abeb9006b11b02cf5e9b209fda28693c31ae1e4e012e314"
|
||||
dependencies = [
|
||||
"futures-core",
|
||||
"futures-task",
|
||||
@@ -217,17 +178,16 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "futures-io"
|
||||
version = "0.3.15"
|
||||
version = "0.3.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "acc499defb3b348f8d8f3f66415835a9131856ff7714bf10dadfc4ec4bdb29a1"
|
||||
checksum = "de27142b013a8e869c14957e6d2edeef89e97c289e69d042ee3a49acd8b51789"
|
||||
|
||||
[[package]]
|
||||
name = "futures-macro"
|
||||
version = "0.3.15"
|
||||
version = "0.3.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a4c40298486cdf52cc00cd6d6987892ba502c7656a16a4192a9992b1ccedd121"
|
||||
checksum = "d0b5a30a4328ab5473878237c447333c093297bded83a4983d10f4deea240d39"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
"proc-macro-hack",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
@@ -236,23 +196,25 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "futures-sink"
|
||||
version = "0.3.15"
|
||||
version = "0.3.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a57bead0ceff0d6dde8f465ecd96c9338121bb7717d3e7b108059531870c4282"
|
||||
checksum = "3f2032893cb734c7a05d85ce0cc8b8c4075278e93b24b66f9de99d6eb0fa8acc"
|
||||
|
||||
[[package]]
|
||||
name = "futures-task"
|
||||
version = "0.3.15"
|
||||
version = "0.3.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8a16bef9fc1a4dddb5bee51c989e3fbba26569cbb0e31f5b303c184e3dd33dae"
|
||||
checksum = "bdb66b5f09e22019b1ab0830f7785bcea8e7a42148683f99214f73f8ec21a626"
|
||||
dependencies = [
|
||||
"once_cell",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "futures-util"
|
||||
version = "0.3.15"
|
||||
version = "0.3.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "feb5c238d27e2bf94ffdfd27b2c29e3df4a68c4193bb6427384259e2bf191967"
|
||||
checksum = "8764574ff08b701a084482c3c7031349104b07ac897393010494beaa18ce32c6"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
"futures-channel",
|
||||
"futures-core",
|
||||
"futures-io",
|
||||
@@ -260,7 +222,7 @@ dependencies = [
|
||||
"futures-sink",
|
||||
"futures-task",
|
||||
"memchr",
|
||||
"pin-project-lite",
|
||||
"pin-project",
|
||||
"pin-utils",
|
||||
"proc-macro-hack",
|
||||
"proc-macro-nested",
|
||||
@@ -273,20 +235,9 @@ version = "0.1.14"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7abc8dd8451921606d809ba32e95b6111925cd2906060d2dcc29c070220503eb"
|
||||
dependencies = [
|
||||
"cfg-if 0.1.10",
|
||||
"cfg-if",
|
||||
"libc",
|
||||
"wasi 0.9.0+wasi-snapshot-preview1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "getrandom"
|
||||
version = "0.2.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7fcd999463524c52659517fe2cea98493cfe485d10565e7b0fb07dbba7ad2753"
|
||||
dependencies = [
|
||||
"cfg-if 1.0.0",
|
||||
"libc",
|
||||
"wasi 0.10.2+wasi-snapshot-preview1",
|
||||
"wasi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -310,15 +261,6 @@ version = "0.4.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dc6f3ad7b9d11a0c00842ff8de1b60ee58661048eb8049ed33c73594f359d7e6"
|
||||
|
||||
[[package]]
|
||||
name = "js-sys"
|
||||
version = "0.3.51"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "83bdfbace3a0e81a4253f73b49e960b053e396a11012cbd49b9b74d6a2b67062"
|
||||
dependencies = [
|
||||
"wasm-bindgen",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "kata-trace-forwarder"
|
||||
version = "0.0.1"
|
||||
@@ -327,10 +269,9 @@ dependencies = [
|
||||
"bincode",
|
||||
"byteorder",
|
||||
"clap",
|
||||
"futures",
|
||||
"libc",
|
||||
"logging",
|
||||
"nix 0.20.0",
|
||||
"nix",
|
||||
"opentelemetry",
|
||||
"opentelemetry-jaeger",
|
||||
"protobuf",
|
||||
@@ -352,9 +293,9 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
|
||||
|
||||
[[package]]
|
||||
name = "libc"
|
||||
version = "0.2.94"
|
||||
version = "0.2.71"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "18794a8ad5b29321f790b55d93dfba91e125cb1a9edbd4f8e3150acc771c1a5e"
|
||||
checksum = "9457b06509d27052635f90d6466700c65095fdf75409b3fbdd903e988b886f49"
|
||||
|
||||
[[package]]
|
||||
name = "log"
|
||||
@@ -362,7 +303,7 @@ version = "0.4.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "14b6052be84e6b71ab17edffc2eeabf5c2c3ae1fdb464aae35ac50c67a44e1f7"
|
||||
dependencies = [
|
||||
"cfg-if 0.1.10",
|
||||
"cfg-if",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -399,26 +340,15 @@ checksum = "3728d817d99e5ac407411fa471ff9800a778d88a24685968b36824eaf4bee400"
|
||||
|
||||
[[package]]
|
||||
name = "nix"
|
||||
version = "0.19.1"
|
||||
version = "0.15.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b2ccba0cfe4fdf15982d1674c69b1fd80bad427d293849982668dfe454bd61f2"
|
||||
checksum = "3b2e0b4f3320ed72aaedb9a5ac838690a8047c7b275da22711fddff4f8a14229"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"cc",
|
||||
"cfg-if 1.0.0",
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "nix"
|
||||
version = "0.20.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fa9b4819da1bc61c0ea48b63b7bc8604064dd43013e7cc325df098d49cd7c18a"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"cc",
|
||||
"cfg-if 1.0.0",
|
||||
"cfg-if",
|
||||
"libc",
|
||||
"void",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -451,33 +381,34 @@ dependencies = [
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "opentelemetry"
|
||||
version = "0.14.0"
|
||||
name = "once_cell"
|
||||
version = "1.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "492848ff47f11b7f9de0443b404e2c5775f695e1af6b7076ca25f999581d547a"
|
||||
checksum = "0b631f7e854af39a1739f401cf34a8a013dfe09eac4fa4dba91e9768bd28168d"
|
||||
|
||||
[[package]]
|
||||
name = "opentelemetry"
|
||||
version = "0.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e1dbc1028f1f215373e28473238527c8799fbe88c58bae255585602c7316fa30"
|
||||
dependencies = [
|
||||
"async-trait",
|
||||
"crossbeam-channel 0.5.1",
|
||||
"bincode",
|
||||
"futures",
|
||||
"js-sys",
|
||||
"lazy_static",
|
||||
"percent-encoding",
|
||||
"pin-project",
|
||||
"rand 0.8.3",
|
||||
"prometheus",
|
||||
"rand",
|
||||
"serde",
|
||||
"thiserror",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "opentelemetry-jaeger"
|
||||
version = "0.13.0"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "97fd9ed34f208e0394bfb17522ba0d890925685dfd883147670ed474339d4647"
|
||||
checksum = "4da8b4162e8ae52c894f23895477f0d0340d34d8d35c367edf53de83adb1a6df"
|
||||
dependencies = [
|
||||
"async-trait",
|
||||
"lazy_static",
|
||||
"opentelemetry",
|
||||
"thiserror",
|
||||
"thrift",
|
||||
]
|
||||
|
||||
@@ -498,30 +429,24 @@ checksum = "d4fd5641d01c8f18a23da7b6fe29298ff4b55afcccdf78973b24cf3175fee32e"
|
||||
|
||||
[[package]]
|
||||
name = "pin-project"
|
||||
version = "1.0.7"
|
||||
version = "0.4.22"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c7509cc106041c40a4518d2af7a61530e1eed0e6285296a3d8c5472806ccc4a4"
|
||||
checksum = "12e3a6cdbfe94a5e4572812a0201f8c0ed98c1c452c7b8563ce2276988ef9c17"
|
||||
dependencies = [
|
||||
"pin-project-internal",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pin-project-internal"
|
||||
version = "1.0.7"
|
||||
version = "0.4.22"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "48c950132583b500556b1efd71d45b319029f2b71518d979fcc208e16b42426f"
|
||||
checksum = "6a0ffd45cf79d88737d7cc85bfd5d2894bee1139b356e616fe85dc389c61aaf7"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pin-project-lite"
|
||||
version = "0.2.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dc0e1f259c92177c30a4c9d177246edd0a3568b25756a977d0632cf8fa37e905"
|
||||
|
||||
[[package]]
|
||||
name = "pin-utils"
|
||||
version = "0.1.0"
|
||||
@@ -536,9 +461,9 @@ checksum = "237a5ed80e274dbc66f86bd59c1e25edc039660be53194b5fe0a482e0f2612ea"
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro-hack"
|
||||
version = "0.5.19"
|
||||
version = "0.5.16"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dbf0c48bc1d91375ae5c3cd81e3722dff1abcf81a30960240640d223f59fe0e5"
|
||||
checksum = "7e0456befd48169b9f13ef0f0ad46d492cf9d2dbb918bcf38e01eed4ce3ec5e4"
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro-nested"
|
||||
@@ -548,19 +473,39 @@ checksum = "eba180dafb9038b050a4c280019bbedf9f2467b61e5d892dcad585bb57aadc5a"
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro2"
|
||||
version = "1.0.27"
|
||||
version = "1.0.18"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f0d8caf72986c1a598726adc988bb5984792ef84f5ee5aa50209145ee8077038"
|
||||
checksum = "beae6331a816b1f65d04c45b078fd8e6c93e8071771f41b8163255bbd8d7c8fa"
|
||||
dependencies = [
|
||||
"unicode-xid",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "prometheus"
|
||||
version = "0.7.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5567486d5778e2c6455b1b90ff1c558f29e751fc018130fa182e15828e728af1"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"fnv",
|
||||
"lazy_static",
|
||||
"protobuf",
|
||||
"quick-error",
|
||||
"spin",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "protobuf"
|
||||
version = "2.14.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8e86d370532557ae7573551a1ec8235a0f8d6cb276c7c9e6aa490b511c447485"
|
||||
|
||||
[[package]]
|
||||
name = "quick-error"
|
||||
version = "1.2.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a1d01941d82fa2ab50be1e79e6714289dd7cde78eba4c074bc5a4374f650dfe0"
|
||||
|
||||
[[package]]
|
||||
name = "quote"
|
||||
version = "1.0.7"
|
||||
@@ -576,23 +521,11 @@ version = "0.7.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6a6b1679d49b24bbfe0c803429aa1874472f50d9b363131f0e89fc356b544d03"
|
||||
dependencies = [
|
||||
"getrandom 0.1.14",
|
||||
"getrandom",
|
||||
"libc",
|
||||
"rand_chacha 0.2.2",
|
||||
"rand_core 0.5.1",
|
||||
"rand_hc 0.2.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand"
|
||||
version = "0.8.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0ef9e7e66b4468674bfcb0c81af8b7fa0bb154fa9f28eb840da5c447baeb8d7e"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"rand_chacha 0.3.0",
|
||||
"rand_core 0.6.2",
|
||||
"rand_hc 0.3.0",
|
||||
"rand_chacha",
|
||||
"rand_core",
|
||||
"rand_hc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -602,17 +535,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f4c8ed856279c9737206bf725bf36935d8666ead7aa69b52be55af369d193402"
|
||||
dependencies = [
|
||||
"ppv-lite86",
|
||||
"rand_core 0.5.1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand_chacha"
|
||||
version = "0.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e12735cf05c9e10bf21534da50a147b924d555dc7a547c42e6bb2d5b6017ae0d"
|
||||
dependencies = [
|
||||
"ppv-lite86",
|
||||
"rand_core 0.6.2",
|
||||
"rand_core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -621,16 +544,7 @@ version = "0.5.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19"
|
||||
dependencies = [
|
||||
"getrandom 0.1.14",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand_core"
|
||||
version = "0.6.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "34cf66eb183df1c5876e2dcf6b13d57340741e8dc255b48e40a26de954d06ae7"
|
||||
dependencies = [
|
||||
"getrandom 0.2.3",
|
||||
"getrandom",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -639,16 +553,7 @@ version = "0.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ca3129af7b92a17112d59ad498c6f81eaf463253766b90396d39ea7a39d6613c"
|
||||
dependencies = [
|
||||
"rand_core 0.5.1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand_hc"
|
||||
version = "0.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3190ef7066a446f2e7f42e239d161e905420ccab01eb967c9eb27d21b2322a73"
|
||||
dependencies = [
|
||||
"rand_core 0.6.2",
|
||||
"rand_core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -663,7 +568,10 @@ version = "1.3.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9c3780fcf44b193bc4d09f36d2a3c87b251da4a046c87795a0d35f4f927ad8e6"
|
||||
dependencies = [
|
||||
"aho-corasick",
|
||||
"memchr",
|
||||
"regex-syntax",
|
||||
"thread_local",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -699,18 +607,18 @@ checksum = "71d301d4193d031abdd79ff7e3dd721168a9572ef3fe51a1517aba235bd8f86e"
|
||||
|
||||
[[package]]
|
||||
name = "serde"
|
||||
version = "1.0.126"
|
||||
version = "1.0.114"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ec7505abeacaec74ae4778d9d9328fe5a5d04253220a85c4ee022239fc996d03"
|
||||
checksum = "5317f7588f0a5078ee60ef675ef96735a1442132dc645eb1d12c018620ed8cd3"
|
||||
dependencies = [
|
||||
"serde_derive",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_derive"
|
||||
version = "1.0.126"
|
||||
version = "1.0.114"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "963a7dbc9895aeac7ac90e74f34a5d5261828f79df35cbed41e10189d3804d43"
|
||||
checksum = "2a0be94b04690fbaed37cddffc5c134bf537c8e3329d53e982fe04c374978f8e"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
@@ -730,9 +638,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "sharded-slab"
|
||||
version = "0.1.1"
|
||||
version = "0.0.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "79c719719ee05df97490f80a45acfc99e5a30ce98a1e4fb67aee422745ae14e3"
|
||||
checksum = "06d5a3f5166fb5b42a5439f2eee8b9de149e235961e3eb21c5808fc3ea17ff3e"
|
||||
dependencies = [
|
||||
"lazy_static",
|
||||
]
|
||||
@@ -755,7 +663,7 @@ version = "2.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "51b3336ce47ce2f96673499fc07eb85e3472727b9a7a2959964b002c2ce8fbbb"
|
||||
dependencies = [
|
||||
"crossbeam-channel 0.4.2",
|
||||
"crossbeam-channel",
|
||||
"slog",
|
||||
"take_mut",
|
||||
"thread_local",
|
||||
@@ -790,6 +698,12 @@ version = "1.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c7cb5678e1615754284ec264d9bb5b4c27d2018577fd90ac0ceb578591ed5ee4"
|
||||
|
||||
[[package]]
|
||||
name = "spin"
|
||||
version = "0.5.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d"
|
||||
|
||||
[[package]]
|
||||
name = "strsim"
|
||||
version = "0.8.0"
|
||||
@@ -798,9 +712,9 @@ checksum = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a"
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "1.0.72"
|
||||
version = "1.0.33"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a1e8cdbefb79a9a5a65e0db8b47b723ee907b7c7f8496c76a1770b5c310bab82"
|
||||
checksum = "e8d5d96e8cbb005d6959f119f773bfaebb5684296108fb32600c00cde305b2cd"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
@@ -819,9 +733,9 @@ version = "3.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7a6e24d9338a0a5be79593e2fa15a648add6138caa803e2d5bc782c371732ca9"
|
||||
dependencies = [
|
||||
"cfg-if 0.1.10",
|
||||
"cfg-if",
|
||||
"libc",
|
||||
"rand 0.7.3",
|
||||
"rand",
|
||||
"redox_syscall",
|
||||
"remove_dir_all",
|
||||
"winapi",
|
||||
@@ -836,26 +750,6 @@ dependencies = [
|
||||
"unicode-width",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "thiserror"
|
||||
version = "1.0.25"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fa6f76457f59514c7eeb4e59d891395fab0b2fd1d40723ae737d64153392e9c6"
|
||||
dependencies = [
|
||||
"thiserror-impl",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "thiserror-impl"
|
||||
version = "1.0.25"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8a36768c0fbf1bb15eca10defa29526bda730a2376c2ab4393ccfa16fb1a318d"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "thread_local"
|
||||
version = "1.0.1"
|
||||
@@ -899,21 +793,20 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "tracing"
|
||||
version = "0.1.26"
|
||||
version = "0.1.15"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "09adeb8c97449311ccd28a427f96fb563e7fd31aabf994189879d9da2394b89d"
|
||||
checksum = "a41f40ed0e162c911ac6fcb53ecdc8134c46905fdbbae8c50add462a538b495f"
|
||||
dependencies = [
|
||||
"cfg-if 1.0.0",
|
||||
"pin-project-lite",
|
||||
"cfg-if",
|
||||
"tracing-attributes",
|
||||
"tracing-core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tracing-attributes"
|
||||
version = "0.1.15"
|
||||
version = "0.1.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c42e6fa53307c8a17e4ccd4dc81cf5ec38db9209f59b222210375b54ee40d1e2"
|
||||
checksum = "99bbad0de3fd923c9c3232ead88510b783e5a4d16a6154adffa3d53308de984c"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
@@ -922,18 +815,18 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "tracing-core"
|
||||
version = "0.1.18"
|
||||
version = "0.1.10"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a9ff14f98b1a4b289c6248a023c1c2fa1491062964e9fed67ab29c4e4da4a052"
|
||||
checksum = "0aa83a9a47081cd522c09c81b31aec2c9273424976f922ad61c053b58350b715"
|
||||
dependencies = [
|
||||
"lazy_static",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tracing-log"
|
||||
version = "0.1.2"
|
||||
version = "0.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a6923477a48e41c1951f1999ef8bb5a3023eb723ceadafe78ffb65dc366761e3"
|
||||
checksum = "5e0f8c7178e13481ff6765bd169b33e8d554c5d2bbede5e32c356194be02b9b9"
|
||||
dependencies = [
|
||||
"lazy_static",
|
||||
"log",
|
||||
@@ -942,22 +835,22 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "tracing-opentelemetry"
|
||||
version = "0.13.0"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e2f4cb277b92a8ba1170b3b911056428ce2ef9993351baf5965bb0359a2e5963"
|
||||
checksum = "d79fdf3c82e6ea14c0f54cc9418aef57252150c6da0bc5f18553f0136f0dcd31"
|
||||
dependencies = [
|
||||
"opentelemetry",
|
||||
"rand",
|
||||
"tracing",
|
||||
"tracing-core",
|
||||
"tracing-log",
|
||||
"tracing-subscriber",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tracing-serde"
|
||||
version = "0.1.2"
|
||||
version = "0.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fb65ea441fbb84f9f6748fd496cf7f63ec9af5bca94dd86456978d055e8eb28b"
|
||||
checksum = "b6ccba2f8f16e0ed268fc765d9b7ff22e965e7185d32f8f1ec8294fe17d86e79"
|
||||
dependencies = [
|
||||
"serde",
|
||||
"tracing-core",
|
||||
@@ -965,11 +858,11 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "tracing-subscriber"
|
||||
version = "0.2.18"
|
||||
version = "0.2.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "aa5553bf0883ba7c9cbe493b085c29926bd41b66afc31ff72cf17ff4fb60dcd5"
|
||||
checksum = "04a11b459109e38ff6e1b580bafef4142a11d44889f5d07424cbce2fd2a2a119"
|
||||
dependencies = [
|
||||
"ansi_term 0.12.1",
|
||||
"ansi_term",
|
||||
"chrono",
|
||||
"lazy_static",
|
||||
"matchers",
|
||||
@@ -978,8 +871,6 @@ dependencies = [
|
||||
"serde_json",
|
||||
"sharded-slab",
|
||||
"smallvec",
|
||||
"thread_local",
|
||||
"tracing",
|
||||
"tracing-core",
|
||||
"tracing-log",
|
||||
"tracing-serde",
|
||||
@@ -1004,13 +895,19 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f1bddf1187be692e79c5ffeab891132dfb0f236ed36a43c7ed39f1165ee20191"
|
||||
|
||||
[[package]]
|
||||
name = "vsock"
|
||||
version = "0.2.3"
|
||||
name = "void"
|
||||
version = "1.0.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "50e2ef09834e1d203d24556512c0e58e66de203440bd9d74c30a33f7240091c6"
|
||||
checksum = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d"
|
||||
|
||||
[[package]]
|
||||
name = "vsock"
|
||||
version = "0.1.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "63b4354dabee252603a8b1a63e4adb3934dfbf1ff05ef4c3d653c2dfd67f0788"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"nix 0.19.1",
|
||||
"nix",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -1019,66 +916,6 @@ version = "0.9.0+wasi-snapshot-preview1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519"
|
||||
|
||||
[[package]]
|
||||
name = "wasi"
|
||||
version = "0.10.2+wasi-snapshot-preview1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fd6fbd9a79829dd1ad0cc20627bf1ed606756a7f77edff7b66b7064f9cb327c6"
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen"
|
||||
version = "0.2.74"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d54ee1d4ed486f78874278e63e4069fc1ab9f6a18ca492076ffb90c5eb2997fd"
|
||||
dependencies = [
|
||||
"cfg-if 1.0.0",
|
||||
"wasm-bindgen-macro",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-backend"
|
||||
version = "0.2.74"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3b33f6a0694ccfea53d94db8b2ed1c3a8a4c86dd936b13b9f0a15ec4a451b900"
|
||||
dependencies = [
|
||||
"bumpalo",
|
||||
"lazy_static",
|
||||
"log",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
"wasm-bindgen-shared",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-macro"
|
||||
version = "0.2.74"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "088169ca61430fe1e58b8096c24975251700e7b1f6fd91cc9d59b04fb9b18bd4"
|
||||
dependencies = [
|
||||
"quote",
|
||||
"wasm-bindgen-macro-support",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-macro-support"
|
||||
version = "0.2.74"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "be2241542ff3d9f241f5e2cb6dd09b37efe786df8851c54957683a49f0987a97"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
"wasm-bindgen-backend",
|
||||
"wasm-bindgen-shared",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-shared"
|
||||
version = "0.2.74"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d7cff876b8f18eed75a66cf49b65e7f967cb354a7aa16003fb55dbfd25b44b4f"
|
||||
|
||||
[[package]]
|
||||
name = "winapi"
|
||||
version = "0.3.9"
|
||||
|
||||
@@ -10,22 +10,21 @@ authors = ["The Kata Containers community <kata-dev@lists.katacontainers.io>"]
|
||||
edition = "2018"
|
||||
|
||||
[dependencies]
|
||||
futures = "0.3.15"
|
||||
clap = "2.33.0"
|
||||
vsock = "0.2.3"
|
||||
nix = "0.20.0"
|
||||
libc = "0.2.94"
|
||||
serde = { version = "1.0.126", features = ["derive"] }
|
||||
bincode = "1.3.3"
|
||||
byteorder = "1.4.3"
|
||||
vsock = "0.1.5"
|
||||
nix = "0.15.0"
|
||||
libc = "0.2.66"
|
||||
serde = { version = "1.0.106", features = ["derive"] }
|
||||
bincode = "1.2.1"
|
||||
byteorder = "1.3.4"
|
||||
serde_json = "1.0.44"
|
||||
anyhow = "1.0.31"
|
||||
opentelemetry = { version = "0.14.0", features=["serialize"] }
|
||||
opentelemetry-jaeger = "0.13.0"
|
||||
opentelemetry = { version = "0.5.0", features=["serialize"] }
|
||||
opentelemetry-jaeger = "0.4.0"
|
||||
protobuf = "=2.14.0"
|
||||
tracing-opentelemetry = "0.13.0"
|
||||
tracing = "0.1.26"
|
||||
tracing-subscriber = "0.2.18"
|
||||
tracing-opentelemetry = "0.4.0"
|
||||
tracing = "0.1.14"
|
||||
tracing-subscriber = "0.2.5"
|
||||
|
||||
logging = { path = "../../pkg/logging" }
|
||||
slog = "2.5.2"
|
||||
|
||||
@@ -3,12 +3,13 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
//
|
||||
|
||||
use anyhow::{anyhow, Context, Result};
|
||||
use byteorder::{ByteOrder, NetworkEndian};
|
||||
use opentelemetry::sdk::export::trace::{SpanData, SpanExporter};
|
||||
use opentelemetry::exporter::trace::SpanData;
|
||||
use opentelemetry::exporter::trace::{ExportResult, SpanExporter};
|
||||
use slog::{debug, info, o, Logger};
|
||||
use std::io::{ErrorKind, Read};
|
||||
use std::net::Shutdown;
|
||||
use std::sync::Arc;
|
||||
use vsock::VsockStream;
|
||||
|
||||
// The VSOCK "packet" protocol used comprises two elements:
|
||||
@@ -19,27 +20,23 @@ use vsock::VsockStream;
|
||||
// This constant defines the number of bytes used to encode the header on the
|
||||
// wire. In other words, the first 64-bits of the packet contain a number
|
||||
// specifying how many bytes are in the remainder of the packet.
|
||||
//
|
||||
// Must match the value of the variable of the same name in the agents
|
||||
// vsock-exporter.
|
||||
const HEADER_SIZE_BYTES: u64 = std::mem::size_of::<u64>() as u64;
|
||||
|
||||
fn mk_io_err(msg: &str) -> std::io::Error {
|
||||
std::io::Error::new(std::io::ErrorKind::Other, msg.to_string())
|
||||
}
|
||||
|
||||
pub async fn handle_connection<'a>(
|
||||
pub fn handle_connection(
|
||||
logger: Logger,
|
||||
mut conn: VsockStream,
|
||||
exporter: &'a mut dyn SpanExporter,
|
||||
) -> Result<()> {
|
||||
exporter: &dyn SpanExporter,
|
||||
) -> Result<(), std::io::Error> {
|
||||
let logger = logger.new(o!("subsystem" => "handler",
|
||||
"connection" => format!("{:?}", conn)));
|
||||
|
||||
debug!(logger, "handling connection");
|
||||
|
||||
handle_trace_data(logger.clone(), &mut conn, exporter)
|
||||
.await
|
||||
.map_err(|e| mk_io_err(&format!("failed to handle data: {:}", e)))?;
|
||||
|
||||
debug!(&logger, "handled data");
|
||||
@@ -52,11 +49,11 @@ pub async fn handle_connection<'a>(
|
||||
Ok(())
|
||||
}
|
||||
|
||||
async fn handle_trace_data<'a>(
|
||||
fn handle_trace_data(
|
||||
logger: Logger,
|
||||
reader: &'a mut dyn Read,
|
||||
exporter: &'a mut dyn SpanExporter,
|
||||
) -> Result<()> {
|
||||
reader: &mut dyn Read,
|
||||
exporter: &dyn SpanExporter,
|
||||
) -> Result<(), String> {
|
||||
loop {
|
||||
let mut header: [u8; HEADER_SIZE_BYTES as usize] = [0; HEADER_SIZE_BYTES as usize];
|
||||
|
||||
@@ -70,7 +67,7 @@ async fn handle_trace_data<'a>(
|
||||
break;
|
||||
}
|
||||
|
||||
return Err(anyhow!("failed to read header: {:}", e));
|
||||
return Err(format!("failed to read header: {:}", e));
|
||||
}
|
||||
};
|
||||
|
||||
@@ -81,7 +78,7 @@ async fn handle_trace_data<'a>(
|
||||
|
||||
reader
|
||||
.read_exact(&mut encoded_payload)
|
||||
.with_context(|| format!("failed to read payload"))?;
|
||||
.map_err(|e| format!("failed to read payload: {:}", e))?;
|
||||
|
||||
debug!(logger, "read payload");
|
||||
|
||||
@@ -90,15 +87,15 @@ async fn handle_trace_data<'a>(
|
||||
|
||||
debug!(logger, "deserialised payload");
|
||||
|
||||
let mut batch = Vec::<SpanData>::new();
|
||||
let mut batch = Vec::<Arc<SpanData>>::new();
|
||||
|
||||
batch.push(span_data);
|
||||
batch.push(Arc::new(span_data));
|
||||
|
||||
// Call low-level Jaeger exporter to send the trace span immediately.
|
||||
let result = exporter.export(batch).await;
|
||||
let result = exporter.export(batch);
|
||||
|
||||
if result.is_err() {
|
||||
return Err(anyhow!("failed to export trace spans: {:?}", result));
|
||||
if result != ExportResult::Success {
|
||||
return Err(format!("failed to export trace spans: {:?}", result));
|
||||
}
|
||||
|
||||
debug!(logger, "exported trace spans");
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
// Copyright (c) 2020-2021 Intel Corporation
|
||||
// Copyright (c) 2020 Intel Corporation
|
||||
//
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
//
|
||||
|
||||
use crate::handler;
|
||||
use anyhow::Result;
|
||||
use futures::executor::block_on;
|
||||
use nix::sys::socket::{SockAddr, VsockAddr};
|
||||
use slog::{debug, error, info, o, Logger};
|
||||
use vsock::{SockAddr, VsockListener};
|
||||
use std::io;
|
||||
use vsock::VsockListener;
|
||||
|
||||
use crate::tracer;
|
||||
|
||||
@@ -44,8 +44,9 @@ impl VsockTraceServer {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn start(&mut self) -> Result<()> {
|
||||
let sock_addr = SockAddr::new_vsock(self.vsock_cid, self.vsock_port);
|
||||
pub fn start(&mut self) -> Result<(), io::Error> {
|
||||
let vsock_addr = VsockAddr::new(self.vsock_cid, self.vsock_port);
|
||||
let sock_addr = SockAddr::Vsock(vsock_addr);
|
||||
|
||||
let listener = VsockListener::bind(&sock_addr)?;
|
||||
|
||||
@@ -57,7 +58,7 @@ impl VsockTraceServer {
|
||||
self.jaeger_port,
|
||||
);
|
||||
|
||||
let mut exporter = result?;
|
||||
let exporter = result?;
|
||||
|
||||
for conn in listener.incoming() {
|
||||
debug!(self.logger, "got client connection");
|
||||
@@ -71,9 +72,7 @@ impl VsockTraceServer {
|
||||
|
||||
let logger = self.logger.new(o!());
|
||||
|
||||
let f = handler::handle_connection(logger, conn, &mut exporter);
|
||||
|
||||
block_on(f)?;
|
||||
handler::handle_connection(logger, conn, &exporter)?;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
// Copyright (c) 2020-2021 Intel Corporation
|
||||
// Copyright (c) 2020 Intel Corporation
|
||||
//
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
//
|
||||
|
||||
use opentelemetry::KeyValue;
|
||||
use opentelemetry::api::Key;
|
||||
use std::net::SocketAddr;
|
||||
|
||||
pub fn create_jaeger_trace_exporter(
|
||||
@@ -15,6 +15,11 @@ pub fn create_jaeger_trace_exporter(
|
||||
|
||||
let jaeger_addr = format!("{}:{}", jaeger_host, jaeger_port);
|
||||
|
||||
let process = opentelemetry_jaeger::Process {
|
||||
service_name: jaeger_service_name,
|
||||
tags: vec![Key::new("exporter").string(exporter_type)],
|
||||
};
|
||||
|
||||
let socket_addr: SocketAddr = match jaeger_addr.parse() {
|
||||
Ok(a) => a,
|
||||
Err(e) => {
|
||||
@@ -25,11 +30,10 @@ pub fn create_jaeger_trace_exporter(
|
||||
}
|
||||
};
|
||||
|
||||
let exporter = match opentelemetry_jaeger::new_pipeline()
|
||||
.with_service_name(jaeger_service_name)
|
||||
let exporter = match opentelemetry_jaeger::Exporter::builder()
|
||||
.with_agent_endpoint(socket_addr.to_string())
|
||||
.with_tags(vec![KeyValue::new("exporter", exporter_type)])
|
||||
.init_exporter()
|
||||
.with_process(process)
|
||||
.init()
|
||||
{
|
||||
Ok(x) => x,
|
||||
Err(e) => {
|
||||
|
||||
518
tools/agent-ctl/Cargo.lock
generated
518
tools/agent-ctl/Cargo.lock
generated
File diff suppressed because it is too large
Load Diff
@@ -1,3 +1,5 @@
|
||||
[](https://travis-ci.org/kata-containers/osbuilder)
|
||||
|
||||
# osbuilder
|
||||
|
||||
* [osbuilder](#osbuilder)
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
ARG IMAGE_REGISTRY=docker.io
|
||||
FROM ${IMAGE_REGISTRY}/alpine:3.13.5
|
||||
FROM ${IMAGE_REGISTRY}/alpine:3.11.6
|
||||
|
||||
RUN apk update && apk add \
|
||||
bash \
|
||||
|
||||
@@ -562,14 +562,15 @@ EOT
|
||||
-e '/^\[Unit\]/a ConditionPathExists=\/dev\/ptp0' ${chrony_systemd_service}
|
||||
fi
|
||||
|
||||
# The CC on s390x for fedora needs to be manually set to gcc when the golang is downloaded from the main page.
|
||||
# See issue: https://github.com/kata-containers/osbuilder/issues/217
|
||||
[ "$distro" == "fedora" ] && [ "$ARCH" == "s390x" ] && export CC=gcc
|
||||
|
||||
AGENT_DIR="${ROOTFS_DIR}/usr/bin"
|
||||
AGENT_DEST="${AGENT_DIR}/${AGENT_BIN}"
|
||||
|
||||
if [ -z "${AGENT_SOURCE_BIN}" ] ; then
|
||||
if [ "$ARCH" == "ppc64le" ] || [ "$ARCH" == "s390x" ]; then
|
||||
LIBC=gnu
|
||||
echo "WARNING: Forcing LIBC=gnu because $ARCH has no musl Rust target"
|
||||
fi
|
||||
[ "$ARCH" == "ppc64le" ] && { LIBC=gnu; echo "WARNING: Forcing LIBC=gnu for ppc64le because musl toolchain is not supported on ppc64le"; }
|
||||
[ "$LIBC" == "musl" ] && bash ${script_dir}/../../../ci/install_musl.sh
|
||||
# rust agent needs ${arch}-unknown-linux-${LIBC}
|
||||
rustup show | grep linux-${LIBC} > /dev/null || bash ${script_dir}/../../../ci/install_rust.sh
|
||||
|
||||
@@ -339,8 +339,10 @@ RUN ln -sf /usr/bin/g++ /bin/musl-g++
|
||||
[ -f "${dockerfile_template}" ] || die "${dockerfile_template}: file not found"
|
||||
fi
|
||||
|
||||
# ppc64le and s390x have no musl target
|
||||
if [ "${architecture}" == "ppc64le" ] || [ "${architecture}" == "s390x" ]; then
|
||||
# powerpc have no musl target, don't setup rust enviroment
|
||||
# since we cannot static link agent. Besides, there is
|
||||
# also long double representation problem when building musl-libc
|
||||
if [ "${architecture}" == "ppc64le" ]; then
|
||||
sed \
|
||||
-e "s|@GO_VERSION@|${GO_VERSION}|g" \
|
||||
-e "s|@OS_VERSION@|${OS_VERSION:-}|g" \
|
||||
@@ -349,6 +351,17 @@ RUN ln -sf /usr/bin/g++ /bin/musl-g++
|
||||
-e "s|@INSTALL_RUST@|${install_rust//$'\n'/\\n}|g" \
|
||||
-e "s|@SET_PROXY@|${set_proxy:-}|g" \
|
||||
"${dockerfile_template}" > Dockerfile
|
||||
# no musl target on s390x, will use GNU
|
||||
elif [ "${architecture}" == "s390x" ]; then
|
||||
sed \
|
||||
-e "s|@GO_VERSION@|${GO_VERSION}|g" \
|
||||
-e "s|@OS_VERSION@|${OS_VERSION:-}|g" \
|
||||
-e "s|@INSTALL_CMAKE@|${install_cmake//$'\n'/\\n}|g" \
|
||||
-e "s|@INSTALL_MUSL@||g" \
|
||||
-e "s|@INSTALL_GO@|${install_go//$'\n'/\\n}|g" \
|
||||
-e "s|@INSTALL_RUST@|${install_rust//$'\n'/\\n}|g" \
|
||||
-e "s|@SET_PROXY@|${set_proxy:-}|g" \
|
||||
"${dockerfile_template}" > Dockerfile
|
||||
else
|
||||
sed \
|
||||
-e "s|@GO_VERSION@|${GO_VERSION}|g" \
|
||||
|
||||
@@ -18,7 +18,7 @@ spec:
|
||||
katacontainers.io/kata-runtime: cleanup
|
||||
containers:
|
||||
- name: kube-kata-cleanup
|
||||
image: katadocker/kata-deploy:2.2.0-alpha0
|
||||
image: katadocker/kata-deploy:2.1.1
|
||||
imagePullPolicy: Always
|
||||
command: [ "bash", "-c", "/opt/kata-artifacts/scripts/kata-deploy.sh reset" ]
|
||||
env:
|
||||
|
||||
@@ -16,7 +16,7 @@ spec:
|
||||
serviceAccountName: kata-label-node
|
||||
containers:
|
||||
- name: kube-kata
|
||||
image: katadocker/kata-deploy:2.2.0-alpha0
|
||||
image: katadocker/kata-deploy:2.1.1
|
||||
imagePullPolicy: Always
|
||||
lifecycle:
|
||||
preStop:
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user