Skip to content

Commit

Permalink
feat: server IP configuration
Browse files Browse the repository at this point in the history
If the server is running in a network with a static IP it can be directly accessed from the CLI and workspaces

Signed-off-by: Toma Puljak <[email protected]>
  • Loading branch information
Tpuljak committed Jun 26, 2024
1 parent c8b9757 commit f7a4bf4
Show file tree
Hide file tree
Showing 17 changed files with 204 additions and 48 deletions.
44 changes: 44 additions & 0 deletions internal/util/apiclient/conversion/server_config.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
// Copyright 2024 Daytona Platforms Inc.
// SPDX-License-Identifier: Apache-2.0

package conversion

import (
"github.com/daytonaio/daytona/pkg/apiclient"
"github.com/daytonaio/daytona/pkg/server"
)

func ToServerConfig(serverConfigDto *apiclient.ServerConfig) *server.Config {
if serverConfigDto == nil {
return nil
}

config := &server.Config{
Id: *serverConfigDto.Id,
ProvidersDir: *serverConfigDto.ProvidersDir,
RegistryUrl: *serverConfigDto.RegistryUrl,
ServerDownloadUrl: *serverConfigDto.ServerDownloadUrl,
IpWithProtocol: serverConfigDto.IpWithProtocol,
ApiPort: uint32(*serverConfigDto.ApiPort),
LocalBuilderRegistryPort: uint32(*serverConfigDto.LocalBuilderRegistryPort),
BuilderRegistryServer: *serverConfigDto.BuilderRegistryServer,
BuildImageNamespace: *serverConfigDto.BuildImageNamespace,
HeadscalePort: uint32(*serverConfigDto.HeadscalePort),
BinariesPath: *serverConfigDto.BinariesPath,
LogFilePath: *serverConfigDto.LogFilePath,
DefaultProjectImage: *serverConfigDto.DefaultProjectImage,
DefaultProjectUser: *serverConfigDto.DefaultProjectUser,
DefaultProjectPostStartCommands: serverConfigDto.DefaultProjectPostStartCommands,
BuilderImage: *serverConfigDto.BuilderImage,
}

if serverConfigDto.Frps != nil {
config.Frps = &server.FRPSConfig{
Domain: *serverConfigDto.Frps.Domain,
Port: uint32(*serverConfigDto.Frps.Port),
Protocol: *serverConfigDto.Frps.Protocol,
}
}

return config
}
11 changes: 6 additions & 5 deletions pkg/api/controllers/binary/get_daytona.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,22 +4,23 @@
package binary

import (
"fmt"
"net/http"
"net/url"

"github.com/daytonaio/daytona/internal/constants"
"github.com/daytonaio/daytona/pkg/server"
"github.com/gin-gonic/gin"
)

// Used in projects to download the Daytona binary
func GetDaytonaScript(ctx *gin.Context) {
scheme := "http"
if ctx.Request.TLS != nil || ctx.GetHeader("X-Forwarded-Proto") == "https" {
scheme = "https"
c, err := server.GetConfig()
if err != nil {
ctx.String(http.StatusInternalServerError, err.Error())
return
}

downloadUrl, _ := url.JoinPath(fmt.Sprintf("%s://%s", scheme, ctx.Request.Host), "binary")
downloadUrl, _ := url.JoinPath(c.GetApiUrl(), "binary")
getServerScript := constants.GetDaytonaScript(downloadUrl)

ctx.String(http.StatusOK, getServerScript)
Expand Down
3 changes: 3 additions & 0 deletions pkg/api/docs/docs.go
Original file line number Diff line number Diff line change
Expand Up @@ -1569,6 +1569,9 @@ const docTemplate = `{
"id": {
"type": "string"
},
"ipWithProtocol": {
"type": "string"
},
"localBuilderRegistryPort": {
"type": "integer"
},
Expand Down
3 changes: 3 additions & 0 deletions pkg/api/docs/swagger.json
Original file line number Diff line number Diff line change
Expand Up @@ -1566,6 +1566,9 @@
"id": {
"type": "string"
},
"ipWithProtocol": {
"type": "string"
},
"localBuilderRegistryPort": {
"type": "integer"
},
Expand Down
2 changes: 2 additions & 0 deletions pkg/api/docs/swagger.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -292,6 +292,8 @@ definitions:
type: integer
id:
type: string
ipWithProtocol:
type: string
localBuilderRegistryPort:
type: integer
logFilePath:
Expand Down
3 changes: 3 additions & 0 deletions pkg/apiclient/api/openapi.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -1306,6 +1306,7 @@ components:
apiPort: 0
headscalePort: 1
buildImageNamespace: buildImageNamespace
ipWithProtocol: ipWithProtocol
serverDownloadUrl: serverDownloadUrl
binariesPath: binariesPath
logFilePath: logFilePath
Expand Down Expand Up @@ -1341,6 +1342,8 @@ components:
type: integer
id:
type: string
ipWithProtocol:
type: string
localBuilderRegistryPort:
type: integer
logFilePath:
Expand Down
26 changes: 26 additions & 0 deletions pkg/apiclient/docs/ServerConfig.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ Name | Type | Description | Notes
**Frps** | Pointer to [**FRPSConfig**](FRPSConfig.md) | | [optional]
**HeadscalePort** | Pointer to **int32** | | [optional]
**Id** | Pointer to **string** | | [optional]
**IpWithProtocol** | Pointer to **string** | | [optional]
**LocalBuilderRegistryPort** | Pointer to **int32** | | [optional]
**LogFilePath** | Pointer to **string** | | [optional]
**ProvidersDir** | Pointer to **string** | | [optional]
Expand Down Expand Up @@ -315,6 +316,31 @@ SetId sets Id field to given value.

HasId returns a boolean if a field has been set.

### GetIpWithProtocol

`func (o *ServerConfig) GetIpWithProtocol() string`

GetIpWithProtocol returns the IpWithProtocol field if non-nil, zero value otherwise.

### GetIpWithProtocolOk

`func (o *ServerConfig) GetIpWithProtocolOk() (*string, bool)`

GetIpWithProtocolOk returns a tuple with the IpWithProtocol field if it's non-nil, zero value otherwise
and a boolean to check if the value has been set.

### SetIpWithProtocol

`func (o *ServerConfig) SetIpWithProtocol(v string)`

SetIpWithProtocol sets IpWithProtocol field to given value.

### HasIpWithProtocol

`func (o *ServerConfig) HasIpWithProtocol() bool`

HasIpWithProtocol returns a boolean if a field has been set.

### GetLocalBuilderRegistryPort

`func (o *ServerConfig) GetLocalBuilderRegistryPort() int32`
Expand Down
36 changes: 36 additions & 0 deletions pkg/apiclient/model_server_config.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions pkg/cmd/apikey/generate.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@ import (
"github.com/spf13/cobra"

"github.com/daytonaio/daytona/cmd/daytona/config"
"github.com/daytonaio/daytona/internal/util"
apiclient_util "github.com/daytonaio/daytona/internal/util/apiclient"
"github.com/daytonaio/daytona/internal/util/apiclient/conversion"
"github.com/daytonaio/daytona/pkg/apiclient"
"github.com/daytonaio/daytona/pkg/views"
"github.com/daytonaio/daytona/pkg/views/server/apikey"
Expand Down Expand Up @@ -71,7 +71,7 @@ var GenerateCmd = &cobra.Command{
log.Fatal(err)
}

apiUrl := util.GetFrpcApiUrl(*serverConfig.Frps.Protocol, *serverConfig.Id, *serverConfig.Frps.Domain)
apiUrl := conversion.ToServerConfig(serverConfig).GetApiUrl()

view.Render(key, apiUrl)
},
Expand Down
4 changes: 1 addition & 3 deletions pkg/cmd/server/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ import (
log "github.com/sirupsen/logrus"
"github.com/spf13/cobra"

"github.com/daytonaio/daytona/internal/util"
"github.com/daytonaio/daytona/pkg/cmd/output"
"github.com/daytonaio/daytona/pkg/server"
)
Expand All @@ -22,8 +21,7 @@ var configCmd = &cobra.Command{
log.Fatal(err)
}

apiUrl := util.GetFrpcApiUrl(config.Frps.Protocol, config.Id, config.Frps.Domain)
output.Output = apiUrl
output.Output = config.GetApiUrl()

view.RenderConfig(config)
},
Expand Down
30 changes: 18 additions & 12 deletions pkg/cmd/server/serve.go
Original file line number Diff line number Diff line change
Expand Up @@ -96,11 +96,19 @@ var ServeCmd = &cobra.Command{
log.Fatal(err)
}

var headscaleServerUrl string
if c.IpWithProtocol != nil {
headscaleServerUrl = fmt.Sprintf("%s:%d", *c.IpWithProtocol, c.HeadscalePort)
// FIXME
headscaleServerUrl = strings.Replace(headscaleServerUrl, "http://", "https://", 1)
} else if c.Frps != nil {
headscaleServerUrl = util.GetFrpcHeadscaleUrl(c.Frps.Protocol, c.Id, c.Frps.Domain)
}

headscaleServer := headscale.NewHeadscaleServer(&headscale.HeadscaleServerConfig{
ServerId: c.Id,
FrpsDomain: c.Frps.Domain,
FrpsProtocol: c.Frps.Protocol,
HeadscalePort: c.HeadscalePort,
ServerId: c.Id,
ServerUrl: headscaleServerUrl,
Port: c.HeadscalePort,
})
err = headscaleServer.Init()
if err != nil {
Expand Down Expand Up @@ -137,14 +145,12 @@ var ServeCmd = &cobra.Command{
ApiKeyStore: apiKeyStore,
})

headscaleUrl := util.GetFrpcHeadscaleUrl(c.Frps.Protocol, c.Id, c.Frps.Domain)

providerManager := manager.NewProviderManager(manager.ProviderManagerConfig{
LogsDir: logsDir,
ProviderTargetService: providerTargetService,
ApiUrl: util.GetFrpcApiUrl(c.Frps.Protocol, c.Id, c.Frps.Domain),
ServerUrl: headscaleServerUrl,
ApiUrl: c.GetApiUrl(),
DaytonaDownloadUrl: getDaytonaScriptUrl(c),
ServerUrl: headscaleUrl,
RegistryUrl: c.RegistryUrl,
BaseDir: c.ProvidersDir,
CreateProviderNetworkKey: func(providerName string) (string, error) {
Expand Down Expand Up @@ -185,8 +191,8 @@ var ServeCmd = &cobra.Command{
ApiKeyService: apiKeyService,
GitProviderService: gitProviderService,
ContainerRegistryService: containerRegistryService,
ServerApiUrl: util.GetFrpcApiUrl(c.Frps.Protocol, c.Id, c.Frps.Domain),
ServerUrl: headscaleUrl,
ServerApiUrl: c.GetApiUrl(),
ServerUrl: headscaleServerUrl,
DefaultProjectImage: c.DefaultProjectImage,
DefaultProjectUser: c.DefaultProjectUser,
DefaultProjectPostStartCommands: c.DefaultProjectPostStartCommands,
Expand Down Expand Up @@ -268,12 +274,12 @@ func waitForServerToStart(apiServer *api.ApiServer) error {
}

func getDaytonaScriptUrl(config *server.Config) string {
url, _ := url.JoinPath(util.GetFrpcApiUrl(config.Frps.Protocol, config.Id, config.Frps.Domain), "binary", "script")
url, _ := url.JoinPath(config.GetApiUrl(), "binary", "script")
return url
}

func printServerStartedMessage(c *server.Config, runAsDaemon bool) {
started_view.Render(c.ApiPort, util.GetFrpcApiUrl(c.Frps.Protocol, c.Id, c.Frps.Domain), runAsDaemon)
started_view.Render(c.ApiPort, c.GetApiUrl(), runAsDaemon)
}

func getDbPath() (string, error) {
Expand Down
4 changes: 2 additions & 2 deletions pkg/server/headscale/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,8 @@ func (s *HeadscaleServer) getHeadscaleConfig() (*hstypes.Config, error) {

cfg := &hstypes.Config{
DBtype: "sqlite3",
ServerURL: fmt.Sprintf("https://%s.%s", s.serverId, s.frpsDomain),
Addr: fmt.Sprintf("0.0.0.0:%d", s.headscalePort),
ServerURL: s.serverUrl,
Addr: fmt.Sprintf("0.0.0.0:%d", s.port),
EphemeralNodeInactivityTimeout: 5 * time.Minute,
NodeUpdateCheckInterval: 10 * time.Second,
BaseDomain: "daytona.local",
Expand Down
2 changes: 1 addition & 1 deletion pkg/server/headscale/connect.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ func (s *HeadscaleServer) Connect() error {
log.Fatal(err)
}

tsNetServer.ControlURL = fmt.Sprintf("http://localhost:%d", s.headscalePort)
tsNetServer.ControlURL = s.serverUrl
tsNetServer.AuthKey = authKey

defer tsNetServer.Close()
Expand Down
21 changes: 9 additions & 12 deletions pkg/server/headscale/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,26 +11,23 @@ import (
)

type HeadscaleServerConfig struct {
ServerId string
FrpsDomain string
FrpsProtocol string
HeadscalePort uint32
ServerId string
Port uint32
ServerUrl string
}

func NewHeadscaleServer(config *HeadscaleServerConfig) *HeadscaleServer {
return &HeadscaleServer{
serverId: config.ServerId,
frpsDomain: config.FrpsDomain,
frpsProtocol: config.FrpsProtocol,
headscalePort: config.HeadscalePort,
serverId: config.ServerId,
port: config.Port,
serverUrl: config.ServerUrl,
}
}

type HeadscaleServer struct {
serverId string
frpsDomain string
frpsProtocol string
headscalePort uint32
serverId string
port uint32
serverUrl string
}

func (s *HeadscaleServer) Init() error {
Expand Down
Loading

0 comments on commit f7a4bf4

Please sign in to comment.