From bc44f4259e16fc72dfef15c96a43fca43dcf5a07 Mon Sep 17 00:00:00 2001 From: Florent Gluck <florent.gluck@hesge.ch> Date: Thu, 13 Jul 2023 00:23:32 +0200 Subject: [PATCH] server: - optimisation: now passes "nodefaults" to qemu in order to suppress several non-needed backends - template code optimisation: internally manipulates templates by reference instead of by copy --- src/server/exec/QemuSystem.go | 3 +++ src/server/router/routerTemplates.go | 16 ++++++++-------- src/server/vms/template.go | 4 +--- src/server/vms/templates.go | 27 ++++++++++++++------------- src/server/vms/vm.go | 2 -- src/server/vms/vms.go | 8 ++++---- 6 files changed, 30 insertions(+), 30 deletions(-) diff --git a/src/server/exec/QemuSystem.go b/src/server/exec/QemuSystem.go index 2f7d0dd..77764b2 100644 --- a/src/server/exec/QemuSystem.go +++ b/src/server/exec/QemuSystem.go @@ -78,6 +78,9 @@ func NewQemuSystem(qgaSock string, cpus, ram int, nic string, usbDevs []string, // Enable KVM args := []string{"-enable-kvm"} + // Suppresses several non-needed backends: serial, parallel, floppy, CD-ROM, SD card, etc. + // More info here: https://gitlab.com/qemu-project/qemu/-/issues/322 + args = append(args, "-nodefaults") // CPU args = append(args, "-cpu", "host", "-smp", "cpus="+strconv.Itoa(cpus)) // RAM diff --git a/src/server/router/routerTemplates.go b/src/server/router/routerTemplates.go index af61195..8679d72 100644 --- a/src/server/router/routerTemplates.go +++ b/src/server/router/routerTemplates.go @@ -41,12 +41,12 @@ func (r *RouterTemplates)GetTemplates(c echo.Context) error { // If the logged user has CAP_TPL_LIST_ANY, lists all templates. if user.HasCapability(caps.CAP_TPL_LIST_ANY) { // Returns all templates - return c.JSONPretty(http.StatusOK, r.tpl.GetNetworkSerializedTemplates(func(t vms.Template) bool { return true }), " ") + return c.JSONPretty(http.StatusOK, r.tpl.GetNetworkSerializedTemplates(func(template *vms.Template) bool { return true }), " ") } else if user.HasCapability(caps.CAP_TPL_LIST) { // Returns templates owned by the logged user and public templates. return c.JSONPretty(http.StatusOK, - r.tpl.GetNetworkSerializedTemplates(func(t vms.Template) bool { - return t.GetOwner() == user.Email || t.IsPublic() + r.tpl.GetNetworkSerializedTemplates(func(template *vms.Template) bool { + return template.GetOwner() == user.Email || template.IsPublic() }), " ") } else { return echo.NewHTTPError(http.StatusUnauthorized, msgInsufficientCaps) @@ -290,19 +290,19 @@ func (r *RouterTemplates)ExportDisk(c echo.Context) error { } if user.HasCapability(caps.CAP_TPL_READFS_ANY) { - t, err := r.tpl.GetTemplate(tplID) + template, err := r.tpl.GetTemplate(tplID) if err != nil { return echo.NewHTTPError(http.StatusNotFound, err.Error()) } - return c.File(t.GetTemplateDiskPath()) + return c.File(template.GetTemplateDiskPath()) } else if user.HasCapability(caps.CAP_TPL_READFS) { - t, err := r.tpl.GetTemplate(tplID) + template, err := r.tpl.GetTemplate(tplID) if err != nil { return echo.NewHTTPError(http.StatusNotFound, err.Error()) } - if t.IsPublic() || t.GetOwner() == user.Email { - return c.File(t.GetTemplateDiskPath()) + if template.IsPublic() || template.GetOwner() == user.Email { + return c.File(template.GetTemplateDiskPath()) } } diff --git a/src/server/vms/template.go b/src/server/vms/template.go index 4bd6dfd..96a58ea 100644 --- a/src/server/vms/template.go +++ b/src/server/vms/template.go @@ -27,8 +27,6 @@ const ( templatePrivate = "private" ) -var dummyTemplate = Template{} - // Creates a template from a VM's disk. func NewTemplateFromVM(name, owner, access string, vm *VM) (*Template, error) { vm.mutex.Lock() @@ -149,7 +147,7 @@ func (template *Template)SerializeToNetwork() template.TemplateSerialized { return template.t } -// Creates a template. +// Cr1eates a template. func newTemplate(name, owner, access string) (*Template, error) { id, err := uuid.NewRandom() if err != nil { diff --git a/src/server/vms/templates.go b/src/server/vms/templates.go index d46df9a..ac3dbb9 100644 --- a/src/server/vms/templates.go +++ b/src/server/vms/templates.go @@ -14,10 +14,10 @@ import( ) type ( - TemplateKeeperFn func(tpl Template) bool + TemplateKeeperFn func(tpl *Template) bool Templates struct { - m map[string]Template + m map[string]*Template dir string // Base directory where templates reside rwlock *sync.RWMutex } @@ -35,7 +35,7 @@ func GetTemplatesInstance() *Templates { // NOTE: path is the root directory where templates reside. func InitTemplates() error { templatesDir := paths.GetInstance().TemplatesDir - templates = &Templates { m: make(map[string]Template), dir: templatesDir, rwlock: new(sync.RWMutex) } + templates = &Templates { m: make(map[string]*Template), dir: templatesDir, rwlock: new(sync.RWMutex) } dirs, err := utils.GetSubDirs(templatesDir) if err != nil { @@ -64,18 +64,19 @@ func InitTemplates() error { continue } - templates.m[templateDir] = *template + templates.m[templateDir] = template } return nil } // Returns the list of templates for which TemplateKeeperFn returns true. -func (templates *Templates)GetNetworkSerializedTemplates(keep TemplateKeeperFn) []t.TemplateSerialized { +func (templates *Templates)GetNetworkSerializedTemplates(keepFn TemplateKeeperFn) []t.TemplateSerialized { templates.rwlock.RLock() + list := []t.TemplateSerialized{} for _, tpl := range templates.m { - if keep(tpl) { + if keepFn(tpl) { list = append(list, tpl.SerializeToNetwork()) } } @@ -89,13 +90,13 @@ func (templates *Templates)GetNetworkSerializedTemplates(keep TemplateKeeperFn) } // Returns a template by its ID. -func (templates *Templates)GetTemplate(tplID uuid.UUID) (Template, error) { +func (templates *Templates)GetTemplate(tplID uuid.UUID) (*Template, error) { templates.rwlock.RLock() defer templates.rwlock.RUnlock() template, exists := templates.m[tplID.String()] if !exists { - return dummyTemplate, errors.New("Template not found") + return nil, errors.New("Template not found") } return template, nil } @@ -136,7 +137,7 @@ func (templates *Templates)AddTemplate(template *Template) error { } // Adds template to the map of templates. - templates.m[template.t.ID.String()] = *template + templates.m[template.t.ID.String()] = template return nil } @@ -149,6 +150,8 @@ func (templates *Templates)EditTemplate(tplID uuid.UUID, name, access string) er } // Only updates fields that have changed. + oriVal := tpl.t // Saves original template values. + if name != "" { tpl.t.Name = name } @@ -157,6 +160,8 @@ func (templates *Templates)EditTemplate(tplID uuid.UUID, name, access string) er } if err = tpl.validate(); err != nil { + // Restores original template values. + tpl.t = oriVal return err } @@ -165,10 +170,6 @@ func (templates *Templates)EditTemplate(tplID uuid.UUID, name, access string) er return err } - key := tpl.t.ID.String() - delete(templates.m, key) - templates.m[key] = tpl - return nil } diff --git a/src/server/vms/vm.go b/src/server/vms/vm.go index 6082fd6..3e89f86 100644 --- a/src/server/vms/vm.go +++ b/src/server/vms/vm.go @@ -52,8 +52,6 @@ const ( vmQGASockFile = "qga.sock" ) -var dummyVM = VM{} - // Custom password generator with the following characters removed: 0, O, l, I var passwordGen, _ = password.NewGenerator(&password.GeneratorInput{ LowerLetters: "abcdefghijkmnopqrstuvwxyz", diff --git a/src/server/vms/vms.go b/src/server/vms/vms.go index 1c385b5..f925002 100644 --- a/src/server/vms/vms.go +++ b/src/server/vms/vms.go @@ -120,7 +120,7 @@ func (vms *VMs)GetVM(vmID uuid.UUID) (*VM, error) { func (vms *VMs)getVMUnsafe(vmID uuid.UUID) (*VM, error) { vm, exists := vms.m[vmID.String()] if !exists { - return &dummyVM, errors.New("VM not found") + return nil, errors.New("VM not found") } return vm, nil } @@ -378,7 +378,7 @@ func (vms *VMs)EditVM(vmID uuid.UUID, p *params.VMEdit) error { } // Only updates fields that have changed. - prevVal := vm.v // Saves previous params values. + oriVal := vm.v // Saves original VM values. if p.Name != "" { vm.v.Name = p.Name @@ -397,8 +397,8 @@ func (vms *VMs)EditVM(vmID uuid.UUID, p *params.VMEdit) error { } if err = vm.validate(); err != nil { - // Restores previous values. - vm.v = prevVal + // Restores original VM values. + vm.v = oriVal return err } -- GitLab