Skip to content

Commit 57c893d

Browse files
committed
Merge remote-tracking branch 'origin/main' into bcherry/node-next
2 parents 0eef212 + 71e6866 commit 57c893d

File tree

12 files changed

+312
-108
lines changed

12 files changed

+312
-108
lines changed

cmd/lk/agent.go

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ import (
1919
"errors"
2020
"fmt"
2121
"os"
22+
"path/filepath"
2223
"regexp"
2324
"slices"
2425
"strings"
@@ -111,6 +112,22 @@ var (
111112
DisableSliceFlagSeparator: true,
112113
ArgsUsage: "[working-dir]",
113114
},
115+
{
116+
Name: "dockerfile",
117+
Usage: "Generate Dockerfile and .dockerignore for your project",
118+
Before: createAgentClient,
119+
Action: generateAgentDockerfile,
120+
Flags: []cli.Flag{
121+
silentFlag,
122+
&cli.BoolFlag{
123+
Name: "overwrite",
124+
Usage: "Overwrite existing Dockerfile and/or .dockerignore if they exist",
125+
Required: false,
126+
Value: false,
127+
},
128+
},
129+
ArgsUsage: "[working-dir]",
130+
},
114131
{
115132
Name: "config",
116133
Usage: fmt.Sprintf("Creates a %s in the working directory for an existing agent.", config.LiveKitTOMLFile),
@@ -378,6 +395,7 @@ func createAgent(ctx context.Context, cmd *cli.Command) error {
378395
}
379396

380397
projectType, err := agentfs.DetectProjectType(workingDir)
398+
fmt.Printf("Detected project type [%s]\n", util.Accented(string(projectType)))
381399
if err != nil {
382400
return fmt.Errorf("unable to determine project type: %w, please use a supported project type, or create your own Dockerfile in the current directory", err)
383401
}
@@ -1232,3 +1250,68 @@ func requireConfig(workingDir, tomlFilename string) (bool, error) {
12321250
lkConfig, exists, err = config.LoadTOMLFile(workingDir, tomlFilename)
12331251
return exists, err
12341252
}
1253+
1254+
func generateAgentDockerfile(ctx context.Context, cmd *cli.Command) error {
1255+
if cmd.NArg() > 0 {
1256+
workingDir = cmd.Args().First()
1257+
}
1258+
1259+
if stat, err := os.Stat(workingDir); err != nil || !stat.IsDir() {
1260+
return fmt.Errorf("invalid working directory: %s", workingDir)
1261+
}
1262+
1263+
settingsMap, err := getClientSettings(ctx, cmd.Bool("silent"))
1264+
if err != nil {
1265+
return err
1266+
}
1267+
1268+
projectType, err := agentfs.DetectProjectType(workingDir)
1269+
fmt.Printf("Detected project type [%s]\n", util.Accented(string(projectType)))
1270+
if err != nil {
1271+
return fmt.Errorf("unable to determine project type: %w, please use a supported project type, or create your own Dockerfile in the current directory", err)
1272+
}
1273+
1274+
dockerfilePath := filepath.Join(workingDir, "Dockerfile")
1275+
dockerignorePath := filepath.Join(workingDir, ".dockerignore")
1276+
overwrite := cmd.Bool("overwrite")
1277+
1278+
writeDockerfile := true
1279+
writeDockerignore := true
1280+
if !overwrite {
1281+
if _, err := os.Stat(dockerfilePath); err == nil {
1282+
fmt.Println(util.Accented("Dockerfile") + " already exists; skipping. Use --overwrite to replace.")
1283+
writeDockerfile = false
1284+
}
1285+
if _, err := os.Stat(dockerignorePath); err == nil {
1286+
fmt.Println(util.Accented(".dockerignore") + " already exists; skipping. Use --overwrite to replace.")
1287+
writeDockerignore = false
1288+
}
1289+
}
1290+
1291+
if !writeDockerfile && !writeDockerignore {
1292+
return nil
1293+
}
1294+
1295+
// Generate contents without writing
1296+
dockerfileContent, dockerignoreContent, err := agentfs.GenerateDockerArtifacts(workingDir, projectType, settingsMap)
1297+
if err != nil {
1298+
return err
1299+
}
1300+
1301+
if writeDockerfile {
1302+
if err := os.WriteFile(dockerfilePath, dockerfileContent, 0644); err != nil {
1303+
return err
1304+
}
1305+
1306+
fmt.Printf("Wrote new %s\n", util.Accented("Dockerfile"))
1307+
}
1308+
1309+
if writeDockerignore {
1310+
if err := os.WriteFile(dockerignorePath, dockerignoreContent, 0644); err != nil {
1311+
return err
1312+
}
1313+
fmt.Printf("Wrote new %s\n", util.Accented(".dockerignore"))
1314+
}
1315+
1316+
return nil
1317+
}

cmd/lk/sip.go

Lines changed: 94 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -236,26 +236,34 @@ var (
236236
Name: "trunks",
237237
Usage: "Sets a list of trunks for the dispatch rule",
238238
},
239-
&cli.StringFlag{
240-
Name: "direct",
241-
Usage: "Sets a direct dispatch to a specified room",
242-
},
243-
&cli.StringFlag{
244-
Name: "caller",
245-
Aliases: []string{"individual"},
246-
Usage: "Sets a individual caller dispatch to a new room with a specific prefix",
247-
},
248-
&cli.StringFlag{
249-
Name: "callee",
250-
Usage: "Sets a callee number dispatch to a new room with a specific prefix",
251-
},
252-
&cli.BoolFlag{
253-
Name: "pin",
254-
Usage: "PIN for a dispatch rule",
255-
},
256-
&cli.BoolFlag{
257-
Name: "randomize",
258-
Usage: "Randomize room name, only applies to callee dispatch",
239+
},
240+
MutuallyExclusiveFlags: []cli.MutuallyExclusiveFlags{
241+
{
242+
Flags: [][]cli.Flag{
243+
{
244+
&cli.StringFlag{
245+
Name: "direct",
246+
Usage: "Sets a direct dispatch to a specified room",
247+
},
248+
},
249+
{
250+
&cli.StringFlag{
251+
Name: "caller",
252+
Aliases: []string{"individual"},
253+
Usage: "Sets a individual caller dispatch to a new room with a specific prefix",
254+
},
255+
},
256+
{
257+
&cli.StringFlag{
258+
Name: "callee",
259+
Usage: "Sets a callee number dispatch to a new room with a specific prefix",
260+
},
261+
&cli.BoolFlag{
262+
Name: "randomize",
263+
Usage: "Randomize room name",
264+
},
265+
},
266+
},
259267
},
260268
},
261269
},
@@ -278,6 +286,35 @@ var (
278286
Usage: "Sets a new list of trunk IDs",
279287
},
280288
},
289+
MutuallyExclusiveFlags: []cli.MutuallyExclusiveFlags{
290+
{
291+
Flags: [][]cli.Flag{
292+
{
293+
&cli.StringFlag{
294+
Name: "direct",
295+
Usage: "Sets a direct dispatch to a specified room",
296+
},
297+
},
298+
{
299+
&cli.StringFlag{
300+
Name: "caller",
301+
Aliases: []string{"individual"},
302+
Usage: "Sets a individual caller dispatch to a new room with a specific prefix",
303+
},
304+
},
305+
{
306+
&cli.StringFlag{
307+
Name: "callee",
308+
Usage: "Sets a callee number dispatch to a new room with a specific prefix",
309+
},
310+
&cli.BoolFlag{
311+
Name: "randomize",
312+
Usage: "Randomize room name",
313+
},
314+
},
315+
},
316+
},
317+
},
281318
},
282319
{
283320
Name: "delete",
@@ -944,6 +981,43 @@ func updateSIPDispatchRule(ctx context.Context, cmd *cli.Command) error {
944981
req.Name = &val
945982
}
946983
req.TrunkIds = listUpdateFlag(cmd, "trunks")
984+
if val := cmd.String("direct"); val != "" {
985+
if req.Rule != nil {
986+
return fmt.Errorf("only one dispatch rule type is allowed")
987+
}
988+
req.Rule = &livekit.SIPDispatchRule{
989+
Rule: &livekit.SIPDispatchRule_DispatchRuleDirect{
990+
DispatchRuleDirect: &livekit.SIPDispatchRuleDirect{
991+
RoomName: val,
992+
},
993+
},
994+
}
995+
}
996+
if val := cmd.String("caller"); val != "" {
997+
if req.Rule != nil {
998+
return fmt.Errorf("only one dispatch rule type is allowed")
999+
}
1000+
req.Rule = &livekit.SIPDispatchRule{
1001+
Rule: &livekit.SIPDispatchRule_DispatchRuleIndividual{
1002+
DispatchRuleIndividual: &livekit.SIPDispatchRuleIndividual{
1003+
RoomPrefix: val,
1004+
},
1005+
},
1006+
}
1007+
}
1008+
if val := cmd.String("callee"); val != "" {
1009+
if req.Rule != nil {
1010+
return fmt.Errorf("only one dispatch rule type is allowed")
1011+
}
1012+
req.Rule = &livekit.SIPDispatchRule{
1013+
Rule: &livekit.SIPDispatchRule_DispatchRuleCallee{
1014+
DispatchRuleCallee: &livekit.SIPDispatchRuleCallee{
1015+
RoomPrefix: val,
1016+
Randomize: cmd.Bool("randomize"),
1017+
},
1018+
},
1019+
}
1020+
}
9471021
info, err := cli.UpdateSIPDispatchRule(ctx, &livekit.UpdateSIPDispatchRuleRequest{
9481022
SipDispatchRuleId: id,
9491023
Action: &livekit.UpdateSIPDispatchRuleRequest_Update{

cmd/lk/token.go

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,14 @@ var (
107107
Name: "grant",
108108
Usage: "Additional `VIDEO_GRANT` fields. It'll be merged with other arguments (JSON formatted)",
109109
},
110+
&cli.StringFlag{
111+
Name: "agent",
112+
Usage: "Agent to dispatch to the room (identified by agent_name)",
113+
},
114+
&cli.StringFlag{
115+
Name: "job-metadata",
116+
Usage: "Metadata attached to job dispatched to the agent (ctx.job.metadata)",
117+
},
110118
},
111119
},
112120
},
@@ -322,6 +330,19 @@ func createToken(ctx context.Context, c *cli.Command) error {
322330

323331
at := accessToken(project.APIKey, project.APISecret, grant, participant)
324332

333+
if grant.RoomJoin {
334+
if agent := c.String("agent"); agent != "" {
335+
jobMetadata := c.String("job-metadata")
336+
at.SetRoomConfig(&livekit.RoomConfiguration{
337+
Agents: []*livekit.RoomAgentDispatch{
338+
{
339+
AgentName: agent,
340+
Metadata: jobMetadata,
341+
},
342+
},
343+
})
344+
}
345+
}
325346
if metadata != "" {
326347
at.SetMetadata(metadata)
327348
}

go.mod

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ require (
2424
github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c
2525
github.com/pkg/errors v0.9.1
2626
github.com/schollz/progressbar/v3 v3.18.0
27-
github.com/stretchr/testify v1.10.0
27+
github.com/stretchr/testify v1.11.0
2828
github.com/twitchtv/twirp v8.1.3+incompatible
2929
github.com/urfave/cli/v3 v3.4.1
3030
go.uber.org/atomic v1.11.0

go.sum

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -445,8 +445,8 @@ github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/
445445
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
446446
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
447447
github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
448-
github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA=
449-
github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
448+
github.com/stretchr/testify v1.11.0 h1:ib4sjIrwZKxE5u/Japgo/7SJV3PvgjGiRNAvTVGqQl8=
449+
github.com/stretchr/testify v1.11.0/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U=
450450
github.com/tonistiigi/fsutil v0.0.0-20250605211040-586307ad452f h1:MoxeMfHAe5Qj/ySSBfL8A7l1V+hxuluj8owsIEEZipI=
451451
github.com/tonistiigi/fsutil v0.0.0-20250605211040-586307ad452f/go.mod h1:BKdcez7BiVtBvIcef90ZPc6ebqIWr4JWD7+EvLm6J98=
452452
github.com/tonistiigi/go-csvvalue v0.0.0-20240814133006-030d3b2625d0 h1:2f304B10LaZdB8kkVEaoXvAMVan2tl9AiK4G0odjQtE=

0 commit comments

Comments
 (0)