diff --git a/go.mod b/go.mod index 99e32d3d..5bb86a10 100644 --- a/go.mod +++ b/go.mod @@ -12,8 +12,8 @@ require ( github.com/charmbracelet/lipgloss v1.1.0 github.com/docker/go-units v0.5.0 github.com/go-git/go-git/v5 v5.14.0 - github.com/go-openapi/runtime v0.29.0 - github.com/go-openapi/strfmt v0.24.0 + github.com/go-openapi/runtime v0.29.2 + github.com/go-openapi/strfmt v0.25.0 github.com/goccy/go-yaml v1.10.0 github.com/golang/protobuf v1.5.4 github.com/hashicorp/go-multierror v1.1.1 @@ -21,15 +21,15 @@ require ( github.com/nsf/jsondiff v0.0.0-20210926074059-1e845ec5d249 github.com/oklog/run v1.1.0 github.com/panta/machineid v1.0.2 - github.com/signadot/go-sdk v0.3.8-0.20250929174621-a6dd8680c9eb + github.com/signadot/go-sdk v0.3.8-0.20251204135517-652cdb5127f0 github.com/signadot/libconnect v0.1.1-0.20251105071521-21dfbecb25cc github.com/spf13/cobra v1.8.1 github.com/spf13/viper v1.11.0 github.com/theckman/yacspin v0.13.12 github.com/xeonx/timeago v1.0.0-rc5 github.com/zalando/go-keyring v0.2.6 - golang.org/x/net v0.44.0 - golang.org/x/term v0.35.0 + golang.org/x/net v0.47.0 + golang.org/x/term v0.37.0 google.golang.org/grpc v1.72.2 google.golang.org/protobuf v1.36.6 k8s.io/client-go v0.33.0 @@ -58,17 +58,17 @@ require ( github.com/fxamacker/cbor/v2 v2.7.0 // indirect github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376 // indirect github.com/go-git/go-billy/v5 v5.6.2 // indirect - github.com/go-openapi/swag/cmdutils v0.25.1 // indirect - github.com/go-openapi/swag/conv v0.25.1 // indirect - github.com/go-openapi/swag/fileutils v0.25.1 // indirect - github.com/go-openapi/swag/jsonname v0.25.1 // indirect - github.com/go-openapi/swag/jsonutils v0.25.1 // indirect - github.com/go-openapi/swag/loading v0.25.1 // indirect - github.com/go-openapi/swag/mangling v0.25.1 // indirect - github.com/go-openapi/swag/netutils v0.25.1 // indirect - github.com/go-openapi/swag/stringutils v0.25.1 // indirect - github.com/go-openapi/swag/typeutils v0.25.1 // indirect - github.com/go-openapi/swag/yamlutils v0.25.1 // indirect + github.com/go-openapi/swag/cmdutils v0.25.4 // indirect + github.com/go-openapi/swag/conv v0.25.4 // indirect + github.com/go-openapi/swag/fileutils v0.25.4 // indirect + github.com/go-openapi/swag/jsonname v0.25.4 // indirect + github.com/go-openapi/swag/jsonutils v0.25.4 // indirect + github.com/go-openapi/swag/loading v0.25.4 // indirect + github.com/go-openapi/swag/mangling v0.25.4 // indirect + github.com/go-openapi/swag/netutils v0.25.4 // indirect + github.com/go-openapi/swag/stringutils v0.25.4 // indirect + github.com/go-openapi/swag/typeutils v0.25.4 // indirect + github.com/go-openapi/swag/yamlutils v0.25.4 // indirect github.com/go-viper/mapstructure/v2 v2.4.0 // indirect github.com/godbus/dbus/v5 v5.1.0 // indirect github.com/golang/groupcache v0.0.0-20241129210726-2c02b8208cf8 // indirect @@ -94,7 +94,7 @@ require ( github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e // indirect go.opentelemetry.io/auto/sdk v1.2.1 // indirect go.yaml.in/yaml/v3 v3.0.4 // indirect - golang.org/x/sync v0.17.0 // indirect + golang.org/x/sync v0.18.0 // indirect google.golang.org/genproto/googleapis/rpc v0.0.0-20250519155744-55703ea1f237 // indirect gopkg.in/evanphx/json-patch.v4 v4.12.0 // indirect gopkg.in/warnings.v0 v0.1.2 // indirect @@ -103,7 +103,6 @@ require ( ) require ( - github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 // indirect github.com/charmbracelet/bubbles v0.21.0 github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect github.com/emicklei/go-restful/v3 v3.11.0 // indirect @@ -111,14 +110,14 @@ require ( github.com/fsnotify/fsnotify v1.7.0 // indirect github.com/go-logr/logr v1.4.3 // indirect github.com/go-logr/stdr v1.2.2 // indirect - github.com/go-openapi/analysis v0.24.0 // indirect - github.com/go-openapi/errors v0.22.3 // indirect - github.com/go-openapi/jsonpointer v0.22.1 // indirect - github.com/go-openapi/jsonreference v0.21.2 // indirect - github.com/go-openapi/loads v0.23.1 // indirect - github.com/go-openapi/spec v0.22.0 // indirect - github.com/go-openapi/swag v0.25.1 // indirect - github.com/go-openapi/validate v0.25.0 // indirect + github.com/go-openapi/analysis v0.24.1 // indirect + github.com/go-openapi/errors v0.22.4 // indirect + github.com/go-openapi/jsonpointer v0.22.3 // indirect + github.com/go-openapi/jsonreference v0.21.3 // indirect + github.com/go-openapi/loads v0.23.2 // indirect + github.com/go-openapi/spec v0.22.1 // indirect + github.com/go-openapi/swag v0.25.4 // indirect + github.com/go-openapi/validate v0.25.1 // indirect github.com/gogo/protobuf v1.3.2 // indirect github.com/google/go-cmp v0.7.0 // indirect github.com/google/uuid v1.6.0 // indirect @@ -144,14 +143,14 @@ require ( github.com/spf13/jwalterweatherman v1.1.0 // indirect github.com/spf13/pflag v1.0.5 // indirect github.com/subosito/gotenv v1.4.2 // indirect - go.mongodb.org/mongo-driver v1.17.4 // indirect + go.mongodb.org/mongo-driver v1.17.6 // indirect go.opentelemetry.io/otel v1.38.0 // indirect go.opentelemetry.io/otel/metric v1.38.0 // indirect go.opentelemetry.io/otel/trace v1.38.0 // indirect - golang.org/x/crypto v0.42.0 // indirect + golang.org/x/crypto v0.44.0 // indirect golang.org/x/oauth2 v0.29.0 // indirect - golang.org/x/sys v0.36.0 // indirect - golang.org/x/text v0.29.0 // indirect + golang.org/x/sys v0.38.0 // indirect + golang.org/x/text v0.31.0 // indirect golang.org/x/time v0.9.0 // indirect golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 // indirect gopkg.in/inf.v0 v0.9.1 // indirect @@ -171,4 +170,4 @@ require ( // Used for local dev //replace github.com/signadot/libconnect => ../libconnect/ -// replace github.com/signadot/go-sdk => ../go-sdk +//replace github.com/signadot/go-sdk => ../go-sdk diff --git a/go.sum b/go.sum index 045735c1..56904f73 100644 --- a/go.sum +++ b/go.sum @@ -55,8 +55,6 @@ github.com/argoproj/argo-rollouts v1.8.3 h1:blbtQva4IK9r6gFh+dWkCrLnFdPOWiv9ubQY github.com/argoproj/argo-rollouts v1.8.3/go.mod h1:kCAUvIfMGfOyVf3lvQbBt0nqQn4Pd+zB5/YwKv+UBa8= github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5 h1:0CwZNZbxp69SHPdPJAN/hZIm0C4OItdklCFmMRWYpio= github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs= -github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 h1:DklsrG3dyBCFEj5IhUbnKptjxatkF07cF2ak3yi77so= -github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2/go.mod h1:WaHUgvxTVq04UNunO+XhnAqY/wQc+bxr74GqbsZ/Jqw= github.com/atotto/clipboard v0.1.4 h1:EH0zSVneZPSuFR11BlR9YppQTVDbh5+16AmcJi4g1z4= github.com/atotto/clipboard v0.1.4/go.mod h1:ZY9tmq7sm5xIbd9bOK4onWV4S6X0u6GY7Vn0Yu86PYI= github.com/aymanbagabas/go-osc52/v2 v2.0.1 h1:HwpRHbFMcZLEVr42D4p7XBqjyuxQH5SMiErDT4WkJ2k= @@ -156,50 +154,54 @@ github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= github.com/go-logr/zapr v1.3.0 h1:XGdV8XW8zdwFiwOA2Dryh1gj2KRQyOOoNmBy4EplIcQ= github.com/go-logr/zapr v1.3.0/go.mod h1:YKepepNBd1u/oyhd/yQmtjVXmm9uML4IXUgMOwR8/Gg= -github.com/go-openapi/analysis v0.24.0 h1:vE/VFFkICKyYuTWYnplQ+aVr45vlG6NcZKC7BdIXhsA= -github.com/go-openapi/analysis v0.24.0/go.mod h1:GLyoJA+bvmGGaHgpfeDh8ldpGo69fAJg7eeMDMRCIrw= -github.com/go-openapi/errors v0.22.3 h1:k6Hxa5Jg1TUyZnOwV2Lh81j8ayNw5VVYLvKrp4zFKFs= -github.com/go-openapi/errors v0.22.3/go.mod h1:+WvbaBBULWCOna//9B9TbLNGSFOfF8lY9dw4hGiEiKQ= -github.com/go-openapi/jsonpointer v0.22.1 h1:sHYI1He3b9NqJ4wXLoJDKmUmHkWy/L7rtEo92JUxBNk= -github.com/go-openapi/jsonpointer v0.22.1/go.mod h1:pQT9OsLkfz1yWoMgYFy4x3U5GY5nUlsOn1qSBH5MkCM= -github.com/go-openapi/jsonreference v0.21.2 h1:Wxjda4M/BBQllegefXrY/9aq1fxBA8sI5M/lFU6tSWU= -github.com/go-openapi/jsonreference v0.21.2/go.mod h1:pp3PEjIsJ9CZDGCNOyXIQxsNuroxm8FAJ/+quA0yKzQ= -github.com/go-openapi/loads v0.23.1 h1:H8A0dX2KDHxDzc797h0+uiCZ5kwE2+VojaQVaTlXvS0= -github.com/go-openapi/loads v0.23.1/go.mod h1:hZSXkyACCWzWPQqizAv/Ye0yhi2zzHwMmoXQ6YQml44= -github.com/go-openapi/runtime v0.29.0 h1:Y7iDTFarS9XaFQ+fA+lBLngMwH6nYfqig1G+pHxMRO0= -github.com/go-openapi/runtime v0.29.0/go.mod h1:52HOkEmLL/fE4Pg3Kf9nxc9fYQn0UsIWyGjGIJE9dkg= -github.com/go-openapi/spec v0.22.0 h1:xT/EsX4frL3U09QviRIZXvkh80yibxQmtoEvyqug0Tw= -github.com/go-openapi/spec v0.22.0/go.mod h1:K0FhKxkez8YNS94XzF8YKEMULbFrRw4m15i2YUht4L0= -github.com/go-openapi/strfmt v0.24.0 h1:dDsopqbI3wrrlIzeXRbqMihRNnjzGC+ez4NQaAAJLuc= -github.com/go-openapi/strfmt v0.24.0/go.mod h1:Lnn1Bk9rZjXxU9VMADbEEOo7D7CDyKGLsSKekhFr7s4= -github.com/go-openapi/swag v0.25.1 h1:6uwVsx+/OuvFVPqfQmOOPsqTcm5/GkBhNwLqIR916n8= -github.com/go-openapi/swag v0.25.1/go.mod h1:bzONdGlT0fkStgGPd3bhZf1MnuPkf2YAys6h+jZipOo= -github.com/go-openapi/swag/cmdutils v0.25.1 h1:nDke3nAFDArAa631aitksFGj2omusks88GF1VwdYqPY= -github.com/go-openapi/swag/cmdutils v0.25.1/go.mod h1:pdae/AFo6WxLl5L0rq87eRzVPm/XRHM3MoYgRMvG4A0= -github.com/go-openapi/swag/conv v0.25.1 h1:+9o8YUg6QuqqBM5X6rYL/p1dpWeZRhoIt9x7CCP+he0= -github.com/go-openapi/swag/conv v0.25.1/go.mod h1:Z1mFEGPfyIKPu0806khI3zF+/EUXde+fdeksUl2NiDs= -github.com/go-openapi/swag/fileutils v0.25.1 h1:rSRXapjQequt7kqalKXdcpIegIShhTPXx7yw0kek2uU= -github.com/go-openapi/swag/fileutils v0.25.1/go.mod h1:+NXtt5xNZZqmpIpjqcujqojGFek9/w55b3ecmOdtg8M= -github.com/go-openapi/swag/jsonname v0.25.1 h1:Sgx+qbwa4ej6AomWC6pEfXrA6uP2RkaNjA9BR8a1RJU= -github.com/go-openapi/swag/jsonname v0.25.1/go.mod h1:71Tekow6UOLBD3wS7XhdT98g5J5GR13NOTQ9/6Q11Zo= -github.com/go-openapi/swag/jsonutils v0.25.1 h1:AihLHaD0brrkJoMqEZOBNzTLnk81Kg9cWr+SPtxtgl8= -github.com/go-openapi/swag/jsonutils v0.25.1/go.mod h1:JpEkAjxQXpiaHmRO04N1zE4qbUEg3b7Udll7AMGTNOo= -github.com/go-openapi/swag/jsonutils/fixtures_test v0.25.1 h1:DSQGcdB6G0N9c/KhtpYc71PzzGEIc/fZ1no35x4/XBY= -github.com/go-openapi/swag/jsonutils/fixtures_test v0.25.1/go.mod h1:kjmweouyPwRUEYMSrbAidoLMGeJ5p6zdHi9BgZiqmsg= -github.com/go-openapi/swag/loading v0.25.1 h1:6OruqzjWoJyanZOim58iG2vj934TysYVptyaoXS24kw= -github.com/go-openapi/swag/loading v0.25.1/go.mod h1:xoIe2EG32NOYYbqxvXgPzne989bWvSNoWoyQVWEZicc= -github.com/go-openapi/swag/mangling v0.25.1 h1:XzILnLzhZPZNtmxKaz/2xIGPQsBsvmCjrJOWGNz/ync= -github.com/go-openapi/swag/mangling v0.25.1/go.mod h1:CdiMQ6pnfAgyQGSOIYnZkXvqhnnwOn997uXZMAd/7mQ= -github.com/go-openapi/swag/netutils v0.25.1 h1:2wFLYahe40tDUHfKT1GRC4rfa5T1B4GWZ+msEFA4Fl4= -github.com/go-openapi/swag/netutils v0.25.1/go.mod h1:CAkkvqnUJX8NV96tNhEQvKz8SQo2KF0f7LleiJwIeRE= -github.com/go-openapi/swag/stringutils v0.25.1 h1:Xasqgjvk30eUe8VKdmyzKtjkVjeiXx1Iz0zDfMNpPbw= -github.com/go-openapi/swag/stringutils v0.25.1/go.mod h1:JLdSAq5169HaiDUbTvArA2yQxmgn4D6h4A+4HqVvAYg= -github.com/go-openapi/swag/typeutils v0.25.1 h1:rD/9HsEQieewNt6/k+JBwkxuAHktFtH3I3ysiFZqukA= -github.com/go-openapi/swag/typeutils v0.25.1/go.mod h1:9McMC/oCdS4BKwk2shEB7x17P6HmMmA6dQRtAkSnNb8= -github.com/go-openapi/swag/yamlutils v0.25.1 h1:mry5ez8joJwzvMbaTGLhw8pXUnhDK91oSJLDPF1bmGk= -github.com/go-openapi/swag/yamlutils v0.25.1/go.mod h1:cm9ywbzncy3y6uPm/97ysW8+wZ09qsks+9RS8fLWKqg= -github.com/go-openapi/validate v0.25.0 h1:JD9eGX81hDTjoY3WOzh6WqxVBVl7xjsLnvDo1GL5WPU= -github.com/go-openapi/validate v0.25.0/go.mod h1:SUY7vKrN5FiwK6LyvSwKjDfLNirSfWwHNgxd2l29Mmw= +github.com/go-openapi/analysis v0.24.1 h1:Xp+7Yn/KOnVWYG8d+hPksOYnCYImE3TieBa7rBOesYM= +github.com/go-openapi/analysis v0.24.1/go.mod h1:dU+qxX7QGU1rl7IYhBC8bIfmWQdX4Buoea4TGtxXY84= +github.com/go-openapi/errors v0.22.4 h1:oi2K9mHTOb5DPW2Zjdzs/NIvwi2N3fARKaTJLdNabaM= +github.com/go-openapi/errors v0.22.4/go.mod h1:z9S8ASTUqx7+CP1Q8dD8ewGH/1JWFFLX/2PmAYNQLgk= +github.com/go-openapi/jsonpointer v0.22.3 h1:dKMwfV4fmt6Ah90zloTbUKWMD+0he+12XYAsPotrkn8= +github.com/go-openapi/jsonpointer v0.22.3/go.mod h1:0lBbqeRsQ5lIanv3LHZBrmRGHLHcQoOXQnf88fHlGWo= +github.com/go-openapi/jsonreference v0.21.3 h1:96Dn+MRPa0nYAR8DR1E03SblB5FJvh7W6krPI0Z7qMc= +github.com/go-openapi/jsonreference v0.21.3/go.mod h1:RqkUP0MrLf37HqxZxrIAtTWW4ZJIK1VzduhXYBEeGc4= +github.com/go-openapi/loads v0.23.2 h1:rJXAcP7g1+lWyBHC7iTY+WAF0rprtM+pm8Jxv1uQJp4= +github.com/go-openapi/loads v0.23.2/go.mod h1:IEVw1GfRt/P2Pplkelxzj9BYFajiWOtY2nHZNj4UnWY= +github.com/go-openapi/runtime v0.29.2 h1:UmwSGWNmWQqKm1c2MGgXVpC2FTGwPDQeUsBMufc5Yj0= +github.com/go-openapi/runtime v0.29.2/go.mod h1:biq5kJXRJKBJxTDJXAa00DOTa/anflQPhT0/wmjuy+0= +github.com/go-openapi/spec v0.22.1 h1:beZMa5AVQzRspNjvhe5aG1/XyBSMeX1eEOs7dMoXh/k= +github.com/go-openapi/spec v0.22.1/go.mod h1:c7aeIQT175dVowfp7FeCvXXnjN/MrpaONStibD2WtDA= +github.com/go-openapi/strfmt v0.25.0 h1:7R0RX7mbKLa9EYCTHRcCuIPcaqlyQiWNPTXwClK0saQ= +github.com/go-openapi/strfmt v0.25.0/go.mod h1:nNXct7OzbwrMY9+5tLX4I21pzcmE6ccMGXl3jFdPfn8= +github.com/go-openapi/swag v0.25.4 h1:OyUPUFYDPDBMkqyxOTkqDYFnrhuhi9NR6QVUvIochMU= +github.com/go-openapi/swag v0.25.4/go.mod h1:zNfJ9WZABGHCFg2RnY0S4IOkAcVTzJ6z2Bi+Q4i6qFQ= +github.com/go-openapi/swag/cmdutils v0.25.4 h1:8rYhB5n6WawR192/BfUu2iVlxqVR9aRgGJP6WaBoW+4= +github.com/go-openapi/swag/cmdutils v0.25.4/go.mod h1:pdae/AFo6WxLl5L0rq87eRzVPm/XRHM3MoYgRMvG4A0= +github.com/go-openapi/swag/conv v0.25.4 h1:/Dd7p0LZXczgUcC/Ikm1+YqVzkEeCc9LnOWjfkpkfe4= +github.com/go-openapi/swag/conv v0.25.4/go.mod h1:3LXfie/lwoAv0NHoEuY1hjoFAYkvlqI/Bn5EQDD3PPU= +github.com/go-openapi/swag/fileutils v0.25.4 h1:2oI0XNW5y6UWZTC7vAxC8hmsK/tOkWXHJQH4lKjqw+Y= +github.com/go-openapi/swag/fileutils v0.25.4/go.mod h1:cdOT/PKbwcysVQ9Tpr0q20lQKH7MGhOEb6EwmHOirUk= +github.com/go-openapi/swag/jsonname v0.25.4 h1:bZH0+MsS03MbnwBXYhuTttMOqk+5KcQ9869Vye1bNHI= +github.com/go-openapi/swag/jsonname v0.25.4/go.mod h1:GPVEk9CWVhNvWhZgrnvRA6utbAltopbKwDu8mXNUMag= +github.com/go-openapi/swag/jsonutils v0.25.4 h1:VSchfbGhD4UTf4vCdR2F4TLBdLwHyUDTd1/q4i+jGZA= +github.com/go-openapi/swag/jsonutils v0.25.4/go.mod h1:7OYGXpvVFPn4PpaSdPHJBtF0iGnbEaTk8AvBkoWnaAY= +github.com/go-openapi/swag/jsonutils/fixtures_test v0.25.4 h1:IACsSvBhiNJwlDix7wq39SS2Fh7lUOCJRmx/4SN4sVo= +github.com/go-openapi/swag/jsonutils/fixtures_test v0.25.4/go.mod h1:Mt0Ost9l3cUzVv4OEZG+WSeoHwjWLnarzMePNDAOBiM= +github.com/go-openapi/swag/loading v0.25.4 h1:jN4MvLj0X6yhCDduRsxDDw1aHe+ZWoLjW+9ZQWIKn2s= +github.com/go-openapi/swag/loading v0.25.4/go.mod h1:rpUM1ZiyEP9+mNLIQUdMiD7dCETXvkkC30z53i+ftTE= +github.com/go-openapi/swag/mangling v0.25.4 h1:2b9kBJk9JvPgxr36V23FxJLdwBrpijI26Bx5JH4Hp48= +github.com/go-openapi/swag/mangling v0.25.4/go.mod h1:6dxwu6QyORHpIIApsdZgb6wBk/DPU15MdyYj/ikn0Hg= +github.com/go-openapi/swag/netutils v0.25.4 h1:Gqe6K71bGRb3ZQLusdI8p/y1KLgV4M/k+/HzVSqT8H0= +github.com/go-openapi/swag/netutils v0.25.4/go.mod h1:m2W8dtdaoX7oj9rEttLyTeEFFEBvnAx9qHd5nJEBzYg= +github.com/go-openapi/swag/stringutils v0.25.4 h1:O6dU1Rd8bej4HPA3/CLPciNBBDwZj9HiEpdVsb8B5A8= +github.com/go-openapi/swag/stringutils v0.25.4/go.mod h1:GTsRvhJW5xM5gkgiFe0fV3PUlFm0dr8vki6/VSRaZK0= +github.com/go-openapi/swag/typeutils v0.25.4 h1:1/fbZOUN472NTc39zpa+YGHn3jzHWhv42wAJSN91wRw= +github.com/go-openapi/swag/typeutils v0.25.4/go.mod h1:Ou7g//Wx8tTLS9vG0UmzfCsjZjKhpjxayRKTHXf2pTE= +github.com/go-openapi/swag/yamlutils v0.25.4 h1:6jdaeSItEUb7ioS9lFoCZ65Cne1/RZtPBZ9A56h92Sw= +github.com/go-openapi/swag/yamlutils v0.25.4/go.mod h1:MNzq1ulQu+yd8Kl7wPOut/YHAAU/H6hL91fF+E2RFwc= +github.com/go-openapi/testify/enable/yaml/v2 v2.0.2 h1:0+Y41Pz1NkbTHz8NngxTuAXxEodtNSI1WG1c/m5Akw4= +github.com/go-openapi/testify/enable/yaml/v2 v2.0.2/go.mod h1:kme83333GCtJQHXQ8UKX3IBZu6z8T5Dvy5+CW3NLUUg= +github.com/go-openapi/testify/v2 v2.0.2 h1:X999g3jeLcoY8qctY/c/Z8iBHTbwLz7R2WXd6Ub6wls= +github.com/go-openapi/testify/v2 v2.0.2/go.mod h1:HCPmvFFnheKK2BuwSA0TbbdxJ3I16pjwMkYkP4Ywn54= +github.com/go-openapi/validate v0.25.1 h1:sSACUI6Jcnbo5IWqbYHgjibrhhmt3vR6lCzKZnmAgBw= +github.com/go-openapi/validate v0.25.1/go.mod h1:RMVyVFYte0gbSTaZ0N4KmTn6u/kClvAFp+mAVfS/DQc= github.com/go-playground/assert/v2 v2.0.1/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4= github.com/go-playground/locales v0.13.0 h1:HyWk6mgj5qFqCT5fjGBuRArbVDfE4hi8+e8ceBS/t7Q= github.com/go-playground/locales v0.13.0/go.mod h1:taPMhCMXrRLJO55olJkUXHZBHCxTMfnGwq/HNwmWNS8= @@ -413,8 +415,8 @@ github.com/sahilm/fuzzy v0.1.1 h1:ceu5RHF8DGgoi+/dR5PsECjCDH1BE3Fnmpo7aVXOdRA= github.com/sahilm/fuzzy v0.1.1/go.mod h1:VFvziUEIMCrT6A6tw2RFIXPXXmzXbOsSHF0DOI8ZK9Y= github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3 h1:n661drycOFuPLCN3Uc8sB6B/s6Z4t2xvBgU1htSHuq8= github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3/go.mod h1:A0bzQcvG0E7Rwjx0REVgAGH58e96+X0MeOfepqsbeW4= -github.com/signadot/go-sdk v0.3.8-0.20250929174621-a6dd8680c9eb h1:o4hbuZx3EQFPseMfmpTVjmg2RnIaJ64abFzl0BdRW2k= -github.com/signadot/go-sdk v0.3.8-0.20250929174621-a6dd8680c9eb/go.mod h1:Sun8u3KgCLtVNEckPYYzlTxpvrUkdFbq7KUD28Admf8= +github.com/signadot/go-sdk v0.3.8-0.20251204135517-652cdb5127f0 h1:hu+gMqrxjYJexz6yMo+eFdrFQpdNe/MB9Ueyz2sBPKU= +github.com/signadot/go-sdk v0.3.8-0.20251204135517-652cdb5127f0/go.mod h1:hqXhjeoK2VC3/4hwoYZbTsuODm6zivao7kK+CYN60F4= github.com/signadot/libconnect v0.1.1-0.20251105071521-21dfbecb25cc h1:+KqZCPSfwrUeePHicVDBz9hZdkRV6iDfzlRmJukkhGc= github.com/signadot/libconnect v0.1.1-0.20251105071521-21dfbecb25cc/go.mod h1:1EIEmcXp64cMzIKdmYhzGQXaDUy+VOsNQFzJHxi9164= github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= @@ -465,8 +467,8 @@ github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9de github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/zalando/go-keyring v0.2.6 h1:r7Yc3+H+Ux0+M72zacZoItR3UDxeWfKTcabvkI8ua9s= github.com/zalando/go-keyring v0.2.6/go.mod h1:2TCrxYrbUNYfNS/Kgy/LSrkSQzZ5UPVH85RwfczwvcI= -go.mongodb.org/mongo-driver v1.17.4 h1:jUorfmVzljjr0FLzYQsGP8cgN/qzzxlY9Vh0C9KFXVw= -go.mongodb.org/mongo-driver v1.17.4/go.mod h1:Hy04i7O2kC4RS06ZrhPRqj/u4DTYkFDAAccj+rVKqgQ= +go.mongodb.org/mongo-driver v1.17.6 h1:87JUG1wZfWsr6rIz3ZmpH90rL5tea7O3IHuSwHUpsss= +go.mongodb.org/mongo-driver v1.17.6/go.mod h1:Hy04i7O2kC4RS06ZrhPRqj/u4DTYkFDAAccj+rVKqgQ= go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= @@ -499,8 +501,8 @@ golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPh golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= -golang.org/x/crypto v0.42.0 h1:chiH31gIWm57EkTXpwnqf8qeuMUi0yekh6mT2AvFlqI= -golang.org/x/crypto v0.42.0/go.mod h1:4+rDnOTJhQCx2q7/j6rAN5XDw8kPjeaXEUR2eL94ix8= +golang.org/x/crypto v0.44.0 h1:A97SsFvM3AIwEEmTBiaxPPTYpDC47w720rdiiUvgoAU= +golang.org/x/crypto v0.44.0/go.mod h1:013i+Nw79BMiQiMsOPcVCB5ZIJbYkerPrGnOa00tvmc= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= @@ -570,8 +572,8 @@ golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v golang.org/x/net v0.0.0-20210316092652-d523dce5a7f4/go.mod h1:RBQZq4jEuRlivfhVLdyRGr576XBO4/greRjx4P4O3yc= golang.org/x/net v0.0.0-20210331212208-0fccb6fa2b5c/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.44.0 h1:evd8IRDyfNBMBTTY5XRF1vaZlD+EmWx6x8PkhR04H/I= -golang.org/x/net v0.44.0/go.mod h1:ECOoLqd5U3Lhyeyo/QDCEVQ4sNgYsqvCZ722XogGieY= +golang.org/x/net v0.47.0 h1:Mx+4dIFzqraBXUugkia1OOvlD6LemFo1ALMHjrXDOhY= +golang.org/x/net v0.47.0/go.mod h1:/jNxtkgq5yWUGYkaZGqo27cfGZ1c5Nen03aYrrKpVRU= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= @@ -594,8 +596,8 @@ golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/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-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.17.0 h1:l60nONMj9l5drqw6jlhIELNv9I0A4OFgRsG9k2oT9Ug= -golang.org/x/sync v0.17.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI= +golang.org/x/sync v0.18.0 h1:kr88TuHDroi+UVf+0hZnirlk8o8T+4MrK6mr60WkH/I= +golang.org/x/sync v0.18.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -643,11 +645,11 @@ golang.org/x/sys v0.0.0-20220406163625-3f8b81556e12/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.36.0 h1:KVRy2GtZBrk1cBYA7MKu5bEZFxQk4NIDV6RLVcC8o0k= -golang.org/x/sys v0.36.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= +golang.org/x/sys v0.38.0 h1:3yZWxaJjBmCWXqhN1qh02AkOnCQ1poK6oF+a7xWL6Gc= +golang.org/x/sys v0.38.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= -golang.org/x/term v0.35.0 h1:bZBVKBudEyhRcajGcNc3jIfWPqV4y/Kt2XcoigOWtDQ= -golang.org/x/term v0.35.0/go.mod h1:TPGtkTLesOwf2DE8CgVYiZinHAOuy5AYUYT1lENIZnA= +golang.org/x/term v0.37.0 h1:8EGAD0qCmHYZg6J17DvsMy9/wJ7/D/4pV/wfnld5lTU= +golang.org/x/term v0.37.0/go.mod h1:5pB4lxRNYYVZuTLmy8oR2BH8dflOR+IbTYFD8fi3254= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/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.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -657,8 +659,8 @@ golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= -golang.org/x/text v0.29.0 h1:1neNs90w9YzJ9BocxfsQNHKuAT4pkghyXc4nhZ6sJvk= -golang.org/x/text v0.29.0/go.mod h1:7MhJOA9CD2qZyOKYazxdYMF85OwPdEr9jTtBpO7ydH4= +golang.org/x/text v0.31.0 h1:aC8ghyu4JhP8VojJ2lEHBnochRno1sgL6nEi9WGFGMM= +golang.org/x/text v0.31.0/go.mod h1:tKRAlv61yKIjGGHX/4tP1LTbc13YSec1pxVEWXzfoeM= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= @@ -713,8 +715,8 @@ golang.org/x/tools v0.0.0-20210105154028-b0ab187a4818/go.mod h1:emZCQorbCU4vsT4f golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20210108195828-e2f9c7f1fc8e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0= -golang.org/x/tools v0.36.0 h1:kWS0uv/zsvHEle1LbV5LE8QujrxB3wfQyxHfhOk0Qkg= -golang.org/x/tools v0.36.0/go.mod h1:WBDiHKJK8YgLHlcQPYQzNCkUxUypCaa5ZegCVutKm+s= +golang.org/x/tools v0.38.0 h1:Hx2Xv8hISq8Lm16jvBZ2VQf+RLmbd7wVUsALibYI/IQ= +golang.org/x/tools v0.38.0/go.mod h1:yEsQ/d/YK8cjh0L6rZlY8tgtlKiBNTL14pGDJPJpYQs= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= diff --git a/internal/builder/sandbox.go b/internal/builder/sandbox.go index 64e22db9..633f8e1f 100644 --- a/internal/builder/sandbox.go +++ b/internal/builder/sandbox.go @@ -4,7 +4,6 @@ import ( "errors" "strconv" - "github.com/signadot/cli/internal/utils/system" "github.com/signadot/go-sdk/models" ) @@ -79,13 +78,11 @@ func (sb *SandboxBuilder) GetLastAddedOverrideName() *string { return sb.lastAddedOverrideName } -func (sb *SandboxBuilder) SetMachineID() *SandboxBuilder { +func (sb *SandboxBuilder) SetDevboxID(id string) *SandboxBuilder { return sb.withError(func() error { - machineID, err := system.GetMachineID() - if err != nil { - return err + sb.internal.Spec.Connection = &models.Connection{ + DevboxID: id, } - sb.internal.Spec.LocalMachineID = machineID return nil }) } diff --git a/internal/command/devbox/delete.go b/internal/command/devbox/delete.go index 7be1adab..67d1ed57 100644 --- a/internal/command/devbox/delete.go +++ b/internal/command/devbox/delete.go @@ -6,10 +6,12 @@ import ( "fmt" "io" "os" - "os/signal" - "syscall" + "strings" + "time" "github.com/signadot/cli/internal/config" + devboxpkg "github.com/signadot/cli/internal/devbox" + "github.com/signadot/go-sdk/client/devboxes" "github.com/spf13/cobra" ) @@ -17,14 +19,14 @@ func newDelete(devbox *config.Devbox) *cobra.Command { cfg := &config.DevboxDelete{Devbox: devbox} cmd := &cobra.Command{ - Use: "delete NAME", + Use: "delete ID", Short: "Delete a devbox", - Long: `Delete a devbox by name. + Long: `Delete a devbox by ID. This will remove the devbox registration and any associated local state.`, Args: cobra.ExactArgs(1), RunE: func(cmd *cobra.Command, args []string) error { - cfg.Name = args[0] + cfg.ID = args[0] return deleteDevbox(cfg, cmd.ErrOrStderr()) }, } @@ -35,55 +37,62 @@ This will remove the devbox registration and any associated local state.`, } func deleteDevbox(cfg *config.DevboxDelete, log io.Writer) error { - ctx, cancel := signal.NotifyContext(context.Background(), - os.Interrupt, syscall.SIGTERM, syscall.SIGHUP) + ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) defer cancel() if err := cfg.InitAPIConfig(); err != nil { return err } - if cfg.Name == "" { - return errors.New("devbox name is required") + if cfg.ID == "" { + return errors.New("devbox ID is required") } - // TODO: Implement API call to delete devbox - // Example: - // params := devboxes.NewDeleteDevboxParams(). - // WithContext(ctx). - // WithOrgName(cfg.Org). - // WithUser(cfg.User). - // WithDevboxName(cfg.Name) - // - // _, err := cfg.Client.Devboxes.DeleteDevbox(params, nil) - // if err != nil { - // return err - // } - - _ = ctx // TODO: remove when implementing API call - fmt.Fprintf(log, "TODO: Implement devbox delete API call\n") - fmt.Fprintf(log, "Deleted devbox %q.\n\n", cfg.Name) - - // TODO: If this is the default devbox, clean up ~/.signadot/default-devbox - // Example: - // if isDefaultDevbox(cfg.Name) { - // if err := removeDefaultDevbox(); err != nil { - // fmt.Fprintf(log, "Warning: failed to remove default devbox config: %v\n", err) - // } - // } - - // TODO: Wait for deletion with polling if cfg.Wait is true - // Example: - // if cfg.Wait { - // if err := waitForDeleted(ctx, cfg, log, cfg.Name); err != nil { - // return err - // } - // } + // Delete the devbox + params := devboxes.NewDeleteDevboxParams(). + WithContext(ctx). + WithOrgName(cfg.Org). + WithDevboxID(cfg.ID) + _, err := cfg.Client.Devboxes.DeleteDevbox(params) + if err != nil { + return fmt.Errorf("failed to delete devbox: %w", err) + } + + // Check if this is the local devbox and clean up the ID file if so + if err := cleanupLocalDevboxID(cfg.ID, log); err != nil { + // Log warning but continue with deletion + fmt.Fprintf(log, "Warning: failed to check local devbox ID file: %v\n", err) + } + + fmt.Fprintf(log, "Deleted devbox (ID: %s).\n", cfg.ID) return nil } -// TODO: Implement helper functions -// func isDefaultDevbox(name string) bool { ... } -// func removeDefaultDevbox() error { ... } -// func waitForDeleted(ctx context.Context, cfg *config.DevboxDelete, log io.Writer, name string) error { ... } +// cleanupLocalDevboxID checks if the deleted devbox is the local devbox and removes the ID file if so. +func cleanupLocalDevboxID(devboxID string, log io.Writer) error { + idFile, err := devboxpkg.IDFile() + if err != nil { + return err + } + + data, err := os.ReadFile(idFile) + if err != nil { + if os.IsNotExist(err) { + // File doesn't exist, nothing to clean up + return nil + } + return err + } + + localID := strings.TrimSpace(string(data)) + if localID == devboxID { + // This is the local devbox, remove the ID file + if err := os.Remove(idFile); err != nil { + return fmt.Errorf("failed to remove local devbox ID file: %w", err) + } + fmt.Fprintf(log, "Removed local devbox ID file.\n") + } + + return nil +} diff --git a/internal/command/devbox/list.go b/internal/command/devbox/list.go index 42bc3c5e..776bfc4e 100644 --- a/internal/command/devbox/list.go +++ b/internal/command/devbox/list.go @@ -1,11 +1,14 @@ package devbox import ( + "context" "fmt" "io" + "time" "github.com/signadot/cli/internal/config" "github.com/signadot/cli/internal/print" + "github.com/signadot/go-sdk/client/devboxes" "github.com/spf13/cobra" ) @@ -21,6 +24,7 @@ func newList(devbox *config.Devbox) *cobra.Command { }, } + cfg.AddFlags(cmd) return cmd } @@ -29,32 +33,29 @@ func list(cfg *config.DevboxList, out io.Writer) error { return err } - // TODO: Implement API call to list devboxes - // Example: - // resp, err := cfg.Client.Devboxes.ListDevboxes( - // devboxes.NewListDevboxesParams(). - // WithOrgName(cfg.Org). - // WithUser(cfg.User), - // nil, - // ) - // if err != nil { - // return err - // } - - // For now, return a placeholder - fmt.Fprintln(out, "TODO: Implement devbox list API call") - - // TODO: Handle output format + ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) + defer cancel() + params := devboxes.NewGetDevboxesParams(). + WithContext(ctx). + WithOrgName(cfg.Org) + if cfg.ShowAll { + all := "true" + params = params.WithAll(&all) + } + resp, err := cfg.Client.Devboxes.GetDevboxes(params) + if err != nil { + return err + } + + devboxes := resp.Payload + switch cfg.OutputFormat { case config.OutputFormatDefault: - // return printDevboxTable(out, resp.Payload) - return nil + return printDevboxTable(out, devboxes) case config.OutputFormatJSON: - // return print.RawJSON(out, resp.Payload) - return print.RawJSON(out, []interface{}{}) + return print.RawJSON(out, devboxes) case config.OutputFormatYAML: - // return print.RawYAML(out, resp.Payload) - return print.RawYAML(out, []interface{}{}) + return print.RawYAML(out, devboxes) default: return fmt.Errorf("unsupported output format: %q", cfg.OutputFormat) } diff --git a/internal/command/devbox/printers.go b/internal/command/devbox/printers.go index f3d9ec0c..e6db590b 100644 --- a/internal/command/devbox/printers.go +++ b/internal/command/devbox/printers.go @@ -5,74 +5,61 @@ import ( "time" "github.com/signadot/cli/internal/sdtab" + "github.com/signadot/go-sdk/models" "github.com/xeonx/timeago" ) // devboxRow represents a row in the devbox table output. type devboxRow struct { - Name string `sdtab:"NAME"` - Primary string `sdtab:"PRIMARY"` - HostName string `sdtab:"HOSTNAME,trunc"` + ID string `sdtab:"ID"` + Name string `sdtab:"NAME,trunc"` OS string `sdtab:"OS"` MachineID string `sdtab:"MACHINE ID,trunc"` - LastActive string `sdtab:"LAST ACTIVE"` Status string `sdtab:"STATUS"` + ValidUntil string `sdtab:"VALID UNTIL"` } -// TODO: Define the Devbox model type once API is implemented -// For now, using a placeholder interface -type DevboxModel interface{} - // printDevboxTable prints devboxes in a table format. -func printDevboxTable(out io.Writer, devboxes []DevboxModel) error { +func printDevboxTable(out io.Writer, devboxes []*models.Devbox) error { t := sdtab.New[devboxRow](out) t.AddHeader() - // TODO: Iterate over actual devbox models once API is implemented - // Example: - // for _, db := range devboxes { - // lastActive := "" - // if db.Status != nil && db.Status.Session != nil { - // renewedAt, err := time.Parse(time.RFC3339, db.Status.Session.RenewedAt) - // if err == nil { - // lastActive = timeago.NoMax(timeago.English).Format(renewedAt) - // } - // } - // - // primary := "no" - // if db.Machine != nil && db.Machine.Primary { - // primary = "yes" - // } - // - // status := "inactive" - // if db.Status != nil && db.Status.Session != nil { - // validUntil, err := time.Parse(time.RFC3339, db.Status.Session.ValidUntil) - // if err == nil && validUntil.After(time.Now()) { - // status = "active" - // } - // } - // - // t.AddRow(devboxRow{ - // Name: db.Machine.Name, - // Primary: primary, - // HostName: db.Machine.Meta.HostName, - // OS: db.Machine.Meta.OS, - // MachineID: db.Machine.Meta.LocalMachineID, - // LastActive: lastActive, - // Status: status, - // }) - // } + for _, db := range devboxes { + validUntil := "-" + if db.Status != nil && db.Status.Session != nil && db.Status.Session.ValidUntil != "" { + vu, err := time.Parse(time.RFC3339, db.Status.Session.ValidUntil) + if err == nil { + validUntil = timeago.NoMax(timeago.English).Format(vu) + } + } + + status := "inactive" + if db.Status != nil && db.Status.Session != nil && db.Status.Session.ValidUntil != "" { + validUntil, err := time.Parse(time.RFC3339, db.Status.Session.ValidUntil) + if err == nil && validUntil.After(time.Now()) { + status = "active" + } + } + + name := db.Metadata["name"] + os := db.Metadata["goos"] + machineID := db.Metadata["machine-id"] + // Truncate machine ID to 12 characters with "..." suffix + machineID = sdtab.Truncate(machineID, 12) + if db.Status.Session != nil { + ses := db.Status.Session + _ = ses + } - // Placeholder row for testing - t.AddRow(devboxRow{ - Name: "example-devbox", - Primary: "yes", - HostName: "localhost", - OS: "linux", - MachineID: "abc123", - LastActive: timeago.NoMax(timeago.English).Format(time.Now()), - Status: "inactive", - }) + t.AddRow(devboxRow{ + ID: db.ID, + Name: name, + OS: os, + MachineID: machineID, + ValidUntil: validUntil, + Status: status, + }) + } return t.Flush() } diff --git a/internal/command/devbox/register.go b/internal/command/devbox/register.go index 92f4732a..5e0df1e0 100644 --- a/internal/command/devbox/register.go +++ b/internal/command/devbox/register.go @@ -9,6 +9,7 @@ import ( "syscall" "github.com/signadot/cli/internal/config" + devboxpkg "github.com/signadot/cli/internal/devbox" "github.com/spf13/cobra" ) @@ -42,59 +43,51 @@ func register(cfg *config.DevboxRegister, out, log io.Writer) error { return err } - // TODO: Get machine metadata (localMachineID, hostName, OS, CLIVersion) - // This should come from system info utilities - // Example: - // machineID := getMachineID() - // hostName, _ := os.Hostname() - // osInfo := runtime.GOOS - - // TODO: Implement API call to claim/register devbox - // Example: - // claimReq := &models.DevboxClaimRequest{ - // Machine: &models.Machine{ - // Name: cfg.Name, // Optional, may be empty - // Primary: cfg.Primary, - // Meta: &models.MachineMeta{ - // LocalMachineID: machineID, - // HostName: hostName, - // OS: osInfo, - // CLIVersion: version.Version, - // }, - // }, - // } - // - // resp, err := cfg.Client.Devboxes.ClaimDevbox( - // devboxes.NewClaimDevboxParams(). - // WithContext(ctx). - // WithOrgName(cfg.Org). - // WithUser(cfg.User). - // WithBody(claimReq), - // nil, - // ) - // if err != nil { - // return err - // } - - // TODO: Store the machine info in ~/.signadot/default-devbox - // Example: - // if err := saveDefaultDevbox(resp.Payload.Machine); err != nil { - // return err - // } - - // For now, return a placeholder - _ = ctx - fmt.Fprintln(log, "TODO: Implement devbox register API call") - if cfg.Name != "" { - fmt.Fprintf(out, "Registered devbox with name: %s\n", cfg.Name) + // Check if a devbox ID file already exists + idFile, err := devboxpkg.IDFile() + if err != nil { + return fmt.Errorf("failed to get devbox ID file path: %w", err) + } + + existingID := "" + if _, err := os.Stat(idFile); err == nil { + // File exists, read the existing ID + data, err := os.ReadFile(idFile) + if err == nil { + existingID = string(data) + fmt.Fprintf(log, "Warning: devbox ID file already exists (ID: %s). It will be overwritten.\n", existingID) + } + } + + // Register the devbox + devboxID, err := devboxpkg.RegisterDevbox(ctx, cfg.API, cfg.Claim, cfg.Name) + if err != nil { + return fmt.Errorf("failed to register devbox: %w", err) + } + + // Save the devbox ID to file + if err := os.WriteFile(idFile, []byte(devboxID), 0600); err != nil { + return fmt.Errorf("failed to save devbox ID: %w", err) + } + + // Get the devbox name that was used (might be hostname if not provided) + devboxName := cfg.Name + if devboxName == "" { + hostname, err := os.Hostname() + if err == nil { + devboxName = hostname + } else { + devboxName = "unknown" + } + } + + // Print success message + if existingID != "" && existingID != devboxID { + fmt.Fprintf(out, "Successfully registered devbox (ID: %s, name: %s)\n", devboxID, devboxName) + fmt.Fprintf(out, "Previous devbox ID (%s) has been replaced.\n", existingID) } else { - fmt.Fprintln(out, "Registered devbox (name will be auto-generated)") + fmt.Fprintf(out, "Successfully registered devbox (ID: %s, name: %s)\n", devboxID, devboxName) } return nil } - -// TODO: Implement helper functions -// func getMachineID() string { ... } -// func saveDefaultDevbox(machine *models.Machine) error { ... } -// func loadDefaultDevbox() (*models.Machine, error) { ... } diff --git a/internal/command/local/connect.go b/internal/command/local/connect.go index fdd34814..4e751697 100644 --- a/internal/command/local/connect.go +++ b/internal/command/local/connect.go @@ -1,6 +1,7 @@ package local import ( + "context" "encoding/json" "fmt" "io" @@ -16,10 +17,12 @@ import ( "github.com/Masterminds/semver" "github.com/fatih/color" "github.com/signadot/cli/internal/config" + "github.com/signadot/cli/internal/devbox" sbmapi "github.com/signadot/cli/internal/locald/api/sandboxmanager" sbmgr "github.com/signadot/cli/internal/locald/sandboxmanager" "github.com/signadot/cli/internal/utils/system" clusters "github.com/signadot/go-sdk/client/cluster" + "github.com/signadot/go-sdk/client/devboxes" "github.com/signadot/libconnect/common/processes" connectcfg "github.com/signadot/libconnect/config" "github.com/spf13/cobra" @@ -50,6 +53,41 @@ func runConnect(cmd *cobra.Command, out io.Writer, cfg *config.LocalConnect, arg return fmt.Errorf("output format %s not supported for connect", cfg.OutputFormat) } + // get devbox claim and session + ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) + defer cancel() + + var devboxID string + if cfg.Devbox != "" { + // If devbox ID is provided, validate it exists + if err := devbox.ValidateDevboxID(ctx, cfg.API, cfg.Devbox); err != nil { + return err + } + devboxID = cfg.Devbox + } else { + // If no devbox ID provided, use the stored ID from file + var err error + devboxID, err = devbox.GetID(ctx, cfg.API, true, "") + if err != nil { + return err + } + } + + // Claim the session for the devbox + params := devboxes.NewClaimDevboxParams(). + WithContext(ctx). + WithOrgName(cfg.Org). + WithDevboxID(devboxID) + _, err := cfg.Client.Devboxes.ClaimDevbox(params) + if err != nil { + return fmt.Errorf("failed to claim devbox session: %w", err) + } + + devboxSessionID, err := devbox.GetSessionID(ctx, cfg.API, devboxID) + if err != nil { + return err + } + // we will pass the connConfig to rootmanager and sandboxmanager connConfig, err := cfg.GetConnectionConfig(cfg.Cluster) if err != nil { @@ -98,6 +136,8 @@ func runConnect(cmd *cobra.Command, out io.Writer, cfg *config.LocalConnect, arg APIKey: cfg.GetAPIKey(), Debug: cfg.LocalConfig.Debug, ConnectTimeout: cfg.WaitTimeout.String(), + DevboxID: devboxID, + DevboxSessionID: devboxSessionID, } if cfg.DumpCIConfig { d, _ := yaml.Marshal(ciConfig) diff --git a/internal/command/local/override/instrument.go b/internal/command/local/override/instrument.go index 2e24b743..77876490 100644 --- a/internal/command/local/override/instrument.go +++ b/internal/command/local/override/instrument.go @@ -8,6 +8,7 @@ import ( "github.com/signadot/cli/internal/builder" "github.com/signadot/cli/internal/config" + "github.com/signadot/cli/internal/devbox" "github.com/signadot/cli/internal/utils" "github.com/signadot/go-sdk/client/sandboxes" "github.com/signadot/go-sdk/models" @@ -20,7 +21,7 @@ func hasSandboxOverride(sb *models.Sandbox) bool { } func applyOverrideToSandbox(ctx context.Context, cfg *config.LocalOverrideCreate, - baseSandbox *models.Sandbox, workloadName string, logPort int, + baseSandbox *models.Sandbox, workloadName, devboxID string, logPort int, ) (*models.Sandbox, string, undoFunc, error) { // generate the override mw policy arg policyArg, err := builder.NewOverrideArgPolicy(cfg.ExcludedStatusCodes) @@ -37,11 +38,11 @@ func applyOverrideToSandbox(ctx context.Context, cfg *config.LocalOverrideCreate } } - // build the snadbox + // build the sandbox sbBuilder := builder. BuildSandbox(cfg.Sandbox, builder.WithData(*baseSandbox)). AddOverrideMiddleware(cfg.Port, cfg.To, []string{workloadName}, policyArg, log). - SetMachineID() + SetDevboxID(devboxID) sb, err := sbBuilder.Build() if err != nil { @@ -73,9 +74,13 @@ func applyOverrideToSandbox(ctx context.Context, cfg *config.LocalOverrideCreate func deleteOverrideFromSandbox(ctx context.Context, cfg *config.API, sandbox *models.Sandbox, overrideName string) error { // Use the sandbox builder to delete the override + devboxID, err := devbox.GetID(ctx, cfg, false, "") + if err != nil { + return err + } sbBuilder := builder. BuildSandbox(sandbox.Name, builder.WithData(*sandbox)). - SetMachineID(). + SetDevboxID(devboxID). DeleteOverrideMiddleware(overrideName) sb, err := sbBuilder.Build() diff --git a/internal/command/local/override/override.go b/internal/command/local/override/override.go index 4bcc0d1f..49b760ae 100644 --- a/internal/command/local/override/override.go +++ b/internal/command/local/override/override.go @@ -55,10 +55,13 @@ func runOverride(rootCtx context.Context, out, errOut io.Writer, // Make sure sandbox manager is running against the sandbox cluster // (signadot local connect has been executed) - _, err = sbmgr.ValidateSandboxManager(sb.Spec.Cluster) + stResp, err := sbmgr.ValidateSandboxManager(sb.Spec.Cluster) if err != nil { return err } + if stResp.DevboxSession == nil { + return errors.New("not connected with a devbox session (CLI locald version mismatch) please disconnect and reconnect") + } // Create the log server (if needed) var ( @@ -72,7 +75,8 @@ func runOverride(rootCtx context.Context, out, errOut io.Writer, // Apply the override to the sandbox printOverrideProgress(out, fmt.Sprintf("Applying override to %s", cfg.Sandbox)) - _, overrideName, undo, err := applyOverrideToSandbox(ctx, cfg, sb, cfg.Workload, logPort) + _, overrideName, undo, err := applyOverrideToSandbox(ctx, cfg, sb, cfg.Workload, + stResp.DevboxSession.DevboxId, logPort) if err != nil { return err } diff --git a/internal/command/local/printers.go b/internal/command/local/printers.go index 55edf7e6..fea547f4 100644 --- a/internal/command/local/printers.go +++ b/internal/command/local/printers.go @@ -37,6 +37,7 @@ func printRawStatus(cfg *config.LocalStatus, out io.Writer, printer func(out io. ControlPlaneProxy any `json:"controlPlaneProxy,omitempty"` SandboxesWatcher any `json:"sandboxesWatcher,omitempty"` Sandboxes any `json:"sandboxes,omitempty"` + DevboxSession any `json:"devboxSession,omitempty"` } rawSt := rawStatus{ @@ -48,6 +49,7 @@ func printRawStatus(cfg *config.LocalStatus, out io.Writer, printer func(out io. ControlPlaneProxy: getRawControlPlaneProxy(cfg, ciConfig, status.ControlPlaneProxy, statusMap), SandboxesWatcher: getRawWatcher(cfg, status.Watcher, statusMap), Sandboxes: statusMap["sandboxes"], + DevboxSession: getRawDevboxSession(cfg, status.DevboxSession, statusMap), } return printer(out, rawSt) @@ -325,6 +327,40 @@ func getRawWatcher(cfg *config.LocalStatus, watcher *commonapi.WatcherStatus, return result } +func getRawDevboxSession(cfg *config.LocalStatus, devboxSession *commonapi.DevboxSessionStatus, + statusMap map[string]any) any { + if devboxSession == nil { + return nil + } + + if cfg.Details { + // Details view - return full status from map + return statusMap["devboxSession"] + } + + // Standard view + type PrintableDevboxSession struct { + Healthy bool `json:"healthy"` + SessionReleased bool `json:"sessionReleased"` + DevboxId string `json:"devboxId,omitempty"` + SessionId string `json:"sessionId,omitempty"` + LastErrorReason string `json:"lastErrorReason,omitempty"` + } + + result := &PrintableDevboxSession{ + Healthy: devboxSession.Healthy, + SessionReleased: devboxSession.SessionReleased, + DevboxId: devboxSession.DevboxId, + SessionId: devboxSession.SessionId, + } + + if devboxSession.LastErrorReason != "" { + result.LastErrorReason = devboxSession.LastErrorReason + } + + return result +} + func printLocalStatus(cfg *config.LocalStatus, out io.Writer, status *sbmapi.StatusResponse) error { ciConfig, err := sbmapi.ToCIConfig(status.CiConfig) if err != nil { @@ -344,6 +380,12 @@ func printLocalStatus(cfg *config.LocalStatus, out io.Writer, status *sbmapi.Sta } // runtime config printer.printRuntimeConfig() + // Check devbox session status + if status.DevboxSession != nil && status.DevboxSession.SessionReleased { + printer.printErrors(append(connectErrs, fmt.Errorf("devbox session no longer available (released by another process)"))) + return nil + } + // print status if len(connectErrs) == 0 { printer.printSuccess() @@ -392,6 +434,7 @@ func (p *statusPrinter) printSuccess() { if p.status.OperatorInfo != nil { p.printOperatorInfo() } + p.printDevboxSessionStatus() switch p.ciConfig.ConnectionConfig.Type { case connectcfg.PortForwardLinkType: p.printPortforwardStatus() @@ -415,6 +458,37 @@ func (p *statusPrinter) printOperatorInfo() { p.printLine(p.out, 1, msg, "*") } +func (p *statusPrinter) printDevboxSessionStatus() { + if p.status.DevboxSession == nil { + return + } + + ds := p.status.DevboxSession + if ds.SessionReleased { + msg := "devbox session no longer available" + if ds.LastErrorReason != "" { + msg += fmt.Sprintf(": %s", ds.LastErrorReason) + } + p.printLine(p.out, 1, msg, p.red("✗")) + } else if ds.Healthy { + msg := fmt.Sprintf("devbox session active (devbox: %s, session: %s)", ds.DevboxId, ds.SessionId) + if p.cfg.Details && ds.SessionId != "" { + msg = fmt.Sprintf("devbox session active") + p.printLine(p.out, 1, msg, p.green("✓")) + p.printLine(p.out, 2, fmt.Sprintf("Devbox ID: %s", ds.DevboxId), "*") + p.printLine(p.out, 2, fmt.Sprintf("Session ID: %s", ds.SessionId), "*") + } else { + p.printLine(p.out, 1, msg, p.green("✓")) + } + } else { + msg := "devbox session unhealthy" + if ds.LastErrorReason != "" { + msg += fmt.Sprintf(": %s", ds.LastErrorReason) + } + p.printLine(p.out, 1, msg, p.red("✗")) + } +} + func (p *statusPrinter) printPortforwardStatus() { p.printLine(p.out, 1, fmt.Sprintf("port-forward listening at %q", p.status.Portforward.LocalAddress), "*") } diff --git a/internal/command/locald/locald.go b/internal/command/locald/locald.go index 1807a2ad..4a589b71 100644 --- a/internal/command/locald/locald.go +++ b/internal/command/locald/locald.go @@ -100,6 +100,7 @@ func run(cfg *config.LocalDaemon, args []string) error { if err := os.Chown(pidFile, ciConfig.User.UID, ciConfig.User.GID); err != nil { log.Warn("couldn't change ownership of pidfile", "error", err) } + // Clean up PID file on exit (normal shutdown, error, or panic) defer func() { os.Remove(pidFile) }() diff --git a/internal/command/sandbox/apply.go b/internal/command/sandbox/apply.go index e5dc6023..42736e9d 100644 --- a/internal/command/sandbox/apply.go +++ b/internal/command/sandbox/apply.go @@ -11,6 +11,7 @@ import ( "github.com/signadot/cli/internal/builder" "github.com/signadot/cli/internal/config" + "github.com/signadot/cli/internal/devbox" sbmapi "github.com/signadot/cli/internal/locald/api/sandboxmanager" sbmgr "github.com/signadot/cli/internal/locald/sandboxmanager" "github.com/signadot/cli/internal/print" @@ -65,10 +66,10 @@ func apply(cfg *config.SandboxApply, out, log io.Writer, args []string) error { return err } - // Set machine ID for local sandboxes + // Set devbox ID for local sandboxes sb, err := builder. BuildSandbox(req.Name, builder.WithData(*req)). - SetMachineID(). + SetDevboxID(status.DevboxSession.DevboxId). Build() if err != nil { return err @@ -92,11 +93,11 @@ func apply(cfg *config.SandboxApply, out, log io.Writer, args []string) error { req.Name, resp.RoutingKey, *req.Spec.Cluster) if len(req.Spec.Local) > 0 && status.OperatorInfo == nil { - // we are dealing with an old operator that doesn't support sandboxes - // watcher, go ahead and register the sandbox in sandboxmanager. - if err = sbmgr.RegisterSandbox(resp.Name, resp.RoutingKey); err != nil { - return fmt.Errorf("couldn't register sandbox in sandboxmanager, %v", err) + id, err := devbox.GetID(ctx, cfg.API, false, "" /* name set on connect */) + if err != nil { + return err } + _ = id } if cfg.Wait { diff --git a/internal/command/traffic/instrument.go b/internal/command/traffic/instrument.go index 4c52a90e..3f0ea598 100644 --- a/internal/command/traffic/instrument.go +++ b/internal/command/traffic/instrument.go @@ -2,6 +2,7 @@ package traffic import ( "context" + "errors" "fmt" "io" @@ -100,15 +101,16 @@ func applyWithLocal(ctx context.Context, cfg *config.TrafficWatch, hasLocal = true } if hasLocal { - _, err := sbmgr.ValidateSandboxManager(sb.Spec.Cluster) + connectStatus, err := sbmgr.ValidateSandboxManager(sb.Spec.Cluster) if err != nil { return err } - machineID, err := system.GetMachineID() - if err != nil { - return err + if connectStatus.DevboxSession == nil { + return errors.New("no devbox session") + } + sb.Spec.Connection = &models.Connection{ + DevboxID: connectStatus.DevboxSession.DevboxId, } - sb.Spec.LocalMachineID = machineID } // remove deprecated sb.Spec.Endpoints = nil diff --git a/internal/config/devbox.go b/internal/config/devbox.go index 49893aed..7cc7f138 100644 --- a/internal/config/devbox.go +++ b/internal/config/devbox.go @@ -1,8 +1,6 @@ package config import ( - "time" - "github.com/spf13/cobra" ) @@ -14,31 +12,36 @@ type Devbox struct { // DevboxList contains configuration for listing devboxes. type DevboxList struct { *Devbox + + // Flags + ShowAll bool +} + +// AddFlags adds flags for devbox list command. +func (c *DevboxList) AddFlags(cmd *cobra.Command) { + cmd.Flags().BoolVar(&c.ShowAll, "all", false, "list all devboxes") } // DevboxRegister contains configuration for registering a devbox. type DevboxRegister struct { *Devbox - Name string - Primary bool + Name string + Claim bool } // AddFlags adds flags for devbox register command. func (c *DevboxRegister) AddFlags(cmd *cobra.Command) { cmd.Flags().StringVar(&c.Name, "name", "", "name for the devbox (optional, will be generated if not provided)") - cmd.Flags().BoolVar(&c.Primary, "primary", true, "mark this devbox as primary") + cmd.Flags().BoolVar(&c.Claim, "claim", false, "claim connect session during registration") } // DevboxDelete contains configuration for deleting a devbox. type DevboxDelete struct { *Devbox - Name string - Wait bool - WaitTimeout time.Duration + ID string } // AddFlags adds flags for devbox delete command. func (c *DevboxDelete) AddFlags(cmd *cobra.Command) { - cmd.Flags().BoolVar(&c.Wait, "wait", true, "wait for devbox to be deleted") - cmd.Flags().DurationVar(&c.WaitTimeout, "wait-timeout", 5*time.Minute, "timeout to wait for deletion") + // No flags currently } diff --git a/internal/config/local.go b/internal/config/local.go index 5a239bf5..523abf55 100644 --- a/internal/config/local.go +++ b/internal/config/local.go @@ -109,7 +109,7 @@ type LocalConnect struct { func (c *LocalConnect) AddFlags(cmd *cobra.Command) { cmd.Flags().StringVar(&c.Cluster, "cluster", "", "specify cluster connection config") - cmd.Flags().StringVar(&c.Devbox, "devbox", "", "specify devbox name to use for this connection") + cmd.Flags().StringVar(&c.Devbox, "devbox", "", "specify devbox ID to use for this connection") cmd.Flags().BoolVar(&c.Unprivileged, "unprivileged", false, "run without root privileges") cmd.Flags().Var(&c.Wait, "wait", "status to wait for while connecting {none,connect,sandboxes}") diff --git a/internal/config/locald.go b/internal/config/locald.go index a4bb8a64..6f50b2fb 100644 --- a/internal/config/locald.go +++ b/internal/config/locald.go @@ -37,7 +37,6 @@ func (ld *LocalDaemon) InitLocalDaemon() error { ciBytes []byte err error ) - if ld.ConnectInvocationConfigFile != "" { ciBytes, err = os.ReadFile(ld.ConnectInvocationConfigFile) if err != nil { @@ -79,6 +78,8 @@ type ConnectInvocationConfig struct { APIKey string `json:"apiKey"` Debug bool `json:"debug"` ConnectTimeout string `json:"connectTimeout"` + DevboxID string `json:"devboxID"` + DevboxSessionID string `json:"devboxSessionID"` } type ConnectInvocationUser struct { diff --git a/internal/devbox/get_id.go b/internal/devbox/get_id.go new file mode 100644 index 00000000..8770e40a --- /dev/null +++ b/internal/devbox/get_id.go @@ -0,0 +1,183 @@ +package devbox + +import ( + "context" + "fmt" + "net/http" + "os" + "path/filepath" + "runtime" + + "github.com/signadot/cli/internal/config" + "github.com/signadot/cli/internal/utils/system" + "github.com/signadot/go-sdk/client/devboxes" + "github.com/signadot/go-sdk/models" +) + +// ValidateDevboxID validates that a devbox ID exists and returns an error if it doesn't. +func ValidateDevboxID(ctx context.Context, apiConfig *config.API, devboxID string) error { + params := devboxes.NewGetDevboxParams(). + WithContext(ctx). + WithOrgName(apiConfig.Org). + WithDevboxID(devboxID) + + resp, err := apiConfig.Client.Devboxes.GetDevbox(params) + if err != nil { + return fmt.Errorf("failed to validate devbox ID: %w", err) + } + if resp.Code() != http.StatusOK { + return fmt.Errorf("devbox ID %q not found: status %d %s", devboxID, resp.Code(), http.StatusText(resp.Code())) + } + return nil +} + +// GetSessionID tries to get the session id of devbox indicated by devboxID. Upon success err is nil and +// if the devbox is connected, a non-empty string id is returned. If the devbox is not connected, the +// empty string is returned. +func GetSessionID(ctx context.Context, apiConfig *config.API, devboxID string) (id string, err error) { + params := devboxes.NewGetDevboxParams(). + WithContext(ctx). + WithOrgName(apiConfig.Org). + WithDevboxID(devboxID) + + resp, err := apiConfig.Client.Devboxes.GetDevbox(params) + if err != nil { + return "", err + } + switch resp.Code() { + case http.StatusOK: + session := resp.Payload.Status.Session + if session == nil { + return "", nil + } + return session.ID, nil + default: + return "", fmt.Errorf("error fetching devbox: status %d %s", resp.Code(), http.StatusText(resp.Code())) + } +} + +func GetID(ctx context.Context, apiConfig *config.API, claim bool, name string) (string, error) { + file, err := IDFile() + if err != nil { + return "", err + } + d, err := os.ReadFile(file) + id := string(d) + if err != nil { + if os.IsNotExist(err) { + id, err := getIDByAPI(ctx, apiConfig, claim, name) + if err != nil { + return "", err + } + if err := os.WriteFile(file, []byte(id), 0600); err != nil { + return "", err + } + return id, nil + } + return "", err + } + if name != "" { + // get devbox, check name equals input. if not, + // call getIDByAPI with the new name to get the updated id + // which will fall through to the claim code below + params := devboxes.NewGetDevboxParams(). + WithContext(ctx). + WithOrgName(apiConfig.Org). + WithDevboxID(id) + + resp, err := apiConfig.Client.Devboxes.GetDevbox(params) + if err != nil { + return "", err + } + if resp.Code() == http.StatusOK && resp.Payload != nil { + devboxName := "" + if resp.Payload.Metadata != nil { + devboxName = resp.Payload.Metadata["name"] + } + if devboxName != name { + // Name doesn't match, get new ID with the updated name + newID, err := getIDByAPI(ctx, apiConfig, claim, name) + if err != nil { + return "", err + } + return newID, nil + } + } else { + return "", fmt.Errorf("unable to get devbox: status %d %s", resp.Code(), http.StatusText(resp.Code())) + } + } + if !claim { + return id, nil + } + params := devboxes.NewClaimDevboxParams(). + WithContext(ctx). + WithOrgName(apiConfig.Org). + WithDevboxID(id) + + _, err = apiConfig.Client.Devboxes.ClaimDevbox(params) + if err != nil { + return "", err + } + return id, nil +} + +func IDFile() (string, error) { + sdir, err := system.GetSignadotDir() + if err != nil { + return "", err + } + return filepath.Join(sdir, ".devbox-id"), nil +} + +// RegisterDevbox registers a devbox with the API and returns the devbox ID. +// If name is empty, it will use the hostname. If claim is true, it will also claim a session. +func RegisterDevbox(ctx context.Context, cfg *config.API, claim bool, name string) (string, error) { + return getIDByAPI(ctx, cfg, claim, name) +} + +func getIDByAPI(ctx context.Context, cfg *config.API, claim bool, name string) (string, error) { + meta, err := getDevboxMeta(name) + if err != nil { + return "", err + } + req := &models.DevboxRegistration{ + Metadata: meta, + Claim: claim, + } + params := devboxes.NewRegisterDevboxParams(). + WithContext(ctx). + WithOrgName(cfg.Org). + WithData(req) + regOK, regCreated, err := cfg.Client.Devboxes.RegisterDevbox(params) + if err != nil { + return "", err + } + var reg *models.Devbox + if regOK != nil { + reg = regOK.Payload + } else if regCreated != nil { + reg = regCreated.Payload + } + return reg.ID, nil +} + +func getDevboxMeta(name string) (map[string]string, error) { + host, err := os.Hostname() + if err != nil { + return nil, err + } + if name == "" { + name = host + } + mid, err := system.GetMachineID() + if err != nil { + return nil, err + } + return map[string]string{ + "name": name, + "machine-id": mid, + "goos": runtime.GOOS, + "goarch": runtime.GOARCH, + "host": host, + }, nil +} diff --git a/internal/devbox/session_manager.go b/internal/devbox/session_manager.go new file mode 100644 index 00000000..c93642cf --- /dev/null +++ b/internal/devbox/session_manager.go @@ -0,0 +1,452 @@ +package devbox + +import ( + "context" + "fmt" + "net/http" + "strings" + "sync" + "time" + + "log/slog" + + "github.com/signadot/cli/internal/auth" + "github.com/signadot/cli/internal/buildinfo" + "github.com/signadot/cli/internal/config" + "github.com/signadot/go-sdk/client" + sdkauth "github.com/signadot/go-sdk/client/auth" + "github.com/signadot/go-sdk/client/devboxes" + "github.com/signadot/go-sdk/transport" + "github.com/spf13/viper" +) + +const ( + // RenewalInterval is how often to renew the devbox session + RenewalInterval = 1 * time.Minute + // RenewalJitter adds randomness to avoid thundering herd + RenewalJitter = 30 * time.Second +) + +type SessionManager struct { + log *slog.Logger + ciConfig *config.ConnectInvocationConfig + apiClient *client.SignadotAPI + renewalTicker *time.Ticker + doneCh chan struct{} + shutdownCh chan struct{} + sessionReleased bool + lastError error + lastErrorTime time.Time + mu sync.RWMutex +} + +func NewSessionManager(log *slog.Logger, ciConfig *config.ConnectInvocationConfig, shutdownCh chan struct{}) (*SessionManager, error) { + if ciConfig.DevboxID == "" || ciConfig.DevboxSessionID == "" { + return nil, fmt.Errorf("incomplete or absent devbox session info") + } + + // Resolve auth dynamically + authInfo, err := auth.ResolveAuth() + if err != nil { + return nil, fmt.Errorf("failed to resolve auth: %w", err) + } + if authInfo == nil { + return nil, fmt.Errorf("no auth found") + } + + // Create API client with dynamic auth resolution + apiClient, err := createAPIClient(ciConfig, authInfo) + if err != nil { + return nil, fmt.Errorf("failed to create API client: %w", err) + } + + dsm := &SessionManager{ + log: log.With("component", "devbox-session-manager"), + ciConfig: ciConfig, + apiClient: apiClient, + doneCh: make(chan struct{}), + shutdownCh: shutdownCh, + } + + return dsm, nil +} + +func createAPIClient(ciConfig *config.ConnectInvocationConfig, authInfo *auth.ResolvedAuth) (*client.SignadotAPI, error) { + // Check if bearer token is expired and refresh if needed + if authInfo != nil && authInfo.BearerToken != "" && authInfo.APIKey == "" { + if authInfo.ExpiresAt != nil && time.Now().After(*authInfo.ExpiresAt) { + if authInfo.RefreshToken != "" { + // Refresh the token + refreshedAuth, err := refreshBearerToken(authInfo) + if err != nil { + return nil, fmt.Errorf("failed to refresh bearer token: %w", err) + } + authInfo = refreshedAuth + } else { + return nil, fmt.Errorf("bearer token expired and no refresh token available") + } + } + } + + // Get API URL from viper (similar to config.API.basicInit) + apiURL := "https://api.signadot.com" + if apiURLFromViper := viper.GetString("api_url"); apiURLFromViper != "" { + apiURL = apiURLFromViper + } + + // Create transport config + cfg := &transport.APIConfig{ + APIURL: apiURL, + UserAgent: fmt.Sprintf("signadot-cli:%s", buildinfo.Version), + Debug: false, + } + + // Set auth - prefer resolved auth, but fall back to CI config API key if available + // (similar to how control plane proxy handles it) + if authInfo != nil && authInfo.APIKey != "" { + cfg.APIKey = authInfo.APIKey + } else if authInfo != nil && authInfo.BearerToken != "" { + cfg.BearerToken = authInfo.BearerToken + } else if ciConfig.APIKey != "" { + // Fall back to API key from CI config + cfg.APIKey = ciConfig.APIKey + } else { + return nil, fmt.Errorf("no API key or bearer token found") + } + + // Initialize transport + t, err := transport.InitAPITransport(cfg) + if err != nil { + return nil, fmt.Errorf("failed to init API transport: %w", err) + } + + // Create client + return client.New(t, nil), nil +} + +// refreshBearerToken refreshes an expired bearer token using the refresh token +func refreshBearerToken(authInfo *auth.ResolvedAuth) (*auth.ResolvedAuth, error) { + // Create an unauthenticated API client for the refresh call + apiURL := "https://api.signadot.com" + if apiURLFromViper := viper.GetString("api_url"); apiURLFromViper != "" { + apiURL = apiURLFromViper + } + + cfg := &transport.APIConfig{ + APIURL: apiURL, + UserAgent: fmt.Sprintf("signadot-cli:%s", buildinfo.Version), + Debug: false, + } + + t, err := transport.InitAPITransport(cfg) + if err != nil { + return nil, fmt.Errorf("failed to init unauthenticated API transport: %w", err) + } + + unauthClient := client.New(t, nil) + + // Call the refresh endpoint + params := &sdkauth.AuthDeviceRefreshTokenParams{ + Data: authInfo.RefreshToken, + } + + resp, err := unauthClient.Auth.AuthDeviceRefreshToken(params) + if err != nil { + return nil, fmt.Errorf("failed to refresh token: %w", err) + } + + expiresAt := time.Now().Add(time.Duration(resp.Payload.ExpiresIn) * time.Second) + + // Update auth info with new tokens + newAuthInfo := &auth.ResolvedAuth{ + Source: authInfo.Source, + Auth: auth.Auth{ + APIKey: authInfo.APIKey, + BearerToken: resp.Payload.AccessToken, + RefreshToken: resp.Payload.RefreshToken, + OrgName: authInfo.OrgName, + ExpiresAt: &expiresAt, + }, + } + + // Save the refreshed token back to storage + if err := saveRefreshedAuth(newAuthInfo); err != nil { + // Log but don't fail - we can still use the refreshed token for this request + // The next ResolveAuth() call will get the old token, but it will be refreshed again + } + + return newAuthInfo, nil +} + +// saveRefreshedAuth saves the refreshed auth back to the storage (keyring or plaintext) +func saveRefreshedAuth(authInfo *auth.ResolvedAuth) error { + switch authInfo.Source { + case auth.KeyringAuthSource: + keyringStorage := auth.NewKeyringStorage() + return keyringStorage.Store(&authInfo.Auth) + case auth.PlainTextAuthSource: + plainTextStorage := auth.NewPlainTextStorage() + return plainTextStorage.Store(&authInfo.Auth) + default: + // Config source doesn't need saving (it's in viper) + return nil + } +} + +func (dsm *SessionManager) Start(ctx context.Context) { + dsm.log.Info("Starting devbox session manager", + "devboxID", dsm.ciConfig.DevboxID, + "sessionID", dsm.ciConfig.DevboxSessionID) + + // Do initial renewal + go dsm.renewLoop(ctx) + + // Set up periodic renewal + interval := RenewalInterval + time.Duration(time.Now().UnixNano()%int64(RenewalJitter)) + dsm.renewalTicker = time.NewTicker(interval) + defer dsm.renewalTicker.Stop() + + go func() { + for { + select { + case <-dsm.doneCh: + return + case <-dsm.renewalTicker.C: + dsm.renewSession(ctx) + } + } + }() +} + +func (dsm *SessionManager) renewLoop(ctx context.Context) { + // Initial renewal + dsm.renewSession(ctx) + + // Periodic renewals + for { + select { + case <-dsm.doneCh: + return + case <-time.After(RenewalInterval): + dsm.renewSession(ctx) + } + } +} + +func (dsm *SessionManager) renewSession(ctx context.Context) { + // Resolve auth dynamically to get org + authInfo, err := auth.ResolveAuth() + if err != nil { + dsm.log.Error("Failed to resolve auth for renewal", "error", err) + return + } + if authInfo == nil || authInfo.OrgName == "" { + dsm.log.Error("No org found in auth") + return + } + + // Recreate API client if needed (in case auth changed or token expired) + apiClient, err := createAPIClient(dsm.ciConfig, authInfo) + if err != nil { + dsm.log.Error("Failed to recreate API client", "error", err) + return + } + dsm.apiClient = apiClient + + params := devboxes.NewRenewDevboxParams(). + WithContext(ctx). + WithOrgName(authInfo.OrgName). + WithDevboxID(dsm.ciConfig.DevboxID) + + resp, err := dsm.apiClient.Devboxes.RenewDevbox(params) + if err != nil { + // Check if the error indicates the session was released by another process + if dsm.isSessionReleasedError(err) { + dsm.log.Warn("Devbox session was released by another process", + "devboxID", dsm.ciConfig.DevboxID, + "sessionID", dsm.ciConfig.DevboxSessionID) + dsm.setSessionReleased(err) + dsm.triggerShutdown() + return + } + dsm.log.Error("Failed to renew devbox session", "error", err) + dsm.setError(err) + return + } + + // Check response status code - 404 or similar might indicate session was released + if resp.Code() == http.StatusNotFound { + err := fmt.Errorf("devbox session not found (status %d)", resp.Code()) + dsm.log.Warn("Devbox session not found (likely released by another process)", + "devboxID", dsm.ciConfig.DevboxID, + "sessionID", dsm.ciConfig.DevboxSessionID) + dsm.setSessionReleased(err) + dsm.triggerShutdown() + return + } + + // Also verify the session ID matches by checking the devbox status + if !dsm.verifySessionStillActive(ctx, authInfo.OrgName) { + err := fmt.Errorf("devbox session ID mismatch") + dsm.log.Warn("Devbox session ID mismatch (likely released by another process)", + "devboxID", dsm.ciConfig.DevboxID, + "sessionID", dsm.ciConfig.DevboxSessionID) + dsm.setSessionReleased(err) + dsm.triggerShutdown() + return + } + + dsm.log.Debug("Renewed devbox session", + "devboxID", dsm.ciConfig.DevboxID, + "sessionID", dsm.ciConfig.DevboxSessionID, + "statusCode", resp.Code()) +} + +func (dsm *SessionManager) releaseSession() { + dsm.log.Info("Releasing devbox session", + "devboxID", dsm.ciConfig.DevboxID, + "sessionID", dsm.ciConfig.DevboxSessionID) + + // Use a background context with timeout for release to ensure it completes + // even if the original context is cancelled + releaseCtx, cancel := context.WithTimeout(context.Background(), 10*time.Second) + defer cancel() + + // Resolve auth dynamically to get org + authInfo, err := auth.ResolveAuth() + if err != nil { + dsm.log.Error("Failed to resolve auth for release", "error", err) + return + } + if authInfo == nil || authInfo.OrgName == "" { + dsm.log.Error("No org found in auth") + return + } + + // Recreate API client if needed (in case auth changed or token expired) + apiClient, err := createAPIClient(dsm.ciConfig, authInfo) + if err != nil { + dsm.log.Error("Failed to recreate API client for release", "error", err) + return + } + + params := devboxes.NewReleaseDevboxParams(). + WithContext(releaseCtx). + WithOrgName(authInfo.OrgName). + WithDevboxID(dsm.ciConfig.DevboxID) + + resp, err := apiClient.Devboxes.ReleaseDevbox(params) + if err != nil { + dsm.log.Error("Failed to release devbox session", "error", err) + return + } + + dsm.log.Info("Released devbox session", + "devboxID", dsm.ciConfig.DevboxID, + "sessionID", dsm.ciConfig.DevboxSessionID, + "statusCode", resp.Code()) +} + +func (dsm *SessionManager) Stop(ctx context.Context) { + select { + case <-dsm.doneCh: + default: + close(dsm.doneCh) + } + + dsm.renewalTicker.Stop() + + // Release session on shutdown + dsm.releaseSession() +} + +// isSessionReleasedError checks if an error indicates the session was released +func (dsm *SessionManager) isSessionReleasedError(err error) bool { + if err == nil { + return false + } + errStr := err.Error() + // Check for common error patterns that indicate session was released + return strings.Contains(errStr, "404") || + strings.Contains(errStr, "not found") || + strings.Contains(errStr, "session") && strings.Contains(errStr, "released") +} + +// verifySessionStillActive checks if the current session ID still matches the devbox's active session +func (dsm *SessionManager) verifySessionStillActive(ctx context.Context, orgName string) bool { + params := devboxes.NewGetDevboxParams(). + WithContext(ctx). + WithOrgName(orgName). + WithDevboxID(dsm.ciConfig.DevboxID) + + resp, err := dsm.apiClient.Devboxes.GetDevbox(params) + if err != nil { + // If we can't check, assume it's still active to avoid false positives + dsm.log.Debug("Failed to verify session status, assuming still active", "error", err) + return true + } + + if resp.Code() != http.StatusOK { + // If we can't get the devbox, assume it's still active + return true + } + + session := resp.Payload.Status.Session + if session == nil { + // No active session means it was released + return false + } + + // Session ID mismatch means another process claimed/released it + return session.ID == dsm.ciConfig.DevboxSessionID +} + +// setSessionReleased marks the session as released +func (dsm *SessionManager) setSessionReleased(err error) { + dsm.mu.Lock() + defer dsm.mu.Unlock() + dsm.sessionReleased = true + dsm.lastError = err + dsm.lastErrorTime = time.Now() +} + +// setError records an error without marking session as released +func (dsm *SessionManager) setError(err error) { + dsm.mu.Lock() + defer dsm.mu.Unlock() + dsm.lastError = err + dsm.lastErrorTime = time.Now() +} + +// WasSessionReleased returns whether the session was released +func (dsm *SessionManager) WasSessionReleased() bool { + dsm.mu.RLock() + defer dsm.mu.RUnlock() + return dsm.sessionReleased +} + +// GetStatus returns the current session status +func (dsm *SessionManager) GetStatus() (healthy bool, sessionReleased bool, devboxID string, sessionID string, lastError error, lastErrorTime time.Time) { + dsm.mu.RLock() + defer dsm.mu.RUnlock() + + if dsm.ciConfig == nil { + return false, false, "", "", nil, time.Time{} + } + + healthy = !dsm.sessionReleased && dsm.lastError == nil + return healthy, dsm.sessionReleased, dsm.ciConfig.DevboxID, dsm.ciConfig.DevboxSessionID, dsm.lastError, dsm.lastErrorTime +} + +// triggerShutdown closes the shutdown channel to trigger sandbox manager shutdown +func (dsm *SessionManager) triggerShutdown() { + if dsm.shutdownCh == nil { + return + } + select { + case <-dsm.shutdownCh: + // Already closed + default: + close(dsm.shutdownCh) + } +} diff --git a/internal/locald/api/common.pb.go b/internal/locald/api/common.pb.go index 4e59bd86..9d58effb 100644 --- a/internal/locald/api/common.pb.go +++ b/internal/locald/api/common.pb.go @@ -1,7 +1,7 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.36.6 -// protoc v3.21.12 +// protoc-gen-go v1.26.0 +// protoc v6.33.0 // source: internal/locald/api/common.proto package api @@ -12,7 +12,6 @@ import ( timestamppb "google.golang.org/protobuf/types/known/timestamppb" reflect "reflect" sync "sync" - unsafe "unsafe" ) const ( @@ -24,20 +23,23 @@ const ( // Service health type ServiceHealth struct { - state protoimpl.MessageState `protogen:"open.v1"` + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + Healthy bool `protobuf:"varint,1,opt,name=healthy,proto3" json:"healthy,omitempty"` ErrorCount uint32 `protobuf:"varint,2,opt,name=error_count,json=errorCount,proto3" json:"error_count,omitempty"` LastErrorReason string `protobuf:"bytes,3,opt,name=last_error_reason,json=lastErrorReason,proto3" json:"last_error_reason,omitempty"` LastErrorTime *timestamppb.Timestamp `protobuf:"bytes,4,opt,name=last_error_time,json=lastErrorTime,proto3" json:"last_error_time,omitempty"` - unknownFields protoimpl.UnknownFields - sizeCache protoimpl.SizeCache } func (x *ServiceHealth) Reset() { *x = ServiceHealth{} - mi := &file_internal_locald_api_common_proto_msgTypes[0] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) + if protoimpl.UnsafeEnabled { + mi := &file_internal_locald_api_common_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } func (x *ServiceHealth) String() string { @@ -48,7 +50,7 @@ func (*ServiceHealth) ProtoMessage() {} func (x *ServiceHealth) ProtoReflect() protoreflect.Message { mi := &file_internal_locald_api_common_proto_msgTypes[0] - if x != nil { + if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -93,19 +95,22 @@ func (x *ServiceHealth) GetLastErrorTime() *timestamppb.Timestamp { // LocalNet status (produced by root controller) type LocalNetStatus struct { - state protoimpl.MessageState `protogen:"open.v1"` - Health *ServiceHealth `protobuf:"bytes,1,opt,name=health,proto3" json:"health,omitempty"` - Cidrs []string `protobuf:"bytes,2,rep,name=cidrs,proto3" json:"cidrs,omitempty"` - ExcludedCidrs []string `protobuf:"bytes,3,rep,name=excluded_cidrs,json=excludedCidrs,proto3" json:"excluded_cidrs,omitempty"` - unknownFields protoimpl.UnknownFields + state protoimpl.MessageState sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Health *ServiceHealth `protobuf:"bytes,1,opt,name=health,proto3" json:"health,omitempty"` + Cidrs []string `protobuf:"bytes,2,rep,name=cidrs,proto3" json:"cidrs,omitempty"` + ExcludedCidrs []string `protobuf:"bytes,3,rep,name=excluded_cidrs,json=excludedCidrs,proto3" json:"excluded_cidrs,omitempty"` } func (x *LocalNetStatus) Reset() { *x = LocalNetStatus{} - mi := &file_internal_locald_api_common_proto_msgTypes[1] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) + if protoimpl.UnsafeEnabled { + mi := &file_internal_locald_api_common_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } func (x *LocalNetStatus) String() string { @@ -116,7 +121,7 @@ func (*LocalNetStatus) ProtoMessage() {} func (x *LocalNetStatus) ProtoReflect() protoreflect.Message { mi := &file_internal_locald_api_common_proto_msgTypes[1] - if x != nil { + if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -154,20 +159,23 @@ func (x *LocalNetStatus) GetExcludedCidrs() []string { // Hosts status (produced by root controller) type HostsStatus struct { - state protoimpl.MessageState `protogen:"open.v1"` + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + Health *ServiceHealth `protobuf:"bytes,1,opt,name=health,proto3" json:"health,omitempty"` NumHosts uint32 `protobuf:"varint,2,opt,name=num_hosts,json=numHosts,proto3" json:"num_hosts,omitempty"` NumUpdates uint32 `protobuf:"varint,3,opt,name=num_updates,json=numUpdates,proto3" json:"num_updates,omitempty"` LastUpdateTime *timestamppb.Timestamp `protobuf:"bytes,4,opt,name=last_update_time,json=lastUpdateTime,proto3" json:"last_update_time,omitempty"` - unknownFields protoimpl.UnknownFields - sizeCache protoimpl.SizeCache } func (x *HostsStatus) Reset() { *x = HostsStatus{} - mi := &file_internal_locald_api_common_proto_msgTypes[2] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) + if protoimpl.UnsafeEnabled { + mi := &file_internal_locald_api_common_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } func (x *HostsStatus) String() string { @@ -178,7 +186,7 @@ func (*HostsStatus) ProtoMessage() {} func (x *HostsStatus) ProtoReflect() protoreflect.Message { mi := &file_internal_locald_api_common_proto_msgTypes[2] - if x != nil { + if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -223,18 +231,21 @@ func (x *HostsStatus) GetLastUpdateTime() *timestamppb.Timestamp { // PortForward status (produced by local controller) type PortForwardStatus struct { - state protoimpl.MessageState `protogen:"open.v1"` - Health *ServiceHealth `protobuf:"bytes,1,opt,name=health,proto3" json:"health,omitempty"` - LocalAddress string `protobuf:"bytes,2,opt,name=local_address,json=localAddress,proto3" json:"local_address,omitempty"` - unknownFields protoimpl.UnknownFields + state protoimpl.MessageState sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Health *ServiceHealth `protobuf:"bytes,1,opt,name=health,proto3" json:"health,omitempty"` + LocalAddress string `protobuf:"bytes,2,opt,name=local_address,json=localAddress,proto3" json:"local_address,omitempty"` } func (x *PortForwardStatus) Reset() { *x = PortForwardStatus{} - mi := &file_internal_locald_api_common_proto_msgTypes[3] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) + if protoimpl.UnsafeEnabled { + mi := &file_internal_locald_api_common_proto_msgTypes[3] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } func (x *PortForwardStatus) String() string { @@ -245,7 +256,7 @@ func (*PortForwardStatus) ProtoMessage() {} func (x *PortForwardStatus) ProtoReflect() protoreflect.Message { mi := &file_internal_locald_api_common_proto_msgTypes[3] - if x != nil { + if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -276,18 +287,21 @@ func (x *PortForwardStatus) GetLocalAddress() string { // ControlPlaneProxy status (produced by local controller) type ControlPlaneProxyStatus struct { - state protoimpl.MessageState `protogen:"open.v1"` - Health *ServiceHealth `protobuf:"bytes,1,opt,name=health,proto3" json:"health,omitempty"` - LocalAddress string `protobuf:"bytes,2,opt,name=local_address,json=localAddress,proto3" json:"local_address,omitempty"` - unknownFields protoimpl.UnknownFields + state protoimpl.MessageState sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Health *ServiceHealth `protobuf:"bytes,1,opt,name=health,proto3" json:"health,omitempty"` + LocalAddress string `protobuf:"bytes,2,opt,name=local_address,json=localAddress,proto3" json:"local_address,omitempty"` } func (x *ControlPlaneProxyStatus) Reset() { *x = ControlPlaneProxyStatus{} - mi := &file_internal_locald_api_common_proto_msgTypes[4] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) + if protoimpl.UnsafeEnabled { + mi := &file_internal_locald_api_common_proto_msgTypes[4] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } func (x *ControlPlaneProxyStatus) String() string { @@ -298,7 +312,7 @@ func (*ControlPlaneProxyStatus) ProtoMessage() {} func (x *ControlPlaneProxyStatus) ProtoReflect() protoreflect.Message { mi := &file_internal_locald_api_common_proto_msgTypes[4] - if x != nil { + if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -329,17 +343,20 @@ func (x *ControlPlaneProxyStatus) GetLocalAddress() string { // Sandboxes watcher status (produced by local controller) type WatcherStatus struct { - state protoimpl.MessageState `protogen:"open.v1"` - Health *ServiceHealth `protobuf:"bytes,1,opt,name=health,proto3" json:"health,omitempty"` - unknownFields protoimpl.UnknownFields + state protoimpl.MessageState sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Health *ServiceHealth `protobuf:"bytes,1,opt,name=health,proto3" json:"health,omitempty"` } func (x *WatcherStatus) Reset() { *x = WatcherStatus{} - mi := &file_internal_locald_api_common_proto_msgTypes[5] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) + if protoimpl.UnsafeEnabled { + mi := &file_internal_locald_api_common_proto_msgTypes[5] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } func (x *WatcherStatus) String() string { @@ -350,7 +367,7 @@ func (*WatcherStatus) ProtoMessage() {} func (x *WatcherStatus) ProtoReflect() protoreflect.Message { mi := &file_internal_locald_api_common_proto_msgTypes[5] - if x != nil { + if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -374,19 +391,22 @@ func (x *WatcherStatus) GetHealth() *ServiceHealth { // Sandbox status (produced by local controller) type SandboxStatus struct { - state protoimpl.MessageState `protogen:"open.v1"` + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` RoutingKey string `protobuf:"bytes,2,opt,name=routing_key,json=routingKey,proto3" json:"routing_key,omitempty"` LocalWorkloads []*SandboxStatus_LocalWorkload `protobuf:"bytes,3,rep,name=local_workloads,json=localWorkloads,proto3" json:"local_workloads,omitempty"` - unknownFields protoimpl.UnknownFields - sizeCache protoimpl.SizeCache } func (x *SandboxStatus) Reset() { *x = SandboxStatus{} - mi := &file_internal_locald_api_common_proto_msgTypes[6] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) + if protoimpl.UnsafeEnabled { + mi := &file_internal_locald_api_common_proto_msgTypes[6] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } func (x *SandboxStatus) String() string { @@ -397,7 +417,7 @@ func (*SandboxStatus) ProtoMessage() {} func (x *SandboxStatus) ProtoReflect() protoreflect.Message { mi := &file_internal_locald_api_common_proto_msgTypes[6] - if x != nil { + if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -434,19 +454,22 @@ func (x *SandboxStatus) GetLocalWorkloads() []*SandboxStatus_LocalWorkload { } type OperatorInfo struct { - state protoimpl.MessageState `protogen:"open.v1"` - Version string `protobuf:"bytes,1,opt,name=version,proto3" json:"version,omitempty"` - GitCommit string `protobuf:"bytes,2,opt,name=git_commit,json=gitCommit,proto3" json:"git_commit,omitempty"` - BuildDate string `protobuf:"bytes,3,opt,name=build_date,json=buildDate,proto3" json:"build_date,omitempty"` - unknownFields protoimpl.UnknownFields + state protoimpl.MessageState sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Version string `protobuf:"bytes,1,opt,name=version,proto3" json:"version,omitempty"` + GitCommit string `protobuf:"bytes,2,opt,name=git_commit,json=gitCommit,proto3" json:"git_commit,omitempty"` + BuildDate string `protobuf:"bytes,3,opt,name=build_date,json=buildDate,proto3" json:"build_date,omitempty"` } func (x *OperatorInfo) Reset() { *x = OperatorInfo{} - mi := &file_internal_locald_api_common_proto_msgTypes[7] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) + if protoimpl.UnsafeEnabled { + mi := &file_internal_locald_api_common_proto_msgTypes[7] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } func (x *OperatorInfo) String() string { @@ -457,7 +480,7 @@ func (*OperatorInfo) ProtoMessage() {} func (x *OperatorInfo) ProtoReflect() protoreflect.Message { mi := &file_internal_locald_api_common_proto_msgTypes[7] - if x != nil { + if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -493,21 +516,118 @@ func (x *OperatorInfo) GetBuildDate() string { return "" } -type SandboxStatus_Baseline struct { - state protoimpl.MessageState `protogen:"open.v1"` - ApiVersion string `protobuf:"bytes,1,opt,name=apiVersion,proto3" json:"apiVersion,omitempty"` - Kind string `protobuf:"bytes,2,opt,name=kind,proto3" json:"kind,omitempty"` - Namespace string `protobuf:"bytes,3,opt,name=namespace,proto3" json:"namespace,omitempty"` - Name string `protobuf:"bytes,4,opt,name=name,proto3" json:"name,omitempty"` +// Devbox session status (produced by local controller) +type DevboxSessionStatus struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields + + // Whether the devbox session is active and healthy + Healthy bool `protobuf:"varint,1,opt,name=healthy,proto3" json:"healthy,omitempty"` + // Whether the session was released by another process + SessionReleased bool `protobuf:"varint,2,opt,name=session_released,json=sessionReleased,proto3" json:"session_released,omitempty"` + // Devbox ID + DevboxId string `protobuf:"bytes,3,opt,name=devbox_id,json=devboxId,proto3" json:"devbox_id,omitempty"` + // Session ID + SessionId string `protobuf:"bytes,4,opt,name=session_id,json=sessionId,proto3" json:"session_id,omitempty"` + // Last error reason if unhealthy + LastErrorReason string `protobuf:"bytes,5,opt,name=last_error_reason,json=lastErrorReason,proto3" json:"last_error_reason,omitempty"` + // Last error time if unhealthy + LastErrorTime *timestamppb.Timestamp `protobuf:"bytes,6,opt,name=last_error_time,json=lastErrorTime,proto3" json:"last_error_time,omitempty"` +} + +func (x *DevboxSessionStatus) Reset() { + *x = DevboxSessionStatus{} + if protoimpl.UnsafeEnabled { + mi := &file_internal_locald_api_common_proto_msgTypes[8] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *DevboxSessionStatus) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*DevboxSessionStatus) ProtoMessage() {} + +func (x *DevboxSessionStatus) ProtoReflect() protoreflect.Message { + mi := &file_internal_locald_api_common_proto_msgTypes[8] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use DevboxSessionStatus.ProtoReflect.Descriptor instead. +func (*DevboxSessionStatus) Descriptor() ([]byte, []int) { + return file_internal_locald_api_common_proto_rawDescGZIP(), []int{8} +} + +func (x *DevboxSessionStatus) GetHealthy() bool { + if x != nil { + return x.Healthy + } + return false +} + +func (x *DevboxSessionStatus) GetSessionReleased() bool { + if x != nil { + return x.SessionReleased + } + return false +} + +func (x *DevboxSessionStatus) GetDevboxId() string { + if x != nil { + return x.DevboxId + } + return "" +} + +func (x *DevboxSessionStatus) GetSessionId() string { + if x != nil { + return x.SessionId + } + return "" +} + +func (x *DevboxSessionStatus) GetLastErrorReason() string { + if x != nil { + return x.LastErrorReason + } + return "" +} + +func (x *DevboxSessionStatus) GetLastErrorTime() *timestamppb.Timestamp { + if x != nil { + return x.LastErrorTime + } + return nil +} + +type SandboxStatus_Baseline struct { + state protoimpl.MessageState sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + ApiVersion string `protobuf:"bytes,1,opt,name=apiVersion,proto3" json:"apiVersion,omitempty"` + Kind string `protobuf:"bytes,2,opt,name=kind,proto3" json:"kind,omitempty"` + Namespace string `protobuf:"bytes,3,opt,name=namespace,proto3" json:"namespace,omitempty"` + Name string `protobuf:"bytes,4,opt,name=name,proto3" json:"name,omitempty"` } func (x *SandboxStatus_Baseline) Reset() { *x = SandboxStatus_Baseline{} - mi := &file_internal_locald_api_common_proto_msgTypes[8] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) + if protoimpl.UnsafeEnabled { + mi := &file_internal_locald_api_common_proto_msgTypes[9] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } func (x *SandboxStatus_Baseline) String() string { @@ -517,8 +637,8 @@ func (x *SandboxStatus_Baseline) String() string { func (*SandboxStatus_Baseline) ProtoMessage() {} func (x *SandboxStatus_Baseline) ProtoReflect() protoreflect.Message { - mi := &file_internal_locald_api_common_proto_msgTypes[8] - if x != nil { + mi := &file_internal_locald_api_common_proto_msgTypes[9] + if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -562,18 +682,21 @@ func (x *SandboxStatus_Baseline) GetName() string { } type SandboxStatus_BaselineToLocal struct { - state protoimpl.MessageState `protogen:"open.v1"` - BaselinePort int32 `protobuf:"varint,1,opt,name=baseline_port,json=baselinePort,proto3" json:"baseline_port,omitempty"` - LocalAddress string `protobuf:"bytes,2,opt,name=local_address,json=localAddress,proto3" json:"local_address,omitempty"` - unknownFields protoimpl.UnknownFields + state protoimpl.MessageState sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + BaselinePort int32 `protobuf:"varint,1,opt,name=baseline_port,json=baselinePort,proto3" json:"baseline_port,omitempty"` + LocalAddress string `protobuf:"bytes,2,opt,name=local_address,json=localAddress,proto3" json:"local_address,omitempty"` } func (x *SandboxStatus_BaselineToLocal) Reset() { *x = SandboxStatus_BaselineToLocal{} - mi := &file_internal_locald_api_common_proto_msgTypes[9] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) + if protoimpl.UnsafeEnabled { + mi := &file_internal_locald_api_common_proto_msgTypes[10] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } func (x *SandboxStatus_BaselineToLocal) String() string { @@ -583,8 +706,8 @@ func (x *SandboxStatus_BaselineToLocal) String() string { func (*SandboxStatus_BaselineToLocal) ProtoMessage() {} func (x *SandboxStatus_BaselineToLocal) ProtoReflect() protoreflect.Message { - mi := &file_internal_locald_api_common_proto_msgTypes[9] - if x != nil { + mi := &file_internal_locald_api_common_proto_msgTypes[10] + if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -614,7 +737,10 @@ func (x *SandboxStatus_BaselineToLocal) GetLocalAddress() string { } type SandboxStatus_LocalWorkload struct { - state protoimpl.MessageState `protogen:"open.v1"` + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + // The workload name Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` // "fork target" @@ -623,16 +749,16 @@ type SandboxStatus_LocalWorkload struct { // destinations in the tunnel WorkloadPortMapping []*SandboxStatus_BaselineToLocal `protobuf:"bytes,3,rep,name=workloadPortMapping,proto3" json:"workloadPortMapping,omitempty"` // tunnel health - TunnelHealth *ServiceHealth `protobuf:"bytes,4,opt,name=tunnel_health,json=tunnelHealth,proto3" json:"tunnel_health,omitempty"` - unknownFields protoimpl.UnknownFields - sizeCache protoimpl.SizeCache + TunnelHealth *ServiceHealth `protobuf:"bytes,4,opt,name=tunnel_health,json=tunnelHealth,proto3" json:"tunnel_health,omitempty"` } func (x *SandboxStatus_LocalWorkload) Reset() { *x = SandboxStatus_LocalWorkload{} - mi := &file_internal_locald_api_common_proto_msgTypes[10] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) + if protoimpl.UnsafeEnabled { + mi := &file_internal_locald_api_common_proto_msgTypes[11] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } func (x *SandboxStatus_LocalWorkload) String() string { @@ -642,8 +768,8 @@ func (x *SandboxStatus_LocalWorkload) String() string { func (*SandboxStatus_LocalWorkload) ProtoMessage() {} func (x *SandboxStatus_LocalWorkload) ProtoReflect() protoreflect.Message { - mi := &file_internal_locald_api_common_proto_msgTypes[10] - if x != nil { + mi := &file_internal_locald_api_common_proto_msgTypes[11] + if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -688,74 +814,144 @@ func (x *SandboxStatus_LocalWorkload) GetTunnelHealth() *ServiceHealth { var File_internal_locald_api_common_proto protoreflect.FileDescriptor -const file_internal_locald_api_common_proto_rawDesc = "" + - "\n" + - " internal/locald/api/common.proto\x12\tapicommon\x1a\x1fgoogle/protobuf/timestamp.proto\"\xba\x01\n" + - "\rServiceHealth\x12\x18\n" + - "\ahealthy\x18\x01 \x01(\bR\ahealthy\x12\x1f\n" + - "\verror_count\x18\x02 \x01(\rR\n" + - "errorCount\x12*\n" + - "\x11last_error_reason\x18\x03 \x01(\tR\x0flastErrorReason\x12B\n" + - "\x0flast_error_time\x18\x04 \x01(\v2\x1a.google.protobuf.TimestampR\rlastErrorTime\"\x7f\n" + - "\x0eLocalNetStatus\x120\n" + - "\x06health\x18\x01 \x01(\v2\x18.apicommon.ServiceHealthR\x06health\x12\x14\n" + - "\x05cidrs\x18\x02 \x03(\tR\x05cidrs\x12%\n" + - "\x0eexcluded_cidrs\x18\x03 \x03(\tR\rexcludedCidrs\"\xc3\x01\n" + - "\vHostsStatus\x120\n" + - "\x06health\x18\x01 \x01(\v2\x18.apicommon.ServiceHealthR\x06health\x12\x1b\n" + - "\tnum_hosts\x18\x02 \x01(\rR\bnumHosts\x12\x1f\n" + - "\vnum_updates\x18\x03 \x01(\rR\n" + - "numUpdates\x12D\n" + - "\x10last_update_time\x18\x04 \x01(\v2\x1a.google.protobuf.TimestampR\x0elastUpdateTime\"j\n" + - "\x11PortForwardStatus\x120\n" + - "\x06health\x18\x01 \x01(\v2\x18.apicommon.ServiceHealthR\x06health\x12#\n" + - "\rlocal_address\x18\x02 \x01(\tR\flocalAddress\"p\n" + - "\x17ControlPlaneProxyStatus\x120\n" + - "\x06health\x18\x01 \x01(\v2\x18.apicommon.ServiceHealthR\x06health\x12#\n" + - "\rlocal_address\x18\x02 \x01(\tR\flocalAddress\"A\n" + - "\rWatcherStatus\x120\n" + - "\x06health\x18\x01 \x01(\v2\x18.apicommon.ServiceHealthR\x06health\"\xe4\x04\n" + - "\rSandboxStatus\x12\x12\n" + - "\x04name\x18\x01 \x01(\tR\x04name\x12\x1f\n" + - "\vrouting_key\x18\x02 \x01(\tR\n" + - "routingKey\x12O\n" + - "\x0flocal_workloads\x18\x03 \x03(\v2&.apicommon.SandboxStatus.LocalWorkloadR\x0elocalWorkloads\x1ap\n" + - "\bBaseline\x12\x1e\n" + - "\n" + - "apiVersion\x18\x01 \x01(\tR\n" + - "apiVersion\x12\x12\n" + - "\x04kind\x18\x02 \x01(\tR\x04kind\x12\x1c\n" + - "\tnamespace\x18\x03 \x01(\tR\tnamespace\x12\x12\n" + - "\x04name\x18\x04 \x01(\tR\x04name\x1a[\n" + - "\x0fBaselineToLocal\x12#\n" + - "\rbaseline_port\x18\x01 \x01(\x05R\fbaselinePort\x12#\n" + - "\rlocal_address\x18\x02 \x01(\tR\flocalAddress\x1a\xfd\x01\n" + - "\rLocalWorkload\x12\x12\n" + - "\x04name\x18\x01 \x01(\tR\x04name\x12=\n" + - "\bbaseline\x18\x02 \x01(\v2!.apicommon.SandboxStatus.BaselineR\bbaseline\x12Z\n" + - "\x13workloadPortMapping\x18\x03 \x03(\v2(.apicommon.SandboxStatus.BaselineToLocalR\x13workloadPortMapping\x12=\n" + - "\rtunnel_health\x18\x04 \x01(\v2\x18.apicommon.ServiceHealthR\ftunnelHealth\"f\n" + - "\fOperatorInfo\x12\x18\n" + - "\aversion\x18\x01 \x01(\tR\aversion\x12\x1d\n" + - "\n" + - "git_commit\x18\x02 \x01(\tR\tgitCommit\x12\x1d\n" + - "\n" + - "build_date\x18\x03 \x01(\tR\tbuildDateB-Z+github.com/signadot/cli/internal/locald/apib\x06proto3" +var file_internal_locald_api_common_proto_rawDesc = []byte{ + 0x0a, 0x20, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2f, 0x6c, 0x6f, 0x63, 0x61, 0x6c, + 0x64, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x12, 0x09, 0x61, 0x70, 0x69, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x1a, 0x1f, 0x67, + 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x74, + 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xba, + 0x01, 0x0a, 0x0d, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, + 0x12, 0x18, 0x0a, 0x07, 0x68, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x08, 0x52, 0x07, 0x68, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x79, 0x12, 0x1f, 0x0a, 0x0b, 0x65, 0x72, + 0x72, 0x6f, 0x72, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, + 0x0a, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x2a, 0x0a, 0x11, 0x6c, + 0x61, 0x73, 0x74, 0x5f, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x5f, 0x72, 0x65, 0x61, 0x73, 0x6f, 0x6e, + 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0f, 0x6c, 0x61, 0x73, 0x74, 0x45, 0x72, 0x72, 0x6f, + 0x72, 0x52, 0x65, 0x61, 0x73, 0x6f, 0x6e, 0x12, 0x42, 0x0a, 0x0f, 0x6c, 0x61, 0x73, 0x74, 0x5f, + 0x65, 0x72, 0x72, 0x6f, 0x72, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, + 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x0d, 0x6c, 0x61, + 0x73, 0x74, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x54, 0x69, 0x6d, 0x65, 0x22, 0x7f, 0x0a, 0x0e, 0x4c, + 0x6f, 0x63, 0x61, 0x6c, 0x4e, 0x65, 0x74, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x30, 0x0a, + 0x06, 0x68, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x18, 0x2e, + 0x61, 0x70, 0x69, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, + 0x65, 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x52, 0x06, 0x68, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x12, + 0x14, 0x0a, 0x05, 0x63, 0x69, 0x64, 0x72, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, 0x52, 0x05, + 0x63, 0x69, 0x64, 0x72, 0x73, 0x12, 0x25, 0x0a, 0x0e, 0x65, 0x78, 0x63, 0x6c, 0x75, 0x64, 0x65, + 0x64, 0x5f, 0x63, 0x69, 0x64, 0x72, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0d, 0x65, + 0x78, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x64, 0x43, 0x69, 0x64, 0x72, 0x73, 0x22, 0xc3, 0x01, 0x0a, + 0x0b, 0x48, 0x6f, 0x73, 0x74, 0x73, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x30, 0x0a, 0x06, + 0x68, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x61, + 0x70, 0x69, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, + 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x52, 0x06, 0x68, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x12, 0x1b, + 0x0a, 0x09, 0x6e, 0x75, 0x6d, 0x5f, 0x68, 0x6f, 0x73, 0x74, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x0d, 0x52, 0x08, 0x6e, 0x75, 0x6d, 0x48, 0x6f, 0x73, 0x74, 0x73, 0x12, 0x1f, 0x0a, 0x0b, 0x6e, + 0x75, 0x6d, 0x5f, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0d, + 0x52, 0x0a, 0x6e, 0x75, 0x6d, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x73, 0x12, 0x44, 0x0a, 0x10, + 0x6c, 0x61, 0x73, 0x74, 0x5f, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x5f, 0x74, 0x69, 0x6d, 0x65, + 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, + 0x6d, 0x70, 0x52, 0x0e, 0x6c, 0x61, 0x73, 0x74, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x54, 0x69, + 0x6d, 0x65, 0x22, 0x6a, 0x0a, 0x11, 0x50, 0x6f, 0x72, 0x74, 0x46, 0x6f, 0x72, 0x77, 0x61, 0x72, + 0x64, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x30, 0x0a, 0x06, 0x68, 0x65, 0x61, 0x6c, 0x74, + 0x68, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x61, 0x70, 0x69, 0x63, 0x6f, 0x6d, + 0x6d, 0x6f, 0x6e, 0x2e, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x48, 0x65, 0x61, 0x6c, 0x74, + 0x68, 0x52, 0x06, 0x68, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x12, 0x23, 0x0a, 0x0d, 0x6c, 0x6f, 0x63, + 0x61, 0x6c, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x0c, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x22, 0x70, + 0x0a, 0x17, 0x43, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x50, 0x6c, 0x61, 0x6e, 0x65, 0x50, 0x72, + 0x6f, 0x78, 0x79, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x30, 0x0a, 0x06, 0x68, 0x65, 0x61, + 0x6c, 0x74, 0x68, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x61, 0x70, 0x69, 0x63, + 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x48, 0x65, 0x61, + 0x6c, 0x74, 0x68, 0x52, 0x06, 0x68, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x12, 0x23, 0x0a, 0x0d, 0x6c, + 0x6f, 0x63, 0x61, 0x6c, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x0c, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, + 0x22, 0x41, 0x0a, 0x0d, 0x57, 0x61, 0x74, 0x63, 0x68, 0x65, 0x72, 0x53, 0x74, 0x61, 0x74, 0x75, + 0x73, 0x12, 0x30, 0x0a, 0x06, 0x68, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x18, 0x2e, 0x61, 0x70, 0x69, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x53, 0x65, + 0x72, 0x76, 0x69, 0x63, 0x65, 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x52, 0x06, 0x68, 0x65, 0x61, + 0x6c, 0x74, 0x68, 0x22, 0xe4, 0x04, 0x0a, 0x0d, 0x53, 0x61, 0x6e, 0x64, 0x62, 0x6f, 0x78, 0x53, + 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x1f, 0x0a, 0x0b, 0x72, 0x6f, 0x75, + 0x74, 0x69, 0x6e, 0x67, 0x5f, 0x6b, 0x65, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, + 0x72, 0x6f, 0x75, 0x74, 0x69, 0x6e, 0x67, 0x4b, 0x65, 0x79, 0x12, 0x4f, 0x0a, 0x0f, 0x6c, 0x6f, + 0x63, 0x61, 0x6c, 0x5f, 0x77, 0x6f, 0x72, 0x6b, 0x6c, 0x6f, 0x61, 0x64, 0x73, 0x18, 0x03, 0x20, + 0x03, 0x28, 0x0b, 0x32, 0x26, 0x2e, 0x61, 0x70, 0x69, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, + 0x53, 0x61, 0x6e, 0x64, 0x62, 0x6f, 0x78, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x2e, 0x4c, 0x6f, + 0x63, 0x61, 0x6c, 0x57, 0x6f, 0x72, 0x6b, 0x6c, 0x6f, 0x61, 0x64, 0x52, 0x0e, 0x6c, 0x6f, 0x63, + 0x61, 0x6c, 0x57, 0x6f, 0x72, 0x6b, 0x6c, 0x6f, 0x61, 0x64, 0x73, 0x1a, 0x70, 0x0a, 0x08, 0x42, + 0x61, 0x73, 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x12, 0x1e, 0x0a, 0x0a, 0x61, 0x70, 0x69, 0x56, 0x65, + 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x61, 0x70, 0x69, + 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x12, 0x0a, 0x04, 0x6b, 0x69, 0x6e, 0x64, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6b, 0x69, 0x6e, 0x64, 0x12, 0x1c, 0x0a, 0x09, 0x6e, + 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, + 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, + 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x1a, 0x5b, 0x0a, + 0x0f, 0x42, 0x61, 0x73, 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x54, 0x6f, 0x4c, 0x6f, 0x63, 0x61, 0x6c, + 0x12, 0x23, 0x0a, 0x0d, 0x62, 0x61, 0x73, 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x5f, 0x70, 0x6f, 0x72, + 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0c, 0x62, 0x61, 0x73, 0x65, 0x6c, 0x69, 0x6e, + 0x65, 0x50, 0x6f, 0x72, 0x74, 0x12, 0x23, 0x0a, 0x0d, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x5f, 0x61, + 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x6c, 0x6f, + 0x63, 0x61, 0x6c, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x1a, 0xfd, 0x01, 0x0a, 0x0d, 0x4c, + 0x6f, 0x63, 0x61, 0x6c, 0x57, 0x6f, 0x72, 0x6b, 0x6c, 0x6f, 0x61, 0x64, 0x12, 0x12, 0x0a, 0x04, + 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, + 0x12, 0x3d, 0x0a, 0x08, 0x62, 0x61, 0x73, 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x21, 0x2e, 0x61, 0x70, 0x69, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x53, + 0x61, 0x6e, 0x64, 0x62, 0x6f, 0x78, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x2e, 0x42, 0x61, 0x73, + 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x52, 0x08, 0x62, 0x61, 0x73, 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x12, + 0x5a, 0x0a, 0x13, 0x77, 0x6f, 0x72, 0x6b, 0x6c, 0x6f, 0x61, 0x64, 0x50, 0x6f, 0x72, 0x74, 0x4d, + 0x61, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x28, 0x2e, 0x61, + 0x70, 0x69, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x53, 0x61, 0x6e, 0x64, 0x62, 0x6f, 0x78, + 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x2e, 0x42, 0x61, 0x73, 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x54, + 0x6f, 0x4c, 0x6f, 0x63, 0x61, 0x6c, 0x52, 0x13, 0x77, 0x6f, 0x72, 0x6b, 0x6c, 0x6f, 0x61, 0x64, + 0x50, 0x6f, 0x72, 0x74, 0x4d, 0x61, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x12, 0x3d, 0x0a, 0x0d, 0x74, + 0x75, 0x6e, 0x6e, 0x65, 0x6c, 0x5f, 0x68, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x18, 0x04, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x61, 0x70, 0x69, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x53, + 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x52, 0x0c, 0x74, 0x75, + 0x6e, 0x6e, 0x65, 0x6c, 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x22, 0x66, 0x0a, 0x0c, 0x4f, 0x70, + 0x65, 0x72, 0x61, 0x74, 0x6f, 0x72, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x18, 0x0a, 0x07, 0x76, 0x65, + 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x76, 0x65, 0x72, + 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x1d, 0x0a, 0x0a, 0x67, 0x69, 0x74, 0x5f, 0x63, 0x6f, 0x6d, 0x6d, + 0x69, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x67, 0x69, 0x74, 0x43, 0x6f, 0x6d, + 0x6d, 0x69, 0x74, 0x12, 0x1d, 0x0a, 0x0a, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x5f, 0x64, 0x61, 0x74, + 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x44, 0x61, + 0x74, 0x65, 0x22, 0x86, 0x02, 0x0a, 0x13, 0x44, 0x65, 0x76, 0x62, 0x6f, 0x78, 0x53, 0x65, 0x73, + 0x73, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x18, 0x0a, 0x07, 0x68, 0x65, + 0x61, 0x6c, 0x74, 0x68, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x68, 0x65, 0x61, + 0x6c, 0x74, 0x68, 0x79, 0x12, 0x29, 0x0a, 0x10, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x5f, + 0x72, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0f, + 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x64, 0x12, + 0x1b, 0x0a, 0x09, 0x64, 0x65, 0x76, 0x62, 0x6f, 0x78, 0x5f, 0x69, 0x64, 0x18, 0x03, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x08, 0x64, 0x65, 0x76, 0x62, 0x6f, 0x78, 0x49, 0x64, 0x12, 0x1d, 0x0a, 0x0a, + 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x09, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x12, 0x2a, 0x0a, 0x11, 0x6c, + 0x61, 0x73, 0x74, 0x5f, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x5f, 0x72, 0x65, 0x61, 0x73, 0x6f, 0x6e, + 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0f, 0x6c, 0x61, 0x73, 0x74, 0x45, 0x72, 0x72, 0x6f, + 0x72, 0x52, 0x65, 0x61, 0x73, 0x6f, 0x6e, 0x12, 0x42, 0x0a, 0x0f, 0x6c, 0x61, 0x73, 0x74, 0x5f, + 0x65, 0x72, 0x72, 0x6f, 0x72, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, + 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x0d, 0x6c, 0x61, + 0x73, 0x74, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x54, 0x69, 0x6d, 0x65, 0x42, 0x2d, 0x5a, 0x2b, 0x67, + 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x64, + 0x6f, 0x74, 0x2f, 0x63, 0x6c, 0x69, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2f, + 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x64, 0x2f, 0x61, 0x70, 0x69, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x33, +} var ( file_internal_locald_api_common_proto_rawDescOnce sync.Once - file_internal_locald_api_common_proto_rawDescData []byte + file_internal_locald_api_common_proto_rawDescData = file_internal_locald_api_common_proto_rawDesc ) func file_internal_locald_api_common_proto_rawDescGZIP() []byte { file_internal_locald_api_common_proto_rawDescOnce.Do(func() { - file_internal_locald_api_common_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_internal_locald_api_common_proto_rawDesc), len(file_internal_locald_api_common_proto_rawDesc))) + file_internal_locald_api_common_proto_rawDescData = protoimpl.X.CompressGZIP(file_internal_locald_api_common_proto_rawDescData) }) return file_internal_locald_api_common_proto_rawDescData } -var file_internal_locald_api_common_proto_msgTypes = make([]protoimpl.MessageInfo, 11) -var file_internal_locald_api_common_proto_goTypes = []any{ +var file_internal_locald_api_common_proto_msgTypes = make([]protoimpl.MessageInfo, 12) +var file_internal_locald_api_common_proto_goTypes = []interface{}{ (*ServiceHealth)(nil), // 0: apicommon.ServiceHealth (*LocalNetStatus)(nil), // 1: apicommon.LocalNetStatus (*HostsStatus)(nil), // 2: apicommon.HostsStatus @@ -764,28 +960,30 @@ var file_internal_locald_api_common_proto_goTypes = []any{ (*WatcherStatus)(nil), // 5: apicommon.WatcherStatus (*SandboxStatus)(nil), // 6: apicommon.SandboxStatus (*OperatorInfo)(nil), // 7: apicommon.OperatorInfo - (*SandboxStatus_Baseline)(nil), // 8: apicommon.SandboxStatus.Baseline - (*SandboxStatus_BaselineToLocal)(nil), // 9: apicommon.SandboxStatus.BaselineToLocal - (*SandboxStatus_LocalWorkload)(nil), // 10: apicommon.SandboxStatus.LocalWorkload - (*timestamppb.Timestamp)(nil), // 11: google.protobuf.Timestamp + (*DevboxSessionStatus)(nil), // 8: apicommon.DevboxSessionStatus + (*SandboxStatus_Baseline)(nil), // 9: apicommon.SandboxStatus.Baseline + (*SandboxStatus_BaselineToLocal)(nil), // 10: apicommon.SandboxStatus.BaselineToLocal + (*SandboxStatus_LocalWorkload)(nil), // 11: apicommon.SandboxStatus.LocalWorkload + (*timestamppb.Timestamp)(nil), // 12: google.protobuf.Timestamp } var file_internal_locald_api_common_proto_depIdxs = []int32{ - 11, // 0: apicommon.ServiceHealth.last_error_time:type_name -> google.protobuf.Timestamp + 12, // 0: apicommon.ServiceHealth.last_error_time:type_name -> google.protobuf.Timestamp 0, // 1: apicommon.LocalNetStatus.health:type_name -> apicommon.ServiceHealth 0, // 2: apicommon.HostsStatus.health:type_name -> apicommon.ServiceHealth - 11, // 3: apicommon.HostsStatus.last_update_time:type_name -> google.protobuf.Timestamp + 12, // 3: apicommon.HostsStatus.last_update_time:type_name -> google.protobuf.Timestamp 0, // 4: apicommon.PortForwardStatus.health:type_name -> apicommon.ServiceHealth 0, // 5: apicommon.ControlPlaneProxyStatus.health:type_name -> apicommon.ServiceHealth 0, // 6: apicommon.WatcherStatus.health:type_name -> apicommon.ServiceHealth - 10, // 7: apicommon.SandboxStatus.local_workloads:type_name -> apicommon.SandboxStatus.LocalWorkload - 8, // 8: apicommon.SandboxStatus.LocalWorkload.baseline:type_name -> apicommon.SandboxStatus.Baseline - 9, // 9: apicommon.SandboxStatus.LocalWorkload.workloadPortMapping:type_name -> apicommon.SandboxStatus.BaselineToLocal - 0, // 10: apicommon.SandboxStatus.LocalWorkload.tunnel_health:type_name -> apicommon.ServiceHealth - 11, // [11:11] is the sub-list for method output_type - 11, // [11:11] is the sub-list for method input_type - 11, // [11:11] is the sub-list for extension type_name - 11, // [11:11] is the sub-list for extension extendee - 0, // [0:11] is the sub-list for field type_name + 11, // 7: apicommon.SandboxStatus.local_workloads:type_name -> apicommon.SandboxStatus.LocalWorkload + 12, // 8: apicommon.DevboxSessionStatus.last_error_time:type_name -> google.protobuf.Timestamp + 9, // 9: apicommon.SandboxStatus.LocalWorkload.baseline:type_name -> apicommon.SandboxStatus.Baseline + 10, // 10: apicommon.SandboxStatus.LocalWorkload.workloadPortMapping:type_name -> apicommon.SandboxStatus.BaselineToLocal + 0, // 11: apicommon.SandboxStatus.LocalWorkload.tunnel_health:type_name -> apicommon.ServiceHealth + 12, // [12:12] is the sub-list for method output_type + 12, // [12:12] is the sub-list for method input_type + 12, // [12:12] is the sub-list for extension type_name + 12, // [12:12] is the sub-list for extension extendee + 0, // [0:12] is the sub-list for field type_name } func init() { file_internal_locald_api_common_proto_init() } @@ -793,13 +991,159 @@ func file_internal_locald_api_common_proto_init() { if File_internal_locald_api_common_proto != nil { return } + if !protoimpl.UnsafeEnabled { + file_internal_locald_api_common_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ServiceHealth); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_internal_locald_api_common_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*LocalNetStatus); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_internal_locald_api_common_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*HostsStatus); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_internal_locald_api_common_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*PortForwardStatus); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_internal_locald_api_common_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ControlPlaneProxyStatus); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_internal_locald_api_common_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*WatcherStatus); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_internal_locald_api_common_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*SandboxStatus); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_internal_locald_api_common_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*OperatorInfo); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_internal_locald_api_common_proto_msgTypes[8].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*DevboxSessionStatus); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_internal_locald_api_common_proto_msgTypes[9].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*SandboxStatus_Baseline); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_internal_locald_api_common_proto_msgTypes[10].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*SandboxStatus_BaselineToLocal); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_internal_locald_api_common_proto_msgTypes[11].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*SandboxStatus_LocalWorkload); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + } type x struct{} out := protoimpl.TypeBuilder{ File: protoimpl.DescBuilder{ GoPackagePath: reflect.TypeOf(x{}).PkgPath(), - RawDescriptor: unsafe.Slice(unsafe.StringData(file_internal_locald_api_common_proto_rawDesc), len(file_internal_locald_api_common_proto_rawDesc)), + RawDescriptor: file_internal_locald_api_common_proto_rawDesc, NumEnums: 0, - NumMessages: 11, + NumMessages: 12, NumExtensions: 0, NumServices: 0, }, @@ -808,6 +1152,7 @@ func file_internal_locald_api_common_proto_init() { MessageInfos: file_internal_locald_api_common_proto_msgTypes, }.Build() File_internal_locald_api_common_proto = out.File + file_internal_locald_api_common_proto_rawDesc = nil file_internal_locald_api_common_proto_goTypes = nil file_internal_locald_api_common_proto_depIdxs = nil } diff --git a/internal/locald/api/common.proto b/internal/locald/api/common.proto index fbab355c..9481b462 100644 --- a/internal/locald/api/common.proto +++ b/internal/locald/api/common.proto @@ -82,4 +82,20 @@ message OperatorInfo { string version = 1; string git_commit = 2; string build_date = 3; +} + +// Devbox session status (produced by local controller) +message DevboxSessionStatus { + // Whether the devbox session is active and healthy + bool healthy = 1; + // Whether the session was released by another process + bool session_released = 2; + // Devbox ID + string devbox_id = 3; + // Session ID + string session_id = 4; + // Last error reason if unhealthy + string last_error_reason = 5; + // Last error time if unhealthy + google.protobuf.Timestamp last_error_time = 6; } \ No newline at end of file diff --git a/internal/locald/api/rootmanager/root_manager_api.pb.go b/internal/locald/api/rootmanager/root_manager_api.pb.go index cd468733..585f5c4b 100644 --- a/internal/locald/api/rootmanager/root_manager_api.pb.go +++ b/internal/locald/api/rootmanager/root_manager_api.pb.go @@ -1,7 +1,7 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.36.6 -// protoc v3.21.12 +// protoc-gen-go v1.26.0 +// protoc v6.33.0 // source: internal/locald/api/rootmanager/root_manager_api.proto package rootmanager @@ -12,7 +12,6 @@ import ( protoimpl "google.golang.org/protobuf/runtime/protoimpl" reflect "reflect" sync "sync" - unsafe "unsafe" ) const ( @@ -23,16 +22,18 @@ const ( ) type StatusRequest struct { - state protoimpl.MessageState `protogen:"open.v1"` - unknownFields protoimpl.UnknownFields + state protoimpl.MessageState sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields } func (x *StatusRequest) Reset() { *x = StatusRequest{} - mi := &file_internal_locald_api_rootmanager_root_manager_api_proto_msgTypes[0] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) + if protoimpl.UnsafeEnabled { + mi := &file_internal_locald_api_rootmanager_root_manager_api_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } func (x *StatusRequest) String() string { @@ -43,7 +44,7 @@ func (*StatusRequest) ProtoMessage() {} func (x *StatusRequest) ProtoReflect() protoreflect.Message { mi := &file_internal_locald_api_rootmanager_root_manager_api_proto_msgTypes[0] - if x != nil { + if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -59,18 +60,21 @@ func (*StatusRequest) Descriptor() ([]byte, []int) { } type StatusResponse struct { - state protoimpl.MessageState `protogen:"open.v1"` - Localnet *api.LocalNetStatus `protobuf:"bytes,1,opt,name=localnet,proto3" json:"localnet,omitempty"` - Hosts *api.HostsStatus `protobuf:"bytes,2,opt,name=hosts,proto3" json:"hosts,omitempty"` - unknownFields protoimpl.UnknownFields + state protoimpl.MessageState sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Localnet *api.LocalNetStatus `protobuf:"bytes,1,opt,name=localnet,proto3" json:"localnet,omitempty"` + Hosts *api.HostsStatus `protobuf:"bytes,2,opt,name=hosts,proto3" json:"hosts,omitempty"` } func (x *StatusResponse) Reset() { *x = StatusResponse{} - mi := &file_internal_locald_api_rootmanager_root_manager_api_proto_msgTypes[1] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) + if protoimpl.UnsafeEnabled { + mi := &file_internal_locald_api_rootmanager_root_manager_api_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } func (x *StatusResponse) String() string { @@ -81,7 +85,7 @@ func (*StatusResponse) ProtoMessage() {} func (x *StatusResponse) ProtoReflect() protoreflect.Message { mi := &file_internal_locald_api_rootmanager_root_manager_api_proto_msgTypes[1] - if x != nil { + if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -111,16 +115,18 @@ func (x *StatusResponse) GetHosts() *api.HostsStatus { } type ShutdownRequest struct { - state protoimpl.MessageState `protogen:"open.v1"` - unknownFields protoimpl.UnknownFields + state protoimpl.MessageState sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields } func (x *ShutdownRequest) Reset() { *x = ShutdownRequest{} - mi := &file_internal_locald_api_rootmanager_root_manager_api_proto_msgTypes[2] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) + if protoimpl.UnsafeEnabled { + mi := &file_internal_locald_api_rootmanager_root_manager_api_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } func (x *ShutdownRequest) String() string { @@ -131,7 +137,7 @@ func (*ShutdownRequest) ProtoMessage() {} func (x *ShutdownRequest) ProtoReflect() protoreflect.Message { mi := &file_internal_locald_api_rootmanager_root_manager_api_proto_msgTypes[2] - if x != nil { + if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -147,16 +153,18 @@ func (*ShutdownRequest) Descriptor() ([]byte, []int) { } type ShutdownResponse struct { - state protoimpl.MessageState `protogen:"open.v1"` - unknownFields protoimpl.UnknownFields + state protoimpl.MessageState sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields } func (x *ShutdownResponse) Reset() { *x = ShutdownResponse{} - mi := &file_internal_locald_api_rootmanager_root_manager_api_proto_msgTypes[3] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) + if protoimpl.UnsafeEnabled { + mi := &file_internal_locald_api_rootmanager_root_manager_api_proto_msgTypes[3] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } func (x *ShutdownResponse) String() string { @@ -167,7 +175,7 @@ func (*ShutdownResponse) ProtoMessage() {} func (x *ShutdownResponse) ProtoReflect() protoreflect.Message { mi := &file_internal_locald_api_rootmanager_root_manager_api_proto_msgTypes[3] - if x != nil { + if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -184,33 +192,55 @@ func (*ShutdownResponse) Descriptor() ([]byte, []int) { var File_internal_locald_api_rootmanager_root_manager_api_proto protoreflect.FileDescriptor -const file_internal_locald_api_rootmanager_root_manager_api_proto_rawDesc = "" + - "\n" + - "6internal/locald/api/rootmanager/root_manager_api.proto\x12\vrootmanager\x1a internal/locald/api/common.proto\"\x0f\n" + - "\rStatusRequest\"u\n" + - "\x0eStatusResponse\x125\n" + - "\blocalnet\x18\x01 \x01(\v2\x19.apicommon.LocalNetStatusR\blocalnet\x12,\n" + - "\x05hosts\x18\x02 \x01(\v2\x16.apicommon.HostsStatusR\x05hosts\"\x11\n" + - "\x0fShutdownRequest\"\x12\n" + - "\x10ShutdownResponse2\xa0\x01\n" + - "\x0eRootManagerAPI\x12C\n" + - "\x06Status\x12\x1a.rootmanager.StatusRequest\x1a\x1b.rootmanager.StatusResponse\"\x00\x12I\n" + - "\bShutdown\x12\x1c.rootmanager.ShutdownRequest\x1a\x1d.rootmanager.ShutdownResponse\"\x00B9Z7github.com/signadot/cli/internal/locald/api/rootmanagerb\x06proto3" +var file_internal_locald_api_rootmanager_root_manager_api_proto_rawDesc = []byte{ + 0x0a, 0x36, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2f, 0x6c, 0x6f, 0x63, 0x61, 0x6c, + 0x64, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x72, 0x6f, 0x6f, 0x74, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, + 0x72, 0x2f, 0x72, 0x6f, 0x6f, 0x74, 0x5f, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x72, 0x5f, 0x61, + 0x70, 0x69, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x0b, 0x72, 0x6f, 0x6f, 0x74, 0x6d, 0x61, + 0x6e, 0x61, 0x67, 0x65, 0x72, 0x1a, 0x20, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2f, + 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x64, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, + 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x0f, 0x0a, 0x0d, 0x53, 0x74, 0x61, 0x74, 0x75, + 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x75, 0x0a, 0x0e, 0x53, 0x74, 0x61, 0x74, + 0x75, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x35, 0x0a, 0x08, 0x6c, 0x6f, + 0x63, 0x61, 0x6c, 0x6e, 0x65, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x61, + 0x70, 0x69, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x4c, 0x6f, 0x63, 0x61, 0x6c, 0x4e, 0x65, + 0x74, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x08, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x6e, 0x65, + 0x74, 0x12, 0x2c, 0x0a, 0x05, 0x68, 0x6f, 0x73, 0x74, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x16, 0x2e, 0x61, 0x70, 0x69, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x48, 0x6f, 0x73, + 0x74, 0x73, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x05, 0x68, 0x6f, 0x73, 0x74, 0x73, 0x22, + 0x11, 0x0a, 0x0f, 0x53, 0x68, 0x75, 0x74, 0x64, 0x6f, 0x77, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x22, 0x12, 0x0a, 0x10, 0x53, 0x68, 0x75, 0x74, 0x64, 0x6f, 0x77, 0x6e, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x32, 0xa0, 0x01, 0x0a, 0x0e, 0x52, 0x6f, 0x6f, 0x74, 0x4d, + 0x61, 0x6e, 0x61, 0x67, 0x65, 0x72, 0x41, 0x50, 0x49, 0x12, 0x43, 0x0a, 0x06, 0x53, 0x74, 0x61, + 0x74, 0x75, 0x73, 0x12, 0x1a, 0x2e, 0x72, 0x6f, 0x6f, 0x74, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, + 0x72, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, + 0x1b, 0x2e, 0x72, 0x6f, 0x6f, 0x74, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x72, 0x2e, 0x53, 0x74, + 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x49, + 0x0a, 0x08, 0x53, 0x68, 0x75, 0x74, 0x64, 0x6f, 0x77, 0x6e, 0x12, 0x1c, 0x2e, 0x72, 0x6f, 0x6f, + 0x74, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x72, 0x2e, 0x53, 0x68, 0x75, 0x74, 0x64, 0x6f, 0x77, + 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1d, 0x2e, 0x72, 0x6f, 0x6f, 0x74, 0x6d, + 0x61, 0x6e, 0x61, 0x67, 0x65, 0x72, 0x2e, 0x53, 0x68, 0x75, 0x74, 0x64, 0x6f, 0x77, 0x6e, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x42, 0x39, 0x5a, 0x37, 0x67, 0x69, 0x74, + 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x64, 0x6f, 0x74, + 0x2f, 0x63, 0x6c, 0x69, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2f, 0x6c, 0x6f, + 0x63, 0x61, 0x6c, 0x64, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x72, 0x6f, 0x6f, 0x74, 0x6d, 0x61, 0x6e, + 0x61, 0x67, 0x65, 0x72, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, +} var ( file_internal_locald_api_rootmanager_root_manager_api_proto_rawDescOnce sync.Once - file_internal_locald_api_rootmanager_root_manager_api_proto_rawDescData []byte + file_internal_locald_api_rootmanager_root_manager_api_proto_rawDescData = file_internal_locald_api_rootmanager_root_manager_api_proto_rawDesc ) func file_internal_locald_api_rootmanager_root_manager_api_proto_rawDescGZIP() []byte { file_internal_locald_api_rootmanager_root_manager_api_proto_rawDescOnce.Do(func() { - file_internal_locald_api_rootmanager_root_manager_api_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_internal_locald_api_rootmanager_root_manager_api_proto_rawDesc), len(file_internal_locald_api_rootmanager_root_manager_api_proto_rawDesc))) + file_internal_locald_api_rootmanager_root_manager_api_proto_rawDescData = protoimpl.X.CompressGZIP(file_internal_locald_api_rootmanager_root_manager_api_proto_rawDescData) }) return file_internal_locald_api_rootmanager_root_manager_api_proto_rawDescData } var file_internal_locald_api_rootmanager_root_manager_api_proto_msgTypes = make([]protoimpl.MessageInfo, 4) -var file_internal_locald_api_rootmanager_root_manager_api_proto_goTypes = []any{ +var file_internal_locald_api_rootmanager_root_manager_api_proto_goTypes = []interface{}{ (*StatusRequest)(nil), // 0: rootmanager.StatusRequest (*StatusResponse)(nil), // 1: rootmanager.StatusResponse (*ShutdownRequest)(nil), // 2: rootmanager.ShutdownRequest @@ -237,11 +267,61 @@ func file_internal_locald_api_rootmanager_root_manager_api_proto_init() { if File_internal_locald_api_rootmanager_root_manager_api_proto != nil { return } + if !protoimpl.UnsafeEnabled { + file_internal_locald_api_rootmanager_root_manager_api_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*StatusRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_internal_locald_api_rootmanager_root_manager_api_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*StatusResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_internal_locald_api_rootmanager_root_manager_api_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ShutdownRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_internal_locald_api_rootmanager_root_manager_api_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ShutdownResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + } type x struct{} out := protoimpl.TypeBuilder{ File: protoimpl.DescBuilder{ GoPackagePath: reflect.TypeOf(x{}).PkgPath(), - RawDescriptor: unsafe.Slice(unsafe.StringData(file_internal_locald_api_rootmanager_root_manager_api_proto_rawDesc), len(file_internal_locald_api_rootmanager_root_manager_api_proto_rawDesc)), + RawDescriptor: file_internal_locald_api_rootmanager_root_manager_api_proto_rawDesc, NumEnums: 0, NumMessages: 4, NumExtensions: 0, @@ -252,6 +332,7 @@ func file_internal_locald_api_rootmanager_root_manager_api_proto_init() { MessageInfos: file_internal_locald_api_rootmanager_root_manager_api_proto_msgTypes, }.Build() File_internal_locald_api_rootmanager_root_manager_api_proto = out.File + file_internal_locald_api_rootmanager_root_manager_api_proto_rawDesc = nil file_internal_locald_api_rootmanager_root_manager_api_proto_goTypes = nil file_internal_locald_api_rootmanager_root_manager_api_proto_depIdxs = nil } diff --git a/internal/locald/api/rootmanager/root_manager_api_grpc.pb.go b/internal/locald/api/rootmanager/root_manager_api_grpc.pb.go index 61be1809..9e070df3 100644 --- a/internal/locald/api/rootmanager/root_manager_api_grpc.pb.go +++ b/internal/locald/api/rootmanager/root_manager_api_grpc.pb.go @@ -1,8 +1,4 @@ // Code generated by protoc-gen-go-grpc. DO NOT EDIT. -// versions: -// - protoc-gen-go-grpc v1.2.0 -// - protoc v3.21.12 -// source: internal/locald/api/rootmanager/root_manager_api.proto package rootmanager diff --git a/internal/locald/api/sandboxmanager/sandbox_manager_api.pb.go b/internal/locald/api/sandboxmanager/sandbox_manager_api.pb.go index effc9b6e..98f9c3be 100644 --- a/internal/locald/api/sandboxmanager/sandbox_manager_api.pb.go +++ b/internal/locald/api/sandboxmanager/sandbox_manager_api.pb.go @@ -1,7 +1,7 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.36.6 -// protoc v3.21.12 +// protoc-gen-go v1.26.0 +// protoc v6.33.0 // source: internal/locald/api/sandboxmanager/sandbox_manager_api.proto package sandboxmanager @@ -13,7 +13,6 @@ import ( structpb "google.golang.org/protobuf/types/known/structpb" reflect "reflect" sync "sync" - unsafe "unsafe" ) const ( @@ -24,16 +23,18 @@ const ( ) type StatusRequest struct { - state protoimpl.MessageState `protogen:"open.v1"` - unknownFields protoimpl.UnknownFields + state protoimpl.MessageState sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields } func (x *StatusRequest) Reset() { *x = StatusRequest{} - mi := &file_internal_locald_api_sandboxmanager_sandbox_manager_api_proto_msgTypes[0] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) + if protoimpl.UnsafeEnabled { + mi := &file_internal_locald_api_sandboxmanager_sandbox_manager_api_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } func (x *StatusRequest) String() string { @@ -44,7 +45,7 @@ func (*StatusRequest) ProtoMessage() {} func (x *StatusRequest) ProtoReflect() protoreflect.Message { mi := &file_internal_locald_api_sandboxmanager_sandbox_manager_api_proto_msgTypes[0] - if x != nil { + if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -60,7 +61,10 @@ func (*StatusRequest) Descriptor() ([]byte, []int) { } type StatusResponse struct { - state protoimpl.MessageState `protogen:"open.v1"` + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + // connect invocation config // (instance of internal/config/locald.ConnectInvocationConfig) CiConfig *structpb.Struct `protobuf:"bytes,1,opt,name=ci_config,json=ciConfig,proto3" json:"ci_config,omitempty"` @@ -71,15 +75,16 @@ type StatusResponse struct { ControlPlaneProxy *api.ControlPlaneProxyStatus `protobuf:"bytes,8,opt,name=control_plane_proxy,json=controlPlaneProxy,proto3" json:"control_plane_proxy,omitempty"` Watcher *api.WatcherStatus `protobuf:"bytes,6,opt,name=watcher,proto3" json:"watcher,omitempty"` Sandboxes []*api.SandboxStatus `protobuf:"bytes,5,rep,name=sandboxes,proto3" json:"sandboxes,omitempty"` - unknownFields protoimpl.UnknownFields - sizeCache protoimpl.SizeCache + DevboxSession *api.DevboxSessionStatus `protobuf:"bytes,9,opt,name=devbox_session,json=devboxSession,proto3" json:"devbox_session,omitempty"` } func (x *StatusResponse) Reset() { *x = StatusResponse{} - mi := &file_internal_locald_api_sandboxmanager_sandbox_manager_api_proto_msgTypes[1] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) + if protoimpl.UnsafeEnabled { + mi := &file_internal_locald_api_sandboxmanager_sandbox_manager_api_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } func (x *StatusResponse) String() string { @@ -90,7 +95,7 @@ func (*StatusResponse) ProtoMessage() {} func (x *StatusResponse) ProtoReflect() protoreflect.Message { mi := &file_internal_locald_api_sandboxmanager_sandbox_manager_api_proto_msgTypes[1] - if x != nil { + if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -161,17 +166,26 @@ func (x *StatusResponse) GetSandboxes() []*api.SandboxStatus { return nil } +func (x *StatusResponse) GetDevboxSession() *api.DevboxSessionStatus { + if x != nil { + return x.DevboxSession + } + return nil +} + type ShutdownRequest struct { - state protoimpl.MessageState `protogen:"open.v1"` - unknownFields protoimpl.UnknownFields + state protoimpl.MessageState sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields } func (x *ShutdownRequest) Reset() { *x = ShutdownRequest{} - mi := &file_internal_locald_api_sandboxmanager_sandbox_manager_api_proto_msgTypes[2] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) + if protoimpl.UnsafeEnabled { + mi := &file_internal_locald_api_sandboxmanager_sandbox_manager_api_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } func (x *ShutdownRequest) String() string { @@ -182,7 +196,7 @@ func (*ShutdownRequest) ProtoMessage() {} func (x *ShutdownRequest) ProtoReflect() protoreflect.Message { mi := &file_internal_locald_api_sandboxmanager_sandbox_manager_api_proto_msgTypes[2] - if x != nil { + if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -198,16 +212,18 @@ func (*ShutdownRequest) Descriptor() ([]byte, []int) { } type ShutdownResponse struct { - state protoimpl.MessageState `protogen:"open.v1"` - unknownFields protoimpl.UnknownFields + state protoimpl.MessageState sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields } func (x *ShutdownResponse) Reset() { *x = ShutdownResponse{} - mi := &file_internal_locald_api_sandboxmanager_sandbox_manager_api_proto_msgTypes[3] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) + if protoimpl.UnsafeEnabled { + mi := &file_internal_locald_api_sandboxmanager_sandbox_manager_api_proto_msgTypes[3] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } func (x *ShutdownResponse) String() string { @@ -218,7 +234,7 @@ func (*ShutdownResponse) ProtoMessage() {} func (x *ShutdownResponse) ProtoReflect() protoreflect.Message { mi := &file_internal_locald_api_sandboxmanager_sandbox_manager_api_proto_msgTypes[3] - if x != nil { + if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -234,18 +250,21 @@ func (*ShutdownResponse) Descriptor() ([]byte, []int) { } type RegisterSandboxRequest struct { - state protoimpl.MessageState `protogen:"open.v1"` - SandboxName string `protobuf:"bytes,1,opt,name=sandbox_name,json=sandboxName,proto3" json:"sandbox_name,omitempty"` - RoutingKey string `protobuf:"bytes,2,opt,name=routing_key,json=routingKey,proto3" json:"routing_key,omitempty"` - unknownFields protoimpl.UnknownFields + state protoimpl.MessageState sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + SandboxName string `protobuf:"bytes,1,opt,name=sandbox_name,json=sandboxName,proto3" json:"sandbox_name,omitempty"` + RoutingKey string `protobuf:"bytes,2,opt,name=routing_key,json=routingKey,proto3" json:"routing_key,omitempty"` } func (x *RegisterSandboxRequest) Reset() { *x = RegisterSandboxRequest{} - mi := &file_internal_locald_api_sandboxmanager_sandbox_manager_api_proto_msgTypes[4] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) + if protoimpl.UnsafeEnabled { + mi := &file_internal_locald_api_sandboxmanager_sandbox_manager_api_proto_msgTypes[4] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } func (x *RegisterSandboxRequest) String() string { @@ -256,7 +275,7 @@ func (*RegisterSandboxRequest) ProtoMessage() {} func (x *RegisterSandboxRequest) ProtoReflect() protoreflect.Message { mi := &file_internal_locald_api_sandboxmanager_sandbox_manager_api_proto_msgTypes[4] - if x != nil { + if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -286,16 +305,18 @@ func (x *RegisterSandboxRequest) GetRoutingKey() string { } type RegisterSandboxResponse struct { - state protoimpl.MessageState `protogen:"open.v1"` - unknownFields protoimpl.UnknownFields + state protoimpl.MessageState sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields } func (x *RegisterSandboxResponse) Reset() { *x = RegisterSandboxResponse{} - mi := &file_internal_locald_api_sandboxmanager_sandbox_manager_api_proto_msgTypes[5] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) + if protoimpl.UnsafeEnabled { + mi := &file_internal_locald_api_sandboxmanager_sandbox_manager_api_proto_msgTypes[5] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } func (x *RegisterSandboxResponse) String() string { @@ -306,7 +327,7 @@ func (*RegisterSandboxResponse) ProtoMessage() {} func (x *RegisterSandboxResponse) ProtoReflect() protoreflect.Message { mi := &file_internal_locald_api_sandboxmanager_sandbox_manager_api_proto_msgTypes[5] - if x != nil { + if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -324,17 +345,20 @@ func (*RegisterSandboxResponse) Descriptor() ([]byte, []int) { // Resource outputs // --------------------------------------------------------------------------- type GetResourceOutputsRequest struct { - state protoimpl.MessageState `protogen:"open.v1"` - SandboxRoutingKey string `protobuf:"bytes,1,opt,name=sandbox_routing_key,json=sandboxRoutingKey,proto3" json:"sandbox_routing_key,omitempty"` - unknownFields protoimpl.UnknownFields - sizeCache protoimpl.SizeCache + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + SandboxRoutingKey string `protobuf:"bytes,1,opt,name=sandbox_routing_key,json=sandboxRoutingKey,proto3" json:"sandbox_routing_key,omitempty"` } func (x *GetResourceOutputsRequest) Reset() { *x = GetResourceOutputsRequest{} - mi := &file_internal_locald_api_sandboxmanager_sandbox_manager_api_proto_msgTypes[6] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) + if protoimpl.UnsafeEnabled { + mi := &file_internal_locald_api_sandboxmanager_sandbox_manager_api_proto_msgTypes[6] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } func (x *GetResourceOutputsRequest) String() string { @@ -345,7 +369,7 @@ func (*GetResourceOutputsRequest) ProtoMessage() {} func (x *GetResourceOutputsRequest) ProtoReflect() protoreflect.Message { mi := &file_internal_locald_api_sandboxmanager_sandbox_manager_api_proto_msgTypes[6] - if x != nil { + if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -368,17 +392,20 @@ func (x *GetResourceOutputsRequest) GetSandboxRoutingKey() string { } type GetResourceOutputsResponse struct { - state protoimpl.MessageState `protogen:"open.v1"` - ResourceOutputs []*ResourceOutputs `protobuf:"bytes,1,rep,name=resource_outputs,json=resourceOutputs,proto3" json:"resource_outputs,omitempty"` - unknownFields protoimpl.UnknownFields - sizeCache protoimpl.SizeCache + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + ResourceOutputs []*ResourceOutputs `protobuf:"bytes,1,rep,name=resource_outputs,json=resourceOutputs,proto3" json:"resource_outputs,omitempty"` } func (x *GetResourceOutputsResponse) Reset() { *x = GetResourceOutputsResponse{} - mi := &file_internal_locald_api_sandboxmanager_sandbox_manager_api_proto_msgTypes[7] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) + if protoimpl.UnsafeEnabled { + mi := &file_internal_locald_api_sandboxmanager_sandbox_manager_api_proto_msgTypes[7] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } func (x *GetResourceOutputsResponse) String() string { @@ -389,7 +416,7 @@ func (*GetResourceOutputsResponse) ProtoMessage() {} func (x *GetResourceOutputsResponse) ProtoReflect() protoreflect.Message { mi := &file_internal_locald_api_sandboxmanager_sandbox_manager_api_proto_msgTypes[7] - if x != nil { + if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -412,18 +439,21 @@ func (x *GetResourceOutputsResponse) GetResourceOutputs() []*ResourceOutputs { } type ResourceOutputs struct { - state protoimpl.MessageState `protogen:"open.v1"` - ResourceName string `protobuf:"bytes,1,opt,name=resource_name,json=resourceName,proto3" json:"resource_name,omitempty"` - Outputs []*ResourceOutputItem `protobuf:"bytes,2,rep,name=outputs,proto3" json:"outputs,omitempty"` - unknownFields protoimpl.UnknownFields + state protoimpl.MessageState sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + ResourceName string `protobuf:"bytes,1,opt,name=resource_name,json=resourceName,proto3" json:"resource_name,omitempty"` + Outputs []*ResourceOutputItem `protobuf:"bytes,2,rep,name=outputs,proto3" json:"outputs,omitempty"` } func (x *ResourceOutputs) Reset() { *x = ResourceOutputs{} - mi := &file_internal_locald_api_sandboxmanager_sandbox_manager_api_proto_msgTypes[8] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) + if protoimpl.UnsafeEnabled { + mi := &file_internal_locald_api_sandboxmanager_sandbox_manager_api_proto_msgTypes[8] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } func (x *ResourceOutputs) String() string { @@ -434,7 +464,7 @@ func (*ResourceOutputs) ProtoMessage() {} func (x *ResourceOutputs) ProtoReflect() protoreflect.Message { mi := &file_internal_locald_api_sandboxmanager_sandbox_manager_api_proto_msgTypes[8] - if x != nil { + if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -464,18 +494,21 @@ func (x *ResourceOutputs) GetOutputs() []*ResourceOutputItem { } type ResourceOutputItem struct { - state protoimpl.MessageState `protogen:"open.v1"` - Key string `protobuf:"bytes,1,opt,name=key,proto3" json:"key,omitempty"` - Value string `protobuf:"bytes,2,opt,name=value,proto3" json:"value,omitempty"` - unknownFields protoimpl.UnknownFields + state protoimpl.MessageState sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Key string `protobuf:"bytes,1,opt,name=key,proto3" json:"key,omitempty"` + Value string `protobuf:"bytes,2,opt,name=value,proto3" json:"value,omitempty"` } func (x *ResourceOutputItem) Reset() { *x = ResourceOutputItem{} - mi := &file_internal_locald_api_sandboxmanager_sandbox_manager_api_proto_msgTypes[9] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) + if protoimpl.UnsafeEnabled { + mi := &file_internal_locald_api_sandboxmanager_sandbox_manager_api_proto_msgTypes[9] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } func (x *ResourceOutputItem) String() string { @@ -486,7 +519,7 @@ func (*ResourceOutputItem) ProtoMessage() {} func (x *ResourceOutputItem) ProtoReflect() protoreflect.Message { mi := &file_internal_locald_api_sandboxmanager_sandbox_manager_api_proto_msgTypes[9] - if x != nil { + if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -517,56 +550,130 @@ func (x *ResourceOutputItem) GetValue() string { var File_internal_locald_api_sandboxmanager_sandbox_manager_api_proto protoreflect.FileDescriptor -const file_internal_locald_api_sandboxmanager_sandbox_manager_api_proto_rawDesc = "" + - "\n" + - "\n" + - "\vportforward\x18\x04 \x01(\v2\x1c.apicommon.PortForwardStatusR\vportforward\x12R\n" + - "\x13control_plane_proxy\x18\b \x01(\v2\".apicommon.ControlPlaneProxyStatusR\x11controlPlaneProxy\x122\n" + - "\awatcher\x18\x06 \x01(\v2\x18.apicommon.WatcherStatusR\awatcher\x126\n" + - "\tsandboxes\x18\x05 \x03(\v2\x18.apicommon.SandboxStatusR\tsandboxes\"\x11\n" + - "\x0fShutdownRequest\"\x12\n" + - "\x10ShutdownResponse\"\\\n" + - "\x16RegisterSandboxRequest\x12!\n" + - "\fsandbox_name\x18\x01 \x01(\tR\vsandboxName\x12\x1f\n" + - "\vrouting_key\x18\x02 \x01(\tR\n" + - "routingKey\"\x19\n" + - "\x17RegisterSandboxResponse\"K\n" + - "\x19GetResourceOutputsRequest\x12.\n" + - "\x13sandbox_routing_key\x18\x01 \x01(\tR\x11sandboxRoutingKey\"h\n" + - "\x1aGetResourceOutputsResponse\x12J\n" + - "\x10resource_outputs\x18\x01 \x03(\v2\x1f.sandboxmanager.ResourceOutputsR\x0fresourceOutputs\"t\n" + - "\x0fResourceOutputs\x12#\n" + - "\rresource_name\x18\x01 \x01(\tR\fresourceName\x12<\n" + - "\aoutputs\x18\x02 \x03(\v2\".sandboxmanager.ResourceOutputItemR\aoutputs\"<\n" + - "\x12ResourceOutputItem\x12\x10\n" + - "\x03key\x18\x01 \x01(\tR\x03key\x12\x14\n" + - "\x05value\x18\x02 \x01(\tR\x05value2\x84\x03\n" + - "\x11SandboxManagerAPI\x12I\n" + - "\x06Status\x12\x1d.sandboxmanager.StatusRequest\x1a\x1e.sandboxmanager.StatusResponse\"\x00\x12O\n" + - "\bShutdown\x12\x1f.sandboxmanager.ShutdownRequest\x1a .sandboxmanager.ShutdownResponse\"\x00\x12d\n" + - "\x0fRegisterSandbox\x12&.sandboxmanager.RegisterSandboxRequest\x1a'.sandboxmanager.RegisterSandboxResponse\"\x00\x12m\n" + - "\x12GetResourceOutputs\x12).sandboxmanager.GetResourceOutputsRequest\x1a*.sandboxmanager.GetResourceOutputsResponse\"\x00B google.protobuf.Struct @@ -595,21 +703,22 @@ var file_internal_locald_api_sandboxmanager_sandbox_manager_api_proto_depIdxs = 15, // 5: sandboxmanager.StatusResponse.control_plane_proxy:type_name -> apicommon.ControlPlaneProxyStatus 16, // 6: sandboxmanager.StatusResponse.watcher:type_name -> apicommon.WatcherStatus 17, // 7: sandboxmanager.StatusResponse.sandboxes:type_name -> apicommon.SandboxStatus - 8, // 8: sandboxmanager.GetResourceOutputsResponse.resource_outputs:type_name -> sandboxmanager.ResourceOutputs - 9, // 9: sandboxmanager.ResourceOutputs.outputs:type_name -> sandboxmanager.ResourceOutputItem - 0, // 10: sandboxmanager.SandboxManagerAPI.Status:input_type -> sandboxmanager.StatusRequest - 2, // 11: sandboxmanager.SandboxManagerAPI.Shutdown:input_type -> sandboxmanager.ShutdownRequest - 4, // 12: sandboxmanager.SandboxManagerAPI.RegisterSandbox:input_type -> sandboxmanager.RegisterSandboxRequest - 6, // 13: sandboxmanager.SandboxManagerAPI.GetResourceOutputs:input_type -> sandboxmanager.GetResourceOutputsRequest - 1, // 14: sandboxmanager.SandboxManagerAPI.Status:output_type -> sandboxmanager.StatusResponse - 3, // 15: sandboxmanager.SandboxManagerAPI.Shutdown:output_type -> sandboxmanager.ShutdownResponse - 5, // 16: sandboxmanager.SandboxManagerAPI.RegisterSandbox:output_type -> sandboxmanager.RegisterSandboxResponse - 7, // 17: sandboxmanager.SandboxManagerAPI.GetResourceOutputs:output_type -> sandboxmanager.GetResourceOutputsResponse - 14, // [14:18] is the sub-list for method output_type - 10, // [10:14] is the sub-list for method input_type - 10, // [10:10] is the sub-list for extension type_name - 10, // [10:10] is the sub-list for extension extendee - 0, // [0:10] is the sub-list for field type_name + 18, // 8: sandboxmanager.StatusResponse.devbox_session:type_name -> apicommon.DevboxSessionStatus + 8, // 9: sandboxmanager.GetResourceOutputsResponse.resource_outputs:type_name -> sandboxmanager.ResourceOutputs + 9, // 10: sandboxmanager.ResourceOutputs.outputs:type_name -> sandboxmanager.ResourceOutputItem + 0, // 11: sandboxmanager.SandboxManagerAPI.Status:input_type -> sandboxmanager.StatusRequest + 2, // 12: sandboxmanager.SandboxManagerAPI.Shutdown:input_type -> sandboxmanager.ShutdownRequest + 4, // 13: sandboxmanager.SandboxManagerAPI.RegisterSandbox:input_type -> sandboxmanager.RegisterSandboxRequest + 6, // 14: sandboxmanager.SandboxManagerAPI.GetResourceOutputs:input_type -> sandboxmanager.GetResourceOutputsRequest + 1, // 15: sandboxmanager.SandboxManagerAPI.Status:output_type -> sandboxmanager.StatusResponse + 3, // 16: sandboxmanager.SandboxManagerAPI.Shutdown:output_type -> sandboxmanager.ShutdownResponse + 5, // 17: sandboxmanager.SandboxManagerAPI.RegisterSandbox:output_type -> sandboxmanager.RegisterSandboxResponse + 7, // 18: sandboxmanager.SandboxManagerAPI.GetResourceOutputs:output_type -> sandboxmanager.GetResourceOutputsResponse + 15, // [15:19] is the sub-list for method output_type + 11, // [11:15] is the sub-list for method input_type + 11, // [11:11] is the sub-list for extension type_name + 11, // [11:11] is the sub-list for extension extendee + 0, // [0:11] is the sub-list for field type_name } func init() { file_internal_locald_api_sandboxmanager_sandbox_manager_api_proto_init() } @@ -617,11 +726,133 @@ func file_internal_locald_api_sandboxmanager_sandbox_manager_api_proto_init() { if File_internal_locald_api_sandboxmanager_sandbox_manager_api_proto != nil { return } + if !protoimpl.UnsafeEnabled { + file_internal_locald_api_sandboxmanager_sandbox_manager_api_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*StatusRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_internal_locald_api_sandboxmanager_sandbox_manager_api_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*StatusResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_internal_locald_api_sandboxmanager_sandbox_manager_api_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ShutdownRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_internal_locald_api_sandboxmanager_sandbox_manager_api_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ShutdownResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_internal_locald_api_sandboxmanager_sandbox_manager_api_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*RegisterSandboxRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_internal_locald_api_sandboxmanager_sandbox_manager_api_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*RegisterSandboxResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_internal_locald_api_sandboxmanager_sandbox_manager_api_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GetResourceOutputsRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_internal_locald_api_sandboxmanager_sandbox_manager_api_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GetResourceOutputsResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_internal_locald_api_sandboxmanager_sandbox_manager_api_proto_msgTypes[8].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ResourceOutputs); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_internal_locald_api_sandboxmanager_sandbox_manager_api_proto_msgTypes[9].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ResourceOutputItem); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + } type x struct{} out := protoimpl.TypeBuilder{ File: protoimpl.DescBuilder{ GoPackagePath: reflect.TypeOf(x{}).PkgPath(), - RawDescriptor: unsafe.Slice(unsafe.StringData(file_internal_locald_api_sandboxmanager_sandbox_manager_api_proto_rawDesc), len(file_internal_locald_api_sandboxmanager_sandbox_manager_api_proto_rawDesc)), + RawDescriptor: file_internal_locald_api_sandboxmanager_sandbox_manager_api_proto_rawDesc, NumEnums: 0, NumMessages: 10, NumExtensions: 0, @@ -632,6 +863,7 @@ func file_internal_locald_api_sandboxmanager_sandbox_manager_api_proto_init() { MessageInfos: file_internal_locald_api_sandboxmanager_sandbox_manager_api_proto_msgTypes, }.Build() File_internal_locald_api_sandboxmanager_sandbox_manager_api_proto = out.File + file_internal_locald_api_sandboxmanager_sandbox_manager_api_proto_rawDesc = nil file_internal_locald_api_sandboxmanager_sandbox_manager_api_proto_goTypes = nil file_internal_locald_api_sandboxmanager_sandbox_manager_api_proto_depIdxs = nil } diff --git a/internal/locald/api/sandboxmanager/sandbox_manager_api.proto b/internal/locald/api/sandboxmanager/sandbox_manager_api.proto index daa4a3ae..95ca8303 100644 --- a/internal/locald/api/sandboxmanager/sandbox_manager_api.proto +++ b/internal/locald/api/sandboxmanager/sandbox_manager_api.proto @@ -42,6 +42,7 @@ message StatusResponse { apicommon.ControlPlaneProxyStatus control_plane_proxy = 8; apicommon.WatcherStatus watcher = 6; repeated apicommon.SandboxStatus sandboxes = 5; + apicommon.DevboxSessionStatus devbox_session = 9; } // Shutdown diff --git a/internal/locald/api/sandboxmanager/sandbox_manager_api_grpc.pb.go b/internal/locald/api/sandboxmanager/sandbox_manager_api_grpc.pb.go index c99b2aa2..ea725bf0 100644 --- a/internal/locald/api/sandboxmanager/sandbox_manager_api_grpc.pb.go +++ b/internal/locald/api/sandboxmanager/sandbox_manager_api_grpc.pb.go @@ -1,8 +1,4 @@ // Code generated by protoc-gen-go-grpc. DO NOT EDIT. -// versions: -// - protoc-gen-go-grpc v1.2.0 -// - protoc v3.21.12 -// source: internal/locald/api/sandboxmanager/sandbox_manager_api.proto package sandboxmanager diff --git a/internal/locald/rootmanager/sbmgr_monitor.go b/internal/locald/rootmanager/sbmgr_monitor.go index 9f910a01..e5743eef 100644 --- a/internal/locald/rootmanager/sbmgr_monitor.go +++ b/internal/locald/rootmanager/sbmgr_monitor.go @@ -104,6 +104,11 @@ func (mon *sbmgrMonitor) run() { goto tick } mon.setProcInfo(procDone, procPID) + + // Check status periodically while process is running + // If session is released, stop monitoring (don't restart) + go mon.checkStatusLoop(procDone) + select { case <-procDone: case <-mon.done: @@ -186,3 +191,57 @@ func (mon *sbmgrMonitor) stop() error { return nil } + +// checkStatusLoop periodically checks sandbox manager status while it's running +// If session is released, stops the monitor to prevent restart +func (mon *sbmgrMonitor) checkStatusLoop(procDone <-chan struct{}) { + ticker := time.NewTicker(5 * time.Second) + defer ticker.Stop() + + for { + select { + case <-procDone: + // Process exited, stop checking + return + case <-mon.done: + // Monitor is stopping + return + case <-ticker.C: + // Check status + if mon.checkSessionReleased() { + mon.log.Info("Devbox session was released, stopping sandbox manager monitor") + close(mon.done) + return + } + } + } +} + +// checkSessionReleased checks if the sandbox manager reports session_released +func (mon *sbmgrMonitor) checkSessionReleased() bool { + // Try to connect to sandbox manager + grpcConn, err := grpc.NewClient("127.0.0.1:6666", grpc.WithTransportCredentials(insecure.NewCredentials())) + if err != nil { + // Can't connect, assume not released (process might be starting) + return false + } + defer grpcConn.Close() + + // Get status + sbManagerClient := sbmapi.NewSandboxManagerAPIClient(grpcConn) + ctx, cancel := context.WithTimeout(context.Background(), 2*time.Second) + defer cancel() + + status, err := sbManagerClient.Status(ctx, &sbmapi.StatusRequest{}) + if err != nil { + // Can't get status, assume not released + return false + } + + // Check if session is released + if status.DevboxSession != nil && status.DevboxSession.SessionReleased { + return true + } + + return false +} diff --git a/internal/locald/sandboxmanager/sandbox_manager.go b/internal/locald/sandboxmanager/sandbox_manager.go index 3b1e645b..bc865853 100644 --- a/internal/locald/sandboxmanager/sandbox_manager.go +++ b/internal/locald/sandboxmanager/sandbox_manager.go @@ -8,13 +8,15 @@ import ( "os" "os/signal" "syscall" + "time" "log/slog" "github.com/signadot/cli/internal/auth" "github.com/signadot/cli/internal/config" + "github.com/signadot/cli/internal/devbox" + rootapi "github.com/signadot/cli/internal/locald/api/rootmanager" sbapi "github.com/signadot/cli/internal/locald/api/sandboxmanager" - "github.com/signadot/cli/internal/utils/system" "github.com/signadot/go-sdk/transport" tunapiclient "github.com/signadot/libconnect/common/apiclient" "github.com/signadot/libconnect/common/controlplaneproxy" @@ -37,7 +39,6 @@ type sandboxManager struct { ciConfig *config.ConnectInvocationConfig connConfig *connectcfg.ConnectionConfig hostname string - machineID string grpcServer *grpc.Server portForward *portforward.PortForward ctlPlaneProxy *controlplaneproxy.Proxy @@ -46,6 +47,13 @@ type sandboxManager struct { // tunnel API tunAPIClient tunapiclient.Client proxyAddress string + + // devbox session management + devboxSessionMgr *devbox.SessionManager + + // session released state (deadend mode) + sessionReleased bool + sbmServer *sbmServer } func NewSandboxManager(cfg *config.LocalDaemon, args []string, log *slog.Logger) (*sandboxManager, error) { @@ -58,22 +66,22 @@ func NewSandboxManager(cfg *config.LocalDaemon, args []string, log *slog.Logger) return nil, err } - // Resolve the machine ID - machineID, err := system.GetMachineID() + ciConfig := cfg.ConnectInvocationConfig + + // Create devbox session manager + devboxSessionMgr, err := devbox.NewSessionManager(log, ciConfig, shutdownCh) if err != nil { - return nil, err + return nil, fmt.Errorf("failed to create devbox session manager: %w", err) } - ciConfig := cfg.ConnectInvocationConfig - return &sandboxManager{ - log: log, - ciConfig: ciConfig, - connConfig: ciConfig.ConnectionConfig, - hostname: hostname, - machineID: machineID, - grpcServer: grpcServer, - shutdownCh: shutdownCh, + log: log, + ciConfig: ciConfig, + connConfig: ciConfig.ConnectionConfig, + hostname: hostname, + grpcServer: grpcServer, + shutdownCh: shutdownCh, + devboxSessionMgr: devboxSessionMgr, }, nil } @@ -148,12 +156,12 @@ func (m *sandboxManager) Run(ctx context.Context) error { } // Create the watcher - sbmWatcher := newSandboxManagerWatcher(m.log, m.machineID, m.revtunClient, oiu, m.shutdownCh) + sbmWatcher := newSandboxManagerWatcher(m.log, m.ciConfig.DevboxSessionID, m.revtunClient, oiu, m.shutdownCh) // Register our service in gRPC server - sbmServer := newSandboxManagerGRPCServer(m.log, m.ciConfig, m.portForward, m.ctlPlaneProxy, - sbmWatcher, oiu, m.shutdownCh) - sbapi.RegisterSandboxManagerAPIServer(m.grpcServer, sbmServer) + m.sbmServer = newSandboxManagerGRPCServer(m.log, m.ciConfig, m.portForward, m.ctlPlaneProxy, + sbmWatcher, oiu, m.shutdownCh, m.devboxSessionMgr) + sbapi.RegisterSandboxManagerAPIServer(m.grpcServer, m.sbmServer) // Run the gRPC server if err := m.runAPIServer(); err != nil { @@ -194,16 +202,42 @@ func (m *sandboxManager) Run(ctx context.Context) error { } } + // Start devbox session manager + m.devboxSessionMgr.Start(runCtx) + // Run the sandboxes watcher sbmWatcher.run(runCtx, m.tunAPIClient) // Wait until termination <-runCtx.Done() - // Clean up + // Check if shutdown was triggered by devbox session release + if m.devboxSessionMgr.WasSessionReleased() { + m.log.Info("Devbox session was released, entering deadend state") + m.sessionReleased = true + + // Shutdown root manager (tunnel, localnet, etchosts) + m.shutdownRootManager() + + // Stop all active work but keep gRPC server running + sbmWatcher.stop() + m.devboxSessionMgr.Stop(ctx) + if m.portForward != nil { + m.portForward.Close() + } else if m.ctlPlaneProxy != nil { + m.ctlPlaneProxy.Close(ctx) + } + + // Keep gRPC server running in deadend state + // Wait forever (until process is killed externally) + select {} + } + + // Normal shutdown m.log.Info("Shutting down") m.grpcServer.GracefulStop() sbmWatcher.stop() + m.devboxSessionMgr.Stop(ctx) if m.portForward != nil { m.portForward.Close() } else if m.ctlPlaneProxy != nil { @@ -260,3 +294,23 @@ func (m *sandboxManager) revtunClient() revtun.Client { panic(fmt.Errorf("invalid inbound protocol: %s", m.connConfig.Inbound.Protocol)) } } + +// shutdownRootManager calls the root manager's Shutdown API to shut down tunnel and services +func (m *sandboxManager) shutdownRootManager() { + if m.sbmServer == nil { + return + } + rootClient := m.sbmServer.getRootClient() + if rootClient == nil { + m.log.Warn("Could not get root manager client to shutdown") + return + } + shutdownCtx, cancel := context.WithTimeout(context.Background(), 10*time.Second) + defer cancel() + _, err := rootClient.Shutdown(shutdownCtx, &rootapi.ShutdownRequest{}) + if err != nil { + m.log.Warn("Failed to shutdown root manager", "error", err) + } else { + m.log.Info("Root manager shutdown requested") + } +} diff --git a/internal/locald/sandboxmanager/sandbox_server.go b/internal/locald/sandboxmanager/sandbox_server.go index f49482be..64c7803f 100644 --- a/internal/locald/sandboxmanager/sandbox_server.go +++ b/internal/locald/sandboxmanager/sandbox_server.go @@ -9,6 +9,7 @@ import ( "log/slog" "github.com/signadot/cli/internal/config" + "github.com/signadot/cli/internal/devbox" commonapi "github.com/signadot/cli/internal/locald/api" rootapi "github.com/signadot/cli/internal/locald/api/rootmanager" sbapi "github.com/signadot/cli/internal/locald/api/sandboxmanager" @@ -19,6 +20,7 @@ import ( "google.golang.org/grpc/codes" "google.golang.org/grpc/credentials/insecure" "google.golang.org/grpc/status" + "google.golang.org/protobuf/types/known/timestamppb" ) type sbmServer struct { @@ -45,20 +47,24 @@ type sbmServer struct { // shutdown shutdownCh chan struct{} + + // devbox session manager + devboxSessionMgr *devbox.SessionManager } func newSandboxManagerGRPCServer(log *slog.Logger, ciConfig *config.ConnectInvocationConfig, portForward *portforward.PortForward, ctlPlaneProxy *controlplaneproxy.Proxy, sbmWatcher *sbmWatcher, oiu *operatorInfoUpdater, - shutdownCh chan struct{}) *sbmServer { + shutdownCh chan struct{}, devboxSessionMgr *devbox.SessionManager) *sbmServer { srv := &sbmServer{ - log: log, - oiu: oiu, - ciConfig: ciConfig, - portForward: portForward, - ctlPlaneProxy: ctlPlaneProxy, - sbmWatcher: sbmWatcher, - shutdownCh: shutdownCh, + log: log, + oiu: oiu, + ciConfig: ciConfig, + portForward: portForward, + ctlPlaneProxy: ctlPlaneProxy, + sbmWatcher: sbmWatcher, + shutdownCh: shutdownCh, + devboxSessionMgr: devboxSessionMgr, } return srv } @@ -79,6 +85,7 @@ func (s *sbmServer) Status(ctx context.Context, req *sbapi.StatusRequest) (*sbap ControlPlaneProxy: s.controlPlaneProxyStatus(), Watcher: s.watcherStatus(), Sandboxes: s.sbStatuses(), + DevboxSession: s.devboxSessionStatus(), } resp.Hosts, resp.Localnet = s.rootStatus() return resp, nil @@ -198,6 +205,32 @@ func (s *sbmServer) watcherStatus() *commonapi.WatcherStatus { } } +func (s *sbmServer) devboxSessionStatus() *commonapi.DevboxSessionStatus { + if s.devboxSessionMgr == nil { + return &commonapi.DevboxSessionStatus{ + Healthy: false, + } + } + + healthy, sessionReleased, devboxID, sessionID, lastError, lastErrorTime := s.devboxSessionMgr.GetStatus() + + status := &commonapi.DevboxSessionStatus{ + Healthy: healthy && !sessionReleased, + SessionReleased: sessionReleased, + DevboxId: devboxID, + SessionId: sessionID, + } + + if lastError != nil { + status.LastErrorReason = lastError.Error() + if !lastErrorTime.IsZero() { + status.LastErrorTime = timestamppb.New(lastErrorTime) + } + } + + return status +} + func (s *sbmServer) sbStatuses() []*commonapi.SandboxStatus { sandboxes := s.sbmWatcher.getSandboxes() diff --git a/internal/locald/sandboxmanager/sandboxes_watcher.go b/internal/locald/sandboxmanager/sandboxes_watcher.go index f5d6a2e4..0a5098e1 100644 --- a/internal/locald/sandboxmanager/sandboxes_watcher.go +++ b/internal/locald/sandboxmanager/sandboxes_watcher.go @@ -23,7 +23,7 @@ type sbmWatcher struct { log *slog.Logger oiu *operatorInfoUpdater - machineID string + devboxSessionID string // sandbox controllers sbMu sync.Mutex @@ -37,12 +37,12 @@ type sbmWatcher struct { shutdownCh chan struct{} } -func newSandboxManagerWatcher(log *slog.Logger, machineID string, revtunClient func() revtun.Client, +func newSandboxManagerWatcher(log *slog.Logger, devboxSessionID string, revtunClient func() revtun.Client, oiu *operatorInfoUpdater, shutdownCh chan struct{}) *sbmWatcher { srv := &sbmWatcher{ - log: log, - oiu: oiu, - machineID: machineID, + log: log, + oiu: oiu, + devboxSessionID: devboxSessionID, status: svchealth.ServiceHealth{ Healthy: false, LastErrorReason: "Starting", @@ -64,7 +64,7 @@ func (sbw *sbmWatcher) watchSandboxes(ctx context.Context, tunAPIClient tunapicl // watch loop for { sbwClient, err := tunAPIClient.WatchLocalSandboxes(ctx, &tunapiv1.WatchLocalSandboxesRequest{ - MachineId: sbw.machineID, + MachineId: sbw.devboxSessionID, }) if err != nil { // don't retry if the context has been cancelled diff --git a/internal/locald/sandboxmanager/sdk.go b/internal/locald/sandboxmanager/sdk.go index b2f40db0..84fb4982 100644 --- a/internal/locald/sandboxmanager/sdk.go +++ b/internal/locald/sandboxmanager/sdk.go @@ -209,7 +209,7 @@ func connectSandboxManager() (*grpc.ClientConn, error) { } // ValidateSandboxManager validates that sandboxmanager is running, connected to the right cluster, -// and returns the status and a sandbox with machine ID set if needed. +// and returns the status and a sandbox with devbox session ID set if needed. // This function is useful for operations that require local sandbox functionality. func ValidateSandboxManager(expectedCluster *string) (*sbmapi.StatusResponse, error) { // Get sandboxmanager status