Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion DomCon/domain_list.go
Original file line number Diff line number Diff line change
Expand Up @@ -146,7 +146,7 @@ func (DC *DomListControl) RetrieveAllDomain(logger *zap.Logger) error {
return err
}

logger.Info("retreiving intital vm", zap.Int("number", len(DC.DomainList)))
logger.Info("retrieving initial vm", zap.Int("number", len(DC.DomainList)))
return nil
}

Expand Down
4 changes: 2 additions & 2 deletions api/Control/Control.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ func (h *Handler) ForceShutDownVM(w http.ResponseWriter, r *http.Request) {

dom, err := h.DomainControl.GetDomain(param.UUID)
if err != nil {
ERR := virerr.ErrorJoin(err, fmt.Errorf("error shutting down vm, retreving Get domin error "))
ERR := virerr.ErrorJoin(err, fmt.Errorf("error shutting down vm, retrieving domain"))
resp.ResponseWriteErr(w, ERR, http.StatusInternalServerError)
h.Logger.Error("failed to get domain for forceShutdown", zap.String("uuid", param.UUID), zap.Error(ERR))
return
Expand Down Expand Up @@ -57,7 +57,7 @@ func (h *Handler) DeleteVM(w http.ResponseWriter, r *http.Request) {

domain, err := h.DomainControl.GetDomain(param.UUID)
if err != nil {
ERR := virerr.ErrorJoin(err, fmt.Errorf("error deleting vm, retreving Get domin error "))
ERR := virerr.ErrorJoin(err, fmt.Errorf("error deleting vm, retrieving domain"))
resp.ResponseWriteErr(w, ERR, http.StatusInternalServerError)
h.Logger.Error("failed to get domain for deleteVM", zap.String("uuid", param.UUID), zap.Error(ERR))
return
Expand Down
8 changes: 3 additions & 5 deletions api/Create/Create.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,11 +35,9 @@ func (h *Handler) BootVM(w http.ResponseWriter, r *http.Request) {
return
}

err := DomainExisting.Domain.Create()
if err != nil {
newErr := virerr.ErrorGen(virerr.DomainGenerationError, fmt.Errorf(" %w error while booting domain, from BootVM", err))
h.Logger.Error("error from booting vm", zap.Error(newErr))
resp.ResponseWriteErr(w, newErr, http.StatusInternalServerError)
if err := creation.BootExistingVM(DomainExisting); err != nil {
h.Logger.Error("error booting vm", zap.Error(err))
resp.ResponseWriteErr(w, err, http.StatusInternalServerError)
return
}

Expand Down
4 changes: 2 additions & 2 deletions api/Create/model.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ type CreateVMRequest struct {
DomName string `json:"domName"`
UUID string `json:"uuid"`
OS string `json:"os"`
HardwardInfo vmtypes.HardwareInfo `json:"HWInfo"`
HardwareInfo vmtypes.HardwareInfo `json:"HWInfo"`
NetConf network.NetDefine `json:"network"`
Users []vmtypes.User_info_VM `json:"users"`
SDNUUID string `json:"sdnUUID"`
Expand All @@ -21,7 +21,7 @@ func (r *CreateVMRequest) toVMInitInfo() *vmtypes.VM_Init_Info {
DomName: r.DomName,
UUID: r.UUID,
OS: r.OS,
HardwardInfo: r.HardwardInfo,
HardwareInfo: r.HardwareInfo,
NetConf: r.NetConf,
Users: r.Users,
SDNUUID: r.SDNUUID,
Expand Down
35 changes: 3 additions & 32 deletions api/Status/Status.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ func (h *Handler) ReturnStatusUUID(w http.ResponseWriter, r *http.Request) {
resp.ResponseWriteErr(w, err, http.StatusBadRequest)
return
}
h.Logger.Info("retreving domain status", zap.String("uuid", param.UUID))
h.Logger.Info("retrieving domain status", zap.String("uuid", param.UUID))

outputStruct, err := svcstatus.DataTypeRouter(param.DataType)
if err != nil {
Expand Down Expand Up @@ -99,41 +99,12 @@ func (h *Handler) ReturnAllUUIDs(w http.ResponseWriter, r *http.Request) {
resp.ResponseWriteOK(w, &respData)
}

func (h *Handler) getAllDomainStates() ([]DomainStateResponse, error) {
domains, err := h.LibvirtConn.ListAllDomains(0)
if err != nil {
return nil, err
}
defer func() {
for _, d := range domains {
d.Free()
}
}()

var result []DomainStateResponse
for _, d := range domains {
uuid, err := d.GetUUIDString()
if err != nil {
continue
}
state, _, err := d.GetState()
if err != nil {
continue
}
result = append(result, DomainStateResponse{
UUID: uuid,
DomainState: state,
})
}
return result, nil
}

func (h *Handler) ReturnAllDomainStates(w http.ResponseWriter, r *http.Request) {
h.Logger.Info("ReturnAllDomainStates handler entered")

resp := httputil.ResponseGen[[]DomainStateResponse]("Get All Domain States")
resp := httputil.ResponseGen[[]svcstatus.DomainStateInfo]("Get All Domain States")

states, err := h.getAllDomainStates()
states, err := svcstatus.ListAllDomainStates(h.LibvirtConn)
if err != nil {
resp.ResponseWriteErr(w, err, http.StatusInternalServerError)
return
Expand Down
5 changes: 0 additions & 5 deletions api/Status/model.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ package status

import (
svcstatus "github.com/easy-cloud-Knet/KWS_Core/services/status"
"libvirt.org/go/libvirt"
)

type DomainStatusRequest struct {
Expand All @@ -22,7 +21,3 @@ type UUIDListResponse struct {
UUIDs []string `json:"uuids"`
}

type DomainStateResponse struct {
DomainState libvirt.DomainState `json:"currentState"`
UUID string `json:"UUID"`
}
45 changes: 45 additions & 0 deletions api/Status/status_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package status

import (
"bytes"
"fmt"
"net/http"
"net/http/httptest"
"testing"
Expand All @@ -12,6 +13,7 @@ import (
svcstatus "github.com/easy-cloud-Knet/KWS_Core/services/status"
testutil "github.com/easy-cloud-Knet/KWS_Core/test"
"go.uber.org/zap"
"libvirt.org/go/libvirt"
)

// ─── mock ───────────────────────────────────────────────────────────────────
Expand Down Expand Up @@ -175,3 +177,46 @@ func TestReturnAllUUIDs_WithUUIDs(t *testing.T) {
t.Errorf("expected %d, got %d", http.StatusOK, w.Code)
}
}

// ─── ReturnAllDomainStates ───────────────────────────────────────────────────

type mockConnect struct {
domains []libvirt.Domain
err error
}

func (m *mockConnect) ListAllDomains(_ libvirt.ConnectListAllDomainsFlags) ([]libvirt.Domain, error) {
return m.domains, m.err
}

func TestReturnAllDomainStates_ConnectError(t *testing.T) {
h := &Handler{
LibvirtConn: &mockConnect{err: fmt.Errorf("connect error")},
DomainControl: &mockDomainController{},
Logger: zap.NewNop(),
}
r := httptest.NewRequest(http.MethodGet, "/getAll-uuidstatusList", nil)
w := httptest.NewRecorder()

h.ReturnAllDomainStates(w, r)

if w.Code != http.StatusInternalServerError {
t.Errorf("expected %d, got %d", http.StatusInternalServerError, w.Code)
}
}

func TestReturnAllDomainStates_Empty(t *testing.T) {
h := &Handler{
LibvirtConn: &mockConnect{domains: []libvirt.Domain{}},
DomainControl: &mockDomainController{},
Logger: zap.NewNop(),
}
r := httptest.NewRequest(http.MethodGet, "/getAll-uuidstatusList", nil)
w := httptest.NewRecorder()

h.ReturnAllDomainStates(w, r)

if w.Code != http.StatusOK {
t.Errorf("expected %d, got %d", http.StatusOK, w.Code)
}
}
2 changes: 1 addition & 1 deletion internal/domain/domain.go
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ func (DP *State) GetInfo(domain Domain) error {
DP.UUID = uuidParsed.String()
userInfo, err := domain.GetGuestInfo(libvirt.DOMAIN_GUEST_INFO_USERS, 0)
if err != nil {
return virerr.ErrorGen(virerr.DomainStatusError, fmt.Errorf("error retreving guest info: %w", err))
return virerr.ErrorGen(virerr.DomainStatusError, fmt.Errorf("error retrieving guest info: %w", err))
}
DP.Users = userInfo.Users
return nil
Expand Down
6 changes: 3 additions & 3 deletions internal/error/Error.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import (
type VirError string

const (
FaildDeEncoding VirError = "Error Not Found"
FailedDecoding VirError = "Error Not Found"
DomainSearchError VirError = "Error Serching Domain"
NoSuchDomain VirError = "Domain Not Found"

Expand All @@ -22,8 +22,8 @@ const (
InvalidParameter VirError = "Invalid parameter entered"
WrongParameter VirError = "Not validated parameter In"

DomainStatusError VirError = "Error Retreving Domain Status"
HostStatusError VirError = "Error Retreving Host Status"
DomainStatusError VirError = "Error Retrieving Domain Status"
HostStatusError VirError = "Error Retrieving Host Status"

DeletionDomainError VirError = "Error Deleting Domain"
DomainShutdownError VirError = "failed in Deleting domain"
Expand Down
6 changes: 3 additions & 3 deletions internal/host/host.go
Original file line number Diff line number Diff line change
Expand Up @@ -113,13 +113,13 @@ func (HDI *DiskInfo) GetHostInfo(_ *domStatus.DomainListStatus) error {

func (SI *GeneralInfo) GetHostInfo(status *domStatus.DomainListStatus) error {
if err := SI.CPU.GetHostInfo(status); err != nil {
return virerr.ErrorGen(virerr.HostStatusError, fmt.Errorf("general Status:error retreving host Status %w", err))
return virerr.ErrorGen(virerr.HostStatusError, fmt.Errorf("general Status:error retrieving host status %w", err))
}
if err := SI.Disk.GetHostInfo(status); err != nil {
return virerr.ErrorGen(virerr.HostStatusError, fmt.Errorf("general Status:error retreving host Status %w", err))
return virerr.ErrorGen(virerr.HostStatusError, fmt.Errorf("general Status:error retrieving host status %w", err))
}
if err := SI.Memory.GetHostInfo(status); err != nil {
return virerr.ErrorGen(virerr.HostStatusError, fmt.Errorf("general Status:error retreving host Status %w", err))
return virerr.ErrorGen(virerr.HostStatusError, fmt.Errorf("general Status:error retrieving host status %w", err))
}
return nil
}
Expand Down
3 changes: 0 additions & 3 deletions internal/server/middleware/libvirt.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,7 @@ func LibvirtMiddleware(check func() bool, logger *zap.Logger) func(http.Handler)
return func(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if !check() {
// find a way for graceful shutdown of server when libvirt connection is unavailable
logger.Panic("libvirt connection unavailable", zap.String("path", r.URL.Path))
http.Error(w, "service unavailable", http.StatusServiceUnavailable)
return
}
next.ServeHTTP(w, r)
})
Expand Down
17 changes: 8 additions & 9 deletions pkg/httputil/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ type BaseResponse[T any] struct {
Information *T `json:"information,omitempty"`
Message string `json:"message"`
Errors *virerr.ErrorDescriptor `json:"errors,omitempty"`
ErrorDebug string `json:"errrorDebug,omitempty"`
ErrorDebug string `json:"errorDebug,omitempty"`
}

func ResponseGen[T any](message string) *BaseResponse[T] {
Expand All @@ -25,25 +25,24 @@ func ResponseGen[T any](message string) *BaseResponse[T] {
func HttpDecoder[T any](r *http.Request, param *T) error {
body, err := io.ReadAll(r.Body)
if err != nil {
return virerr.ErrorGen(virerr.FaildDeEncoding, fmt.Errorf("%w error unmarshaling body into Structure", err))
return virerr.ErrorGen(virerr.FailedDecoding, fmt.Errorf("%w error unmarshaling body into Structure", err))
}
defer r.Body.Close()

if err := json.Unmarshal(body, param); err != nil {
return virerr.ErrorGen(virerr.FaildDeEncoding, fmt.Errorf("%w error unmarshaling body into Structure", err))
return virerr.ErrorGen(virerr.FailedDecoding, fmt.Errorf("%w error unmarshaling body into Structure", err))
}
return nil
}

func (br *BaseResponse[T]) ResponseWriteErr(w http.ResponseWriter, err error, statusCode int) {
br.Message += " failed"
errDesc, ok := err.(virerr.ErrorDescriptor)
if !ok {
http.Error(w, br.Message, http.StatusInternalServerError)
return
if errDesc, ok := err.(virerr.ErrorDescriptor); ok {
br.Errors = &errDesc
br.ErrorDebug = errDesc.Error()
} else {
br.ErrorDebug = err.Error()
}
br.Errors = &errDesc
br.ErrorDebug = errDesc.Error()
data, marshalErr := json.Marshal(br)
if marshalErr != nil {
http.Error(w, "failed to marshal error response", http.StatusInternalServerError)
Expand Down
4 changes: 2 additions & 2 deletions pkg/parsor/XML_Parsor.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,11 +40,11 @@ func (XP *VM_CREATE_XML) XML_Parsor(spec *vmtypes.VM_Init_Info) error {
UUID: spec.UUID,
Memory: Memory{
Unit: "GiB",
Size: spec.HardwardInfo.Memory,
Size: spec.HardwareInfo.Memory,
},
VCPU: VCPU{
Placement: "static",
Count: spec.HardwardInfo.CPU,
Count: spec.HardwareInfo.CPU,
},
Features: Features{
ACPI: ACPI{},
Expand Down
10 changes: 5 additions & 5 deletions pkg/parsor/xml_parsor_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ var testSpec = &vmtypes.VM_Init_Info{
DomName: "test-vm",
UUID: "123e4567-e89b-12d3-a456-426614174000",
OS: "debian",
HardwardInfo: vmtypes.HardwareInfo{
HardwareInfo: vmtypes.HardwareInfo{
CPU: 2,
Memory: 4,
Disk: 20,
Expand Down Expand Up @@ -99,11 +99,11 @@ func TestXMLParsor(t *testing.T) {
if xp.UUID != testSpec.UUID {
t.Errorf("uuid: expected %s, got %s", testSpec.UUID, xp.UUID)
}
if xp.Memory.Size != testSpec.HardwardInfo.Memory {
t.Errorf("memory: expected %d, got %d", testSpec.HardwardInfo.Memory, xp.Memory.Size)
if xp.Memory.Size != testSpec.HardwareInfo.Memory {
t.Errorf("memory: expected %d, got %d", testSpec.HardwareInfo.Memory, xp.Memory.Size)
}
if xp.VCPU.Count != testSpec.HardwardInfo.CPU {
t.Errorf("vcpu: expected %d, got %d", testSpec.HardwardInfo.CPU, xp.VCPU.Count)
if xp.VCPU.Count != testSpec.HardwareInfo.CPU {
t.Errorf("vcpu: expected %d, got %d", testSpec.HardwareInfo.CPU, xp.VCPU.Count)
}
if len(xp.Devices.Disks) != 2 {
t.Errorf("disks: expected 2, got %d", len(xp.Devices.Disks))
Expand Down
2 changes: 1 addition & 1 deletion pkg/types/vm.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ type VM_Init_Info struct {
DomName string `json:"domName"`
UUID string `json:"uuid"`
OS string `json:"os"`
HardwardInfo HardwareInfo `json:"HWInfo"`
HardwareInfo HardwareInfo `json:"HWInfo"`
NetConf network.NetDefine `json:"network"`
Users []User_info_VM `json:"users"`
SDNUUID string `json:"sdnUUID"`
Expand Down
14 changes: 14 additions & 0 deletions services/creation/boot_domain.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package creation

import (
"fmt"

virerr "github.com/easy-cloud-Knet/KWS_Core/internal/error"
)

func BootExistingVM(d BootableDomain) error {
if err := d.Create(); err != nil {
return virerr.ErrorGen(virerr.DomainGenerationError, fmt.Errorf("error starting domain: %w", err))
}
return nil
}
31 changes: 31 additions & 0 deletions services/creation/creation_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -58,3 +58,34 @@ func TestCreateVM_DomainDefineXMLError(t *testing.T) {

// TODO: processCloudInitFiles, GenerateXML 내부 로직 테스트는
// YamlParsor, XMLDefiner 인터페이스 + VM_CREATE_XML.MarshalXML() 추가 후 가능.

type mockBootableDomain struct {
createErr error
called bool
}

func (m *mockBootableDomain) Create() error {
m.called = true
return m.createErr
}

func TestBootExistingVM_Success(t *testing.T) {
mock := &mockBootableDomain{}
if err := BootExistingVM(mock); err != nil {
t.Errorf("expected nil, got %v", err)
}
if !mock.called {
t.Error("Create not called")
}
}

func TestBootExistingVM_Error(t *testing.T) {
mock := &mockBootableDomain{createErr: fmt.Errorf("libvirt error")}
err := BootExistingVM(mock)
if err == nil {
t.Fatal("expected error, got nil")
}
if !errors.Is(err, virerr.DomainGenerationError) {
t.Errorf("expected DomainGenerationError, got %v", err)
}
}
6 changes: 6 additions & 0 deletions services/creation/domain.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,3 +17,9 @@ type Configurer interface {
type LibvirtConnect interface {
DomainDefineXML(xmlConfig string) (*libvirt.Domain, error)
}

// BootableDomain abstracts domain boot for testing.
// *libvirt.Domain satisfies this via structural typing.
type BootableDomain interface {
Create() error
}
Loading
Loading