diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml new file mode 100644 index 0000000..23f6592 --- /dev/null +++ b/.github/workflows/lint.yml @@ -0,0 +1,27 @@ +name: Lint + +on: + push: + branches: ["**"] + pull_request: + branches: ["**"] + +jobs: + lint: + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v4 + + - uses: actions/setup-go@v5 + with: + go-version-file: go.mod + cache: false + + - name: Install system dependencies + run: sudo apt-get install -y libvirt-dev pkg-config + + - name: golangci-lint + uses: golangci/golangci-lint-action@v6 + with: + version: latest diff --git a/.github/workflows/unit-test.yml b/.github/workflows/unit-test.yml new file mode 100644 index 0000000..9408e2a --- /dev/null +++ b/.github/workflows/unit-test.yml @@ -0,0 +1,28 @@ +name: Unit Test + +on: + push: + branches: ["**"] + pull_request: + branches: ["**"] + +jobs: + test: + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v4 + + - uses: actions/setup-go@v5 + with: + go-version-file: go.mod + cache: true + + - name: Install system dependencies + run: sudo apt-get install -y libvirt-dev pkg-config whois + + - name: Build + run: go build ./... + + - name: Test + run: go test -v -count=1 ./... diff --git a/.golangci.yml b/.golangci.yml new file mode 100644 index 0000000..d120871 --- /dev/null +++ b/.golangci.yml @@ -0,0 +1,24 @@ +linters: + enable: + - errcheck + - unused + - govet + - staticcheck + +issues: + exclude-rules: + # libvirt resource cleanup — error return is not actionable + - linters: [errcheck] + text: "Error return value of `.*\\.Free` is not checked" + + # zap logger sync — standard deferred pattern + - linters: [errcheck] + text: "Error return value of `.*\\.Sync` is not checked" + + # http.ResponseWriter.Write — error not recoverable after headers sent + - linters: [errcheck] + text: "Error return value of `.*w\\.Write` is not checked" + + # json.Encoder.Encode in HTTP handlers — same rationale + - linters: [errcheck] + text: "Error return value of `.*\\.Encode` is not checked" diff --git a/DomCon/domainList_status/cpu_status.go b/DomCon/domainList_status/cpu_status.go index f765065..a9627b9 100644 --- a/DomCon/domainList_status/cpu_status.go +++ b/DomCon/domainList_status/cpu_status.go @@ -7,7 +7,7 @@ import ( // 인터페이스 구현체 -func (vs *VCPUStatus) EmitStatus(dls *DomainListStatus) error { +func (vs *VCPUStatus) EmitStatus(dls *DomainListStatus) { vs.Total = int(dls.VCPUTotal) vs.Allocated = int(dls.VcpuAllocated) vs.Sleeping = int(dls.VcpuSleeping) @@ -16,8 +16,6 @@ func (vs *VCPUStatus) EmitStatus(dls *DomainListStatus) error { if vs.Idle < 0 { vs.Idle = 0 } - - return nil } func (dls *DomainListStatus) Update() { @@ -29,23 +27,18 @@ func (dls *DomainListStatus) UpdateCPUTotal() { dls.VCPUTotal = int64(totalCPU) } -func (dls *DomainListStatus) AddAllocatedCPU(vcpu int) error { +func (dls *DomainListStatus) AddAllocatedCPU(vcpu int) { atomic.AddInt64(&dls.VcpuAllocated, int64(vcpu)) - return nil } -func (dls *DomainListStatus) AddSleepingCPU(vcpu int) error { +func (dls *DomainListStatus) AddSleepingCPU(vcpu int) { atomic.AddInt64(&dls.VcpuSleeping, int64(vcpu)) - return nil } -func (dls *DomainListStatus) TakeAllocatedCPU(vcpu int) error { +func (dls *DomainListStatus) TakeAllocatedCPU(vcpu int) { atomic.AddInt64(&dls.VcpuAllocated, -int64(vcpu)) - return nil } -func (dls *DomainListStatus) TakeSleepingCPU(vcpu int) error { - +func (dls *DomainListStatus) TakeSleepingCPU(vcpu int) { atomic.AddInt64(&dls.VcpuSleeping, -int64(vcpu)) - return nil } diff --git a/DomCon/domain_list.go b/DomCon/domain_list.go index c3b6737..bf2d4dc 100755 --- a/DomCon/domain_list.go +++ b/DomCon/domain_list.go @@ -58,20 +58,21 @@ func (DC *DomListControl) GetDomain(uuid string, LibvirtInst *libvirt.Connect) ( if err != nil { return nil, err } - DC.AddNewDomain(dom, uuid) + if err := DC.AddNewDomain(dom, uuid); err != nil { + return nil, err + } return dom, nil } return domain, nil } -func (DC *DomListControl) DeleteDomain(Domain *libvirt.Domain, uuid string, vcpu int) error { +func (DC *DomListControl) DeleteDomain(Domain *libvirt.Domain, uuid string, vcpu int) { DC.domainListMutex.Lock() delete(DC.DomainList, uuid) Domain.Free() DC.domainListMutex.Unlock() DC.DomainListStatus.TakeAllocatedCPU(vcpu) - return nil } func (DC *DomListControl) FindAndDeleteDomain(LibvirtInst *libvirt.Connect, uuid string) error { diff --git a/DomCon/domain_seeker.go b/DomCon/domain_seeker.go index 755e44e..8fa1cca 100755 --- a/DomCon/domain_seeker.go +++ b/DomCon/domain_seeker.go @@ -8,15 +8,13 @@ import ( "libvirt.org/go/libvirt" ) - -func DomSeekUUIDFactory(LibInstance *libvirt.Connect,UUID string)*DomainSeekingByUUID{ - return &DomainSeekingByUUID{ +func DomSeekUUIDFactory(LibInstance *libvirt.Connect, UUID string) *DomainSeekingByUUID { + return &DomainSeekingByUUID{ LibvirtInst: LibInstance, UUID: UUID, } } - func ReturnUUID(UUID string) (*uuid.UUID, error) { uuidParsed, err := uuid.Parse(UUID) if err != nil { @@ -25,23 +23,20 @@ func ReturnUUID(UUID string) (*uuid.UUID, error) { return &uuidParsed, nil } - func (DSU *DomainSeekingByUUID) ReturnDomain() (*Domain, error) { parsedUUID, err := uuid.Parse(DSU.UUID) if err != nil { - return nil,virerr.ErrorGen(virerr.InvalidUUID, err) + return nil, virerr.ErrorGen(virerr.InvalidUUID, err) } domain, err := DSU.LibvirtInst.LookupDomainByUUID(parsedUUID[:]) if err != nil { - return nil,virerr.ErrorGen(virerr.DomainSearchError, err) - }else if domain==nil { - return nil,virerr.ErrorGen(virerr.NoSuchDomain, err) + return nil, virerr.ErrorGen(virerr.DomainSearchError, err) + } else if domain == nil { + return nil, virerr.ErrorGen(virerr.NoSuchDomain, err) } - return &Domain{ Domain: domain, domainMutex: sync.Mutex{}, }, nil } - diff --git a/api/snapshot_model.go b/api/snapshot_model.go deleted file mode 100644 index 7e6cd2c..0000000 --- a/api/snapshot_model.go +++ /dev/null @@ -1,28 +0,0 @@ -package api - -// Snapshot API structures -type SnapshotRequest struct { - UUID string `json:"UUID"` - Name string `json:"Name,omitempty"` - Description string `json:"Description,omitempty"` - Quiesce bool `json:"Quiesce,omitempty"` -} - -type ExternalSnapshotRequest struct { - UUID string `json:"UUID"` - Name string `json:"Name,omitempty"` - Description string `json:"Description,omitempty"` - BaseDir string `json:"BaseDir,omitempty"` - Quiesce bool `json:"Quiesce,omitempty"` - Live bool `json:"Live,omitempty"` -} - -type ExternalSnapshotResponse struct { - UUID string `json:"UUID"` - SnapName string `json:"SnapName"` -} - -type ExternalSnapshotListResponse struct { - UUID string `json:"UUID"` - SnapNames []string `json:"SnapNames"` -} diff --git a/api/status.go b/api/status.go index b9c2ece..bb7087b 100755 --- a/api/status.go +++ b/api/status.go @@ -10,11 +10,6 @@ import ( "go.uber.org/zap" ) - - - - - func (i *InstHandler) ReturnStatusUUID(w http.ResponseWriter, r *http.Request) { param := &DomainStatusRequest{} resp := ResponseGen[status.DataTypeHandler]("domain Status UUID") @@ -38,14 +33,15 @@ func (i *InstHandler) ReturnStatusUUID(w http.ResponseWriter, r *http.Request) { DomainDetail := status.DomainDetailFactory(outputStruct, dom) - outputStruct.GetInfo(dom) + if err := outputStruct.GetInfo(dom); err != nil { + resp.ResponseWriteErr(w, err, http.StatusInternalServerError) + return + } DomainDetail.DataHandle = outputStruct resp.ResponseWriteOK(w, &DomainDetail.DataHandle) } - - func (i *InstHandler) ReturnStatusHost(w http.ResponseWriter, r *http.Request) { param := &HostStatusRequest{} resp := ResponseGen[status.HostDataTypeHandler]("Host Status Return") @@ -62,7 +58,6 @@ func (i *InstHandler) ReturnStatusHost(w http.ResponseWriter, r *http.Request) { return } - host, err := status.HostInfoHandler(dataHandle, i.DomainControl.DomainListStatus) if err != nil { resp.ResponseWriteErr(w, err, http.StatusInternalServerError) diff --git a/api/utils.go b/api/utils.go index 610adbe..a66d99d 100755 --- a/api/utils.go +++ b/api/utils.go @@ -10,18 +10,16 @@ import ( virerr "github.com/easy-cloud-Knet/KWS_Core/error" ) - - type BaseResponse[T any] struct { - Information *T `json:"information,omitempty"` - Message string `json:"message"` + Information *T `json:"information,omitempty"` + Message string `json:"message"` Errors *virerr.ErrorDescriptor `json:"errors,omitempty"` - ErrorDebug string `json:"errrorDebug,omitempty"` + ErrorDebug string `json:"errrorDebug,omitempty"` } func ResponseGen[T any](message string) *BaseResponse[T] { return &BaseResponse[T]{ - Message: fmt.Sprintf("%s operation", message), + Message: fmt.Sprintf("%s operation", message), } } @@ -29,25 +27,25 @@ 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.FaildDeEncoding, 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.FaildDeEncoding, 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{ + errDesc, ok := err.(virerr.ErrorDescriptor) + if !ok { http.Error(w, br.Message, http.StatusInternalServerError) return } br.Errors = &errDesc - br.ErrorDebug= errDesc.Error() + br.ErrorDebug = errDesc.Error() data, marshalErr := json.Marshal(br) if marshalErr != nil { http.Error(w, "failed to marshal error response", http.StatusInternalServerError) @@ -61,23 +59,21 @@ func (br *BaseResponse[T]) ResponseWriteErr(w http.ResponseWriter, err error, st func (br *BaseResponse[T]) ResponseWriteOK(w http.ResponseWriter, info *T) { br.Message += " success" br.Information = info - br.Errors=nil + br.Errors = nil data, err := json.Marshal(br) if err != nil { http.Error(w, "failed to marshal success response", http.StatusInternalServerError) return } - w.Header().Set("Content-Type", "application/json") w.WriteHeader(http.StatusOK) w.Write(data) } - -func (i *InstHandler) domainConGetter()(*domCon.DomListControl, error){ - if(i.DomainControl == nil){ +func (i *InstHandler) domainConGetter() (*domCon.DomListControl, error) { + if i.DomainControl == nil { return nil, virerr.ErrorGen(virerr.InvalidParameter, fmt.Errorf("domainController not initialled yet")) } - return i.DomainControl,nil + return i.DomainControl, nil } diff --git a/error/Error.go b/error/Error.go index d9bf317..d64b29b 100755 --- a/error/Error.go +++ b/error/Error.go @@ -8,38 +8,38 @@ import ( type VirError string const ( - FaildDeEncoding VirError = "Error Not Found" + FaildDeEncoding VirError = "Error Not Found" DomainSearchError VirError = "Error Serching Domain" - NoSuchDomain VirError = "Domain Not Found" - - DomainGenerationError VirError ="error Generating Domain" - LackCapacityRAM VirError = "Not enough RAM" // control - LackCapacityCPU VirError = "Not Enough CPU" // - LackCapacityHD VirError = "Not Enough HardDisk" // - - InvalidUUID VirError = "Invalid UUID Provided" - - InvalidParameter VirError= "Invalid parameter entered" - WrongParameter VirError= "Not validated parameter In" - - DomainStatusError VirError ="Error Retreving Domain Status" - HostStatusError VirError ="Error Retreving Host Status" + NoSuchDomain VirError = "Domain Not Found" - DeletionDomainError VirError= "Error Deleting Domain" - DomainShutdownError VirError= "failed in Deleting domain" + DomainGenerationError VirError = "error Generating Domain" + LackCapacityRAM VirError = "Not enough RAM" // control + LackCapacityCPU VirError = "Not Enough CPU" // + LackCapacityHD VirError = "Not Enough HardDisk" // + + InvalidUUID VirError = "Invalid UUID Provided" + + InvalidParameter VirError = "Invalid parameter entered" + WrongParameter VirError = "Not validated parameter In" + + DomainStatusError VirError = "Error Retreving Domain Status" + HostStatusError VirError = "Error Retreving Host Status" + + DeletionDomainError VirError = "Error Deleting Domain" + DomainShutdownError VirError = "failed in Deleting domain" SnapshotError VirError = "Error in Snapshot Operation" ) - // VirError는 error 인터페이스를 구현 func (ve VirError) Error() string { return string(ve) } + // err 구조체 정의 type ErrorDescriptor struct { - ErrorType VirError `json:"error type"` - Detail error `json:"detail"` + ErrorType VirError `json:"error type"` + Detail error `json:"detail"` } // err 구조체의 Error() 메서드 구현 @@ -65,20 +65,18 @@ func (e ErrorDescriptor) As(target interface{}) bool { return true } -func ErrorGen(baseError VirError, detailError error) error{ +func ErrorGen(baseError VirError, detailError error) error { return ErrorDescriptor{ - ErrorType:baseError, - Detail: detailError, + ErrorType: baseError, + Detail: detailError, } } -func ErrorJoin(baseError error ,appendingError error) error{ - v,ok := baseError.(ErrorDescriptor) - if !ok{ +func ErrorJoin(baseError error, appendingError error) error { + v, ok := baseError.(ErrorDescriptor) + if !ok { return ErrorGen(VirError(baseError.Error()), appendingError) } - v.Detail=fmt.Errorf("%w %w", appendingError, v.Detail) + v.Detail = fmt.Errorf("%w %w", appendingError, v.Detail) return v } - - diff --git a/main.go b/main.go index 57a6a51..ab00b02 100755 --- a/main.go +++ b/main.go @@ -9,6 +9,7 @@ import ( "github.com/easy-cloud-Knet/KWS_Core/api" syslogger "github.com/easy-cloud-Knet/KWS_Core/logger" "github.com/easy-cloud-Knet/KWS_Core/server" + "go.uber.org/zap" ) func main() { @@ -24,7 +25,9 @@ func main() { libvirtInst.LibvirtConnection() libvirtInst.DomainControl.DomainListStatus.Update() - libvirtInst.DomainControl.RetrieveAllDomain(libvirtInst.LibvirtInst, logger) + if err := libvirtInst.DomainControl.RetrieveAllDomain(libvirtInst.LibvirtInst, logger); err != nil { + logger.Fatal("failed to retrieve domains on startup", zap.Error(err)) + } go server.InitServer(8080, &libvirtInst, logger) defer func() { diff --git a/net/networkConf.go b/net/networkConf.go index ccf2d2c..7393111 100755 --- a/net/networkConf.go +++ b/net/networkConf.go @@ -5,4 +5,3 @@ import ( ) // systemd networkd 관리 - diff --git a/net/networkdParsor.go b/net/networkdParsor.go index cad7c6b..1ae2e9d 100644 --- a/net/networkdParsor.go +++ b/net/networkdParsor.go @@ -1,4 +1 @@ package network - - - diff --git a/net/type.go b/net/type.go index bdc3607..f8a5f2a 100755 --- a/net/type.go +++ b/net/type.go @@ -28,7 +28,5 @@ type NetInterface struct { type VnetInterface struct { } - -type Networkd struct{ - -} \ No newline at end of file +type Networkd struct { +} diff --git a/vm/parsor/XML_Parsor.go b/vm/parsor/XML_Parsor.go index f2fcfb3..2100ff4 100755 --- a/vm/parsor/XML_Parsor.go +++ b/vm/parsor/XML_Parsor.go @@ -92,7 +92,7 @@ func (XP *VM_CREATE_XML) XML_Parsor(spec *VM_Init_Info) error { InterfaceID: spec.SDNUUID, }, }, - MTU: MTU{ Size: 1450}, // MTU 설정 추가 + MTU: MTU{Size: 1450}, // MTU 설정 추가 Model: InterfaceModel{ Type: "virtio", }, diff --git a/vm/parsor/cloud-init/type.go b/vm/parsor/cloud-init/type.go index e145d28..8fd47a4 100755 --- a/vm/parsor/cloud-init/type.go +++ b/vm/parsor/cloud-init/type.go @@ -1,7 +1,5 @@ package userconfig - - type User_specific struct { Name string `yaml:"name,omitempty"` Passwd string `yaml:"passwd,omitempty"` @@ -12,7 +10,6 @@ type User_specific struct { Shell string `yaml:"shell,omitempty"` } - type User_write_file struct { Path string `yaml:"path"` Permissions string `yaml:"permissions"` @@ -26,8 +23,6 @@ type User_data_yaml struct { Runcmd []string `yaml:"runcmd"` } - - type Meta_data_yaml struct { Instance_ID string `yaml:"instance-id"` Local_Host_Id string `yaml:"local-hostname"` diff --git a/vm/parsor/type.go b/vm/parsor/type.go index d75893c..2b7fd4e 100755 --- a/vm/parsor/type.go +++ b/vm/parsor/type.go @@ -30,7 +30,7 @@ type User_info_VM struct { type HardwareInfo struct { CPU int `json:"cpu"` Memory int `json:"memory"` - Disk int `json:"disk"` + Disk int `json:"disk"` } // gonna replace fields in VM_Init_Info @@ -148,19 +148,19 @@ type ConsoleTarget struct { } type Interface struct { - Type string `xml:"type,attr"` - Source NetworkSource `xml:"source"` - Virtualport VirPort `xml:"virtualport"` + Type string `xml:"type,attr"` + Source NetworkSource `xml:"source"` + Virtualport VirPort `xml:"virtualport"` Model InterfaceModel `xml:"model"` - MacAddress MacAddress `xml:"mac"` - MTU MTU `xml:"mtu"` + MacAddress MacAddress `xml:"mac"` + MTU MTU `xml:"mtu"` } type MTU struct { Size int `xml:"size,attr"` } type VirPort struct { - Type string `xml:"type,attr"` + Type string `xml:"type,attr"` Parameter Parameter `xml:"parameters"` } type Parameter struct { @@ -186,5 +186,4 @@ type MacAddress struct { Address string `xml:"address,attr"` } - -// func VM_Init_Info \ No newline at end of file +// func VM_Init_Info diff --git a/vm/parsor/util.go b/vm/parsor/util.go index cf1c4fa..2542769 100644 --- a/vm/parsor/util.go +++ b/vm/parsor/util.go @@ -5,43 +5,42 @@ import ( "strings" ) - func UUIDValidator(uuid string) bool { - if len(uuid) != 36 { - return false - } - - // A quick check for path traversal characters. - // This is a good first line of defense. - if strings.ContainsAny(uuid, "/\\.") { - return false - } - - // Your original UUID format validation loop - for i, c := range uuid { - if (i == 8 || i == 13 || i == 18 || i == 23) && c != '-' { - return false - } - if (i != 8 && i != 13 && i != 18 && i != 23) && (c < '0' || c > '9') && (c < 'a' || c > 'f') && (c < 'A' || c > 'F') { - return false - } - } - return true + if len(uuid) != 36 { + return false + } + + // A quick check for path traversal characters. + // This is a good first line of defense. + if strings.ContainsAny(uuid, "/\\.") { + return false + } + + // Your original UUID format validation loop + for i, c := range uuid { + if (i == 8 || i == 13 || i == 18 || i == 23) && c != '-' { + return false + } + if (i != 8 && i != 13 && i != 18 && i != 23) && (c < '0' || c > '9') && (c < 'a' || c > 'f') && (c < 'A' || c > 'F') { + return false + } + } + return true } func GetSafeFilePath(baseDir, uuid string) (string, bool) { - if !filepath.IsAbs(baseDir) { - return "", false - } - if !UUIDValidator(uuid) { - return "", false - } - - fullPath := filepath.Join(baseDir, uuid) - cleanedPath := filepath.Clean(fullPath) - if !strings.HasPrefix(cleanedPath, baseDir) { - return "", false - } - - return cleanedPath, true + if !filepath.IsAbs(baseDir) { + return "", false + } + if !UUIDValidator(uuid) { + return "", false + } + + fullPath := filepath.Join(baseDir, uuid) + cleanedPath := filepath.Clean(fullPath) + if !strings.HasPrefix(cleanedPath, baseDir) { + return "", false + } + + return cleanedPath, true } diff --git a/vm/service/creation/common.go b/vm/service/creation/common.go index 41ded9f..602c1d5 100755 --- a/vm/service/creation/common.go +++ b/vm/service/creation/common.go @@ -8,8 +8,7 @@ import ( virerr "github.com/easy-cloud-Knet/KWS_Core/error" ) - -func (DB localConfigurer)CreateDiskImage(dirPath string, diskSize int) error { +func (DB localConfigurer) CreateDiskImage(dirPath string, diskSize int) error { baseImage := fmt.Sprintf("/var/lib/kws/baseimg/%s", DB.VMDescription.OS) targetImage := filepath.Join(dirPath, fmt.Sprintf("%s.qcow2", DB.VMDescription.UUID)) qemuImgCmd := exec.Command("qemu-img", "create", diff --git a/vm/service/creation/create_type.go b/vm/service/creation/create_type.go index b6a2896..764107a 100755 --- a/vm/service/creation/create_type.go +++ b/vm/service/creation/create_type.go @@ -14,23 +14,20 @@ import ( // 2. CreateVM 이후 생성이 성공적이였음을 확인할 경우, DomCon에 vm 을 추가할 것 // 3. /var/lib/kws/{uuid} 내부에 가상 하드디스크, vm config에 대한 내용응 가지고 있어야 함. - type VMCreator interface { CreateVM() (*libvirt.Domain, error) } - - -type LocalCreator struct{ +type LocalCreator struct { DomainConfiger *localConfigurer - libvirtInst *libvirt.Connect - logger *zap.Logger + libvirtInst *libvirt.Connect + logger *zap.Logger } -// LocalCreator가 json에서 읽어온 데이터를 통해 새로운 vm을 만들 때 사용됨. -// CreateVM()의 구현체 -type NewDomainFromSnapshot struct{ +// LocalCreator가 json에서 읽어온 데이터를 통해 새로운 vm을 만들 때 사용됨. +// CreateVM()의 구현체 +type NewDomainFromSnapshot struct { } type localConfigurer struct { diff --git a/vm/service/creation/local_domain.go b/vm/service/creation/local_domain.go index 912f15b..317f11a 100755 --- a/vm/service/creation/local_domain.go +++ b/vm/service/creation/local_domain.go @@ -15,7 +15,6 @@ import ( "libvirt.org/go/libvirt" ) - func LocalConfFactory(param *parsor.VM_Init_Info, logger *zap.Logger) *localConfigurer { return &localConfigurer{ VMDescription: param, @@ -25,21 +24,18 @@ func LocalConfFactory(param *parsor.VM_Init_Info, logger *zap.Logger) *localConf } } -func LocalCreatorFactory(confige *localConfigurer,libvirtInst *libvirt.Connect,logger *zap.Logger )(*LocalCreator){ +func LocalCreatorFactory(confige *localConfigurer, libvirtInst *libvirt.Connect, logger *zap.Logger) *LocalCreator { return &LocalCreator{ - DomainConfiger:confige, - libvirtInst:libvirtInst, - logger:logger, + DomainConfiger: confige, + libvirtInst: libvirtInst, + logger: logger, } } - - - -func (DCB *LocalCreator) CreateVM()(*domCon.Domain,error){ - //DomainConfiger 를 인터페이스로 둔다면 타입 체크로 분기 가능 - err:= DCB.DomainConfiger.Generate(DCB.libvirtInst,DCB.logger) - if err!=nil{ +func (DCB *LocalCreator) CreateVM() (*domCon.Domain, error) { + //DomainConfiger 를 인터페이스로 둔다면 타입 체크로 분기 가능 + err := DCB.DomainConfiger.Generate(DCB.libvirtInst, DCB.logger) + if err != nil { DCB.logger.Warn("error whiling configuring base Configures, ", zap.Error(err)) } @@ -47,51 +43,45 @@ func (DCB *LocalCreator) CreateVM()(*domCon.Domain,error){ if err != nil { errDesc := virerr.ErrorGen(virerr.DomainGenerationError, fmt.Errorf("in domain-Creator, XML marshaling error: %w", err)) DCB.logger.Error(errDesc.Error()) - return nil,errDesc + return nil, errDesc } - domain,err :=CreateDomainWithXML(DCB.libvirtInst,output) - if err!=nil{ + domain, err := CreateDomainWithXML(DCB.libvirtInst, output) + if err != nil { errDesc := virerr.ErrorGen(virerr.DomainGenerationError, fmt.Errorf("in domain-Creator, error occured from creating with libvirt: %w", err)) DCB.logger.Error(errDesc.Error()) - return nil,errDesc - + return nil, errDesc + } - err=domain.Create() - if err!=nil{ + err = domain.Create() + if err != nil { errDesc := virerr.ErrorGen(virerr.DomainGenerationError, fmt.Errorf("in domain-Creator, XML marshaling error: %w", err)) DCB.logger.Error(errDesc.Error()) - return nil,errDesc + return nil, errDesc } - domconDom:=domCon.NewDomainInstance(domain) - return domconDom,nil + domconDom := domCon.NewDomainInstance(domain) + return domconDom, nil } - - - -func (DB localConfigurer) Generate(LibvirtInst *libvirt.Connect, logger *zap.Logger) (error) { - dirPath,err := parsor.GetSafeFilePath("/var/lib/kws", DB.VMDescription.UUID) +func (DB localConfigurer) Generate(LibvirtInst *libvirt.Connect, logger *zap.Logger) error { + dirPath, err := parsor.GetSafeFilePath("/var/lib/kws", DB.VMDescription.UUID) if dirPath == "" { errDesc := fmt.Errorf("failed to generate safe file path for UUID %s %v", DB.VMDescription.UUID, err) logger.Error("failed to generate safe file path or some macilous attack happened. aborting", zap.Error(errDesc)) return virerr.ErrorGen(virerr.DomainGenerationError, errDesc) } - - - if err := os.MkdirAll(dirPath, 0755); err != nil { errDesc := fmt.Errorf("failed to create directory (%s)", dirPath) logger.Error("failed making directory", zap.Error(errDesc)) - return virerr.ErrorGen(virerr.DomainGenerationError, errDesc) + return virerr.ErrorGen(virerr.DomainGenerationError, errDesc) } // cloud-init 파일 처리 if err := DB.processCloudInitFiles(dirPath); err != nil { errorEncapsed := virerr.ErrorJoin(err, fmt.Errorf("in domain-parsor,")) logger.Error(errorEncapsed.Error()) - return errorEncapsed + return errorEncapsed } logger.Info("generating configuration file successfully done", zap.String("filePath", dirPath)) @@ -108,7 +98,9 @@ func (DB localConfigurer) Generate(LibvirtInst *libvirt.Connect, logger *zap.Log return err } - DB.DeviceDefiner.XML_Parsor(DB.VMDescription) + if err := DB.DeviceDefiner.XML_Parsor(DB.VMDescription); err != nil { + return virerr.ErrorGen(virerr.DomainGenerationError, fmt.Errorf("XML_Parsor error: %w", err)) + } return nil } @@ -135,7 +127,6 @@ func (DB localConfigurer) processCloudInitFiles(dirPath string) error { return nil } - func (DB localConfigurer) CreateISOFile(dirPath string) error { isoOutput := filepath.Join(dirPath, "cidata.iso") @@ -156,16 +147,16 @@ func (DB localConfigurer) CreateISOFile(dirPath string) error { return nil } - -func CreateDomainWithXML(LibvirtInst *libvirt.Connect ,config []byte) (*libvirt.Domain, error) { +func CreateDomainWithXML(LibvirtInst *libvirt.Connect, config []byte) (*libvirt.Domain, error) { // DomainCreateXMLWithFiles를 호출하여 도메인을 생성합니다. domain, err := LibvirtInst.DomainDefineXML(string(config)) if err != nil { - return nil, virerr.ErrorGen(virerr.DomainGenerationError,fmt.Errorf("domain creating with libvirt daemon from xml err %w", err)) + return nil, virerr.ErrorGen(virerr.DomainGenerationError, fmt.Errorf("domain creating with libvirt daemon from xml err %w", err)) // cpu나 ip 중복 등을 검사하는 코드를 삽입하고, 그에 맞는 에러 반환 필요 - } + } //이전까지 생성 된 파일 삭제 해야됨. - return domain ,nil + return domain, nil } -// local 파일에서 vm을 생성할 경우 사용 \ No newline at end of file + +// local 파일에서 vm을 생성할 경우 사용 diff --git a/vm/service/snapshot/external_metadata.go b/vm/service/snapshot/external_metadata.go index c3ed846..a75e5ff 100644 --- a/vm/service/snapshot/external_metadata.go +++ b/vm/service/snapshot/external_metadata.go @@ -6,7 +6,8 @@ import ( "strings" ) -const defaultSnapshotRoot = "/var/lib/kws" +// TODO: 실제 사용 시 아래 두 nolint 태그 제거할 것 +const defaultSnapshotRoot = "/var/lib/kws" //nolint:unused type ExternalSnapshotOptions struct { BaseDir string @@ -15,7 +16,7 @@ type ExternalSnapshotOptions struct { Live bool } -func resolveSnapshotRoot(opts *ExternalSnapshotOptions) (string, error) { +func resolveSnapshotRoot(opts *ExternalSnapshotOptions) (string, error) { //nolint:unused if opts == nil || opts.BaseDir == "" { return defaultSnapshotRoot, nil } diff --git a/vm/service/termination/delete_domain.go b/vm/service/termination/delete_domain.go index f1af15a..5de315b 100755 --- a/vm/service/termination/delete_domain.go +++ b/vm/service/termination/delete_domain.go @@ -11,27 +11,26 @@ import ( "libvirt.org/go/libvirt" ) - func DomainDeleterFactory(Domain *domCon.Domain, DelType DomainDeleteType, uuid string) (*DomainDeleter, error) { return &DomainDeleter{ - uuid:uuid, - domain: Domain, + uuid: uuid, + domain: Domain, DeletionType: DelType, - }, nil + }, nil } -func (DD *DomainDeleter) DeleteDomain() (*libvirt.Domain,error){ +func (DD *DomainDeleter) DeleteDomain() (*libvirt.Domain, error) { dom := DD.domain isRunning, _ := dom.Domain.IsActive() if isRunning && DD.DeletionType == SoftDelete { - return nil,virerr.ErrorGen(virerr.DeletionDomainError, fmt.Errorf("domain is running, cannot softDelete running domain")) + return nil, virerr.ErrorGen(virerr.DeletionDomainError, fmt.Errorf("domain is running, cannot softDelete running domain")) } else if isRunning && DD.DeletionType == HardDelete { DomainTerminator := &DomainTerminator{domain: dom} - _,err := DomainTerminator.TerminateDomain() + _, err := DomainTerminator.TerminateDomain() if err != nil { - return nil,virerr.ErrorGen(virerr.DeletionDomainError, fmt.Errorf("failed deleting domain in libvirt instance: %w", err)) + return nil, virerr.ErrorGen(virerr.DeletionDomainError, fmt.Errorf("failed deleting domain in libvirt instance: %w", err)) } } basicFilePath := "/var/lib/kws/" @@ -41,13 +40,12 @@ func (DD *DomainDeleter) DeleteDomain() (*libvirt.Domain,error){ deleteCmd.Stderr = os.Stderr if err := deleteCmd.Run(); err != nil { - return nil,virerr.ErrorGen(virerr.DeletionDomainError, fmt.Errorf("failed deleting files in %s: %w", FilePath, err)) + return nil, virerr.ErrorGen(virerr.DeletionDomainError, fmt.Errorf("failed deleting files in %s: %w", FilePath, err)) } if err := dom.Domain.Undefine(); err != nil { - return nil,virerr.ErrorGen(virerr.DeletionDomainError, fmt.Errorf("failed deleting domain in libvirt instance: %w", err)) + return nil, virerr.ErrorGen(virerr.DeletionDomainError, fmt.Errorf("failed deleting domain in libvirt instance: %w", err)) } - - return dom.Domain,nil + return dom.Domain, nil } diff --git a/vm/service/termination/terminate_domain.go b/vm/service/termination/terminate_domain.go index 4ef8b6c..138f32b 100755 --- a/vm/service/termination/terminate_domain.go +++ b/vm/service/termination/terminate_domain.go @@ -19,11 +19,11 @@ func (DD *DomainTerminator) TerminateDomain() (*libvirt.Domain, error) { isRunning, err := dom.Domain.IsActive() if !isRunning { - return nil,virerr.ErrorGen(virerr.DomainShutdownError, fmt.Errorf("error checking domain's aliveness, from libvirt. %w", err)) + return nil, virerr.ErrorGen(virerr.DomainShutdownError, fmt.Errorf("error checking domain's aliveness, from libvirt. %w", err)) } if err := dom.Domain.Destroy(); err != nil { - return nil,virerr.ErrorGen(virerr.DomainShutdownError, fmt.Errorf("error shutting down domain, from libvirt. %w, %v", err,DD)) + return nil, virerr.ErrorGen(virerr.DomainShutdownError, fmt.Errorf("error shutting down domain, from libvirt. %w, %v", err, DD)) } return dom.Domain, nil diff --git a/vm/service/termination/terminator_type.go b/vm/service/termination/terminator_type.go index 0be07ce..7eebe16 100755 --- a/vm/service/termination/terminator_type.go +++ b/vm/service/termination/terminator_type.go @@ -12,19 +12,19 @@ const ( SoftDelete ) -type DomainDeletion interface{ - DeleteDomain() (*libvirt.Domain,error) +type DomainDeletion interface { + DeleteDomain() (*libvirt.Domain, error) } -type DomainTermination interface{ - TerminateDomain() (*libvirt.Domain,error) +type DomainTermination interface { + TerminateDomain() (*libvirt.Domain, error) } type DomainTerminator struct { domain *domCon.Domain } type DomainDeleter struct { - uuid string - domain *domCon.Domain - DeletionType DomainDeleteType + uuid string + domain *domCon.Domain + DeletionType DomainDeleteType }