blob: b06555977e9d5a0082cca96475bbb589903399ca [file] [log] [blame]
# Copyright (c) 2010 The Chromium OS Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
import logging, os, urllib
# If you create and remote_power_switch_machines
# there, we will use it to configure the power switch.
# Example configuration:
# remote_power_switch_machines = {
# "myserver": "rps,cyclades-acs,powerswitch1,device1,password"
# }
from site_remote_power_config import remote_power_switch_machines
remote_power_switch_machines = {}
# If remote_power_switch_machines was not defined in site_remote_power_config,
# we look in the AFE database for a label which defines how we should behave.
# Here is an example label:
# "rps,cyclades-acs,powerswitch1,device1,password"
# If you attach the above label to device1, then we will use the "cyclades-acs"
# powerswitch to turn the power to device1 on and off, and pass in the above
# configuration to the CycladesACSRemotePowerSwitch class.
if not remote_power_switch_machines:
settings = 'autotest_lib.frontend.settings'
os.environ['DJANGO_SETTINGS_MODULE'] = settings
from autotest_lib.frontend.afe import models
# factory function for choosing which remote power class to return
def ParseConfig(config):
type = config.split(",", 3)[1]
cls = power_switch_types[type]
if cls:
return cls(config)
raise AssertionError
def RemotePower(host):
if not remote_power_switch_machines:
host_obj = models.Host.valid_objects.get(hostname=host)
for label in host_obj.labels.all():
name =
if name.startswith("rps,"):
return ParseConfig(name)
elif host in remote_power_switch_machines:
return ParseConfig(remote_power_switch_machines[host])
return None
class CycladesACSRemotePowerSwitch(object):
This class implements power control for Cyclades ACS boxes.
The config string contains five components, separated by commas:
1) prefix ("rps")
2) type ("cyclades-acs")
3) hostname of power switch box
4) port to use on power switch box
5) password to enter when connecting to power switch box
Example usage:
config = "rps,cyclades-acs,powerswitch1,device1,password"
switch = CycladesACSRemotePowerSwitch(config)
def __init__(self, config):
self.power_ip, self.power_port, self.password = config.split(",")[2:]
def _set_power(self, state):
from autotest_lib.client.common_lib import pexpect
hostname = self.power_ip
username = 'root:%s' % self.power_port
cmd = ('ssh -l %s '
'-o StrictHostKeyChecking=no '
'-o UserKnownHostsFile=/dev/null '
'%s' % (username, hostname))
ssh = pexpect.spawn(cmd)
ssh.expect('password:', timeout=30)
ssh.expect('\n', timeout=30)
ssh.send('\020')'Connecting to power switch (%s@%s)' % (username,
ssh.expect('Please choose an option:', timeout=30)
if state:
ssh.expect('Outlet turned on', timeout=30)'Power turned on for %s' % self.dict['power_port'])
ssh.expect('Outlet turned off', timeout=30)'Power turned off for %s' % self.dict['power_port'])
def set_power_on(self):
def set_power_off(self):
class HTTPPowerSwitch(object):
This class implements power control via standard HTTP GET requests.
The config string contains four components, separated by commas:
1) prefix ("rps")
2) type ("cyclades-acs")
3) URL to turn power on
4) URL to turn power off
Example usage:
url_prefix = "http://user:password@powerswitch1/Set.cmd?CMD=SetPower&P"
config = "rps,http,%s1=1,%s1=0" % (url_prefix, url_prefix)
switch = HTTPPowerSwitch(config)
def __init__(self, config):
self.on_url, self.off_url = config.split(",")[2:]
def _get_url(self, url):
f = urllib.urlopen(url)
def set_power_on(self):
def set_power_off(self):
power_switch_types = {
'cyclades-acs': CycladesACSRemotePowerSwitch,
'http': HTTPPowerSwitch