Merge pull request #21 from sh8121att/network_ignore_metadata
Network ignore metadata
This commit is contained in:
commit
84f054610a
@ -25,4 +25,4 @@ RUN python3 setup.py install
|
|||||||
|
|
||||||
EXPOSE 9000
|
EXPOSE 9000
|
||||||
|
|
||||||
CMD ["uwsgi","--http",":9000","-w","drydock_provisioner.drydock","--callable","drydock","--enable-threads","-L","--pyargv","--config-file /etc/drydock/drydock.conf"]
|
CMD ["uwsgi","--http",":9000","-w","drydock_provisioner.drydock","--callable","drydock","--enable-threads","-L","--python-autoreload","1","--pyargv","--config-file /etc/drydock/drydock.conf"]
|
||||||
|
@ -84,8 +84,78 @@ ExecStart=/var/tmp/prom_init.sh /etc/prom_init.yaml
|
|||||||
WantedBy=multi-user.target
|
WantedBy=multi-user.target
|
||||||
"""
|
"""
|
||||||
prom_init = \
|
prom_init = \
|
||||||
"""!/bin/bash
|
"""#!/usr/bin/env bash
|
||||||
echo $HTTP_PROXY
|
|
||||||
echo $NO_PROXY
|
if [ "$(id -u)" != "0" ]; then
|
||||||
cat $1
|
echo "This script must be run as root." 1>&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
|
||||||
|
set -ex
|
||||||
|
|
||||||
|
#Promenade Variables
|
||||||
|
DOCKER_PACKAGE="docker.io"
|
||||||
|
DOCKER_VERSION=1.12.6-0ubuntu1~16.04.1
|
||||||
|
|
||||||
|
#Proxy Variables
|
||||||
|
DOCKER_HTTP_PROXY=${{DOCKER_HTTP_PROXY:-${{HTTP_PROXY:-${{http_proxy}}}}}}
|
||||||
|
DOCKER_HTTPS_PROXY=${{DOCKER_HTTPS_PROXY:-${{HTTPS_PROXY:-${{https_proxy}}}}}}
|
||||||
|
DOCKER_NO_PROXY=${{DOCKER_NO_PROXY:-${{NO_PROXY:-${{}no_proxy}}}}}}
|
||||||
|
|
||||||
|
|
||||||
|
mkdir -p /etc/docker
|
||||||
|
cat <<EOS > /etc/docker/daemon.json
|
||||||
|
{{
|
||||||
|
"live-restore": true,
|
||||||
|
"storage-driver": "overlay2"
|
||||||
|
}}
|
||||||
|
EOS
|
||||||
|
|
||||||
|
#Configuration for Docker Behind a Proxy
|
||||||
|
mkdir -p /etc/systemd/system/docker.service.d
|
||||||
|
|
||||||
|
#Set HTTPS Proxy Variable
|
||||||
|
cat <<EOF > /etc/systemd/system/docker.service.d/http-proxy.conf
|
||||||
|
[Service]
|
||||||
|
Environment="HTTP_PROXY=${{DOCKER_HTTP_PROXY}}"
|
||||||
|
EOF
|
||||||
|
|
||||||
|
#Set HTTPS Proxy Variable
|
||||||
|
cat <<EOF > /etc/systemd/system/docker.service.d/https-proxy.conf
|
||||||
|
[Service]
|
||||||
|
Environment="HTTPS_PROXY=${{DOCKER_HTTPS_PROXY}}"
|
||||||
|
EOF
|
||||||
|
|
||||||
|
#Set No Proxy Variable
|
||||||
|
cat <<EOF > /etc/systemd/system/docker.service.d/no-proxy.conf
|
||||||
|
[Service]
|
||||||
|
Environment="NO_PROXY=${{DOCKER_NO_PROXY}}"
|
||||||
|
EOF
|
||||||
|
|
||||||
|
#Reload systemd and docker if present
|
||||||
|
systemctl daemon-reload
|
||||||
|
systemctl restart docker || true
|
||||||
|
|
||||||
|
export DEBIAN_FRONTEND=noninteractive
|
||||||
|
apt-get update -qq
|
||||||
|
apt-get install -y -qq --no-install-recommends \
|
||||||
|
$DOCKER_PACKAGE=$DOCKER_VERSION \
|
||||||
|
|
||||||
|
|
||||||
|
if [ -f "${{PROMENADE_LOAD_IMAGE}}" ]; then
|
||||||
|
echo === Loading updated promenade image ===
|
||||||
|
docker load -i "${{PROMENADE_LOAD_IMAGE}}"
|
||||||
|
fi
|
||||||
|
|
||||||
|
docker pull quay.io/attcomdev/promenade:experimental
|
||||||
|
docker run -t --rm \
|
||||||
|
-v /:/target \
|
||||||
|
quay.io/attcomdev/promenade:experimental \
|
||||||
|
promenade \
|
||||||
|
-v \
|
||||||
|
join \
|
||||||
|
--hostname $(hostname) \
|
||||||
|
--config-path /target$(realpath $1)
|
||||||
|
touch /var/lib/prom.done
|
||||||
"""
|
"""
|
@ -214,7 +214,7 @@ class Machines(model_base.ResourceCollectionBase):
|
|||||||
maas_node = None
|
maas_node = None
|
||||||
|
|
||||||
if node_model.oob_type == 'ipmi':
|
if node_model.oob_type == 'ipmi':
|
||||||
node_oob_network = node_model.oob_network
|
node_oob_network = node_model.oob_parameters['network']
|
||||||
node_oob_ip = node_model.get_network_address(node_oob_network)
|
node_oob_ip = node_model.get_network_address(node_oob_network)
|
||||||
|
|
||||||
if node_oob_ip is None:
|
if node_oob_ip is None:
|
||||||
|
@ -15,6 +15,7 @@ import time
|
|||||||
import logging
|
import logging
|
||||||
|
|
||||||
from pyghmi.ipmi.command import Command
|
from pyghmi.ipmi.command import Command
|
||||||
|
from pyghmi.exceptions import IpmiException
|
||||||
|
|
||||||
import drydock_provisioner.config as config
|
import drydock_provisioner.config as config
|
||||||
import drydock_provisioner.error as errors
|
import drydock_provisioner.error as errors
|
||||||
@ -171,23 +172,8 @@ class PyghmiTaskRunner(drivers.DriverTaskRunner):
|
|||||||
"task node scope")
|
"task node scope")
|
||||||
|
|
||||||
|
|
||||||
ipmi_network = self.node.oob_network
|
|
||||||
ipmi_address = self.node.get_network_address(ipmi_network)
|
|
||||||
|
|
||||||
if ipmi_address is None:
|
|
||||||
self.orchestrator.task_field_update(self.task.get_id(),
|
|
||||||
result=hd_fields.ActionResult.Incomplete,
|
|
||||||
status=hd_fields.TaskStatus.Errored)
|
|
||||||
raise errors.DriverError("Node %s has no IPMI address" %
|
|
||||||
(target_node_name))
|
|
||||||
|
|
||||||
self.orchestrator.task_field_update(self.task.get_id(),
|
self.orchestrator.task_field_update(self.task.get_id(),
|
||||||
status=hd_fields.TaskStatus.Running)
|
status=hd_fields.TaskStatus.Running)
|
||||||
ipmi_account = self.node.oob_account
|
|
||||||
ipmi_credential = self.node.oob_credential
|
|
||||||
|
|
||||||
ipmi_session = Command(bmc=ipmi_address, userid=ipmi_account,
|
|
||||||
password=ipmi_credential)
|
|
||||||
|
|
||||||
if task_action == hd_fields.OrchestratorAction.ConfigNodePxe:
|
if task_action == hd_fields.OrchestratorAction.ConfigNodePxe:
|
||||||
self.orchestrator.task_field_update(self.task.get_id(),
|
self.orchestrator.task_field_update(self.task.get_id(),
|
||||||
@ -195,91 +181,124 @@ class PyghmiTaskRunner(drivers.DriverTaskRunner):
|
|||||||
status=hd_fields.TaskStatus.Complete)
|
status=hd_fields.TaskStatus.Complete)
|
||||||
return
|
return
|
||||||
elif task_action == hd_fields.OrchestratorAction.SetNodeBoot:
|
elif task_action == hd_fields.OrchestratorAction.SetNodeBoot:
|
||||||
ipmi_session.set_bootdev('pxe')
|
|
||||||
|
worked = False
|
||||||
|
|
||||||
|
self.logger.debug("Setting bootdev to PXE for %s" % self.node.name)
|
||||||
|
self.exec_ipmi_command(Command.set_bootdev, 'pxe')
|
||||||
|
|
||||||
time.sleep(3)
|
time.sleep(3)
|
||||||
|
|
||||||
bootdev = ipmi_session.get_bootdev()
|
bootdev = self.exec_ipmi_command(Command.get_bootdev)
|
||||||
|
|
||||||
if bootdev.get('bootdev', '') == 'network':
|
if bootdev.get('bootdev', '') == 'network':
|
||||||
|
self.logger.debug("%s reports bootdev of network" % self.node.name)
|
||||||
self.orchestrator.task_field_update(self.task.get_id(),
|
self.orchestrator.task_field_update(self.task.get_id(),
|
||||||
result=hd_fields.ActionResult.Success,
|
result=hd_fields.ActionResult.Success,
|
||||||
status=hd_fields.TaskStatus.Complete)
|
status=hd_fields.TaskStatus.Complete)
|
||||||
|
return
|
||||||
else:
|
else:
|
||||||
self.orchestrator.task_field_update(self.task.get_id(),
|
self.logger.warning("%s reports bootdev of %s" % (ipmi_address, bootdev.get('bootdev', None)))
|
||||||
|
worked = False
|
||||||
|
|
||||||
|
self.logger.error("Giving up on IPMI command to %s after 3 attempts" % self.node.name)
|
||||||
|
self.orchestrator.task_field_update(self.task.get_id(),
|
||||||
result=hd_fields.ActionResult.Failure,
|
result=hd_fields.ActionResult.Failure,
|
||||||
status=hd_fields.TaskStatus.Complete)
|
status=hd_fields.TaskStatus.Complete)
|
||||||
return
|
return
|
||||||
elif task_action == hd_fields.OrchestratorAction.PowerOffNode:
|
elif task_action == hd_fields.OrchestratorAction.PowerOffNode:
|
||||||
ipmi_session.set_power('off')
|
worked = False
|
||||||
|
|
||||||
|
self.logger.debug("Sending set_power = off command to %s" % self.node.name)
|
||||||
|
self.exec_ipmi_command(Command.set_power, 'off')
|
||||||
|
|
||||||
i = 18
|
i = 18
|
||||||
|
|
||||||
while i > 0:
|
while i > 0:
|
||||||
power_state = ipmi_session.get_power()
|
self.logger.debug("Polling powerstate waiting for success.")
|
||||||
|
power_state = self.exec_ipmi_command(Command.get_power)
|
||||||
if power_state.get('powerstate', '') == 'off':
|
if power_state.get('powerstate', '') == 'off':
|
||||||
|
self.logger.debug("Node reports powerstate of off")
|
||||||
|
worked = True
|
||||||
break
|
break
|
||||||
time.sleep(10)
|
time.sleep(10)
|
||||||
i = i - 1
|
i = i - 1
|
||||||
|
|
||||||
if power_state.get('powerstate', '') == 'off':
|
if worked:
|
||||||
self.orchestrator.task_field_update(self.task.get_id(),
|
self.orchestrator.task_field_update(self.task.get_id(),
|
||||||
result=hd_fields.ActionResult.Success,
|
result=hd_fields.ActionResult.Success,
|
||||||
status=hd_fields.TaskStatus.Complete)
|
status=hd_fields.TaskStatus.Complete)
|
||||||
else:
|
else:
|
||||||
|
self.logger.error("Giving up on IPMI command to %s" % self.node.name)
|
||||||
self.orchestrator.task_field_update(self.task.get_id(),
|
self.orchestrator.task_field_update(self.task.get_id(),
|
||||||
result=hd_fields.ActionResult.Failure,
|
result=hd_fields.ActionResult.Failure,
|
||||||
status=hd_fields.TaskStatus.Complete)
|
status=hd_fields.TaskStatus.Complete)
|
||||||
return
|
return
|
||||||
elif task_action == hd_fields.OrchestratorAction.PowerOnNode:
|
elif task_action == hd_fields.OrchestratorAction.PowerOnNode:
|
||||||
ipmi_session.set_power('on')
|
worked = False
|
||||||
|
|
||||||
|
self.logger.debug("Sending set_power = off command to %s" % self.node.name)
|
||||||
|
self.exec_ipmi_command(Command.set_power, 'off')
|
||||||
|
|
||||||
i = 18
|
i = 18
|
||||||
|
|
||||||
while i > 0:
|
while i > 0:
|
||||||
power_state = ipmi_session.get_power()
|
self.logger.debug("Polling powerstate waiting for success.")
|
||||||
if power_state.get('powerstate', '') == 'on':
|
power_state = self.exec_ipmi_command(Command.get_power)
|
||||||
|
if power_state.get('powerstate', '') == 'off':
|
||||||
|
self.logger.debug("Node reports powerstate of off")
|
||||||
|
worked = True
|
||||||
break
|
break
|
||||||
time.sleep(10)
|
time.sleep(10)
|
||||||
i = i - 1
|
i = i - 1
|
||||||
|
|
||||||
if power_state.get('powerstate', '') == 'on':
|
if worked:
|
||||||
self.orchestrator.task_field_update(self.task.get_id(),
|
self.orchestrator.task_field_update(self.task.get_id(),
|
||||||
result=hd_fields.ActionResult.Success,
|
result=hd_fields.ActionResult.Success,
|
||||||
status=hd_fields.TaskStatus.Complete)
|
status=hd_fields.TaskStatus.Complete)
|
||||||
else:
|
else:
|
||||||
|
self.logger.error("Giving up on IPMI command to %s" % self.node.name)
|
||||||
self.orchestrator.task_field_update(self.task.get_id(),
|
self.orchestrator.task_field_update(self.task.get_id(),
|
||||||
result=hd_fields.ActionResult.Failure,
|
result=hd_fields.ActionResult.Failure,
|
||||||
status=hd_fields.TaskStatus.Complete)
|
status=hd_fields.TaskStatus.Complete)
|
||||||
return
|
return
|
||||||
elif task_action == hd_fields.OrchestratorAction.PowerCycleNode:
|
elif task_action == hd_fields.OrchestratorAction.PowerCycleNode:
|
||||||
ipmi_session.set_power('off')
|
self.logger.debug("Sending set_power = off command to %s" % self.node.name)
|
||||||
|
self.exec_ipmi_command(Command.set_power, 'off')
|
||||||
|
|
||||||
# Wait for power state of off before booting back up
|
# Wait for power state of off before booting back up
|
||||||
# We'll wait for up to 3 minutes to power off
|
# We'll wait for up to 3 minutes to power off
|
||||||
i = 18
|
i = 18
|
||||||
|
|
||||||
while i > 0:
|
while i > 0:
|
||||||
power_state = ipmi_session.get_power()
|
power_state = self.exec_ipmi_command(Command.get_power)
|
||||||
if power_state.get('powerstate', '') == 'off':
|
if power_state is not None and power_state.get('powerstate', '') == 'off':
|
||||||
|
self.logger.debug("%s reports powerstate of off" % self.node.name)
|
||||||
break
|
break
|
||||||
|
elif power_state is None:
|
||||||
|
self.logger.debug("None response on IPMI power query to %s" % self.node.name)
|
||||||
time.sleep(10)
|
time.sleep(10)
|
||||||
i = i - 1
|
i = i - 1
|
||||||
|
|
||||||
if power_state.get('powerstate', '') == 'on':
|
if power_state.get('powerstate', '') == 'on':
|
||||||
|
self.logger.warning("Failed powering down node %s during power cycle task" % self.node.name)
|
||||||
self.orchestrator.task_field_update(self.task.get_id(),
|
self.orchestrator.task_field_update(self.task.get_id(),
|
||||||
result=hd_fields.ActionResult.Failure,
|
result=hd_fields.ActionResult.Failure,
|
||||||
status=hd_fields.TaskStatus.Complete)
|
status=hd_fields.TaskStatus.Complete)
|
||||||
return
|
return
|
||||||
|
|
||||||
ipmi_session.set_power('on')
|
self.logger.debug("Sending set_power = on command to %s" % self.node.name)
|
||||||
|
self.exec_ipmi_command(Command.set_power, 'on')
|
||||||
|
|
||||||
i = 18
|
i = 18
|
||||||
|
|
||||||
while i > 0:
|
while i > 0:
|
||||||
power_state = ipmi_session.get_power()
|
power_state = self.exec_ipmi_command(Command.get_power)
|
||||||
if power_state.get('powerstate', '') == 'on':
|
if power_state is not None and power_state.get('powerstate', '') == 'on':
|
||||||
|
self.logger.debug("%s reports powerstate of on" % self.node.name)
|
||||||
break
|
break
|
||||||
|
elif power_state is None:
|
||||||
|
self.logger.debug("None response on IPMI power query to %s" % self.node.name)
|
||||||
time.sleep(10)
|
time.sleep(10)
|
||||||
i = i - 1
|
i = i - 1
|
||||||
|
|
||||||
@ -288,6 +307,7 @@ class PyghmiTaskRunner(drivers.DriverTaskRunner):
|
|||||||
result=hd_fields.ActionResult.Success,
|
result=hd_fields.ActionResult.Success,
|
||||||
status=hd_fields.TaskStatus.Complete)
|
status=hd_fields.TaskStatus.Complete)
|
||||||
else:
|
else:
|
||||||
|
self.logger.warning("Failed powering up node %s during power cycle task" % self.node.name)
|
||||||
self.orchestrator.task_field_update(self.task.get_id(),
|
self.orchestrator.task_field_update(self.task.get_id(),
|
||||||
result=hd_fields.ActionResult.Failure,
|
result=hd_fields.ActionResult.Failure,
|
||||||
status=hd_fields.TaskStatus.Complete)
|
status=hd_fields.TaskStatus.Complete)
|
||||||
@ -299,4 +319,66 @@ class PyghmiTaskRunner(drivers.DriverTaskRunner):
|
|||||||
result=hd_fields.ActionResult.Success,
|
result=hd_fields.ActionResult.Success,
|
||||||
status=hd_fields.TaskStatus.Complete,
|
status=hd_fields.TaskStatus.Complete,
|
||||||
result_detail=mci_id)
|
result_detail=mci_id)
|
||||||
return
|
return
|
||||||
|
|
||||||
|
def get_ipmi_session(self):
|
||||||
|
"""
|
||||||
|
Initialize a Pyghmi IPMI session to this runner's self.node
|
||||||
|
|
||||||
|
:return: An instance of pyghmi.ipmi.command.Command initialized to nodes' IPMI interface
|
||||||
|
"""
|
||||||
|
|
||||||
|
node = self.node
|
||||||
|
|
||||||
|
if node.oob_type != 'ipmi':
|
||||||
|
raise errors.DriverError("Node OOB type is not IPMI")
|
||||||
|
|
||||||
|
ipmi_network = self.node.oob_parameters['network']
|
||||||
|
ipmi_address = self.node.get_network_address(ipmi_network)
|
||||||
|
|
||||||
|
if ipmi_address is None:
|
||||||
|
raise errors.DriverError("Node %s has no IPMI address" %
|
||||||
|
(node.name))
|
||||||
|
|
||||||
|
|
||||||
|
ipmi_account = self.node.oob_parameters['account']
|
||||||
|
ipmi_credential = self.node.oob_parameters['credential']
|
||||||
|
|
||||||
|
self.logger.debug("Starting IPMI session to %s with %s/%s" %
|
||||||
|
(ipmi_address, ipmi_account, ipmi_credential[:1]))
|
||||||
|
ipmi_session = Command(bmc=ipmi_address, userid=ipmi_account,
|
||||||
|
password=ipmi_credential)
|
||||||
|
|
||||||
|
return ipmi_session
|
||||||
|
|
||||||
|
def exec_ipmi_command(self, callable, *args):
|
||||||
|
"""
|
||||||
|
Call an IPMI command after establishing a session with this runner's node
|
||||||
|
|
||||||
|
:param callable: The pyghmi Command method to call
|
||||||
|
:param args: The args to pass the callable
|
||||||
|
"""
|
||||||
|
attempts = 0
|
||||||
|
while attempts < 5:
|
||||||
|
try:
|
||||||
|
self.logger.debug("Initializing IPMI session")
|
||||||
|
ipmi_session = self.get_ipmi_session()
|
||||||
|
except IpmiException as iex:
|
||||||
|
self.logger.error("Error initializing IPMI session for node %s" % self.node.name)
|
||||||
|
self.logger.debug("IPMI Exception: %s" % str(iex))
|
||||||
|
self.logger.warning("IPMI command failed, retrying after 15 seconds...")
|
||||||
|
time.sleep(15)
|
||||||
|
attempts = attempts + 1
|
||||||
|
continue
|
||||||
|
|
||||||
|
try:
|
||||||
|
self.logger.debug("Calling IPMI command %s on %s" % (callable.__name__, self.node.name))
|
||||||
|
response = callable(ipmi_session, *args)
|
||||||
|
ipmi_session.ipmi_session.logout()
|
||||||
|
return response
|
||||||
|
except IpmiException as iex:
|
||||||
|
self.logger.error("Error sending command: %s" % str(iex))
|
||||||
|
self.logger.warning("IPMI command failed, retrying after 15 seconds...")
|
||||||
|
time.sleep(15)
|
||||||
|
attempts = attempts + 1
|
||||||
|
|
||||||
|
@ -12,8 +12,10 @@
|
|||||||
# See the License for the specific language governing permissions and
|
# See the License for the specific language governing permissions and
|
||||||
# limitations under the License.
|
# limitations under the License.
|
||||||
import logging
|
import logging
|
||||||
from oslo_config import cfg
|
|
||||||
import sys
|
import sys
|
||||||
|
import os
|
||||||
|
|
||||||
|
from oslo_config import cfg
|
||||||
|
|
||||||
import drydock_provisioner.config as config
|
import drydock_provisioner.config as config
|
||||||
import drydock_provisioner.objects as objects
|
import drydock_provisioner.objects as objects
|
||||||
@ -35,7 +37,7 @@ def start_drydock():
|
|||||||
config.conf(sys.argv[1:])
|
config.conf(sys.argv[1:])
|
||||||
|
|
||||||
if config.conf.debug:
|
if config.conf.debug:
|
||||||
config.conf.logging.log_level = 'DEBUG'
|
config.conf.set_override(name='log_level', override='DEBUG', group='logging')
|
||||||
|
|
||||||
# Setup root logger
|
# Setup root logger
|
||||||
logger = logging.getLogger(config.conf.logging.global_logger_name)
|
logger = logging.getLogger(config.conf.logging.global_logger_name)
|
||||||
@ -63,6 +65,11 @@ def start_drydock():
|
|||||||
input_ingester = ingester.Ingester()
|
input_ingester = ingester.Ingester()
|
||||||
input_ingester.enable_plugins(config.conf.plugins.ingester)
|
input_ingester.enable_plugins(config.conf.plugins.ingester)
|
||||||
|
|
||||||
|
# Check if we have an API key in the environment
|
||||||
|
# Hack around until we move MaaS configs to the YAML schema
|
||||||
|
if 'MAAS_API_KEY' in os.environ:
|
||||||
|
config.conf.set_override(name='maas_api_key', override=os.environ['MAAS_API_KEY'], group='maasdriver')
|
||||||
|
|
||||||
# Now that loggers are configured, log the effective config
|
# Now that loggers are configured, log the effective config
|
||||||
config.conf.log_opt_values(logging.getLogger(config.conf.logging.global_logger_name), logging.DEBUG)
|
config.conf.log_opt_values(logging.getLogger(config.conf.logging.global_logger_name), logging.DEBUG)
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user