Skip to content

Commit

Permalink
Merge pull request #59 from MissionCriticalCloud/fix/expand-sec-stora…
Browse files Browse the repository at this point in the history
…ge-pool

Expand sec storage pool based on required capacity
  • Loading branch information
Boris Schrijver authored Aug 18, 2016
2 parents 9e7aa71 + df314b3 commit b8f08b4
Show file tree
Hide file tree
Showing 10 changed files with 379 additions and 376 deletions.

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package com.cloud.storage.secondary;

class SecondaryStorageCapacityCalculator {

public int calculateRequiredCapacity(final int commandsStandBy, final int commandsPerVm) {
final double ratio = (double) commandsStandBy / (double) commandsPerVm;
return new Double(Math.ceil(ratio)).intValue();
}
}

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -11,33 +11,33 @@

public interface SecondaryStorageVmManager extends Manager {

public static final int DEFAULT_SS_VM_RAMSIZE = 512; // 512M
public static final int DEFAULT_SS_VM_CPUMHZ = 500; // 500 MHz
public static final int DEFAULT_SS_VM_MTUSIZE = 1500;
public static final int DEFAULT_SS_VM_CAPACITY = 50; // max command execution session per SSVM
public static final int DEFAULT_STANDBY_CAPACITY = 10; // standy capacity to reserve per zone
int DEFAULT_SS_VM_RAMSIZE = 512; // 512M
int DEFAULT_SS_VM_CPUMHZ = 500; // 500 MHz
int DEFAULT_SS_VM_MTUSIZE = 1500;
int DEFAULT_SS_VM_CAPACITY = 50; // max command execution session per SSVM
int DEFAULT_STANDBY_CAPACITY = 10; // standy capacity to reserve per zone

public static final String ALERT_SUBJECT = "secondarystoragevm-alert";
String ALERT_SUBJECT = "secondarystoragevm-alert";

public SecondaryStorageVmVO startSecStorageVm(long ssVmVmId);
SecondaryStorageVmVO startSecStorageVm(long ssVmVmId);

public boolean stopSecStorageVm(long ssVmVmId);
boolean stopSecStorageVm(long ssVmVmId);

public boolean rebootSecStorageVm(long ssVmVmId);
boolean rebootSecStorageVm(long ssVmVmId);

public boolean destroySecStorageVm(long ssVmVmId);
boolean destroySecStorageVm(long ssVmVmId);

public void onAgentConnect(Long dcId, StartupCommand cmd);
void onAgentConnect(Long dcId, StartupCommand cmd);

public boolean generateFirewallConfiguration(Long agentId);
boolean generateFirewallConfiguration(Long agentId);

public boolean generateVMSetupCommand(Long hostId);
boolean generateVMSetupCommand(Long hostId);

public Pair<HostVO, SecondaryStorageVmVO> assignSecStorageVm(long zoneId, Command cmd);
Pair<HostVO, SecondaryStorageVmVO> assignSecStorageVm(long zoneId, Command cmd);

boolean generateSetupCommand(Long hostId);

public List<HostVO> listUpAndConnectingSecondaryStorageVmHost(Long dcId);
List<HostVO> listUpAndConnectingSecondaryStorageVmHost(Long dcId);

public HostVO pickSsvmHost(HostVO ssHost);
HostVO pickSsvmHost(HostVO ssHost);
}
Original file line number Diff line number Diff line change
Expand Up @@ -20,21 +20,25 @@
import com.cloud.utils.DateUtil;
import com.cloud.utils.component.ManagerBase;
import com.cloud.utils.exception.CloudRuntimeException;
import com.cloud.vm.AfterScanAction;
import com.cloud.vm.NicProfile;
import com.cloud.vm.SystemVm;
import com.cloud.vm.SystemVmLoadScanHandler;
import com.cloud.vm.VirtualMachineProfile;
import org.apache.cloudstack.context.CallContext;

import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
import java.util.stream.Stream;

import org.apache.commons.collections.CollectionUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public abstract class SystemVmManagerBase extends ManagerBase {
public abstract class SystemVmManagerBase extends ManagerBase implements SystemVmLoadScanHandler<Long> {
private static final Logger logger = LoggerFactory.getLogger(SystemVmManagerBase.class);

protected void computeVmIps(final SystemVm vmVO, final DataCenter dc, final List<NicProfile> nics) {
Expand Down Expand Up @@ -131,4 +135,26 @@ protected String computeManagementServerIpList(final ManagementServerService man
return managementServerService.discoverManagementServerIps()
.collect(Collectors.joining(PROPERTY_LIST_SEPARATOR));
}

public void resizePool(final Long pool, final AfterScanAction action, final Object actionArgs) {
final int count = action.getValue();
final Stream<Integer> iterations = IntStream.range(0, count).boxed();
switch (action.getAction()) {
case EXPAND:
iterations.forEach(i -> {
logger.debug("Expanding pool [iteration {}/{}]", i + 1, count);
expandPool(pool, actionArgs);
});
break;
case SHRINK:
iterations.forEach(i -> {
logger.debug("Shrinking pool [iteration {}/{}]", i + 1, count);
shrinkPool(pool, actionArgs);
});
break;
case NOP:
logger.debug("Breaking off resizing pool because no action was selected");
return;
}
}
}
46 changes: 46 additions & 0 deletions cosmic-core/server/src/main/java/com/cloud/vm/AfterScanAction.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
package com.cloud.vm;

import org.apache.commons.lang.builder.ToStringBuilder;

public class AfterScanAction {
public enum Action {
NOP, EXPAND, SHRINK
}

private final Action action;
private final int value;

private AfterScanAction(final Action action, final int value) {
this.action = action;
this.value = value;
}

public static AfterScanAction expand() {
return new AfterScanAction(Action.EXPAND, 1);
}

public static AfterScanAction expand(final int ammoun) {
return new AfterScanAction(Action.EXPAND, ammoun);
}

public static AfterScanAction shrink() {
return new AfterScanAction(Action.SHRINK, 1);
}

public static AfterScanAction nop() {
return new AfterScanAction(Action.NOP, 0);
}

public Action getAction() {
return action;
}

public int getValue() {
return value;
}

@Override
public String toString() {
return ToStringBuilder.reflectionToString(this);
}
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package com.cloud.vm;

import com.cloud.utils.Pair;
import com.cloud.vm.SystemVmLoadScanner.AfterScanAction;

public interface SystemVmLoadScanHandler<T> {
String getScanHandlerName();
Expand All @@ -16,6 +15,8 @@ public interface SystemVmLoadScanHandler<T> {

Pair<AfterScanAction, Object> scanPool(T pool);

void resizePool(T pool, AfterScanAction action, Object actionArgs);

void expandPool(T pool, Object actionArgs);

void shrinkPool(T pool, Object actionArgs);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -71,18 +71,7 @@ private void loadScan() {
if (_scanHandler.isPoolReadyForScan(p)) {
final Pair<AfterScanAction, Object> actionInfo = _scanHandler.scanPool(p);

switch (actionInfo.first()) {
case nop:
break;

case expand:
_scanHandler.expandPool(p, actionInfo.second());
break;

case shrink:
_scanHandler.shrinkPool(p, actionInfo.second());
break;
}
_scanHandler.resizePool(p, actionInfo.first(), actionInfo.second());
}
}

Expand All @@ -103,8 +92,4 @@ public void stop() {

_capacityScanLock.releaseRef();
}

public enum AfterScanAction {
nop, expand, shrink
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
package com.cloud.storage.secondary;

import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.core.Is.is;

import java.util.Arrays;
import java.util.Collection;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import org.junit.runners.Parameterized.Parameters;

@RunWith(Parameterized.class)
public class SecondaryStorageCapacityCalculatorTest {

@Parameters(name = "{index}: calculateRequiredCapacity({0},{1})={2}")
public static Collection<Integer[]> data() {
return Arrays.asList(new Integer[][]{
{1, 1, 1}, {2, 2, 1}, {3, 3, 1}, {10, 10, 1}, // required capacity is exactly matched by 1 VM
{2, 1, 2}, {3, 1, 3}, {4, 1, 4}, {5, 1, 5}, // required capacity is met by having as many VMs as the required stand by
{4, 2, 2}, {6, 2, 3}, {8, 2, 4}, {10, 2, 5}, // required capacity is met by having as many VMs as the required stand by (x2)
{6, 3, 2}, {9, 3, 3}, {12, 3, 4}, {15, 3, 5}, // required capacity is met by having as many VMs as the required stand by (x3)
{1, 2, 1}, {1, 3, 1}, {2, 4, 1}, {3, 6, 1}, // required capacity is surpassed (single VM is enough)
});
}

private final int commandsStandBy;
private final int commandsPerVm;
private final int expected;

public SecondaryStorageCapacityCalculatorTest(final int commandsStandBy, final int commandsPerVm, final int expected) {
this.commandsStandBy = commandsStandBy;
this.commandsPerVm = commandsPerVm;
this.expected = expected;
}

@Test
public void test_calculateRequiredCapacity() throws Exception {
final SecondaryStorageCapacityCalculator calculator = new SecondaryStorageCapacityCalculator();

final int requiredVms = calculator.calculateRequiredCapacity(commandsStandBy, commandsPerVm);

assertThat(requiredVms, is(expected));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
import static org.mockito.Mockito.when;

import com.cloud.managementserver.ManagementServerService;
import com.cloud.utils.Pair;
import com.cloud.vm.AfterScanAction;

import java.util.stream.Stream;

Expand Down Expand Up @@ -32,5 +34,50 @@ class SystemVmManagerBaseImpl extends SystemVmManagerBase {
public String computeManagementServerIpList(final ManagementServerService managementServerService) {
return super.computeManagementServerIpList(managementServerService);
}

@Override
public String getScanHandlerName() {
return null;
}

@Override
public boolean canScan() {
return false;
}

@Override
public void onScanStart() {

}

@Override
public Long[] getScannablePools() {
return new Long[0];
}

@Override
public boolean isPoolReadyForScan(final Long pool) {
return false;
}

@Override
public Pair<AfterScanAction, Object> scanPool(final Long pool) {
return null;
}

@Override
public void expandPool(final Long pool, final Object actionArgs) {

}

@Override
public void shrinkPool(final Long pool, final Object actionArgs) {

}

@Override
public void onScanEnd() {

}
}
}

0 comments on commit b8f08b4

Please # to comment.