// 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.
//
// Automatically generated by addcopyright.py at 01/29/2013
// Apache License, Version 2.0 (the "License"); you may not use this
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
//
// Automatically generated by addcopyright.py at 04/03/2012
package com.cloud.baremetal.networkservice;

import com.cloud.agent.IAgentControl;
import com.cloud.agent.api.Answer;
import com.cloud.agent.api.CheckNetworkAnswer;
import com.cloud.agent.api.CheckNetworkCommand;
import com.cloud.agent.api.CheckVirtualMachineAnswer;
import com.cloud.agent.api.CheckVirtualMachineCommand;
import com.cloud.agent.api.Command;
import com.cloud.agent.api.HostVmStateReportEntry;
import com.cloud.agent.api.MaintainAnswer;
import com.cloud.agent.api.MaintainCommand;
import com.cloud.agent.api.MigrateAnswer;
import com.cloud.agent.api.MigrateCommand;
import com.cloud.agent.api.PingCommand;
import com.cloud.agent.api.PingRoutingCommand;
import com.cloud.agent.api.PrepareForMigrationAnswer;
import com.cloud.agent.api.PrepareForMigrationCommand;
import com.cloud.agent.api.ReadyAnswer;
import com.cloud.agent.api.ReadyCommand;
import com.cloud.agent.api.RebootAnswer;
import com.cloud.agent.api.RebootCommand;
import com.cloud.agent.api.SecurityGroupRulesCmd;
import com.cloud.agent.api.StartAnswer;
import com.cloud.agent.api.StartCommand;
import com.cloud.agent.api.StartupCommand;
import com.cloud.agent.api.StartupRoutingCommand;
import com.cloud.agent.api.StopAnswer;
import com.cloud.agent.api.StopCommand;
import com.cloud.agent.api.baremetal.IpmISetBootDevCommand;
import com.cloud.agent.api.baremetal.IpmISetBootDevCommand.BootDev;
import com.cloud.agent.api.baremetal.IpmiBootorResetCommand;
import com.cloud.agent.api.to.VirtualMachineTO;
import com.cloud.baremetal.manager.BaremetalManager;
import com.cloud.configuration.Config;
import com.cloud.host.Host.Type;
import com.cloud.hypervisor.Hypervisor;
import com.cloud.resource.ServerResource;
import com.cloud.utils.component.ManagerBase;
import com.cloud.utils.db.QueryBuilder;
import com.cloud.utils.db.SearchCriteria;
import com.cloud.utils.exception.CloudRuntimeException;
import com.cloud.utils.script.OutputInterpreter;
import com.cloud.utils.script.Script;
import com.cloud.utils.script.Script2;
import com.cloud.utils.script.Script2.ParamType;
import com.cloud.vm.VMInstanceVO;
import com.cloud.vm.VirtualMachine;
import com.cloud.vm.VirtualMachine.PowerState;
import com.cloud.vm.dao.VMInstanceDao;
import org.apache.cloudstack.api.ApiConstants;
import org.apache.cloudstack.framework.config.dao.ConfigurationDao;
import org.apache.log4j.Logger;

import javax.naming.ConfigurationException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;

public class BareMetalResourceBase extends ManagerBase implements ServerResource {
    private static final Logger s_logger = Logger.getLogger(BareMetalResourceBase.class);
    protected String _uuid;
    protected String _zone;
    protected String _pod;
    protected Long hostId;
    protected String _cluster;
    protected long _memCapacity;
    protected long _cpuCapacity;
    protected long _cpuNum;
    protected String _mac;
    protected String _username;
    protected String _password;
    protected String _ip;
    protected boolean _isEchoScAgent;
    protected IAgentControl _agentControl;
    protected Script2 _pingCommand;
    protected Script2 _setPxeBootCommand;
    protected Script2 _setDiskBootCommand;
    protected Script2 _rebootCommand;
    protected Script2 _getStatusCommand;
    protected Script2 _powerOnCommand;
    protected Script2 _powerOffCommand;
    protected Script2 _forcePowerOffCommand;
    protected Script2 _bootOrRebootCommand;
    protected String _vmName;
    protected int ipmiRetryTimes = 5;
    protected boolean provisionDoneNotificationOn = false;
    protected int isProvisionDoneNotificationTimeout = 1800;

    protected ConfigurationDao configDao;
    protected VMInstanceDao vmDao;


    @Override
    public boolean configure(String name, Map<String, Object> params) throws ConfigurationException {
        setName(name);
        _uuid = (String) params.get("guid");
        try {
            _memCapacity = Long.parseLong((String) params.get(ApiConstants.MEMORY)) * 1024L * 1024L;
            _cpuCapacity = Long.parseLong((String) params.get(ApiConstants.CPU_SPEED));
            _cpuNum = Long.parseLong((String) params.get(ApiConstants.CPU_NUMBER));
        } catch (NumberFormatException e) {
            throw new ConfigurationException(String.format("Unable to parse number of CPU or memory capacity "
                    + "or cpu capacity(cpu number = %1$s memCapacity=%2$s, cpuCapacity=%3$s", params.get(ApiConstants.CPU_NUMBER),
                    params.get(ApiConstants.MEMORY), params.get(ApiConstants.CPU_SPEED)));
        }

        _zone = (String) params.get("zone");
        _pod = (String) params.get("pod");
        _cluster = (String) params.get("cluster");
        hostId = (Long) params.get("hostId");
        _ip = (String) params.get(ApiConstants.PRIVATE_IP);
        _mac = (String) params.get(ApiConstants.HOST_MAC);
        _username = (String) params.get(ApiConstants.USERNAME);
        _password = (String) params.get(ApiConstants.PASSWORD);
        _vmName = (String) params.get("vmName");
        String echoScAgent = (String) params.get(BaremetalManager.EchoSecurityGroupAgent);
        vmDao = (VMInstanceDao) params.get("vmDao");
        configDao = (ConfigurationDao) params.get("configDao");

        if (_pod == null) {
            throw new ConfigurationException("Unable to get the pod");
        }

        if (_cluster == null) {
            throw new ConfigurationException("Unable to get the pod");
        }

        if (_ip == null) {
            throw new ConfigurationException("Unable to get the host address");
        }

        if (_mac.equalsIgnoreCase("unknown")) {
            throw new ConfigurationException("Unable to get the host mac address");
        }

        if (_mac.split(":").length != 6) {
            throw new ConfigurationException("Wrong MAC format(" + _mac
                    + "). It must be in format of for example 00:11:ba:33:aa:dd which is not case sensitive");
        }

        if (_uuid == null) {
            throw new ConfigurationException("Unable to get the uuid");
        }

        if (echoScAgent != null) {
            _isEchoScAgent = Boolean.valueOf(echoScAgent);
        }

        String ipmiIface = "default";
        try {
            ipmiIface = configDao.getValue(Config.BaremetalIpmiLanInterface.key());
        } catch (Exception e) {
            s_logger.debug(e.getMessage(), e);
        }

        try {
            ipmiRetryTimes = Integer.parseInt(configDao.getValue(Config.BaremetalIpmiRetryTimes.key()));
        } catch (Exception e) {
            s_logger.debug(e.getMessage(), e);
        }

        try {
            provisionDoneNotificationOn = Boolean.valueOf(configDao.getValue(Config.BaremetalProvisionDoneNotificationEnabled.key()));
            isProvisionDoneNotificationTimeout = Integer.parseInt(configDao.getValue(Config.BaremetalProvisionDoneNotificationTimeout.key()));
        } catch (Exception e) {
            s_logger.debug(e.getMessage(), e);
        }

        String injectScript = "scripts/util/ipmi.py";
        String scriptPath = Script.findScript("", injectScript);
        if (scriptPath == null) {
            throw new ConfigurationException("Cannot find ping script " + scriptPath);
        }
        String pythonPath = "/usr/bin/python";
        _pingCommand = new Script2(pythonPath, s_logger);
        _pingCommand.add(scriptPath);
        _pingCommand.add("ping");
        _pingCommand.add("interface=" + ipmiIface);
        _pingCommand.add("hostname=" + _ip);
        _pingCommand.add("usrname=" + _username);
        _pingCommand.add("password=" + _password, ParamType.PASSWORD);

        _setPxeBootCommand = new Script2(pythonPath, s_logger);
        _setPxeBootCommand.add(scriptPath);
        _setPxeBootCommand.add("boot_dev");
        _setPxeBootCommand.add("interface=" + ipmiIface);
        _setPxeBootCommand.add("hostname=" + _ip);
        _setPxeBootCommand.add("usrname=" + _username);
        _setPxeBootCommand.add("password=" + _password, ParamType.PASSWORD);
        _setPxeBootCommand.add("dev=pxe");

        _setDiskBootCommand = new Script2(pythonPath, s_logger);
        _setDiskBootCommand.add(scriptPath);
        _setDiskBootCommand.add("boot_dev");
        _setDiskBootCommand.add("interface=" + ipmiIface);
        _setDiskBootCommand.add("hostname=" + _ip);
        _setDiskBootCommand.add("usrname=" + _username);
        _setDiskBootCommand.add("password=" + _password, ParamType.PASSWORD);
        _setDiskBootCommand.add("dev=disk");

        _rebootCommand = new Script2(pythonPath, s_logger);
        _rebootCommand.add(scriptPath);
        _rebootCommand.add("reboot");
        _rebootCommand.add("interface=" + ipmiIface);
        _rebootCommand.add("hostname=" + _ip);
        _rebootCommand.add("usrname=" + _username);
        _rebootCommand.add("password=" + _password, ParamType.PASSWORD);

        _getStatusCommand = new Script2(pythonPath, s_logger);
        _getStatusCommand.add(scriptPath);
        _getStatusCommand.add("ping");
        _getStatusCommand.add("interface=" + ipmiIface);
        _getStatusCommand.add("hostname=" + _ip);
        _getStatusCommand.add("usrname=" + _username);
        _getStatusCommand.add("password=" + _password, ParamType.PASSWORD);

        _powerOnCommand = new Script2(pythonPath, s_logger);
        _powerOnCommand.add(scriptPath);
        _powerOnCommand.add("power");
        _powerOnCommand.add("interface=" + ipmiIface);
        _powerOnCommand.add("hostname=" + _ip);
        _powerOnCommand.add("usrname=" + _username);
        _powerOnCommand.add("password=" + _password, ParamType.PASSWORD);
        _powerOnCommand.add("action=on");

        _powerOffCommand = new Script2(pythonPath, s_logger);
        _powerOffCommand.add(scriptPath);
        _powerOffCommand.add("power");
        _powerOffCommand.add("interface=" + ipmiIface);
        _powerOffCommand.add("hostname=" + _ip);
        _powerOffCommand.add("usrname=" + _username);
        _powerOffCommand.add("password=" + _password, ParamType.PASSWORD);
        _powerOffCommand.add("action=soft");

        _forcePowerOffCommand = new Script2(pythonPath, s_logger);
        _forcePowerOffCommand.add(scriptPath);
        _forcePowerOffCommand.add("power");
        _forcePowerOffCommand.add("interface=" + ipmiIface);
        _forcePowerOffCommand.add("hostname=" + _ip);
        _forcePowerOffCommand.add("usrname=" + _username);
        _forcePowerOffCommand.add("password=" + _password, ParamType.PASSWORD);
        _forcePowerOffCommand.add("action=off");

        _bootOrRebootCommand = new Script2(pythonPath, s_logger);
        _bootOrRebootCommand.add(scriptPath);
        _bootOrRebootCommand.add("boot_or_reboot");
        _bootOrRebootCommand.add("interface=" + ipmiIface);
        _bootOrRebootCommand.add("hostname=" + _ip);
        _bootOrRebootCommand.add("usrname=" + _username);
        _bootOrRebootCommand.add("password=" + _password, ParamType.PASSWORD);

        return true;
    }

    protected boolean doScript(Script cmd) {
        return doScript(cmd, null);
    }

    protected boolean doScript(Script cmd, int retry) {
        return doScript(cmd, null, retry);
    }

    protected boolean doScript(Script cmd, OutputInterpreter interpreter) {
        return doScript(cmd, interpreter, ipmiRetryTimes);
    }

    protected boolean doScript(Script cmd, OutputInterpreter interpreter, int retry) {
        String res = null;
        while (retry-- > 0) {
            if (interpreter == null) {
                res = cmd.execute();
            } else {
                res = cmd.execute(interpreter);
            }
            if (res != null && res.startsWith("Error: Unable to establish LAN")) {
                s_logger.warn("IPMI script timeout(" + cmd.toString() + "), will retry " + retry + " times");
                try {
                    TimeUnit.SECONDS.sleep(1);
                } catch (InterruptedException e) {
                    s_logger.debug("[ignored] interupted while waiting to retry running script.");
                }
                continue;
            } else if (res == null) {
                return true;
            } else {
                break;
            }
        }

        s_logger.warn("IPMI Scirpt failed due to " + res + "(" + cmd.toString() + ")");
        return false;
    }

    @Override
    public boolean start() {
        return true;
    }

    @Override
    public boolean stop() {
        return true;
    }

    @Override
    public Type getType() {
        return com.cloud.host.Host.Type.Routing;
    }

    protected Map<String, HostVmStateReportEntry> getHostVmStateReport() {
        Map<String, HostVmStateReportEntry> states = new HashMap<String, HostVmStateReportEntry>();
        if (hostId != null) {
            final List<? extends VMInstanceVO> vms = vmDao.listByHostId(hostId);
            for (VMInstanceVO vm : vms) {
                states.put(
                    vm.getInstanceName(),
                    new HostVmStateReportEntry(
                        vm.getPowerState(), "host-" + hostId
                    )
                );
            }
        }
        return states;
    }

    @Override
    public StartupCommand[] initialize() {
        StartupRoutingCommand cmd = new StartupRoutingCommand(0, 0, 0, 0, null, Hypervisor.HypervisorType.BareMetal,
            new HashMap<String, String>());

        cmd.setDataCenter(_zone);
        cmd.setPod(_pod);
        cmd.setCluster(_cluster);
        cmd.setGuid(_uuid);
        cmd.setName(_ip);
        cmd.setPrivateIpAddress(_ip);
        cmd.setStorageIpAddress(_ip);
        cmd.setVersion(BareMetalResourceBase.class.getPackage().getImplementationVersion());
        cmd.setCpus((int) _cpuNum);
        cmd.setSpeed(_cpuCapacity);
        cmd.setMemory(_memCapacity);
        cmd.setPrivateMacAddress(_mac);
        cmd.setPublicMacAddress(_mac);
        return new StartupCommand[] { cmd };
    }

    private boolean ipmiPing() {
        return doScript(_pingCommand);
    }

    @Override
    public PingCommand getCurrentStatus(long id) {
        try {
            if (!ipmiPing()) {
                Thread.sleep(1000);
                if (!ipmiPing()) {
                    s_logger.warn("Cannot ping ipmi nic " + _ip);
                    return null;
                }
            }
        } catch (Exception e) {
            s_logger.debug("Cannot ping ipmi nic " + _ip, e);
            return null;
        }

        return new PingRoutingCommand(getType(), id, null);

            /*
        if (hostId != null) {
            final List<? extends VMInstanceVO> vms = vmDao.listByHostId(hostId);
            if (vms.isEmpty()) {
                return new PingRoutingCommand(getType(), id, null);
            } else {
                VMInstanceVO vm = vms.get(0);
                SecurityGroupHttpClient client = new SecurityGroupHttpClient();
                HashMap<String, Pair<Long, Long>> nwGrpStates = client.sync(vm.getInstanceName(), vm.getId(), vm.getPrivateIpAddress());
                return new PingRoutingWithNwGroupsCommand(getType(), id, null, nwGrpStates);
            }
        } else {
            return new PingRoutingCommand(getType(), id, null);
        }
            */
    }

    protected Answer execute(IpmISetBootDevCommand cmd) {
        Script bootCmd = null;
        if (cmd.getBootDev() == BootDev.disk) {
            bootCmd = _setDiskBootCommand;
        } else if (cmd.getBootDev() == BootDev.pxe) {
            bootCmd = _setPxeBootCommand;
        } else {
            throw new CloudRuntimeException("Unkonwn boot dev " + cmd.getBootDev());
        }

        String bootDev = cmd.getBootDev().name();
        if (!doScript(bootCmd)) {
            s_logger.warn("Set " + _ip + " boot dev to " + bootDev + "failed");
            return new Answer(cmd, false, "Set " + _ip + " boot dev to " + bootDev + "failed");
        }

        s_logger.warn("Set " + _ip + " boot dev to " + bootDev + "Success");
        return new Answer(cmd, true, "Set " + _ip + " boot dev to " + bootDev + "Success");
    }

    protected MaintainAnswer execute(MaintainCommand cmd) {
        return new MaintainAnswer(cmd, false);
    }

    protected PrepareForMigrationAnswer execute(PrepareForMigrationCommand cmd) {
        return new PrepareForMigrationAnswer(cmd);
    }

    protected MigrateAnswer execute(MigrateCommand cmd) {
        if (!doScript(_powerOffCommand)) {
            return new MigrateAnswer(cmd, false, "IPMI power off failed", null);
        }
        return new MigrateAnswer(cmd, true, "success", null);
    }

    protected CheckVirtualMachineAnswer execute(final CheckVirtualMachineCommand cmd) {
        return new CheckVirtualMachineAnswer(cmd, PowerState.PowerOff, null);
    }

    protected Answer execute(IpmiBootorResetCommand cmd) {
        if (!doScript(_bootOrRebootCommand)) {
            return new Answer(cmd, false, "IPMI boot or reboot failed");
        }
        return new Answer(cmd, true, "Success");

    }

    protected CheckNetworkAnswer execute(CheckNetworkCommand cmd) {
        return new CheckNetworkAnswer(cmd, true, "Success");
    }

    protected Answer execute(SecurityGroupRulesCmd cmd) {
        SecurityGroupHttpClient hc = new SecurityGroupHttpClient();
        return hc.call(cmd.getGuestIp(), cmd);
    }

    @Override
    public Answer executeRequest(Command cmd) {
        try {
            if (cmd instanceof ReadyCommand) {
                return execute((ReadyCommand) cmd);
            } else if (cmd instanceof StartCommand) {
                return execute((StartCommand) cmd);
            } else if (cmd instanceof StopCommand) {
                return execute((StopCommand) cmd);
            } else if (cmd instanceof RebootCommand) {
                return execute((RebootCommand) cmd);
            } else if (cmd instanceof IpmISetBootDevCommand) {
                return execute((IpmISetBootDevCommand) cmd);
            } else if (cmd instanceof MaintainCommand) {
                return execute((MaintainCommand) cmd);
            } else if (cmd instanceof PrepareForMigrationCommand) {
                return execute((PrepareForMigrationCommand) cmd);
            } else if (cmd instanceof MigrateCommand) {
                return execute((MigrateCommand) cmd);
            } else if (cmd instanceof CheckVirtualMachineCommand) {
                return execute((CheckVirtualMachineCommand) cmd);
            } else if (cmd instanceof IpmiBootorResetCommand) {
                return execute((IpmiBootorResetCommand) cmd);
            } else if (cmd instanceof SecurityGroupRulesCmd) {
                return execute((SecurityGroupRulesCmd) cmd);
            } else if (cmd instanceof CheckNetworkCommand) {
                return execute((CheckNetworkCommand) cmd);
            } else {
                return Answer.createUnsupportedCommandAnswer(cmd);
            }
        } catch (Throwable t) {
            s_logger.debug(t.getMessage(), t);
            return new Answer(cmd, false, t.getMessage());
        }
    }

    protected boolean isPowerOn(String str) {
        if (str.startsWith("Chassis Power is on")) {
            return true;
        } else if (str.startsWith("Chassis Power is off")) {
            return false;
        } else {
            throw new CloudRuntimeException("Cannot parse IPMI power status " + str);
        }
    }

    protected RebootAnswer execute(final RebootCommand cmd) {
        String infoStr = "Command not supported in present state";
        OutputInterpreter.AllLinesParser interpreter = new OutputInterpreter.AllLinesParser();
        if (!doScript(_rebootCommand, interpreter, 10)) {
            if (interpreter.getLines().contains(infoStr)) {
                // try again, this error should be temporary
                if (!doScript(_rebootCommand, interpreter, 10)) {
                    return new RebootAnswer(cmd, "IPMI reboot failed", false);
                }
            } else {
                return new RebootAnswer(cmd, "IPMI reboot failed", false);
            }
        }

        return new RebootAnswer(cmd, "reboot succeeded", true);
    }

    protected StopAnswer execute(final StopCommand cmd) {
        boolean success = false;
        int count = 0;
        Script powerOff = _powerOffCommand;

        while (count < 10) {
            if (!doScript(powerOff)) {
                break;
            }

            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                break;
            }

            OutputInterpreter.AllLinesParser interpreter = new OutputInterpreter.AllLinesParser();
            if (!doScript(_getStatusCommand, interpreter)) {
                success = true;
                s_logger.warn("Cannot get power status of " + getName() + ", assume VM state changed successfully");
                break;
            }

            if (!isPowerOn(interpreter.getLines())) {
                success = true;
                break;
            } else {
                powerOff = _forcePowerOffCommand;
            }

            count++;
        }

        return success ? new StopAnswer(cmd, "Success", true) : new StopAnswer(cmd, "IPMI power off failed", false);
    }

    protected StartAnswer execute(StartCommand cmd) {
        VirtualMachineTO vm = cmd.getVirtualMachine();

        OutputInterpreter.AllLinesParser interpreter = new OutputInterpreter.AllLinesParser();
        if (!doScript(_getStatusCommand, interpreter)) {
            return new StartAnswer(cmd, "Cannot get current power status of " + getName());
        }

        if (isPowerOn(interpreter.getLines())) {
            if (!doScript(_rebootCommand)) {
                return new StartAnswer(cmd, "IPMI reboot failed");
            }
        } else {
            if (!doScript(_powerOnCommand)) {
                return new StartAnswer(cmd, "IPMI power on failed");
            }
        }

        if (_isEchoScAgent) {
            SecurityGroupHttpClient hc = new SecurityGroupHttpClient();
            boolean echoRet = hc.echo(vm.getNics()[0].getIp(), TimeUnit.MINUTES.toMillis(30), TimeUnit.MINUTES.toMillis(1));
            if (!echoRet) {
                return new StartAnswer(cmd, String.format("Call security group agent on vm[%s] timeout", vm.getNics()[0].getIp()));
            }
        }

        if (provisionDoneNotificationOn) {
            QueryBuilder<VMInstanceVO> q = QueryBuilder.create(VMInstanceVO.class);
            q.and(q.entity().getInstanceName(), SearchCriteria.Op.EQ, vm.getName());
            VMInstanceVO vmvo = q.find();

            if (vmvo.getLastHostId() == null) {
                // this is new created vm
                long timeout = System.currentTimeMillis() + TimeUnit.SECONDS.toMillis(isProvisionDoneNotificationTimeout);
                while (timeout > System.currentTimeMillis()) {
                    try {
                        TimeUnit.SECONDS.sleep(5);
                    } catch (InterruptedException e) {
                        s_logger.warn(e.getMessage(), e);
                    }

                    q = QueryBuilder.create(VMInstanceVO.class);
                    q.and(q.entity().getInstanceName(), SearchCriteria.Op.EQ, vm.getName());
                    vmvo = q.find();
                    if (vmvo == null) {
                        return new StartAnswer(cmd, String.format("cannot find vm[name:%s] while waiting for baremtal provision done notification", vm.getName()));
                    }

                    if (VirtualMachine.State.Running == vmvo.getState()) {
                        return new StartAnswer(cmd);
                    }

                    s_logger.debug(String.format("still wait for baremetal provision done notification for vm[name:%s], current vm state is %s", vmvo.getInstanceName(), vmvo.getState()));
                }

                return new StartAnswer(cmd, String.format("timeout after %s seconds, no baremetal provision done notification received. vm[name:%s] failed to start", isProvisionDoneNotificationTimeout, vm.getName()));
            }
        }

        s_logger.debug("Start bare metal vm " + vm.getName() + "successfully");
        _vmName = vm.getName();
        return new StartAnswer(cmd);
    }

    protected ReadyAnswer execute(ReadyCommand cmd) {
        // derived resource should check if the PXE server is ready
        s_logger.debug("Bare metal resource " + getName() + " is ready");
        return new ReadyAnswer(cmd);
    }

    @Override
    public void disconnected() {

    }

    @Override
    public IAgentControl getAgentControl() {
        return _agentControl;
    }

    @Override
    public void setAgentControl(IAgentControl agentControl) {
        _agentControl = agentControl;
    }

}
