Skip to content

Commit f7a4bf4

Browse files
committed
feat: server IP configuration
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]>
1 parent c8b9757 commit f7a4bf4

File tree

17 files changed

+204
-48
lines changed

17 files changed

+204
-48
lines changed
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
// Copyright 2024 Daytona Platforms Inc.
2+
// SPDX-License-Identifier: Apache-2.0
3+
4+
package conversion
5+
6+
import (
7+
"github.com/daytonaio/daytona/pkg/apiclient"
8+
"github.com/daytonaio/daytona/pkg/server"
9+
)
10+
11+
func ToServerConfig(serverConfigDto *apiclient.ServerConfig) *server.Config {
12+
if serverConfigDto == nil {
13+
return nil
14+
}
15+
16+
config := &server.Config{
17+
Id: *serverConfigDto.Id,
18+
ProvidersDir: *serverConfigDto.ProvidersDir,
19+
RegistryUrl: *serverConfigDto.RegistryUrl,
20+
ServerDownloadUrl: *serverConfigDto.ServerDownloadUrl,
21+
IpWithProtocol: serverConfigDto.IpWithProtocol,
22+
ApiPort: uint32(*serverConfigDto.ApiPort),
23+
LocalBuilderRegistryPort: uint32(*serverConfigDto.LocalBuilderRegistryPort),
24+
BuilderRegistryServer: *serverConfigDto.BuilderRegistryServer,
25+
BuildImageNamespace: *serverConfigDto.BuildImageNamespace,
26+
HeadscalePort: uint32(*serverConfigDto.HeadscalePort),
27+
BinariesPath: *serverConfigDto.BinariesPath,
28+
LogFilePath: *serverConfigDto.LogFilePath,
29+
DefaultProjectImage: *serverConfigDto.DefaultProjectImage,
30+
DefaultProjectUser: *serverConfigDto.DefaultProjectUser,
31+
DefaultProjectPostStartCommands: serverConfigDto.DefaultProjectPostStartCommands,
32+
BuilderImage: *serverConfigDto.BuilderImage,
33+
}
34+
35+
if serverConfigDto.Frps != nil {
36+
config.Frps = &server.FRPSConfig{
37+
Domain: *serverConfigDto.Frps.Domain,
38+
Port: uint32(*serverConfigDto.Frps.Port),
39+
Protocol: *serverConfigDto.Frps.Protocol,
40+
}
41+
}
42+
43+
return config
44+
}

pkg/api/controllers/binary/get_daytona.go

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,22 +4,23 @@
44
package binary
55

66
import (
7-
"fmt"
87
"net/http"
98
"net/url"
109

1110
"github.com/daytonaio/daytona/internal/constants"
11+
"github.com/daytonaio/daytona/pkg/server"
1212
"github.com/gin-gonic/gin"
1313
)
1414

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

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

2526
ctx.String(http.StatusOK, getServerScript)

pkg/api/docs/docs.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1569,6 +1569,9 @@ const docTemplate = `{
15691569
"id": {
15701570
"type": "string"
15711571
},
1572+
"ipWithProtocol": {
1573+
"type": "string"
1574+
},
15721575
"localBuilderRegistryPort": {
15731576
"type": "integer"
15741577
},

pkg/api/docs/swagger.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1566,6 +1566,9 @@
15661566
"id": {
15671567
"type": "string"
15681568
},
1569+
"ipWithProtocol": {
1570+
"type": "string"
1571+
},
15691572
"localBuilderRegistryPort": {
15701573
"type": "integer"
15711574
},

pkg/api/docs/swagger.yaml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -292,6 +292,8 @@ definitions:
292292
type: integer
293293
id:
294294
type: string
295+
ipWithProtocol:
296+
type: string
295297
localBuilderRegistryPort:
296298
type: integer
297299
logFilePath:

pkg/apiclient/api/openapi.yaml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1306,6 +1306,7 @@ components:
13061306
apiPort: 0
13071307
headscalePort: 1
13081308
buildImageNamespace: buildImageNamespace
1309+
ipWithProtocol: ipWithProtocol
13091310
serverDownloadUrl: serverDownloadUrl
13101311
binariesPath: binariesPath
13111312
logFilePath: logFilePath
@@ -1341,6 +1342,8 @@ components:
13411342
type: integer
13421343
id:
13431344
type: string
1345+
ipWithProtocol:
1346+
type: string
13441347
localBuilderRegistryPort:
13451348
type: integer
13461349
logFilePath:

pkg/apiclient/docs/ServerConfig.md

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ Name | Type | Description | Notes
1515
**Frps** | Pointer to [**FRPSConfig**](FRPSConfig.md) | | [optional]
1616
**HeadscalePort** | Pointer to **int32** | | [optional]
1717
**Id** | Pointer to **string** | | [optional]
18+
**IpWithProtocol** | Pointer to **string** | | [optional]
1819
**LocalBuilderRegistryPort** | Pointer to **int32** | | [optional]
1920
**LogFilePath** | Pointer to **string** | | [optional]
2021
**ProvidersDir** | Pointer to **string** | | [optional]
@@ -315,6 +316,31 @@ SetId sets Id field to given value.
315316

316317
HasId returns a boolean if a field has been set.
317318

319+
### GetIpWithProtocol
320+
321+
`func (o *ServerConfig) GetIpWithProtocol() string`
322+
323+
GetIpWithProtocol returns the IpWithProtocol field if non-nil, zero value otherwise.
324+
325+
### GetIpWithProtocolOk
326+
327+
`func (o *ServerConfig) GetIpWithProtocolOk() (*string, bool)`
328+
329+
GetIpWithProtocolOk returns a tuple with the IpWithProtocol field if it's non-nil, zero value otherwise
330+
and a boolean to check if the value has been set.
331+
332+
### SetIpWithProtocol
333+
334+
`func (o *ServerConfig) SetIpWithProtocol(v string)`
335+
336+
SetIpWithProtocol sets IpWithProtocol field to given value.
337+
338+
### HasIpWithProtocol
339+
340+
`func (o *ServerConfig) HasIpWithProtocol() bool`
341+
342+
HasIpWithProtocol returns a boolean if a field has been set.
343+
318344
### GetLocalBuilderRegistryPort
319345

320346
`func (o *ServerConfig) GetLocalBuilderRegistryPort() int32`

pkg/apiclient/model_server_config.go

Lines changed: 36 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

pkg/cmd/apikey/generate.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,8 @@ import (
1111
"github.com/spf13/cobra"
1212

1313
"github.com/daytonaio/daytona/cmd/daytona/config"
14-
"github.com/daytonaio/daytona/internal/util"
1514
apiclient_util "github.com/daytonaio/daytona/internal/util/apiclient"
15+
"github.com/daytonaio/daytona/internal/util/apiclient/conversion"
1616
"github.com/daytonaio/daytona/pkg/apiclient"
1717
"github.com/daytonaio/daytona/pkg/views"
1818
"github.com/daytonaio/daytona/pkg/views/server/apikey"
@@ -71,7 +71,7 @@ var GenerateCmd = &cobra.Command{
7171
log.Fatal(err)
7272
}
7373

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

7676
view.Render(key, apiUrl)
7777
},

pkg/cmd/server/config.go

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@ import (
88
log "github.com/sirupsen/logrus"
99
"github.com/spf13/cobra"
1010

11-
"github.com/daytonaio/daytona/internal/util"
1211
"github.com/daytonaio/daytona/pkg/cmd/output"
1312
"github.com/daytonaio/daytona/pkg/server"
1413
)
@@ -22,8 +21,7 @@ var configCmd = &cobra.Command{
2221
log.Fatal(err)
2322
}
2423

25-
apiUrl := util.GetFrpcApiUrl(config.Frps.Protocol, config.Id, config.Frps.Domain)
26-
output.Output = apiUrl
24+
output.Output = config.GetApiUrl()
2725

2826
view.RenderConfig(config)
2927
},

pkg/cmd/server/serve.go

Lines changed: 18 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -96,11 +96,19 @@ var ServeCmd = &cobra.Command{
9696
log.Fatal(err)
9797
}
9898

99+
var headscaleServerUrl string
100+
if c.IpWithProtocol != nil {
101+
headscaleServerUrl = fmt.Sprintf("%s:%d", *c.IpWithProtocol, c.HeadscalePort)
102+
// FIXME
103+
headscaleServerUrl = strings.Replace(headscaleServerUrl, "http://", "https://", 1)
104+
} else if c.Frps != nil {
105+
headscaleServerUrl = util.GetFrpcHeadscaleUrl(c.Frps.Protocol, c.Id, c.Frps.Domain)
106+
}
107+
99108
headscaleServer := headscale.NewHeadscaleServer(&headscale.HeadscaleServerConfig{
100-
ServerId: c.Id,
101-
FrpsDomain: c.Frps.Domain,
102-
FrpsProtocol: c.Frps.Protocol,
103-
HeadscalePort: c.HeadscalePort,
109+
ServerId: c.Id,
110+
ServerUrl: headscaleServerUrl,
111+
Port: c.HeadscalePort,
104112
})
105113
err = headscaleServer.Init()
106114
if err != nil {
@@ -137,14 +145,12 @@ var ServeCmd = &cobra.Command{
137145
ApiKeyStore: apiKeyStore,
138146
})
139147

140-
headscaleUrl := util.GetFrpcHeadscaleUrl(c.Frps.Protocol, c.Id, c.Frps.Domain)
141-
142148
providerManager := manager.NewProviderManager(manager.ProviderManagerConfig{
143149
LogsDir: logsDir,
144150
ProviderTargetService: providerTargetService,
145-
ApiUrl: util.GetFrpcApiUrl(c.Frps.Protocol, c.Id, c.Frps.Domain),
151+
ServerUrl: headscaleServerUrl,
152+
ApiUrl: c.GetApiUrl(),
146153
DaytonaDownloadUrl: getDaytonaScriptUrl(c),
147-
ServerUrl: headscaleUrl,
148154
RegistryUrl: c.RegistryUrl,
149155
BaseDir: c.ProvidersDir,
150156
CreateProviderNetworkKey: func(providerName string) (string, error) {
@@ -185,8 +191,8 @@ var ServeCmd = &cobra.Command{
185191
ApiKeyService: apiKeyService,
186192
GitProviderService: gitProviderService,
187193
ContainerRegistryService: containerRegistryService,
188-
ServerApiUrl: util.GetFrpcApiUrl(c.Frps.Protocol, c.Id, c.Frps.Domain),
189-
ServerUrl: headscaleUrl,
194+
ServerApiUrl: c.GetApiUrl(),
195+
ServerUrl: headscaleServerUrl,
190196
DefaultProjectImage: c.DefaultProjectImage,
191197
DefaultProjectUser: c.DefaultProjectUser,
192198
DefaultProjectPostStartCommands: c.DefaultProjectPostStartCommands,
@@ -268,12 +274,12 @@ func waitForServerToStart(apiServer *api.ApiServer) error {
268274
}
269275

270276
func getDaytonaScriptUrl(config *server.Config) string {
271-
url, _ := url.JoinPath(util.GetFrpcApiUrl(config.Frps.Protocol, config.Id, config.Frps.Domain), "binary", "script")
277+
url, _ := url.JoinPath(config.GetApiUrl(), "binary", "script")
272278
return url
273279
}
274280

275281
func printServerStartedMessage(c *server.Config, runAsDaemon bool) {
276-
started_view.Render(c.ApiPort, util.GetFrpcApiUrl(c.Frps.Protocol, c.Id, c.Frps.Domain), runAsDaemon)
282+
started_view.Render(c.ApiPort, c.GetApiUrl(), runAsDaemon)
277283
}
278284

279285
func getDbPath() (string, error) {

pkg/server/headscale/config.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,8 +27,8 @@ func (s *HeadscaleServer) getHeadscaleConfig() (*hstypes.Config, error) {
2727

2828
cfg := &hstypes.Config{
2929
DBtype: "sqlite3",
30-
ServerURL: fmt.Sprintf("https://%s.%s", s.serverId, s.frpsDomain),
31-
Addr: fmt.Sprintf("0.0.0.0:%d", s.headscalePort),
30+
ServerURL: s.serverUrl,
31+
Addr: fmt.Sprintf("0.0.0.0:%d", s.port),
3232
EphemeralNodeInactivityTimeout: 5 * time.Minute,
3333
NodeUpdateCheckInterval: 10 * time.Second,
3434
BaseDomain: "daytona.local",

pkg/server/headscale/connect.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ func (s *HeadscaleServer) Connect() error {
2727
log.Fatal(err)
2828
}
2929

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

3333
defer tsNetServer.Close()

pkg/server/headscale/server.go

Lines changed: 9 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -11,26 +11,23 @@ import (
1111
)
1212

1313
type HeadscaleServerConfig struct {
14-
ServerId string
15-
FrpsDomain string
16-
FrpsProtocol string
17-
HeadscalePort uint32
14+
ServerId string
15+
Port uint32
16+
ServerUrl string
1817
}
1918

2019
func NewHeadscaleServer(config *HeadscaleServerConfig) *HeadscaleServer {
2120
return &HeadscaleServer{
22-
serverId: config.ServerId,
23-
frpsDomain: config.FrpsDomain,
24-
frpsProtocol: config.FrpsProtocol,
25-
headscalePort: config.HeadscalePort,
21+
serverId: config.ServerId,
22+
port: config.Port,
23+
serverUrl: config.ServerUrl,
2624
}
2725
}
2826

2927
type HeadscaleServer struct {
30-
serverId string
31-
frpsDomain string
32-
frpsProtocol string
33-
headscalePort uint32
28+
serverId string
29+
port uint32
30+
serverUrl string
3431
}
3532

3633
func (s *HeadscaleServer) Init() error {

0 commit comments

Comments
 (0)