parent
533b86cbbe
commit
edc73d3159
@ -0,0 +1,4 @@ |
|||||||
|
SHELL=/bin/sh |
||||||
|
|
||||||
|
# activate LVM volumes on reboot |
||||||
|
@reboot oneadmin test -x /var/tmp/one/tm/fs_lvm/activate && /var/tmp/one/tm/fs_lvm/activate >/dev/null 2>&1 |
@ -0,0 +1,30 @@ |
|||||||
|
#!/sbin/openrc-run |
||||||
|
|
||||||
|
name=$RC_SVCNAME |
||||||
|
description="OpenNebula Gate Proxy Service" |
||||||
|
command="/usr/bin/ruby /usr/lib/one/onegate-proxy/onegate-proxy.rb" |
||||||
|
command_user="oneadmin:cloud" |
||||||
|
pidfile="/run/one/${RC_SVCNAME}.pid" |
||||||
|
supervisor="supervise-daemon" |
||||||
|
|
||||||
|
depend() { |
||||||
|
need opennebula |
||||||
|
after syslog networking netmount |
||||||
|
} |
||||||
|
|
||||||
|
start() { |
||||||
|
ebegin "Starting $RC_SVCNAME" |
||||||
|
start-stop-daemon --background \ |
||||||
|
--exec $command \ |
||||||
|
--make-pidfile --pidfile $pidfile --user $command_user \ |
||||||
|
--start |
||||||
|
eend $? |
||||||
|
} |
||||||
|
|
||||||
|
stop() { |
||||||
|
ebegin "Stopping $RC_SVCNAME" |
||||||
|
start-stop-daemon --stop \ |
||||||
|
--exec $command \ |
||||||
|
--pidfile $pidfile --user $command_user |
||||||
|
eend $? |
||||||
|
} |
@ -0,0 +1,11 @@ |
|||||||
|
/var/log/one/onegate-proxy.log { |
||||||
|
delaycompress |
||||||
|
dateext |
||||||
|
dateformat -%Y%m%d-%s |
||||||
|
compress |
||||||
|
weekly |
||||||
|
rotate 52 |
||||||
|
missingok |
||||||
|
notifempty |
||||||
|
copytruncate |
||||||
|
} |
@ -0,0 +1 @@ |
|||||||
|
oneadmin ALL=(ALL:ALL) NOPASSWD: ONE_CEPH, ONE_NET, ONE_OVS, ONE_LVM, ONE_MEM, ONE_VGPU |
@ -0,0 +1,3 @@ |
|||||||
|
net.bridge.bridge-nf-call-arptables = 1 |
||||||
|
net.bridge.bridge-nf-call-ip6tables = 1 |
||||||
|
net.bridge.bridge-nf-call-iptables = 1 |
@ -1,57 +0,0 @@ |
|||||||
#!/bin/sh |
|
||||||
|
|
||||||
set -e |
|
||||||
|
|
||||||
ONEHOME=/var/lib/one |
|
||||||
ONE_GROUP=cloud |
|
||||||
ONE_USER=oneadmin |
|
||||||
ONE_UID=9869 |
|
||||||
ONE_GID=9869 |
|
||||||
ONE_COMMENT="OpenNebula administrator account" |
|
||||||
|
|
||||||
create_cloudgroup() { |
|
||||||
if ! getent group $ONE_GROUP > /dev/null 2>&1; then |
|
||||||
addgroup --system --gid $ONE_GID $ONE_GROUP |
|
||||||
fi |
|
||||||
} |
|
||||||
|
|
||||||
create_oneuser() { |
|
||||||
if ! getent passwd $ONE_USER > /dev/null 2>&1; then |
|
||||||
adduser --system --gecos "$ONE_COMMENT" --uid $ONE_UID --ingroup $ONE_GROUP --home $ONEHOME --shell /bin/ash $ONE_USER |
|
||||||
else |
|
||||||
ONEHOME=`getent passwd $ONE_USER | cut -f6 -d:` |
|
||||||
# Renable user (give him a shell) |
|
||||||
usermod --shell /bin/ash $ONE_USER |
|
||||||
fi |
|
||||||
|
|
||||||
if ! getent group disk | grep "\b$ONE_USER\b" &>/dev/null; then |
|
||||||
usermod -a -G disk $ONE_USER |
|
||||||
fi |
|
||||||
} |
|
||||||
|
|
||||||
create_cloudgroup |
|
||||||
create_oneuser |
|
||||||
|
|
||||||
# Install ~oneadmin/.ssh/config if not present on a fresh install only |
|
||||||
if [ ! -e "${ONEHOME}/.ssh/config" ] && [ -z "$2" ]; then |
|
||||||
if [ ! -d "${ONEHOME}/.ssh" ]; then |
|
||||||
mkdir -p "${ONEHOME}/.ssh" |
|
||||||
chmod 0700 "${ONEHOME}/.ssh" |
|
||||||
chown "$ONE_USER:$ONE_GROUP" "${ONEHOME}/.ssh" |
|
||||||
fi |
|
||||||
cp /usr/share/one/ssh/config "${ONEHOME}/.ssh/config" |
|
||||||
chmod 0600 "${ONEHOME}/.ssh/config" |
|
||||||
chown "$ONE_USER:$ONE_GROUP" "${ONEHOME}/.ssh/config" |
|
||||||
fi |
|
||||||
|
|
||||||
# Set permissions and owner oneadmin:cloud |
|
||||||
for F in /var/lock/one /var/log/one /var/run/one |
|
||||||
do |
|
||||||
if [ ! -d "${F}" ]; then |
|
||||||
mkdir -p "${F}" |
|
||||||
chmod 0750 "${F}" |
|
||||||
chown "${ONE_USER}:${ONE_GROUP}" "${F}" |
|
||||||
fi |
|
||||||
done |
|
||||||
|
|
||||||
exit 0 |
|
@ -0,0 +1,140 @@ |
|||||||
|
#!/bin/sh |
||||||
|
|
||||||
|
set -e |
||||||
|
|
||||||
|
ONEHOME=/var/lib/one |
||||||
|
ONE_GROUP=cloud |
||||||
|
ONE_USER=oneadmin |
||||||
|
|
||||||
|
# Add oneadmin user into libvirt group |
||||||
|
if getent group libvirt >/dev/null && ! getent group libvirt | cut -f4 -d: | grep -q "\<$ONE_USER\>"; then |
||||||
|
adduser $ONE_USER libvirt |
||||||
|
fi |
||||||
|
|
||||||
|
# Add oneadmin user into kvm group |
||||||
|
if getent group kvm >/dev/null && ! getent group kvm | cut -f4 -d: | grep -q "\<$ONE_USER\>"; then |
||||||
|
adduser $ONE_USER kvm |
||||||
|
fi |
||||||
|
|
||||||
|
# Backup libvirt/QEMU configuration, reconfigure for OpenNebula |
||||||
|
if [ -e /etc/libvirt/qemu.conf ]; then |
||||||
|
cp -f /etc/libvirt/qemu.conf "/etc/libvirt/qemu.conf.$(date +'%Y-%m-%d_%H:%M:%S')" |
||||||
|
fi |
||||||
|
|
||||||
|
AUGTOOL=$(augtool -A 2>/dev/null <<EOF |
||||||
|
set /augeas/load/Libvirtd_qemu/lens Libvirtd_qemu.lns |
||||||
|
set /augeas/load/Libvirtd_qemu/incl /etc/libvirt/qemu.conf |
||||||
|
load |
||||||
|
|
||||||
|
set /files/etc/libvirt/qemu.conf/user oneadmin |
||||||
|
set /files/etc/libvirt/qemu.conf/group cloud |
||||||
|
set /files/etc/libvirt/qemu.conf/dynamic_ownership 0 |
||||||
|
|
||||||
|
save |
||||||
|
EOF |
||||||
|
) |
||||||
|
|
||||||
|
# generate generic qemu-kvm-one symlink |
||||||
|
/usr/bin/qemu-kvm-one-gen |
||||||
|
|
||||||
|
if [ -n "${AUGTOOL}" ] && [ -z "${AUGTOOL##*Saved *}" ]; then |
||||||
|
systemctl try-restart libvirtd 2>/dev/null || true |
||||||
|
fi |
||||||
|
|
||||||
|
# # Automatically added by dh_systemd_enable/12.10ubuntu1 |
||||||
|
# if [ "$1" = "configure" ] || [ "$1" = "abort-upgrade" ] || [ "$1" = "abort-deconfigure" ] || [ "$1" = "abort-remove" ] ; then |
||||||
|
# if deb-systemd-helper debian-installed 'opennebula-gate-proxy.service'; then |
||||||
|
# # This will only remove masks created by d-s-h on package removal. |
||||||
|
# deb-systemd-helper unmask 'opennebula-gate-proxy.service' >/dev/null || true |
||||||
|
# |
||||||
|
# if deb-systemd-helper --quiet was-enabled 'opennebula-gate-proxy.service'; then |
||||||
|
# # Create new symlinks, if any. |
||||||
|
# deb-systemd-helper enable 'opennebula-gate-proxy.service' >/dev/null || true |
||||||
|
# fi |
||||||
|
# fi |
||||||
|
# |
||||||
|
# # Update the statefile to add new symlinks (if any), which need to be cleaned |
||||||
|
# # up on purge. Also remove old symlinks. |
||||||
|
# deb-systemd-helper update-state 'opennebula-gate-proxy.service' >/dev/null || true |
||||||
|
# fi |
||||||
|
# # End automatically added section |
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
create_cloudgroup() { |
||||||
|
if ! getent group $ONE_GROUP > /dev/null 2>&1; then |
||||||
|
addgroup --system --gid $ONE_GID $ONE_GROUP |
||||||
|
fi |
||||||
|
} |
||||||
|
|
||||||
|
create_oneuser() { |
||||||
|
if ! getent passwd $ONE_USER > /dev/null 2>&1; then |
||||||
|
adduser --system --gecos "$ONE_COMMENT" --uid $ONE_UID --ingroup $ONE_GROUP --home $ONEHOME --shell /bin/ash $ONE_USER |
||||||
|
else |
||||||
|
ONEHOME=`getent passwd $ONE_USER | cut -f6 -d:` |
||||||
|
# Renable user (give him a shell) |
||||||
|
usermod --shell /bin/ash $ONE_USER |
||||||
|
fi |
||||||
|
|
||||||
|
if ! getent group disk | grep "\b$ONE_USER\b" &>/dev/null; then |
||||||
|
usermod -a -G disk $ONE_USER |
||||||
|
fi |
||||||
|
} |
||||||
|
|
||||||
|
create_cloudgroup |
||||||
|
create_oneuser |
||||||
|
|
||||||
|
# Install ~oneadmin/.ssh/config if not present on a fresh install only |
||||||
|
if [ ! -e "${ONEHOME}/.ssh/config" ] && [ -z "$2" ]; then |
||||||
|
if [ ! -d "${ONEHOME}/.ssh" ]; then |
||||||
|
mkdir -p "${ONEHOME}/.ssh" |
||||||
|
chmod 0700 "${ONEHOME}/.ssh" |
||||||
|
chown "$ONE_USER:$ONE_GROUP" "${ONEHOME}/.ssh" |
||||||
|
fi |
||||||
|
cp /usr/share/one/ssh/config "${ONEHOME}/.ssh/config" |
||||||
|
chmod 0600 "${ONEHOME}/.ssh/config" |
||||||
|
chown "$ONE_USER:$ONE_GROUP" "${ONEHOME}/.ssh/config" |
||||||
|
fi |
||||||
|
|
||||||
|
# Set permissions and owner oneadmin:cloud |
||||||
|
for F in /var/lock/one /var/log/one /var/run/one |
||||||
|
do |
||||||
|
if [ ! -d "${F}" ]; then |
||||||
|
mkdir -p "${F}" |
||||||
|
chmod 0750 "${F}" |
||||||
|
chown "${ONE_USER}:${ONE_GROUP}" "${F}" |
||||||
|
fi |
||||||
|
done |
||||||
|
|
||||||
|
exit 0 |
@ -0,0 +1,120 @@ |
|||||||
|
#!/bin/bash |
||||||
|
|
||||||
|
# -------------------------------------------------------------------------- # |
||||||
|
# Copyright 2002-2023, 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. # |
||||||
|
#--------------------------------------------------------------------------- # |
||||||
|
|
||||||
|
if [ -z "$ONE_LOCATION" ]; then |
||||||
|
ONEGATE_PROXY_PID=/var/run/one/onegate-proxy.pid |
||||||
|
ONEGATE_PROXY_SERVER=/usr/lib/one/onegate-proxy/onegate-proxy.rb |
||||||
|
ONEGATE_PROXY_LOCK_FILE=/var/lock/one/.onegate-proxy.lock |
||||||
|
ONEGATE_PROXY_LOG=/var/log/one/onegate-proxy.log |
||||||
|
ONEGATE_PROXY_LOG_ERROR=/var/log/one/onegate-proxy.error |
||||||
|
else |
||||||
|
ONEGATE_PROXY_PID=$ONE_LOCATION/var/onegate-proxy.pid |
||||||
|
ONEGATE_PROXY_SERVER=$ONE_LOCATION/lib/onegate-proxy/onegate-proxy.rb |
||||||
|
ONEGATE_PROXY_LOCK_FILE=$ONE_LOCATION/var/.onegate-proxy.lock |
||||||
|
ONEGATE_PROXY_LOG=$ONE_LOCATION/var/onegate-proxy.log |
||||||
|
ONEGATE_PROXY_LOG_ERROR=$ONE_LOCATION/var/onegate-proxy.error |
||||||
|
fi |
||||||
|
|
||||||
|
setup() |
||||||
|
{ |
||||||
|
if [ -f $ONEGATE_PROXY_LOCK_FILE ]; then |
||||||
|
if [ -f $ONEGATE_PROXY_PID ]; then |
||||||
|
ONEGATEPID=`cat $ONEGATE_PROXY_PID` |
||||||
|
ps $ONEGATEPID &> /dev/null |
||||||
|
if [ $? -eq 0 ]; then |
||||||
|
echo -n "OneGate Server is still running (PID:$ONEGATEPID). Please " |
||||||
|
echo "try 'onegate-proxy stop' first." |
||||||
|
exit 1 |
||||||
|
fi |
||||||
|
fi |
||||||
|
echo "Stale .lock detected. Erasing it." |
||||||
|
rm $ONEGATE_PROXY_LOCK_FILE |
||||||
|
fi |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
start() |
||||||
|
{ |
||||||
|
if [ ! -f "$ONEGATE_PROXY_SERVER" ]; then |
||||||
|
echo "Cannot find $ONEGATE_PROXY_SERVER." |
||||||
|
exit 1 |
||||||
|
fi |
||||||
|
|
||||||
|
# Start the onegate daemon |
||||||
|
touch $ONEGATE_PROXY_LOCK_FILE |
||||||
|
ruby $ONEGATE_PROXY_SERVER > $ONEGATE_PROXY_LOG 2>$ONEGATE_PROXY_LOG_ERROR & |
||||||
|
LASTPID=$! |
||||||
|
|
||||||
|
if [ $? -ne 0 ]; then |
||||||
|
echo "Error executing onegate-proxy." |
||||||
|
echo "Check $ONEGATE_PROXY_LOG_ERROR and $ONEGATE_PROXY_LOG for more information" |
||||||
|
exit 1 |
||||||
|
else |
||||||
|
echo $LASTPID > $ONEGATE_PROXY_PID |
||||||
|
fi |
||||||
|
|
||||||
|
sleep 1 |
||||||
|
ps $LASTPID &> /dev/null |
||||||
|
|
||||||
|
if [ $? -ne 0 ]; then |
||||||
|
echo "Error executing onegate-proxy." |
||||||
|
echo "Check $ONEGATE_PROXY_LOG_ERROR and $ONEGATE_PROXY_LOG for more information" |
||||||
|
exit 1 |
||||||
|
fi |
||||||
|
|
||||||
|
echo "onegate-proxy started" |
||||||
|
} |
||||||
|
|
||||||
|
# |
||||||
|
# Function that stops the daemon/service |
||||||
|
# |
||||||
|
stop() |
||||||
|
{ |
||||||
|
if [ ! -f $ONEGATE_PROXY_PID ]; then |
||||||
|
echo "Couldn't find onegate-proxy process pid." |
||||||
|
exit 1 |
||||||
|
fi |
||||||
|
|
||||||
|
# Kill the onegate daemon |
||||||
|
kill -INT `cat $ONEGATE_PROXY_PID` &> /dev/null |
||||||
|
|
||||||
|
# Remove pid files |
||||||
|
rm -f $ONEGATE_PROXY_LOCK_FILE &> /dev/null |
||||||
|
rm -f $ONEGATE_PROXY_PID &> /dev/null |
||||||
|
|
||||||
|
echo "onegate-proxy stopped" |
||||||
|
} |
||||||
|
|
||||||
|
case "$1" in |
||||||
|
start) |
||||||
|
setup |
||||||
|
start |
||||||
|
;; |
||||||
|
stop) |
||||||
|
stop |
||||||
|
;; |
||||||
|
restart) |
||||||
|
stop |
||||||
|
setup |
||||||
|
start |
||||||
|
;; |
||||||
|
*) |
||||||
|
echo "Usage: onegate-proxy {start|stop|restart}" >&2 |
||||||
|
exit 3 |
||||||
|
;; |
||||||
|
esac |
@ -0,0 +1,120 @@ |
|||||||
|
#!/bin/sh |
||||||
|
|
||||||
|
# -------------------------------------------------------------------------- # |
||||||
|
# Copyright 2002-2023, 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. # |
||||||
|
#--------------------------------------------------------------------------- # |
||||||
|
|
||||||
|
set -e |
||||||
|
|
||||||
|
CMD=$(basename ${0}) |
||||||
|
|
||||||
|
# file path to the new qemu-kvm symlink |
||||||
|
QEMU_ONE="/usr/bin/qemu-kvm-one" |
||||||
|
|
||||||
|
# |
||||||
|
# functions |
||||||
|
# |
||||||
|
|
||||||
|
print_usage() |
||||||
|
{ |
||||||
|
cat <<EOF |
||||||
|
NAME: |
||||||
|
${CMD} - System agnostic QEMU/KVM symlink generator |
||||||
|
|
||||||
|
It will try to find a qemu-kvm binary in the system from a list of known |
||||||
|
paths and if successful - it will create a proper symlink: |
||||||
|
'${QEMU_ONE}' |
||||||
|
|
||||||
|
USAGE: |
||||||
|
${CMD} [-f|--force] |
||||||
|
Find the system QEMU binary and create the symlink |
||||||
|
|
||||||
|
-f|--force: This option will overwrite existing symlink or file |
||||||
|
|
||||||
|
${CMD} -h|--help |
||||||
|
Print this help |
||||||
|
EOF |
||||||
|
} |
||||||
|
|
||||||
|
# |
||||||
|
# main |
||||||
|
# |
||||||
|
|
||||||
|
FORCE_CREATE= |
||||||
|
case "$1" in |
||||||
|
'') |
||||||
|
: |
||||||
|
;; |
||||||
|
-h|--help) |
||||||
|
print_usage |
||||||
|
exit 0 |
||||||
|
;; |
||||||
|
-f|--force) |
||||||
|
FORCE_CREATE=yes |
||||||
|
;; |
||||||
|
*) |
||||||
|
echo "ERROR: ${CMD}: Unknown option '${1}' !" >&2 |
||||||
|
print_usage >&2 |
||||||
|
exit 1 |
||||||
|
;; |
||||||
|
esac |
||||||
|
|
||||||
|
# find cpu arch or default to x86_64 |
||||||
|
if command -v arch >/dev/null 2>&1 ; then |
||||||
|
ARCH=$(arch) |
||||||
|
else |
||||||
|
ARCH="x86_64" |
||||||
|
fi |
||||||
|
|
||||||
|
# verify that symlink is not already created |
||||||
|
if [ -L "${QEMU_ONE}" ] ; then |
||||||
|
# symlink already exists |
||||||
|
|
||||||
|
qemu_target=$(readlink "${QEMU_ONE}") |
||||||
|
|
||||||
|
if [ -e "${qemu_target}" ] && [ -z "${FORCE_CREATE}" ] ; then |
||||||
|
# symlink is valid |
||||||
|
exit 0 |
||||||
|
fi |
||||||
|
elif [ -e "${QEMU_ONE}" ] ; then |
||||||
|
# there is a file of the same name and it is not a symlink |
||||||
|
|
||||||
|
if [ -z "${FORCE_CREATE}" ] ; then |
||||||
|
echo "ERROR: ${CMD}: File '${QEMU_ONE}' already exists but it is not a symlink !" >&2 |
||||||
|
exit 1 |
||||||
|
else |
||||||
|
# --force is used |
||||||
|
rm -f "${QEMU_ONE}" |
||||||
|
fi |
||||||
|
fi |
||||||
|
|
||||||
|
# search the known paths for qemu binary |
||||||
|
# |
||||||
|
# NOTE: you can add new supported paths here in the future |
||||||
|
for QEMU_BIN in \ |
||||||
|
/usr/libexec/qemu-kvm \ |
||||||
|
/usr/bin/qemu-kvm \ |
||||||
|
/usr/bin/qemu-system-${ARCH} \ |
||||||
|
; |
||||||
|
do |
||||||
|
if [ -e "${QEMU_BIN}" ] ; then |
||||||
|
ln -s ${FORCE_CREATE:+-f} "${QEMU_BIN}" "${QEMU_ONE}" |
||||||
|
exit 0 |
||||||
|
fi |
||||||
|
done |
||||||
|
|
||||||
|
# no qemu binary found -> we signal error and exit |
||||||
|
echo "ERROR: ${CMD}: No qemu kvm binary found !" >&2 |
||||||
|
exit 1 |
@ -0,0 +1,309 @@ |
|||||||
|
#!/usr/bin/env ruby |
||||||
|
# -------------------------------------------------------------------------- # |
||||||
|
# Copyright 2002-2023, 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. # |
||||||
|
#--------------------------------------------------------------------------- # |
||||||
|
|
||||||
|
# frozen_string_literal: true |
||||||
|
|
||||||
|
# rubocop:disable Lint/MissingCopEnableDirective |
||||||
|
# rubocop:disable Lint/RedundantRequireStatement |
||||||
|
# rubocop:disable Layout/FirstHashElementIndentation |
||||||
|
# rubocop:disable Layout/HashAlignment |
||||||
|
# rubocop:disable Layout/HeredocIndentation |
||||||
|
# rubocop:disable Layout/IndentationWidth |
||||||
|
# rubocop:disable Style/HashSyntax |
||||||
|
# rubocop:disable Style/ParallelAssignment |
||||||
|
|
||||||
|
ONE_LOCATION = ENV['ONE_LOCATION'] |
||||||
|
|
||||||
|
if !ONE_LOCATION |
||||||
|
RUBY_LIB_LOCATION = '/usr/lib/one/ruby' |
||||||
|
GEMS_LOCATION = '/usr/share/one/gems' |
||||||
|
ETC_LOCATION = '/etc/one' |
||||||
|
REMOTES_LOCATION = '/var/tmp/one' |
||||||
|
else |
||||||
|
RUBY_LIB_LOCATION = ONE_LOCATION + '/lib/ruby' |
||||||
|
GEMS_LOCATION = ONE_LOCATION + '/share/gems' |
||||||
|
ETC_LOCATION = ONE_LOCATION + '/etc' |
||||||
|
REMOTES_LOCATION = ONE_LOCATION + '/var/remotes' |
||||||
|
end |
||||||
|
|
||||||
|
CONFIGURATION_FILE = REMOTES_LOCATION + '/etc/onegate-proxy.conf' |
||||||
|
|
||||||
|
# %%RUBYGEMS_SETUP_BEGIN%% |
||||||
|
if File.directory?(GEMS_LOCATION) |
||||||
|
real_gems_path = File.realpath(GEMS_LOCATION) |
||||||
|
if !defined?(Gem) || Gem.path != [real_gems_path] |
||||||
|
$LOAD_PATH.reject! {|p| p =~ /vendor_ruby/ } |
||||||
|
|
||||||
|
# Suppress warnings from Rubygems |
||||||
|
# https://github.com/OpenNebula/one/issues/5379 |
||||||
|
begin |
||||||
|
verb = $VERBOSE |
||||||
|
$VERBOSE = nil |
||||||
|
require 'rubygems' |
||||||
|
Gem.use_paths(real_gems_path) |
||||||
|
ensure |
||||||
|
$VERBOSE = verb |
||||||
|
end |
||||||
|
end |
||||||
|
end |
||||||
|
# %%RUBYGEMS_SETUP_END%% |
||||||
|
|
||||||
|
$LOAD_PATH << RUBY_LIB_LOCATION |
||||||
|
|
||||||
|
require 'async/io' |
||||||
|
require 'async/io/stream' |
||||||
|
require 'async/io/trap' |
||||||
|
require 'etc' |
||||||
|
require 'pp' |
||||||
|
require 'rb-inotify' |
||||||
|
require 'socket' |
||||||
|
require 'yaml' |
||||||
|
|
||||||
|
$stdout.sync = true |
||||||
|
$stderr.sync = true |
||||||
|
|
||||||
|
DEFAULT_OPTIONS = { |
||||||
|
:debug_level => 2, # 0 = ERROR, 1 = WARNING, 2 = INFO, 3 = DEBUG |
||||||
|
:process_owner => 'oneadmin', |
||||||
|
:onegate_addr => '127.0.0.1', |
||||||
|
:onegate_port => '5030', |
||||||
|
:service_addr => '169.254.16.9' |
||||||
|
}.freeze |
||||||
|
|
||||||
|
# Proxy-class for converting log levels between OpenNebula and |
||||||
|
# the socketry/console library. It also splits specific log levels |
||||||
|
# into separate stdout and stderr loggers. |
||||||
|
class Logger |
||||||
|
|
||||||
|
LOG_LEVEL_MAP = { |
||||||
|
0 => '3', # ERROR |
||||||
|
1 => '2', # WARN |
||||||
|
2 => '1', # INFO |
||||||
|
3 => '0' # DEBUG |
||||||
|
}.freeze |
||||||
|
|
||||||
|
def initialize(log_level = 2) |
||||||
|
@out = Console::Logger.default_logger $stdout, { |
||||||
|
'CONSOLE_LEVEL' => LOG_LEVEL_MAP[log_level] |
||||||
|
} |
||||||
|
@err = Console::Logger.default_logger $stderr, { |
||||||
|
'CONSOLE_LEVEL' => LOG_LEVEL_MAP[log_level] |
||||||
|
} |
||||||
|
end |
||||||
|
|
||||||
|
# rubocop:disable Style/ArgumentsForwarding |
||||||
|
def error(*args, &block) |
||||||
|
@err.error(*args, &block) |
||||||
|
end |
||||||
|
|
||||||
|
def warn(*args, &block) |
||||||
|
@err.warn(*args, &block) |
||||||
|
end |
||||||
|
|
||||||
|
def info(*args, &block) |
||||||
|
@out.info(*args, &block) |
||||||
|
end |
||||||
|
|
||||||
|
def debug(*args, &block) |
||||||
|
@err.debug(*args, &block) |
||||||
|
end |
||||||
|
# rubocop:enable Style/ArgumentsForwarding |
||||||
|
|
||||||
|
end |
||||||
|
|
||||||
|
# Class that implements a classic two-way TCP socket proxy (async). |
||||||
|
class OneGateProxy |
||||||
|
|
||||||
|
def initialize(options = {}) |
||||||
|
@options = DEFAULT_OPTIONS.dup.merge! options |
||||||
|
@options.each {|k, v| instance_variable_set("@#{k}", v) } |
||||||
|
|
||||||
|
@logger = Logger.new options[:debug_level] |
||||||
|
|
||||||
|
@sigint = Async::IO::Trap.new :INT |
||||||
|
@sigint.install! |
||||||
|
|
||||||
|
@inotify = setup_inotify |
||||||
|
@inotify_io = Async::IO::Generic.new @inotify.to_io |
||||||
|
|
||||||
|
@proxy_ep = Async::IO::Endpoint.socket setup_socket |
||||||
|
end |
||||||
|
|
||||||
|
def run |
||||||
|
# NOTE: At this point all config should be set in stone, |
||||||
|
# we can drop root privileges.. |
||||||
|
drop_privileges |
||||||
|
|
||||||
|
Async do |task| |
||||||
|
# Make CTRL-C work.. |
||||||
|
task.async do |
||||||
|
@sigint.wait { exit 0 } |
||||||
|
end |
||||||
|
|
||||||
|
# Handle filesystem notifications.. |
||||||
|
task.async do |
||||||
|
@inotify.process while @inotify_io.wait_readable |
||||||
|
end |
||||||
|
|
||||||
|
glue_peers task |
||||||
|
end |
||||||
|
end |
||||||
|
|
||||||
|
private |
||||||
|
|
||||||
|
def drop_privileges |
||||||
|
new_gid, new_uid = Etc.getpwnam(@process_owner).gid, |
||||||
|
Etc.getpwnam(@process_owner).uid |
||||||
|
|
||||||
|
@logger.info(self) do |
||||||
|
"Drop root privileges -> #{@process_owner}" |
||||||
|
end |
||||||
|
|
||||||
|
Process::Sys.setgid new_gid |
||||||
|
Process::Sys.setuid new_uid |
||||||
|
end |
||||||
|
|
||||||
|
def setup_inotify |
||||||
|
inotify = INotify::Notifier.new |
||||||
|
inotify.watch(CONFIGURATION_FILE, :modify) do |
||||||
|
@logger.info(self) do |
||||||
|
"#{CONFIGURATION_FILE} has been just updated, exiting.." |
||||||
|
end |
||||||
|
# We assume here that the service will be restarted by |
||||||
|
# the service manager. |
||||||
|
exit 0 |
||||||
|
end |
||||||
|
inotify |
||||||
|
rescue Errno::ENOENT => e |
||||||
|
@logger.error(self) do |
||||||
|
e.message |
||||||
|
end |
||||||
|
# We assume here that the service will be restarted by |
||||||
|
# the service manager. |
||||||
|
exit e.class::Errno |
||||||
|
end |
||||||
|
|
||||||
|
def setup_service_addr |
||||||
|
# NOTE: We need the service_addr to be defined on one of the interfaces |
||||||
|
# inside the host, one natural choice is the loopback interface (lo). |
||||||
|
# Effectively we set it once, subsequent restarts of the service should |
||||||
|
# honor the idempotence. |
||||||
|
ip_address_add_cmd = lambda do |cidr_host, nic_device| |
||||||
|
check = "[ -n \"$(ip a s to '#{cidr_host}' dev '#{nic_device}')\" ]" |
||||||
|
apply = "ip a a '#{cidr_host}' dev '#{nic_device}'" |
||||||
|
"#{check.strip} >/dev/null 2>&1 || #{apply.strip}" |
||||||
|
end |
||||||
|
system ip_address_add_cmd.call "#{@service_addr}/32", 'lo' |
||||||
|
end |
||||||
|
|
||||||
|
def setup_socket(listen = Socket::SOMAXCONN) |
||||||
|
# NOTE: Must be executed before calling bind(), otherwise it fails.. |
||||||
|
setup_service_addr |
||||||
|
|
||||||
|
sock = Socket.new Socket::AF_INET, Socket::SOCK_STREAM, 0 |
||||||
|
sock.setsockopt Socket::SOL_SOCKET, Socket::SO_REUSEADDR, 1 |
||||||
|
|
||||||
|
@logger.info(self) do |
||||||
|
"Bind #{Addrinfo.tcp(@service_addr, @onegate_port).inspect}" |
||||||
|
end |
||||||
|
|
||||||
|
sock.bind Socket.pack_sockaddr_in(@onegate_port, @service_addr) |
||||||
|
sock.listen listen |
||||||
|
sock |
||||||
|
end |
||||||
|
|
||||||
|
def glue_streams(stream1, stream2, task) |
||||||
|
Async do |
||||||
|
concurrent = [] |
||||||
|
concurrent << task.async do |
||||||
|
while (chunk = stream1.read_partial) |
||||||
|
stream2.write chunk |
||||||
|
stream2.flush |
||||||
|
end |
||||||
|
end |
||||||
|
concurrent << task.async do |
||||||
|
while (chunk = stream2.read_partial) |
||||||
|
stream1.write chunk |
||||||
|
stream1.flush |
||||||
|
end |
||||||
|
end |
||||||
|
concurrent.each(&:wait) |
||||||
|
end |
||||||
|
end |
||||||
|
|
||||||
|
def glue_peers(task) |
||||||
|
@proxy_ep.accept do |vm_peer| |
||||||
|
@logger.debug(self) do |
||||||
|
"Accept #{vm_peer.remote_address.inspect}" |
||||||
|
end |
||||||
|
|
||||||
|
begin |
||||||
|
gate_ep = Async::IO::Endpoint.tcp @onegate_addr, |
||||||
|
@onegate_port |
||||||
|
gate_ep.connect do |gate_peer| |
||||||
|
vm_stream, gate_stream = Async::IO::Stream.new(vm_peer), |
||||||
|
Async::IO::Stream.new(gate_peer) |
||||||
|
|
||||||
|
glue_streams(vm_stream, gate_stream, task).wait |
||||||
|
|
||||||
|
@logger.debug(self) do |
||||||
|
"Close #{gate_peer.remote_address.inspect}" |
||||||
|
end |
||||||
|
|
||||||
|
gate_peer.close |
||||||
|
end |
||||||
|
rescue Errno::ECONNREFUSED, |
||||||
|
Errno::ECONNRESET, |
||||||
|
Errno::EHOSTUNREACH, |
||||||
|
Errno::ETIMEDOUT => e |
||||||
|
@logger.error(self) do |
||||||
|
e.message |
||||||
|
end |
||||||
|
end |
||||||
|
|
||||||
|
@logger.debug(self) do |
||||||
|
"Close #{vm_peer.remote_address.inspect}" |
||||||
|
end |
||||||
|
|
||||||
|
vm_peer.close |
||||||
|
end |
||||||
|
end |
||||||
|
|
||||||
|
end |
||||||
|
|
||||||
|
if caller.empty? |
||||||
|
options = DEFAULT_OPTIONS.dup |
||||||
|
|
||||||
|
# NOTE: The "CONFIGURATION_FILE" is updated during the host sync procedure. |
||||||
|
begin |
||||||
|
options.merge! YAML.load_file(CONFIGURATION_FILE) |
||||||
|
rescue StandardError => e |
||||||
|
warn "Error parsing config file #{CONFIGURATION_FILE}: #{e.message}" |
||||||
|
exit 1 |
||||||
|
end |
||||||
|
|
||||||
|
puts <<~HEADER |
||||||
|
-------------------------------------- |
||||||
|
Proxy configuration |
||||||
|
-------------------------------------- |
||||||
|
#{options.pretty_inspect.strip} |
||||||
|
-------------------------------------- |
||||||
|
HEADER |
||||||
|
|
||||||
|
service = OneGateProxy.new options |
||||||
|
service.run |
||||||
|
end |
Loading…
Reference in new issue