mirror of https://github.com/apache/cloudstack.git
initial checkin for multiple secondary storage
This commit is contained in:
parent
a84678cca0
commit
ba6b2ca670
|
|
@ -18,22 +18,15 @@
|
|||
package com.cloud.agent.api;
|
||||
|
||||
public class SecStorageSetupCommand extends Command {
|
||||
private Long dcId;
|
||||
String [] allowedInternalSites = new String[0];
|
||||
String copyUserName;
|
||||
String copyPassword;
|
||||
private String secUrl;
|
||||
|
||||
public SecStorageSetupCommand() {
|
||||
super();
|
||||
}
|
||||
|
||||
public SecStorageSetupCommand(Long dcId) {
|
||||
public SecStorageSetupCommand(String secUrl) {
|
||||
super();
|
||||
this.dcId = dcId;
|
||||
}
|
||||
|
||||
public Long getDataCenterId() {
|
||||
return dcId;
|
||||
this.secUrl = secUrl;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -41,28 +34,11 @@ public class SecStorageSetupCommand extends Command {
|
|||
return true;
|
||||
}
|
||||
|
||||
public String[] getAllowedInternalSites() {
|
||||
return allowedInternalSites;
|
||||
}
|
||||
|
||||
public void setAllowedInternalSites(String[] allowedInternalSites) {
|
||||
this.allowedInternalSites = allowedInternalSites;
|
||||
}
|
||||
|
||||
public String getCopyUserName() {
|
||||
return copyUserName;
|
||||
}
|
||||
|
||||
public void setCopyUserName(String copyUserName) {
|
||||
this.copyUserName = copyUserName;
|
||||
}
|
||||
|
||||
public String getCopyPassword() {
|
||||
return copyPassword;
|
||||
}
|
||||
|
||||
public void setCopyPassword(String copyPassword) {
|
||||
this.copyPassword = copyPassword;
|
||||
}
|
||||
public String getSecUrl() {
|
||||
return secUrl;
|
||||
}
|
||||
|
||||
public void setSecUrl(String secUrl) {
|
||||
this.secUrl = secUrl;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,58 @@
|
|||
/**
|
||||
* Copyright (C) 2010 Cloud.com, Inc. All rights reserved.
|
||||
*
|
||||
* This software is licensed under the GNU General Public License v3 or later.
|
||||
*
|
||||
* It is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or any later version.
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
package com.cloud.agent.api;
|
||||
|
||||
public class SecStorageVMSetupCommand extends Command {
|
||||
String [] allowedInternalSites = new String[0];
|
||||
String copyUserName;
|
||||
String copyPassword;
|
||||
|
||||
public SecStorageVMSetupCommand() {
|
||||
super();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean executeInSequence() {
|
||||
return true;
|
||||
}
|
||||
|
||||
public String[] getAllowedInternalSites() {
|
||||
return allowedInternalSites;
|
||||
}
|
||||
|
||||
public void setAllowedInternalSites(String[] allowedInternalSites) {
|
||||
this.allowedInternalSites = allowedInternalSites;
|
||||
}
|
||||
|
||||
public String getCopyUserName() {
|
||||
return copyUserName;
|
||||
}
|
||||
|
||||
public void setCopyUserName(String copyUserName) {
|
||||
this.copyUserName = copyUserName;
|
||||
}
|
||||
|
||||
public String getCopyPassword() {
|
||||
return copyPassword;
|
||||
}
|
||||
|
||||
public void setCopyPassword(String copyPassword) {
|
||||
this.copyPassword = copyPassword;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,33 @@
|
|||
/**
|
||||
* Copyright (C) 2010 Cloud.com, Inc. All rights reserved.
|
||||
*
|
||||
* This software is licensed under the GNU General Public License v3 or later.
|
||||
*
|
||||
* It is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or any later version.
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
package com.cloud.agent.api;
|
||||
|
||||
import com.cloud.host.Host;
|
||||
|
||||
public class StartupSecondaryStorageCommand extends StartupCommand {
|
||||
|
||||
public StartupSecondaryStorageCommand() {
|
||||
super(Host.Type.ConsoleProxy);
|
||||
setIqn("NoIqn");
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean executeInSequence() {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
@ -64,7 +64,11 @@ public class StartupStorageCommand extends StartupCommand {
|
|||
return parent;
|
||||
}
|
||||
|
||||
public void setNfsShare(String nfsShare) {
|
||||
public void setParent(String parent) {
|
||||
this.parent = parent;
|
||||
}
|
||||
|
||||
public void setNfsShare(String nfsShare) {
|
||||
this.nfsShare = nfsShare;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@ package com.cloud.agent.api.storage;
|
|||
|
||||
import com.cloud.storage.Storage.ImageFormat;
|
||||
|
||||
public abstract class AbstractDownloadCommand extends StorageCommand {
|
||||
public abstract class AbstractDownloadCommand extends ssCommand {
|
||||
|
||||
private String url;
|
||||
private ImageFormat format;
|
||||
|
|
@ -40,7 +40,13 @@ public abstract class AbstractDownloadCommand extends StorageCommand {
|
|||
}
|
||||
|
||||
protected AbstractDownloadCommand(AbstractDownloadCommand that) {
|
||||
this(that.name, that.url, that.format, that.accountId);
|
||||
super(that);
|
||||
assert(that.url != null);
|
||||
|
||||
this.url = that.url.replace('\\', '/');
|
||||
this.format = that.format;
|
||||
this.accountId = that.accountId;
|
||||
this.name = that.name;
|
||||
}
|
||||
|
||||
public String getUrl() {
|
||||
|
|
|
|||
|
|
@ -18,16 +18,16 @@
|
|||
|
||||
package com.cloud.agent.api.storage;
|
||||
|
||||
import com.cloud.agent.api.Command;
|
||||
|
||||
public class DeleteTemplateCommand extends Command {
|
||||
|
||||
String templatePath;
|
||||
public class DeleteTemplateCommand extends ssCommand {
|
||||
private String templatePath;
|
||||
|
||||
|
||||
public DeleteTemplateCommand() {
|
||||
}
|
||||
|
||||
public DeleteTemplateCommand(String templatePath) {
|
||||
public DeleteTemplateCommand(String secUrl, String templatePath) {
|
||||
this.setSecUrl(secUrl);
|
||||
this.templatePath = templatePath;
|
||||
}
|
||||
|
||||
|
|
@ -39,5 +39,4 @@ public class DeleteTemplateCommand extends Command {
|
|||
public String getTemplatePath() {
|
||||
return templatePath;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -64,23 +64,20 @@ public class DownloadCommand extends AbstractDownloadCommand {
|
|||
this.maxDownloadSizeInBytes = that.getMaxDownloadSizeInBytes();
|
||||
}
|
||||
|
||||
public DownloadCommand(VirtualMachineTemplate template, Long maxDownloadSizeInBytes) {
|
||||
public DownloadCommand(String secUrl, VirtualMachineTemplate template, Long maxDownloadSizeInBytes) {
|
||||
super(template.getUniqueName(), template.getUrl(), template.getFormat(), template.getAccountId());
|
||||
this.hvm = template.isRequiresHvm();
|
||||
this.checksum = template.getChecksum();
|
||||
this.id = template.getId();
|
||||
this.description = template.getDisplayText();
|
||||
this.setSecUrl(secUrl);
|
||||
this.maxDownloadSizeInBytes = maxDownloadSizeInBytes;
|
||||
}
|
||||
|
||||
public DownloadCommand(String url, String name, ImageFormat format, boolean isHvm, Long accountId, Long templateId, String descr, String cksum, String user, String passwd, Long maxDownloadSizeInBytes) {
|
||||
super(name, url, format, accountId);
|
||||
this.setHvm(isHvm);
|
||||
this.description = descr;
|
||||
this.checksum = cksum;
|
||||
this.id = templateId;
|
||||
public DownloadCommand(String secUrl, String url, VirtualMachineTemplate template, String user, String passwd, Long maxDownloadSizeInBytes) {
|
||||
this(secUrl, template, maxDownloadSizeInBytes);
|
||||
this.setUrl(url);
|
||||
auth = new PasswordAuth(user, passwd);
|
||||
this.maxDownloadSizeInBytes = maxDownloadSizeInBytes;
|
||||
}
|
||||
|
||||
public long getId() {
|
||||
|
|
@ -103,7 +100,7 @@ public class DownloadCommand extends AbstractDownloadCommand {
|
|||
return checksum;
|
||||
}
|
||||
|
||||
public void setDescription(String description) {
|
||||
public void setDescription(String description) {
|
||||
this.description = description;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,55 @@
|
|||
/**
|
||||
* Copyright (C) 2010 Cloud.com, Inc. All rights reserved.
|
||||
*
|
||||
* This software is licensed under the GNU General Public License v3 or later.
|
||||
*
|
||||
* It is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or any later version.
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
package com.cloud.agent.api.storage;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import com.cloud.agent.api.Answer;
|
||||
|
||||
import com.cloud.storage.template.TemplateInfo;
|
||||
|
||||
public class ListTemplateAnswer extends Answer {
|
||||
private String secUrl;
|
||||
private Map<String, TemplateInfo> templateInfos;
|
||||
|
||||
public ListTemplateAnswer() {
|
||||
|
||||
}
|
||||
|
||||
public ListTemplateAnswer(String secUrl, Map<String, TemplateInfo> templateInfos) {
|
||||
super(null, true, "success");
|
||||
this.setSecUrl(secUrl);
|
||||
this.templateInfos = templateInfos;
|
||||
}
|
||||
|
||||
public Map<String, TemplateInfo> getTemplateInfo() {
|
||||
return templateInfos;
|
||||
}
|
||||
|
||||
public void setTemplateInfo(Map<String, TemplateInfo> templateInfos) {
|
||||
this.templateInfos = templateInfos;
|
||||
}
|
||||
|
||||
public void setSecUrl(String secUrl) {
|
||||
this.secUrl = secUrl;
|
||||
}
|
||||
|
||||
public String getSecUrl() {
|
||||
return secUrl;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,43 @@
|
|||
/**
|
||||
* Copyright (C) 2010 Cloud.com, Inc. All rights reserved.
|
||||
*
|
||||
* This software is licensed under the GNU General Public License v3 or later.
|
||||
*
|
||||
* It is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or any later version.
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
package com.cloud.agent.api.storage;
|
||||
|
||||
public class ListTemplateCommand extends StorageCommand {
|
||||
private String secUrl;
|
||||
|
||||
public ListTemplateCommand() {
|
||||
}
|
||||
|
||||
public ListTemplateCommand(String secUrl) {
|
||||
this.secUrl = secUrl;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean executeInSequence() {
|
||||
return false;
|
||||
}
|
||||
|
||||
public String getSecUrl() {
|
||||
return secUrl;
|
||||
}
|
||||
|
||||
public void setSecUrl(String secUrl) {
|
||||
this.secUrl = secUrl;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,50 @@
|
|||
/**
|
||||
* Copyright (C) 2010 Cloud.com, Inc. All rights reserved.
|
||||
*
|
||||
* This software is licensed under the GNU General Public License v3 or later.
|
||||
*
|
||||
* It is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or any later version.
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
package com.cloud.agent.api.storage;
|
||||
|
||||
import com.cloud.agent.api.Command;
|
||||
|
||||
public abstract class ssCommand extends Command {
|
||||
private String secUrl;
|
||||
|
||||
|
||||
public ssCommand() {
|
||||
}
|
||||
|
||||
protected ssCommand(ssCommand that) {
|
||||
this.secUrl = that.secUrl;
|
||||
}
|
||||
public ssCommand(String secUrl) {
|
||||
this.secUrl = secUrl;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean executeInSequence() {
|
||||
return true;
|
||||
}
|
||||
|
||||
public String getSecUrl() {
|
||||
return secUrl;
|
||||
}
|
||||
|
||||
public void setSecUrl(String secUrl) {
|
||||
this.secUrl = secUrl;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -36,8 +36,10 @@ public interface Host {
|
|||
ExternalLoadBalancer(false),
|
||||
PxeServer(false),
|
||||
TrafficMonitor(false),
|
||||
ExternalDhcp(false);
|
||||
|
||||
ExternalDhcp(false),
|
||||
SecondaryStorageVM(true),
|
||||
LocalSecondaryStorage(false);
|
||||
boolean _virtual;
|
||||
private Type(boolean virtual) {
|
||||
_virtual = virtual;
|
||||
|
|
|
|||
|
|
@ -110,5 +110,5 @@ public class Storage {
|
|||
}
|
||||
}
|
||||
|
||||
public static enum StorageResourceType {STORAGE_POOL, STORAGE_HOST, SECONDARY_STORAGE}
|
||||
public static enum StorageResourceType {STORAGE_POOL, STORAGE_HOST, SECONDARY_STORAGE, LOCAL_SECONDARY_STORAGE}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -91,6 +91,9 @@ public class SnapshotVO implements Snapshot {
|
|||
@Column(name="swift_id")
|
||||
long swiftId;
|
||||
|
||||
@Column(name="sechost_id")
|
||||
Long secHostId;
|
||||
|
||||
@Column(name="swift_name")
|
||||
String swiftName;
|
||||
|
||||
|
|
@ -121,7 +124,8 @@ public class SnapshotVO implements Snapshot {
|
|||
this.status = Status.Creating;
|
||||
this.prevSnapshotId = 0;
|
||||
this.hypervisorType = hypervisorType;
|
||||
this.version = "2.2";
|
||||
this.version = "2.2";
|
||||
this.secHostId = null;
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -190,6 +194,14 @@ public class SnapshotVO implements Snapshot {
|
|||
this.swiftId = swiftId;
|
||||
}
|
||||
|
||||
public Long getSecHostId() {
|
||||
return secHostId;
|
||||
}
|
||||
|
||||
public void setSecHostId(Long secHostId) {
|
||||
this.secHostId = secHostId;
|
||||
}
|
||||
|
||||
public String getSwiftName() {
|
||||
return swiftName;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -32,13 +32,14 @@ import com.cloud.agent.api.PingCommand;
|
|||
import com.cloud.agent.api.PingStorageCommand;
|
||||
import com.cloud.agent.api.ReadyAnswer;
|
||||
import com.cloud.agent.api.ReadyCommand;
|
||||
import com.cloud.agent.api.SecStorageSetupCommand;
|
||||
import com.cloud.agent.api.StartupCommand;
|
||||
import com.cloud.agent.api.StartupStorageCommand;
|
||||
import com.cloud.agent.api.storage.ssCommand;
|
||||
import com.cloud.agent.api.storage.DownloadCommand;
|
||||
import com.cloud.agent.api.storage.DownloadProgressCommand;
|
||||
import com.cloud.host.Host;
|
||||
import com.cloud.host.Host.Type;
|
||||
import com.cloud.resource.ServerResource;
|
||||
import com.cloud.resource.ServerResourceBase;
|
||||
import com.cloud.storage.Storage;
|
||||
import com.cloud.storage.Storage.StoragePoolType;
|
||||
|
|
@ -48,7 +49,7 @@ import com.cloud.storage.template.DownloadManagerImpl;
|
|||
import com.cloud.storage.template.TemplateInfo;
|
||||
import com.cloud.utils.component.ComponentLocator;
|
||||
|
||||
public class LocalSecondaryStorageResource extends ServerResourceBase implements ServerResource {
|
||||
public class LocalSecondaryStorageResource extends ServerResourceBase implements SecondaryStorageResource {
|
||||
private static final Logger s_logger = Logger.getLogger(LocalSecondaryStorageResource.class);
|
||||
int _timeout;
|
||||
|
||||
|
|
@ -70,11 +71,13 @@ public class LocalSecondaryStorageResource extends ServerResourceBase implements
|
|||
@Override
|
||||
public Answer executeRequest(Command cmd) {
|
||||
if (cmd instanceof DownloadProgressCommand) {
|
||||
return _dlMgr.handleDownloadCommand((DownloadProgressCommand)cmd);
|
||||
return _dlMgr.handleDownloadCommand(this, (DownloadProgressCommand)cmd);
|
||||
} else if (cmd instanceof DownloadCommand) {
|
||||
return _dlMgr.handleDownloadCommand((DownloadCommand)cmd);
|
||||
return _dlMgr.handleDownloadCommand(this, (DownloadCommand)cmd);
|
||||
} else if (cmd instanceof CheckHealthCommand) {
|
||||
return new CheckHealthAnswer((CheckHealthCommand)cmd, true);
|
||||
} else if (cmd instanceof SecStorageSetupCommand){
|
||||
return new Answer(cmd, true, "success");
|
||||
} else if (cmd instanceof ReadyCommand) {
|
||||
return new ReadyAnswer((ReadyCommand)cmd);
|
||||
} else {
|
||||
|
|
@ -84,7 +87,7 @@ public class LocalSecondaryStorageResource extends ServerResourceBase implements
|
|||
|
||||
@Override
|
||||
public Type getType() {
|
||||
return Host.Type.SecondaryStorage;
|
||||
return Host.Type.LocalSecondaryStorage;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -92,6 +95,12 @@ public class LocalSecondaryStorageResource extends ServerResourceBase implements
|
|||
return new PingStorageCommand(Host.Type.Storage, id, new HashMap<String, Boolean>());
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getRootDir(ssCommand cmd){
|
||||
return null;
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public boolean configure(String name, Map<String, Object> params) throws ConfigurationException {
|
||||
|
|
@ -159,8 +168,8 @@ public class LocalSecondaryStorageResource extends ServerResourceBase implements
|
|||
@Override
|
||||
public StartupCommand[] initialize() {
|
||||
|
||||
final StartupStorageCommand cmd = new StartupStorageCommand(_parent, StoragePoolType.Filesystem, 1024l*1024l*1024l*1024l, _dlMgr.gatherTemplateInfo());
|
||||
cmd.setResourceType(Storage.StorageResourceType.SECONDARY_STORAGE);
|
||||
final StartupStorageCommand cmd = new StartupStorageCommand(_parent, StoragePoolType.Filesystem, 1024l*1024l*1024l*1024l, _dlMgr.gatherTemplateInfo(_parent));
|
||||
cmd.setResourceType(Storage.StorageResourceType.LOCAL_SECONDARY_STORAGE);
|
||||
cmd.setIqn("local://");
|
||||
fillNetworkInformation(cmd);
|
||||
cmd.setDataCenter(_dc);
|
||||
|
|
@ -168,11 +177,7 @@ public class LocalSecondaryStorageResource extends ServerResourceBase implements
|
|||
cmd.setGuid(_guid);
|
||||
cmd.setName(_guid);
|
||||
cmd.setVersion(LocalSecondaryStorageResource.class.getPackage().getImplementationVersion());
|
||||
|
||||
/* gather TemplateInfo in second storage */
|
||||
final Map<String, TemplateInfo> tInfo = _dlMgr.gatherTemplateInfo();
|
||||
cmd.setTemplateInfo(tInfo);
|
||||
|
||||
|
||||
return new StartupCommand [] {cmd};
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -26,11 +26,13 @@ import java.net.InetAddress;
|
|||
import java.net.UnknownHostException;
|
||||
import java.security.MessageDigest;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.net.URI;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Random;
|
||||
import java.util.UUID;
|
||||
|
||||
import javax.naming.ConfigurationException;
|
||||
|
||||
|
|
@ -48,28 +50,30 @@ import com.cloud.agent.api.PingStorageCommand;
|
|||
import com.cloud.agent.api.ReadyAnswer;
|
||||
import com.cloud.agent.api.ReadyCommand;
|
||||
import com.cloud.agent.api.SecStorageFirewallCfgCommand;
|
||||
import com.cloud.agent.api.SecStorageFirewallCfgCommand.PortConfig;
|
||||
import com.cloud.agent.api.SecStorageSetupCommand;
|
||||
import com.cloud.agent.api.StartupSecondaryStorageCommand;
|
||||
import com.cloud.agent.api.SecStorageFirewallCfgCommand.PortConfig;
|
||||
import com.cloud.agent.api.SecStorageVMSetupCommand;
|
||||
import com.cloud.agent.api.StartupCommand;
|
||||
import com.cloud.agent.api.StartupStorageCommand;
|
||||
import com.cloud.agent.api.storage.CreateEntityDownloadURLCommand;
|
||||
import com.cloud.agent.api.storage.DeleteEntityDownloadURLCommand;
|
||||
import com.cloud.agent.api.storage.DeleteTemplateCommand;
|
||||
import com.cloud.agent.api.storage.ListTemplateAnswer;
|
||||
import com.cloud.agent.api.storage.ListTemplateCommand;
|
||||
import com.cloud.agent.api.storage.ssCommand;
|
||||
import com.cloud.agent.api.storage.DownloadCommand;
|
||||
import com.cloud.agent.api.storage.DownloadProgressCommand;
|
||||
import com.cloud.agent.api.storage.UploadCommand;
|
||||
import com.cloud.host.Host;
|
||||
import com.cloud.host.Host.Type;
|
||||
import com.cloud.resource.ServerResource;
|
||||
import com.cloud.resource.ServerResourceBase;
|
||||
import com.cloud.storage.Storage;
|
||||
import com.cloud.storage.Storage.StoragePoolType;
|
||||
import com.cloud.storage.StorageLayer;
|
||||
import com.cloud.storage.template.DownloadManager;
|
||||
import com.cloud.storage.template.DownloadManagerImpl;
|
||||
import com.cloud.storage.template.TemplateInfo;
|
||||
import com.cloud.storage.template.UploadManager;
|
||||
import com.cloud.storage.template.UploadManagerImpl;
|
||||
import com.cloud.storage.template.DownloadManagerImpl.ZfsPathParser;
|
||||
import com.cloud.utils.NumbersUtil;
|
||||
import com.cloud.utils.component.ComponentLocator;
|
||||
import com.cloud.utils.exception.CloudRuntimeException;
|
||||
|
|
@ -78,18 +82,14 @@ import com.cloud.utils.net.NfsUtils;
|
|||
import com.cloud.utils.script.Script;
|
||||
import com.cloud.vm.SecondaryStorageVm;
|
||||
|
||||
public class NfsSecondaryStorageResource extends ServerResourceBase implements ServerResource {
|
||||
public class NfsSecondaryStorageResource extends ServerResourceBase implements SecondaryStorageResource {
|
||||
private static final Logger s_logger = Logger.getLogger(NfsSecondaryStorageResource.class);
|
||||
int _timeout;
|
||||
|
||||
String _instance;
|
||||
String _parent;
|
||||
|
||||
String _instance;
|
||||
String _dc;
|
||||
String _pod;
|
||||
String _guid;
|
||||
String _nfsPath;
|
||||
String _mountParent;
|
||||
String _role;
|
||||
Map<String, Object> _params;
|
||||
StorageLayer _storage;
|
||||
|
|
@ -111,24 +111,16 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S
|
|||
|
||||
@Override
|
||||
public void disconnected() {
|
||||
if (_parent != null && !_inSystemVM) {
|
||||
Script script = new Script(!_inSystemVM, "umount", _timeout, s_logger);
|
||||
script.add(_parent);
|
||||
script.execute();
|
||||
|
||||
File file = new File(_parent);
|
||||
file.delete();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Answer executeRequest(Command cmd) {
|
||||
if (cmd instanceof DownloadProgressCommand) {
|
||||
return _dlMgr.handleDownloadCommand((DownloadProgressCommand)cmd);
|
||||
return _dlMgr.handleDownloadCommand(this, (DownloadProgressCommand)cmd);
|
||||
} else if (cmd instanceof DownloadCommand) {
|
||||
return _dlMgr.handleDownloadCommand((DownloadCommand)cmd);
|
||||
return _dlMgr.handleDownloadCommand(this, (DownloadCommand)cmd);
|
||||
} else if (cmd instanceof UploadCommand) {
|
||||
return _upldMgr.handleUploadCommand((UploadCommand)cmd);
|
||||
return _upldMgr.handleUploadCommand(this, (UploadCommand)cmd);
|
||||
} else if (cmd instanceof CreateEntityDownloadURLCommand){
|
||||
return _upldMgr.handleCreateEntityURLCommand((CreateEntityDownloadURLCommand)cmd);
|
||||
} else if(cmd instanceof DeleteEntityDownloadURLCommand){
|
||||
|
|
@ -143,10 +135,14 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S
|
|||
return new ReadyAnswer((ReadyCommand)cmd);
|
||||
} else if (cmd instanceof SecStorageFirewallCfgCommand){
|
||||
return execute((SecStorageFirewallCfgCommand)cmd);
|
||||
} else if (cmd instanceof SecStorageVMSetupCommand){
|
||||
return execute((SecStorageVMSetupCommand)cmd);
|
||||
} else if (cmd instanceof SecStorageSetupCommand){
|
||||
return execute((SecStorageSetupCommand)cmd);
|
||||
return execute((SecStorageSetupCommand)cmd);
|
||||
} else if (cmd instanceof ComputeChecksumCommand){
|
||||
return execute((ComputeChecksumCommand)cmd);
|
||||
} else if (cmd instanceof ListTemplateCommand){
|
||||
return execute((ListTemplateCommand)cmd);
|
||||
} else {
|
||||
return Answer.createUnsupportedCommandAnswer(cmd);
|
||||
}
|
||||
|
|
@ -210,7 +206,40 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S
|
|||
return new Answer(cmd, true, checksum);
|
||||
}
|
||||
|
||||
|
||||
private Answer execute(SecStorageSetupCommand cmd) {
|
||||
if (!_inSystemVM){
|
||||
return new Answer(cmd, true, null);
|
||||
}
|
||||
String secUrl = cmd.getSecUrl();
|
||||
try {
|
||||
URI uri = new URI(secUrl);
|
||||
String nfsHost = uri.getHost();
|
||||
|
||||
InetAddress nfsHostAddr = InetAddress.getByName(nfsHost);
|
||||
String nfsHostIp = nfsHostAddr.getHostAddress();
|
||||
|
||||
addRouteToInternalIpOrCidr(_localgw, _eth1ip, _eth1mask, nfsHostIp);
|
||||
return new Answer(cmd, true, "success");
|
||||
} catch (Exception e) {
|
||||
String msg = "GetRootDir for " + secUrl + " failed due to " + e.toString();
|
||||
s_logger.error(msg);
|
||||
return new Answer(cmd, false, msg);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private Answer execute(ListTemplateCommand cmd) {
|
||||
if (!_inSystemVM){
|
||||
return new Answer(cmd, true, null);
|
||||
}
|
||||
String root = getRootDir(cmd.getSecUrl());
|
||||
Map<String, TemplateInfo> templateInfos = _dlMgr.gatherTemplateInfo(root);
|
||||
return new ListTemplateAnswer(cmd.getSecUrl(), templateInfos);
|
||||
}
|
||||
|
||||
private Answer execute(SecStorageVMSetupCommand cmd) {
|
||||
if (!_inSystemVM){
|
||||
return new Answer(cmd, true, null);
|
||||
}
|
||||
|
|
@ -274,8 +303,9 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S
|
|||
}
|
||||
|
||||
protected GetStorageStatsAnswer execute(final GetStorageStatsCommand cmd) {
|
||||
final long usedSize = getUsedSize();
|
||||
final long totalSize = getTotalSize();
|
||||
String rootDir = getRootDir(cmd.getLocalPath());
|
||||
final long usedSize = getUsedSize(rootDir);
|
||||
final long totalSize = getTotalSize(rootDir);
|
||||
if (usedSize == -1 || totalSize == -1) {
|
||||
return new GetStorageStatsAnswer(cmd, "Unable to get storage stats");
|
||||
} else {
|
||||
|
|
@ -285,7 +315,7 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S
|
|||
|
||||
protected Answer execute(final DeleteTemplateCommand cmd) {
|
||||
String relativeTemplatePath = cmd.getTemplatePath();
|
||||
String parent = _parent;
|
||||
String parent = getRootDir(cmd);
|
||||
|
||||
if (relativeTemplatePath.startsWith(File.separator)) {
|
||||
relativeTemplatePath = relativeTemplatePath.substring(1);
|
||||
|
|
@ -331,12 +361,39 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S
|
|||
return new Answer(cmd, true, null);
|
||||
}
|
||||
|
||||
protected long getUsedSize() {
|
||||
return _storage.getUsedSpace(_parent);
|
||||
|
||||
public String getRootDir(String secUrl) {
|
||||
try {
|
||||
URI uri = new URI(secUrl);
|
||||
String nfsHost = uri.getHost();
|
||||
|
||||
InetAddress nfsHostAddr = InetAddress.getByName(nfsHost);
|
||||
String nfsHostIp = nfsHostAddr.getHostAddress();
|
||||
String nfsPath = nfsHostIp + ":" + uri.getPath();
|
||||
String dir = UUID.nameUUIDFromBytes(nfsPath.getBytes()).toString();
|
||||
String root = "/mnt/SecStorage/" + dir;
|
||||
mount(root, nfsPath);
|
||||
return root;
|
||||
} catch (Exception e) {
|
||||
String msg = "GetRootDir for " + secUrl + " failed due to " + e.toString();
|
||||
s_logger.error(msg, e);
|
||||
throw new CloudRuntimeException(msg);
|
||||
}
|
||||
}
|
||||
|
||||
protected long getTotalSize() {
|
||||
return _storage.getTotalSpace(_parent);
|
||||
|
||||
@Override
|
||||
public String getRootDir(ssCommand cmd){
|
||||
return getRootDir(cmd.getSecUrl());
|
||||
|
||||
}
|
||||
|
||||
protected long getUsedSize(String rootDir) {
|
||||
return _storage.getUsedSpace(rootDir);
|
||||
}
|
||||
|
||||
protected long getTotalSize(String rootDir) {
|
||||
return _storage.getTotalSpace(rootDir);
|
||||
}
|
||||
|
||||
protected long convertFilesystemSize(final String size) {
|
||||
|
|
@ -440,22 +497,7 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S
|
|||
_pod = (String)params.get("pod");
|
||||
|
||||
_instance = (String)params.get("instance");
|
||||
|
||||
_mountParent = (String)params.get("mount.parent");
|
||||
if (_mountParent == null) {
|
||||
_mountParent = File.separator + "mnt";
|
||||
}
|
||||
|
||||
if (_instance != null) {
|
||||
_mountParent = _mountParent + File.separator + _instance;
|
||||
}
|
||||
|
||||
_nfsPath = (String)params.get("mount.path");
|
||||
if (_nfsPath == null) {
|
||||
throw new ConfigurationException("Unable to find mount.path");
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
String inSystemVM = (String)params.get("secondary.storage.vm");
|
||||
if (inSystemVM == null || "true".equalsIgnoreCase(inSystemVM)) {
|
||||
|
|
@ -473,19 +515,7 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S
|
|||
}
|
||||
|
||||
String mgmtHost = (String)params.get("host");
|
||||
String nfsHost = NfsUtils.getHostPart(_nfsPath);
|
||||
if (nfsHost == null) {
|
||||
s_logger.error("Invalid or corrupt nfs url " + _nfsPath);
|
||||
throw new CloudRuntimeException("Unable to determine host part of nfs path");
|
||||
}
|
||||
try {
|
||||
InetAddress nfsHostAddr = InetAddress.getByName(nfsHost);
|
||||
nfsHost = nfsHostAddr.getHostAddress();
|
||||
} catch (UnknownHostException uhe) {
|
||||
s_logger.error("Unable to resolve nfs host " + nfsHost);
|
||||
throw new CloudRuntimeException("Unable to resolve nfs host to an ip address " + nfsHost);
|
||||
}
|
||||
addRouteToInternalIpOrCidr(_localgw, _eth1ip, _eth1mask, nfsHost);
|
||||
|
||||
addRouteToInternalIpOrCidr(_localgw, _eth1ip, _eth1mask, mgmtHost);
|
||||
if (internalDns2 != null) {
|
||||
addRouteToInternalIpOrCidr(_localgw, _eth1ip, _eth1mask, internalDns2);
|
||||
|
|
@ -503,16 +533,8 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S
|
|||
_params.put("install.numthreads", "50");
|
||||
_params.put("secondary.storage.vm", "true");
|
||||
}
|
||||
_parent = mount(_nfsPath, _mountParent);
|
||||
if (_parent == null) {
|
||||
throw new ConfigurationException("Unable to create mount point");
|
||||
}
|
||||
|
||||
|
||||
s_logger.info("Mount point established at " + _parent);
|
||||
|
||||
try {
|
||||
_params.put("template.parent", _parent);
|
||||
_params.put(StorageLayer.InstanceConfigKey, _storage);
|
||||
_dlMgr = new DownloadManagerImpl();
|
||||
_dlMgr.configure("DownloadManager", _params);
|
||||
|
|
@ -615,67 +637,58 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S
|
|||
return result;
|
||||
}
|
||||
|
||||
protected String mount(String path, String parent) {
|
||||
String mountPoint = null;
|
||||
for (int i = 0; i < 10; i++) {
|
||||
String mntPt = parent + File.separator + Integer.toHexString(_rand.nextInt(Integer.MAX_VALUE));
|
||||
File file = new File(mntPt);
|
||||
if (!file.exists()) {
|
||||
if (_storage.mkdir(mntPt)) {
|
||||
mountPoint = mntPt;
|
||||
break;
|
||||
}
|
||||
protected String mount(String root, String nfsPath) {
|
||||
File file = new File(root);
|
||||
if (!file.exists()) {
|
||||
if (!_storage.mkdir(root)) {
|
||||
s_logger.debug("create mount point: " + root);
|
||||
} else {
|
||||
s_logger.debug("Unable to create mount point: " + root);
|
||||
return null;
|
||||
}
|
||||
s_logger.debug("Unable to create mount: " + mntPt);
|
||||
}
|
||||
|
||||
if (mountPoint == null) {
|
||||
s_logger.warn("Unable to create a mount point");
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
Script script = null;
|
||||
String result = null;
|
||||
script = new Script(!_inSystemVM, "umount", _timeout, s_logger);
|
||||
script.add(path);
|
||||
result = script.execute();
|
||||
|
||||
if( _parent != null ) {
|
||||
script = new Script("rmdir", _timeout, s_logger);
|
||||
script.add(_parent);
|
||||
result = script.execute();
|
||||
script = new Script(!_inSystemVM, "mount", _timeout, s_logger);
|
||||
List<String> res = new ArrayList<String>();
|
||||
ZfsPathParser parser = new ZfsPathParser(root);
|
||||
script.execute(parser);
|
||||
res.addAll(parser.getPaths());
|
||||
for( String s : res ) {
|
||||
if ( s.contains(root)) {
|
||||
return root;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Script command = new Script(!_inSystemVM, "mount", _timeout, s_logger);
|
||||
command.add("-t", "nfs");
|
||||
if (_inSystemVM) {
|
||||
//Fedora Core 12 errors out with any -o option executed from java
|
||||
command.add("-o", "soft,timeo=133,retrans=2147483647,tcp,acdirmax=0,acdirmin=0");
|
||||
}
|
||||
command.add(path);
|
||||
command.add(mountPoint);
|
||||
command.add(nfsPath);
|
||||
command.add(root);
|
||||
result = command.execute();
|
||||
if (result != null) {
|
||||
s_logger.warn("Unable to mount " + path + " due to " + result);
|
||||
File file = new File(mountPoint);
|
||||
s_logger.warn("Unable to mount " + nfsPath + " due to " + result);
|
||||
file = new File(root);
|
||||
if (file.exists())
|
||||
file.delete();
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// XXX: Adding the check for creation of snapshots dir here. Might have to move it somewhere more logical later.
|
||||
if (!checkForSnapshotsDir(mountPoint)) {
|
||||
if (!checkForSnapshotsDir(root)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// Create the volumes dir
|
||||
if (!checkForVolumesDir(mountPoint)) {
|
||||
if (!checkForVolumesDir(root)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return mountPoint;
|
||||
return root;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -690,62 +703,12 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S
|
|||
|
||||
@Override
|
||||
public StartupCommand[] initialize() {
|
||||
/*disconnected();
|
||||
|
||||
_parent = mount(_nfsPath, _mountParent);
|
||||
|
||||
if( _parent == null ) {
|
||||
s_logger.warn("Unable to mount the nfs server");
|
||||
return null;
|
||||
}
|
||||
|
||||
try {
|
||||
_params.put("template.parent", _parent);
|
||||
_params.put(StorageLayer.InstanceConfigKey, _storage);
|
||||
_dlMgr = new DownloadManagerImpl();
|
||||
_dlMgr.configure("DownloadManager", _params);
|
||||
} catch (ConfigurationException e) {
|
||||
s_logger.warn("Caught problem while configuring folers", e);
|
||||
return null;
|
||||
}*/
|
||||
|
||||
final StartupStorageCommand cmd = new StartupStorageCommand(_parent, StoragePoolType.NetworkFilesystem, getTotalSize(), new HashMap<String, TemplateInfo>());
|
||||
|
||||
cmd.setHostType(getType());
|
||||
cmd.setResourceType(Storage.StorageResourceType.SECONDARY_STORAGE);
|
||||
cmd.setIqn(null);
|
||||
|
||||
final StartupSecondaryStorageCommand cmd = new StartupSecondaryStorageCommand();
|
||||
fillNetworkInformation(cmd);
|
||||
cmd.setDataCenter(_dc);
|
||||
cmd.setPod(_pod);
|
||||
cmd.setGuid(_guid);
|
||||
cmd.setName(_guid);
|
||||
cmd.setVersion(NfsSecondaryStorageResource.class.getPackage().getImplementationVersion());
|
||||
/* gather TemplateInfo in second storage */
|
||||
|
||||
Map<String, TemplateInfo> tInfo = new HashMap<String, TemplateInfo>();
|
||||
if(SecondaryStorageVm.Role.templateProcessor.toString().equals(_role))
|
||||
tInfo = _dlMgr.gatherTemplateInfo();
|
||||
cmd.setTemplateInfo(tInfo);
|
||||
cmd.getHostDetails().put("mount.parent", _mountParent);
|
||||
cmd.getHostDetails().put("mount.path", _nfsPath);
|
||||
String tok[] = _nfsPath.split(":");
|
||||
cmd.setNfsShare("nfs://" + tok[0] + tok[1]);
|
||||
if (cmd.getHostDetails().get("orig.url") == null) {
|
||||
if (tok.length != 2) {
|
||||
throw new CloudRuntimeException("Not valid NFS path" + _nfsPath);
|
||||
}
|
||||
String nfsUrl = "nfs://" + tok[0] + tok[1];
|
||||
cmd.getHostDetails().put("orig.url", nfsUrl);
|
||||
}
|
||||
InetAddress addr;
|
||||
try {
|
||||
addr = InetAddress.getByName(tok[0]);
|
||||
cmd.setPrivateIpAddress(addr.getHostAddress());
|
||||
} catch (UnknownHostException e) {
|
||||
cmd.setPrivateIpAddress(tok[0]);
|
||||
}
|
||||
return new StartupCommand [] {cmd};
|
||||
if(_publicIp != null)
|
||||
cmd.setPublicIpAddress(_publicIp);
|
||||
return new StartupCommand[] {cmd};
|
||||
}
|
||||
|
||||
protected boolean checkForSnapshotsDir(String mountPoint) {
|
||||
|
|
|
|||
|
|
@ -0,0 +1,30 @@
|
|||
/**
|
||||
* Copyright (C) 2010 Cloud.com, Inc. All rights reserved.
|
||||
*
|
||||
* This software is licensed under the GNU General Public License v3 or later.
|
||||
*
|
||||
* It is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or any later version.
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
package com.cloud.storage.resource;
|
||||
import com.cloud.agent.api.storage.ssCommand;
|
||||
import com.cloud.resource.ServerResource;
|
||||
/**
|
||||
*
|
||||
* SecondaryStorageServerResource is a generic container to execute commands sent
|
||||
* to the agent.
|
||||
*/
|
||||
public interface SecondaryStorageResource extends ServerResource {
|
||||
|
||||
public String getRootDir(ssCommand cmd);
|
||||
|
||||
}
|
||||
|
|
@ -24,6 +24,7 @@ import com.cloud.agent.api.storage.DownloadAnswer;
|
|||
import com.cloud.agent.api.storage.DownloadCommand;
|
||||
import com.cloud.storage.VMTemplateHostVO;
|
||||
import com.cloud.storage.Storage.ImageFormat;
|
||||
import com.cloud.storage.resource.SecondaryStorageResource;
|
||||
import com.cloud.utils.component.Manager;
|
||||
|
||||
/**
|
||||
|
|
@ -90,20 +91,12 @@ public interface DownloadManager extends Manager {
|
|||
* @param cmd cmd from server
|
||||
* @return answer representing status of download.
|
||||
*/
|
||||
public DownloadAnswer handleDownloadCommand(DownloadCommand cmd);
|
||||
public DownloadAnswer handleDownloadCommand(SecondaryStorageResource resource, DownloadCommand cmd);
|
||||
|
||||
/**
|
||||
* List the paths of the public templates successfully installed in the public templates location
|
||||
* @return
|
||||
*/
|
||||
public List<String> listPublicTemplates();
|
||||
|
||||
/**
|
||||
/**
|
||||
* @return list of template info for installed templates
|
||||
*/
|
||||
public Map<String, TemplateInfo> gatherTemplateInfo();
|
||||
|
||||
public String getPublicTemplateRepo();
|
||||
|
||||
public Map<String, TemplateInfo> gatherTemplateInfo(String templateDir);
|
||||
}
|
||||
|
|
@ -47,6 +47,7 @@ import com.cloud.exception.InternalErrorException;
|
|||
import com.cloud.storage.Storage.ImageFormat;
|
||||
import com.cloud.storage.StorageLayer;
|
||||
import com.cloud.storage.VMTemplateHostVO;
|
||||
import com.cloud.storage.resource.SecondaryStorageResource;
|
||||
import com.cloud.storage.template.Processor.FormatInfo;
|
||||
import com.cloud.storage.template.TemplateDownloader.DownloadCompleteCallback;
|
||||
import com.cloud.storage.template.TemplateDownloader.Status;
|
||||
|
|
@ -125,14 +126,6 @@ public class DownloadManagerImpl implements DownloadManager {
|
|||
return checksum;
|
||||
}
|
||||
|
||||
public DownloadJob(TemplateDownloader td, String jobId, DownloadCommand cmd) {
|
||||
this.td = td;
|
||||
this.jobId = jobId;
|
||||
this.tmpltName = cmd.getName();
|
||||
this.format = cmd.getFormat();
|
||||
this.hvm = cmd.isHvm();
|
||||
}
|
||||
|
||||
public TemplateDownloader getTemplateDownloader() {
|
||||
return td;
|
||||
}
|
||||
|
|
@ -205,8 +198,7 @@ public class DownloadManagerImpl implements DownloadManager {
|
|||
}
|
||||
|
||||
public static final Logger s_logger = Logger.getLogger(DownloadManagerImpl.class);
|
||||
private String parentDir;
|
||||
private String publicTemplateRepo;
|
||||
private String _templateDir;
|
||||
private String createTmpltScr;
|
||||
private Adapters<Processor> processors;
|
||||
|
||||
|
|
@ -284,7 +276,7 @@ public class DownloadManagerImpl implements DownloadManager {
|
|||
_storage.mkdirs(templatePath);
|
||||
|
||||
// once template path is set, remove the parent dir so that the template is installed with a relative path
|
||||
String finalTemplatePath = templatePath.substring(parentDir.length());
|
||||
String finalTemplatePath = _templateDir + File.separator + dnld.getAccountId() + File.separator + dnld.getId() + File.separator;
|
||||
dnld.setTmpltPath(finalTemplatePath);
|
||||
|
||||
int imgSizeGigs = (int) Math.ceil(_storage.getSize(td.getDownloadLocalPath()) * 1.0d / (1024 * 1024 * 1024));
|
||||
|
|
@ -438,11 +430,6 @@ public class DownloadManagerImpl implements DownloadManager {
|
|||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getPublicTemplateRepo() {
|
||||
return publicTemplateRepo;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDownloadError(String jobId) {
|
||||
DownloadJob dj = jobs.get(jobId);
|
||||
|
|
@ -515,9 +502,9 @@ public class DownloadManagerImpl implements DownloadManager {
|
|||
}
|
||||
|
||||
@Override
|
||||
public DownloadAnswer handleDownloadCommand(DownloadCommand cmd) {
|
||||
public DownloadAnswer handleDownloadCommand(SecondaryStorageResource resource, DownloadCommand cmd) {
|
||||
if (cmd instanceof DownloadProgressCommand) {
|
||||
return handleDownloadProgressCmd((DownloadProgressCommand) cmd);
|
||||
return handleDownloadProgressCmd( resource, (DownloadProgressCommand) cmd);
|
||||
}
|
||||
|
||||
if (cmd.getUrl() == null) {
|
||||
|
|
@ -527,9 +514,9 @@ public class DownloadManagerImpl implements DownloadManager {
|
|||
if (cmd.getName() == null) {
|
||||
return new DownloadAnswer("Invalid Name", VMTemplateStorageResourceAssoc.Status.DOWNLOAD_ERROR);
|
||||
}
|
||||
|
||||
|
||||
String installPathPrefix = null;
|
||||
installPathPrefix = publicTemplateRepo;
|
||||
installPathPrefix = resource.getRootDir(cmd) + File.separator + _templateDir;
|
||||
|
||||
String user = null;
|
||||
String password = null;
|
||||
|
|
@ -556,7 +543,7 @@ public class DownloadManagerImpl implements DownloadManager {
|
|||
}
|
||||
}
|
||||
|
||||
private DownloadAnswer handleDownloadProgressCmd(DownloadProgressCommand cmd) {
|
||||
private DownloadAnswer handleDownloadProgressCmd(SecondaryStorageResource resource, DownloadProgressCommand cmd) {
|
||||
String jobId = cmd.getJobId();
|
||||
DownloadAnswer answer;
|
||||
DownloadJob dj = null;
|
||||
|
|
@ -565,7 +552,7 @@ public class DownloadManagerImpl implements DownloadManager {
|
|||
if (dj == null) {
|
||||
if (cmd.getRequest() == RequestType.GET_OR_RESTART) {
|
||||
DownloadCommand dcmd = new DownloadCommand(cmd);
|
||||
return handleDownloadCommand(dcmd);
|
||||
return handleDownloadCommand(resource, dcmd);
|
||||
} else {
|
||||
return new DownloadAnswer("Cannot find job", VMTemplateStorageResourceAssoc.Status.DOWNLOAD_ERROR.UNKNOWN);
|
||||
}
|
||||
|
|
@ -614,11 +601,6 @@ public class DownloadManagerImpl implements DownloadManager {
|
|||
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> listPublicTemplates() {
|
||||
return listTemplates(publicTemplateRepo);
|
||||
}
|
||||
|
||||
private List<String> listTemplates(String rootdir) {
|
||||
List<String> result = new ArrayList<String>();
|
||||
Script script = new Script(listTmpltScr, s_logger);
|
||||
|
|
@ -631,9 +613,10 @@ public class DownloadManagerImpl implements DownloadManager {
|
|||
}
|
||||
|
||||
@Override
|
||||
public Map<String, TemplateInfo> gatherTemplateInfo() {
|
||||
public Map<String, TemplateInfo> gatherTemplateInfo(String rootDir) {
|
||||
Map<String, TemplateInfo> result = new HashMap<String, TemplateInfo>();
|
||||
List<String> publicTmplts = listPublicTemplates();
|
||||
String templateDir = rootDir + File.separator + _templateDir;
|
||||
List<String> publicTmplts = listTemplates(templateDir);
|
||||
for (String tmplt : publicTmplts) {
|
||||
String path = tmplt.substring(0, tmplt.lastIndexOf(File.separator));
|
||||
TemplateLocation loc = new TemplateLocation(_storage, path);
|
||||
|
|
@ -641,14 +624,14 @@ public class DownloadManagerImpl implements DownloadManager {
|
|||
if (!loc.load()) {
|
||||
s_logger.warn("Post download installation was not completed for " + path);
|
||||
loc.purge();
|
||||
_storage.cleanup(path, publicTemplateRepo);
|
||||
_storage.cleanup(path, templateDir);
|
||||
continue;
|
||||
}
|
||||
} catch (IOException e) {
|
||||
s_logger.warn("Unable to load template location " + path, e);
|
||||
loc.purge();
|
||||
try {
|
||||
_storage.cleanup(path, publicTemplateRepo);
|
||||
_storage.cleanup(path, templateDir);
|
||||
} catch (IOException e1) {
|
||||
s_logger.warn("Unable to cleanup " + path, e1);
|
||||
}
|
||||
|
|
@ -747,7 +730,6 @@ public class DownloadManagerImpl implements DownloadManager {
|
|||
_sslCopy = Boolean.parseBoolean(useSsl);
|
||||
|
||||
}
|
||||
configureFolders(name, params);
|
||||
String inSystemVM = (String)params.get("secondary.storage.vm");
|
||||
if (inSystemVM != null && "true".equalsIgnoreCase(inSystemVM)) {
|
||||
s_logger.info("DownloadManager: starting additional services since we are inside system vm");
|
||||
|
|
@ -797,6 +779,12 @@ public class DownloadManagerImpl implements DownloadManager {
|
|||
processors.add(new ComponentInfo<Adapter>("VMDK Processor", VmdkProcessor.class, processor));
|
||||
|
||||
_processors = new Adapters<Processor>("processors", processors);
|
||||
|
||||
_templateDir = (String) params.get("public.templates.root.dir");
|
||||
if (_templateDir == null) {
|
||||
_templateDir = TemplateConstants.DEFAULT_TMPLT_ROOT_DIR;
|
||||
}
|
||||
_templateDir += File.separator + TemplateConstants.DEFAULT_TMPLT_FIRST_LEVEL_DIR;
|
||||
// Add more processors here.
|
||||
threadPool = Executors.newFixedThreadPool(numInstallThreads);
|
||||
return true;
|
||||
|
|
@ -816,34 +804,6 @@ public class DownloadManagerImpl implements DownloadManager {
|
|||
}
|
||||
}
|
||||
|
||||
protected void configureFolders(String name, Map<String, Object> params) throws ConfigurationException {
|
||||
parentDir = (String) params.get("template.parent");
|
||||
if (parentDir == null) {
|
||||
throw new ConfigurationException("Unable to find the parent root for the templates");
|
||||
}
|
||||
|
||||
String value = (String) params.get("public.templates.root.dir");
|
||||
if (value == null) {
|
||||
value = TemplateConstants.DEFAULT_TMPLT_ROOT_DIR;
|
||||
}
|
||||
|
||||
if (value.startsWith(File.separator)) {
|
||||
publicTemplateRepo = value;
|
||||
} else {
|
||||
publicTemplateRepo = parentDir + File.separator + value;
|
||||
}
|
||||
|
||||
if (!publicTemplateRepo.endsWith(File.separator)) {
|
||||
publicTemplateRepo += File.separator;
|
||||
}
|
||||
|
||||
publicTemplateRepo += TemplateConstants.DEFAULT_TMPLT_FIRST_LEVEL_DIR;
|
||||
|
||||
if (!_storage.mkdirs(publicTemplateRepo)) {
|
||||
throw new ConfigurationException("Unable to create public templates directory");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return _name;
|
||||
|
|
@ -898,14 +858,5 @@ public class DownloadManagerImpl implements DownloadManager {
|
|||
s_logger.warn("Error in creating directory =" + result );
|
||||
return;
|
||||
}
|
||||
|
||||
command = new Script("/bin/bash", s_logger);
|
||||
command.add("-c");
|
||||
command.add("ln -sf " + publicTemplateRepo + " /var/www/html/copy/template");
|
||||
result = command.execute();
|
||||
if (result != null) {
|
||||
s_logger.warn("Error in linking err=" + result );
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -26,6 +26,7 @@ import com.cloud.agent.api.storage.UploadAnswer;
|
|||
import com.cloud.agent.api.storage.UploadCommand;
|
||||
import com.cloud.storage.Storage.ImageFormat;
|
||||
import com.cloud.storage.Upload.Status;
|
||||
import com.cloud.storage.resource.SecondaryStorageResource;
|
||||
import com.cloud.utils.component.Manager;
|
||||
|
||||
public interface UploadManager extends Manager {
|
||||
|
|
@ -70,7 +71,7 @@ public interface UploadManager extends Manager {
|
|||
* @param cmd cmd from server
|
||||
* @return answer representing status of upload.
|
||||
*/
|
||||
public UploadAnswer handleUploadCommand(UploadCommand cmd);
|
||||
public UploadAnswer handleUploadCommand(SecondaryStorageResource resource, UploadCommand cmd);
|
||||
|
||||
public String getPublicTemplateRepo();
|
||||
|
||||
|
|
|
|||
|
|
@ -44,6 +44,7 @@ import com.cloud.storage.Storage.ImageFormat;
|
|||
import com.cloud.storage.StorageLayer;
|
||||
import com.cloud.storage.Upload;
|
||||
import com.cloud.storage.UploadVO;
|
||||
import com.cloud.storage.resource.SecondaryStorageResource;
|
||||
import com.cloud.storage.template.TemplateUploader.Status;
|
||||
import com.cloud.storage.template.TemplateUploader.UploadCompleteCallback;
|
||||
import com.cloud.utils.NumbersUtil;
|
||||
|
|
@ -319,7 +320,7 @@ public class UploadManagerImpl implements UploadManager {
|
|||
}
|
||||
|
||||
@Override
|
||||
public UploadAnswer handleUploadCommand(UploadCommand cmd) {
|
||||
public UploadAnswer handleUploadCommand(SecondaryStorageResource resource, UploadCommand cmd) {
|
||||
s_logger.warn("Handling the upload " +cmd.getInstallPath() + " " + cmd.getId());
|
||||
if (cmd instanceof UploadProgressCommand) {
|
||||
return handleUploadProgressCmd((UploadProgressCommand) cmd);
|
||||
|
|
|
|||
|
|
@ -264,4 +264,7 @@ public interface AgentManager extends Manager {
|
|||
|
||||
boolean updateHostPassword(UpdateHostPasswordCmd upasscmd);
|
||||
|
||||
long sendToSecStorage(HostVO ssHost, Command cmd, Listener listener);
|
||||
|
||||
Answer sendToSecStorage(HostVO ssHost, Command cmd);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -65,6 +65,7 @@ import com.cloud.agent.api.StartupExternalLoadBalancerCommand;
|
|||
import com.cloud.agent.api.StartupProxyCommand;
|
||||
import com.cloud.agent.api.StartupPxeServerCommand;
|
||||
import com.cloud.agent.api.StartupRoutingCommand;
|
||||
import com.cloud.agent.api.StartupSecondaryStorageCommand;
|
||||
import com.cloud.agent.api.StartupStorageCommand;
|
||||
import com.cloud.agent.api.StartupTrafficMonitorCommand;
|
||||
import com.cloud.agent.api.UnsupportedAnswer;
|
||||
|
|
@ -501,6 +502,549 @@ public class AgentManagerImpl implements AgentManager, HandlerFactory, Manager {
|
|||
return attache;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<? extends Cluster> discoverCluster(AddClusterCmd cmd) throws IllegalArgumentException, DiscoveryException {
|
||||
Long dcId = cmd.getZoneId();
|
||||
Long podId = cmd.getPodId();
|
||||
String clusterName = cmd.getClusterName();
|
||||
String url = cmd.getUrl();
|
||||
String username = cmd.getUsername();
|
||||
String password = cmd.getPassword();
|
||||
|
||||
if(url != null) {
|
||||
url = URLDecoder.decode(url);
|
||||
}
|
||||
|
||||
URI uri = null;
|
||||
|
||||
// Check if the zone exists in the system
|
||||
DataCenterVO zone = _dcDao.findById(dcId);
|
||||
if (zone == null) {
|
||||
throw new InvalidParameterValueException("Can't find zone by id " + dcId);
|
||||
}
|
||||
|
||||
Account account = UserContext.current().getCaller();
|
||||
if (Grouping.AllocationState.Disabled == zone.getAllocationState() && !_accountMgr.isRootAdmin(account.getType())) {
|
||||
throw new PermissionDeniedException("Cannot perform this operation, Zone is currently disabled: " + dcId);
|
||||
}
|
||||
|
||||
// Check if the pod exists in the system
|
||||
if (podId != null) {
|
||||
if (_podDao.findById(podId) == null) {
|
||||
throw new InvalidParameterValueException("Can't find pod by id " + podId);
|
||||
}
|
||||
// check if pod belongs to the zone
|
||||
HostPodVO pod = _podDao.findById(podId);
|
||||
if (!Long.valueOf(pod.getDataCenterId()).equals(dcId)) {
|
||||
throw new InvalidParameterValueException("Pod " + podId + " doesn't belong to the zone " + dcId);
|
||||
}
|
||||
}
|
||||
|
||||
// Verify cluster information and create a new cluster if needed
|
||||
if (clusterName == null || clusterName.isEmpty()) {
|
||||
throw new InvalidParameterValueException("Please specify cluster name");
|
||||
}
|
||||
|
||||
if (cmd.getHypervisor() == null || cmd.getHypervisor().isEmpty()) {
|
||||
throw new InvalidParameterValueException("Please specify a hypervisor");
|
||||
}
|
||||
|
||||
Hypervisor.HypervisorType hypervisorType = Hypervisor.HypervisorType.getType(cmd.getHypervisor());
|
||||
if (hypervisorType == null) {
|
||||
s_logger.error("Unable to resolve " + cmd.getHypervisor() + " to a valid supported hypervisor type");
|
||||
throw new InvalidParameterValueException("Unable to resolve " + cmd.getHypervisor() + " to a supported ");
|
||||
}
|
||||
|
||||
Cluster.ClusterType clusterType = null;
|
||||
if (cmd.getClusterType() != null && !cmd.getClusterType().isEmpty()) {
|
||||
clusterType = Cluster.ClusterType.valueOf(cmd.getClusterType());
|
||||
}
|
||||
if (clusterType == null) {
|
||||
clusterType = Cluster.ClusterType.CloudManaged;
|
||||
}
|
||||
|
||||
Grouping.AllocationState allocationState = null;
|
||||
if (cmd.getAllocationState() != null && !cmd.getAllocationState().isEmpty()) {
|
||||
try {
|
||||
allocationState = Grouping.AllocationState.valueOf(cmd.getAllocationState());
|
||||
} catch (IllegalArgumentException ex) {
|
||||
throw new InvalidParameterValueException("Unable to resolve Allocation State '" + cmd.getAllocationState() + "' to a supported state");
|
||||
}
|
||||
}
|
||||
if (allocationState == null) {
|
||||
allocationState = Grouping.AllocationState.Enabled;
|
||||
}
|
||||
|
||||
Discoverer discoverer = getMatchingDiscover(hypervisorType);
|
||||
if (discoverer == null) {
|
||||
|
||||
throw new InvalidParameterValueException("Could not find corresponding resource manager for " + cmd.getHypervisor());
|
||||
}
|
||||
|
||||
List<ClusterVO> result = new ArrayList<ClusterVO>();
|
||||
|
||||
long clusterId = 0;
|
||||
ClusterVO cluster = new ClusterVO(dcId, podId, clusterName);
|
||||
cluster.setHypervisorType(cmd.getHypervisor());
|
||||
|
||||
cluster.setClusterType(clusterType);
|
||||
cluster.setAllocationState(allocationState);
|
||||
try {
|
||||
cluster = _clusterDao.persist(cluster);
|
||||
} catch (Exception e) {
|
||||
// no longer tolerate exception during the cluster creation phase
|
||||
throw new CloudRuntimeException("Unable to create cluster " + clusterName + " in pod " + podId + " and data center " + dcId, e);
|
||||
}
|
||||
clusterId = cluster.getId();
|
||||
result.add(cluster);
|
||||
|
||||
if (clusterType == Cluster.ClusterType.CloudManaged) {
|
||||
return result;
|
||||
}
|
||||
|
||||
// save cluster details for later cluster/host cross-checking
|
||||
Map<String, String> details = new HashMap<String, String>();
|
||||
details.put("url", url);
|
||||
details.put("username", username);
|
||||
details.put("password", password);
|
||||
_clusterDetailsDao.persist(cluster.getId(), details);
|
||||
|
||||
boolean success = false;
|
||||
try {
|
||||
try {
|
||||
uri = new URI(UriUtils.encodeURIComponent(url));
|
||||
if (uri.getScheme() == null) {
|
||||
throw new InvalidParameterValueException("uri.scheme is null " + url + ", add http:// as a prefix");
|
||||
} else if (uri.getScheme().equalsIgnoreCase("http")) {
|
||||
if (uri.getHost() == null || uri.getHost().equalsIgnoreCase("") || uri.getPath() == null || uri.getPath().equalsIgnoreCase("")) {
|
||||
throw new InvalidParameterValueException("Your host and/or path is wrong. Make sure it's of the format http://hostname/path");
|
||||
}
|
||||
}
|
||||
} catch (URISyntaxException e) {
|
||||
throw new InvalidParameterValueException(url + " is not a valid uri");
|
||||
}
|
||||
|
||||
List<HostVO> hosts = new ArrayList<HostVO>();
|
||||
Map<? extends ServerResource, Map<String, String>> resources = null;
|
||||
|
||||
try {
|
||||
resources = discoverer.find(dcId, podId, clusterId, uri, username, password);
|
||||
} catch (Exception e) {
|
||||
s_logger.info("Exception in external cluster discovery process with discoverer: " + discoverer.getName());
|
||||
}
|
||||
if (resources != null) {
|
||||
for (Map.Entry<? extends ServerResource, Map<String, String>> entry : resources.entrySet()) {
|
||||
ServerResource resource = entry.getKey();
|
||||
|
||||
// For Hyper-V, we are here means agent have already started and connected to management server
|
||||
if (hypervisorType == Hypervisor.HypervisorType.Hyperv) {
|
||||
break;
|
||||
}
|
||||
|
||||
AgentAttache attache = simulateStart(null, resource, entry.getValue(), true, null, null);
|
||||
if (attache != null) {
|
||||
hosts.add(_hostDao.findById(attache.getId()));
|
||||
}
|
||||
discoverer.postDiscovery(hosts, _nodeId);
|
||||
}
|
||||
s_logger.info("External cluster has been successfully discovered by " + discoverer.getName());
|
||||
success = true;
|
||||
return result;
|
||||
}
|
||||
|
||||
s_logger.warn("Unable to find the server resources at " + url);
|
||||
throw new DiscoveryException("Unable to add the external cluster");
|
||||
} catch (Throwable e) {
|
||||
s_logger.error("Unexpected exception ", e);
|
||||
throw new DiscoveryException("Unable to add the external cluster due to unhandled exception");
|
||||
} finally {
|
||||
if (!success) {
|
||||
_clusterDetailsDao.deleteDetails(clusterId);
|
||||
_clusterDao.remove(clusterId);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private Discoverer getMatchingDiscover(Hypervisor.HypervisorType hypervisorType) {
|
||||
Enumeration<Discoverer> en = _discoverers.enumeration();
|
||||
while (en.hasMoreElements()) {
|
||||
Discoverer discoverer = en.nextElement();
|
||||
if (discoverer.getHypervisorType() == hypervisorType) {
|
||||
return discoverer;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<? extends Host> discoverHosts(AddHostCmd cmd) throws IllegalArgumentException, DiscoveryException, InvalidParameterValueException {
|
||||
Long dcId = cmd.getZoneId();
|
||||
Long podId = cmd.getPodId();
|
||||
Long clusterId = cmd.getClusterId();
|
||||
String clusterName = cmd.getClusterName();
|
||||
String url = cmd.getUrl();
|
||||
String username = cmd.getUsername();
|
||||
String password = cmd.getPassword();
|
||||
Long memCapacity = cmd.getMemCapacity();
|
||||
Long cpuSpeed = cmd.getCpuSpeed();
|
||||
Long cpuNum = cmd.getCpuNum();
|
||||
String mac = cmd.getMac();
|
||||
List<String> hostTags = cmd.getHostTags();
|
||||
Map<String, String> bareMetalParams = new HashMap<String, String>();
|
||||
|
||||
dcId = _accountMgr.checkAccessAndSpecifyAuthority(UserContext.current().getCaller(), dcId);
|
||||
|
||||
// this is for standalone option
|
||||
if (clusterName == null && clusterId == null) {
|
||||
clusterName = "Standalone-" + url;
|
||||
}
|
||||
|
||||
if ( clusterId != null ) {
|
||||
ClusterVO cluster = _clusterDao.findById(clusterId);
|
||||
if ( cluster == null ) {
|
||||
throw new InvalidParameterValueException("can not fine cluster for clusterId " + clusterId);
|
||||
} else {
|
||||
if ( cluster.getGuid() == null ) {
|
||||
List<HostVO> hosts = _hostDao.listByCluster(clusterId);
|
||||
if ( ! hosts.isEmpty() ) {
|
||||
throw new CloudRuntimeException("Guid is not updated for cluster " + clusterId + " need to wait hosts in this cluster up");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (cmd.getHypervisor().equalsIgnoreCase(Hypervisor.HypervisorType.BareMetal.toString())) {
|
||||
if (memCapacity == null) {
|
||||
memCapacity = Long.valueOf(0);
|
||||
}
|
||||
if (cpuSpeed == null) {
|
||||
cpuSpeed = Long.valueOf(0);
|
||||
}
|
||||
if (cpuNum == null) {
|
||||
cpuNum = Long.valueOf(0);
|
||||
}
|
||||
if (mac == null) {
|
||||
mac = "unknown";
|
||||
}
|
||||
|
||||
bareMetalParams.put("cpuNum", cpuNum.toString());
|
||||
bareMetalParams.put("cpuCapacity", cpuSpeed.toString());
|
||||
bareMetalParams.put("memCapacity", memCapacity.toString());
|
||||
bareMetalParams.put("mac", mac);
|
||||
if (hostTags != null) {
|
||||
bareMetalParams.put("hostTag", hostTags.get(0));
|
||||
}
|
||||
}
|
||||
String allocationState = cmd.getAllocationState();
|
||||
if (allocationState == null) {
|
||||
allocationState = Host.HostAllocationState.Enabled.toString();
|
||||
}
|
||||
|
||||
return discoverHostsFull(dcId, podId, clusterId, clusterName, url, username, password, cmd.getHypervisor(), hostTags, bareMetalParams, allocationState);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<? extends Host> discoverHosts(AddSecondaryStorageCmd cmd) throws IllegalArgumentException, DiscoveryException, InvalidParameterValueException {
|
||||
Long dcId = cmd.getZoneId();
|
||||
String url = cmd.getUrl();
|
||||
return discoverHosts(dcId, null, null, null, url, null, null, "SecondaryStorage", null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<HostVO> discoverHosts(Long dcId, Long podId, Long clusterId, String clusterName, String url, String username, String password, String hypervisorType, List<String> hostTags)
|
||||
throws IllegalArgumentException, DiscoveryException, InvalidParameterValueException {
|
||||
return discoverHostsFull(dcId, podId, clusterId, clusterName, url, username, password, hypervisorType, hostTags, null, null);
|
||||
}
|
||||
|
||||
private List<HostVO> discoverHostsFull(Long dcId, Long podId, Long clusterId, String clusterName, String url, String username, String password, String hypervisorType, List<String> hostTags,
|
||||
Map<String, String> params, String allocationState) throws IllegalArgumentException, DiscoveryException, InvalidParameterValueException {
|
||||
URI uri = null;
|
||||
|
||||
// Check if the zone exists in the system
|
||||
DataCenterVO zone = _dcDao.findById(dcId);
|
||||
if (zone == null) {
|
||||
throw new InvalidParameterValueException("Can't find zone by id " + dcId);
|
||||
}
|
||||
|
||||
Account account = UserContext.current().getCaller();
|
||||
if (Grouping.AllocationState.Disabled == zone.getAllocationState() && !_accountMgr.isRootAdmin(account.getType())) {
|
||||
throw new PermissionDeniedException("Cannot perform this operation, Zone is currently disabled: " + dcId);
|
||||
}
|
||||
|
||||
// Check if the pod exists in the system
|
||||
if (podId != null) {
|
||||
if (_podDao.findById(podId) == null) {
|
||||
throw new InvalidParameterValueException("Can't find pod by id " + podId);
|
||||
}
|
||||
// check if pod belongs to the zone
|
||||
HostPodVO pod = _podDao.findById(podId);
|
||||
if (!Long.valueOf(pod.getDataCenterId()).equals(dcId)) {
|
||||
throw new InvalidParameterValueException("Pod " + podId + " doesn't belong to the zone " + dcId);
|
||||
}
|
||||
}
|
||||
|
||||
// Verify cluster information and create a new cluster if needed
|
||||
if (clusterName != null && clusterId != null) {
|
||||
throw new InvalidParameterValueException("Can't specify cluster by both id and name");
|
||||
}
|
||||
|
||||
if (hypervisorType == null || hypervisorType.isEmpty()) {
|
||||
throw new InvalidParameterValueException("Need to specify Hypervisor Type");
|
||||
}
|
||||
|
||||
if ((clusterName != null || clusterId != null) && podId == null) {
|
||||
throw new InvalidParameterValueException("Can't specify cluster without specifying the pod");
|
||||
}
|
||||
|
||||
if (clusterId != null) {
|
||||
if (_clusterDao.findById(clusterId) == null) {
|
||||
throw new InvalidParameterValueException("Can't find cluster by id " + clusterId);
|
||||
}
|
||||
}
|
||||
|
||||
if (clusterName != null) {
|
||||
ClusterVO cluster = new ClusterVO(dcId, podId, clusterName);
|
||||
cluster.setHypervisorType(hypervisorType);
|
||||
try {
|
||||
cluster = _clusterDao.persist(cluster);
|
||||
} catch (Exception e) {
|
||||
cluster = _clusterDao.findBy(clusterName, podId);
|
||||
if (cluster == null) {
|
||||
throw new CloudRuntimeException("Unable to create cluster " + clusterName + " in pod " + podId + " and data center " + dcId, e);
|
||||
}
|
||||
}
|
||||
clusterId = cluster.getId();
|
||||
}
|
||||
|
||||
try {
|
||||
uri = new URI(UriUtils.encodeURIComponent(url));
|
||||
if (uri.getScheme() == null) {
|
||||
throw new InvalidParameterValueException("uri.scheme is null " + url + ", add nfs:// as a prefix");
|
||||
} else if (uri.getScheme().equalsIgnoreCase("nfs")) {
|
||||
if (uri.getHost() == null || uri.getHost().equalsIgnoreCase("") || uri.getPath() == null || uri.getPath().equalsIgnoreCase("")) {
|
||||
throw new InvalidParameterValueException("Your host and/or path is wrong. Make sure it's of the format nfs://hostname/path");
|
||||
}
|
||||
}
|
||||
} catch (URISyntaxException e) {
|
||||
throw new InvalidParameterValueException(url + " is not a valid uri");
|
||||
}
|
||||
|
||||
List<HostVO> hosts = new ArrayList<HostVO>();
|
||||
s_logger.info("Trying to add a new host at " + url + " in data center " + dcId);
|
||||
Enumeration<Discoverer> en = _discoverers.enumeration();
|
||||
boolean isHypervisorTypeSupported = false;
|
||||
while (en.hasMoreElements()) {
|
||||
Discoverer discoverer = en.nextElement();
|
||||
if (params != null) {
|
||||
discoverer.putParam(params);
|
||||
}
|
||||
|
||||
if (!discoverer.matchHypervisor(hypervisorType)) {
|
||||
continue;
|
||||
}
|
||||
isHypervisorTypeSupported = true;
|
||||
Map<? extends ServerResource, Map<String, String>> resources = null;
|
||||
|
||||
try {
|
||||
resources = discoverer.find(dcId, podId, clusterId, uri, username, password);
|
||||
} catch (DiscoveredWithErrorException e) {
|
||||
throw e;
|
||||
} catch (Exception e) {
|
||||
s_logger.info("Exception in host discovery process with discoverer: " + discoverer.getName() + ", skip to another discoverer if there is any");
|
||||
}
|
||||
if (resources != null) {
|
||||
for (Map.Entry<? extends ServerResource, Map<String, String>> entry : resources.entrySet()) {
|
||||
ServerResource resource = entry.getKey();
|
||||
/*
|
||||
* For KVM, if we go to here, that means kvm agent is already connected to mgt svr.
|
||||
*/
|
||||
if (resource instanceof KvmDummyResourceBase) {
|
||||
Map<String, String> details = entry.getValue();
|
||||
String guid = details.get("guid");
|
||||
List<HostVO> kvmHosts = _hostDao.listBy(Host.Type.Routing, clusterId, podId, dcId);
|
||||
for (HostVO host : kvmHosts) {
|
||||
if (host.getGuid().equalsIgnoreCase(guid)) {
|
||||
hosts.add(host);
|
||||
return hosts;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
AgentAttache attache = simulateStart(null, resource, entry.getValue(), true, hostTags, allocationState);
|
||||
if (attache != null) {
|
||||
hosts.add(_hostDao.findById(attache.getId()));
|
||||
}
|
||||
discoverer.postDiscovery(hosts, _nodeId);
|
||||
|
||||
}
|
||||
s_logger.info("server resources successfully discovered by " + discoverer.getName());
|
||||
return hosts;
|
||||
}
|
||||
}
|
||||
if (!isHypervisorTypeSupported) {
|
||||
String msg = "Do not support HypervisorType " + hypervisorType + " for " + url;
|
||||
s_logger.warn(msg);
|
||||
throw new DiscoveryException(msg);
|
||||
}
|
||||
s_logger.warn("Unable to find the server resources at " + url);
|
||||
throw new DiscoveryException("Unable to add the host");
|
||||
}
|
||||
|
||||
@Override
|
||||
@DB
|
||||
public boolean deleteCluster(DeleteClusterCmd cmd) {
|
||||
Transaction txn = Transaction.currentTxn();
|
||||
try {
|
||||
txn.start();
|
||||
ClusterVO cluster = _clusterDao.lockRow(cmd.getId(), true);
|
||||
if (cluster == null) {
|
||||
if (s_logger.isDebugEnabled()) {
|
||||
s_logger.debug("Cluster: " + cmd.getId() + " does not even exist. Delete call is ignored.");
|
||||
}
|
||||
txn.rollback();
|
||||
return true;
|
||||
}
|
||||
|
||||
List<HostVO> hosts = _hostDao.listByCluster(cmd.getId());
|
||||
if (hosts.size() > 0) {
|
||||
if (s_logger.isDebugEnabled()) {
|
||||
s_logger.debug("Cluster: " + cmd.getId() + " still has hosts");
|
||||
}
|
||||
txn.rollback();
|
||||
return false;
|
||||
}
|
||||
|
||||
_clusterDao.remove(cmd.getId());
|
||||
|
||||
txn.commit();
|
||||
return true;
|
||||
} catch (Throwable t) {
|
||||
s_logger.error("Unable to delete cluster: " + cmd.getId(), t);
|
||||
txn.rollback();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@DB
|
||||
public Cluster updateCluster(Cluster clusterToUpdate, String clusterType, String hypervisor, String allocationState) {
|
||||
|
||||
ClusterVO cluster = (ClusterVO) clusterToUpdate;
|
||||
// Verify cluster information and update the cluster if needed
|
||||
boolean doUpdate = false;
|
||||
|
||||
if (hypervisor != null && !hypervisor.isEmpty()) {
|
||||
Hypervisor.HypervisorType hypervisorType = Hypervisor.HypervisorType.getType(hypervisor);
|
||||
if (hypervisorType == null) {
|
||||
s_logger.error("Unable to resolve " + hypervisor + " to a valid supported hypervisor type");
|
||||
throw new InvalidParameterValueException("Unable to resolve " + hypervisor + " to a supported type");
|
||||
} else {
|
||||
cluster.setHypervisorType(hypervisor);
|
||||
doUpdate = true;
|
||||
}
|
||||
}
|
||||
|
||||
Cluster.ClusterType newClusterType = null;
|
||||
if (clusterType != null && !clusterType.isEmpty()) {
|
||||
try {
|
||||
newClusterType = Cluster.ClusterType.valueOf(clusterType);
|
||||
} catch (IllegalArgumentException ex) {
|
||||
throw new InvalidParameterValueException("Unable to resolve " + clusterType + " to a supported type");
|
||||
}
|
||||
if (newClusterType == null) {
|
||||
s_logger.error("Unable to resolve " + clusterType + " to a valid supported cluster type");
|
||||
throw new InvalidParameterValueException("Unable to resolve " + clusterType + " to a supported type");
|
||||
} else {
|
||||
cluster.setClusterType(newClusterType);
|
||||
doUpdate = true;
|
||||
}
|
||||
}
|
||||
|
||||
Grouping.AllocationState newAllocationState = null;
|
||||
if (allocationState != null && !allocationState.isEmpty()) {
|
||||
try {
|
||||
newAllocationState = Grouping.AllocationState.valueOf(allocationState);
|
||||
} catch (IllegalArgumentException ex) {
|
||||
throw new InvalidParameterValueException("Unable to resolve Allocation State '" + allocationState + "' to a supported state");
|
||||
}
|
||||
if (newAllocationState == null) {
|
||||
s_logger.error("Unable to resolve " + allocationState + " to a valid supported allocation State");
|
||||
throw new InvalidParameterValueException("Unable to resolve " + allocationState + " to a supported state");
|
||||
} else {
|
||||
cluster.setAllocationState(newAllocationState);
|
||||
doUpdate = true;
|
||||
}
|
||||
}
|
||||
if (doUpdate) {
|
||||
Transaction txn = Transaction.currentTxn();
|
||||
try {
|
||||
txn.start();
|
||||
_clusterDao.update(cluster.getId(), cluster);
|
||||
txn.commit();
|
||||
} catch (Exception e) {
|
||||
s_logger.error("Unable to update cluster due to " + e.getMessage(), e);
|
||||
throw new CloudRuntimeException("Failed to update cluster. Please contact Cloud Support.");
|
||||
}
|
||||
}
|
||||
return cluster;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Cluster getCluster(Long clusterId) {
|
||||
return _clusterDao.findById(clusterId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Answer sendToSecStorage(HostVO ssHost, Command cmd) {
|
||||
if( ssHost.getType() == Host.Type.LocalSecondaryStorage ) {
|
||||
return easySend(ssHost.getId(), cmd);
|
||||
} else if ( ssHost.getType() == Host.Type.SecondaryStorage) {
|
||||
return sendToSSVM(ssHost.getDataCenterId(), cmd);
|
||||
} else {
|
||||
String msg = "do not support Secondary Storage type " + ssHost.getType();
|
||||
s_logger.warn(msg);
|
||||
return new Answer(cmd, false, msg);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public long sendToSecStorage(HostVO ssHost, Command cmd, Listener listener) {
|
||||
if( ssHost.getType() == Host.Type.LocalSecondaryStorage ) {
|
||||
return gatherStats(ssHost.getId(), cmd, listener);
|
||||
} else if ( ssHost.getType() == Host.Type.SecondaryStorage) {
|
||||
return sendToSSVM(ssHost.getDataCenterId(), cmd, listener);
|
||||
} else {
|
||||
s_logger.warn("do not support Secondary Storage type " + ssHost.getType());
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
private long sendToSSVM(final long dcId, final Command cmd, final Listener listener) {
|
||||
List<HostVO> ssAHosts = _hostDao.listByTypeDataCenter(Host.Type.SecondaryStorageVM, dcId);
|
||||
if (ssAHosts == null || ssAHosts.isEmpty() ) {
|
||||
return -1;
|
||||
}
|
||||
int size = ssAHosts.size();
|
||||
Random rn = new Random(System.currentTimeMillis());
|
||||
HostVO ssAhost = ssAHosts.get(rn.nextInt(size));
|
||||
try {
|
||||
return send(ssAhost.getId(), new Commands(cmd), listener);
|
||||
} catch (final AgentUnavailableException e) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
private Answer sendToSSVM(final long dcId, final Command cmd) {
|
||||
List<HostVO> ssAHosts = _hostDao.listByTypeDataCenter(Host.Type.SecondaryStorageVM, dcId);
|
||||
if (ssAHosts == null || ssAHosts.isEmpty() ) {
|
||||
return new Answer(cmd, false, "can not find secondary storage VM agent for data center " + dcId);
|
||||
}
|
||||
int size = ssAHosts.size();
|
||||
Random rn = new Random(System.currentTimeMillis());
|
||||
HostVO ssAhost = ssAHosts.get(rn.nextInt(size));
|
||||
return easySend(ssAhost.getId(), cmd);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Answer sendTo(Long dcId, HypervisorType type, Command cmd) {
|
||||
|
|
@ -889,6 +1433,9 @@ public class AgentManagerImpl implements AgentManager, HandlerFactory, Manager {
|
|||
return seq;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public long gatherStats(final Long hostId, final Command cmd, final Listener listener) {
|
||||
try {
|
||||
|
|
@ -1738,9 +2285,13 @@ public class AgentManagerImpl implements AgentManager, HandlerFactory, Manager {
|
|||
if (resource != null && resource instanceof DummySecondaryStorageResource) {
|
||||
resource = null;
|
||||
}
|
||||
}else if (ssCmd.getResourceType() == Storage.StorageResourceType.LOCAL_SECONDARY_STORAGE) {
|
||||
type = Host.Type.LocalSecondaryStorage;
|
||||
|
||||
} else {
|
||||
type = Host.Type.Storage;
|
||||
}
|
||||
|
||||
final Map<String, String> hostDetails = ssCmd.getHostDetails();
|
||||
if (hostDetails != null) {
|
||||
if (details != null) {
|
||||
|
|
@ -1761,10 +2312,10 @@ public class AgentManagerImpl implements AgentManager, HandlerFactory, Manager {
|
|||
details = hostDetails;
|
||||
}
|
||||
}
|
||||
} else if (startup instanceof StartupSecondaryStorageCommand) {
|
||||
type = Host.Type.SecondaryStorageVM;
|
||||
} else if (startup instanceof StartupProxyCommand) {
|
||||
type = Host.Type.ConsoleProxy;
|
||||
} else if (startup instanceof StartupRoutingCommand) {
|
||||
type = Host.Type.Routing;
|
||||
} else if (startup instanceof StartupExternalFirewallCommand) {
|
||||
type = Host.Type.ExternalFirewall;
|
||||
} else if (startup instanceof StartupExternalLoadBalancerCommand) {
|
||||
|
|
|
|||
|
|
@ -169,4 +169,8 @@ public interface HostDao extends GenericDao<HostVO, Long> {
|
|||
boolean directConnect(HostVO host, long msId, boolean secondConnect);
|
||||
|
||||
HostVO findTrafficMonitorHost();
|
||||
|
||||
List<HostVO> listLocalSecondaryStorageHosts();
|
||||
|
||||
List<HostVO> listLocalSecondaryStorageHosts(long dataCenterId);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -54,6 +54,8 @@ import com.cloud.utils.db.SearchCriteria.Op;
|
|||
import com.cloud.utils.db.Transaction;
|
||||
import com.cloud.utils.db.UpdateBuilder;
|
||||
import com.cloud.utils.exception.CloudRuntimeException;
|
||||
|
||||
import edu.emory.mathcs.backport.java.util.Collections;
|
||||
|
||||
@Local(value = { HostDao.class }) @DB(txn=false)
|
||||
@TableGenerator(name="host_req_sq", table="op_host", pkColumnName="id", valueColumnName="sequence", allocationSize=1)
|
||||
|
|
@ -271,28 +273,51 @@ public class HostDaoImpl extends GenericDaoBase<HostVO, Long> implements HostDao
|
|||
}
|
||||
|
||||
@Override
|
||||
public HostVO findSecondaryStorageHost(long dcId) {
|
||||
SearchCriteria<HostVO> sc = TypeDcSearch.create();
|
||||
sc.setParameters("type", Host.Type.SecondaryStorage);
|
||||
sc.setParameters("dc", dcId);
|
||||
List<HostVO> storageHosts = listBy(sc);
|
||||
|
||||
if (storageHosts == null || storageHosts.size() < 1) {
|
||||
return null;
|
||||
} else {
|
||||
return storageHosts.get(0);
|
||||
}
|
||||
public HostVO findSecondaryStorageHost(long dcId) {
|
||||
SearchCriteria<HostVO> sc = TypeDcSearch.create();
|
||||
sc.setParameters("type", Host.Type.SecondaryStorage);
|
||||
sc.setParameters("dc", dcId);
|
||||
List<HostVO> storageHosts = listBy(sc);
|
||||
if (storageHosts == null || storageHosts.size() < 1) {
|
||||
return null;
|
||||
} else {
|
||||
Collections.shuffle(storageHosts);
|
||||
return storageHosts.get(0);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<HostVO> listSecondaryStorageHosts() {
|
||||
SearchCriteria<HostVO> sc = TypeSearch.create();
|
||||
sc.setParameters("type", Host.Type.SecondaryStorage);
|
||||
List<HostVO> secondaryStorageHosts = listIncludingRemovedBy(sc);
|
||||
|
||||
return secondaryStorageHosts;
|
||||
}
|
||||
|
||||
SearchCriteria<HostVO> sc = createSearchCriteria();
|
||||
sc.addAnd("type", SearchCriteria.Op.EQ, Host.Type.SecondaryStorage);
|
||||
return search(sc, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<HostVO> listSecondaryStorageHosts(long dataCenterId) {
|
||||
SearchCriteria<HostVO> sc = createSearchCriteria();
|
||||
sc.addAnd("dataCenterId", SearchCriteria.Op.EQ, dataCenterId);
|
||||
sc.addAnd("type", SearchCriteria.Op.EQ, Host.Type.SecondaryStorage);
|
||||
return search(sc, null);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<HostVO> listLocalSecondaryStorageHosts() {
|
||||
SearchCriteria<HostVO> sc = createSearchCriteria();
|
||||
sc.addAnd("type", SearchCriteria.Op.EQ, Host.Type.LocalSecondaryStorage);
|
||||
return search(sc, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<HostVO> listLocalSecondaryStorageHosts(long dataCenterId) {
|
||||
SearchCriteria<HostVO> sc = createSearchCriteria();
|
||||
sc.addAnd("dataCenterId", SearchCriteria.Op.EQ, dataCenterId);
|
||||
sc.addAnd("type", SearchCriteria.Op.EQ, Host.Type.LocalSecondaryStorage);
|
||||
return search(sc, null);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<HostVO> findDirectlyConnectedHosts() {
|
||||
SearchCriteria<HostVO> sc = DirectlyConnectedSearch.create();
|
||||
|
|
|
|||
|
|
@ -248,17 +248,11 @@ public class StatsCollector {
|
|||
class StorageCollector implements Runnable {
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
SearchCriteria<HostVO> sc = _hostDao.createSearchCriteria();
|
||||
ConcurrentHashMap<Long, StorageStats> storageStats = new ConcurrentHashMap<Long, StorageStats>();
|
||||
List<HostVO> hosts = _hostDao.search(sc, null);
|
||||
|
||||
sc.addAnd("status", SearchCriteria.Op.EQ, Status.Up.toString());
|
||||
sc.addAnd("type", SearchCriteria.Op.EQ, Host.Type.SecondaryStorage.toString());
|
||||
|
||||
hosts = _hostDao.search(sc, null);
|
||||
try {
|
||||
List<HostVO> hosts = _hostDao.listSecondaryStorageHosts();
|
||||
ConcurrentHashMap<Long, StorageStats> storageStats = new ConcurrentHashMap<Long, StorageStats>();
|
||||
for (HostVO host : hosts) {
|
||||
GetStorageStatsCommand command = new GetStorageStatsCommand(host.getGuid());
|
||||
GetStorageStatsCommand command = new GetStorageStatsCommand(host.getStorageUrl());
|
||||
long hostId = host.getId();
|
||||
Answer answer = _agentMgr.easySend(hostId, command);
|
||||
if (answer != null && answer.getResult()) {
|
||||
|
|
|
|||
|
|
@ -182,6 +182,7 @@ import com.cloud.vm.dao.DomainRouterDao;
|
|||
import com.cloud.vm.dao.SecondaryStorageVmDao;
|
||||
import com.cloud.vm.dao.UserVmDao;
|
||||
import com.cloud.vm.dao.VMInstanceDao;
|
||||
import java.util.Random;
|
||||
|
||||
@Local(value = { StorageManager.class, StorageService.class })
|
||||
public class StorageManagerImpl implements StorageManager, StorageService, Manager, ClusterManagerListener {
|
||||
|
|
@ -221,6 +222,8 @@ public class StorageManagerImpl implements StorageManager, StorageService, Manag
|
|||
@Inject
|
||||
protected SnapshotDao _snapshotDao;
|
||||
@Inject
|
||||
protected SnapshotManager _snapMgr;
|
||||
@Inject
|
||||
protected SnapshotPolicyDao _snapshotPolicyDao;
|
||||
@Inject
|
||||
protected StoragePoolHostDao _storagePoolHostDao;
|
||||
|
|
@ -590,7 +593,7 @@ public class StorageManagerImpl implements StorageManager, StorageService, Manag
|
|||
Long volumeId = snapshot.getVolumeId();
|
||||
String primaryStoragePoolNameLabel = pool.getUuid(); // pool's uuid is actually the namelabel.
|
||||
Long dcId = snapshot.getDataCenterId();
|
||||
String secondaryStoragePoolUrl = getSecondaryStorageURL(dcId);
|
||||
String secondaryStoragePoolUrl = _snapMgr.getSecondaryStorageURL(snapshot);
|
||||
long accountId = snapshot.getAccountId();
|
||||
|
||||
String backedUpSnapshotUuid = snapshot.getBackupSnapshotId();
|
||||
|
|
@ -928,7 +931,7 @@ public class StorageManagerImpl implements StorageManager, StorageService, Manag
|
|||
@Override
|
||||
public String getSecondaryStorageURL(long zoneId) {
|
||||
// Determine the secondary storage URL
|
||||
HostVO secondaryStorageHost = _hostDao.findSecondaryStorageHost(zoneId);
|
||||
HostVO secondaryStorageHost = getSecondaryStorageHost(zoneId);
|
||||
|
||||
if (secondaryStorageHost == null) {
|
||||
return null;
|
||||
|
|
@ -939,7 +942,15 @@ public class StorageManagerImpl implements StorageManager, StorageService, Manag
|
|||
|
||||
@Override
|
||||
public HostVO getSecondaryStorageHost(long zoneId) {
|
||||
return _hostDao.findSecondaryStorageHost(zoneId);
|
||||
List<HostVO> hosts = _hostDao.listSecondaryStorageHosts(zoneId);
|
||||
if( hosts == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
int size = hosts.size();
|
||||
Random rn = new Random();
|
||||
int index = rn.nextInt(size);
|
||||
return hosts.get(index);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -1884,7 +1895,7 @@ public class StorageManagerImpl implements StorageManager, StorageService, Manag
|
|||
String installPath = destroyedTemplateHostVO.getInstallPath();
|
||||
|
||||
if (installPath != null) {
|
||||
Answer answer = _agentMgr.easySend(hostId, new DeleteTemplateCommand(destroyedTemplateHostVO.getInstallPath()));
|
||||
Answer answer = _agentMgr.sendToSecStorage(secondaryStorageHost, new DeleteTemplateCommand(secondaryStorageHost.getStorageUrl(),destroyedTemplateHostVO.getInstallPath()));
|
||||
|
||||
if (answer == null || !answer.getResult()) {
|
||||
s_logger.debug("Failed to delete " + destroyedTemplateHostVO + " due to " + ((answer == null) ? "answer is null" : answer.getDetails()));
|
||||
|
|
|
|||
|
|
@ -35,5 +35,6 @@ public interface SnapshotDao extends GenericDao<SnapshotVO, Long> {
|
|||
List<SnapshotVO> listByBackupUuid(long volumeId, String backupUuid);
|
||||
long updateSnapshotVersion(long volumeId, String from, String to);
|
||||
List<SnapshotVO> listByVolumeIdVersion(long volumeId, String version);
|
||||
Long getSecHostId(long volumeId);
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -39,6 +39,7 @@ public class SnapshotDaoImpl extends GenericDaoBase<SnapshotVO, Long> implements
|
|||
public static final Logger s_logger = Logger.getLogger(SnapshotDaoImpl.class.getName());
|
||||
private static final String GET_LAST_SNAPSHOT = "SELECT id FROM snapshots where volume_id = ? AND id != ? AND path IS NOT NULL ORDER BY created DESC";
|
||||
private static final String UPDATE_SNAPSHOT_VERSION = "UPDATE snapshots SET version = ? WHERE volume_id = ? AND version = ?";
|
||||
private static final String GET_SECHOST_ID = "SELECT sechost_id FROM snapshots where volume_id = ? AND backup_snap_id IS NOT NULL AND sechost_id IS NOT NULL LIMIT 1";
|
||||
|
||||
private final SearchBuilder<SnapshotVO> VolumeIdSearch;
|
||||
private final SearchBuilder<SnapshotVO> VolumeIdTypeSearch;
|
||||
|
|
@ -129,6 +130,23 @@ public class SnapshotDaoImpl extends GenericDaoBase<SnapshotVO, Long> implements
|
|||
|
||||
}
|
||||
|
||||
@Override
|
||||
public Long getSecHostId(long volumeId) {
|
||||
|
||||
Transaction txn = Transaction.currentTxn();
|
||||
PreparedStatement pstmt = null;
|
||||
String sql = GET_SECHOST_ID;
|
||||
try {
|
||||
pstmt = txn.prepareAutoCloseStatement(sql);
|
||||
pstmt.setLong(1, volumeId);
|
||||
ResultSet rs = pstmt.executeQuery();
|
||||
if (rs.next()) {
|
||||
return rs.getLong(1);
|
||||
}
|
||||
} catch (Exception ex) {
|
||||
}
|
||||
return null;
|
||||
}
|
||||
@Override
|
||||
public long getLastSnapshot(long volumeId, long snapId) {
|
||||
Transaction txn = Transaction.currentTxn();
|
||||
|
|
|
|||
|
|
@ -33,6 +33,7 @@ import com.cloud.agent.api.Answer;
|
|||
import com.cloud.agent.api.Command;
|
||||
import com.cloud.agent.api.StartupCommand;
|
||||
import com.cloud.agent.api.StartupRoutingCommand;
|
||||
import com.cloud.agent.api.StartupSecondaryStorageCommand;
|
||||
import com.cloud.agent.api.StartupStorageCommand;
|
||||
import com.cloud.agent.api.storage.DownloadAnswer;
|
||||
import com.cloud.agent.api.storage.DownloadCommand;
|
||||
|
|
@ -48,6 +49,7 @@ import com.cloud.storage.VMTemplateStorageResourceAssoc.Status;
|
|||
import com.cloud.storage.VMTemplateVO;
|
||||
import com.cloud.storage.dao.VMTemplateHostDao;
|
||||
import com.cloud.storage.download.DownloadState.DownloadEvent;
|
||||
import com.cloud.storage.template.TemplateInfo;
|
||||
import com.cloud.utils.exception.CloudRuntimeException;
|
||||
|
||||
/**
|
||||
|
|
@ -277,25 +279,16 @@ public class DownloadListener implements Listener {
|
|||
|
||||
@Override
|
||||
public void processConnect(HostVO agent, StartupCommand cmd) throws ConnectionException {
|
||||
if (!((cmd instanceof StartupStorageCommand) || (cmd instanceof StartupRoutingCommand))) {
|
||||
return;
|
||||
}
|
||||
if (cmd instanceof StartupRoutingCommand) {
|
||||
downloadMonitor.handleSysTemplateDownload(agent);
|
||||
} else {
|
||||
if (cmd.getGuid().startsWith("iso:")) {
|
||||
//FIXME: do not download template for ISO secondary
|
||||
return;
|
||||
}
|
||||
|
||||
long agentId = agent.getId();
|
||||
|
||||
} else if ( cmd instanceof StartupStorageCommand) {
|
||||
StartupStorageCommand storage = (StartupStorageCommand)cmd;
|
||||
if (storage.getResourceType() == Storage.StorageResourceType.STORAGE_HOST ||
|
||||
storage.getResourceType() == Storage.StorageResourceType.SECONDARY_STORAGE )
|
||||
{
|
||||
downloadMonitor.handleTemplateSync(agentId, storage.getTemplateInfo());
|
||||
}
|
||||
if( storage.getResourceType() == Storage.StorageResourceType.SECONDARY_STORAGE ) {
|
||||
downloadMonitor.addSystemVMTemplatesToHost(agent, storage.getTemplateInfo());
|
||||
downloadMonitor.handleTemplateSync(agent.getId());
|
||||
}
|
||||
} else if ( cmd instanceof StartupSecondaryStorageCommand ) {
|
||||
downloadMonitor.handleTemplateSync(agent.getDataCenterId());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -38,7 +38,7 @@ public interface DownloadMonitor extends Manager{
|
|||
|
||||
public void cancelAllDownloads(Long templateId);
|
||||
|
||||
public void handleTemplateSync(long id, Map<String, TemplateInfo> templateInfo);
|
||||
public void handleTemplateSync(HostVO host);
|
||||
|
||||
public void copyTemplate(VMTemplateVO template, HostVO sourceServer, HostVO destServer)
|
||||
throws StorageUnavailableException;
|
||||
|
|
@ -46,4 +46,8 @@ public interface DownloadMonitor extends Manager{
|
|||
/*When new host added, take a look at if there are templates needed to be downloaded for the same hypervisor as the host*/
|
||||
void handleSysTemplateDownload(HostVO hostId);
|
||||
|
||||
void handleTemplateSync(long dcId);
|
||||
|
||||
void addSystemVMTemplatesToHost(HostVO host, Map<String, TemplateInfo> templateInfos);
|
||||
|
||||
}
|
||||
|
|
@ -19,9 +19,11 @@ package com.cloud.storage.download;
|
|||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Random;
|
||||
import java.util.Set;
|
||||
import java.util.Timer;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
|
@ -32,10 +34,13 @@ import org.apache.log4j.Logger;
|
|||
|
||||
import com.cloud.agent.AgentManager;
|
||||
import com.cloud.agent.Listener;
|
||||
import com.cloud.agent.api.Answer;
|
||||
import com.cloud.agent.api.Command;
|
||||
import com.cloud.agent.api.storage.DeleteTemplateCommand;
|
||||
import com.cloud.agent.api.storage.DownloadCommand;
|
||||
import com.cloud.agent.api.storage.DownloadProgressCommand;
|
||||
import com.cloud.agent.api.storage.ListTemplateAnswer;
|
||||
import com.cloud.agent.api.storage.ListTemplateCommand;
|
||||
import com.cloud.agent.api.storage.DownloadProgressCommand.RequestType;
|
||||
import com.cloud.alert.AlertManager;
|
||||
import com.cloud.configuration.dao.ConfigurationDao;
|
||||
|
|
@ -101,8 +106,6 @@ public class DownloadMonitorImpl implements DownloadMonitor {
|
|||
@Inject
|
||||
AlertManager _alertMgr;
|
||||
|
||||
@Inject
|
||||
HostDao _serverDao = null;
|
||||
@Inject
|
||||
private final DataCenterDao _dcDao = null;
|
||||
@Inject
|
||||
|
|
@ -133,7 +136,6 @@ public class DownloadMonitorImpl implements DownloadMonitor {
|
|||
final Map<VMTemplateHostVO, DownloadListener> _listenerMap = new ConcurrentHashMap<VMTemplateHostVO, DownloadListener>();
|
||||
|
||||
|
||||
|
||||
public long send(Long hostId, Command cmd, Listener listener) {
|
||||
return _agentMgr.gatherStats(hostId, cmd, listener);
|
||||
}
|
||||
|
|
@ -229,7 +231,7 @@ public class DownloadMonitorImpl implements DownloadMonitor {
|
|||
if(destTmpltHost != null) {
|
||||
start();
|
||||
|
||||
DownloadCommand dcmd = new DownloadCommand(url, template.getUniqueName(), template.getFormat(), template.isRequiresHvm(), template.getAccountId(), template.getId(), template.getDisplayText(), template.getChecksum(), TemplateConstants.DEFAULT_HTTP_AUTH_USER, _copyAuthPasswd, maxTemplateSizeInBytes);
|
||||
DownloadCommand dcmd = new DownloadCommand(destServer.getStorageUrl(), url, template, TemplateConstants.DEFAULT_HTTP_AUTH_USER, _copyAuthPasswd, maxTemplateSizeInBytes);
|
||||
DownloadListener dl = downloadJobExists?_listenerMap.get(destTmpltHost):null;
|
||||
if (dl == null) {
|
||||
dl = new DownloadListener(destServer, template, _timer, _vmTemplateHostDao, destTmpltHost.getId(), this, dcmd);
|
||||
|
|
@ -241,7 +243,7 @@ public class DownloadMonitorImpl implements DownloadMonitor {
|
|||
|
||||
_listenerMap.put(destTmpltHost, dl);
|
||||
|
||||
long result = send(destServer.getId(), dcmd, dl);
|
||||
long result = _agentMgr.sendToSecStorage(destServer, dcmd, dl);
|
||||
if (result == -1) {
|
||||
s_logger.warn("Unable to start /resume COPY of template " + template.getUniqueName() + " to " + destServer.getName());
|
||||
dl.setDisconnected();
|
||||
|
|
@ -294,10 +296,10 @@ public class DownloadMonitorImpl implements DownloadMonitor {
|
|||
}
|
||||
|
||||
Long maxTemplateSizeInBytes = getMaxTemplateSizeInBytes();
|
||||
|
||||
String url = sserver.getStorageUrl();
|
||||
if(vmTemplateHost != null) {
|
||||
start();
|
||||
DownloadCommand dcmd = new DownloadCommand(template, maxTemplateSizeInBytes);
|
||||
DownloadCommand dcmd = new DownloadCommand(url, template, maxTemplateSizeInBytes);
|
||||
dcmd.setUrl(vmTemplateHost.getDownloadUrl());
|
||||
if (vmTemplateHost.isCopy()) {
|
||||
dcmd.setCreds(TemplateConstants.DEFAULT_HTTP_AUTH_USER, _copyAuthPasswd);
|
||||
|
|
@ -310,7 +312,7 @@ public class DownloadMonitorImpl implements DownloadMonitor {
|
|||
|
||||
_listenerMap.put(vmTemplateHost, dl);
|
||||
|
||||
long result = send(sserver.getId(), dcmd, dl);
|
||||
long result = _agentMgr.sendToSecStorage(sserver, dcmd, dl);
|
||||
if (result == -1) {
|
||||
s_logger.warn("Unable to start /resume download of template " + template.getUniqueName() + " to " + sserver.getName());
|
||||
dl.setDisconnected();
|
||||
|
|
@ -323,32 +325,29 @@ public class DownloadMonitorImpl implements DownloadMonitor {
|
|||
|
||||
@Override
|
||||
public boolean downloadTemplateToStorage(Long templateId, Long zoneId) {
|
||||
if (isTemplateUpdateable(templateId)) {
|
||||
List<DataCenterVO> dcs = new ArrayList<DataCenterVO>();
|
||||
|
||||
if (zoneId == null) {
|
||||
dcs.addAll(_dcDao.listAllIncludingRemoved());
|
||||
} else {
|
||||
dcs.add(_dcDao.findById(zoneId));
|
||||
}
|
||||
|
||||
for (DataCenterVO dc: dcs) {
|
||||
initiateTemplateDownload(templateId, dc.getId());
|
||||
}
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
List<DataCenterVO> dcs = new ArrayList<DataCenterVO>();
|
||||
if (zoneId == null) {
|
||||
dcs.addAll(_dcDao.listAll());
|
||||
} else {
|
||||
dcs.add(_dcDao.findById(zoneId));
|
||||
}
|
||||
for ( DataCenterVO dc : dcs ) {
|
||||
List<HostVO> ssHosts = _hostDao.listBy(Host.Type.SecondaryStorage, dc.getId());
|
||||
for ( HostVO ssHost : ssHosts ) {
|
||||
if (isTemplateUpdateable(ssHost.getId(), templateId)) {
|
||||
|
||||
initiateTemplateDownload(templateId, ssHost);
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private void initiateTemplateDownload(Long templateId, Long dataCenterId) {
|
||||
private void initiateTemplateDownload(Long templateId, HostVO ssHost) {
|
||||
VMTemplateVO template = _templateDao.findById(templateId);
|
||||
if (template != null && (template.getUrl() != null)) {
|
||||
//find all storage hosts and tell them to initiate download
|
||||
List<HostVO> storageServers = _serverDao.listByTypeDataCenter(Host.Type.SecondaryStorage, dataCenterId);
|
||||
for (HostVO sserver: storageServers) {
|
||||
downloadTemplateToStorage(template, sserver);
|
||||
}
|
||||
downloadTemplateToStorage(template, ssHost);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -428,47 +427,104 @@ public class DownloadMonitorImpl implements DownloadMonitor {
|
|||
if (ssHosts == null || ssHosts.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
HostVO sshost = ssHosts.get(0);
|
||||
/*Download all the templates in zone with the same hypervisortype*/
|
||||
|
||||
for ( HostVO ssHost : ssHosts) {
|
||||
List<VMTemplateVO> rtngTmplts = _templateDao.listAllSystemVMTemplates();
|
||||
List<VMTemplateVO> defaultBuiltin = _templateDao.listDefaultBuiltinTemplates();
|
||||
|
||||
|
||||
for (VMTemplateVO rtngTmplt : rtngTmplts) {
|
||||
if (rtngTmplt.getHypervisorType() == hostHyper) {
|
||||
toBeDownloaded.add(rtngTmplt);
|
||||
}
|
||||
}
|
||||
|
||||
for (VMTemplateVO builtinTmplt : defaultBuiltin) {
|
||||
if (builtinTmplt.getHypervisorType() == hostHyper) {
|
||||
toBeDownloaded.add(builtinTmplt);
|
||||
}
|
||||
}
|
||||
|
||||
for (VMTemplateVO template: toBeDownloaded) {
|
||||
VMTemplateHostVO tmpltHost = _vmTemplateHostDao.findByHostTemplate(ssHost.getId(), template.getId());
|
||||
if (tmpltHost == null || tmpltHost.getDownloadState() != Status.DOWNLOADED) {
|
||||
downloadTemplateToStorage(template, ssHost);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addSystemVMTemplatesToHost(HostVO host, Map<String, TemplateInfo> templateInfos){
|
||||
if ( templateInfos == null ) {
|
||||
return;
|
||||
}
|
||||
Long hostId = host.getId();
|
||||
List<VMTemplateVO> rtngTmplts = _templateDao.listAllSystemVMTemplates();
|
||||
List<VMTemplateVO> defaultBuiltin = _templateDao.listDefaultBuiltinTemplates();
|
||||
|
||||
|
||||
for (VMTemplateVO rtngTmplt : rtngTmplts) {
|
||||
if (rtngTmplt.getHypervisorType() == hostHyper) {
|
||||
toBeDownloaded.add(rtngTmplt);
|
||||
for ( VMTemplateVO tmplt : rtngTmplts ) {
|
||||
TemplateInfo tmpltInfo = templateInfos.get(tmplt.getUniqueName());
|
||||
if ( tmpltInfo == null ) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
for (VMTemplateVO builtinTmplt : defaultBuiltin) {
|
||||
if (builtinTmplt.getHypervisorType() == hostHyper) {
|
||||
toBeDownloaded.add(builtinTmplt);
|
||||
}
|
||||
}
|
||||
|
||||
for (VMTemplateVO template: toBeDownloaded) {
|
||||
VMTemplateHostVO tmpltHost = _vmTemplateHostDao.findByHostTemplate(sshost.getId(), template.getId());
|
||||
if (tmpltHost == null || tmpltHost.getDownloadState() != Status.DOWNLOADED) {
|
||||
if (_vmTemplateZoneDao.findByZoneTemplate(sshost.getDataCenterId(), template.getId()) == null) {
|
||||
_templateDao.addTemplateToZone(template, sshost.getDataCenterId());
|
||||
}
|
||||
downloadTemplateToStorage(template, sshost);
|
||||
VMTemplateHostVO tmpltHost = _vmTemplateHostDao.findByHostTemplate(hostId, tmplt.getId());
|
||||
if ( tmpltHost == null ) {
|
||||
tmpltHost = new VMTemplateHostVO(hostId, tmplt.getId(), new Date(), 100, Status.DOWNLOADED, null, null, null, tmpltInfo.getInstallPath(), tmplt.getUrl());
|
||||
tmpltHost.setSize(tmpltInfo.getSize());
|
||||
tmpltHost.setPhysicalSize(tmpltInfo.getPhysicalSize());
|
||||
_vmTemplateHostDao.persist(tmpltHost);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleTemplateSync(long dcId) {
|
||||
List<HostVO> ssHosts = _hostDao.listSecondaryStorageHosts(dcId);
|
||||
for ( HostVO ssHost : ssHosts ) {
|
||||
Long hostId = ssHost.getId();
|
||||
List<VMTemplateHostVO> ths = _vmTemplateHostDao.listByHostId(hostId);
|
||||
Map<String, TemplateInfo> templateInfos = new HashMap<String, TemplateInfo>();
|
||||
for ( VMTemplateHostVO th : ths ) {
|
||||
String tname = _templateDao.findById(th.getTemplateId()).getUniqueName();
|
||||
templateInfos.put(tname, null);
|
||||
}
|
||||
handleTemplateSync(ssHost);
|
||||
}
|
||||
}
|
||||
|
||||
private Map<String, TemplateInfo> listTemplate(HostVO ssHost) {
|
||||
ListTemplateCommand cmd = new ListTemplateCommand(ssHost.getStorageUrl());
|
||||
Answer answer = _agentMgr.sendToSecStorage(ssHost, cmd);
|
||||
if (answer != null && answer.getResult()) {
|
||||
ListTemplateAnswer tanswer = (ListTemplateAnswer)answer;
|
||||
return tanswer.getTemplateInfo();
|
||||
} else {
|
||||
if (s_logger.isDebugEnabled()) {
|
||||
s_logger.debug("can not list template for secondary storage host " + ssHost.getId());
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleTemplateSync(long sserverId, Map<String, TemplateInfo> templateInfos) {
|
||||
HostVO storageHost = _serverDao.findById(sserverId);
|
||||
if (storageHost == null) {
|
||||
public void handleTemplateSync(HostVO ssHost) {
|
||||
Long sserverId = ssHost.getId();
|
||||
if (ssHost == null) {
|
||||
s_logger.warn("Huh? Agent id " + sserverId + " does not correspond to a row in hosts table?");
|
||||
return;
|
||||
}
|
||||
long zoneId = storageHost.getDataCenterId();
|
||||
}
|
||||
if ( ssHost.getType() != Host.Type.SecondaryStorage ) {
|
||||
s_logger.warn("Huh? Agent id " + sserverId + " is not secondary storage host");
|
||||
return;
|
||||
}
|
||||
Map<String, TemplateInfo> templateInfos = listTemplate(ssHost);
|
||||
if( templateInfos == null ) {
|
||||
return;
|
||||
}
|
||||
long zoneId = ssHost.getDataCenterId();
|
||||
|
||||
Set<VMTemplateVO> toBeDownloaded = new HashSet<VMTemplateVO>();
|
||||
List<VMTemplateVO> allTemplates = _templateDao.listAllInZone(storageHost.getDataCenterId());
|
||||
List<VMTemplateVO> allTemplates = _templateDao.listAllInZone(ssHost.getDataCenterId());
|
||||
List<VMTemplateVO> rtngTmplts = _templateDao.listAllSystemVMTemplates();
|
||||
List<VMTemplateVO> defaultBuiltin = _templateDao.listDefaultBuiltinTemplates();
|
||||
|
||||
|
|
@ -561,19 +617,15 @@ public class DownloadMonitorImpl implements DownloadMonitor {
|
|||
}
|
||||
|
||||
if (toBeDownloaded.size() > 0) {
|
||||
HostVO sserver = _serverDao.findById(sserverId);
|
||||
if (sserver == null) {
|
||||
throw new CloudRuntimeException("Unable to find host from id");
|
||||
}
|
||||
/*Only download templates whose hypervirsor type is in the zone*/
|
||||
List<HypervisorType> availHypers = _clusterDao.getAvailableHypervisorInZone(sserver.getDataCenterId());
|
||||
List<HypervisorType> availHypers = _clusterDao.getAvailableHypervisorInZone(ssHost.getDataCenterId());
|
||||
/* Baremetal need not to download any template */
|
||||
availHypers.remove(HypervisorType.BareMetal);
|
||||
availHypers.add(HypervisorType.None); //bug 9809: resume ISO download.
|
||||
for (VMTemplateVO tmplt: toBeDownloaded) {
|
||||
|
||||
if (tmplt.getUrl() == null){ // If url is null we cant initiate the download so mark it as an error.
|
||||
VMTemplateHostVO tmpltHost = _vmTemplateHostDao.findByHostTemplate(sserver.getId(), tmplt.getId());
|
||||
VMTemplateHostVO tmpltHost = _vmTemplateHostDao.findByHostTemplate(ssHost.getId(), tmplt.getId());
|
||||
if(tmpltHost != null){
|
||||
tmpltHost.setDownloadState(Status.DOWNLOAD_ERROR);
|
||||
tmpltHost.setDownloadPercent(0);
|
||||
|
|
@ -584,16 +636,16 @@ public class DownloadMonitorImpl implements DownloadMonitor {
|
|||
}
|
||||
|
||||
if (availHypers.contains(tmplt.getHypervisorType())) {
|
||||
s_logger.debug("Template " + tmplt.getName() + " needs to be downloaded to " + sserver.getName());
|
||||
downloadTemplateToStorage(tmplt, sserver);
|
||||
s_logger.debug("Template " + tmplt.getName() + " needs to be downloaded to " + ssHost.getName());
|
||||
downloadTemplateToStorage(tmplt, ssHost);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (String uniqueName: templateInfos.keySet()) {
|
||||
TemplateInfo tInfo = templateInfos.get(uniqueName);
|
||||
DeleteTemplateCommand dtCommand = new DeleteTemplateCommand(tInfo.getInstallPath());
|
||||
long result = send(sserverId, dtCommand, null);
|
||||
DeleteTemplateCommand dtCommand = new DeleteTemplateCommand(ssHost.getStorageUrl(), tInfo.getInstallPath());
|
||||
long result = _agentMgr.sendToSecStorage(ssHost, dtCommand, null);
|
||||
if (result == -1 ){
|
||||
String description = "Failed to delete " + tInfo.getTemplateName() + " on secondary storage " + sserverId + " which isn't in the database";
|
||||
s_logger.error(description);
|
||||
|
|
|
|||
|
|
@ -35,6 +35,8 @@ import com.cloud.agent.api.GetStorageStatsAnswer;
|
|||
import com.cloud.agent.api.GetStorageStatsCommand;
|
||||
import com.cloud.agent.api.PingCommand;
|
||||
import com.cloud.agent.api.PingStorageCommand;
|
||||
import com.cloud.agent.api.ReadyAnswer;
|
||||
import com.cloud.agent.api.ReadyCommand;
|
||||
import com.cloud.agent.api.StartupCommand;
|
||||
import com.cloud.agent.api.StartupStorageCommand;
|
||||
import com.cloud.agent.api.storage.DownloadAnswer;
|
||||
|
|
@ -87,7 +89,9 @@ public class DummySecondaryStorageResource extends ServerResourceBase implements
|
|||
} else if (cmd instanceof GetStorageStatsCommand) {
|
||||
return execute((GetStorageStatsCommand)cmd);
|
||||
} else if (cmd instanceof CheckHealthCommand) {
|
||||
return new CheckHealthAnswer((CheckHealthCommand)cmd, true);
|
||||
return new CheckHealthAnswer((CheckHealthCommand)cmd, true);
|
||||
} else if (cmd instanceof ReadyCommand) {
|
||||
return new ReadyAnswer((ReadyCommand)cmd);
|
||||
} else {
|
||||
return Answer.createUnsupportedCommandAnswer(cmd);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -25,6 +25,7 @@ import com.cloud.agent.api.AgentControlCommand;
|
|||
import com.cloud.agent.api.Answer;
|
||||
import com.cloud.agent.api.Command;
|
||||
import com.cloud.agent.api.StartupCommand;
|
||||
import com.cloud.agent.api.StartupSecondaryStorageCommand;
|
||||
import com.cloud.agent.api.StartupStorageCommand;
|
||||
import com.cloud.host.HostVO;
|
||||
import com.cloud.host.Status;
|
||||
|
|
@ -67,17 +68,26 @@ public class SecondaryStorageListener implements Listener {
|
|||
|
||||
@Override
|
||||
public void processConnect(HostVO agent, StartupCommand cmd) {
|
||||
if (cmd instanceof StartupStorageCommand) {
|
||||
if(s_logger.isInfoEnabled())
|
||||
s_logger.info("Received a host startup notification");
|
||||
|
||||
StartupStorageCommand ss = (StartupStorageCommand)cmd;
|
||||
if (ss.getResourceType() == Storage.StorageResourceType.SECONDARY_STORAGE) {
|
||||
_ssVmMgr.onAgentConnect(agent.getDataCenterId(), cmd);
|
||||
_ssVmMgr.generateFirewallConfiguration(agent.getId());
|
||||
_ssVmMgr.generateSetupCommand(agent.getDataCenterId());
|
||||
|
||||
if ((cmd instanceof StartupStorageCommand) ) {
|
||||
StartupStorageCommand scmd = (StartupStorageCommand)cmd;
|
||||
if (scmd.getResourceType() == Storage.StorageResourceType.SECONDARY_STORAGE ) {
|
||||
_ssVmMgr.generateSetupCommand(agent.getId());
|
||||
return;
|
||||
}
|
||||
}
|
||||
} else if (cmd instanceof StartupSecondaryStorageCommand) {
|
||||
if(s_logger.isInfoEnabled()) {
|
||||
s_logger.info("Received a host startup notification " + cmd);
|
||||
}
|
||||
_ssVmMgr.onAgentConnect(agent.getDataCenterId(), cmd);
|
||||
_ssVmMgr.generateSetupCommand(agent.getId());
|
||||
_ssVmMgr.generateFirewallConfiguration(agent.getId());
|
||||
_ssVmMgr.generateVMSetupCommand(agent.getId());
|
||||
return;
|
||||
}
|
||||
return;
|
||||
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
|||
|
|
@ -35,6 +35,7 @@ import com.cloud.agent.api.Command;
|
|||
import com.cloud.agent.api.RebootCommand;
|
||||
import com.cloud.agent.api.SecStorageFirewallCfgCommand;
|
||||
import com.cloud.agent.api.SecStorageSetupCommand;
|
||||
import com.cloud.agent.api.SecStorageVMSetupCommand;
|
||||
import com.cloud.agent.api.StartupCommand;
|
||||
import com.cloud.agent.api.StopAnswer;
|
||||
import com.cloud.agent.api.check.CheckSshAnswer;
|
||||
|
|
@ -212,38 +213,84 @@ public class SecondaryStorageManagerImpl implements SecondaryStorageVmManager, V
|
|||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean generateFirewallConfiguration(Long hostId) {
|
||||
if (hostId == null) {
|
||||
return true;
|
||||
SecondaryStorageVmVO getSSVMfromHost(HostVO ssAHost) {
|
||||
if( ssAHost.getType() == Host.Type.SecondaryStorageVM ) {
|
||||
return _secStorageVmDao.findByInstanceName(ssAHost.getName());
|
||||
}
|
||||
boolean success = true;
|
||||
List<DataCenterVO> allZones = _dcDao.listAll();
|
||||
for (DataCenterVO zone : allZones) {
|
||||
success = success && generateFirewallConfigurationForZone(zone.getId());
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean generateSetupCommand(Long ssHostId) {
|
||||
HostVO cssHost = _hostDao.findById(ssHostId);
|
||||
Long zoneId = cssHost.getDataCenterId();
|
||||
if( cssHost.getType() == Host.Type.SecondaryStorageVM ) {
|
||||
|
||||
SecondaryStorageVmVO secStorageVm = _secStorageVmDao.findByInstanceName(cssHost.getName());
|
||||
if (secStorageVm == null) {
|
||||
s_logger.warn("secondary storage VM " + cssHost.getName() + " doesn't exist");
|
||||
return false;
|
||||
}
|
||||
if (secStorageVm.getState() != State.Running) {
|
||||
s_logger.warn("secondary storage VM " + cssHost.getName() + " is not running");
|
||||
return false;
|
||||
}
|
||||
List<HostVO> ssHosts = _hostDao.listSecondaryStorageHosts(zoneId);
|
||||
for( HostVO ssHost : ssHosts ) {
|
||||
String secUrl = ssHost.getStorageUrl();
|
||||
SecStorageSetupCommand setupCmd = new SecStorageSetupCommand(secUrl);
|
||||
|
||||
Answer answer = _agentMgr.easySend(ssHostId, setupCmd);
|
||||
if (answer != null && answer.getResult()) {
|
||||
if (s_logger.isDebugEnabled()) {
|
||||
s_logger.debug("Successfully programmed secondary storage " + ssHost.getName() + " in secondary storage VM " + secStorageVm.getInstanceName());
|
||||
}
|
||||
} else {
|
||||
if (s_logger.isDebugEnabled()) {
|
||||
s_logger.debug("Successfully programmed secondary storage " + ssHost.getName() + " in secondary storage VM " + secStorageVm.getInstanceName());
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
} else if( cssHost.getType() == Host.Type.SecondaryStorage ) {
|
||||
List<SecondaryStorageVmVO> alreadyRunning = _secStorageVmDao.getSecStorageVmListInStates(SecondaryStorageVm.Role.templateProcessor, zoneId, State.Running);
|
||||
String secUrl = cssHost.getStorageUrl();
|
||||
SecStorageSetupCommand setupCmd = new SecStorageSetupCommand(secUrl);
|
||||
for ( SecondaryStorageVmVO ssVm : alreadyRunning ) {
|
||||
HostVO host = _hostDao.findByName(ssVm.getInstanceName());
|
||||
Answer answer = _agentMgr.easySend(host.getId(), setupCmd);
|
||||
if (answer != null && answer.getResult()) {
|
||||
if (s_logger.isDebugEnabled()) {
|
||||
s_logger.debug("Successfully programmed secondary storage " + host.getName() + " in secondary storage VM " + ssVm.getInstanceName());
|
||||
}
|
||||
} else {
|
||||
if (s_logger.isDebugEnabled()) {
|
||||
s_logger.debug("Successfully programmed secondary storage " + host.getName() + " in secondary storage VM " + ssVm.getInstanceName());
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean generateSetupCommand(Long zoneId) {
|
||||
|
||||
List<SecondaryStorageVmVO> zoneSsvms = _secStorageVmDao.listByZoneId(SecondaryStorageVm.Role.templateProcessor, zoneId);
|
||||
if (zoneSsvms.size() == 0) {
|
||||
return true;
|
||||
public boolean generateVMSetupCommand(Long ssAHostId) {
|
||||
HostVO ssAHost = _hostDao.findById(ssAHostId);
|
||||
if( ssAHost.getType() != Host.Type.SecondaryStorageVM ) {
|
||||
return false;
|
||||
}
|
||||
SecondaryStorageVmVO secStorageVm = zoneSsvms.get(0);// FIXME: assumes
|
||||
// one vm per zone.
|
||||
if (secStorageVm.getState() != State.Running && secStorageVm.getState() != State.Starting) {
|
||||
s_logger.warn("No running secondary storage vms found in zone " + zoneId + " , skip programming http auth");
|
||||
return true;
|
||||
SecondaryStorageVmVO secStorageVm = _secStorageVmDao.findByInstanceName(ssAHost.getName());
|
||||
if (secStorageVm == null) {
|
||||
s_logger.warn("secondary storage VM " + ssAHost.getName() + " doesn't exist");
|
||||
return false;
|
||||
}
|
||||
Host storageHost = _hostDao.findSecondaryStorageHost(zoneId);
|
||||
if (storageHost == null) {
|
||||
s_logger.warn("No storage hosts found in zone " + zoneId + " , skip programming http auth");
|
||||
return true;
|
||||
if (secStorageVm.getState() != State.Running) {
|
||||
s_logger.warn("secondary storage VM " + ssAHost.getName() + " is not running");
|
||||
return false;
|
||||
}
|
||||
SecStorageSetupCommand setupCmd = new SecStorageSetupCommand(zoneId);
|
||||
|
||||
SecStorageVMSetupCommand setupCmd = new SecStorageVMSetupCommand();
|
||||
if (_allowedInternalSites != null) {
|
||||
List<String> allowedCidrs = new ArrayList<String>();
|
||||
String[] cidrs = _allowedInternalSites.split(",");
|
||||
|
|
@ -265,7 +312,7 @@ public class SecondaryStorageManagerImpl implements SecondaryStorageVmManager, V
|
|||
String copyPasswd = _configDao.getValue("secstorage.copy.password");
|
||||
setupCmd.setCopyPassword(copyPasswd);
|
||||
setupCmd.setCopyUserName(TemplateConstants.DEFAULT_HTTP_AUTH_USER);
|
||||
Answer answer = _agentMgr.easySend(storageHost.getId(), setupCmd);
|
||||
Answer answer = _agentMgr.easySend(ssAHostId, setupCmd);
|
||||
if (answer != null && answer.getResult()) {
|
||||
if (s_logger.isDebugEnabled()) {
|
||||
s_logger.debug("Successfully programmed http auth into " + secStorageVm.getHostName());
|
||||
|
|
@ -284,49 +331,68 @@ public class SecondaryStorageManagerImpl implements SecondaryStorageVmManager, V
|
|||
return null;
|
||||
}
|
||||
|
||||
private boolean generateFirewallConfigurationForZone(Long zoneId) {
|
||||
List<SecondaryStorageVmVO> zoneSsvms = _secStorageVmDao.listByZoneId(SecondaryStorageVm.Role.templateProcessor, zoneId);
|
||||
if (zoneSsvms.size() == 0) {
|
||||
@Override
|
||||
public boolean generateFirewallConfiguration(Long ssAHostId) {
|
||||
if ( ssAHostId == null ) {
|
||||
return true;
|
||||
}
|
||||
SecondaryStorageVmVO secStorageVm = zoneSsvms.get(0);// FIXME: assumes
|
||||
// one vm per zone.
|
||||
if (secStorageVm.getState() != State.Running && secStorageVm.getState() != State.Starting) {
|
||||
s_logger.warn("No running secondary storage vms found in zone " + zoneId + " , skip programming firewall rules");
|
||||
return true;
|
||||
HostVO ssAHost = _hostDao.findById(ssAHostId);
|
||||
Long zoneId = ssAHost.getDataCenterId();
|
||||
SecondaryStorageVmVO thisSecStorageVm = _secStorageVmDao.findByInstanceName(ssAHost.getName());
|
||||
|
||||
if (thisSecStorageVm == null) {
|
||||
s_logger.warn("secondary storage VM " + ssAHost.getName() + " doesn't exist");
|
||||
return false;
|
||||
}
|
||||
Host storageHost = _hostDao.findSecondaryStorageHost(zoneId);
|
||||
if (storageHost == null) {
|
||||
s_logger.warn("No storage hosts found in zone " + zoneId + " , skip programming firewall rules");
|
||||
return true;
|
||||
if (thisSecStorageVm.getState() != State.Running) {
|
||||
s_logger.warn("secondary storage VM " + ssAHost.getName() + " is not running");
|
||||
return false;
|
||||
}
|
||||
|
||||
List<SecondaryStorageVmVO> alreadyRunning = _secStorageVmDao.getSecStorageVmListInStates(SecondaryStorageVm.Role.templateProcessor, State.Running, State.Migrating, State.Starting);
|
||||
|
||||
String copyPort = Integer.toString(TemplateConstants.DEFAULT_TMPLT_COPY_PORT);
|
||||
String copyPort = _useSSlCopy? "443" : Integer.toString(TemplateConstants.DEFAULT_TMPLT_COPY_PORT);
|
||||
SecStorageFirewallCfgCommand cpc = new SecStorageFirewallCfgCommand();
|
||||
SecStorageFirewallCfgCommand thiscpc = new SecStorageFirewallCfgCommand();
|
||||
thiscpc.addPortConfig(thisSecStorageVm.getPublicIpAddress(), copyPort, true, TemplateConstants.DEFAULT_TMPLT_COPY_INTF);
|
||||
for (SecondaryStorageVmVO ssVm : alreadyRunning) {
|
||||
if ( ssVm.getDataCenterId() == zoneId ) {
|
||||
continue;
|
||||
}
|
||||
if (ssVm.getPublicIpAddress() != null) {
|
||||
if (ssVm.getId() == secStorageVm.getId()) {
|
||||
continue;
|
||||
}
|
||||
cpc.addPortConfig(ssVm.getPublicIpAddress(), copyPort, true, TemplateConstants.DEFAULT_TMPLT_COPY_INTF);
|
||||
if (_useSSlCopy) {
|
||||
cpc.addPortConfig(ssVm.getPublicIpAddress(), "443", true, TemplateConstants.DEFAULT_TMPLT_COPY_INTF);
|
||||
}
|
||||
if ( ssVm.getState() != State.Running ) {
|
||||
continue;
|
||||
}
|
||||
String instanceName = ssVm.getInstanceName();
|
||||
HostVO host = _hostDao.findByName(instanceName);
|
||||
Answer answer = _agentMgr.easySend(host.getId(), thiscpc);
|
||||
if (answer != null && answer.getResult()) {
|
||||
if (s_logger.isDebugEnabled()) {
|
||||
s_logger.debug("Successfully programmed firewall rules into " + ssVm.getHostName());
|
||||
}
|
||||
} else {
|
||||
if (s_logger.isDebugEnabled()) {
|
||||
s_logger.debug("failed to program firewall rules into secondary storage vm : " + ssVm.getHostName());
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
Answer answer = _agentMgr.easySend(storageHost.getId(), cpc);
|
||||
|
||||
Answer answer = _agentMgr.easySend(ssAHostId, cpc);
|
||||
if (answer != null && answer.getResult()) {
|
||||
if (s_logger.isDebugEnabled()) {
|
||||
s_logger.debug("Successfully programmed firewall rules into " + secStorageVm.getHostName());
|
||||
s_logger.debug("Successfully programmed firewall rules into " + thisSecStorageVm.getHostName());
|
||||
}
|
||||
return true;
|
||||
} else {
|
||||
if (s_logger.isDebugEnabled()) {
|
||||
s_logger.debug("failed to program firewall rules into secondary storage vm : " + secStorageVm.getHostName());
|
||||
s_logger.debug("failed to program firewall rules into secondary storage vm : " + thisSecStorageVm.getHostName());
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
|
|
@ -500,7 +566,8 @@ public class SecondaryStorageManagerImpl implements SecondaryStorageVmManager, V
|
|||
}
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
|
||||
boolean secStorageVmFromStoppedPool = false;
|
||||
SecondaryStorageVmVO secStorageVm = assignSecStorageVmFromStoppedPool(dataCenterId, role);
|
||||
if (secStorageVm == null) {
|
||||
|
|
@ -685,7 +752,7 @@ public class SecondaryStorageManagerImpl implements SecondaryStorageVmManager, V
|
|||
_mgmt_port = NumbersUtil.parseInt(value, 8250);
|
||||
|
||||
_listener = new SecondaryStorageListener(this);
|
||||
_agentMgr.registerForHostEvents(_listener, true, true, false);
|
||||
_agentMgr.registerForHostEvents(_listener, true, false, true);
|
||||
|
||||
_itMgr.registerGuru(VirtualMachine.Type.SecondaryStorageVm, this);
|
||||
|
||||
|
|
@ -851,19 +918,8 @@ public class SecondaryStorageManagerImpl implements SecondaryStorageVmManager, V
|
|||
buf.append(" zone=").append(dest.getDataCenter().getId());
|
||||
buf.append(" pod=").append(dest.getPod().getId());
|
||||
|
||||
if (profile.getVirtualMachine().getRole() == SecondaryStorageVm.Role.templateProcessor) {
|
||||
buf.append(" guid=").append(secHost.getGuid());
|
||||
} else {
|
||||
buf.append(" guid=").append(profile.getVirtualMachine().getHostName());
|
||||
}
|
||||
buf.append(" guid=").append(profile.getVirtualMachine().getHostName());
|
||||
|
||||
String nfsMountPoint = null;
|
||||
try {
|
||||
nfsMountPoint = NfsUtils.url2Mount(secHost.getStorageUrl());
|
||||
} catch (Exception e) {
|
||||
}
|
||||
|
||||
buf.append(" mount.path=").append(nfsMountPoint);
|
||||
if (_configDao.isPremium()) {
|
||||
if (profile.getHypervisorType() == HypervisorType.Hyperv) {
|
||||
buf.append(" resource=com.cloud.storage.resource.CifsSecondaryStorageResource");
|
||||
|
|
@ -875,7 +931,6 @@ public class SecondaryStorageManagerImpl implements SecondaryStorageVmManager, V
|
|||
}
|
||||
buf.append(" instance=SecStorage");
|
||||
buf.append(" sslcopy=").append(Boolean.toString(_useSSlCopy));
|
||||
buf.append(" role=").append(profile.getVirtualMachine().getRole().toString());
|
||||
|
||||
boolean externalDhcp = false;
|
||||
String externalDhcpStr = _configDao.getValue("direct.attach.network.externalIpAllocator.enabled");
|
||||
|
|
@ -1048,16 +1103,14 @@ public class SecondaryStorageManagerImpl implements SecondaryStorageVmManager, V
|
|||
public Pair<AfterScanAction, Object> scanPool(Long pool) {
|
||||
long dataCenterId = pool.longValue();
|
||||
|
||||
List<SecondaryStorageVmVO> alreadyRunning = _secStorageVmDao.getSecStorageVmListInStates(SecondaryStorageVm.Role.templateProcessor, dataCenterId, State.Running, State.Migrating,
|
||||
State.Starting);
|
||||
List<SecondaryStorageVmVO> stopped = _secStorageVmDao.getSecStorageVmListInStates(SecondaryStorageVm.Role.templateProcessor, dataCenterId, State.Stopped, State.Stopping);
|
||||
if (alreadyRunning.size() == 0) {
|
||||
if (stopped.size() == 0) {
|
||||
s_logger.info("No secondary storage vms found in datacenter id=" + dataCenterId + ", starting a new one");
|
||||
return new Pair<AfterScanAction, Object>(AfterScanAction.expand, SecondaryStorageVm.Role.templateProcessor);
|
||||
} else {
|
||||
s_logger.warn("Stopped secondary storage vms found in datacenter id=" + dataCenterId + ", not restarting them automatically");
|
||||
}
|
||||
List<SecondaryStorageVmVO> ssVms = _secStorageVmDao.getSecStorageVmListInStates(SecondaryStorageVm.Role.templateProcessor, dataCenterId, State.Running, State.Migrating,
|
||||
State.Starting, State.Stopped, State.Stopping );
|
||||
int vmSize = (ssVms == null)? 0 : ssVms.size();
|
||||
List<HostVO> ssHosts = _hostDao.listSecondaryStorageHosts(dataCenterId);
|
||||
int hostSize = (ssHosts == null)? 0 : ssHosts.size();
|
||||
if ( hostSize > vmSize ) {
|
||||
s_logger.info("No secondary storage vms found in datacenter id=" + dataCenterId + ", starting a new one");
|
||||
return new Pair<AfterScanAction, Object>(AfterScanAction.expand, SecondaryStorageVm.Role.templateProcessor);
|
||||
}
|
||||
|
||||
return new Pair<AfterScanAction, Object>(AfterScanAction.nop, SecondaryStorageVm.Role.templateProcessor);
|
||||
|
|
|
|||
|
|
@ -40,7 +40,8 @@ public interface SecondaryStorageVmManager extends Manager {
|
|||
public boolean destroySecStorageVm(long ssVmVmId);
|
||||
public void onAgentConnect(Long dcId, StartupCommand cmd);
|
||||
public boolean generateFirewallConfiguration(Long agentId);
|
||||
public boolean generateSetupCommand(Long zoneId);
|
||||
public boolean generateVMSetupCommand(Long hostId);
|
||||
|
||||
public Pair<HostVO, SecondaryStorageVmVO> assignSecStorageVm(long zoneId, Command cmd);
|
||||
public Pair<HostVO, SecondaryStorageVmVO> assignSecStorageVm(long zoneId, Command cmd);
|
||||
boolean generateSetupCommand(Long hostId);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -130,4 +130,6 @@ public interface SnapshotManager {
|
|||
List<SnapshotVO> listSnapsforPolicy(long policyId, Filter filter);
|
||||
|
||||
void downloadSnapshotsFromSwift(SnapshotVO ss);
|
||||
|
||||
String getSecondaryStorageURL(SnapshotVO snapshot);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -518,8 +518,10 @@ public class SnapshotManagerImpl implements SnapshotManager, SnapshotService, Ma
|
|||
String primaryStoragePoolNameLabel = _storageMgr.getPrimaryStorageNameLabel(volume);
|
||||
Long dcId = volume.getDataCenterId();
|
||||
Long accountId = volume.getAccountId();
|
||||
|
||||
String secondaryStoragePoolUrl = _storageMgr.getSecondaryStorageURL(volume.getDataCenterId());
|
||||
|
||||
HostVO secHost = getSecHost(volumeId, volume.getDataCenterId());
|
||||
|
||||
String secondaryStoragePoolUrl = secHost.getStorageUrl();
|
||||
String snapshotUuid = snapshot.getPath();
|
||||
// In order to verify that the snapshot is not empty,
|
||||
// we check if the parent of the snapshot is not the same as the parent of the previous snapshot.
|
||||
|
|
@ -603,6 +605,14 @@ public class SnapshotManagerImpl implements SnapshotManager, SnapshotService, Ma
|
|||
|
||||
}
|
||||
|
||||
private HostVO getSecHost(long volumeId, long dcId) {
|
||||
Long id = _snapshotDao.getSecHostId(volumeId);
|
||||
if ( id != null) {
|
||||
return _hostDao.findById(id);
|
||||
}
|
||||
return _storageMgr.getSecondaryStorageHost(dcId);
|
||||
}
|
||||
|
||||
private Long getSnapshotUserId() {
|
||||
Long userId = UserContext.current().getCallerUserId();
|
||||
if (userId == null) {
|
||||
|
|
@ -766,6 +776,13 @@ public class SnapshotManagerImpl implements SnapshotManager, SnapshotService, Ma
|
|||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getSecondaryStorageURL(SnapshotVO snapshot) {
|
||||
HostVO secHost = _hostDao.findById(snapshot.getSecHostId());
|
||||
return secHost.getStorageUrl();
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
@DB
|
||||
public boolean destroySnapshotBackUp(long snapshotId) {
|
||||
|
|
@ -776,7 +793,7 @@ public class SnapshotManagerImpl implements SnapshotManager, SnapshotService, Ma
|
|||
throw new CloudRuntimeException("Destroying snapshot " + snapshotId + " backup failed due to unable to find snapshot ");
|
||||
}
|
||||
|
||||
String secondaryStoragePoolUrl = _storageMgr.getSecondaryStorageURL(snapshot.getDataCenterId());
|
||||
String secondaryStoragePoolUrl = getSecondaryStorageURL(snapshot);
|
||||
Long dcId = snapshot.getDataCenterId();
|
||||
Long accountId = snapshot.getAccountId();
|
||||
Long volumeId = snapshot.getVolumeId();
|
||||
|
|
@ -954,32 +971,35 @@ public class SnapshotManagerImpl implements SnapshotManager, SnapshotService, Ma
|
|||
}
|
||||
Long volumeId = volume.getId();
|
||||
Long dcId = volume.getDataCenterId();
|
||||
String secondaryStoragePoolURL = _storageMgr.getSecondaryStorageURL(dcId);
|
||||
String primaryStoragePoolNameLabel = _storageMgr.getPrimaryStorageNameLabel(volume);
|
||||
if (_snapshotDao.listByVolumeIdIncludingRemoved(volumeId).isEmpty()) {
|
||||
// This volume doesn't have any snapshots. Nothing do delete.
|
||||
continue;
|
||||
}
|
||||
DeleteSnapshotsDirCommand cmd = new DeleteSnapshotsDirCommand(primaryStoragePoolNameLabel, secondaryStoragePoolURL, dcId, accountId, volumeId, volume.getPath());
|
||||
Answer answer = null;
|
||||
Long poolId = volume.getPoolId();
|
||||
if (poolId != null) {
|
||||
// Retry only once for this command. There's low chance of failure because of a connection problem.
|
||||
try {
|
||||
answer = _storageMgr.sendToPool(poolId, cmd);
|
||||
} catch (StorageUnavailableException e) {
|
||||
|
||||
List<HostVO> ssHosts = _hostDao.listSecondaryStorageHosts(dcId);
|
||||
for ( HostVO ssHost : ssHosts ) {
|
||||
DeleteSnapshotsDirCommand cmd = new DeleteSnapshotsDirCommand(primaryStoragePoolNameLabel, ssHost.getStorageUrl(), dcId, accountId, volumeId, volume.getPath());
|
||||
Answer answer = null;
|
||||
Long poolId = volume.getPoolId();
|
||||
if (poolId != null) {
|
||||
// Retry only once for this command. There's low chance of failure because of a connection problem.
|
||||
try {
|
||||
answer = _storageMgr.sendToPool(poolId, cmd);
|
||||
} catch (StorageUnavailableException e) {
|
||||
}
|
||||
} else {
|
||||
s_logger.info("Pool id for volume id: " + volumeId + " belonging to account id: " + accountId + " is null. Assuming the snapshotsDir for the account has already been deleted");
|
||||
}
|
||||
} else {
|
||||
s_logger.info("Pool id for volume id: " + volumeId + " belonging to account id: " + accountId + " is null. Assuming the snapshotsDir for the account has already been deleted");
|
||||
}
|
||||
|
||||
if (success) {
|
||||
// SnapshotsDir has been deleted for the volumes so far.
|
||||
success = (answer != null) && answer.getResult();
|
||||
|
||||
if (success) {
|
||||
s_logger.debug("Deleted snapshotsDir for volume: " + volumeId + " under account: " + accountId);
|
||||
} else if (answer != null) {
|
||||
s_logger.error(answer.getDetails());
|
||||
// SnapshotsDir has been deleted for the volumes so far.
|
||||
success = (answer != null) && answer.getResult();
|
||||
if (success) {
|
||||
s_logger.debug("Deleted snapshotsDir for volume: " + volumeId + " under account: " + accountId);
|
||||
} else if (answer != null) {
|
||||
s_logger.error(answer.getDetails());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -39,4 +39,5 @@ public interface SecondaryStorageVmDao extends GenericDao<SecondaryStorageVmVO,
|
|||
public List<Long> getRunningSecStorageVmListByMsid(SecondaryStorageVm.Role role, long msid);
|
||||
|
||||
public List<Long> listRunningSecStorageOrderByLoad(SecondaryStorageVm.Role role, long zoneId);
|
||||
SecondaryStorageVmVO findByInstanceName(String instanceName);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -47,7 +47,8 @@ public class SecondaryStorageVmDaoImpl extends GenericDaoBase<SecondaryStorageVm
|
|||
protected SearchBuilder<SecondaryStorageVmVO> LastHostSearch;
|
||||
protected SearchBuilder<SecondaryStorageVmVO> HostUpSearch;
|
||||
protected SearchBuilder<SecondaryStorageVmVO> ZoneSearch;
|
||||
protected SearchBuilder<SecondaryStorageVmVO> StateChangeSearch;
|
||||
protected SearchBuilder<SecondaryStorageVmVO> StateChangeSearch;
|
||||
protected SearchBuilder<SecondaryStorageVmVO> InstanceSearch;
|
||||
|
||||
protected final Attribute _updateTimeAttr;
|
||||
|
||||
|
|
@ -68,6 +69,10 @@ public class SecondaryStorageVmDaoImpl extends GenericDaoBase<SecondaryStorageVm
|
|||
HostSearch.and("role", HostSearch.entity().getRole(), SearchCriteria.Op.EQ);
|
||||
HostSearch.done();
|
||||
|
||||
InstanceSearch = createSearchBuilder();
|
||||
InstanceSearch.and("instanceName", InstanceSearch.entity().getInstanceName(), SearchCriteria.Op.EQ);
|
||||
InstanceSearch.done();
|
||||
|
||||
LastHostSearch = createSearchBuilder();
|
||||
LastHostSearch.and("lastHost", LastHostSearch.entity().getLastHostId(), SearchCriteria.Op.EQ);
|
||||
LastHostSearch.and("state", LastHostSearch.entity().getState(), SearchCriteria.Op.EQ);
|
||||
|
|
@ -186,6 +191,19 @@ public class SecondaryStorageVmDaoImpl extends GenericDaoBase<SecondaryStorageVm
|
|||
}
|
||||
return l;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public SecondaryStorageVmVO findByInstanceName(String instanceName) {
|
||||
SearchCriteria<SecondaryStorageVmVO> sc = InstanceSearch.create();
|
||||
sc.setParameters("instanceName", instanceName);
|
||||
List<SecondaryStorageVmVO> list = listBy(sc);
|
||||
if( list == null ) {
|
||||
return null;
|
||||
} else {
|
||||
return list.get(0);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<SecondaryStorageVmVO> listByZoneId(SecondaryStorageVm.Role role, long zoneId) {
|
||||
|
|
|
|||
|
|
@ -410,6 +410,7 @@ CREATE TABLE `cloud`.`snapshots` (
|
|||
`backup_snap_id` varchar(255) COMMENT 'Back up uuid of the snapshot',
|
||||
`swift_id` bigint unsigned COMMENT 'which swift',
|
||||
`swift_name` varchar(255) COMMENT 'Back up name in swift',
|
||||
`sechost_id` bigint unsigned COMMENT 'secondary storage host id',
|
||||
`prev_snap_id` bigint unsigned COMMENT 'Id of the most recent snapshot',
|
||||
`hypervisor_type` varchar(32) NOT NULL COMMENT 'hypervisor that the snapshot was taken under',
|
||||
`version` varchar(32) COMMENT 'snapshot version',
|
||||
|
|
|
|||
Loading…
Reference in New Issue