mirror of
https://github.com/OpenNebula/one.git
synced 2024-12-22 13:33:52 +03:00
F #1684: Support for LXD/LXC Containers. The LXD/LXC drivers are heavily
inspired by the LXD addon https://github.com/OpenNebula/addon-lxdone. Co-authored-by: Daniel Clavijo Coca <dclavijo@opennebula.systems> Co-authored-by: Sergio Vega Gutiérrez <svega@opennebula.systems> Co-authored-by: José Manuel de la Fé Herrero <jmdelafe92@gmail.com>
This commit is contained in:
parent
175e9456ce
commit
07399094b3
4
.gitignore
vendored
4
.gitignore
vendored
@ -21,6 +21,8 @@ src/oca/java/jar
|
|||||||
src/oca/java/share/doc
|
src/oca/java/share/doc
|
||||||
src/oca/java/java-oca*.tar.gz
|
src/oca/java/java-oca*.tar.gz
|
||||||
|
|
||||||
|
src/vmm_mad/remotes/lxd/tests/
|
||||||
|
|
||||||
src/docker_machine/pkg
|
src/docker_machine/pkg
|
||||||
src/docker_machine/src/docker_machine/bin/docker-machine-driver-opennebula
|
src/docker_machine/src/docker_machine/bin/docker-machine-driver-opennebula
|
||||||
src/docker_machine/src/docker_machine/vendor/
|
src/docker_machine/src/docker_machine/vendor/
|
||||||
@ -36,3 +38,5 @@ src/sunstone/public/locale/languages/*.js
|
|||||||
|
|
||||||
share/esx-fw-vnc/*.rpm
|
share/esx-fw-vnc/*.rpm
|
||||||
share/esx-fw-vnc/.vagrant*
|
share/esx-fw-vnc/.vagrant*
|
||||||
|
|
||||||
|
*.vscode
|
||||||
|
62
SConstruct
Normal file → Executable file
62
SConstruct
Normal file → Executable file
@ -21,11 +21,11 @@ sys.path.append("./share/scons")
|
|||||||
from lex_bison import *
|
from lex_bison import *
|
||||||
|
|
||||||
# This is the absolute path where the project is located
|
# This is the absolute path where the project is located
|
||||||
cwd=os.getcwd()
|
cwd = os.getcwd()
|
||||||
|
|
||||||
# Environment that will be applied to each scons child
|
# Environment that will be applied to each scons child
|
||||||
main_env=Environment()
|
main_env = Environment()
|
||||||
main_env['ENV']['PATH']=os.environ['PATH']
|
main_env['ENV']['PATH'] = os.environ['PATH']
|
||||||
|
|
||||||
# snippet borrowed from http://dev.gentoo.org/~vapier/scons-blows.txt
|
# snippet borrowed from http://dev.gentoo.org/~vapier/scons-blows.txt
|
||||||
# makes scons aware of build related environment variables
|
# makes scons aware of build related environment variables
|
||||||
@ -40,7 +40,7 @@ if os.environ.has_key('CXXFLAGS'):
|
|||||||
if os.environ.has_key('LDFLAGS'):
|
if os.environ.has_key('LDFLAGS'):
|
||||||
main_env['LINKFLAGS'] += SCons.Util.CLVar(os.environ['LDFLAGS'])
|
main_env['LINKFLAGS'] += SCons.Util.CLVar(os.environ['LDFLAGS'])
|
||||||
else:
|
else:
|
||||||
os.environ['LDFLAGS']=""
|
os.environ['LDFLAGS'] = ""
|
||||||
|
|
||||||
# Add builders for flex and bison
|
# Add builders for flex and bison
|
||||||
add_lex(main_env)
|
add_lex(main_env)
|
||||||
@ -110,13 +110,13 @@ main_env.Append(LIBS=['z'])
|
|||||||
#######################
|
#######################
|
||||||
|
|
||||||
# SQLITE
|
# SQLITE
|
||||||
sqlite_dir=ARGUMENTS.get('sqlite_dir', 'none')
|
sqlite_dir = ARGUMENTS.get('sqlite_dir', 'none')
|
||||||
if sqlite_dir!='none':
|
if sqlite_dir != 'none':
|
||||||
main_env.Append(LIBPATH=[sqlite_dir+"/lib", sqlite_dir+"/lib64"])
|
main_env.Append(LIBPATH=[sqlite_dir+"/lib", sqlite_dir+"/lib64"])
|
||||||
main_env.Append(CPPPATH=[sqlite_dir+"/include"])
|
main_env.Append(CPPPATH=[sqlite_dir+"/include"])
|
||||||
|
|
||||||
sqlite=ARGUMENTS.get('sqlite', 'yes')
|
sqlite = ARGUMENTS.get('sqlite', 'yes')
|
||||||
if sqlite=='yes':
|
if sqlite == 'yes':
|
||||||
main_env.Append(sqlite='yes')
|
main_env.Append(sqlite='yes')
|
||||||
main_env.Append(CPPFLAGS=["-DSQLITE_DB"])
|
main_env.Append(CPPFLAGS=["-DSQLITE_DB"])
|
||||||
main_env.Append(LIBS=['sqlite3'])
|
main_env.Append(LIBS=['sqlite3'])
|
||||||
@ -124,8 +124,8 @@ else:
|
|||||||
main_env.Append(sqlite='no')
|
main_env.Append(sqlite='no')
|
||||||
|
|
||||||
# MySQL
|
# MySQL
|
||||||
mysql=ARGUMENTS.get('mysql', 'no')
|
mysql = ARGUMENTS.get('mysql', 'no')
|
||||||
if mysql=='yes':
|
if mysql == 'yes':
|
||||||
main_env.Append(mysql='yes')
|
main_env.Append(mysql='yes')
|
||||||
main_env.Append(CPPFLAGS=["-DMYSQL_DB"])
|
main_env.Append(CPPFLAGS=["-DMYSQL_DB"])
|
||||||
main_env.Append(LIBS=['mysqlclient'])
|
main_env.Append(LIBS=['mysqlclient'])
|
||||||
@ -133,22 +133,22 @@ else:
|
|||||||
main_env.Append(mysql='no')
|
main_env.Append(mysql='no')
|
||||||
|
|
||||||
# Flag to compile with xmlrpc-c versions prior to 1.31 (September 2012)
|
# Flag to compile with xmlrpc-c versions prior to 1.31 (September 2012)
|
||||||
new_xmlrpc=ARGUMENTS.get('new_xmlrpc', 'no')
|
new_xmlrpc = ARGUMENTS.get('new_xmlrpc', 'no')
|
||||||
if new_xmlrpc=='yes':
|
if new_xmlrpc == 'yes':
|
||||||
main_env.Append(new_xmlrpc='yes')
|
main_env.Append(new_xmlrpc='yes')
|
||||||
else:
|
else:
|
||||||
main_env.Append(new_xmlrpc='no')
|
main_env.Append(new_xmlrpc='no')
|
||||||
main_env.Append(CPPFLAGS=["-DOLD_XMLRPC"])
|
main_env.Append(CPPFLAGS=["-DOLD_XMLRPC"])
|
||||||
|
|
||||||
# xmlrpc
|
# xmlrpc
|
||||||
xmlrpc_dir=ARGUMENTS.get('xmlrpc', 'none')
|
xmlrpc_dir = ARGUMENTS.get('xmlrpc', 'none')
|
||||||
if xmlrpc_dir!='none':
|
if xmlrpc_dir != 'none':
|
||||||
main_env.Append(LIBPATH=[xmlrpc_dir+"/lib", xmlrpc_dir+"/lib64"])
|
main_env.Append(LIBPATH=[xmlrpc_dir+"/lib", xmlrpc_dir+"/lib64"])
|
||||||
main_env.Append(CPPPATH=[xmlrpc_dir+"/include"])
|
main_env.Append(CPPPATH=[xmlrpc_dir+"/include"])
|
||||||
|
|
||||||
# systemd
|
# systemd
|
||||||
systemd=ARGUMENTS.get('systemd', 'no')
|
systemd = ARGUMENTS.get('systemd', 'no')
|
||||||
if systemd=='yes':
|
if systemd == 'yes':
|
||||||
main_env.Append(systemd='yes')
|
main_env.Append(systemd='yes')
|
||||||
main_env.Append(CPPFLAGS=["-DSYSTEMD"])
|
main_env.Append(CPPFLAGS=["-DSYSTEMD"])
|
||||||
main_env.Append(LIBS=['systemd'])
|
main_env.Append(LIBS=['systemd'])
|
||||||
@ -156,8 +156,8 @@ else:
|
|||||||
main_env.Append(systemd='no')
|
main_env.Append(systemd='no')
|
||||||
|
|
||||||
# build lex/bison
|
# build lex/bison
|
||||||
build_parsers=ARGUMENTS.get('parsers', 'no')
|
build_parsers = ARGUMENTS.get('parsers', 'no')
|
||||||
if build_parsers=='yes':
|
if build_parsers == 'yes':
|
||||||
main_env.Append(parsers='yes')
|
main_env.Append(parsers='yes')
|
||||||
else:
|
else:
|
||||||
main_env.Append(parsers='no')
|
main_env.Append(parsers='no')
|
||||||
@ -173,7 +173,7 @@ main_env.Append(docker_machine=ARGUMENTS.get('docker_machine', 'no'))
|
|||||||
|
|
||||||
if not main_env.GetOption('clean'):
|
if not main_env.GetOption('clean'):
|
||||||
try:
|
try:
|
||||||
if mysql=='yes':
|
if mysql == 'yes':
|
||||||
main_env.ParseConfig('mysql_config --cflags --libs')
|
main_env.ParseConfig('mysql_config --cflags --libs')
|
||||||
except Exception, e:
|
except Exception, e:
|
||||||
print ""
|
print ""
|
||||||
@ -186,28 +186,27 @@ if not main_env.GetOption('clean'):
|
|||||||
print ""
|
print ""
|
||||||
exit(-1)
|
exit(-1)
|
||||||
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
main_env.ParseConfig(("LDFLAGS='%s' share/scons/get_xmlrpc_config"+
|
main_env.ParseConfig(("LDFLAGS='%s' share/scons/get_xmlrpc_config" +
|
||||||
" server") % (os.environ['LDFLAGS'],))
|
" server") % (os.environ['LDFLAGS'],))
|
||||||
main_env.ParseConfig(("LDFLAGS='%s' share/scons/get_xmlrpc_config"+
|
main_env.ParseConfig(("LDFLAGS='%s' share/scons/get_xmlrpc_config" +
|
||||||
" client") % (os.environ['LDFLAGS'],))
|
" client") % (os.environ['LDFLAGS'],))
|
||||||
|
|
||||||
except Exception, e:
|
except Exception, e:
|
||||||
print ""
|
print ""
|
||||||
print "Error searching for xmlrpc-c libraries. Please check this"+\
|
print "Error searching for xmlrpc-c libraries. Please check this" +\
|
||||||
" things:"
|
" things:"
|
||||||
print ""
|
print ""
|
||||||
print " * You have installed development libraries for xmlrpc-c. One"+\
|
print " * You have installed development libraries for xmlrpc-c. One" +\
|
||||||
" way to check"
|
" way to check"
|
||||||
print " this is calling xmlrpc-c-config that is provided with the"+\
|
print " this is calling xmlrpc-c-config that is provided with the" +\
|
||||||
" development"
|
" development"
|
||||||
print " package."
|
print " package."
|
||||||
print " * Check that the version of xmlrpc-c is at least 1.06. You"+\
|
print " * Check that the version of xmlrpc-c is at least 1.06. You" +\
|
||||||
" can do this also"
|
" can do this also"
|
||||||
print " calling:"
|
print " calling:"
|
||||||
print " $ xmlrpc-c-config --version"
|
print " $ xmlrpc-c-config --version"
|
||||||
print " * If all this requirements are already met please send log"+\
|
print " * If all this requirements are already met please send log" +\
|
||||||
" files located in"
|
" files located in"
|
||||||
print " .xmlrpc_test to the mailing list."
|
print " .xmlrpc_test to the mailing list."
|
||||||
print ""
|
print ""
|
||||||
@ -269,9 +268,10 @@ build_scripts=[
|
|||||||
'share/rubygems/SConstruct',
|
'share/rubygems/SConstruct',
|
||||||
'src/im_mad/collectd/SConstruct',
|
'src/im_mad/collectd/SConstruct',
|
||||||
'src/client/SConstruct',
|
'src/client/SConstruct',
|
||||||
'src/docker_machine/SConstruct'
|
'src/docker_machine/SConstruct',
|
||||||
|
'src/vmm_mad/remotes/lib/lxd/svncterm_server/SConstruct'
|
||||||
]
|
]
|
||||||
|
|
||||||
for script in build_scripts:
|
for script in build_scripts:
|
||||||
env=main_env.Clone()
|
env = main_env.Clone()
|
||||||
SConscript(script, exports='env')
|
SConscript(script, exports='env')
|
||||||
|
65
install.sh
65
install.sh
@ -253,12 +253,16 @@ VAR_DIRS="$VAR_LOCATION/remotes \
|
|||||||
$VAR_LOCATION/remotes/etc \
|
$VAR_LOCATION/remotes/etc \
|
||||||
$VAR_LOCATION/remotes/etc/datastore/ceph \
|
$VAR_LOCATION/remotes/etc/datastore/ceph \
|
||||||
$VAR_LOCATION/remotes/etc/im/kvm-probes.d \
|
$VAR_LOCATION/remotes/etc/im/kvm-probes.d \
|
||||||
|
$VAR_LOCATION/remotes/etc/im/lxd-probes.d \
|
||||||
$VAR_LOCATION/remotes/etc/vmm/kvm \
|
$VAR_LOCATION/remotes/etc/vmm/kvm \
|
||||||
|
$VAR_LOCATION/remotes/etc/vmm/lxd \
|
||||||
$VAR_LOCATION/remotes/etc/vmm/vcenter \
|
$VAR_LOCATION/remotes/etc/vmm/vcenter \
|
||||||
$VAR_LOCATION/remotes/etc/vnm \
|
$VAR_LOCATION/remotes/etc/vnm \
|
||||||
$VAR_LOCATION/remotes/im \
|
$VAR_LOCATION/remotes/im \
|
||||||
$VAR_LOCATION/remotes/im/kvm.d \
|
$VAR_LOCATION/remotes/im/kvm.d \
|
||||||
$VAR_LOCATION/remotes/im/kvm-probes.d \
|
$VAR_LOCATION/remotes/im/kvm-probes.d \
|
||||||
|
$VAR_LOCATION/remotes/im/lxd.d \
|
||||||
|
$VAR_LOCATION/remotes/im/lxd-probes.d \
|
||||||
$VAR_LOCATION/remotes/im/vcenter.d \
|
$VAR_LOCATION/remotes/im/vcenter.d \
|
||||||
$VAR_LOCATION/remotes/im/ec2.d \
|
$VAR_LOCATION/remotes/im/ec2.d \
|
||||||
$VAR_LOCATION/remotes/im/az.d \
|
$VAR_LOCATION/remotes/im/az.d \
|
||||||
@ -270,6 +274,7 @@ VAR_DIRS="$VAR_LOCATION/remotes \
|
|||||||
$VAR_LOCATION/remotes/vmm/ec2 \
|
$VAR_LOCATION/remotes/vmm/ec2 \
|
||||||
$VAR_LOCATION/remotes/vmm/az \
|
$VAR_LOCATION/remotes/vmm/az \
|
||||||
$VAR_LOCATION/remotes/vmm/one \
|
$VAR_LOCATION/remotes/vmm/one \
|
||||||
|
$VAR_LOCATION/remotes/vmm/lxd \
|
||||||
$VAR_LOCATION/remotes/vnm \
|
$VAR_LOCATION/remotes/vnm \
|
||||||
$VAR_LOCATION/remotes/vnm/802.1Q \
|
$VAR_LOCATION/remotes/vnm/802.1Q \
|
||||||
$VAR_LOCATION/remotes/vnm/vxlan \
|
$VAR_LOCATION/remotes/vnm/vxlan \
|
||||||
@ -396,6 +401,9 @@ INSTALL_FILES=(
|
|||||||
IM_PROBES_KVM_FILES:$VAR_LOCATION/remotes/im/kvm.d
|
IM_PROBES_KVM_FILES:$VAR_LOCATION/remotes/im/kvm.d
|
||||||
IM_PROBES_KVM_PROBES_FILES:$VAR_LOCATION/remotes/im/kvm-probes.d
|
IM_PROBES_KVM_PROBES_FILES:$VAR_LOCATION/remotes/im/kvm-probes.d
|
||||||
IM_PROBES_ETC_KVM_PROBES_FILES:$VAR_LOCATION/remotes/etc/im/kvm-probes.d
|
IM_PROBES_ETC_KVM_PROBES_FILES:$VAR_LOCATION/remotes/etc/im/kvm-probes.d
|
||||||
|
IM_PROBES_LXD_FILES:$VAR_LOCATION/remotes/im/lxd.d
|
||||||
|
IM_PROBES_LXD_PROBES_FILES:$VAR_LOCATION/remotes/im/lxd-probes.d
|
||||||
|
IM_PROBES_ETC_LXD_PROBES_FILES:$VAR_LOCATION/remotes/etc/im/lxd-probes.d
|
||||||
IM_PROBES_VCENTER_FILES:$VAR_LOCATION/remotes/im/vcenter.d
|
IM_PROBES_VCENTER_FILES:$VAR_LOCATION/remotes/im/vcenter.d
|
||||||
IM_PROBES_EC2_FILES:$VAR_LOCATION/remotes/im/ec2.d
|
IM_PROBES_EC2_FILES:$VAR_LOCATION/remotes/im/ec2.d
|
||||||
IM_PROBES_AZ_FILES:$VAR_LOCATION/remotes/im/az.d
|
IM_PROBES_AZ_FILES:$VAR_LOCATION/remotes/im/az.d
|
||||||
@ -411,7 +419,10 @@ INSTALL_FILES=(
|
|||||||
VMM_EXEC_LIB_FILES:$VAR_LOCATION/remotes/vmm/lib
|
VMM_EXEC_LIB_FILES:$VAR_LOCATION/remotes/vmm/lib
|
||||||
VMM_EXEC_LIB_VCENTER_FILES:$LIB_LOCATION/ruby/vcenter_driver
|
VMM_EXEC_LIB_VCENTER_FILES:$LIB_LOCATION/ruby/vcenter_driver
|
||||||
VMM_EXEC_KVM_SCRIPTS:$VAR_LOCATION/remotes/vmm/kvm
|
VMM_EXEC_KVM_SCRIPTS:$VAR_LOCATION/remotes/vmm/kvm
|
||||||
|
VMM_EXEC_LXD_SCRIPTS:$VAR_LOCATION/remotes/vmm/lxd
|
||||||
|
VMM_EXEC_LXD_LIB:$VAR_LOCATION/remotes/vmm/lxd
|
||||||
VMM_EXEC_ETC_KVM_SCRIPTS:$VAR_LOCATION/remotes/etc/vmm/kvm
|
VMM_EXEC_ETC_KVM_SCRIPTS:$VAR_LOCATION/remotes/etc/vmm/kvm
|
||||||
|
VMM_EXEC_ETC_LXD_SCRIPTS:$VAR_LOCATION/remotes/etc/vmm/lxd
|
||||||
VMM_EXEC_VCENTER_SCRIPTS:$VAR_LOCATION/remotes/vmm/vcenter
|
VMM_EXEC_VCENTER_SCRIPTS:$VAR_LOCATION/remotes/vmm/vcenter
|
||||||
VMM_EXEC_ETC_VCENTER_SCRIPTS:$VAR_LOCATION/remotes/etc/vmm/vcenter
|
VMM_EXEC_ETC_VCENTER_SCRIPTS:$VAR_LOCATION/remotes/etc/vmm/vcenter
|
||||||
VMM_EXEC_EC2_SCRIPTS:$VAR_LOCATION/remotes/vmm/ec2
|
VMM_EXEC_EC2_SCRIPTS:$VAR_LOCATION/remotes/vmm/ec2
|
||||||
@ -712,6 +723,45 @@ VMM_EXEC_LIB_VCENTER_FILES="src/vmm_mad/remotes/lib/vcenter_driver/datastore.rb
|
|||||||
src/vmm_mad/remotes/lib/vcenter_driver/vm_template.rb \
|
src/vmm_mad/remotes/lib/vcenter_driver/vm_template.rb \
|
||||||
src/vmm_mad/remotes/lib/vcenter_driver/network.rb"
|
src/vmm_mad/remotes/lib/vcenter_driver/network.rb"
|
||||||
|
|
||||||
|
#-------------------------------------------------------------------------------
|
||||||
|
# VMM SH Driver LXD scripts, to be installed under $REMOTES_LOCATION/vmm/lxd
|
||||||
|
#-------------------------------------------------------------------------------
|
||||||
|
VMM_EXEC_LXD_SCRIPTS="src/vmm_mad/remotes/lxd/cancel \
|
||||||
|
src/vmm_mad/remotes/lxd/deploy \
|
||||||
|
src/vmm_mad/remotes/lxd/migrate \
|
||||||
|
src/vmm_mad/remotes/lxd/migrate_local \
|
||||||
|
src/vmm_mad/remotes/lxd/restore \
|
||||||
|
src/vmm_mad/remotes/lxd/reboot \
|
||||||
|
src/vmm_mad/remotes/lxd/reset \
|
||||||
|
src/vmm_mad/remotes/lxd/save \
|
||||||
|
src/vmm_mad/remotes/lxd/poll \
|
||||||
|
src/vmm_mad/remotes/lxd/attach_disk \
|
||||||
|
src/vmm_mad/remotes/lxd/detach_disk \
|
||||||
|
src/vmm_mad/remotes/lxd/attach_nic \
|
||||||
|
src/vmm_mad/remotes/lxd/detach_nic \
|
||||||
|
src/vmm_mad/remotes/lxd/snapshot_create \
|
||||||
|
src/vmm_mad/remotes/lxd/snapshot_revert \
|
||||||
|
src/vmm_mad/remotes/lxd/snapshot_delete \
|
||||||
|
src/vmm_mad/remotes/lxd/shutdown \
|
||||||
|
src/vmm_mad/remotes/lxd/reconfigure \
|
||||||
|
src/vmm_mad/remotes/lxd/prereconfigure \
|
||||||
|
src/vmm_mad/remotes/lxd/resize_disk"
|
||||||
|
|
||||||
|
VMM_EXEC_LXD_LIB="src/vmm_mad/remotes/lib/lxd/opennebula_vm.rb \
|
||||||
|
src/vmm_mad/remotes/lib/lxd/mapper/mapper.rb \
|
||||||
|
src/vmm_mad/remotes/lib/lxd/mapper/qcow2.rb \
|
||||||
|
src/vmm_mad/remotes/lib/lxd/mapper/raw.rb \
|
||||||
|
src/vmm_mad/remotes/lib/lxd/mapper/rbd.rb \
|
||||||
|
src/vmm_mad/remotes/lib/lxd/client.rb \
|
||||||
|
src/vmm_mad/remotes/lib/lxd/command.rb \
|
||||||
|
src/vmm_mad/remotes/lib/lxd/container.rb"
|
||||||
|
|
||||||
|
#-------------------------------------------------------------------------------
|
||||||
|
# VMM configuration LXD scripts, to be installed under $REMOTES_LOCATION/etc/vmm/lxd
|
||||||
|
#-------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
VMM_EXEC_ETC_LXD_SCRIPTS="src/vmm_mad/remotes/lxd/lxdrc"
|
||||||
|
|
||||||
#-------------------------------------------------------------------------------
|
#-------------------------------------------------------------------------------
|
||||||
# VMM SH Driver KVM scripts, to be installed under $REMOTES_LOCATION/vmm/kvm
|
# VMM SH Driver KVM scripts, to be installed under $REMOTES_LOCATION/vmm/kvm
|
||||||
#-------------------------------------------------------------------------------
|
#-------------------------------------------------------------------------------
|
||||||
@ -870,6 +920,21 @@ IM_PROBES_KVM_PROBES_FILES="src/im_mad/remotes/kvm-probes.d/kvm.rb \
|
|||||||
|
|
||||||
IM_PROBES_ETC_KVM_PROBES_FILES="src/im_mad/remotes/kvm-probes.d/pci.conf"
|
IM_PROBES_ETC_KVM_PROBES_FILES="src/im_mad/remotes/kvm-probes.d/pci.conf"
|
||||||
|
|
||||||
|
IM_PROBES_LXD_PROBES_FILES="src/im_mad/remotes/lxd-probes.d/lxd.rb \
|
||||||
|
src/im_mad/remotes/lxd-probes.d/architecture.sh \
|
||||||
|
src/im_mad/remotes/lxd-probes.d/cpu.sh \
|
||||||
|
src/im_mad/remotes/lxd-probes.d/poll.sh \
|
||||||
|
src/im_mad/remotes/lxd-probes.d/name.sh \
|
||||||
|
src/im_mad/remotes/lxd-probes.d/pci.rb \
|
||||||
|
src/im_mad/remotes/lxd-probes.d/monitor_ds.sh \
|
||||||
|
src/im_mad/remotes/lxd-probes.d/version.sh \
|
||||||
|
src/im_mad/remotes/lxd-probes.d/collectd-client-shepherd.sh"
|
||||||
|
|
||||||
|
IM_PROBES_LXD_FILES="src/im_mad/remotes/lxd.d/collectd-client_control.sh \
|
||||||
|
src/im_mad/remotes/lxd.d/collectd-client.rb"
|
||||||
|
|
||||||
|
IM_PROBES_ETC_LXD_PROBES_FILES="src/im_mad/remotes/lxd-probes.d/pci.conf"
|
||||||
|
|
||||||
IM_PROBES_VCENTER_FILES="src/im_mad/remotes/vcenter.d/poll"
|
IM_PROBES_VCENTER_FILES="src/im_mad/remotes/vcenter.d/poll"
|
||||||
|
|
||||||
IM_PROBES_EC2_FILES="src/im_mad/remotes/ec2.d/poll"
|
IM_PROBES_EC2_FILES="src/im_mad/remotes/ec2.d/poll"
|
||||||
|
@ -409,6 +409,32 @@ IM_MAD = [
|
|||||||
# ARGUMENTS = "-r 3 -t 15 -w 90 kvm-probes" ]
|
# ARGUMENTS = "-r 3 -t 15 -w 90 kvm-probes" ]
|
||||||
#-------------------------------------------------------------------------------
|
#-------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
#-------------------------------------------------------------------------------
|
||||||
|
# LXD UDP-push Information Driver Manager Configuration
|
||||||
|
# -r number of retries when monitoring a host
|
||||||
|
# -t number of threads, i.e. number of hosts monitored at the same time
|
||||||
|
# -w Timeout in seconds to execute external commands (default unlimited)
|
||||||
|
#-------------------------------------------------------------------------------
|
||||||
|
IM_MAD = [
|
||||||
|
NAME = "lxd",
|
||||||
|
SUNSTONE_NAME = "LXD",
|
||||||
|
EXECUTABLE = "one_im_ssh",
|
||||||
|
ARGUMENTS = "-r 3 -t 15 -w 90 lxd" ]
|
||||||
|
#-------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
#-------------------------------------------------------------------------------
|
||||||
|
# LXD SSH-pull Information Driver Manager Configuration
|
||||||
|
# -r number of retries when monitoring a host
|
||||||
|
# -t number of threads, i.e. number of hosts monitored at the same time
|
||||||
|
# -w Timeout in seconds to execute external commands (default unlimited)
|
||||||
|
#-------------------------------------------------------------------------------
|
||||||
|
# IM_MAD = [
|
||||||
|
# NAME = "lxd",
|
||||||
|
# SUNSTONE_NAME = "lxd-ssh",
|
||||||
|
# EXECUTABLE = "one_im_ssh",
|
||||||
|
# ARGUMENTS = "-r 3 -t 15 -w 90 lxd-probes" ]
|
||||||
|
#-------------------------------------------------------------------------------
|
||||||
|
|
||||||
#-------------------------------------------------------------------------------
|
#-------------------------------------------------------------------------------
|
||||||
# vCenter Information Driver Manager Configuration
|
# vCenter Information Driver Manager Configuration
|
||||||
# -r number of retries when monitoring a host
|
# -r number of retries when monitoring a host
|
||||||
@ -548,6 +574,32 @@ VM_MAD = [
|
|||||||
|
|
||||||
#-------------------------------------------------------------------------------
|
#-------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
#-------------------------------------------------------------------------------
|
||||||
|
# LXD Virtualization Driver Manager Configuration
|
||||||
|
# -r number of retries when monitoring a host
|
||||||
|
# -t number of threads, i.e. number of hosts monitored at the same time
|
||||||
|
# -l <actions[=command_name]> actions executed locally, command can be
|
||||||
|
# overridden for each action.
|
||||||
|
# Valid actions: deploy, shutdown, cancel, save, restore, migrate, poll
|
||||||
|
# An example: "-l migrate=migrate_local,save"
|
||||||
|
# -p more than one action per host in parallel, needs support from hypervisor
|
||||||
|
# -s <shell> to execute remote commands, bash by default
|
||||||
|
# -w Timeout in seconds to execute external commands (default unlimited)
|
||||||
|
#
|
||||||
|
#-------------------------------------------------------------------------------
|
||||||
|
VM_MAD = [
|
||||||
|
NAME = "lxd",
|
||||||
|
SUNSTONE_NAME = "LXD",
|
||||||
|
EXECUTABLE = "one_vmm_exec",
|
||||||
|
ARGUMENTS = "-t 15 -r 0 lxd",
|
||||||
|
# DEFAULT = "vmm_exec/vmm_exec_lxd.conf",
|
||||||
|
TYPE = "xml",
|
||||||
|
KEEP_SNAPSHOTS = "no",
|
||||||
|
IMPORTED_VMS_ACTIONS = "terminate, terminate-hard, reboot, reboot-hard, poweroff, poweroff-hard, suspend, resume, stop, delete, nic-attach, nic-detach"
|
||||||
|
]
|
||||||
|
|
||||||
|
#-------------------------------------------------------------------------------
|
||||||
|
|
||||||
#-------------------------------------------------------------------------------
|
#-------------------------------------------------------------------------------
|
||||||
# vCenter Virtualization Driver Manager Configuration
|
# vCenter Virtualization Driver Manager Configuration
|
||||||
# -r number of retries when monitoring a host
|
# -r number of retries when monitoring a host
|
||||||
|
@ -1,19 +0,0 @@
|
|||||||
#!/bin/sh
|
|
||||||
|
|
||||||
# -------------------------------------------------------------------------- #
|
|
||||||
# Copyright 2002-2018, OpenNebula Project, OpenNebula Systems #
|
|
||||||
# #
|
|
||||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may #
|
|
||||||
# not use this file except in compliance with the License. You may obtain #
|
|
||||||
# a copy of the License at #
|
|
||||||
# #
|
|
||||||
# http://www.apache.org/licenses/LICENSE-2.0 #
|
|
||||||
# #
|
|
||||||
# Unless required by applicable law or agreed to in writing, software #
|
|
||||||
# distributed under the License is distributed on an "AS IS" BASIS, #
|
|
||||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. #
|
|
||||||
# See the License for the specific language governing permissions and #
|
|
||||||
# limitations under the License. #
|
|
||||||
#--------------------------------------------------------------------------- #
|
|
||||||
|
|
||||||
echo ARCH=`uname -m`
|
|
1
src/im_mad/remotes/kvm-probes.d/architecture.sh
Symbolic link
1
src/im_mad/remotes/kvm-probes.d/architecture.sh
Symbolic link
@ -0,0 +1 @@
|
|||||||
|
../node-probes.d/architecture.sh
|
1
src/im_mad/remotes/kvm-probes.d/collectd-client-shepherd.sh
Symbolic link
1
src/im_mad/remotes/kvm-probes.d/collectd-client-shepherd.sh
Symbolic link
@ -0,0 +1 @@
|
|||||||
|
../common.d/collectd-client-shepherd.sh
|
@ -1,35 +0,0 @@
|
|||||||
#!/bin/sh
|
|
||||||
|
|
||||||
# -------------------------------------------------------------------------- #
|
|
||||||
# Copyright 2002-2018, OpenNebula Project, OpenNebula Systems #
|
|
||||||
# #
|
|
||||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may #
|
|
||||||
# not use this file except in compliance with the License. You may obtain #
|
|
||||||
# a copy of the License at #
|
|
||||||
# #
|
|
||||||
# http://www.apache.org/licenses/LICENSE-2.0 #
|
|
||||||
# #
|
|
||||||
# Unless required by applicable law or agreed to in writing, software #
|
|
||||||
# distributed under the License is distributed on an "AS IS" BASIS, #
|
|
||||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. #
|
|
||||||
# See the License for the specific language governing permissions and #
|
|
||||||
# limitations under the License. #
|
|
||||||
#--------------------------------------------------------------------------- #
|
|
||||||
|
|
||||||
MODEL=''
|
|
||||||
|
|
||||||
if [ -f /proc/cpuinfo ]; then
|
|
||||||
for NAME in 'model name' 'cpu'; do
|
|
||||||
MODEL=$(grep -m1 "^${NAME}[[:space:]]*:" /proc/cpuinfo | \
|
|
||||||
cut -d: -f2 | \
|
|
||||||
sed -e 's/^ *//')
|
|
||||||
|
|
||||||
if [ -n "${MODEL}" ]; then
|
|
||||||
break
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ -n "${MODEL}" ]; then
|
|
||||||
echo "MODELNAME=\"${MODEL}\""
|
|
||||||
fi
|
|
1
src/im_mad/remotes/kvm-probes.d/cpu.sh
Symbolic link
1
src/im_mad/remotes/kvm-probes.d/cpu.sh
Symbolic link
@ -0,0 +1 @@
|
|||||||
|
../node-probes.d/cpu.sh
|
1
src/im_mad/remotes/kvm-probes.d/monitor_ds.sh
Symbolic link
1
src/im_mad/remotes/kvm-probes.d/monitor_ds.sh
Symbolic link
@ -0,0 +1 @@
|
|||||||
|
../common.d/monitor_ds.sh
|
@ -1,21 +0,0 @@
|
|||||||
#!/bin/sh
|
|
||||||
|
|
||||||
# -------------------------------------------------------------------------- #
|
|
||||||
# Copyright 2002-2018, OpenNebula Project, OpenNebula Systems #
|
|
||||||
# #
|
|
||||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may #
|
|
||||||
# not use this file except in compliance with the License. You may obtain #
|
|
||||||
# a copy of the License at #
|
|
||||||
# #
|
|
||||||
# http://www.apache.org/licenses/LICENSE-2.0 #
|
|
||||||
# #
|
|
||||||
# Unless required by applicable law or agreed to in writing, software #
|
|
||||||
# distributed under the License is distributed on an "AS IS" BASIS, #
|
|
||||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. #
|
|
||||||
# See the License for the specific language governing permissions and #
|
|
||||||
# limitations under the License. #
|
|
||||||
#--------------------------------------------------------------------------- #
|
|
||||||
|
|
||||||
echo HOSTNAME=`uname -n`
|
|
||||||
|
|
||||||
|
|
1
src/im_mad/remotes/kvm-probes.d/name.sh
Symbolic link
1
src/im_mad/remotes/kvm-probes.d/name.sh
Symbolic link
@ -0,0 +1 @@
|
|||||||
|
../node-probes.d/name.sh
|
@ -1,66 +0,0 @@
|
|||||||
# -------------------------------------------------------------------------- #
|
|
||||||
# Copyright 2002-2018, OpenNebula Project, OpenNebula Systems #
|
|
||||||
# #
|
|
||||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may #
|
|
||||||
# not use this file except in compliance with the License. You may obtain #
|
|
||||||
# a copy of the License at #
|
|
||||||
# #
|
|
||||||
# http://www.apache.org/licenses/LICENSE-2.0 #
|
|
||||||
# #
|
|
||||||
# Unless required by applicable law or agreed to in writing, software #
|
|
||||||
# distributed under the License is distributed on an "AS IS" BASIS, #
|
|
||||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. #
|
|
||||||
# See the License for the specific language governing permissions and #
|
|
||||||
# limitations under the License. #
|
|
||||||
#--------------------------------------------------------------------------- #
|
|
||||||
|
|
||||||
# This option specifies the main filters for PCI card monitoring. The format
|
|
||||||
# is the same as used by lspci to filter on PCI card by vendor:device(:class)
|
|
||||||
# identification. Several filters can be added as a list, or separated
|
|
||||||
# by commas. The NULL filter will retrieve all PCI cards.
|
|
||||||
#
|
|
||||||
# From lspci help:
|
|
||||||
# -d [<vendor>]:[<device>][:<class>]
|
|
||||||
# Show only devices with specified vendor, device and class ID.
|
|
||||||
# The ID's are given in hexadecimal and may be omitted or given
|
|
||||||
# as "*", both meaning "any value"#
|
|
||||||
#
|
|
||||||
# For example:
|
|
||||||
# :filter:
|
|
||||||
# - '10de:*' # all NVIDIA VGA cards
|
|
||||||
# - '10de:11bf' # only GK104GL [GRID K2]
|
|
||||||
# - '*:10d3' # only 82574L Gigabit Network cards
|
|
||||||
# - '8086::0c03' # only Intel USB controllers
|
|
||||||
#
|
|
||||||
# or
|
|
||||||
#
|
|
||||||
# :filter: '*:*' # all devices
|
|
||||||
#
|
|
||||||
# or
|
|
||||||
#
|
|
||||||
# :filter: '0:0' # no devices
|
|
||||||
#
|
|
||||||
:filter: '0:0'
|
|
||||||
|
|
||||||
# The PCI cards list restricted by the :filter option above can be even more
|
|
||||||
# filtered by the list of exact PCI addresses (bus:device.func).
|
|
||||||
#
|
|
||||||
# For example:
|
|
||||||
# :short_address:
|
|
||||||
# - '07:00.0'
|
|
||||||
# - '06:00.0'
|
|
||||||
#
|
|
||||||
:short_address: []
|
|
||||||
|
|
||||||
# The PCI cards list restricted by the :filter option above can be even more
|
|
||||||
# filtered by matching the device name against the list of regular expression
|
|
||||||
# case-insensitive patterns.
|
|
||||||
#
|
|
||||||
# For example:
|
|
||||||
# :device_name:
|
|
||||||
# - 'Virtual Function'
|
|
||||||
# - 'Gigabit Network'
|
|
||||||
# - 'USB.*Host Controller'
|
|
||||||
# - '^MegaRAID'
|
|
||||||
#
|
|
||||||
:device_name: []
|
|
1
src/im_mad/remotes/kvm-probes.d/pci.conf
Symbolic link
1
src/im_mad/remotes/kvm-probes.d/pci.conf
Symbolic link
@ -0,0 +1 @@
|
|||||||
|
../node-probes.d/pci.conf
|
@ -1,118 +0,0 @@
|
|||||||
#!/usr/bin/env ruby
|
|
||||||
|
|
||||||
# -------------------------------------------------------------------------- #
|
|
||||||
# Copyright 2002-2018, OpenNebula Project, OpenNebula Systems #
|
|
||||||
# #
|
|
||||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may #
|
|
||||||
# not use this file except in compliance with the License. You may obtain #
|
|
||||||
# a copy of the License at #
|
|
||||||
# #
|
|
||||||
# http://www.apache.org/licenses/LICENSE-2.0 #
|
|
||||||
# #
|
|
||||||
# Unless required by applicable law or agreed to in writing, software #
|
|
||||||
# distributed under the License is distributed on an "AS IS" BASIS, #
|
|
||||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. #
|
|
||||||
# See the License for the specific language governing permissions and #
|
|
||||||
# limitations under the License. #
|
|
||||||
#--------------------------------------------------------------------------- #
|
|
||||||
|
|
||||||
require 'shellwords'
|
|
||||||
require 'yaml'
|
|
||||||
|
|
||||||
begin
|
|
||||||
NAME = File.join(File.dirname(__FILE__), '../../etc/im/kvm-probes.d/pci.conf')
|
|
||||||
CONF = {
|
|
||||||
:filter => '0:0',
|
|
||||||
:short_address => [],
|
|
||||||
:device_name => [],
|
|
||||||
}.merge(YAML.load_file(NAME))
|
|
||||||
rescue
|
|
||||||
STDERR.puts "Invalid configuration #{NAME}"
|
|
||||||
exit(-1)
|
|
||||||
end
|
|
||||||
|
|
||||||
def get_pci(filter=nil)
|
|
||||||
command = "lspci -mmnn"
|
|
||||||
command << " -d #{filter}" if filter
|
|
||||||
|
|
||||||
text = %x(#{command})
|
|
||||||
|
|
||||||
text.split("\n").map {|l| Shellwords.split(l) }
|
|
||||||
end
|
|
||||||
|
|
||||||
def get_name_and_id(text)
|
|
||||||
m = text.match(/^(.*) \[(....)\]$/)
|
|
||||||
return m[1], m[2]
|
|
||||||
end
|
|
||||||
|
|
||||||
def parse_pci(pci)
|
|
||||||
card = {}
|
|
||||||
|
|
||||||
card[:short_address] = pci[0]
|
|
||||||
card[:libvirt_address] =
|
|
||||||
"pci_0000_#{card[:short_address].gsub(/[:.]/, '_')}"
|
|
||||||
card[:address] = "0000:#{card[:short_address].gsub(/[:.]/, ':')}"
|
|
||||||
|
|
||||||
card[:class_name], card[:class] = get_name_and_id(pci[1])
|
|
||||||
card[:vendor_name], card[:vendor] = get_name_and_id(pci[2])
|
|
||||||
card[:device_name], card[:device] = get_name_and_id(pci[3])
|
|
||||||
|
|
||||||
card[:bus], card[:slot], card[:function] = pci[0].split(/[:.]/)
|
|
||||||
|
|
||||||
card[:type] = [card[:vendor], card[:device], card[:class]].join(':')
|
|
||||||
|
|
||||||
card
|
|
||||||
end
|
|
||||||
|
|
||||||
def get_devices(filter=nil)
|
|
||||||
if filter
|
|
||||||
filter = [filter].flatten.map { |f| f.split(',') }.flatten
|
|
||||||
else
|
|
||||||
filter = [nil]
|
|
||||||
end
|
|
||||||
|
|
||||||
filter.map do |f|
|
|
||||||
get_pci(f).map {|pci| parse_pci(pci) }
|
|
||||||
end.flatten
|
|
||||||
end
|
|
||||||
|
|
||||||
filter = CONF[:filter]
|
|
||||||
|
|
||||||
devices = get_devices(filter)
|
|
||||||
|
|
||||||
def pval(name, value)
|
|
||||||
%Q( #{name} = "#{value}")
|
|
||||||
end
|
|
||||||
|
|
||||||
devices.each do |dev|
|
|
||||||
next if !CONF[:short_address].empty? && !CONF[:short_address].include?(dev[:short_address])
|
|
||||||
|
|
||||||
if !CONF[:device_name].empty?
|
|
||||||
matched = CONF[:device_name].each { |pattern|
|
|
||||||
break true if !(dev[:device_name] =~ /#{pattern}/i).nil?
|
|
||||||
}
|
|
||||||
|
|
||||||
next if matched != true
|
|
||||||
end
|
|
||||||
|
|
||||||
puts "PCI = ["
|
|
||||||
values = [
|
|
||||||
pval('TYPE', dev[:type]),
|
|
||||||
pval('VENDOR', dev[:vendor]),
|
|
||||||
pval('VENDOR_NAME', dev[:vendor_name]),
|
|
||||||
pval('DEVICE', dev[:device]),
|
|
||||||
pval('DEVICE_NAME', dev[:device_name]),
|
|
||||||
pval('CLASS', dev[:class]),
|
|
||||||
pval('CLASS_NAME', dev[:class_name]),
|
|
||||||
pval('ADDRESS', dev[:address]),
|
|
||||||
pval('SHORT_ADDRESS', dev[:short_address]),
|
|
||||||
pval('DOMAIN', '0000'),
|
|
||||||
pval('BUS', dev[:bus]),
|
|
||||||
pval('SLOT', dev[:slot]),
|
|
||||||
pval('FUNCTION', dev[:function])
|
|
||||||
]
|
|
||||||
|
|
||||||
puts values.join(",\n")
|
|
||||||
puts "]"
|
|
||||||
end
|
|
||||||
|
|
1
src/im_mad/remotes/kvm-probes.d/pci.rb
Symbolic link
1
src/im_mad/remotes/kvm-probes.d/pci.rb
Symbolic link
@ -0,0 +1 @@
|
|||||||
|
../node-probes.d/pci.rb
|
1
src/im_mad/remotes/kvm-probes.d/version.sh
Symbolic link
1
src/im_mad/remotes/kvm-probes.d/version.sh
Symbolic link
@ -0,0 +1 @@
|
|||||||
|
../common.d/version.sh
|
1
src/im_mad/remotes/lxd-probes.d/architecture.sh
Symbolic link
1
src/im_mad/remotes/lxd-probes.d/architecture.sh
Symbolic link
@ -0,0 +1 @@
|
|||||||
|
../node-probes.d/architecture.sh
|
1
src/im_mad/remotes/lxd-probes.d/collectd-client-shepherd.sh
Symbolic link
1
src/im_mad/remotes/lxd-probes.d/collectd-client-shepherd.sh
Symbolic link
@ -0,0 +1 @@
|
|||||||
|
../common.d/collectd-client-shepherd.sh
|
1
src/im_mad/remotes/lxd-probes.d/cpu.sh
Symbolic link
1
src/im_mad/remotes/lxd-probes.d/cpu.sh
Symbolic link
@ -0,0 +1 @@
|
|||||||
|
../node-probes.d/cpu.sh
|
99
src/im_mad/remotes/lxd-probes.d/lxd.rb
Executable file
99
src/im_mad/remotes/lxd-probes.d/lxd.rb
Executable file
@ -0,0 +1,99 @@
|
|||||||
|
#!/usr/bin/env ruby
|
||||||
|
|
||||||
|
# -------------------------------------------------------------------------- #
|
||||||
|
# Copyright 2002-2018, OpenNebula Project, OpenNebula Systems #
|
||||||
|
# #
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License"); you may #
|
||||||
|
# not use this file except in compliance with the License. You may obtain #
|
||||||
|
# a copy of the License at #
|
||||||
|
# #
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0 #
|
||||||
|
# #
|
||||||
|
# Unless required by applicable law or agreed to in writing, software #
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS, #
|
||||||
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. #
|
||||||
|
# See the License for the specific language governing permissions and #
|
||||||
|
# limitations under the License. #
|
||||||
|
#--------------------------------------------------------------------------- #
|
||||||
|
|
||||||
|
def print_info(name, value)
|
||||||
|
value = "0" if value.nil? or value.to_s.strip.empty?
|
||||||
|
puts "#{name}=#{value}"
|
||||||
|
end
|
||||||
|
|
||||||
|
######
|
||||||
|
# First, get all the posible info out of virsh
|
||||||
|
# TODO : use virsh freecell when available
|
||||||
|
######
|
||||||
|
|
||||||
|
ENV['LANG'] = 'C'
|
||||||
|
ENV['LC_ALL'] = 'C'
|
||||||
|
|
||||||
|
nodeinfo_text = `virsh -c qemu:///system nodeinfo`
|
||||||
|
exit(-1) if $?.exitstatus != 0
|
||||||
|
|
||||||
|
nodeinfo_text.split(/\n/).each{|line|
|
||||||
|
if line =~ /^CPU\(s\)/
|
||||||
|
$total_cpu = line.split(':')[1].strip.to_i * 100
|
||||||
|
elsif line =~ /^CPU frequency/
|
||||||
|
$cpu_speed = line.split(':')[1].strip.split(' ')[0]
|
||||||
|
elsif line =~ /^Memory size/
|
||||||
|
$total_memory = line.split(':')[1].strip.split(' ')[0]
|
||||||
|
end
|
||||||
|
}
|
||||||
|
|
||||||
|
######
|
||||||
|
# CPU
|
||||||
|
######
|
||||||
|
vmstat = `vmstat 1 2`
|
||||||
|
$free_cpu = $total_cpu * ((vmstat.split("\n").to_a.last.split)[14].to_i)/100
|
||||||
|
$used_cpu = $total_cpu - $free_cpu
|
||||||
|
|
||||||
|
######
|
||||||
|
# MEMORY
|
||||||
|
######
|
||||||
|
memory = `cat /proc/meminfo`
|
||||||
|
meminfo = Hash.new()
|
||||||
|
memory.each_line do |line|
|
||||||
|
key, value = line.split(':')
|
||||||
|
meminfo[key] = /\d+/.match(value)[0].to_i
|
||||||
|
end
|
||||||
|
|
||||||
|
$total_memory = meminfo['MemTotal']
|
||||||
|
|
||||||
|
$used_memory = meminfo['MemTotal'] - meminfo['MemFree'] - meminfo['Buffers'] - meminfo['Cached']
|
||||||
|
$free_memory = $total_memory - $used_memory
|
||||||
|
|
||||||
|
######
|
||||||
|
# INTERFACE
|
||||||
|
######
|
||||||
|
NETINTERFACE = 'eth|bond|em|enp|p[0-9]+p[0-9]+'
|
||||||
|
|
||||||
|
net_text=`cat /proc/net/dev`
|
||||||
|
exit(-1) if $?.exitstatus != 0
|
||||||
|
|
||||||
|
$netrx = 0
|
||||||
|
$nettx = 0
|
||||||
|
|
||||||
|
net_text.split(/\n/).each do |line|
|
||||||
|
next unless line =~ /^ *#{NETINTERFACE}/
|
||||||
|
|
||||||
|
arr = line.split(':')[1].split(' ')
|
||||||
|
$netrx += arr[0].to_i
|
||||||
|
$nettx += arr[8].to_i
|
||||||
|
end
|
||||||
|
|
||||||
|
print_info("HYPERVISOR","lxd")
|
||||||
|
|
||||||
|
print_info("TOTALCPU",$total_cpu)
|
||||||
|
print_info("CPUSPEED",$cpu_speed)
|
||||||
|
|
||||||
|
print_info("TOTALMEMORY",$total_memory)
|
||||||
|
print_info("USEDMEMORY",$used_memory)
|
||||||
|
print_info("FREEMEMORY",$free_memory)
|
||||||
|
|
||||||
|
print_info("FREECPU",$free_cpu)
|
||||||
|
print_info("USEDCPU",$used_cpu)
|
||||||
|
|
||||||
|
print_info("NETRX",$netrx)
|
||||||
|
print_info("NETTX",$nettx)
|
1
src/im_mad/remotes/lxd-probes.d/monitor_ds.sh
Symbolic link
1
src/im_mad/remotes/lxd-probes.d/monitor_ds.sh
Symbolic link
@ -0,0 +1 @@
|
|||||||
|
../common.d/monitor_ds.sh
|
1
src/im_mad/remotes/lxd-probes.d/name.sh
Symbolic link
1
src/im_mad/remotes/lxd-probes.d/name.sh
Symbolic link
@ -0,0 +1 @@
|
|||||||
|
../node-probes.d/name.sh
|
1
src/im_mad/remotes/lxd-probes.d/pci.conf
Symbolic link
1
src/im_mad/remotes/lxd-probes.d/pci.conf
Symbolic link
@ -0,0 +1 @@
|
|||||||
|
../node-probes.d/pci.conf
|
1
src/im_mad/remotes/lxd-probes.d/pci.rb
Symbolic link
1
src/im_mad/remotes/lxd-probes.d/pci.rb
Symbolic link
@ -0,0 +1 @@
|
|||||||
|
../node-probes.d/pci.rb
|
19
src/im_mad/remotes/lxd-probes.d/poll.sh
Executable file
19
src/im_mad/remotes/lxd-probes.d/poll.sh
Executable file
@ -0,0 +1,19 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
# -------------------------------------------------------------------------- #
|
||||||
|
# Copyright 2002-2018, OpenNebula Project, OpenNebula Systems #
|
||||||
|
# #
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License"); you may #
|
||||||
|
# not use this file except in compliance with the License. You may obtain #
|
||||||
|
# a copy of the License at #
|
||||||
|
# #
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0 #
|
||||||
|
# #
|
||||||
|
# Unless required by applicable law or agreed to in writing, software #
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS, #
|
||||||
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. #
|
||||||
|
# See the License for the specific language governing permissions and #
|
||||||
|
# limitations under the License. #
|
||||||
|
#--------------------------------------------------------------------------- #
|
||||||
|
|
||||||
|
../../vmm/lxd/poll -t
|
1
src/im_mad/remotes/lxd-probes.d/version.sh
Symbolic link
1
src/im_mad/remotes/lxd-probes.d/version.sh
Symbolic link
@ -0,0 +1 @@
|
|||||||
|
../common.d/version.sh
|
1
src/im_mad/remotes/lxd.d/collectd-client.rb
Symbolic link
1
src/im_mad/remotes/lxd.d/collectd-client.rb
Symbolic link
@ -0,0 +1 @@
|
|||||||
|
../common.d/collectd-client.rb
|
1
src/im_mad/remotes/lxd.d/collectd-client_control.sh
Symbolic link
1
src/im_mad/remotes/lxd.d/collectd-client_control.sh
Symbolic link
@ -0,0 +1 @@
|
|||||||
|
../common.d/collectd-client_control.sh
|
19
src/im_mad/remotes/node-probes.d/architecture.sh
Executable file
19
src/im_mad/remotes/node-probes.d/architecture.sh
Executable file
@ -0,0 +1,19 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
# -------------------------------------------------------------------------- #
|
||||||
|
# Copyright 2002-2018, OpenNebula Project, OpenNebula Systems #
|
||||||
|
# #
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License"); you may #
|
||||||
|
# not use this file except in compliance with the License. You may obtain #
|
||||||
|
# a copy of the License at #
|
||||||
|
# #
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0 #
|
||||||
|
# #
|
||||||
|
# Unless required by applicable law or agreed to in writing, software #
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS, #
|
||||||
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. #
|
||||||
|
# See the License for the specific language governing permissions and #
|
||||||
|
# limitations under the License. #
|
||||||
|
#--------------------------------------------------------------------------- #
|
||||||
|
|
||||||
|
echo ARCH=`uname -m`
|
35
src/im_mad/remotes/node-probes.d/cpu.sh
Executable file
35
src/im_mad/remotes/node-probes.d/cpu.sh
Executable file
@ -0,0 +1,35 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
# -------------------------------------------------------------------------- #
|
||||||
|
# Copyright 2002-2018, OpenNebula Project, OpenNebula Systems #
|
||||||
|
# #
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License"); you may #
|
||||||
|
# not use this file except in compliance with the License. You may obtain #
|
||||||
|
# a copy of the License at #
|
||||||
|
# #
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0 #
|
||||||
|
# #
|
||||||
|
# Unless required by applicable law or agreed to in writing, software #
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS, #
|
||||||
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. #
|
||||||
|
# See the License for the specific language governing permissions and #
|
||||||
|
# limitations under the License. #
|
||||||
|
#--------------------------------------------------------------------------- #
|
||||||
|
|
||||||
|
MODEL=''
|
||||||
|
|
||||||
|
if [ -f /proc/cpuinfo ]; then
|
||||||
|
for NAME in 'model name' 'cpu'; do
|
||||||
|
MODEL=$(grep -m1 "^${NAME}[[:space:]]*:" /proc/cpuinfo | \
|
||||||
|
cut -d: -f2 | \
|
||||||
|
sed -e 's/^ *//')
|
||||||
|
|
||||||
|
if [ -n "${MODEL}" ]; then
|
||||||
|
break
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -n "${MODEL}" ]; then
|
||||||
|
echo "MODELNAME=\"${MODEL}\""
|
||||||
|
fi
|
21
src/im_mad/remotes/node-probes.d/name.sh
Executable file
21
src/im_mad/remotes/node-probes.d/name.sh
Executable file
@ -0,0 +1,21 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
# -------------------------------------------------------------------------- #
|
||||||
|
# Copyright 2002-2018, OpenNebula Project, OpenNebula Systems #
|
||||||
|
# #
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License"); you may #
|
||||||
|
# not use this file except in compliance with the License. You may obtain #
|
||||||
|
# a copy of the License at #
|
||||||
|
# #
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0 #
|
||||||
|
# #
|
||||||
|
# Unless required by applicable law or agreed to in writing, software #
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS, #
|
||||||
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. #
|
||||||
|
# See the License for the specific language governing permissions and #
|
||||||
|
# limitations under the License. #
|
||||||
|
#--------------------------------------------------------------------------- #
|
||||||
|
|
||||||
|
echo HOSTNAME=`uname -n`
|
||||||
|
|
||||||
|
|
66
src/im_mad/remotes/node-probes.d/pci.conf
Normal file
66
src/im_mad/remotes/node-probes.d/pci.conf
Normal file
@ -0,0 +1,66 @@
|
|||||||
|
# -------------------------------------------------------------------------- #
|
||||||
|
# Copyright 2002-2018, OpenNebula Project, OpenNebula Systems #
|
||||||
|
# #
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License"); you may #
|
||||||
|
# not use this file except in compliance with the License. You may obtain #
|
||||||
|
# a copy of the License at #
|
||||||
|
# #
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0 #
|
||||||
|
# #
|
||||||
|
# Unless required by applicable law or agreed to in writing, software #
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS, #
|
||||||
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. #
|
||||||
|
# See the License for the specific language governing permissions and #
|
||||||
|
# limitations under the License. #
|
||||||
|
#--------------------------------------------------------------------------- #
|
||||||
|
|
||||||
|
# This option specifies the main filters for PCI card monitoring. The format
|
||||||
|
# is the same as used by lspci to filter on PCI card by vendor:device(:class)
|
||||||
|
# identification. Several filters can be added as a list, or separated
|
||||||
|
# by commas. The NULL filter will retrieve all PCI cards.
|
||||||
|
#
|
||||||
|
# From lspci help:
|
||||||
|
# -d [<vendor>]:[<device>][:<class>]
|
||||||
|
# Show only devices with specified vendor, device and class ID.
|
||||||
|
# The ID's are given in hexadecimal and may be omitted or given
|
||||||
|
# as "*", both meaning "any value"#
|
||||||
|
#
|
||||||
|
# For example:
|
||||||
|
# :filter:
|
||||||
|
# - '10de:*' # all NVIDIA VGA cards
|
||||||
|
# - '10de:11bf' # only GK104GL [GRID K2]
|
||||||
|
# - '*:10d3' # only 82574L Gigabit Network cards
|
||||||
|
# - '8086::0c03' # only Intel USB controllers
|
||||||
|
#
|
||||||
|
# or
|
||||||
|
#
|
||||||
|
# :filter: '*:*' # all devices
|
||||||
|
#
|
||||||
|
# or
|
||||||
|
#
|
||||||
|
# :filter: '0:0' # no devices
|
||||||
|
#
|
||||||
|
:filter: '0:0'
|
||||||
|
|
||||||
|
# The PCI cards list restricted by the :filter option above can be even more
|
||||||
|
# filtered by the list of exact PCI addresses (bus:device.func).
|
||||||
|
#
|
||||||
|
# For example:
|
||||||
|
# :short_address:
|
||||||
|
# - '07:00.0'
|
||||||
|
# - '06:00.0'
|
||||||
|
#
|
||||||
|
:short_address: []
|
||||||
|
|
||||||
|
# The PCI cards list restricted by the :filter option above can be even more
|
||||||
|
# filtered by matching the device name against the list of regular expression
|
||||||
|
# case-insensitive patterns.
|
||||||
|
#
|
||||||
|
# For example:
|
||||||
|
# :device_name:
|
||||||
|
# - 'Virtual Function'
|
||||||
|
# - 'Gigabit Network'
|
||||||
|
# - 'USB.*Host Controller'
|
||||||
|
# - '^MegaRAID'
|
||||||
|
#
|
||||||
|
:device_name: []
|
121
src/im_mad/remotes/node-probes.d/pci.rb
Executable file
121
src/im_mad/remotes/node-probes.d/pci.rb
Executable file
@ -0,0 +1,121 @@
|
|||||||
|
#!/usr/bin/env ruby
|
||||||
|
|
||||||
|
# -------------------------------------------------------------------------- #
|
||||||
|
# Copyright 2002-2018, OpenNebula Project, OpenNebula Systems #
|
||||||
|
# #
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License"); you may #
|
||||||
|
# not use this file except in compliance with the License. You may obtain #
|
||||||
|
# a copy of the License at #
|
||||||
|
# #
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0 #
|
||||||
|
# #
|
||||||
|
# Unless required by applicable law or agreed to in writing, software #
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS, #
|
||||||
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. #
|
||||||
|
# See the License for the specific language governing permissions and #
|
||||||
|
# limitations under the License. #
|
||||||
|
#--------------------------------------------------------------------------- #
|
||||||
|
|
||||||
|
require 'shellwords'
|
||||||
|
require 'yaml'
|
||||||
|
|
||||||
|
begin
|
||||||
|
probes_path = File.dirname(File.realdirpath(__FILE__))
|
||||||
|
ETC_NAME = probes_path.split(File::SEPARATOR)[-1]
|
||||||
|
|
||||||
|
NAME = File.join(File.dirname(__FILE__),"../../etc/im/#{ETC_NAME}/pci.conf")
|
||||||
|
CONF = {
|
||||||
|
:filter => '0:0',
|
||||||
|
:short_address => [],
|
||||||
|
:device_name => [],
|
||||||
|
}.merge(YAML.load_file(NAME))
|
||||||
|
rescue
|
||||||
|
STDERR.puts "Invalid configuration #{NAME}"
|
||||||
|
exit(-1)
|
||||||
|
end
|
||||||
|
|
||||||
|
def get_pci(filter=nil)
|
||||||
|
command = "lspci -mmnn"
|
||||||
|
command << " -d #{filter}" if filter
|
||||||
|
|
||||||
|
text = %x(#{command})
|
||||||
|
|
||||||
|
text.split("\n").map {|l| Shellwords.split(l) }
|
||||||
|
end
|
||||||
|
|
||||||
|
def get_name_and_id(text)
|
||||||
|
m = text.match(/^(.*) \[(....)\]$/)
|
||||||
|
return m[1], m[2]
|
||||||
|
end
|
||||||
|
|
||||||
|
def parse_pci(pci)
|
||||||
|
card = {}
|
||||||
|
|
||||||
|
card[:short_address] = pci[0]
|
||||||
|
card[:libvirt_address] =
|
||||||
|
"pci_0000_#{card[:short_address].gsub(/[:.]/, '_')}"
|
||||||
|
card[:address] = "0000:#{card[:short_address].gsub(/[:.]/, ':')}"
|
||||||
|
|
||||||
|
card[:class_name], card[:class] = get_name_and_id(pci[1])
|
||||||
|
card[:vendor_name], card[:vendor] = get_name_and_id(pci[2])
|
||||||
|
card[:device_name], card[:device] = get_name_and_id(pci[3])
|
||||||
|
|
||||||
|
card[:bus], card[:slot], card[:function] = pci[0].split(/[:.]/)
|
||||||
|
|
||||||
|
card[:type] = [card[:vendor], card[:device], card[:class]].join(':')
|
||||||
|
|
||||||
|
card
|
||||||
|
end
|
||||||
|
|
||||||
|
def get_devices(filter=nil)
|
||||||
|
if filter
|
||||||
|
filter = [filter].flatten.map { |f| f.split(',') }.flatten
|
||||||
|
else
|
||||||
|
filter = [nil]
|
||||||
|
end
|
||||||
|
|
||||||
|
filter.map do |f|
|
||||||
|
get_pci(f).map {|pci| parse_pci(pci) }
|
||||||
|
end.flatten
|
||||||
|
end
|
||||||
|
|
||||||
|
filter = CONF[:filter]
|
||||||
|
|
||||||
|
devices = get_devices(filter)
|
||||||
|
|
||||||
|
def pval(name, value)
|
||||||
|
%Q( #{name} = "#{value}")
|
||||||
|
end
|
||||||
|
|
||||||
|
devices.each do |dev|
|
||||||
|
next if !CONF[:short_address].empty? && !CONF[:short_address].include?(dev[:short_address])
|
||||||
|
|
||||||
|
if !CONF[:device_name].empty?
|
||||||
|
matched = CONF[:device_name].each { |pattern|
|
||||||
|
break true if !(dev[:device_name] =~ /#{pattern}/i).nil?
|
||||||
|
}
|
||||||
|
|
||||||
|
next if matched != true
|
||||||
|
end
|
||||||
|
|
||||||
|
puts "PCI = ["
|
||||||
|
values = [
|
||||||
|
pval('TYPE', dev[:type]),
|
||||||
|
pval('VENDOR', dev[:vendor]),
|
||||||
|
pval('VENDOR_NAME', dev[:vendor_name]),
|
||||||
|
pval('DEVICE', dev[:device]),
|
||||||
|
pval('DEVICE_NAME', dev[:device_name]),
|
||||||
|
pval('CLASS', dev[:class]),
|
||||||
|
pval('CLASS_NAME', dev[:class_name]),
|
||||||
|
pval('ADDRESS', dev[:address]),
|
||||||
|
pval('SHORT_ADDRESS', dev[:short_address]),
|
||||||
|
pval('DOMAIN', '0000'),
|
||||||
|
pval('BUS', dev[:bus]),
|
||||||
|
pval('SLOT', dev[:slot]),
|
||||||
|
pval('FUNCTION', dev[:function])
|
||||||
|
]
|
||||||
|
|
||||||
|
puts values.join(",\n")
|
||||||
|
puts "]"
|
||||||
|
end
|
||||||
|
|
128
src/vmm_mad/remotes/lib/lxd/client.rb
Normal file
128
src/vmm_mad/remotes/lib/lxd/client.rb
Normal file
@ -0,0 +1,128 @@
|
|||||||
|
#!/usr/bin/ruby
|
||||||
|
|
||||||
|
# -------------------------------------------------------------------------- #
|
||||||
|
# Copyright 2002-2018, OpenNebula Project, OpenNebula Systems #
|
||||||
|
# #
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License"); you may #
|
||||||
|
# not use this file except in compliance with the License. You may obtain #
|
||||||
|
# a copy of the License at #
|
||||||
|
# #
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0 #
|
||||||
|
# #
|
||||||
|
# Unless required by applicable law or agreed to in writing, software #
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS, #
|
||||||
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. #
|
||||||
|
# See the License for the specific language governing permissions and #
|
||||||
|
# limitations under the License. #
|
||||||
|
#--------------------------------------------------------------------------- #
|
||||||
|
|
||||||
|
require 'net/http'
|
||||||
|
require 'socket'
|
||||||
|
require 'json'
|
||||||
|
|
||||||
|
#
|
||||||
|
# LXD API Client. This class is used to interact with LXD. Wraps API calls
|
||||||
|
# through the REST API
|
||||||
|
#
|
||||||
|
class LXDClient
|
||||||
|
|
||||||
|
# API Configuration Attributes
|
||||||
|
|
||||||
|
API = '/1.0'.freeze
|
||||||
|
HEADER = { 'Host' => 'localhost' }.freeze
|
||||||
|
|
||||||
|
SOCK_PATH = '/var/lib/lxd/unix.socket'
|
||||||
|
|
||||||
|
# Enable communication with LXD via unix socket
|
||||||
|
begin
|
||||||
|
SOCK = Net::BufferedIO.new(UNIXSocket.new(SOCK_PATH))
|
||||||
|
rescue StandardError
|
||||||
|
STDERR.puts('Could not open LXD socket')
|
||||||
|
Process.exit(1)
|
||||||
|
end
|
||||||
|
|
||||||
|
# Performs HTTP::Get
|
||||||
|
# Params:
|
||||||
|
# +uri+:: +string+ API path
|
||||||
|
def get(uri)
|
||||||
|
get_response(Net::HTTP::Get.new("#{API}/#{uri}", HEADER), data = nil)
|
||||||
|
end
|
||||||
|
|
||||||
|
# Performs HTTP::Delete
|
||||||
|
# Params:
|
||||||
|
# +uri+:: +string+ API path
|
||||||
|
def delete(uri)
|
||||||
|
get_response(Net::HTTP::Delete.new("#{API}/#{uri}", HEADER), data = nil)
|
||||||
|
end
|
||||||
|
|
||||||
|
# Performs HTTP::Put
|
||||||
|
# Params:
|
||||||
|
# +uri+:: +string+ API path
|
||||||
|
def put(uri, data)
|
||||||
|
get_response(Net::HTTP::Put.new("#{API}/#{uri}", HEADER), data)
|
||||||
|
end
|
||||||
|
|
||||||
|
# Performs HTTP::Post
|
||||||
|
# Params:
|
||||||
|
# +uri+:: +string+ API path
|
||||||
|
def post(uri, data)
|
||||||
|
get_response(Net::HTTP::Post.new("#{API}/#{uri}", HEADER), data)
|
||||||
|
end
|
||||||
|
|
||||||
|
# Performs HTTP::Patch
|
||||||
|
# Params:
|
||||||
|
# +uri+:: +string+ API path
|
||||||
|
def patch(uri, data)
|
||||||
|
get_response(Net::HTTP::Patch.new("#{API}/#{uri}", HEADER), data)
|
||||||
|
end
|
||||||
|
|
||||||
|
# Waits for an operation returned in response to be completed
|
||||||
|
def wait(response, timeout)
|
||||||
|
operation_id = response['operation'].split('/').last
|
||||||
|
|
||||||
|
timeout = "?timeout=#{timeout}" if timeout
|
||||||
|
|
||||||
|
response = get("operations/#{operation_id}/wait#{timeout}")
|
||||||
|
|
||||||
|
raise LXDError, response if response['metadata']['status'] == 'Failure'
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
# Returns the HTTPResponse body as a hash
|
||||||
|
# Params:
|
||||||
|
# +request+:: +Net::HTTP::Request+ made to the http server
|
||||||
|
# +data+:: +string+ for post/put/patch requests that send data to the server
|
||||||
|
# (may be nil)
|
||||||
|
|
||||||
|
def get_response(request, data)
|
||||||
|
request.body = JSON.dump(data) unless data.nil?
|
||||||
|
|
||||||
|
request.exec(SOCK, '1.1', request.path)
|
||||||
|
|
||||||
|
response = nil
|
||||||
|
|
||||||
|
loop do
|
||||||
|
response = Net::HTTPResponse.read_new(SOCK)
|
||||||
|
break unless response.is_a?(Net::HTTPContinue)
|
||||||
|
end
|
||||||
|
|
||||||
|
response.reading_body(SOCK, request.response_body_permitted?) {}
|
||||||
|
|
||||||
|
response = JSON.parse(response.body)
|
||||||
|
|
||||||
|
raise LXDError, response if response['type'] == 'error'
|
||||||
|
|
||||||
|
response
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
# Error used for raising LXDClient exception when response is error return value
|
||||||
|
class LXDError < StandardError
|
||||||
|
attr_reader :body
|
||||||
|
|
||||||
|
def initialize(msg = 'LXD API error')
|
||||||
|
@body = msg
|
||||||
|
super
|
||||||
|
end
|
||||||
|
end
|
77
src/vmm_mad/remotes/lib/lxd/command.rb
Normal file
77
src/vmm_mad/remotes/lib/lxd/command.rb
Normal file
@ -0,0 +1,77 @@
|
|||||||
|
#!/usr/bin/ruby
|
||||||
|
|
||||||
|
# -------------------------------------------------------------------------- #
|
||||||
|
# Copyright 2002-2018, OpenNebula Project, OpenNebula Systems #
|
||||||
|
# #
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License"); you may #
|
||||||
|
# not use this file except in compliance with the License. You may obtain #
|
||||||
|
# a copy of the License at #
|
||||||
|
# #
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0 #
|
||||||
|
# #
|
||||||
|
# Unless required by applicable law or agreed to in writing, software #
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS, #
|
||||||
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. #
|
||||||
|
# See the License for the specific language governing permissions and #
|
||||||
|
# limitations under the License. #
|
||||||
|
#--------------------------------------------------------------------------- #
|
||||||
|
|
||||||
|
require 'open3'
|
||||||
|
|
||||||
|
# This module can be used to execute commands. It wraps popen3 and provides
|
||||||
|
# locking capabilites using flock
|
||||||
|
module Command
|
||||||
|
LOCK_FILE = '/tmp/onelxd-lock'
|
||||||
|
|
||||||
|
def self.execute(cmd, block)
|
||||||
|
rc = -1
|
||||||
|
stdout = ''
|
||||||
|
stderr = ''
|
||||||
|
|
||||||
|
begin
|
||||||
|
fd = lock if block
|
||||||
|
|
||||||
|
Open3.popen3(cmd) { |i, o, e, t|
|
||||||
|
rc = t.value.exitstatus
|
||||||
|
|
||||||
|
stdout = o.read
|
||||||
|
stderr = e.read
|
||||||
|
|
||||||
|
o.close
|
||||||
|
e.close
|
||||||
|
}
|
||||||
|
rescue
|
||||||
|
|
||||||
|
ensure
|
||||||
|
unlock(fd) if block
|
||||||
|
end
|
||||||
|
|
||||||
|
[rc, stdout, stderr]
|
||||||
|
end
|
||||||
|
|
||||||
|
def self.execute_once(cmd, lock)
|
||||||
|
execute(cmd, lock) unless running?(cmd.split[0])
|
||||||
|
end
|
||||||
|
|
||||||
|
def self.lxc_execute(lxd_id, cmd)
|
||||||
|
cmd = "lxc exec #{lxd_id} -- #{cmd}"
|
||||||
|
execute(cmd, true)
|
||||||
|
end
|
||||||
|
|
||||||
|
# Return true if command is running
|
||||||
|
def self.running?(command)
|
||||||
|
!`ps --noheaders -C #{command}`.empty?
|
||||||
|
end
|
||||||
|
|
||||||
|
def self.lock
|
||||||
|
lfd = File.open(LOCK_FILE,"w")
|
||||||
|
lfd.flock(File::LOCK_EX)
|
||||||
|
|
||||||
|
return lfd
|
||||||
|
end
|
||||||
|
|
||||||
|
def self.unlock(lfd)
|
||||||
|
lfd.close
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
418
src/vmm_mad/remotes/lib/lxd/container.rb
Normal file
418
src/vmm_mad/remotes/lib/lxd/container.rb
Normal file
@ -0,0 +1,418 @@
|
|||||||
|
#!/usr/bin/ruby
|
||||||
|
|
||||||
|
# -------------------------------------------------------------------------- #
|
||||||
|
# Copyright 2002-2018, OpenNebula Project, OpenNebula Systems #
|
||||||
|
# #
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License"); you may #
|
||||||
|
# not use this file except in compliance with the License. You may obtain #
|
||||||
|
# a copy of the License at #
|
||||||
|
# #
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0 #
|
||||||
|
# #
|
||||||
|
# Unless required by applicable law or agreed to in writing, software #
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS, #
|
||||||
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. #
|
||||||
|
# See the License for the specific language governing permissions and #
|
||||||
|
# limitations under the License. #
|
||||||
|
#--------------------------------------------------------------------------- #
|
||||||
|
|
||||||
|
$LOAD_PATH.unshift File.dirname(__FILE__)
|
||||||
|
|
||||||
|
require 'client'
|
||||||
|
|
||||||
|
require 'opennebula_vm'
|
||||||
|
require 'command'
|
||||||
|
|
||||||
|
require 'mapper'
|
||||||
|
require 'raw'
|
||||||
|
require 'qcow2'
|
||||||
|
require 'rbd'
|
||||||
|
|
||||||
|
# This class interacts with the LXD container on REST level
|
||||||
|
class Container
|
||||||
|
|
||||||
|
#---------------------------------------------------------------------------
|
||||||
|
# Class Constants API and Containers Paths
|
||||||
|
#---------------------------------------------------------------------------
|
||||||
|
CONTAINERS = 'containers'.freeze
|
||||||
|
|
||||||
|
#---------------------------------------------------------------------------
|
||||||
|
# Methods to access container attributes
|
||||||
|
#---------------------------------------------------------------------------
|
||||||
|
CONTAINER_ATTRIBUTES = %w[name status status_code devices config profile
|
||||||
|
expanded_config expanded_devices architecture].freeze
|
||||||
|
|
||||||
|
CONTAINER_ATTRIBUTES.each do |attr|
|
||||||
|
define_method(attr.to_sym) do
|
||||||
|
@lxc[attr]
|
||||||
|
end
|
||||||
|
|
||||||
|
define_method("#{attr}=".to_sym) do |value|
|
||||||
|
@lxc[attr] = value
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
# Return if this is a wild container. Needs the associated OpenNebulaVM
|
||||||
|
# description
|
||||||
|
def wild?
|
||||||
|
@one.wild? if @one
|
||||||
|
end
|
||||||
|
|
||||||
|
#---------------------------------------------------------------------------
|
||||||
|
# Class constructors & static methods
|
||||||
|
#---------------------------------------------------------------------------
|
||||||
|
# Creates the container object in memory.
|
||||||
|
# Can be later created in LXD using create method
|
||||||
|
def initialize(lxc, one, client)
|
||||||
|
@client = client
|
||||||
|
|
||||||
|
@lxc = lxc
|
||||||
|
@one = one
|
||||||
|
end
|
||||||
|
|
||||||
|
class << self
|
||||||
|
|
||||||
|
# Returns specific container, by its name
|
||||||
|
# Params:
|
||||||
|
# +name+:: container name
|
||||||
|
def get(name, one_xml, client)
|
||||||
|
info = client.get("#{CONTAINERS}/#{name}")['metadata']
|
||||||
|
|
||||||
|
one = nil
|
||||||
|
one = OpenNebulaVM.new(one_xml) if one_xml
|
||||||
|
|
||||||
|
Container.new(info, one, client)
|
||||||
|
rescue LXDError => exception
|
||||||
|
raise exception
|
||||||
|
end
|
||||||
|
|
||||||
|
# Creates container from a OpenNebula VM xml description
|
||||||
|
def new_from_xml(one_xml, client)
|
||||||
|
one = OpenNebulaVM.new(one_xml)
|
||||||
|
|
||||||
|
Container.new(one.to_lxc, one, client)
|
||||||
|
end
|
||||||
|
|
||||||
|
# Returns an array of container objects
|
||||||
|
def get_all(client)
|
||||||
|
containers = []
|
||||||
|
|
||||||
|
container_names = client.get(CONTAINERS)['metadata']
|
||||||
|
container_names.each do |name|
|
||||||
|
name = name.split('/').last
|
||||||
|
containers.push(get(name, nil, client))
|
||||||
|
end
|
||||||
|
|
||||||
|
containers
|
||||||
|
end
|
||||||
|
|
||||||
|
# Returns boolean indicating if the container exists(true) or not (false)
|
||||||
|
def exist?(name, client)
|
||||||
|
client.get("#{CONTAINERS}/#{name}")
|
||||||
|
true
|
||||||
|
rescue LXDError => exception
|
||||||
|
raise exception if exception.body['error_code'] != 404
|
||||||
|
|
||||||
|
false
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
#---------------------------------------------------------------------------
|
||||||
|
# Container Management & Monitor
|
||||||
|
#---------------------------------------------------------------------------
|
||||||
|
# Create a container without a base image
|
||||||
|
def create(wait: true, timeout: '')
|
||||||
|
@lxc['source'] = { 'type' => 'none' }
|
||||||
|
wait?(@client.post(CONTAINERS, @lxc), wait, timeout)
|
||||||
|
|
||||||
|
@lxc = @client.get("#{CONTAINERS}/#{name}")['metadata']
|
||||||
|
end
|
||||||
|
|
||||||
|
# Delete container
|
||||||
|
def delete(wait: true, timeout: '')
|
||||||
|
wait?(@client.delete("#{CONTAINERS}/#{name}"), wait, timeout)
|
||||||
|
end
|
||||||
|
|
||||||
|
# Updates the container in LXD server with the new configuration
|
||||||
|
def update(wait: true, timeout: '')
|
||||||
|
wait?(@client.put("#{CONTAINERS}/#{name}", @lxc), wait, timeout)
|
||||||
|
end
|
||||||
|
|
||||||
|
# Returns the container current state
|
||||||
|
def monitor
|
||||||
|
@client.get("#{CONTAINERS}/#{name}/state")
|
||||||
|
end
|
||||||
|
|
||||||
|
# Retreive metadata for the container
|
||||||
|
def get_metadata
|
||||||
|
@lxc = @client.get("#{CONTAINERS}/#{name}")['metadata']
|
||||||
|
end
|
||||||
|
|
||||||
|
# Runs command inside container
|
||||||
|
# @param command [String] to execute through lxc exec
|
||||||
|
def exec(command)
|
||||||
|
Command.lxd_execute(name, command)
|
||||||
|
end
|
||||||
|
|
||||||
|
#---------------------------------------------------------------------------
|
||||||
|
# Contianer Status Control
|
||||||
|
#---------------------------------------------------------------------------
|
||||||
|
def start(options = {})
|
||||||
|
change_state(__method__, options)
|
||||||
|
end
|
||||||
|
|
||||||
|
def stop(options = {})
|
||||||
|
change_state(__method__, options)
|
||||||
|
end
|
||||||
|
|
||||||
|
def restart(options = {})
|
||||||
|
change_state(__method__, options)
|
||||||
|
end
|
||||||
|
|
||||||
|
def freeze(options = {})
|
||||||
|
change_state(__method__, options)
|
||||||
|
end
|
||||||
|
|
||||||
|
def unfreeze(options = {})
|
||||||
|
change_state(__method__, options)
|
||||||
|
end
|
||||||
|
|
||||||
|
#---------------------------------------------------------------------------
|
||||||
|
# Container Networking
|
||||||
|
#---------------------------------------------------------------------------
|
||||||
|
def attach_nic(mac)
|
||||||
|
return unless @one
|
||||||
|
|
||||||
|
nic_xml = @one.get_nic_by_mac(mac)
|
||||||
|
|
||||||
|
return unless nic_xml
|
||||||
|
|
||||||
|
nic_config = @one.nic(nic_xml)
|
||||||
|
|
||||||
|
@lxc['devices'].update(nic_config)
|
||||||
|
|
||||||
|
update
|
||||||
|
end
|
||||||
|
|
||||||
|
def detach_nic(mac)
|
||||||
|
@lxc['devices'].delete_if do |device, config|
|
||||||
|
device.include?('eth') && config['hwaddr'] == mac
|
||||||
|
end
|
||||||
|
|
||||||
|
update
|
||||||
|
end
|
||||||
|
|
||||||
|
#---------------------------------------------------------------------------
|
||||||
|
# Container Storage
|
||||||
|
#---------------------------------------------------------------------------
|
||||||
|
# Sets up the container mounts for type: disk devices.
|
||||||
|
def setup_storage(operation)
|
||||||
|
return unless @one
|
||||||
|
|
||||||
|
@one.get_disks.each do |disk|
|
||||||
|
setup_disk(disk, operation)
|
||||||
|
end
|
||||||
|
|
||||||
|
return unless @one.has_context?
|
||||||
|
|
||||||
|
csrc = @lxc['devices']['context']['source'].clone
|
||||||
|
|
||||||
|
context = @one.get_context_disk
|
||||||
|
mapper = FSRawMapper.new
|
||||||
|
|
||||||
|
context_path = "#{@one.lxdrc[:containers]}/#{name}/rootfs/context"
|
||||||
|
create_context_dir = "#{Mapper::COMMANDS[:su_mkdir]} #{context_path}"
|
||||||
|
|
||||||
|
Command.execute(create_context_dir, false)
|
||||||
|
|
||||||
|
mapper.public_send(operation, @one, context, csrc)
|
||||||
|
end
|
||||||
|
|
||||||
|
# Generate the context devices and maps the context the device
|
||||||
|
def attach_context
|
||||||
|
@one.context(@lxc['devices'])
|
||||||
|
|
||||||
|
csrc = @lxc['devices']['context']['source'].clone
|
||||||
|
|
||||||
|
context = @one.get_context_disk
|
||||||
|
mapper = FSRawMapper.new
|
||||||
|
|
||||||
|
mapper.map(@one, context, csrc)
|
||||||
|
|
||||||
|
update
|
||||||
|
end
|
||||||
|
|
||||||
|
# Removes the context section from the LXD configuration and unmap the
|
||||||
|
# context device
|
||||||
|
def detach_context
|
||||||
|
return unless @one.has_context?
|
||||||
|
|
||||||
|
csrc = @lxc['devices']['context']['source'].clone
|
||||||
|
|
||||||
|
@lxc['devices'].delete('context')['source']
|
||||||
|
|
||||||
|
update
|
||||||
|
|
||||||
|
context = @one.get_context_disk
|
||||||
|
mapper = FSRawMapper.new
|
||||||
|
|
||||||
|
mapper.unmap(@one, context, csrc)
|
||||||
|
end
|
||||||
|
|
||||||
|
# Attach disk to container (ATTACH = YES) in VM description
|
||||||
|
def attach_disk(source)
|
||||||
|
disk_element = hotplug_disk
|
||||||
|
return unless disk_element
|
||||||
|
|
||||||
|
setup_disk(disk_element, 'map')
|
||||||
|
|
||||||
|
source2 = source.dup
|
||||||
|
if source
|
||||||
|
mapper_location = source2.index('/disk.')
|
||||||
|
source2.insert(mapper_location, '/mapper')
|
||||||
|
end
|
||||||
|
|
||||||
|
disk_hash = @one.disk(disk_element, source2, nil)
|
||||||
|
|
||||||
|
@lxc['devices'].update(disk_hash)
|
||||||
|
|
||||||
|
update
|
||||||
|
end
|
||||||
|
|
||||||
|
# Detects disk being hotplugged
|
||||||
|
def hotplug_disk
|
||||||
|
return unless @one
|
||||||
|
|
||||||
|
disk_a = @one.get_disks.select do |disk|
|
||||||
|
disk['ATTACH'].casecmp('YES').zero?
|
||||||
|
end
|
||||||
|
|
||||||
|
disk_a.first
|
||||||
|
end
|
||||||
|
|
||||||
|
# Detach disk to container (ATTACH = YES) in VM description
|
||||||
|
def detach_disk
|
||||||
|
disk_element = hotplug_disk
|
||||||
|
return unless disk_element
|
||||||
|
|
||||||
|
disk_name = "disk#{disk_element['DISK_ID']}"
|
||||||
|
|
||||||
|
csrc = @lxc['devices'][disk_name]['source'].clone
|
||||||
|
|
||||||
|
|
||||||
|
@lxc['devices'].delete(disk_name)['source']
|
||||||
|
|
||||||
|
update
|
||||||
|
|
||||||
|
mapper = new_disk_mapper(@one, disk_element)
|
||||||
|
mapper.unmap(@one, disk_element, csrc)
|
||||||
|
end
|
||||||
|
|
||||||
|
# Setup the disk by mapping/unmapping the disk device
|
||||||
|
def setup_disk(disk, operation)
|
||||||
|
return unless @one
|
||||||
|
|
||||||
|
ds_path = @one.ds_path
|
||||||
|
ds_id = @one.sysds_id
|
||||||
|
|
||||||
|
vm_id = @one.vm_id
|
||||||
|
disk_id = disk['DISK_ID']
|
||||||
|
|
||||||
|
if disk_id == @one.rootfs_id
|
||||||
|
target = "#{@one.lxdrc[:containers]}/#{name}/rootfs"
|
||||||
|
else
|
||||||
|
target = @one.disk_mountpoint(disk_id)
|
||||||
|
end
|
||||||
|
|
||||||
|
mapper = new_disk_mapper(disk)
|
||||||
|
mapper.public_send(operation, @one, disk, target)
|
||||||
|
end
|
||||||
|
|
||||||
|
# Start the svncterm server if it is down.
|
||||||
|
def vnc(signal)
|
||||||
|
command = @one.vnc_command(signal)
|
||||||
|
return if command.nil?
|
||||||
|
|
||||||
|
w = @one.lxdrc[:vnc][:width]
|
||||||
|
h = @one.lxdrc[:vnc][:height]
|
||||||
|
t = @one.lxdrc[:vnc][:timeout]
|
||||||
|
|
||||||
|
vnc_args = "-w #{w} -h #{h} -t #{t}"
|
||||||
|
|
||||||
|
pipe = '/tmp/svncterm_server_pipe'
|
||||||
|
bin = 'svncterm_server'
|
||||||
|
server = "#{bin} #{vnc_args}"
|
||||||
|
|
||||||
|
Command.execute_once(server, true)
|
||||||
|
|
||||||
|
lfd = Command.lock
|
||||||
|
|
||||||
|
File.open(pipe, 'a') do |f|
|
||||||
|
f.write command
|
||||||
|
end
|
||||||
|
|
||||||
|
ensure
|
||||||
|
Command.unlock(lfd) if lfd
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
# Waits or no for response depending on wait value
|
||||||
|
def wait?(response, wait, timeout)
|
||||||
|
@client.wait(response, timeout) unless wait == false
|
||||||
|
end
|
||||||
|
|
||||||
|
# Performs an action on the container that changes the execution status.
|
||||||
|
# Accepts optional args
|
||||||
|
def change_state(action, options)
|
||||||
|
options.update(:action => action)
|
||||||
|
|
||||||
|
response = @client.put("#{CONTAINERS}/#{name}/state", options)
|
||||||
|
wait?(response, options[:wait], options[:timeout])
|
||||||
|
|
||||||
|
@lxc = @client.get("#{CONTAINERS}/#{name}")['metadata']
|
||||||
|
|
||||||
|
status
|
||||||
|
end
|
||||||
|
|
||||||
|
# Returns a mapper for the disk
|
||||||
|
# @param disk [XMLElement] with the disk data
|
||||||
|
#
|
||||||
|
# TODO This maps should be built dynamically or based on a DISK attribute
|
||||||
|
# so new mappers does not need to modified source code
|
||||||
|
def new_disk_mapper(disk)
|
||||||
|
case disk['TYPE']
|
||||||
|
when 'FILE'
|
||||||
|
ds_path = @one.ds_path
|
||||||
|
ds_id = @one.sysds_id
|
||||||
|
|
||||||
|
vm_id = @one.vm_id
|
||||||
|
disk_id = disk['DISK_ID']
|
||||||
|
|
||||||
|
ds = "#{ds_path}/#{ds_id}/#{vm_id}/disk.#{disk_id}"
|
||||||
|
|
||||||
|
Command.execute("#{Mapper::COMMANDS[:chmod_nfs]} #{ds}", false)
|
||||||
|
|
||||||
|
_rc, out, _err = Command.execute("#{Mapper::COMMANDS[:file]} #{ds}", false)
|
||||||
|
|
||||||
|
case out
|
||||||
|
when /.*QEMU QCOW.*/
|
||||||
|
OpenNebula.log "Using qcow2 mapper for #{ds}"
|
||||||
|
return Qcow2Mapper.new
|
||||||
|
when /.*filesystem.*/
|
||||||
|
OpenNebula.log "Using raw filesystem mapper for #{ds}"
|
||||||
|
return FSRawMapper.new
|
||||||
|
when /.*boot sector.*/
|
||||||
|
OpenNebula.log "Using raw disk mapper for #{ds}"
|
||||||
|
return DiskRawMapper.new
|
||||||
|
else
|
||||||
|
OpenNebula.log('Unknown image format, trying raw filesystem mapper')
|
||||||
|
return FSRawMapper.new
|
||||||
|
end
|
||||||
|
when 'RBD'
|
||||||
|
RBDMapper.new
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
413
src/vmm_mad/remotes/lib/lxd/mapper/mapper.rb
Normal file
413
src/vmm_mad/remotes/lib/lxd/mapper/mapper.rb
Normal file
@ -0,0 +1,413 @@
|
|||||||
|
#!/usr/bin/ruby
|
||||||
|
|
||||||
|
# -------------------------------------------------------------------------- #
|
||||||
|
# Copyright 2002-2018, OpenNebula Project, OpenNebula Systems #
|
||||||
|
# #
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License"); you may #
|
||||||
|
# not use this file except in compliance with the License. You may obtain #
|
||||||
|
# a copy of the License at #
|
||||||
|
# #
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0 #
|
||||||
|
# #
|
||||||
|
# Unless required by applicable law or agreed to in writing, software #
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS, #
|
||||||
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. #
|
||||||
|
# See the License for the specific language governing permissions and #
|
||||||
|
# limitations under the License. #
|
||||||
|
#--------------------------------------------------------------------------- #
|
||||||
|
|
||||||
|
$LOAD_PATH.unshift File.dirname(__FILE__)
|
||||||
|
|
||||||
|
require 'fileutils'
|
||||||
|
require 'json'
|
||||||
|
|
||||||
|
require 'opennebula_vm'
|
||||||
|
require 'command'
|
||||||
|
|
||||||
|
# Mappers class provides an interface to map devices into the host filesystem
|
||||||
|
# This class uses an array of partitions as output by lsblk in JSON:
|
||||||
|
# [
|
||||||
|
# {
|
||||||
|
# "name" : "loop1p3",
|
||||||
|
# "path" : "/dev/mapper/loop1p3",
|
||||||
|
# "type" : "part",
|
||||||
|
# "fstype" : "..",
|
||||||
|
# "label" : null,
|
||||||
|
# "uuid" : null,
|
||||||
|
# "fsavail": "...M",
|
||||||
|
# "fsuse%" : "..%",
|
||||||
|
# "mountpoint":"/boot"
|
||||||
|
# },
|
||||||
|
# {
|
||||||
|
# ....
|
||||||
|
# children : [
|
||||||
|
# ]
|
||||||
|
# }
|
||||||
|
# ]
|
||||||
|
class Mapper
|
||||||
|
#---------------------------------------------------------------------------
|
||||||
|
# Class constants
|
||||||
|
# - COMMANDS list of commands executed by the driver. This list can
|
||||||
|
# be tunned to specific paths. It contians the list of commands executed
|
||||||
|
# as root
|
||||||
|
#---------------------------------------------------------------------------
|
||||||
|
COMMANDS = {
|
||||||
|
:lsblk => 'sudo lsblk',
|
||||||
|
:losetup => 'sudo losetup',
|
||||||
|
:mount => 'sudo mount',
|
||||||
|
:umount => 'sudo umount',
|
||||||
|
:kpartx => 'sudo kpartx',
|
||||||
|
:nbd => 'sudo qemu-nbd',
|
||||||
|
:su_mkdir => 'sudo mkdir -p',
|
||||||
|
:mkdir => 'mkdir -p',
|
||||||
|
:cat => 'sudo cat',
|
||||||
|
:file => 'file -L',
|
||||||
|
:blkid => 'sudo blkid',
|
||||||
|
:e2fsck => 'sudo e2fsck',
|
||||||
|
:resize2fs => 'sudo resize2fs',
|
||||||
|
:xfs_growfs => 'sudo xfs_growfs',
|
||||||
|
:chmod_nfs => 'chmod o+w'
|
||||||
|
}
|
||||||
|
|
||||||
|
#---------------------------------------------------------------------------
|
||||||
|
# Interface to be implemented by specific mapper modules
|
||||||
|
#---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
# Maps the disk to host devices
|
||||||
|
# @param onevm [OpenNebulaVM] with the VM description
|
||||||
|
# @param disk [XMLElement] with the disk data
|
||||||
|
# @param directory [String] where the disk has to be mounted
|
||||||
|
# @return [String] Name of the mapped device, empty in case of error.
|
||||||
|
#
|
||||||
|
# Errors should be log using OpenNebula driver functions
|
||||||
|
def do_map(one_vm, disk, directory)
|
||||||
|
OpenNebula.log_error("map function not implemented for #{self.class}")
|
||||||
|
return nil
|
||||||
|
end
|
||||||
|
|
||||||
|
# Unmaps a previously mapped partition
|
||||||
|
# @param device [String] where the disk is mapped
|
||||||
|
# @param disk [XMLElement] with the disk data
|
||||||
|
# @param directory [String] where the disk has to be mounted
|
||||||
|
#
|
||||||
|
# @return nil
|
||||||
|
def do_unmap(device, one_vm, disk, directory)
|
||||||
|
OpenNebula.log_error("unmap function not implemented for #{self.class}")
|
||||||
|
return nil
|
||||||
|
end
|
||||||
|
|
||||||
|
#---------------------------------------------------------------------------
|
||||||
|
# Mapper Interface 'map' & 'unmap' methods
|
||||||
|
#---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
# Maps a disk to a given directory
|
||||||
|
# @param onevm [OpenNebulaVM] with the VM description
|
||||||
|
# @param disk [XMLElement] with the disk data
|
||||||
|
# @param directory [String] Path to the directory where the disk has to be
|
||||||
|
# mounted. Example: /var/lib/one/datastores/100/3/mapper/disk.2
|
||||||
|
#
|
||||||
|
# @return true on success
|
||||||
|
def map(one_vm, disk, directory)
|
||||||
|
device = do_map(one_vm, disk, directory)
|
||||||
|
|
||||||
|
OpenNebula.log_info "Mapping disk at #{directory} using device #{device}"
|
||||||
|
|
||||||
|
return false if !device
|
||||||
|
|
||||||
|
partitions = lsblk(device)
|
||||||
|
|
||||||
|
return false if !partitions
|
||||||
|
|
||||||
|
#-----------------------------------------------------------------------
|
||||||
|
# Mount disk images with partitions
|
||||||
|
#-----------------------------------------------------------------------
|
||||||
|
|
||||||
|
return mount(partitions, directory) if partitions[0]['type'] == 'part'
|
||||||
|
|
||||||
|
#-----------------------------------------------------------------------
|
||||||
|
# Resize partitions if needed and mount single filesystem disk images
|
||||||
|
#-----------------------------------------------------------------------
|
||||||
|
type = partitions[0]['type']
|
||||||
|
|
||||||
|
return mount_dev(device, directory) unless %w[loop disk].include?(type)
|
||||||
|
|
||||||
|
size = disk['SIZE'].to_i if disk['SIZE']
|
||||||
|
osize = disk['ORIGINAL_SIZE'].to_i if disk['ORIGINAL_SIZE']
|
||||||
|
|
||||||
|
# TODO: Osize is always < size after 1st resize during deployment
|
||||||
|
return mount_dev(device, directory) unless size > osize
|
||||||
|
|
||||||
|
# Resize filesystem
|
||||||
|
cmd = "#{COMMANDS[:blkid]} -o export #{device}"
|
||||||
|
_rc, o, _e = Command.execute(cmd, false)
|
||||||
|
|
||||||
|
fs_type = ''
|
||||||
|
|
||||||
|
o.each_line {|l|
|
||||||
|
next unless (m = l.match(/TYPE=(.*)/))
|
||||||
|
|
||||||
|
fs_type = m[1]
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
rc = true
|
||||||
|
|
||||||
|
OpenNebula.log_info "Resizing filesystem #{fs_type} on #{device}"
|
||||||
|
|
||||||
|
case fs_type
|
||||||
|
when /xfs/
|
||||||
|
rc = mount_dev(device, directory)
|
||||||
|
return false unless rc
|
||||||
|
|
||||||
|
Command.execute("#{COMMANDS[:xfs_growfs]} -d #{directory}", false)
|
||||||
|
when /ext/
|
||||||
|
Command.execute("#{COMMANDS[:e2fsck]} -f -y #{device}", false)
|
||||||
|
Command.execute("#{COMMANDS[:resize2fs]} #{device}", false)
|
||||||
|
rc = mount_dev(device, directory)
|
||||||
|
else
|
||||||
|
OpenNebula.log_info "Skipped filesystem #{fs_type} resize"
|
||||||
|
rc = mount_dev(device, directory)
|
||||||
|
end
|
||||||
|
|
||||||
|
rc
|
||||||
|
end
|
||||||
|
|
||||||
|
# Unmaps a disk from a given directory
|
||||||
|
# @param disk [XMLElement] with the disk data
|
||||||
|
# @param directory [String] Path to the directory where the disk has to be
|
||||||
|
# mounted. Example: /var/lib/one/datastores/100/3/mapper/disk.2
|
||||||
|
#
|
||||||
|
# @return true on success
|
||||||
|
def unmap(one_vm, disk, directory)
|
||||||
|
OpenNebula.log_info "Unmapping disk at #{directory}"
|
||||||
|
|
||||||
|
sys_parts = lsblk('')
|
||||||
|
partitions = []
|
||||||
|
device = ''
|
||||||
|
|
||||||
|
return false if !sys_parts
|
||||||
|
|
||||||
|
sys_parts.each { |d|
|
||||||
|
if d['mountpoint'] == directory
|
||||||
|
partitions = [d]
|
||||||
|
device = d['path']
|
||||||
|
break
|
||||||
|
end
|
||||||
|
|
||||||
|
d['children'].each { |c|
|
||||||
|
if c['mountpoint'] == directory
|
||||||
|
partitions = d['children']
|
||||||
|
device = d['path']
|
||||||
|
break
|
||||||
|
end
|
||||||
|
} if d['children']
|
||||||
|
|
||||||
|
break if !partitions.empty?
|
||||||
|
}
|
||||||
|
|
||||||
|
partitions.delete_if { |p| !p['mountpoint'] }
|
||||||
|
|
||||||
|
partitions.sort! { |a,b|
|
||||||
|
b['mountpoint'].length <=> a['mountpoint'].length
|
||||||
|
}
|
||||||
|
|
||||||
|
umount(partitions)
|
||||||
|
|
||||||
|
do_unmap(device, one_vm, disk, directory)
|
||||||
|
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
#---------------------------------------------------------------------------
|
||||||
|
# Methods to mount/umount partitions
|
||||||
|
#---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
# Umounts partitions
|
||||||
|
# @param partitions [Array] with partition device names
|
||||||
|
def umount(partitions)
|
||||||
|
partitions.each { |p|
|
||||||
|
next if !p['mountpoint']
|
||||||
|
|
||||||
|
umount_dev(p['path'])
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
# Mounts partitions
|
||||||
|
# @param partitions [Array] with partition device names
|
||||||
|
# @param path [String] to directory to mount the disk partitions
|
||||||
|
def mount(partitions, path)
|
||||||
|
# Single partition
|
||||||
|
# ----------------
|
||||||
|
return mount_dev(partitions[0]['path'], path) if partitions.size == 1
|
||||||
|
|
||||||
|
# Multiple partitions
|
||||||
|
# -------------------
|
||||||
|
rc = true
|
||||||
|
fstab = ''
|
||||||
|
|
||||||
|
# Look for fstab and mount rootfs in path. First partition with
|
||||||
|
# a /etc/fstab file is used as rootfs and it is kept mounted
|
||||||
|
partitions.each do |p|
|
||||||
|
rc = mount_dev(p['path'], path)
|
||||||
|
|
||||||
|
return false if !rc
|
||||||
|
|
||||||
|
cmd = "#{COMMANDS[:cat]} #{path}/etc/fstab"
|
||||||
|
|
||||||
|
rc, fstab, e = Command.execute(cmd, false)
|
||||||
|
|
||||||
|
if fstab.empty?
|
||||||
|
umount_dev(p['path'])
|
||||||
|
next
|
||||||
|
end
|
||||||
|
|
||||||
|
break
|
||||||
|
end
|
||||||
|
|
||||||
|
if fstab.empty?
|
||||||
|
OpenNebula.log_error("mount: No fstab file found in disk partitions")
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
|
||||||
|
# Parse fstab contents & mount partitions
|
||||||
|
fstab.each_line do |l|
|
||||||
|
next if l.strip.chomp.empty?
|
||||||
|
next if l =~ /\s*#/
|
||||||
|
|
||||||
|
fs, mount_point, type, opts, dump, pass = l.split
|
||||||
|
|
||||||
|
if l =~ /^\s*LABEL=/ # disk by LABEL
|
||||||
|
value = fs.split("=").last.strip.chomp
|
||||||
|
key = 'label'
|
||||||
|
elsif l =~ /^\s*UUID=/ #disk by UUID
|
||||||
|
value = fs.split("=").last.strip.chomp
|
||||||
|
key = 'uuid'
|
||||||
|
else #disk by device - NOT SUPPORTED or other FS
|
||||||
|
next
|
||||||
|
end
|
||||||
|
|
||||||
|
next if mount_point == '/' || mount_point == 'swap'
|
||||||
|
|
||||||
|
partitions.each { |p|
|
||||||
|
next if p[key] != value
|
||||||
|
|
||||||
|
rc = mount_dev(p['path'], path + mount_point)
|
||||||
|
return false if !rc
|
||||||
|
break
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
return rc
|
||||||
|
end
|
||||||
|
|
||||||
|
# --------------------------------------------------------------------------
|
||||||
|
# Functions to mount/umount devices
|
||||||
|
# --------------------------------------------------------------------------
|
||||||
|
|
||||||
|
# Mount the given device. It creates the directory if need. NOTE: The rootfs
|
||||||
|
# dir is created as root as it is typically under lxd/storage-pools and it
|
||||||
|
# is managed by LXD
|
||||||
|
# @param dev [String] device name
|
||||||
|
# @param path [String] to mount the device
|
||||||
|
#
|
||||||
|
# @return true on success
|
||||||
|
def mount_dev(dev, path)
|
||||||
|
OpenNebula.log_info "Mounting #{dev} at #{path}"
|
||||||
|
|
||||||
|
if path =~ /.*\/rootfs/
|
||||||
|
cmd = COMMANDS[:su_mkdir]
|
||||||
|
else
|
||||||
|
cmd = COMMANDS[:mkdir]
|
||||||
|
end
|
||||||
|
|
||||||
|
Command.execute("#{cmd} #{path}", false)
|
||||||
|
|
||||||
|
rc, out, err = Command.execute("#{COMMANDS[:mount]} #{dev} #{path}",true)
|
||||||
|
|
||||||
|
if rc != 0
|
||||||
|
OpenNebula.log_error("mount_dev: #{err}")
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
|
||||||
|
true
|
||||||
|
end
|
||||||
|
|
||||||
|
def umount_dev(dev)
|
||||||
|
OpenNebula.log_info "Umounting disk mapped at #{dev}"
|
||||||
|
|
||||||
|
Command.execute("#{COMMANDS[:umount]} #{dev}", true)
|
||||||
|
end
|
||||||
|
|
||||||
|
#---------------------------------------------------------------------------
|
||||||
|
# Mapper helper functions
|
||||||
|
#---------------------------------------------------------------------------
|
||||||
|
# Get the partitions on the system or device
|
||||||
|
# @param device [String] to get the partitions from. Use and empty string
|
||||||
|
# for host partitions
|
||||||
|
# @return [Hash] with partitions
|
||||||
|
def lsblk(device)
|
||||||
|
rc, o, e = Command.execute("#{COMMANDS[:lsblk]} -OJ #{device}", false)
|
||||||
|
|
||||||
|
if rc != 0 || o.empty?
|
||||||
|
OpenNebula.log_error("lsblk: #{e}")
|
||||||
|
return nil
|
||||||
|
end
|
||||||
|
|
||||||
|
partitions = nil
|
||||||
|
|
||||||
|
begin
|
||||||
|
partitions = JSON.parse(o)['blockdevices']
|
||||||
|
|
||||||
|
if !device.empty?
|
||||||
|
partitions = partitions[0]
|
||||||
|
|
||||||
|
if partitions['children']
|
||||||
|
partitions = partitions['children']
|
||||||
|
else
|
||||||
|
partitions = [partitions]
|
||||||
|
end
|
||||||
|
|
||||||
|
partitions.delete_if { |p|
|
||||||
|
p['fstype'].casecmp?('swap') if p['fstype']
|
||||||
|
}
|
||||||
|
end
|
||||||
|
rescue
|
||||||
|
OpenNebula.log_error("lsblk: error parsing lsblk -OJ #{device}")
|
||||||
|
return nil
|
||||||
|
end
|
||||||
|
|
||||||
|
# Fix for lsblk paths for version < 2.33
|
||||||
|
partitions.each { |p|
|
||||||
|
lsblk_path(p)
|
||||||
|
|
||||||
|
p['children'].each { |q| lsblk_path(q) } if p['children']
|
||||||
|
}
|
||||||
|
|
||||||
|
partitions
|
||||||
|
end
|
||||||
|
|
||||||
|
# @return [String] the canonical disk path for the given disk
|
||||||
|
def disk_source(one_vm, disk)
|
||||||
|
ds_path = one_vm.ds_path
|
||||||
|
ds_id = one_vm.sysds_id
|
||||||
|
|
||||||
|
vm_id = one_vm.vm_id
|
||||||
|
disk_id = disk['DISK_ID']
|
||||||
|
|
||||||
|
"#{ds_path}/#{ds_id}/#{vm_id}/disk.#{disk_id}"
|
||||||
|
end
|
||||||
|
|
||||||
|
# Adds path to the partition Hash. This is needed for lsblk version < 2.33
|
||||||
|
def lsblk_path(p)
|
||||||
|
return unless !p['path'] && p['name']
|
||||||
|
|
||||||
|
if File.exists?("/dev/#{p['name']}")
|
||||||
|
p['path'] = "/dev/#{p['name']}"
|
||||||
|
elsif File.exists?("/dev/mapper/#{p['name']}")
|
||||||
|
p['path'] = "/dev/mapper/#{p['name']}"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
86
src/vmm_mad/remotes/lib/lxd/mapper/qcow2.rb
Normal file
86
src/vmm_mad/remotes/lib/lxd/mapper/qcow2.rb
Normal file
@ -0,0 +1,86 @@
|
|||||||
|
#!/usr/bin/ruby
|
||||||
|
|
||||||
|
# -------------------------------------------------------------------------- #
|
||||||
|
# Copyright 2002-2018, OpenNebula Project, OpenNebula Systems #
|
||||||
|
# #
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License"); you may #
|
||||||
|
# not use this file except in compliance with the License. You may obtain #
|
||||||
|
# a copy of the License at #
|
||||||
|
# #
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0 #
|
||||||
|
# #
|
||||||
|
# Unless required by applicable law or agreed to in writing, software #
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS, #
|
||||||
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. #
|
||||||
|
# See the License for the specific language governing permissions and #
|
||||||
|
# limitations under the License. #
|
||||||
|
#--------------------------------------------------------------------------- #
|
||||||
|
|
||||||
|
$LOAD_PATH.unshift File.dirname(__FILE__)
|
||||||
|
|
||||||
|
require 'mapper'
|
||||||
|
|
||||||
|
class Qcow2Mapper < Mapper
|
||||||
|
# Max number of block devices. This should be set to the parameter used
|
||||||
|
# to load the nbd kernel module (default in kernel is 16)
|
||||||
|
NBDS_MAX = 256
|
||||||
|
|
||||||
|
def do_map(one_vm, disk, directory)
|
||||||
|
device = nbd_device
|
||||||
|
|
||||||
|
return nil if device.empty?
|
||||||
|
|
||||||
|
dsrc = disk_source(one_vm, disk)
|
||||||
|
cmd = "#{COMMANDS[:nbd]} -c #{device} #{dsrc}"
|
||||||
|
|
||||||
|
rc, out, err = Command.execute(cmd, true)
|
||||||
|
|
||||||
|
loop do
|
||||||
|
sleep 0.5
|
||||||
|
|
||||||
|
nbd_parts = lsblk(device)
|
||||||
|
|
||||||
|
break if nbd_parts && nbd_parts[0] && nbd_parts[0]['fstype']
|
||||||
|
end
|
||||||
|
|
||||||
|
if rc != 0
|
||||||
|
OpenNebula.log_error("do_map: #{err}")
|
||||||
|
return nil
|
||||||
|
end
|
||||||
|
|
||||||
|
device
|
||||||
|
end
|
||||||
|
|
||||||
|
def do_unmap(device, one_vm, disk, directory)
|
||||||
|
cmd = "#{COMMANDS[:nbd]} -d #{device}"
|
||||||
|
|
||||||
|
rc, out, err = Command.execute(cmd, true)
|
||||||
|
|
||||||
|
if rc != 0
|
||||||
|
OpenNebula.log_error("do_unmap: #{err}")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def nbd_device()
|
||||||
|
sys_parts = lsblk('')
|
||||||
|
device_id = -1
|
||||||
|
nbds = []
|
||||||
|
|
||||||
|
sys_parts.each { |p|
|
||||||
|
m = p['name'].match(/nbd(\d+)/)
|
||||||
|
next if !m
|
||||||
|
|
||||||
|
nbds << m[1].to_i
|
||||||
|
}
|
||||||
|
|
||||||
|
NBDS_MAX.times { |i|
|
||||||
|
return "/dev/nbd#{i}" unless nbds.include?(i)
|
||||||
|
}
|
||||||
|
|
||||||
|
OpenNebula.log_error("nbd_device: Cannot find free nbd device")
|
||||||
|
|
||||||
|
''
|
||||||
|
end
|
||||||
|
end
|
87
src/vmm_mad/remotes/lib/lxd/mapper/raw.rb
Normal file
87
src/vmm_mad/remotes/lib/lxd/mapper/raw.rb
Normal file
@ -0,0 +1,87 @@
|
|||||||
|
#!/usr/bin/ruby
|
||||||
|
|
||||||
|
# -------------------------------------------------------------------------- #
|
||||||
|
# Copyright 2002-2018, OpenNebula Project, OpenNebula Systems #
|
||||||
|
# #
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License"); you may #
|
||||||
|
# not use this file except in compliance with the License. You may obtain #
|
||||||
|
# a copy of the License at #
|
||||||
|
# #
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0 #
|
||||||
|
# #
|
||||||
|
# Unless required by applicable law or agreed to in writing, software #
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS, #
|
||||||
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. #
|
||||||
|
# See the License for the specific language governing permissions and #
|
||||||
|
# limitations under the License. #
|
||||||
|
#--------------------------------------------------------------------------- #
|
||||||
|
|
||||||
|
$LOAD_PATH.unshift File.dirname(__FILE__)
|
||||||
|
|
||||||
|
require 'mapper'
|
||||||
|
|
||||||
|
#-------------------------------------------------------------------------------
|
||||||
|
# These classes implements the mapping of raw filesystems & raw disk images
|
||||||
|
#-------------------------------------------------------------------------------
|
||||||
|
class FSRawMapper < Mapper
|
||||||
|
|
||||||
|
def do_map(one_vm, disk, directory)
|
||||||
|
dsrc = disk_source(one_vm, disk)
|
||||||
|
cmd = "#{COMMANDS[:losetup]} -f --show #{dsrc}"
|
||||||
|
|
||||||
|
rc, out, err = Command.execute(cmd, true)
|
||||||
|
|
||||||
|
if rc != 0 || out.empty?
|
||||||
|
OpenNebula.log_error("do_map: #{err}")
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
out.chomp
|
||||||
|
end
|
||||||
|
|
||||||
|
def do_unmap(device, one_vm, disk, directory)
|
||||||
|
cmd = "#{COMMANDS[:losetup]} -d #{device}"
|
||||||
|
|
||||||
|
rc, _out, err = Command.execute(cmd, true)
|
||||||
|
|
||||||
|
OpenNebula.log_error("do_unmap: #{err}") if rc != 0
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
class DiskRawMapper < Mapper
|
||||||
|
# Maps the whole file using kpartx. The output should be something like:
|
||||||
|
# $ sudo kpartx -av /var/lib/one/datastores/100/0/disk.0
|
||||||
|
# add map loop3p1 (253:0): 0 204800 linear 7:3 2048
|
||||||
|
# add map loop3p2 (253:1): 0 524288 linear 7:3 206848
|
||||||
|
# add map loop3p3 (253:2): 0 1366016 linear 7:3 731136
|
||||||
|
# Fisrt line is matched to look for loop device 3, and return "/dev/loop3"
|
||||||
|
def do_map(one_vm, disk, directory)
|
||||||
|
dsrc = disk_source(one_vm, disk)
|
||||||
|
cmd = "#{COMMANDS[:kpartx]} -av #{dsrc}"
|
||||||
|
|
||||||
|
rc, out, err = Command.execute(cmd, true)
|
||||||
|
|
||||||
|
if rc != 0 || out.empty?
|
||||||
|
OpenNebula.log_error("do_map: #{err}")
|
||||||
|
return nil
|
||||||
|
end
|
||||||
|
|
||||||
|
loopdev = out.lines[0].match(/.*add map loop(\d+)p\d+.*/)
|
||||||
|
|
||||||
|
return nil if !loopdev
|
||||||
|
|
||||||
|
"/dev/loop#{loopdev[1]}"
|
||||||
|
end
|
||||||
|
|
||||||
|
# Unmaps all devices and loops with kpartx using the source file
|
||||||
|
def do_unmap(device, one_vm, disk, directory)
|
||||||
|
dsrc = disk_source(one_vm, disk)
|
||||||
|
cmd = "#{COMMANDS[:kpartx]} -d #{dsrc}"
|
||||||
|
|
||||||
|
rc, out, err = Command.execute(cmd, true)
|
||||||
|
|
||||||
|
if rc != 0
|
||||||
|
OpenNebula.log_error("do_unmap: #{err}")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
60
src/vmm_mad/remotes/lib/lxd/mapper/rbd.rb
Normal file
60
src/vmm_mad/remotes/lib/lxd/mapper/rbd.rb
Normal file
@ -0,0 +1,60 @@
|
|||||||
|
#!/usr/bin/ruby
|
||||||
|
|
||||||
|
# -------------------------------------------------------------------------- #
|
||||||
|
# Copyright 2002-2018, OpenNebula Project, OpenNebula Systems #
|
||||||
|
# #
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License"); you may #
|
||||||
|
# not use this file except in compliance with the License. You may obtain #
|
||||||
|
# a copy of the License at #
|
||||||
|
# #
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0 #
|
||||||
|
# #
|
||||||
|
# Unless required by applicable law or agreed to in writing, software #
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS, #
|
||||||
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. #
|
||||||
|
# See the License for the specific language governing permissions and #
|
||||||
|
# limitations under the License. #
|
||||||
|
#--------------------------------------------------------------------------- #
|
||||||
|
|
||||||
|
$LOAD_PATH.unshift File.dirname(__FILE__)
|
||||||
|
|
||||||
|
require 'mapper'
|
||||||
|
|
||||||
|
# Ceph RBD mapper
|
||||||
|
class RBD < Mapper
|
||||||
|
|
||||||
|
def initialize(ceph_user)
|
||||||
|
@ceph_user = ceph_user
|
||||||
|
end
|
||||||
|
|
||||||
|
def map(image)
|
||||||
|
`sudo rbd --id #{@ceph_user} map #{image}`.chomp
|
||||||
|
end
|
||||||
|
|
||||||
|
def unmap(block)
|
||||||
|
shell("sudo rbd --id #{@ceph_user} unmap #{block}")
|
||||||
|
end
|
||||||
|
|
||||||
|
# Returns an array of mountable block's partitions
|
||||||
|
def detect_parts(block)
|
||||||
|
parts = `blkid | grep #{block} | grep -w UUID | awk {'print $1'}`.split(":\n")
|
||||||
|
uuids = []
|
||||||
|
parts.each {|part| uuids.append `blkid #{part} -o export | grep -w UUID`.chomp("\n")[5..-1] }
|
||||||
|
|
||||||
|
formatted = []
|
||||||
|
0.upto parts.length - 1 do |i|
|
||||||
|
formatted[i] = { 'name' => parts[i], 'uuid' => uuids[i] }
|
||||||
|
end
|
||||||
|
|
||||||
|
formatted
|
||||||
|
end
|
||||||
|
|
||||||
|
def get_parts(block)
|
||||||
|
parts = detect_parts(block)
|
||||||
|
parts.each do |part|
|
||||||
|
part['name'].slice!('//dev')
|
||||||
|
end
|
||||||
|
parts
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
425
src/vmm_mad/remotes/lib/lxd/opennebula_vm.rb
Normal file
425
src/vmm_mad/remotes/lib/lxd/opennebula_vm.rb
Normal file
@ -0,0 +1,425 @@
|
|||||||
|
# -------------------------------------------------------------------------- #
|
||||||
|
# Copyright 2002-2018, OpenNebula Project, OpenNebula Systems #
|
||||||
|
# #
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License"); you may #
|
||||||
|
# not use this file except in compliance with the License. You may obtain #
|
||||||
|
# a copy of the License at #
|
||||||
|
# #
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0 #
|
||||||
|
# #
|
||||||
|
# Unless required by applicable law or agreed to in writing, software #
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS, #
|
||||||
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. #
|
||||||
|
# See the License for the specific language governing permissions and #
|
||||||
|
# limitations under the License. #
|
||||||
|
#--------------------------------------------------------------------------- #
|
||||||
|
require 'rexml/document'
|
||||||
|
require 'yaml'
|
||||||
|
|
||||||
|
# This class reads and holds configuration attributes for the LXD driver
|
||||||
|
class LXDConfiguration < Hash
|
||||||
|
|
||||||
|
DEFAULT_CONFIGURATION = {
|
||||||
|
:vnc => {
|
||||||
|
:command => '/bin/bash',
|
||||||
|
:width => '800',
|
||||||
|
:height => '600',
|
||||||
|
:timeout => '300'
|
||||||
|
},
|
||||||
|
:datastore_location => '/var/lib/one/datastores',
|
||||||
|
:containers => '/var/lib/lxd/storage-pools/default/containers'
|
||||||
|
}
|
||||||
|
|
||||||
|
def initialize
|
||||||
|
replace(DEFAULT_CONFIGURATION)
|
||||||
|
|
||||||
|
begin
|
||||||
|
merge!(YAML.load_file("#{__dir__}/../../etc/vmm/lxd/lxdrc"))
|
||||||
|
rescue
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
# This class parses and wraps the information in the Driver action data
|
||||||
|
class OpenNebulaVM
|
||||||
|
|
||||||
|
attr_reader :xml, :vm_id, :vm_name, :sysds_id, :ds_path, :rootfs_id, :lxdrc
|
||||||
|
|
||||||
|
#---------------------------------------------------------------------------
|
||||||
|
# Class Constructor
|
||||||
|
#---------------------------------------------------------------------------
|
||||||
|
def initialize(xml)
|
||||||
|
@xml = XMLElement.new_s(xml)
|
||||||
|
@xml = @xml.element('//VM')
|
||||||
|
|
||||||
|
@vm_id = @xml['//TEMPLATE/VMID']
|
||||||
|
@sysds_id = @xml['//HISTORY_RECORDS/HISTORY/DS_ID']
|
||||||
|
|
||||||
|
@vm_name = @xml['//DEPLOY_ID']
|
||||||
|
@vm_name = "one-#{@vm_id}" if @vm_name.empty?
|
||||||
|
|
||||||
|
return if wild?
|
||||||
|
|
||||||
|
# Load Driver configuration
|
||||||
|
@lxdrc = LXDConfiguration.new
|
||||||
|
|
||||||
|
@ds_path = @lxdrc[:datastore_location]
|
||||||
|
|
||||||
|
# Sets the DISK ID of the root filesystem
|
||||||
|
disk = @xml.element('//TEMPLATE/DISK')
|
||||||
|
|
||||||
|
return unless disk
|
||||||
|
|
||||||
|
@rootfs_id = disk['DISK_ID']
|
||||||
|
boot_order = @xml['//TEMPLATE/OS/BOOT']
|
||||||
|
@rootfs_id = boot_order.split(',')[0][-1] unless boot_order.empty?
|
||||||
|
end
|
||||||
|
|
||||||
|
def has_context?
|
||||||
|
!@xml['//TEMPLATE/CONTEXT/DISK_ID'].empty?
|
||||||
|
end
|
||||||
|
|
||||||
|
def wild?
|
||||||
|
@vm_name && !@vm_name.include?('one-')
|
||||||
|
end
|
||||||
|
|
||||||
|
# Returns a Hash representing the LXC configuration for this OpenNebulaVM
|
||||||
|
def to_lxc
|
||||||
|
lxc = {}
|
||||||
|
|
||||||
|
lxc['name'] = @vm_name
|
||||||
|
|
||||||
|
lxc['config'] = {}
|
||||||
|
lxc['devices'] = {}
|
||||||
|
|
||||||
|
profile(lxc)
|
||||||
|
memory(lxc['config'])
|
||||||
|
cpu(lxc['config'])
|
||||||
|
extra_config(lxc['config'])
|
||||||
|
network(lxc['devices'])
|
||||||
|
storage(lxc['devices']) unless wild?
|
||||||
|
|
||||||
|
lxc
|
||||||
|
end
|
||||||
|
|
||||||
|
#---------------------------------------------------------------------------
|
||||||
|
# Container Attribute Mapping
|
||||||
|
#---------------------------------------------------------------------------
|
||||||
|
# Creates a dictionary for LXD containing $MEMORY RAM allocated
|
||||||
|
def memory(hash)
|
||||||
|
hash['limits.memory'] = "#{@xml['//TEMPLATE/MEMORY']}MB"
|
||||||
|
end
|
||||||
|
|
||||||
|
# Creates a dictionary for LXD $CPU percentage and cores
|
||||||
|
def cpu(hash)
|
||||||
|
cpu = @xml['//TEMPLATE/CPU']
|
||||||
|
hash['limits.cpu.allowance'] = "#{(cpu.to_f * 100).to_i}%"
|
||||||
|
|
||||||
|
vcpu = @xml['//TEMPLATE/VCPU']
|
||||||
|
hash['limits.cpu'] = vcpu unless vcpu.empty?
|
||||||
|
end
|
||||||
|
|
||||||
|
#---------------------------------------------------------------------------
|
||||||
|
# Container Device Mapping: Networking
|
||||||
|
#---------------------------------------------------------------------------
|
||||||
|
# Get nic by mac
|
||||||
|
def get_nic_by_mac(mac)
|
||||||
|
get_nics.each do |n|
|
||||||
|
return n if n['MAC'] == mac
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def get_nics
|
||||||
|
@xml.elements('//TEMPLATE/NIC')
|
||||||
|
end
|
||||||
|
|
||||||
|
# Sets up the network interfaces configuration in devices
|
||||||
|
def network(hash)
|
||||||
|
get_nics.each do |n|
|
||||||
|
hash.update(nic(n))
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
# Creates a nic hash from NIC xml root
|
||||||
|
def nic(info)
|
||||||
|
eth = {
|
||||||
|
'name' => "eth#{info['NIC_ID']}",
|
||||||
|
'host_name' => info['TARGET'],
|
||||||
|
'parent' => info['BRIDGE'],
|
||||||
|
'hwaddr' => info['MAC'],
|
||||||
|
'nictype' => 'bridged',
|
||||||
|
'type' => 'nic'
|
||||||
|
}
|
||||||
|
|
||||||
|
nic_map = {
|
||||||
|
'limits.ingress' => 'INBOUND_AVG_BW',
|
||||||
|
'limits.egress' => 'OUTBOUND_AVG_BW'
|
||||||
|
}
|
||||||
|
|
||||||
|
io_map(nic_map, eth, info) {|v| "#{v.to_i * 8}kbit" }
|
||||||
|
|
||||||
|
{ "eth#{info['NIC_ID']}" => eth }
|
||||||
|
end
|
||||||
|
|
||||||
|
#---------------------------------------------------------------------------
|
||||||
|
# Container Device Mapping: Storage
|
||||||
|
#---------------------------------------------------------------------------
|
||||||
|
# Get disk by target
|
||||||
|
def get_disk_by_target(value)
|
||||||
|
get_disk_by('TARGET', value)
|
||||||
|
end
|
||||||
|
|
||||||
|
# Get disk by id
|
||||||
|
def get_disk_by_id(value)
|
||||||
|
get_disk_by('DISK_ID', value)
|
||||||
|
end
|
||||||
|
|
||||||
|
# Get a disk depending on the filter xml key and the matching value
|
||||||
|
def get_disks_by(filter, value)
|
||||||
|
get_disks.each do |n|
|
||||||
|
return n if n[filter] == value
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def get_context_disk()
|
||||||
|
@xml.element('//TEMPLATE/CONTEXT')
|
||||||
|
end
|
||||||
|
|
||||||
|
def get_disks
|
||||||
|
@xml.elements('//TEMPLATE/DISK')
|
||||||
|
end
|
||||||
|
|
||||||
|
# Sets up the storage devices configuration in devices
|
||||||
|
def storage(hash)
|
||||||
|
disks = @xml.elements('//TEMPLATE/DISK')
|
||||||
|
|
||||||
|
disks.each do |n|
|
||||||
|
hash.update(disk(n, nil, nil))
|
||||||
|
end
|
||||||
|
|
||||||
|
context(hash)
|
||||||
|
end
|
||||||
|
|
||||||
|
# Generate Context information
|
||||||
|
def context(hash)
|
||||||
|
cid = @xml['//TEMPLATE/CONTEXT/DISK_ID']
|
||||||
|
|
||||||
|
return if cid.empty?
|
||||||
|
|
||||||
|
source = "#{@ds_path}/#{@sysds_id}/#{@vm_id}/mapper/disk.#{cid}"
|
||||||
|
|
||||||
|
hash['context'] = {
|
||||||
|
'type' => 'disk',
|
||||||
|
'source' => source,
|
||||||
|
'path' => '/context'
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
def disk_mountpoint(disk_id)
|
||||||
|
"#{@ds_path}/#{@sysds_id}/#{@vm_id}/mapper/disk.#{disk_id}"
|
||||||
|
end
|
||||||
|
|
||||||
|
# Creates a disk hash from DISK xml element
|
||||||
|
def disk(info, source, path)
|
||||||
|
disk_id = info['DISK_ID']
|
||||||
|
disk = {}
|
||||||
|
|
||||||
|
#-----------------------------------------------------------------------
|
||||||
|
# Source & Path attributes
|
||||||
|
#-----------------------------------------------------------------------
|
||||||
|
if disk_id == @rootfs_id
|
||||||
|
disk_name = 'root'
|
||||||
|
disk = { 'type' => 'disk', 'path' => '/', 'pool' => 'default' }
|
||||||
|
else
|
||||||
|
source ||= disk_mountpoint(disk_id)
|
||||||
|
|
||||||
|
unless path
|
||||||
|
path = info['TARGET']
|
||||||
|
path = "/media/#{disk_id}" unless path[0] == '/'
|
||||||
|
end
|
||||||
|
|
||||||
|
disk_name = "disk#{disk_id}"
|
||||||
|
disk = { 'type' => 'disk', 'source' => source, 'path' => path }
|
||||||
|
end
|
||||||
|
|
||||||
|
#-----------------------------------------------------------------------
|
||||||
|
# Readonly attributes
|
||||||
|
#-----------------------------------------------------------------------
|
||||||
|
if info['READONLY'].casecmp('yes').zero?
|
||||||
|
disk['readonly'] = 'true'
|
||||||
|
else
|
||||||
|
disk['readonly'] = 'false'
|
||||||
|
end
|
||||||
|
|
||||||
|
#-----------------------------------------------------------------------
|
||||||
|
# IO limits
|
||||||
|
#-----------------------------------------------------------------------
|
||||||
|
tbytes = info['TOTAL_BYTES_SEC']
|
||||||
|
tiops = info['TOTAL_IOPS_SEC']
|
||||||
|
|
||||||
|
if tbytes && !tbytes.empty?
|
||||||
|
disk['limits.max'] = tbytes
|
||||||
|
elsif tiops && !tiops.empty?
|
||||||
|
disk['limits.max'] = "#{tiops}iops"
|
||||||
|
end
|
||||||
|
|
||||||
|
if tbytes.empty? && tiops.empty?
|
||||||
|
disk_map = {
|
||||||
|
'limits.read' => 'READ_BYTES_SEC',
|
||||||
|
'limits.write' => 'WRITE_BYTES_SEC'
|
||||||
|
}
|
||||||
|
|
||||||
|
mapped = io_map(disk_map, disk, info) {|v| v }
|
||||||
|
|
||||||
|
if !mapped
|
||||||
|
disk_map = {
|
||||||
|
'limits.read' => 'READ_IOPS_SEC',
|
||||||
|
'limits.write' => 'WRITE_IOPS_SEC'
|
||||||
|
}
|
||||||
|
|
||||||
|
io_map(disk_map, disk, info) {|v| "#{v}iops" }
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
{ disk_name => disk }
|
||||||
|
end
|
||||||
|
|
||||||
|
#---------------------------------------------------------------------------
|
||||||
|
# Container Mapping: Extra Configuration & Profiles
|
||||||
|
#---------------------------------------------------------------------------
|
||||||
|
def extra_config(hash)
|
||||||
|
security = {
|
||||||
|
'security.privileged' => 'false',
|
||||||
|
'security.nesting' => 'false'
|
||||||
|
}
|
||||||
|
|
||||||
|
security.each_key do |key|
|
||||||
|
item = "LXD_SECURITY_#{key.split('.').last.swapcase}"
|
||||||
|
|
||||||
|
value = @xml["//USER_TEMPLATE/#{item}"]
|
||||||
|
security[key] = value unless value.empty?
|
||||||
|
end
|
||||||
|
|
||||||
|
hash.merge!(security)
|
||||||
|
|
||||||
|
raw_data = {}
|
||||||
|
|
||||||
|
data = @xml['//TEMPLATE/RAW/DATA']
|
||||||
|
type = @xml['//TEMPLATE/RAW/TYPE']
|
||||||
|
|
||||||
|
if !data.empty? && type.casecmp('lxd').zero?
|
||||||
|
begin
|
||||||
|
raw_data = JSON.parse("{#{data}}")
|
||||||
|
rescue StandardError
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
hash.merge!(raw_data) unless raw_data.empty?
|
||||||
|
end
|
||||||
|
|
||||||
|
def profile(hash)
|
||||||
|
profile = @xml['//USER_TEMPLATE/LXD_PROFILE']
|
||||||
|
profile = 'default' if profile.empty?
|
||||||
|
|
||||||
|
hash['profiles'] = [profile]
|
||||||
|
end
|
||||||
|
|
||||||
|
def device_info(devices, key, filter)
|
||||||
|
devices.each do |device|
|
||||||
|
return device[key] if device[key].value?(filter)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
# Creates container vnc connection
|
||||||
|
# Creates or closes a connection to a container rfb port depending on signal
|
||||||
|
def vnc_command(signal)
|
||||||
|
data = @xml.element('//TEMPLATE/GRAPHICS')
|
||||||
|
return unless data && data['PORT'] && data['TYPE'] == 'VNC'
|
||||||
|
|
||||||
|
pass = data['PASSWD']
|
||||||
|
pass = '-' unless pass && !pass.empty?
|
||||||
|
|
||||||
|
case signal
|
||||||
|
when 'start'
|
||||||
|
command = @lxdrc[:vnc][:command]
|
||||||
|
"#{data['PORT']} #{pass} lxc exec #{@vm_name} #{command}\n"
|
||||||
|
when 'stop'
|
||||||
|
"-#{data['PORT']}\n"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
# Maps IO limits from an OpenNebula VM configuration to a LXD configuration
|
||||||
|
# map: Hash that defines LXD name to OpenNebula name mapping
|
||||||
|
# lxd_conf: Hash with LXD configuration
|
||||||
|
# one_conf: XML Element with OpenNebula Configuration
|
||||||
|
#
|
||||||
|
# Block: To transform OpenNebula value
|
||||||
|
def io_map(map, lxd_conf, one_conf)
|
||||||
|
mapped = false
|
||||||
|
|
||||||
|
map.each do |key, value|
|
||||||
|
one_value = one_conf[value]
|
||||||
|
|
||||||
|
next if one_value.empty?
|
||||||
|
|
||||||
|
lxd_conf[key] = yield(one_value)
|
||||||
|
|
||||||
|
mapped = true
|
||||||
|
end
|
||||||
|
|
||||||
|
mapped
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
# This class abstracts the access to XML elements. It provides basic methods
|
||||||
|
# to get elements by their xpath
|
||||||
|
class XMLElement
|
||||||
|
|
||||||
|
def initialize(xml)
|
||||||
|
@xml = xml
|
||||||
|
end
|
||||||
|
|
||||||
|
# Create a new XMLElement using a xml document in a string
|
||||||
|
def self.new_s(xml_s)
|
||||||
|
xml = nil
|
||||||
|
xml = REXML::Document.new(xml_s).root unless xml_s.empty?
|
||||||
|
|
||||||
|
new(xml)
|
||||||
|
end
|
||||||
|
|
||||||
|
# Gets the text associated to a th element. The element is select by
|
||||||
|
# its xpath. If not found an empty string is returned
|
||||||
|
def [](key)
|
||||||
|
element = @xml.elements[key.to_s]
|
||||||
|
|
||||||
|
return '' if (element && !element.has_text?) || !element
|
||||||
|
|
||||||
|
element.text
|
||||||
|
end
|
||||||
|
|
||||||
|
# Return an XMLElement for the given xpath
|
||||||
|
def element(key)
|
||||||
|
e = @xml.elements[key.to_s]
|
||||||
|
|
||||||
|
element = nil
|
||||||
|
element = XMLElement.new(e) if e
|
||||||
|
|
||||||
|
element
|
||||||
|
end
|
||||||
|
|
||||||
|
# Get elements by xpath. This function returns an Array of XMLElements
|
||||||
|
def elements(key)
|
||||||
|
collection = []
|
||||||
|
|
||||||
|
@xml.elements.each(key) do |pelem|
|
||||||
|
collection << XMLElement.new(pelem)
|
||||||
|
end
|
||||||
|
|
||||||
|
collection
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
31
src/vmm_mad/remotes/lib/lxd/svncterm_server/SConstruct
Normal file
31
src/vmm_mad/remotes/lib/lxd/svncterm_server/SConstruct
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
# ---------------------------------------------------------------------------- #
|
||||||
|
# Copyright 2002-2018, OpenNebula Project, OpenNebula Systems #
|
||||||
|
# #
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License"); you may #
|
||||||
|
# not use this file except in compliance with the License. You may obtain #
|
||||||
|
# a copy of the License at #
|
||||||
|
# #
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0 #
|
||||||
|
# #
|
||||||
|
# Unless required by applicable law or agreed to in writing, software #
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS, #
|
||||||
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. #
|
||||||
|
# See the License for the specific language governing permissions and #
|
||||||
|
# limitations under the License. #
|
||||||
|
# ---------------------------------------------------------------------------- #
|
||||||
|
|
||||||
|
import os
|
||||||
|
|
||||||
|
env = Environment()
|
||||||
|
|
||||||
|
env['LIBS'] = ['-lz']
|
||||||
|
|
||||||
|
env.Program('genfont.c')
|
||||||
|
|
||||||
|
env = Environment()
|
||||||
|
env['LIBS'] = ['-lvncserver', '-lnsl', '-lpthread', '-lz', '-ljpeg',
|
||||||
|
'-lutil', '-lgnutls']
|
||||||
|
|
||||||
|
env['CFLAGS'] = ['-D_GNU_SOURCE']
|
||||||
|
|
||||||
|
env.Program('svncterm_server.c')
|
35
src/vmm_mad/remotes/lib/lxd/svncterm_server/copyright
Normal file
35
src/vmm_mad/remotes/lib/lxd/svncterm_server/copyright
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
Copyright 2002-2018, OpenNebula Project, OpenNebula Systems
|
||||||
|
|
||||||
|
-Changes to genfont utility
|
||||||
|
* Update psf loader to PSFv2
|
||||||
|
* Added command line options & usage
|
||||||
|
* Other minor code changes
|
||||||
|
|
||||||
|
-Changes to svncterm
|
||||||
|
* Added command line options
|
||||||
|
* inetd like behavior, start vncserver when a conneciton is accepted
|
||||||
|
|
||||||
|
|
||||||
|
Copyright (C) 2016 Universitat Politecnica de Valencia
|
||||||
|
* Removing the usage of TLS and the need of patched versions of libraries
|
||||||
|
|
||||||
|
Copyright (C) 2007 Proxmox Server Solutions GmbH
|
||||||
|
|
||||||
|
Copyright: svncterm is under GNU GPL, the GNU General Public License.
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; either version 2 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License along
|
||||||
|
with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
|
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
|
||||||
|
The complete text of the GNU General
|
||||||
|
Public License can be found in `/usr/share/common-licenses/GPL'.
|
371
src/vmm_mad/remotes/lib/lxd/svncterm_server/genfont.c
Normal file
371
src/vmm_mad/remotes/lib/lxd/svncterm_server/genfont.c
Normal file
@ -0,0 +1,371 @@
|
|||||||
|
/*
|
||||||
|
|
||||||
|
Copyright (C) 2007 Proxmox Server Solutions GmbH
|
||||||
|
|
||||||
|
Copyright: vzdump is under GNU GPL, the GNU General Public License.
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; version 2 dated June, 1991.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||||
|
02111-1307, USA.
|
||||||
|
|
||||||
|
Author: Dietmar Maurer <dietmar@proxmox.com>
|
||||||
|
|
||||||
|
Copyright 2002-2018, OpenNebula Project, OpenNebula Systems
|
||||||
|
|
||||||
|
- Update psf loader to PSFv2
|
||||||
|
- Added command line options & usage
|
||||||
|
- Other minor code changes
|
||||||
|
|
||||||
|
contact@opennebula.systems
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <zlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
/* -------------------------------------------------------------------------- */
|
||||||
|
/* Font glyph storage array and map pointer */
|
||||||
|
/* -------------------------------------------------------------------------- */
|
||||||
|
/* map unicode to font */
|
||||||
|
static unsigned short vt_fontmap[65536];
|
||||||
|
|
||||||
|
/* font glyph storage */
|
||||||
|
static unsigned char * vt_font_data = NULL;
|
||||||
|
|
||||||
|
static int vt_font_size = 0; //Index to current glyph
|
||||||
|
static int vt_font_maxsize = 0; //Max size of fontmap
|
||||||
|
|
||||||
|
/* -------------------------------------------------------------------------- */
|
||||||
|
/* PC Screen Font v2 data (PSFv2) Header & Constants */
|
||||||
|
/* -------------------------------------------------------------------------- */
|
||||||
|
#define PSF2_MAGIC0 0x72
|
||||||
|
#define PSF2_MAGIC1 0xb5
|
||||||
|
#define PSF2_MAGIC2 0x4a
|
||||||
|
#define PSF2_MAGIC3 0x86
|
||||||
|
|
||||||
|
/* bits used in flags */
|
||||||
|
#define PSF2_HAS_UNICODE_TABLE 0x01
|
||||||
|
|
||||||
|
/* max version recognized so far */
|
||||||
|
#define PSF2_MAXVERSION 0
|
||||||
|
|
||||||
|
/* UTF8 separators */
|
||||||
|
#define PSF2_SEPARATOR 0xFF
|
||||||
|
#define PSF2_STARTSEQ 0xFE
|
||||||
|
|
||||||
|
struct psf2_header
|
||||||
|
{
|
||||||
|
unsigned char magic[4];
|
||||||
|
unsigned int version;
|
||||||
|
unsigned int headersize; /* offset of bitmaps in file */
|
||||||
|
unsigned int flags;
|
||||||
|
unsigned int length; /* number of glyphs */
|
||||||
|
unsigned int charsize; /* number of bytes for each character */
|
||||||
|
unsigned int height, width; /* max dimensions of glyphs */
|
||||||
|
/* charsize = height * ((width + 7) / 8) */
|
||||||
|
};
|
||||||
|
|
||||||
|
/* -------------------------------------------------------------------------- */
|
||||||
|
/* Font map management */
|
||||||
|
/* -------------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Copy the glyph to the font map array
|
||||||
|
* @param data, the glyph bitmap
|
||||||
|
* @param gzise, size of glyph
|
||||||
|
*/
|
||||||
|
static int font_add_glyph (const char *data, unsigned int gsize)
|
||||||
|
{
|
||||||
|
if (vt_font_size >= vt_font_maxsize)
|
||||||
|
{
|
||||||
|
vt_font_maxsize += 256;
|
||||||
|
vt_font_data = realloc (vt_font_data, vt_font_maxsize * gsize);
|
||||||
|
}
|
||||||
|
|
||||||
|
memcpy(vt_font_data + vt_font_size * gsize, data, gsize);
|
||||||
|
|
||||||
|
return vt_font_size++;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Convert UTF8 to (1, 2 & 3 bytes) Unicode char
|
||||||
|
* Return 0 success, -1 not ucode, -2 EOU (end of unicode)
|
||||||
|
*/
|
||||||
|
static int utf8_2_unicode(gzFile stream, char s, u_int16_t * ucode)
|
||||||
|
{
|
||||||
|
char s1, s2;
|
||||||
|
|
||||||
|
*ucode = (u_int16_t) s;
|
||||||
|
|
||||||
|
if (*ucode == 0xFFFF)
|
||||||
|
{
|
||||||
|
return -2;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (*ucode == 0xFFFE)
|
||||||
|
{
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!(*ucode & 0x80))
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
*ucode = 0;
|
||||||
|
|
||||||
|
if ((s & 0xE0) == 0xC0)
|
||||||
|
{
|
||||||
|
gzread(stream, &s1, 1);
|
||||||
|
|
||||||
|
*ucode = (s & 0x1F) << 6;
|
||||||
|
*ucode |= (s1 & 0x3F);
|
||||||
|
}
|
||||||
|
else if ((s & 0xF0) == 0xE0)
|
||||||
|
{
|
||||||
|
gzread(stream, &s1, 1);
|
||||||
|
gzread(stream, &s2, 1);
|
||||||
|
|
||||||
|
*ucode = (s & 0x0F) << 12;
|
||||||
|
*ucode |= (s1 & 0x3F) << 6;
|
||||||
|
*ucode |= (s2 & 0x3F);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Load the PSF font file
|
||||||
|
*/
|
||||||
|
static int load_psf_font (const char *filename, int is_default)
|
||||||
|
{
|
||||||
|
struct psf2_header psf2hdr;
|
||||||
|
|
||||||
|
size_t psf2hdr_len = sizeof(struct psf2_header);
|
||||||
|
|
||||||
|
gzFile f = gzopen(filename, "rb");
|
||||||
|
|
||||||
|
if (f == NULL)
|
||||||
|
{
|
||||||
|
fprintf (stderr, "unable to read file %s\n", filename);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ---------------------------------------------------------------------- */
|
||||||
|
/* Load PSF2 header and check consistency */
|
||||||
|
/* ---------------------------------------------------------------------- */
|
||||||
|
if (gzread(f, &psf2hdr, psf2hdr_len) != psf2hdr_len)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "Wrong header in psf2 font file (%s)\n", filename);
|
||||||
|
gzclose(f);
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (psf2hdr.magic[0] != PSF2_MAGIC0 || psf2hdr.magic[1] != PSF2_MAGIC1 ||
|
||||||
|
psf2hdr.magic[2] != PSF2_MAGIC2 || psf2hdr.magic[3] != PSF2_MAGIC3 )
|
||||||
|
{
|
||||||
|
fprintf(stderr, "File %s not in PSFv2 format\n", filename);
|
||||||
|
gzclose(f);
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!(psf2hdr.flags & PSF2_HAS_UNICODE_TABLE))
|
||||||
|
{
|
||||||
|
fprintf(stderr, "File %s does not include Unicode glyphs\n", filename);
|
||||||
|
gzclose(f);
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( psf2hdr.height != 16 && psf2hdr.width != 8 )
|
||||||
|
{
|
||||||
|
fprintf(stderr, "File %s does not include 8x16 font\n", filename);
|
||||||
|
gzclose(f);
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ---------------------------------------------------------------------- */
|
||||||
|
/* Read the bitmaps */
|
||||||
|
/* ---------------------------------------------------------------------- */
|
||||||
|
int gsize = psf2hdr.charsize;
|
||||||
|
int font_size = gsize * psf2hdr.length;
|
||||||
|
|
||||||
|
char *chardata = (char *) malloc (font_size);
|
||||||
|
|
||||||
|
if (gzread(f, chardata, font_size)!= font_size)
|
||||||
|
{
|
||||||
|
fprintf (stderr, "Cannot read font character data from %s\n", filename);
|
||||||
|
gzclose (f);
|
||||||
|
|
||||||
|
free(chardata);
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ---------------------------------------------------------------------- */
|
||||||
|
/* Read the Unicode description of the glyphs */
|
||||||
|
/* ---------------------------------------------------------------------- */
|
||||||
|
for (int glyph = 0 ;glyph < psf2hdr.length ;glyph++)
|
||||||
|
{
|
||||||
|
int fi = 0;
|
||||||
|
char s;
|
||||||
|
|
||||||
|
while (gzread(f, &s, 1) == 1)
|
||||||
|
{
|
||||||
|
u_int16_t uchar;
|
||||||
|
|
||||||
|
int rc = utf8_2_unicode(f, s, &uchar);
|
||||||
|
|
||||||
|
if ( rc == -1 )
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
else if ( rc == -2 )
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!vt_fontmap[uchar] && uchar != 0)
|
||||||
|
{
|
||||||
|
if (!fi)
|
||||||
|
{
|
||||||
|
fi = font_add_glyph(chardata + glyph * gsize, gsize);
|
||||||
|
}
|
||||||
|
|
||||||
|
vt_fontmap[uchar] = fi;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (is_default && fi && glyph < 256)
|
||||||
|
{
|
||||||
|
vt_fontmap[0xf000 + glyph] = fi;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
free(chardata);
|
||||||
|
gzclose(f);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* -------------------------------------------------------------------------- */
|
||||||
|
/* Print the include file */
|
||||||
|
/* -------------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
void print_glyphs ()
|
||||||
|
{
|
||||||
|
printf ("static int vt_font_size = %d;\n\n", vt_font_size);
|
||||||
|
|
||||||
|
printf ("static unsigned char vt_font_data[] = {\n");
|
||||||
|
|
||||||
|
for (int i = 0; i < vt_font_size; i++)
|
||||||
|
{
|
||||||
|
printf("\t/* %d 0x%02x */\n", i, i);
|
||||||
|
|
||||||
|
for (int j = 0; j < 16; j++) //glyph size == 16
|
||||||
|
{
|
||||||
|
unsigned char d = vt_font_data[i*16+j];
|
||||||
|
|
||||||
|
printf ("\t0x%02X, /* ", d);
|
||||||
|
|
||||||
|
for (int k = 128; k > 0; k = k>>1)
|
||||||
|
{
|
||||||
|
printf ("%c", (d & k) ? '1': '0');
|
||||||
|
}
|
||||||
|
|
||||||
|
printf (" */\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
printf ("\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
printf ("};\n\n");
|
||||||
|
|
||||||
|
printf ("static unsigned short vt_fontmap[65536] = {\n");
|
||||||
|
|
||||||
|
for (int i = 0; i < 0x0ffff; i++)
|
||||||
|
{
|
||||||
|
printf ("\t/* 0x%04X => */ %d,\n", i, vt_fontmap[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
printf ("};\n\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
/* -------------------------------------------------------------------------- */
|
||||||
|
/* -------------------------------------------------------------------------- */
|
||||||
|
/* -------------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
static void print_usage()
|
||||||
|
{
|
||||||
|
fprintf(stderr, "Usage: genfont [-d font_path] [font1 font2...]\n");
|
||||||
|
fprintf(stderr, "Generate Glyph Bitmaps and associated Unicode mapping\n\n");
|
||||||
|
fprintf(stderr, "\tfont1... List of fonts, the first one is the default\n\n");
|
||||||
|
fprintf(stderr, "\t-d path: Font path defaults to /usr/share/consolefonts\n\n");
|
||||||
|
fprintf(stderr, "Example: genfont default8x16.psf.gz lat1u-16.psf.gz"
|
||||||
|
" lat2u-16.psf.gz\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
int main (int argc, char** argv)
|
||||||
|
{
|
||||||
|
char empty[] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
|
||||||
|
char font_dir[PATH_MAX - 256] = "/usr/share/consolefonts";
|
||||||
|
|
||||||
|
int opt;
|
||||||
|
|
||||||
|
/* ---------------------------------------------------------------------- */
|
||||||
|
/* Arguments parsing */
|
||||||
|
/* ---------------------------------------------------------------------- */
|
||||||
|
while ((opt = getopt(argc, argv, "hd:")) != -1) {
|
||||||
|
switch (opt) {
|
||||||
|
case 'h':
|
||||||
|
print_usage();
|
||||||
|
exit(0);
|
||||||
|
case 'd':
|
||||||
|
strncpy(font_dir, optarg, PATH_MAX - 257);
|
||||||
|
break;
|
||||||
|
default: /* '?' */
|
||||||
|
print_usage();
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ---------------------------------------------------------------------- */
|
||||||
|
/* Load PSF fonts & print glyphs */
|
||||||
|
/* ---------------------------------------------------------------------- */
|
||||||
|
font_add_glyph(empty, sizeof(empty));
|
||||||
|
|
||||||
|
if ( optind >= argc )
|
||||||
|
{
|
||||||
|
print_usage();
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i=optind ; i < argc; ++i)
|
||||||
|
{
|
||||||
|
char font_path[PATH_MAX];
|
||||||
|
|
||||||
|
snprintf(font_path, PATH_MAX, "%s/%s", font_dir, argv[i]);
|
||||||
|
|
||||||
|
/* font load order is only important if glyphs are redefined */
|
||||||
|
load_psf_font(font_path, i == optind);
|
||||||
|
}
|
||||||
|
|
||||||
|
print_glyphs ();
|
||||||
|
|
||||||
|
exit (0);
|
||||||
|
}
|
||||||
|
|
72293
src/vmm_mad/remotes/lib/lxd/svncterm_server/glyphs.h
Normal file
72293
src/vmm_mad/remotes/lib/lxd/svncterm_server/glyphs.h
Normal file
File diff suppressed because it is too large
Load Diff
235
src/vmm_mad/remotes/lib/lxd/svncterm_server/svncterm.h
Normal file
235
src/vmm_mad/remotes/lib/lxd/svncterm_server/svncterm.h
Normal file
@ -0,0 +1,235 @@
|
|||||||
|
#include <rfb/rfb.h>
|
||||||
|
|
||||||
|
#define IBUFSIZE 1024
|
||||||
|
#define MAX_ESC_PARAMS 16
|
||||||
|
|
||||||
|
typedef unsigned short unicode;
|
||||||
|
|
||||||
|
typedef struct TextAttributes {
|
||||||
|
unsigned int fgcol:4;
|
||||||
|
unsigned int bgcol:4;
|
||||||
|
unsigned int bold:1;
|
||||||
|
unsigned int uline:1;
|
||||||
|
unsigned int blink:1;
|
||||||
|
unsigned int invers:1;
|
||||||
|
unsigned int unvisible:1;
|
||||||
|
} TextAttributes;
|
||||||
|
|
||||||
|
typedef struct TextCell {
|
||||||
|
unicode ch;
|
||||||
|
TextAttributes attrib;
|
||||||
|
} TextCell;
|
||||||
|
|
||||||
|
typedef struct vncTerm {
|
||||||
|
int maxx;
|
||||||
|
int maxy;
|
||||||
|
|
||||||
|
int width;
|
||||||
|
int height;
|
||||||
|
|
||||||
|
int total_height;
|
||||||
|
int scroll_height;
|
||||||
|
int y_base;
|
||||||
|
int y_displ;
|
||||||
|
int altbuf:1;
|
||||||
|
|
||||||
|
unsigned int utf8:1; // utf8 mode
|
||||||
|
long utf_char; // used by utf8 parser
|
||||||
|
int utf_count; // used by utf8 parser
|
||||||
|
|
||||||
|
|
||||||
|
TextAttributes default_attrib;
|
||||||
|
|
||||||
|
TextCell *cells;
|
||||||
|
TextCell *altcells;
|
||||||
|
|
||||||
|
rfbScreenInfoPtr screen;
|
||||||
|
|
||||||
|
// cursor
|
||||||
|
TextAttributes cur_attrib;
|
||||||
|
TextAttributes cur_attrib_saved;
|
||||||
|
int tty_state; // 0 - normal, 1 - ESC, 2 - CSI
|
||||||
|
int cx; // cursor x position
|
||||||
|
int cy; // cursor y position
|
||||||
|
int cx_saved; // saved cursor x position
|
||||||
|
int cy_saved; // saved cursor y position
|
||||||
|
int esc_buf[MAX_ESC_PARAMS];
|
||||||
|
int esc_count;
|
||||||
|
int esc_ques;
|
||||||
|
int esc_has_par;
|
||||||
|
char osc_textbuf[4096];
|
||||||
|
char osc_cmd;
|
||||||
|
int region_top;
|
||||||
|
int region_bottom;
|
||||||
|
|
||||||
|
unsigned int charset:1; // G0 or G1
|
||||||
|
unsigned int charset_saved:1; // G0 or G1
|
||||||
|
unsigned int g0enc:2;
|
||||||
|
unsigned int g0enc_saved:2;
|
||||||
|
unsigned int g1enc:2;
|
||||||
|
unsigned int g1enc_saved:2;
|
||||||
|
unsigned int cur_enc:2;
|
||||||
|
unsigned int cur_enc_saved:2;
|
||||||
|
|
||||||
|
// input buffer
|
||||||
|
char ibuf[IBUFSIZE];
|
||||||
|
int ibuf_count;
|
||||||
|
|
||||||
|
unicode *selection;
|
||||||
|
int selection_len;
|
||||||
|
|
||||||
|
unsigned int mark_active:1;
|
||||||
|
|
||||||
|
unsigned int report_mouse:1;
|
||||||
|
|
||||||
|
} vncTerm;
|
||||||
|
|
||||||
|
/* Unicode translations copied from kernel source consolemap.c */
|
||||||
|
|
||||||
|
#define LAT1_MAP 0
|
||||||
|
#define GRAF_MAP 1
|
||||||
|
#define IBMPC_MAP 2
|
||||||
|
#define USER_MAP 3
|
||||||
|
|
||||||
|
static unsigned short translations[][256] = {
|
||||||
|
/* 8-bit Latin-1 mapped to Unicode -- trivial mapping */
|
||||||
|
{
|
||||||
|
0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007,
|
||||||
|
0x0008, 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f,
|
||||||
|
0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017,
|
||||||
|
0x0018, 0x0019, 0x001a, 0x001b, 0x001c, 0x001d, 0x001e, 0x001f,
|
||||||
|
0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027,
|
||||||
|
0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f,
|
||||||
|
0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037,
|
||||||
|
0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f,
|
||||||
|
0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047,
|
||||||
|
0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f,
|
||||||
|
0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057,
|
||||||
|
0x0058, 0x0059, 0x005a, 0x005b, 0x005c, 0x005d, 0x005e, 0x005f,
|
||||||
|
0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067,
|
||||||
|
0x0068, 0x0069, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x006f,
|
||||||
|
0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077,
|
||||||
|
0x0078, 0x0079, 0x007a, 0x007b, 0x007c, 0x007d, 0x007e, 0x007f,
|
||||||
|
0x0080, 0x0081, 0x0082, 0x0083, 0x0084, 0x0085, 0x0086, 0x0087,
|
||||||
|
0x0088, 0x0089, 0x008a, 0x008b, 0x008c, 0x008d, 0x008e, 0x008f,
|
||||||
|
0x0090, 0x0091, 0x0092, 0x0093, 0x0094, 0x0095, 0x0096, 0x0097,
|
||||||
|
0x0098, 0x0099, 0x009a, 0x009b, 0x009c, 0x009d, 0x009e, 0x009f,
|
||||||
|
0x00a0, 0x00a1, 0x00a2, 0x00a3, 0x00a4, 0x00a5, 0x00a6, 0x00a7,
|
||||||
|
0x00a8, 0x00a9, 0x00aa, 0x00ab, 0x00ac, 0x00ad, 0x00ae, 0x00af,
|
||||||
|
0x00b0, 0x00b1, 0x00b2, 0x00b3, 0x00b4, 0x00b5, 0x00b6, 0x00b7,
|
||||||
|
0x00b8, 0x00b9, 0x00ba, 0x00bb, 0x00bc, 0x00bd, 0x00be, 0x00bf,
|
||||||
|
0x00c0, 0x00c1, 0x00c2, 0x00c3, 0x00c4, 0x00c5, 0x00c6, 0x00c7,
|
||||||
|
0x00c8, 0x00c9, 0x00ca, 0x00cb, 0x00cc, 0x00cd, 0x00ce, 0x00cf,
|
||||||
|
0x00d0, 0x00d1, 0x00d2, 0x00d3, 0x00d4, 0x00d5, 0x00d6, 0x00d7,
|
||||||
|
0x00d8, 0x00d9, 0x00da, 0x00db, 0x00dc, 0x00dd, 0x00de, 0x00df,
|
||||||
|
0x00e0, 0x00e1, 0x00e2, 0x00e3, 0x00e4, 0x00e5, 0x00e6, 0x00e7,
|
||||||
|
0x00e8, 0x00e9, 0x00ea, 0x00eb, 0x00ec, 0x00ed, 0x00ee, 0x00ef,
|
||||||
|
0x00f0, 0x00f1, 0x00f2, 0x00f3, 0x00f4, 0x00f5, 0x00f6, 0x00f7,
|
||||||
|
0x00f8, 0x00f9, 0x00fa, 0x00fb, 0x00fc, 0x00fd, 0x00fe, 0x00ff
|
||||||
|
},
|
||||||
|
/* VT100 graphics mapped to Unicode */
|
||||||
|
{
|
||||||
|
0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007,
|
||||||
|
0x0008, 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f,
|
||||||
|
0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017,
|
||||||
|
0x0018, 0x0019, 0x001a, 0x001b, 0x001c, 0x001d, 0x001e, 0x001f,
|
||||||
|
0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027,
|
||||||
|
0x0028, 0x0029, 0x002a, 0x2192, 0x2190, 0x2191, 0x2193, 0x002f,
|
||||||
|
0x2588, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037,
|
||||||
|
0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f,
|
||||||
|
0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047,
|
||||||
|
0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f,
|
||||||
|
0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057,
|
||||||
|
0x0058, 0x0059, 0x005a, 0x005b, 0x005c, 0x005d, 0x005e, 0x00a0,
|
||||||
|
0x25c6, 0x2592, 0x2409, 0x240c, 0x240d, 0x240a, 0x00b0, 0x00b1,
|
||||||
|
0x2591, 0x240b, 0x2518, 0x2510, 0x250c, 0x2514, 0x253c, 0x23ba,
|
||||||
|
0x23bb, 0x2500, 0x23bc, 0x23bd, 0x251c, 0x2524, 0x2534, 0x252c,
|
||||||
|
0x2502, 0x2264, 0x2265, 0x03c0, 0x2260, 0x00a3, 0x00b7, 0x007f,
|
||||||
|
0x0080, 0x0081, 0x0082, 0x0083, 0x0084, 0x0085, 0x0086, 0x0087,
|
||||||
|
0x0088, 0x0089, 0x008a, 0x008b, 0x008c, 0x008d, 0x008e, 0x008f,
|
||||||
|
0x0090, 0x0091, 0x0092, 0x0093, 0x0094, 0x0095, 0x0096, 0x0097,
|
||||||
|
0x0098, 0x0099, 0x009a, 0x009b, 0x009c, 0x009d, 0x009e, 0x009f,
|
||||||
|
0x00a0, 0x00a1, 0x00a2, 0x00a3, 0x00a4, 0x00a5, 0x00a6, 0x00a7,
|
||||||
|
0x00a8, 0x00a9, 0x00aa, 0x00ab, 0x00ac, 0x00ad, 0x00ae, 0x00af,
|
||||||
|
0x00b0, 0x00b1, 0x00b2, 0x00b3, 0x00b4, 0x00b5, 0x00b6, 0x00b7,
|
||||||
|
0x00b8, 0x00b9, 0x00ba, 0x00bb, 0x00bc, 0x00bd, 0x00be, 0x00bf,
|
||||||
|
0x00c0, 0x00c1, 0x00c2, 0x00c3, 0x00c4, 0x00c5, 0x00c6, 0x00c7,
|
||||||
|
0x00c8, 0x00c9, 0x00ca, 0x00cb, 0x00cc, 0x00cd, 0x00ce, 0x00cf,
|
||||||
|
0x00d0, 0x00d1, 0x00d2, 0x00d3, 0x00d4, 0x00d5, 0x00d6, 0x00d7,
|
||||||
|
0x00d8, 0x00d9, 0x00da, 0x00db, 0x00dc, 0x00dd, 0x00de, 0x00df,
|
||||||
|
0x00e0, 0x00e1, 0x00e2, 0x00e3, 0x00e4, 0x00e5, 0x00e6, 0x00e7,
|
||||||
|
0x00e8, 0x00e9, 0x00ea, 0x00eb, 0x00ec, 0x00ed, 0x00ee, 0x00ef,
|
||||||
|
0x00f0, 0x00f1, 0x00f2, 0x00f3, 0x00f4, 0x00f5, 0x00f6, 0x00f7,
|
||||||
|
0x00f8, 0x00f9, 0x00fa, 0x00fb, 0x00fc, 0x00fd, 0x00fe, 0x00ff
|
||||||
|
},
|
||||||
|
/* IBM Codepage 437 mapped to Unicode */
|
||||||
|
{
|
||||||
|
0x0000, 0x263a, 0x263b, 0x2665, 0x2666, 0x2663, 0x2660, 0x2022,
|
||||||
|
0x25d8, 0x25cb, 0x25d9, 0x2642, 0x2640, 0x266a, 0x266b, 0x263c,
|
||||||
|
0x25b6, 0x25c0, 0x2195, 0x203c, 0x00b6, 0x00a7, 0x25ac, 0x21a8,
|
||||||
|
0x2191, 0x2193, 0x2192, 0x2190, 0x221f, 0x2194, 0x25b2, 0x25bc,
|
||||||
|
0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027,
|
||||||
|
0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f,
|
||||||
|
0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037,
|
||||||
|
0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f,
|
||||||
|
0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047,
|
||||||
|
0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f,
|
||||||
|
0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057,
|
||||||
|
0x0058, 0x0059, 0x005a, 0x005b, 0x005c, 0x005d, 0x005e, 0x005f,
|
||||||
|
0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067,
|
||||||
|
0x0068, 0x0069, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x006f,
|
||||||
|
0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077,
|
||||||
|
0x0078, 0x0079, 0x007a, 0x007b, 0x007c, 0x007d, 0x007e, 0x2302,
|
||||||
|
0x00c7, 0x00fc, 0x00e9, 0x00e2, 0x00e4, 0x00e0, 0x00e5, 0x00e7,
|
||||||
|
0x00ea, 0x00eb, 0x00e8, 0x00ef, 0x00ee, 0x00ec, 0x00c4, 0x00c5,
|
||||||
|
0x00c9, 0x00e6, 0x00c6, 0x00f4, 0x00f6, 0x00f2, 0x00fb, 0x00f9,
|
||||||
|
0x00ff, 0x00d6, 0x00dc, 0x00a2, 0x00a3, 0x00a5, 0x20a7, 0x0192,
|
||||||
|
0x00e1, 0x00ed, 0x00f3, 0x00fa, 0x00f1, 0x00d1, 0x00aa, 0x00ba,
|
||||||
|
0x00bf, 0x2310, 0x00ac, 0x00bd, 0x00bc, 0x00a1, 0x00ab, 0x00bb,
|
||||||
|
0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x2561, 0x2562, 0x2556,
|
||||||
|
0x2555, 0x2563, 0x2551, 0x2557, 0x255d, 0x255c, 0x255b, 0x2510,
|
||||||
|
0x2514, 0x2534, 0x252c, 0x251c, 0x2500, 0x253c, 0x255e, 0x255f,
|
||||||
|
0x255a, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256c, 0x2567,
|
||||||
|
0x2568, 0x2564, 0x2565, 0x2559, 0x2558, 0x2552, 0x2553, 0x256b,
|
||||||
|
0x256a, 0x2518, 0x250c, 0x2588, 0x2584, 0x258c, 0x2590, 0x2580,
|
||||||
|
0x03b1, 0x00df, 0x0393, 0x03c0, 0x03a3, 0x03c3, 0x00b5, 0x03c4,
|
||||||
|
0x03a6, 0x0398, 0x03a9, 0x03b4, 0x221e, 0x03c6, 0x03b5, 0x2229,
|
||||||
|
0x2261, 0x00b1, 0x2265, 0x2264, 0x2320, 0x2321, 0x00f7, 0x2248,
|
||||||
|
0x00b0, 0x2219, 0x00b7, 0x221a, 0x207f, 0x00b2, 0x25a0, 0x00a0
|
||||||
|
},
|
||||||
|
/* User mapping -- default to codes for direct font mapping */
|
||||||
|
{
|
||||||
|
0xf000, 0xf001, 0xf002, 0xf003, 0xf004, 0xf005, 0xf006, 0xf007,
|
||||||
|
0xf008, 0xf009, 0xf00a, 0xf00b, 0xf00c, 0xf00d, 0xf00e, 0xf00f,
|
||||||
|
0xf010, 0xf011, 0xf012, 0xf013, 0xf014, 0xf015, 0xf016, 0xf017,
|
||||||
|
0xf018, 0xf019, 0xf01a, 0xf01b, 0xf01c, 0xf01d, 0xf01e, 0xf01f,
|
||||||
|
0xf020, 0xf021, 0xf022, 0xf023, 0xf024, 0xf025, 0xf026, 0xf027,
|
||||||
|
0xf028, 0xf029, 0xf02a, 0xf02b, 0xf02c, 0xf02d, 0xf02e, 0xf02f,
|
||||||
|
0xf030, 0xf031, 0xf032, 0xf033, 0xf034, 0xf035, 0xf036, 0xf037,
|
||||||
|
0xf038, 0xf039, 0xf03a, 0xf03b, 0xf03c, 0xf03d, 0xf03e, 0xf03f,
|
||||||
|
0xf040, 0xf041, 0xf042, 0xf043, 0xf044, 0xf045, 0xf046, 0xf047,
|
||||||
|
0xf048, 0xf049, 0xf04a, 0xf04b, 0xf04c, 0xf04d, 0xf04e, 0xf04f,
|
||||||
|
0xf050, 0xf051, 0xf052, 0xf053, 0xf054, 0xf055, 0xf056, 0xf057,
|
||||||
|
0xf058, 0xf059, 0xf05a, 0xf05b, 0xf05c, 0xf05d, 0xf05e, 0xf05f,
|
||||||
|
0xf060, 0xf061, 0xf062, 0xf063, 0xf064, 0xf065, 0xf066, 0xf067,
|
||||||
|
0xf068, 0xf069, 0xf06a, 0xf06b, 0xf06c, 0xf06d, 0xf06e, 0xf06f,
|
||||||
|
0xf070, 0xf071, 0xf072, 0xf073, 0xf074, 0xf075, 0xf076, 0xf077,
|
||||||
|
0xf078, 0xf079, 0xf07a, 0xf07b, 0xf07c, 0xf07d, 0xf07e, 0xf07f,
|
||||||
|
0xf080, 0xf081, 0xf082, 0xf083, 0xf084, 0xf085, 0xf086, 0xf087,
|
||||||
|
0xf088, 0xf089, 0xf08a, 0xf08b, 0xf08c, 0xf08d, 0xf08e, 0xf08f,
|
||||||
|
0xf090, 0xf091, 0xf092, 0xf093, 0xf094, 0xf095, 0xf096, 0xf097,
|
||||||
|
0xf098, 0xf099, 0xf09a, 0xf09b, 0xf09c, 0xf09d, 0xf09e, 0xf09f,
|
||||||
|
0xf0a0, 0xf0a1, 0xf0a2, 0xf0a3, 0xf0a4, 0xf0a5, 0xf0a6, 0xf0a7,
|
||||||
|
0xf0a8, 0xf0a9, 0xf0aa, 0xf0ab, 0xf0ac, 0xf0ad, 0xf0ae, 0xf0af,
|
||||||
|
0xf0b0, 0xf0b1, 0xf0b2, 0xf0b3, 0xf0b4, 0xf0b5, 0xf0b6, 0xf0b7,
|
||||||
|
0xf0b8, 0xf0b9, 0xf0ba, 0xf0bb, 0xf0bc, 0xf0bd, 0xf0be, 0xf0bf,
|
||||||
|
0xf0c0, 0xf0c1, 0xf0c2, 0xf0c3, 0xf0c4, 0xf0c5, 0xf0c6, 0xf0c7,
|
||||||
|
0xf0c8, 0xf0c9, 0xf0ca, 0xf0cb, 0xf0cc, 0xf0cd, 0xf0ce, 0xf0cf,
|
||||||
|
0xf0d0, 0xf0d1, 0xf0d2, 0xf0d3, 0xf0d4, 0xf0d5, 0xf0d6, 0xf0d7,
|
||||||
|
0xf0d8, 0xf0d9, 0xf0da, 0xf0db, 0xf0dc, 0xf0dd, 0xf0de, 0xf0df,
|
||||||
|
0xf0e0, 0xf0e1, 0xf0e2, 0xf0e3, 0xf0e4, 0xf0e5, 0xf0e6, 0xf0e7,
|
||||||
|
0xf0e8, 0xf0e9, 0xf0ea, 0xf0eb, 0xf0ec, 0xf0ed, 0xf0ee, 0xf0ef,
|
||||||
|
0xf0f0, 0xf0f1, 0xf0f2, 0xf0f3, 0xf0f4, 0xf0f5, 0xf0f6, 0xf0f7,
|
||||||
|
0xf0f8, 0xf0f9, 0xf0fa, 0xf0fb, 0xf0fc, 0xf0fd, 0xf0fe, 0xf0ff
|
||||||
|
}
|
||||||
|
};
|
2426
src/vmm_mad/remotes/lib/lxd/svncterm_server/svncterm_server.c
Normal file
2426
src/vmm_mad/remotes/lib/lxd/svncterm_server/svncterm_server.c
Normal file
File diff suppressed because it is too large
Load Diff
40
src/vmm_mad/remotes/lxd/attach_disk
Executable file
40
src/vmm_mad/remotes/lxd/attach_disk
Executable file
@ -0,0 +1,40 @@
|
|||||||
|
#!/usr/bin/ruby
|
||||||
|
|
||||||
|
# -------------------------------------------------------------------------- #
|
||||||
|
# Copyright 2002-2018, OpenNebula Project, OpenNebula Systems #
|
||||||
|
# #
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License"); you may #
|
||||||
|
# not use this file except in compliance with the License. You may obtain #
|
||||||
|
# a copy of the License at #
|
||||||
|
# #
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0 #
|
||||||
|
# #
|
||||||
|
# Unless required by applicable law or agreed to in writing, software #
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS, #
|
||||||
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. #
|
||||||
|
# See the License for the specific language governing permissions and #
|
||||||
|
# limitations under the License. #
|
||||||
|
#--------------------------------------------------------------------------- #
|
||||||
|
|
||||||
|
$LOAD_PATH.unshift File.dirname(__FILE__)
|
||||||
|
|
||||||
|
require 'container'
|
||||||
|
|
||||||
|
require_relative '../../scripts_common'
|
||||||
|
|
||||||
|
# ------------------------------------------------------------------------------
|
||||||
|
# Action Arguments, STDIN includes XML description of the OpenNebula VM
|
||||||
|
# ------------------------------------------------------------------------------
|
||||||
|
vm_name = ARGV[0]
|
||||||
|
image_path = ARGV[1]
|
||||||
|
target = ARGV[2]
|
||||||
|
disk_index = ARGV[3]
|
||||||
|
xml64 = ARGV[4]
|
||||||
|
vm_id = ARGV[5]
|
||||||
|
|
||||||
|
xml = STDIN.read
|
||||||
|
|
||||||
|
client = LXDClient.new
|
||||||
|
container = Container.get(vm_name, xml, client)
|
||||||
|
|
||||||
|
container.attach_disk(image_path)
|
43
src/vmm_mad/remotes/lxd/attach_nic
Executable file
43
src/vmm_mad/remotes/lxd/attach_nic
Executable file
@ -0,0 +1,43 @@
|
|||||||
|
#!/usr/bin/ruby
|
||||||
|
|
||||||
|
# -------------------------------------------------------------------------- #
|
||||||
|
# Copyright 2002-2018, OpenNebula Project, OpenNebula Systems #
|
||||||
|
# #
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License"); you may #
|
||||||
|
# not use this file except in compliance with the License. You may obtain #
|
||||||
|
# a copy of the License at #
|
||||||
|
# #
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0 #
|
||||||
|
# #
|
||||||
|
# Unless required by applicable law or agreed to in writing, software #
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS, #
|
||||||
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. #
|
||||||
|
# See the License for the specific language governing permissions and #
|
||||||
|
# limitations under the License. #
|
||||||
|
#--------------------------------------------------------------------------- #
|
||||||
|
|
||||||
|
$LOAD_PATH.unshift File.dirname(__FILE__)
|
||||||
|
|
||||||
|
require 'container'
|
||||||
|
|
||||||
|
require_relative '../../scripts_common'
|
||||||
|
|
||||||
|
# ------------------------------------------------------------------------------
|
||||||
|
# Action Arguments, STDIN includes XML description of the OpenNebula VM
|
||||||
|
# ------------------------------------------------------------------------------
|
||||||
|
vm_name = ARGV[0]
|
||||||
|
mac = ARGV[1]
|
||||||
|
bridge = ARGV[2]
|
||||||
|
model = ARGV[3]
|
||||||
|
net_drv = ARGV[4]
|
||||||
|
host_nic= ARGV[5]
|
||||||
|
|
||||||
|
vm_id = ARGV[6]
|
||||||
|
host = ARGV[7]
|
||||||
|
|
||||||
|
xml = STDIN.read
|
||||||
|
|
||||||
|
client = LXDClient.new
|
||||||
|
container = Container.get(vm_name, xml, client)
|
||||||
|
|
||||||
|
container.attach_nic(mac)
|
19
src/vmm_mad/remotes/lxd/cancel
Executable file
19
src/vmm_mad/remotes/lxd/cancel
Executable file
@ -0,0 +1,19 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# -------------------------------------------------------------------------- #
|
||||||
|
# Copyright 2002-2018, OpenNebula Project, OpenNebula Systems #
|
||||||
|
# #
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License"); you may #
|
||||||
|
# not use this file except in compliance with the License. You may obtain #
|
||||||
|
# a copy of the License at #
|
||||||
|
# #
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0 #
|
||||||
|
# #
|
||||||
|
# Unless required by applicable law or agreed to in writing, software #
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS, #
|
||||||
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. #
|
||||||
|
# See the License for the specific language governing permissions and #
|
||||||
|
# limitations under the License. #
|
||||||
|
#--------------------------------------------------------------------------- #
|
||||||
|
|
||||||
|
$(dirname $0)/shutdown $@ '-f'
|
91
src/vmm_mad/remotes/lxd/deploy
Executable file
91
src/vmm_mad/remotes/lxd/deploy
Executable file
@ -0,0 +1,91 @@
|
|||||||
|
#!/usr/bin/ruby
|
||||||
|
|
||||||
|
# -------------------------------------------------------------------------- #
|
||||||
|
# Copyright 2002-2018, OpenNebula Project, OpenNebula Systems #
|
||||||
|
# #
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License"); you may #
|
||||||
|
# not use this file except in compliance with the License. You may obtain #
|
||||||
|
# a copy of the License at #
|
||||||
|
# #
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0 #
|
||||||
|
# #
|
||||||
|
# Unless required by applicable law or agreed to in writing, software #
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS, #
|
||||||
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. #
|
||||||
|
# See the License for the specific language governing permissions and #
|
||||||
|
# limitations under the License. #
|
||||||
|
#--------------------------------------------------------------------------- #
|
||||||
|
|
||||||
|
$LOAD_PATH.unshift File.dirname(__FILE__)
|
||||||
|
|
||||||
|
require 'container'
|
||||||
|
|
||||||
|
require_relative '../../scripts_common'
|
||||||
|
|
||||||
|
# ------------------------------------------------------------------------------
|
||||||
|
# Action Arguments, STDIN includes XML description of the OpenNebula VM
|
||||||
|
# ------------------------------------------------------------------------------
|
||||||
|
xml_path = ARGV[0]
|
||||||
|
vm_id = ARGV[2]
|
||||||
|
|
||||||
|
xml = STDIN.read
|
||||||
|
|
||||||
|
# ------------------------------------------------------------------------------
|
||||||
|
# Action Arguments, STDIN includes XML description of the OpenNebula VM
|
||||||
|
# ------------------------------------------------------------------------------
|
||||||
|
client = LXDClient.new
|
||||||
|
container = Container.new_from_xml(xml, client)
|
||||||
|
|
||||||
|
# ------------------------------------------------------------------------------
|
||||||
|
# Create Container in LXD
|
||||||
|
# - Already exists: gets container metadata from LXD and set OpenNebula
|
||||||
|
# configurations to update existing container.
|
||||||
|
# - Not exists. Creates new container in LXD.
|
||||||
|
# ------------------------------------------------------------------------------
|
||||||
|
if Container.exist?(container.name, client)
|
||||||
|
OpenNebula.log_info('Overriding container')
|
||||||
|
|
||||||
|
config = container.config
|
||||||
|
devices = container.devices
|
||||||
|
|
||||||
|
container.get_metadata
|
||||||
|
|
||||||
|
err_msg = 'A container with the same ID is already running'
|
||||||
|
raise LXDError, err_msg if container.status == 'Running'
|
||||||
|
|
||||||
|
container.config = config
|
||||||
|
|
||||||
|
container.devices = devices
|
||||||
|
|
||||||
|
container.update
|
||||||
|
else
|
||||||
|
container.create
|
||||||
|
end
|
||||||
|
|
||||||
|
# ------------------------------------------------------------------------------
|
||||||
|
# Start the container, if not wild, maps storage to host directories
|
||||||
|
# ------------------------------------------------------------------------------
|
||||||
|
if container.wild?
|
||||||
|
container.start
|
||||||
|
else
|
||||||
|
container.setup_storage('map')
|
||||||
|
|
||||||
|
if container.start != 'Running'
|
||||||
|
OpenNebula.log_error('Container failed to start')
|
||||||
|
|
||||||
|
container.setup_storage('unmap')
|
||||||
|
container.delete
|
||||||
|
|
||||||
|
raise LXDError, container.status
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
#-------------------------------------------------------------------------------
|
||||||
|
# Updates container configuration with the OpenNebulaVM description
|
||||||
|
# ------------------------------------------------------------------------------
|
||||||
|
container.config.update('user.xml' => xml)
|
||||||
|
container.update
|
||||||
|
|
||||||
|
container.vnc('start')
|
||||||
|
|
||||||
|
puts container.name
|
38
src/vmm_mad/remotes/lxd/detach_disk
Executable file
38
src/vmm_mad/remotes/lxd/detach_disk
Executable file
@ -0,0 +1,38 @@
|
|||||||
|
#!/usr/bin/ruby
|
||||||
|
|
||||||
|
# -------------------------------------------------------------------------- #
|
||||||
|
# Copyright 2002-2018, OpenNebula Project, OpenNebula Systems #
|
||||||
|
# #
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License"); you may #
|
||||||
|
# not use this file except in compliance with the License. You may obtain #
|
||||||
|
# a copy of the License at #
|
||||||
|
# #
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0 #
|
||||||
|
# #
|
||||||
|
# Unless required by applicable law or agreed to in writing, software #
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS, #
|
||||||
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. #
|
||||||
|
# See the License for the specific language governing permissions and #
|
||||||
|
# limitations under the License. #
|
||||||
|
#--------------------------------------------------------------------------- #
|
||||||
|
|
||||||
|
$LOAD_PATH.unshift File.dirname(__FILE__)
|
||||||
|
|
||||||
|
require 'container'
|
||||||
|
|
||||||
|
require_relative '../../scripts_common'
|
||||||
|
|
||||||
|
# ------------------------------------------------------------------------------
|
||||||
|
# Action Arguments, STDIN includes XML description of the OpenNebula VM
|
||||||
|
# ------------------------------------------------------------------------------
|
||||||
|
vm_name = ARGV[0]
|
||||||
|
tgt_path = ARGV[1]
|
||||||
|
tgt = ARGV[2]
|
||||||
|
tgt_index = ARGV[3]
|
||||||
|
|
||||||
|
xml = STDIN.read
|
||||||
|
|
||||||
|
client = LXDClient.new
|
||||||
|
container = Container.get(vm_name, xml, client)
|
||||||
|
|
||||||
|
container.detach_disk
|
39
src/vmm_mad/remotes/lxd/detach_nic
Executable file
39
src/vmm_mad/remotes/lxd/detach_nic
Executable file
@ -0,0 +1,39 @@
|
|||||||
|
#!/usr/bin/ruby
|
||||||
|
|
||||||
|
# -------------------------------------------------------------------------- #
|
||||||
|
# Copyright 2002-2018, OpenNebula Project, OpenNebula Systems #
|
||||||
|
# #
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License"); you may #
|
||||||
|
# not use this file except in compliance with the License. You may obtain #
|
||||||
|
# a copy of the License at #
|
||||||
|
# #
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0 #
|
||||||
|
# #
|
||||||
|
# Unless required by applicable law or agreed to in writing, software #
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS, #
|
||||||
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. #
|
||||||
|
# See the License for the specific language governing permissions and #
|
||||||
|
# limitations under the License. #
|
||||||
|
#--------------------------------------------------------------------------- #
|
||||||
|
|
||||||
|
$LOAD_PATH.unshift File.dirname(__FILE__)
|
||||||
|
|
||||||
|
require 'container'
|
||||||
|
|
||||||
|
require_relative '../../scripts_common'
|
||||||
|
|
||||||
|
# ------------------------------------------------------------------------------
|
||||||
|
# Action Arguments, STDIN includes XML description of the OpenNebula VM
|
||||||
|
# ------------------------------------------------------------------------------
|
||||||
|
vm_name = ARGV[0]
|
||||||
|
mac = ARGV[1]
|
||||||
|
vm_id = ARGV[2]
|
||||||
|
host = ARGV[3]
|
||||||
|
|
||||||
|
xml = STDIN.read
|
||||||
|
|
||||||
|
client = LXDClient.new
|
||||||
|
container = Container.get(vm_name, xml, client)
|
||||||
|
|
||||||
|
container.detach_nic(mac)
|
||||||
|
|
46
src/vmm_mad/remotes/lxd/lxdrc
Normal file
46
src/vmm_mad/remotes/lxd/lxdrc
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
# -------------------------------------------------------------------------- #
|
||||||
|
# Copyright 2002-2018, OpenNebula Project, OpenNebula Systems #
|
||||||
|
# #
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License"); you may #
|
||||||
|
# not use this file except in compliance with the License. You may obtain #
|
||||||
|
# a copy of the License at #
|
||||||
|
# #
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0 #
|
||||||
|
# #
|
||||||
|
# Unless required by applicable law or agreed to in writing, software #
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS, #
|
||||||
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. #
|
||||||
|
# See the License for the specific language governing permissions and #
|
||||||
|
# limitations under the License. #
|
||||||
|
#--------------------------------------------------------------------------- #
|
||||||
|
|
||||||
|
################################################################################
|
||||||
|
# VNC Options
|
||||||
|
################################################################################
|
||||||
|
#
|
||||||
|
# Options to customize the VNC access to the container:
|
||||||
|
# - :command: to be executed in the VNC terminal.
|
||||||
|
# - :width: of the terminal
|
||||||
|
# - :height: of the terminal
|
||||||
|
# - :timeout: seconds to close the terminal if no input has been received
|
||||||
|
:vnc:
|
||||||
|
:command: /bin/bash
|
||||||
|
:width: 800
|
||||||
|
:height: 600
|
||||||
|
:timeout: 300
|
||||||
|
|
||||||
|
################################################################################
|
||||||
|
# OpenNebula Configuration Options
|
||||||
|
################################################################################
|
||||||
|
#
|
||||||
|
# Default path for the datastores. This only need to be change if the
|
||||||
|
# corresponding value in oned.conf has been modified.
|
||||||
|
:datastore_location: /var/lib/one/datastores
|
||||||
|
|
||||||
|
|
||||||
|
################################################################################
|
||||||
|
# LXD Options
|
||||||
|
################################################################################
|
||||||
|
#
|
||||||
|
# Path to containers location to mount the root file systems
|
||||||
|
:containers: /var/lib/lxd/storage-pools/default/containers
|
1
src/vmm_mad/remotes/lxd/migrate
Symbolic link
1
src/vmm_mad/remotes/lxd/migrate
Symbolic link
@ -0,0 +1 @@
|
|||||||
|
../common/not_supported.sh
|
1
src/vmm_mad/remotes/lxd/migrate_local
Symbolic link
1
src/vmm_mad/remotes/lxd/migrate_local
Symbolic link
@ -0,0 +1 @@
|
|||||||
|
../common/not_supported.sh
|
275
src/vmm_mad/remotes/lxd/poll
Executable file
275
src/vmm_mad/remotes/lxd/poll
Executable file
@ -0,0 +1,275 @@
|
|||||||
|
#!/usr/bin/env ruby
|
||||||
|
|
||||||
|
# -------------------------------------------------------------------------- #
|
||||||
|
# Copyright 2002-2018, OpenNebula Project, OpenNebula Systems #
|
||||||
|
# #
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License"); you may #
|
||||||
|
# not use this file except in compliance with the License. You may obtain #
|
||||||
|
# a copy of the License at #
|
||||||
|
# #
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0 #
|
||||||
|
# #
|
||||||
|
# Unless required by applicable law or agreed to in writing, software #
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS, #
|
||||||
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. #
|
||||||
|
# See the License for the specific language governing permissions and #
|
||||||
|
# limitations under the License. #
|
||||||
|
#--------------------------------------------------------------------------- #
|
||||||
|
|
||||||
|
$LOAD_PATH.unshift File.dirname(__FILE__)
|
||||||
|
|
||||||
|
require 'container'
|
||||||
|
require 'client'
|
||||||
|
require_relative '../lib/poll_common'
|
||||||
|
|
||||||
|
require 'base64'
|
||||||
|
|
||||||
|
################################################################################
|
||||||
|
#
|
||||||
|
# LXD Monitor Module
|
||||||
|
#
|
||||||
|
################################################################################
|
||||||
|
module LXD
|
||||||
|
|
||||||
|
CLIENT = LXDClient.new
|
||||||
|
|
||||||
|
class << self
|
||||||
|
|
||||||
|
# Get the information of a single VM. In case of error the VM is reported
|
||||||
|
# as not found.
|
||||||
|
# @param one_vm [String] with the VM name
|
||||||
|
def get_vm_info(one_vm)
|
||||||
|
vm = Container.get(one_vm, nil, CLIENT)
|
||||||
|
|
||||||
|
return { :state => '-' } unless vm
|
||||||
|
|
||||||
|
vm_info = get_values([vm]).first.last
|
||||||
|
|
||||||
|
vm_info
|
||||||
|
end
|
||||||
|
|
||||||
|
# Gets the information of all VMs
|
||||||
|
#
|
||||||
|
# @return [Hash, nil] Hash with the VM information or nil in case of error
|
||||||
|
def get_all_vm_info
|
||||||
|
vms = Container.get_all(CLIENT)
|
||||||
|
|
||||||
|
return unless vms
|
||||||
|
|
||||||
|
vms_info = get_values(vms)
|
||||||
|
vms_info
|
||||||
|
end
|
||||||
|
|
||||||
|
def get_values(vms)
|
||||||
|
vms_info = {}
|
||||||
|
|
||||||
|
running_containers = []
|
||||||
|
|
||||||
|
vms.each do |container|
|
||||||
|
values = {}
|
||||||
|
name = container.name
|
||||||
|
values[:state] = get_state(container)
|
||||||
|
|
||||||
|
unless name =~ /^one-\d+/ # Wild VMs
|
||||||
|
template = to_one(container)
|
||||||
|
values[:template] = Base64.encode64(template).delete("\n")
|
||||||
|
values[:vm_name] = name
|
||||||
|
end
|
||||||
|
|
||||||
|
vms_info[name] = values
|
||||||
|
next unless values[:state] == 'a'
|
||||||
|
|
||||||
|
vmd = container.monitor['metadata']
|
||||||
|
|
||||||
|
values[:memory] = get_memory(name)
|
||||||
|
values[:netrx], values[:nettx] = get_net_statistics(vmd['network'])
|
||||||
|
|
||||||
|
running_containers.append(name)
|
||||||
|
vms_info[name][:memory] = values[:memory]
|
||||||
|
end
|
||||||
|
|
||||||
|
unless running_containers.empty?
|
||||||
|
cpu = get_cpu(running_containers)
|
||||||
|
vms.each do |container|
|
||||||
|
vms_info[container.name][:cpu] = cpu[container.name] if cpu[container.name]
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
vms_info
|
||||||
|
end
|
||||||
|
|
||||||
|
# Get and translate LXD state to Opennebula monitor state
|
||||||
|
# @param state [String] libvirt state
|
||||||
|
# @return [String] OpenNebula state
|
||||||
|
#
|
||||||
|
# LXD states for the guest are
|
||||||
|
# * 'running' state refers to containers which are currently active.
|
||||||
|
# * 'frozen' after lxc freeze (suspended).
|
||||||
|
# * 'stopped' container not running or in the process of shutting down.
|
||||||
|
# * 'failure' container have failed.
|
||||||
|
def get_state(container)
|
||||||
|
begin
|
||||||
|
status = container.status.downcase
|
||||||
|
rescue StandardError
|
||||||
|
status = 'unknown'
|
||||||
|
end
|
||||||
|
|
||||||
|
case status
|
||||||
|
when 'running'
|
||||||
|
state = 'a'
|
||||||
|
when 'frozen'
|
||||||
|
state = 'p'
|
||||||
|
when 'stopped'
|
||||||
|
state = 'd'
|
||||||
|
when 'failure'
|
||||||
|
state = 'e'
|
||||||
|
else
|
||||||
|
state = '-'
|
||||||
|
end
|
||||||
|
|
||||||
|
state
|
||||||
|
end
|
||||||
|
|
||||||
|
def get_memory(vm_name)
|
||||||
|
stat = File.read('/sys/fs/cgroup/memory/lxc/' + vm_name + '/memory.usage_in_bytes').to_i
|
||||||
|
stat / 1024
|
||||||
|
end
|
||||||
|
|
||||||
|
def get_net_statistics(vmd)
|
||||||
|
netrx = 0
|
||||||
|
nettx = 0
|
||||||
|
|
||||||
|
vmd.each do |interface, values|
|
||||||
|
next if interface == 'lo'
|
||||||
|
|
||||||
|
netrx += values['counters']['bytes_received']
|
||||||
|
nettx += values['counters']['bytes_sent']
|
||||||
|
end
|
||||||
|
|
||||||
|
[netrx, nettx]
|
||||||
|
end
|
||||||
|
|
||||||
|
# Gathers process information from a set of VMs.
|
||||||
|
# @param vm_names [Array] of vms indexed by name. Value is a hash with :pid
|
||||||
|
# @return [Hash] with ps information
|
||||||
|
def get_cpu(vm_names)
|
||||||
|
multiplier = `nproc`.to_i * 100
|
||||||
|
|
||||||
|
start_cpu_jiffies = get_cpu_jiffies
|
||||||
|
|
||||||
|
cpu_used = {}
|
||||||
|
vm_names.each do |vm_name|
|
||||||
|
cpu_used[vm_name] = get_process_jiffies(vm_name).to_f
|
||||||
|
end
|
||||||
|
|
||||||
|
sleep 1
|
||||||
|
|
||||||
|
cpu_jiffies = get_cpu_jiffies - start_cpu_jiffies
|
||||||
|
|
||||||
|
vm_names.each do |vm_name|
|
||||||
|
cpu_used[vm_name] = (get_process_jiffies(vm_name).to_f -
|
||||||
|
cpu_used[vm_name]) / cpu_jiffies
|
||||||
|
|
||||||
|
cpu_used[vm_name] = (cpu_used[vm_name] * multiplier).round(2)
|
||||||
|
end
|
||||||
|
|
||||||
|
cpu_used
|
||||||
|
end
|
||||||
|
|
||||||
|
def get_cpu_jiffies
|
||||||
|
begin
|
||||||
|
stat = File.read('/proc/stat')
|
||||||
|
rescue StandardError
|
||||||
|
return 0
|
||||||
|
end
|
||||||
|
|
||||||
|
jiffies = 0
|
||||||
|
|
||||||
|
# skip cpu string and guest jiffies
|
||||||
|
stat.lines.first.split(' ')[1..-3].each do |num|
|
||||||
|
jiffies += num.to_i
|
||||||
|
end
|
||||||
|
|
||||||
|
jiffies
|
||||||
|
end
|
||||||
|
|
||||||
|
def get_process_jiffies(vm_name)
|
||||||
|
begin
|
||||||
|
jiffies = 0
|
||||||
|
stat = File.read('/sys/fs/cgroup/cpu,cpuacct/lxc/' + vm_name + '/cpuacct.stat')
|
||||||
|
stat.lines.each {|line| jiffies += line.split(' ')[1] }
|
||||||
|
rescue StandardError
|
||||||
|
return 0
|
||||||
|
end
|
||||||
|
|
||||||
|
jiffies
|
||||||
|
end
|
||||||
|
|
||||||
|
def parse_memory(memory)
|
||||||
|
mem_suffix = memory[-2..-1]
|
||||||
|
memory = memory[0..-3].to_i # remove sufix
|
||||||
|
case mem_suffix[-2..-1]
|
||||||
|
when 'GB'
|
||||||
|
memory *= 1024
|
||||||
|
when 'TB'
|
||||||
|
memory *= 1024**2
|
||||||
|
end
|
||||||
|
memory
|
||||||
|
end
|
||||||
|
|
||||||
|
def to_one(container)
|
||||||
|
name = container.name
|
||||||
|
arch = container.architecture
|
||||||
|
capacity = container.expanded_config
|
||||||
|
|
||||||
|
cpu = ""
|
||||||
|
vcpu= ""
|
||||||
|
mem = ""
|
||||||
|
|
||||||
|
if capacity
|
||||||
|
cpu = capacity['limits.cpu.allowance']
|
||||||
|
vcpu = capacity['limits.cpu']
|
||||||
|
mem = capacity['limits.memory']
|
||||||
|
end
|
||||||
|
|
||||||
|
cpu = "50%" if !cpu || cpu.empty?
|
||||||
|
vcpu = "1" if !vcpu || vcpu.empty?
|
||||||
|
mem = "512M" if !mem || mem.empty?
|
||||||
|
|
||||||
|
cpu = cpu.chomp('%').to_f / 100
|
||||||
|
mem = parse_memory(mem)
|
||||||
|
|
||||||
|
template = <<EOT
|
||||||
|
NAME="#{name}"
|
||||||
|
CPU=#{cpu}
|
||||||
|
VCPU=#{vcpu}
|
||||||
|
MEMORY=#{mem}
|
||||||
|
HYPERVISOR="lxd"
|
||||||
|
IMPORT_VM_ID="#{name}"
|
||||||
|
OS=[ARCH="#{arch}"]
|
||||||
|
EOT
|
||||||
|
template
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
################################################################################
|
||||||
|
# MAIN PROGRAM
|
||||||
|
################################################################################
|
||||||
|
|
||||||
|
hypervisor = LXD
|
||||||
|
# file = '../../etc/vmm/kvm/kvmrc'
|
||||||
|
|
||||||
|
# load_vars(hypervisor)
|
||||||
|
|
||||||
|
vm_id = ARGV[0]
|
||||||
|
|
||||||
|
if vm_id == '-t'
|
||||||
|
print_all_vm_template(hypervisor)
|
||||||
|
elsif vm_id
|
||||||
|
print_one_vm_info(hypervisor, vm_id)
|
||||||
|
else
|
||||||
|
print_all_vm_info(hypervisor)
|
||||||
|
end
|
39
src/vmm_mad/remotes/lxd/prereconfigure
Executable file
39
src/vmm_mad/remotes/lxd/prereconfigure
Executable file
@ -0,0 +1,39 @@
|
|||||||
|
#!/usr/bin/ruby
|
||||||
|
|
||||||
|
# -------------------------------------------------------------------------- #
|
||||||
|
# Copyright 2002-2018, OpenNebula Project, OpenNebula Systems #
|
||||||
|
# #
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License"); you may #
|
||||||
|
# not use this file except in compliance with the License. You may obtain #
|
||||||
|
# a copy of the License at #
|
||||||
|
# #
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0 #
|
||||||
|
# #
|
||||||
|
# Unless required by applicable law or agreed to in writing, software #
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS, #
|
||||||
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. #
|
||||||
|
# See the License for the specific language governing permissions and #
|
||||||
|
# limitations under the License. #
|
||||||
|
#--------------------------------------------------------------------------- #
|
||||||
|
|
||||||
|
$LOAD_PATH.unshift File.dirname(__FILE__)
|
||||||
|
|
||||||
|
require 'container'
|
||||||
|
|
||||||
|
require_relative '../../scripts_common'
|
||||||
|
|
||||||
|
# ------------------------------------------------------------------------------
|
||||||
|
# Action Arguments, STDIN includes XML description of the OpenNebula VM
|
||||||
|
# ------------------------------------------------------------------------------
|
||||||
|
vm_name = ARGV[0]
|
||||||
|
vm_id = ARGV[2]
|
||||||
|
|
||||||
|
xml = STDIN.read
|
||||||
|
|
||||||
|
# ------------------------------------------------------------------------------
|
||||||
|
# Setup Context for the container
|
||||||
|
# ------------------------------------------------------------------------------
|
||||||
|
client = LXDClient.new
|
||||||
|
container = Container.get(vm_name, xml, client)
|
||||||
|
|
||||||
|
container.detach_context
|
42
src/vmm_mad/remotes/lxd/reboot
Executable file
42
src/vmm_mad/remotes/lxd/reboot
Executable file
@ -0,0 +1,42 @@
|
|||||||
|
#!/usr/bin/ruby
|
||||||
|
|
||||||
|
# -------------------------------------------------------------------------- #
|
||||||
|
# Copyright 2002-2018, OpenNebula Project, OpenNebula Systems #
|
||||||
|
# #
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License"); you may #
|
||||||
|
# not use this file except in compliance with the License. You may obtain #
|
||||||
|
# a copy of the License at #
|
||||||
|
# #
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0 #
|
||||||
|
# #
|
||||||
|
# Unless required by applicable law or agreed to in writing, software #
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS, #
|
||||||
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. #
|
||||||
|
# See the License for the specific language governing permissions and #
|
||||||
|
# limitations under the License. #
|
||||||
|
#--------------------------------------------------------------------------- #
|
||||||
|
|
||||||
|
$LOAD_PATH.unshift File.dirname(__FILE__)
|
||||||
|
|
||||||
|
require 'container'
|
||||||
|
|
||||||
|
require_relative '../../scripts_common'
|
||||||
|
|
||||||
|
# ------------------------------------------------------------------------------
|
||||||
|
# Action Arguments, STDIN includes XML description of the OpenNebula VM
|
||||||
|
# ------------------------------------------------------------------------------
|
||||||
|
vm_name = ARGV[0]
|
||||||
|
|
||||||
|
client = LXDClient.new
|
||||||
|
container = Container.get(vm_name, nil, client)
|
||||||
|
|
||||||
|
# ------------------------------------------------------------------------------
|
||||||
|
# Stop the container, start it and reset VNC server
|
||||||
|
# ------------------------------------------------------------------------------
|
||||||
|
if ARGV[-1] == '-f'
|
||||||
|
container.stop(:force => true)
|
||||||
|
else
|
||||||
|
container.stop
|
||||||
|
end
|
||||||
|
|
||||||
|
container.start
|
43
src/vmm_mad/remotes/lxd/reconfigure
Executable file
43
src/vmm_mad/remotes/lxd/reconfigure
Executable file
@ -0,0 +1,43 @@
|
|||||||
|
#!/usr/bin/ruby
|
||||||
|
|
||||||
|
# -------------------------------------------------------------------------- #
|
||||||
|
# Copyright 2002-2018, OpenNebula Project, OpenNebula Systems #
|
||||||
|
# #
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License"); you may #
|
||||||
|
# not use this file except in compliance with the License. You may obtain #
|
||||||
|
# a copy of the License at #
|
||||||
|
# #
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0 #
|
||||||
|
# #
|
||||||
|
# Unless required by applicable law or agreed to in writing, software #
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS, #
|
||||||
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. #
|
||||||
|
# See the License for the specific language governing permissions and #
|
||||||
|
# limitations under the License. #
|
||||||
|
#--------------------------------------------------------------------------- #
|
||||||
|
|
||||||
|
$LOAD_PATH.unshift File.dirname(__FILE__)
|
||||||
|
|
||||||
|
require 'container'
|
||||||
|
|
||||||
|
require_relative '../../scripts_common'
|
||||||
|
|
||||||
|
# ------------------------------------------------------------------------------
|
||||||
|
# Action Arguments, STDIN includes XML description of the OpenNebula VM
|
||||||
|
# ------------------------------------------------------------------------------
|
||||||
|
vm_name = ARGV[0]
|
||||||
|
iso_path = ARGV[2]
|
||||||
|
vm_id = ARGV[3]
|
||||||
|
|
||||||
|
xml = STDIN.read
|
||||||
|
|
||||||
|
# ------------------------------------------------------------------------------
|
||||||
|
# Setup Context for the container
|
||||||
|
# ------------------------------------------------------------------------------
|
||||||
|
if iso_path != ''
|
||||||
|
client = LXDClient.new
|
||||||
|
container = Container.get(vm_name, xml, client)
|
||||||
|
|
||||||
|
container.attach_context
|
||||||
|
container.exec('one-contextd local 2>/dev/null')
|
||||||
|
end
|
19
src/vmm_mad/remotes/lxd/reset
Executable file
19
src/vmm_mad/remotes/lxd/reset
Executable file
@ -0,0 +1,19 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# -------------------------------------------------------------------------- #
|
||||||
|
# Copyright 2002-2018, OpenNebula Project, OpenNebula Systems #
|
||||||
|
# #
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License"); you may #
|
||||||
|
# not use this file except in compliance with the License. You may obtain #
|
||||||
|
# a copy of the License at #
|
||||||
|
# #
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0 #
|
||||||
|
# #
|
||||||
|
# Unless required by applicable law or agreed to in writing, software #
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS, #
|
||||||
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. #
|
||||||
|
# See the License for the specific language governing permissions and #
|
||||||
|
# limitations under the License. #
|
||||||
|
#--------------------------------------------------------------------------- #
|
||||||
|
|
||||||
|
$(dirname $0)/reboot $1 '-f'
|
1
src/vmm_mad/remotes/lxd/resize_disk
Symbolic link
1
src/vmm_mad/remotes/lxd/resize_disk
Symbolic link
@ -0,0 +1 @@
|
|||||||
|
../common/not_supported.sh
|
1
src/vmm_mad/remotes/lxd/restore
Symbolic link
1
src/vmm_mad/remotes/lxd/restore
Symbolic link
@ -0,0 +1 @@
|
|||||||
|
../common/not_supported.sh
|
1
src/vmm_mad/remotes/lxd/save
Symbolic link
1
src/vmm_mad/remotes/lxd/save
Symbolic link
@ -0,0 +1 @@
|
|||||||
|
../common/not_supported.sh
|
57
src/vmm_mad/remotes/lxd/shutdown
Executable file
57
src/vmm_mad/remotes/lxd/shutdown
Executable file
@ -0,0 +1,57 @@
|
|||||||
|
#!/usr/bin/ruby
|
||||||
|
|
||||||
|
# -------------------------------------------------------------------------- #
|
||||||
|
# Copyright 2002-2018, OpenNebula Project, OpenNebula Systems #
|
||||||
|
# #
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License"); you may #
|
||||||
|
# not use this file except in compliance with the License. You may obtain #
|
||||||
|
# a copy of the License at #
|
||||||
|
# #
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0 #
|
||||||
|
# #
|
||||||
|
# Unless required by applicable law or agreed to in writing, software #
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS, #
|
||||||
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. #
|
||||||
|
# See the License for the specific language governing permissions and #
|
||||||
|
# limitations under the License. #
|
||||||
|
#--------------------------------------------------------------------------- #
|
||||||
|
|
||||||
|
$LOAD_PATH.unshift File.dirname(__FILE__)
|
||||||
|
|
||||||
|
require 'container'
|
||||||
|
|
||||||
|
require_relative '../../scripts_common'
|
||||||
|
|
||||||
|
# ------------------------------------------------------------------------------
|
||||||
|
# Action Arguments, STDIN includes XML description of the OpenNebula VM
|
||||||
|
# ------------------------------------------------------------------------------
|
||||||
|
vm_name = ARGV[0]
|
||||||
|
vm_id = ARGV[2]
|
||||||
|
|
||||||
|
xml = STDIN.read
|
||||||
|
|
||||||
|
client = LXDClient.new
|
||||||
|
container = Container.get(vm_name, xml, client)
|
||||||
|
|
||||||
|
# ------------------------------------------------------------------------------
|
||||||
|
# Stop the container & unmap devices if not a wild container
|
||||||
|
# ------------------------------------------------------------------------------
|
||||||
|
if ARGV[-1] == '-f'
|
||||||
|
container.stop(:force => true)
|
||||||
|
else
|
||||||
|
container.stop
|
||||||
|
end
|
||||||
|
|
||||||
|
if !container.wild?
|
||||||
|
begin
|
||||||
|
container.setup_storage('unmap')
|
||||||
|
rescue StandardError => e
|
||||||
|
container.start
|
||||||
|
raise e
|
||||||
|
end
|
||||||
|
|
||||||
|
container.delete
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
container.vnc('stop')
|
1
src/vmm_mad/remotes/lxd/snapshot_create
Symbolic link
1
src/vmm_mad/remotes/lxd/snapshot_create
Symbolic link
@ -0,0 +1 @@
|
|||||||
|
../common/not_supported.sh
|
1
src/vmm_mad/remotes/lxd/snapshot_delete
Symbolic link
1
src/vmm_mad/remotes/lxd/snapshot_delete
Symbolic link
@ -0,0 +1 @@
|
|||||||
|
../common/not_supported.sh
|
1
src/vmm_mad/remotes/lxd/snapshot_revert
Symbolic link
1
src/vmm_mad/remotes/lxd/snapshot_revert
Symbolic link
@ -0,0 +1 @@
|
|||||||
|
../common/not_supported.sh
|
@ -16,76 +16,142 @@
|
|||||||
|
|
||||||
module VNMMAD
|
module VNMMAD
|
||||||
|
|
||||||
module VNMNetwork
|
module VNMNetwork
|
||||||
|
|
||||||
# This Hash will be pppulated by the NicKVM and other hypervisor-nic
|
# This Hash will be pppulated by the NicKVM and other hypervisor-nic
|
||||||
# specific classes.
|
# specific classes.
|
||||||
HYPERVISORS = {}
|
HYPERVISORS = {}
|
||||||
|
|
||||||
# This class represents the NICS of a VM, it provides a factory method
|
# This class represents the NICS of a VM, it provides a factory method
|
||||||
# to create VMs of the given hyprtvisor
|
# to create VMs of the given hyprtvisor
|
||||||
class Nics < Array
|
class Nics < Array
|
||||||
def initialize(hypervisor)
|
|
||||||
@nicClass = HYPERVISORS[hypervisor] || NicKVM
|
|
||||||
end
|
|
||||||
|
|
||||||
def new_nic
|
def initialize(hypervisor)
|
||||||
@nicClass.new
|
@nicClass = HYPERVISORS[hypervisor] || NicKVM
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
############################################################################
|
|
||||||
# Hypervisor specific implementation of network interfaces. Each class
|
|
||||||
# implements the following interface:
|
|
||||||
# - get_info to populste the VM.vm_info Hash
|
|
||||||
# - get_tap to set the [:tap] attribute with the associated NIC
|
|
||||||
############################################################################
|
|
||||||
|
|
||||||
# A NIC using KVM. This class implements functions to get the physical
|
|
||||||
# interface that the NIC is using, based on the MAC address
|
|
||||||
class NicKVM < Hash
|
|
||||||
VNMNetwork::HYPERVISORS["kvm"] = self
|
|
||||||
|
|
||||||
def initialize
|
|
||||||
super(nil)
|
|
||||||
end
|
|
||||||
|
|
||||||
# Get the VM information with virsh dumpxml
|
|
||||||
def get_info(vm)
|
|
||||||
if vm.deploy_id
|
|
||||||
deploy_id = vm.deploy_id
|
|
||||||
else
|
|
||||||
deploy_id = vm['DEPLOY_ID']
|
|
||||||
end
|
end
|
||||||
|
|
||||||
if deploy_id and vm.vm_info[:dumpxml].nil?
|
def new_nic
|
||||||
vm.vm_info[:dumpxml] = `#{VNMNetwork::COMMANDS[:virsh]} dumpxml #{deploy_id} 2>/dev/null`
|
@nicClass.new
|
||||||
|
end
|
||||||
|
|
||||||
vm.vm_info.each_key do |k|
|
end
|
||||||
vm.vm_info[k] = nil if vm.vm_info[k].to_s.strip.empty?
|
|
||||||
|
############################################################################
|
||||||
|
# Hypervisor specific implementation of network interfaces. Each class
|
||||||
|
# implements the following interface:
|
||||||
|
# - get_info to populste the VM.vm_info Hash
|
||||||
|
# - get_tap to set the [:tap] attribute with the associated NIC
|
||||||
|
############################################################################
|
||||||
|
|
||||||
|
# A NIC using KVM. This class implements functions to get the physical
|
||||||
|
# interface that the NIC is using, based on the MAC address
|
||||||
|
class NicKVM < Hash
|
||||||
|
|
||||||
|
VNMNetwork::HYPERVISORS['kvm'] = self
|
||||||
|
|
||||||
|
def initialize
|
||||||
|
super(nil)
|
||||||
|
end
|
||||||
|
|
||||||
|
# Get the VM information with virsh dumpxml
|
||||||
|
def get_info(vm)
|
||||||
|
if vm.deploy_id
|
||||||
|
deploy_id = vm.deploy_id
|
||||||
|
else
|
||||||
|
deploy_id = vm['DEPLOY_ID']
|
||||||
|
end
|
||||||
|
|
||||||
|
if deploy_id && vm.vm_info[:dumpxml].nil?
|
||||||
|
vm.vm_info[:dumpxml] = `#{VNMNetwork::COMMANDS[:virsh]} dumpxml #{deploy_id} 2>/dev/null`
|
||||||
|
|
||||||
|
vm.vm_info.each_key do |k|
|
||||||
|
vm.vm_info[k] = nil if vm.vm_info[k].to_s.strip.empty?
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
|
||||||
|
|
||||||
# Look for the tap in
|
# Look for the tap in
|
||||||
# devices/interface[@type='bridge']/mac[@address='<mac>']/../target"
|
# devices/interface[@type='bridge']/mac[@address='<mac>']/../target"
|
||||||
def get_tap(vm)
|
def get_tap(vm)
|
||||||
dumpxml = vm.vm_info[:dumpxml]
|
dumpxml = vm.vm_info[:dumpxml]
|
||||||
|
|
||||||
if dumpxml
|
if dumpxml
|
||||||
dumpxml_root = REXML::Document.new(dumpxml).root
|
dumpxml_root = REXML::Document.new(dumpxml).root
|
||||||
|
|
||||||
xpath = "devices/interface[@type='bridge']/" \
|
xpath = "devices/interface[@type='bridge']/" \
|
||||||
"mac[@address='#{self[:mac]}']/../target"
|
"mac[@address='#{self[:mac]}']/../target"
|
||||||
|
|
||||||
tap = dumpxml_root.elements[xpath]
|
tap = dumpxml_root.elements[xpath]
|
||||||
|
|
||||||
self[:tap] = tap.attributes['dev'] if tap
|
self[:tap] = tap.attributes['dev'] if tap
|
||||||
|
end
|
||||||
|
|
||||||
|
self
|
||||||
end
|
end
|
||||||
|
|
||||||
self
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# A NIC using LXD. This class implements functions to get the physical
|
||||||
|
# interface that the NIC is using, based on the MAC address
|
||||||
|
class NicLXD < Hash
|
||||||
|
|
||||||
|
VNMNetwork::HYPERVISORS['lxd'] = self
|
||||||
|
|
||||||
|
def initialize
|
||||||
|
super(nil)
|
||||||
|
end
|
||||||
|
|
||||||
|
# Get the VM information with lxc config show
|
||||||
|
def get_info(vm)
|
||||||
|
if vm.deploy_id
|
||||||
|
deploy_id = vm.deploy_id
|
||||||
|
else
|
||||||
|
deploy_id = vm['DEPLOY_ID']
|
||||||
|
end
|
||||||
|
|
||||||
|
if deploy_id && vm.vm_info[:dumpxml].nil?
|
||||||
|
vm.vm_info[:dumpxml] = YAML.safe_load(`lxc config show #{deploy_id} 2>/dev/null`)
|
||||||
|
|
||||||
|
vm.vm_info.each_key do |k|
|
||||||
|
vm.vm_info[k] = nil if vm.vm_info[k].to_s.strip.empty?
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
# Look for the tap in config
|
||||||
|
def get_tap(vm)
|
||||||
|
dumpxml = vm.vm_info[:dumpxml]
|
||||||
|
|
||||||
|
if dumpxml
|
||||||
|
devices = dumpxml['devices']
|
||||||
|
xpath = find_path(devices, self[:mac])
|
||||||
|
end
|
||||||
|
|
||||||
|
if xpath
|
||||||
|
self[:tap] = devices[xpath]['host_name'] if devices[xpath]['host_name']
|
||||||
|
end
|
||||||
|
|
||||||
|
self
|
||||||
|
end
|
||||||
|
|
||||||
|
def find_path(hash, text)
|
||||||
|
path = '' unless path.is_a?(String)
|
||||||
|
hash.each do |k, v|
|
||||||
|
if v == text
|
||||||
|
return k
|
||||||
|
end
|
||||||
|
|
||||||
|
if v.is_a?(Hash)
|
||||||
|
path = k
|
||||||
|
tmp = find_path(v, text)
|
||||||
|
end
|
||||||
|
return path unless tmp.nil?
|
||||||
|
end
|
||||||
|
nil
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
end
|
|
||||||
|
|
||||||
end
|
end
|
||||||
|
Loading…
Reference in New Issue
Block a user