├── .gitignore ├── src ├── task │ ├── go.mod │ ├── handle_cell_status_updated.go │ ├── handle_guest_deleted.go │ ├── handle_guest_system_reset.go │ ├── handle_address_changed.go │ ├── query_unallocated_cells.go │ ├── data_qualifier.go │ ├── delete_compute_pool.go │ ├── delete_storage_pool.go │ ├── delete_system_template.go │ ├── disable_compute_cell.go │ ├── sync_image_server.go │ ├── handle_guest_created.go │ ├── handle_guest_started.go │ ├── handle_guest_stopped.go │ ├── delete_address_pool.go │ ├── delete_security_policy_group.go │ ├── enable_compute_cell.go │ ├── get_guest.go │ ├── query_storage_pool.go │ ├── query_cells_by_pool.go │ ├── get_migration.go │ ├── handle_media_detached.go │ ├── get_storage_pool.go │ ├── remove_security_policy_rule.go │ ├── remove_address_range.go │ ├── handle_media_attached.go │ ├── get_compute_pool.go │ ├── query_migration.go │ ├── query_system_templates.go │ ├── remove_compute_cell.go │ ├── create_address_pool.go │ ├── get_security_policy_group.go │ ├── get_batch_stop_guest.go │ ├── add_address_range.go │ ├── get_batch_delete_guest.go │ ├── move_security_policy_rule.go │ ├── create_storage_pool.go │ ├── modify_storage_pool.go │ ├── query_compute_pool.go │ ├── handle_guest_updated.go │ ├── query_instance_status.go │ ├── query_address_range.go │ ├── query_cell_storage_paths.go │ ├── create_compute_pool.go │ ├── get_system_template.go │ ├── modify_compute_pool.go │ ├── handle_instance_migrated.go │ ├── get_batch_create_guest.go │ ├── query_zone_status.go │ ├── get_compute_pool_status.go │ ├── get_disk_image.go │ ├── change_cell_storage_path.go │ ├── get_media_image.go │ ├── delete_disk_image.go │ ├── modify_disk_image.go │ ├── query_disk_image.go │ ├── query_media_image.go │ ├── create_media_image.go │ ├── delete_media_image.go │ ├── modify_media_image.go │ ├── sync_disk_images.go │ ├── sync_media_images.go │ ├── get_compute_cell_status.go │ ├── get_address_range.go │ ├── get_security_policy_rules.go │ ├── handle_cell_disconnected.go │ ├── query_address_pool.go │ ├── get_auth.go │ ├── query_snapshot.go │ ├── get_guest_security_policy.go │ ├── add_security_policy_rule.go │ ├── create_security_policy_group.go │ ├── modify_security_policy_group.go │ ├── get_address_pool.go │ ├── search_guests.go │ ├── add_guest_security_rule.go │ ├── change_guest_security_action.go │ ├── eject_media.go │ ├── modify_security_policy_rule.go │ ├── create_system_template.go │ ├── modify_address_pool.go │ ├── move_guest_security_rule.go │ ├── modify_guest_security_rule.go │ ├── remove_guest_security_rule.go │ ├── modify_system_template.go │ ├── query_compute_pool_status.go │ ├── delete_guest.go │ ├── shrink_guest_disk.go │ └── reset_instance_monitor_secret.go ├── imageserver │ ├── delete_disk_image.go │ ├── go.mod │ ├── delete_media_image.go │ ├── sync_disk_images.go │ ├── sync_media_images.go │ ├── get_media_image.go │ ├── get_disk_image.go │ ├── create_disk_image.go │ ├── create_media_image.go │ ├── modify_disk_image.go │ ├── modify_media_image.go │ ├── handle_disk_image_update.go │ ├── query_media_image.go │ ├── query_disk_image.go │ ├── task_manager.go │ └── image_service_test.go └── modules │ └── go.mod ├── LICENSE ├── core_service_test.go └── go.mod /.gitignore: -------------------------------------------------------------------------------- 1 | # Binaries for programs and plugins 2 | *.exe 3 | *.exe~ 4 | *.dll 5 | *.so 6 | *.dylib 7 | 8 | # Test binary, build with `go test -c` 9 | *.test 10 | 11 | # Output of the go coverage tool, specifically when used with LiteIDE 12 | *.out 13 | 14 | .idea 15 | log 16 | cert 17 | config 18 | data 19 | pkg 20 | core 21 | core.* 22 | -------------------------------------------------------------------------------- /src/task/go.mod: -------------------------------------------------------------------------------- 1 | module github.com/project-nano/core/task 2 | 3 | go 1.19 4 | 5 | replace ( 6 | github.com/project-nano/core/modules => ../modules 7 | github.com/project-nano/framework => ../../../framework 8 | ) 9 | 10 | require ( 11 | github.com/pkg/errors v0.9.1 12 | github.com/project-nano/core/modules v0.0.0-00010101000000-000000000000 13 | github.com/project-nano/framework v1.0.9 14 | github.com/rs/xid v1.5.0 // indirect 15 | ) 16 | -------------------------------------------------------------------------------- /src/task/handle_cell_status_updated.go: -------------------------------------------------------------------------------- 1 | package task 2 | 3 | import ( 4 | "github.com/project-nano/framework" 5 | "github.com/project-nano/core/modules" 6 | "log" 7 | ) 8 | 9 | type HandleCellStatusUpdatedExecutor struct { 10 | ResourceModule modules.ResourceModule 11 | } 12 | 13 | func (executor *HandleCellStatusUpdatedExecutor)Execute(id framework.SessionID, event framework.Message, 14 | incoming chan framework.Message, terminate chan bool) error { 15 | var usage = modules.CellStatusReport{} 16 | if err := usage.FromMessage(event); err != nil{ 17 | log.Printf("handle cell usage fail: %s", err.Error()) 18 | return err 19 | } 20 | executor.ResourceModule.UpdateCellStatus(usage) 21 | return nil 22 | } -------------------------------------------------------------------------------- /src/task/handle_guest_deleted.go: -------------------------------------------------------------------------------- 1 | package task 2 | 3 | import ( 4 | "github.com/project-nano/framework" 5 | "log" 6 | "github.com/project-nano/core/modules" 7 | ) 8 | 9 | type HandleGuestDeletedExecutor struct { 10 | Sender framework.MessageSender 11 | ResourceModule modules.ResourceModule 12 | } 13 | 14 | func (executor *HandleGuestDeletedExecutor)Execute(id framework.SessionID, event framework.Message, 15 | incoming chan framework.Message, terminate chan bool) error { 16 | instanceID, err := event.GetString(framework.ParamKeyInstance) 17 | if err != nil { 18 | return err 19 | } 20 | log.Printf("[%08X] recv guest '%s' deleted from %s.[%08X]", id, instanceID, 21 | event.GetSender(), event.GetFromSession()) 22 | var respChan = make(chan error) 23 | executor.ResourceModule.DeallocateInstance(instanceID, nil, respChan) 24 | err = <- respChan 25 | if err != nil{ 26 | log.Printf("[%08X] deallocate guest fail: %s", id, err.Error()) 27 | } 28 | return nil 29 | } 30 | -------------------------------------------------------------------------------- /src/task/handle_guest_system_reset.go: -------------------------------------------------------------------------------- 1 | package task 2 | 3 | import ( 4 | "github.com/project-nano/framework" 5 | "github.com/project-nano/core/modules" 6 | "log" 7 | "errors" 8 | ) 9 | 10 | type HandleGuestSystemResetExecutor struct { 11 | ResourceModule modules.ResourceModule 12 | } 13 | 14 | func (executor *HandleGuestSystemResetExecutor)Execute(id framework.SessionID, request framework.Message, 15 | incoming chan framework.Message, terminate chan bool) (err error) { 16 | var guestID string 17 | if guestID, err = request.GetString(framework.ParamKeyGuest); err != nil{ 18 | return 19 | } 20 | var respChan = make(chan error, 1) 21 | if !request.IsSuccess(){ 22 | err = errors.New(request.GetError()) 23 | } 24 | executor.ResourceModule.FinishResetSystem(guestID, err, respChan) 25 | err = <- respChan 26 | if err != nil{ 27 | log.Printf("[%08X] recv guest reset finish, but update fail: %s", id, err.Error()) 28 | }else{ 29 | log.Printf("[%08X] reset system of guest '%s' finished", id, guestID) 30 | } 31 | return nil 32 | } 33 | -------------------------------------------------------------------------------- /src/task/handle_address_changed.go: -------------------------------------------------------------------------------- 1 | package task 2 | 3 | import ( 4 | "github.com/project-nano/framework" 5 | "github.com/project-nano/core/modules" 6 | "log" 7 | ) 8 | 9 | type HandleAddressChangedExecutor struct { 10 | ResourceModule modules.ResourceModule 11 | } 12 | 13 | func (executor *HandleAddressChangedExecutor)Execute(id framework.SessionID, event framework.Message, 14 | incoming chan framework.Message, terminate chan bool) error { 15 | instanceID, err := event.GetString(framework.ParamKeyInstance) 16 | if err != nil { 17 | return err 18 | } 19 | address, err := event.GetString(framework.ParamKeyAddress) 20 | if err != nil{ 21 | return err 22 | } 23 | 24 | log.Printf("[%08X] address of guest '%s' changed to %s, notify from %s.[%08X]", id, instanceID, 25 | address, event.GetSender(), event.GetFromSession()) 26 | var respChan = make(chan error) 27 | executor.ResourceModule.UpdateInstanceAddress(instanceID, address, respChan) 28 | err = <- respChan 29 | if err != nil{ 30 | log.Printf("[%08X] update address fail: %s", id, err.Error()) 31 | } 32 | return nil 33 | } -------------------------------------------------------------------------------- /src/task/query_unallocated_cells.go: -------------------------------------------------------------------------------- 1 | package task 2 | 3 | import ( 4 | "github.com/project-nano/framework" 5 | "github.com/project-nano/core/modules" 6 | "log" 7 | ) 8 | 9 | type QueryUnallocatedCellsExecutor struct { 10 | Sender framework.MessageSender 11 | ResourceModule modules.ResourceModule 12 | } 13 | 14 | func (executor *QueryUnallocatedCellsExecutor)Execute(id framework.SessionID, request framework.Message, 15 | incoming chan framework.Message, terminate chan bool) error { 16 | 17 | log.Printf("[%08X] query unallocated compute cells from %s.[%08X]", id, request.GetSender(), request.GetFromSession()) 18 | var respChan= make(chan modules.ResourceResult) 19 | 20 | executor.ResourceModule.GetUnallocatedCells(respChan) 21 | result := <-respChan 22 | 23 | resp, _ := framework.CreateJsonMessage(framework.QueryUnallocatedComputePoolCellResponse) 24 | resp.SetSuccess(true) 25 | resp.SetFromSession(id) 26 | resp.SetToSession(request.GetFromSession()) 27 | modules.CellsToMessage(resp, result.ComputeCellInfoList) 28 | return executor.Sender.SendMessage(resp, request.GetSender()) 29 | } 30 | 31 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019 project-nano 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /src/task/data_qualifier.go: -------------------------------------------------------------------------------- 1 | package task 2 | 3 | import ( 4 | "regexp" 5 | "fmt" 6 | ) 7 | 8 | //[^\da-zA-Z-] 9 | 10 | var ( 11 | normalNameQualifier = regexp.MustCompile("[^\\w-]") 12 | snapshotNameQualifier = regexp.MustCompile("[^\\w-.]") 13 | imageNameQualifier = regexp.MustCompile("[^\\w-.]") 14 | ) 15 | 16 | func QualifyNormalName(input string) (err error){ 17 | var matched = normalNameQualifier.FindStringSubmatch(input) 18 | if 0 != len(matched){ 19 | err = fmt.Errorf("illegal char '%s' (only '0~9a~Z_-' allowed)", matched[0]) 20 | return err 21 | } 22 | return nil 23 | } 24 | 25 | func QualifyImageName(snapshot string) (err error){ 26 | var matched = imageNameQualifier.FindStringSubmatch(snapshot) 27 | if 0 != len(matched){ 28 | err = fmt.Errorf("illegal char '%s' (only '0~9a~Z_-.' allowed)", matched[0]) 29 | return err 30 | } 31 | return nil 32 | } 33 | 34 | func QualifySnapshotName(snapshot string) (err error){ 35 | var matched = snapshotNameQualifier.FindStringSubmatch(snapshot) 36 | if 0 != len(matched){ 37 | err = fmt.Errorf("illegal char '%s' (only '0~9a~Z_-.' allowed)", matched[0]) 38 | return err 39 | } 40 | return nil 41 | } 42 | -------------------------------------------------------------------------------- /src/imageserver/delete_disk_image.go: -------------------------------------------------------------------------------- 1 | package imageserver 2 | 3 | import ( 4 | "github.com/project-nano/framework" 5 | "log" 6 | ) 7 | 8 | type DeleteDiskImageExecutor struct { 9 | Sender framework.MessageSender 10 | ImageServer *ImageManager 11 | } 12 | 13 | 14 | func (executor *DeleteDiskImageExecutor)Execute(id framework.SessionID, request framework.Message, 15 | incoming chan framework.Message, terminate chan bool) (err error) { 16 | imageID, err := request.GetString(framework.ParamKeyImage) 17 | if err != nil{ 18 | return err 19 | } 20 | resp, _ := framework.CreateJsonMessage(framework.DeleteDiskImageResponse) 21 | resp.SetSuccess(false) 22 | resp.SetFromSession(id) 23 | resp.SetToSession(request.GetFromSession()) 24 | 25 | var respChan = make(chan error, 1) 26 | executor.ImageServer.DeleteDiskImage(imageID, respChan) 27 | err = <-respChan 28 | if err != nil { 29 | resp.SetError(err.Error()) 30 | log.Printf("[%08X] delete disk image fail: %s", id, err.Error()) 31 | return executor.Sender.SendMessage(resp, request.GetSender()) 32 | } 33 | resp.SetSuccess(true) 34 | log.Printf("[%08X] disk image '%s' deleted", id, imageID) 35 | return executor.Sender.SendMessage(resp, request.GetSender()) 36 | } -------------------------------------------------------------------------------- /src/imageserver/go.mod: -------------------------------------------------------------------------------- 1 | module github.com/project-nano/core/imageserver 2 | 3 | go 1.19 4 | 5 | replace github.com/project-nano/framework => ../../../framework 6 | 7 | require ( 8 | github.com/julienschmidt/httprouter v1.3.0 9 | github.com/project-nano/framework v1.0.9 10 | github.com/satori/go.uuid v1.2.0 11 | ) 12 | 13 | require ( 14 | github.com/kardianos/osext v0.0.0-20190222173326-2bc1f35cddc0 // indirect 15 | github.com/klauspost/cpuid/v2 v2.2.5 // indirect 16 | github.com/klauspost/reedsolomon v1.11.8 // indirect 17 | github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e // indirect 18 | github.com/pkg/errors v0.9.1 // indirect 19 | github.com/project-nano/sonar v0.0.0-20190628085230-df7942628d6f // indirect 20 | github.com/sevlyar/go-daemon v0.1.6 // indirect 21 | github.com/templexxx/cpufeat v0.0.0-20180724012125-cef66df7f161 // indirect 22 | github.com/templexxx/xor v0.0.0-20191217153810-f85b25db303b // indirect 23 | github.com/tjfoc/gmsm v1.4.1 // indirect 24 | github.com/xtaci/kcp-go v5.4.20+incompatible // indirect 25 | golang.org/x/crypto v0.13.0 // indirect 26 | golang.org/x/net v0.15.0 // indirect 27 | golang.org/x/sys v0.12.0 // indirect 28 | gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f // indirect 29 | ) 30 | -------------------------------------------------------------------------------- /src/imageserver/delete_media_image.go: -------------------------------------------------------------------------------- 1 | package imageserver 2 | 3 | import ( 4 | "github.com/project-nano/framework" 5 | "log" 6 | ) 7 | 8 | type DeleteMediaImageExecutor struct { 9 | Sender framework.MessageSender 10 | ImageServer *ImageManager 11 | } 12 | 13 | 14 | func (executor *DeleteMediaImageExecutor)Execute(id framework.SessionID, request framework.Message, 15 | incoming chan framework.Message, terminate chan bool) (err error) { 16 | imageID, err := request.GetString(framework.ParamKeyImage) 17 | if err != nil{ 18 | return err 19 | } 20 | resp, _ := framework.CreateJsonMessage(framework.DeleteMediaImageResponse) 21 | resp.SetSuccess(false) 22 | resp.SetFromSession(id) 23 | resp.SetToSession(request.GetFromSession()) 24 | 25 | var respChan = make(chan error, 1) 26 | executor.ImageServer.DeleteMediaImage(imageID, respChan) 27 | err = <- respChan 28 | if err != nil{ 29 | resp.SetError(err.Error()) 30 | log.Printf("[%08X] delete media image fail: %s", id, err.Error()) 31 | return executor.Sender.SendMessage(resp, request.GetSender()) 32 | } 33 | //deallocated 34 | resp.SetSuccess(true) 35 | log.Printf("[%08X] media image '%s' deleted", id, imageID) 36 | return executor.Sender.SendMessage(resp, request.GetSender()) 37 | } 38 | -------------------------------------------------------------------------------- /src/task/delete_compute_pool.go: -------------------------------------------------------------------------------- 1 | package task 2 | 3 | import ( 4 | "github.com/project-nano/framework" 5 | "github.com/project-nano/core/modules" 6 | "log" 7 | ) 8 | 9 | type DeleteComputePoolExecutor struct { 10 | Sender framework.MessageSender 11 | ResourceModule modules.ResourceModule 12 | } 13 | 14 | func (executor *DeleteComputePoolExecutor)Execute(id framework.SessionID, request framework.Message, 15 | incoming chan framework.Message, terminate chan bool) error { 16 | pool, err := request.GetString(framework.ParamKeyPool) 17 | if err != nil{ 18 | return err 19 | } 20 | log.Printf("[%08X] request delete compute pool '%s' from %s.[%08X]", id, pool, request.GetSender(), request.GetFromSession()) 21 | var respChan= make(chan error) 22 | 23 | executor.ResourceModule.DeletePool(pool, respChan) 24 | 25 | resp, _ := framework.CreateJsonMessage(framework.DeleteComputePoolResponse) 26 | resp.SetSuccess(false) 27 | resp.SetFromSession(id) 28 | resp.SetToSession(request.GetFromSession()) 29 | 30 | err = <-respChan 31 | if err != nil{ 32 | resp.SetError(err.Error()) 33 | log.Printf("[%08X] delete compute pool fail: %s", id, err.Error()) 34 | }else{ 35 | resp.SetSuccess(true) 36 | } 37 | 38 | return executor.Sender.SendMessage(resp, request.GetSender()) 39 | } -------------------------------------------------------------------------------- /src/task/delete_storage_pool.go: -------------------------------------------------------------------------------- 1 | package task 2 | 3 | import ( 4 | "github.com/project-nano/framework" 5 | "github.com/project-nano/core/modules" 6 | "log" 7 | ) 8 | 9 | type DeleteStoragePoolExecutor struct { 10 | Sender framework.MessageSender 11 | ResourceModule modules.ResourceModule 12 | } 13 | 14 | func (executor *DeleteStoragePoolExecutor)Execute(id framework.SessionID, request framework.Message, 15 | incoming chan framework.Message, terminate chan bool) error { 16 | pool, err := request.GetString(framework.ParamKeyStorage) 17 | if err != nil{ 18 | return err 19 | } 20 | log.Printf("[%08X] request delete storage pool '%s' from %s.[%08X]", id, pool, request.GetSender(), request.GetFromSession()) 21 | var respChan= make(chan error) 22 | 23 | executor.ResourceModule.DeleteStoragePool(pool, respChan) 24 | 25 | resp, _ := framework.CreateJsonMessage(framework.DeleteStoragePoolResponse) 26 | resp.SetSuccess(false) 27 | resp.SetFromSession(id) 28 | resp.SetToSession(request.GetFromSession()) 29 | 30 | err = <-respChan 31 | if err != nil{ 32 | resp.SetError(err.Error()) 33 | log.Printf("[%08X] delete storage pool fail: %s", id, err.Error()) 34 | }else{ 35 | resp.SetSuccess(true) 36 | } 37 | 38 | return executor.Sender.SendMessage(resp, request.GetSender()) 39 | } 40 | -------------------------------------------------------------------------------- /src/modules/go.mod: -------------------------------------------------------------------------------- 1 | module github.com/project-nano/core/modules 2 | 3 | go 1.19 4 | 5 | replace github.com/project-nano/framework => ../../../framework 6 | 7 | require ( 8 | github.com/julienschmidt/httprouter v1.3.0 9 | github.com/pkg/errors v0.9.1 10 | github.com/project-nano/framework v1.0.9 11 | github.com/rs/xid v1.5.0 12 | github.com/satori/go.uuid v1.2.0 13 | ) 14 | 15 | require ( 16 | github.com/kardianos/osext v0.0.0-20190222173326-2bc1f35cddc0 // indirect 17 | github.com/klauspost/cpuid/v2 v2.2.5 // indirect 18 | github.com/klauspost/reedsolomon v1.11.8 // indirect 19 | github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e // indirect 20 | github.com/project-nano/sonar v0.0.0-20190628085230-df7942628d6f // indirect 21 | github.com/sevlyar/go-daemon v0.1.6 // indirect 22 | github.com/templexxx/cpufeat v0.0.0-20180724012125-cef66df7f161 // indirect 23 | github.com/templexxx/xor v0.0.0-20191217153810-f85b25db303b // indirect 24 | github.com/tjfoc/gmsm v1.4.1 // indirect 25 | github.com/xtaci/kcp-go v5.4.20+incompatible // indirect 26 | github.com/xtaci/lossyconn v0.0.0-20200209145036-adba10fffc37 // indirect 27 | golang.org/x/crypto v0.13.0 // indirect 28 | golang.org/x/net v0.15.0 // indirect 29 | golang.org/x/sys v0.12.0 // indirect 30 | gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f // indirect 31 | ) 32 | -------------------------------------------------------------------------------- /src/task/delete_system_template.go: -------------------------------------------------------------------------------- 1 | package task 2 | 3 | import ( 4 | "fmt" 5 | "github.com/project-nano/core/modules" 6 | "github.com/project-nano/framework" 7 | "log" 8 | ) 9 | 10 | type DeleteSystemTemplateExecutor struct { 11 | Sender framework.MessageSender 12 | ResourceModule modules.ResourceModule 13 | } 14 | 15 | func (executor *DeleteSystemTemplateExecutor)Execute(id framework.SessionID, request framework.Message, 16 | incoming chan framework.Message, terminate chan bool) (err error){ 17 | 18 | var templateID string 19 | if templateID, err = request.GetString(framework.ParamKeyTemplate); err != nil{ 20 | err = fmt.Errorf("get template id fail: %s", err.Error()) 21 | return 22 | } 23 | var respChan = make(chan error, 1) 24 | executor.ResourceModule.DeleteSystemTemplate(templateID, respChan) 25 | err = <- respChan 26 | 27 | resp, _ := framework.CreateJsonMessage(framework.DeleteTemplateResponse) 28 | resp.SetSuccess(false) 29 | resp.SetFromSession(id) 30 | resp.SetToSession(request.GetFromSession()) 31 | 32 | if err != nil{ 33 | resp.SetError(err.Error()) 34 | log.Printf("[%08X] handle delete system template from %s.[%08X] fail: %s", 35 | id, request.GetSender(), request.GetFromSession(), err.Error()) 36 | }else{ 37 | resp.SetSuccess(true) 38 | } 39 | return executor.Sender.SendMessage(resp, request.GetSender()) 40 | } 41 | -------------------------------------------------------------------------------- /src/task/disable_compute_cell.go: -------------------------------------------------------------------------------- 1 | package task 2 | 3 | import ( 4 | "github.com/project-nano/framework" 5 | "github.com/project-nano/core/modules" 6 | "log" 7 | ) 8 | 9 | type DisableComputeCellExecutor struct { 10 | Sender framework.MessageSender 11 | ResourceModule modules.ResourceModule 12 | } 13 | 14 | func (executor *DisableComputeCellExecutor)Execute(id framework.SessionID, request framework.Message, 15 | incoming chan framework.Message, terminate chan bool) (err error) { 16 | poolName, err := request.GetString(framework.ParamKeyPool) 17 | if err != nil { 18 | return err 19 | } 20 | cellName, err := request.GetString(framework.ParamKeyCell) 21 | if err != nil { 22 | return err 23 | } 24 | var respChan = make(chan error, 1) 25 | executor.ResourceModule.DisableCell(poolName, cellName, false, respChan) 26 | 27 | resp, _ := framework.CreateJsonMessage(framework.DisableComputePoolCellResponse) 28 | resp.SetSuccess(false) 29 | resp.SetFromSession(id) 30 | resp.SetToSession(request.GetFromSession()) 31 | err = <-respChan 32 | if err != nil { 33 | resp.SetError(err.Error()) 34 | log.Printf("[%08X] disable compute cell fail: %s", id, err.Error()) 35 | }else{ 36 | resp.SetSuccess(true) 37 | log.Printf("[%08X] cell '%s' disabled in pool %s", id, cellName, poolName) 38 | } 39 | return executor.Sender.SendMessage(resp, request.GetSender()) 40 | } 41 | -------------------------------------------------------------------------------- /src/task/sync_image_server.go: -------------------------------------------------------------------------------- 1 | package task 2 | 3 | import ( 4 | "github.com/project-nano/framework" 5 | "github.com/project-nano/core/modules" 6 | "net/http" 7 | "log" 8 | ) 9 | 10 | type SyncImageServerExecutor struct { 11 | Sender framework.MessageSender 12 | ResourceModule modules.ResourceModule 13 | Client *http.Client 14 | } 15 | 16 | func (executor *SyncImageServerExecutor) Execute(id framework.SessionID, request framework.Message, 17 | incoming chan framework.Message, terminate chan bool) (err error) { 18 | const ( 19 | Protocol = "https" 20 | ) 21 | var serverName, mediaHost string 22 | var mediaPort uint 23 | if serverName, err = request.GetString(framework.ParamKeyName);err != nil{ 24 | log.Printf("[%08X] sync image server fail: %s", id, err.Error()) 25 | return nil 26 | } 27 | if mediaHost, err = request.GetString(framework.ParamKeyHost);err != nil{ 28 | log.Printf("[%08X] sync image server fail: %s", id, err.Error()) 29 | return nil 30 | } 31 | if mediaPort, err = request.GetUInt(framework.ParamKeyPort);err != nil{ 32 | log.Printf("[%08X] sync image server fail: %s", id, err.Error()) 33 | return nil 34 | } 35 | executor.ResourceModule.AddImageServer(serverName, mediaHost, int(mediaPort)) 36 | log.Printf("[%08X] new imager server '%s' available (%s:%d)", id, serverName, mediaHost, mediaPort) 37 | 38 | return nil 39 | } 40 | -------------------------------------------------------------------------------- /core_service_test.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "github.com/project-nano/framework" 5 | "net" 6 | "testing" 7 | ) 8 | 9 | func getCoreServiceForTest() (core *CoreService, err error) { 10 | const ( 11 | domainName = "nano" 12 | groupAddress = "224.0.0.226" 13 | groupPort = 5599 14 | listenAddress = "192.168.1.167" 15 | configPath = "config" 16 | dataPath = "data" 17 | ) 18 | var inf *net.Interface 19 | if inf, err = framework.InterfaceByAddress(listenAddress); nil != err { 20 | return 21 | } 22 | var endpoint framework.EndpointService 23 | if endpoint, err = framework.CreateStubEndpoint(groupAddress, groupPort, domainName, listenAddress); err != nil { 24 | return 25 | } 26 | core = &CoreService{EndpointService: endpoint, ConfigPath: configPath, DataPath: dataPath} 27 | core.RegisterHandler(core) 28 | err = core.GenerateName(framework.ServiceTypeCore, inf) 29 | return 30 | } 31 | 32 | func TestCoreService_StartAndStop(t *testing.T) { 33 | core, err := getCoreServiceForTest() 34 | if err != nil { 35 | t.Fatalf("load service fail: %s", err.Error()) 36 | return 37 | } 38 | if err = core.Start(); err != nil { 39 | t.Fatalf("start service fail: %s", err.Error()) 40 | return 41 | } 42 | if err = core.Stop(); err != nil { 43 | t.Fatalf("stop service fail: %s", err.Error()) 44 | } 45 | t.Log("test core service start and stop success") 46 | } 47 | -------------------------------------------------------------------------------- /src/task/handle_guest_created.go: -------------------------------------------------------------------------------- 1 | package task 2 | 3 | import ( 4 | "github.com/project-nano/framework" 5 | "github.com/project-nano/core/modules" 6 | "log" 7 | ) 8 | 9 | type HandleGuestCreatedExecutor struct { 10 | Sender framework.MessageSender 11 | ResourceModule modules.ResourceModule 12 | } 13 | 14 | func (executor *HandleGuestCreatedExecutor)Execute(id framework.SessionID, event framework.Message, 15 | incoming chan framework.Message, terminate chan bool) (err error) { 16 | var instanceID, monitorSecret, ethernet string 17 | var monitorPort uint 18 | if instanceID, err = event.GetString(framework.ParamKeyInstance); err != nil { 19 | return 20 | } 21 | 22 | if monitorPort, err = event.GetUInt(framework.ParamKeyMonitor); err != nil{ 23 | return 24 | } 25 | 26 | if monitorSecret, err = event.GetString(framework.ParamKeySecret); err != nil{ 27 | return 28 | } 29 | if ethernet, err = event.GetString(framework.ParamKeyHardware); err != nil{ 30 | return 31 | } 32 | log.Printf("[%08X] recv guest '%s' created from %s.[%08X], monitor port %d", id, instanceID, 33 | event.GetSender(), event.GetFromSession(), monitorPort) 34 | var respChan = make(chan error) 35 | executor.ResourceModule.ConfirmInstance(instanceID, monitorPort, monitorSecret, ethernet, respChan) 36 | err = <- respChan 37 | if err != nil{ 38 | log.Printf("[%08X] confirm instance fail: %s", id, err.Error()) 39 | } 40 | return nil 41 | } 42 | -------------------------------------------------------------------------------- /src/task/handle_guest_started.go: -------------------------------------------------------------------------------- 1 | package task 2 | 3 | import ( 4 | "github.com/project-nano/framework" 5 | "log" 6 | "github.com/project-nano/core/modules" 7 | ) 8 | 9 | type HandleGuestStartedExecutor struct { 10 | Sender framework.MessageSender 11 | ResourceModule modules.ResourceModule 12 | } 13 | 14 | func (executor *HandleGuestStartedExecutor)Execute(id framework.SessionID, event framework.Message, 15 | incoming chan framework.Message, terminate chan bool) error { 16 | instanceID, err := event.GetString(framework.ParamKeyInstance) 17 | if err != nil { 18 | return err 19 | } 20 | log.Printf("[%08X] recv guest '%s' started from %s.[%08X]", id, instanceID, 21 | event.GetSender(), event.GetFromSession()) 22 | var status modules.InstanceStatus 23 | { 24 | var respChan = make(chan modules.ResourceResult) 25 | executor.ResourceModule.GetInstanceStatus(instanceID, respChan) 26 | result := <- respChan 27 | if result.Error != nil{ 28 | errMsg := result.Error.Error() 29 | log.Printf("[%08X] fetch guest fail: %s", id, errMsg) 30 | return result.Error 31 | } 32 | status = result.Instance 33 | } 34 | status.Running = true 35 | { 36 | var respChan = make(chan error) 37 | executor.ResourceModule.UpdateInstanceStatus(status, respChan) 38 | err = <- respChan 39 | if err != nil{ 40 | log.Printf("[%08X] warning: update started status fail: %s", id, err) 41 | } 42 | return nil 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /src/task/handle_guest_stopped.go: -------------------------------------------------------------------------------- 1 | package task 2 | 3 | import ( 4 | "github.com/project-nano/framework" 5 | "github.com/project-nano/core/modules" 6 | "log" 7 | ) 8 | 9 | type HandleGuestStoppedExecutor struct { 10 | Sender framework.MessageSender 11 | ResourceModule modules.ResourceModule 12 | } 13 | 14 | func (executor *HandleGuestStoppedExecutor)Execute(id framework.SessionID, event framework.Message, 15 | incoming chan framework.Message, terminate chan bool) error { 16 | instanceID, err := event.GetString(framework.ParamKeyInstance) 17 | if err != nil { 18 | return err 19 | } 20 | log.Printf("[%08X] recv guest '%s' stopped from %s.[%08X]", id, instanceID, 21 | event.GetSender(), event.GetFromSession()) 22 | var status modules.InstanceStatus 23 | { 24 | var respChan = make(chan modules.ResourceResult) 25 | executor.ResourceModule.GetInstanceStatus(instanceID, respChan) 26 | result := <- respChan 27 | if result.Error != nil{ 28 | errMsg := result.Error.Error() 29 | log.Printf("[%08X] fetch guest fail: %s", id, errMsg) 30 | return result.Error 31 | } 32 | status = result.Instance 33 | } 34 | status.Running = false 35 | { 36 | var respChan = make(chan error) 37 | executor.ResourceModule.UpdateInstanceStatus(status, respChan) 38 | err = <- respChan 39 | if err != nil{ 40 | log.Printf("[%08X] warning: update stopped status fail: %s", id, err) 41 | } 42 | return nil 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /src/task/delete_address_pool.go: -------------------------------------------------------------------------------- 1 | package task 2 | 3 | import ( 4 | "github.com/project-nano/framework" 5 | "log" 6 | "github.com/project-nano/core/modules" 7 | ) 8 | 9 | type DeleteAddressPoolExecutor struct { 10 | Sender framework.MessageSender 11 | ResourceModule modules.ResourceModule 12 | } 13 | 14 | 15 | func (executor *DeleteAddressPoolExecutor)Execute(id framework.SessionID, request framework.Message, 16 | incoming chan framework.Message, terminate chan bool) (err error) { 17 | var poolName string 18 | if poolName, err = request.GetString(framework.ParamKeyAddress); err != nil{ 19 | return 20 | } 21 | var respChan = make(chan error, 1) 22 | executor.ResourceModule.DeleteAddressPool(poolName, respChan) 23 | resp, _ := framework.CreateJsonMessage(framework.DeleteAddressPoolResponse) 24 | resp.SetFromSession(id) 25 | resp.SetToSession(request.GetFromSession()) 26 | resp.SetSuccess(false) 27 | 28 | err = <- respChan 29 | if err != nil{ 30 | resp.SetError(err.Error()) 31 | log.Printf("[%08X] request delete address pool from %s.[%08X] fail: %s", 32 | id, request.GetSender(), request.GetFromSession(), err.Error()) 33 | return executor.Sender.SendMessage(resp, request.GetSender()) 34 | } 35 | 36 | resp.SetSuccess(true) 37 | log.Printf("[%08X] address pool '%s' deleted from %s.[%08X]", 38 | id, poolName, request.GetSender(), request.GetFromSession()) 39 | return executor.Sender.SendMessage(resp, request.GetSender()) 40 | } 41 | -------------------------------------------------------------------------------- /src/task/delete_security_policy_group.go: -------------------------------------------------------------------------------- 1 | package task 2 | 3 | import ( 4 | "fmt" 5 | "github.com/project-nano/core/modules" 6 | "github.com/project-nano/framework" 7 | "log" 8 | ) 9 | 10 | type DeleteSecurityPolicyGroupExecutor struct { 11 | Sender framework.MessageSender 12 | ResourceModule modules.ResourceModule 13 | } 14 | 15 | func (executor *DeleteSecurityPolicyGroupExecutor) Execute(id framework.SessionID, request framework.Message, 16 | incoming chan framework.Message, terminate chan bool) (err error) { 17 | var policyID string 18 | if policyID, err = request.GetString(framework.ParamKeyPolicy);err != nil{ 19 | err = fmt.Errorf("get policy group ID fail: %s", err.Error()) 20 | return 21 | } 22 | 23 | resp, _ := framework.CreateJsonMessage(framework.DeletePolicyGroupResponse) 24 | resp.SetToSession(request.GetFromSession()) 25 | resp.SetFromSession(id) 26 | resp.SetTransactionID(request.GetTransactionID()) 27 | resp.SetSuccess(false) 28 | var respChan = make(chan error, 1) 29 | executor.ResourceModule.DeleteSecurityPolicyGroup(policyID, respChan) 30 | err = <- respChan 31 | if err != nil{ 32 | log.Printf("[%08X] delete security policy group '%s' fail: %s", 33 | id, policyID, err.Error()) 34 | resp.SetError(err.Error()) 35 | }else{ 36 | log.Printf("[%08X] security policy group '%s' deleted", 37 | id, policyID) 38 | resp.SetSuccess(true) 39 | } 40 | return executor.Sender.SendMessage(resp, request.GetSender()) 41 | } 42 | -------------------------------------------------------------------------------- /src/task/enable_compute_cell.go: -------------------------------------------------------------------------------- 1 | package task 2 | 3 | import ( 4 | "github.com/project-nano/framework" 5 | "github.com/project-nano/core/modules" 6 | "log" 7 | ) 8 | 9 | type EnableComputeCellExecutor struct { 10 | Sender framework.MessageSender 11 | ResourceModule modules.ResourceModule 12 | } 13 | 14 | func (executor *EnableComputeCellExecutor)Execute(id framework.SessionID, request framework.Message, 15 | incoming chan framework.Message, terminate chan bool) (err error) { 16 | poolName, err := request.GetString(framework.ParamKeyPool) 17 | if err != nil { 18 | return err 19 | } 20 | cellName, err := request.GetString(framework.ParamKeyCell) 21 | if err != nil { 22 | return err 23 | } 24 | //log.Printf("[%08X] request enable cell '%s' in pool '%s' from %s.[%08X]", id, cellName, poolName, 25 | // request.GetSender(), request.GetFromSession()) 26 | var respChan = make(chan error, 1) 27 | executor.ResourceModule.EnableCell(poolName, cellName, respChan) 28 | 29 | resp, _ := framework.CreateJsonMessage(framework.EnableComputePoolCellResponse) 30 | resp.SetSuccess(false) 31 | resp.SetFromSession(id) 32 | resp.SetToSession(request.GetFromSession()) 33 | err = <-respChan 34 | if err != nil { 35 | resp.SetError(err.Error()) 36 | log.Printf("[%08X] enable compute cell fail: %s", id, err.Error()) 37 | }else{ 38 | resp.SetSuccess(true) 39 | log.Printf("[%08X] cell '%s' enabled in pool %s", id, cellName, poolName) 40 | } 41 | return executor.Sender.SendMessage(resp, request.GetSender()) 42 | } -------------------------------------------------------------------------------- /src/task/get_guest.go: -------------------------------------------------------------------------------- 1 | package task 2 | 3 | import ( 4 | "github.com/project-nano/framework" 5 | "github.com/project-nano/core/modules" 6 | "log" 7 | ) 8 | 9 | type GetGuestConfigExecutor struct { 10 | Sender framework.MessageSender 11 | ResourceModule modules.ResourceModule 12 | } 13 | 14 | func (executor *GetGuestConfigExecutor)Execute(id framework.SessionID, request framework.Message, 15 | incoming chan framework.Message, terminate chan bool) error { 16 | var err error 17 | instanceID, err := request.GetString(framework.ParamKeyInstance) 18 | if err != nil{ 19 | return err 20 | } 21 | //log.Printf("[%08X] request get guest '%s' config from %s.[%08X]", id, instanceID, 22 | // request.GetSender(), request.GetFromSession()) 23 | 24 | resp, _ := framework.CreateJsonMessage(framework.QueryGuestResponse) 25 | resp.SetToSession(request.GetFromSession()) 26 | resp.SetFromSession(id) 27 | resp.SetSuccess(false) 28 | 29 | var config modules.InstanceStatus 30 | { 31 | var respChan = make(chan modules.ResourceResult) 32 | executor.ResourceModule.GetInstanceStatus(instanceID, respChan) 33 | result := <- respChan 34 | if result.Error != nil{ 35 | errMsg := result.Error.Error() 36 | log.Printf("[%08X] get config fail: %s", id, errMsg) 37 | resp.SetError(errMsg) 38 | return executor.Sender.SendMessage(resp, request.GetSender()) 39 | } 40 | config = result.Instance 41 | } 42 | config.Marshal(resp) 43 | resp.SetSuccess(true) 44 | return executor.Sender.SendMessage(resp, request.GetSender()) 45 | } 46 | -------------------------------------------------------------------------------- /src/task/query_storage_pool.go: -------------------------------------------------------------------------------- 1 | package task 2 | 3 | import ( 4 | "github.com/project-nano/core/modules" 5 | "github.com/project-nano/framework" 6 | ) 7 | 8 | type QueryStoragePoolExecutor struct { 9 | Sender framework.MessageSender 10 | ResourceModule modules.ResourceModule 11 | } 12 | 13 | 14 | func (executor *QueryStoragePoolExecutor)Execute(id framework.SessionID, request framework.Message, 15 | incoming chan framework.Message, terminate chan bool) error{ 16 | //log.Printf("[%08X] query storage pool from %s.[%08X]", id, request.GetSender(), request.GetFromSession()) 17 | var respChan = make(chan modules.ResourceResult) 18 | executor.ResourceModule.QueryStoragePool(respChan) 19 | result := <- respChan 20 | var nameArray, typeArray, hostArray, targetArray []string 21 | for _, info := range result.StoragePoolList { 22 | nameArray = append(nameArray, info.Name) 23 | typeArray = append(typeArray, info.Type) 24 | hostArray = append(hostArray, info.Host) 25 | targetArray = append(targetArray, info.Target) 26 | } 27 | resp, _ := framework.CreateJsonMessage(framework.QueryStoragePoolResponse) 28 | resp.SetSuccess(true) 29 | resp.SetFromSession(id) 30 | resp.SetToSession(request.GetFromSession()) 31 | resp.SetStringArray(framework.ParamKeyName, nameArray) 32 | resp.SetStringArray(framework.ParamKeyType, typeArray) 33 | resp.SetStringArray(framework.ParamKeyHost, hostArray) 34 | resp.SetStringArray(framework.ParamKeyTarget, targetArray) 35 | return executor.Sender.SendMessage(resp, request.GetSender()) 36 | } 37 | -------------------------------------------------------------------------------- /src/task/query_cells_by_pool.go: -------------------------------------------------------------------------------- 1 | package task 2 | 3 | import ( 4 | "github.com/project-nano/framework" 5 | "log" 6 | "github.com/project-nano/core/modules" 7 | ) 8 | 9 | type QueryCellsByPoolExecutor struct { 10 | Sender framework.MessageSender 11 | ResourceModule modules.ResourceModule 12 | } 13 | 14 | 15 | func (executor *QueryCellsByPoolExecutor)Execute(id framework.SessionID, request framework.Message, 16 | incoming chan framework.Message, terminate chan bool) error{ 17 | poolName, err := request.GetString(framework.ParamKeyPool) 18 | if err != nil{ 19 | return err 20 | } 21 | //log.Printf("[%08X] query cells by pool from %s.[%08X]", id, request.GetSender(), request.GetFromSession()) 22 | var respChan = make(chan modules.ResourceResult) 23 | executor.ResourceModule.QueryCellsInPool(poolName, respChan) 24 | result := <- respChan 25 | resp, _ := framework.CreateJsonMessage(framework.QueryComputePoolResponse) 26 | resp.SetSuccess(false) 27 | resp.SetFromSession(id) 28 | resp.SetToSession(request.GetFromSession()) 29 | 30 | if result.Error != nil{ 31 | resp.SetError(result.Error.Error()) 32 | log.Printf("[%08X] query cells fail: %s", id, result.Error.Error()) 33 | return executor.Sender.SendMessage(resp, request.GetSender()) 34 | } 35 | 36 | //log.Printf("[%08X] %d cells available in pool '%s'", id, len(result.ComputeCellInfoList), poolName) 37 | resp.SetSuccess(true) 38 | modules.CellsToMessage(resp, result.ComputeCellInfoList) 39 | 40 | return executor.Sender.SendMessage(resp, request.GetSender()) 41 | } 42 | -------------------------------------------------------------------------------- /go.mod: -------------------------------------------------------------------------------- 1 | module github.com/project-nano/core 2 | 3 | go 1.19 4 | 5 | replace ( 6 | github.com/project-nano/core/imageserver => ./src/imageserver 7 | github.com/project-nano/core/modules => ./src/modules 8 | github.com/project-nano/core/task => ./src/task 9 | github.com/project-nano/framework => ../framework 10 | ) 11 | 12 | require ( 13 | github.com/project-nano/core/imageserver v0.0.0-00010101000000-000000000000 14 | github.com/project-nano/core/modules v0.0.0-00010101000000-000000000000 15 | github.com/project-nano/core/task v0.0.0-00010101000000-000000000000 16 | github.com/project-nano/framework v1.0.9 17 | github.com/project-nano/sonar v0.0.0-20190628085230-df7942628d6f 18 | ) 19 | 20 | require ( 21 | github.com/julienschmidt/httprouter v1.3.0 // indirect 22 | github.com/kardianos/osext v0.0.0-20190222173326-2bc1f35cddc0 // indirect 23 | github.com/klauspost/cpuid/v2 v2.2.5 // indirect 24 | github.com/klauspost/reedsolomon v1.11.8 // indirect 25 | github.com/pkg/errors v0.9.1 // indirect 26 | github.com/rs/xid v1.5.0 // indirect 27 | github.com/satori/go.uuid v1.2.0 // indirect 28 | github.com/sevlyar/go-daemon v0.1.6 // indirect 29 | github.com/templexxx/cpufeat v0.0.0-20180724012125-cef66df7f161 // indirect 30 | github.com/templexxx/xor v0.0.0-20191217153810-f85b25db303b // indirect 31 | github.com/tjfoc/gmsm v1.4.1 // indirect 32 | github.com/xtaci/kcp-go v5.4.20+incompatible // indirect 33 | golang.org/x/crypto v0.13.0 // indirect 34 | golang.org/x/net v0.15.0 // indirect 35 | golang.org/x/sys v0.12.0 // indirect 36 | ) 37 | -------------------------------------------------------------------------------- /src/imageserver/sync_disk_images.go: -------------------------------------------------------------------------------- 1 | package imageserver 2 | 3 | import ( 4 | "fmt" 5 | "github.com/project-nano/framework" 6 | "log" 7 | ) 8 | 9 | type SyncDiskImagesExecutor struct { 10 | Sender framework.MessageSender 11 | ImageServer *ImageManager 12 | } 13 | 14 | func (executor *SyncDiskImagesExecutor)Execute(id framework.SessionID, request framework.Message, 15 | incoming chan framework.Message, terminate chan bool) (err error) { 16 | var owner, group string 17 | if owner, err = request.GetString(framework.ParamKeyUser); err != nil { 18 | err = fmt.Errorf("get owner fail: %s", err.Error()) 19 | return err 20 | } 21 | if group, err = request.GetString(framework.ParamKeyGroup); err != nil { 22 | err = fmt.Errorf("get group fail: %s", err.Error()) 23 | return err 24 | } 25 | log.Printf("[%08X] %s.[%08X] request synchronize disk images...", 26 | id, request.GetSender(), request.GetFromSession()) 27 | var respChan = make(chan error, 1) 28 | executor.ImageServer.SyncDiskImages(owner, group, respChan) 29 | err = <- respChan 30 | 31 | resp, _ := framework.CreateJsonMessage(framework.SynchronizeDiskImageResponse) 32 | resp.SetSuccess(false) 33 | resp.SetFromSession(id) 34 | resp.SetToSession(request.GetFromSession()) 35 | 36 | if err != nil{ 37 | resp.SetError(err.Error()) 38 | log.Printf("[%08X] sync disk images fail: %s", id, err.Error()) 39 | }else{ 40 | log.Printf("[%08X] disk images synchronized", id) 41 | resp.SetSuccess(true) 42 | } 43 | return executor.Sender.SendMessage(resp, request.GetSender()) 44 | } 45 | -------------------------------------------------------------------------------- /src/imageserver/sync_media_images.go: -------------------------------------------------------------------------------- 1 | package imageserver 2 | 3 | import ( 4 | "fmt" 5 | "github.com/project-nano/framework" 6 | "log" 7 | ) 8 | 9 | type SyncMediaImagesExecutor struct { 10 | Sender framework.MessageSender 11 | ImageServer *ImageManager 12 | } 13 | 14 | func (executor *SyncMediaImagesExecutor)Execute(id framework.SessionID, request framework.Message, 15 | incoming chan framework.Message, terminate chan bool) (err error) { 16 | var owner, group string 17 | if owner, err = request.GetString(framework.ParamKeyUser); err != nil { 18 | err = fmt.Errorf("get owner fail: %s", err.Error()) 19 | return err 20 | } 21 | if group, err = request.GetString(framework.ParamKeyGroup); err != nil { 22 | err = fmt.Errorf("get group fail: %s", err.Error()) 23 | return err 24 | } 25 | log.Printf("[%08X] %s.[%08X] request synchronize media images...", 26 | id, request.GetSender(), request.GetFromSession()) 27 | var respChan = make(chan error, 1) 28 | executor.ImageServer.SyncMediaImages(owner, group, respChan) 29 | err = <- respChan 30 | 31 | resp, _ := framework.CreateJsonMessage(framework.SynchronizeMediaImageResponse) 32 | resp.SetSuccess(false) 33 | resp.SetFromSession(id) 34 | resp.SetToSession(request.GetFromSession()) 35 | 36 | if err != nil{ 37 | resp.SetError(err.Error()) 38 | log.Printf("[%08X] sync media images fail: %s", id, err.Error()) 39 | }else{ 40 | log.Printf("[%08X] media images synchronized", id) 41 | resp.SetSuccess(true) 42 | } 43 | return executor.Sender.SendMessage(resp, request.GetSender()) 44 | } 45 | -------------------------------------------------------------------------------- /src/imageserver/get_media_image.go: -------------------------------------------------------------------------------- 1 | package imageserver 2 | 3 | import ( 4 | "github.com/project-nano/framework" 5 | "log" 6 | ) 7 | 8 | type GetMediaImageExecutor struct { 9 | Sender framework.MessageSender 10 | ImageServer *ImageManager 11 | } 12 | 13 | 14 | func (executor *GetMediaImageExecutor)Execute(id framework.SessionID, request framework.Message, 15 | incoming chan framework.Message, terminate chan bool) (err error) { 16 | 17 | imageID, err := request.GetString(framework.ParamKeyImage) 18 | if err != nil{ 19 | return err 20 | } 21 | var respChan = make(chan ImageResult, 1) 22 | executor.ImageServer.GetMediaImage(imageID, respChan) 23 | var result = <- respChan 24 | resp, _ := framework.CreateJsonMessage(framework.GetMediaImageResponse) 25 | resp.SetSuccess(false) 26 | resp.SetFromSession(id) 27 | resp.SetToSession(request.GetFromSession()) 28 | 29 | if result.Error != nil{ 30 | err = result.Error 31 | log.Printf("[%08X] get media image fail: %s", id, err.Error()) 32 | resp.SetError(err.Error()) 33 | return executor.Sender.SendMessage(resp, request.GetSender()) 34 | } 35 | var image = result.MediaImage 36 | resp.SetSuccess(true) 37 | resp.SetString(framework.ParamKeyName, image.Name) 38 | resp.SetString(framework.ParamKeyDescription, image.Description) 39 | resp.SetStringArray(framework.ParamKeyTag, image.Tags) 40 | resp.SetString(framework.ParamKeyUser, image.Owner) 41 | resp.SetString(framework.ParamKeyGroup, image.Group) 42 | 43 | resp.SetUInt(framework.ParamKeySize, uint(image.Size)) 44 | return executor.Sender.SendMessage(resp, request.GetSender()) 45 | } 46 | -------------------------------------------------------------------------------- /src/task/get_migration.go: -------------------------------------------------------------------------------- 1 | package task 2 | 3 | import ( 4 | "github.com/project-nano/framework" 5 | "github.com/project-nano/core/modules" 6 | "log" 7 | ) 8 | 9 | type GetMigrationExecutor struct { 10 | Sender framework.MessageSender 11 | ResourceModule modules.ResourceModule 12 | } 13 | 14 | func (executor *GetMigrationExecutor)Execute(id framework.SessionID, request framework.Message, 15 | incoming chan framework.Message, terminate chan bool) (err error){ 16 | var migrationID string 17 | migrationID, err = request.GetString(framework.ParamKeyMigration) 18 | if err != nil{ 19 | return 20 | } 21 | resp, _ := framework.CreateJsonMessage(framework.GetMigrationResponse) 22 | resp.SetSuccess(false) 23 | resp.SetToSession(request.GetFromSession()) 24 | resp.SetFromSession(id) 25 | 26 | var respChan = make(chan modules.ResourceResult, 1) 27 | executor.ResourceModule.GetMigration(migrationID, respChan) 28 | var result = <- respChan 29 | if result.Error != nil{ 30 | err = result.Error 31 | log.Printf("[%08X] get migration fail: %s", id, err.Error()) 32 | resp.SetError(err.Error()) 33 | return nil 34 | } 35 | var migration = result.Migration 36 | resp.SetSuccess(true) 37 | resp.SetString(framework.ParamKeyMigration, migrationID) 38 | resp.SetBoolean(framework.ParamKeyStatus, migration.Finished) 39 | resp.SetUInt(framework.ParamKeyProgress, migration.Progress) 40 | if migration.Error != nil{ 41 | resp.SetString(framework.ParamKeyError, migration.Error.Error()) 42 | }else{ 43 | resp.SetString(framework.ParamKeyError, "") 44 | } 45 | return executor.Sender.SendMessage(resp, request.GetSender()) 46 | } -------------------------------------------------------------------------------- /src/task/handle_media_detached.go: -------------------------------------------------------------------------------- 1 | package task 2 | 3 | import ( 4 | "github.com/project-nano/framework" 5 | "github.com/project-nano/core/modules" 6 | "log" 7 | ) 8 | 9 | type HandleMediaDetachedExecutor struct { 10 | Sender framework.MessageSender 11 | ResourceModule modules.ResourceModule 12 | } 13 | 14 | func (executor *HandleMediaDetachedExecutor)Execute(id framework.SessionID, event framework.Message, 15 | incoming chan framework.Message, terminate chan bool) error { 16 | instanceID, err := event.GetString(framework.ParamKeyInstance) 17 | if err != nil { 18 | return err 19 | } 20 | 21 | log.Printf("[%08X] media '%s' detached from guest '%s' from %s.[%08X]", id, instanceID, 22 | event.GetSender(), event.GetFromSession()) 23 | 24 | var status modules.InstanceStatus 25 | { 26 | var respChan = make(chan modules.ResourceResult) 27 | executor.ResourceModule.GetInstanceStatus(instanceID, respChan) 28 | result := <- respChan 29 | if result.Error != nil{ 30 | errMsg := result.Error.Error() 31 | log.Printf("[%08X] fetch guest fail: %s", id, errMsg) 32 | return result.Error 33 | } 34 | if !result.Instance.MediaAttached{ 35 | log.Printf("[%08X] warning: media already detached", id) 36 | return nil 37 | } 38 | status = result.Instance 39 | } 40 | status.MediaAttached = false 41 | status.MediaSource = "" 42 | { 43 | var respChan = make(chan error) 44 | executor.ResourceModule.UpdateInstanceStatus(status, respChan) 45 | err = <- respChan 46 | if err != nil{ 47 | log.Printf("[%08X] warning: update media status fail: %s", id, err) 48 | } 49 | return nil 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /src/task/get_storage_pool.go: -------------------------------------------------------------------------------- 1 | package task 2 | 3 | import ( 4 | "github.com/project-nano/core/modules" 5 | "github.com/project-nano/framework" 6 | "log" 7 | ) 8 | 9 | type GetStoragePoolExecutor struct { 10 | Sender framework.MessageSender 11 | ResourceModule modules.ResourceModule 12 | } 13 | 14 | 15 | func (executor *GetStoragePoolExecutor)Execute(id framework.SessionID, request framework.Message, 16 | incoming chan framework.Message, terminate chan bool) (err error){ 17 | poolName, err := request.GetString(framework.ParamKeyStorage) 18 | if err != nil{ 19 | return 20 | } 21 | log.Printf("[%08X] get storage pool '%s' from %s.[%08X]", id, poolName, request.GetSender(), request.GetFromSession()) 22 | var respChan = make(chan modules.ResourceResult) 23 | executor.ResourceModule.GetStoragePool(poolName, respChan) 24 | result := <- respChan 25 | resp, _ := framework.CreateJsonMessage(framework.GetStoragePoolResponse) 26 | resp.SetSuccess(false) 27 | resp.SetFromSession(id) 28 | resp.SetToSession(request.GetFromSession()) 29 | 30 | if result.Error != nil{ 31 | err = result.Error 32 | resp.SetError(err.Error()) 33 | log.Printf("[%08X] get storage pool fail: %s", id, err.Error()) 34 | return executor.Sender.SendMessage(resp, request.GetSender()) 35 | } 36 | var poolInfo = result.StoragePool 37 | resp.SetString(framework.ParamKeyName, poolInfo.Name) 38 | resp.SetString(framework.ParamKeyType, poolInfo.Type) 39 | resp.SetString(framework.ParamKeyHost, poolInfo.Host) 40 | resp.SetString(framework.ParamKeyTarget, poolInfo.Target) 41 | resp.SetSuccess(true) 42 | return executor.Sender.SendMessage(resp, request.GetSender()) 43 | } 44 | -------------------------------------------------------------------------------- /src/task/remove_security_policy_rule.go: -------------------------------------------------------------------------------- 1 | package task 2 | 3 | import ( 4 | "fmt" 5 | "github.com/project-nano/core/modules" 6 | "github.com/project-nano/framework" 7 | "log" 8 | ) 9 | 10 | type RemoveSecurityPolicyRuleExecutor struct { 11 | Sender framework.MessageSender 12 | ResourceModule modules.ResourceModule 13 | } 14 | 15 | func (executor *RemoveSecurityPolicyRuleExecutor) Execute(id framework.SessionID, request framework.Message, 16 | incoming chan framework.Message, terminate chan bool) (err error) { 17 | var policyID string 18 | if policyID, err = request.GetString(framework.ParamKeyPolicy);err != nil{ 19 | err = fmt.Errorf("get policy group ID fail: %s", err.Error()) 20 | return 21 | } 22 | var index int 23 | if index, err = request.GetInt(framework.ParamKeyIndex);err != nil{ 24 | err = fmt.Errorf("get index fail: %s", err.Error()) 25 | return 26 | } 27 | 28 | resp, _ := framework.CreateJsonMessage(framework.RemovePolicyRuleResponse) 29 | resp.SetToSession(request.GetFromSession()) 30 | resp.SetFromSession(id) 31 | resp.SetTransactionID(request.GetTransactionID()) 32 | resp.SetSuccess(false) 33 | var respChan = make(chan error, 1) 34 | executor.ResourceModule.RemoveSecurityPolicyRule(policyID, index, respChan) 35 | err = <- respChan 36 | if err != nil{ 37 | log.Printf("[%08X] remove %dth rule of security policy '%s' fail: %s", 38 | id, index, policyID, err.Error()) 39 | resp.SetError(err.Error()) 40 | }else{ 41 | log.Printf("[%08X] %dth rule of security policy '%s' removed", 42 | id, index, policyID) 43 | resp.SetSuccess(true) 44 | } 45 | return executor.Sender.SendMessage(resp, request.GetSender()) 46 | } 47 | -------------------------------------------------------------------------------- /src/imageserver/get_disk_image.go: -------------------------------------------------------------------------------- 1 | package imageserver 2 | 3 | import ( 4 | "github.com/project-nano/framework" 5 | "log" 6 | ) 7 | 8 | type GetDiskImageExecutor struct { 9 | Sender framework.MessageSender 10 | ImageServer *ImageManager 11 | } 12 | 13 | 14 | func (executor *GetDiskImageExecutor)Execute(id framework.SessionID, request framework.Message, 15 | incoming chan framework.Message, terminate chan bool) (err error) { 16 | imageID, err := request.GetString(framework.ParamKeyImage) 17 | if err != nil{ 18 | return err 19 | } 20 | var respChan = make(chan ImageResult, 1) 21 | executor.ImageServer.GetDiskImage(imageID, respChan) 22 | var result = <- respChan 23 | resp, _ := framework.CreateJsonMessage(framework.GetDiskImageResponse) 24 | resp.SetSuccess(false) 25 | resp.SetFromSession(id) 26 | resp.SetToSession(request.GetFromSession()) 27 | 28 | if result.Error != nil{ 29 | err := result.Error 30 | log.Printf("[%08X] get disk image fail: %s", id, err.Error()) 31 | resp.SetError(err.Error()) 32 | return executor.Sender.SendMessage(resp, request.GetSender()) 33 | } 34 | var image = result.DiskImage 35 | resp.SetSuccess(true) 36 | resp.SetString(framework.ParamKeyName, image.Name) 37 | resp.SetString(framework.ParamKeyDescription, image.Description) 38 | resp.SetStringArray(framework.ParamKeyTag, image.Tags) 39 | resp.SetString(framework.ParamKeyUser, image.Owner) 40 | resp.SetString(framework.ParamKeyGroup, image.Group) 41 | 42 | resp.SetUInt(framework.ParamKeySize, uint(image.Size)) 43 | resp.SetUInt(framework.ParamKeyProgress, image.Progress) 44 | 45 | resp.SetBoolean(framework.ParamKeyEnable, image.Created) 46 | return executor.Sender.SendMessage(resp, request.GetSender()) 47 | } 48 | -------------------------------------------------------------------------------- /src/task/remove_address_range.go: -------------------------------------------------------------------------------- 1 | package task 2 | 3 | import ( 4 | "github.com/project-nano/framework" 5 | "log" 6 | "github.com/project-nano/core/modules" 7 | ) 8 | 9 | type RemoveAddressRangeExecutor struct { 10 | Sender framework.MessageSender 11 | ResourceModule modules.ResourceModule 12 | } 13 | 14 | 15 | func (executor *RemoveAddressRangeExecutor)Execute(id framework.SessionID, request framework.Message, 16 | incoming chan framework.Message, terminate chan bool) (err error) { 17 | var poolName, rangeType, startAddress string 18 | if poolName, err = request.GetString(framework.ParamKeyAddress); err != nil{ 19 | return 20 | } 21 | if rangeType, err = request.GetString(framework.ParamKeyType); err != nil{ 22 | return 23 | } 24 | if startAddress, err = request.GetString(framework.ParamKeyStart); err != nil{ 25 | return 26 | } 27 | var respChan = make(chan error, 1) 28 | executor.ResourceModule.RemoveAddressRange(poolName, rangeType, startAddress, respChan) 29 | resp, _ := framework.CreateJsonMessage(framework.RemoveAddressRangeResponse) 30 | resp.SetFromSession(id) 31 | resp.SetToSession(request.GetFromSession()) 32 | resp.SetSuccess(false) 33 | 34 | err = <- respChan 35 | if err != nil{ 36 | resp.SetError(err.Error()) 37 | log.Printf("[%08X] request remove address range from %s.[%08X] fail: %s", 38 | id, request.GetSender(), request.GetFromSession(), err.Error()) 39 | return executor.Sender.SendMessage(resp, request.GetSender()) 40 | } 41 | resp.SetSuccess(true) 42 | log.Printf("[%08X] range '%s' removed from pool '%s' by %s.[%08X]", 43 | id, startAddress, 44 | poolName, request.GetSender(), request.GetFromSession()) 45 | return executor.Sender.SendMessage(resp, request.GetSender()) 46 | } 47 | -------------------------------------------------------------------------------- /src/task/handle_media_attached.go: -------------------------------------------------------------------------------- 1 | package task 2 | 3 | import ( 4 | "log" 5 | "github.com/project-nano/core/modules" 6 | "github.com/project-nano/framework" 7 | ) 8 | 9 | type HandleMediaAttachedExecutor struct { 10 | Sender framework.MessageSender 11 | ResourceModule modules.ResourceModule 12 | } 13 | 14 | func (executor *HandleMediaAttachedExecutor)Execute(id framework.SessionID, event framework.Message, 15 | incoming chan framework.Message, terminate chan bool) error { 16 | instanceID, err := event.GetString(framework.ParamKeyInstance) 17 | if err != nil { 18 | return err 19 | } 20 | 21 | mediaSource, err := event.GetString(framework.ParamKeyMedia) 22 | if err != nil{ 23 | return err 24 | } 25 | 26 | log.Printf("[%08X] media '%s' attached to guest '%s' from %s.[%08X]", id, mediaSource, instanceID, 27 | event.GetSender(), event.GetFromSession()) 28 | 29 | var status modules.InstanceStatus 30 | { 31 | var respChan = make(chan modules.ResourceResult) 32 | executor.ResourceModule.GetInstanceStatus(instanceID, respChan) 33 | result := <- respChan 34 | if result.Error != nil{ 35 | errMsg := result.Error.Error() 36 | log.Printf("[%08X] fetch guest fail: %s", id, errMsg) 37 | return result.Error 38 | } 39 | if result.Instance.MediaAttached{ 40 | log.Printf("[%08X] warning: media already attached", id) 41 | return nil 42 | } 43 | status = result.Instance 44 | } 45 | status.MediaAttached = true 46 | status.MediaSource = mediaSource 47 | { 48 | var respChan = make(chan error) 49 | executor.ResourceModule.UpdateInstanceStatus(status, respChan) 50 | err = <- respChan 51 | if err != nil{ 52 | log.Printf("[%08X] warning: update media status fail: %s", id, err) 53 | } 54 | return nil 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /src/task/get_compute_pool.go: -------------------------------------------------------------------------------- 1 | package task 2 | 3 | import ( 4 | "github.com/project-nano/framework" 5 | "github.com/project-nano/core/modules" 6 | "log" 7 | ) 8 | 9 | type GetComputePoolExecutor struct { 10 | Sender framework.MessageSender 11 | ResourceModule modules.ResourceModule 12 | } 13 | 14 | 15 | func (executor *GetComputePoolExecutor)Execute(id framework.SessionID, request framework.Message, 16 | incoming chan framework.Message, terminate chan bool) (err error){ 17 | poolName, err := request.GetString(framework.ParamKeyPool) 18 | if err != nil{ 19 | return 20 | } 21 | log.Printf("[%08X] get compute pool '%s' from %s.[%08X]", id, poolName, request.GetSender(), request.GetFromSession()) 22 | var respChan = make(chan modules.ResourceResult) 23 | executor.ResourceModule.GetComputePool(poolName, respChan) 24 | result := <- respChan 25 | resp, _ := framework.CreateJsonMessage(framework.GetComputePoolResponse) 26 | resp.SetSuccess(false) 27 | resp.SetFromSession(id) 28 | resp.SetToSession(request.GetFromSession()) 29 | 30 | if result.Error != nil{ 31 | err = result.Error 32 | resp.SetError(err.Error()) 33 | log.Printf("[%08X] get compute pool fail: %s", id, err.Error()) 34 | return executor.Sender.SendMessage(resp, request.GetSender()) 35 | } 36 | var poolInfo = result.ComputePoolConfig 37 | resp.SetString(framework.ParamKeyName, poolInfo.Name) 38 | resp.SetBoolean(framework.ParamKeyEnable, poolInfo.Enabled) 39 | resp.SetUInt(framework.ParamKeyCell, uint(poolInfo.CellCount)) 40 | resp.SetString(framework.ParamKeyNetwork, poolInfo.Network) 41 | resp.SetString(framework.ParamKeyStorage, poolInfo.Storage) 42 | resp.SetBoolean(framework.ParamKeyOption, poolInfo.Failover) 43 | resp.SetSuccess(true) 44 | return executor.Sender.SendMessage(resp, request.GetSender()) 45 | } -------------------------------------------------------------------------------- /src/imageserver/create_disk_image.go: -------------------------------------------------------------------------------- 1 | package imageserver 2 | 3 | import ( 4 | "github.com/project-nano/framework" 5 | "log" 6 | ) 7 | 8 | type CreateDiskImageExecutor struct { 9 | Sender framework.MessageSender 10 | ImageServer *ImageManager 11 | } 12 | 13 | func (executor *CreateDiskImageExecutor)Execute(id framework.SessionID, request framework.Message, 14 | incoming chan framework.Message, terminate chan bool) (err error) { 15 | var config ImageConfig 16 | if config.Name, err = request.GetString(framework.ParamKeyName); err != nil { 17 | return err 18 | } 19 | if config.Owner, err = request.GetString(framework.ParamKeyUser); err != nil { 20 | return err 21 | } 22 | if config.Group, err = request.GetString(framework.ParamKeyGroup); err != nil { 23 | return err 24 | } 25 | if config.Description, err = request.GetString(framework.ParamKeyDescription); err != nil { 26 | return err 27 | } 28 | if config.Tags, err = request.GetStringArray(framework.ParamKeyTag); err != nil { 29 | return err 30 | } 31 | var respChan = make(chan ImageResult, 1) 32 | executor.ImageServer.CreateDiskImage(config, respChan) 33 | result := <- respChan 34 | 35 | resp, _ := framework.CreateJsonMessage(framework.CreateDiskImageResponse) 36 | resp.SetSuccess(false) 37 | resp.SetFromSession(id) 38 | resp.SetToSession(request.GetFromSession()) 39 | 40 | if result.Error != nil{ 41 | err = result.Error 42 | resp.SetError(err.Error()) 43 | log.Printf("[%08X] create disk image fail: %s", id, err.Error()) 44 | return executor.Sender.SendMessage(resp, request.GetSender()) 45 | } 46 | log.Printf("[%08X] new disk image '%s' created(id '%s')", id, config.Name, result.ID) 47 | resp.SetString(framework.ParamKeyImage, result.ID) 48 | resp.SetSuccess(true) 49 | return executor.Sender.SendMessage(resp, request.GetSender()) 50 | } 51 | 52 | -------------------------------------------------------------------------------- /src/imageserver/create_media_image.go: -------------------------------------------------------------------------------- 1 | package imageserver 2 | 3 | import ( 4 | "github.com/project-nano/framework" 5 | "log" 6 | ) 7 | 8 | type CreateMediaImageExecutor struct { 9 | Sender framework.MessageSender 10 | ImageServer *ImageManager 11 | } 12 | 13 | 14 | func (executor *CreateMediaImageExecutor)Execute(id framework.SessionID, request framework.Message, 15 | incoming chan framework.Message, terminate chan bool) (err error) { 16 | var config ImageConfig 17 | if config.Name, err = request.GetString(framework.ParamKeyName); err != nil { 18 | return err 19 | } 20 | if config.Owner, err = request.GetString(framework.ParamKeyUser); err != nil { 21 | return err 22 | } 23 | if config.Group, err = request.GetString(framework.ParamKeyGroup); err != nil { 24 | return err 25 | } 26 | if config.Description, err = request.GetString(framework.ParamKeyDescription); err != nil { 27 | return err 28 | } 29 | if config.Tags, err = request.GetStringArray(framework.ParamKeyTag); err != nil { 30 | return err 31 | } 32 | var respChan = make(chan ImageResult, 1) 33 | executor.ImageServer.CreateMediaImage(config, respChan) 34 | result := <- respChan 35 | 36 | resp, _ := framework.CreateJsonMessage(framework.CreateMediaImageResponse) 37 | resp.SetSuccess(false) 38 | resp.SetFromSession(id) 39 | resp.SetToSession(request.GetFromSession()) 40 | 41 | if result.Error != nil{ 42 | err = result.Error 43 | resp.SetError(err.Error()) 44 | log.Printf("[%08X] create media image fail: %s", id, err.Error()) 45 | return executor.Sender.SendMessage(resp, request.GetSender()) 46 | } 47 | log.Printf("[%08X] new media image '%s' created(id '%s')", id, config.Name, result.ID) 48 | resp.SetString(framework.ParamKeyImage, result.ID) 49 | resp.SetSuccess(true) 50 | return executor.Sender.SendMessage(resp, request.GetSender()) 51 | } 52 | -------------------------------------------------------------------------------- /src/imageserver/modify_disk_image.go: -------------------------------------------------------------------------------- 1 | package imageserver 2 | 3 | import ( 4 | "github.com/project-nano/framework" 5 | "log" 6 | ) 7 | 8 | type ModifyDiskImageExecutor struct { 9 | Sender framework.MessageSender 10 | ImageServer *ImageManager 11 | } 12 | 13 | 14 | func (executor *ModifyDiskImageExecutor)Execute(id framework.SessionID, request framework.Message, 15 | incoming chan framework.Message, terminate chan bool) (err error) { 16 | var imageID string 17 | if imageID, err = request.GetString(framework.ParamKeyImage); err != nil{ 18 | return 19 | } 20 | var config ImageConfig 21 | if config.Name, err = request.GetString(framework.ParamKeyName); err != nil { 22 | return err 23 | } 24 | if config.Owner, err = request.GetString(framework.ParamKeyUser); err != nil { 25 | return err 26 | } 27 | if config.Group, err = request.GetString(framework.ParamKeyGroup); err != nil { 28 | return err 29 | } 30 | if config.Description, err = request.GetString(framework.ParamKeyDescription); err != nil { 31 | return err 32 | } 33 | if config.Tags, err = request.GetStringArray(framework.ParamKeyTag); err != nil { 34 | return err 35 | } 36 | var respChan = make(chan error, 1) 37 | executor.ImageServer.ModifyDiskImage(imageID, config, respChan) 38 | err = <- respChan 39 | 40 | resp, _ := framework.CreateJsonMessage(framework.ModifyMediaImageResponse) 41 | resp.SetSuccess(false) 42 | resp.SetFromSession(id) 43 | resp.SetToSession(request.GetFromSession()) 44 | 45 | if err != nil{ 46 | resp.SetError(err.Error()) 47 | log.Printf("[%08X] modify disk image fail: %s", id, err.Error()) 48 | return executor.Sender.SendMessage(resp, request.GetSender()) 49 | } 50 | log.Printf("[%08X] disk image '%s' modified", id, imageID) 51 | resp.SetSuccess(true) 52 | return executor.Sender.SendMessage(resp, request.GetSender()) 53 | } 54 | -------------------------------------------------------------------------------- /src/imageserver/modify_media_image.go: -------------------------------------------------------------------------------- 1 | package imageserver 2 | 3 | import ( 4 | "github.com/project-nano/framework" 5 | "log" 6 | ) 7 | 8 | type ModifyMediaImageExecutor struct { 9 | Sender framework.MessageSender 10 | ImageServer *ImageManager 11 | } 12 | 13 | 14 | func (executor *ModifyMediaImageExecutor)Execute(id framework.SessionID, request framework.Message, 15 | incoming chan framework.Message, terminate chan bool) (err error) { 16 | var imageID string 17 | if imageID, err = request.GetString(framework.ParamKeyImage); err != nil{ 18 | return 19 | } 20 | var config ImageConfig 21 | if config.Name, err = request.GetString(framework.ParamKeyName); err != nil { 22 | return err 23 | } 24 | if config.Owner, err = request.GetString(framework.ParamKeyUser); err != nil { 25 | return err 26 | } 27 | if config.Group, err = request.GetString(framework.ParamKeyGroup); err != nil { 28 | return err 29 | } 30 | if config.Description, err = request.GetString(framework.ParamKeyDescription); err != nil { 31 | return err 32 | } 33 | if config.Tags, err = request.GetStringArray(framework.ParamKeyTag); err != nil { 34 | return err 35 | } 36 | var respChan = make(chan error, 1) 37 | executor.ImageServer.ModifyMediaImage(imageID, config, respChan) 38 | err = <- respChan 39 | 40 | resp, _ := framework.CreateJsonMessage(framework.ModifyMediaImageResponse) 41 | resp.SetSuccess(false) 42 | resp.SetFromSession(id) 43 | resp.SetToSession(request.GetFromSession()) 44 | 45 | if err != nil{ 46 | resp.SetError(err.Error()) 47 | log.Printf("[%08X] modify media image fail: %s", id, err.Error()) 48 | return executor.Sender.SendMessage(resp, request.GetSender()) 49 | } 50 | log.Printf("[%08X] media image '%s' modified", id, imageID) 51 | resp.SetSuccess(true) 52 | return executor.Sender.SendMessage(resp, request.GetSender()) 53 | } 54 | 55 | -------------------------------------------------------------------------------- /src/task/query_migration.go: -------------------------------------------------------------------------------- 1 | package task 2 | 3 | import ( 4 | "github.com/project-nano/framework" 5 | "github.com/project-nano/core/modules" 6 | "log" 7 | ) 8 | 9 | type QueryMigrationExecutor struct { 10 | Sender framework.MessageSender 11 | ResourceModule modules.ResourceModule 12 | } 13 | 14 | func (executor *QueryMigrationExecutor)Execute(id framework.SessionID, request framework.Message, 15 | incoming chan framework.Message, terminate chan bool) (err error){ 16 | resp, _ := framework.CreateJsonMessage(framework.QueryMigrationResponse) 17 | resp.SetSuccess(false) 18 | resp.SetToSession(request.GetFromSession()) 19 | resp.SetFromSession(id) 20 | var respChan = make(chan modules.ResourceResult, 1) 21 | executor.ResourceModule.QueryMigration(respChan) 22 | var result = <- respChan 23 | if result.Error != nil{ 24 | err = result.Error 25 | log.Printf("[%08X] query migration fail: %s", err.Error()) 26 | resp.SetError(err.Error()) 27 | return nil 28 | } 29 | var idList, errMessage []string 30 | var finish, progress []uint64 31 | for _, m := range result.MigrationList { 32 | idList = append(idList, m.ID) 33 | if m.Finished{ 34 | finish = append(finish, 1) 35 | }else{ 36 | finish = append(finish, 0) 37 | } 38 | progress = append(progress, uint64(m.Progress)) 39 | if m.Error != nil{ 40 | errMessage = append(errMessage, m.Error.Error()) 41 | }else{ 42 | errMessage = append(errMessage, "") 43 | } 44 | 45 | } 46 | resp.SetSuccess(true) 47 | resp.SetStringArray(framework.ParamKeyMigration, idList) 48 | resp.SetUIntArray(framework.ParamKeyStatus, finish) 49 | resp.SetUIntArray(framework.ParamKeyProgress, progress) 50 | resp.SetStringArray(framework.ParamKeyError, errMessage) 51 | log.Printf("[%08X] %d migrations available", id, len(idList)) 52 | return executor.Sender.SendMessage(resp, request.GetSender()) 53 | } -------------------------------------------------------------------------------- /src/task/query_system_templates.go: -------------------------------------------------------------------------------- 1 | package task 2 | 3 | import ( 4 | "github.com/project-nano/core/modules" 5 | "github.com/project-nano/framework" 6 | "log" 7 | ) 8 | 9 | type QuerySystemTemplatesExecutor struct { 10 | Sender framework.MessageSender 11 | ResourceModule modules.ResourceModule 12 | } 13 | 14 | func (executor *QuerySystemTemplatesExecutor)Execute(id framework.SessionID, request framework.Message, 15 | incoming chan framework.Message, terminate chan bool) (err error){ 16 | var respChan = make(chan modules.ResourceResult, 1) 17 | executor.ResourceModule.QuerySystemTemplates(respChan) 18 | var result = <- respChan 19 | 20 | resp, _ := framework.CreateJsonMessage(framework.QueryTemplateResponse) 21 | resp.SetSuccess(false) 22 | resp.SetFromSession(id) 23 | resp.SetToSession(request.GetFromSession()) 24 | 25 | if result.Error != nil{ 26 | err = result.Error 27 | resp.SetError(err.Error()) 28 | log.Printf("[%08X] handle query system templates from %s.[%08X] fail: %s", 29 | id, request.GetSender(), request.GetFromSession(), err.Error()) 30 | }else{ 31 | var idList, nameList, osList, createList, modifiedList []string 32 | for _, t := range result.TemplateList { 33 | idList = append(idList, t.ID) 34 | nameList = append(nameList, t.Name) 35 | osList = append(osList, t.OperatingSystem) 36 | createList = append(createList, t.CreatedTime) 37 | modifiedList = append(modifiedList, t.ModifiedTime) 38 | } 39 | resp.SetSuccess(true) 40 | resp.SetStringArray(framework.ParamKeyID, idList) 41 | resp.SetStringArray(framework.ParamKeyName, nameList) 42 | resp.SetStringArray(framework.ParamKeySystem, osList) 43 | resp.SetStringArray(framework.ParamKeyCreate, createList) 44 | resp.SetStringArray(framework.ParamKeyModify, modifiedList) 45 | } 46 | 47 | return executor.Sender.SendMessage(resp, request.GetSender()) 48 | } 49 | -------------------------------------------------------------------------------- /src/task/remove_compute_cell.go: -------------------------------------------------------------------------------- 1 | package task 2 | 3 | import ( 4 | "github.com/project-nano/framework" 5 | "github.com/project-nano/core/modules" 6 | "log" 7 | ) 8 | 9 | type RemoveComputePoolExecutor struct { 10 | Sender framework.MessageSender 11 | ResourceModule modules.ResourceModule 12 | } 13 | 14 | func (executor *RemoveComputePoolExecutor)Execute(id framework.SessionID, request framework.Message, 15 | incoming chan framework.Message, terminate chan bool) error { 16 | pool, err := request.GetString(framework.ParamKeyPool) 17 | if err != nil{ 18 | return err 19 | } 20 | cellName, err := request.GetString(framework.ParamKeyCell) 21 | if err != nil{ 22 | return err 23 | } 24 | log.Printf("[%08X] request remove cell '%s' from pool '%s' from %s.[%08X]", id, cellName, pool, 25 | request.GetSender(), request.GetFromSession()) 26 | var respChan= make(chan error) 27 | executor.ResourceModule.RemoveCell(pool, cellName, respChan) 28 | 29 | resp, _ := framework.CreateJsonMessage(framework.RemoveComputePoolCellResponse) 30 | resp.SetSuccess(false) 31 | resp.SetFromSession(id) 32 | resp.SetToSession(request.GetFromSession()) 33 | 34 | err = <-respChan 35 | if err != nil{ 36 | resp.SetError(err.Error()) 37 | log.Printf("[%08X] remove compute cell fail: %s", id, err.Error()) 38 | return executor.Sender.SendMessage(resp, request.GetSender()) 39 | } 40 | resp.SetSuccess(true) 41 | if err = executor.Sender.SendMessage(resp, request.GetSender()); err != nil{ 42 | log.Printf("[%08X] warning: send cell removed response to '%s' fail: %s", id, request.GetSender(), err.Error()) 43 | } 44 | event, _ := framework.CreateJsonMessage(framework.ComputeCellRemovedEvent) 45 | if err = executor.Sender.SendMessage(event, cellName); err != nil{ 46 | log.Printf("[%08X] warning: notify cell removed to '%s' fail: %s", id, cellName, err.Error()) 47 | } 48 | return nil 49 | } 50 | -------------------------------------------------------------------------------- /src/task/create_address_pool.go: -------------------------------------------------------------------------------- 1 | package task 2 | 3 | import ( 4 | "fmt" 5 | "github.com/project-nano/framework" 6 | "github.com/project-nano/core/modules" 7 | "log" 8 | ) 9 | 10 | type CreateAddressPoolExecutor struct { 11 | Sender framework.MessageSender 12 | ResourceModule modules.ResourceModule 13 | } 14 | 15 | 16 | func (executor *CreateAddressPoolExecutor)Execute(id framework.SessionID, request framework.Message, 17 | incoming chan framework.Message, terminate chan bool) (err error) { 18 | var config modules.AddressPoolConfig 19 | var poolName string 20 | if poolName, err = request.GetString(framework.ParamKeyAddress); err != nil{ 21 | return 22 | } 23 | config.Name = poolName 24 | if config.Gateway, err = request.GetString(framework.ParamKeyGateway); err != nil{ 25 | return 26 | } 27 | if config.DNS, err = request.GetStringArray(framework.ParamKeyServer); err != nil{ 28 | return 29 | } 30 | if config.Provider, err = request.GetString(framework.ParamKeyMode); err != nil{ 31 | err = fmt.Errorf("get provider fail: %s", err.Error()) 32 | return 33 | } 34 | var respChan = make(chan error, 1) 35 | executor.ResourceModule.CreateAddressPool(config, respChan) 36 | resp, _ := framework.CreateJsonMessage(framework.CreateAddressPoolResponse) 37 | resp.SetFromSession(id) 38 | resp.SetToSession(request.GetFromSession()) 39 | resp.SetSuccess(false) 40 | 41 | err = <- respChan 42 | if err != nil{ 43 | resp.SetError(err.Error()) 44 | log.Printf("[%08X] request create address pool from %s.[%08X] fail: %s", 45 | id, request.GetSender(), request.GetFromSession(), err.Error()) 46 | return executor.Sender.SendMessage(resp, request.GetSender()) 47 | } 48 | 49 | resp.SetSuccess(true) 50 | log.Printf("[%08X] address pool '%s' created from %s.[%08X]", 51 | id, poolName, request.GetSender(), request.GetFromSession()) 52 | return executor.Sender.SendMessage(resp, request.GetSender()) 53 | } 54 | -------------------------------------------------------------------------------- /src/task/get_security_policy_group.go: -------------------------------------------------------------------------------- 1 | package task 2 | 3 | import ( 4 | "fmt" 5 | "github.com/project-nano/core/modules" 6 | "github.com/project-nano/framework" 7 | "log" 8 | ) 9 | 10 | type GetSecurityPolicyGroupExecutor struct { 11 | Sender framework.MessageSender 12 | ResourceModule modules.ResourceModule 13 | } 14 | 15 | func (executor *GetSecurityPolicyGroupExecutor) Execute(id framework.SessionID, request framework.Message, 16 | incoming chan framework.Message, terminate chan bool) (err error) { 17 | var policyID string 18 | if policyID, err = request.GetString(framework.ParamKeyPolicy);err != nil{ 19 | err = fmt.Errorf("get policy group ID fail: %s", err.Error()) 20 | return 21 | } 22 | 23 | resp, _ := framework.CreateJsonMessage(framework.GetPolicyGroupResponse) 24 | resp.SetToSession(request.GetFromSession()) 25 | resp.SetFromSession(id) 26 | resp.SetTransactionID(request.GetTransactionID()) 27 | resp.SetSuccess(false) 28 | var respChan = make(chan modules.ResourceResult, 1) 29 | executor.ResourceModule.GetSecurityPolicyGroup(policyID, respChan) 30 | var result = <- respChan 31 | if result.Error != nil{ 32 | err = result.Error 33 | log.Printf("[%08X] get security policy group '%s' fail: %s", 34 | id, policyID, err.Error()) 35 | resp.SetError(err.Error()) 36 | }else{ 37 | var policy = result.PolicyGroup 38 | resp.SetString(framework.ParamKeyPolicy, policy.ID) 39 | resp.SetString(framework.ParamKeyName, policy.Name) 40 | resp.SetString(framework.ParamKeyDescription, policy.Description) 41 | resp.SetString(framework.ParamKeyUser, policy.User) 42 | resp.SetString(framework.ParamKeyGroup, policy.Group) 43 | resp.SetBoolean(framework.ParamKeyAction, policy.Accept) 44 | resp.SetBoolean(framework.ParamKeyEnable, policy.Enabled) 45 | resp.SetBoolean(framework.ParamKeyLimit, policy.Global) 46 | resp.SetSuccess(true) 47 | } 48 | return executor.Sender.SendMessage(resp, request.GetSender()) 49 | } 50 | -------------------------------------------------------------------------------- /src/task/get_batch_stop_guest.go: -------------------------------------------------------------------------------- 1 | package task 2 | 3 | import ( 4 | "github.com/project-nano/framework" 5 | "github.com/project-nano/core/modules" 6 | "log" 7 | ) 8 | 9 | type GetBatchStopGuestExecutor struct { 10 | Sender framework.MessageSender 11 | ResourceModule modules.ResourceModule 12 | } 13 | 14 | func (executor *GetBatchStopGuestExecutor)Execute(id framework.SessionID, request framework.Message, 15 | incoming chan framework.Message, terminate chan bool) (err error) { 16 | var batchID string 17 | if batchID, err = request.GetString(framework.ParamKeyID);err != nil{ 18 | return err 19 | } 20 | resp, _ := framework.CreateJsonMessage(framework.GetBatchStopGuestResponse) 21 | resp.SetFromSession(id) 22 | resp.SetToSession(request.GetFromSession()) 23 | resp.SetSuccess(false) 24 | 25 | var respChan = make(chan modules.ResourceResult, 1) 26 | executor.ResourceModule.GetBatchStopGuestStatus(batchID, respChan) 27 | var result = <- respChan 28 | if result.Error != nil{ 29 | err = result.Error 30 | log.Printf("[%08X] get batch stop status from %s.[%08X] fail: %s", id, request.GetSender(), request.GetFromSession(), err.Error()) 31 | resp.SetError(err.Error()) 32 | return executor.Sender.SendMessage(resp, request.GetSender()) 33 | } 34 | 35 | var guestStatus []uint64 36 | var guestID, guestName, stopError []string 37 | 38 | for _, status := range result.BatchStop{ 39 | guestStatus = append(guestStatus, uint64(status.Status)) 40 | guestID = append(guestID, status.ID) 41 | guestName = append(guestName, status.Name) 42 | stopError = append(stopError, status.Error) 43 | } 44 | resp.SetSuccess(true) 45 | resp.SetStringArray(framework.ParamKeyName, guestName) 46 | resp.SetStringArray(framework.ParamKeyGuest, guestID) 47 | resp.SetStringArray(framework.ParamKeyError, stopError) 48 | resp.SetUIntArray(framework.ParamKeyStatus, guestStatus) 49 | return executor.Sender.SendMessage(resp, request.GetSender()) 50 | } 51 | 52 | -------------------------------------------------------------------------------- /src/task/add_address_range.go: -------------------------------------------------------------------------------- 1 | package task 2 | 3 | import ( 4 | "github.com/project-nano/framework" 5 | "github.com/project-nano/core/modules" 6 | "log" 7 | ) 8 | 9 | type AddAddressRangeExecutor struct { 10 | Sender framework.MessageSender 11 | ResourceModule modules.ResourceModule 12 | } 13 | 14 | 15 | func (executor *AddAddressRangeExecutor)Execute(id framework.SessionID, request framework.Message, 16 | incoming chan framework.Message, terminate chan bool) (err error) { 17 | var poolName, rangeType string 18 | if poolName, err = request.GetString(framework.ParamKeyAddress); err != nil{ 19 | return 20 | } 21 | if rangeType, err = request.GetString(framework.ParamKeyType); err != nil{ 22 | return 23 | } 24 | var config modules.AddressRangeConfig 25 | if config.Start, err = request.GetString(framework.ParamKeyStart); err != nil{ 26 | return 27 | } 28 | if config.End, err = request.GetString(framework.ParamKeyEnd); err != nil{ 29 | return 30 | } 31 | if config.Netmask, err = request.GetString(framework.ParamKeyMask); err != nil{ 32 | return 33 | } 34 | var respChan = make(chan error, 1) 35 | executor.ResourceModule.AddAddressRange(poolName, rangeType, config, respChan) 36 | resp, _ := framework.CreateJsonMessage(framework.AddAddressRangeResponse) 37 | resp.SetFromSession(id) 38 | resp.SetToSession(request.GetFromSession()) 39 | resp.SetSuccess(false) 40 | 41 | err = <- respChan 42 | if err != nil{ 43 | resp.SetError(err.Error()) 44 | log.Printf("[%08X] request add address range from %s.[%08X] fail: %s", 45 | id, request.GetSender(), request.GetFromSession(), err.Error()) 46 | return executor.Sender.SendMessage(resp, request.GetSender()) 47 | } 48 | resp.SetSuccess(true) 49 | log.Printf("[%08X] range '%s ~ %s/%s' added to pool '%s' from %s.[%08X]", 50 | id, config.Start, config.End, config.Netmask, 51 | poolName, request.GetSender(), request.GetFromSession()) 52 | return executor.Sender.SendMessage(resp, request.GetSender()) 53 | } 54 | -------------------------------------------------------------------------------- /src/task/get_batch_delete_guest.go: -------------------------------------------------------------------------------- 1 | package task 2 | 3 | import ( 4 | "github.com/project-nano/framework" 5 | "github.com/project-nano/core/modules" 6 | "log" 7 | ) 8 | 9 | type GetBatchDeleteGuestExecutor struct { 10 | Sender framework.MessageSender 11 | ResourceModule modules.ResourceModule 12 | } 13 | 14 | 15 | func (executor *GetBatchDeleteGuestExecutor)Execute(id framework.SessionID, request framework.Message, 16 | incoming chan framework.Message, terminate chan bool) (err error) { 17 | var batchID string 18 | if batchID, err = request.GetString(framework.ParamKeyID);err != nil{ 19 | return err 20 | } 21 | resp, _ := framework.CreateJsonMessage(framework.GetBatchDeleteGuestResponse) 22 | resp.SetFromSession(id) 23 | resp.SetToSession(request.GetFromSession()) 24 | resp.SetSuccess(false) 25 | 26 | var respChan = make(chan modules.ResourceResult, 1) 27 | executor.ResourceModule.GetBatchDeleteGuestStatus(batchID, respChan) 28 | var result = <- respChan 29 | if result.Error != nil{ 30 | err = result.Error 31 | log.Printf("[%08X] get batch delete status from %s.[%08X] fail: %s", id, request.GetSender(), request.GetFromSession(), err.Error()) 32 | resp.SetError(err.Error()) 33 | return executor.Sender.SendMessage(resp, request.GetSender()) 34 | } 35 | 36 | var guestStatus []uint64 37 | var guestID, guestName, deleteError []string 38 | 39 | for _, status := range result.BatchDelete{ 40 | guestStatus = append(guestStatus, uint64(status.Status)) 41 | guestID = append(guestID, status.ID) 42 | guestName = append(guestName, status.Name) 43 | deleteError = append(deleteError, status.Error) 44 | } 45 | resp.SetSuccess(true) 46 | resp.SetStringArray(framework.ParamKeyName, guestName) 47 | resp.SetStringArray(framework.ParamKeyGuest, guestID) 48 | resp.SetStringArray(framework.ParamKeyError, deleteError) 49 | resp.SetUIntArray(framework.ParamKeyStatus, guestStatus) 50 | return executor.Sender.SendMessage(resp, request.GetSender()) 51 | } 52 | 53 | -------------------------------------------------------------------------------- /src/task/move_security_policy_rule.go: -------------------------------------------------------------------------------- 1 | package task 2 | 3 | import ( 4 | "fmt" 5 | "github.com/project-nano/core/modules" 6 | "github.com/project-nano/framework" 7 | "log" 8 | ) 9 | 10 | type MoveSecurityPolicyRuleExecutor struct { 11 | Sender framework.MessageSender 12 | ResourceModule modules.ResourceModule 13 | } 14 | 15 | func (executor *MoveSecurityPolicyRuleExecutor)Execute(id framework.SessionID, request framework.Message, 16 | incoming chan framework.Message, terminate chan bool) (err error) { 17 | var policyID string 18 | if policyID, err = request.GetString(framework.ParamKeyPolicy);err != nil{ 19 | err = fmt.Errorf("get policy group ID fail: %s", err.Error()) 20 | return 21 | } 22 | var index int 23 | if index, err = request.GetInt(framework.ParamKeyIndex);err != nil{ 24 | err = fmt.Errorf("get index fail: %s", err.Error()) 25 | return 26 | } 27 | var moveUp bool 28 | if moveUp, err = request.GetBoolean(framework.ParamKeyFlag); err != nil{ 29 | err = fmt.Errorf("get move flag fail: %s", err.Error()) 30 | return 31 | } 32 | 33 | resp, _ := framework.CreateJsonMessage(framework.ChangePolicyRuleOrderResponse) 34 | resp.SetToSession(request.GetFromSession()) 35 | resp.SetFromSession(id) 36 | resp.SetTransactionID(request.GetTransactionID()) 37 | resp.SetSuccess(false) 38 | var respChan = make(chan error, 1) 39 | executor.ResourceModule.MoveSecurityPolicyRule(policyID, index, moveUp, respChan) 40 | err = <- respChan 41 | if err != nil{ 42 | log.Printf("[%08X] move %dth rule of security policy '%s' fail: %s", 43 | id, index, policyID, err.Error()) 44 | resp.SetError(err.Error()) 45 | }else{ 46 | if moveUp{ 47 | log.Printf("[%08X] %dth rule of security policy '%s' moved up", 48 | id, index, policyID) 49 | }else{ 50 | log.Printf("[%08X] %dth rule of security policy '%s' moved down", 51 | id, index, policyID) 52 | } 53 | resp.SetSuccess(true) 54 | } 55 | return executor.Sender.SendMessage(resp, request.GetSender()) 56 | } 57 | -------------------------------------------------------------------------------- /src/task/create_storage_pool.go: -------------------------------------------------------------------------------- 1 | package task 2 | 3 | import ( 4 | "github.com/project-nano/framework" 5 | "github.com/project-nano/core/modules" 6 | "log" 7 | "fmt" 8 | ) 9 | 10 | type CreateStoragePoolExecutor struct { 11 | Sender framework.MessageSender 12 | ResourceModule modules.ResourceModule 13 | } 14 | 15 | func (executor *CreateStoragePoolExecutor)Execute(id framework.SessionID, request framework.Message, 16 | incoming chan framework.Message, terminate chan bool) (err error) { 17 | var pool, storageType, host, target string 18 | pool, err = request.GetString(framework.ParamKeyStorage) 19 | if err != nil { 20 | return 21 | } 22 | if storageType, err = request.GetString(framework.ParamKeyType); err != nil{ 23 | return 24 | } 25 | if host, err = request.GetString(framework.ParamKeyHost); err != nil{ 26 | return 27 | } 28 | if target, err = request.GetString(framework.ParamKeyTarget); err != nil{ 29 | return 30 | } 31 | 32 | log.Printf("[%08X] request create storage pool '%s' from %s.[%08X]", id, pool, 33 | request.GetSender(), request.GetFromSession()) 34 | 35 | resp, _ := framework.CreateJsonMessage(framework.CreateStoragePoolResponse) 36 | resp.SetSuccess(false) 37 | resp.SetFromSession(id) 38 | resp.SetToSession(request.GetFromSession()) 39 | 40 | if err = QualifyNormalName(pool); err != nil{ 41 | log.Printf("[%08X] invalid pool name '%s' : %s", id, pool, err.Error()) 42 | err = fmt.Errorf("invalid pool name '%s': %s", pool, err.Error()) 43 | resp.SetError(err.Error()) 44 | return executor.Sender.SendMessage(resp, request.GetSender()) 45 | } 46 | 47 | var respChan= make(chan error) 48 | executor.ResourceModule.CreateStoragePool(pool, storageType, host, target, respChan) 49 | err = <-respChan 50 | if err != nil{ 51 | resp.SetError(err.Error()) 52 | log.Printf("[%08X] create storage pool fail: %s", id, err.Error()) 53 | }else{ 54 | resp.SetSuccess(true) 55 | } 56 | 57 | return executor.Sender.SendMessage(resp, request.GetSender()) 58 | } 59 | -------------------------------------------------------------------------------- /src/task/modify_storage_pool.go: -------------------------------------------------------------------------------- 1 | package task 2 | 3 | import ( 4 | "github.com/project-nano/framework" 5 | "log" 6 | "fmt" 7 | "github.com/project-nano/core/modules" 8 | ) 9 | 10 | type ModifyStoragePoolExecutor struct { 11 | Sender framework.MessageSender 12 | ResourceModule modules.ResourceModule 13 | } 14 | 15 | func (executor *ModifyStoragePoolExecutor)Execute(id framework.SessionID, request framework.Message, 16 | incoming chan framework.Message, terminate chan bool) (err error) { 17 | var pool, storageType, host, target string 18 | pool, err = request.GetString(framework.ParamKeyStorage) 19 | if err != nil { 20 | return 21 | } 22 | if storageType, err = request.GetString(framework.ParamKeyType); err != nil{ 23 | return 24 | } 25 | if host, err = request.GetString(framework.ParamKeyHost); err != nil{ 26 | return 27 | } 28 | if target, err = request.GetString(framework.ParamKeyTarget); err != nil{ 29 | return 30 | } 31 | 32 | log.Printf("[%08X] request modify storage pool '%s' from %s.[%08X]", id, pool, 33 | request.GetSender(), request.GetFromSession()) 34 | 35 | resp, _ := framework.CreateJsonMessage(framework.ModifyStoragePoolResponse) 36 | resp.SetSuccess(false) 37 | resp.SetFromSession(id) 38 | resp.SetToSession(request.GetFromSession()) 39 | 40 | if err = QualifyNormalName(pool); err != nil{ 41 | log.Printf("[%08X] invalid pool name '%s' : %s", id, pool, err.Error()) 42 | err = fmt.Errorf("invalid pool name '%s': %s", pool, err.Error()) 43 | resp.SetError(err.Error()) 44 | return executor.Sender.SendMessage(resp, request.GetSender()) 45 | } 46 | 47 | var respChan= make(chan error) 48 | executor.ResourceModule.ModifyStoragePool(pool, storageType, host, target, respChan) 49 | err = <-respChan 50 | if err != nil{ 51 | resp.SetError(err.Error()) 52 | log.Printf("[%08X] modify storage pool fail: %s", id, err.Error()) 53 | }else{ 54 | resp.SetSuccess(true) 55 | } 56 | 57 | return executor.Sender.SendMessage(resp, request.GetSender()) 58 | } 59 | 60 | -------------------------------------------------------------------------------- /src/task/query_compute_pool.go: -------------------------------------------------------------------------------- 1 | package task 2 | 3 | import ( 4 | "github.com/project-nano/core/modules" 5 | "github.com/project-nano/framework" 6 | ) 7 | 8 | type QueryComputePoolExecutor struct { 9 | Sender framework.MessageSender 10 | ResourceModule modules.ResourceModule 11 | } 12 | 13 | 14 | func (executor *QueryComputePoolExecutor)Execute(id framework.SessionID, request framework.Message, 15 | incoming chan framework.Message, terminate chan bool) error{ 16 | //log.Printf("[%08X] query compute pool from %s.[%08X]", id, request.GetSender(), request.GetFromSession()) 17 | var respChan = make(chan modules.ResourceResult) 18 | executor.ResourceModule.GetAllComputePool(respChan) 19 | result := <- respChan 20 | var nameArray, networkArray, storageArray []string 21 | var cellArray, statusArray, failoverArray []uint64 22 | for _, info := range result.ComputePoolInfoList{ 23 | if info.Enabled{ 24 | statusArray = append(statusArray, 1) 25 | }else { 26 | statusArray = append(statusArray, 0) 27 | } 28 | if info.Failover{ 29 | failoverArray = append(failoverArray, 1) 30 | }else { 31 | failoverArray = append(failoverArray, 0) 32 | } 33 | nameArray = append(nameArray, info.Name) 34 | cellArray = append(cellArray, info.CellCount) 35 | networkArray = append(networkArray, info.Network) 36 | storageArray = append(storageArray, info.Storage) 37 | } 38 | resp, _ := framework.CreateJsonMessage(framework.QueryComputePoolResponse) 39 | resp.SetSuccess(true) 40 | resp.SetFromSession(id) 41 | resp.SetToSession(request.GetFromSession()) 42 | resp.SetStringArray(framework.ParamKeyName, nameArray) 43 | resp.SetStringArray(framework.ParamKeyNetwork, networkArray) 44 | resp.SetStringArray(framework.ParamKeyStorage, storageArray) 45 | resp.SetUIntArray(framework.ParamKeyStatus, statusArray) 46 | resp.SetUIntArray(framework.ParamKeyCell, cellArray) 47 | resp.SetUIntArray(framework.ParamKeyOption, failoverArray) 48 | return executor.Sender.SendMessage(resp, request.GetSender()) 49 | } -------------------------------------------------------------------------------- /src/task/handle_guest_updated.go: -------------------------------------------------------------------------------- 1 | package task 2 | 3 | import ( 4 | "github.com/project-nano/framework" 5 | "github.com/project-nano/core/modules" 6 | "log" 7 | "errors" 8 | ) 9 | 10 | type HandleGuestUpdatedExecutor struct { 11 | Sender framework.MessageSender 12 | ResourceModule modules.ResourceModule 13 | } 14 | 15 | func (executor *HandleGuestUpdatedExecutor)Execute(id framework.SessionID, event framework.Message, 16 | incoming chan framework.Message, terminate chan bool) error { 17 | instanceID, err := event.GetString(framework.ParamKeyInstance) 18 | if err != nil { 19 | return err 20 | } 21 | if !event.IsSuccess(){ 22 | log.Printf("[%08X] guest '%s' create fail: %s", id, instanceID, event.GetError()) 23 | err = errors.New(event.GetError()) 24 | var respChan = make(chan error) 25 | executor.ResourceModule.DeallocateInstance(instanceID, err, respChan) 26 | <- respChan 27 | return nil 28 | } 29 | 30 | progress, err := event.GetUInt(framework.ParamKeyProgress) 31 | if err != nil{ 32 | return err 33 | } 34 | 35 | log.Printf("[%08X] update guest '%s' progress to %d%% from %s.[%08X]", id, instanceID, 36 | progress, event.GetSender(), event.GetFromSession()) 37 | 38 | var status modules.InstanceStatus 39 | { 40 | var respChan = make(chan modules.ResourceResult) 41 | executor.ResourceModule.GetInstanceStatus(instanceID, respChan) 42 | result := <- respChan 43 | if result.Error != nil{ 44 | errMsg := result.Error.Error() 45 | log.Printf("[%08X] fetch guest fail: %s", id, errMsg) 46 | return result.Error 47 | } 48 | if result.Instance.Created{ 49 | log.Printf("[%08X] warning: guest already created", id) 50 | return nil 51 | } 52 | status = result.Instance 53 | } 54 | status.Progress = progress 55 | { 56 | var respChan = make(chan error) 57 | executor.ResourceModule.UpdateInstanceStatus(status, respChan) 58 | err = <- respChan 59 | if err != nil{ 60 | log.Printf("[%08X] warning: update progress fail: %s", id, err) 61 | } 62 | return nil 63 | } 64 | } -------------------------------------------------------------------------------- /src/task/query_instance_status.go: -------------------------------------------------------------------------------- 1 | package task 2 | 3 | import ( 4 | "github.com/project-nano/framework" 5 | "log" 6 | "github.com/project-nano/core/modules" 7 | ) 8 | 9 | type QueryInstanceStatusExecutor struct { 10 | Sender framework.MessageSender 11 | ResourceModule modules.ResourceModule 12 | } 13 | 14 | func (executor *QueryInstanceStatusExecutor)Execute(id framework.SessionID, request framework.Message, 15 | incoming chan framework.Message, terminate chan bool) (err error) { 16 | poolName, err := request.GetString(framework.ParamKeyPool) 17 | if err != nil{ 18 | return err 19 | } 20 | var inCell = false 21 | cellName, err := request.GetString(framework.ParamKeyCell) 22 | if err == nil{ 23 | inCell = true 24 | } 25 | var respChan = make(chan modules.ResourceResult) 26 | if inCell{ 27 | //log.Printf("[%08X] request query instance status in cell '%s' from %s.[%08X]", id, cellName, 28 | // request.GetSender(), request.GetFromSession()) 29 | executor.ResourceModule.QueryInstanceStatusInCell(poolName, cellName, respChan) 30 | }else{ 31 | //log.Printf("[%08X] request query instance status in pool '%s' from %s.[%08X]", id, poolName, 32 | // request.GetSender(), request.GetFromSession()) 33 | executor.ResourceModule.QueryInstanceStatusInPool(poolName, respChan) 34 | } 35 | result := <- respChan 36 | 37 | resp, _ := framework.CreateJsonMessage(framework.QueryInstanceStatusResponse) 38 | resp.SetToSession(request.GetFromSession()) 39 | resp.SetFromSession(id) 40 | resp.SetSuccess(false) 41 | if result.Error != nil{ 42 | err = result.Error 43 | log.Printf("[%08X] query instance status fail: %s", id, err.Error()) 44 | resp.SetError(err.Error()) 45 | return executor.Sender.SendMessage(resp, request.GetSender()) 46 | } 47 | 48 | var instances = result.InstanceList 49 | modules.MarshalInstanceStatusListToMessage(instances, resp) 50 | resp.SetSuccess(true) 51 | //log.Printf("[%08X] %d instance(s) available", id, len(instances)) 52 | return executor.Sender.SendMessage(resp, request.GetSender()) 53 | } 54 | -------------------------------------------------------------------------------- /src/task/query_address_range.go: -------------------------------------------------------------------------------- 1 | package task 2 | 3 | import ( 4 | "log" 5 | "github.com/project-nano/framework" 6 | "github.com/project-nano/core/modules" 7 | ) 8 | 9 | type QueryAddressRangeExecutor struct { 10 | Sender framework.MessageSender 11 | ResourceModule modules.ResourceModule 12 | } 13 | 14 | 15 | func (executor *QueryAddressRangeExecutor)Execute(id framework.SessionID, request framework.Message, 16 | incoming chan framework.Message, terminate chan bool) (err error) { 17 | var poolName, rangeType string 18 | if poolName, err = request.GetString(framework.ParamKeyAddress); err != nil{ 19 | return 20 | } 21 | if rangeType, err = request.GetString(framework.ParamKeyType); err != nil{ 22 | return 23 | } 24 | var respChan = make(chan modules.ResourceResult, 1) 25 | executor.ResourceModule.QueryAddressRange(poolName, rangeType, respChan) 26 | resp, _ := framework.CreateJsonMessage(framework.QueryAddressRangeResponse) 27 | resp.SetFromSession(id) 28 | resp.SetToSession(request.GetFromSession()) 29 | resp.SetSuccess(false) 30 | 31 | var result = <- respChan 32 | if result.Error != nil{ 33 | err = result.Error 34 | resp.SetError(err.Error()) 35 | log.Printf("[%08X] query address range from %s.[%08X] fail: %s", 36 | id, request.GetSender(), request.GetFromSession(), err.Error()) 37 | return executor.Sender.SendMessage(resp, request.GetSender()) 38 | } 39 | var startArray, endArray, maskArray []string 40 | for _, status := range result.AddressRangeList { 41 | startArray = append(startArray, status.Start) 42 | endArray = append(endArray, status.End) 43 | maskArray = append(maskArray, status.Netmask) 44 | } 45 | resp.SetSuccess(true) 46 | resp.SetStringArray(framework.ParamKeyStart, startArray) 47 | resp.SetStringArray(framework.ParamKeyEnd, endArray) 48 | resp.SetStringArray(framework.ParamKeyMask, maskArray) 49 | log.Printf("[%08X] reply %d address range(s) to %s.[%08X]", 50 | id, len(result.AddressRangeList), request.GetSender(), request.GetFromSession()) 51 | return executor.Sender.SendMessage(resp, request.GetSender()) 52 | } -------------------------------------------------------------------------------- /src/task/query_cell_storage_paths.go: -------------------------------------------------------------------------------- 1 | package task 2 | 3 | import ( 4 | "errors" 5 | "fmt" 6 | "github.com/project-nano/core/modules" 7 | "github.com/project-nano/framework" 8 | "log" 9 | "time" 10 | ) 11 | 12 | type QueryStoragePathsExecutor struct { 13 | Sender framework.MessageSender 14 | ResourceModule modules.ResourceModule 15 | } 16 | 17 | func (executor *QueryStoragePathsExecutor) Execute(id framework.SessionID, request framework.Message, 18 | incoming chan framework.Message, terminate chan bool) (err error) { 19 | var targetCell string 20 | if targetCell, err = request.GetString(framework.ParamKeyCell); err != nil { 21 | err = fmt.Errorf("get target cell fail: %s", err.Error()) 22 | return 23 | } 24 | resp, _ := framework.CreateJsonMessage(framework.QueryCellStorageResponse) 25 | resp.SetToSession(request.GetFromSession()) 26 | resp.SetFromSession(id) 27 | resp.SetSuccess(false) 28 | 29 | var fromSession = request.GetFromSession() 30 | { 31 | //redirect request 32 | request.SetFromSession(id) 33 | if err = executor.Sender.SendMessage(request, targetCell); err != nil { 34 | log.Printf("[%08X] redirect query storage request to cell '%s' fail: %s", id, targetCell, err.Error()) 35 | resp.SetError(err.Error()) 36 | return executor.Sender.SendMessage(resp, request.GetSender()) 37 | } 38 | timer := time.NewTimer(modules.GetConfigurator().GetOperateTimeout()) 39 | select { 40 | case cellResp := <-incoming: 41 | if !cellResp.IsSuccess() { 42 | err = errors.New(cellResp.GetError()) 43 | log.Printf("[%08X] cell query storage paths fail: %s", id, cellResp.GetError()) 44 | } else { 45 | cellResp.SetSuccess(true) 46 | } 47 | cellResp.SetFromSession(id) 48 | cellResp.SetToSession(fromSession) 49 | //forward 50 | return executor.Sender.SendMessage(cellResp, request.GetSender()) 51 | case <-timer.C: 52 | //timeout 53 | log.Printf("[%08X] wait query response timeout", id) 54 | resp.SetError("cell timeout") 55 | return executor.Sender.SendMessage(resp, request.GetSender()) 56 | } 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /src/task/create_compute_pool.go: -------------------------------------------------------------------------------- 1 | package task 2 | 3 | import ( 4 | "github.com/project-nano/framework" 5 | "github.com/project-nano/core/modules" 6 | "log" 7 | "fmt" 8 | ) 9 | 10 | type CreateComputePoolExecutor struct { 11 | Sender framework.MessageSender 12 | ResourceModule modules.ResourceModule 13 | } 14 | 15 | func (executor *CreateComputePoolExecutor)Execute(id framework.SessionID, request framework.Message, 16 | incoming chan framework.Message, terminate chan bool) error { 17 | pool, err := request.GetString(framework.ParamKeyPool) 18 | if err != nil{ 19 | return err 20 | } 21 | storagePool, _ := request.GetString(framework.ParamKeyStorage) 22 | if "" == storagePool{ 23 | log.Printf("[%08X] request create compute pool '%s' using local storage from %s.[%08X]", id, pool, request.GetSender(), request.GetFromSession()) 24 | }else{ 25 | log.Printf("[%08X] request create compute pool '%s' using storage pool '%s' from %s.[%08X]", id, pool, storagePool, 26 | request.GetSender(), request.GetFromSession()) 27 | } 28 | addressPool, _ := request.GetString(framework.ParamKeyNetwork) 29 | var failover = false 30 | failover, _ = request.GetBoolean(framework.ParamKeyOption) 31 | 32 | resp, _ := framework.CreateJsonMessage(framework.CreateComputePoolResponse) 33 | resp.SetSuccess(false) 34 | resp.SetFromSession(id) 35 | resp.SetToSession(request.GetFromSession()) 36 | 37 | if err = QualifyNormalName(pool); err != nil{ 38 | log.Printf("[%08X] invalid pool name '%s' : %s", id, pool, err.Error()) 39 | err = fmt.Errorf("invalid pool name '%s': %s", pool, err.Error()) 40 | resp.SetError(err.Error()) 41 | return executor.Sender.SendMessage(resp, request.GetSender()) 42 | } 43 | 44 | var respChan= make(chan error) 45 | executor.ResourceModule.CreatePool(pool, storagePool, addressPool, failover, respChan) 46 | err = <-respChan 47 | if err != nil{ 48 | resp.SetError(err.Error()) 49 | log.Printf("[%08X] create compute pool fail: %s", id, err.Error()) 50 | }else{ 51 | resp.SetSuccess(true) 52 | } 53 | 54 | return executor.Sender.SendMessage(resp, request.GetSender()) 55 | } -------------------------------------------------------------------------------- /src/task/get_system_template.go: -------------------------------------------------------------------------------- 1 | package task 2 | 3 | import ( 4 | "fmt" 5 | "github.com/project-nano/core/modules" 6 | "github.com/project-nano/framework" 7 | "log" 8 | ) 9 | 10 | type GetSystemTemplateExecutor struct { 11 | Sender framework.MessageSender 12 | ResourceModule modules.ResourceModule 13 | } 14 | 15 | func (executor *GetSystemTemplateExecutor)Execute(id framework.SessionID, request framework.Message, 16 | incoming chan framework.Message, terminate chan bool) (err error){ 17 | var templateID string 18 | if templateID, err = request.GetString(framework.ParamKeyTemplate); err != nil{ 19 | err = fmt.Errorf("get template id fail: %s", err.Error()) 20 | return 21 | } 22 | var respChan = make(chan modules.ResourceResult, 1) 23 | executor.ResourceModule.GetSystemTemplate(templateID, respChan) 24 | var result = <- respChan 25 | 26 | resp, _ := framework.CreateJsonMessage(framework.GetTemplateResponse) 27 | resp.SetSuccess(false) 28 | resp.SetFromSession(id) 29 | resp.SetToSession(request.GetFromSession()) 30 | 31 | if result.Error != nil{ 32 | err = result.Error 33 | resp.SetError(err.Error()) 34 | log.Printf("[%08X] handle get system template from %s.[%08X] fail: %s", 35 | id, request.GetSender(), request.GetFromSession(), err.Error()) 36 | }else{ 37 | var t = result.Template 38 | resp.SetSuccess(true) 39 | resp.SetString(framework.ParamKeyID, t.ID) 40 | resp.SetString(framework.ParamKeyName, t.Name) 41 | resp.SetString(framework.ParamKeyAdmin, t.Admin) 42 | resp.SetString(framework.ParamKeySystem, t.OperatingSystem) 43 | resp.SetString(framework.ParamKeyDisk, t.Disk) 44 | resp.SetString(framework.ParamKeyNetwork, t.Network) 45 | resp.SetString(framework.ParamKeyDisplay, t.Display) 46 | resp.SetString(framework.ParamKeyMonitor, t.Control) 47 | resp.SetString(framework.ParamKeyDevice, t.USB) 48 | resp.SetString(framework.ParamKeyInterface, t.Tablet) 49 | resp.SetString(framework.ParamKeyCreate, t.CreatedTime) 50 | resp.SetString(framework.ParamKeyModify, t.ModifiedTime) 51 | } 52 | return executor.Sender.SendMessage(resp, request.GetSender()) 53 | } 54 | -------------------------------------------------------------------------------- /src/task/modify_compute_pool.go: -------------------------------------------------------------------------------- 1 | package task 2 | 3 | import ( 4 | "github.com/project-nano/framework" 5 | "github.com/project-nano/core/modules" 6 | "log" 7 | "fmt" 8 | ) 9 | 10 | type ModifyComputePoolExecutor struct { 11 | Sender framework.MessageSender 12 | ResourceModule modules.ResourceModule 13 | } 14 | 15 | func (executor *ModifyComputePoolExecutor)Execute(id framework.SessionID, request framework.Message, 16 | incoming chan framework.Message, terminate chan bool) error { 17 | pool, err := request.GetString(framework.ParamKeyPool) 18 | if err != nil{ 19 | return err 20 | } 21 | storagePool, _ := request.GetString(framework.ParamKeyStorage) 22 | if "" == storagePool{ 23 | log.Printf("[%08X] request modify compute pool '%s' using local storage from %s.[%08X]", id, pool, request.GetSender(), request.GetFromSession()) 24 | }else{ 25 | log.Printf("[%08X] request modify compute pool '%s' using storage pool '%s' from %s.[%08X]", id, pool, storagePool, 26 | request.GetSender(), request.GetFromSession()) 27 | } 28 | addressPool, _ := request.GetString(framework.ParamKeyNetwork) 29 | var failover = false 30 | failover, _ = request.GetBoolean(framework.ParamKeyOption) 31 | 32 | 33 | resp, _ := framework.CreateJsonMessage(framework.ModifyComputePoolResponse) 34 | resp.SetSuccess(false) 35 | resp.SetFromSession(id) 36 | resp.SetToSession(request.GetFromSession()) 37 | 38 | if err = QualifyNormalName(pool); err != nil{ 39 | log.Printf("[%08X] invalid pool name '%s' : %s", id, pool, err.Error()) 40 | err = fmt.Errorf("invalid pool name '%s': %s", pool, err.Error()) 41 | resp.SetError(err.Error()) 42 | return executor.Sender.SendMessage(resp, request.GetSender()) 43 | } 44 | 45 | var respChan= make(chan error) 46 | executor.ResourceModule.ModifyPool(pool, storagePool, addressPool, failover, respChan) 47 | err = <-respChan 48 | if err != nil{ 49 | resp.SetError(err.Error()) 50 | log.Printf("[%08X] modify compute pool fail: %s", id, err.Error()) 51 | }else{ 52 | resp.SetSuccess(true) 53 | } 54 | 55 | return executor.Sender.SendMessage(resp, request.GetSender()) 56 | } 57 | -------------------------------------------------------------------------------- /src/task/handle_instance_migrated.go: -------------------------------------------------------------------------------- 1 | package task 2 | 3 | import ( 4 | "github.com/project-nano/framework" 5 | "github.com/project-nano/core/modules" 6 | "log" 7 | ) 8 | 9 | type HandleInstanceMigratedExecutor struct { 10 | Sender framework.MessageSender 11 | ResourceModule modules.ResourceModule 12 | } 13 | 14 | func (executor *HandleInstanceMigratedExecutor)Execute(id framework.SessionID, request framework.Message, 15 | incoming chan framework.Message, terminate chan bool) (err error){ 16 | var failover = false 17 | var migrationID string 18 | var instances []string 19 | var monitorPorts []uint64 20 | failover, err = request.GetBoolean(framework.ParamKeyImmediate) 21 | if err != nil{ 22 | return 23 | } 24 | if instances, err = request.GetStringArray(framework.ParamKeyInstance);err != nil{ 25 | return 26 | } 27 | if monitorPorts, err = request.GetUIntArray(framework.ParamKeyMonitor); err != nil{ 28 | return 29 | } 30 | if !failover{ 31 | //active migration 32 | migrationID, err = request.GetString(framework.ParamKeyMigration) 33 | if err != nil{ 34 | return 35 | } 36 | 37 | var respChan = make(chan error, 1) 38 | executor.ResourceModule.FinishMigration(migrationID, instances, monitorPorts, respChan) 39 | err = <- respChan 40 | if err != nil{ 41 | log.Printf("[%08X] finish migration fail: %s", id, err.Error()) 42 | }else{ 43 | log.Printf("[%08X] migration '%s' finished from %s.[%08X]", id, migrationID, request.GetSender(), request.GetFromSession()) 44 | } 45 | return nil 46 | }else{ 47 | //failover 48 | sourceCell, err := request.GetString(framework.ParamKeyCell) 49 | if err != nil{ 50 | return err 51 | } 52 | var respChan = make(chan error, 1) 53 | executor.ResourceModule.MigrateInstance(sourceCell, request.GetSender(), instances, monitorPorts, respChan) 54 | err = <- respChan 55 | if err != nil{ 56 | log.Printf("[%08X] migrate instance fail: %s", id, err.Error()) 57 | }else{ 58 | log.Printf("[%08X] %d instance(s) migrated from '%s' to '%s'", id, len(instances), sourceCell, request.GetSender()) 59 | } 60 | return nil 61 | } 62 | 63 | } -------------------------------------------------------------------------------- /src/task/get_batch_create_guest.go: -------------------------------------------------------------------------------- 1 | package task 2 | 3 | import ( 4 | "github.com/project-nano/core/modules" 5 | "log" 6 | "github.com/project-nano/framework" 7 | ) 8 | 9 | type GetBatchCreateGuestExecutor struct { 10 | Sender framework.MessageSender 11 | ResourceModule modules.ResourceModule 12 | } 13 | 14 | 15 | func (executor *GetBatchCreateGuestExecutor)Execute(id framework.SessionID, request framework.Message, 16 | incoming chan framework.Message, terminate chan bool) (err error) { 17 | var batchID string 18 | if batchID, err = request.GetString(framework.ParamKeyID);err != nil{ 19 | return err 20 | } 21 | resp, _ := framework.CreateJsonMessage(framework.GetBatchCreateGuestResponse) 22 | resp.SetFromSession(id) 23 | resp.SetToSession(request.GetFromSession()) 24 | resp.SetSuccess(false) 25 | 26 | var respChan = make(chan modules.ResourceResult, 1) 27 | executor.ResourceModule.GetBatchCreateGuestStatus(batchID, respChan) 28 | var result = <- respChan 29 | if result.Error != nil{ 30 | err = result.Error 31 | log.Printf("[%08X] get batch create status from %s.[%08X] fail: %s", id, request.GetSender(), request.GetFromSession(), err.Error()) 32 | resp.SetError(err.Error()) 33 | return executor.Sender.SendMessage(resp, request.GetSender()) 34 | } 35 | 36 | var guestStatus, createProgress []uint64 37 | var guestID, guestName, deleteError []string 38 | 39 | for _, status := range result.BatchCreate{ 40 | guestStatus = append(guestStatus, uint64(status.Status)) 41 | createProgress = append(createProgress, uint64(status.Progress)) 42 | guestID = append(guestID, status.ID) 43 | guestName = append(guestName, status.Name) 44 | deleteError = append(deleteError, status.Error) 45 | } 46 | resp.SetSuccess(true) 47 | resp.SetStringArray(framework.ParamKeyName, guestName) 48 | resp.SetStringArray(framework.ParamKeyGuest, guestID) 49 | resp.SetStringArray(framework.ParamKeyError, deleteError) 50 | resp.SetUIntArray(framework.ParamKeyStatus, guestStatus) 51 | resp.SetUIntArray(framework.ParamKeyProgress, createProgress) 52 | return executor.Sender.SendMessage(resp, request.GetSender()) 53 | } -------------------------------------------------------------------------------- /src/task/query_zone_status.go: -------------------------------------------------------------------------------- 1 | package task 2 | 3 | import ( 4 | "github.com/project-nano/framework" 5 | "github.com/project-nano/core/modules" 6 | "log" 7 | ) 8 | 9 | type QueryZoneStatusExecutor struct { 10 | Sender framework.MessageSender 11 | ResourceModule modules.ResourceModule 12 | } 13 | 14 | func (executor *QueryZoneStatusExecutor)Execute(id framework.SessionID, request framework.Message, 15 | incoming chan framework.Message, terminate chan bool) error { 16 | 17 | //log.Printf("[%08X] query zone status from %s.[%08X]", id, request.GetSender(), request.GetFromSession()) 18 | var respChan= make(chan modules.ResourceResult) 19 | 20 | executor.ResourceModule.QueryZoneStatus(respChan) 21 | result := <-respChan 22 | 23 | resp, _ := framework.CreateJsonMessage(framework.QueryZoneStatusResponse) 24 | resp.SetFromSession(id) 25 | resp.SetToSession(request.GetFromSession()) 26 | if result.Error != nil{ 27 | resp.SetSuccess(false) 28 | resp.SetError(result.Error.Error()) 29 | log.Printf("[%08X] get zone status fail: %s", id, result.Error.Error()) 30 | return executor.Sender.SendMessage(resp, request.GetSender()) 31 | } 32 | resp.SetSuccess(true) 33 | //assemble 34 | var s = result.Zone 35 | resp.SetString(framework.ParamKeyName, s.Name) 36 | resp.SetUIntArray(framework.ParamKeyPool, []uint64{s.DisabledPools, s.EnabledPools}) 37 | resp.SetUIntArray(framework.ParamKeyCell, []uint64{s.OfflineCells, s.OnlineCells}) 38 | resp.SetUIntArray(framework.ParamKeyInstance, []uint64{s.StoppedInstances, s.RunningInstances, s.LostInstances, s.MigratingInstances}) 39 | resp.SetFloat(framework.ParamKeyUsage, s.CpuUsage) 40 | resp.SetUInt(framework.ParamKeyCore, s.Cores) 41 | resp.SetUIntArray(framework.ParamKeyMemory, []uint64{s.MemoryAvailable, s.Memory}) 42 | resp.SetUIntArray(framework.ParamKeyDisk, []uint64{s.DiskAvailable, s.Disk}) 43 | resp.SetUIntArray(framework.ParamKeySpeed, []uint64{s.ReadSpeed, s.WriteSpeed, s.ReceiveSpeed, s.SendSpeed}) 44 | resp.SetString(framework.ParamKeyStart, s.StartTime.Format(modules.TimeFormatLayout)) 45 | 46 | return executor.Sender.SendMessage(resp, request.GetSender()) 47 | } 48 | -------------------------------------------------------------------------------- /src/task/get_compute_pool_status.go: -------------------------------------------------------------------------------- 1 | package task 2 | 3 | import ( 4 | "github.com/project-nano/framework" 5 | "github.com/project-nano/core/modules" 6 | "log" 7 | ) 8 | 9 | type GetComputePoolStatusExecutor struct { 10 | Sender framework.MessageSender 11 | ResourceModule modules.ResourceModule 12 | } 13 | 14 | func (executor *GetComputePoolStatusExecutor)Execute(id framework.SessionID, request framework.Message, 15 | incoming chan framework.Message, terminate chan bool) error { 16 | poolName, err := request.GetString(framework.ParamKeyPool) 17 | if err != nil{ 18 | return err 19 | } 20 | 21 | //log.Printf("[%08X] get compute pool '%s' status from %s.[%08X]", id, poolName, request.GetSender(), request.GetFromSession()) 22 | var respChan= make(chan modules.ResourceResult) 23 | 24 | executor.ResourceModule.GetComputePoolStatus(poolName, respChan) 25 | result := <-respChan 26 | 27 | resp, _ := framework.CreateJsonMessage(framework.GetComputePoolStatusResponse) 28 | resp.SetFromSession(id) 29 | resp.SetToSession(request.GetFromSession()) 30 | if result.Error != nil{ 31 | err = result.Error 32 | resp.SetSuccess(false) 33 | resp.SetError(err.Error()) 34 | log.Printf("[%08X] get compute pool status fail: %s", id, err.Error()) 35 | return executor.Sender.SendMessage(resp, request.GetSender()) 36 | } 37 | var s = result.ComputePool 38 | 39 | resp.SetSuccess(true) 40 | //assemble 41 | resp.SetString(framework.ParamKeyName, s.Name) 42 | resp.SetBoolean(framework.ParamKeyEnable, s.Enabled) 43 | resp.SetUIntArray(framework.ParamKeyCell, []uint64{s.OfflineCells, s.OnlineCells}) 44 | resp.SetUIntArray(framework.ParamKeyInstance, []uint64{s.StoppedInstances, s.RunningInstances, s.LostInstances, s.MigratingInstances}) 45 | resp.SetFloat(framework.ParamKeyUsage, s.CpuUsage) 46 | resp.SetUInt(framework.ParamKeyCore, s.Cores) 47 | resp.SetUIntArray(framework.ParamKeyMemory, []uint64{s.MemoryAvailable, s.Memory}) 48 | resp.SetUIntArray(framework.ParamKeyDisk, []uint64{s.DiskAvailable, s.Disk}) 49 | resp.SetUIntArray(framework.ParamKeySpeed, []uint64{s.ReadSpeed, s.WriteSpeed, s.ReceiveSpeed, s.SendSpeed}) 50 | 51 | return executor.Sender.SendMessage(resp, request.GetSender()) 52 | } 53 | 54 | -------------------------------------------------------------------------------- /src/task/get_disk_image.go: -------------------------------------------------------------------------------- 1 | package task 2 | 3 | import ( 4 | "github.com/project-nano/core/modules" 5 | "github.com/project-nano/framework" 6 | "log" 7 | "time" 8 | ) 9 | 10 | type GetDiskImageExecutor struct { 11 | Sender framework.MessageSender 12 | ResourceModule modules.ResourceModule 13 | } 14 | 15 | func (executor *GetDiskImageExecutor) Execute(id framework.SessionID, request framework.Message, 16 | incoming chan framework.Message, terminate chan bool) (err error) { 17 | 18 | var originSession = request.GetFromSession() 19 | var respChan = make(chan modules.ResourceResult, 1) 20 | executor.ResourceModule.GetImageServer(respChan) 21 | var result = <-respChan 22 | resp, _ := framework.CreateJsonMessage(framework.GetDiskImageResponse) 23 | resp.SetSuccess(false) 24 | resp.SetFromSession(id) 25 | resp.SetToSession(request.GetFromSession()) 26 | 27 | if result.Error != nil { 28 | err := result.Error 29 | log.Printf("[%08X] get image server fail: %s", id, err.Error()) 30 | resp.SetError(err.Error()) 31 | return executor.Sender.SendMessage(resp, request.GetSender()) 32 | } 33 | 34 | //forward to image server 35 | request.SetFromSession(id) 36 | request.SetToSession(0) 37 | var imageServer = result.Name 38 | 39 | if err = executor.Sender.SendMessage(request, imageServer); err != nil { 40 | log.Printf("[%08X] forward get disk to image server fail: %s", id, err.Error()) 41 | resp.SetError(err.Error()) 42 | return executor.Sender.SendMessage(resp, request.GetSender()) 43 | } 44 | //wait response 45 | timer := time.NewTimer(modules.GetConfigurator().GetOperateTimeout()) 46 | select { 47 | case forwardResp := <-incoming: 48 | if !forwardResp.IsSuccess() { 49 | log.Printf("[%08X] get disk image fail: %s", id, forwardResp.GetError()) 50 | } 51 | forwardResp.SetFromSession(id) 52 | forwardResp.SetToSession(originSession) 53 | forwardResp.SetTransactionID(request.GetTransactionID()) 54 | //forward 55 | return executor.Sender.SendMessage(forwardResp, request.GetSender()) 56 | 57 | case <-timer.C: 58 | //timeout 59 | log.Printf("[%08X] get disk image timeout", id) 60 | resp.SetError("time out") 61 | return executor.Sender.SendMessage(resp, request.GetSender()) 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /src/task/change_cell_storage_path.go: -------------------------------------------------------------------------------- 1 | package task 2 | 3 | import ( 4 | "errors" 5 | "fmt" 6 | "github.com/project-nano/core/modules" 7 | "github.com/project-nano/framework" 8 | "log" 9 | "time" 10 | ) 11 | 12 | type ChangeStoragePathsExecutor struct { 13 | Sender framework.MessageSender 14 | ResourceModule modules.ResourceModule 15 | } 16 | 17 | func (executor *ChangeStoragePathsExecutor) Execute(id framework.SessionID, request framework.Message, 18 | incoming chan framework.Message, terminate chan bool) (err error) { 19 | var targetCell string 20 | if targetCell, err = request.GetString(framework.ParamKeyCell); err != nil { 21 | err = fmt.Errorf("get target cell fail: %s", err.Error()) 22 | return 23 | } 24 | if _, err = request.GetString(framework.ParamKeyPath); err != nil { 25 | err = fmt.Errorf("get target path fail: %s", err.Error()) 26 | return 27 | } 28 | resp, _ := framework.CreateJsonMessage(framework.ModifyCellStorageResponse) 29 | resp.SetToSession(request.GetFromSession()) 30 | resp.SetFromSession(id) 31 | resp.SetSuccess(false) 32 | 33 | var fromSession = request.GetFromSession() 34 | { 35 | //redirect request 36 | request.SetFromSession(id) 37 | if err = executor.Sender.SendMessage(request, targetCell); err != nil { 38 | log.Printf("[%08X] redirect modify storage request to cell '%s' fail: %s", id, targetCell, err.Error()) 39 | resp.SetError(err.Error()) 40 | return executor.Sender.SendMessage(resp, request.GetSender()) 41 | } 42 | timer := time.NewTimer(modules.GetConfigurator().GetOperateTimeout()) 43 | select { 44 | case cellResp := <-incoming: 45 | if !cellResp.IsSuccess() { 46 | err = errors.New(cellResp.GetError()) 47 | log.Printf("[%08X] cell change storage paths fail: %s", id, cellResp.GetError()) 48 | } else { 49 | cellResp.SetSuccess(true) 50 | } 51 | cellResp.SetFromSession(id) 52 | cellResp.SetToSession(fromSession) 53 | //forward 54 | return executor.Sender.SendMessage(cellResp, request.GetSender()) 55 | case <-timer.C: 56 | //timeout 57 | log.Printf("[%08X] wait change response timeout", id) 58 | resp.SetError("cell timeout") 59 | return executor.Sender.SendMessage(resp, request.GetSender()) 60 | } 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /src/task/get_media_image.go: -------------------------------------------------------------------------------- 1 | package task 2 | 3 | import ( 4 | "github.com/project-nano/core/modules" 5 | "github.com/project-nano/framework" 6 | "log" 7 | "time" 8 | ) 9 | 10 | type GetMediaImageExecutor struct { 11 | Sender framework.MessageSender 12 | ResourceModule modules.ResourceModule 13 | } 14 | 15 | func (executor *GetMediaImageExecutor) Execute(id framework.SessionID, request framework.Message, 16 | incoming chan framework.Message, terminate chan bool) (err error) { 17 | 18 | var originSession = request.GetFromSession() 19 | var respChan = make(chan modules.ResourceResult, 1) 20 | executor.ResourceModule.GetImageServer(respChan) 21 | var result = <-respChan 22 | resp, _ := framework.CreateJsonMessage(framework.GetMediaImageResponse) 23 | resp.SetSuccess(false) 24 | resp.SetFromSession(id) 25 | resp.SetToSession(request.GetFromSession()) 26 | 27 | if result.Error != nil { 28 | err := result.Error 29 | log.Printf("[%08X] get image server fail: %s", id, err.Error()) 30 | resp.SetError(err.Error()) 31 | return executor.Sender.SendMessage(resp, request.GetSender()) 32 | } 33 | 34 | //forward to image server 35 | request.SetFromSession(id) 36 | request.SetToSession(0) 37 | var imageServer = result.Name 38 | 39 | if err = executor.Sender.SendMessage(request, imageServer); err != nil { 40 | log.Printf("[%08X] forward get media to image server fail: %s", id, err.Error()) 41 | resp.SetError(err.Error()) 42 | return executor.Sender.SendMessage(resp, request.GetSender()) 43 | } 44 | //wait response 45 | timer := time.NewTimer(modules.GetConfigurator().GetOperateTimeout()) 46 | select { 47 | case forwardResp := <-incoming: 48 | if !forwardResp.IsSuccess() { 49 | log.Printf("[%08X] get media image fail: %s", id, forwardResp.GetError()) 50 | } 51 | forwardResp.SetFromSession(id) 52 | forwardResp.SetToSession(originSession) 53 | forwardResp.SetTransactionID(request.GetTransactionID()) 54 | //forward 55 | return executor.Sender.SendMessage(forwardResp, request.GetSender()) 56 | 57 | case <-timer.C: 58 | //timeout 59 | log.Printf("[%08X] get media image timeout", id) 60 | resp.SetError("time out") 61 | return executor.Sender.SendMessage(resp, request.GetSender()) 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /src/task/delete_disk_image.go: -------------------------------------------------------------------------------- 1 | package task 2 | 3 | import ( 4 | "github.com/project-nano/core/modules" 5 | "github.com/project-nano/framework" 6 | "log" 7 | "time" 8 | ) 9 | 10 | type DeleteDiskImageExecutor struct { 11 | Sender framework.MessageSender 12 | ResourceModule modules.ResourceModule 13 | } 14 | 15 | func (executor *DeleteDiskImageExecutor) Execute(id framework.SessionID, request framework.Message, 16 | incoming chan framework.Message, terminate chan bool) (err error) { 17 | 18 | var originSession = request.GetFromSession() 19 | var respChan = make(chan modules.ResourceResult, 1) 20 | executor.ResourceModule.GetImageServer(respChan) 21 | var result = <-respChan 22 | resp, _ := framework.CreateJsonMessage(framework.DeleteDiskImageResponse) 23 | resp.SetSuccess(false) 24 | resp.SetFromSession(id) 25 | resp.SetToSession(request.GetFromSession()) 26 | 27 | if result.Error != nil { 28 | err := result.Error 29 | log.Printf("[%08X] get image server fail: %s", id, err.Error()) 30 | resp.SetError(err.Error()) 31 | return executor.Sender.SendMessage(resp, request.GetSender()) 32 | } 33 | 34 | //forward to image server 35 | request.SetFromSession(id) 36 | request.SetToSession(0) 37 | var imageServer = result.Name 38 | 39 | if err = executor.Sender.SendMessage(request, imageServer); err != nil { 40 | log.Printf("[%08X] forward delete disk to image server fail: %s", id, err.Error()) 41 | resp.SetError(err.Error()) 42 | return executor.Sender.SendMessage(resp, request.GetSender()) 43 | } 44 | //wait response 45 | timer := time.NewTimer(modules.GetConfigurator().GetOperateTimeout()) 46 | select { 47 | case forwardResp := <-incoming: 48 | if !forwardResp.IsSuccess() { 49 | log.Printf("[%08X] delete disk image fail: %s", id, forwardResp.GetError()) 50 | } 51 | forwardResp.SetFromSession(id) 52 | forwardResp.SetToSession(originSession) 53 | forwardResp.SetTransactionID(request.GetTransactionID()) 54 | //forward 55 | return executor.Sender.SendMessage(forwardResp, request.GetSender()) 56 | 57 | case <-timer.C: 58 | //timeout 59 | log.Printf("[%08X] delete disk image timeout", id) 60 | resp.SetError("time out") 61 | return executor.Sender.SendMessage(resp, request.GetSender()) 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /src/task/modify_disk_image.go: -------------------------------------------------------------------------------- 1 | package task 2 | 3 | import ( 4 | "github.com/project-nano/core/modules" 5 | "github.com/project-nano/framework" 6 | "log" 7 | "time" 8 | ) 9 | 10 | type ModifyDiskImageExecutor struct { 11 | Sender framework.MessageSender 12 | ResourceModule modules.ResourceModule 13 | } 14 | 15 | func (executor *ModifyDiskImageExecutor) Execute(id framework.SessionID, request framework.Message, 16 | incoming chan framework.Message, terminate chan bool) (err error) { 17 | 18 | var originSession = request.GetFromSession() 19 | var respChan = make(chan modules.ResourceResult, 1) 20 | executor.ResourceModule.GetImageServer(respChan) 21 | var result = <-respChan 22 | resp, _ := framework.CreateJsonMessage(framework.ModifyDiskImageResponse) 23 | resp.SetSuccess(false) 24 | resp.SetFromSession(id) 25 | resp.SetToSession(request.GetFromSession()) 26 | 27 | if result.Error != nil { 28 | err := result.Error 29 | log.Printf("[%08X] get image server fail: %s", id, err.Error()) 30 | resp.SetError(err.Error()) 31 | return executor.Sender.SendMessage(resp, request.GetSender()) 32 | } 33 | 34 | //forward to image server 35 | request.SetFromSession(id) 36 | request.SetToSession(0) 37 | var imageServer = result.Name 38 | 39 | if err = executor.Sender.SendMessage(request, imageServer); err != nil { 40 | log.Printf("[%08X] forward modify disk to image server fail: %s", id, err.Error()) 41 | resp.SetError(err.Error()) 42 | return executor.Sender.SendMessage(resp, request.GetSender()) 43 | } 44 | //wait response 45 | timer := time.NewTimer(modules.GetConfigurator().GetOperateTimeout()) 46 | select { 47 | case forwardResp := <-incoming: 48 | if !forwardResp.IsSuccess() { 49 | log.Printf("[%08X] modify disk image fail: %s", id, forwardResp.GetError()) 50 | } 51 | forwardResp.SetFromSession(id) 52 | forwardResp.SetToSession(originSession) 53 | forwardResp.SetTransactionID(request.GetTransactionID()) 54 | //forward 55 | return executor.Sender.SendMessage(forwardResp, request.GetSender()) 56 | 57 | case <-timer.C: 58 | //timeout 59 | log.Printf("[%08X] modify disk image timeout", id) 60 | resp.SetError("time out") 61 | return executor.Sender.SendMessage(resp, request.GetSender()) 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /src/task/query_disk_image.go: -------------------------------------------------------------------------------- 1 | package task 2 | 3 | import ( 4 | "github.com/project-nano/core/modules" 5 | "github.com/project-nano/framework" 6 | "log" 7 | "time" 8 | ) 9 | 10 | type QueryDiskImageExecutor struct { 11 | Sender framework.MessageSender 12 | ResourceModule modules.ResourceModule 13 | } 14 | 15 | func (executor *QueryDiskImageExecutor) Execute(id framework.SessionID, request framework.Message, 16 | incoming chan framework.Message, terminate chan bool) (err error) { 17 | 18 | var originSession = request.GetFromSession() 19 | var respChan = make(chan modules.ResourceResult, 1) 20 | executor.ResourceModule.GetImageServer(respChan) 21 | var result = <-respChan 22 | resp, _ := framework.CreateJsonMessage(framework.QueryDiskImageResponse) 23 | resp.SetSuccess(false) 24 | resp.SetFromSession(id) 25 | resp.SetToSession(request.GetFromSession()) 26 | 27 | if result.Error != nil { 28 | err := result.Error 29 | log.Printf("[%08X] get image server fail: %s", id, err.Error()) 30 | resp.SetError(err.Error()) 31 | return executor.Sender.SendMessage(resp, request.GetSender()) 32 | } 33 | 34 | //forward to image server 35 | request.SetFromSession(id) 36 | request.SetToSession(0) 37 | var imageServer = result.Name 38 | 39 | if err = executor.Sender.SendMessage(request, imageServer); err != nil { 40 | log.Printf("[%08X] forward query disk to image server fail: %s", id, err.Error()) 41 | resp.SetError(err.Error()) 42 | return executor.Sender.SendMessage(resp, request.GetSender()) 43 | } 44 | //wait response 45 | timer := time.NewTimer(modules.GetConfigurator().GetOperateTimeout()) 46 | select { 47 | case forwardResp := <-incoming: 48 | if !forwardResp.IsSuccess() { 49 | log.Printf("[%08X] query disk image fail: %s", id, forwardResp.GetError()) 50 | } 51 | forwardResp.SetFromSession(id) 52 | forwardResp.SetToSession(originSession) 53 | forwardResp.SetTransactionID(request.GetTransactionID()) 54 | //forward 55 | return executor.Sender.SendMessage(forwardResp, request.GetSender()) 56 | 57 | case <-timer.C: 58 | //timeout 59 | log.Printf("[%08X] query disk image timeout", id) 60 | resp.SetError("time out") 61 | return executor.Sender.SendMessage(resp, request.GetSender()) 62 | } 63 | 64 | } 65 | -------------------------------------------------------------------------------- /src/task/query_media_image.go: -------------------------------------------------------------------------------- 1 | package task 2 | 3 | import ( 4 | "github.com/project-nano/core/modules" 5 | "github.com/project-nano/framework" 6 | "log" 7 | "time" 8 | ) 9 | 10 | type QueryMediaImageExecutor struct { 11 | Sender framework.MessageSender 12 | ResourceModule modules.ResourceModule 13 | } 14 | 15 | func (executor *QueryMediaImageExecutor) Execute(id framework.SessionID, request framework.Message, 16 | incoming chan framework.Message, terminate chan bool) (err error) { 17 | 18 | var originSession = request.GetFromSession() 19 | var respChan = make(chan modules.ResourceResult, 1) 20 | executor.ResourceModule.GetImageServer(respChan) 21 | var result = <-respChan 22 | resp, _ := framework.CreateJsonMessage(framework.QueryMediaImageResponse) 23 | resp.SetSuccess(false) 24 | resp.SetFromSession(id) 25 | resp.SetToSession(request.GetFromSession()) 26 | 27 | if result.Error != nil { 28 | err := result.Error 29 | log.Printf("[%08X] get image server fail: %s", id, err.Error()) 30 | resp.SetError(err.Error()) 31 | return executor.Sender.SendMessage(resp, request.GetSender()) 32 | } 33 | 34 | //forward to image server 35 | request.SetFromSession(id) 36 | request.SetToSession(0) 37 | var imageServer = result.Name 38 | 39 | if err = executor.Sender.SendMessage(request, imageServer); err != nil { 40 | log.Printf("[%08X] forward query media to image server fail: %s", id, err.Error()) 41 | resp.SetError(err.Error()) 42 | return executor.Sender.SendMessage(resp, request.GetSender()) 43 | } 44 | //wait response 45 | timer := time.NewTimer(modules.GetConfigurator().GetOperateTimeout()) 46 | select { 47 | case forwardResp := <-incoming: 48 | if !forwardResp.IsSuccess() { 49 | log.Printf("[%08X] query media image fail: %s", id, forwardResp.GetError()) 50 | } 51 | forwardResp.SetFromSession(id) 52 | forwardResp.SetToSession(originSession) 53 | forwardResp.SetTransactionID(request.GetTransactionID()) 54 | //forward 55 | return executor.Sender.SendMessage(forwardResp, request.GetSender()) 56 | 57 | case <-timer.C: 58 | //timeout 59 | log.Printf("[%08X] query media image timeout", id) 60 | resp.SetError("time out") 61 | return executor.Sender.SendMessage(resp, request.GetSender()) 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /src/task/create_media_image.go: -------------------------------------------------------------------------------- 1 | package task 2 | 3 | import ( 4 | "github.com/project-nano/core/modules" 5 | "github.com/project-nano/framework" 6 | "log" 7 | "time" 8 | ) 9 | 10 | type CreateMediaImageExecutor struct { 11 | Sender framework.MessageSender 12 | ResourceModule modules.ResourceModule 13 | } 14 | 15 | func (executor *CreateMediaImageExecutor) Execute(id framework.SessionID, request framework.Message, 16 | incoming chan framework.Message, terminate chan bool) (err error) { 17 | 18 | var originSession = request.GetFromSession() 19 | var respChan = make(chan modules.ResourceResult, 1) 20 | executor.ResourceModule.GetImageServer(respChan) 21 | var result = <-respChan 22 | resp, _ := framework.CreateJsonMessage(framework.CreateMediaImageResponse) 23 | resp.SetSuccess(false) 24 | resp.SetFromSession(id) 25 | resp.SetToSession(request.GetFromSession()) 26 | 27 | if result.Error != nil { 28 | err := result.Error 29 | log.Printf("[%08X] get image server fail: %s", id, err.Error()) 30 | resp.SetError(err.Error()) 31 | return executor.Sender.SendMessage(resp, request.GetSender()) 32 | } 33 | 34 | //forward to image server 35 | request.SetFromSession(id) 36 | request.SetToSession(0) 37 | var imageServer = result.Name 38 | 39 | if err = executor.Sender.SendMessage(request, imageServer); err != nil { 40 | log.Printf("[%08X] forward create media to image server fail: %s", id, err.Error()) 41 | resp.SetError(err.Error()) 42 | return executor.Sender.SendMessage(resp, request.GetSender()) 43 | } 44 | //wait response 45 | timer := time.NewTimer(modules.GetConfigurator().GetOperateTimeout()) 46 | select { 47 | case forwardResp := <-incoming: 48 | if !forwardResp.IsSuccess() { 49 | log.Printf("[%08X] create media image fail: %s", id, forwardResp.GetError()) 50 | } 51 | forwardResp.SetFromSession(id) 52 | forwardResp.SetToSession(originSession) 53 | forwardResp.SetTransactionID(request.GetTransactionID()) 54 | //forward 55 | return executor.Sender.SendMessage(forwardResp, request.GetSender()) 56 | 57 | case <-timer.C: 58 | //timeout 59 | log.Printf("[%08X] create media image timeout", id) 60 | resp.SetError("time out") 61 | return executor.Sender.SendMessage(resp, request.GetSender()) 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /src/task/delete_media_image.go: -------------------------------------------------------------------------------- 1 | package task 2 | 3 | import ( 4 | "github.com/project-nano/core/modules" 5 | "github.com/project-nano/framework" 6 | "log" 7 | "time" 8 | ) 9 | 10 | type DeleteMediaImageExecutor struct { 11 | Sender framework.MessageSender 12 | ResourceModule modules.ResourceModule 13 | } 14 | 15 | func (executor *DeleteMediaImageExecutor) Execute(id framework.SessionID, request framework.Message, 16 | incoming chan framework.Message, terminate chan bool) (err error) { 17 | 18 | var originSession = request.GetFromSession() 19 | var respChan = make(chan modules.ResourceResult, 1) 20 | executor.ResourceModule.GetImageServer(respChan) 21 | var result = <-respChan 22 | resp, _ := framework.CreateJsonMessage(framework.DeleteMediaImageResponse) 23 | resp.SetSuccess(false) 24 | resp.SetFromSession(id) 25 | resp.SetToSession(request.GetFromSession()) 26 | 27 | if result.Error != nil { 28 | err := result.Error 29 | log.Printf("[%08X] get image server fail: %s", id, err.Error()) 30 | resp.SetError(err.Error()) 31 | return executor.Sender.SendMessage(resp, request.GetSender()) 32 | } 33 | 34 | //forward to image server 35 | request.SetFromSession(id) 36 | request.SetToSession(0) 37 | var imageServer = result.Name 38 | 39 | if err = executor.Sender.SendMessage(request, imageServer); err != nil { 40 | log.Printf("[%08X] forward delete media to image server fail: %s", id, err.Error()) 41 | resp.SetError(err.Error()) 42 | return executor.Sender.SendMessage(resp, request.GetSender()) 43 | } 44 | //wait response 45 | timer := time.NewTimer(modules.GetConfigurator().GetOperateTimeout()) 46 | select { 47 | case forwardResp := <-incoming: 48 | if !forwardResp.IsSuccess() { 49 | log.Printf("[%08X] delete media image fail: %s", id, forwardResp.GetError()) 50 | } 51 | forwardResp.SetFromSession(id) 52 | forwardResp.SetToSession(originSession) 53 | forwardResp.SetTransactionID(request.GetTransactionID()) 54 | //forward 55 | return executor.Sender.SendMessage(forwardResp, request.GetSender()) 56 | 57 | case <-timer.C: 58 | //timeout 59 | log.Printf("[%08X] delete media image timeout", id) 60 | resp.SetError("time out") 61 | return executor.Sender.SendMessage(resp, request.GetSender()) 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /src/task/modify_media_image.go: -------------------------------------------------------------------------------- 1 | package task 2 | 3 | import ( 4 | "github.com/project-nano/core/modules" 5 | "github.com/project-nano/framework" 6 | "log" 7 | "time" 8 | ) 9 | 10 | type ModifyMediaImageExecutor struct { 11 | Sender framework.MessageSender 12 | ResourceModule modules.ResourceModule 13 | } 14 | 15 | func (executor *ModifyMediaImageExecutor) Execute(id framework.SessionID, request framework.Message, 16 | incoming chan framework.Message, terminate chan bool) (err error) { 17 | 18 | var originSession = request.GetFromSession() 19 | var respChan = make(chan modules.ResourceResult, 1) 20 | executor.ResourceModule.GetImageServer(respChan) 21 | var result = <-respChan 22 | resp, _ := framework.CreateJsonMessage(framework.ModifyMediaImageResponse) 23 | resp.SetSuccess(false) 24 | resp.SetFromSession(id) 25 | resp.SetToSession(request.GetFromSession()) 26 | 27 | if result.Error != nil { 28 | err := result.Error 29 | log.Printf("[%08X] get image server fail: %s", id, err.Error()) 30 | resp.SetError(err.Error()) 31 | return executor.Sender.SendMessage(resp, request.GetSender()) 32 | } 33 | 34 | //forward to image server 35 | request.SetFromSession(id) 36 | request.SetToSession(0) 37 | var imageServer = result.Name 38 | 39 | if err = executor.Sender.SendMessage(request, imageServer); err != nil { 40 | log.Printf("[%08X] forward modify media to image server fail: %s", id, err.Error()) 41 | resp.SetError(err.Error()) 42 | return executor.Sender.SendMessage(resp, request.GetSender()) 43 | } 44 | //wait response 45 | timer := time.NewTimer(modules.GetConfigurator().GetOperateTimeout()) 46 | select { 47 | case forwardResp := <-incoming: 48 | if !forwardResp.IsSuccess() { 49 | log.Printf("[%08X] modify media image fail: %s", id, forwardResp.GetError()) 50 | } 51 | forwardResp.SetFromSession(id) 52 | forwardResp.SetToSession(originSession) 53 | forwardResp.SetTransactionID(request.GetTransactionID()) 54 | //forward 55 | return executor.Sender.SendMessage(forwardResp, request.GetSender()) 56 | 57 | case <-timer.C: 58 | //timeout 59 | log.Printf("[%08X] modify media image timeout", id) 60 | resp.SetError("time out") 61 | return executor.Sender.SendMessage(resp, request.GetSender()) 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /src/task/sync_disk_images.go: -------------------------------------------------------------------------------- 1 | package task 2 | 3 | import ( 4 | "github.com/project-nano/core/modules" 5 | "github.com/project-nano/framework" 6 | "log" 7 | "time" 8 | ) 9 | 10 | type SyncDiskImagesExecutor struct { 11 | Sender framework.MessageSender 12 | ResourceModule modules.ResourceModule 13 | } 14 | 15 | func (executor *SyncDiskImagesExecutor) Execute(id framework.SessionID, request framework.Message, 16 | incoming chan framework.Message, terminate chan bool) (err error) { 17 | 18 | var originSession = request.GetFromSession() 19 | var respChan = make(chan modules.ResourceResult, 1) 20 | executor.ResourceModule.GetImageServer(respChan) 21 | var result = <-respChan 22 | resp, _ := framework.CreateJsonMessage(framework.SynchronizeDiskImageResponse) 23 | resp.SetSuccess(false) 24 | resp.SetFromSession(id) 25 | resp.SetToSession(request.GetFromSession()) 26 | 27 | if result.Error != nil { 28 | err = result.Error 29 | log.Printf("[%08X] get image server for sync disk images fail: %s", id, err.Error()) 30 | resp.SetError(err.Error()) 31 | return executor.Sender.SendMessage(resp, request.GetSender()) 32 | } 33 | 34 | //forward to image server 35 | request.SetFromSession(id) 36 | request.SetToSession(0) 37 | var imageServer = result.Name 38 | 39 | if err = executor.Sender.SendMessage(request, imageServer); err != nil { 40 | log.Printf("[%08X] forward sync disk images request fail: %s", id, err.Error()) 41 | resp.SetError(err.Error()) 42 | return executor.Sender.SendMessage(resp, request.GetSender()) 43 | } 44 | //wait response 45 | timer := time.NewTimer(modules.GetConfigurator().GetOperateTimeout()) 46 | select { 47 | case forwardResp := <-incoming: 48 | if !forwardResp.IsSuccess() { 49 | log.Printf("[%08X] sync disk images fail: %s", id, forwardResp.GetError()) 50 | } 51 | forwardResp.SetFromSession(id) 52 | forwardResp.SetToSession(originSession) 53 | forwardResp.SetTransactionID(request.GetTransactionID()) 54 | //forward 55 | return executor.Sender.SendMessage(forwardResp, request.GetSender()) 56 | 57 | case <-timer.C: 58 | //timeout 59 | log.Printf("[%08X] sync disk images timeout", id) 60 | resp.SetError("time out") 61 | return executor.Sender.SendMessage(resp, request.GetSender()) 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /src/task/sync_media_images.go: -------------------------------------------------------------------------------- 1 | package task 2 | 3 | import ( 4 | "github.com/project-nano/core/modules" 5 | "github.com/project-nano/framework" 6 | "log" 7 | "time" 8 | ) 9 | 10 | type SyncMediaImagesExecutor struct { 11 | Sender framework.MessageSender 12 | ResourceModule modules.ResourceModule 13 | } 14 | 15 | func (executor *SyncMediaImagesExecutor) Execute(id framework.SessionID, request framework.Message, 16 | incoming chan framework.Message, terminate chan bool) (err error) { 17 | 18 | var originSession = request.GetFromSession() 19 | var respChan = make(chan modules.ResourceResult, 1) 20 | executor.ResourceModule.GetImageServer(respChan) 21 | var result = <-respChan 22 | resp, _ := framework.CreateJsonMessage(framework.SynchronizeMediaImageResponse) 23 | resp.SetSuccess(false) 24 | resp.SetFromSession(id) 25 | resp.SetToSession(request.GetFromSession()) 26 | 27 | if result.Error != nil { 28 | err = result.Error 29 | log.Printf("[%08X] get image server for sync media images fail: %s", id, err.Error()) 30 | resp.SetError(err.Error()) 31 | return executor.Sender.SendMessage(resp, request.GetSender()) 32 | } 33 | 34 | //forward to image server 35 | request.SetFromSession(id) 36 | request.SetToSession(0) 37 | var imageServer = result.Name 38 | 39 | if err = executor.Sender.SendMessage(request, imageServer); err != nil { 40 | log.Printf("[%08X] forward sync media images request fail: %s", id, err.Error()) 41 | resp.SetError(err.Error()) 42 | return executor.Sender.SendMessage(resp, request.GetSender()) 43 | } 44 | //wait response 45 | timer := time.NewTimer(modules.GetConfigurator().GetOperateTimeout()) 46 | select { 47 | case forwardResp := <-incoming: 48 | if !forwardResp.IsSuccess() { 49 | log.Printf("[%08X] sync media images fail: %s", id, forwardResp.GetError()) 50 | } 51 | forwardResp.SetFromSession(id) 52 | forwardResp.SetToSession(originSession) 53 | forwardResp.SetTransactionID(request.GetTransactionID()) 54 | //forward 55 | return executor.Sender.SendMessage(forwardResp, request.GetSender()) 56 | 57 | case <-timer.C: 58 | //timeout 59 | log.Printf("[%08X] sync media images timeout", id) 60 | resp.SetError("time out") 61 | return executor.Sender.SendMessage(resp, request.GetSender()) 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /src/task/get_compute_cell_status.go: -------------------------------------------------------------------------------- 1 | package task 2 | 3 | import ( 4 | "github.com/project-nano/framework" 5 | "github.com/project-nano/core/modules" 6 | "log" 7 | ) 8 | 9 | type GetComputeCellStatusExecutor struct { 10 | Sender framework.MessageSender 11 | ResourceModule modules.ResourceModule 12 | } 13 | 14 | func (executor *GetComputeCellStatusExecutor)Execute(id framework.SessionID, request framework.Message, 15 | incoming chan framework.Message, terminate chan bool) error { 16 | poolName, err := request.GetString(framework.ParamKeyPool) 17 | if err != nil{ 18 | return err 19 | } 20 | cellName, err := request.GetString(framework.ParamKeyCell) 21 | if err != nil{ 22 | return err 23 | } 24 | 25 | //log.Printf("[%08X] get compute cell '%s' status from %s.[%08X]", id, cellName, request.GetSender(), request.GetFromSession()) 26 | var respChan= make(chan modules.ResourceResult) 27 | 28 | executor.ResourceModule.GetComputeCellStatus(poolName, cellName, respChan) 29 | result := <-respChan 30 | 31 | resp, _ := framework.CreateJsonMessage(framework.GetComputePoolCellStatusResponse) 32 | resp.SetFromSession(id) 33 | resp.SetToSession(request.GetFromSession()) 34 | if result.Error != nil{ 35 | err = result.Error 36 | resp.SetSuccess(false) 37 | resp.SetError(err.Error()) 38 | log.Printf("[%08X] get compute cell status fail: %s", id, err.Error()) 39 | return executor.Sender.SendMessage(resp, request.GetSender()) 40 | } 41 | var s = result.ComputeCell 42 | 43 | resp.SetSuccess(true) 44 | //assemble 45 | resp.SetString(framework.ParamKeyName, s.Name) 46 | resp.SetString(framework.ParamKeyAddress, s.Address) 47 | resp.SetBoolean(framework.ParamKeyEnable, s.Enabled) 48 | resp.SetBoolean(framework.ParamKeyStatus, s.Alive) 49 | resp.SetUIntArray(framework.ParamKeyInstance, []uint64{s.StoppedInstances, s.RunningInstances, s.LostInstances, s.MigratingInstances}) 50 | resp.SetFloat(framework.ParamKeyUsage, s.CpuUsage) 51 | resp.SetUInt(framework.ParamKeyCore, s.Cores) 52 | resp.SetUIntArray(framework.ParamKeyMemory, []uint64{s.MemoryAvailable, s.Memory}) 53 | resp.SetUIntArray(framework.ParamKeyDisk, []uint64{s.DiskAvailable, s.Disk}) 54 | resp.SetUIntArray(framework.ParamKeySpeed, []uint64{s.ReadSpeed, s.WriteSpeed, s.ReceiveSpeed, s.SendSpeed}) 55 | 56 | return executor.Sender.SendMessage(resp, request.GetSender()) 57 | } 58 | 59 | -------------------------------------------------------------------------------- /src/task/get_address_range.go: -------------------------------------------------------------------------------- 1 | package task 2 | 3 | import ( 4 | "github.com/project-nano/core/modules" 5 | "github.com/project-nano/framework" 6 | "log" 7 | ) 8 | 9 | type GetAddressRangeExecutor struct { 10 | Sender framework.MessageSender 11 | ResourceModule modules.ResourceModule 12 | } 13 | 14 | 15 | func (executor *GetAddressRangeExecutor)Execute(id framework.SessionID, request framework.Message, 16 | incoming chan framework.Message, terminate chan bool) (err error) { 17 | 18 | var poolName, rangeType, startAddress string 19 | if poolName, err = request.GetString(framework.ParamKeyAddress); err != nil{ 20 | return 21 | } 22 | if rangeType, err = request.GetString(framework.ParamKeyType); err != nil{ 23 | return 24 | } 25 | if startAddress, err = request.GetString(framework.ParamKeyStart); err != nil{ 26 | return 27 | } 28 | var respChan = make(chan modules.ResourceResult, 1) 29 | executor.ResourceModule.GetAddressRange(poolName, rangeType, startAddress, respChan) 30 | resp, _ := framework.CreateJsonMessage(framework.GetAddressRangeResponse) 31 | resp.SetFromSession(id) 32 | resp.SetToSession(request.GetFromSession()) 33 | resp.SetSuccess(false) 34 | 35 | var result = <- respChan 36 | if result.Error != nil{ 37 | err = result.Error 38 | resp.SetError(err.Error()) 39 | log.Printf("[%08X] request get address range from %s.[%08X] fail: %s", 40 | id, request.GetSender(), request.GetFromSession(), err.Error()) 41 | return executor.Sender.SendMessage(resp, request.GetSender()) 42 | } 43 | var status = result.AddressRange 44 | 45 | var addressArray, instanceArray []string 46 | for _, allocated := range status.Allocated{ 47 | addressArray = append(addressArray, allocated.Address) 48 | instanceArray = append(instanceArray, allocated.Instance) 49 | } 50 | 51 | resp.SetSuccess(true) 52 | resp.SetString(framework.ParamKeyStart, status.Start) 53 | resp.SetString(framework.ParamKeyEnd, status.End) 54 | resp.SetString(framework.ParamKeyMask, status.Netmask) 55 | resp.SetUInt(framework.ParamKeyCount, uint(status.Capacity)) 56 | resp.SetStringArray(framework.ParamKeyAddress, addressArray) 57 | resp.SetStringArray(framework.ParamKeyInstance, instanceArray) 58 | log.Printf("[%08X] reply status of address range '%s' to %s.[%08X]", 59 | id, startAddress, request.GetSender(), request.GetFromSession()) 60 | return executor.Sender.SendMessage(resp, request.GetSender()) 61 | } 62 | -------------------------------------------------------------------------------- /src/task/get_security_policy_rules.go: -------------------------------------------------------------------------------- 1 | package task 2 | 3 | import ( 4 | "fmt" 5 | "github.com/project-nano/core/modules" 6 | "github.com/project-nano/framework" 7 | "log" 8 | ) 9 | 10 | type GetSecurityPolicyRulesExecutor struct { 11 | Sender framework.MessageSender 12 | ResourceModule modules.ResourceModule 13 | } 14 | 15 | func (executor *GetSecurityPolicyRulesExecutor)Execute(id framework.SessionID, request framework.Message, 16 | incoming chan framework.Message, terminate chan bool) (err error) { 17 | var policyID string 18 | if policyID, err = request.GetString(framework.ParamKeyPolicy);err != nil{ 19 | err = fmt.Errorf("get policy group ID fail: %s", err.Error()) 20 | return 21 | } 22 | 23 | resp, _ := framework.CreateJsonMessage(framework.QueryPolicyRuleResponse) 24 | resp.SetToSession(request.GetFromSession()) 25 | resp.SetFromSession(id) 26 | resp.SetTransactionID(request.GetTransactionID()) 27 | resp.SetSuccess(false) 28 | var respChan = make(chan modules.ResourceResult, 1) 29 | executor.ResourceModule.GetSecurityPolicyRules(policyID, respChan) 30 | var result = <- respChan 31 | if result.Error != nil{ 32 | err = result.Error 33 | log.Printf("[%08X] get all rules of security policy '%s' fail: %s", 34 | id, policyID, err.Error()) 35 | resp.SetError(err.Error()) 36 | }else{ 37 | var actions, targetPorts []uint64 38 | var protocols, sourceAddresses, targetAddresses []string 39 | for _, rule := range result.PolicyRuleList{ 40 | if rule.Accept{ 41 | actions = append(actions, modules.PolicyRuleActionAccept) 42 | }else{ 43 | actions = append(actions, modules.PolicyRuleActionReject) 44 | } 45 | targetPorts = append(targetPorts, uint64(rule.TargetPort)) 46 | protocols = append(protocols, string(rule.Protocol)) 47 | targetAddresses = append(targetAddresses, rule.TargetAddress) 48 | sourceAddresses = append(sourceAddresses, rule.SourceAddress) 49 | } 50 | resp.SetUIntArray(framework.ParamKeyAction, actions) 51 | resp.SetUIntArray(framework.ParamKeyPort, targetPorts) 52 | resp.SetStringArray(framework.ParamKeyProtocol, protocols) 53 | resp.SetStringArray(framework.ParamKeyFrom, sourceAddresses) 54 | resp.SetStringArray(framework.ParamKeyTo, targetAddresses) 55 | log.Printf("[%08X] %d rules of security policy '%s' available", 56 | id, len(actions), policyID) 57 | resp.SetSuccess(true) 58 | } 59 | return executor.Sender.SendMessage(resp, request.GetSender()) 60 | } -------------------------------------------------------------------------------- /src/imageserver/handle_disk_image_update.go: -------------------------------------------------------------------------------- 1 | package imageserver 2 | 3 | import ( 4 | "github.com/project-nano/framework" 5 | "log" 6 | "errors" 7 | ) 8 | 9 | type DiskImageUpdateExecutor struct { 10 | Sender framework.MessageSender 11 | ImageServer *ImageManager 12 | } 13 | 14 | func (executor *DiskImageUpdateExecutor)Execute(id framework.SessionID, event framework.Message, 15 | incoming chan framework.Message, terminate chan bool) (err error) { 16 | imageID, err := event.GetString(framework.ParamKeyImage) 17 | if err != nil{ 18 | return 19 | } 20 | if !event.IsSuccess(){ 21 | err = errors.New(event.GetError()) 22 | log.Printf("[%08X] update disk image progress fail: %s", id, err.Error()) 23 | executor.releaseImage(id, imageID) 24 | return err 25 | } 26 | var created bool 27 | var progress uint 28 | if created, err = event.GetBoolean(framework.ParamKeyEnable);err != nil{ 29 | log.Printf("[%08X] parse created status from disk image updated fail: %s", id, err.Error()) 30 | executor.releaseImage(id, imageID) 31 | return err 32 | } 33 | if progress, err = event.GetUInt(framework.ParamKeyProgress);err != nil{ 34 | log.Printf("[%08X] parse progress from disk image updated fail: %s", id, err.Error()) 35 | executor.releaseImage(id, imageID) 36 | return err 37 | } 38 | if created{ 39 | //finished 40 | var imageSize uint 41 | if imageSize, err = event.GetUInt(framework.ParamKeySize); err != nil{ 42 | log.Printf("[%08X] parse image size from disk image updated fail: %s", id, err.Error()) 43 | executor.releaseImage(id, imageID) 44 | return err 45 | } 46 | log.Printf("[%08X] disk image creation finished, %d MB in size", id, imageSize >> 20) 47 | 48 | }else{ 49 | var respChan = make(chan error, 1) 50 | executor.ImageServer.UpdateDiskImageProgress(imageID, progress, respChan) 51 | err = <- respChan 52 | if err != nil{ 53 | log.Printf("[%08X] update disk image progress fail: %s", id, err.Error()) 54 | return err 55 | } 56 | //log.Printf("[%08X] progress %d %%", id, progress) 57 | } 58 | return nil 59 | } 60 | 61 | func (executor *DiskImageUpdateExecutor) releaseImage(id framework.SessionID, imageID string){ 62 | var respChan = make(chan error, 1) 63 | executor.ImageServer.DeleteDiskImage(imageID, respChan) 64 | var err = <- respChan 65 | if err != nil{ 66 | log.Printf("[%08X] delete disk image fail: %s", id, imageID) 67 | }else { 68 | log.Printf("[%08X] disk image '%s' deleted", id, imageID) 69 | } 70 | } -------------------------------------------------------------------------------- /src/task/handle_cell_disconnected.go: -------------------------------------------------------------------------------- 1 | package task 2 | 3 | import ( 4 | "github.com/project-nano/framework" 5 | "github.com/project-nano/core/modules" 6 | "log" 7 | ) 8 | 9 | type HandleCellDisconnectedExecutor struct { 10 | Sender framework.MessageSender 11 | ResourceModule modules.ResourceModule 12 | } 13 | 14 | func (executor *HandleCellDisconnectedExecutor)Execute(id framework.SessionID, request framework.Message, 15 | incoming chan framework.Message, terminate chan bool) (err error) { 16 | cellName, err := request.GetString(framework.ParamKeyCell) 17 | if err != nil { 18 | return 19 | } 20 | gracefullyClose, err := request.GetBoolean(framework.ParamKeyFlag) 21 | if err != nil{ 22 | return 23 | } 24 | if gracefullyClose{ 25 | var respChan = make(chan error, 1) 26 | executor.ResourceModule.SetCellDead(cellName, respChan) 27 | err = <- respChan 28 | if err != nil{ 29 | log.Printf("[%08X] set cell dead fail: %s", id, err.Error()) 30 | }else{ 31 | log.Printf("[%08X] remote cell '%s' closed", id, cellName) 32 | } 33 | return 34 | } 35 | var plan map[string][]string 36 | { 37 | var respChan = make(chan modules.ResourceResult, 1) 38 | executor.ResourceModule.BuildFailoverPlan(cellName, respChan) 39 | var result = <- respChan 40 | if result.Error != nil{ 41 | err = result.Error 42 | log.Printf("[%08X] handle cell '%s' disconnected fail: %s", id, cellName, err.Error()) 43 | return nil 44 | } 45 | if 0 == len(result.FailoverPlan){ 46 | //no plan need execute 47 | log.Printf("[%08X] cell '%s' lost", id, cellName) 48 | return nil 49 | } 50 | plan = result.FailoverPlan 51 | } 52 | var instanceCount = 0 53 | for targetName, instances := range plan{ 54 | migrate, _ := framework.CreateJsonMessage(framework.AttachInstanceRequest) 55 | migrate.SetStringArray(framework.ParamKeyInstance, instances) 56 | migrate.SetBoolean(framework.ParamKeyImmediate, true) 57 | migrate.SetString(framework.ParamKeyCell, cellName) 58 | if err = executor.Sender.SendMessage(migrate, targetName);err != nil{ 59 | log.Printf("[%08X] warning: send migrate request to '%s' fail: %s", id, targetName, err.Error()) 60 | }else{ 61 | log.Printf("[%08X] try migrate %d instances to cell '%s'", id, len(instances), targetName) 62 | } 63 | instanceCount += len(instances) 64 | } 65 | log.Printf("[%08X] %d instance(s) on cell '%s' dispatched to %d new cells by automated failover.", 66 | id, instanceCount, cellName, len(plan)) 67 | return nil 68 | } 69 | -------------------------------------------------------------------------------- /src/imageserver/query_media_image.go: -------------------------------------------------------------------------------- 1 | package imageserver 2 | 3 | import ( 4 | "github.com/project-nano/framework" 5 | "log" 6 | ) 7 | 8 | type QueryMediaImageExecutor struct { 9 | Sender framework.MessageSender 10 | ImageServer *ImageManager 11 | } 12 | 13 | 14 | func (executor *QueryMediaImageExecutor)Execute(id framework.SessionID, request framework.Message, 15 | incoming chan framework.Message, terminate chan bool) (err error) { 16 | var filterOwner, filterGroup string 17 | filterOwner, _ = request.GetString(framework.ParamKeyUser) 18 | filterGroup, _ = request.GetString(framework.ParamKeyGroup) 19 | 20 | var respChan = make(chan ImageResult, 1) 21 | executor.ImageServer.QueryMediaImage(filterOwner, filterGroup, respChan) 22 | 23 | var result = <- respChan 24 | 25 | resp, _ := framework.CreateJsonMessage(framework.QueryMediaImageResponse) 26 | resp.SetSuccess(false) 27 | resp.SetFromSession(id) 28 | resp.SetToSession(request.GetFromSession()) 29 | 30 | if result.Error != nil{ 31 | err = result.Error 32 | resp.SetError(err.Error()) 33 | log.Printf("[%08X] query media image fail: %s", id, err.Error()) 34 | return executor.Sender.SendMessage(resp, request.GetSender()) 35 | } 36 | 37 | var name, imageID, description, tags, createTime, modifyTime []string 38 | var size, tagCount[]uint64 39 | for _, image := range result.MediaList { 40 | name = append(name, image.Name) 41 | imageID = append(imageID, image.ID) 42 | description = append(description, image.Description) 43 | size = append(size, uint64(image.Size)) 44 | count := uint64(len(image.Tags)) 45 | tagCount = append(tagCount, count) 46 | for _, tag := range image.Tags{ 47 | tags = append(tags, tag) 48 | } 49 | createTime = append(createTime, image.CreateTime) 50 | modifyTime = append(modifyTime, image.ModifyTime) 51 | } 52 | 53 | resp.SetSuccess(true) 54 | resp.SetStringArray(framework.ParamKeyName, name) 55 | resp.SetStringArray(framework.ParamKeyImage, imageID) 56 | resp.SetStringArray(framework.ParamKeyDescription, description) 57 | resp.SetStringArray(framework.ParamKeyTag, tags) 58 | resp.SetStringArray(framework.ParamKeyCreate, createTime) 59 | resp.SetStringArray(framework.ParamKeyModify, modifyTime) 60 | 61 | resp.SetUIntArray(framework.ParamKeySize, size) 62 | resp.SetUIntArray(framework.ParamKeyCount, tagCount) 63 | //log.Printf("[%08X] query media image success, %d image(s) available", id, len(result.MediaList)) 64 | return executor.Sender.SendMessage(resp, request.GetSender()) 65 | 66 | } -------------------------------------------------------------------------------- /src/task/query_address_pool.go: -------------------------------------------------------------------------------- 1 | package task 2 | 3 | import ( 4 | "github.com/project-nano/framework" 5 | "github.com/project-nano/core/modules" 6 | "log" 7 | ) 8 | 9 | type QueryAddressPoolExecutor struct { 10 | Sender framework.MessageSender 11 | ResourceModule modules.ResourceModule 12 | } 13 | 14 | 15 | func (executor *QueryAddressPoolExecutor)Execute(id framework.SessionID, request framework.Message, 16 | incoming chan framework.Message, terminate chan bool) (err error) { 17 | var respChan = make(chan modules.ResourceResult, 1) 18 | executor.ResourceModule.QueryAddressPool(respChan) 19 | resp, _ := framework.CreateJsonMessage(framework.QueryAddressPoolResponse) 20 | resp.SetFromSession(id) 21 | resp.SetToSession(request.GetFromSession()) 22 | resp.SetSuccess(false) 23 | 24 | var result = <- respChan 25 | if result.Error != nil{ 26 | err = result.Error 27 | resp.SetError(err.Error()) 28 | log.Printf("[%08X] query address pool from %s.[%08X] fail: %s", 29 | id, request.GetSender(), request.GetFromSession(), err.Error()) 30 | return executor.Sender.SendMessage(resp, request.GetSender()) 31 | } 32 | var nameArray, gatewayArray, dnsArray, providerArray []string 33 | var addressArray, allocateArray, dnsCountArray []uint64 34 | for _, pool := range result.AddressPoolList { 35 | nameArray = append(nameArray, pool.Name) 36 | gatewayArray = append(gatewayArray, pool.Gateway) 37 | providerArray = append(providerArray, pool.Provider) 38 | var addressCount uint32 = 0 39 | allocateArray = append(allocateArray, uint64(len(pool.Allocated))) 40 | for _, addressRange := range pool.Ranges{ 41 | addressCount += addressRange.Capacity 42 | } 43 | addressArray = append(addressArray, uint64(addressCount)) 44 | dnsCountArray = append(dnsCountArray, uint64(len(pool.DNS))) 45 | dnsArray = append(dnsArray, pool.DNS...) 46 | } 47 | resp.SetSuccess(true) 48 | resp.SetStringArray(framework.ParamKeyName, nameArray) 49 | resp.SetStringArray(framework.ParamKeyGateway, gatewayArray) 50 | resp.SetStringArray(framework.ParamKeyServer, dnsArray) 51 | resp.SetStringArray(framework.ParamKeyMode, providerArray) 52 | resp.SetUIntArray(framework.ParamKeyAddress, addressArray) 53 | resp.SetUIntArray(framework.ParamKeyAllocate, allocateArray) 54 | resp.SetUIntArray(framework.ParamKeyCount, dnsCountArray) 55 | log.Printf("[%08X] reply %d address pool(s) to %s.[%08X]", 56 | id, len(result.AddressPoolList), request.GetSender(), request.GetFromSession()) 57 | return executor.Sender.SendMessage(resp, request.GetSender()) 58 | } 59 | 60 | -------------------------------------------------------------------------------- /src/task/get_auth.go: -------------------------------------------------------------------------------- 1 | package task 2 | 3 | import ( 4 | "github.com/project-nano/core/modules" 5 | "github.com/project-nano/framework" 6 | "log" 7 | "time" 8 | ) 9 | 10 | type GetGuestPasswordExecutor struct { 11 | Sender framework.MessageSender 12 | ResourceModule modules.ResourceModule 13 | } 14 | 15 | func (executor *GetGuestPasswordExecutor) Execute(id framework.SessionID, request framework.Message, 16 | incoming chan framework.Message, terminate chan bool) error { 17 | guestID, err := request.GetString(framework.ParamKeyGuest) 18 | if err != nil { 19 | return err 20 | } 21 | 22 | log.Printf("[%08X] request get password of '%s' from %s.[%08X]", id, guestID, 23 | request.GetSender(), request.GetFromSession()) 24 | 25 | var ins modules.InstanceStatus 26 | resp, _ := framework.CreateJsonMessage(framework.GetAuthResponse) 27 | resp.SetToSession(request.GetFromSession()) 28 | resp.SetFromSession(id) 29 | resp.SetSuccess(false) 30 | { 31 | var respChan = make(chan modules.ResourceResult) 32 | executor.ResourceModule.GetInstanceStatus(guestID, respChan) 33 | result := <-respChan 34 | if result.Error != nil { 35 | log.Printf("[%08X] fetch instance fail: %s", id, result.Error.Error()) 36 | resp.SetError(result.Error.Error()) 37 | return executor.Sender.SendMessage(resp, request.GetSender()) 38 | } 39 | ins = result.Instance 40 | } 41 | { 42 | //request delete 43 | forward, _ := framework.CreateJsonMessage(framework.GetAuthRequest) 44 | forward.SetFromSession(id) 45 | forward.SetString(framework.ParamKeyGuest, guestID) 46 | if err = executor.Sender.SendMessage(forward, ins.Cell); err != nil { 47 | log.Printf("[%08X] forward get password to cell '%s' fail: %s", id, ins.Cell, err.Error()) 48 | resp.SetError(err.Error()) 49 | return executor.Sender.SendMessage(resp, request.GetSender()) 50 | } 51 | timer := time.NewTimer(modules.GetConfigurator().GetOperateTimeout()) 52 | select { 53 | case cellResp := <-incoming: 54 | if cellResp.IsSuccess() { 55 | log.Printf("[%08X] get password success", id) 56 | } else { 57 | log.Printf("[%08X] get password fail: %s", id, cellResp.GetError()) 58 | } 59 | cellResp.SetFromSession(id) 60 | cellResp.SetToSession(request.GetFromSession()) 61 | //forward 62 | return executor.Sender.SendMessage(cellResp, request.GetSender()) 63 | case <-timer.C: 64 | //timeout 65 | log.Printf("[%08X] wait get password response timeout", id) 66 | resp.SetError("request timeout") 67 | return executor.Sender.SendMessage(resp, request.GetSender()) 68 | } 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /src/task/query_snapshot.go: -------------------------------------------------------------------------------- 1 | package task 2 | 3 | import ( 4 | "github.com/project-nano/core/modules" 5 | "github.com/project-nano/framework" 6 | "log" 7 | "time" 8 | ) 9 | 10 | type QuerySnapshotExecutor struct { 11 | Sender framework.MessageSender 12 | ResourceModule modules.ResourceModule 13 | } 14 | 15 | func (executor *QuerySnapshotExecutor) Execute(id framework.SessionID, request framework.Message, 16 | incoming chan framework.Message, terminate chan bool) error { 17 | instanceID, err := request.GetString(framework.ParamKeyInstance) 18 | if err != nil { 19 | return err 20 | } 21 | log.Printf("[%08X] request query snapshot of guest '%s' from %s.[%08X]", id, instanceID, 22 | request.GetSender(), request.GetFromSession()) 23 | 24 | var ins modules.InstanceStatus 25 | resp, _ := framework.CreateJsonMessage(framework.QuerySnapshotResponse) 26 | resp.SetToSession(request.GetFromSession()) 27 | resp.SetFromSession(id) 28 | resp.SetSuccess(false) 29 | { 30 | var respChan = make(chan modules.ResourceResult) 31 | executor.ResourceModule.GetInstanceStatus(instanceID, respChan) 32 | result := <-respChan 33 | if result.Error != nil { 34 | log.Printf("[%08X] fetch instance fail: %s", id, result.Error.Error()) 35 | resp.SetError(result.Error.Error()) 36 | return executor.Sender.SendMessage(resp, request.GetSender()) 37 | } 38 | ins = result.Instance 39 | } 40 | { 41 | //forward request 42 | forward, _ := framework.CreateJsonMessage(framework.QuerySnapshotRequest) 43 | forward.SetFromSession(id) 44 | forward.SetString(framework.ParamKeyInstance, instanceID) 45 | if err = executor.Sender.SendMessage(forward, ins.Cell); err != nil { 46 | log.Printf("[%08X] forward query snapshot to cell '%s' fail: %s", id, ins.Cell, err.Error()) 47 | resp.SetError(err.Error()) 48 | return executor.Sender.SendMessage(resp, request.GetSender()) 49 | } 50 | timer := time.NewTimer(modules.GetConfigurator().GetOperateTimeout()) 51 | select { 52 | case cellResp := <-incoming: 53 | if !cellResp.IsSuccess() { 54 | // log.Printf("[%08X] cell get snapshot success", id) 55 | //}else{ 56 | log.Printf("[%08X] cell query snapshot fail: %s", id, cellResp.GetError()) 57 | } 58 | cellResp.SetFromSession(id) 59 | cellResp.SetToSession(request.GetFromSession()) 60 | //forward 61 | return executor.Sender.SendMessage(cellResp, request.GetSender()) 62 | case <-timer.C: 63 | //timeout 64 | log.Printf("[%08X] wait query snapshot response timeout", id) 65 | resp.SetError("cell timeout") 66 | return executor.Sender.SendMessage(resp, request.GetSender()) 67 | } 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /src/task/get_guest_security_policy.go: -------------------------------------------------------------------------------- 1 | package task 2 | 3 | import ( 4 | "fmt" 5 | "github.com/project-nano/core/modules" 6 | "github.com/project-nano/framework" 7 | "log" 8 | "time" 9 | ) 10 | 11 | type GetGuestSecurityPolicyExecutor struct { 12 | Sender framework.MessageSender 13 | ResourceModule modules.ResourceModule 14 | } 15 | 16 | func (executor *GetGuestSecurityPolicyExecutor) Execute(id framework.SessionID, request framework.Message, 17 | incoming chan framework.Message, terminate chan bool) (err error) { 18 | var instanceID string 19 | if instanceID, err = request.GetString(framework.ParamKeyInstance); err != nil { 20 | err = fmt.Errorf("get instance ID fail: %s", err.Error()) 21 | return 22 | } 23 | var instance modules.InstanceStatus 24 | resp, _ := framework.CreateJsonMessage(framework.GetGuestRuleResponse) 25 | resp.SetToSession(request.GetFromSession()) 26 | resp.SetFromSession(id) 27 | resp.SetTransactionID(request.GetTransactionID()) 28 | resp.SetSuccess(false) 29 | { 30 | var respChan = make(chan modules.ResourceResult, 1) 31 | executor.ResourceModule.GetInstanceStatus(instanceID, respChan) 32 | var result = <-respChan 33 | if result.Error != nil { 34 | err = result.Error 35 | log.Printf("[%08X] get instance '%s' for security policy fail: %s", 36 | id, instanceID, err.Error()) 37 | resp.SetError(err.Error()) 38 | return executor.Sender.SendMessage(resp, request.GetSender()) 39 | } 40 | instance = result.Instance 41 | } 42 | { 43 | //forward request 44 | var forward = framework.CloneJsonMessage(request) 45 | forward.SetFromSession(id) 46 | if err = executor.Sender.SendMessage(forward, instance.Cell); err != nil { 47 | log.Printf("[%08X] forward get secuirty policy to cell '%s' fail: %s", id, instance.Cell, err.Error()) 48 | resp.SetError(err.Error()) 49 | return executor.Sender.SendMessage(resp, request.GetSender()) 50 | } 51 | timer := time.NewTimer(modules.GetConfigurator().GetOperateTimeout()) 52 | select { 53 | case cellResp := <-incoming: 54 | if !cellResp.IsSuccess() { 55 | log.Printf("[%08X] cell get secuirty policy fail: %s", id, cellResp.GetError()) 56 | } 57 | cellResp.SetFromSession(id) 58 | cellResp.SetToSession(request.GetFromSession()) 59 | cellResp.SetTransactionID(request.GetTransactionID()) 60 | //forward 61 | return executor.Sender.SendMessage(cellResp, request.GetSender()) 62 | case <-timer.C: 63 | //timeout 64 | log.Printf("[%08X] wait get secuirty policy timeout", id) 65 | resp.SetError("cell timeout") 66 | return executor.Sender.SendMessage(resp, request.GetSender()) 67 | } 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /src/task/add_security_policy_rule.go: -------------------------------------------------------------------------------- 1 | package task 2 | 3 | import ( 4 | "fmt" 5 | "github.com/project-nano/core/modules" 6 | "github.com/project-nano/framework" 7 | "log" 8 | ) 9 | 10 | type AddSecurityPolicyRuleExecutor struct { 11 | Sender framework.MessageSender 12 | ResourceModule modules.ResourceModule 13 | } 14 | 15 | func (executor *AddSecurityPolicyRuleExecutor)Execute(id framework.SessionID, request framework.Message, 16 | incoming chan framework.Message, terminate chan bool) (err error) { 17 | var policyID string 18 | if policyID, err = request.GetString(framework.ParamKeyPolicy);err != nil{ 19 | err = fmt.Errorf("get policy group ID fail: %s", err.Error()) 20 | return 21 | } 22 | var rule modules.SecurityPolicyRule 23 | if rule.Accept, err = request.GetBoolean(framework.ParamKeyAction); err != nil{ 24 | err = fmt.Errorf("get action fail: %s", err.Error()) 25 | return 26 | } 27 | var protocol string 28 | if protocol, err = request.GetString(framework.ParamKeyProtocol); err != nil{ 29 | err = fmt.Errorf("get protocol fail: %s", err.Error()) 30 | return 31 | } 32 | switch protocol { 33 | case modules.PolicyRuleProtocolTCP: 34 | case modules.PolicyRuleProtocolUDP: 35 | case modules.PolicyRuleProtocolICMP: 36 | default: 37 | err = fmt.Errorf("invalid protocol: %s", protocol) 38 | return 39 | } 40 | rule.Protocol = modules.PolicyRuleProtocol(protocol) 41 | if rule.SourceAddress, err = request.GetString(framework.ParamKeyFrom); err != nil{ 42 | err = fmt.Errorf("get source address fail: %s", err.Error()) 43 | return 44 | } 45 | if rule.TargetAddress, err = request.GetString(framework.ParamKeyTo); err != nil{ 46 | err = fmt.Errorf("get target address fail: %s", err.Error()) 47 | return 48 | } 49 | if rule.TargetPort, err = request.GetUInt(framework.ParamKeyPort); err != nil{ 50 | err = fmt.Errorf("get target port fail: %s", err.Error()) 51 | return 52 | } 53 | 54 | resp, _ := framework.CreateJsonMessage(framework.AddPolicyRuleResponse) 55 | resp.SetToSession(request.GetFromSession()) 56 | resp.SetFromSession(id) 57 | resp.SetTransactionID(request.GetTransactionID()) 58 | resp.SetSuccess(false) 59 | var respChan = make(chan error, 1) 60 | executor.ResourceModule.AddSecurityPolicyRule(policyID, rule, respChan) 61 | err = <- respChan 62 | if err != nil{ 63 | log.Printf("[%08X] add new rule to security policy '%s' fail: %s", 64 | id, policyID, err.Error()) 65 | resp.SetError(err.Error()) 66 | }else{ 67 | log.Printf("[%08X] new rule of security policy '%s' added", 68 | id, policyID) 69 | resp.SetSuccess(true) 70 | } 71 | return executor.Sender.SendMessage(resp, request.GetSender()) 72 | } 73 | -------------------------------------------------------------------------------- /src/task/create_security_policy_group.go: -------------------------------------------------------------------------------- 1 | package task 2 | 3 | import ( 4 | "fmt" 5 | "github.com/project-nano/core/modules" 6 | "github.com/project-nano/framework" 7 | "log" 8 | ) 9 | 10 | type CreateSecurityPolicyGroupExecutor struct { 11 | Sender framework.MessageSender 12 | ResourceModule modules.ResourceModule 13 | } 14 | 15 | func (executor *CreateSecurityPolicyGroupExecutor) Execute(id framework.SessionID, request framework.Message, 16 | incoming chan framework.Message, terminate chan bool) (err error) { 17 | var config modules.SecurityPolicyGroup 18 | if config.Name, err = request.GetString(framework.ParamKeyName); err != nil{ 19 | err = fmt.Errorf("get name fail: %s", err.Error()) 20 | return 21 | } 22 | if config.Description, err = request.GetString(framework.ParamKeyDescription); err != nil{ 23 | err = fmt.Errorf("get description fail: %s", err.Error()) 24 | return 25 | } 26 | if config.User, err = request.GetString(framework.ParamKeyUser); err != nil{ 27 | err = fmt.Errorf("get user fail: %s", err.Error()) 28 | return 29 | } 30 | if config.Group, err = request.GetString(framework.ParamKeyGroup); err != nil{ 31 | err = fmt.Errorf("get group fail: %s", err.Error()) 32 | return 33 | } 34 | if config.Accept, err = request.GetBoolean(framework.ParamKeyAction); err != nil{ 35 | err = fmt.Errorf("get accpet flag fail: %s", err.Error()) 36 | return 37 | } 38 | if config.Enabled, err = request.GetBoolean(framework.ParamKeyEnable); err != nil{ 39 | err = fmt.Errorf("get enabled flag fail: %s", err.Error()) 40 | return 41 | } 42 | if config.Global, err = request.GetBoolean(framework.ParamKeyLimit); err != nil{ 43 | err = fmt.Errorf("get global flag fail: %s", err.Error()) 44 | return 45 | } 46 | 47 | resp, _ := framework.CreateJsonMessage(framework.CreatePolicyGroupResponse) 48 | resp.SetToSession(request.GetFromSession()) 49 | resp.SetFromSession(id) 50 | resp.SetTransactionID(request.GetTransactionID()) 51 | resp.SetSuccess(false) 52 | var respChan = make(chan modules.ResourceResult, 1) 53 | executor.ResourceModule.CreateSecurityPolicyGroup(config, respChan) 54 | var result = <- respChan 55 | if result.Error != nil{ 56 | err = result.Error 57 | log.Printf("[%08X] create security policy group '%s' fail: %s", 58 | id, config.Name, err.Error()) 59 | resp.SetError(err.Error()) 60 | }else{ 61 | var policy = result.PolicyGroup 62 | log.Printf("[%08X] new security policy group '%s'('%s') created", 63 | id, config.Name, policy.ID) 64 | resp.SetString(framework.ParamKeyPolicy, policy.ID) 65 | resp.SetSuccess(true) 66 | } 67 | return executor.Sender.SendMessage(resp, request.GetSender()) 68 | } 69 | -------------------------------------------------------------------------------- /src/task/modify_security_policy_group.go: -------------------------------------------------------------------------------- 1 | package task 2 | 3 | import ( 4 | "fmt" 5 | "github.com/project-nano/core/modules" 6 | "github.com/project-nano/framework" 7 | "log" 8 | ) 9 | 10 | type ModifySecurityPolicyGroupExecutor struct { 11 | Sender framework.MessageSender 12 | ResourceModule modules.ResourceModule 13 | } 14 | 15 | func (executor *ModifySecurityPolicyGroupExecutor) Execute(id framework.SessionID, request framework.Message, 16 | incoming chan framework.Message, terminate chan bool) (err error) { 17 | var policyID string 18 | if policyID, err = request.GetString(framework.ParamKeyPolicy);err != nil{ 19 | err = fmt.Errorf("get policy group ID fail: %s", err.Error()) 20 | return 21 | } 22 | var config modules.SecurityPolicyGroup 23 | if config.Name, err = request.GetString(framework.ParamKeyName); err != nil{ 24 | err = fmt.Errorf("get name fail: %s", err.Error()) 25 | return 26 | } 27 | if config.Description, err = request.GetString(framework.ParamKeyDescription); err != nil{ 28 | err = fmt.Errorf("get description fail: %s", err.Error()) 29 | return 30 | } 31 | if config.User, err = request.GetString(framework.ParamKeyUser); err != nil{ 32 | err = fmt.Errorf("get user fail: %s", err.Error()) 33 | return 34 | } 35 | if config.Group, err = request.GetString(framework.ParamKeyGroup); err != nil{ 36 | err = fmt.Errorf("get group fail: %s", err.Error()) 37 | return 38 | } 39 | if config.Accept, err = request.GetBoolean(framework.ParamKeyAction); err != nil{ 40 | err = fmt.Errorf("get accpet flag fail: %s", err.Error()) 41 | return 42 | } 43 | if config.Enabled, err = request.GetBoolean(framework.ParamKeyEnable); err != nil{ 44 | err = fmt.Errorf("get enabled flag fail: %s", err.Error()) 45 | return 46 | } 47 | if config.Global, err = request.GetBoolean(framework.ParamKeyLimit); err != nil{ 48 | err = fmt.Errorf("get global flag fail: %s", err.Error()) 49 | return 50 | } 51 | 52 | resp, _ := framework.CreateJsonMessage(framework.ModifyPolicyGroupResponse) 53 | resp.SetToSession(request.GetFromSession()) 54 | resp.SetFromSession(id) 55 | resp.SetTransactionID(request.GetTransactionID()) 56 | resp.SetSuccess(false) 57 | var respChan = make(chan error, 1) 58 | executor.ResourceModule.ModifySecurityPolicyGroup(policyID, config, respChan) 59 | err = <- respChan 60 | if err != nil{ 61 | log.Printf("[%08X] modify security policy group '%s' fail: %s", 62 | id, policyID, err.Error()) 63 | resp.SetError(err.Error()) 64 | }else{ 65 | log.Printf("[%08X] security policy group '%s' modified", 66 | id, policyID) 67 | resp.SetSuccess(true) 68 | } 69 | return executor.Sender.SendMessage(resp, request.GetSender()) 70 | } 71 | -------------------------------------------------------------------------------- /src/task/get_address_pool.go: -------------------------------------------------------------------------------- 1 | package task 2 | 3 | import ( 4 | "log" 5 | "github.com/project-nano/framework" 6 | "github.com/project-nano/core/modules" 7 | ) 8 | 9 | type GetAddressPoolExecutor struct { 10 | Sender framework.MessageSender 11 | ResourceModule modules.ResourceModule 12 | } 13 | 14 | 15 | func (executor *GetAddressPoolExecutor)Execute(id framework.SessionID, request framework.Message, 16 | incoming chan framework.Message, terminate chan bool) (err error) { 17 | var poolName string 18 | if poolName, err = request.GetString(framework.ParamKeyAddress); err != nil{ 19 | return 20 | } 21 | var respChan = make(chan modules.ResourceResult, 1) 22 | executor.ResourceModule.GetAddressPool(poolName, respChan) 23 | resp, _ := framework.CreateJsonMessage(framework.GetAddressPoolResponse) 24 | resp.SetFromSession(id) 25 | resp.SetToSession(request.GetFromSession()) 26 | resp.SetSuccess(false) 27 | 28 | var result = <- respChan 29 | if result.Error != nil{ 30 | err = result.Error 31 | resp.SetError(err.Error()) 32 | log.Printf("[%08X] get address pool from %s.[%08X] fail: %s", 33 | id, request.GetSender(), request.GetFromSession(), err.Error()) 34 | return executor.Sender.SendMessage(resp, request.GetSender()) 35 | } 36 | var status = result.AddressPool 37 | var startArray, endArray, maskArray []string 38 | var capacityArray []uint64 39 | for _, addressRange := range status.Ranges{ 40 | startArray = append(startArray, addressRange.Start) 41 | endArray = append(endArray, addressRange.End) 42 | maskArray = append(maskArray, addressRange.Netmask) 43 | capacityArray = append(capacityArray, uint64(addressRange.Capacity)) 44 | } 45 | 46 | var addressArray, instanceArray []string 47 | for _, allocated := range status.Allocated{ 48 | addressArray = append(addressArray, allocated.Address) 49 | instanceArray = append(instanceArray, allocated.Instance) 50 | } 51 | resp.SetSuccess(true) 52 | resp.SetString(framework.ParamKeyGateway, status.Gateway) 53 | resp.SetString(framework.ParamKeyMode, status.Provider) 54 | resp.SetStringArray(framework.ParamKeyServer, status.DNS) 55 | resp.SetStringArray(framework.ParamKeyStart, startArray) 56 | resp.SetStringArray(framework.ParamKeyEnd, endArray) 57 | resp.SetStringArray(framework.ParamKeyMask, maskArray) 58 | resp.SetUIntArray(framework.ParamKeyCount, capacityArray) 59 | resp.SetStringArray(framework.ParamKeyAddress, addressArray) 60 | resp.SetStringArray(framework.ParamKeyInstance, instanceArray) 61 | log.Printf("[%08X] reply status of address pool '%s' to %s.[%08X]", 62 | id, poolName, request.GetSender(), request.GetFromSession()) 63 | return executor.Sender.SendMessage(resp, request.GetSender()) 64 | } -------------------------------------------------------------------------------- /src/task/search_guests.go: -------------------------------------------------------------------------------- 1 | package task 2 | 3 | import ( 4 | "errors" 5 | "github.com/project-nano/core/modules" 6 | "github.com/project-nano/framework" 7 | "log" 8 | ) 9 | 10 | type SearchGuestsExecutor struct { 11 | Sender framework.MessageSender 12 | ResourceModule modules.ResourceModule 13 | } 14 | 15 | func (executor *SearchGuestsExecutor) Execute(id framework.SessionID, request framework.Message, 16 | incoming chan framework.Message, terminate chan bool) (err error) { 17 | var condition modules.SearchGuestsCondition 18 | if condition.Pool, err = request.GetString(framework.ParamKeyPool); err != nil { 19 | return err 20 | } 21 | if condition.Cell, err = request.GetString(framework.ParamKeyCell); err != nil { 22 | return err 23 | } 24 | if condition.Keyword, err = request.GetString(framework.ParamKeyData); err != nil { 25 | return err 26 | } 27 | if condition.Limit, err = request.GetInt(framework.ParamKeyLimit); err != nil { 28 | return err 29 | } 30 | if condition.Offset, err = request.GetInt(framework.ParamKeyStart); err != nil { 31 | return err 32 | } 33 | // read owner and group 34 | if condition.Owner, err = request.GetString(framework.ParamKeyUser); err != nil { 35 | return err 36 | } 37 | if condition.Group, err = request.GetString(framework.ParamKeyGroup); err != nil { 38 | return err 39 | } 40 | resp, _ := framework.CreateJsonMessage(framework.SearchGuestResponse) 41 | resp.SetSuccess(false) 42 | resp.SetFromSession(id) 43 | resp.SetToSession(request.GetFromSession()) 44 | defer func() { 45 | if err != nil { 46 | resp.SetError(err.Error()) 47 | } 48 | if err = executor.Sender.SendMessage(resp, request.GetSender()); err != nil { 49 | log.Printf("[%08X] warning: notify search guests result fail: %s", id, err.Error()) 50 | } 51 | }() 52 | if "" == condition.Owner { 53 | err = errors.New("must specify owner") 54 | return 55 | } 56 | { 57 | var respChan = make(chan modules.ResourceResult, 1) 58 | executor.ResourceModule.SearchGuests(condition, respChan) 59 | result := <-respChan 60 | if result.Error != nil { 61 | err = result.Error 62 | log.Printf("[%08X] search guests fail: %s", id, err.Error()) 63 | return 64 | } 65 | var guests = result.InstanceList 66 | if err = modules.MarshalInstanceStatusListToMessage(guests, resp); err != nil { 67 | log.Printf("[%08X] build response message for search guests result fail: %s", id, err.Error()) 68 | return 69 | } 70 | var flags = []uint64{uint64(result.Total), uint64(result.Limit), uint64(result.Offset)} 71 | resp.SetUIntArray(framework.ParamKeyFlag, flags) 72 | //log.Printf("[%08X] %d guest(s) available", id, len(guests)) 73 | resp.SetSuccess(true) 74 | return 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /src/task/add_guest_security_rule.go: -------------------------------------------------------------------------------- 1 | package task 2 | 3 | import ( 4 | "fmt" 5 | "github.com/project-nano/core/modules" 6 | "github.com/project-nano/framework" 7 | "log" 8 | "time" 9 | ) 10 | 11 | type AddGuestSecurityRuleExecutor struct { 12 | Sender framework.MessageSender 13 | ResourceModule modules.ResourceModule 14 | } 15 | 16 | func (executor *AddGuestSecurityRuleExecutor) Execute(id framework.SessionID, request framework.Message, 17 | incoming chan framework.Message, terminate chan bool) (err error) { 18 | var instanceID string 19 | if instanceID, err = request.GetString(framework.ParamKeyInstance); err != nil { 20 | err = fmt.Errorf("get instance ID fail: %s", err.Error()) 21 | return 22 | } 23 | var instance modules.InstanceStatus 24 | resp, _ := framework.CreateJsonMessage(framework.AddGuestRuleResponse) 25 | resp.SetToSession(request.GetFromSession()) 26 | resp.SetFromSession(id) 27 | resp.SetTransactionID(request.GetTransactionID()) 28 | resp.SetSuccess(false) 29 | { 30 | var respChan = make(chan modules.ResourceResult, 1) 31 | executor.ResourceModule.GetInstanceStatus(instanceID, respChan) 32 | var result = <-respChan 33 | if result.Error != nil { 34 | err = result.Error 35 | log.Printf("[%08X] get instance '%s' for add security rule fail: %s", 36 | id, instanceID, err.Error()) 37 | resp.SetError(err.Error()) 38 | return executor.Sender.SendMessage(resp, request.GetSender()) 39 | } 40 | instance = result.Instance 41 | } 42 | { 43 | //forward request 44 | var forward = framework.CloneJsonMessage(request) 45 | forward.SetFromSession(id) 46 | if err = executor.Sender.SendMessage(forward, instance.Cell); err != nil { 47 | log.Printf("[%08X] forward add security rule to cell '%s' fail: %s", id, instance.Cell, err.Error()) 48 | resp.SetError(err.Error()) 49 | return executor.Sender.SendMessage(resp, request.GetSender()) 50 | } 51 | timer := time.NewTimer(modules.GetConfigurator().GetOperateTimeout()) 52 | select { 53 | case cellResp := <-incoming: 54 | if cellResp.IsSuccess() { 55 | log.Printf("[%08X] new security rule of instance '%s' added", id, instance.Name) 56 | } else { 57 | log.Printf("[%08X] cell add security rule fail: %s", id, cellResp.GetError()) 58 | } 59 | cellResp.SetFromSession(id) 60 | cellResp.SetToSession(request.GetFromSession()) 61 | cellResp.SetTransactionID(request.GetTransactionID()) 62 | //forward 63 | return executor.Sender.SendMessage(cellResp, request.GetSender()) 64 | case <-timer.C: 65 | //timeout 66 | log.Printf("[%08X] wait add security rule response timeout", id) 67 | resp.SetError("cell timeout") 68 | return executor.Sender.SendMessage(resp, request.GetSender()) 69 | } 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /src/task/change_guest_security_action.go: -------------------------------------------------------------------------------- 1 | package task 2 | 3 | import ( 4 | "fmt" 5 | "github.com/project-nano/core/modules" 6 | "github.com/project-nano/framework" 7 | "log" 8 | "time" 9 | ) 10 | 11 | type ChangeGuestSecurityActionExecutor struct { 12 | Sender framework.MessageSender 13 | ResourceModule modules.ResourceModule 14 | } 15 | 16 | func (executor *ChangeGuestSecurityActionExecutor) Execute(id framework.SessionID, request framework.Message, 17 | incoming chan framework.Message, terminate chan bool) (err error) { 18 | var instanceID string 19 | if instanceID, err = request.GetString(framework.ParamKeyInstance); err != nil { 20 | err = fmt.Errorf("get instance ID fail: %s", err.Error()) 21 | return 22 | } 23 | var instance modules.InstanceStatus 24 | resp, _ := framework.CreateJsonMessage(framework.ChangeGuestRuleDefaultActionResponse) 25 | resp.SetToSession(request.GetFromSession()) 26 | resp.SetFromSession(id) 27 | resp.SetTransactionID(request.GetTransactionID()) 28 | resp.SetSuccess(false) 29 | { 30 | var respChan = make(chan modules.ResourceResult, 1) 31 | executor.ResourceModule.GetInstanceStatus(instanceID, respChan) 32 | var result = <-respChan 33 | if result.Error != nil { 34 | err = result.Error 35 | log.Printf("[%08X] get instance '%s' for change default security action fail: %s", 36 | id, instanceID, err.Error()) 37 | resp.SetError(err.Error()) 38 | return executor.Sender.SendMessage(resp, request.GetSender()) 39 | } 40 | instance = result.Instance 41 | } 42 | { 43 | //forward request 44 | var forward = framework.CloneJsonMessage(request) 45 | forward.SetFromSession(id) 46 | if err = executor.Sender.SendMessage(forward, instance.Cell); err != nil { 47 | log.Printf("[%08X] forward change default security action to cell '%s' fail: %s", id, instance.Cell, err.Error()) 48 | resp.SetError(err.Error()) 49 | return executor.Sender.SendMessage(resp, request.GetSender()) 50 | } 51 | timer := time.NewTimer(modules.GetConfigurator().GetOperateTimeout()) 52 | select { 53 | case cellResp := <-incoming: 54 | if cellResp.IsSuccess() { 55 | log.Printf("[%08X] default security action of instance '%s' changed", 56 | id, instance.Name) 57 | } else { 58 | log.Printf("[%08X] cell change default security action fail: %s", id, cellResp.GetError()) 59 | } 60 | cellResp.SetFromSession(id) 61 | cellResp.SetToSession(request.GetFromSession()) 62 | cellResp.SetTransactionID(request.GetTransactionID()) 63 | //forward 64 | return executor.Sender.SendMessage(cellResp, request.GetSender()) 65 | case <-timer.C: 66 | //timeout 67 | log.Printf("[%08X] wait change default security action timeout", id) 68 | resp.SetError("cell timeout") 69 | return executor.Sender.SendMessage(resp, request.GetSender()) 70 | } 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /src/imageserver/query_disk_image.go: -------------------------------------------------------------------------------- 1 | package imageserver 2 | 3 | import ( 4 | "github.com/project-nano/framework" 5 | "log" 6 | ) 7 | 8 | type QueryDiskImageExecutor struct { 9 | Sender framework.MessageSender 10 | ImageServer *ImageManager 11 | } 12 | 13 | 14 | func (executor *QueryDiskImageExecutor)Execute(id framework.SessionID, request framework.Message, 15 | incoming chan framework.Message, terminate chan bool) (err error) { 16 | 17 | filterOwner, _ := request.GetString(framework.ParamKeyUser) 18 | filterGroup, _ := request.GetString(framework.ParamKeyGroup) 19 | filterTags, _ := request.GetStringArray(framework.ParamKeyTag) 20 | 21 | var respChan = make(chan ImageResult, 1) 22 | executor.ImageServer.QueryDiskImage(filterOwner, filterGroup, filterTags, respChan) 23 | 24 | var result = <- respChan 25 | 26 | resp, _ := framework.CreateJsonMessage(framework.QueryDiskImageResponse) 27 | resp.SetSuccess(false) 28 | resp.SetFromSession(id) 29 | resp.SetToSession(request.GetFromSession()) 30 | 31 | if result.Error != nil{ 32 | err = result.Error 33 | resp.SetError(err.Error()) 34 | log.Printf("[%08X] query disk image fail: %s", id, err.Error()) 35 | return executor.Sender.SendMessage(resp, request.GetSender()) 36 | } 37 | 38 | var name, imageID, description, tags, createTime, modifyTime []string 39 | var size, tagCount, created, progress []uint64 40 | for _, image := range result.DiskList { 41 | name = append(name, image.Name) 42 | imageID = append(imageID, image.ID) 43 | description = append(description, image.Description) 44 | size = append(size, uint64(image.Size)) 45 | count := uint64(len(image.Tags)) 46 | tagCount = append(tagCount, count) 47 | for _, tag := range image.Tags{ 48 | tags = append(tags, tag) 49 | } 50 | createTime = append(createTime, image.CreateTime) 51 | modifyTime = append(modifyTime, image.ModifyTime) 52 | if image.Created{ 53 | created = append(created, 1) 54 | }else{ 55 | created = append(created, 0) 56 | } 57 | progress = append(progress, uint64(image.Progress)) 58 | } 59 | 60 | resp.SetSuccess(true) 61 | resp.SetStringArray(framework.ParamKeyName, name) 62 | resp.SetStringArray(framework.ParamKeyImage, imageID) 63 | resp.SetStringArray(framework.ParamKeyDescription, description) 64 | resp.SetStringArray(framework.ParamKeyTag, tags) 65 | resp.SetStringArray(framework.ParamKeyCreate, createTime) 66 | resp.SetStringArray(framework.ParamKeyModify, modifyTime) 67 | 68 | resp.SetUIntArray(framework.ParamKeySize, size) 69 | resp.SetUIntArray(framework.ParamKeyCount, tagCount) 70 | resp.SetUIntArray(framework.ParamKeyStatus, created) 71 | resp.SetUIntArray(framework.ParamKeyProgress, progress) 72 | //log.Printf("[%08X] query disk image success, %d image(s) available", id, len(result.DiskList)) 73 | return executor.Sender.SendMessage(resp, request.GetSender()) 74 | 75 | } 76 | -------------------------------------------------------------------------------- /src/task/eject_media.go: -------------------------------------------------------------------------------- 1 | package task 2 | 3 | import ( 4 | "fmt" 5 | "github.com/project-nano/core/modules" 6 | "github.com/project-nano/framework" 7 | "log" 8 | "time" 9 | ) 10 | 11 | type EjectMediaExecutor struct { 12 | Sender framework.MessageSender 13 | ResourceModule modules.ResourceModule 14 | } 15 | 16 | func (executor *EjectMediaExecutor) Execute(id framework.SessionID, request framework.Message, 17 | incoming chan framework.Message, terminate chan bool) error { 18 | instanceID, err := request.GetString(framework.ParamKeyInstance) 19 | if err != nil { 20 | return err 21 | } 22 | log.Printf("[%08X] request eject media from guest '%s' from %s.[%08X]", id, instanceID, 23 | request.GetSender(), request.GetFromSession()) 24 | 25 | var ins modules.InstanceStatus 26 | resp, _ := framework.CreateJsonMessage(framework.EjectMediaResponse) 27 | resp.SetToSession(request.GetFromSession()) 28 | resp.SetFromSession(id) 29 | resp.SetSuccess(false) 30 | { 31 | var respChan = make(chan modules.ResourceResult) 32 | executor.ResourceModule.GetInstanceStatus(instanceID, respChan) 33 | result := <-respChan 34 | if result.Error != nil { 35 | log.Printf("[%08X] fetch instance fail: %s", id, result.Error.Error()) 36 | resp.SetError(result.Error.Error()) 37 | return executor.Sender.SendMessage(resp, request.GetSender()) 38 | } 39 | ins = result.Instance 40 | if !ins.Running { 41 | err = fmt.Errorf("instance '%s' is stopped", instanceID) 42 | log.Printf("[%08X] instance '%s' is stopped", id, instanceID) 43 | resp.SetError(err.Error()) 44 | return executor.Sender.SendMessage(resp, request.GetSender()) 45 | } 46 | } 47 | { 48 | //forward request 49 | forward, _ := framework.CreateJsonMessage(framework.EjectMediaRequest) 50 | forward.SetFromSession(id) 51 | forward.SetString(framework.ParamKeyInstance, instanceID) 52 | if err = executor.Sender.SendMessage(forward, ins.Cell); err != nil { 53 | log.Printf("[%08X] forward eject to cell '%s' fail: %s", id, ins.Cell, err.Error()) 54 | resp.SetError(err.Error()) 55 | return executor.Sender.SendMessage(resp, request.GetSender()) 56 | } 57 | timer := time.NewTimer(modules.GetConfigurator().GetOperateTimeout()) 58 | select { 59 | case cellResp := <-incoming: 60 | if cellResp.IsSuccess() { 61 | log.Printf("[%08X] cell eject media success", id) 62 | } else { 63 | log.Printf("[%08X] cell eject media fail: %s", id, cellResp.GetError()) 64 | } 65 | cellResp.SetFromSession(id) 66 | cellResp.SetToSession(request.GetFromSession()) 67 | //forward 68 | return executor.Sender.SendMessage(cellResp, request.GetSender()) 69 | case <-timer.C: 70 | //timeout 71 | log.Printf("[%08X] wait eject response timeout", id) 72 | resp.SetError("cell timeout") 73 | return executor.Sender.SendMessage(resp, request.GetSender()) 74 | } 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /src/task/modify_security_policy_rule.go: -------------------------------------------------------------------------------- 1 | package task 2 | 3 | import ( 4 | "fmt" 5 | "github.com/project-nano/core/modules" 6 | "github.com/project-nano/framework" 7 | "log" 8 | ) 9 | 10 | type ModifySecurityPolicyRuleExecutor struct { 11 | Sender framework.MessageSender 12 | ResourceModule modules.ResourceModule 13 | } 14 | 15 | func (executor *ModifySecurityPolicyRuleExecutor)Execute(id framework.SessionID, request framework.Message, 16 | incoming chan framework.Message, terminate chan bool) (err error) { 17 | var policyID string 18 | if policyID, err = request.GetString(framework.ParamKeyPolicy);err != nil{ 19 | err = fmt.Errorf("get policy group ID fail: %s", err.Error()) 20 | return 21 | } 22 | var index int 23 | if index, err = request.GetInt(framework.ParamKeyIndex);err != nil{ 24 | err = fmt.Errorf("get index fail: %s", err.Error()) 25 | return 26 | } 27 | var rule modules.SecurityPolicyRule 28 | if rule.Accept, err = request.GetBoolean(framework.ParamKeyAction); err != nil{ 29 | err = fmt.Errorf("get action fail: %s", err.Error()) 30 | return 31 | } 32 | var protocol string 33 | if protocol, err = request.GetString(framework.ParamKeyProtocol); err != nil{ 34 | err = fmt.Errorf("get protocol fail: %s", err.Error()) 35 | return 36 | } 37 | switch protocol { 38 | case modules.PolicyRuleProtocolTCP: 39 | case modules.PolicyRuleProtocolUDP: 40 | case modules.PolicyRuleProtocolICMP: 41 | default: 42 | err = fmt.Errorf("invalid protocol: %s", protocol) 43 | return 44 | } 45 | rule.Protocol = modules.PolicyRuleProtocol(protocol) 46 | if rule.SourceAddress, err = request.GetString(framework.ParamKeyFrom); err != nil{ 47 | err = fmt.Errorf("get source address fail: %s", err.Error()) 48 | return 49 | } 50 | if rule.TargetAddress, err = request.GetString(framework.ParamKeyTo); err != nil{ 51 | err = fmt.Errorf("get target address fail: %s", err.Error()) 52 | return 53 | } 54 | if rule.TargetPort, err = request.GetUInt(framework.ParamKeyPort); err != nil{ 55 | err = fmt.Errorf("get target port fail: %s", err.Error()) 56 | return 57 | } 58 | 59 | resp, _ := framework.CreateJsonMessage(framework.ModifyPolicyRuleResponse) 60 | resp.SetToSession(request.GetFromSession()) 61 | resp.SetFromSession(id) 62 | resp.SetTransactionID(request.GetTransactionID()) 63 | resp.SetSuccess(false) 64 | var respChan = make(chan error, 1) 65 | executor.ResourceModule.ModifySecurityPolicyRule(policyID, index, rule, respChan) 66 | err = <- respChan 67 | if err != nil{ 68 | log.Printf("[%08X] modify %dth rule of security policy '%s' fail: %s", 69 | id, index, policyID, err.Error()) 70 | resp.SetError(err.Error()) 71 | }else{ 72 | log.Printf("[%08X] %dth rule of security policy '%s' modified", 73 | id, index, policyID) 74 | resp.SetSuccess(true) 75 | } 76 | return executor.Sender.SendMessage(resp, request.GetSender()) 77 | } 78 | -------------------------------------------------------------------------------- /src/task/create_system_template.go: -------------------------------------------------------------------------------- 1 | package task 2 | 3 | import ( 4 | "fmt" 5 | "github.com/project-nano/core/modules" 6 | "github.com/project-nano/framework" 7 | "log" 8 | ) 9 | 10 | type CreateSystemTemplateExecutor struct { 11 | Sender framework.MessageSender 12 | ResourceModule modules.ResourceModule 13 | } 14 | 15 | func (executor *CreateSystemTemplateExecutor)Execute(id framework.SessionID, request framework.Message, 16 | incoming chan framework.Message, terminate chan bool) (err error){ 17 | var config modules.SystemTemplateConfig 18 | if config.Name, err = request.GetString(framework.ParamKeyName); err != nil{ 19 | err = fmt.Errorf("get template name fail: %s", err.Error()) 20 | return 21 | } 22 | if config.Admin, err = request.GetString(framework.ParamKeyAdmin); err != nil{ 23 | err = fmt.Errorf("get admin name fail: %s", err.Error()) 24 | return 25 | } 26 | if config.OperatingSystem, err = request.GetString(framework.ParamKeySystem); err != nil{ 27 | err = fmt.Errorf("get oprating system fail: %s", err.Error()) 28 | return 29 | } 30 | if config.Disk, err = request.GetString(framework.ParamKeyDisk); err != nil{ 31 | err = fmt.Errorf("get disk option fail: %s", err.Error()) 32 | return 33 | } 34 | if config.Network, err = request.GetString(framework.ParamKeyNetwork); err != nil{ 35 | err = fmt.Errorf("get network option fail: %s", err.Error()) 36 | return 37 | } 38 | if config.Display, err = request.GetString(framework.ParamKeyDisplay); err != nil{ 39 | err = fmt.Errorf("get display option fail: %s", err.Error()) 40 | return 41 | } 42 | if config.Control, err = request.GetString(framework.ParamKeyMonitor); err != nil{ 43 | err = fmt.Errorf("get control option fail: %s", err.Error()) 44 | return 45 | } 46 | if config.USB, err = request.GetString(framework.ParamKeyDevice); err != nil{ 47 | err = fmt.Errorf("get usb option fail: %s", err.Error()) 48 | return 49 | } 50 | if config.Tablet, err = request.GetString(framework.ParamKeyInterface); err != nil{ 51 | err = fmt.Errorf("get tablet option fail: %s", err.Error()) 52 | return 53 | } 54 | 55 | var respChan = make(chan modules.ResourceResult, 1) 56 | executor.ResourceModule.CreateSystemTemplate(config, respChan) 57 | var result = <- respChan 58 | 59 | resp, _ := framework.CreateJsonMessage(framework.ModifyTemplateResponse) 60 | resp.SetSuccess(false) 61 | resp.SetFromSession(id) 62 | resp.SetToSession(request.GetFromSession()) 63 | 64 | if result.Error != nil{ 65 | err = result.Error 66 | resp.SetError(err.Error()) 67 | log.Printf("[%08X] handle create system template from %s.[%08X] fail: %s", 68 | id, request.GetSender(), request.GetFromSession(), err.Error()) 69 | }else{ 70 | var t = result.Template 71 | resp.SetSuccess(true) 72 | resp.SetString(framework.ParamKeyID, t.ID) 73 | } 74 | return executor.Sender.SendMessage(resp, request.GetSender()) 75 | } 76 | -------------------------------------------------------------------------------- /src/task/modify_address_pool.go: -------------------------------------------------------------------------------- 1 | package task 2 | 3 | import ( 4 | "fmt" 5 | "github.com/project-nano/framework" 6 | "github.com/project-nano/core/modules" 7 | "log" 8 | ) 9 | 10 | type ModifyAddressPoolExecutor struct { 11 | Sender framework.MessageSender 12 | ResourceModule modules.ResourceModule 13 | } 14 | 15 | 16 | func (executor *ModifyAddressPoolExecutor)Execute(id framework.SessionID, request framework.Message, 17 | incoming chan framework.Message, terminate chan bool) (err error) { 18 | var config modules.AddressPoolConfig 19 | var poolName string 20 | if poolName, err = request.GetString(framework.ParamKeyAddress); err != nil{ 21 | return 22 | } 23 | config.Name = poolName 24 | if config.Gateway, err = request.GetString(framework.ParamKeyGateway); err != nil{ 25 | return 26 | } 27 | if config.DNS, err = request.GetStringArray(framework.ParamKeyServer); err != nil{ 28 | return 29 | } 30 | if config.Provider, err = request.GetString(framework.ParamKeyMode); err != nil{ 31 | err = fmt.Errorf("get provider fail: %s", err.Error()) 32 | return 33 | } 34 | var respChan = make(chan modules.ResourceResult, 1) 35 | executor.ResourceModule.ModifyAddressPool(config, respChan) 36 | resp, _ := framework.CreateJsonMessage(framework.ModifyAddressPoolResponse) 37 | resp.SetFromSession(id) 38 | resp.SetToSession(request.GetFromSession()) 39 | resp.SetSuccess(false) 40 | 41 | var result = <- respChan 42 | if result.Error != nil{ 43 | err = result.Error 44 | resp.SetError(err.Error()) 45 | log.Printf("[%08X] request modify address pool from %s.[%08X] fail: %s", 46 | id, request.GetSender(), request.GetFromSession(), err.Error()) 47 | return executor.Sender.SendMessage(resp, request.GetSender()) 48 | } 49 | resp.SetSuccess(true) 50 | log.Printf("[%08X] address pool '%s' modified from %s.[%08X]", 51 | id, poolName, request.GetSender(), request.GetFromSession()) 52 | if err = executor.Sender.SendMessage(resp, request.GetSender()); err != nil{ 53 | log.Printf("[%08X] warning: send modify address pool response fail: %s", id, err.Error()) 54 | } 55 | if 0 != len(result.ComputeCellInfoList) { 56 | notify, _ := framework.CreateJsonMessage(framework.AddressPoolChangedEvent) 57 | notify.SetString(framework.ParamKeyAddress, poolName) 58 | notify.SetString(framework.ParamKeyGateway, config.Gateway) 59 | notify.SetString(framework.ParamKeyMode, config.Provider) 60 | notify.SetStringArray(framework.ParamKeyServer, config.DNS) 61 | notify.SetFromSession(id) 62 | for _, cell := range result.ComputeCellInfoList { 63 | if err = executor.Sender.SendMessage(notify, cell.Name); err != nil{ 64 | log.Printf("[%08X] warning: notify address pool change to '%s' fail: %s", id, cell.Name, err.Error()) 65 | } 66 | } 67 | log.Printf("[%08X] notified address pool changed to %d affected cell", id, len(result.ComputeCellInfoList)) 68 | } 69 | return nil 70 | } 71 | -------------------------------------------------------------------------------- /src/task/move_guest_security_rule.go: -------------------------------------------------------------------------------- 1 | package task 2 | 3 | import ( 4 | "fmt" 5 | "github.com/project-nano/core/modules" 6 | "github.com/project-nano/framework" 7 | "log" 8 | "time" 9 | ) 10 | 11 | type MoveGuestSecurityRuleExecutor struct { 12 | Sender framework.MessageSender 13 | ResourceModule modules.ResourceModule 14 | } 15 | 16 | func (executor *MoveGuestSecurityRuleExecutor) Execute(id framework.SessionID, request framework.Message, 17 | incoming chan framework.Message, terminate chan bool) (err error) { 18 | var instanceID string 19 | if instanceID, err = request.GetString(framework.ParamKeyInstance); err != nil { 20 | err = fmt.Errorf("get instance ID fail: %s", err.Error()) 21 | return 22 | } 23 | var index int 24 | if index, err = request.GetInt(framework.ParamKeyIndex); err != nil { 25 | err = fmt.Errorf("get index fail: %s", err.Error()) 26 | return 27 | } 28 | var instance modules.InstanceStatus 29 | resp, _ := framework.CreateJsonMessage(framework.ChangeGuestRuleOrderResponse) 30 | resp.SetToSession(request.GetFromSession()) 31 | resp.SetFromSession(id) 32 | resp.SetTransactionID(request.GetTransactionID()) 33 | resp.SetSuccess(false) 34 | { 35 | var respChan = make(chan modules.ResourceResult, 1) 36 | executor.ResourceModule.GetInstanceStatus(instanceID, respChan) 37 | var result = <-respChan 38 | if result.Error != nil { 39 | err = result.Error 40 | log.Printf("[%08X] get instance '%s' for move security rule fail: %s", 41 | id, instanceID, err.Error()) 42 | resp.SetError(err.Error()) 43 | return executor.Sender.SendMessage(resp, request.GetSender()) 44 | } 45 | instance = result.Instance 46 | } 47 | { 48 | //forward request 49 | var forward = framework.CloneJsonMessage(request) 50 | forward.SetFromSession(id) 51 | if err = executor.Sender.SendMessage(forward, instance.Cell); err != nil { 52 | log.Printf("[%08X] forward move security rule to cell '%s' fail: %s", id, instance.Cell, err.Error()) 53 | resp.SetError(err.Error()) 54 | return executor.Sender.SendMessage(resp, request.GetSender()) 55 | } 56 | timer := time.NewTimer(modules.GetConfigurator().GetOperateTimeout()) 57 | select { 58 | case cellResp := <-incoming: 59 | if cellResp.IsSuccess() { 60 | log.Printf("[%08X] %dth security rule of instance '%s' moved", 61 | id, index, instance.Name) 62 | } else { 63 | log.Printf("[%08X] cell move security rule fail: %s", id, cellResp.GetError()) 64 | } 65 | cellResp.SetFromSession(id) 66 | cellResp.SetToSession(request.GetFromSession()) 67 | cellResp.SetTransactionID(request.GetTransactionID()) 68 | //forward 69 | return executor.Sender.SendMessage(cellResp, request.GetSender()) 70 | case <-timer.C: 71 | //timeout 72 | log.Printf("[%08X] wait move security rule response timeout", id) 73 | resp.SetError("cell timeout") 74 | return executor.Sender.SendMessage(resp, request.GetSender()) 75 | } 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /src/task/modify_guest_security_rule.go: -------------------------------------------------------------------------------- 1 | package task 2 | 3 | import ( 4 | "fmt" 5 | "github.com/project-nano/core/modules" 6 | "github.com/project-nano/framework" 7 | "log" 8 | "time" 9 | ) 10 | 11 | type ModifyGuestSecurityRuleExecutor struct { 12 | Sender framework.MessageSender 13 | ResourceModule modules.ResourceModule 14 | } 15 | 16 | func (executor *ModifyGuestSecurityRuleExecutor) Execute(id framework.SessionID, request framework.Message, 17 | incoming chan framework.Message, terminate chan bool) (err error) { 18 | var instanceID string 19 | if instanceID, err = request.GetString(framework.ParamKeyInstance); err != nil { 20 | err = fmt.Errorf("get instance ID fail: %s", err.Error()) 21 | return 22 | } 23 | var index int 24 | if index, err = request.GetInt(framework.ParamKeyIndex); err != nil { 25 | err = fmt.Errorf("get index fail: %s", err.Error()) 26 | return 27 | } 28 | var instance modules.InstanceStatus 29 | resp, _ := framework.CreateJsonMessage(framework.ModifyGuestRuleResponse) 30 | resp.SetToSession(request.GetFromSession()) 31 | resp.SetFromSession(id) 32 | resp.SetTransactionID(request.GetTransactionID()) 33 | resp.SetSuccess(false) 34 | { 35 | var respChan = make(chan modules.ResourceResult, 1) 36 | executor.ResourceModule.GetInstanceStatus(instanceID, respChan) 37 | var result = <-respChan 38 | if result.Error != nil { 39 | err = result.Error 40 | log.Printf("[%08X] get instance '%s' for modify security rule fail: %s", 41 | id, instanceID, err.Error()) 42 | resp.SetError(err.Error()) 43 | return executor.Sender.SendMessage(resp, request.GetSender()) 44 | } 45 | instance = result.Instance 46 | } 47 | { 48 | //forward request 49 | var forward = framework.CloneJsonMessage(request) 50 | forward.SetFromSession(id) 51 | if err = executor.Sender.SendMessage(forward, instance.Cell); err != nil { 52 | log.Printf("[%08X] forward modify security rule to cell '%s' fail: %s", id, instance.Cell, err.Error()) 53 | resp.SetError(err.Error()) 54 | return executor.Sender.SendMessage(resp, request.GetSender()) 55 | } 56 | timer := time.NewTimer(modules.GetConfigurator().GetOperateTimeout()) 57 | select { 58 | case cellResp := <-incoming: 59 | if cellResp.IsSuccess() { 60 | log.Printf("[%08X] %dth security rule of instance '%s' modified", 61 | id, index, instance.Name) 62 | } else { 63 | log.Printf("[%08X] cell modify security rule fail: %s", id, cellResp.GetError()) 64 | } 65 | cellResp.SetFromSession(id) 66 | cellResp.SetToSession(request.GetFromSession()) 67 | cellResp.SetTransactionID(request.GetTransactionID()) 68 | //forward 69 | return executor.Sender.SendMessage(cellResp, request.GetSender()) 70 | case <-timer.C: 71 | //timeout 72 | log.Printf("[%08X] wait modify security rule response timeout", id) 73 | resp.SetError("cell timeout") 74 | return executor.Sender.SendMessage(resp, request.GetSender()) 75 | } 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /src/task/remove_guest_security_rule.go: -------------------------------------------------------------------------------- 1 | package task 2 | 3 | import ( 4 | "fmt" 5 | "github.com/project-nano/core/modules" 6 | "github.com/project-nano/framework" 7 | "log" 8 | "time" 9 | ) 10 | 11 | type RemoveGuestSecurityRuleExecutor struct { 12 | Sender framework.MessageSender 13 | ResourceModule modules.ResourceModule 14 | } 15 | 16 | func (executor *RemoveGuestSecurityRuleExecutor) Execute(id framework.SessionID, request framework.Message, 17 | incoming chan framework.Message, terminate chan bool) (err error) { 18 | var instanceID string 19 | if instanceID, err = request.GetString(framework.ParamKeyInstance); err != nil { 20 | err = fmt.Errorf("get instance ID fail: %s", err.Error()) 21 | return 22 | } 23 | var index int 24 | if index, err = request.GetInt(framework.ParamKeyIndex); err != nil { 25 | err = fmt.Errorf("get index fail: %s", err.Error()) 26 | return 27 | } 28 | var instance modules.InstanceStatus 29 | resp, _ := framework.CreateJsonMessage(framework.RemoveGuestRuleResponse) 30 | resp.SetToSession(request.GetFromSession()) 31 | resp.SetFromSession(id) 32 | resp.SetTransactionID(request.GetTransactionID()) 33 | resp.SetSuccess(false) 34 | { 35 | var respChan = make(chan modules.ResourceResult, 1) 36 | executor.ResourceModule.GetInstanceStatus(instanceID, respChan) 37 | var result = <-respChan 38 | if result.Error != nil { 39 | err = result.Error 40 | log.Printf("[%08X] get instance '%s' for remove security rule fail: %s", 41 | id, instanceID, err.Error()) 42 | resp.SetError(err.Error()) 43 | return executor.Sender.SendMessage(resp, request.GetSender()) 44 | } 45 | instance = result.Instance 46 | } 47 | { 48 | //forward request 49 | var forward = framework.CloneJsonMessage(request) 50 | forward.SetFromSession(id) 51 | if err = executor.Sender.SendMessage(forward, instance.Cell); err != nil { 52 | log.Printf("[%08X] forward remove security rule to cell '%s' fail: %s", id, instance.Cell, err.Error()) 53 | resp.SetError(err.Error()) 54 | return executor.Sender.SendMessage(resp, request.GetSender()) 55 | } 56 | timer := time.NewTimer(modules.GetConfigurator().GetOperateTimeout()) 57 | select { 58 | case cellResp := <-incoming: 59 | if cellResp.IsSuccess() { 60 | log.Printf("[%08X] %dth security rule of instance '%s' removed", 61 | id, index, instance.Name) 62 | } else { 63 | log.Printf("[%08X] cell remove security rule fail: %s", id, cellResp.GetError()) 64 | } 65 | cellResp.SetFromSession(id) 66 | cellResp.SetToSession(request.GetFromSession()) 67 | cellResp.SetTransactionID(request.GetTransactionID()) 68 | //forward 69 | return executor.Sender.SendMessage(cellResp, request.GetSender()) 70 | case <-timer.C: 71 | //timeout 72 | log.Printf("[%08X] wait remove security rule response timeout", id) 73 | resp.SetError("cell timeout") 74 | return executor.Sender.SendMessage(resp, request.GetSender()) 75 | } 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /src/task/modify_system_template.go: -------------------------------------------------------------------------------- 1 | package task 2 | 3 | import ( 4 | "fmt" 5 | "github.com/project-nano/core/modules" 6 | "github.com/project-nano/framework" 7 | "log" 8 | ) 9 | 10 | type ModifySystemTemplateExecutor struct { 11 | Sender framework.MessageSender 12 | ResourceModule modules.ResourceModule 13 | } 14 | 15 | func (executor *ModifySystemTemplateExecutor)Execute(id framework.SessionID, request framework.Message, 16 | incoming chan framework.Message, terminate chan bool) (err error){ 17 | var templateID string 18 | if templateID, err = request.GetString(framework.ParamKeyTemplate); err != nil{ 19 | err = fmt.Errorf("get template id fail: %s", err.Error()) 20 | return 21 | } 22 | var config modules.SystemTemplateConfig 23 | if config.Name, err = request.GetString(framework.ParamKeyName); err != nil{ 24 | err = fmt.Errorf("get template name fail: %s", err.Error()) 25 | return 26 | } 27 | if config.Admin, err = request.GetString(framework.ParamKeyAdmin); err != nil{ 28 | err = fmt.Errorf("get admin name fail: %s", err.Error()) 29 | return 30 | } 31 | if config.OperatingSystem, err = request.GetString(framework.ParamKeySystem); err != nil{ 32 | err = fmt.Errorf("get oprating system fail: %s", err.Error()) 33 | return 34 | } 35 | if config.Disk, err = request.GetString(framework.ParamKeyDisk); err != nil{ 36 | err = fmt.Errorf("get disk option fail: %s", err.Error()) 37 | return 38 | } 39 | if config.Network, err = request.GetString(framework.ParamKeyNetwork); err != nil{ 40 | err = fmt.Errorf("get network option fail: %s", err.Error()) 41 | return 42 | } 43 | if config.Display, err = request.GetString(framework.ParamKeyDisplay); err != nil{ 44 | err = fmt.Errorf("get display option fail: %s", err.Error()) 45 | return 46 | } 47 | if config.Control, err = request.GetString(framework.ParamKeyMonitor); err != nil{ 48 | err = fmt.Errorf("get control option fail: %s", err.Error()) 49 | return 50 | } 51 | if config.USB, err = request.GetString(framework.ParamKeyDevice); err != nil{ 52 | err = fmt.Errorf("get usb option fail: %s", err.Error()) 53 | return 54 | } 55 | if config.Tablet, err = request.GetString(framework.ParamKeyInterface); err != nil{ 56 | err = fmt.Errorf("get tablet option fail: %s", err.Error()) 57 | return 58 | } 59 | 60 | var respChan = make(chan error, 1) 61 | executor.ResourceModule.ModifySystemTemplate(templateID, config, respChan) 62 | err = <- respChan 63 | 64 | resp, _ := framework.CreateJsonMessage(framework.ModifyTemplateResponse) 65 | resp.SetSuccess(false) 66 | resp.SetFromSession(id) 67 | resp.SetToSession(request.GetFromSession()) 68 | 69 | if err != nil{ 70 | resp.SetError(err.Error()) 71 | log.Printf("[%08X] handle modify system template from %s.[%08X] fail: %s", 72 | id, request.GetSender(), request.GetFromSession(), err.Error()) 73 | }else{ 74 | resp.SetSuccess(true) 75 | } 76 | return executor.Sender.SendMessage(resp, request.GetSender()) 77 | } 78 | -------------------------------------------------------------------------------- /src/imageserver/task_manager.go: -------------------------------------------------------------------------------- 1 | package imageserver 2 | 3 | import ( 4 | "fmt" 5 | "github.com/project-nano/framework" 6 | ) 7 | 8 | type TaskManager struct { 9 | *framework.TransactionEngine 10 | } 11 | 12 | func CreateTaskManager(sender framework.MessageSender, imageManager *ImageManager) (*TaskManager, error) { 13 | engine, err := framework.CreateTransactionEngine() 14 | if err != nil { 15 | return nil, err 16 | } 17 | 18 | var manager= TaskManager{engine} 19 | 20 | if err = manager.RegisterExecutor(framework.QueryMediaImageRequest, 21 | &QueryMediaImageExecutor{sender, imageManager}); err != nil{ 22 | return nil, err 23 | } 24 | if err = manager.RegisterExecutor(framework.GetMediaImageRequest, 25 | &GetMediaImageExecutor{sender, imageManager}); err != nil{ 26 | return nil, err 27 | } 28 | if err = manager.RegisterExecutor(framework.CreateMediaImageRequest, 29 | &CreateMediaImageExecutor{sender, imageManager}); err != nil{ 30 | return nil, err 31 | } 32 | if err = manager.RegisterExecutor(framework.ModifyMediaImageRequest, 33 | &ModifyMediaImageExecutor{sender, imageManager}); err != nil{ 34 | return nil, err 35 | } 36 | if err = manager.RegisterExecutor(framework.DeleteMediaImageRequest, 37 | &DeleteMediaImageExecutor{sender, imageManager}); err != nil{ 38 | return nil, err 39 | } 40 | 41 | if err = manager.RegisterExecutor(framework.QueryDiskImageRequest, 42 | &QueryDiskImageExecutor{sender, imageManager}); err != nil{ 43 | return nil, err 44 | } 45 | if err = manager.RegisterExecutor(framework.GetDiskImageRequest, 46 | &GetDiskImageExecutor{sender, imageManager}); err != nil{ 47 | return nil, err 48 | } 49 | if err = manager.RegisterExecutor(framework.CreateDiskImageRequest, 50 | &CreateDiskImageExecutor{sender, imageManager}); err != nil{ 51 | return nil, err 52 | } 53 | if err = manager.RegisterExecutor(framework.ModifyDiskImageRequest, 54 | &ModifyDiskImageExecutor{sender, imageManager}); err != nil{ 55 | return nil, err 56 | } 57 | if err = manager.RegisterExecutor(framework.DeleteDiskImageRequest, 58 | &DeleteDiskImageExecutor{sender, imageManager}); err != nil{ 59 | return nil, err 60 | } 61 | if err = manager.RegisterExecutor(framework.DiskImageUpdatedEvent, 62 | &DiskImageUpdateExecutor{sender, imageManager}); err != nil{ 63 | return nil, err 64 | } 65 | if err = manager.RegisterExecutor(framework.SynchronizeDiskImageRequest, 66 | &SyncDiskImagesExecutor{ 67 | Sender: sender, 68 | ImageServer: imageManager, 69 | }); err != nil { 70 | err = fmt.Errorf("register sync disk images fail: %s", err.Error()) 71 | return nil, err 72 | } 73 | if err = manager.RegisterExecutor(framework.SynchronizeMediaImageRequest, 74 | &SyncMediaImagesExecutor{ 75 | Sender: sender, 76 | ImageServer: imageManager, 77 | }); err != nil { 78 | err = fmt.Errorf("register sync disk images fail: %s", err.Error()) 79 | return nil, err 80 | } 81 | 82 | return &manager, nil 83 | } 84 | -------------------------------------------------------------------------------- /src/task/query_compute_pool_status.go: -------------------------------------------------------------------------------- 1 | package task 2 | 3 | import ( 4 | "github.com/project-nano/framework" 5 | "github.com/project-nano/core/modules" 6 | "log" 7 | ) 8 | 9 | type QueryComputePoolStatusExecutor struct { 10 | Sender framework.MessageSender 11 | ResourceModule modules.ResourceModule 12 | } 13 | 14 | func (executor *QueryComputePoolStatusExecutor)Execute(id framework.SessionID, request framework.Message, 15 | incoming chan framework.Message, terminate chan bool) (err error) { 16 | 17 | //log.Printf("[%08X] query compute pool status from %s.[%08X]", id, request.GetSender(), request.GetFromSession()) 18 | var respChan= make(chan modules.ResourceResult) 19 | 20 | executor.ResourceModule.QueryComputePoolStatus(respChan) 21 | result := <-respChan 22 | 23 | resp, _ := framework.CreateJsonMessage(framework.QueryComputePoolStatusResponse) 24 | resp.SetFromSession(id) 25 | resp.SetToSession(request.GetFromSession()) 26 | if result.Error != nil{ 27 | err = result.Error 28 | resp.SetSuccess(false) 29 | resp.SetError(err.Error()) 30 | log.Printf("[%08X] query compute pool status fail: %s", id, err.Error()) 31 | return executor.Sender.SendMessage(resp, request.GetSender()) 32 | } 33 | resp.SetSuccess(true) 34 | var name []string 35 | var enabled, cells, instance, usage, cores, memory, disk, speed []uint64 36 | for _, s := range result.ComputePoolList { 37 | name = append(name, s.Name) 38 | if s.Enabled{ 39 | enabled = append(enabled, 1) 40 | }else{ 41 | enabled = append(enabled, 0) 42 | } 43 | cells = append(cells, s.OfflineCells) 44 | cells = append(cells, s.OnlineCells) 45 | instance = append(instance, s.StoppedInstances) 46 | instance = append(instance, s.RunningInstances) 47 | instance = append(instance, s.LostInstances) 48 | instance = append(instance, s.MigratingInstances) 49 | usage = append(usage, uint64(s.CpuUsage))//todo: tripped decimal 50 | cores = append(cores, uint64(s.Cores)) 51 | memory = append(memory, s.MemoryAvailable) 52 | memory = append(memory, s.Memory) 53 | disk = append(disk, s.DiskAvailable) 54 | disk = append(disk, s.Disk) 55 | speed = append(speed, s.ReadSpeed) 56 | speed = append(speed, s.WriteSpeed) 57 | speed = append(speed, s.ReceiveSpeed) 58 | speed = append(speed, s.SendSpeed) 59 | } 60 | 61 | //assemble 62 | resp.SetStringArray(framework.ParamKeyName, name) 63 | resp.SetUIntArray(framework.ParamKeyEnable, enabled) 64 | resp.SetUIntArray(framework.ParamKeyCell, cells) 65 | resp.SetUIntArray(framework.ParamKeyInstance, instance) 66 | resp.SetUIntArray(framework.ParamKeyUsage, usage) 67 | resp.SetUIntArray(framework.ParamKeyCore, cores) 68 | resp.SetUIntArray(framework.ParamKeyMemory, memory) 69 | resp.SetUIntArray(framework.ParamKeyDisk, disk) 70 | resp.SetUIntArray(framework.ParamKeySpeed, speed) 71 | //log.Printf("[%08X] %d compute pool status available", id, len(name)) 72 | return executor.Sender.SendMessage(resp, request.GetSender()) 73 | } 74 | 75 | -------------------------------------------------------------------------------- /src/task/delete_guest.go: -------------------------------------------------------------------------------- 1 | package task 2 | 3 | import ( 4 | "fmt" 5 | "github.com/project-nano/core/modules" 6 | "github.com/project-nano/framework" 7 | "log" 8 | "time" 9 | ) 10 | 11 | type DeleteGuestExecutor struct { 12 | Sender framework.MessageSender 13 | ResourceModule modules.ResourceModule 14 | } 15 | 16 | func (executor *DeleteGuestExecutor) Execute(id framework.SessionID, request framework.Message, 17 | incoming chan framework.Message, terminate chan bool) error { 18 | instanceID, err := request.GetString(framework.ParamKeyInstance) 19 | if err != nil { 20 | return err 21 | } 22 | log.Printf("[%08X] request delete guest '%s' from %s.[%08X]", id, instanceID, 23 | request.GetSender(), request.GetFromSession()) 24 | var ins modules.InstanceStatus 25 | resp, _ := framework.CreateJsonMessage(framework.DeleteGuestResponse) 26 | resp.SetToSession(request.GetFromSession()) 27 | resp.SetFromSession(id) 28 | resp.SetTransactionID(request.GetTransactionID()) 29 | resp.SetSuccess(false) 30 | { 31 | var respChan = make(chan modules.ResourceResult) 32 | executor.ResourceModule.GetInstanceStatus(instanceID, respChan) 33 | result := <-respChan 34 | if result.Error != nil { 35 | log.Printf("[%08X] fetch instance fail: %s", id, result.Error.Error()) 36 | resp.SetError(result.Error.Error()) 37 | return executor.Sender.SendMessage(resp, request.GetSender()) 38 | } 39 | ins = result.Instance 40 | if ins.Running { 41 | err = fmt.Errorf("instance '%s' is still running", instanceID) 42 | log.Printf("[%08X] instance '%s' is still running", id, instanceID) 43 | resp.SetError(err.Error()) 44 | return executor.Sender.SendMessage(resp, request.GetSender()) 45 | } 46 | } 47 | { 48 | //request delete 49 | forward, _ := framework.CreateJsonMessage(framework.DeleteGuestRequest) 50 | forward.SetFromSession(id) 51 | forward.SetString(framework.ParamKeyInstance, instanceID) 52 | if err = executor.Sender.SendMessage(forward, ins.Cell); err != nil { 53 | log.Printf("[%08X] forward delete to cell '%s' fail: %s", id, ins.Cell, err.Error()) 54 | resp.SetError(err.Error()) 55 | return executor.Sender.SendMessage(resp, request.GetSender()) 56 | } 57 | timer := time.NewTimer(modules.GetConfigurator().GetOperateTimeout()) 58 | select { 59 | case cellResp := <-incoming: 60 | if cellResp.IsSuccess() { 61 | log.Printf("[%08X] cell delete guest success", id) 62 | } else { 63 | log.Printf("[%08X] cell delete guest fail: %s", id, cellResp.GetError()) 64 | } 65 | cellResp.SetFromSession(id) 66 | cellResp.SetToSession(request.GetFromSession()) 67 | cellResp.SetTransactionID(request.GetTransactionID()) 68 | //forward 69 | return executor.Sender.SendMessage(cellResp, request.GetSender()) 70 | case <-timer.C: 71 | //timeout 72 | log.Printf("[%08X] wait delete response timeout", id) 73 | resp.SetError("cell timeout") 74 | return executor.Sender.SendMessage(resp, request.GetSender()) 75 | } 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /src/imageserver/image_service_test.go: -------------------------------------------------------------------------------- 1 | package imageserver 2 | 3 | import ( 4 | "fmt" 5 | "github.com/project-nano/framework" 6 | "net" 7 | "testing" 8 | ) 9 | 10 | // dummyService implement ServiceHandler 11 | type dummyService struct { 12 | } 13 | 14 | func (dummy *dummyService) OnMessageReceived(msg framework.Message) { 15 | fmt.Printf("dummy service receive message: %s\n", msg) 16 | } 17 | 18 | func (dummy *dummyService) OnServiceConnected(name string, t framework.ServiceType, address string) { 19 | fmt.Printf("dummy service connected: %s, %d, %s\n", name, t, address) 20 | } 21 | 22 | func (dummy *dummyService) OnServiceDisconnected(name string, t framework.ServiceType, gracefully bool) { 23 | fmt.Printf("dummy service disconnected: %s, %d, %t\n", name, t, gracefully) 24 | } 25 | 26 | // OnDependencyReady 27 | func (dummy *dummyService) OnDependencyReady() { 28 | fmt.Println("dummy service dependency ready") 29 | } 30 | 31 | // InitialEndpoint 32 | func (dummy *dummyService) InitialEndpoint() error { 33 | fmt.Println("dummy service initial endpoint") 34 | return nil 35 | } 36 | 37 | func (dummy *dummyService) OnEndpointStarted() error { 38 | fmt.Println("dummy service endpoint started") 39 | return nil 40 | } 41 | 42 | func (dummy *dummyService) OnEndpointStopped() { 43 | fmt.Println("dummy service endpoint stopped") 44 | } 45 | 46 | func getImageServiceForTest() (image *ImageService, stub framework.EndpointService, err error) { 47 | const ( 48 | domainName = "nano" 49 | groupAddress = "224.0.0.226" 50 | groupPort = 5599 51 | listenAddress = "192.168.1.167" 52 | configPath = "../../config" 53 | dataPath = "../../data" 54 | ) 55 | var inf *net.Interface 56 | if inf, err = framework.InterfaceByAddress(listenAddress); nil != err { 57 | return 58 | } 59 | if stub, err = framework.CreateStubEndpoint(groupAddress, groupPort, domainName, listenAddress); err != nil { 60 | return 61 | } 62 | var dummy dummyService 63 | stub.RegisterHandler(&dummy) 64 | var endpoint framework.EndpointService 65 | if endpoint, err = framework.CreatePeerEndpoint(groupAddress, groupPort, domainName); err != nil { 66 | return 67 | } 68 | image = &ImageService{EndpointService: endpoint, ConfigPath: configPath, DataPath: dataPath} 69 | image.RegisterHandler(image) 70 | err = image.GenerateName(framework.ServiceTypeImage, inf) 71 | return 72 | } 73 | 74 | func TestImageService_StartAndStop(t *testing.T) { 75 | imageService, stub, err := getImageServiceForTest() 76 | if err != nil { 77 | t.Fatalf("load service fail: %s", err.Error()) 78 | return 79 | } 80 | if err = stub.Start(); err != nil { 81 | t.Fatalf("start stub fail: %s", err.Error()) 82 | return 83 | } 84 | defer func() { 85 | _ = stub.Stop() 86 | }() 87 | if err = imageService.Start(); err != nil { 88 | t.Fatalf("start service fail: %s", err.Error()) 89 | return 90 | } 91 | if err = imageService.Stop(); err != nil { 92 | t.Fatalf("stop service fail: %s", err.Error()) 93 | } 94 | t.Log("test image service start and stop success") 95 | } 96 | -------------------------------------------------------------------------------- /src/task/shrink_guest_disk.go: -------------------------------------------------------------------------------- 1 | package task 2 | 3 | import ( 4 | "fmt" 5 | "github.com/project-nano/core/modules" 6 | "github.com/project-nano/framework" 7 | "log" 8 | "time" 9 | ) 10 | 11 | type ShrinkGuestDiskExecutor struct { 12 | Sender framework.MessageSender 13 | ResourceModule modules.ResourceModule 14 | } 15 | 16 | func (executor *ShrinkGuestDiskExecutor) Execute(id framework.SessionID, request framework.Message, 17 | incoming chan framework.Message, terminate chan bool) error { 18 | guestID, err := request.GetString(framework.ParamKeyGuest) 19 | if err != nil { 20 | return err 21 | } 22 | index, err := request.GetUInt(framework.ParamKeyDisk) 23 | if err != nil { 24 | return err 25 | } 26 | var diskIndex = int(index) 27 | 28 | log.Printf("[%08X] request shrink disk of '%s' from %s.[%08X]", id, guestID, 29 | request.GetSender(), request.GetFromSession()) 30 | 31 | var ins modules.InstanceStatus 32 | resp, _ := framework.CreateJsonMessage(framework.ShrinkDiskResponse) 33 | resp.SetToSession(request.GetFromSession()) 34 | resp.SetFromSession(id) 35 | resp.SetSuccess(false) 36 | { 37 | var respChan = make(chan modules.ResourceResult) 38 | executor.ResourceModule.GetInstanceStatus(guestID, respChan) 39 | result := <-respChan 40 | if result.Error != nil { 41 | log.Printf("[%08X] fetch instance fail: %s", id, result.Error.Error()) 42 | resp.SetError(result.Error.Error()) 43 | return executor.Sender.SendMessage(resp, request.GetSender()) 44 | } 45 | ins = result.Instance 46 | if diskIndex >= len(ins.Disks) { 47 | err = fmt.Errorf("invalid disk index %d", diskIndex) 48 | log.Printf("[%08X] %s", id, err.Error()) 49 | resp.SetError(err.Error()) 50 | return executor.Sender.SendMessage(resp, request.GetSender()) 51 | } 52 | } 53 | { 54 | //request delete 55 | forward, _ := framework.CreateJsonMessage(framework.ShrinkDiskRequest) 56 | forward.SetFromSession(id) 57 | forward.SetString(framework.ParamKeyGuest, guestID) 58 | forward.SetUInt(framework.ParamKeyDisk, index) 59 | if err = executor.Sender.SendMessage(forward, ins.Cell); err != nil { 60 | log.Printf("[%08X] forward shrink disk to cell '%s' fail: %s", id, ins.Cell, err.Error()) 61 | resp.SetError(err.Error()) 62 | return executor.Sender.SendMessage(resp, request.GetSender()) 63 | } 64 | timer := time.NewTimer(modules.GetConfigurator().GetOperateTimeout()) 65 | select { 66 | case cellResp := <-incoming: 67 | if cellResp.IsSuccess() { 68 | log.Printf("[%08X] shrink disk success", id) 69 | } else { 70 | log.Printf("[%08X] shrink disk fail: %s", id, cellResp.GetError()) 71 | } 72 | cellResp.SetFromSession(id) 73 | cellResp.SetToSession(request.GetFromSession()) 74 | //forward 75 | return executor.Sender.SendMessage(cellResp, request.GetSender()) 76 | case <-timer.C: 77 | //timeout 78 | log.Printf("[%08X] wait shrink disk response timeout", id) 79 | resp.SetError("request timeout") 80 | return executor.Sender.SendMessage(resp, request.GetSender()) 81 | } 82 | } 83 | } 84 | -------------------------------------------------------------------------------- /src/task/reset_instance_monitor_secret.go: -------------------------------------------------------------------------------- 1 | package task 2 | 3 | import ( 4 | "errors" 5 | "fmt" 6 | "github.com/project-nano/core/modules" 7 | "github.com/project-nano/framework" 8 | "log" 9 | "time" 10 | ) 11 | 12 | type ResetMonitorSecretExecutor struct { 13 | Sender framework.MessageSender 14 | ResourceModule modules.ResourceModule 15 | } 16 | 17 | func (executor *ResetMonitorSecretExecutor) Execute(id framework.SessionID, request framework.Message, 18 | incoming chan framework.Message, terminate chan bool) (err error) { 19 | var guestID string 20 | if guestID, err = request.GetString(framework.ParamKeyGuest); err != nil { 21 | err = fmt.Errorf("get guest id fail: %s", err.Error()) 22 | return err 23 | } 24 | 25 | var ins modules.InstanceStatus 26 | resp, _ := framework.CreateJsonMessage(framework.ResetSecretResponse) 27 | resp.SetToSession(request.GetFromSession()) 28 | resp.SetFromSession(id) 29 | resp.SetSuccess(false) 30 | 31 | { 32 | var respChan = make(chan modules.ResourceResult) 33 | executor.ResourceModule.GetInstanceStatus(guestID, respChan) 34 | result := <-respChan 35 | if result.Error != nil { 36 | log.Printf("[%08X] fetch instance fail: %s", id, result.Error.Error()) 37 | resp.SetError(result.Error.Error()) 38 | return executor.Sender.SendMessage(resp, request.GetSender()) 39 | } 40 | ins = result.Instance 41 | } 42 | var fromSession = request.GetFromSession() 43 | { 44 | //redirect request 45 | request.SetFromSession(id) 46 | if err = executor.Sender.SendMessage(request, ins.Cell); err != nil { 47 | log.Printf("[%08X] redirect reset request to cell '%s' fail: %s", id, ins.Cell, err.Error()) 48 | resp.SetError(err.Error()) 49 | return executor.Sender.SendMessage(resp, request.GetSender()) 50 | } 51 | timer := time.NewTimer(modules.GetConfigurator().GetOperateTimeout()) 52 | select { 53 | case cellResp := <-incoming: 54 | if cellResp.IsSuccess() { 55 | var newSecret string 56 | if newSecret, err = cellResp.GetString(framework.ParamKeySecret); err != nil { 57 | err = fmt.Errorf("get new secret from response fail: %s", err.Error()) 58 | } else { 59 | var respChan = make(chan error, 1) 60 | executor.ResourceModule.UpdateInstanceMonitorSecret(guestID, newSecret, respChan) 61 | err = <-respChan 62 | if err == nil { 63 | log.Printf("[%08X] monitor secret of guest '%s' reset", id, ins.Name) 64 | } 65 | } 66 | } else { 67 | err = errors.New(cellResp.GetError()) 68 | } 69 | if err != nil { 70 | log.Printf("[%08X] cell reset monitor secret fail: %s", id, cellResp.GetError()) 71 | } else { 72 | cellResp.SetSuccess(true) 73 | } 74 | cellResp.SetFromSession(id) 75 | cellResp.SetToSession(fromSession) 76 | //forward 77 | return executor.Sender.SendMessage(cellResp, request.GetSender()) 78 | case <-timer.C: 79 | //timeout 80 | log.Printf("[%08X] wait reset response timeout", id) 81 | resp.SetError("cell timeout") 82 | return executor.Sender.SendMessage(resp, request.GetSender()) 83 | } 84 | } 85 | } 86 | --------------------------------------------------------------------------------