mirror of
https://github.com/apache/cloudstack.git
synced 2025-10-26 08:42:29 +01:00
CLOUDSTACK-5840:Migration from NFS to S3 should be done in one API
(updateCloudToUseObjectStore) instead of two APIs.
This commit is contained in:
parent
858b9b1177
commit
649d9d927f
@ -17,8 +17,8 @@
|
|||||||
package com.cloud.storage;
|
package com.cloud.storage;
|
||||||
|
|
||||||
import java.net.UnknownHostException;
|
import java.net.UnknownHostException;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
import org.apache.cloudstack.api.command.admin.storage.AddImageStoreCmd;
|
|
||||||
import org.apache.cloudstack.api.command.admin.storage.CancelPrimaryStorageMaintenanceCmd;
|
import org.apache.cloudstack.api.command.admin.storage.CancelPrimaryStorageMaintenanceCmd;
|
||||||
import org.apache.cloudstack.api.command.admin.storage.CreateSecondaryStagingStoreCmd;
|
import org.apache.cloudstack.api.command.admin.storage.CreateSecondaryStagingStoreCmd;
|
||||||
import org.apache.cloudstack.api.command.admin.storage.CreateStoragePoolCmd;
|
import org.apache.cloudstack.api.command.admin.storage.CreateStoragePoolCmd;
|
||||||
@ -92,7 +92,8 @@ public interface StorageService {
|
|||||||
|
|
||||||
boolean deleteSecondaryStagingStore(DeleteSecondaryStagingStoreCmd cmd);
|
boolean deleteSecondaryStagingStore(DeleteSecondaryStagingStoreCmd cmd);
|
||||||
|
|
||||||
ImageStore discoverImageStore(AddImageStoreCmd cmd) throws IllegalArgumentException, DiscoveryException, InvalidParameterValueException;
|
public ImageStore discoverImageStore(String name, String url, String providerName, Long dcId, Map details) throws IllegalArgumentException, DiscoveryException,
|
||||||
|
InvalidParameterValueException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Prepare NFS secondary storage for object store migration
|
* Prepare NFS secondary storage for object store migration
|
||||||
@ -105,6 +106,9 @@ public interface StorageService {
|
|||||||
* @throws InsufficientCapacityException
|
* @throws InsufficientCapacityException
|
||||||
* TODO
|
* TODO
|
||||||
*/
|
*/
|
||||||
public ImageStore prepareSecondaryStorageForObjectStoreMigration(Long storeId) throws ResourceUnavailableException, InsufficientCapacityException;
|
public ImageStore migrateToObjectStore(String name, String url, String providerName, Map details) throws IllegalArgumentException, DiscoveryException,
|
||||||
|
InvalidParameterValueException;
|
||||||
|
|
||||||
|
public ImageStore prepareSecondaryStorageForObjectStoreMigration(Long storeId) throws ResourceUnavailableException,
|
||||||
|
InsufficientCapacityException;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -24,7 +24,6 @@ import org.apache.cloudstack.api.ApiErrorCode;
|
|||||||
import org.apache.cloudstack.api.BaseCmd;
|
import org.apache.cloudstack.api.BaseCmd;
|
||||||
import org.apache.cloudstack.api.Parameter;
|
import org.apache.cloudstack.api.Parameter;
|
||||||
import org.apache.cloudstack.api.ServerApiException;
|
import org.apache.cloudstack.api.ServerApiException;
|
||||||
import org.apache.cloudstack.api.command.admin.storage.AddImageStoreCmd;
|
|
||||||
import org.apache.cloudstack.api.response.ImageStoreResponse;
|
import org.apache.cloudstack.api.response.ImageStoreResponse;
|
||||||
import org.apache.cloudstack.api.response.ZoneResponse;
|
import org.apache.cloudstack.api.response.ZoneResponse;
|
||||||
|
|
||||||
@ -75,19 +74,14 @@ public class AddSecondaryStorageCmd extends BaseCmd {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void execute(){
|
public void execute(){
|
||||||
AddImageStoreCmd cmd = new AddImageStoreCmd();
|
|
||||||
cmd.setUrl(this.getUrl());
|
|
||||||
cmd.setZoneId(this.getZoneId());
|
|
||||||
cmd.setProviderName("NFS");
|
|
||||||
|
|
||||||
try{
|
try{
|
||||||
ImageStore result = _storageService.discoverImageStore(cmd);
|
ImageStore result = _storageService.discoverImageStore(null, getUrl(), "NFS", getZoneId(), null);
|
||||||
ImageStoreResponse storeResponse = null;
|
ImageStoreResponse storeResponse = null;
|
||||||
if (result != null ) {
|
if (result != null ) {
|
||||||
storeResponse = _responseGenerator.createImageStoreResponse(result);
|
storeResponse = _responseGenerator.createImageStoreResponse(result);
|
||||||
storeResponse.setResponseName(getCommandName());
|
storeResponse.setResponseName(getCommandName());
|
||||||
storeResponse.setObjectName("secondarystorage");
|
storeResponse.setObjectName("secondarystorage");
|
||||||
this.setResponseObject(storeResponse);
|
setResponseObject(storeResponse);
|
||||||
} else {
|
} else {
|
||||||
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to add secondary storage");
|
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to add secondary storage");
|
||||||
}
|
}
|
||||||
|
|||||||
@ -95,7 +95,7 @@ public class AddImageStoreCmd extends BaseCmd {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public String getProviderName() {
|
public String getProviderName() {
|
||||||
return this.providerName;
|
return providerName;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setUrl(String url) {
|
public void setUrl(String url) {
|
||||||
@ -131,13 +131,13 @@ public class AddImageStoreCmd extends BaseCmd {
|
|||||||
@Override
|
@Override
|
||||||
public void execute(){
|
public void execute(){
|
||||||
try{
|
try{
|
||||||
ImageStore result = _storageService.discoverImageStore(this);
|
ImageStore result = _storageService.discoverImageStore(getName(), getUrl(), getProviderName(), getZoneId(), getDetails());
|
||||||
ImageStoreResponse storeResponse = null;
|
ImageStoreResponse storeResponse = null;
|
||||||
if (result != null) {
|
if (result != null) {
|
||||||
storeResponse = _responseGenerator.createImageStoreResponse(result);
|
storeResponse = _responseGenerator.createImageStoreResponse(result);
|
||||||
storeResponse.setResponseName(getCommandName());
|
storeResponse.setResponseName(getCommandName());
|
||||||
storeResponse.setObjectName("imagestore");
|
storeResponse.setObjectName("imagestore");
|
||||||
this.setResponseObject(storeResponse);
|
setResponseObject(storeResponse);
|
||||||
} else {
|
} else {
|
||||||
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to add secondary storage");
|
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to add secondary storage");
|
||||||
}
|
}
|
||||||
|
|||||||
@ -86,9 +86,6 @@ public final class AddS3Cmd extends BaseCmd {
|
|||||||
public void execute() throws ResourceUnavailableException, InsufficientCapacityException, ServerApiException, ConcurrentOperationException,
|
public void execute() throws ResourceUnavailableException, InsufficientCapacityException, ServerApiException, ConcurrentOperationException,
|
||||||
ResourceAllocationException, NetworkRuleConflictException {
|
ResourceAllocationException, NetworkRuleConflictException {
|
||||||
|
|
||||||
AddImageStoreCmd cmd = new AddImageStoreCmd() {
|
|
||||||
@Override
|
|
||||||
public Map<String, String> getDetails() {
|
|
||||||
Map<String, String> dm = new HashMap<String, String>();
|
Map<String, String> dm = new HashMap<String, String>();
|
||||||
dm.put(ApiConstants.S3_ACCESS_KEY, getAccessKey());
|
dm.put(ApiConstants.S3_ACCESS_KEY, getAccessKey());
|
||||||
dm.put(ApiConstants.S3_SECRET_KEY, getSecretKey());
|
dm.put(ApiConstants.S3_SECRET_KEY, getSecretKey());
|
||||||
@ -106,13 +103,10 @@ public final class AddS3Cmd extends BaseCmd {
|
|||||||
if (getSocketTimeout() != null) {
|
if (getSocketTimeout() != null) {
|
||||||
dm.put(ApiConstants.S3_SOCKET_TIMEOUT, getSocketTimeout().toString());
|
dm.put(ApiConstants.S3_SOCKET_TIMEOUT, getSocketTimeout().toString());
|
||||||
}
|
}
|
||||||
return dm;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
cmd.setProviderName("S3");
|
|
||||||
|
|
||||||
try{
|
try{
|
||||||
ImageStore result = _storageService.discoverImageStore(cmd);
|
ImageStore result = _storageService.discoverImageStore(null, null, "S3", null, dm);
|
||||||
ImageStoreResponse storeResponse = null;
|
ImageStoreResponse storeResponse = null;
|
||||||
if (result != null) {
|
if (result != null) {
|
||||||
storeResponse = _responseGenerator.createImageStoreResponse(result);
|
storeResponse = _responseGenerator.createImageStoreResponse(result);
|
||||||
|
|||||||
@ -1,110 +0,0 @@
|
|||||||
// Licensed to the Apache Software Foundation (ASF) under one
|
|
||||||
// or more contributor license agreements. See the NOTICE file
|
|
||||||
// distributed with this work for additional information
|
|
||||||
// regarding copyright ownership. The ASF licenses this file
|
|
||||||
// to you under the Apache License, Version 2.0 (the
|
|
||||||
// "License"); you may not use this file except in compliance
|
|
||||||
// with the License. You may obtain a copy of the License at
|
|
||||||
//
|
|
||||||
// http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
//
|
|
||||||
// Unless required by applicable law or agreed to in writing,
|
|
||||||
// software distributed under the License is distributed on an
|
|
||||||
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
|
||||||
// KIND, either express or implied. See the License for the
|
|
||||||
// specific language governing permissions and limitations
|
|
||||||
// under the License.
|
|
||||||
package org.apache.cloudstack.api.command.admin.storage;
|
|
||||||
|
|
||||||
import org.apache.log4j.Logger;
|
|
||||||
|
|
||||||
import org.apache.cloudstack.api.APICommand;
|
|
||||||
import org.apache.cloudstack.api.ApiCommandJobType;
|
|
||||||
import org.apache.cloudstack.api.ApiConstants;
|
|
||||||
import org.apache.cloudstack.api.ApiErrorCode;
|
|
||||||
import org.apache.cloudstack.api.BaseAsyncCmd;
|
|
||||||
import org.apache.cloudstack.api.Parameter;
|
|
||||||
import org.apache.cloudstack.api.ServerApiException;
|
|
||||||
import org.apache.cloudstack.api.response.ImageStoreResponse;
|
|
||||||
import org.apache.cloudstack.context.CallContext;
|
|
||||||
|
|
||||||
import com.cloud.event.EventTypes;
|
|
||||||
import com.cloud.exception.InsufficientCapacityException;
|
|
||||||
import com.cloud.exception.ResourceUnavailableException;
|
|
||||||
import com.cloud.storage.ImageStore;
|
|
||||||
import com.cloud.user.Account;
|
|
||||||
|
|
||||||
@APICommand(name = "prepareSecondaryStorageForMigration",
|
|
||||||
description = "Prepare a NFS secondary storage to migrate to use object store like S3",
|
|
||||||
responseObject = ImageStoreResponse.class)
|
|
||||||
public class PrepareSecondaryStorageForMigrationCmd extends BaseAsyncCmd {
|
|
||||||
public static final Logger s_logger = Logger.getLogger(PrepareSecondaryStorageForMigrationCmd.class.getName());
|
|
||||||
private static final String s_name = "preparesecondarystorageformigrationresponse";
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////////
|
|
||||||
//////////////// API parameters /////////////////////
|
|
||||||
/////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
@Parameter(name = ApiConstants.ID, type = CommandType.UUID, entityType = ImageStoreResponse.class, required = true, description = "Secondary image store ID")
|
|
||||||
private Long id;
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////////
|
|
||||||
/////////////////// Accessors ///////////////////////
|
|
||||||
/////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
public Long getId() {
|
|
||||||
return id;
|
|
||||||
}
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////////
|
|
||||||
/////////////// API Implementation///////////////////
|
|
||||||
/////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getCommandName() {
|
|
||||||
return s_name;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public ApiCommandJobType getInstanceType() {
|
|
||||||
return ApiCommandJobType.ImageStore;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Long getInstanceId() {
|
|
||||||
return getId();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public long getEntityOwnerId() {
|
|
||||||
Account account = CallContext.current().getCallingAccount();
|
|
||||||
if (account != null) {
|
|
||||||
return account.getId();
|
|
||||||
}
|
|
||||||
|
|
||||||
return Account.ACCOUNT_ID_SYSTEM; // no account info given, parent this command to SYSTEM so ERROR events are tracked
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getEventType() {
|
|
||||||
return EventTypes.EVENT_MIGRATE_PREPARE_SECONDARY_STORAGE;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getEventDescription() {
|
|
||||||
return "preparing secondary storage: " + getId() + " for object store migration";
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void execute() throws ResourceUnavailableException, InsufficientCapacityException {
|
|
||||||
ImageStore result = _storageService.prepareSecondaryStorageForObjectStoreMigration(getId());
|
|
||||||
if (result != null) {
|
|
||||||
ImageStoreResponse response = _responseGenerator.createImageStoreResponse(result);
|
|
||||||
response.setResponseName(getCommandName());
|
|
||||||
response.setResponseName("secondarystorage");
|
|
||||||
setResponseObject(response);
|
|
||||||
} else {
|
|
||||||
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to prepare secondary storage for object store migration");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -0,0 +1,142 @@
|
|||||||
|
// Licensed to the Apache Software Foundation (ASF) under one
|
||||||
|
// or more contributor license agreements. See the NOTICE file
|
||||||
|
// distributed with this work for additional information
|
||||||
|
// regarding copyright ownership. The ASF licenses this file
|
||||||
|
// to you under the Apache License, Version 2.0 (the
|
||||||
|
// "License"); you may not use this file except in compliance
|
||||||
|
// with the License. You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing,
|
||||||
|
// software distributed under the License is distributed on an
|
||||||
|
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||||
|
// KIND, either express or implied. See the License for the
|
||||||
|
// specific language governing permissions and limitations
|
||||||
|
// under the License.
|
||||||
|
package org.apache.cloudstack.api.command.admin.storage;
|
||||||
|
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Iterator;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import org.apache.log4j.Logger;
|
||||||
|
|
||||||
|
import org.apache.cloudstack.api.APICommand;
|
||||||
|
import org.apache.cloudstack.api.ApiConstants;
|
||||||
|
import org.apache.cloudstack.api.ApiErrorCode;
|
||||||
|
import org.apache.cloudstack.api.BaseCmd;
|
||||||
|
import org.apache.cloudstack.api.Parameter;
|
||||||
|
import org.apache.cloudstack.api.ServerApiException;
|
||||||
|
import org.apache.cloudstack.api.response.ImageStoreResponse;
|
||||||
|
|
||||||
|
import com.cloud.exception.DiscoveryException;
|
||||||
|
import com.cloud.storage.ImageStore;
|
||||||
|
import com.cloud.user.Account;
|
||||||
|
|
||||||
|
@APICommand(name = "updateCloudToUseObjectStore", description = "Migrate current NFS secondary storages to use object store.", responseObject = ImageStoreResponse.class, since = "4.3.0")
|
||||||
|
public class UpdateCloudToUseObjectStoreCmd extends BaseCmd {
|
||||||
|
public static final Logger s_logger = Logger.getLogger(UpdateCloudToUseObjectStoreCmd.class.getName());
|
||||||
|
private static final String s_name = "updatecloudtouseobjectstoreresponse";
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////
|
||||||
|
//////////////// API parameters /////////////////////
|
||||||
|
/////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
@Parameter(name=ApiConstants.NAME, type=CommandType.STRING, description="the name for the image store")
|
||||||
|
private String name;
|
||||||
|
|
||||||
|
@Parameter(name=ApiConstants.URL, type=CommandType.STRING, description="the URL for the image store")
|
||||||
|
private String url;
|
||||||
|
|
||||||
|
@Parameter(name=ApiConstants.PROVIDER, type=CommandType.STRING,
|
||||||
|
required=true, description="the image store provider name")
|
||||||
|
private String providerName;
|
||||||
|
|
||||||
|
@Parameter(name=ApiConstants.DETAILS, type=CommandType.MAP, description="the details for the image store. Example: details[0].key=accesskey&details[0].value=s389ddssaa&details[1].key=secretkey&details[1].value=8dshfsss")
|
||||||
|
private Map details;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////
|
||||||
|
/////////////////// Accessors ///////////////////////
|
||||||
|
/////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
|
||||||
|
public String getUrl() {
|
||||||
|
return url;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Map<String, String> getDetails() {
|
||||||
|
Map<String, String> detailsMap = null;
|
||||||
|
if (details != null && !details.isEmpty()) {
|
||||||
|
detailsMap = new HashMap<String, String>();
|
||||||
|
Collection<?> props = details.values();
|
||||||
|
Iterator<?> iter = props.iterator();
|
||||||
|
while (iter.hasNext()) {
|
||||||
|
HashMap<String, String> detail = (HashMap<String, String>) iter.next();
|
||||||
|
String key = detail.get("key");
|
||||||
|
String value = detail.get("value");
|
||||||
|
detailsMap.put(key, value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return detailsMap;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getProviderName() {
|
||||||
|
return providerName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setUrl(String url) {
|
||||||
|
this.url = url;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public void setProviderName(String providerName) {
|
||||||
|
this.providerName = providerName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDetails(Map<String, String> details) {
|
||||||
|
this.details = details;
|
||||||
|
}
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////
|
||||||
|
/////////////// API Implementation///////////////////
|
||||||
|
/////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getCommandName() {
|
||||||
|
return s_name;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public long getEntityOwnerId() {
|
||||||
|
return Account.ACCOUNT_ID_SYSTEM;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void execute(){
|
||||||
|
try{
|
||||||
|
ImageStore result = _storageService.migrateToObjectStore(getName(), getUrl(), getProviderName(), getDetails());
|
||||||
|
ImageStoreResponse storeResponse = null;
|
||||||
|
if (result != null ) {
|
||||||
|
storeResponse = _responseGenerator.createImageStoreResponse(result);
|
||||||
|
storeResponse.setResponseName(getCommandName());
|
||||||
|
storeResponse.setObjectName("imagestore");
|
||||||
|
setResponseObject(storeResponse);
|
||||||
|
} else {
|
||||||
|
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to add secondary storage");
|
||||||
|
}
|
||||||
|
} catch (DiscoveryException ex) {
|
||||||
|
s_logger.warn("Exception: ", ex);
|
||||||
|
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, ex.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -27,7 +27,6 @@ import org.apache.cloudstack.api.ApiErrorCode;
|
|||||||
import org.apache.cloudstack.api.BaseCmd;
|
import org.apache.cloudstack.api.BaseCmd;
|
||||||
import org.apache.cloudstack.api.Parameter;
|
import org.apache.cloudstack.api.Parameter;
|
||||||
import org.apache.cloudstack.api.ServerApiException;
|
import org.apache.cloudstack.api.ServerApiException;
|
||||||
import org.apache.cloudstack.api.command.admin.storage.AddImageStoreCmd;
|
|
||||||
import org.apache.cloudstack.api.response.ImageStoreResponse;
|
import org.apache.cloudstack.api.response.ImageStoreResponse;
|
||||||
|
|
||||||
import com.cloud.exception.DiscoveryException;
|
import com.cloud.exception.DiscoveryException;
|
||||||
@ -91,27 +90,19 @@ public class AddSwiftCmd extends BaseCmd {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void execute() {
|
public void execute() {
|
||||||
AddImageStoreCmd cmd = new AddImageStoreCmd() {
|
|
||||||
@Override
|
|
||||||
public Map<String, String> getDetails() {
|
|
||||||
Map<String, String> dm = new HashMap<String, String>();
|
Map<String, String> dm = new HashMap<String, String>();
|
||||||
dm.put(ApiConstants.ACCOUNT, getAccount());
|
dm.put(ApiConstants.ACCOUNT, getAccount());
|
||||||
dm.put(ApiConstants.USERNAME, getUsername());
|
dm.put(ApiConstants.USERNAME, getUsername());
|
||||||
dm.put(ApiConstants.KEY, getKey());
|
dm.put(ApiConstants.KEY, getKey());
|
||||||
return dm;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
cmd.setProviderName("Swift");
|
|
||||||
cmd.setUrl(this.getUrl());
|
|
||||||
|
|
||||||
try{
|
try{
|
||||||
ImageStore result = _storageService.discoverImageStore(cmd);
|
ImageStore result = _storageService.discoverImageStore(null, getUrl(), "Swift", null, dm);
|
||||||
ImageStoreResponse storeResponse = null;
|
ImageStoreResponse storeResponse = null;
|
||||||
if (result != null) {
|
if (result != null) {
|
||||||
storeResponse = _responseGenerator.createImageStoreResponse(result);
|
storeResponse = _responseGenerator.createImageStoreResponse(result);
|
||||||
storeResponse.setResponseName(getCommandName());
|
storeResponse.setResponseName(getCommandName());
|
||||||
storeResponse.setObjectName("secondarystorage");
|
storeResponse.setObjectName("secondarystorage");
|
||||||
this.setResponseObject(storeResponse);
|
setResponseObject(storeResponse);
|
||||||
} else {
|
} else {
|
||||||
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to add Swift secondary storage");
|
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to add Swift secondary storage");
|
||||||
}
|
}
|
||||||
|
|||||||
@ -16,6 +16,12 @@
|
|||||||
// under the License.
|
// under the License.
|
||||||
package org.apache.cloudstack.api.command.test;
|
package org.apache.cloudstack.api.command.test;
|
||||||
|
|
||||||
|
import static org.mockito.Matchers.anyLong;
|
||||||
|
import static org.mockito.Matchers.anyObject;
|
||||||
|
import static org.mockito.Matchers.anyString;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
import junit.framework.Assert;
|
import junit.framework.Assert;
|
||||||
import junit.framework.TestCase;
|
import junit.framework.TestCase;
|
||||||
|
|
||||||
@ -56,7 +62,8 @@ public class AddSecondaryStorageCmdTest extends TestCase {
|
|||||||
|
|
||||||
ImageStore store = Mockito.mock(ImageStore.class);
|
ImageStore store = Mockito.mock(ImageStore.class);
|
||||||
|
|
||||||
Mockito.when(resourceService.discoverImageStore(addImageStoreCmd)).thenReturn(store);
|
Mockito.when(resourceService.discoverImageStore(anyString(), anyString(), anyString(), anyLong(), (Map)anyObject()))
|
||||||
|
.thenReturn(store);
|
||||||
|
|
||||||
ResponseGenerator responseGenerator = Mockito.mock(ResponseGenerator.class);
|
ResponseGenerator responseGenerator = Mockito.mock(ResponseGenerator.class);
|
||||||
addImageStoreCmd._responseGenerator = responseGenerator;
|
addImageStoreCmd._responseGenerator = responseGenerator;
|
||||||
@ -83,7 +90,8 @@ public class AddSecondaryStorageCmdTest extends TestCase {
|
|||||||
StorageService resourceService = Mockito.mock(StorageService.class);
|
StorageService resourceService = Mockito.mock(StorageService.class);
|
||||||
addImageStoreCmd._storageService = resourceService;
|
addImageStoreCmd._storageService = resourceService;
|
||||||
|
|
||||||
Mockito.when(resourceService.discoverImageStore(addImageStoreCmd)).thenReturn(null);
|
Mockito.when(resourceService.discoverImageStore(anyString(), anyString(), anyString(), anyLong(), (Map)anyObject()))
|
||||||
|
.thenReturn(null);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
addImageStoreCmd.execute();
|
addImageStoreCmd.execute();
|
||||||
|
|||||||
@ -266,7 +266,7 @@ deleteImageStore=1
|
|||||||
createSecondaryStagingStore=1
|
createSecondaryStagingStore=1
|
||||||
listSecondaryStagingStores=1
|
listSecondaryStagingStores=1
|
||||||
deleteSecondaryStagingStore=1
|
deleteSecondaryStagingStore=1
|
||||||
prepareSecondaryStorageForMigration=1
|
updateCloudToUseObjectStore=1
|
||||||
|
|
||||||
#### host commands
|
#### host commands
|
||||||
addHost=3
|
addHost=3
|
||||||
|
|||||||
@ -42,9 +42,6 @@ import javax.crypto.spec.SecretKeySpec;
|
|||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
import javax.naming.ConfigurationException;
|
import javax.naming.ConfigurationException;
|
||||||
|
|
||||||
import com.cloud.service.ServiceOfferingVO;
|
|
||||||
import com.cloud.service.dao.ServiceOfferingDao;
|
|
||||||
import org.apache.cloudstack.framework.config.ConfigDepot;
|
|
||||||
import org.apache.commons.codec.binary.Base64;
|
import org.apache.commons.codec.binary.Base64;
|
||||||
import org.apache.log4j.Logger;
|
import org.apache.log4j.Logger;
|
||||||
|
|
||||||
@ -166,7 +163,7 @@ import org.apache.cloudstack.api.command.admin.storage.ListSecondaryStagingStore
|
|||||||
import org.apache.cloudstack.api.command.admin.storage.ListStoragePoolsCmd;
|
import org.apache.cloudstack.api.command.admin.storage.ListStoragePoolsCmd;
|
||||||
import org.apache.cloudstack.api.command.admin.storage.ListStorageProvidersCmd;
|
import org.apache.cloudstack.api.command.admin.storage.ListStorageProvidersCmd;
|
||||||
import org.apache.cloudstack.api.command.admin.storage.PreparePrimaryStorageForMaintenanceCmd;
|
import org.apache.cloudstack.api.command.admin.storage.PreparePrimaryStorageForMaintenanceCmd;
|
||||||
import org.apache.cloudstack.api.command.admin.storage.PrepareSecondaryStorageForMigrationCmd;
|
import org.apache.cloudstack.api.command.admin.storage.UpdateCloudToUseObjectStoreCmd;
|
||||||
import org.apache.cloudstack.api.command.admin.storage.UpdateStoragePoolCmd;
|
import org.apache.cloudstack.api.command.admin.storage.UpdateStoragePoolCmd;
|
||||||
import org.apache.cloudstack.api.command.admin.swift.AddSwiftCmd;
|
import org.apache.cloudstack.api.command.admin.swift.AddSwiftCmd;
|
||||||
import org.apache.cloudstack.api.command.admin.swift.ListSwiftsCmd;
|
import org.apache.cloudstack.api.command.admin.swift.ListSwiftsCmd;
|
||||||
@ -444,6 +441,7 @@ import org.apache.cloudstack.engine.orchestration.service.VolumeOrchestrationSer
|
|||||||
import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreManager;
|
import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreManager;
|
||||||
import org.apache.cloudstack.engine.subsystem.api.storage.StoragePoolAllocator;
|
import org.apache.cloudstack.engine.subsystem.api.storage.StoragePoolAllocator;
|
||||||
import org.apache.cloudstack.engine.subsystem.api.storage.VolumeDataFactory;
|
import org.apache.cloudstack.engine.subsystem.api.storage.VolumeDataFactory;
|
||||||
|
import org.apache.cloudstack.framework.config.ConfigDepot;
|
||||||
import org.apache.cloudstack.framework.config.ConfigKey;
|
import org.apache.cloudstack.framework.config.ConfigKey;
|
||||||
import org.apache.cloudstack.framework.config.dao.ConfigurationDao;
|
import org.apache.cloudstack.framework.config.dao.ConfigurationDao;
|
||||||
import org.apache.cloudstack.framework.config.impl.ConfigurationVO;
|
import org.apache.cloudstack.framework.config.impl.ConfigurationVO;
|
||||||
@ -535,6 +533,8 @@ import com.cloud.projects.ProjectManager;
|
|||||||
import com.cloud.resource.ResourceManager;
|
import com.cloud.resource.ResourceManager;
|
||||||
import com.cloud.server.ResourceTag.ResourceObjectType;
|
import com.cloud.server.ResourceTag.ResourceObjectType;
|
||||||
import com.cloud.server.auth.UserAuthenticator;
|
import com.cloud.server.auth.UserAuthenticator;
|
||||||
|
import com.cloud.service.ServiceOfferingVO;
|
||||||
|
import com.cloud.service.dao.ServiceOfferingDao;
|
||||||
import com.cloud.storage.DiskOfferingVO;
|
import com.cloud.storage.DiskOfferingVO;
|
||||||
import com.cloud.storage.GuestOS;
|
import com.cloud.storage.GuestOS;
|
||||||
import com.cloud.storage.GuestOSCategoryVO;
|
import com.cloud.storage.GuestOSCategoryVO;
|
||||||
@ -752,7 +752,7 @@ public class ManagementServerImpl extends ManagerBase implements ManagementServe
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void setPlanners(List<DeploymentPlanner> planners) {
|
public void setPlanners(List<DeploymentPlanner> planners) {
|
||||||
this._planners = planners;
|
_planners = planners;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
@ -2842,7 +2842,7 @@ public class ManagementServerImpl extends ManagerBase implements ManagementServe
|
|||||||
cmdList.add(CreateSecondaryStagingStoreCmd.class);
|
cmdList.add(CreateSecondaryStagingStoreCmd.class);
|
||||||
cmdList.add(ListSecondaryStagingStoresCmd.class);
|
cmdList.add(ListSecondaryStagingStoresCmd.class);
|
||||||
cmdList.add(DeleteSecondaryStagingStoreCmd.class);
|
cmdList.add(DeleteSecondaryStagingStoreCmd.class);
|
||||||
cmdList.add(PrepareSecondaryStorageForMigrationCmd.class);
|
cmdList.add(UpdateCloudToUseObjectStoreCmd.class);
|
||||||
cmdList.add(CreateApplicationLoadBalancerCmd.class);
|
cmdList.add(CreateApplicationLoadBalancerCmd.class);
|
||||||
cmdList.add(ListApplicationLoadBalancersCmd.class);
|
cmdList.add(ListApplicationLoadBalancersCmd.class);
|
||||||
cmdList.add(DeleteApplicationLoadBalancerCmd.class);
|
cmdList.add(DeleteApplicationLoadBalancerCmd.class);
|
||||||
|
|||||||
@ -41,7 +41,9 @@ import javax.ejb.Local;
|
|||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
import javax.naming.ConfigurationException;
|
import javax.naming.ConfigurationException;
|
||||||
|
|
||||||
import org.apache.cloudstack.api.command.admin.storage.AddImageStoreCmd;
|
import org.apache.log4j.Logger;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
import org.apache.cloudstack.api.command.admin.storage.CancelPrimaryStorageMaintenanceCmd;
|
import org.apache.cloudstack.api.command.admin.storage.CancelPrimaryStorageMaintenanceCmd;
|
||||||
import org.apache.cloudstack.api.command.admin.storage.CreateSecondaryStagingStoreCmd;
|
import org.apache.cloudstack.api.command.admin.storage.CreateSecondaryStagingStoreCmd;
|
||||||
import org.apache.cloudstack.api.command.admin.storage.CreateStoragePoolCmd;
|
import org.apache.cloudstack.api.command.admin.storage.CreateStoragePoolCmd;
|
||||||
@ -84,8 +86,6 @@ import org.apache.cloudstack.storage.datastore.db.TemplateDataStoreDao;
|
|||||||
import org.apache.cloudstack.storage.datastore.db.TemplateDataStoreVO;
|
import org.apache.cloudstack.storage.datastore.db.TemplateDataStoreVO;
|
||||||
import org.apache.cloudstack.storage.datastore.db.VolumeDataStoreDao;
|
import org.apache.cloudstack.storage.datastore.db.VolumeDataStoreDao;
|
||||||
import org.apache.cloudstack.storage.datastore.db.VolumeDataStoreVO;
|
import org.apache.cloudstack.storage.datastore.db.VolumeDataStoreVO;
|
||||||
import org.apache.log4j.Logger;
|
|
||||||
import org.springframework.stereotype.Component;
|
|
||||||
|
|
||||||
import com.cloud.agent.AgentManager;
|
import com.cloud.agent.AgentManager;
|
||||||
import com.cloud.agent.api.Answer;
|
import com.cloud.agent.api.Answer;
|
||||||
@ -269,7 +269,7 @@ public class StorageManagerImpl extends ManagerBase implements StorageManager, C
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void setDiscoverers(List<StoragePoolDiscoverer> discoverers) {
|
public void setDiscoverers(List<StoragePoolDiscoverer> discoverers) {
|
||||||
this._discoverers = discoverers;
|
_discoverers = discoverers;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected SearchBuilder<VMTemplateHostVO> HostTemplateStatesSearch;
|
protected SearchBuilder<VMTemplateHostVO> HostTemplateStatesSearch;
|
||||||
@ -1634,8 +1634,8 @@ public class StorageManagerImpl extends ManagerBase implements StorageManager, C
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ImageStore discoverImageStore(AddImageStoreCmd cmd) throws IllegalArgumentException, DiscoveryException, InvalidParameterValueException {
|
public ImageStore discoverImageStore(String name, String url, String providerName, Long dcId, Map details) throws IllegalArgumentException, DiscoveryException,
|
||||||
String providerName = cmd.getProviderName();
|
InvalidParameterValueException {
|
||||||
DataStoreProvider storeProvider = _dataStoreProviderMgr.getDataStoreProvider(providerName);
|
DataStoreProvider storeProvider = _dataStoreProviderMgr.getDataStoreProvider(providerName);
|
||||||
|
|
||||||
if (storeProvider == null) {
|
if (storeProvider == null) {
|
||||||
@ -1646,16 +1646,13 @@ public class StorageManagerImpl extends ManagerBase implements StorageManager, C
|
|||||||
providerName = storeProvider.getName(); // ignored passed provider name and use default image store provider name
|
providerName = storeProvider.getName(); // ignored passed provider name and use default image store provider name
|
||||||
}
|
}
|
||||||
|
|
||||||
Long dcId = cmd.getZoneId();
|
|
||||||
Map details = cmd.getDetails();
|
|
||||||
ScopeType scopeType = ScopeType.ZONE;
|
ScopeType scopeType = ScopeType.ZONE;
|
||||||
if (dcId == null) {
|
if (dcId == null) {
|
||||||
scopeType = ScopeType.REGION;
|
scopeType = ScopeType.REGION;
|
||||||
}
|
}
|
||||||
|
|
||||||
String name = cmd.getName();
|
|
||||||
if (name == null) {
|
if (name == null) {
|
||||||
name = cmd.getUrl();
|
name = url;
|
||||||
}
|
}
|
||||||
ImageStoreVO imageStore = _imageStoreDao.findByName(name);
|
ImageStoreVO imageStore = _imageStoreDao.findByName(name);
|
||||||
if (imageStore != null) {
|
if (imageStore != null) {
|
||||||
@ -1694,8 +1691,8 @@ public class StorageManagerImpl extends ManagerBase implements StorageManager, C
|
|||||||
|
|
||||||
Map<String, Object> params = new HashMap<String, Object>();
|
Map<String, Object> params = new HashMap<String, Object>();
|
||||||
params.put("zoneId", dcId);
|
params.put("zoneId", dcId);
|
||||||
params.put("url", cmd.getUrl());
|
params.put("url", url);
|
||||||
params.put("name", cmd.getName());
|
params.put("name", name);
|
||||||
params.put("details", details);
|
params.put("details", details);
|
||||||
params.put("scope", scopeType);
|
params.put("scope", scopeType);
|
||||||
params.put("providerName", storeProvider.getName());
|
params.put("providerName", storeProvider.getName());
|
||||||
@ -1730,6 +1727,41 @@ public class StorageManagerImpl extends ManagerBase implements StorageManager, C
|
|||||||
return (ImageStore)_dataStoreMgr.getDataStore(store.getId(), DataStoreRole.Image);
|
return (ImageStore)_dataStoreMgr.getDataStore(store.getId(), DataStoreRole.Image);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ImageStore migrateToObjectStore(String name, String url, String providerName, Map details) throws IllegalArgumentException, DiscoveryException,
|
||||||
|
InvalidParameterValueException {
|
||||||
|
// check if current cloud is ready to migrate, we only support cloud with only NFS secondary storages
|
||||||
|
List<ImageStoreVO> imgStores = _imageStoreDao.listImageStores();
|
||||||
|
List<ImageStoreVO> nfsStores = new ArrayList<ImageStoreVO>();
|
||||||
|
if (imgStores != null && imgStores.size() > 0) {
|
||||||
|
for (ImageStoreVO store : imgStores) {
|
||||||
|
if (!store.getProviderName().equals(DataStoreProvider.NFS_IMAGE)) {
|
||||||
|
throw new InvalidParameterValueException("We only support migrate NFS secondary storage to use object store!");
|
||||||
|
} else {
|
||||||
|
nfsStores.add(store);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// convert all NFS secondary storage to staging store
|
||||||
|
if (nfsStores != null && nfsStores.size() > 0) {
|
||||||
|
for (ImageStoreVO store : nfsStores) {
|
||||||
|
long storeId = store.getId();
|
||||||
|
|
||||||
|
_accountMgr.checkAccessAndSpecifyAuthority(CallContext.current().getCallingAccount(), store.getDataCenterId());
|
||||||
|
|
||||||
|
DataStoreProvider provider = dataStoreProviderMgr.getDataStoreProvider(store.getProviderName());
|
||||||
|
DataStoreLifeCycle lifeCycle = provider.getDataStoreLifeCycle();
|
||||||
|
DataStore secStore = dataStoreMgr.getDataStore(storeId, DataStoreRole.Image);
|
||||||
|
lifeCycle.migrateToObjectStore(secStore);
|
||||||
|
// update store_role in template_store_ref and snapshot_store_ref to ImageCache
|
||||||
|
_templateStoreDao.updateStoreRoleToCachce(storeId);
|
||||||
|
_snapshotStoreDao.updateStoreRoleToCache(storeId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// add object store
|
||||||
|
return discoverImageStore(name, url, providerName, null, details);
|
||||||
|
}
|
||||||
|
|
||||||
private void duplicateCacheStoreRecordsToRegionStore(long storeId) {
|
private void duplicateCacheStoreRecordsToRegionStore(long storeId) {
|
||||||
_templateStoreDao.duplicateCacheRecordsOnRegionStore(storeId);
|
_templateStoreDao.duplicateCacheRecordsOnRegionStore(storeId);
|
||||||
_snapshotStoreDao.duplicateCacheRecordsOnRegionStore(storeId);
|
_snapshotStoreDao.duplicateCacheRecordsOnRegionStore(storeId);
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user