Skip to content

Commit

Permalink
Merge branch 'main' into laurent/traefik-container
Browse files Browse the repository at this point in the history
  • Loading branch information
laurentluce committed Dec 3, 2023
2 parents 94d6d9b + 0c23166 commit 128f2e4
Show file tree
Hide file tree
Showing 48 changed files with 876 additions and 255 deletions.
28 changes: 28 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,33 @@
# Changelog

## [0.85.40](https://github.com/kurtosis-tech/kurtosis/compare/0.85.39...0.85.40) (2023-12-02)


### Features

* change change license to Apache 2.0 ([#1884](https://github.com/kurtosis-tech/kurtosis/issues/1884)) ([64084d8](https://github.com/kurtosis-tech/kurtosis/commit/64084d8e7ce18ebb86b05d17035db90971c2f867))


### Bug Fixes

* cache bug ([#1885](https://github.com/kurtosis-tech/kurtosis/issues/1885)) ([82e46e2](https://github.com/kurtosis-tech/kurtosis/commit/82e46e249006e85b4f71824798370968d8ee7731))
* change tail package ([#1874](https://github.com/kurtosis-tech/kurtosis/issues/1874)) ([f4e87ec](https://github.com/kurtosis-tech/kurtosis/commit/f4e87ec6757219b089ca3b7d2692bc15c42f8fd1))

## [0.85.39](https://github.com/kurtosis-tech/kurtosis/compare/0.85.38...0.85.39) (2023-11-30)


### Features

* emui package details page ([#1873](https://github.com/kurtosis-tech/kurtosis/issues/1873)) ([e2b75b2](https://github.com/kurtosis-tech/kurtosis/commit/e2b75b25d597ddfc49f0ebec1de5e2f7ca840281))
* User service ports Traefik Docker labels ([#1871](https://github.com/kurtosis-tech/kurtosis/issues/1871)) ([d18f20e](https://github.com/kurtosis-tech/kurtosis/commit/d18f20eee93d94739ea9bf497fc5d6780452d57d))


### Bug Fixes

* move log collector creation logic ([#1870](https://github.com/kurtosis-tech/kurtosis/issues/1870)) ([b695e27](https://github.com/kurtosis-tech/kurtosis/commit/b695e27742c653b635183c4db04e739b182eaec6))
* service name collision error message ([#1863](https://github.com/kurtosis-tech/kurtosis/issues/1863)) ([164b316](https://github.com/kurtosis-tech/kurtosis/commit/164b316d335e128668c9ca8b9f9eb74b22efe9ce))
* Update custom Nix dev deps to work on also linux ([#1862](https://github.com/kurtosis-tech/kurtosis/issues/1862)) ([d11cd37](https://github.com/kurtosis-tech/kurtosis/commit/d11cd37d5b733114937dd3d4e874255a03c1399d))

## [0.85.38](https://github.com/kurtosis-tech/kurtosis/compare/0.85.37...0.85.38) (2023-11-29)


Expand Down
8 changes: 4 additions & 4 deletions LICENSE.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ Business Source License 1.1
Parameters

Licensor: Kurtosis Technologies, Inc.
Licensed Work: Kurtosis 0.85.38
Licensed Work: Kurtosis 0.85.40
The Licensed Work is (c) 2023 Kurtosis Technologies, Inc.
Additional Use Grant: You may make use of the Licensed Work, provided that
you may not use the Licensed Work for an Environment Orchestration Service.
Expand All @@ -12,9 +12,9 @@ you may not use the Licensed Work for an Environment Orchestration Service.
allows third parties (other than your employees and
contractors) to create distributed system environments.

Change Date: 2027-11-29
Change Date: 2027-12-02

Change License: AGPLv3 (GNU Affero General Public License Version 3)
Change License: Apache 2.0 (Apache License, Version 2.0)

For information about alternative licensing arrangements for the Software,
please visit: https://kurtosis.com/
Expand Down Expand Up @@ -97,4 +97,4 @@ other recipients of the licensed work to be provided by Licensor:

3. To specify a Change Date.

4. Not to modify this License in any other way.
4. Not to modify this License in any other way.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ Check out an introductory demo video here:

How do I get going?
===================
To see Kurtosis in action, first install it using the instructions [here](https://docs.kurtosis.com/install). _Note that we're working on a cloud-hosted version of Kurtosis that doesn't require any local installation; if this is interesting to you then let us know [here](https://mp2k8nqxxgj.typeform.com/to/U1HcXT1H) and we'll let you know when it's available._
To see Kurtosis in action, first install it using the instructions [here](https://docs.kurtosis.com/install) or visit [Kurtosis Cloud][https://cloud.kurtosis.com/] to provision a remote host.

Then, run the [Redis voting app Kurtosis package](https://github.com/kurtosis-tech/awesome-kurtosis/tree/main/redis-voting-app):

Expand Down
2 changes: 1 addition & 1 deletion api/golang/kurtosis_version/kurtosis_version.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,6 @@ const (
// !!!!!!!!!!! DO NOT UPDATE! WILL BE MANUALLY UPDATED DURING THE RELEASE PROCESS !!!!!!!!!!!!!!!!!!!!!!
// This is necessary so that Kurt Core consumers will know if they're compatible with the currently-running
// API container
KurtosisVersion = "0.85.38"
KurtosisVersion = "0.85.40"
// !!!!!!!!!!! DO NOT UPDATE! WILL BE MANUALLY UPDATED DURING THE RELEASE PROCESS !!!!!!!!!!!!!!!!!!!!!!
)
2 changes: 1 addition & 1 deletion api/rust/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "kurtosis-sdk"
version = "0.85.38"
version = "0.85.40"
license = "BUSL-1.1"
description = "Rust SDK for Kurtosis"
edition = "2021"
Expand Down
2 changes: 1 addition & 1 deletion api/typescript/package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "kurtosis-sdk",
"//": "NOTE: DO NOT UPDATE THIS VERSION MANUALLY - IT WILL BE UPDATED DURING THE RELEASE PROCESS!",
"version": "0.85.38",
"version": "0.85.40",
"main": "./build/index",
"description": "This repo contains a Typescript client for communicating with the Kurtosis Engine server, which is responsible for creating, managing and destroying Kurtosis Enclaves.",
"types": "./build/index",
Expand Down
2 changes: 1 addition & 1 deletion api/typescript/src/kurtosis_version/kurtosis_version.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// !!!!!!!!!!! DO NOT UPDATE! WILL BE MANUALLY UPDATED DURING THE RELEASE PROCESS !!!!!!!!!!!!!!!!!!!!!!
// This is necessary so that Kurt Core consumers (e.g. modules) will know if they're compatible with the currently-running
// API container
export const KURTOSIS_VERSION: string = "0.85.38"
export const KURTOSIS_VERSION: string = "0.85.40"
// !!!!!!!!!!! DO NOT UPDATE! WILL BE MANUALLY UPDATED DURING THE RELEASE PROCESS !!!!!!!!!!!!!!!!!!!!!!
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,6 @@ const (
shouldFetchStoppedContainersWhenDumpingEnclave = true
shouldFetchStoppedContainersWhenDisconnectingFromEnclaveNetworks = false

defaultHttpLogsCollectorPortNum = uint16(9712)
defaultTcpLogsCollectorPortNum = uint16(9713)

serializedArgs = "SERIALIZED_ARGS"
)

Expand Down Expand Up @@ -149,19 +146,6 @@ func (backend *DockerKurtosisBackend) CreateEnclave(ctx context.Context, enclave

// TODO: return production mode for create enclave request as well
newEnclave := enclave.NewEnclave(enclaveUuid, enclaveName, enclave.EnclaveStatus_Empty, &creationTime, false)
// TODO the logs collector has a random private ip address in the enclave network that must be tracked
if _, err := backend.CreateLogsCollectorForEnclave(ctx, enclaveUuid, defaultTcpLogsCollectorPortNum, defaultHttpLogsCollectorPortNum); err != nil {
return nil, stacktrace.Propagate(err, "An error occurred creating the logs collector with TCP port number '%v' and HTTP port number '%v'", defaultTcpLogsCollectorPortNum, defaultHttpLogsCollectorPortNum)
}
shouldDeleteLogsCollector := true
defer func() {
if shouldDeleteLogsCollector {
err = backend.DestroyLogsCollectorForEnclave(ctx, enclaveUuid)
if err != nil {
logrus.Errorf("Couldn't cleanup logs collector for enclave '%v' as the following error was thrown:\n%v", enclaveUuid, err)
}
}
}()

if err := backend.ConnectReverseProxyToNetwork(ctx, networkId); err != nil {
return nil, stacktrace.Propagate(err, "An error occurred connecting the reverse proxy to the enclave network with ID '%v'", networkId)
Expand All @@ -176,7 +160,6 @@ func (backend *DockerKurtosisBackend) CreateEnclave(ctx context.Context, enclave
}
}()

shouldDeleteLogsCollector = false
shouldDeleteNetwork = false
shouldDeleteVolume = false
shouldDisconnectReverseProxyFromNetwork = false
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,12 @@ func ValidateUserCustomLabelKey(str string) error {
return nil
}

// CreateNewDockerUserCustomLabelKey creates a Traefik Docker label with the Traefik label key prefix
func CreateNewDockerTraefikLabelKey(str string) (*DockerLabelKey, error) {
labelKeyStr := traefikLabelKeyPrefixStr + str
return createNewDockerLabelKey(labelKeyStr)
}

func createNewDockerLabelKey(str string) (*DockerLabelKey, error) {
if err := validate(str); err != nil {
return nil, stacktrace.NewError("Label key string '%v' is not valid", str)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,9 @@ const (
logsServiceUuidDockerLabelKey = "service_uuid"
logsServiceShortUuidDockerLabelKey = "service_short_uuid"
logsServiceNameDockerLabelKey = "service_name"

// Traefik label keys
traefikLabelKeyPrefixStr = "traefik."
)

// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! DO NOT CHANGE THESE VALUES !!!!!!!!!!!!!!!!!!!!!!!!!!!!!
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,13 @@ package object_attributes_provider
import (
"crypto/md5"
"encoding/hex"
"fmt"
"net"
"strconv"
"strings"
"time"

"github.com/kurtosis-tech/kurtosis/container-engine-lib/lib/backend_impls/docker/docker_kurtosis_backend/consts"
"github.com/kurtosis-tech/kurtosis/container-engine-lib/lib/backend_impls/docker/object_attributes_provider/docker_label_key"
"github.com/kurtosis-tech/kurtosis/container-engine-lib/lib/backend_impls/docker/object_attributes_provider/docker_label_value"
"github.com/kurtosis-tech/kurtosis/container-engine-lib/lib/backend_impls/docker/object_attributes_provider/docker_object_name"
Expand All @@ -13,9 +20,6 @@ import (
"github.com/kurtosis-tech/kurtosis/container-engine-lib/lib/backend_interface/objects/service_directory"
"github.com/kurtosis-tech/kurtosis/container-engine-lib/lib/uuid_generator"
"github.com/kurtosis-tech/stacktrace"
"net"
"strings"
"time"
)

const (
Expand Down Expand Up @@ -250,6 +254,14 @@ func (provider *dockerEnclaveObjectAttributesProviderImpl) ForUserServiceContain
labels[dockerLabelKey] = dockerLabelValue
}

traefikLabels, err := provider.getTraefikLabelsForEnclaveObject(serviceUuidStr, privatePorts)
if err != nil {
return nil, stacktrace.Propagate(err, "An error occurred getting traefik labels for enclave object with UUID '%v'", serviceUuid)
}
for traefikLabelKey, traefikLabelValue := range traefikLabels {
labels[traefikLabelKey] = traefikLabelValue
}

objectAttributes, err := newDockerObjectAttributesImpl(name, labels)
if err != nil {
return nil, stacktrace.Propagate(
Expand Down Expand Up @@ -516,6 +528,94 @@ func (provider *dockerEnclaveObjectAttributesProviderImpl) getLabelsForEnclaveOb
return labels, nil
}

// Return Traefik labels
// Including the labels required to route traffic to the user service ports based on the Host header:
// <port number>-<service short uuid>-<enclave short uuid>
// The Traefik service name format is: <enclave short uuid>-<service short uuid>-<port number>
// With the following input:
// Enclave short UUID: 65d2fb6d6732
// Service short UUID: 3771c85af16a
// HTTP Port 1 number: 80
// HTTP Port 2 number: 81
// the following labels are returned:
// "traefik.enable": "true",
// "traefik.http.routers.65d2fb6d6732-3771c85af16a-80.rule": "Host(`80-3771c85af16a-65d2fb6d6732`)",
// "traefik.http.routers.65d2fb6d6732-3771c85af16a-80.service": "65d2fb6d6732-3771c85af16a-80",
// "traefik.http.services.65d2fb6d6732-3771c85af16a-80.loadbalancer.server.port": "80"
// "traefik.http.routers.65d2fb6d6732-3771c85af16a-81.rule": "Host(`81-3771c85af16a-65d2fb6d6732`)",
// "traefik.http.routers.65d2fb6d6732-3771c85af16a-81.service": "65d2fb6d6732-3771c85af16a-81",
// "traefik.http.services.65d2fb6d6732-3771c85af16a-81.loadbalancer.server.port": "81"
func (provider *dockerEnclaveObjectAttributesProviderImpl) getTraefikLabelsForEnclaveObject(serviceUuid string, ports map[string]*port_spec.PortSpec) (map[*docker_label_key.DockerLabelKey]*docker_label_value.DockerLabelValue, error) {
labels := map[*docker_label_key.DockerLabelKey]*docker_label_value.DockerLabelValue{}

for _, portSpec := range ports {
maybeApplicationProtocol := ""
if portSpec.GetMaybeApplicationProtocol() != nil {
maybeApplicationProtocol = *portSpec.GetMaybeApplicationProtocol()
}
if maybeApplicationProtocol == consts.HttpApplicationProtocol {
shortEnclaveUuid := uuid_generator.ShortenedUUIDString(provider.enclaveId.GetString())
shortServiceUuid := uuid_generator.ShortenedUUIDString(serviceUuid)
servicePortStr := fmt.Sprintf("%s-%s-%d", shortEnclaveUuid, shortServiceUuid, portSpec.GetNumber())

// Host rule
ruleKeySuffix := fmt.Sprintf("http.routers.%s.rule", servicePortStr)
ruleLabelKey, err := docker_label_key.CreateNewDockerTraefikLabelKey(ruleKeySuffix)
if err != nil {
return nil, stacktrace.Propagate(err, "An error occurred getting the traefik rule label key with suffix '%v'", ruleKeySuffix)
}
ruleValue := fmt.Sprintf("Host(`%d-%s-%s`)", portSpec.GetNumber(), shortServiceUuid, shortEnclaveUuid)
ruleLabelValue, err := docker_label_value.CreateNewDockerLabelValue(ruleValue)
if err != nil {
return nil, stacktrace.Propagate(err, "An error occurred creating the traefik rule label value with value '%v'", ruleValue)
}
labels[ruleLabelKey] = ruleLabelValue

// Service name
serviceKeySuffix := fmt.Sprintf("http.routers.%s.service", servicePortStr)
serviceLabelKey, err := docker_label_key.CreateNewDockerTraefikLabelKey(serviceKeySuffix)
if err != nil {
return nil, stacktrace.Propagate(err, "An error occurred getting the traefik service label key with suffix '%v'", serviceKeySuffix)
}
serviceValue := servicePortStr
serviceLabelValue, err := docker_label_value.CreateNewDockerLabelValue(serviceValue)
if err != nil {
return nil, stacktrace.Propagate(err, "An error occurred creating the traefik service label value with value '%v'", serviceValue)
}
labels[serviceLabelKey] = serviceLabelValue

// Service port number
portKeySuffix := fmt.Sprintf("http.services.%s.loadbalancer.server.port", servicePortStr)
portLabelKey, err := docker_label_key.CreateNewDockerTraefikLabelKey(portKeySuffix)
if err != nil {
return nil, stacktrace.Propagate(err, "An error occurred getting the traefik port label key with suffix '%v'", portKeySuffix)
}
portValue := strconv.Itoa(int(portSpec.GetNumber()))
portLabelValue, err := docker_label_value.CreateNewDockerLabelValue(portValue)
if err != nil {
return nil, stacktrace.Propagate(err, "An error occurred creating the traefik port label value with value '%v'", portValue)
}
labels[portLabelKey] = portLabelValue
}
}

if len(labels) > 0 {
// Enable Traefik for this service is there is at least one traefik label
traefikEnableLabelKey, err := docker_label_key.CreateNewDockerTraefikLabelKey("enable")
if err != nil {
return nil, stacktrace.Propagate(err, "An error occurred getting the traefik enable label key")
}
traefikEnableValue := "true"
traefikEnableLabelValue, err := docker_label_value.CreateNewDockerLabelValue(traefikEnableValue)
if err != nil {
return nil, stacktrace.Propagate(err, "An error occurred creating the traefik enable label value with value '%v'", traefikEnableValue)
}
labels[traefikEnableLabelKey] = traefikEnableLabelValue
}

return labels, nil
}

func getLabelKeyValuesAsStrings(labels map[*docker_label_key.DockerLabelKey]*docker_label_value.DockerLabelValue) map[string]string {
result := map[string]string{}
for key, value := range labels {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
package object_attributes_provider

import (
"net"
"testing"
"time"

"github.com/kurtosis-tech/kurtosis/container-engine-lib/lib/backend_impls/docker/docker_kurtosis_backend/consts"
"github.com/kurtosis-tech/kurtosis/container-engine-lib/lib/backend_impls/docker/object_attributes_provider/docker_label_key"
"github.com/kurtosis-tech/kurtosis/container-engine-lib/lib/backend_interface/objects/port_spec"
"github.com/kurtosis-tech/kurtosis/container-engine-lib/lib/backend_interface/objects/service"
"github.com/stretchr/testify/require"
)

const (
enclaveUuid = "65d2fb6d673249b8b4a91a2f4ae616de"
)

var (
portWaitForTest = port_spec.NewWait(5 * time.Second)
)

func TestForUserServiceContainer(t *testing.T) {
objAttrsProvider := GetDockerObjectAttributesProvider()
enclaveObjAttrsProvider, err := objAttrsProvider.ForEnclave(enclaveUuid)
require.NoError(t, err, "An unexpected error occurred getting the enclave object attributes provider")

serviceName := service.ServiceName("nginx")
serviceUuid := service.ServiceUUID("3771c85af16a40a18201acf4b4b5ad28")
privateIpAddr := net.IP("1.2.3.4")
port1Id := "port1"
port1Num := uint16(23)
port1Protocol := port_spec.TransportProtocol_TCP
port1Spec, err := port_spec.NewPortSpec(port1Num, port1Protocol, "", portWaitForTest)
require.NoError(t, err, "An unexpected error occurred creating port 1 spec")
port2Id := "port2"
port2Num := uint16(45)
port2Protocol := port_spec.TransportProtocol_TCP
port2ApplicationProtocol := consts.HttpApplicationProtocol
port2Spec, err := port_spec.NewPortSpec(port2Num, port2Protocol, port2ApplicationProtocol, portWaitForTest)
require.NoError(t, err, "An unexpected error occurred creating port 2 spec")
privatePorts := map[string]*port_spec.PortSpec{
port1Id: port1Spec,
port2Id: port2Spec,
}
userLabels := map[string]string{}
containerAttrs, err := enclaveObjAttrsProvider.ForUserServiceContainer(
serviceName,
serviceUuid,
privateIpAddr,
privatePorts,
userLabels,
)
require.NoError(t, err, "An unexpected error occurred getting the container attributes")
objName := containerAttrs.GetName()
require.Equal(t, objName.GetString(), "nginx--3771c85af16a40a18201acf4b4b5ad28")
objLabels := containerAttrs.GetLabels()
for labelKey, labelValue := range objLabels {
switch labelKey.GetString() {
case docker_label_key.AppIDDockerLabelKey.GetString():
require.Equal(t, labelValue.GetString(), "kurtosis")
case docker_label_key.ContainerTypeDockerLabelKey.GetString():
require.Equal(t, labelValue.GetString(), "user-service")
case docker_label_key.EnclaveUUIDDockerLabelKey.GetString():
require.Equal(t, labelValue.GetString(), "65d2fb6d673249b8b4a91a2f4ae616de")
case "traefik.enable":
require.Equal(t, labelValue.GetString(), "true")
case "traefik.http.routers.65d2fb6d6732-3771c85af16a-23.rule":
require.Fail(t, "A traefik label for port 23 should not be present")
case "traefik.http.routers.65d2fb6d6732-3771c85af16a-45.rule":
require.Equal(t, labelValue.GetString(), "Host(`45-3771c85af16a-65d2fb6d6732`)")
case "traefik.http.routers.65d2fb6d6732-3771c85af16a-45.service":
require.Equal(t, labelValue.GetString(), "65d2fb6d6732-3771c85af16a-45")
case "traefik.http.services.65d2fb6d6732-3771c85af16a-45.loadbalancer.server.port":
require.Equal(t, labelValue.GetString(), "45")
default:
break
}
}
}
2 changes: 1 addition & 1 deletion docs/docs/guides/running-in-k8s.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ There are many different ways to get a Kubernetes cluster (roughly ordered easie
- Deploy it on a managed Kuberenetes cluster, managing scaling and configurations yourself (e.g. EKS, AKS, GKE)

:::tip Kurtosis Kloud Early Access
If you're looking to run a stress-free "Kurtosis on Kubernetes in the cloud", look no further! We're excited to launch an early access offering for [Kurtosis Kloud](https://mp2k8nqxxgj.typeform.com/to/U1HcXT1H). Once you [sign up](https://mp2k8nqxxgj.typeform.com/to/U1HcXT1H), we'll reach out to you with the next steps.
If you're looking to run a stress-free "Kurtosis on Kubernetes in the cloud", look no further! Check out [Kurtosis Cloud](https://cloud.kurtosis.com/).
:::


Expand Down
Loading

0 comments on commit 128f2e4

Please sign in to comment.