Summary: adding new files

Detail: missed adding completely new files in initial commit

Signed-off-by: Marcus Sorensen <marcus@betterservers.com> 1357669762 -0700
This commit is contained in:
Marcus Sorensen 2013-01-08 11:29:22 -07:00
parent 8f1e6bebed
commit 7149d737e1
5 changed files with 734 additions and 0 deletions

View File

@ -0,0 +1,40 @@
// 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 com.cloud.agent.api.storage;
import com.cloud.agent.api.Answer;
public class ResizeVolumeAnswer extends Answer {
private long newSize;
protected ResizeVolumeAnswer() {
}
public ResizeVolumeAnswer(ResizeVolumeCommand cmd, boolean result, String details, long newSize) {
super(cmd, result, details);
this.newSize = newSize;
}
public ResizeVolumeAnswer(ResizeVolumeCommand cmd, boolean result, String details) {
super(cmd, result, details);
}
public long getNewSize() {
return newSize;
}
}

View File

@ -0,0 +1,86 @@
// 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 com.cloud.agent.api.storage;
import com.cloud.agent.api.Command;
import com.cloud.agent.api.to.StorageFilerTO;
import com.cloud.storage.StoragePool;
public class ResizeVolumeCommand extends Command {
private String path;
private StorageFilerTO pool;
private String vmInstance;
private Long newSize;
private Long currentSize;
private boolean shrinkOk;
protected ResizeVolumeCommand() {
}
public ResizeVolumeCommand(String path,
StorageFilerTO pool,
Long currentSize,
Long newSize,
boolean shrinkOk,
String vmInstance)
{
this.path = path;
this.pool = pool;
this.vmInstance = vmInstance;
this.currentSize = currentSize;
this.newSize = newSize;
this.shrinkOk = shrinkOk;
}
public String getPath() {
return path;
}
public String getPoolUuid() {
return pool.getUuid();
}
public StorageFilerTO getPool() {
return pool;
}
public long getNewSize() {
return newSize;
}
public long getCurrentSize() {
return currentSize;
}
public boolean getShrinkOk() {
return shrinkOk;
}
public String getInstanceName() {
return vmInstance;
}
/**
* {@inheritDoc}
*/
@Override
public boolean executeInSequence() {
return false;
}
}

View File

@ -0,0 +1,156 @@
// 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 com.cloud.api.commands;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Pattern;
import java.util.regex.Matcher;
import org.apache.log4j.Logger;
import com.cloud.api.ApiConstants;
import com.cloud.api.BaseListTaggedResourcesCmd;
import com.cloud.api.BaseCmd;
import com.cloud.api.BaseAsyncCmd;
import com.cloud.api.IdentityMapper;
import com.cloud.api.Implementation;
import com.cloud.api.Parameter;
import com.cloud.api.response.ListResponse;
import com.cloud.api.response.VolumeResponse;
import com.cloud.api.ServerApiException;
import com.cloud.exception.InvalidParameterValueException;
import com.cloud.exception.PermissionDeniedException;
import com.cloud.exception.ResourceAllocationException;
import com.cloud.async.AsyncJob;
import com.cloud.event.EventTypes;
import com.cloud.projects.Project;
import com.cloud.storage.Volume;
import com.cloud.user.Account;
import com.cloud.user.UserContext;
@Implementation(description="Resizes a volume", responseObject=VolumeResponse.class)
public class ResizeVolumeCmd extends BaseAsyncCmd {
public static final Logger s_logger = Logger.getLogger(ResizeVolumeCmd.class.getName());
private static final String s_name = "resizevolumeresponse";
/////////////////////////////////////////////////////
//////////////// API parameters /////////////////////
/////////////////////////////////////////////////////
@IdentityMapper(entityTableName="volumes")
@Parameter(name=ApiConstants.ID, type=CommandType.LONG, description="the ID of the disk volume")
private Long id;
@Parameter(name=ApiConstants.SIZE, type=CommandType.LONG, required=false, description="New volume size in G")
private Long size;
@Parameter(name=ApiConstants.SHRINK_OK, type=CommandType.BOOLEAN, required=false, description="Verify OK to Shrink")
private boolean shrinkOk;
@IdentityMapper(entityTableName="disk_offering")
@Parameter(name=ApiConstants.DISK_OFFERING_ID, type=CommandType.LONG, required=false, description="new disk offering id")
private Long newDiskOfferingId;
/////////////////////////////////////////////////////
/////////////////// Accessors ///////////////////////
/////////////////////////////////////////////////////
public Long getEntityId() {
return id;
}
public Long getSize() {
return size;
}
public boolean getShrinkOk() {
return shrinkOk;
}
public Long getNewDiskOfferingId() {
return newDiskOfferingId;
}
/////////////////////////////////////////////////////
/////////////// API Implementation///////////////////
/////////////////////////////////////////////////////
@Override
public String getCommandName() {
return s_name;
}
@Override
public AsyncJob.Type getInstanceType() {
return AsyncJob.Type.Volume;
}
public static String getResultObjectName() {
return "volume";
}
@Override
public long getEntityOwnerId() {
Volume volume = _entityMgr.findById(Volume.class, getEntityId());
if (volume == null) {
throw new InvalidParameterValueException("Unable to find volume by id=" + id);
}
Account account = _accountService.getAccount(volume.getAccountId());
//Can resize volumes for enabled projects/accounts only
if (account.getType() == Account.ACCOUNT_TYPE_PROJECT) {
Project project = _projectService.findByProjectAccountId(volume.getAccountId());
if (project.getState() != Project.State.Active) {
throw new PermissionDeniedException("Can't add resources to project id=" + project.getId() + " in state=" + project.getState() + " as it's no longer active");
}
} else if (account.getState() == Account.State.disabled) {
throw new PermissionDeniedException("The owner of volume " + id + " is disabled: " + account);
}
return volume.getAccountId();
}
@Override
public String getEventType() {
return EventTypes.EVENT_VOLUME_RESIZE;
}
@Override
public String getEventDescription() {
return "Volume Id: " + getEntityId() + " to size " + getSize() + "G" ;
}
@Override
public void execute(){
UserContext.current().setEventDetails("Volume Id: " + getEntityId() + " to size " + getSize() + "G");
Volume volume = _storageService.resizeVolume(this);
if (volume != null) {
VolumeResponse response = _responseGenerator.createVolumeResponse(volume);
//FIXME - have to be moved to ApiResponseHelper
response.setResponseName(getCommandName());
this.setResponseObject(response);
} else {
throw new ServerApiException(BaseCmd.INTERNAL_ERROR, "Failed to resize volume");
}
}
}

View File

@ -0,0 +1,199 @@
// 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 src.com.cloud.agent.api.test;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.assertFalse;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import org.junit.Test;
import com.cloud.agent.api.storage.ResizeVolumeCommand;
import com.cloud.agent.api.to.StorageFilerTO;
import com.cloud.storage.StoragePool;
import com.cloud.storage.Storage.StoragePoolType;
import com.cloud.storage.StoragePoolStatus;
public class ResizeVolumeCommandTest {
public StoragePool dummypool = new StoragePool() {
public long getId() {
return 1L;
};
public String getName() {
return "name";
};
public String getUuid() {
return "bed9f83e-cac3-11e1-ac8a-0050568b007e";
};
public StoragePoolType getPoolType() {
return StoragePoolType.Filesystem;
};
public Date getCreated() {
Date date = null;
try {
date = new SimpleDateFormat("MM/dd/yyyy HH:mm:ss")
.parse("01/01/1970 12:12:12");
} catch (ParseException e) {
e.printStackTrace();
}
return date;
}
public Date getUpdateTime() {
return new Date();
};
public long getDataCenterId() {
return 0L;
};
public long getCapacityBytes() {
return 0L;
};
public long getAvailableBytes() {
return 0L;
};
public Long getClusterId() {
return 0L;
};
public String getHostAddress() {
return "hostAddress";
};
public String getPath() {
return "path";
};
public String getUserInfo() {
return "userInfo";
};
public boolean isShared() {
return false;
};
public boolean isLocal() {
return false;
};
public StoragePoolStatus getStatus() {
return StoragePoolStatus.Up;
};
public int getPort() {
return 25;
};
public Long getPodId() {
return 0L;
};
};
Long newSize = 4194304L;
Long currentSize = 1048576L;
ResizeVolumeCommand rv = new ResizeVolumeCommand("dummydiskpath",
new StorageFilerTO(dummypool), currentSize, newSize, false,
"vmName");
@Test
public void testExecuteInSequence() {
boolean b = rv.executeInSequence();
assertFalse(b);
}
@Test
public void testGetPath() {
String path = rv.getPath();
assertTrue(path.equals("dummydiskpath"));
}
@Test
public void testGetPoolUuid() {
String poolUuid = rv.getPoolUuid();
assertTrue(poolUuid.equals("bed9f83e-cac3-11e1-ac8a-0050568b007e"));
}
@Test
public void testGetPool() {
StorageFilerTO pool = rv.getPool();
Long id = pool.getId();
Long expectedL = 1L;
assertEquals(expectedL, id);
String uuid = pool.getUuid();
assertTrue(uuid.equals("bed9f83e-cac3-11e1-ac8a-0050568b007e"));
String host = pool.getHost();
assertTrue(host.equals("hostAddress"));
String path = pool.getPath();
assertTrue(path.equals("path"));
String userInfo = pool.getUserInfo();
assertTrue(userInfo.equals("userInfo"));
Integer port = pool.getPort();
Integer expectedI = 25;
assertEquals(expectedI, port);
StoragePoolType type = pool.getType();
assertEquals(StoragePoolType.Filesystem, type);
String str = pool.toString();
assertTrue(str.equals("Pool[" + id.toString() + "|" + host + ":"
+ port.toString() + "|" + path + "]"));
}
@Test
public void testGetNewSize() {
long newSize = rv.getNewSize();
assertTrue(newSize == 4194304L);
}
@Test
public void testGetCurrentSize() {
long currentSize = rv.getCurrentSize();
assertTrue(currentSize == 1048576L);
}
@Test
public void testGetShrinkOk() {
assertFalse(rv.getShrinkOk());
}
@Test
public void testGetInstanceName() {
String vmName = rv.getInstanceName();
assertTrue(vmName.equals("vmName"));
}
}

View File

@ -0,0 +1,253 @@
#!/usr/bin/env bash
# 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.
# resizevolume.sh -- resize a volume
usage() {
printf "Usage: %s: -c <current-volume-size> -s <new-volume-size> -p <volume path> -v <vm instance name> -t <storage-type> -r <shrink-bool>\n" $(basename $0) >&2
}
getdevmappername() {
local path=$1
local devmappername=`readlink -f $path |cut -d/ -f3`
if [[ $devmappername =~ "dm-" ]]
then
dmname=$devmappername
return 0
else
return 1;
fi
}
getdevmappersize() {
local dm=$1
if [ ! -e "/sys/block/${dm}/size" ]
then
log "unable to find ${dm} in /sys/block" 1
exit 1
fi
actualsize=$((`cat /sys/block/${dm}/size`*512));
if [[ -z "$actualsize" ]]
then
log "unable to find actual size of ${dm}" 1
exit 1
fi
return 0
}
# log "message" 1 <-- prints to stdout as well as log, to pass error up to cloudstack
# log "message" prints only to log file
# variable shouldwelog controls whether we print to log file
log() {
local d=`date`
local msg=${1}
local stdout=${2}
if [ ! -z "$stdout" ]
then
echo $1
fi
if [ $shouldwelog -eq 1 ]
then
echo "$d - $1" >> /var/log/cloud/agent/resizevolume.log
fi
}
failshrink() {
# if this is a shrink operation, fail if commands will shrink the volume and we haven't signed of on shrinking
if [ $actualsize -gt $newsize ]
then
if [ "$shrink" == "false" ]
then
log "result would shrink the volume from $actualsize to $newsize, but confirmation to shrink wasn't passed. Shrink='$shrink'" 1
exit 1
fi
fi
}
notifyqemu() {
#move this back into cloudstack libvirt calls once the libvirt java bindings support block resize
#we try to inform hypervisor of new size, but don't fail if we can't
if `virsh help 2>/dev/null | grep -q blockresize`
then
if `virsh domstate $vmname >/dev/null 2>&1`
then
sizeinkb=$(($newsize/1024))
virsh blockresize --domain $vmname --path $path --size $sizeinkb >/dev/null 2>&1
retval=$?
if [ -z $retval ] || [ $retval -ne 0 ]
then
log "failed to live resize $path to size of $sizeinkb kb" 1
else
liveresize='true'
fi
fi
fi
}
resizelvm() {
local dmname=''
local actualsize=''
local liveresize='false'
##### sanity checks #####
if ! `lvresize --version > /dev/null 2>&1`
then
log "unable to resolve executable 'lvresize'" 1
exit 1
fi
if ! `virsh --version > /dev/null 2>&1`
then
log "unable to resolve executable 'virsh'" 1
exit 1
fi
##### end sanity #####
if ! getdevmappername $path
then
log "unable to resolve a device mapper dev from $path" 1
exit 1
fi
getdevmappersize $dmname
if [ $actualsize -ne $currentsize ]
then
log "disk isn't the size we think it is: cloudstack said $currentsize, disk said $actualsize."
fi
# if this is a shrink operation, fail if commands will shrink the volume and we haven't signed of on shrinking
failshrink
output=`lvresize -f -L ${newsize}B $path 2>&1`
retval=$?
if [ -z $retval ] || [ $retval -ne 0 ]
then
log "lvresize failed: $output " 1
exit 1
fi
#move this back into cloudstack libvirt calls once the libvirt java bindings support block resize
#we try to inform hypervisor of new size, but don't fail if we can't
notifyqemu
log "performed successful resize - dm:$dmname currentsize:$currentsize newsize:$newsize path:$path type:$ptype vmname:$vmname live:$liveresize shrink:$shrink"
}
resizeqcow2() {
##### sanity checks #####
if [ ! -e "$path" ]
then
log "unable to find file $path" 1
exit 1
fi
if ! `qemu-img info /dev/null > /dev/null 2>&1`
then
log "unable to resolve executable 'qemu-img'" 1
exit 1
fi
if ! `virsh --version > /dev/null 2>&1`
then
log "unable to resolve executable 'virsh'" 1
exit 1
fi
##### end sanity #####
$actualsize=`qemu-img info $path | grep "virtual size" | sed -re 's/^.*\(([0-9]+).*$/\1/g'`
if [ $actualsize -ne $currentsize ]
then
log "disk isn't the size we think it is: cloudstack said $currentsize, disk said $actualsize."
fi
# if this is a shrink operation, fail if commands will shrink the volume and we haven't signed of on shrinking
failshrink
output=`qemu-img resize $path $newsize 2>&1`
retval=$?
if [ -z $retval ] || [ $retval -ne 0 ]
then
log "qemu-img resize failed: $output" 1
exit 1
fi
#move this back into cloudstack libvirt calls once the libvirt java bindings support block resize
#we try to inform hypervisor of new size, but don't fail if we can't
notifyqemu
log "performed successful resize - currentsize:$currentsize newsize:$newsize path:$path type:$ptype vmname:$vmname live:$liveresize shrink:$shrink"
}
sflag=
cflag=
pflag=
vflag=
tflag=
rflag=
while getopts 'c:s:v:p:t:r:' OPTION
do
case $OPTION in
s) sflag=1
newsize="$OPTARG"
;;
c) cflag=1
currentsize="$OPTARG"
;;
v) vflag=1
vmname="$OPTARG"
;;
p) dflag=1
path="$OPTARG"
;;
t) tflag=1
ptype="$OPTARG"
;;
r) rflag=1
shrink="$OPTARG"
;;
?) usage
exit 2
;;
esac
done
shouldwelog=1 #set this to 1 while debugging to get output in /var/log/cloud/agent/resizevolume.log
if [ "$ptype" == "CLVM" ]
then
resizelvm
elif [ "$ptype" == "QCOW2" ]
then
resizeqcow2
else
echo "unsupported type $ptype"
exit 1;
fi
exit 0