diff --git a/src/client/cmdVM/vmImportDir.go b/src/client/cmdVM/vmImportDir.go index 60421183ea4bed76ebf6f094301a7c0dfac49e7d..1507bae0912072f61106b6f2556c354ac08ba0e4 100644 --- a/src/client/cmdVM/vmImportDir.go +++ b/src/client/cmdVM/vmImportDir.go @@ -3,7 +3,6 @@ package cmdVM import ( u "nexus-client/utils" cu "nexus-common/utils" - "nexus-libclient/utils" libclient "nexus-libclient/vm" "os" ) @@ -67,7 +66,7 @@ func (cmd *ImportDir) Run(args []string) int { } tmpTarGzFile += ".tar.gz" defer os.Remove(tmpTarGzFile) - if err := utils.TarGzDir(localDir, tmpTarGzFile); err != nil { + if err := cu.TarGzDir(localDir, tmpTarGzFile); err != nil { u.PrintlnErr(err) return 1 } diff --git a/src/common/utils/files.go b/src/common/utils/files.go index 600f5fb4a8901b27bffd29dc2ab5c3f952e05603..e83cab568bb4762b10382d985d22a52d077180d6 100644 --- a/src/common/utils/files.go +++ b/src/common/utils/files.go @@ -1,9 +1,15 @@ package utils import ( + "archive/tar" + "bytes" + "compress/gzip" "errors" + "io" + "io/fs" "os" "path/filepath" + "strings" "github.com/google/uuid" ) @@ -38,3 +44,107 @@ func CreateRandomEmptyFile() (string, error) { return filePath, nil } + +// Creates a tar.gz archive of dir and all its files and subdirectories. +// Note: dir can also be a file. +// Source code slightly modified from: https://gist.github.com/mimoo/25fc9716e0f1353791f5908f94d6e726 +func TarGzDir(dir, archive string) error { + _, err := os.Stat(dir) + if errors.Is(err, fs.ErrNotExist) { + return errors.New("Error: \"" + dir + "\" does not exist") + } + + var buf bytes.Buffer + + gzWriter := gzip.NewWriter(&buf) + tarWriter := tar.NewWriter(gzWriter) + + // Walks through every file in the directory + filepath.Walk(dir, func(file string, fi os.FileInfo, e error) error { + header, err := tar.FileInfoHeader(fi, file) + if err != nil { + return err + } + + fileRel := strings.TrimPrefix(file, dir) + fileRel = filepath.Join(filepath.Base(dir), fileRel) + header.Name = filepath.ToSlash(fileRel) + + if err := tarWriter.WriteHeader(header); err != nil { + return err + } + // if not a dir, write file content + if !fi.IsDir() { + data, err := os.Open(file) + if err != nil { + return err + } + if _, err := io.Copy(tarWriter, data); err != nil { + return err + } + } + return nil + }) + + if err := tarWriter.Close(); err != nil { + return err + } + if err := gzWriter.Close(); err != nil { + return err + } + + fileToWrite, err := os.OpenFile(archive, os.O_CREATE|os.O_RDWR, os.FileMode(0750)) + if err != nil { + return err + } + if _, err := io.Copy(fileToWrite, &buf); err != nil { + return err + } + + return nil +} + +// Returns the list of subdirectories present in dir. +func GetSubDirs(dir string) ([]string, error) { + subDirs := []string{} + + currentDir, err := os.Open(dir) + if err != nil { + return nil, err + } + + // Retrieves all files entries in the directory (0 = all files in the directory). + files, err := currentDir.Readdir(0) + if err != nil { + currentDir.Close() + return nil, err + } + + currentDir.Close() + + // Loop over file entries + for _, f := range files { + if f.IsDir() { + subDirs = append(subDirs, filepath.Join(dir, f.Name())) + } + } + + return subDirs, nil +} + +func CopyFiles(source, dest string) error { + src, err := os.Open(source) + if err != nil { + return err + } + defer src.Close() + + dst, err := os.Create(dest) + if err != nil { + return err + } + defer dst.Close() + _, err = io.Copy(dst, src) + + return err +} diff --git a/src/libclient/go.mod b/src/libclient/go.mod index c70650134288db7317bc630162112b449fd69d52..ce6b5963d314da076922d0b489c46e8c0a0697e4 100644 --- a/src/libclient/go.mod +++ b/src/libclient/go.mod @@ -6,9 +6,19 @@ replace nexus-common => ../common require nexus-common v0.0.0-00010101000000-000000000000 -require golang.org/x/net v0.27.0 // indirect +require ( + github.com/gabriel-vasile/mimetype v1.4.3 // indirect + github.com/go-playground/locales v0.14.1 // indirect + github.com/go-playground/universal-translator v0.18.1 // indirect + github.com/leodido/go-urn v1.4.0 // indirect + golang.org/x/crypto v0.25.0 // indirect + golang.org/x/net v0.27.0 // indirect + golang.org/x/sys v0.22.0 // indirect + golang.org/x/text v0.16.0 // indirect +) require ( + github.com/go-playground/validator/v10 v10.23.0 github.com/go-resty/resty/v2 v2.16.2 - github.com/google/uuid v1.6.0 // indirect + github.com/google/uuid v1.6.0 ) diff --git a/src/libclient/go.sum b/src/libclient/go.sum index 5060da736650c97cec6eb978d30c4256168b46a3..58ff6fbbafcb9337813e3153a45c349b39ff4be2 100644 --- a/src/libclient/go.sum +++ b/src/libclient/go.sum @@ -1,6 +1,22 @@ +github.com/gabriel-vasile/mimetype v1.4.3 h1:in2uUcidCuFcDKtdcBxlR0rJ1+fsokWf+uqxgUFjbI0= +github.com/gabriel-vasile/mimetype v1.4.3/go.mod h1:d8uq/6HKRL6CGdk+aubisF/M5GcPfT7nKyLpA0lbSSk= +github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/oXslEjJA= +github.com/go-playground/locales v0.14.1/go.mod h1:hxrqLVvrK65+Rwrd5Fc6F2O76J/NuW9t0sjnWqG1slY= +github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJnYK9S473LQFuzCbDbfSFY= +github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY= +github.com/go-playground/validator/v10 v10.23.0 h1:/PwmTwZhS0dPkav3cdK9kV1FsAmrL8sThn8IHr/sO+o= +github.com/go-playground/validator/v10 v10.23.0/go.mod h1:dbuPbCMFw/DrkbEynArYaCwl3amGuJotoKCe95atGMM= github.com/go-resty/resty/v2 v2.16.2 h1:CpRqTjIzq/rweXUt9+GxzzQdlkqMdt8Lm/fuK/CAbAg= github.com/go-resty/resty/v2 v2.16.2/go.mod h1:0fHAoK7JoBy/Ch36N8VFeMsK7xQOHhvWaC3iOktwmIU= github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/leodido/go-urn v1.4.0 h1:WT9HwE9SGECu3lg4d/dIA+jxlljEa1/ffXKmRjqdmIQ= +github.com/leodido/go-urn v1.4.0/go.mod h1:bvxc+MVxLKB4z00jd1z+Dvzr47oO32F/QSNjSBOlFxI= +golang.org/x/crypto v0.25.0 h1:ypSNr+bnYL2YhwoMt2zPxHFmbAN1KZs/njMG3hxUp30= +golang.org/x/crypto v0.25.0/go.mod h1:T+wALwcMOSE0kXgUAnPAHqTLW+XHgcELELW8VaDgm/M= golang.org/x/net v0.27.0 h1:5K3Njcw06/l2y9vpGCSdcxWOYHOUk3dVNGDXN+FvAys= golang.org/x/net v0.27.0/go.mod h1:dDi0PyhWNoiUOrAS8uXv/vnScO4wnHQO4mj9fn/RytE= +golang.org/x/sys v0.22.0 h1:RI27ohtqKCnwULzJLqkv897zojh5/DwS/ENaMzUOaWI= +golang.org/x/sys v0.22.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/text v0.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4= +golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI= diff --git a/src/libclient/utils/files.go b/src/libclient/utils/files.go deleted file mode 100644 index c8dcf2d4c0164d984efb4a7873485b0eb61fa4be..0000000000000000000000000000000000000000 --- a/src/libclient/utils/files.go +++ /dev/null @@ -1,72 +0,0 @@ -package utils - -import ( - "archive/tar" - "bytes" - "compress/gzip" - "errors" - "io" - "io/fs" - "os" - "path/filepath" - "strings" -) - -// Creates a tar.gz archive of dir and all its files and subdirectories. -// Note: dir can also be a file. -// Source code slightly modified from: https://gist.github.com/mimoo/25fc9716e0f1353791f5908f94d6e726 -func TarGzDir(dir, archive string) error { - _, err := os.Stat(dir) - if errors.Is(err, fs.ErrNotExist) { - return errors.New("Error: \"" + dir + "\" does not exist") - } - - var buf bytes.Buffer - - gzWriter := gzip.NewWriter(&buf) - tarWriter := tar.NewWriter(gzWriter) - - // Walks through every file in the directory - filepath.Walk(dir, func(file string, fi os.FileInfo, err error) error { - header, err := tar.FileInfoHeader(fi, file) - if err != nil { - return err - } - - fileRel := strings.TrimPrefix(file, dir) - fileRel = filepath.Join(filepath.Base(dir), fileRel) - header.Name = filepath.ToSlash(fileRel) - - if err := tarWriter.WriteHeader(header); err != nil { - return err - } - // if not a dir, write file content - if !fi.IsDir() { - data, err := os.Open(file) - if err != nil { - return err - } - if _, err := io.Copy(tarWriter, data); err != nil { - return err - } - } - return nil - }) - - if err := tarWriter.Close(); err != nil { - return err - } - if err := gzWriter.Close(); err != nil { - return err - } - - fileToWrite, err := os.OpenFile(archive, os.O_CREATE|os.O_RDWR, os.FileMode(0750)) - if err != nil { - return err - } - if _, err := io.Copy(fileToWrite, &buf); err != nil { - return err - } - - return nil -} diff --git a/src/server/utils/files.go b/src/server/utils/files.go deleted file mode 100644 index 67351766868bc956970d6ff447e3ecdcefe1615a..0000000000000000000000000000000000000000 --- a/src/server/utils/files.go +++ /dev/null @@ -1,52 +0,0 @@ -package utils - -import ( - "io" - "os" - "path/filepath" -) - -// Returns the list of subdirectories present in dir. -func GetSubDirs(dir string) ([]string, error) { - subDirs := []string{} - - currentDir, err := os.Open(dir) - if err != nil { - return nil, err - } - - // Retrieves all files entries in the directory (0 = all files in the directory). - files, err := currentDir.Readdir(0) - if err != nil { - currentDir.Close() - return nil, err - } - - currentDir.Close() - - // Loop over file entries - for _, f := range files { - if f.IsDir() { - subDirs = append(subDirs, filepath.Join(dir, f.Name())) - } - } - - return subDirs, nil -} - -func CopyFiles(source, dest string) error { - src, err := os.Open(source) - if err != nil { - return err - } - defer src.Close() - - dst, err := os.Create(dest) - if err != nil { - return err - } - defer dst.Close() - _, err = io.Copy(dst, src) - - return err -} diff --git a/src/server/utils/random.go b/src/server/utils/random.go index 85942a09844daeace7a5019312dd742533547e99..5c8d3b068ef89e037250e19e505d27544ec69cbd 100644 --- a/src/server/utils/random.go +++ b/src/server/utils/random.go @@ -5,12 +5,15 @@ import ( "time" ) +var r *rand.Rand + // Initializes the random number generator. func RandInit() { - rand.Seed(time.Now().UnixNano()) + randSrc := rand.NewSource(time.Now().UnixNano()) + r = rand.New(randSrc) } // Returns an int in the range [min,max] (both inclusive). func Rand(min, max int) int { - return rand.Intn(max-min+1) + min + return r.Intn(max-min+1) + min } diff --git a/src/server/vms/template.go b/src/server/vms/template.go index 234dc6cf36a557b540a39d0a575a32813e7c4ae5..ae45fad6d6713da6db6eaeda55b07da64409774e 100644 --- a/src/server/vms/template.go +++ b/src/server/vms/template.go @@ -4,8 +4,8 @@ import ( "encoding/json" "errors" "nexus-common/template" + "nexus-common/utils" "nexus-server/exec" - "nexus-server/utils" "os" "path/filepath" "time" diff --git a/src/server/vms/templates.go b/src/server/vms/templates.go index 8227293d63d9ba13f94aac4d74001a4193dbf846..d4e22f868269acd53c961db3da94b1f7210fe1fa 100644 --- a/src/server/vms/templates.go +++ b/src/server/vms/templates.go @@ -3,7 +3,7 @@ package vms import ( "errors" t "nexus-common/template" - "nexus-server/utils" + "nexus-common/utils" "os" "path" "path/filepath" diff --git a/src/server/vms/vms.go b/src/server/vms/vms.go index edb1a7060c2b3f594aafa0584de36dac7ad14b1f..bb379669877d71097950d06f2aa828ba8cca11ec 100644 --- a/src/server/vms/vms.go +++ b/src/server/vms/vms.go @@ -6,6 +6,7 @@ import ( "math" "nexus-common/caps" "nexus-common/params" + cu "nexus-common/utils" vmc "nexus-common/vm" "nexus-server/config" "nexus-server/exec" @@ -62,19 +63,19 @@ func InitVMs() error { vms.usedPorts[conf.Core.APIDefaultPort] = true errMsg := "Failed reading VMs directory: " - dirs1, err := utils.GetSubDirs(vmsDir) + dirs1, err := cu.GetSubDirs(vmsDir) if err != nil { return errors.New(errMsg + err.Error()) } for d1 := range dirs1 { - dirs2, err := utils.GetSubDirs(dirs1[d1]) + dirs2, err := cu.GetSubDirs(dirs1[d1]) if err != nil { return errors.New(errMsg + err.Error()) } for d2 := range dirs2 { - dirs3, err := utils.GetSubDirs(dirs2[d2]) + dirs3, err := cu.GetSubDirs(dirs2[d2]) if err != nil { return errors.New(errMsg + err.Error()) }