Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
S
Secure solution for nexus infrastructure
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Wiki
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Snippets
Build
Pipelines
Jobs
Pipeline schedules
Artifacts
Deploy
Releases
Package registry
Model registry
Operate
Environments
Terraform modules
Monitor
Incidents
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
GitLab community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
flg_masters
TM
Secure solution for nexus infrastructure
Commits
8c1f7902
Commit
8c1f7902
authored
Sep 1, 2022
by
Florent Gluck
Browse files
Options
Downloads
Patches
Plain Diff
Updated VM import/export to be simpler and more robust
parent
f01c77e1
Branches
Branches containing commit
No related tags found
No related merge requests found
Changes
4
Show whitespace changes
Inline
Side-by-side
Showing
4 changed files
src/exec/VirtTarIn.go
+44
-0
44 additions, 0 deletions
src/exec/VirtTarIn.go
src/exec/VirtTarOut.go
+47
-0
47 additions, 0 deletions
src/exec/VirtTarOut.go
src/router/routerVMs.go
+7
-40
7 additions, 40 deletions
src/router/routerVMs.go
src/vms/vms.go
+3
-3
3 additions, 3 deletions
src/vms/vms.go
with
101 additions
and
43 deletions
src/exec/Virt
Copy
In.go
→
src/exec/Virt
Tar
In.go
+
44
−
0
View file @
8c1f7902
...
...
@@ -8,33 +8,31 @@ import (
)
const
(
virt
copyi
nBinary
=
"virt-
copy
-in"
virt
TarI
nBinary
=
"virt-
tar
-in"
)
// Check virt-
copy
-in is available.
func
CheckVirt
Copy
In
()
error
{
output
,
err
:=
exec
.
Command
(
virt
copyi
nBinary
,
"--version"
)
.
Output
()
// Check
s
virt-
tar
-in is available.
func
CheckVirt
Tar
In
()
error
{
output
,
err
:=
exec
.
Command
(
virt
TarI
nBinary
,
"--version"
)
.
Output
()
if
err
!=
nil
{
return
errors
.
New
(
virt
copyi
nBinary
+
" is required but not found. On Ubuntu/Debian, it can be installed with
\"
sudo apt-get install guestfish
\"
."
)
return
errors
.
New
(
virt
TarI
nBinary
+
" is required but not found. On Ubuntu/Debian, it can be installed with
\"
sudo apt-get install guestfish
\"
."
)
}
out
:=
string
(
output
)
lines
:=
strings
.
Split
(
out
,
"
\n
"
)
fields
:=
strings
.
Split
(
lines
[
0
],
" "
)
if
len
(
fields
)
<
2
{
return
errors
.
New
(
"Failed extracting "
+
virt
copyi
nBinary
+
" version number!"
)
return
errors
.
New
(
"Failed extracting "
+
virt
TarI
nBinary
+
" version number!"
)
}
cmd
:=
fields
[
0
]
if
cmd
!=
virt
copyi
nBinary
{
return
errors
.
New
(
virt
copyi
nBinary
+
" is required, but not found."
)
if
cmd
!=
virt
TarI
nBinary
{
return
errors
.
New
(
virt
TarI
nBinary
+
" is required, but not found."
)
}
return
nil
}
// Creates a virt-copy-in command that recursively copy a directory on the host (localDir)
// into a directory on the VM's filesystem (vmDir).
// Note: both directories must exist, otherwise the command will fail.
func
CopyToVM
(
vmDiskFile
,
localDir
,
vmDir
string
)
error
{
cmd
:=
exec
.
Command
(
virtcopyinBinary
,
"-a"
,
vmDiskFile
,
localDir
,
vmDir
)
// Runs virt-tar-in which unarchive a local archive into a directory (vmDir) inside the VM disk.
func
CopyToVM
(
vmDiskFile
,
tarFile
,
vmDir
string
)
error
{
cmd
:=
exec
.
Command
(
virtTarInBinary
,
"-a"
,
vmDiskFile
,
tarFile
,
vmDir
)
stdoutStderr
,
err
:=
cmd
.
CombinedOutput
()
if
err
!=
nil
{
output
:=
fmt
.
Sprintf
(
"[%s]"
,
stdoutStderr
)
...
...
This diff is collapsed.
Click to expand it.
src/exec/Virt
Copy
Out.go
→
src/exec/Virt
Tar
Out.go
+
47
−
0
View file @
8c1f7902
...
...
@@ -8,33 +8,34 @@ import (
)
const
(
virt
copyo
utBinary
=
"virt-
copy
-out"
virt
TarO
utBinary
=
"virt-
tar
-out"
)
// Check virt-
copy
-out is available.
// Check
s
virt-
tar
-out is available.
func
CheckVirtCopyOut
()
error
{
output
,
err
:=
exec
.
Command
(
virt
copyo
utBinary
,
"--version"
)
.
Output
()
output
,
err
:=
exec
.
Command
(
virt
TarO
utBinary
,
"--version"
)
.
Output
()
if
err
!=
nil
{
return
errors
.
New
(
virt
copyo
utBinary
+
" is required but not found. On Ubuntu/Debian, it can be installed with
\"
sudo apt-get install guestfish
\"
."
)
return
errors
.
New
(
virt
TarO
utBinary
+
" is required but not found. On Ubuntu/Debian, it can be installed with
\"
sudo apt-get install guestfish
\"
."
)
}
out
:=
string
(
output
)
lines
:=
strings
.
Split
(
out
,
"
\n
"
)
fields
:=
strings
.
Split
(
lines
[
0
],
" "
)
if
len
(
fields
)
<
2
{
return
errors
.
New
(
"Failed extracting "
+
virt
copyo
utBinary
+
" version number!"
)
return
errors
.
New
(
"Failed extracting "
+
virt
TarO
utBinary
+
" version number!"
)
}
cmd
:=
fields
[
0
]
if
cmd
!=
virt
copyo
utBinary
{
return
errors
.
New
(
virt
copyo
utBinary
+
" is required, but not found."
)
if
cmd
!=
virt
TarO
utBinary
{
return
errors
.
New
(
virt
TarO
utBinary
+
" is required, but not found."
)
}
return
nil
}
// Creates a virt-copy-out command that recursively copies a directory from the VM's
// filesystem (vmDir) into a directory on the host (localDir).
// Note: both directories must exist, otherwise the command will fail.
func
CopyFromVM
(
vmDiskFile
,
vmDir
,
localDir
string
)
error
{
cmd
:=
exec
.
Command
(
virtcopyoutBinary
,
"-a"
,
vmDiskFile
,
vmDir
,
localDir
)
// Runs virt-tar-in which unarchive a local archive into a directory (vmDir) inside the VM disk.
// Runs virt-copy-out which recursively extract a directory from the VM's
// filesystem (vmDir) into a tar archive.
func
CopyFromVM
(
vmDiskFile
,
vmDir
,
tarFile
string
)
error
{
cmd
:=
exec
.
Command
(
virtTarOutBinary
,
"-a"
,
vmDiskFile
,
vmDir
,
tarFile
)
stdoutStderr
,
err
:=
cmd
.
CombinedOutput
()
if
err
!=
nil
{
output
:=
fmt
.
Sprintf
(
"[%s]"
,
stdoutStderr
)
...
...
This diff is collapsed.
Click to expand it.
src/router/routerVMs.go
+
7
−
40
View file @
8c1f7902
...
...
@@ -9,7 +9,6 @@ import (
"nexus-server/caps"
"nexus-server/users"
"nexus-server/paths"
"nexus-server/utils"
"github.com/google/uuid"
"github.com/labstack/echo/v4"
"github.com/go-playground/validator/v10"
...
...
@@ -445,32 +444,16 @@ func (r *RouterVMs)ExportVMDir(c echo.Context) error {
return
echo
.
NewHTTPError
(
http
.
StatusBadRequest
,
err
.
Error
())
}
// Creates a unique t
emporary directory in which the VM's dir will be recursively copied
.
// Creates a unique t
ar filename
.
tmpDir
:=
paths
.
GetInstance
()
.
TmpDir
uniqTmpDir
:=
filepath
.
Join
(
tmpDir
,
"exportdir_"
+
vm
.
ID
.
String
())
if
err
:=
os
.
Mkdir
(
uniqTmpDir
,
0750
);
err
!=
nil
{
log
.
Error
(
"Failed creating tmp dir for VM dir copy: "
+
err
.
Error
())
return
echo
.
NewHTTPError
(
http
.
StatusInternalServerError
,
"Failed creating tmp dir for VM dir copy"
)
}
defer
func
(
dir
string
)
{
if
err
:=
os
.
RemoveAll
(
dir
);
err
!=
nil
{
log
.
Error
(
"Failed removing tmp dir for VM dir copy: "
+
err
.
Error
())
}
}(
uniqTmpDir
)
// Extracts VM's p.Dir directory inside uniqTmpDir directory on the host.
if
err
:=
r
.
vms
.
ExportVMFiles
(
vm
,
p
.
Dir
,
uniqTmpDir
);
err
!=
nil
{
return
echo
.
NewHTTPError
(
http
.
StatusBadRequest
,
"Failed reading VM's dir"
)
}
// Creates a tar archive from the extracted VM directory.
tarFile
:=
filepath
.
Join
(
tmpDir
,
"exportdir_"
+
vm
.
ID
.
String
()
+
".tar"
)
if
err
:=
utils
.
TarDir
(
uniqTmpDir
,
tarFile
);
err
!=
nil
{
log
.
Error
(
"Failed creating archive
\"
"
+
tarFile
+
"
\"
: "
+
err
.
Error
())
return
echo
.
NewHTTPError
(
http
.
StatusInternalServerError
,
"Failed creating VM's dir archive"
)
// Extracts VM's p.Dir directory into tarFile on the host.
if
err
:=
r
.
vms
.
ExportVMFiles
(
vm
,
p
.
Dir
,
tarFile
);
err
!=
nil
{
return
echo
.
NewHTTPError
(
http
.
StatusBadRequest
,
"Failed extracting VM's dir"
)
}
// Sends the archive back to the client and once
done
, deletes it.
// Sends the archive back to the client and once
completed
, deletes it.
defer
func
(
file
string
)
{
if
err
:=
os
.
Remove
(
file
);
err
!=
nil
{
log
.
Error
(
"Failed removing archive of extracted VM dir: "
+
err
.
Error
())
...
...
@@ -489,7 +472,6 @@ func (r *RouterVMs)ImportFilesToVM(c echo.Context) error {
return
r
.
performVMAction
(
c
,
caps
.
CAP_VM_WRITEFS_ANY
,
caps
.
CAP_VM_WRITEFS
,
func
(
c
echo
.
Context
,
vm
*
vms
.
VM
)
error
{
// Retrieves the various client arguments.
vmDir
:=
c
.
FormValue
(
"vmDir"
)
localDir
:=
c
.
FormValue
(
"localDir"
)
// Retrieves the tar archive (uploadedTarFile).
tarFile
,
err
:=
c
.
FormFile
(
"file"
)
...
...
@@ -521,24 +503,9 @@ func (r *RouterVMs)ImportFilesToVM(c echo.Context) error {
return
echo
.
NewHTTPError
(
http
.
StatusInternalServerError
,
err
.
Error
())
}
// Extracts the archive into tmpExtractDir.
tmpExtractDir
:=
filepath
.
Join
(
tmpDir
,
"upload_"
+
uuid
.
String
())
if
err
:=
os
.
Mkdir
(
tmpExtractDir
,
0750
);
err
!=
nil
{
msg
:=
"ImportFilesToVM: failed creating dir: "
+
err
.
Error
()
log
.
Error
(
msg
)
return
echo
.
NewHTTPError
(
http
.
StatusInternalServerError
,
msg
)
}
defer
os
.
RemoveAll
(
tmpExtractDir
)
if
err
:=
utils
.
Untar
(
uploadedTarFile
,
tmpExtractDir
);
err
!=
nil
{
msg
:=
"ImportFilesToVM: failed unarchiving tarball: "
+
err
.
Error
()
log
.
Error
(
msg
)
return
echo
.
NewHTTPError
(
http
.
StatusInternalServerError
,
msg
)
}
// Copy the archive's files into the VM
// IMPORTANT: check the VM is NOT running!
if
err
=
r
.
vms
.
ImportFilesToVM
(
vm
,
filepath
.
Join
(
tmpExtractDir
,
localDir
)
,
vmDir
);
err
!=
nil
{
if
err
=
r
.
vms
.
ImportFilesToVM
(
vm
,
uploadedTarFile
,
vmDir
);
err
!=
nil
{
return
echo
.
NewHTTPError
(
http
.
StatusBadRequest
,
err
.
Error
())
}
...
...
This diff is collapsed.
Click to expand it.
src/vms/vms.go
+
3
−
3
View file @
8c1f7902
...
...
@@ -364,10 +364,10 @@ func (vms *VMs)DeleteVMAccess(vmID uuid.UUID, loggedUserEmail, userEmail string)
return
nil
}
// Exports a VM's directory and its subdirectories into
the specified directory
on the host.
func
(
vms
*
VMs
)
ExportVMFiles
(
vm
*
VM
,
vmDir
,
hostDir
string
)
error
{
// Exports a VM's directory and its subdirectories into
a tar archive
on the host.
func
(
vms
*
VMs
)
ExportVMFiles
(
vm
*
VM
,
vmDir
,
tarFile
string
)
error
{
vmDisk
:=
vm
.
getDiskPath
()
return
exec
.
CopyFromVM
(
vmDisk
,
vmDir
,
hostDir
)
return
exec
.
CopyFromVM
(
vmDisk
,
vmDir
,
tarFile
)
}
// Import files into a VM's filesystem, in a specified directory.
...
...
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
sign in
to comment