Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
OpenDAS
dynamo
Commits
8621d914
Commit
8621d914
authored
Mar 28, 2025
by
Biswa Panda
Committed by
GitHub
Mar 28, 2025
Browse files
feat: dynamo deploy hello world example to k8s (#205)
parent
988378ab
Changes
48
Expand all
Show whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
998 additions
and
249 deletions
+998
-249
deploy/dynamo/operator/internal/controller/dynamonimdeployment_controller.go
...tor/internal/controller/dynamonimdeployment_controller.go
+20
-34
deploy/dynamo/operator/internal/nim/nim.go
deploy/dynamo/operator/internal/nim/nim.go
+22
-12
deploy/dynamo/operator/internal/nim/nim_test.go
deploy/dynamo/operator/internal/nim/nim_test.go
+19
-12
deploy/dynamo/sdk/src/dynamo/sdk/cli/cli.py
deploy/dynamo/sdk/src/dynamo/sdk/cli/cli.py
+10
-5
deploy/dynamo/sdk/src/dynamo/sdk/cli/deployment.py
deploy/dynamo/sdk/src/dynamo/sdk/cli/deployment.py
+804
-106
deploy/dynamo/sdk/src/dynamo/sdk/cli/server.py
deploy/dynamo/sdk/src/dynamo/sdk/cli/server.py
+87
-79
deploy/dynamo/tests/test_deployment.sh
deploy/dynamo/tests/test_deployment.sh
+35
-0
lib/bindings/python/pyproject.toml
lib/bindings/python/pyproject.toml
+1
-1
No files found.
deploy/dynamo/operator/internal/controller/dynamonimdeployment_controller.go
View file @
8621d914
...
@@ -1163,7 +1163,7 @@ func (r *DynamoNimDeploymentReconciler) createOrUpdateVirtualService(ctx context
...
@@ -1163,7 +1163,7 @@ func (r *DynamoNimDeploymentReconciler) createOrUpdateVirtualService(ctx context
Route
:
[]
*
istioNetworking
.
HTTPRouteDestination
{
Route
:
[]
*
istioNetworking
.
HTTPRouteDestination
{
{
{
Destination
:
&
istioNetworking
.
Destination
{
Destination
:
&
istioNetworking
.
Destination
{
Host
:
fmt
.
Sprintf
(
"%s.yatai.svc.cluster.local"
,
dynamoNimDeployment
.
Name
)
,
Host
:
dynamoNimDeployment
.
Name
,
Port
:
&
istioNetworking
.
PortSelector
{
Port
:
&
istioNetworking
.
PortSelector
{
Number
:
3000
,
Number
:
3000
,
},
},
...
@@ -1186,6 +1186,11 @@ func (r *DynamoNimDeploymentReconciler) createOrUpdateVirtualService(ctx context
...
@@ -1186,6 +1186,11 @@ func (r *DynamoNimDeploymentReconciler) createOrUpdateVirtualService(ctx context
vsEnabled
:=
dynamoNimDeployment
.
Spec
.
Ingress
.
Enabled
&&
dynamoNimDeployment
.
Spec
.
Ingress
.
UseVirtualService
!=
nil
&&
*
dynamoNimDeployment
.
Spec
.
Ingress
.
UseVirtualService
vsEnabled
:=
dynamoNimDeployment
.
Spec
.
Ingress
.
Enabled
&&
dynamoNimDeployment
.
Spec
.
Ingress
.
UseVirtualService
!=
nil
&&
*
dynamoNimDeployment
.
Spec
.
Ingress
.
UseVirtualService
if
err
:=
ctrl
.
SetControllerReference
(
dynamoNimDeployment
,
vs
,
r
.
Scheme
);
err
!=
nil
{
log
.
Error
(
err
,
"Failed to set controller reference for the VirtualService"
)
return
false
,
err
}
if
err
!=
nil
{
if
err
!=
nil
{
if
vsEnabled
{
if
vsEnabled
{
log
.
Info
(
"VirtualService not found, creating new one"
)
log
.
Info
(
"VirtualService not found, creating new one"
)
...
@@ -1209,7 +1214,7 @@ func (r *DynamoNimDeploymentReconciler) createOrUpdateVirtualService(ctx context
...
@@ -1209,7 +1214,7 @@ func (r *DynamoNimDeploymentReconciler) createOrUpdateVirtualService(ctx context
}
}
log
.
Info
(
"VirtualService found, updating"
,
"OldVirtualService"
,
oldVS
)
log
.
Info
(
"VirtualService found, updating"
,
"OldVirtualService"
,
oldVS
)
vs
.
ObjectMeta
.
ResourceVersion
=
oldVS
.
ObjectMeta
.
ResourceVersion
if
err
:=
r
.
Update
(
ctx
,
vs
);
err
!=
nil
{
if
err
:=
r
.
Update
(
ctx
,
vs
);
err
!=
nil
{
log
.
Error
(
err
,
"Failed to update VirtualService"
)
log
.
Error
(
err
,
"Failed to update VirtualService"
)
return
false
,
err
return
false
,
err
...
@@ -1764,34 +1769,12 @@ monitoring.options.insecure=true`
...
@@ -1764,34 +1769,12 @@ monitoring.options.insecure=true`
// do nothing
// do nothing
}
}
livenessProbe
:=
&
corev1
.
Probe
{
var
livenessProbe
*
corev1
.
Probe
InitialDelaySeconds
:
10
,
TimeoutSeconds
:
20
,
FailureThreshold
:
6
,
ProbeHandler
:
corev1
.
ProbeHandler
{
HTTPGet
:
&
corev1
.
HTTPGetAction
{
Path
:
"/livez"
,
Port
:
intstr
.
FromString
(
commonconsts
.
BentoContainerPortName
),
},
},
}
if
opt
.
dynamoNimDeployment
.
Spec
.
LivenessProbe
!=
nil
{
if
opt
.
dynamoNimDeployment
.
Spec
.
LivenessProbe
!=
nil
{
livenessProbe
=
opt
.
dynamoNimDeployment
.
Spec
.
LivenessProbe
livenessProbe
=
opt
.
dynamoNimDeployment
.
Spec
.
LivenessProbe
}
}
readinessProbe
:=
&
corev1
.
Probe
{
var
readinessProbe
*
corev1
.
Probe
InitialDelaySeconds
:
5
,
TimeoutSeconds
:
5
,
FailureThreshold
:
12
,
ProbeHandler
:
corev1
.
ProbeHandler
{
HTTPGet
:
&
corev1
.
HTTPGetAction
{
Path
:
"/readyz"
,
Port
:
intstr
.
FromString
(
commonconsts
.
BentoContainerPortName
),
},
},
}
if
opt
.
dynamoNimDeployment
.
Spec
.
ReadinessProbe
!=
nil
{
if
opt
.
dynamoNimDeployment
.
Spec
.
ReadinessProbe
!=
nil
{
readinessProbe
=
opt
.
dynamoNimDeployment
.
Spec
.
ReadinessProbe
readinessProbe
=
opt
.
dynamoNimDeployment
.
Spec
.
ReadinessProbe
}
}
...
@@ -1803,11 +1786,9 @@ monitoring.options.insecure=true`
...
@@ -1803,11 +1786,9 @@ monitoring.options.insecure=true`
args
=
append
(
args
,
"uv"
,
"run"
,
"dynamo"
,
"start"
)
args
=
append
(
args
,
"uv"
,
"run"
,
"dynamo"
,
"start"
)
if
opt
.
dynamoNimDeployment
.
Spec
.
ServiceName
!=
""
{
// todo : remove this line when https://github.com/ai-dynamo/dynamo/issues/345 is fixed
args
=
append
(
args
,
[]
string
{
"--service-name"
,
opt
.
dynamoNimDeployment
.
Spec
.
ServiceName
}
...
)
enableDependsOption
:=
false
}
if
len
(
opt
.
dynamoNimDeployment
.
Spec
.
ExternalServices
)
>
0
&&
enableDependsOption
{
if
len
(
opt
.
dynamoNimDeployment
.
Spec
.
ExternalServices
)
>
0
{
serviceSuffix
:=
fmt
.
Sprintf
(
"%s.svc.cluster.local:3000"
,
opt
.
dynamoNimDeployment
.
Namespace
)
serviceSuffix
:=
fmt
.
Sprintf
(
"%s.svc.cluster.local:3000"
,
opt
.
dynamoNimDeployment
.
Namespace
)
keys
:=
make
([]
string
,
0
,
len
(
opt
.
dynamoNimDeployment
.
Spec
.
ExternalServices
))
keys
:=
make
([]
string
,
0
,
len
(
opt
.
dynamoNimDeployment
.
Spec
.
ExternalServices
))
...
@@ -1823,13 +1804,18 @@ monitoring.options.insecure=true`
...
@@ -1823,13 +1804,18 @@ monitoring.options.insecure=true`
if
service
.
DeploymentSelectorKey
==
"name"
{
if
service
.
DeploymentSelectorKey
==
"name"
{
dependsFlag
:=
fmt
.
Sprintf
(
"--depends
\"
%s=http://%s.%s
\"
"
,
key
,
service
.
DeploymentSelectorValue
,
serviceSuffix
)
dependsFlag
:=
fmt
.
Sprintf
(
"--depends
\"
%s=http://%s.%s
\"
"
,
key
,
service
.
DeploymentSelectorValue
,
serviceSuffix
)
args
=
append
(
args
,
dependsFlag
)
args
=
append
(
args
,
dependsFlag
)
}
else
if
service
.
DeploymentSelectorKey
==
"
nova
"
{
}
else
if
service
.
DeploymentSelectorKey
==
"
dynamo
"
{
dependsFlag
:=
fmt
.
Sprintf
(
"--depends
\"
%s=
nova
://%s
\"
"
,
key
,
service
.
DeploymentSelectorValue
)
dependsFlag
:=
fmt
.
Sprintf
(
"--depends
\"
%s=
dynamo
://%s
\"
"
,
key
,
service
.
DeploymentSelectorValue
)
args
=
append
(
args
,
dependsFlag
)
args
=
append
(
args
,
dependsFlag
)
}
else
{
}
else
{
return
nil
,
errors
.
Errorf
(
"DeploymentSelectorKey '%s' not supported. Only 'name' and 'nova' are supported"
,
service
.
DeploymentSelectorKey
)
return
nil
,
errors
.
Errorf
(
"DeploymentSelectorKey '%s' not supported. Only 'name' and 'dynamo' are supported"
,
service
.
DeploymentSelectorKey
)
}
}
}
}
}
if
opt
.
dynamoNimDeployment
.
Spec
.
ServiceName
!=
""
{
args
=
append
(
args
,
[]
string
{
"--service-name"
,
opt
.
dynamoNimDeployment
.
Spec
.
ServiceName
}
...
)
args
=
append
(
args
,
"src."
+
opt
.
dynamoNimDeployment
.
Spec
.
DynamoTag
)
}
}
yataiResources
:=
opt
.
dynamoNimDeployment
.
Spec
.
Resources
yataiResources
:=
opt
.
dynamoNimDeployment
.
Spec
.
Resources
...
...
deploy/dynamo/operator/internal/nim/nim.go
View file @
8621d914
...
@@ -44,7 +44,7 @@ import (
...
@@ -44,7 +44,7 @@ import (
)
)
// ServiceConfig represents the YAML configuration structure for a service
// ServiceConfig represents the YAML configuration structure for a service
type
Nova
Config
struct
{
type
Dynamo
Config
struct
{
Enabled
bool
`yaml:"enabled"`
Enabled
bool
`yaml:"enabled"`
Namespace
string
`yaml:"namespace"`
Namespace
string
`yaml:"namespace"`
Name
string
`yaml:"name"`
Name
string
`yaml:"name"`
...
@@ -67,7 +67,7 @@ type Autoscaling struct {
...
@@ -67,7 +67,7 @@ type Autoscaling struct {
}
}
type
Config
struct
{
type
Config
struct
{
Nova
*
Nova
Config
`yaml:"
nova
,omitempty"`
Dynamo
*
Dynamo
Config
`yaml:"
dynamo
,omitempty"`
Resources
*
Resources
`yaml:"resources,omitempty"`
Resources
*
Resources
`yaml:"resources,omitempty"`
Traffic
*
Traffic
`yaml:"traffic,omitempty"`
Traffic
*
Traffic
`yaml:"traffic,omitempty"`
Autoscaling
*
Autoscaling
`yaml:"autoscaling,omitempty"`
Autoscaling
*
Autoscaling
`yaml:"autoscaling,omitempty"`
...
@@ -131,7 +131,9 @@ func RetrieveDynamoNimDownloadURL(ctx context.Context, dynamoDeployment *v1alpha
...
@@ -131,7 +131,9 @@ func RetrieveDynamoNimDownloadURL(ctx context.Context, dynamoDeployment *v1alpha
// ServicesConfig represents the top-level YAML structure of a dynamoNim yaml file stored in a dynamoNim tar file
// ServicesConfig represents the top-level YAML structure of a dynamoNim yaml file stored in a dynamoNim tar file
type
DynamoNIMConfig
struct
{
type
DynamoNIMConfig
struct
{
DynamoTag
string
`yaml:"service"`
Services
[]
ServiceConfig
`yaml:"services"`
Services
[]
ServiceConfig
`yaml:"services"`
EntryService
string
`yaml:"entry_service"`
}
}
type
EventRecorder
interface
{
type
EventRecorder
interface
{
...
@@ -249,16 +251,24 @@ func GetDynamoNIMConfig(ctx context.Context, dynamoDeployment *v1alpha1.DynamoDe
...
@@ -249,16 +251,24 @@ func GetDynamoNIMConfig(ctx context.Context, dynamoDeployment *v1alpha1.DynamoDe
// generate DynamoNIMDeployment from config
// generate DynamoNIMDeployment from config
func
GenerateDynamoNIMDeployments
(
parentDynamoDeployment
*
v1alpha1
.
DynamoDeployment
,
config
*
DynamoNIMConfig
)
(
map
[
string
]
*
v1alpha1
.
DynamoNimDeployment
,
error
)
{
func
GenerateDynamoNIMDeployments
(
parentDynamoDeployment
*
v1alpha1
.
DynamoDeployment
,
config
*
DynamoNIMConfig
)
(
map
[
string
]
*
v1alpha1
.
DynamoNimDeployment
,
error
)
{
nova
Services
:=
make
(
map
[
string
]
string
)
dynamo
Services
:=
make
(
map
[
string
]
string
)
deployments
:=
make
(
map
[
string
]
*
v1alpha1
.
DynamoNimDeployment
)
deployments
:=
make
(
map
[
string
]
*
v1alpha1
.
DynamoNimDeployment
)
for
_
,
service
:=
range
config
.
Services
{
for
_
,
service
:=
range
config
.
Services
{
deployment
:=
&
v1alpha1
.
DynamoNimDeployment
{}
deployment
:=
&
v1alpha1
.
DynamoNimDeployment
{}
deployment
.
Name
=
fmt
.
Sprintf
(
"%s-%s"
,
parentDynamoDeployment
.
Name
,
strings
.
ToLower
(
service
.
Name
))
deployment
.
Name
=
fmt
.
Sprintf
(
"%s-%s"
,
parentDynamoDeployment
.
Name
,
strings
.
ToLower
(
service
.
Name
))
deployment
.
Namespace
=
parentDynamoDeployment
.
Namespace
deployment
.
Namespace
=
parentDynamoDeployment
.
Namespace
deployment
.
Spec
.
DynamoTag
=
config
.
DynamoTag
deployment
.
Spec
.
DynamoNim
=
strings
.
Split
(
parentDynamoDeployment
.
Spec
.
DynamoNim
,
":"
)[
0
]
deployment
.
Spec
.
DynamoNim
=
strings
.
Split
(
parentDynamoDeployment
.
Spec
.
DynamoNim
,
":"
)[
0
]
deployment
.
Spec
.
ServiceName
=
service
.
Name
deployment
.
Spec
.
ServiceName
=
service
.
Name
if
service
.
Config
.
Nova
!=
nil
&&
service
.
Config
.
Nova
.
Enabled
{
if
service
.
Config
.
Dynamo
!=
nil
&&
service
.
Config
.
Dynamo
.
Enabled
{
novaServices
[
service
.
Name
]
=
fmt
.
Sprintf
(
"%s/%s"
,
service
.
Config
.
Nova
.
Name
,
service
.
Config
.
Nova
.
Namespace
)
dynamoServices
[
service
.
Name
]
=
fmt
.
Sprintf
(
"%s/%s"
,
service
.
Config
.
Dynamo
.
Name
,
service
.
Config
.
Dynamo
.
Namespace
)
}
else
{
// dynamo is not enabled
if
config
.
EntryService
==
service
.
Name
{
// enable virtual service for the entry service
deployment
.
Spec
.
Ingress
.
Enabled
=
true
deployment
.
Spec
.
Ingress
.
UseVirtualService
=
&
deployment
.
Spec
.
Ingress
.
Enabled
}
}
}
if
service
.
Config
.
Resources
!=
nil
{
if
service
.
Config
.
Resources
!=
nil
{
deployment
.
Spec
.
Resources
=
&
compounaiCommon
.
Resources
{
deployment
.
Spec
.
Resources
=
&
compounaiCommon
.
Resources
{
...
@@ -296,10 +306,10 @@ func GenerateDynamoNIMDeployments(parentDynamoDeployment *v1alpha1.DynamoDeploym
...
@@ -296,10 +306,10 @@ func GenerateDynamoNIMDeployments(parentDynamoDeployment *v1alpha1.DynamoDeploym
if
dependencyDeployment
==
nil
{
if
dependencyDeployment
==
nil
{
return
nil
,
fmt
.
Errorf
(
"dependency %s not found"
,
dependentServiceName
)
return
nil
,
fmt
.
Errorf
(
"dependency %s not found"
,
dependentServiceName
)
}
}
if
nova
Service
,
ok
:=
nova
Services
[
dependentServiceName
];
ok
{
if
dynamo
Service
,
ok
:=
dynamo
Services
[
dependentServiceName
];
ok
{
deployment
.
Spec
.
ExternalServices
[
dependentServiceName
]
=
v1alpha1
.
ExternalService
{
deployment
.
Spec
.
ExternalServices
[
dependentServiceName
]
=
v1alpha1
.
ExternalService
{
DeploymentSelectorKey
:
"
nova
"
,
DeploymentSelectorKey
:
"
dynamo
"
,
DeploymentSelectorValue
:
nova
Service
,
DeploymentSelectorValue
:
dynamo
Service
,
}
}
}
else
{
}
else
{
deployment
.
Spec
.
ExternalServices
[
dependentServiceName
]
=
v1alpha1
.
ExternalService
{
deployment
.
Spec
.
ExternalServices
[
dependentServiceName
]
=
v1alpha1
.
ExternalService
{
...
...
deploy/dynamo/operator/internal/nim/nim_test.go
View file @
8621d914
...
@@ -50,12 +50,13 @@ func TestGenerateDynamoNIMDeployments(t *testing.T) {
...
@@ -50,12 +50,13 @@ func TestGenerateDynamoNIMDeployments(t *testing.T) {
},
},
},
},
config
:
&
DynamoNIMConfig
{
config
:
&
DynamoNIMConfig
{
DynamoTag
:
"dynamonim:MyService1"
,
Services
:
[]
ServiceConfig
{
Services
:
[]
ServiceConfig
{
{
{
Name
:
"service1"
,
Name
:
"service1"
,
Dependencies
:
[]
map
[
string
]
string
{{
"service"
:
"service2"
}},
Dependencies
:
[]
map
[
string
]
string
{{
"service"
:
"service2"
}},
Config
:
Config
{
Config
:
Config
{
Nova
:
&
Nova
Config
{
Dynamo
:
&
Dynamo
Config
{
Enabled
:
true
,
Enabled
:
true
,
Namespace
:
"default"
,
Namespace
:
"default"
,
Name
:
"service1"
,
Name
:
"service1"
,
...
@@ -76,7 +77,7 @@ func TestGenerateDynamoNIMDeployments(t *testing.T) {
...
@@ -76,7 +77,7 @@ func TestGenerateDynamoNIMDeployments(t *testing.T) {
Name
:
"service2"
,
Name
:
"service2"
,
Dependencies
:
[]
map
[
string
]
string
{},
Dependencies
:
[]
map
[
string
]
string
{},
Config
:
Config
{
Config
:
Config
{
Nova
:
&
Nova
Config
{
Dynamo
:
&
Dynamo
Config
{
Enabled
:
false
,
Enabled
:
false
,
},
},
},
},
...
@@ -92,6 +93,7 @@ func TestGenerateDynamoNIMDeployments(t *testing.T) {
...
@@ -92,6 +93,7 @@ func TestGenerateDynamoNIMDeployments(t *testing.T) {
},
},
Spec
:
v1alpha1
.
DynamoNimDeploymentSpec
{
Spec
:
v1alpha1
.
DynamoNimDeploymentSpec
{
DynamoNim
:
"dynamonim"
,
DynamoNim
:
"dynamonim"
,
DynamoTag
:
"dynamonim:MyService1"
,
ServiceName
:
"service1"
,
ServiceName
:
"service1"
,
Resources
:
&
compounaiCommon
.
Resources
{
Resources
:
&
compounaiCommon
.
Resources
{
Requests
:
&
compounaiCommon
.
ResourceItem
{
Requests
:
&
compounaiCommon
.
ResourceItem
{
...
@@ -125,8 +127,9 @@ func TestGenerateDynamoNIMDeployments(t *testing.T) {
...
@@ -125,8 +127,9 @@ func TestGenerateDynamoNIMDeployments(t *testing.T) {
Namespace
:
"default"
,
Namespace
:
"default"
,
},
},
Spec
:
v1alpha1
.
DynamoNimDeploymentSpec
{
Spec
:
v1alpha1
.
DynamoNimDeploymentSpec
{
ServiceName
:
"service2"
,
DynamoNim
:
"dynamonim"
,
DynamoNim
:
"dynamonim"
,
DynamoTag
:
"dynamonim:MyService1"
,
ServiceName
:
"service2"
,
},
},
},
},
},
},
...
@@ -145,16 +148,13 @@ func TestGenerateDynamoNIMDeployments(t *testing.T) {
...
@@ -145,16 +148,13 @@ func TestGenerateDynamoNIMDeployments(t *testing.T) {
},
},
},
},
config
:
&
DynamoNIMConfig
{
config
:
&
DynamoNIMConfig
{
DynamoTag
:
"dynamonim:MyService2"
,
EntryService
:
"service1"
,
Services
:
[]
ServiceConfig
{
Services
:
[]
ServiceConfig
{
{
{
Name
:
"service1"
,
Name
:
"service1"
,
Dependencies
:
[]
map
[
string
]
string
{{
"service"
:
"service2"
}},
Dependencies
:
[]
map
[
string
]
string
{{
"service"
:
"service2"
}},
Config
:
Config
{
Config
:
Config
{
Nova
:
&
NovaConfig
{
Enabled
:
true
,
Namespace
:
"default"
,
Name
:
"service1"
,
},
Resources
:
&
Resources
{
Resources
:
&
Resources
{
CPU
:
"1"
,
CPU
:
"1"
,
Memory
:
"1Gi"
,
Memory
:
"1Gi"
,
...
@@ -171,7 +171,7 @@ func TestGenerateDynamoNIMDeployments(t *testing.T) {
...
@@ -171,7 +171,7 @@ func TestGenerateDynamoNIMDeployments(t *testing.T) {
Name
:
"service2"
,
Name
:
"service2"
,
Dependencies
:
[]
map
[
string
]
string
{},
Dependencies
:
[]
map
[
string
]
string
{},
Config
:
Config
{
Config
:
Config
{
Nova
:
&
Nova
Config
{
Dynamo
:
&
Dynamo
Config
{
Enabled
:
true
,
Enabled
:
true
,
Namespace
:
"default"
,
Namespace
:
"default"
,
Name
:
"service2"
,
Name
:
"service2"
,
...
@@ -189,6 +189,7 @@ func TestGenerateDynamoNIMDeployments(t *testing.T) {
...
@@ -189,6 +189,7 @@ func TestGenerateDynamoNIMDeployments(t *testing.T) {
},
},
Spec
:
v1alpha1
.
DynamoNimDeploymentSpec
{
Spec
:
v1alpha1
.
DynamoNimDeploymentSpec
{
DynamoNim
:
"dynamonim"
,
DynamoNim
:
"dynamonim"
,
DynamoTag
:
"dynamonim:MyService2"
,
ServiceName
:
"service1"
,
ServiceName
:
"service1"
,
Resources
:
&
compounaiCommon
.
Resources
{
Resources
:
&
compounaiCommon
.
Resources
{
Requests
:
&
compounaiCommon
.
ResourceItem
{
Requests
:
&
compounaiCommon
.
ResourceItem
{
...
@@ -210,10 +211,14 @@ func TestGenerateDynamoNIMDeployments(t *testing.T) {
...
@@ -210,10 +211,14 @@ func TestGenerateDynamoNIMDeployments(t *testing.T) {
},
},
ExternalServices
:
map
[
string
]
v1alpha1
.
ExternalService
{
ExternalServices
:
map
[
string
]
v1alpha1
.
ExternalService
{
"service2"
:
{
"service2"
:
{
DeploymentSelectorKey
:
"
nova
"
,
DeploymentSelectorKey
:
"
dynamo
"
,
DeploymentSelectorValue
:
"service2/default"
,
DeploymentSelectorValue
:
"service2/default"
,
},
},
},
},
Ingress
:
v1alpha1
.
IngressSpec
{
Enabled
:
true
,
UseVirtualService
:
&
[]
bool
{
true
}[
0
],
},
},
},
},
},
"service2"
:
{
"service2"
:
{
...
@@ -223,6 +228,7 @@ func TestGenerateDynamoNIMDeployments(t *testing.T) {
...
@@ -223,6 +228,7 @@ func TestGenerateDynamoNIMDeployments(t *testing.T) {
},
},
Spec
:
v1alpha1
.
DynamoNimDeploymentSpec
{
Spec
:
v1alpha1
.
DynamoNimDeploymentSpec
{
DynamoNim
:
"dynamonim"
,
DynamoNim
:
"dynamonim"
,
DynamoTag
:
"dynamonim:MyService2"
,
ServiceName
:
"service2"
,
ServiceName
:
"service2"
,
},
},
},
},
...
@@ -242,12 +248,13 @@ func TestGenerateDynamoNIMDeployments(t *testing.T) {
...
@@ -242,12 +248,13 @@ func TestGenerateDynamoNIMDeployments(t *testing.T) {
},
},
},
},
config
:
&
DynamoNIMConfig
{
config
:
&
DynamoNIMConfig
{
DynamoTag
:
"dynamonim:MyService3"
,
Services
:
[]
ServiceConfig
{
Services
:
[]
ServiceConfig
{
{
{
Name
:
"service1"
,
Name
:
"service1"
,
Dependencies
:
[]
map
[
string
]
string
{{
"service"
:
"service2"
}},
Dependencies
:
[]
map
[
string
]
string
{{
"service"
:
"service2"
}},
Config
:
Config
{
Config
:
Config
{
Nova
:
&
Nova
Config
{
Dynamo
:
&
Dynamo
Config
{
Enabled
:
true
,
Enabled
:
true
,
Namespace
:
"default"
,
Namespace
:
"default"
,
Name
:
"service1"
,
Name
:
"service1"
,
...
@@ -268,7 +275,7 @@ func TestGenerateDynamoNIMDeployments(t *testing.T) {
...
@@ -268,7 +275,7 @@ func TestGenerateDynamoNIMDeployments(t *testing.T) {
Name
:
"service3"
,
Name
:
"service3"
,
Dependencies
:
[]
map
[
string
]
string
{},
Dependencies
:
[]
map
[
string
]
string
{},
Config
:
Config
{
Config
:
Config
{
Nova
:
&
Nova
Config
{
Dynamo
:
&
Dynamo
Config
{
Enabled
:
true
,
Enabled
:
true
,
Namespace
:
"default"
,
Namespace
:
"default"
,
Name
:
"service3"
,
Name
:
"service3"
,
...
...
deploy/dynamo/sdk/src/dynamo/sdk/cli/cli.py
View file @
8621d914
...
@@ -24,17 +24,21 @@ def create_bentoml_cli() -> click.Command:
...
@@ -24,17 +24,21 @@ def create_bentoml_cli() -> click.Command:
from
bentoml._internal.context
import
server_context
from
bentoml._internal.context
import
server_context
from
bentoml_cli.bentos
import
bento_command
from
bentoml_cli.bentos
import
bento_command
# from bentoml_cli.cloud import cloud_command
# from bentoml_cli.containerize import containerize_command
# from bentoml_cli.containerize import containerize_command
from
bentoml_cli.utils
import
get_entry_points
from
bentoml_cli.utils
import
get_entry_points
from
dynamo.sdk.cli.deployment
import
deployment_command
# from dynamo.sdk.cli.deploy import deploy_command
# from dynamo.sdk.cli.deploy import deploy_command
from
dynamo.sdk.cli.run
import
run_command
from
dynamo.sdk.cli.run
import
run_command
from
dynamo.sdk.cli.serve
import
serve_command
from
dynamo.sdk.cli.serve
import
serve_command
from
dynamo.sdk.cli.server
import
cloud_command
# from dynamo.sdk.cli.server import cloud_command
from
dynamo.sdk.cli.start
import
start_command
from
dynamo.sdk.cli.start
import
start_command
from
dynamo.sdk.cli.utils
import
DynamoCommandGroup
from
dynamo.sdk.cli.utils
import
DynamoCommandGroup
# from dynamo.sdk.cli.cloud import cloud_command
server_context
.
service_type
=
"cli"
server_context
.
service_type
=
"cli"
CONTEXT_SETTINGS
=
{
"help_option_names"
:
(
"-h"
,
"--help"
)}
CONTEXT_SETTINGS
=
{
"help_option_names"
:
(
"-h"
,
"--help"
)}
...
@@ -52,14 +56,15 @@ def create_bentoml_cli() -> click.Command:
...
@@ -52,14 +56,15 @@ def create_bentoml_cli() -> click.Command:
"""
"""
# Add top-level CLI commands
# Add top-level CLI commands
#
bentoml_cli.add_command(cloud_command)
bentoml_cli
.
add_command
(
cloud_command
)
bentoml_cli
.
add_single_command
(
bento_command
,
"build"
)
bentoml_cli
.
add_single_command
(
bento_command
,
"build"
)
bentoml_cli
.
add_subcommands
(
start_command
)
bentoml_cli
.
add_subcommands
(
start_command
)
bentoml_cli
.
add_single_command
(
bento_command
,
"get"
)
bentoml_cli
.
add_subcommands
(
serve_command
)
bentoml_cli
.
add_subcommands
(
serve_command
)
bentoml_cli
.
add_subcommands
(
run_command
)
bentoml_cli
.
add_subcommands
(
run_command
)
# bentoml_cli.add_command(containerize_command)
# bentoml_cli.add_command(deploy_command)
# bentoml_cli.add_command(deploy_command)
# bentoml_cli.add_command(containerize_command)
bentoml_cli
.
add_command
(
deployment_command
)
# Load commands from extensions
# Load commands from extensions
for
ep
in
get_entry_points
(
"bentoml.commands"
):
for
ep
in
get_entry_points
(
"bentoml.commands"
):
bentoml_cli
.
add_command
(
ep
.
load
())
bentoml_cli
.
add_command
(
ep
.
load
())
...
...
deploy/dynamo/sdk/src/dynamo/sdk/cli/deployment.py
View file @
8621d914
This diff is collapsed.
Click to expand it.
deploy/dynamo/sdk/src/dynamo/sdk/cli/server.py
View file @
8621d914
...
@@ -26,17 +26,19 @@ from bentoml._internal.cloud.config import (
...
@@ -26,17 +26,19 @@ from bentoml._internal.cloud.config import (
CloudClientContext
,
CloudClientContext
,
)
)
from
bentoml._internal.configuration.containers
import
BentoMLContainer
from
bentoml._internal.configuration.containers
import
BentoMLContainer
from
bentoml._internal.utils
import
add_experimental_docstring
from
bentoml._internal.utils.cattr
import
bentoml_cattr
from
bentoml._internal.utils.cattr
import
bentoml_cattr
from
bentoml.exceptions
import
CLIException
,
CloudRESTApiClientError
from
bentoml.exceptions
import
CLIException
,
CloudRESTApiClientError
@
click
.
group
(
name
=
"server"
)
def
build_cloud_command
()
->
click
.
Group
:
def
cloud_command
():
@
click
.
group
(
name
=
"server"
)
@
add_experimental_docstring
def
cloud_command
():
"""Interact with your Dynamo Server"""
"""Interact with your Dynamo Server"""
@
cloud_command
.
command
()
@
cloud_command
.
command
()
@
click
.
option
(
@
click
.
option
(
"--endpoint"
,
"--endpoint"
,
type
=
click
.
STRING
,
type
=
click
.
STRING
,
help
=
"Dynamo Server endpoint"
,
help
=
"Dynamo Server endpoint"
,
...
@@ -45,16 +47,16 @@ def cloud_command():
...
@@ -45,16 +47,16 @@ def cloud_command():
show_default
=
True
,
show_default
=
True
,
show_envvar
=
True
,
show_envvar
=
True
,
required
=
True
,
required
=
True
,
)
)
@
click
.
option
(
@
click
.
option
(
"--api-token"
,
"--api-token"
,
type
=
click
.
STRING
,
type
=
click
.
STRING
,
help
=
"Dynamo Server user API token"
,
help
=
"Dynamo Server user API token"
,
envvar
=
"DYNAMO_SERVER_API_KEY"
,
envvar
=
"DYNAMO_SERVER_API_KEY"
,
show_envvar
=
True
,
show_envvar
=
True
,
required
=
True
,
required
=
True
,
)
)
def
login
(
endpoint
:
str
,
api_token
:
str
)
->
None
:
# type: ignore
def
login
(
endpoint
:
str
,
api_token
:
str
)
->
None
:
# type: ignore
"""Connect to your Dynamo Server. You can find deployment instructions for this in our docs"""
"""Connect to your Dynamo Server. You can find deployment instructions for this in our docs"""
try
:
try
:
cloud_rest_client
=
RestApiClient
(
endpoint
,
api_token
)
cloud_rest_client
=
RestApiClient
(
endpoint
,
api_token
)
...
@@ -72,7 +74,9 @@ def login(endpoint: str, api_token: str) -> None: # type: ignore
...
@@ -72,7 +74,9 @@ def login(endpoint: str, api_token: str) -> None: # type: ignore
cloud_context
=
BentoMLContainer
.
cloud_context
.
get
()
cloud_context
=
BentoMLContainer
.
cloud_context
.
get
()
ctx
=
CloudClientContext
(
ctx
=
CloudClientContext
(
name
=
cloud_context
if
cloud_context
is
not
None
else
current_context_name
,
name
=
cloud_context
if
cloud_context
is
not
None
else
current_context_name
,
endpoint
=
endpoint
,
endpoint
=
endpoint
,
api_token
=
api_token
,
api_token
=
api_token
,
email
=
user
.
email
,
email
=
user
.
email
,
...
@@ -80,7 +84,7 @@ def login(endpoint: str, api_token: str) -> None: # type: ignore
...
@@ -80,7 +84,7 @@ def login(endpoint: str, api_token: str) -> None: # type: ignore
ctx
.
save
()
ctx
.
save
()
rich
.
print
(
rich
.
print
(
f
":white_check_mark: Configured
Bento
Cloud credentials (current-context:
{
ctx
.
name
}
)"
f
":white_check_mark: Configured
Dynamo
Cloud credentials (current-context:
{
ctx
.
name
}
)"
)
)
rich
.
print
(
rich
.
print
(
f
":white_check_mark: Logged in as [blue]
{
user
.
email
}
[/] at [blue]
{
org
.
name
}
[/] organization"
f
":white_check_mark: Logged in as [blue]
{
user
.
email
}
[/] at [blue]
{
org
.
name
}
[/] organization"
...
@@ -97,25 +101,29 @@ def login(endpoint: str, api_token: str) -> None: # type: ignore
...
@@ -97,25 +101,29 @@ def login(endpoint: str, api_token: str) -> None: # type: ignore
file
=
sys
.
stderr
,
file
=
sys
.
stderr
,
)
)
@
cloud_command
.
command
()
@
cloud_command
.
command
()
def
current_context
()
->
None
:
# type: ignore
def
current_context
()
->
None
:
# type: ignore
"""Get current cloud context."""
"""Get current cloud context."""
rich
.
print_json
(
rich
.
print_json
(
data
=
bentoml_cattr
.
unstructure
(
CloudClientConfig
.
get_config
().
get_context
())
data
=
bentoml_cattr
.
unstructure
(
CloudClientConfig
.
get_config
().
get_context
())
)
)
@
cloud_command
.
command
()
@
cloud_command
.
command
()
def
list_context
()
->
None
:
# type: ignore
def
list_context
()
->
None
:
# type: ignore
"""List all available context."""
"""List all available context."""
config
=
CloudClientConfig
.
get_config
()
config
=
CloudClientConfig
.
get_config
()
rich
.
print_json
(
data
=
bentoml_cattr
.
unstructure
([
i
.
name
for
i
in
config
.
contexts
]))
rich
.
print_json
(
data
=
bentoml_cattr
.
unstructure
([
i
.
name
for
i
in
config
.
contexts
])
)
@
cloud_command
.
command
()
@
cloud_command
.
command
()
@
click
.
argument
(
"context_name"
,
type
=
click
.
STRING
)
@
click
.
argument
(
"context_name"
,
type
=
click
.
STRING
)
def
update_current_context
(
context_name
:
str
)
->
None
:
# type: ignore
def
update_current_context
(
context_name
:
str
)
->
None
:
# type: ignore
"""Update current context"""
"""Update current context"""
ctx
=
CloudClientConfig
.
get_config
().
set_current_context
(
context_name
)
ctx
=
CloudClientConfig
.
get_config
().
set_current_context
(
context_name
)
rich
.
print
(
f
"Successfully switched to context:
{
ctx
.
name
}
"
)
rich
.
print
(
f
"Successfully switched to context:
{
ctx
.
name
}
"
)
return
cloud_command
cloud_command
=
build_cloud_command
()
deploy/dynamo/tests/test_deployment.sh
0 → 100755
View file @
8621d914
#!/bin/bash
#!/bin/bash -e
# SPDX-FileCopyrightText: Copyright (c) 2024-2025 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
# SPDX-License-Identifier: Apache-2.0
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
set
-euo
pipefail
export
DYNAMO_SEREVR
=
"
${
DYNAMO_SEREVR
:-
http
://dynamo-server
}
"
export
DYNAMO_IMAGE
=
"
${
DYNAMO_IMAGE
:-
dynamo
-base
:latest
}
"
export
DEPLOYMENT_NAME
=
"
${
DEPLOYMENT_NAME
:-
ci
-hw
}
"
cd
/workspace/examples/hello_world
# Step.1: Login to dynamo server
dynamo server login
--api-token
TEST-TOKEN
--endpoint
$DYNAMO_SEREVR
# Step.2: build a dynamo nim with framework-less base
DYNAMO_TAG
=
$(
dynamo build hello_world:Frontend |
grep
"Successfully built"
|
awk
-F
"
\"
"
'{ print $2 }'
)
# Step.3: Deploy!
echo
$DYNAMO_TAG
dynamo deployment create
$DYNAMO_TAG
--no-wait
-n
$DEPLOYMENT_NAME
lib/bindings/python/pyproject.toml
View file @
8621d914
...
@@ -26,7 +26,7 @@ license = { text = "Apache-2.0" }
...
@@ -26,7 +26,7 @@ license = { text = "Apache-2.0" }
license-files
=
["LICENSE"]
license-files
=
["LICENSE"]
requires-python
=
">=3.10"
requires-python
=
">=3.10"
dependencies
=
[
dependencies
=
[
"pydantic>=2.10.6"
,
"pydantic>=2.10.6
,<2.11.0
"
,
"uvloop>=0.21.0"
,
"uvloop>=0.21.0"
,
"nats-py>=2.6.0"
,
"nats-py>=2.6.0"
,
]
]
...
...
Prev
1
2
3
Next
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment