# Copyright 2016 Canonical Ltd. This software is licensed under the # GNU Affero General Public License version 3 (see the file LICENSE). """Manual Power Driver.""" __all__ = [] from twisted.internet.defer import maybeDeferred from provisioningserver.drivers.power import PowerDriver from provisioningserver.logger import get_maas_logger maaslog = get_maas_logger("drivers.power.manual") class ManualPowerDriver(PowerDriver): name = "manual" chassis = False can_probe = False description = "Manual" settings = [] ip_extractor = None queryable = False def detect_missing_packages(self): # no required packages return [] def on(self, system_id, context): """Override `on` as we do not need retry logic.""" return maybeDeferred(self.power_on, system_id, context)
# Copyright 2015-2016 Canonical Ltd. This software is licensed under the # GNU Affero General Public License version 3 (see the file LICENSE). """The subnet handler for the WebSocket connection.""" from netaddr import IPNetwork from maasserver.forms.subnet import SubnetForm from maasserver.models import Discovery, RackController, StaticRoute, Subnet from maasserver.models.subnet import get_allocated_ips from maasserver.permissions import NodePermission from maasserver.websockets.handlers.timestampedmodel import ( TimestampedModelHandler, ) from provisioningserver.logger import get_maas_logger from provisioningserver.utils.network import IPRangeStatistics maaslog = get_maas_logger("subnet") class SubnetHandler(TimestampedModelHandler): class Meta: queryset = (Subnet.objects.all().select_related( "vlan").prefetch_related("iprange_set")) pk = "id" form = SubnetForm form_requires_request = False allowed_methods = [ "create", "update", "delete", "get", "list",
# Copyright 2015 Canonical Ltd. This software is licensed under the # GNU Affero General Public License version 3 (see the file LICENSE). """Nova Power Driver.""" __all__ = [] from provisioningserver.drivers.power import PowerDriver from provisioningserver.utils import shell from provisioningserver.logger import get_maas_logger from novaclient import client REQUIRED_PACKAGES = [["nova", "python-novaclient"]] maaslog = get_maas_logger("drivers.power.nova") class NovaPowerDriver(PowerDriver): name = 'nova' description = "OpenStack nova Power Driver." settings = [] def _issue_nova_api(self, power_change, nova_id=None, os_projectname=None, os_username=None, os_password=None, os_authurl=None, os_project_domain_name=None, os_user_domain_name=None, **extra):
from maasserver.utils.curtin import ( curtin_supports_centos_curthook, curtin_supports_custom_storage, curtin_supports_custom_storage_for_dd, curtin_supports_webhook_events, ) from maasserver.utils.osystems import get_release_version_from_string from metadataserver.models import NodeKey from metadataserver.user_data.snippets import get_snippet_context from provisioningserver.drivers.osystem.ubuntu import UbuntuOS from provisioningserver.logger import get_maas_logger, LegacyLogger from provisioningserver.rpc.exceptions import NoConnectionsAvailable from provisioningserver.utils import typed from provisioningserver.utils.url import compose_URL maaslog = get_maas_logger("preseed") log = LegacyLogger() GENERIC_FILENAME = "generic" # Node operating systems which we can deploy with IPv6 networking. OS_WITH_IPv6_SUPPORT = ["ubuntu"] # The path to the Curtin installation log. Curtin uploads this file to MAAS # with its full path once the deployment is finished. CURTIN_INSTALL_LOG = "/tmp/install.log"
from maasserver.models.vlan import VLAN from maasserver.rpc import ( getAllClients, getClientFromIdentifiers, ) from maasserver.utils.orm import transactional from maasserver.utils.threads import deferToDatabase import petname from provisioningserver.drivers import SETTING_SCOPE from provisioningserver.drivers.pod import BlockDeviceType from provisioningserver.drivers.power.registry import PowerDriverRegistry from provisioningserver.logger import get_maas_logger from provisioningserver.utils.twisted import asynchronous from twisted.internet.defer import inlineCallbacks maaslog = get_maas_logger("node") podlog = get_maas_logger("pod") class BaseBMCManager(Manager): """A utility to manage the collection of BMCs.""" extra_filters = {} def get_queryset(self): queryset = QuerySet(self.model, using=self._db) return queryset.filter(**self.extra_filters) class BMCManager(BaseBMCManager): """Manager for `BMC` not `Pod`'s."""
__all__ = ["DiscoveryHandler"] from datetime import datetime import time from maasserver.models import Discovery from maasserver.permissions import NodePermission from maasserver.websockets.base import ( dehydrate_datetime, HandlerPermissionError, ) from maasserver.websockets.handlers.viewmodel import ViewModelHandler from provisioningserver.logger import get_maas_logger maaslog = get_maas_logger("websockets.discovery") class DiscoveryHandler(ViewModelHandler): class Meta: queryset = Discovery.objects.by_unknown_ip_and_mac() batch_key = "first_seen" pk = "discovery_id" allowed_methods = ["list", "get", "clear", "delete_by_mac_and_ip"] def list(self, params): """List objects. :param start: A value of the `batch_key` column and NOT `pk`. They are often the same but that is not a certainty. Make sure the client also understands this distinction.
MAASIPAddressField, MACAddressField, ) from maasserver.models.cleansave import CleanSave from maasserver.models.interface import Interface from maasserver.models.timestampedmodel import TimestampedModel from maasserver.utils.orm import ( get_one, MAASQueriesMixin, UniqueViolation, ) from provisioningserver.logger import get_maas_logger from provisioningserver.utils.network import get_mac_organization maaslog = get_maas_logger("neighbour") class NeighbourQueriesMixin(MAASQueriesMixin): def get_specifiers_q(self, specifiers, separator=':', **kwargs): # This dict is used by the constraints code to identify objects # with particular properties. Please note that changing the keys here # can impact backward compatibility, so use caution. specifier_types = { None: self._add_default_query, 'ip': "__ip", 'mac': "__mac_address", } return super(NeighbourQueriesMixin, self).get_specifiers_q( specifiers, specifier_types=specifier_types, separator=separator,
) from maasserver.utils.threads import deferToDatabase from metadataserver.builtin_scripts import load_builtin_scripts from provisioningserver.logger import ( get_maas_logger, LegacyLogger, ) from provisioningserver.utils.twisted import ( asynchronous, FOREVER, pause, ) from twisted.internet import reactor from twisted.internet.defer import inlineCallbacks maaslog = get_maas_logger("start-up") logger = logging.getLogger(__name__) log = LegacyLogger() @asynchronous(timeout=FOREVER) @inlineCallbacks def start_up(): """Perform start-up tasks for this MAAS server. This is used to: - make sure the singletons required by the application are created - sync the configuration of the external systems driven by MAAS The method will be executed multiple times if multiple processes are used but this method uses database locking to ensure that the methods it calls
from provisioningserver.logger import get_maas_logger from provisioningserver.refresh.maas_api_helper import ( capture_script_output, MD_VERSION, signal, SignalException, ) from provisioningserver.refresh.node_info_scripts import NODE_INFO_SCRIPTS from provisioningserver.utils.shell import ( call_and_check, ExternalProcessError, ) from provisioningserver.utils.twisted import synchronous from provisioningserver.utils.version import get_maas_version maaslog = get_maas_logger("refresh") def get_architecture(): """Get the architecture of the running system.""" try: stdout = call_and_check('archdetect').decode('utf-8') except ExternalProcessError: return '' arch, subarch = stdout.strip().split('/') if arch in ['i386', 'amd64', 'arm64', 'ppc64el']: subarch = 'generic' return '%s/%s' % (arch, subarch) def get_os_release():
from provisioningserver.logger import get_maas_logger, LegacyLogger from provisioningserver.rpc import getRegionClient from provisioningserver.rpc.exceptions import ( NoSuchNode, PowerActionAlreadyInProgress, PowerActionFail, ) from provisioningserver.rpc.region import MarkNodeFailed, UpdateNodePowerState from provisioningserver.utils.twisted import ( asynchronous, callOut, deferred, deferWithTimeout, ) maaslog = get_maas_logger("power") log = LegacyLogger() # Timeout for change_power_state(). We set it to 5 minutes by default, # but it would be lovely if this was configurable. This is only a backstop # meant to cope with broken BMCs. CHANGE_POWER_STATE_TIMEOUT = timedelta(minutes=5).total_seconds() # We could use a Registry here, but it seems kind of like overkill. power_action_registry = {} @asynchronous def power_state_update(system_id, state): """Report to the region about a node's power state.
PROTECT, TextField, ) from maasserver import DefaultMeta from maasserver.enum import ENDPOINT, ENDPOINT_CHOICES from maasserver.models.cleansave import CleanSave from maasserver.models.eventtype import EventType from maasserver.models.node import Node from maasserver.models.timestampedmodel import TimestampedModel from maasserver.utils.dns import validate_hostname from provisioningserver.events import EVENT_DETAILS from provisioningserver.logger import get_maas_logger from provisioningserver.utils.env import get_maas_id maaslog = get_maas_logger("models.event") class EventManager(Manager): """A utility to manage the collection of Events.""" def register_event_and_event_type( self, type_name, type_description="", type_level=logging.INFO, event_action="", event_description="", system_id=None, user=None, ip_address=None, endpoint=ENDPOINT.API,
# Copyright 2014-2016 Canonical Ltd. This software is licensed under the # GNU Affero General Public License version 3 (see the file LICENSE). """API logger.""" __all__ = ["maaslog"] from provisioningserver.logger import get_maas_logger maaslog = get_maas_logger("api")
) from maasserver.utils.orm import transactional from maasserver.utils.threads import deferToDatabase from metadataserver.enum import SCRIPT_STATUS from metadataserver.models import ( Script, ScriptResult, ScriptSet, ) from provisioningserver.logger import get_maas_logger from provisioningserver.refresh.node_info_scripts import NODE_INFO_SCRIPTS from provisioningserver.utils.twisted import synchronous from twisted.application.internet import TimerService maaslog = get_maas_logger("node") def mark_nodes_failed_after_expiring(): """Mark all nodes in that database as failed where the status did not transition in time. `status_expires` is checked on the node to see if the current time is newer than the expired time. """ current_db_time = now() expired_nodes = Node.objects.filter( status__in=NODE_FAILURE_MONITORED_STATUS_TRANSITIONS.keys(), status_expires__isnull=False, status_expires__lte=current_db_time) for node in expired_nodes: maaslog.info("%s: Operation '%s' timed out after %s minutes." % ( node.hostname,
__all__ = ["UEFIAMD64BootMethod"] from itertools import repeat import os import re from textwrap import dedent from provisioningserver.boot import BootMethod, BytesReader, get_parameters from provisioningserver.events import EVENT_TYPES, try_send_rack_event from provisioningserver.kernel_opts import compose_kernel_command_line from provisioningserver.logger import get_maas_logger from provisioningserver.utils import typed from provisioningserver.utils.fs import atomic_symlink maaslog = get_maas_logger("uefi_amd64") CONFIG_FILE = dedent(""" # MAAS GRUB2 pre-loader configuration file # Load based on MAC address first. configfile (pxe)/grub/grub.cfg-${net_default_mac} # Failed to load based on MAC address. # Load amd64 by default, UEFI only supported by 64-bit configfile (pxe)/grub/grub.cfg-default-amd64 """) # GRUB EFINET represents a MAC address in IEEE 802 colon-seperated # format. Required for UEFI as GRUB2 only presents the MAC address # in colon-seperated format.
# Copyright 2015 Canonical Ltd. This software is licensed under the # GNU Affero General Public License version 3 (see the file LICENSE). """Nova Power Driver.""" __all__ = [] from provisioningserver.drivers.power import PowerDriver from provisioningserver.utils import shell from provisioningserver.logger import get_maas_logger from novaclient import client REQUIRED_PACKAGES = [["nova", "python-novaclient"]] maaslog = get_maas_logger("drivers.power.nova") class NovaPowerDriver(PowerDriver): name = 'nova' description = "OpenStack nova Power Driver." settings = [] def _issue_nova_api( self, power_change, nova_id=None, os_tenantname=None, os_username=None, os_password=None, os_authurl=None, **extra): nova = client.Client(2,os_username, os_password, os_tenantname, os_authurl)
RegisterEventType, SendEvent, SendEventIPAddress, SendEventMACAddress, ) from provisioningserver.utils.env import get_maas_id from provisioningserver.utils.twisted import ( asynchronous, callOut, DeferredValue, FOREVER, suppress, ) from twisted.internet.defer import maybeDeferred, succeed maaslog = get_maas_logger("events") log = LegacyLogger() # AUDIT event logging level AUDIT = 0 class EVENT_TYPES: # Power-related events. NODE_POWER_ON_STARTING = "NODE_POWER_ON_STARTING" NODE_POWER_OFF_STARTING = "NODE_POWER_OFF_STARTING" NODE_POWER_CYCLE_STARTING = "NODE_POWER_CYCLE_STARTING" NODE_POWERED_ON = "NODE_POWERED_ON" NODE_POWERED_OFF = "NODE_POWERED_OFF" NODE_POWER_ON_FAILED = "NODE_POWER_ON_FAILED" NODE_POWER_OFF_FAILED = "NODE_POWER_OFF_FAILED"
import os import os.path import re import sys from provisioningserver.logger import get_maas_logger from provisioningserver.utils import ( locate_config, locate_template, ) from provisioningserver.utils.fs import atomic_write from provisioningserver.utils.isc import read_isc_file from provisioningserver.utils.shell import call_and_check import tempita maaslog = get_maas_logger("dns") NAMED_CONF_OPTIONS = 'named.conf.options' MAAS_NAMED_CONF_NAME = 'named.conf.maas' MAAS_NAMED_CONF_OPTIONS_INSIDE_NAME = 'named.conf.options.inside.maas' MAAS_NAMED_RNDC_CONF_NAME = 'named.conf.rndc.maas' MAAS_RNDC_CONF_NAME = 'rndc.conf.maas' def get_dns_config_dir(): """Location of MAAS' bind configuration files.""" setting = os.getenv("MAAS_DNS_CONFIG_DIR", locate_config(os.path.pardir, "bind", "maas")) if isinstance(setting, bytes): fsenc = sys.getfilesystemencoding() return setting.decode(fsenc) else:
from provisioningserver.logger import get_maas_logger from provisioningserver.refresh.node_info_scripts import LXD_OUTPUT_NAME from provisioningserver.rpc.exceptions import PodInvalidResources from provisioningserver.utils import ( debian_to_kernel_architecture, kernel_to_debian_architecture, typed, ) from provisioningserver.utils.lxd import lxd_cpu_speed from provisioningserver.utils.network import generate_mac_address from provisioningserver.utils.twisted import asynchronous, threadDeferred # silence warnings from pylxd because of unverified certs for HTTPS connection urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning) maaslog = get_maas_logger("drivers.pod.lxd") LXD_MAAS_PROFILE = "maas" # Configuration for LXD project created by MAAS itself # # By default don't enable per-project images and storage, since those require # setting up at least one storage pool so that VMs can be created. Users can # change those settings later without affecting MAAS functionality. LXD_MAAS_PROJECT_CONFIG = { "description": "Project managed by MAAS", "config": { "features.images": "false", "features.profiles": "true", "features.storage.volumes": "false", },
] from tempfile import NamedTemporaryFile from lxml import etree import pexpect from provisioningserver.logger import get_maas_logger from provisioningserver.rpc.utils import ( commission_node, create_node, ) from provisioningserver.utils import typed from provisioningserver.utils.shell import select_c_utf8_locale from provisioningserver.utils.twisted import synchronous maaslog = get_maas_logger("drivers.virsh") XPATH_ARCH = "/domain/os/type/@arch" XPATH_BOOT = "/domain/os/boot" XPATH_OS = "/domain/os" # Virsh stores the architecture with a different # label then MAAS. This maps virsh architecture to # MAAS architecture. ARCH_FIX = { 'x86_64': 'amd64', 'ppc64': 'ppc64el', 'ppc64le': 'ppc64el', 'i686': 'i386', }
from provisioningserver.tags import ( DEFAULT_BATCH_SIZE, gen_batches, merge_details, ) from provisioningserver.utils import classify from provisioningserver.utils.twisted import ( asynchronous, FOREVER, synchronous, ) from provisioningserver.utils.xpath import try_match_xpath from twisted.internet.defer import DeferredList maaslog = get_maas_logger("tags") log = LegacyLogger() # The nsmap that XPath expression must be compiled with. This will # ensure that expressions like //lshw:something will work correctly. tag_nsmap = { namespace: namespace for namespace in script_output_nsmap.values() } def chunk_list(items, num_chunks): """Split `items` into (at most) `num_chunks` lists. Every chunk will have at least one element in its list, which may
DiscoveredMachine, DiscoveredPod, DiscoveredPodHints, get_error_message, ) from provisioningserver.drivers.pod.registry import PodDriverRegistry from provisioningserver.logger import get_maas_logger, LegacyLogger from provisioningserver.refresh.maas_api_helper import signal, SignalException from provisioningserver.rpc.exceptions import ( PodActionFail, PodInvalidResources, UnknownPodType, ) from provisioningserver.utils.twisted import asynchronous maaslog = get_maas_logger("pod") log = LegacyLogger() @asynchronous def discover_pod(pod_type, context, pod_id=None, name=None): """Discover all the pod information and return the result to the region controller. The region controller handles parsing the output and updating the database as required. """ pod_driver = PodDriverRegistry.get_item(pod_type) if pod_driver is None: raise UnknownPodType(pod_type) try:
'BMC busy': { 'message': ( "Device busy while performing power action." " MAAS performed several retries. Please wait and try again."), 'exception': PowerConnError }, 'could not find inband device': { 'message': ( "An inband device could not be found." " Check BMC configuration and try again."), 'exception': PowerSettingError }, } maaslog = get_maas_logger("drivers.power.ipmi") class IPMI_DRIVER: DEFAULT = '' LAN = 'LAN' LAN_2_0 = 'LAN_2_0' IPMI_DRIVER_CHOICES = [ [IPMI_DRIVER.LAN, "LAN [IPMI 1.5]"], [IPMI_DRIVER.LAN_2_0, "LAN_2_0 [IPMI 2.0]"], ] class IPMIPowerDriver(PowerDriver):
CannotModifyHostMap, CannotRemoveHostMap, ) from provisioningserver.service_monitor import service_monitor from provisioningserver.utils.fs import sudo_delete_file, sudo_write_file from provisioningserver.utils.service_monitor import ( SERVICE_STATE, ServiceActionError, ) from provisioningserver.utils.shell import call_and_check, ExternalProcessError from provisioningserver.utils.text import split_string_list from provisioningserver.utils.twisted import asynchronous, synchronous from twisted.internet.defer import inlineCallbacks, maybeDeferred from twisted.internet.threads import deferToThread maaslog = get_maas_logger("dhcp") log = LegacyLogger() # Holds the current state of DHCPv4 and DHCPv6. _current_server_state = {} DHCPStateBase = namedtuple( "DHCPStateBase", [ "omapi_key", "failover_peers", "shared_networks", "hosts", "interfaces", "global_dhcp_snippets", ],
# Copyright 2015-2017 Canonical Ltd. This software is licensed under the # GNU Affero General Public License version 3 (see the file LICENSE). """Version utilities.""" from collections import namedtuple from contextlib import suppress from functools import lru_cache import re import pkg_resources from provisioningserver.logger import get_maas_logger from provisioningserver.utils import shell, snappy maaslog = get_maas_logger("version") # the first requirement is always the required package itself DEFAULT_PARSED_VERSION = pkg_resources.require("maas")[0].parsed_version DEFAULT_VERSION = str(DEFAULT_PARSED_VERSION) # Only import apt_pkg and initialize when not running in a snap. if not snappy.running_in_snap(): import apt_pkg apt_pkg.init() # Name of maas package to get version from. REGION_PACKAGE_NAME = "maas-region-api" RACK_PACKAGE_NAME = "maas-rack-controller"
"get_maas_version_subversion", "get_maas_version_ui", "MAASVersion", ] from collections import namedtuple from functools import lru_cache import re from provisioningserver.logger import get_maas_logger from provisioningserver.utils import ( shell, snappy, ) maaslog = get_maas_logger('version') DEFAULT_VERSION = "2.5.0" # Only import apt_pkg and initialize when not running in a snap. if not snappy.running_in_snap(): import apt_pkg apt_pkg.init() # Name of maas package to get version from. REGION_PACKAGE_NAME = "maas-region-api" RACK_PACKAGE_NAME = "maas-rack-controller" def get_version_from_apt(*packages): """Return the version output from `apt_pkg.Cache` for the given package(s),
"""ControllerInfo objects.""" from collections import namedtuple from django.db.models import CASCADE, CharField, Manager, OneToOneField from maasserver import DefaultMeta from maasserver.enum import NODE_TYPE from maasserver.fields import JSONObjectField from maasserver.models.cleansave import CleanSave from maasserver.models.node import Node from maasserver.models.timestampedmodel import TimestampedModel from provisioningserver.logger import get_maas_logger from provisioningserver.utils.version import get_version_tuple maaslog = get_maas_logger("controllerinfo") _ControllerVersionInfo = namedtuple( "ControllerVersionInfo", ("hostname", "system_id", "version", "maasversion"), ) class ControllerVersionInfo(_ControllerVersionInfo): @property def comparable_version(self): return self.maasversion[0:6] def difference(self, other): v1 = self.comparable_version v2 = other.comparable_version
from maasserver.exceptions import NodeActionError from maasserver.forms import DeviceForm, DeviceWithMACsForm from maasserver.forms.interface import InterfaceForm, PhysicalInterfaceForm from maasserver.models.interface import Interface from maasserver.models.node import Device from maasserver.models.staticipaddress import StaticIPAddress from maasserver.models.subnet import Subnet from maasserver.node_action import compile_node_actions from maasserver.permissions import NodePermission from maasserver.utils.orm import reload_object from maasserver.websockets.base import HandlerError, HandlerValidationError from maasserver.websockets.handlers.node import NodeHandler from netaddr import EUI from provisioningserver.logger import get_maas_logger maaslog = get_maas_logger("websockets.device") def get_Interface_from_list(interfaces, mac): """Return the `Interface` object with the given MAC address.""" # Compare using EUI instances so that we're not concerned with a MAC's # canonical form, i.e. colons versus hyphens, uppercase versus lowercase. mac = EUI(mac) for interface in interfaces: ifmac = interface.mac_address if ifmac is not None and EUI(ifmac.raw) == mac: return interface else: return None
GetBootSourcesV2, GetProxies, ) from provisioningserver.utils.twisted import ( pause, retries, ) from twisted.application.internet import TimerService from twisted.internet.defer import ( inlineCallbacks, returnValue, ) from twisted.protocols.amp import UnhandledCommand maaslog = get_maas_logger("boot_image_download_service") log = LegacyLogger() class ImageDownloadService(TimerService, object): """Twisted service to periodically refresh ephemeral images.""" check_interval = timedelta(minutes=5).total_seconds() def __init__(self, client_service, tftp_root, reactor): """Twisted service to periodically refresh ephemeral images. :param client_service: A `ClusterClientService` instance. :param tftp_root: The path to the TFTP root directory. :param reactor: An `IReactor` instance. """
__all__ = ["ServiceMonitorService"] from datetime import timedelta from twisted.application.internet import TimerService from twisted.internet.defer import inlineCallbacks from provisioningserver.config import is_dev_environment from provisioningserver.logger import get_maas_logger, LegacyLogger from provisioningserver.rpc.exceptions import NoConnectionsAvailable from provisioningserver.rpc.region import UpdateServices from provisioningserver.service_monitor import service_monitor from provisioningserver.utils.twisted import pause, retries maaslog = get_maas_logger("service_monitor_service") log = LegacyLogger() class ServiceMonitorService(TimerService, object): """Service to monitor external services that the cluster requires.""" # Services that we don't perform any checks on at the moment and we # always considered working as since they run in the same process as rackd. # "rackd" should not show in this list as the region controller handles # updating the status of "rackd". This is because its status all depends # on the connections across the multiple regions. ALWAYS_RUNNING_SERVICES = [{ "name": "tftp", "status": "running", "status_info": ""
import http.client import json import time import urllib.error import urllib.parse import urllib.request from seamicroclient import exceptions as seamicro_exceptions from seamicroclient.v2 import client as seamicro_client from provisioningserver.logger import get_maas_logger from provisioningserver.rpc.utils import commission_node, create_node from provisioningserver.utils.twisted import synchronous from provisioningserver.utils.url import compose_URL maaslog = get_maas_logger("drivers.seamicro") class POWER_STATUS: ON = "Power-On" OFF = "Power-Off" RESET = "Reset" class SeaMicroError(Exception): """Failure talking to a SeaMicro chassis controller. """ pass class SeaMicroAPIV09Error(SeaMicroError):
from provisioningserver.boot import BootMethodRegistry from provisioningserver.drivers import ArchitectureRegistry from provisioningserver.drivers.osystem import OperatingSystemRegistry from provisioningserver.events import EVENT_TYPES, send_node_event_ip_address from provisioningserver.kernel_opts import KernelParameters from provisioningserver.logger import get_maas_logger, LegacyLogger from provisioningserver.prometheus.metrics import PROMETHEUS_METRICS from provisioningserver.rpc.boot_images import list_boot_images from provisioningserver.rpc.exceptions import BootConfigNoResponse from provisioningserver.rpc.region import GetBootConfig, MarkNodeFailed from provisioningserver.utils import network, tftp, typed from provisioningserver.utils.network import get_all_interface_addresses from provisioningserver.utils.tftp import TFTPPath from provisioningserver.utils.twisted import deferred, RPCFetcher maaslog = get_maas_logger("tftp") log = LegacyLogger() def get_boot_image(params): """Get the boot image for the params on this rack controller.""" # Match on purpose; enlist uses the commissioning purpose. purpose = params["purpose"] if purpose == "enlist": purpose = "commissioning" # Get the matching boot images, minus subarchitecture. boot_images = list_boot_images() boot_images = [ image for image in boot_images
__all__ = [] import json import requests from provisioningserver.drivers.power import ( PowerAuthError, PowerDriver, PowerError, PowerFatalError, PowerToolError, ) from provisioningserver.logger import get_maas_logger maaslog = get_maas_logger("drivers.power.pipower") HEADERS = {'Content-Type': 'application/json'} OFF = 'off' ON = 'on' class PIPowerPowerDriver(PowerDriver): name = 'pipower' description = 'Raspberry Pi Power Driver' settings = [] def detect_missing_packages(self): """Detects any missing packages required""" return []