// Copyright 2012 Citrix Systems, Inc. Licensed under the
// Apache License, Version 2.0 (the "License"); you may not use this
// file except in compliance with the License. Citrix Systems, Inc.
// reserves all rights not expressly granted by 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 04/03/2012
package com.cloud.storage.secondary;
import java.io.File;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.net.URI;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Random;
import javax.ejb.Local;
import javax.naming.ConfigurationException;
import org.apache.log4j.Logger;
import com.cloud.agent.AgentManager;
import com.cloud.configuration.dao.ConfigurationDao;
import com.cloud.host.HostVO;
import com.cloud.host.Status.Event;
import com.cloud.host.dao.HostDao;
import com.cloud.hypervisor.Hypervisor;
import com.cloud.resource.Discoverer;
import com.cloud.resource.DiscovererBase;
import com.cloud.resource.ServerResource;
import com.cloud.storage.VMTemplateVO;
import com.cloud.storage.VMTemplateZoneVO;
import com.cloud.storage.dao.VMTemplateDao;
import com.cloud.storage.dao.VMTemplateHostDao;
import com.cloud.storage.dao.VMTemplateZoneDao;
import com.cloud.storage.resource.DummySecondaryStorageResource;
import com.cloud.storage.resource.LocalSecondaryStorageResource;
import com.cloud.storage.resource.NfsSecondaryStorageResource;
import com.cloud.utils.component.Inject;
import com.cloud.utils.net.NfsUtils;
import com.cloud.utils.script.Script;
/**
* SecondaryStorageDiscoverer is used to discover secondary
* storage servers and make sure everything it can do is
* correct.
*/
@Local(value=Discoverer.class)
public class SecondaryStorageDiscoverer extends DiscovererBase implements Discoverer {
private static final Logger s_logger = Logger.getLogger(SecondaryStorageDiscoverer.class);
long _timeout = 2 * 60 * 1000; // 2 minutes
String _mountParent;
boolean _useServiceVM = false;
Random _random = new Random(System.currentTimeMillis());
@Inject
protected HostDao _hostDao = null;
@Inject
protected VMTemplateDao _tmpltDao = null;
@Inject
protected VMTemplateHostDao _vmTemplateHostDao = null;
@Inject
protected VMTemplateZoneDao _vmTemplateZoneDao = null;
@Inject
protected VMTemplateDao _vmTemplateDao = null;
@Inject
protected ConfigurationDao _configDao = null;
@Inject
protected AgentManager _agentMgr = null;
protected SecondaryStorageDiscoverer() {
}
@Override
public Map<? extends ServerResource, Map<String, String>> find(long dcId, Long podId, Long clusterId, URI uri, String username, String password, List<String> hostTags) {
if (!uri.getScheme().equalsIgnoreCase("nfs") && !uri.getScheme().equalsIgnoreCase("file")
&& !uri.getScheme().equalsIgnoreCase("iso") && !uri.getScheme().equalsIgnoreCase("dummy")) {
s_logger.debug("It's not NFS or file or ISO, so not a secondary storage server: " + uri.toString());
return null;
}
if (uri.getScheme().equalsIgnoreCase("nfs") || uri.getScheme().equalsIgnoreCase("iso")) {
return createNfsSecondaryStorageResource(dcId, podId, uri);
} else if (uri.getScheme().equalsIgnoreCase("file")) {
return createLocalSecondaryStorageResource(dcId, podId, uri);
} else if (uri.getScheme().equalsIgnoreCase("dummy")) {
return createDummySecondaryStorageResource(dcId, podId, uri);
} else {
return null;
}
}
protected Map<? extends ServerResource, Map<String, String>> createNfsSecondaryStorageResource(long dcId, Long podId, URI uri) {
if (_useServiceVM) {
return createDummySecondaryStorageResource(dcId, podId, uri);
}
String mountStr = NfsUtils.uri2Mount(uri);
Script script = new Script(true, "mount", _timeout, s_logger);
String mntPoint = null;
File file = null;
do {
mntPoint = _mountParent + File.separator + Integer.toHexString(_random.nextInt(Integer.MAX_VALUE));
file = new File(mntPoint);
} while (file.exists());
if (!file.mkdirs()) {
s_logger.warn("Unable to make directory: " + mntPoint);
return null;
}
script.add(mountStr, mntPoint);
String result = script.execute();
if (result != null && !result.contains("already mounted")) {
s_logger.warn("Unable to mount " + uri.toString() + " due to " + result);
file.delete();
return null;
}
script = new Script(true, "umount", 0, s_logger);
script.add(mntPoint);
script.execute();
file.delete();
Map<NfsSecondaryStorageResource, Map<String, String>> srs = new HashMap<NfsSecondaryStorageResource, Map<String, String>>();
NfsSecondaryStorageResource storage;
if(_configDao.isPremium()) {
Class<?> impl;
String name = "com.cloud.storage.resource.PremiumSecondaryStorageResource";
try {
impl = Class.forName(name);
final Constructor<?> constructor = impl.getDeclaredConstructor();
constructor.setAccessible(true);
storage = (NfsSecondaryStorageResource)constructor.newInstance();
} catch (final ClassNotFoundException e) {
s_logger.error("Unable to load com.cloud.storage.resource.PremiumSecondaryStorageResource due to ClassNotFoundException");
return null;
} catch (final SecurityException e) {
s_logger.error("Unable to load com.cloud.storage.resource.PremiumSecondaryStorageResource due to SecurityException");
return null;
} catch (final NoSuchMethodException e) {
s_logger.error("Unable to load com.cloud.storage.resource.PremiumSecondaryStorageResource due to NoSuchMethodException");
return null;
} catch (final IllegalArgumentException e) {
s_logger.error("Unable to load com.cloud.storage.resource.PremiumSecondaryStorageResource due to IllegalArgumentException");
return null;
} catch (final InstantiationException e) {
s_logger.error("Unable to load com.cloud.storage.resource.PremiumSecondaryStorageResource due to InstantiationException");
return null;
} catch (final IllegalAccessException e) {
s_logger.error("Unable to load com.cloud.storage.resource.PremiumSecondaryStorageResource due to IllegalAccessException");
return null;
} catch (final InvocationTargetException e) {
s_logger.error("Unable to load com.cloud.storage.resource.PremiumSecondaryStorageResource due to InvocationTargetException");
return null;
}
} else {
storage = new NfsSecondaryStorageResource();
}
Map<String, String> details = new HashMap<String, String>();
details.put("mount.path", mountStr);
details.put("orig.url", uri.toString());
details.put("mount.parent", _mountParent);
Map<String, Object> params = new HashMap<String, Object>();
params.putAll(details);
params.put("zone", Long.toString(dcId));
if (podId != null) {
params.put("pod", podId.toString());
}
params.put("guid", uri.toString());
params.put("secondary.storage.vm", "false");
params.put("max.template.iso.size", _configDao.getValue("max.template.iso.size"));
try {
storage.configure("Storage", params);
} catch (ConfigurationException e) {
s_logger.warn("Unable to configure the storage ", e);
return null;
}
srs.put(storage, details);
return srs;
}
protected Map<? extends ServerResource, Map<String, String>> createLocalSecondaryStorageResource(long dcId, Long podId, URI uri) {
Map<LocalSecondaryStorageResource, Map<String, String>> srs = new HashMap<LocalSecondaryStorageResource, Map<String, String>>();
LocalSecondaryStorageResource storage = new LocalSecondaryStorageResource();
Map<String, String> details = new HashMap<String, String>();
File file = new File(uri);
details.put("mount.path", file.getAbsolutePath());
details.put("orig.url", uri.toString());
Map<String, Object> params = new HashMap<String, Object>();
params.putAll(details);
params.put("zone", Long.toString(dcId));
if (podId != null) {
params.put("pod", podId.toString());
}
params.put("guid", uri.toString());
try {
storage.configure("Storage", params);
} catch (ConfigurationException e) {
s_logger.warn("Unable to configure the storage ", e);
return null;
}
srs.put(storage, details);
return srs;
}
protected Map<ServerResource, Map<String, String>> createDummySecondaryStorageResource(long dcId, Long podId, URI uri) {
Map<ServerResource, Map<String, String>> srs = new HashMap<ServerResource, Map<String, String>>();
DummySecondaryStorageResource storage = new DummySecondaryStorageResource(_useServiceVM);
Map<String, String> details = new HashMap<String, String>();
details.put("mount.path", uri.toString());
details.put("orig.url", uri.toString());
Map<String, Object> params = new HashMap<String, Object>();
params.putAll(details);
params.put("zone", Long.toString(dcId));
if (podId != null) {
params.put("pod", podId.toString());
}
params.put("guid", uri.toString());
try {
storage.configure("Storage", params);
} catch (ConfigurationException e) {
s_logger.warn("Unable to configure the storage ", e);
return null;
}
srs.put(storage, details);
return srs;
}
@Override
public boolean configure(String name, Map<String, Object> params) throws ConfigurationException {
super.configure(name, params);
_mountParent = _params.get("mount.parent");
if (_mountParent == null) {
_mountParent = "/mnt";
}
String useServiceVM = _params.get("secondary.storage.vm");
if ("true".equalsIgnoreCase(useServiceVM)){
_useServiceVM = true;
}
return true;
}
@Override
public boolean matchHypervisor(String hypervisor) {
if( hypervisor.equals("SecondaryStorage")) {
return true;
} else {
return false;
}
}
@Override
public Hypervisor.HypervisorType getHypervisorType() {
return Hypervisor.HypervisorType.None;
}
@Override
public void postDiscovery(List<HostVO> hosts, long msId) {
if (_useServiceVM) {
for (HostVO h: hosts) {
_agentMgr.agentStatusTransitTo(h, Event.AgentDisconnected, msId);
}
}
for (HostVO h: hosts) {
associateTemplatesToZone(h.getId(), h.getDataCenterId());
}
}
private void associateTemplatesToZone(long hostId, long dcId){
VMTemplateZoneVO tmpltZone;
List<VMTemplateVO> allTemplates = _vmTemplateDao.listAll();
for (VMTemplateVO vt: allTemplates){
if (vt.isCrossZones()) {
tmpltZone = _vmTemplateZoneDao.findByZoneTemplate(dcId, vt.getId());
if (tmpltZone == null) {
VMTemplateZoneVO vmTemplateZone = new VMTemplateZoneVO(dcId, vt.getId(), new Date());
_vmTemplateZoneDao.persist(vmTemplateZone);
}
}
}
}
}