mirror of
https://github.com/lordmathis/llamactl.git
synced 2025-11-06 09:04:27 +00:00
Refactor instance management and add InstanceManager interface
This commit is contained in:
@@ -2,7 +2,12 @@ module llamactl
|
|||||||
|
|
||||||
go 1.24.5
|
go 1.24.5
|
||||||
|
|
||||||
require github.com/go-chi/chi/v5 v5.2.2
|
require (
|
||||||
|
github.com/go-chi/chi/v5 v5.2.2
|
||||||
|
github.com/google/uuid v1.6.0
|
||||||
|
github.com/swaggo/http-swagger v1.3.4
|
||||||
|
github.com/swaggo/swag v1.16.5
|
||||||
|
)
|
||||||
|
|
||||||
require (
|
require (
|
||||||
github.com/KyleBanks/depth v1.2.1 // indirect
|
github.com/KyleBanks/depth v1.2.1 // indirect
|
||||||
@@ -13,13 +18,9 @@ require (
|
|||||||
github.com/josharian/intern v1.0.0 // indirect
|
github.com/josharian/intern v1.0.0 // indirect
|
||||||
github.com/mailru/easyjson v0.9.0 // indirect
|
github.com/mailru/easyjson v0.9.0 // indirect
|
||||||
github.com/swaggo/files v1.0.1 // indirect
|
github.com/swaggo/files v1.0.1 // indirect
|
||||||
github.com/swaggo/http-swagger v1.3.4 // indirect
|
|
||||||
github.com/swaggo/swag v1.16.5 // indirect
|
|
||||||
golang.org/x/mod v0.26.0 // indirect
|
golang.org/x/mod v0.26.0 // indirect
|
||||||
golang.org/x/net v0.42.0 // indirect
|
golang.org/x/net v0.42.0 // indirect
|
||||||
golang.org/x/sync v0.16.0 // indirect
|
golang.org/x/sync v0.16.0 // indirect
|
||||||
golang.org/x/sys v0.34.0 // indirect
|
|
||||||
golang.org/x/tools v0.35.0 // indirect
|
golang.org/x/tools v0.35.0 // indirect
|
||||||
gopkg.in/yaml.v2 v2.4.0 // indirect
|
|
||||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
github.com/KyleBanks/depth v1.2.1 h1:5h8fQADFrWtarTdtDudMmGsC7GPbOAu6RVB3ffsVFHc=
|
github.com/KyleBanks/depth v1.2.1 h1:5h8fQADFrWtarTdtDudMmGsC7GPbOAu6RVB3ffsVFHc=
|
||||||
github.com/KyleBanks/depth v1.2.1/go.mod h1:jzSb9d0L43HxTQfT+oSA1EEp2q+ne2uh6XgeJcm8brE=
|
github.com/KyleBanks/depth v1.2.1/go.mod h1:jzSb9d0L43HxTQfT+oSA1EEp2q+ne2uh6XgeJcm8brE=
|
||||||
|
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
github.com/go-chi/chi/v5 v5.2.2 h1:CMwsvRVTbXVytCk1Wd72Zy1LAsAh9GxMmSNWLHCG618=
|
github.com/go-chi/chi/v5 v5.2.2 h1:CMwsvRVTbXVytCk1Wd72Zy1LAsAh9GxMmSNWLHCG618=
|
||||||
github.com/go-chi/chi/v5 v5.2.2/go.mod h1:L2yAIGWB3H+phAw1NxKwWM+7eUH/lU8pOMm5hHcoops=
|
github.com/go-chi/chi/v5 v5.2.2/go.mod h1:L2yAIGWB3H+phAw1NxKwWM+7eUH/lU8pOMm5hHcoops=
|
||||||
@@ -11,12 +12,24 @@ github.com/go-openapi/spec v0.21.0 h1:LTVzPc3p/RzRnkQqLRndbAzjY0d0BCL72A6j3CdL9Z
|
|||||||
github.com/go-openapi/spec v0.21.0/go.mod h1:78u6VdPw81XU44qEWGhtr982gJ5BWg2c0I5XwVMotYk=
|
github.com/go-openapi/spec v0.21.0/go.mod h1:78u6VdPw81XU44qEWGhtr982gJ5BWg2c0I5XwVMotYk=
|
||||||
github.com/go-openapi/swag v0.23.1 h1:lpsStH0n2ittzTnbaSloVZLuB5+fvSY/+hnagBjSNZU=
|
github.com/go-openapi/swag v0.23.1 h1:lpsStH0n2ittzTnbaSloVZLuB5+fvSY/+hnagBjSNZU=
|
||||||
github.com/go-openapi/swag v0.23.1/go.mod h1:STZs8TbRvEQQKUA+JZNAm3EWlgaOBGpyFDqQnDHMef0=
|
github.com/go-openapi/swag v0.23.1/go.mod h1:STZs8TbRvEQQKUA+JZNAm3EWlgaOBGpyFDqQnDHMef0=
|
||||||
|
github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
|
||||||
|
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
||||||
|
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
|
||||||
|
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||||
github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY=
|
github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY=
|
||||||
github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y=
|
github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y=
|
||||||
|
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
|
||||||
|
github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
|
||||||
|
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
|
||||||
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
|
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
|
||||||
github.com/mailru/easyjson v0.9.0 h1:PrnmzHw7262yW8sTBwxi1PdJA3Iw/EKBa8psRf7d9a4=
|
github.com/mailru/easyjson v0.9.0 h1:PrnmzHw7262yW8sTBwxi1PdJA3Iw/EKBa8psRf7d9a4=
|
||||||
github.com/mailru/easyjson v0.9.0/go.mod h1:1+xMtQp2MRNVL/V1bOzuP3aP8VNwRW55fQUto+XFtTU=
|
github.com/mailru/easyjson v0.9.0/go.mod h1:1+xMtQp2MRNVL/V1bOzuP3aP8VNwRW55fQUto+XFtTU=
|
||||||
|
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||||
|
github.com/rogpeppe/go-internal v1.11.0 h1:cWPaGQEPrBb5/AsnsZesgZZ9yb1OQ+GOISoDNXVBh4M=
|
||||||
|
github.com/rogpeppe/go-internal v1.11.0/go.mod h1:ddIwULY96R17DhadqLgMfk9H9tvdUzkipdSkR5nkCZA=
|
||||||
|
github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA=
|
||||||
|
github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
|
||||||
github.com/swaggo/files v1.0.1 h1:J1bVJ4XHZNq0I46UU90611i9/YzdrF7x92oX1ig5IdE=
|
github.com/swaggo/files v1.0.1 h1:J1bVJ4XHZNq0I46UU90611i9/YzdrF7x92oX1ig5IdE=
|
||||||
github.com/swaggo/files v1.0.1/go.mod h1:0qXmMNH6sXNf+73t65aKeB+ApmgxdnkQzVTAj2uaMUg=
|
github.com/swaggo/files v1.0.1/go.mod h1:0qXmMNH6sXNf+73t65aKeB+ApmgxdnkQzVTAj2uaMUg=
|
||||||
github.com/swaggo/http-swagger v1.3.4 h1:q7t/XLx0n15H1Q9/tk3Y9L4n210XzJF5WtnDX64a5ww=
|
github.com/swaggo/http-swagger v1.3.4 h1:q7t/XLx0n15H1Q9/tk3Y9L4n210XzJF5WtnDX64a5ww=
|
||||||
@@ -45,8 +58,6 @@ golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBc
|
|||||||
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.34.0 h1:H5Y5sJ2L2JRdyv7ROF1he/lPdvFsd0mJHFw2ThKHxLA=
|
|
||||||
golang.org/x/sys v0.34.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=
|
|
||||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||||
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
||||||
golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
|
golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
|
||||||
@@ -61,7 +72,7 @@ golang.org/x/tools v0.35.0 h1:mBffYraMEf7aa0sB+NuKnuCy8qI/9Bughn8dC2Gu5r0=
|
|||||||
golang.org/x/tools v0.35.0/go.mod h1:NKdj5HkL/73byiZSJjqJgKn3ep7KjFkBOkR/Hps3VPw=
|
golang.org/x/tools v0.35.0/go.mod h1:NKdj5HkL/73byiZSJjqJgKn3ep7KjFkBOkR/Hps3VPw=
|
||||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||||
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
|
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
|
||||||
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
|
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
|
||||||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||||
|
|||||||
@@ -1,19 +1,12 @@
|
|||||||
package llamactl
|
package llamactl
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/google/uuid"
|
||||||
|
)
|
||||||
|
|
||||||
type Instance struct {
|
type Instance struct {
|
||||||
|
ID uuid.UUID
|
||||||
|
Port int
|
||||||
Status string
|
Status string
|
||||||
Options *LlamaServerOptions
|
Options *InstanceOptions
|
||||||
}
|
|
||||||
|
|
||||||
type InstanceManager interface {
|
|
||||||
}
|
|
||||||
|
|
||||||
type instanceManager struct {
|
|
||||||
instances map[string]*Instance
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewInstanceManager() InstanceManager {
|
|
||||||
return &instanceManager{
|
|
||||||
instances: make(map[string]*Instance),
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
156
server/pkg/manager.go
Normal file
156
server/pkg/manager.go
Normal file
@@ -0,0 +1,156 @@
|
|||||||
|
package llamactl
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
"github.com/google/uuid"
|
||||||
|
)
|
||||||
|
|
||||||
|
// InstanceManager defines the interface for managing instances of the llama server.
|
||||||
|
type InstanceManager interface {
|
||||||
|
ListInstances() ([]*Instance, error)
|
||||||
|
CreateInstance(options *InstanceOptions) (*Instance, error)
|
||||||
|
GetInstance(id uuid.UUID) (*Instance, error)
|
||||||
|
UpdateInstance(id uuid.UUID, options *InstanceOptions) (*Instance, error)
|
||||||
|
DeleteInstance(id uuid.UUID) error
|
||||||
|
StartInstance(id uuid.UUID) (*Instance, error)
|
||||||
|
StopInstance(id uuid.UUID) (*Instance, error)
|
||||||
|
RestartInstance(id uuid.UUID) (*Instance, error)
|
||||||
|
GetInstanceLogs(id uuid.UUID) (string, error)
|
||||||
|
}
|
||||||
|
|
||||||
|
type instanceManager struct {
|
||||||
|
instances map[uuid.UUID]*Instance
|
||||||
|
portRange [][2]int // Range of ports to use for instances
|
||||||
|
ports map[int]bool
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewInstanceManager creates a new instance of InstanceManager.
|
||||||
|
func NewInstanceManager() InstanceManager {
|
||||||
|
return &instanceManager{
|
||||||
|
instances: make(map[uuid.UUID]*Instance),
|
||||||
|
portRange: [][2]int{{8000, 9000}},
|
||||||
|
ports: make(map[int]bool),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ListInstances returns a list of all instances managed by the instance manager.
|
||||||
|
func (im *instanceManager) ListInstances() ([]*Instance, error) {
|
||||||
|
var instances []*Instance
|
||||||
|
for _, instance := range im.instances {
|
||||||
|
instances = append(instances, instance)
|
||||||
|
}
|
||||||
|
return instances, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// CreateInstance creates a new instance with the given options and returns it.
|
||||||
|
// The instance is initially in a "stopped" state.
|
||||||
|
func (im *instanceManager) CreateInstance(options *InstanceOptions) (*Instance, error) {
|
||||||
|
id := uuid.New()
|
||||||
|
instance := &Instance{
|
||||||
|
ID: id,
|
||||||
|
Port: 8080, // Default port, can be changed later
|
||||||
|
Status: "stopped", // Initial status
|
||||||
|
Options: options,
|
||||||
|
}
|
||||||
|
im.instances[id] = instance
|
||||||
|
return instance, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetInstance retrieves an instance by its ID.
|
||||||
|
func (im *instanceManager) GetInstance(id uuid.UUID) (*Instance, error) {
|
||||||
|
instance, exists := im.instances[id]
|
||||||
|
if !exists {
|
||||||
|
return nil, fmt.Errorf("instance with ID %s not found", id)
|
||||||
|
}
|
||||||
|
return instance, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// UpdateInstance updates the options of an existing instance and returns it.
|
||||||
|
func (im *instanceManager) UpdateInstance(id uuid.UUID, options *InstanceOptions) (*Instance, error) {
|
||||||
|
instance, exists := im.instances[id]
|
||||||
|
if !exists {
|
||||||
|
return nil, fmt.Errorf("instance with ID %s not found", id)
|
||||||
|
}
|
||||||
|
instance.Options = options
|
||||||
|
return instance, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeleteInstance removes stopped instance by its ID.
|
||||||
|
func (im *instanceManager) DeleteInstance(id uuid.UUID) error {
|
||||||
|
_, exists := im.instances[id]
|
||||||
|
if !exists {
|
||||||
|
return fmt.Errorf("instance with ID %s not found", id)
|
||||||
|
}
|
||||||
|
|
||||||
|
if im.instances[id].Status != "stopped" {
|
||||||
|
return fmt.Errorf("cannot delete a running instance, stop it first")
|
||||||
|
}
|
||||||
|
|
||||||
|
delete(im.instances, id)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// StartInstance starts a stopped instance and returns it.
|
||||||
|
// If the instance is already running, it returns an error.
|
||||||
|
func (im *instanceManager) StartInstance(id uuid.UUID) (*Instance, error) {
|
||||||
|
instance, exists := im.instances[id]
|
||||||
|
if !exists {
|
||||||
|
return nil, fmt.Errorf("instance with ID %s not found", id)
|
||||||
|
}
|
||||||
|
if instance.Status == "running" {
|
||||||
|
return instance, fmt.Errorf("instance with ID %s is already running", id)
|
||||||
|
}
|
||||||
|
|
||||||
|
//TODO:
|
||||||
|
|
||||||
|
instance.Status = "running"
|
||||||
|
return instance, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// StopInstance stops a running instance and returns it.
|
||||||
|
func (im *instanceManager) StopInstance(id uuid.UUID) (*Instance, error) {
|
||||||
|
instance, exists := im.instances[id]
|
||||||
|
if !exists {
|
||||||
|
return nil, fmt.Errorf("instance with ID %s not found", id)
|
||||||
|
}
|
||||||
|
if instance.Status == "stopped" {
|
||||||
|
return instance, fmt.Errorf("instance with ID %s is already stopped", id)
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO:
|
||||||
|
instance.Status = "stopped"
|
||||||
|
return instance, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// RestartInstance stops and then starts an instance, returning the updated instance.
|
||||||
|
func (im *instanceManager) RestartInstance(id uuid.UUID) (*Instance, error) {
|
||||||
|
instance, err := im.StopInstance(id)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return im.StartInstance(instance.ID)
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetInstanceLogs retrieves the logs for a specific instance by its ID.
|
||||||
|
func (im *instanceManager) GetInstanceLogs(id uuid.UUID) (string, error) {
|
||||||
|
_, exists := im.instances[id]
|
||||||
|
if !exists {
|
||||||
|
return "", fmt.Errorf("instance with ID %s not found", id)
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: Implement actual log retrieval logic
|
||||||
|
return fmt.Sprintf("Logs for instance %s", id), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (im *instanceManager) getNextAvailablePort() (int, error) {
|
||||||
|
for _, portRange := range im.portRange {
|
||||||
|
for port := portRange[0]; port <= portRange[1]; port++ {
|
||||||
|
if !im.ports[port] {
|
||||||
|
im.ports[port] = true
|
||||||
|
return port, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0, fmt.Errorf("no available ports in the specified range")
|
||||||
|
}
|
||||||
@@ -8,7 +8,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
type InstanceOptions struct {
|
type InstanceOptions struct {
|
||||||
Name string
|
Name string `json:"name,omitempty"`
|
||||||
*LlamaServerOptions
|
*LlamaServerOptions
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user