cloudstack-issues mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "ASF GitHub Bot (JIRA)" <j...@apache.org>
Subject [jira] [Commented] (CLOUDSTACK-9299) Out-of-band Management for CloudStack
Date Mon, 02 May 2016 22:36:13 GMT

    [ https://issues.apache.org/jira/browse/CLOUDSTACK-9299?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=15267642#comment-15267642
] 

ASF GitHub Bot commented on CLOUDSTACK-9299:
--------------------------------------------

Github user jburwell commented on a diff in the pull request:

    https://github.com/apache/cloudstack/pull/1502#discussion_r61816897
  
    --- Diff: test/integration/smoke/test_outofbandmanagement.py ---
    @@ -0,0 +1,561 @@
    +# Licensed to the Apache Software Foundation (ASF) under one
    +# or more contributor license agreements.  See the NOTICE file
    +# distributed with this work for additional information
    +# regarding copyright ownership.  The ASF licenses this file
    +# to you 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 marvin
    +from marvin.cloudstackTestCase import *
    +from marvin.cloudstackAPI import *
    +from marvin.lib.utils import *
    +from marvin.lib.base import *
    +from marvin.lib.common import *
    +from marvin.lib.utils import (random_gen)
    +from nose.plugins.attrib import attr
    +
    +from ipmisim.ipmisim import IpmiServerContext, IpmiServer, ThreadedIpmiServer
    +
    +import socket
    +import sys
    +import thread
    +import time
    +
    +
    +class TestOutOfBandManagement(cloudstackTestCase):
    +    """ Test cases for out of band management
    +    """
    +
    +    def setUp(self):
    +        self.apiclient = self.testClient.getApiClient()
    +        self.hypervisor = self.testClient.getHypervisorInfo()
    +        self.dbclient = self.testClient.getDbConnection()
    +        self.services = self.testClient.getParsedTestDataConfig()
    +        self.mgtSvrDetails = self.config.__dict__["mgtSvr"][0].__dict__
    +
    +        self.zone = get_zone(self.apiclient, self.testClient.getZoneForTests())
    +        self.host = None
    +        self.server = None
    +
    +        # use random port for ipmisim
    +        s = socket.socket()
    +        s.bind(('', 0))
    +        self.serverPort = s.getsockname()[1]
    +        s.close()
    +
    +        self.cleanup = []
    +
    +
    +    def tearDown(self):
    +        try:
    +            self.dbclient.execute("delete from oobm where port=%d" % self.getIpmiServerPort())
    +            self.dbclient.execute("delete from mshost_peer where peer_runid=%s" % self.getFakeMsRunId())
    +            self.dbclient.execute("delete from mshost where runid=%s" % self.getFakeMsRunId())
    +            self.dbclient.execute("delete from cluster_details where name='outOfBandManagementEnabled'")
    +            self.dbclient.execute("delete from data_center_details where name='outOfBandManagementEnabled'")
    +            cleanup_resources(self.apiclient, self.cleanup)
    +            if self.server:
    +                self.server.shutdown()
    +                self.server.server_close()
    +        except Exception as e:
    +            raise Exception("Warning: Exception during cleanup : %s" % e)
    +
    +
    +    def getFakeMsId(self):
    +        return 1234567890
    +
    +
    +    def getFakeMsRunId(self):
    +        return 123456
    +
    +
    +    def getHost(self, hostId=None):
    +        if self.host and hostId is None:
    +            return self.host
    +
    +        response = list_hosts(
    +                        self.apiclient,
    +                        zoneid=self.zone.id,
    +                        type='Routing',
    +                        id=hostId
    +                        )
    +        if len(response) > 0:
    +            self.host = response[0]
    +            return self.host
    +        raise self.skipTest("No hosts found, skipping out-of-band management test")
    +
    +
    +    def getIpmiServerIp(self):
    +        s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
    +        s.connect((self.mgtSvrDetails["mgtSvrIp"], self.mgtSvrDetails["port"]))
    +        return s.getsockname()[0]
    +
    +
    +    def getIpmiServerPort(self):
    +        return self.serverPort
    +
    +
    +    def getOobmConfigCmd(self):
    +        cmd = configureOutOfBandManagement.configureOutOfBandManagementCmd()
    +        cmd.driver = 'ipmitool' # The default available driver
    +        cmd.address = self.getIpmiServerIp()
    +        cmd.port = self.getIpmiServerPort()
    +        cmd.username = 'admin'
    +        cmd.password = 'password'
    +        cmd.hostid = self.getHost().id
    +        return cmd
    +
    +
    +    def getOobmEnableCmd(self):
    +        cmd = enableOutOfBandManagementForHost.enableOutOfBandManagementForHostCmd()
    +        cmd.hostid = self.getHost().id
    +        return cmd
    +
    +
    +    def getOobmDisableCmd(self):
    +        cmd = disableOutOfBandManagementForHost.disableOutOfBandManagementForHostCmd()
    +        cmd.hostid = self.getHost().id
    +        return cmd
    +
    +
    +    def getOobmIssueActionCmd(self):
    +        cmd = issueOutOfBandManagementPowerAction.issueOutOfBandManagementPowerActionCmd()
    +        cmd.hostid = self.getHost().id
    +        cmd.action = 'STATUS'
    +        return cmd
    +
    +
    +    def issuePowerActionCmd(self, action, timeout=None):
    +        cmd = self.getOobmIssueActionCmd()
    +        cmd.action = action
    +        if timeout:
    +            cmd.timeout = timeout
    +        return self.apiclient.issueOutOfBandManagementPowerAction(cmd)
    +
    +
    +    def configureAndEnableOobm(self):
    +        self.apiclient.configureOutOfBandManagement(self.getOobmConfigCmd())
    +        response = self.apiclient.enableOutOfBandManagementForHost(self.getOobmEnableCmd())
    +        self.assertEqual(response.enabled, True)
    +
    +
    +    def startIpmiServer(self):
    +        def startIpmiServer(tname, server):
    +            self.debug("Starting ipmisim server")
    +            try:
    +                server.serve_forever()
    +            except Exception: pass
    +        IpmiServerContext('reset')
    +        ThreadedIpmiServer.allow_reuse_address = False
    +        server = ThreadedIpmiServer(('0.0.0.0', self.getIpmiServerPort()), IpmiServer)
    +        thread.start_new_thread(startIpmiServer, ("ipmi-server", server,))
    +        self.server = server
    +
    +
    +    def checkSyncToState(self, state, interval):
    +        self.debug("Waiting for background thread to update powerstate to " + state)
    +        time.sleep(1 + int(interval)*2/1000) # interval is in ms
    +        response = self.getHost(hostId=self.getHost().id).outofbandmanagement
    +        self.assertEqual(response.powerstate, state)
    +
    +
    +    @attr(tags=["smoke", "advanced"])
    +    def test_oobm_configure_invalid_driver(self):
    +        """
    +            Tests out-of-band management configuration with invalid driver
    +        """
    +        cmd = self.getOobmConfigCmd()
    +        cmd.driver = 'randomDriverThatDoesNotExist'
    +        try:
    +            response = self.apiclient.configureOutOfBandManagement(cmd)
    +            self.fail("Expected an exception to be thrown, failing")
    +        except Exception: pass
    +
    +
    +    @attr(tags=["smoke", "advanced"])
    +    def test_oobm_configure_default_driver(self):
    +        """
    +            Tests out-of-band management configuration with valid data
    +        """
    +        cmd = self.getOobmConfigCmd()
    +        response = self.apiclient.configureOutOfBandManagement(cmd)
    +        self.assertEqual(response.hostid, cmd.hostid)
    +        self.assertEqual(response.driver, cmd.driver)
    +        self.assertEqual(response.address, cmd.address)
    +        self.assertEqual(response.port, str(cmd.port))
    +        self.assertEqual(response.username, cmd.username)
    +
    +
    +    @attr(tags=["smoke", "advanced"])
    +    def test_oobm_enable_feature_invalid(self):
    +        """
    +            Tests out-of-band management host enable feature with
    +            invalid options
    +        """
    +        cmd = self.getOobmEnableCmd()
    +        cmd.hostid = -1
    +        try:
    +            response = self.apiclient.enableOutOfBandManagementForHost(cmd)
    +            self.fail("Expected an exception to be thrown, failing")
    +        except Exception: pass
    +
    +        try:
    +            cmd = enableOutOfBandManagementForCluster.enableOutOfBandManagementForClusterCmd()
    +            response = self.apiclient.enableOutOfBandManagementForCluster(cmd)
    +            self.fail("Expected an exception to be thrown, failing")
    +        except Exception: pass
    +
    +        try:
    +            cmd = enableOutOfBandManagementForZone.enableOutOfBandManagementForZoneCmd()
    +            response = self.apiclient.enableOutOfBandManagementForZone(cmd)
    +            self.fail("Expected an exception to be thrown, failing")
    +        except Exception: pass
    +
    +
    +    @attr(tags=["smoke", "advanced"])
    +    def test_oobm_disable_feature_invalid(self):
    +        """
    +            Tests out-of-band management host disable feature with
    +            invalid options
    +        """
    +        cmd = self.getOobmDisableCmd()
    +        cmd.hostid = -1
    +        try:
    +            response = self.apiclient.disableOutOfBandManagementForHost(cmd)
    +            self.fail("Expected an exception to be thrown, failing")
    +        except Exception: pass
    +
    +        try:
    +            cmd = disableOutOfBandManagementForCluster.disableOutOfBandManagementForClusterCmd()
    +            response = self.apiclient.disableOutOfBandManagementForCluster(cmd)
    +            self.fail("Expected an exception to be thrown, failing")
    +        except Exception: pass
    +
    +        try:
    +            cmd = disableOutOfBandManagementForZone.disableOutOfBandManagementForZoneCmd()
    +            response = self.apiclient.disableOutOfBandManagementForZone(cmd)
    +            self.fail("Expected an exception to be thrown, failing")
    +        except Exception: pass
    +
    +
    +    @attr(tags=["smoke", "advanced"])
    +    def test_oobm_enable_feature_valid(self):
    +        """
    +            Tests out-of-band management host enable feature with
    +            valid options
    +        """
    +        self.apiclient.configureOutOfBandManagement(self.getOobmConfigCmd())
    +        cmd = self.getOobmEnableCmd()
    +        response = self.apiclient.enableOutOfBandManagementForHost(cmd)
    +        self.assertEqual(response.hostid, cmd.hostid)
    +        self.assertEqual(response.enabled, True)
    +
    +
    +    @attr(tags=["smoke", "advanced"])
    +    def test_oobm_disable_feature_valid(self):
    +        """
    +            Tests out-of-band management host disable feature with
    +            valid options
    +        """
    +
    +        self.apiclient.configureOutOfBandManagement(self.getOobmConfigCmd())
    +        cmd = self.getOobmDisableCmd()
    +        response = self.apiclient.disableOutOfBandManagementForHost(cmd)
    +        self.assertEqual(response.hostid, cmd.hostid)
    +        self.assertEqual(response.enabled, False)
    +
    +        response = self.getHost(hostId=cmd.hostid).outofbandmanagement
    +        self.assertEqual(response.powerstate, 'Disabled')
    +
    +
    +    @attr(tags=["smoke", "advanced"])
    +    def test_oobm_enabledisable_across_clusterzones(self):
    +        """
    +            Tests out-of-band management enable/disable feature at cluster
    +            and zone level sequentially Zone > Cluster > Host
    +        """
    +        self.configureAndEnableOobm()
    +        self.startIpmiServer()
    +        bmc = IpmiServerContext().bmc
    +        bmc.powerstate = 'off'
    +
    +        host = self.getHost()
    +
    +        # Disable at zone level
    +        cmd = disableOutOfBandManagementForZone.disableOutOfBandManagementForZoneCmd()
    +        cmd.zoneid = host.zoneid
    +        response = self.apiclient.disableOutOfBandManagementForZone(cmd)
    +
    +        # Disable at cluster level
    +        cmd = disableOutOfBandManagementForCluster.disableOutOfBandManagementForClusterCmd()
    +        cmd.clusterid = host.clusterid
    +        response = self.apiclient.disableOutOfBandManagementForCluster(cmd)
    +
    +        # Disable at host level
    +        cmd = disableOutOfBandManagementForHost.disableOutOfBandManagementForHostCmd()
    +        cmd.hostid = host.id
    +        response = self.apiclient.disableOutOfBandManagementForHost(cmd)
    +
    +        try:
    +            self.issuePowerActionCmd('STATUS')
    +            self.fail("Exception was expected, oobm is disabled at zone level")
    +        except Exception: pass
    +
    +        # Enable at zone level
    +        cmd = enableOutOfBandManagementForZone.enableOutOfBandManagementForZoneCmd()
    +        cmd.zoneid = host.zoneid
    +        response = self.apiclient.enableOutOfBandManagementForZone(cmd)
    +
    +        try:
    +            self.issuePowerActionCmd('STATUS')
    +            self.fail("Exception was expected, oobm is disabled at cluster level")
    +        except Exception: pass
    +
    +        # Check background thread syncs state to Disabled
    +        response = self.getHost(hostId=host.id).outofbandmanagement
    +        self.assertEqual(response.powerstate, 'Disabled')
    +        self.dbclient.execute("update oobm set power_state='On' where port=%d" % self.getIpmiServerPort())
    +        interval = list_configurations(
    +            self.apiclient,
    +            name='outofbandmanagement.sync.interval'
    +        )[0].value
    +        self.checkSyncToState('Disabled', interval)
    +
    +        # Enable at cluster level
    +        cmd = enableOutOfBandManagementForCluster.enableOutOfBandManagementForClusterCmd()
    +        cmd.clusterid = host.clusterid
    +        response = self.apiclient.enableOutOfBandManagementForCluster(cmd)
    +
    +        try:
    +            self.issuePowerActionCmd('STATUS')
    +            self.fail("Exception was expected, oobm is disabled at host level")
    +        except Exception: pass
    +
    +        # Enable at host level
    +        cmd = enableOutOfBandManagementForHost.enableOutOfBandManagementForHostCmd()
    +        cmd.hostid = host.id
    +        response = self.apiclient.enableOutOfBandManagementForHost(cmd)
    +
    +        response = self.issuePowerActionCmd('STATUS')
    +        self.assertEqual(response.powerstate, 'Off')
    +
    +
    +    @attr(tags=["smoke", "advanced"])
    +    def test_oobm_issue_power_status(self):
    +        """
    +            Tests out-of-band management issue power action
    +        """
    +        self.configureAndEnableOobm()
    +        self.startIpmiServer()
    +        bmc = IpmiServerContext().bmc
    +        bmc.powerstate = 'on'
    +        response = self.issuePowerActionCmd('STATUS')
    +        self.assertEqual(response.powerstate, 'On')
    +
    +
    +    @attr(tags=["smoke", "advanced"])
    +    def test_oobm_issue_power_on(self):
    +        """
    +            Tests out-of-band management issue power on action
    +        """
    +        self.configureAndEnableOobm()
    +        self.startIpmiServer()
    +        self.issuePowerActionCmd('ON')
    +        response = self.issuePowerActionCmd('STATUS')
    +        self.assertEqual(response.powerstate, 'On')
    +
    +
    +    @attr(tags=["smoke", "advanced"])
    +    def test_oobm_issue_power_off(self):
    +        """
    +            Tests out-of-band management issue power off action
    +        """
    +        self.configureAndEnableOobm()
    +        self.startIpmiServer()
    +        self.issuePowerActionCmd('OFF')
    +        response = self.issuePowerActionCmd('STATUS')
    +        self.assertEqual(response.powerstate, 'Off')
    +
    +
    +    @attr(tags=["smoke", "advanced"])
    +    def test_oobm_issue_power_cycle(self):
    +        """
    +            Tests out-of-band management issue power cycle action
    +        """
    +        self.configureAndEnableOobm()
    +        self.startIpmiServer()
    +        self.issuePowerActionCmd('CYCLE')
    +        response = self.issuePowerActionCmd('STATUS')
    +        self.assertEqual(response.powerstate, 'On')
    +
    +
    +    @attr(tags=["smoke", "advanced"])
    +    def test_oobm_issue_power_reset(self):
    +        """
    +            Tests out-of-band management issue power reset action
    +        """
    +        self.configureAndEnableOobm()
    +        self.startIpmiServer()
    +        self.issuePowerActionCmd('RESET')
    +        response = self.issuePowerActionCmd('STATUS')
    +        self.assertEqual(response.powerstate, 'On')
    +
    +
    +    @attr(tags=["smoke", "advanced"])
    +    def test_oobm_issue_power_soft(self):
    +        """
    +            Tests out-of-band management issue power soft action
    +        """
    +        self.configureAndEnableOobm()
    +        self.startIpmiServer()
    +        self.issuePowerActionCmd('SOFT')
    +        response = self.issuePowerActionCmd('STATUS')
    +        self.assertEqual(response.powerstate, 'Off')
    +
    +
    +    @attr(tags=["smoke", "advanced"])
    +    def test_oobm_background_powerstate_sync(self):
    +        """
    +            Tests out-of-band management background powerstate sync
    +        """
    +        self.debug("Testing oobm background sync")
    +        interval = list_configurations(
    +            self.apiclient,
    +            name='outofbandmanagement.sync.interval'
    +        )[0].value
    +
    +        self.configureAndEnableOobm()
    +        self.startIpmiServer()
    +        bmc = IpmiServerContext().bmc
    +
    +        bmc.powerstate = 'on'
    +        self.checkSyncToState('On', interval)
    +
    +        bmc.powerstate = 'off'
    +        self.checkSyncToState('Off', interval)
    +
    +        self.server.shutdown()
    +        self.server.server_close()
    +
    +        # Check for unknown state (ipmi server not reachable)
    +        self.checkSyncToState('Unknown', interval)
    +
    +
    +    @attr(tags=["smoke", "advanced"])
    +    def test_oobm_multiple_mgmt_server_ownership(self):
    +        """
    +            Tests out-of-band management ownership expiry across multi-mgmt server
    +        """
    +        self.configureAndEnableOobm()
    +
    +        cloudstackVersion = Configurations.listCapabilities(self.apiclient).cloudstackversion
    +
    +        currentMsHosts = []
    +        mshosts = self.dbclient.execute("select msid from mshost where version='%s' and
removed is NULL and state='Up'" % (cloudstackVersion))
    +        if len(mshosts) > 0:
    +            currentMsHosts = map(lambda row: row[0], mshosts)
    +
    +        # Inject fake ms host
    +        self.dbclient.execute("insert into mshost (msid,runid,name,state,version,service_ip,service_port,last_update)
values (%s,%s,'oobm-marvin-fakebox', 'Down', '%s', '127.0.0.1', '22', NOW())" % (self.getFakeMsId(),
self.getFakeMsRunId(), cloudstackVersion))
    +
    +        # Pass ownership to the fake ms id
    +        self.dbclient.execute("update oobm set mgmt_server_id=%d where port=%d" % (self.getFakeMsId(),
self.getIpmiServerPort()))
    +
    +        self.debug("Testing oobm background sync")
    +        pingInterval = float(list_configurations(
    +            self.apiclient,
    +            name='ping.interval'
    +        )[0].value)
    +
    +        pingTimeout = float(list_configurations(
    +            self.apiclient,
    +            name='ping.timeout'
    +        )[0].value)
    +
    +        # Sleep until the ownership gets expired as the fake ms id is not reachable
    +        for _ in range(10):
    +            rows = self.dbclient.execute("select * from mshost_peer where peer_runid=%s"
% self.getFakeMsRunId())
    +            if len(rows) > 0:
    +                self.debug("Mgmt server is now trying to contact the fake mgmt server")
    +                self.dbclient.execute("update mshost set removed=now() where runid=%s"
% self.getFakeMsRunId())
    +                self.dbclient.execute("update mshost_peer set peer_state='Down' where
peer_runid=%s" % self.getFakeMsRunId())
    +                break
    +            time.sleep(1 + (pingInterval * pingTimeout / 10))
    +
    +        for _ in range(100):
    +            rows = self.dbclient.execute("select mgmt_server_id from oobm where port=%d"
% (self.getIpmiServerPort()))
    +            if len(rows) > 0 and rows[0][0] != self.getFakeMsId():
    +                self.debug("Out-of-band management ownership expired as node was detected
to be gone")
    +                break
    +            time.sleep(1 + (pingInterval * pingTimeout / 10))
    --- End diff --
    
    Consider using the ``wait_until`` function to collapse both of these wait loops.


> Out-of-band Management for CloudStack
> -------------------------------------
>
>                 Key: CLOUDSTACK-9299
>                 URL: https://issues.apache.org/jira/browse/CLOUDSTACK-9299
>             Project: CloudStack
>          Issue Type: New Feature
>      Security Level: Public(Anyone can view this level - this is the default.) 
>            Reporter: Rohit Yadav
>            Assignee: Rohit Yadav
>             Fix For: 4.9.0, Future
>
>
> Support access to a host’s out-of-band management interface (e.g. IPMI, iLO, DRAC,
etc.) to manage host power operations (on/off etc.) and querying current power state.
> FS: https://cwiki.apache.org/confluence/display/CLOUDSTACK/Out-of-band+Management+for+CloudStack



--
This message was sent by Atlassian JIRA
(v6.3.4#6332)

Mime
View raw message