Skip to content
Snippets Groups Projects
Commit 1fcb6762 authored by Florent Gluck's avatar Florent Gluck
Browse files

Fixed #39: "VM edit is buggy"

parent 95024bde
No related branches found
No related tags found
No related merge requests found
...@@ -101,7 +101,7 @@ func (r *RouterVMs)GetRebootableVMs(c echo.Context) error { ...@@ -101,7 +101,7 @@ func (r *RouterVMs)GetRebootableVMs(c echo.Context) error {
// curl --cacert ca.pem -X GET https://localhost:1077/vms/edit -H "Authorization: Bearer <AccessToken>" // curl --cacert ca.pem -X GET https://localhost:1077/vms/edit -H "Authorization: Bearer <AccessToken>"
func (r *RouterVMs)GetEditableVMs(c echo.Context) error { func (r *RouterVMs)GetEditableVMs(c echo.Context) error {
return r.performVMsList(c, caps.CAP_VM_EDIT_ANY, caps.CAP_VM_EDIT, func(vm vms.VM) bool { return r.performVMsList(c, caps.CAP_VM_EDIT_ANY, caps.CAP_VM_EDIT, func(vm vms.VM) bool {
return true return !vm.IsRunning()
}) })
} }
...@@ -121,7 +121,7 @@ func (r *RouterVMs)GetEditableVMAccessVMs(c echo.Context) error { ...@@ -121,7 +121,7 @@ func (r *RouterVMs)GetEditableVMAccessVMs(c echo.Context) error {
func(vm vms.VM) bool { func(vm vms.VM) bool {
// First, checks if the user is the VM's owner // First, checks if the user is the VM's owner
if vm.IsOwner(user.Email) { if vm.IsOwner(user.Email) {
return true return !vm.IsRunning()
} else { } else {
// Then, checks that user has CAP_VM_SET_ACCESS and also that // Then, checks that user has CAP_VM_SET_ACCESS and also that
// VM access has CAP_VM_SET_ACCESS set for the user // VM access has CAP_VM_SET_ACCESS set for the user
...@@ -129,7 +129,7 @@ func (r *RouterVMs)GetEditableVMAccessVMs(c echo.Context) error { ...@@ -129,7 +129,7 @@ func (r *RouterVMs)GetEditableVMAccessVMs(c echo.Context) error {
capabilities, exists := vm.Access[user.Email] capabilities, exists := vm.Access[user.Email]
if exists { if exists {
_, visible := capabilities[caps.CAP_VM_SET_ACCESS] _, visible := capabilities[caps.CAP_VM_SET_ACCESS]
return visible return visible && !vm.IsRunning()
} else { } else {
return false return false
} }
......
...@@ -22,9 +22,9 @@ type ( ...@@ -22,9 +22,9 @@ type (
VMs struct { VMs struct {
m map[string]VM m map[string]VM
dir string // Base directory where VMs are stored dir string // Base directory where VMs are stored
rwlock *sync.RWMutex // RWlock to ensure the coherency of the map (m) of VMs rwlock *sync.RWMutex // RWlock to ensure the VMs' map (m) coherency
usedPorts [65536]bool // Indicates which ports are used by the VMs usedPorts [65536]bool // Ports used by VMs
usedRAM int // Used RAM by running VMs (in MB) usedRAM int // RAM used by running VMs (in MB)
} }
) )
...@@ -129,13 +129,21 @@ func (vms *VMs)DeleteVM(vmID uuid.UUID) error { ...@@ -129,13 +129,21 @@ func (vms *VMs)DeleteVM(vmID uuid.UUID) error {
return err return err
} }
// Deletes the VM's files (and directories).
vm.mutex.Lock() vm.mutex.Lock()
if vm.IsRunning() {
vm.mutex.Unlock()
return errors.New("VM must be stopped")
}
// Deletes the VM's files (and directories).
if err := vm.delete(); err != nil { if err := vm.delete(); err != nil {
vm.mutex.Unlock() vm.mutex.Unlock()
return err return err
} }
vm.mutex.Unlock() vm.mutex.Unlock()
// Removes the VM from the map. // Removes the VM from the map.
delete(vms.m, vmID.String()) delete(vms.m, vmID.String())
return nil return nil
...@@ -172,6 +180,10 @@ func (vms *VMs)StartVM(vmID uuid.UUID) (int, string, error) { ...@@ -172,6 +180,10 @@ func (vms *VMs)StartVM(vmID uuid.UUID) (int, string, error) {
return 0, "", err return 0, "", err
} }
if vm.IsRunning() {
return 0, "", errors.New("VM must be stopped")
}
totalRAM, availRAM, err := utils.GetRAM() totalRAM, availRAM, err := utils.GetRAM()
if err != nil { if err != nil {
return -1, "", errors.New("Failed obtaining memory info: "+err.Error()) return -1, "", errors.New("Failed obtaining memory info: "+err.Error())
...@@ -233,8 +245,13 @@ func (vms *VMs)KillVM(vmID uuid.UUID) error { ...@@ -233,8 +245,13 @@ func (vms *VMs)KillVM(vmID uuid.UUID) error {
} }
vm.mutex.Lock() vm.mutex.Lock()
defer vm.mutex.Unlock()
if !vm.IsRunning() {
return errors.New("VM must be running")
}
err = vm.kill() err = vm.kill()
vm.mutex.Unlock()
return err return err
} }
...@@ -249,8 +266,13 @@ func (vms *VMs)ShutdownVM(vmID uuid.UUID) error { ...@@ -249,8 +266,13 @@ func (vms *VMs)ShutdownVM(vmID uuid.UUID) error {
} }
vm.mutex.Lock() vm.mutex.Lock()
defer vm.mutex.Unlock()
if !vm.IsRunning() {
return errors.New("VM must be running")
}
err = vm.shutdown() err = vm.shutdown()
vm.mutex.Unlock()
return err return err
} }
...@@ -265,8 +287,13 @@ func (vms *VMs)RebootVM(vmID uuid.UUID) error { ...@@ -265,8 +287,13 @@ func (vms *VMs)RebootVM(vmID uuid.UUID) error {
} }
vm.mutex.Lock() vm.mutex.Lock()
defer vm.mutex.Unlock()
if !vm.IsRunning() {
return errors.New("VM must be running")
}
err = vm.reboot() err = vm.reboot()
vm.mutex.Unlock()
return err return err
} }
...@@ -285,11 +312,21 @@ func (vms *VMs)IsTemplateUsed(templateID string) bool { ...@@ -285,11 +312,21 @@ func (vms *VMs)IsTemplateUsed(templateID string) bool {
// Edit a VM' specs: name, cpus, ram, nic // Edit a VM' specs: name, cpus, ram, nic
func (vms *VMs)EditVM(vmID uuid.UUID, name string, cpus, ram int, nic NicType, usbDevs []string) error { func (vms *VMs)EditVM(vmID uuid.UUID, name string, cpus, ram int, nic NicType, usbDevs []string) error {
vms.rwlock.Lock()
defer vms.rwlock.Unlock()
vm, err := vms.getVMUnsafe(vmID) vm, err := vms.getVMUnsafe(vmID)
if err != nil { if err != nil {
return err return err
} }
vm.mutex.Lock()
defer vm.mutex.Unlock()
if vm.IsRunning() {
return errors.New("VM must be stopped")
}
// Only updates fields that have changed. // Only updates fields that have changed.
if name != "" { if name != "" {
vm.Name = name vm.Name = name
...@@ -311,11 +348,6 @@ func (vms *VMs)EditVM(vmID uuid.UUID, name string, cpus, ram int, nic NicType, u ...@@ -311,11 +348,6 @@ func (vms *VMs)EditVM(vmID uuid.UUID, name string, cpus, ram int, nic NicType, u
return err return err
} }
vm.mutex.Lock()
defer vm.mutex.Unlock()
vms.rwlock.Lock()
defer vms.rwlock.Unlock()
if err = vms.updateVM(&vm); err != nil { if err = vms.updateVM(&vm); err != nil {
return err return err
} }
...@@ -343,6 +375,10 @@ func (vms *VMs)SetVMAccess(vmID uuid.UUID, loggedUserEmail, userEmail string, ne ...@@ -343,6 +375,10 @@ func (vms *VMs)SetVMAccess(vmID uuid.UUID, loggedUserEmail, userEmail string, ne
vm.mutex.Lock() vm.mutex.Lock()
defer vm.mutex.Unlock() defer vm.mutex.Unlock()
if vm.IsRunning() {
return errors.New("VM must be stopped")
}
// First, check that the logged user is the VM's owner. // First, check that the logged user is the VM's owner.
if !vm.IsOwner(loggedUserEmail) { if !vm.IsOwner(loggedUserEmail) {
// Next, checks the logged user has VM_SET_ACCESS set in her/his VM access. // Next, checks the logged user has VM_SET_ACCESS set in her/his VM access.
...@@ -378,6 +414,10 @@ func (vms *VMs)DeleteVMAccess(vmID uuid.UUID, loggedUserEmail, userEmail string) ...@@ -378,6 +414,10 @@ func (vms *VMs)DeleteVMAccess(vmID uuid.UUID, loggedUserEmail, userEmail string)
vm.mutex.Lock() vm.mutex.Lock()
defer vm.mutex.Unlock() defer vm.mutex.Unlock()
if vm.IsRunning() {
return errors.New("VM must be stopped")
}
// First, check that the logged user is the VM's owner. // First, check that the logged user is the VM's owner.
if !vm.IsOwner(loggedUserEmail) { if !vm.IsOwner(loggedUserEmail) {
// Next, checks the logged user has VM_SET_ACCESS set in her/his VM access. // Next, checks the logged user has VM_SET_ACCESS set in her/his VM access.
...@@ -410,6 +450,10 @@ func (vms *VMs)ExportVMFiles(vm *VM, vmDir, tarGzFile string) error { ...@@ -410,6 +450,10 @@ func (vms *VMs)ExportVMFiles(vm *VM, vmDir, tarGzFile string) error {
// Imports files from a tar.gz archive into a VM's filesystem, in a specified directory. // Imports files from a tar.gz archive into a VM's filesystem, in a specified directory.
func (vms *VMs)ImportFilesToVM(vm *VM, tarGzFile, vmDir string) error { func (vms *VMs)ImportFilesToVM(vm *VM, tarGzFile, vmDir string) error {
if vm.IsRunning() {
return errors.New("VM must be stopped")
}
// Marks the VM to copy from as being busy. // Marks the VM to copy from as being busy.
if err := vms.setDiskBusy(vm); err != nil { if err := vms.setDiskBusy(vm); err != nil {
return errors.New("Failed setting disk busy flag during VM files import: "+err.Error()) return errors.New("Failed setting disk busy flag during VM files import: "+err.Error())
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment