mirror of
https://github.com/cirruslabs/orchard.git
synced 2026-09-29 19:41:15 +02:00
Support port-forwarding directly to Tart Guest Agent (#489)
This commit is contained in:
@@ -83,6 +83,9 @@ linters:
|
|||||||
# Avoid unrelated style churn for now
|
# Avoid unrelated style churn for now
|
||||||
- funcorder
|
- funcorder
|
||||||
|
|
||||||
|
# It's OK to have dynamic errors since we're not a library
|
||||||
|
- err113
|
||||||
|
|
||||||
issues:
|
issues:
|
||||||
# Don't hide multiple issues that belong to one class since GitHub annotations can handle them all nicely.
|
# Don't hide multiple issues that belong to one class since GitHub annotations can handle them all nicely.
|
||||||
max-issues-per-linter: 0
|
max-issues-per-linter: 0
|
||||||
|
|||||||
+15
-3
@@ -380,12 +380,17 @@ paths:
|
|||||||
type: string
|
type: string
|
||||||
get:
|
get:
|
||||||
summary: "Port-forward to a VM using WebSocket protocol"
|
summary: "Port-forward to a VM using WebSocket protocol"
|
||||||
|
description: |
|
||||||
|
Connect to a VM's TCP port, a declared host process, or its Tart Guest Agent.
|
||||||
|
Specify exactly one of `port`, `hostProcess`, or `target=tart-guest-agent`.
|
||||||
|
|
||||||
|
Connecting to Tart Guest Agent requires either the `compute:write` or `compute:connect:tart-guest-agent` role.
|
||||||
tags:
|
tags:
|
||||||
- vms
|
- vms
|
||||||
parameters:
|
parameters:
|
||||||
- in: query
|
- in: query
|
||||||
name: port
|
name: port
|
||||||
description: VM's TCP port number to connect to
|
description: VM's TCP port number to connect to; mutually exclusive with `hostProcess` and `target`.
|
||||||
schema:
|
schema:
|
||||||
type: integer
|
type: integer
|
||||||
minimum: 1
|
minimum: 1
|
||||||
@@ -393,10 +398,17 @@ paths:
|
|||||||
required: false
|
required: false
|
||||||
- in: query
|
- in: query
|
||||||
name: hostProcess
|
name: hostProcess
|
||||||
description: Name of a host process declared in the VM's `hostProcesses` field; mutually exclusive with `port`.
|
description: Name of a host process declared in the VM's `hostProcesses` field; mutually exclusive with `port` and `target`.
|
||||||
schema:
|
schema:
|
||||||
type: string
|
type: string
|
||||||
required: false
|
required: false
|
||||||
|
- in: query
|
||||||
|
name: target
|
||||||
|
description: Forward to the specified target; mutually exclusive with `port` and `hostProcess`.
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
|
enum: [tart-guest-agent]
|
||||||
|
required: false
|
||||||
- in: query
|
- in: query
|
||||||
name: wait
|
name: wait
|
||||||
description: Duration in seconds to wait for the VM to transition into "running" state if not already running.
|
description: Duration in seconds to wait for the VM to transition into "running" state if not already running.
|
||||||
@@ -420,7 +432,7 @@ paths:
|
|||||||
type: string
|
type: string
|
||||||
responses:
|
responses:
|
||||||
'400':
|
'400':
|
||||||
description: Invalid or ambiguous port-forward target specified
|
description: Invalid query parameter or ambiguous port-forward target specified
|
||||||
'404':
|
'404':
|
||||||
description: VM or requested host process doesn't exist
|
description: VM or requested host process doesn't exist
|
||||||
'503':
|
'503':
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ require (
|
|||||||
github.com/avast/retry-go/v4 v4.7.0
|
github.com/avast/retry-go/v4 v4.7.0
|
||||||
github.com/avast/retry-go/v5 v5.0.0
|
github.com/avast/retry-go/v5 v5.0.0
|
||||||
github.com/cirruslabs/chacha v0.16.3
|
github.com/cirruslabs/chacha v0.16.3
|
||||||
|
github.com/cirruslabs/tart-guest-agent v0.14.2
|
||||||
github.com/coder/websocket v1.8.14
|
github.com/coder/websocket v1.8.14
|
||||||
github.com/deckarep/golang-set/v2 v2.8.0
|
github.com/deckarep/golang-set/v2 v2.8.0
|
||||||
github.com/dgraph-io/badger/v3 v3.2103.5
|
github.com/dgraph-io/badger/v3 v3.2103.5
|
||||||
@@ -22,36 +23,36 @@ require (
|
|||||||
github.com/google/uuid v1.6.0
|
github.com/google/uuid v1.6.0
|
||||||
github.com/gosuri/uitable v0.0.4
|
github.com/gosuri/uitable v0.0.4
|
||||||
github.com/hashicorp/go-multierror v1.1.1
|
github.com/hashicorp/go-multierror v1.1.1
|
||||||
github.com/hashicorp/go-version v1.8.0
|
github.com/hashicorp/go-version v1.9.0
|
||||||
github.com/manifoldco/promptui v0.9.0
|
github.com/manifoldco/promptui v0.9.0
|
||||||
github.com/mitchellh/go-grpc-net-conn v0.0.0-20200427190222-eb030e4876f0
|
github.com/mitchellh/go-grpc-net-conn v0.0.0-20200427190222-eb030e4876f0
|
||||||
github.com/pkg/errors v0.9.1
|
github.com/pkg/errors v0.9.1
|
||||||
github.com/pterm/pterm v0.12.83
|
github.com/pterm/pterm v0.12.83
|
||||||
github.com/puzpuzpuz/xsync/v4 v4.4.0
|
github.com/puzpuzpuz/xsync/v4 v4.5.0
|
||||||
github.com/samber/lo v1.53.0
|
github.com/samber/lo v1.53.0
|
||||||
github.com/samber/mo v1.16.0
|
github.com/samber/mo v1.16.0
|
||||||
github.com/sethvargo/go-password v0.3.1
|
github.com/sethvargo/go-password v0.3.1
|
||||||
github.com/shirou/gopsutil/v4 v4.26.2
|
github.com/shirou/gopsutil/v4 v4.26.2
|
||||||
github.com/skratchdot/open-golang v0.0.0-20200116055534-eef842397966
|
github.com/skratchdot/open-golang v0.0.0-20200116055534-eef842397966
|
||||||
github.com/spf13/cobra v1.10.2
|
github.com/spf13/cobra v1.10.2
|
||||||
github.com/stretchr/testify v1.11.1
|
github.com/stretchr/testify v1.12.0
|
||||||
go.opentelemetry.io/contrib/instrumentation/github.com/gin-gonic/gin/otelgin v0.67.0
|
go.opentelemetry.io/contrib/instrumentation/github.com/gin-gonic/gin/otelgin v0.67.0
|
||||||
go.opentelemetry.io/otel v1.42.0
|
go.opentelemetry.io/otel v1.44.0
|
||||||
go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.42.0
|
go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.42.0
|
||||||
go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.42.0
|
go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.42.0
|
||||||
go.opentelemetry.io/otel/metric v1.42.0
|
go.opentelemetry.io/otel/metric v1.44.0
|
||||||
go.opentelemetry.io/otel/sdk/metric v1.42.0
|
go.opentelemetry.io/otel/sdk/metric v1.44.0
|
||||||
go.uber.org/zap v1.27.1
|
go.uber.org/zap v1.28.0
|
||||||
golang.org/x/crypto v0.49.0
|
golang.org/x/crypto v0.51.0
|
||||||
golang.org/x/exp v0.0.0-20250218142911-aa4b98e5adaa
|
golang.org/x/exp v0.0.0-20250218142911-aa4b98e5adaa
|
||||||
golang.org/x/exp/jsonrpc2 v0.0.0-20260718201538-764159d718ef
|
golang.org/x/exp/jsonrpc2 v0.0.0-20260718201538-764159d718ef
|
||||||
golang.org/x/net v0.52.0
|
golang.org/x/net v0.55.0
|
||||||
golang.org/x/sync v0.20.0
|
golang.org/x/sync v0.22.0
|
||||||
golang.org/x/sys v0.46.0
|
golang.org/x/sys v0.47.0
|
||||||
golang.org/x/term v0.41.0
|
golang.org/x/term v0.43.0
|
||||||
golang.org/x/text v0.35.0
|
golang.org/x/text v0.37.0
|
||||||
google.golang.org/grpc v1.79.3
|
google.golang.org/grpc v1.83.0
|
||||||
google.golang.org/protobuf v1.36.11
|
google.golang.org/protobuf v1.36.12
|
||||||
gopkg.in/natefinch/lumberjack.v2 v2.2.1
|
gopkg.in/natefinch/lumberjack.v2 v2.2.1
|
||||||
gopkg.in/yaml.v3 v3.0.1
|
gopkg.in/yaml.v3 v3.0.1
|
||||||
howett.net/plist v1.0.1
|
howett.net/plist v1.0.1
|
||||||
@@ -71,9 +72,8 @@ require (
|
|||||||
github.com/clipperhouse/uax29/v2 v2.7.0 // indirect
|
github.com/clipperhouse/uax29/v2 v2.7.0 // indirect
|
||||||
github.com/cloudwego/base64x v0.1.6 // indirect
|
github.com/cloudwego/base64x v0.1.6 // indirect
|
||||||
github.com/containerd/console v1.0.5 // indirect
|
github.com/containerd/console v1.0.5 // indirect
|
||||||
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect
|
|
||||||
github.com/dgraph-io/ristretto v0.1.1 // indirect
|
github.com/dgraph-io/ristretto v0.1.1 // indirect
|
||||||
github.com/ebitengine/purego v0.10.0 // indirect
|
github.com/ebitengine/purego v0.10.1 // indirect
|
||||||
github.com/fatih/color v1.18.0 // indirect
|
github.com/fatih/color v1.18.0 // indirect
|
||||||
github.com/gabriel-vasile/mimetype v1.4.13 // indirect
|
github.com/gabriel-vasile/mimetype v1.4.13 // indirect
|
||||||
github.com/gin-contrib/sse v1.1.0 // indirect
|
github.com/gin-contrib/sse v1.1.0 // indirect
|
||||||
@@ -125,7 +125,6 @@ require (
|
|||||||
github.com/modern-go/reflect2 v1.0.2 // indirect
|
github.com/modern-go/reflect2 v1.0.2 // indirect
|
||||||
github.com/oklog/ulid/v2 v2.1.1 // indirect
|
github.com/oklog/ulid/v2 v2.1.1 // indirect
|
||||||
github.com/pelletier/go-toml/v2 v2.2.4 // indirect
|
github.com/pelletier/go-toml/v2 v2.2.4 // indirect
|
||||||
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect
|
|
||||||
github.com/power-devops/perfstat v0.0.0-20240221224432-82ca36839d55 // indirect
|
github.com/power-devops/perfstat v0.0.0-20240221224432-82ca36839d55 // indirect
|
||||||
github.com/quic-go/qpack v0.6.0 // indirect
|
github.com/quic-go/qpack v0.6.0 // indirect
|
||||||
github.com/quic-go/quic-go v0.59.0 // indirect
|
github.com/quic-go/quic-go v0.59.0 // indirect
|
||||||
@@ -139,8 +138,8 @@ require (
|
|||||||
go.mongodb.org/mongo-driver/v2 v2.5.0 // indirect
|
go.mongodb.org/mongo-driver/v2 v2.5.0 // indirect
|
||||||
go.opencensus.io v0.22.5 // indirect
|
go.opencensus.io v0.22.5 // indirect
|
||||||
go.opentelemetry.io/auto/sdk v1.2.1 // indirect
|
go.opentelemetry.io/auto/sdk v1.2.1 // indirect
|
||||||
go.opentelemetry.io/otel/sdk v1.42.0 // indirect
|
go.opentelemetry.io/otel/sdk v1.44.0 // indirect
|
||||||
go.opentelemetry.io/otel/trace v1.42.0 // indirect
|
go.opentelemetry.io/otel/trace v1.44.0 // indirect
|
||||||
go.opentelemetry.io/proto/otlp v1.9.0 // indirect
|
go.opentelemetry.io/proto/otlp v1.9.0 // indirect
|
||||||
go.uber.org/multierr v1.11.0 // indirect
|
go.uber.org/multierr v1.11.0 // indirect
|
||||||
go.yaml.in/yaml/v3 v3.0.4 // indirect
|
go.yaml.in/yaml/v3 v3.0.4 // indirect
|
||||||
|
|||||||
@@ -47,6 +47,8 @@ github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1 h1:q763qf9huN11kDQavWs
|
|||||||
github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU=
|
github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU=
|
||||||
github.com/cirruslabs/chacha v0.16.3 h1:rOxn+qXsF3N9tQDpYxJ99e1ZP7G+IsFpzXd47IfSVIg=
|
github.com/cirruslabs/chacha v0.16.3 h1:rOxn+qXsF3N9tQDpYxJ99e1ZP7G+IsFpzXd47IfSVIg=
|
||||||
github.com/cirruslabs/chacha v0.16.3/go.mod h1:6rPd7APYL3lPLA6L9tP5KAwx3l0nYjFA+1o2amYoICI=
|
github.com/cirruslabs/chacha v0.16.3/go.mod h1:6rPd7APYL3lPLA6L9tP5KAwx3l0nYjFA+1o2amYoICI=
|
||||||
|
github.com/cirruslabs/tart-guest-agent v0.14.2 h1:m3pKQ7NYTVKb5whX00AhOXOUOfUXArqLApHWjIWjyL4=
|
||||||
|
github.com/cirruslabs/tart-guest-agent v0.14.2/go.mod h1:zB/fw/qgmS/Ah0idRH2PlYhbtwlQ1/7CeHHqzCigWlM=
|
||||||
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
|
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
|
||||||
github.com/clipperhouse/uax29/v2 v2.7.0 h1:+gs4oBZ2gPfVrKPthwbMzWZDaAFPGYK72F0NJv2v7Vk=
|
github.com/clipperhouse/uax29/v2 v2.7.0 h1:+gs4oBZ2gPfVrKPthwbMzWZDaAFPGYK72F0NJv2v7Vk=
|
||||||
github.com/clipperhouse/uax29/v2 v2.7.0/go.mod h1:EFJ2TJMRUaplDxHKj1qAEhCtQPW2tJSwu5BF98AuoVM=
|
github.com/clipperhouse/uax29/v2 v2.7.0/go.mod h1:EFJ2TJMRUaplDxHKj1qAEhCtQPW2tJSwu5BF98AuoVM=
|
||||||
@@ -78,8 +80,8 @@ github.com/dgryski/go-farm v0.0.0-20190423205320-6a90982ecee2/go.mod h1:SqUrOPUn
|
|||||||
github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk=
|
github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk=
|
||||||
github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY=
|
github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY=
|
||||||
github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto=
|
github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto=
|
||||||
github.com/ebitengine/purego v0.10.0 h1:QIw4xfpWT6GWTzaW5XEKy3HXoqrJGx1ijYHzTF0/ISU=
|
github.com/ebitengine/purego v0.10.1 h1:dewVBCBT2GaMu1SrNTYxQhgQBethzfhiwvZiLGP/qyY=
|
||||||
github.com/ebitengine/purego v0.10.0/go.mod h1:iIjxzd6CiRiOG0UyXP+V1+jWqUXVjPKLAI0mRfJZTmQ=
|
github.com/ebitengine/purego v0.10.1/go.mod h1:iIjxzd6CiRiOG0UyXP+V1+jWqUXVjPKLAI0mRfJZTmQ=
|
||||||
github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
|
github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
|
||||||
github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98=
|
github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98=
|
||||||
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
|
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
|
||||||
@@ -202,8 +204,8 @@ github.com/hashicorp/errwrap v1.0.0 h1:hLrqtEDnRye3+sgx6z4qVLNuviH3MR5aQ0ykNJa/U
|
|||||||
github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
|
github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
|
||||||
github.com/hashicorp/go-multierror v1.1.1 h1:H5DkEtf6CXdFp0N0Em5UCwQpXMWke8IA0+lD48awMYo=
|
github.com/hashicorp/go-multierror v1.1.1 h1:H5DkEtf6CXdFp0N0Em5UCwQpXMWke8IA0+lD48awMYo=
|
||||||
github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9/fmwbPZ6JB6eMoM=
|
github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9/fmwbPZ6JB6eMoM=
|
||||||
github.com/hashicorp/go-version v1.8.0 h1:KAkNb1HAiZd1ukkxDFGmokVZe1Xy9HG6NUp+bPle2i4=
|
github.com/hashicorp/go-version v1.9.0 h1:CeOIz6k+LoN3qX9Z0tyQrPtiB1DFYRPfCIBtaXPSCnA=
|
||||||
github.com/hashicorp/go-version v1.8.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA=
|
github.com/hashicorp/go-version v1.9.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA=
|
||||||
github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ=
|
github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ=
|
||||||
github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
|
github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
|
||||||
github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8=
|
github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8=
|
||||||
@@ -263,8 +265,6 @@ github.com/pelletier/go-toml/v2 v2.2.4/go.mod h1:2gIqNv+qfxSVS7cM2xJQKtLSTLUE9V8
|
|||||||
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
|
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
|
||||||
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||||
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U=
|
|
||||||
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
|
||||||
github.com/power-devops/perfstat v0.0.0-20240221224432-82ca36839d55 h1:o4JXh1EVt9k/+g42oCprj/FisM4qX9L3sZB3upGN2ZU=
|
github.com/power-devops/perfstat v0.0.0-20240221224432-82ca36839d55 h1:o4JXh1EVt9k/+g42oCprj/FisM4qX9L3sZB3upGN2ZU=
|
||||||
github.com/power-devops/perfstat v0.0.0-20240221224432-82ca36839d55/go.mod h1:OmDBASR4679mdNQnz2pUhc2G8CO2JrUAVFDRBDP/hJE=
|
github.com/power-devops/perfstat v0.0.0-20240221224432-82ca36839d55/go.mod h1:OmDBASR4679mdNQnz2pUhc2G8CO2JrUAVFDRBDP/hJE=
|
||||||
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
|
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
|
||||||
@@ -277,8 +277,8 @@ github.com/pterm/pterm v0.12.36/go.mod h1:NjiL09hFhT/vWjQHSj1athJpx6H8cjpHXNAK5b
|
|||||||
github.com/pterm/pterm v0.12.40/go.mod h1:ffwPLwlbXxP+rxT0GsgDTzS3y3rmpAO1NMjUkGTYf8s=
|
github.com/pterm/pterm v0.12.40/go.mod h1:ffwPLwlbXxP+rxT0GsgDTzS3y3rmpAO1NMjUkGTYf8s=
|
||||||
github.com/pterm/pterm v0.12.83 h1:ie+YmGmA727VuhxBlyGr74Ks+7McV6kT99IB8EU80aA=
|
github.com/pterm/pterm v0.12.83 h1:ie+YmGmA727VuhxBlyGr74Ks+7McV6kT99IB8EU80aA=
|
||||||
github.com/pterm/pterm v0.12.83/go.mod h1:xlgc6bFWyJIMtmLJvGim+L7jhSReilOlOnodeIYe4Tk=
|
github.com/pterm/pterm v0.12.83/go.mod h1:xlgc6bFWyJIMtmLJvGim+L7jhSReilOlOnodeIYe4Tk=
|
||||||
github.com/puzpuzpuz/xsync/v4 v4.4.0 h1:vlSN6/CkEY0pY8KaB0yqo/pCLZvp9nhdbBdjipT4gWo=
|
github.com/puzpuzpuz/xsync/v4 v4.5.0 h1:vOSWu6b57/emh+L/Cw0BeQfvxa/cogFywXHeGUxQxAg=
|
||||||
github.com/puzpuzpuz/xsync/v4 v4.4.0/go.mod h1:VJDmTCJMBt8igNxnkQd86r+8KUeN1quSfNKu5bLYFQo=
|
github.com/puzpuzpuz/xsync/v4 v4.5.0/go.mod h1:VJDmTCJMBt8igNxnkQd86r+8KUeN1quSfNKu5bLYFQo=
|
||||||
github.com/quic-go/qpack v0.6.0 h1:g7W+BMYynC1LbYLSqRt8PBg5Tgwxn214ZZR34VIOjz8=
|
github.com/quic-go/qpack v0.6.0 h1:g7W+BMYynC1LbYLSqRt8PBg5Tgwxn214ZZR34VIOjz8=
|
||||||
github.com/quic-go/qpack v0.6.0/go.mod h1:lUpLKChi8njB4ty2bFLX2x4gzDqXwUpaO1DP9qMDZII=
|
github.com/quic-go/qpack v0.6.0/go.mod h1:lUpLKChi8njB4ty2bFLX2x4gzDqXwUpaO1DP9qMDZII=
|
||||||
github.com/quic-go/quic-go v0.59.0 h1:OLJkp1Mlm/aS7dpKgTc6cnpynnD2Xg7C1pwL6vy/SAw=
|
github.com/quic-go/quic-go v0.59.0 h1:OLJkp1Mlm/aS7dpKgTc6cnpynnD2Xg7C1pwL6vy/SAw=
|
||||||
@@ -327,8 +327,8 @@ github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/
|
|||||||
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
|
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
|
||||||
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
|
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
|
||||||
github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
|
github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
|
||||||
github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U=
|
github.com/stretchr/testify v1.12.0 h1:K6Mr6jO9JICuend/5xzTM03ydSV3vdNRYAdPSukj8uI=
|
||||||
github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U=
|
github.com/stretchr/testify v1.12.0/go.mod h1:bOYBZb5qJ00vPzWfIqBUZPaxK8jWiXc6d3ErP4Ca9Gw=
|
||||||
github.com/tklauser/go-sysconf v0.3.16 h1:frioLaCQSsF5Cy1jgRBrzr6t502KIIwQ0MArYICU0nA=
|
github.com/tklauser/go-sysconf v0.3.16 h1:frioLaCQSsF5Cy1jgRBrzr6t502KIIwQ0MArYICU0nA=
|
||||||
github.com/tklauser/go-sysconf v0.3.16/go.mod h1:/qNL9xxDhc7tx3HSRsLWNnuzbVfh3e7gh/BmM179nYI=
|
github.com/tklauser/go-sysconf v0.3.16/go.mod h1:/qNL9xxDhc7tx3HSRsLWNnuzbVfh3e7gh/BmM179nYI=
|
||||||
github.com/tklauser/numcpus v0.11.0 h1:nSTwhKH5e1dMNsCdVBukSZrURJRoHbSEQjdEbY+9RXw=
|
github.com/tklauser/numcpus v0.11.0 h1:nSTwhKH5e1dMNsCdVBukSZrURJRoHbSEQjdEbY+9RXw=
|
||||||
@@ -357,22 +357,24 @@ go.opentelemetry.io/contrib/instrumentation/github.com/gin-gonic/gin/otelgin v0.
|
|||||||
go.opentelemetry.io/contrib/instrumentation/github.com/gin-gonic/gin/otelgin v0.67.0/go.mod h1:WB2cS9y+AwqqKhoo9gw6/ZxlSjFBUQGZ8BQOaD3FVXM=
|
go.opentelemetry.io/contrib/instrumentation/github.com/gin-gonic/gin/otelgin v0.67.0/go.mod h1:WB2cS9y+AwqqKhoo9gw6/ZxlSjFBUQGZ8BQOaD3FVXM=
|
||||||
go.opentelemetry.io/contrib/propagators/b3 v1.42.0 h1:B2Pew5ufEtgkjLF+tSkXjgYZXQr9m7aCm1wLKB0URbU=
|
go.opentelemetry.io/contrib/propagators/b3 v1.42.0 h1:B2Pew5ufEtgkjLF+tSkXjgYZXQr9m7aCm1wLKB0URbU=
|
||||||
go.opentelemetry.io/contrib/propagators/b3 v1.42.0/go.mod h1:iPgUcSEF5DORW6+yNbdw/YevUy+QqJ508ncjhrRSCjc=
|
go.opentelemetry.io/contrib/propagators/b3 v1.42.0/go.mod h1:iPgUcSEF5DORW6+yNbdw/YevUy+QqJ508ncjhrRSCjc=
|
||||||
go.opentelemetry.io/otel v1.42.0 h1:lSQGzTgVR3+sgJDAU/7/ZMjN9Z+vUip7leaqBKy4sho=
|
go.opentelemetry.io/otel v1.44.0 h1:JjwHmHpA4iZ3wBxluu2fbbE7j4kqlE8jXyAyPXH7HqU=
|
||||||
go.opentelemetry.io/otel v1.42.0/go.mod h1:lJNsdRMxCUIWuMlVJWzecSMuNjE7dOYyWlqOXWkdqCc=
|
go.opentelemetry.io/otel v1.44.0/go.mod h1:BMgjTHL9WPRlRjL2oZCBTL4whCGtXch2H4BhOPIAyYc=
|
||||||
go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.42.0 h1:MdKucPl/HbzckWWEisiNqMPhRrAOQX8r4jTuGr636gk=
|
go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.42.0 h1:MdKucPl/HbzckWWEisiNqMPhRrAOQX8r4jTuGr636gk=
|
||||||
go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.42.0/go.mod h1:RolT8tWtfHcjajEH5wFIZ4Dgh5jpPdFXYV9pTAk/qjc=
|
go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.42.0/go.mod h1:RolT8tWtfHcjajEH5wFIZ4Dgh5jpPdFXYV9pTAk/qjc=
|
||||||
go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.42.0 h1:H7O6RlGOMTizyl3R08Kn5pdM06bnH8oscSj7o11tmLA=
|
go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.42.0 h1:H7O6RlGOMTizyl3R08Kn5pdM06bnH8oscSj7o11tmLA=
|
||||||
go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.42.0/go.mod h1:mBFWu/WOVDkWWsR7Tx7h6EpQB8wsv7P0Yrh0Pb7othc=
|
go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.42.0/go.mod h1:mBFWu/WOVDkWWsR7Tx7h6EpQB8wsv7P0Yrh0Pb7othc=
|
||||||
go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.42.0 h1:s/1iRkCKDfhlh1JF26knRneorus8aOwVIDhvYx9WoDw=
|
go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.42.0 h1:s/1iRkCKDfhlh1JF26knRneorus8aOwVIDhvYx9WoDw=
|
||||||
go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.42.0/go.mod h1:UI3wi0FXg1Pofb8ZBiBLhtMzgoTm1TYkMvn71fAqDzs=
|
go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.42.0/go.mod h1:UI3wi0FXg1Pofb8ZBiBLhtMzgoTm1TYkMvn71fAqDzs=
|
||||||
go.opentelemetry.io/otel/metric v1.42.0 h1:2jXG+3oZLNXEPfNmnpxKDeZsFI5o4J+nz6xUlaFdF/4=
|
go.opentelemetry.io/otel/metric v1.44.0 h1:1w0gILTcHdr3YI+ixLyjemwrVnsMURbTZFrSYCdDdmc=
|
||||||
go.opentelemetry.io/otel/metric v1.42.0/go.mod h1:RlUN/7vTU7Ao/diDkEpQpnz3/92J9ko05BIwxYa2SSI=
|
go.opentelemetry.io/otel/metric v1.44.0/go.mod h1:8O7hanEPBNgEMmybD3s2VBKcgWOCsA6tzHBPODAiquo=
|
||||||
go.opentelemetry.io/otel/sdk v1.42.0 h1:LyC8+jqk6UJwdrI/8VydAq/hvkFKNHZVIWuslJXYsDo=
|
go.opentelemetry.io/otel/metric/x v0.66.0 h1:YkCrx1zLOChi9ZcZ6euupOcsgzbVlec7D/xoEU1+cTA=
|
||||||
go.opentelemetry.io/otel/sdk v1.42.0/go.mod h1:rGHCAxd9DAph0joO4W6OPwxjNTYWghRWmkHuGbayMts=
|
go.opentelemetry.io/otel/metric/x v0.66.0/go.mod h1:d1+BDj9t96do0/1LoU1ayfCv79ZgNE41qbhBvnMOBZk=
|
||||||
go.opentelemetry.io/otel/sdk/metric v1.42.0 h1:D/1QR46Clz6ajyZ3G8SgNlTJKBdGp84q9RKCAZ3YGuA=
|
go.opentelemetry.io/otel/sdk v1.44.0 h1:nHYwb9lK+fJPU/dnT6s7W7Z8itMWyqrnVfbheVYrZ58=
|
||||||
go.opentelemetry.io/otel/sdk/metric v1.42.0/go.mod h1:Ua6AAlDKdZ7tdvaQKfSmnFTdHx37+J4ba8MwVCYM5hc=
|
go.opentelemetry.io/otel/sdk v1.44.0/go.mod h1:Osuydd3Se74nqjAKxid74N5eC+jfEqfTegHRnq58oK0=
|
||||||
go.opentelemetry.io/otel/trace v1.42.0 h1:OUCgIPt+mzOnaUTpOQcBiM/PLQ/Op7oq6g4LenLmOYY=
|
go.opentelemetry.io/otel/sdk/metric v1.44.0 h1:3LlKgI+VjbVsjNRFZJZAJ30WjXC5VkNRks6si09iEfI=
|
||||||
go.opentelemetry.io/otel/trace v1.42.0/go.mod h1:f3K9S+IFqnumBkKhRJMeaZeNk9epyhnCmQh/EysQCdc=
|
go.opentelemetry.io/otel/sdk/metric v1.44.0/go.mod h1:5B5pMARnXxKhltooO4xUuCBorl65a4EpnTalObqOigA=
|
||||||
|
go.opentelemetry.io/otel/trace v1.44.0 h1:jxF5CsGYCe74MCRx2X4g7WsY/VBKRqqpNvXlX/6gtIk=
|
||||||
|
go.opentelemetry.io/otel/trace v1.44.0/go.mod h1:oLl1jrMQAVo6v3GAggN+1VH9VIz9iUSvW53sW1Q8PIE=
|
||||||
go.opentelemetry.io/proto/otlp v1.9.0 h1:l706jCMITVouPOqEnii2fIAuO3IVGBRPV5ICjceRb/A=
|
go.opentelemetry.io/proto/otlp v1.9.0 h1:l706jCMITVouPOqEnii2fIAuO3IVGBRPV5ICjceRb/A=
|
||||||
go.opentelemetry.io/proto/otlp v1.9.0/go.mod h1:xE+Cx5E/eEHw+ISFkwPLwCZefwVjY+pqKg1qcK03+/4=
|
go.opentelemetry.io/proto/otlp v1.9.0/go.mod h1:xE+Cx5E/eEHw+ISFkwPLwCZefwVjY+pqKg1qcK03+/4=
|
||||||
go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto=
|
go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto=
|
||||||
@@ -381,8 +383,8 @@ go.uber.org/mock v0.6.0 h1:hyF9dfmbgIX5EfOdasqLsWD6xqpNZlXblLB/Dbnwv3Y=
|
|||||||
go.uber.org/mock v0.6.0/go.mod h1:KiVJ4BqZJaMj4svdfmHM0AUx4NJYO8ZNpPnZn1Z+BBU=
|
go.uber.org/mock v0.6.0/go.mod h1:KiVJ4BqZJaMj4svdfmHM0AUx4NJYO8ZNpPnZn1Z+BBU=
|
||||||
go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0=
|
go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0=
|
||||||
go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y=
|
go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y=
|
||||||
go.uber.org/zap v1.27.1 h1:08RqriUEv8+ArZRYSTXy1LeBScaMpVSTBhCeaZYfMYc=
|
go.uber.org/zap v1.28.0 h1:IZzaP1Fv73/T/pBMLk4VutPl36uNC+OSUh3JLG3FIjo=
|
||||||
go.uber.org/zap v1.27.1/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E=
|
go.uber.org/zap v1.28.0/go.mod h1:rDLpOi171uODNm/mxFcuYWxDsqWSAVkFdX4XojSKg/Q=
|
||||||
go.yaml.in/yaml/v3 v3.0.4 h1:tfq32ie2Jv2UxXFdLJdh3jXuOzWiL1fo0bu/FbuKpbc=
|
go.yaml.in/yaml/v3 v3.0.4 h1:tfq32ie2Jv2UxXFdLJdh3jXuOzWiL1fo0bu/FbuKpbc=
|
||||||
go.yaml.in/yaml/v3 v3.0.4/go.mod h1:DhzuOOF2ATzADvBadXxruRBLzYTpT36CKvDb3+aBEFg=
|
go.yaml.in/yaml/v3 v3.0.4/go.mod h1:DhzuOOF2ATzADvBadXxruRBLzYTpT36CKvDb3+aBEFg=
|
||||||
golang.org/x/arch v0.24.0 h1:qlJ3M9upxvFfwRM51tTg3Yl+8CP9vCC1E7vlFpgv99Y=
|
golang.org/x/arch v0.24.0 h1:qlJ3M9upxvFfwRM51tTg3Yl+8CP9vCC1E7vlFpgv99Y=
|
||||||
@@ -392,8 +394,8 @@ golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACk
|
|||||||
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||||
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||||
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
||||||
golang.org/x/crypto v0.49.0 h1:+Ng2ULVvLHnJ/ZFEq4KdcDd/cfjrrjjNSXNzxg0Y4U4=
|
golang.org/x/crypto v0.51.0 h1:IBPXwPfKxY7cWQZ38ZCIRPI50YLeevDLlLnyC5wRGTI=
|
||||||
golang.org/x/crypto v0.49.0/go.mod h1:ErX4dUh2UM+CFYiXZRTcMpEcN8b/1gxEuv3nODoYtCA=
|
golang.org/x/crypto v0.51.0/go.mod h1:8AdwkbraGNABw2kOX6YFPs3WM22XqI4EXEd8g+x7Oc8=
|
||||||
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||||
golang.org/x/exp v0.0.0-20250218142911-aa4b98e5adaa h1:t2QcU6V556bFjYgu4L6C+6VrCPyJZ+eyRsABUPs1mz4=
|
golang.org/x/exp v0.0.0-20250218142911-aa4b98e5adaa h1:t2QcU6V556bFjYgu4L6C+6VrCPyJZ+eyRsABUPs1mz4=
|
||||||
golang.org/x/exp v0.0.0-20250218142911-aa4b98e5adaa/go.mod h1:BHOTPb3L19zxehTsLoJXVaTktb06DFgmdW6Wb9s8jqk=
|
golang.org/x/exp v0.0.0-20250218142911-aa4b98e5adaa/go.mod h1:BHOTPb3L19zxehTsLoJXVaTktb06DFgmdW6Wb9s8jqk=
|
||||||
@@ -419,8 +421,8 @@ golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwY
|
|||||||
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
||||||
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
|
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
|
||||||
golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
|
golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
|
||||||
golang.org/x/net v0.52.0 h1:He/TN1l0e4mmR3QqHMT2Xab3Aj3L9qjbhRm78/6jrW0=
|
golang.org/x/net v0.55.0 h1:bcvxaJn3e1U6InsFWt1JUq1aSjnRxLzT2rtD2KfkDF8=
|
||||||
golang.org/x/net v0.52.0/go.mod h1:R1MAz7uMZxVMualyPXb+VaqGSa3LIaUqk0eEt3w36Sw=
|
golang.org/x/net v0.55.0/go.mod h1:L5U2KuzuOe1lY7Z+aWVIKK6qEeJXnXV9yzGA+WCHJww=
|
||||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||||
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
@@ -430,8 +432,8 @@ golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJ
|
|||||||
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
golang.org/x/sync v0.20.0 h1:e0PTpb7pjO8GAtTs2dQ6jYa5BWYlMuX047Dco/pItO4=
|
golang.org/x/sync v0.22.0 h1:SZjpbeLmrCk4xhRSZFNZW5gFUeCeFgjekvI/+gfScek=
|
||||||
golang.org/x/sync v0.20.0/go.mod h1:9xrNwdLfx4jkKbNva9FpL6vEN7evnE43NNNJQ2LF3+0=
|
golang.org/x/sync v0.22.0/go.mod h1:9xrNwdLfx4jkKbNva9FpL6vEN7evnE43NNNJQ2LF3+0=
|
||||||
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
golang.org/x/sys v0.0.0-20181122145206-62eef0e2fa9b/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
golang.org/x/sys v0.0.0-20181122145206-62eef0e2fa9b/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
golang.org/x/sys v0.0.0-20181205085412-a5c9d58dba9a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
golang.org/x/sys v0.0.0-20181205085412-a5c9d58dba9a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
@@ -454,22 +456,22 @@ golang.org/x/sys v0.0.0-20221010170243-090e33056c14/go.mod h1:oPkhp1MJrh7nUepCBc
|
|||||||
golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.46.0 h1:noSf2Fq6F8DBgS+LysIkx7rIExoNHJsxOAtPp4rthXw=
|
golang.org/x/sys v0.47.0 h1:o7XGOvZQCADBQQ4Y7VNq2dRWQR7JmOUW8Kxx4ZsNgWs=
|
||||||
golang.org/x/sys v0.46.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw=
|
golang.org/x/sys v0.47.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw=
|
||||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||||
golang.org/x/term v0.0.0-20210220032956-6a3ed077a48d/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
golang.org/x/term v0.0.0-20210220032956-6a3ed077a48d/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||||
golang.org/x/term v0.0.0-20210615171337-6886f2dfbf5b/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
golang.org/x/term v0.0.0-20210615171337-6886f2dfbf5b/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
||||||
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
||||||
golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
|
golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
|
||||||
golang.org/x/term v0.41.0 h1:QCgPso/Q3RTJx2Th4bDLqML4W6iJiaXFq2/ftQF13YU=
|
golang.org/x/term v0.43.0 h1:S4RLU2sB31O/NCl+zFN9Aru9A/Cq2aqKpTZJ6B+DwT4=
|
||||||
golang.org/x/term v0.41.0/go.mod h1:3pfBgksrReYfZ5lvYM0kSO0LIkAl4Yl2bXOkKP7Ec2A=
|
golang.org/x/term v0.43.0/go.mod h1:lrhlHNdQJHO+1qVYiHfFKVuVioJIheAc3fBSMFYEIsk=
|
||||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||||
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||||
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
|
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
|
||||||
golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
|
golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
|
||||||
golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
|
golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
|
||||||
golang.org/x/text v0.35.0 h1:JOVx6vVDFokkpaq1AEptVzLTpDe9KGpj5tR4/X+ybL8=
|
golang.org/x/text v0.37.0 h1:Cqjiwd9eSg8e0QAkyCaQTNHFIIzWtidPahFWR83rTrc=
|
||||||
golang.org/x/text v0.35.0/go.mod h1:khi/HExzZJ2pGnjenulevKNX1W67CUy0AsXcNubPGCA=
|
golang.org/x/text v0.37.0/go.mod h1:a5sjxXGs9hsn/AJVwuElvCAo9v8QYLzvavO5z2PiM38=
|
||||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||||
golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||||
golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
|
golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
|
||||||
@@ -486,8 +488,8 @@ golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8T
|
|||||||
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||||
golang.org/x/xerrors v0.0.0-20240903120638-7835f813f4da h1:noIWHXmPHxILtqtCOPIhSt0ABwskkZKjD3bXGnZGpNY=
|
golang.org/x/xerrors v0.0.0-20240903120638-7835f813f4da h1:noIWHXmPHxILtqtCOPIhSt0ABwskkZKjD3bXGnZGpNY=
|
||||||
golang.org/x/xerrors v0.0.0-20240903120638-7835f813f4da/go.mod h1:NDW/Ps6MPRej6fsCIbMTohpP40sJ/P/vI1MoTEGwX90=
|
golang.org/x/xerrors v0.0.0-20240903120638-7835f813f4da/go.mod h1:NDW/Ps6MPRej6fsCIbMTohpP40sJ/P/vI1MoTEGwX90=
|
||||||
gonum.org/v1/gonum v0.16.0 h1:5+ul4Swaf3ESvrOnidPp4GZbzf0mxVQpDCYUQE7OJfk=
|
gonum.org/v1/gonum v0.17.0 h1:VbpOemQlsSMrYmn7T2OUvQ4dqxQXU+ouZFQsZOx50z4=
|
||||||
gonum.org/v1/gonum v0.16.0/go.mod h1:fef3am4MQ93R2HHpKnLk4/Tbh/s0+wqD5nfa6Pnwy4E=
|
gonum.org/v1/gonum v0.17.0/go.mod h1:El3tOrEuMpv2UdMrbNlKEh9vd86bmQ6vqIcDwxEOc1E=
|
||||||
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
|
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
|
||||||
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
||||||
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
|
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
|
||||||
@@ -500,10 +502,10 @@ google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiq
|
|||||||
google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
|
google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
|
||||||
google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY=
|
google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY=
|
||||||
google.golang.org/grpc v1.28.1/go.mod h1:rpkK4SK4GF4Ach/+MFLZUBavHOvF2JJB5uozKKal+60=
|
google.golang.org/grpc v1.28.1/go.mod h1:rpkK4SK4GF4Ach/+MFLZUBavHOvF2JJB5uozKKal+60=
|
||||||
google.golang.org/grpc v1.79.3 h1:sybAEdRIEtvcD68Gx7dmnwjZKlyfuc61Dyo9pGXXkKE=
|
google.golang.org/grpc v1.83.0 h1:JeNZEKJFbQxArAMl+hiytHauacDNqJUllNfmIMmpqnQ=
|
||||||
google.golang.org/grpc v1.79.3/go.mod h1:KmT0Kjez+0dde/v2j9vzwoAScgEPx/Bw1CYChhHLrHQ=
|
google.golang.org/grpc v1.83.0/go.mod h1:kDyl6SKsiHKt0uylY5gtn5cEjkrIOhQOGDgIc4JGwzQ=
|
||||||
google.golang.org/protobuf v1.36.11 h1:fV6ZwhNocDyBLK0dj+fg8ektcVegBBuEolpbTQyBNVE=
|
google.golang.org/protobuf v1.36.12 h1:pJOKDDOyeXErUroCihFAd5LQuwXBSpVnKGrj5o/fwxc=
|
||||||
google.golang.org/protobuf v1.36.11/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco=
|
google.golang.org/protobuf v1.36.12/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco=
|
||||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||||
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
|
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
|
||||||
|
|||||||
@@ -74,6 +74,12 @@ func (controller *Controller) rpcWatch(ctx *gin.Context) responder.Responder {
|
|||||||
Name: hostProcess.Name,
|
Name: hostProcess.Name,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if tartGuestAgent := target.GetTartGuestAgent(); tartGuestAgent != nil {
|
||||||
|
watchInstruction.PortForwardAction.Target.TartGuestAgent = &v1.PortForwardTargetTartGuestAgent{
|
||||||
|
VMUID: tartGuestAgent.VmUid,
|
||||||
|
}
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
watchInstruction.PortForwardAction.VMUID = typedAction.PortForwardAction.VmUid
|
watchInstruction.PortForwardAction.VMUID = typedAction.PortForwardAction.VmUid
|
||||||
watchInstruction.PortForwardAction.Port = uint16(typedAction.PortForwardAction.Port)
|
watchInstruction.PortForwardAction.Port = uint16(typedAction.PortForwardAction.Port)
|
||||||
|
|||||||
@@ -212,6 +212,7 @@ func (controller *Controller) newSSHExecSession(
|
|||||||
vm.UID,
|
vm.UID,
|
||||||
22,
|
22,
|
||||||
"",
|
"",
|
||||||
|
"",
|
||||||
)
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ import (
|
|||||||
"github.com/cirruslabs/orchard/internal/netconncancel"
|
"github.com/cirruslabs/orchard/internal/netconncancel"
|
||||||
"github.com/cirruslabs/orchard/internal/proxy"
|
"github.com/cirruslabs/orchard/internal/proxy"
|
||||||
"github.com/cirruslabs/orchard/internal/responder"
|
"github.com/cirruslabs/orchard/internal/responder"
|
||||||
|
"github.com/cirruslabs/orchard/pkg/client"
|
||||||
v1 "github.com/cirruslabs/orchard/pkg/resource/v1"
|
v1 "github.com/cirruslabs/orchard/pkg/resource/v1"
|
||||||
"github.com/cirruslabs/orchard/rpc"
|
"github.com/cirruslabs/orchard/rpc"
|
||||||
"github.com/coder/websocket"
|
"github.com/coder/websocket"
|
||||||
@@ -27,15 +28,27 @@ import (
|
|||||||
var errPortForwardRequest = errors.New("failed to request port forwarding")
|
var errPortForwardRequest = errors.New("failed to request port forwarding")
|
||||||
|
|
||||||
func (controller *Controller) portForwardVM(ctx *gin.Context) responder.Responder {
|
func (controller *Controller) portForwardVM(ctx *gin.Context) responder.Responder {
|
||||||
if responder := controller.authorizeAny(ctx, v1.ServiceAccountRoleComputeWrite,
|
|
||||||
v1.ServiceAccountRoleComputeConnect); responder != nil {
|
|
||||||
return responder
|
|
||||||
}
|
|
||||||
|
|
||||||
// Retrieve and parse path and query parameters
|
// Retrieve and parse path and query parameters
|
||||||
name := ctx.Param("name")
|
name := ctx.Param("name")
|
||||||
portRaw := ctx.Query("port")
|
portRaw := ctx.Query("port")
|
||||||
hostProcess := ctx.Query("hostProcess")
|
hostProcess := ctx.Query("hostProcess")
|
||||||
|
target := client.PortForwardTarget(ctx.Query("target"))
|
||||||
|
if target != "" {
|
||||||
|
if err := target.Validate(); err != nil {
|
||||||
|
return responder.JSON(http.StatusBadRequest, NewErrorResponse("%v", err))
|
||||||
|
}
|
||||||
|
if portRaw != "" || hostProcess != "" {
|
||||||
|
return responder.JSON(http.StatusBadRequest,
|
||||||
|
NewErrorResponse("target cannot be combined with port or hostProcess"))
|
||||||
|
}
|
||||||
|
if responder := controller.authorizeAny(ctx, v1.ServiceAccountRoleComputeWrite,
|
||||||
|
v1.ServiceAccountRoleComputeConnectTartGuestAgent); responder != nil {
|
||||||
|
return responder
|
||||||
|
}
|
||||||
|
} else if responder := controller.authorizeAny(ctx, v1.ServiceAccountRoleComputeWrite,
|
||||||
|
v1.ServiceAccountRoleComputeConnect); responder != nil {
|
||||||
|
return responder
|
||||||
|
}
|
||||||
|
|
||||||
// Host process connections require an additional role
|
// Host process connections require an additional role
|
||||||
var port uint64
|
var port uint64
|
||||||
@@ -51,7 +64,7 @@ func (controller *Controller) portForwardVM(ctx *gin.Context) responder.Responde
|
|||||||
if portRaw != "" {
|
if portRaw != "" {
|
||||||
return responder.Code(http.StatusBadRequest)
|
return responder.Code(http.StatusBadRequest)
|
||||||
}
|
}
|
||||||
} else {
|
} else if target == "" {
|
||||||
// VM port forwarding requires a valid non-zero TCP port
|
// VM port forwarding requires a valid non-zero TCP port
|
||||||
port, err = strconv.ParseUint(portRaw, 10, 16)
|
port, err = strconv.ParseUint(portRaw, 10, 16)
|
||||||
if err != nil || port < 1 || port > 65535 {
|
if err != nil || port < 1 || port > 65535 {
|
||||||
@@ -83,7 +96,7 @@ func (controller *Controller) portForwardVM(ctx *gin.Context) responder.Responde
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Commence port forwarding
|
// Commence port forwarding
|
||||||
return controller.portForward(ctx, waitContext, vm.Worker, vm.UID, uint32(port), hostProcess)
|
return controller.portForward(ctx, waitContext, vm.Worker, vm.UID, uint32(port), hostProcess, target)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (controller *Controller) portForward(
|
func (controller *Controller) portForward(
|
||||||
@@ -93,6 +106,7 @@ func (controller *Controller) portForward(
|
|||||||
vmUID string,
|
vmUID string,
|
||||||
port uint32,
|
port uint32,
|
||||||
hostProcess string,
|
hostProcess string,
|
||||||
|
target client.PortForwardTarget,
|
||||||
) responder.Responder {
|
) responder.Responder {
|
||||||
// Request and wait for a connection with a worker
|
// Request and wait for a connection with a worker
|
||||||
rendezvousConn, err := retry.NewWithData[net.Conn](
|
rendezvousConn, err := retry.NewWithData[net.Conn](
|
||||||
@@ -102,7 +116,7 @@ func (controller *Controller) portForward(
|
|||||||
retry.Attempts(0),
|
retry.Attempts(0),
|
||||||
retry.LastErrorOnly(true),
|
retry.LastErrorOnly(true),
|
||||||
).Do(func() (net.Conn, error) {
|
).Do(func() (net.Conn, error) {
|
||||||
return controller.portForwardConnection(ctx, notifyContext, workerName, vmUID, port, hostProcess)
|
return controller.portForwardConnection(ctx, notifyContext, workerName, vmUID, port, hostProcess, target)
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if errors.Is(err, errPortForwardRequest) {
|
if errors.Is(err, errPortForwardRequest) {
|
||||||
@@ -226,6 +240,7 @@ func (controller *Controller) portForwardConnection(
|
|||||||
vmUID string,
|
vmUID string,
|
||||||
port uint32,
|
port uint32,
|
||||||
hostProcess string,
|
hostProcess string,
|
||||||
|
target client.PortForwardTarget,
|
||||||
) (net.Conn, error) {
|
) (net.Conn, error) {
|
||||||
// Create a rendezvous connection point
|
// Create a rendezvous connection point
|
||||||
rendezvousCtx, rendezvousCtxCancel := context.WithCancel(ctx)
|
rendezvousCtx, rendezvousCtxCancel := context.WithCancel(ctx)
|
||||||
@@ -251,6 +266,12 @@ func (controller *Controller) portForwardConnection(
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
} else if target == client.PortForwardTargetTartGuestAgent {
|
||||||
|
portForwardAction.Target = &rpc.WatchInstruction_PortForward_Target{
|
||||||
|
Value: &rpc.WatchInstruction_PortForward_Target_TartGuestAgent_{
|
||||||
|
TartGuestAgent: &rpc.WatchInstruction_PortForward_Target_TartGuestAgent{VmUid: vmUID},
|
||||||
|
},
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
portForwardAction.VmUid = vmUID
|
portForwardAction.VmUid = vmUID
|
||||||
portForwardAction.Port = port
|
portForwardAction.Port = port
|
||||||
|
|||||||
@@ -50,5 +50,5 @@ func (controller *Controller) portForwardWorker(ctx *gin.Context) responder.Resp
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Commence port-forwarding
|
// Commence port-forwarding
|
||||||
return controller.portForward(ctx, waitContext, worker.Name, "", uint32(port), "")
|
return controller.portForward(ctx, waitContext, worker.Name, "", uint32(port), "", "")
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,53 @@
|
|||||||
|
//go:build darwin
|
||||||
|
|
||||||
|
package tests_test
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"net"
|
||||||
|
"testing"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/cirruslabs/orchard/internal/tests/devcontroller"
|
||||||
|
"github.com/cirruslabs/orchard/internal/tests/platformdependent"
|
||||||
|
"github.com/cirruslabs/orchard/pkg/client"
|
||||||
|
guestagent "github.com/cirruslabs/tart-guest-agent/pkg/v1"
|
||||||
|
"github.com/google/uuid"
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
|
"github.com/stretchr/testify/require"
|
||||||
|
"google.golang.org/grpc"
|
||||||
|
"google.golang.org/grpc/credentials/insecure"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestTartGuestAgentPortForward(t *testing.T) {
|
||||||
|
devClient, _, _ := devcontroller.StartIntegrationTestEnvironment(t)
|
||||||
|
|
||||||
|
// Create a VM with Tart Guest Agent pre-installed
|
||||||
|
vmName := "test-guest-agent-" + uuid.NewString()
|
||||||
|
require.NoError(t, devClient.VMs().Create(t.Context(), platformdependent.VM(vmName)))
|
||||||
|
|
||||||
|
// Configure the Tart Guest Agent client to connect through Orchard's port-forwarding API
|
||||||
|
agentConn, err := grpc.NewClient("passthrough:///tart-guest-agent",
|
||||||
|
grpc.WithTransportCredentials(insecure.NewCredentials()),
|
||||||
|
grpc.WithContextDialer(func(_ context.Context, _ string) (net.Conn, error) {
|
||||||
|
// Keep the stream alive beyond gRPC's temporary dial context
|
||||||
|
return devClient.VMs().PortForwardTarget(t.Context(), vmName,
|
||||||
|
client.PortForwardTargetTartGuestAgent, 120)
|
||||||
|
}),
|
||||||
|
)
|
||||||
|
require.NoError(t, err)
|
||||||
|
defer agentConn.Close()
|
||||||
|
|
||||||
|
// Perform IP resolution through the forwarded connection
|
||||||
|
agentClient := guestagent.NewAgentClient(agentConn)
|
||||||
|
|
||||||
|
require.EventuallyWithT(t, func(collect *assert.CollectT) {
|
||||||
|
rpcContext, cancel := context.WithTimeout(t.Context(), 5*time.Second)
|
||||||
|
defer cancel()
|
||||||
|
|
||||||
|
response, err := agentClient.ResolveIP(rpcContext, &guestagent.ResolveIPRequest{},
|
||||||
|
grpc.WaitForReady(true))
|
||||||
|
require.NoError(collect, err)
|
||||||
|
require.NotNil(collect, net.ParseIP(response.GetIp()))
|
||||||
|
}, 2*time.Minute, time.Second)
|
||||||
|
}
|
||||||
@@ -14,6 +14,7 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/avast/retry-go/v4"
|
"github.com/avast/retry-go/v4"
|
||||||
|
"github.com/cirruslabs/orchard/internal/worker/socketalias"
|
||||||
v1 "github.com/cirruslabs/orchard/pkg/resource/v1"
|
v1 "github.com/cirruslabs/orchard/pkg/resource/v1"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -45,7 +46,7 @@ func NewProcess(
|
|||||||
|
|
||||||
// Route the Tart control socket through the runtime directory as well
|
// Route the Tart control socket through the runtime directory as well
|
||||||
// to work around macOS's 104-byte Unix-domain socket limit
|
// to work around macOS's 104-byte Unix-domain socket limit
|
||||||
controlSocket, err = shortenControlSocketPath(runtimeDir, controlSocket)
|
controlSocket, err = socketalias.Create(runtimeDir, controlSocket)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, errors.Join(err, os.RemoveAll(runtimeDir))
|
return nil, errors.Join(err, os.RemoveAll(runtimeDir))
|
||||||
}
|
}
|
||||||
@@ -108,24 +109,6 @@ func NewProcess(
|
|||||||
return process, nil
|
return process, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func shortenControlSocketPath(runtimeDir string, controlSocketPath string) (string, error) {
|
|
||||||
// Make the symlink target absolute because a relative TART_HOME would
|
|
||||||
// otherwise be resolved from runtimeDir, breaking the symlink
|
|
||||||
absoluteControlSocketPath, err := filepath.Abs(controlSocketPath)
|
|
||||||
if err != nil {
|
|
||||||
return "", err
|
|
||||||
}
|
|
||||||
|
|
||||||
// Place the VM's control socket alias in the runtime directory
|
|
||||||
aliasControlSocketPath := filepath.Join(runtimeDir, "vm.sock")
|
|
||||||
|
|
||||||
if err := os.Symlink(absoluteControlSocketPath, aliasControlSocketPath); err != nil {
|
|
||||||
return "", err
|
|
||||||
}
|
|
||||||
|
|
||||||
return aliasControlSocketPath, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (process *Process) Dial(ctx context.Context) (net.Conn, error) {
|
func (process *Process) Dial(ctx context.Context) (net.Conn, error) {
|
||||||
var dialer net.Dialer
|
var dialer net.Dialer
|
||||||
|
|
||||||
|
|||||||
@@ -1,58 +0,0 @@
|
|||||||
//nolint:noctx,testpackage,usetesting // Preserve the socket-path tests and their required short /var/tmp paths.
|
|
||||||
package hostprocess
|
|
||||||
|
|
||||||
import (
|
|
||||||
"net"
|
|
||||||
"os"
|
|
||||||
"path/filepath"
|
|
||||||
"strings"
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"github.com/stretchr/testify/require"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestShortenControlSocketPath(t *testing.T) {
|
|
||||||
// Create a control socket path that exceeds macOS's 104-byte limit
|
|
||||||
const controlSocketName = "control.sock"
|
|
||||||
|
|
||||||
vmDir := filepath.Join(t.TempDir(), strings.Repeat("v", 104))
|
|
||||||
require.NoError(t, os.MkdirAll(vmDir, 0o700))
|
|
||||||
|
|
||||||
controlSocketPath := filepath.Join(vmDir, controlSocketName)
|
|
||||||
require.Greater(t, len(controlSocketPath), 104)
|
|
||||||
|
|
||||||
// Create Orchard's short per-process runtime directory
|
|
||||||
runtimeDir, err := os.MkdirTemp("/var/tmp", "orchard-hp-test-")
|
|
||||||
require.NoError(t, err)
|
|
||||||
t.Cleanup(func() {
|
|
||||||
require.NoError(t, os.RemoveAll(runtimeDir))
|
|
||||||
})
|
|
||||||
|
|
||||||
// Shorten the control socket path and verify the resulting alias
|
|
||||||
shortControlSocketPath, err := shortenControlSocketPath(runtimeDir, controlSocketPath)
|
|
||||||
require.NoError(t, err)
|
|
||||||
require.Equal(t, filepath.Join(runtimeDir, "vm.sock"), shortControlSocketPath)
|
|
||||||
require.Less(t, len(shortControlSocketPath), 104)
|
|
||||||
|
|
||||||
// Model Tart binding the socket relative to the long VM directory
|
|
||||||
t.Chdir(vmDir)
|
|
||||||
|
|
||||||
listener, err := net.Listen("unix", controlSocketName)
|
|
||||||
require.NoError(t, err)
|
|
||||||
t.Cleanup(func() {
|
|
||||||
require.NoError(t, listener.Close())
|
|
||||||
})
|
|
||||||
|
|
||||||
// Model the host process running from Orchard's runtime directory
|
|
||||||
t.Chdir(runtimeDir)
|
|
||||||
|
|
||||||
// Verify connecting through the long absolute path fails
|
|
||||||
connection, err := net.Dial("unix", controlSocketPath)
|
|
||||||
require.Error(t, err)
|
|
||||||
require.Nil(t, connection)
|
|
||||||
|
|
||||||
// Connect to Tart's control socket through Orchard's short alias
|
|
||||||
connection, err = net.Dial("unix", shortControlSocketPath)
|
|
||||||
require.NoError(t, err)
|
|
||||||
require.NoError(t, connection.Close())
|
|
||||||
}
|
|
||||||
+14
-8
@@ -67,7 +67,7 @@ func (worker *Worker) watchRPC(ctx context.Context, operationCtx context.Context
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//nolint:nestif,protogetter // Preserve the original host-process forwarding implementation.
|
//nolint:nestif,protogetter // Preserve the original forwarding implementation.
|
||||||
func (worker *Worker) handlePortForward(
|
func (worker *Worker) handlePortForward(
|
||||||
ctx context.Context,
|
ctx context.Context,
|
||||||
client rpc.ControllerClient,
|
client rpc.ControllerClient,
|
||||||
@@ -98,17 +98,18 @@ func (worker *Worker) handlePortForward(
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// Retrieve the typed host process target, it's the only possible target right now
|
switch {
|
||||||
hostProcess := target.GetHostProcess()
|
case target.GetTartGuestAgent() != nil:
|
||||||
if hostProcess == nil || hostProcess.VmUid == "" || hostProcess.Name == "" {
|
targetConn, err = worker.dialTartGuestAgent(subCtx, target.GetTartGuestAgent().VmUid)
|
||||||
|
case target.GetHostProcess() != nil:
|
||||||
|
targetConn, err = worker.dialHostProcess(subCtx, target.GetHostProcess().VmUid,
|
||||||
|
target.GetHostProcess().Name)
|
||||||
|
default:
|
||||||
worker.logger.Warn("port forwarding failed: invalid or unsupported target")
|
worker.logger.Warn("port forwarding failed: invalid or unsupported target")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// Dial host process
|
|
||||||
targetConn, err = worker.dialHostProcess(ctx, hostProcess.VmUid, hostProcess.Name)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
worker.logger.Warnf("port forwarding failed: failed to connect to host process: %v", err)
|
worker.logger.Warnf("port forwarding failed: %v", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@@ -155,6 +156,11 @@ func (worker *Worker) handlePortForward(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Close the target on return or cancellation to unblock pending reads and writes
|
||||||
|
defer targetConn.Close()
|
||||||
|
stopClosing := context.AfterFunc(subCtx, func() { _ = targetConn.Close() })
|
||||||
|
defer stopClosing()
|
||||||
|
|
||||||
// Proxy bytes
|
// Proxy bytes
|
||||||
grpcConn := &grpc_net_conn.Conn{
|
grpcConn := &grpc_net_conn.Conn{
|
||||||
Stream: stream,
|
Stream: stream,
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ import (
|
|||||||
"net"
|
"net"
|
||||||
|
|
||||||
"github.com/cirruslabs/orchard/internal/proxy"
|
"github.com/cirruslabs/orchard/internal/proxy"
|
||||||
|
"github.com/cirruslabs/orchard/internal/worker/socketalias"
|
||||||
"github.com/cirruslabs/orchard/internal/worker/vmmanager"
|
"github.com/cirruslabs/orchard/internal/worker/vmmanager"
|
||||||
v1 "github.com/cirruslabs/orchard/pkg/resource/v1"
|
v1 "github.com/cirruslabs/orchard/pkg/resource/v1"
|
||||||
"github.com/samber/lo"
|
"github.com/samber/lo"
|
||||||
@@ -48,6 +49,11 @@ func (worker *Worker) handlePortForwardV2(ctx context.Context, portForward *v1.P
|
|||||||
errorMessage = fmt.Sprintf("port-forwarding failed: %v", err)
|
errorMessage = fmt.Sprintf("port-forwarding failed: %v", err)
|
||||||
|
|
||||||
worker.logger.Warn(errorMessage)
|
worker.logger.Warn(errorMessage)
|
||||||
|
} else {
|
||||||
|
// Close the target on return or cancellation to unblock pending reads and writes
|
||||||
|
defer vmConn.Close()
|
||||||
|
stopClosing := context.AfterFunc(ctx, func() { _ = vmConn.Close() })
|
||||||
|
defer stopClosing()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Respond
|
// Respond
|
||||||
@@ -82,13 +88,14 @@ func (worker *Worker) handlePortForwardV2Inner(
|
|||||||
return nil, fmt.Errorf("target and legacy fields are mutually exclusive")
|
return nil, fmt.Errorf("target and legacy fields are mutually exclusive")
|
||||||
}
|
}
|
||||||
|
|
||||||
// Retrieve the typed host process target, it's the only possible target right now
|
switch {
|
||||||
if target.HostProcess == nil || target.HostProcess.VMUID == "" || target.HostProcess.Name == "" {
|
case target.TartGuestAgent != nil:
|
||||||
|
return worker.dialTartGuestAgent(ctx, target.TartGuestAgent.VMUID)
|
||||||
|
case target.HostProcess != nil:
|
||||||
|
return worker.dialHostProcess(ctx, target.HostProcess.VMUID, target.HostProcess.Name)
|
||||||
|
default:
|
||||||
return nil, fmt.Errorf("invalid or unsupported target")
|
return nil, fmt.Errorf("invalid or unsupported target")
|
||||||
}
|
}
|
||||||
|
|
||||||
// Dial host process
|
|
||||||
return worker.dialHostProcess(ctx, target.HostProcess.VMUID, target.HostProcess.Name)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var host string
|
var host string
|
||||||
@@ -133,6 +140,40 @@ func (worker *Worker) handlePortForwardV2Inner(
|
|||||||
return vmConn, nil
|
return vmConn, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//nolint:err113,perfsprint // runtime and VM state failures are reported to the port-forward caller
|
||||||
|
func (worker *Worker) dialTartGuestAgent(ctx context.Context, vmUID string) (net.Conn, error) {
|
||||||
|
// Validate the VM UID and runtime
|
||||||
|
if vmUID == "" {
|
||||||
|
return nil, fmt.Errorf("invalid Tart Guest Agent target: VM UID is required")
|
||||||
|
}
|
||||||
|
|
||||||
|
if worker.runtime.ID() != v1.RuntimeTart || worker.runtime.Synthetic() {
|
||||||
|
return nil, fmt.Errorf("forwarding to Tart Guest Agent requires the Tart runtime")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Find the running VM
|
||||||
|
vm, err := worker.findVMByUID(vmUID)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if !vm.Running() {
|
||||||
|
return nil, fmt.Errorf("VM with UID %q is not running", vmUID)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Connect to Tart Guest Agent through the VM's control socket
|
||||||
|
path, err := vm.OnDiskName().ControlSocketPath()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
conn, err := socketalias.DialContext(ctx, path)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("failed to connect to Tart Guest Agent: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return conn, nil
|
||||||
|
}
|
||||||
|
|
||||||
func (worker *Worker) handleGetIPV2(ctx context.Context, resolveIP *v1.ResolveIPAction) {
|
func (worker *Worker) handleGetIPV2(ctx context.Context, resolveIP *v1.ResolveIPAction) {
|
||||||
var errorMessage string
|
var errorMessage string
|
||||||
|
|
||||||
@@ -192,7 +233,12 @@ func (worker *Worker) findVMByUID(uid string) (vmmanager.VM, error) {
|
|||||||
return vm, nil
|
return vm, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//nolint:err113,perfsprint // Use descriptive errors for host process validation
|
||||||
func (worker *Worker) dialHostProcess(ctx context.Context, vmUID string, name string) (net.Conn, error) {
|
func (worker *Worker) dialHostProcess(ctx context.Context, vmUID string, name string) (net.Conn, error) {
|
||||||
|
if vmUID == "" || name == "" {
|
||||||
|
return nil, fmt.Errorf("invalid host process target: VM UID and name are required")
|
||||||
|
}
|
||||||
|
|
||||||
vm, err := worker.findVMByUID(vmUID)
|
vm, err := worker.findVMByUID(vmUID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
|||||||
@@ -0,0 +1,67 @@
|
|||||||
|
package socketalias
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"errors"
|
||||||
|
"net"
|
||||||
|
"os"
|
||||||
|
"path/filepath"
|
||||||
|
)
|
||||||
|
|
||||||
|
// baseDirectory is the parent directory for transient socket aliases.
|
||||||
|
//
|
||||||
|
// To keep the Unix socket path short enough and fit the platform limit,
|
||||||
|
// we're specifically requesting "/var/tmp" instead of "/var/folders/.../T/".
|
||||||
|
const baseDirectory = "/var/tmp"
|
||||||
|
|
||||||
|
// Create creates a short Unix socket alias in runtimeDir that points to socketPath.
|
||||||
|
//
|
||||||
|
// The alias remains valid until runtimeDir is removed.
|
||||||
|
func Create(runtimeDir string, socketPath string) (string, error) {
|
||||||
|
// Make the symlink target absolute because a relative TART_HOME would
|
||||||
|
// otherwise be resolved from runtimeDir, breaking the symlink
|
||||||
|
absoluteSocketPath, err := filepath.Abs(socketPath)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Place the VM's control socket alias in the runtime directory
|
||||||
|
aliasSocketPath := filepath.Join(runtimeDir, "vm.sock")
|
||||||
|
if err := os.Symlink(absoluteSocketPath, aliasSocketPath); err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
|
||||||
|
return aliasSocketPath, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// DialContext connects to socketPath through a short transient alias.
|
||||||
|
func DialContext(ctx context.Context, socketPath string) (net.Conn, error) {
|
||||||
|
// Create a directory where the transient Unix socket alias will live
|
||||||
|
runtimeDir, err := os.MkdirTemp(baseDirectory, "orchard-socket-")
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Route the socket through the short runtime directory
|
||||||
|
aliasSocketPath, err := Create(runtimeDir, socketPath)
|
||||||
|
if err != nil {
|
||||||
|
return nil, errors.Join(err, os.RemoveAll(runtimeDir))
|
||||||
|
}
|
||||||
|
|
||||||
|
// Connect through the short alias
|
||||||
|
var dialer net.Dialer
|
||||||
|
conn, err := dialer.DialContext(ctx, "unix", aliasSocketPath)
|
||||||
|
|
||||||
|
// Remove the transient alias after the connection attempt
|
||||||
|
cleanupErr := os.RemoveAll(runtimeDir)
|
||||||
|
if err != nil {
|
||||||
|
return nil, errors.Join(err, cleanupErr)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Avoid returning a live connection when its alias cannot be removed
|
||||||
|
if cleanupErr != nil {
|
||||||
|
return nil, errors.Join(cleanupErr, conn.Close())
|
||||||
|
}
|
||||||
|
|
||||||
|
return conn, nil
|
||||||
|
}
|
||||||
@@ -0,0 +1,49 @@
|
|||||||
|
package socketalias_test
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net"
|
||||||
|
"os"
|
||||||
|
"path/filepath"
|
||||||
|
"strings"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/cirruslabs/orchard/internal/worker/socketalias"
|
||||||
|
"github.com/stretchr/testify/require"
|
||||||
|
"golang.org/x/sys/unix"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestDialContextWithLongPath(t *testing.T) {
|
||||||
|
const (
|
||||||
|
socketName = "control.sock"
|
||||||
|
unixSocketPathLimit = len(unix.RawSockaddrUnix{}.Path)
|
||||||
|
doubleUnixSocketPathLimit = 2 * unixSocketPathLimit
|
||||||
|
)
|
||||||
|
|
||||||
|
// Create the socket at an overlong absolute path without passing that path to bind
|
||||||
|
originalWorkingDirectory, err := os.Getwd()
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
socketDir := filepath.Join(t.TempDir(), strings.Repeat("x", doubleUnixSocketPathLimit))
|
||||||
|
require.NoError(t, os.MkdirAll(socketDir, 0o700))
|
||||||
|
socketPath := filepath.Join(socketDir, socketName)
|
||||||
|
|
||||||
|
t.Chdir(socketDir)
|
||||||
|
|
||||||
|
listener, err := (&net.ListenConfig{}).Listen(t.Context(), "unix", socketName)
|
||||||
|
require.NoError(t, err)
|
||||||
|
t.Cleanup(func() {
|
||||||
|
require.NoError(t, listener.Close())
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Chdir(originalWorkingDirectory)
|
||||||
|
|
||||||
|
// Verify that connecting through the long absolute path fails
|
||||||
|
connection, err := (&net.Dialer{}).DialContext(t.Context(), "unix", socketPath)
|
||||||
|
require.Error(t, err)
|
||||||
|
require.Nil(t, connection)
|
||||||
|
|
||||||
|
// Verify that connecting through a short transient alias succeeds
|
||||||
|
connection, err = socketalias.DialContext(t.Context(), socketPath)
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.NoError(t, connection.Close())
|
||||||
|
}
|
||||||
@@ -13,6 +13,21 @@ import (
|
|||||||
"github.com/coder/websocket"
|
"github.com/coder/websocket"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
type PortForwardTarget string
|
||||||
|
|
||||||
|
const (
|
||||||
|
PortForwardTargetTartGuestAgent PortForwardTarget = "tart-guest-agent"
|
||||||
|
)
|
||||||
|
|
||||||
|
func (target PortForwardTarget) Validate() error {
|
||||||
|
switch target {
|
||||||
|
case PortForwardTargetTartGuestAgent:
|
||||||
|
return nil
|
||||||
|
default:
|
||||||
|
return fmt.Errorf("unsupported port-forward target %q", target)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
type VMsService struct {
|
type VMsService struct {
|
||||||
client *Client
|
client *Client
|
||||||
}
|
}
|
||||||
@@ -182,6 +197,19 @@ func (service *VMsService) PortForwardHostProcess(
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (service *VMsService) PortForwardTarget(
|
||||||
|
ctx context.Context,
|
||||||
|
name string,
|
||||||
|
target PortForwardTarget,
|
||||||
|
waitSeconds uint16,
|
||||||
|
) (net.Conn, error) {
|
||||||
|
return service.client.wsRequest(ctx, fmt.Sprintf("vms/%s/port-forward", url.PathEscape(name)),
|
||||||
|
map[string]string{
|
||||||
|
"target": string(target),
|
||||||
|
"wait": strconv.FormatUint(uint64(waitSeconds), 10),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
func (service *VMsService) Exec(
|
func (service *VMsService) Exec(
|
||||||
ctx context.Context,
|
ctx context.Context,
|
||||||
name string,
|
name string,
|
||||||
|
|||||||
@@ -10,13 +10,14 @@ var ErrUnsupportedServiceAccountRole = errors.New("unsupported service account r
|
|||||||
type ServiceAccountRole string
|
type ServiceAccountRole string
|
||||||
|
|
||||||
const (
|
const (
|
||||||
ServiceAccountRoleComputeRead ServiceAccountRole = "compute:read"
|
ServiceAccountRoleComputeRead ServiceAccountRole = "compute:read"
|
||||||
ServiceAccountRoleComputeWrite ServiceAccountRole = "compute:write"
|
ServiceAccountRoleComputeWrite ServiceAccountRole = "compute:write"
|
||||||
ServiceAccountRoleComputeConnect ServiceAccountRole = "compute:connect"
|
ServiceAccountRoleComputeConnect ServiceAccountRole = "compute:connect"
|
||||||
ServiceAccountRoleHostProcessWrite ServiceAccountRole = "host-process:write"
|
ServiceAccountRoleComputeConnectTartGuestAgent ServiceAccountRole = "compute:connect:tart-guest-agent"
|
||||||
ServiceAccountRoleHostProcessConnect ServiceAccountRole = "host-process:connect"
|
ServiceAccountRoleHostProcessWrite ServiceAccountRole = "host-process:write"
|
||||||
ServiceAccountRoleAdminRead ServiceAccountRole = "admin:read"
|
ServiceAccountRoleHostProcessConnect ServiceAccountRole = "host-process:connect"
|
||||||
ServiceAccountRoleAdminWrite ServiceAccountRole = "admin:write"
|
ServiceAccountRoleAdminRead ServiceAccountRole = "admin:read"
|
||||||
|
ServiceAccountRoleAdminWrite ServiceAccountRole = "admin:write"
|
||||||
)
|
)
|
||||||
|
|
||||||
func NewServiceAccountRole(name string) (ServiceAccountRole, error) {
|
func NewServiceAccountRole(name string) (ServiceAccountRole, error) {
|
||||||
@@ -27,6 +28,8 @@ func NewServiceAccountRole(name string) (ServiceAccountRole, error) {
|
|||||||
return ServiceAccountRoleComputeWrite, nil
|
return ServiceAccountRoleComputeWrite, nil
|
||||||
case string(ServiceAccountRoleComputeConnect):
|
case string(ServiceAccountRoleComputeConnect):
|
||||||
return ServiceAccountRoleComputeConnect, nil
|
return ServiceAccountRoleComputeConnect, nil
|
||||||
|
case string(ServiceAccountRoleComputeConnectTartGuestAgent):
|
||||||
|
return ServiceAccountRoleComputeConnectTartGuestAgent, nil
|
||||||
case string(ServiceAccountRoleHostProcessWrite):
|
case string(ServiceAccountRoleHostProcessWrite):
|
||||||
return ServiceAccountRoleHostProcessWrite, nil
|
return ServiceAccountRoleHostProcessWrite, nil
|
||||||
case string(ServiceAccountRoleHostProcessConnect):
|
case string(ServiceAccountRoleHostProcessConnect):
|
||||||
@@ -45,6 +48,7 @@ func AllServiceAccountRoles() []ServiceAccountRole {
|
|||||||
ServiceAccountRoleComputeRead,
|
ServiceAccountRoleComputeRead,
|
||||||
ServiceAccountRoleComputeWrite,
|
ServiceAccountRoleComputeWrite,
|
||||||
ServiceAccountRoleComputeConnect,
|
ServiceAccountRoleComputeConnect,
|
||||||
|
ServiceAccountRoleComputeConnectTartGuestAgent,
|
||||||
ServiceAccountRoleHostProcessWrite,
|
ServiceAccountRoleHostProcessWrite,
|
||||||
ServiceAccountRoleHostProcessConnect,
|
ServiceAccountRoleHostProcessConnect,
|
||||||
ServiceAccountRoleAdminRead,
|
ServiceAccountRoleAdminRead,
|
||||||
|
|||||||
@@ -15,7 +15,8 @@ type PortForwardAction struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type PortForwardTarget struct {
|
type PortForwardTarget struct {
|
||||||
HostProcess *PortForwardTargetHostProcess `json:"hostProcess,omitempty"`
|
HostProcess *PortForwardTargetHostProcess `json:"hostProcess,omitempty"`
|
||||||
|
TartGuestAgent *PortForwardTargetTartGuestAgent `json:"tartGuestAgent,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type PortForwardTargetHostProcess struct {
|
type PortForwardTargetHostProcess struct {
|
||||||
@@ -23,6 +24,10 @@ type PortForwardTargetHostProcess struct {
|
|||||||
Name string `json:"name"`
|
Name string `json:"name"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type PortForwardTargetTartGuestAgent struct {
|
||||||
|
VMUID string `json:"vmUID"`
|
||||||
|
}
|
||||||
|
|
||||||
type SyncVMsAction struct {
|
type SyncVMsAction struct {
|
||||||
// nothing for now
|
// nothing for now
|
||||||
}
|
}
|
||||||
|
|||||||
+96
-28
@@ -224,7 +224,7 @@ type WatchInstruction_PortForward struct {
|
|||||||
VmUid string `protobuf:"bytes,2,opt,name=vm_uid,json=vmUid,proto3" json:"vm_uid,omitempty"`
|
VmUid string `protobuf:"bytes,2,opt,name=vm_uid,json=vmUid,proto3" json:"vm_uid,omitempty"`
|
||||||
Port uint32 `protobuf:"varint,3,opt,name=port,proto3" json:"port,omitempty"`
|
Port uint32 `protobuf:"varint,3,opt,name=port,proto3" json:"port,omitempty"`
|
||||||
// Typed alternative to the legacy port-forwarding destination,
|
// Typed alternative to the legacy port-forwarding destination,
|
||||||
// adding support for host processes
|
// adding support for host processes and Tart Guest Agent
|
||||||
Target *WatchInstruction_PortForward_Target `protobuf:"bytes,4,opt,name=target,proto3" json:"target,omitempty"`
|
Target *WatchInstruction_PortForward_Target `protobuf:"bytes,4,opt,name=target,proto3" json:"target,omitempty"`
|
||||||
unknownFields protoimpl.UnknownFields
|
unknownFields protoimpl.UnknownFields
|
||||||
sizeCache protoimpl.SizeCache
|
sizeCache protoimpl.SizeCache
|
||||||
@@ -384,6 +384,7 @@ type WatchInstruction_PortForward_Target struct {
|
|||||||
// Types that are valid to be assigned to Value:
|
// Types that are valid to be assigned to Value:
|
||||||
//
|
//
|
||||||
// *WatchInstruction_PortForward_Target_HostProcess_
|
// *WatchInstruction_PortForward_Target_HostProcess_
|
||||||
|
// *WatchInstruction_PortForward_Target_TartGuestAgent_
|
||||||
Value isWatchInstruction_PortForward_Target_Value `protobuf_oneof:"value"`
|
Value isWatchInstruction_PortForward_Target_Value `protobuf_oneof:"value"`
|
||||||
unknownFields protoimpl.UnknownFields
|
unknownFields protoimpl.UnknownFields
|
||||||
sizeCache protoimpl.SizeCache
|
sizeCache protoimpl.SizeCache
|
||||||
@@ -435,6 +436,15 @@ func (x *WatchInstruction_PortForward_Target) GetHostProcess() *WatchInstruction
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (x *WatchInstruction_PortForward_Target) GetTartGuestAgent() *WatchInstruction_PortForward_Target_TartGuestAgent {
|
||||||
|
if x != nil {
|
||||||
|
if x, ok := x.Value.(*WatchInstruction_PortForward_Target_TartGuestAgent_); ok {
|
||||||
|
return x.TartGuestAgent
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
type isWatchInstruction_PortForward_Target_Value interface {
|
type isWatchInstruction_PortForward_Target_Value interface {
|
||||||
isWatchInstruction_PortForward_Target_Value()
|
isWatchInstruction_PortForward_Target_Value()
|
||||||
}
|
}
|
||||||
@@ -443,9 +453,16 @@ type WatchInstruction_PortForward_Target_HostProcess_ struct {
|
|||||||
HostProcess *WatchInstruction_PortForward_Target_HostProcess `protobuf:"bytes,1,opt,name=host_process,json=hostProcess,proto3,oneof"`
|
HostProcess *WatchInstruction_PortForward_Target_HostProcess `protobuf:"bytes,1,opt,name=host_process,json=hostProcess,proto3,oneof"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type WatchInstruction_PortForward_Target_TartGuestAgent_ struct {
|
||||||
|
TartGuestAgent *WatchInstruction_PortForward_Target_TartGuestAgent `protobuf:"bytes,2,opt,name=tart_guest_agent,json=tartGuestAgent,proto3,oneof"`
|
||||||
|
}
|
||||||
|
|
||||||
func (*WatchInstruction_PortForward_Target_HostProcess_) isWatchInstruction_PortForward_Target_Value() {
|
func (*WatchInstruction_PortForward_Target_HostProcess_) isWatchInstruction_PortForward_Target_Value() {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (*WatchInstruction_PortForward_Target_TartGuestAgent_) isWatchInstruction_PortForward_Target_Value() {
|
||||||
|
}
|
||||||
|
|
||||||
// Forward the byte stream to a host process, identified by
|
// Forward the byte stream to a host process, identified by
|
||||||
// a VM UID and a host process name
|
// a VM UID and a host process name
|
||||||
type WatchInstruction_PortForward_Target_HostProcess struct {
|
type WatchInstruction_PortForward_Target_HostProcess struct {
|
||||||
@@ -500,25 +517,73 @@ func (x *WatchInstruction_PortForward_Target_HostProcess) GetName() string {
|
|||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Forward the byte stream to the Tart Guest Agent of a VM
|
||||||
|
type WatchInstruction_PortForward_Target_TartGuestAgent struct {
|
||||||
|
state protoimpl.MessageState `protogen:"open.v1"`
|
||||||
|
VmUid string `protobuf:"bytes,1,opt,name=vm_uid,json=vmUid,proto3" json:"vm_uid,omitempty"`
|
||||||
|
unknownFields protoimpl.UnknownFields
|
||||||
|
sizeCache protoimpl.SizeCache
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *WatchInstruction_PortForward_Target_TartGuestAgent) Reset() {
|
||||||
|
*x = WatchInstruction_PortForward_Target_TartGuestAgent{}
|
||||||
|
mi := &file_orchard_proto_msgTypes[8]
|
||||||
|
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||||
|
ms.StoreMessageInfo(mi)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *WatchInstruction_PortForward_Target_TartGuestAgent) String() string {
|
||||||
|
return protoimpl.X.MessageStringOf(x)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (*WatchInstruction_PortForward_Target_TartGuestAgent) ProtoMessage() {}
|
||||||
|
|
||||||
|
func (x *WatchInstruction_PortForward_Target_TartGuestAgent) ProtoReflect() protoreflect.Message {
|
||||||
|
mi := &file_orchard_proto_msgTypes[8]
|
||||||
|
if x != nil {
|
||||||
|
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||||
|
if ms.LoadMessageInfo() == nil {
|
||||||
|
ms.StoreMessageInfo(mi)
|
||||||
|
}
|
||||||
|
return ms
|
||||||
|
}
|
||||||
|
return mi.MessageOf(x)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Deprecated: Use WatchInstruction_PortForward_Target_TartGuestAgent.ProtoReflect.Descriptor instead.
|
||||||
|
func (*WatchInstruction_PortForward_Target_TartGuestAgent) Descriptor() ([]byte, []int) {
|
||||||
|
return file_orchard_proto_rawDescGZIP(), []int{0, 0, 0, 1}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *WatchInstruction_PortForward_Target_TartGuestAgent) GetVmUid() string {
|
||||||
|
if x != nil {
|
||||||
|
return x.VmUid
|
||||||
|
}
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
var File_orchard_proto protoreflect.FileDescriptor
|
var File_orchard_proto protoreflect.FileDescriptor
|
||||||
|
|
||||||
const file_orchard_proto_rawDesc = "" +
|
const file_orchard_proto_rawDesc = "" +
|
||||||
"\n" +
|
"\n" +
|
||||||
"\rorchard.proto\x1a\x1bgoogle/protobuf/empty.proto\"\xfe\x04\n" +
|
"\rorchard.proto\x1a\x1bgoogle/protobuf/empty.proto\"\x88\x06\n" +
|
||||||
"\x10WatchInstruction\x12O\n" +
|
"\x10WatchInstruction\x12O\n" +
|
||||||
"\x13port_forward_action\x18\x01 \x01(\v2\x1d.WatchInstruction.PortForwardH\x00R\x11portForwardAction\x12C\n" +
|
"\x13port_forward_action\x18\x01 \x01(\v2\x1d.WatchInstruction.PortForwardH\x00R\x11portForwardAction\x12C\n" +
|
||||||
"\x0fsync_vms_action\x18\x02 \x01(\v2\x19.WatchInstruction.SyncVMsH\x00R\rsyncVmsAction\x12I\n" +
|
"\x0fsync_vms_action\x18\x02 \x01(\v2\x19.WatchInstruction.SyncVMsH\x00R\rsyncVmsAction\x12I\n" +
|
||||||
"\x11resolve_ip_action\x18\x03 \x01(\v2\x1b.WatchInstruction.ResolveIPH\x00R\x0fresolveIpAction\x1a\xb5\x02\n" +
|
"\x11resolve_ip_action\x18\x03 \x01(\v2\x1b.WatchInstruction.ResolveIPH\x00R\x0fresolveIpAction\x1a\xbf\x03\n" +
|
||||||
"\vPortForward\x12\x18\n" +
|
"\vPortForward\x12\x18\n" +
|
||||||
"\asession\x18\x01 \x01(\tR\asession\x12\x15\n" +
|
"\asession\x18\x01 \x01(\tR\asession\x12\x15\n" +
|
||||||
"\x06vm_uid\x18\x02 \x01(\tR\x05vmUid\x12\x12\n" +
|
"\x06vm_uid\x18\x02 \x01(\tR\x05vmUid\x12\x12\n" +
|
||||||
"\x04port\x18\x03 \x01(\rR\x04port\x12<\n" +
|
"\x04port\x18\x03 \x01(\rR\x04port\x12<\n" +
|
||||||
"\x06target\x18\x04 \x01(\v2$.WatchInstruction.PortForward.TargetR\x06target\x1a\xa2\x01\n" +
|
"\x06target\x18\x04 \x01(\v2$.WatchInstruction.PortForward.TargetR\x06target\x1a\xac\x02\n" +
|
||||||
"\x06Target\x12U\n" +
|
"\x06Target\x12U\n" +
|
||||||
"\fhost_process\x18\x01 \x01(\v20.WatchInstruction.PortForward.Target.HostProcessH\x00R\vhostProcess\x1a8\n" +
|
"\fhost_process\x18\x01 \x01(\v20.WatchInstruction.PortForward.Target.HostProcessH\x00R\vhostProcess\x12_\n" +
|
||||||
|
"\x10tart_guest_agent\x18\x02 \x01(\v23.WatchInstruction.PortForward.Target.TartGuestAgentH\x00R\x0etartGuestAgent\x1a8\n" +
|
||||||
"\vHostProcess\x12\x15\n" +
|
"\vHostProcess\x12\x15\n" +
|
||||||
"\x06vm_uid\x18\x01 \x01(\tR\x05vmUid\x12\x12\n" +
|
"\x06vm_uid\x18\x01 \x01(\tR\x05vmUid\x12\x12\n" +
|
||||||
"\x04name\x18\x02 \x01(\tR\x04nameB\a\n" +
|
"\x04name\x18\x02 \x01(\tR\x04name\x1a'\n" +
|
||||||
|
"\x0eTartGuestAgent\x12\x15\n" +
|
||||||
|
"\x06vm_uid\x18\x01 \x01(\tR\x05vmUidB\a\n" +
|
||||||
"\x05value\x1a\t\n" +
|
"\x05value\x1a\t\n" +
|
||||||
"\aSyncVMs\x1a<\n" +
|
"\aSyncVMs\x1a<\n" +
|
||||||
"\tResolveIP\x12\x18\n" +
|
"\tResolveIP\x12\x18\n" +
|
||||||
@@ -548,17 +613,18 @@ func file_orchard_proto_rawDescGZIP() []byte {
|
|||||||
return file_orchard_proto_rawDescData
|
return file_orchard_proto_rawDescData
|
||||||
}
|
}
|
||||||
|
|
||||||
var file_orchard_proto_msgTypes = make([]protoimpl.MessageInfo, 8)
|
var file_orchard_proto_msgTypes = make([]protoimpl.MessageInfo, 9)
|
||||||
var file_orchard_proto_goTypes = []any{
|
var file_orchard_proto_goTypes = []any{
|
||||||
(*WatchInstruction)(nil), // 0: WatchInstruction
|
(*WatchInstruction)(nil), // 0: WatchInstruction
|
||||||
(*PortForwardData)(nil), // 1: PortForwardData
|
(*PortForwardData)(nil), // 1: PortForwardData
|
||||||
(*ResolveIPResult)(nil), // 2: ResolveIPResult
|
(*ResolveIPResult)(nil), // 2: ResolveIPResult
|
||||||
(*WatchInstruction_PortForward)(nil), // 3: WatchInstruction.PortForward
|
(*WatchInstruction_PortForward)(nil), // 3: WatchInstruction.PortForward
|
||||||
(*WatchInstruction_SyncVMs)(nil), // 4: WatchInstruction.SyncVMs
|
(*WatchInstruction_SyncVMs)(nil), // 4: WatchInstruction.SyncVMs
|
||||||
(*WatchInstruction_ResolveIP)(nil), // 5: WatchInstruction.ResolveIP
|
(*WatchInstruction_ResolveIP)(nil), // 5: WatchInstruction.ResolveIP
|
||||||
(*WatchInstruction_PortForward_Target)(nil), // 6: WatchInstruction.PortForward.Target
|
(*WatchInstruction_PortForward_Target)(nil), // 6: WatchInstruction.PortForward.Target
|
||||||
(*WatchInstruction_PortForward_Target_HostProcess)(nil), // 7: WatchInstruction.PortForward.Target.HostProcess
|
(*WatchInstruction_PortForward_Target_HostProcess)(nil), // 7: WatchInstruction.PortForward.Target.HostProcess
|
||||||
(*emptypb.Empty)(nil), // 8: google.protobuf.Empty
|
(*WatchInstruction_PortForward_Target_TartGuestAgent)(nil), // 8: WatchInstruction.PortForward.Target.TartGuestAgent
|
||||||
|
(*emptypb.Empty)(nil), // 9: google.protobuf.Empty
|
||||||
}
|
}
|
||||||
var file_orchard_proto_depIdxs = []int32{
|
var file_orchard_proto_depIdxs = []int32{
|
||||||
3, // 0: WatchInstruction.port_forward_action:type_name -> WatchInstruction.PortForward
|
3, // 0: WatchInstruction.port_forward_action:type_name -> WatchInstruction.PortForward
|
||||||
@@ -566,17 +632,18 @@ var file_orchard_proto_depIdxs = []int32{
|
|||||||
5, // 2: WatchInstruction.resolve_ip_action:type_name -> WatchInstruction.ResolveIP
|
5, // 2: WatchInstruction.resolve_ip_action:type_name -> WatchInstruction.ResolveIP
|
||||||
6, // 3: WatchInstruction.PortForward.target:type_name -> WatchInstruction.PortForward.Target
|
6, // 3: WatchInstruction.PortForward.target:type_name -> WatchInstruction.PortForward.Target
|
||||||
7, // 4: WatchInstruction.PortForward.Target.host_process:type_name -> WatchInstruction.PortForward.Target.HostProcess
|
7, // 4: WatchInstruction.PortForward.Target.host_process:type_name -> WatchInstruction.PortForward.Target.HostProcess
|
||||||
8, // 5: Controller.Watch:input_type -> google.protobuf.Empty
|
8, // 5: WatchInstruction.PortForward.Target.tart_guest_agent:type_name -> WatchInstruction.PortForward.Target.TartGuestAgent
|
||||||
1, // 6: Controller.PortForward:input_type -> PortForwardData
|
9, // 6: Controller.Watch:input_type -> google.protobuf.Empty
|
||||||
2, // 7: Controller.ResolveIP:input_type -> ResolveIPResult
|
1, // 7: Controller.PortForward:input_type -> PortForwardData
|
||||||
0, // 8: Controller.Watch:output_type -> WatchInstruction
|
2, // 8: Controller.ResolveIP:input_type -> ResolveIPResult
|
||||||
1, // 9: Controller.PortForward:output_type -> PortForwardData
|
0, // 9: Controller.Watch:output_type -> WatchInstruction
|
||||||
8, // 10: Controller.ResolveIP:output_type -> google.protobuf.Empty
|
1, // 10: Controller.PortForward:output_type -> PortForwardData
|
||||||
8, // [8:11] is the sub-list for method output_type
|
9, // 11: Controller.ResolveIP:output_type -> google.protobuf.Empty
|
||||||
5, // [5:8] is the sub-list for method input_type
|
9, // [9:12] is the sub-list for method output_type
|
||||||
5, // [5:5] is the sub-list for extension type_name
|
6, // [6:9] is the sub-list for method input_type
|
||||||
5, // [5:5] is the sub-list for extension extendee
|
6, // [6:6] is the sub-list for extension type_name
|
||||||
0, // [0:5] is the sub-list for field type_name
|
6, // [6:6] is the sub-list for extension extendee
|
||||||
|
0, // [0:6] is the sub-list for field type_name
|
||||||
}
|
}
|
||||||
|
|
||||||
func init() { file_orchard_proto_init() }
|
func init() { file_orchard_proto_init() }
|
||||||
@@ -591,6 +658,7 @@ func file_orchard_proto_init() {
|
|||||||
}
|
}
|
||||||
file_orchard_proto_msgTypes[6].OneofWrappers = []any{
|
file_orchard_proto_msgTypes[6].OneofWrappers = []any{
|
||||||
(*WatchInstruction_PortForward_Target_HostProcess_)(nil),
|
(*WatchInstruction_PortForward_Target_HostProcess_)(nil),
|
||||||
|
(*WatchInstruction_PortForward_Target_TartGuestAgent_)(nil),
|
||||||
}
|
}
|
||||||
type x struct{}
|
type x struct{}
|
||||||
out := protoimpl.TypeBuilder{
|
out := protoimpl.TypeBuilder{
|
||||||
@@ -598,7 +666,7 @@ func file_orchard_proto_init() {
|
|||||||
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
|
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
|
||||||
RawDescriptor: unsafe.Slice(unsafe.StringData(file_orchard_proto_rawDesc), len(file_orchard_proto_rawDesc)),
|
RawDescriptor: unsafe.Slice(unsafe.StringData(file_orchard_proto_rawDesc), len(file_orchard_proto_rawDesc)),
|
||||||
NumEnums: 0,
|
NumEnums: 0,
|
||||||
NumMessages: 8,
|
NumMessages: 9,
|
||||||
NumExtensions: 0,
|
NumExtensions: 0,
|
||||||
NumServices: 1,
|
NumServices: 1,
|
||||||
},
|
},
|
||||||
|
|||||||
+7
-1
@@ -27,8 +27,14 @@ message WatchInstruction {
|
|||||||
string name = 2;
|
string name = 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Forward the byte stream to the Tart Guest Agent running inside the VM
|
||||||
|
message TartGuestAgent {
|
||||||
|
string vm_uid = 1;
|
||||||
|
}
|
||||||
|
|
||||||
oneof value {
|
oneof value {
|
||||||
HostProcess host_process = 1;
|
HostProcess host_process = 1;
|
||||||
|
TartGuestAgent tart_guest_agent = 2;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -40,7 +46,7 @@ message WatchInstruction {
|
|||||||
uint32 port = 3;
|
uint32 port = 3;
|
||||||
|
|
||||||
// Typed alternative to the legacy port-forwarding destination,
|
// Typed alternative to the legacy port-forwarding destination,
|
||||||
// adding support for host processes
|
// adding support for host processes and Tart Guest Agent
|
||||||
Target target = 4;
|
Target target = 4;
|
||||||
}
|
}
|
||||||
message SyncVMs {
|
message SyncVMs {
|
||||||
|
|||||||
Reference in New Issue
Block a user