mirror of https://github.com/apache/cloudstack.git
Merge remote-tracking branch 'origin/main' into add-description-for-secondary-ip-addresses
This commit is contained in:
commit
c19b7cbc73
|
|
@ -0,0 +1,20 @@
|
|||
# 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.
|
||||
|
||||
[codespell]
|
||||
ignore-words = .github/linters/codespell.txt
|
||||
skip = systemvm/agent/noVNC/*,ui/package.json,ui/package-lock.json,ui/public/js/less.min.js,ui/public/locales/*.json,server/src/test/java/org/apache/cloudstack/network/ssl/CertServiceTest.java,test/integration/smoke/test_ssl_offloading.py
|
||||
|
|
@ -17,6 +17,7 @@
|
|||
|
||||
/plugins/storage/volume/linstor @rp-
|
||||
/plugins/storage/volume/storpool @slavkap
|
||||
/plugins/storage/volume/ontap @rajiv1 @sandeeplocharla @piyush5 @suryag
|
||||
|
||||
.pre-commit-config.yaml @jbampton
|
||||
/.github/linters/ @jbampton
|
||||
|
|
|
|||
|
|
@ -22,8 +22,19 @@
|
|||
|
||||
version: 2
|
||||
updates:
|
||||
- package-ecosystem: "maven" # See documentation for possible values
|
||||
directory: "/" # Location of package manifests
|
||||
- package-ecosystem: "github-actions"
|
||||
directory: "/"
|
||||
open-pull-requests-limit: 2
|
||||
schedule:
|
||||
interval: "weekly"
|
||||
groups:
|
||||
github-actions-dependencies:
|
||||
patterns:
|
||||
- "*"
|
||||
cooldown:
|
||||
default-days: 7
|
||||
- package-ecosystem: "maven"
|
||||
directory: "/"
|
||||
schedule:
|
||||
interval: "daily"
|
||||
cooldown:
|
||||
|
|
|
|||
|
|
@ -30,7 +30,7 @@ jobs:
|
|||
build:
|
||||
runs-on: ubuntu-22.04
|
||||
steps:
|
||||
- uses: actions/checkout@v5
|
||||
- uses: actions/checkout@v6
|
||||
|
||||
- name: Set up JDK 17
|
||||
uses: actions/setup-java@v5
|
||||
|
|
|
|||
|
|
@ -217,7 +217,7 @@ jobs:
|
|||
smoke/test_list_volumes"]
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v5
|
||||
- uses: actions/checkout@v6
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
|
|
|
|||
|
|
@ -32,7 +32,7 @@ jobs:
|
|||
name: codecov
|
||||
runs-on: ubuntu-22.04
|
||||
steps:
|
||||
- uses: actions/checkout@v5
|
||||
- uses: actions/checkout@v6
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
|
|
|
|||
|
|
@ -35,7 +35,7 @@ jobs:
|
|||
language: ["actions"]
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v5
|
||||
uses: actions/checkout@v6
|
||||
- name: Initialize CodeQL
|
||||
uses: github/codeql-action/init@v3
|
||||
with:
|
||||
|
|
|
|||
|
|
@ -47,7 +47,7 @@ jobs:
|
|||
- name: Set Docker repository name
|
||||
run: echo "DOCKER_REPOSITORY=apache" >> $GITHUB_ENV
|
||||
|
||||
- uses: actions/checkout@v5
|
||||
- uses: actions/checkout@v6
|
||||
|
||||
- name: Set ACS version
|
||||
run: echo "ACS_VERSION=$(grep '<version>' pom.xml | head -2 | tail -1 | cut -d'>' -f2 |cut -d'<' -f1)" >> $GITHUB_ENV
|
||||
|
|
|
|||
|
|
@ -32,7 +32,7 @@ jobs:
|
|||
name: Main Sonar JaCoCo Build
|
||||
runs-on: ubuntu-22.04
|
||||
steps:
|
||||
- uses: actions/checkout@v5
|
||||
- uses: actions/checkout@v6
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
|
|
|
|||
|
|
@ -32,7 +32,7 @@ jobs:
|
|||
runs-on: ubuntu-22.04
|
||||
steps:
|
||||
- name: Check Out
|
||||
uses: actions/checkout@v5
|
||||
uses: actions/checkout@v6
|
||||
- name: Install
|
||||
run: |
|
||||
python -m pip install --upgrade pip
|
||||
|
|
|
|||
|
|
@ -30,7 +30,7 @@ jobs:
|
|||
build:
|
||||
runs-on: ubuntu-22.04
|
||||
steps:
|
||||
- uses: actions/checkout@v5
|
||||
- uses: actions/checkout@v6
|
||||
- name: Set up JDK 17
|
||||
uses: actions/setup-java@v5
|
||||
with:
|
||||
|
|
|
|||
|
|
@ -33,7 +33,7 @@ jobs:
|
|||
name: Sonar JaCoCo Coverage
|
||||
runs-on: ubuntu-22.04
|
||||
steps:
|
||||
- uses: actions/checkout@v5
|
||||
- uses: actions/checkout@v6
|
||||
with:
|
||||
ref: "refs/pull/${{ github.event.number }}/merge"
|
||||
fetch-depth: 0
|
||||
|
|
|
|||
|
|
@ -31,7 +31,7 @@ jobs:
|
|||
runs-on: ubuntu-22.04
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v5
|
||||
- uses: actions/checkout@v6
|
||||
|
||||
- name: Set up Node
|
||||
uses: actions/setup-node@v5
|
||||
|
|
|
|||
|
|
@ -162,17 +162,15 @@ repos:
|
|||
- id: forbid-submodules
|
||||
- id: mixed-line-ending
|
||||
- id: trailing-whitespace
|
||||
files: ^(LICENSE|NOTICE)$|\.(bat|cfg|cs|css|gitignore|header|in|install|java|md|properties|py|rb|rc|sh|sql|te|template|txt|ucls|vue|xml|xsl|yaml|yml)$|^cloud-cli/bindir/cloud-tool$|^debian/changelog$
|
||||
files: ^(LICENSE|NOTICE)$|README$|\.(bat|cfg|config|cs|css|erb|gitignore|header|in|install|java|md|properties|py|rb|rc|sh|sql|svg|te|template|txt|ucls|vue|xml|xsl|yaml|yml)$|^cloud-cli/bindir/cloud-tool$|^debian/changelog$
|
||||
args: [--markdown-linebreak-ext=md]
|
||||
exclude: ^services/console-proxy/rdpconsole/src/test/doc/freerdp-debug-log\.txt$
|
||||
- repo: https://github.com/codespell-project/codespell
|
||||
rev: v2.4.1
|
||||
rev: v2.4.2
|
||||
hooks:
|
||||
- id: codespell
|
||||
name: run codespell
|
||||
description: Check spelling with codespell
|
||||
args: [--ignore-words=.github/linters/codespell.txt]
|
||||
exclude: ^systemvm/agent/noVNC/|^ui/package\.json$|^ui/package-lock\.json$|^ui/public/js/less\.min\.js$|^ui/public/locales/.*[^n].*\.json$|^server/src/test/java/org/apache/cloudstack/network/ssl/CertServiceTest.java$|^test/integration/smoke/test_ssl_offloading.py$
|
||||
- repo: https://github.com/pycqa/flake8
|
||||
rev: 7.0.0
|
||||
hooks:
|
||||
|
|
@ -186,7 +184,7 @@ repos:
|
|||
description: check Markdown files with markdownlint
|
||||
args: [--config=.github/linters/.markdown-lint.yml]
|
||||
types: [markdown]
|
||||
files: \.(md|mdown|markdown)$
|
||||
files: \.md$
|
||||
- repo: https://github.com/adrienverge/yamllint
|
||||
rev: v1.37.1
|
||||
hooks:
|
||||
|
|
|
|||
|
|
@ -457,3 +457,6 @@ iscsi.session.cleanup.enabled=false
|
|||
|
||||
# Instance conversion VIRT_V2V_TMPDIR env var
|
||||
#convert.instance.env.virtv2v.tmpdir=
|
||||
|
||||
# Time, in seconds, to wait before retrying to rebase during the incremental snapshot process.
|
||||
# incremental.snapshot.retry.rebase.wait=60
|
||||
|
|
|
|||
|
|
@ -885,6 +885,11 @@ public class AgentProperties{
|
|||
*/
|
||||
public static final Property<Boolean> CREATE_FULL_CLONE = new Property<>("create.full.clone", false);
|
||||
|
||||
/**
|
||||
* Time, in seconds, to wait before retrying to rebase during the incremental snapshot process.
|
||||
* */
|
||||
public static final Property<Integer> INCREMENTAL_SNAPSHOT_RETRY_REBASE_WAIT = new Property<>("incremental.snapshot.retry.rebase.wait", 60);
|
||||
|
||||
|
||||
public static class Property <T>{
|
||||
private String name;
|
||||
|
|
|
|||
|
|
@ -26,10 +26,13 @@ public final class BucketTO {
|
|||
|
||||
private String secretKey;
|
||||
|
||||
private long accountId;
|
||||
|
||||
public BucketTO(Bucket bucket) {
|
||||
this.name = bucket.getName();
|
||||
this.accessKey = bucket.getAccessKey();
|
||||
this.secretKey = bucket.getSecretKey();
|
||||
this.accountId = bucket.getAccountId();
|
||||
}
|
||||
|
||||
public BucketTO(String name) {
|
||||
|
|
@ -47,4 +50,8 @@ public final class BucketTO {
|
|||
public String getSecretKey() {
|
||||
return this.secretKey;
|
||||
}
|
||||
|
||||
public long getAccountId() {
|
||||
return this.accountId;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -33,6 +33,7 @@ public class NicTO extends NetworkTO {
|
|||
boolean dpdkEnabled;
|
||||
Integer mtu;
|
||||
Long networkId;
|
||||
boolean enabled;
|
||||
|
||||
String networkSegmentName;
|
||||
|
||||
|
|
@ -154,4 +155,12 @@ public class NicTO extends NetworkTO {
|
|||
public void setNetworkSegmentName(String networkSegmentName) {
|
||||
this.networkSegmentName = networkSegmentName;
|
||||
}
|
||||
|
||||
public boolean isEnabled() {
|
||||
return enabled;
|
||||
}
|
||||
|
||||
public void setEnabled(boolean enabled) {
|
||||
this.enabled = enabled;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -82,7 +82,7 @@ public interface ProjectService {
|
|||
|
||||
Project updateProject(long id, String name, String displayText, String newOwnerName, Long userId, Role newRole) throws ResourceAllocationException;
|
||||
|
||||
boolean addAccountToProject(long projectId, String accountName, String email, Long projectRoleId, Role projectRoleType);
|
||||
boolean addAccountToProject(long projectId, String accountName, String email, Long projectRoleId, Role projectRoleType) throws ResourceAllocationException;
|
||||
|
||||
boolean deleteAccountFromProject(long projectId, String accountName);
|
||||
|
||||
|
|
@ -100,6 +100,6 @@ public interface ProjectService {
|
|||
|
||||
Project findByProjectAccountIdIncludingRemoved(long projectAccountId);
|
||||
|
||||
boolean addUserToProject(Long projectId, String username, String email, Long projectRoleId, Role projectRole);
|
||||
boolean addUserToProject(Long projectId, String username, String email, Long projectRoleId, Role projectRole) throws ResourceAllocationException;
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -71,7 +71,6 @@ import org.apache.cloudstack.api.command.user.vm.GetVMPasswordCmd;
|
|||
import org.apache.cloudstack.api.command.user.vmgroup.UpdateVMGroupCmd;
|
||||
import org.apache.cloudstack.config.Configuration;
|
||||
import org.apache.cloudstack.config.ConfigurationGroup;
|
||||
import org.apache.cloudstack.framework.config.ConfigKey;
|
||||
|
||||
import com.cloud.alert.Alert;
|
||||
import com.cloud.capacity.Capacity;
|
||||
|
|
@ -108,14 +107,6 @@ import com.cloud.vm.VirtualMachineProfile;
|
|||
public interface ManagementService {
|
||||
static final String Name = "management-server";
|
||||
|
||||
ConfigKey<Boolean> JsInterpretationEnabled = new ConfigKey<>("Hidden"
|
||||
, Boolean.class
|
||||
, "js.interpretation.enabled"
|
||||
, "false"
|
||||
, "Enable/Disable all JavaScript interpretation related functionalities to create or update Javascript rules."
|
||||
, false
|
||||
, ConfigKey.Scope.Global);
|
||||
|
||||
/**
|
||||
* returns the a map of the names/values in the configuration table
|
||||
*
|
||||
|
|
@ -534,6 +525,4 @@ public interface ManagementService {
|
|||
|
||||
boolean removeManagementServer(RemoveManagementServerCmd cmd);
|
||||
|
||||
void checkJsInterpretationAllowedIfNeededForParameterValue(String paramName, boolean paramValue);
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -23,9 +23,10 @@ import org.apache.cloudstack.api.InternalIdentity;
|
|||
|
||||
public interface VMTemplateStorageResourceAssoc extends InternalIdentity {
|
||||
public static enum Status {
|
||||
UNKNOWN, DOWNLOAD_ERROR, NOT_DOWNLOADED, DOWNLOAD_IN_PROGRESS, DOWNLOADED, ABANDONED, UPLOADED, NOT_UPLOADED, UPLOAD_ERROR, UPLOAD_IN_PROGRESS, CREATING, CREATED, BYPASSED
|
||||
UNKNOWN, DOWNLOAD_ERROR, NOT_DOWNLOADED, DOWNLOAD_IN_PROGRESS, DOWNLOADED, ABANDONED, LIMIT_REACHED, UPLOADED, NOT_UPLOADED, UPLOAD_ERROR, UPLOAD_IN_PROGRESS, CREATING, CREATED, BYPASSED
|
||||
}
|
||||
|
||||
List<Status> ERROR_DOWNLOAD_STATES = List.of(Status.DOWNLOAD_ERROR, Status.ABANDONED, Status.LIMIT_REACHED, Status.UNKNOWN);
|
||||
List<Status> PENDING_DOWNLOAD_STATES = List.of(Status.NOT_DOWNLOADED, Status.DOWNLOAD_IN_PROGRESS);
|
||||
|
||||
String getInstallPath();
|
||||
|
|
|
|||
|
|
@ -138,6 +138,8 @@ public interface AccountService {
|
|||
|
||||
Long finalizeAccountId(String accountName, Long domainId, Long projectId, boolean enabledOnly);
|
||||
|
||||
Long finalizeAccountId(Long accountId, String accountName, Long domainId, Long projectId);
|
||||
|
||||
/**
|
||||
* returns the user account object for a given user id
|
||||
* @param userId user id
|
||||
|
|
|
|||
|
|
@ -30,6 +30,7 @@ import com.cloud.exception.ResourceAllocationException;
|
|||
import com.cloud.offering.DiskOffering;
|
||||
import com.cloud.offering.ServiceOffering;
|
||||
import com.cloud.template.VirtualMachineTemplate;
|
||||
import org.apache.cloudstack.resourcelimit.Reserver;
|
||||
|
||||
public interface ResourceLimitService {
|
||||
|
||||
|
|
@ -191,6 +192,7 @@ public interface ResourceLimitService {
|
|||
*/
|
||||
public void checkResourceLimit(Account account, ResourceCount.ResourceType type, long... count) throws ResourceAllocationException;
|
||||
public void checkResourceLimitWithTag(Account account, ResourceCount.ResourceType type, String tag, long... count) throws ResourceAllocationException;
|
||||
public void checkResourceLimitWithTag(Account account, Long domainId, boolean considerSystemAccount, ResourceCount.ResourceType type, String tag, long... count) throws ResourceAllocationException;
|
||||
|
||||
/**
|
||||
* Gets the count of resources for a resource type and account
|
||||
|
|
@ -251,12 +253,12 @@ public interface ResourceLimitService {
|
|||
List<String> getResourceLimitStorageTags(DiskOffering diskOffering);
|
||||
void updateTaggedResourceLimitsAndCountsForAccounts(List<AccountResponse> responses, String tag);
|
||||
void updateTaggedResourceLimitsAndCountsForDomains(List<DomainResponse> responses, String tag);
|
||||
void checkVolumeResourceLimit(Account owner, Boolean display, Long size, DiskOffering diskOffering) throws ResourceAllocationException;
|
||||
|
||||
void checkVolumeResourceLimit(Account owner, Boolean display, Long size, DiskOffering diskOffering, List<Reserver> reservations) throws ResourceAllocationException;
|
||||
List<String> getResourceLimitStorageTagsForResourceCountOperation(Boolean display, DiskOffering diskOffering);
|
||||
void checkVolumeResourceLimitForDiskOfferingChange(Account owner, Boolean display, Long currentSize, Long newSize,
|
||||
DiskOffering currentOffering, DiskOffering newOffering) throws ResourceAllocationException;
|
||||
DiskOffering currentOffering, DiskOffering newOffering, List<Reserver> reservations) throws ResourceAllocationException;
|
||||
|
||||
void checkPrimaryStorageResourceLimit(Account owner, Boolean display, Long size, DiskOffering diskOffering) throws ResourceAllocationException;
|
||||
void checkPrimaryStorageResourceLimit(Account owner, Boolean display, Long size, DiskOffering diskOffering, List<Reserver> reservations) throws ResourceAllocationException;
|
||||
|
||||
void incrementVolumeResourceCount(long accountId, Boolean display, Long size, DiskOffering diskOffering);
|
||||
void decrementVolumeResourceCount(long accountId, Boolean display, Long size, DiskOffering diskOffering);
|
||||
|
|
@ -273,25 +275,23 @@ public interface ResourceLimitService {
|
|||
|
||||
void incrementVolumePrimaryStorageResourceCount(long accountId, Boolean display, Long size, DiskOffering diskOffering);
|
||||
void decrementVolumePrimaryStorageResourceCount(long accountId, Boolean display, Long size, DiskOffering diskOffering);
|
||||
void checkVmResourceLimit(Account owner, Boolean display, ServiceOffering serviceOffering, VirtualMachineTemplate template) throws ResourceAllocationException;
|
||||
void checkVmResourceLimit(Account owner, Boolean display, ServiceOffering serviceOffering, VirtualMachineTemplate template, List<Reserver> reservations) throws ResourceAllocationException;
|
||||
void incrementVmResourceCount(long accountId, Boolean display, ServiceOffering serviceOffering, VirtualMachineTemplate template);
|
||||
void decrementVmResourceCount(long accountId, Boolean display, ServiceOffering serviceOffering, VirtualMachineTemplate template);
|
||||
|
||||
void checkVmResourceLimitsForServiceOfferingChange(Account owner, Boolean display, Long currentCpu, Long newCpu,
|
||||
Long currentMemory, Long newMemory, ServiceOffering currentOffering, ServiceOffering newOffering, VirtualMachineTemplate template) throws ResourceAllocationException;
|
||||
Long currentMemory, Long newMemory, ServiceOffering currentOffering, ServiceOffering newOffering, VirtualMachineTemplate template, List<Reserver> reservations) throws ResourceAllocationException;
|
||||
|
||||
void checkVmResourceLimitsForTemplateChange(Account owner, Boolean display, ServiceOffering offering,
|
||||
VirtualMachineTemplate currentTemplate, VirtualMachineTemplate newTemplate) throws ResourceAllocationException;
|
||||
VirtualMachineTemplate currentTemplate, VirtualMachineTemplate newTemplate, List<Reserver> reservations) throws ResourceAllocationException;
|
||||
|
||||
void checkVmCpuResourceLimit(Account owner, Boolean display, ServiceOffering serviceOffering, VirtualMachineTemplate template, Long cpu) throws ResourceAllocationException;
|
||||
void incrementVmCpuResourceCount(long accountId, Boolean display, ServiceOffering serviceOffering, VirtualMachineTemplate template, Long cpu);
|
||||
void decrementVmCpuResourceCount(long accountId, Boolean display, ServiceOffering serviceOffering, VirtualMachineTemplate template, Long cpu);
|
||||
void checkVmMemoryResourceLimit(Account owner, Boolean display, ServiceOffering serviceOffering, VirtualMachineTemplate template, Long memory) throws ResourceAllocationException;
|
||||
void incrementVmMemoryResourceCount(long accountId, Boolean display, ServiceOffering serviceOffering, VirtualMachineTemplate template, Long memory);
|
||||
void decrementVmMemoryResourceCount(long accountId, Boolean display, ServiceOffering serviceOffering, VirtualMachineTemplate template, Long memory);
|
||||
|
||||
void checkVmGpuResourceLimit(Account owner, Boolean display, ServiceOffering serviceOffering, VirtualMachineTemplate template, Long gpu) throws ResourceAllocationException;
|
||||
void incrementVmGpuResourceCount(long accountId, Boolean display, ServiceOffering serviceOffering, VirtualMachineTemplate template, Long gpu);
|
||||
void decrementVmGpuResourceCount(long accountId, Boolean display, ServiceOffering serviceOffering, VirtualMachineTemplate template, Long gpu);
|
||||
|
||||
long recalculateDomainResourceCount(final long domainId, final ResourceType type, String tag);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -162,4 +162,6 @@ public interface Nic extends Identity, InternalIdentity {
|
|||
String getIPv6Address();
|
||||
|
||||
Integer getMtu();
|
||||
|
||||
boolean isEnabled();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -52,6 +52,7 @@ public class NicProfile implements InternalIdentity, Serializable {
|
|||
boolean defaultNic;
|
||||
Integer networkRate;
|
||||
boolean isSecurityGroupEnabled;
|
||||
boolean enabled;
|
||||
|
||||
Integer orderIndex;
|
||||
|
||||
|
|
@ -87,6 +88,7 @@ public class NicProfile implements InternalIdentity, Serializable {
|
|||
broadcastType = network.getBroadcastDomainType();
|
||||
trafficType = network.getTrafficType();
|
||||
format = nic.getAddressFormat();
|
||||
enabled = nic.isEnabled();
|
||||
|
||||
iPv4Address = nic.getIPv4Address();
|
||||
iPv4Netmask = nic.getIPv4Netmask();
|
||||
|
|
@ -414,6 +416,14 @@ public class NicProfile implements InternalIdentity, Serializable {
|
|||
this.ipv4AllocationRaceCheck = ipv4AllocationRaceCheck;
|
||||
}
|
||||
|
||||
public boolean isEnabled() {
|
||||
return enabled;
|
||||
}
|
||||
|
||||
public void setEnabled(boolean enabled) {
|
||||
this.enabled = enabled;
|
||||
}
|
||||
|
||||
//
|
||||
// OTHER METHODS
|
||||
//
|
||||
|
|
|
|||
|
|
@ -40,6 +40,7 @@ import org.apache.cloudstack.api.command.user.vm.ScaleVMCmd;
|
|||
import org.apache.cloudstack.api.command.user.vm.StartVMCmd;
|
||||
import org.apache.cloudstack.api.command.user.vm.UpdateDefaultNicForVMCmd;
|
||||
import org.apache.cloudstack.api.command.user.vm.UpdateVMCmd;
|
||||
import org.apache.cloudstack.api.command.user.vm.UpdateVmNicCmd;
|
||||
import org.apache.cloudstack.api.command.user.vm.UpdateVmNicIpCmd;
|
||||
import org.apache.cloudstack.api.command.user.vm.UpgradeVMCmd;
|
||||
import org.apache.cloudstack.api.command.user.vmgroup.CreateVMGroupCmd;
|
||||
|
|
@ -152,6 +153,8 @@ public interface UserVmService {
|
|||
*/
|
||||
UserVm updateNicIpForVirtualMachine(UpdateVmNicIpCmd cmd);
|
||||
|
||||
UserVm updateVirtualMachineNic(UpdateVmNicCmd cmd);
|
||||
|
||||
UserVm recoverVirtualMachine(RecoverVMCmd cmd) throws ResourceAllocationException;
|
||||
|
||||
/**
|
||||
|
|
@ -524,6 +527,7 @@ public interface UserVmService {
|
|||
* @param userId user ID
|
||||
* @param serviceOffering service offering for the imported VM
|
||||
* @param sshPublicKey ssh key for the imported VM
|
||||
* @param guestOsId guest OS ID for the imported VM (if not passed, then the guest OS of the template will be used)
|
||||
* @param hostName the name for the imported VM
|
||||
* @param hypervisorType hypervisor type for the imported VM
|
||||
* @param customParameters details for the imported VM
|
||||
|
|
@ -533,7 +537,7 @@ public interface UserVmService {
|
|||
* @throws InsufficientCapacityException in case of errors
|
||||
*/
|
||||
UserVm importVM(final DataCenter zone, final Host host, final VirtualMachineTemplate template, final String instanceNameInternal, final String displayName, final Account owner, final String userData, final Account caller, final Boolean isDisplayVm, final String keyboard,
|
||||
final long accountId, final long userId, final ServiceOffering serviceOffering, final String sshPublicKey,
|
||||
final long accountId, final long userId, final ServiceOffering serviceOffering, final String sshPublicKey, final Long guestOsId,
|
||||
final String hostName, final HypervisorType hypervisorType, final Map<String, String> customParameters,
|
||||
final VirtualMachine.PowerState powerState, final LinkedHashMap<String, List<NicProfile>> networkNicMap) throws InsufficientCapacityException;
|
||||
|
||||
|
|
|
|||
|
|
@ -124,6 +124,9 @@ public interface VirtualMachine extends RunningOn, ControlledEntity, Partition,
|
|||
s_fsm.addTransition(new Transition<State, Event>(State.Stopping, VirtualMachine.Event.StopRequested, State.Stopping, null));
|
||||
s_fsm.addTransition(new Transition<State, Event>(State.Stopping, VirtualMachine.Event.AgentReportShutdowned, State.Stopped, Arrays.asList(new Impact[]{Impact.USAGE})));
|
||||
s_fsm.addTransition(new Transition<State, Event>(State.Expunging, VirtualMachine.Event.OperationFailed, State.Expunging,null));
|
||||
// Note: In addition to the Stopped -> Error transition for failed VM creation,
|
||||
// a VM can also transition from Expunging to Error on OperationFailedToError.
|
||||
s_fsm.addTransition(new Transition<State, Event>(State.Expunging, VirtualMachine.Event.OperationFailedToError, State.Error, null));
|
||||
s_fsm.addTransition(new Transition<State, Event>(State.Expunging, VirtualMachine.Event.ExpungeOperation, State.Expunging,null));
|
||||
s_fsm.addTransition(new Transition<State, Event>(State.Error, VirtualMachine.Event.DestroyRequested, State.Expunging, null));
|
||||
s_fsm.addTransition(new Transition<State, Event>(State.Error, VirtualMachine.Event.ExpungeOperation, State.Expunging, null));
|
||||
|
|
|
|||
|
|
@ -127,8 +127,8 @@ public enum ApiCommandResourceType {
|
|||
}
|
||||
|
||||
public static ApiCommandResourceType fromString(String value) {
|
||||
if (StringUtils.isNotEmpty(value) && EnumUtils.isValidEnum(ApiCommandResourceType.class, value)) {
|
||||
return valueOf(value);
|
||||
if (StringUtils.isNotBlank(value) && EnumUtils.isValidEnumIgnoreCase(ApiCommandResourceType.class, value)) {
|
||||
return EnumUtils.getEnumIgnoreCase(ApiCommandResourceType.class, value);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -20,6 +20,7 @@ public class ApiConstants {
|
|||
public static final String ACCOUNT = "account";
|
||||
public static final String ACCOUNTS = "accounts";
|
||||
public static final String ACCOUNT_NAME = "accountname";
|
||||
public static final String ACCOUNT_STATE_TO_SHOW = "accountstatetoshow";
|
||||
public static final String ACCOUNT_TYPE = "accounttype";
|
||||
public static final String ACCOUNT_ID = "accountid";
|
||||
public static final String ACCOUNT_IDS = "accountids";
|
||||
|
|
@ -508,6 +509,7 @@ public class ApiConstants {
|
|||
public static final String REPAIR = "repair";
|
||||
public static final String REPETITION_ALLOWED = "repetitionallowed";
|
||||
public static final String REQUIRES_HVM = "requireshvm";
|
||||
public static final String RESERVED_RESOURCE_DETAILS = "reservedresourcedetails";
|
||||
public static final String RESOURCES = "resources";
|
||||
public static final String RESOURCE_COUNT = "resourcecount";
|
||||
public static final String RESOURCE_NAME = "resourcename";
|
||||
|
|
|
|||
|
|
@ -343,6 +343,8 @@ public interface ResponseGenerator {
|
|||
|
||||
UserVm findUserVmById(Long vmId);
|
||||
|
||||
UserVm findUserVmByNicId(Long nicId);
|
||||
|
||||
Volume findVolumeById(Long volumeId);
|
||||
|
||||
Account findAccountByNameDomain(String accountName, Long domainId);
|
||||
|
|
|
|||
|
|
@ -30,6 +30,7 @@ import org.apache.cloudstack.api.BaseCmd;
|
|||
import org.apache.cloudstack.api.Parameter;
|
||||
import org.apache.cloudstack.api.ResponseObject;
|
||||
import org.apache.cloudstack.api.ServerApiException;
|
||||
import org.apache.cloudstack.api.response.GuestOSResponse;
|
||||
import org.apache.cloudstack.api.response.HostResponse;
|
||||
import org.apache.cloudstack.api.response.NetworkResponse;
|
||||
import org.apache.cloudstack.api.response.StoragePoolResponse;
|
||||
|
|
@ -171,6 +172,13 @@ public class ImportVmCmd extends ImportUnmanagedInstanceCmd {
|
|||
description = "(only for importing VMs from VMware to KVM) optional - if true, forces virt-v2v conversions to write directly on the provided storage pool (avoid using temporary conversion pool).")
|
||||
private Boolean forceConvertToPool;
|
||||
|
||||
@Parameter(name = ApiConstants.OS_ID,
|
||||
type = CommandType.UUID,
|
||||
entityType = GuestOSResponse.class,
|
||||
since = "4.22.1",
|
||||
description = "(only for importing VMs from VMware to KVM) optional - the ID of the guest OS for the imported VM.")
|
||||
private Long guestOsId;
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
/////////////////// Accessors ///////////////////////
|
||||
/////////////////////////////////////////////////////
|
||||
|
|
@ -268,6 +276,10 @@ public class ImportVmCmd extends ImportUnmanagedInstanceCmd {
|
|||
return BooleanUtils.toBooleanDefaultIfNull(forceConvertToPool, false);
|
||||
}
|
||||
|
||||
public Long getGuestOsId() {
|
||||
return guestOsId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getEventDescription() {
|
||||
String vmName = getName();
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@ package org.apache.cloudstack.api.command.user.account;
|
|||
|
||||
import java.util.List;
|
||||
|
||||
import com.cloud.exception.ResourceAllocationException;
|
||||
import org.apache.cloudstack.api.ApiArgValidator;
|
||||
import org.apache.cloudstack.api.ApiCommandResourceType;
|
||||
import org.apache.cloudstack.api.BaseCmd;
|
||||
|
|
@ -106,7 +107,7 @@ public class AddAccountToProjectCmd extends BaseAsyncCmd {
|
|||
/////////////////////////////////////////////////////
|
||||
|
||||
@Override
|
||||
public void execute() {
|
||||
public void execute() throws ResourceAllocationException {
|
||||
if (accountName == null && email == null) {
|
||||
throw new InvalidParameterValueException("Either accountName or email is required");
|
||||
}
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@
|
|||
|
||||
package org.apache.cloudstack.api.command.user.account;
|
||||
|
||||
import com.cloud.exception.ResourceAllocationException;
|
||||
import org.apache.cloudstack.acl.RoleType;
|
||||
import org.apache.cloudstack.api.APICommand;
|
||||
import org.apache.cloudstack.api.ApiArgValidator;
|
||||
|
|
@ -111,7 +112,7 @@ public class AddUserToProjectCmd extends BaseAsyncCmd {
|
|||
/////////////////////////////////////////////////////
|
||||
|
||||
@Override
|
||||
public void execute() {
|
||||
public void execute() throws ResourceAllocationException {
|
||||
validateInput();
|
||||
boolean result = _projectService.addUserToProject(getProjectId(), getUsername(), getEmail(), getProjectRoleId(), getRoleType());
|
||||
if (result) {
|
||||
|
|
|
|||
|
|
@ -20,6 +20,7 @@ package org.apache.cloudstack.api.command.user.backup;
|
|||
import javax.inject.Inject;
|
||||
|
||||
import org.apache.cloudstack.acl.RoleType;
|
||||
import org.apache.cloudstack.api.ACL;
|
||||
import org.apache.cloudstack.api.APICommand;
|
||||
import org.apache.cloudstack.api.ApiConstants;
|
||||
import org.apache.cloudstack.api.ApiErrorCode;
|
||||
|
|
@ -53,6 +54,7 @@ public class RestoreVolumeFromBackupAndAttachToVMCmd extends BaseAsyncCmd {
|
|||
//////////////// API parameters /////////////////////
|
||||
/////////////////////////////////////////////////////
|
||||
|
||||
@ACL
|
||||
@Parameter(name = ApiConstants.BACKUP_ID,
|
||||
type = CommandType.UUID,
|
||||
entityType = BackupResponse.class,
|
||||
|
|
@ -60,12 +62,14 @@ public class RestoreVolumeFromBackupAndAttachToVMCmd extends BaseAsyncCmd {
|
|||
description = "ID of the Instance backup")
|
||||
private Long backupId;
|
||||
|
||||
@ACL
|
||||
@Parameter(name = ApiConstants.VOLUME_ID,
|
||||
type = CommandType.STRING,
|
||||
required = true,
|
||||
description = "ID of the volume backed up")
|
||||
private String volumeUuid;
|
||||
|
||||
@ACL
|
||||
@Parameter(name = ApiConstants.VIRTUAL_MACHINE_ID,
|
||||
type = CommandType.UUID,
|
||||
entityType = UserVmResponse.class,
|
||||
|
|
|
|||
|
|
@ -45,6 +45,11 @@ public class ListGuestOsCmd extends BaseListCmd {
|
|||
@Parameter(name = ApiConstants.ID, type = CommandType.UUID, entityType = GuestOSResponse.class, description = "List by OS type ID")
|
||||
private Long id;
|
||||
|
||||
@Parameter(name = ApiConstants.IDS, type = CommandType.LIST, collectionType = CommandType.UUID,
|
||||
entityType = GuestOSResponse.class, since = "4.22.1",
|
||||
description = "Comma separated list of OS types")
|
||||
private List<Long> ids;
|
||||
|
||||
@Parameter(name = ApiConstants.OS_CATEGORY_ID, type = CommandType.UUID, entityType = GuestOSCategoryResponse.class, description = "List by OS Category ID")
|
||||
private Long osCategoryId;
|
||||
|
||||
|
|
@ -63,6 +68,10 @@ public class ListGuestOsCmd extends BaseListCmd {
|
|||
return id;
|
||||
}
|
||||
|
||||
public List<Long> getIds() {
|
||||
return ids;
|
||||
}
|
||||
|
||||
public Long getOsCategoryId() {
|
||||
return osCategoryId;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -19,6 +19,7 @@ package org.apache.cloudstack.api.command.user.job;
|
|||
import java.util.Date;
|
||||
|
||||
import org.apache.cloudstack.api.APICommand;
|
||||
import org.apache.cloudstack.api.ApiArgValidator;
|
||||
import org.apache.cloudstack.api.ApiConstants;
|
||||
import org.apache.cloudstack.api.BaseListAccountResourcesCmd;
|
||||
import org.apache.cloudstack.api.Parameter;
|
||||
|
|
@ -40,6 +41,12 @@ public class ListAsyncJobsCmd extends BaseListAccountResourcesCmd {
|
|||
@Parameter(name = ApiConstants.MANAGEMENT_SERVER_ID, type = CommandType.UUID, entityType = ManagementServerResponse.class, description = "The id of the management server", since="4.19")
|
||||
private Long managementServerId;
|
||||
|
||||
@Parameter(name = ApiConstants.RESOURCE_ID, validations = {ApiArgValidator.UuidString}, type = CommandType.STRING, description = "the ID of the resource associated with the job", since="4.22.1")
|
||||
private String resourceId;
|
||||
|
||||
@Parameter(name = ApiConstants.RESOURCE_TYPE, type = CommandType.STRING, description = "the type of the resource associated with the job", since="4.22.1")
|
||||
private String resourceType;
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
/////////////////// Accessors ///////////////////////
|
||||
/////////////////////////////////////////////////////
|
||||
|
|
@ -52,6 +59,14 @@ public class ListAsyncJobsCmd extends BaseListAccountResourcesCmd {
|
|||
return managementServerId;
|
||||
}
|
||||
|
||||
public String getResourceId() {
|
||||
return resourceId;
|
||||
}
|
||||
|
||||
public String getResourceType() {
|
||||
return resourceType;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
/////////////// API Implementation///////////////////
|
||||
/////////////////////////////////////////////////////
|
||||
|
|
|
|||
|
|
@ -16,8 +16,8 @@
|
|||
// under the License.
|
||||
package org.apache.cloudstack.api.command.user.job;
|
||||
|
||||
|
||||
import org.apache.cloudstack.api.APICommand;
|
||||
import org.apache.cloudstack.api.ApiArgValidator;
|
||||
import org.apache.cloudstack.api.ApiConstants;
|
||||
import org.apache.cloudstack.api.BaseCmd;
|
||||
import org.apache.cloudstack.api.Parameter;
|
||||
|
|
@ -34,9 +34,15 @@ public class QueryAsyncJobResultCmd extends BaseCmd {
|
|||
//////////////// API parameters /////////////////////
|
||||
/////////////////////////////////////////////////////
|
||||
|
||||
@Parameter(name = ApiConstants.JOB_ID, type = CommandType.UUID, entityType = AsyncJobResponse.class, required = true, description = "The ID of the asynchronous job")
|
||||
@Parameter(name = ApiConstants.JOB_ID, type = CommandType.UUID, entityType = AsyncJobResponse.class, description = "The ID of the asynchronous job")
|
||||
private Long id;
|
||||
|
||||
@Parameter(name = ApiConstants.RESOURCE_ID, validations = {ApiArgValidator.UuidString}, type = CommandType.STRING, description = "the ID of the resource associated with the job", since="4.22.1")
|
||||
private String resourceId;
|
||||
|
||||
@Parameter(name = ApiConstants.RESOURCE_TYPE, type = CommandType.STRING, description = "the type of the resource associated with the job", since="4.22.1")
|
||||
private String resourceType;
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
/////////////////// Accessors ///////////////////////
|
||||
/////////////////////////////////////////////////////
|
||||
|
|
@ -45,6 +51,14 @@ public class QueryAsyncJobResultCmd extends BaseCmd {
|
|||
return id;
|
||||
}
|
||||
|
||||
public String getResourceId() {
|
||||
return resourceId;
|
||||
}
|
||||
|
||||
public String getResourceType() {
|
||||
return resourceType;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
/////////////// API Implementation///////////////////
|
||||
/////////////////////////////////////////////////////
|
||||
|
|
|
|||
|
|
@ -51,6 +51,7 @@ public class CreateVMFromBackupCmd extends BaseDeployVMCmd {
|
|||
//////////////// API parameters /////////////////////
|
||||
/////////////////////////////////////////////////////
|
||||
|
||||
@ACL
|
||||
@Parameter(name = ApiConstants.BACKUP_ID,
|
||||
type = CommandType.UUID,
|
||||
entityType = BackupResponse.class,
|
||||
|
|
|
|||
|
|
@ -0,0 +1,95 @@
|
|||
// 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.user.vm;
|
||||
|
||||
import org.apache.cloudstack.acl.RoleType;
|
||||
import org.apache.cloudstack.api.ACL;
|
||||
import org.apache.cloudstack.api.APICommand;
|
||||
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.ResponseObject;
|
||||
import org.apache.cloudstack.api.ServerApiException;
|
||||
import org.apache.cloudstack.api.response.NicResponse;
|
||||
import org.apache.cloudstack.api.response.UserVmResponse;
|
||||
import org.apache.cloudstack.context.CallContext;
|
||||
|
||||
import com.cloud.event.EventTypes;
|
||||
import com.cloud.user.Account;
|
||||
import com.cloud.uservm.UserVm;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.EnumSet;
|
||||
|
||||
@APICommand(name = "updateVmNic", description = "Updates the specified VM NIC", responseObject = NicResponse.class, requestHasSensitiveInfo = false, responseHasSensitiveInfo = false,
|
||||
authorized = { RoleType.Admin, RoleType.ResourceAdmin, RoleType.DomainAdmin, RoleType.User })
|
||||
public class UpdateVmNicCmd extends BaseAsyncCmd {
|
||||
|
||||
@ACL
|
||||
@Parameter(name = ApiConstants.NIC_ID, type = CommandType.UUID, entityType = NicResponse.class, required = true, description = "NIC ID")
|
||||
private Long nicId;
|
||||
|
||||
@Parameter(name = ApiConstants.ENABLED, type = CommandType.BOOLEAN, description = "If true, sets the NIC state to UP; otherwise, sets the NIC state to DOWN")
|
||||
private Boolean enabled;
|
||||
|
||||
public Long getNicId() {
|
||||
return nicId;
|
||||
}
|
||||
|
||||
public Boolean isEnabled() {
|
||||
return enabled;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getEventType() {
|
||||
return EventTypes.EVENT_NIC_UPDATE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getEventDescription() {
|
||||
return String.format("Updating NIC %s.", getResourceUuid(ApiConstants.NIC_ID));
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getEntityOwnerId() {
|
||||
UserVm vm = _responseGenerator.findUserVmByNicId(nicId);
|
||||
if (vm == null) {
|
||||
return Account.ACCOUNT_ID_SYSTEM;
|
||||
}
|
||||
return vm.getAccountId();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute() {
|
||||
CallContext.current().setEventDetails(String.format("NIC ID: %s", getResourceUuid(ApiConstants.NIC_ID)));
|
||||
|
||||
UserVm result = _userVmService.updateVirtualMachineNic(this);
|
||||
|
||||
ArrayList<ApiConstants.VMDetails> dc = new ArrayList<>();
|
||||
dc.add(ApiConstants.VMDetails.valueOf("nics"));
|
||||
EnumSet<ApiConstants.VMDetails> details = EnumSet.copyOf(dc);
|
||||
|
||||
if (result != null){
|
||||
UserVmResponse response = _responseGenerator.createUserVmResponse(ResponseObject.ResponseView.Restricted, "virtualmachine", details, result).get(0);
|
||||
response.setResponseName(getCommandName());
|
||||
this.setResponseObject(response);
|
||||
} else {
|
||||
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to update NIC from VM.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -32,6 +32,7 @@ import org.apache.cloudstack.api.response.DiskOfferingResponse;
|
|||
import org.apache.cloudstack.api.response.DomainResponse;
|
||||
import org.apache.cloudstack.api.response.ProjectResponse;
|
||||
import org.apache.cloudstack.api.response.SnapshotResponse;
|
||||
import org.apache.cloudstack.api.response.StoragePoolResponse;
|
||||
import org.apache.cloudstack.api.response.UserVmResponse;
|
||||
import org.apache.cloudstack.api.response.VolumeResponse;
|
||||
import org.apache.cloudstack.api.response.ZoneResponse;
|
||||
|
|
@ -109,6 +110,13 @@ public class CreateVolumeCmd extends BaseAsyncCreateCustomIdCmd implements UserC
|
|||
description = "The ID of the Instance; to be used with snapshot Id, Instance to which the volume gets attached after creation")
|
||||
private Long virtualMachineId;
|
||||
|
||||
@Parameter(name = ApiConstants.STORAGE_ID,
|
||||
type = CommandType.UUID,
|
||||
entityType = StoragePoolResponse.class,
|
||||
description = "Storage pool ID to create the volume in. Cannot be used with the snapshotid parameter.",
|
||||
authorized = {RoleType.Admin})
|
||||
private Long storageId;
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
/////////////////// Accessors ///////////////////////
|
||||
/////////////////////////////////////////////////////
|
||||
|
|
@ -153,6 +161,13 @@ public class CreateVolumeCmd extends BaseAsyncCreateCustomIdCmd implements UserC
|
|||
return projectId;
|
||||
}
|
||||
|
||||
public Long getStorageId() {
|
||||
if (snapshotId != null && storageId != null) {
|
||||
throw new IllegalArgumentException("StorageId parameter cannot be specified with the SnapshotId parameter.");
|
||||
}
|
||||
return storageId;
|
||||
}
|
||||
|
||||
public Boolean getDisplayVolume() {
|
||||
return displayVolume;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -46,7 +46,6 @@ public class CreateStaticRouteCmd extends BaseAsyncCreateCmd {
|
|||
@Parameter(name = ApiConstants.GATEWAY_ID,
|
||||
type = CommandType.UUID,
|
||||
entityType = PrivateGatewayResponse.class,
|
||||
required = true,
|
||||
description = "The gateway ID we are creating static route for. Mutually exclusive with the nexthop parameter")
|
||||
private Long gatewayId;
|
||||
|
||||
|
|
|
|||
|
|
@ -85,6 +85,12 @@ public class ExtensionResponse extends BaseResponse {
|
|||
@Param(description = "Removal timestamp of the extension, if applicable")
|
||||
private Date removed;
|
||||
|
||||
@SerializedName(ApiConstants.RESERVED_RESOURCE_DETAILS)
|
||||
@Param(description = "Resource detail names as comma separated string that should be reserved and not visible " +
|
||||
"to end users",
|
||||
since = "4.22.1")
|
||||
protected String reservedResourceDetails;
|
||||
|
||||
public ExtensionResponse(String id, String name, String description, String type) {
|
||||
this.id = id;
|
||||
this.name = name;
|
||||
|
|
@ -179,4 +185,8 @@ public class ExtensionResponse extends BaseResponse {
|
|||
public void setRemoved(Date removed) {
|
||||
this.removed = removed;
|
||||
}
|
||||
|
||||
public void setReservedResourceDetails(String reservedResourceDetails) {
|
||||
this.reservedResourceDetails = reservedResourceDetails;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -146,6 +146,10 @@ public class NicResponse extends BaseResponse {
|
|||
@Param(description = "Public IP address associated with this NIC via Static NAT rule")
|
||||
private String publicIp;
|
||||
|
||||
@SerializedName(ApiConstants.ENABLED)
|
||||
@Param(description = "whether the NIC is enabled or not")
|
||||
private Boolean isEnabled;
|
||||
|
||||
public void setVmId(String vmId) {
|
||||
this.vmId = vmId;
|
||||
}
|
||||
|
|
@ -416,4 +420,12 @@ public class NicResponse extends BaseResponse {
|
|||
public void setPublicIp(String publicIp) {
|
||||
this.publicIp = publicIp;
|
||||
}
|
||||
|
||||
public Boolean getEnabled() {
|
||||
return isEnabled;
|
||||
}
|
||||
|
||||
public void setEnabled(Boolean enabled) {
|
||||
isEnabled = enabled;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -51,6 +51,14 @@ public class UnmanagedInstanceResponse extends BaseResponse {
|
|||
@Param(description = "The name of the host to which Instance belongs")
|
||||
private String hostName;
|
||||
|
||||
@SerializedName(ApiConstants.HYPERVISOR)
|
||||
@Param(description = "The hypervisor to which Instance belongs")
|
||||
private String hypervisor;
|
||||
|
||||
@SerializedName(ApiConstants.HYPERVISOR_VERSION)
|
||||
@Param(description = "The hypervisor version of the host to which Instance belongs")
|
||||
private String hypervisorVersion;
|
||||
|
||||
@SerializedName(ApiConstants.POWER_STATE)
|
||||
@Param(description = "The power state of the Instance")
|
||||
private String powerState;
|
||||
|
|
@ -140,6 +148,22 @@ public class UnmanagedInstanceResponse extends BaseResponse {
|
|||
this.hostName = hostName;
|
||||
}
|
||||
|
||||
public String getHypervisor() {
|
||||
return hypervisor;
|
||||
}
|
||||
|
||||
public void setHypervisor(String hypervisor) {
|
||||
this.hypervisor = hypervisor;
|
||||
}
|
||||
|
||||
public String getHypervisorVersion() {
|
||||
return hypervisorVersion;
|
||||
}
|
||||
|
||||
public void setHypervisorVersion(String hypervisorVersion) {
|
||||
this.hypervisorVersion = hypervisorVersion;
|
||||
}
|
||||
|
||||
public String getPowerState() {
|
||||
return powerState;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -17,8 +17,11 @@
|
|||
|
||||
package org.apache.cloudstack.extension;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public interface ExtensionHelper {
|
||||
Long getExtensionIdForCluster(long clusterId);
|
||||
Extension getExtension(long id);
|
||||
Extension getExtensionForCluster(long clusterId);
|
||||
List<String> getExtensionReservedResourceDetails(long extensionId);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,30 @@
|
|||
// 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.resourcelimit;
|
||||
|
||||
/**
|
||||
* Interface implemented by <code>CheckedReservation</code>.
|
||||
* </br></br>
|
||||
* This is defined in <code>cloud-api</code> to allow methods declared in modules that do not depend on <code>cloud-server</code>
|
||||
* to receive <code>CheckedReservations</code> as parameters.
|
||||
*/
|
||||
public interface Reserver extends AutoCloseable {
|
||||
|
||||
void close();
|
||||
|
||||
}
|
||||
|
|
@ -25,17 +25,28 @@ import org.apache.cloudstack.api.command.admin.volume.ImportVolumeCmd;
|
|||
import org.apache.cloudstack.api.response.ListResponse;
|
||||
import org.apache.cloudstack.api.response.VolumeForImportResponse;
|
||||
import org.apache.cloudstack.api.response.VolumeResponse;
|
||||
import org.apache.cloudstack.framework.config.ConfigKey;
|
||||
import org.apache.cloudstack.framework.config.Configurable;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
public interface VolumeImportUnmanageService extends PluggableService {
|
||||
public interface VolumeImportUnmanageService extends PluggableService, Configurable {
|
||||
|
||||
List<Hypervisor.HypervisorType> SUPPORTED_HYPERVISORS =
|
||||
Arrays.asList(Hypervisor.HypervisorType.KVM, Hypervisor.HypervisorType.VMware);
|
||||
|
||||
List<Storage.StoragePoolType> SUPPORTED_STORAGE_POOL_TYPES_FOR_KVM = Arrays.asList(Storage.StoragePoolType.NetworkFilesystem,
|
||||
Storage.StoragePoolType.Filesystem, Storage.StoragePoolType.RBD);
|
||||
Storage.StoragePoolType.Filesystem, Storage.StoragePoolType.RBD, Storage.StoragePoolType.SharedMountPoint);
|
||||
|
||||
ConfigKey<Boolean> AllowImportVolumeWithBackingFile = new ConfigKey<>(Boolean.class,
|
||||
"allow.import.volume.with.backing.file",
|
||||
"Advanced",
|
||||
"false",
|
||||
"If enabled, allows QCOW2 volumes with backing files to be imported or unmanaged",
|
||||
true,
|
||||
ConfigKey.Scope.Global,
|
||||
null);
|
||||
|
||||
ListResponse<VolumeForImportResponse> listVolumesForImport(ListVolumesForImportCmd cmd);
|
||||
|
||||
|
|
|
|||
|
|
@ -55,6 +55,9 @@ public class UnmanagedInstanceTO {
|
|||
|
||||
private String hostName;
|
||||
|
||||
private String hypervisorType;
|
||||
private String hostHypervisorVersion;
|
||||
|
||||
private List<Disk> disks;
|
||||
|
||||
private List<Nic> nics;
|
||||
|
|
@ -168,6 +171,22 @@ public class UnmanagedInstanceTO {
|
|||
this.hostName = hostName;
|
||||
}
|
||||
|
||||
public String getHypervisorType() {
|
||||
return hypervisorType;
|
||||
}
|
||||
|
||||
public void setHypervisorType(String hypervisorType) {
|
||||
this.hypervisorType = hypervisorType;
|
||||
}
|
||||
|
||||
public String getHostHypervisorVersion() {
|
||||
return hostHypervisorVersion;
|
||||
}
|
||||
|
||||
public void setHostHypervisorVersion(String hostHypervisorVersion) {
|
||||
this.hostHypervisorVersion = hostHypervisorVersion;
|
||||
}
|
||||
|
||||
public List<Disk> getDisks() {
|
||||
return disks;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -26,6 +26,8 @@ import static com.cloud.hypervisor.Hypervisor.HypervisorType.VMware;
|
|||
|
||||
public interface UnmanagedVMsManager extends VmImportService, UnmanageVMService, PluggableService, Configurable {
|
||||
|
||||
String VM_IMPORT_DEFAULT_TEMPLATE_NAME = "system-default-vm-import-dummy-template.iso";
|
||||
String KVM_VM_IMPORT_DEFAULT_TEMPLATE_NAME = "kvm-default-vm-import-dummy-template";
|
||||
ConfigKey<Boolean> UnmanageVMPreserveNic = new ConfigKey<>("Advanced", Boolean.class, "unmanage.vm.preserve.nics", "false",
|
||||
"If set to true, do not remove VM nics (and its MAC addresses) when unmanaging a VM, leaving them allocated but not reserved. " +
|
||||
"If set to false, nics are removed and MAC addresses can be reassigned", true, ConfigKey.Scope.Zone);
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@
|
|||
// under the License.
|
||||
package org.apache.cloudstack.api.command.test;
|
||||
|
||||
import com.cloud.exception.ResourceAllocationException;
|
||||
import junit.framework.Assert;
|
||||
import junit.framework.TestCase;
|
||||
|
||||
|
|
@ -149,6 +150,8 @@ public class AddAccountToProjectCmdTest extends TestCase {
|
|||
addAccountToProjectCmd.execute();
|
||||
} catch (InvalidParameterValueException exception) {
|
||||
Assert.assertEquals("Either accountName or email is required", exception.getLocalizedMessage());
|
||||
} catch (ResourceAllocationException exception) {
|
||||
Assert.fail();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -121,6 +121,11 @@
|
|||
<artifactId>cloud-plugin-storage-volume-adaptive</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.cloudstack</groupId>
|
||||
<artifactId>cloud-plugin-storage-volume-ontap</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.cloudstack</groupId>
|
||||
<artifactId>cloud-plugin-storage-volume-solidfire</artifactId>
|
||||
|
|
|
|||
|
|
@ -0,0 +1,27 @@
|
|||
// 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;
|
||||
|
||||
public class UpdateVmNicAnswer extends Answer {
|
||||
public UpdateVmNicAnswer() {
|
||||
}
|
||||
|
||||
public UpdateVmNicAnswer(UpdateVmNicCommand cmd, boolean success, String result) {
|
||||
super(cmd, success, result);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,51 @@
|
|||
// 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;
|
||||
|
||||
public class UpdateVmNicCommand extends Command {
|
||||
|
||||
String nicMacAddress;
|
||||
String instanceName;
|
||||
Boolean enabled;
|
||||
|
||||
@Override
|
||||
public boolean executeInSequence() {
|
||||
return true;
|
||||
}
|
||||
|
||||
protected UpdateVmNicCommand() {
|
||||
}
|
||||
|
||||
public UpdateVmNicCommand(String nicMacAdderss, String instanceName, Boolean enabled) {
|
||||
this.nicMacAddress = nicMacAdderss;
|
||||
this.instanceName = instanceName;
|
||||
this.enabled = enabled;
|
||||
}
|
||||
|
||||
public String getNicMacAddress() {
|
||||
return nicMacAddress;
|
||||
}
|
||||
|
||||
public String getVmName() {
|
||||
return instanceName;
|
||||
}
|
||||
|
||||
public Boolean isEnabled() {
|
||||
return enabled;
|
||||
}
|
||||
}
|
||||
|
|
@ -140,7 +140,7 @@ public class DownloadAnswer extends Answer {
|
|||
}
|
||||
|
||||
public Long getTemplateSize() {
|
||||
return templateSize;
|
||||
return templateSize == 0 ? templatePhySicalSize : templateSize;
|
||||
}
|
||||
|
||||
public void setTemplatePhySicalSize(long templatePhySicalSize) {
|
||||
|
|
|
|||
|
|
@ -52,6 +52,7 @@ import com.cloud.storage.StorageLayer;
|
|||
import com.cloud.utils.Pair;
|
||||
import com.cloud.utils.UriUtils;
|
||||
import com.cloud.utils.exception.CloudRuntimeException;
|
||||
import com.cloud.utils.net.HttpClientCloudStackUserAgent;
|
||||
import com.cloud.utils.net.Proxy;
|
||||
|
||||
/**
|
||||
|
|
@ -125,6 +126,7 @@ public class HttpTemplateDownloader extends ManagedContextRunnable implements Te
|
|||
GetMethod request = new GetMethod(downloadUrl);
|
||||
request.getParams().setParameter(HttpMethodParams.RETRY_HANDLER, myretryhandler);
|
||||
request.setFollowRedirects(followRedirects);
|
||||
request.getParams().setParameter(HttpMethodParams.USER_AGENT, HttpClientCloudStackUserAgent.CLOUDSTACK_USER_AGENT);
|
||||
return request;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -18,8 +18,11 @@
|
|||
//
|
||||
package com.cloud.storage.template;
|
||||
|
||||
|
||||
import com.cloud.storage.StorageLayer;
|
||||
import com.cloud.utils.UriUtils;
|
||||
import com.cloud.utils.net.HttpClientCloudStackUserAgent;
|
||||
|
||||
import org.apache.commons.httpclient.HttpClient;
|
||||
import org.apache.commons.httpclient.HttpMethod;
|
||||
import org.apache.commons.httpclient.HttpMethodRetryHandler;
|
||||
|
|
@ -59,6 +62,7 @@ public class MetalinkTemplateDownloader extends TemplateDownloaderBase implement
|
|||
GetMethod request = new GetMethod(downloadUrl);
|
||||
request.getParams().setParameter(HttpMethodParams.RETRY_HANDLER, myretryhandler);
|
||||
request.setFollowRedirects(followRedirects);
|
||||
request.getParams().setParameter(HttpMethodParams.USER_AGENT, HttpClientCloudStackUserAgent.CLOUDSTACK_USER_AGENT);
|
||||
if (!toFileSet) {
|
||||
String[] parts = downloadUrl.split("/");
|
||||
String filename = parts[parts.length - 1];
|
||||
|
|
|
|||
|
|
@ -44,6 +44,7 @@ import org.apache.commons.httpclient.params.HttpMethodParams;
|
|||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
import com.cloud.storage.StorageLayer;
|
||||
import com.cloud.utils.net.HttpClientCloudStackUserAgent;
|
||||
|
||||
public class SimpleHttpMultiFileDownloader extends ManagedContextRunnable implements TemplateDownloader {
|
||||
private static final MultiThreadedHttpConnectionManager s_httpClientManager = new MultiThreadedHttpConnectionManager();
|
||||
|
|
@ -95,6 +96,7 @@ public class SimpleHttpMultiFileDownloader extends ManagedContextRunnable implem
|
|||
GetMethod request = new GetMethod(downloadUrl);
|
||||
request.getParams().setParameter(HttpMethodParams.RETRY_HANDLER, retryHandler);
|
||||
request.setFollowRedirects(followRedirects);
|
||||
request.getParams().setParameter(HttpMethodParams.USER_AGENT, HttpClientCloudStackUserAgent.CLOUDSTACK_USER_AGENT);
|
||||
return request;
|
||||
}
|
||||
|
||||
|
|
@ -141,6 +143,7 @@ public class SimpleHttpMultiFileDownloader extends ManagedContextRunnable implem
|
|||
continue;
|
||||
}
|
||||
HeadMethod headMethod = new HeadMethod(downloadUrl);
|
||||
headMethod.getParams().setParameter(HttpMethodParams.USER_AGENT, HttpClientCloudStackUserAgent.CLOUDSTACK_USER_AGENT);
|
||||
try {
|
||||
if (client.executeMethod(headMethod) != HttpStatus.SC_OK) {
|
||||
continue;
|
||||
|
|
|
|||
|
|
@ -34,6 +34,7 @@ public class RestoreBackupCommand extends Command {
|
|||
private List<String> backupVolumesUUIDs;
|
||||
private List<PrimaryDataStoreTO> restoreVolumePools;
|
||||
private List<String> restoreVolumePaths;
|
||||
private List<Long> restoreVolumeSizes;
|
||||
private List<String> backupFiles;
|
||||
private String diskType;
|
||||
private Boolean vmExists;
|
||||
|
|
@ -92,6 +93,14 @@ public class RestoreBackupCommand extends Command {
|
|||
this.restoreVolumePaths = restoreVolumePaths;
|
||||
}
|
||||
|
||||
public List<Long> getRestoreVolumeSizes() {
|
||||
return restoreVolumeSizes;
|
||||
}
|
||||
|
||||
public void setRestoreVolumeSizes(List<Long> restoreVolumeSizes) {
|
||||
this.restoreVolumeSizes = restoreVolumeSizes;
|
||||
}
|
||||
|
||||
public List<String> getBackupFiles() {
|
||||
return backupFiles;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@ package org.apache.cloudstack.direct.download;
|
|||
import com.cloud.utils.UriUtils;
|
||||
import com.cloud.utils.exception.CloudRuntimeException;
|
||||
import org.apache.cloudstack.utils.security.DigestHelper;
|
||||
import org.apache.commons.io.FilenameUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
|
|
@ -33,6 +34,7 @@ import java.security.NoSuchAlgorithmException;
|
|||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
|
||||
public abstract class DirectTemplateDownloaderImpl implements DirectTemplateDownloader {
|
||||
|
||||
|
|
@ -128,15 +130,14 @@ public abstract class DirectTemplateDownloaderImpl implements DirectTemplateDown
|
|||
*/
|
||||
protected File createTemporaryDirectoryAndFile(String downloadDir) {
|
||||
createFolder(downloadDir);
|
||||
return new File(downloadDir + File.separator + getFileNameFromUrl());
|
||||
return new File(downloadDir + File.separator + getTemporaryFileName());
|
||||
}
|
||||
|
||||
/**
|
||||
* Return filename from url
|
||||
* Return filename from the temporary download file
|
||||
*/
|
||||
public String getFileNameFromUrl() {
|
||||
String[] urlParts = url.split("/");
|
||||
return urlParts[urlParts.length - 1];
|
||||
public String getTemporaryFileName() {
|
||||
return String.format("%s.%s", UUID.randomUUID(), FilenameUtils.getExtension(url));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
|||
|
|
@ -19,6 +19,7 @@
|
|||
|
||||
package org.apache.cloudstack.direct.download;
|
||||
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
|
|
@ -32,6 +33,7 @@ import java.util.Map;
|
|||
import com.cloud.utils.Pair;
|
||||
import com.cloud.utils.UriUtils;
|
||||
import com.cloud.utils.exception.CloudRuntimeException;
|
||||
import com.cloud.utils.net.HttpClientCloudStackUserAgent;
|
||||
import com.cloud.utils.storage.QCOW2Utils;
|
||||
import org.apache.commons.collections.MapUtils;
|
||||
import org.apache.commons.httpclient.HttpClient;
|
||||
|
|
@ -39,6 +41,7 @@ import org.apache.commons.httpclient.HttpStatus;
|
|||
import org.apache.commons.httpclient.MultiThreadedHttpConnectionManager;
|
||||
import org.apache.commons.httpclient.methods.GetMethod;
|
||||
import org.apache.commons.httpclient.methods.HeadMethod;
|
||||
import org.apache.commons.httpclient.params.HttpMethodParams;
|
||||
import org.apache.commons.io.IOUtils;
|
||||
|
||||
public class HttpDirectTemplateDownloader extends DirectTemplateDownloaderImpl {
|
||||
|
|
@ -68,6 +71,7 @@ public class HttpDirectTemplateDownloader extends DirectTemplateDownloaderImpl {
|
|||
protected GetMethod createRequest(String downloadUrl, Map<String, String> headers) {
|
||||
GetMethod request = new GetMethod(downloadUrl);
|
||||
request.setFollowRedirects(this.isFollowRedirects());
|
||||
request.getParams().setParameter(HttpMethodParams.USER_AGENT, HttpClientCloudStackUserAgent.CLOUDSTACK_USER_AGENT);
|
||||
if (MapUtils.isNotEmpty(headers)) {
|
||||
for (String key : headers.keySet()) {
|
||||
request.setRequestHeader(key, headers.get(key));
|
||||
|
|
@ -111,6 +115,7 @@ public class HttpDirectTemplateDownloader extends DirectTemplateDownloaderImpl {
|
|||
public boolean checkUrl(String url) {
|
||||
HeadMethod httpHead = new HeadMethod(url);
|
||||
httpHead.setFollowRedirects(this.isFollowRedirects());
|
||||
httpHead.getParams().setParameter(HttpMethodParams.USER_AGENT, HttpClientCloudStackUserAgent.CLOUDSTACK_USER_AGENT);
|
||||
try {
|
||||
int responseCode = client.executeMethod(httpHead);
|
||||
if (responseCode != HttpStatus.SC_OK) {
|
||||
|
|
|
|||
|
|
@ -97,7 +97,7 @@ public class MetalinkDirectTemplateDownloader extends DirectTemplateDownloaderIm
|
|||
DirectTemplateDownloader urlDownloader = createDownloaderForMetalinks(getUrl(), getTemplateId(), getDestPoolPath(),
|
||||
getChecksum(), headers, connectTimeout, soTimeout, null, temporaryDownloadPath);
|
||||
try {
|
||||
setDownloadedFilePath(downloadDir + File.separator + getFileNameFromUrl());
|
||||
setDownloadedFilePath(downloadDir + File.separator + getTemporaryFileName());
|
||||
File f = new File(getDownloadedFilePath());
|
||||
if (f.exists()) {
|
||||
f.delete();
|
||||
|
|
|
|||
|
|
@ -69,7 +69,7 @@ public class NfsDirectTemplateDownloader extends DirectTemplateDownloaderImpl {
|
|||
String mount = String.format(mountCommand, srcHost + ":" + srcPath, "/mnt/" + mountSrcUuid);
|
||||
Script.runSimpleBashScript(mount);
|
||||
String downloadDir = getDestPoolPath() + File.separator + getDirectDownloadTempPath(getTemplateId());
|
||||
setDownloadedFilePath(downloadDir + File.separator + getFileNameFromUrl());
|
||||
setDownloadedFilePath(downloadDir + File.separator + getTemporaryFileName());
|
||||
Script.runSimpleBashScript("cp /mnt/" + mountSrcUuid + srcPath + " " + getDownloadedFilePath());
|
||||
Script.runSimpleBashScript("umount /mnt/" + mountSrcUuid);
|
||||
return new Pair<>(true, getDownloadedFilePath());
|
||||
|
|
|
|||
|
|
@ -19,6 +19,9 @@
|
|||
|
||||
package org.apache.cloudstack.storage.command;
|
||||
|
||||
import com.cloud.configuration.Resource;
|
||||
import org.apache.cloudstack.utils.bytescale.ByteScaleUtils;
|
||||
|
||||
public class TemplateOrVolumePostUploadCommand {
|
||||
|
||||
long entityId;
|
||||
|
|
@ -185,6 +188,11 @@ public class TemplateOrVolumePostUploadCommand {
|
|||
this.description = description;
|
||||
}
|
||||
|
||||
public void setDefaultMaxSecondaryStorageInBytes(long defaultMaxSecondaryStorageInBytes) {
|
||||
this.defaultMaxSecondaryStorageInGB = defaultMaxSecondaryStorageInBytes != Resource.RESOURCE_UNLIMITED ?
|
||||
ByteScaleUtils.bytesToGibibytes(defaultMaxSecondaryStorageInBytes) : Resource.RESOURCE_UNLIMITED;
|
||||
}
|
||||
|
||||
public void setDefaultMaxSecondaryStorageInGB(long defaultMaxSecondaryStorageInGB) {
|
||||
this.defaultMaxSecondaryStorageInGB = defaultMaxSecondaryStorageInGB;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -28,6 +28,7 @@ public class UploadStatusCommand extends Command {
|
|||
}
|
||||
private String entityUuid;
|
||||
private EntityType entityType;
|
||||
private Boolean abort;
|
||||
|
||||
protected UploadStatusCommand() {
|
||||
}
|
||||
|
|
@ -37,6 +38,11 @@ public class UploadStatusCommand extends Command {
|
|||
this.entityType = entityType;
|
||||
}
|
||||
|
||||
public UploadStatusCommand(String entityUuid, EntityType entityType, Boolean abort) {
|
||||
this(entityUuid, entityType);
|
||||
this.abort = abort;
|
||||
}
|
||||
|
||||
public String getEntityUuid() {
|
||||
return entityUuid;
|
||||
}
|
||||
|
|
@ -45,6 +51,10 @@ public class UploadStatusCommand extends Command {
|
|||
return entityType;
|
||||
}
|
||||
|
||||
public Boolean getAbort() {
|
||||
return abort;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean executeInSequence() {
|
||||
return false;
|
||||
|
|
|
|||
|
|
@ -230,6 +230,8 @@ public interface VirtualMachineManager extends Manager {
|
|||
|
||||
Boolean updateDefaultNicForVM(VirtualMachine vm, Nic nic, Nic defaultNic);
|
||||
|
||||
boolean updateVmNic(VirtualMachine vm, Nic nic, Boolean enabled) throws ResourceUnavailableException;
|
||||
|
||||
/**
|
||||
* @param vm
|
||||
* @param network
|
||||
|
|
|
|||
|
|
@ -310,7 +310,7 @@ public interface NetworkOrchestrationService {
|
|||
|
||||
void removeDhcpServiceInSubnet(Nic nic);
|
||||
|
||||
boolean resourceCountNeedsUpdate(NetworkOffering ntwkOff, ACLType aclType);
|
||||
boolean isResourceCountUpdateNeeded(NetworkOffering networkOffering);
|
||||
|
||||
void prepareAllNicsForMigration(VirtualMachineProfile vm, DeployDestination dest);
|
||||
|
||||
|
|
|
|||
|
|
@ -120,7 +120,7 @@ public interface VolumeOrchestrationService {
|
|||
void destroyVolume(Volume volume);
|
||||
|
||||
DiskProfile allocateRawVolume(Type type, String name, DiskOffering offering, Long size, Long minIops, Long maxIops, VirtualMachine vm, VirtualMachineTemplate template,
|
||||
Account owner, Long deviceId);
|
||||
Account owner, Long deviceId, boolean incrementResourceCount);
|
||||
|
||||
VolumeInfo createVolumeOnPrimaryStorage(VirtualMachine vm, VolumeInfo volume, HypervisorType rootDiskHyperType, StoragePool storagePool) throws NoTransitionException;
|
||||
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@ import static org.apache.cloudstack.framework.config.ConfigKey.Scope.Cluster;
|
|||
import com.cloud.deploy.DeploymentPlanner;
|
||||
import com.cloud.host.HostVO;
|
||||
import com.cloud.host.Status;
|
||||
import com.cloud.storage.Storage.StoragePoolType;
|
||||
import com.cloud.utils.component.Manager;
|
||||
import com.cloud.vm.VMInstanceVO;
|
||||
import org.apache.cloudstack.framework.config.ConfigKey;
|
||||
|
|
@ -32,6 +33,8 @@ import java.util.List;
|
|||
*/
|
||||
public interface HighAvailabilityManager extends Manager {
|
||||
|
||||
List<StoragePoolType> LIBVIRT_STORAGE_POOL_TYPES_WITH_HA_SUPPORT = List.of(StoragePoolType.NetworkFilesystem, StoragePoolType.SharedMountPoint);
|
||||
|
||||
ConfigKey<Boolean> ForceHA = new ConfigKey<>("Advanced", Boolean.class, "force.ha", "false",
|
||||
"Force High-Availability to happen even if the VM says no.", true, Cluster);
|
||||
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@
|
|||
|
||||
package com.cloud.vm;
|
||||
|
||||
import static com.cloud.configuration.ConfigurationManagerImpl.EXPOSE_ERRORS_TO_USER;
|
||||
import static com.cloud.configuration.ConfigurationManagerImpl.MIGRATE_VM_ACROSS_CLUSTERS;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
|
|
@ -49,7 +50,6 @@ import javax.inject.Inject;
|
|||
import javax.naming.ConfigurationException;
|
||||
import javax.persistence.EntityExistsException;
|
||||
|
||||
|
||||
import org.apache.cloudstack.affinity.dao.AffinityGroupVMMapDao;
|
||||
import org.apache.cloudstack.annotation.AnnotationService;
|
||||
import org.apache.cloudstack.annotation.dao.AnnotationDao;
|
||||
|
|
@ -153,6 +153,8 @@ import com.cloud.agent.api.UnPlugNicAnswer;
|
|||
import com.cloud.agent.api.UnPlugNicCommand;
|
||||
import com.cloud.agent.api.UnmanageInstanceCommand;
|
||||
import com.cloud.agent.api.UnregisterVMCommand;
|
||||
import com.cloud.agent.api.UpdateVmNicAnswer;
|
||||
import com.cloud.agent.api.UpdateVmNicCommand;
|
||||
import com.cloud.agent.api.VmDiskStatsEntry;
|
||||
import com.cloud.agent.api.VmNetworkStatsEntry;
|
||||
import com.cloud.agent.api.VmStatsEntry;
|
||||
|
|
@ -307,7 +309,6 @@ import com.cloud.vm.snapshot.VMSnapshotVO;
|
|||
import com.cloud.vm.snapshot.dao.VMSnapshotDao;
|
||||
import com.google.gson.Gson;
|
||||
|
||||
|
||||
public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMachineManager, VmWorkJobHandler, Listener, Configurable {
|
||||
|
||||
public static final String VM_WORK_JOB_HANDLER = VirtualMachineManagerImpl.class.getSimpleName();
|
||||
|
|
@ -585,7 +586,7 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac
|
|||
Long deviceId = dataDiskDeviceIds.get(index++);
|
||||
String volumeName = deviceId == null ? "DATA-" + persistedVm.getId() : "DATA-" + persistedVm.getId() + "-" + String.valueOf(deviceId);
|
||||
volumeMgr.allocateRawVolume(Type.DATADISK, volumeName, dataDiskOfferingInfo.getDiskOffering(), dataDiskOfferingInfo.getSize(),
|
||||
dataDiskOfferingInfo.getMinIops(), dataDiskOfferingInfo.getMaxIops(), persistedVm, template, owner, deviceId);
|
||||
dataDiskOfferingInfo.getMinIops(), dataDiskOfferingInfo.getMaxIops(), persistedVm, template, owner, deviceId, true);
|
||||
}
|
||||
}
|
||||
if (datadiskTemplateToDiskOfferingMap != null && !datadiskTemplateToDiskOfferingMap.isEmpty()) {
|
||||
|
|
@ -595,7 +596,7 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac
|
|||
long diskOfferingSize = diskOffering.getDiskSize() / (1024 * 1024 * 1024);
|
||||
VMTemplateVO dataDiskTemplate = _templateDao.findById(dataDiskTemplateToDiskOfferingMap.getKey());
|
||||
volumeMgr.allocateRawVolume(Type.DATADISK, "DATA-" + persistedVm.getId() + "-" + String.valueOf( diskNumber), diskOffering, diskOfferingSize, null, null,
|
||||
persistedVm, dataDiskTemplate, owner, diskNumber);
|
||||
persistedVm, dataDiskTemplate, owner, diskNumber, true);
|
||||
diskNumber++;
|
||||
}
|
||||
}
|
||||
|
|
@ -625,7 +626,7 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac
|
|||
String rootVolumeName = String.format("ROOT-%s", vm.getId());
|
||||
if (template.getFormat() == ImageFormat.ISO) {
|
||||
volumeMgr.allocateRawVolume(Type.ROOT, rootVolumeName, rootDiskOfferingInfo.getDiskOffering(), rootDiskOfferingInfo.getSize(),
|
||||
rootDiskOfferingInfo.getMinIops(), rootDiskOfferingInfo.getMaxIops(), vm, template, owner, null);
|
||||
rootDiskOfferingInfo.getMinIops(), rootDiskOfferingInfo.getMaxIops(), vm, template, owner, null, true);
|
||||
} else if (Arrays.asList(ImageFormat.BAREMETAL, ImageFormat.EXTERNAL).contains(template.getFormat())) {
|
||||
logger.debug("{} has format [{}]. Skipping ROOT volume [{}] allocation.", template, template.getFormat(), rootVolumeName);
|
||||
} else {
|
||||
|
|
@ -931,10 +932,22 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac
|
|||
public void start(final String vmUuid, final Map<VirtualMachineProfile.Param, Object> params, final DeploymentPlan planToDeploy, final DeploymentPlanner planner) {
|
||||
try {
|
||||
advanceStart(vmUuid, params, planToDeploy, planner);
|
||||
} catch (ConcurrentOperationException | InsufficientCapacityException e) {
|
||||
throw new CloudRuntimeException(String.format("Unable to start a VM [%s] due to [%s].", vmUuid, e.getMessage()), e).add(VirtualMachine.class, vmUuid);
|
||||
} catch (ConcurrentOperationException e) {
|
||||
final CallContext cctxt = CallContext.current();
|
||||
final Account account = cctxt.getCallingAccount();
|
||||
if (canExposeError(account)) {
|
||||
throw new CloudRuntimeException(String.format("Unable to start a VM [%s] due to [%s].", vmUuid, e.getMessage()), e).add(VirtualMachine.class, vmUuid);
|
||||
}
|
||||
throw new CloudRuntimeException(String.format("Unable to start a VM [%s] due to concurrent operation.", vmUuid), e).add(VirtualMachine.class, vmUuid);
|
||||
} catch (final InsufficientCapacityException e) {
|
||||
final CallContext cctxt = CallContext.current();
|
||||
final Account account = cctxt.getCallingAccount();
|
||||
if (canExposeError(account)) {
|
||||
throw new CloudRuntimeException(String.format("Unable to start a VM [%s] due to [%s].", vmUuid, e.getMessage()), e).add(VirtualMachine.class, vmUuid);
|
||||
}
|
||||
throw new CloudRuntimeException(String.format("Unable to start a VM [%s] due to insufficient capacity.", vmUuid), e).add(VirtualMachine.class, vmUuid);
|
||||
} catch (final ResourceUnavailableException e) {
|
||||
if (e.getScope() != null && e.getScope().equals(VirtualRouter.class)){
|
||||
if (e.getScope() != null && e.getScope().equals(VirtualRouter.class)) {
|
||||
Account callingAccount = CallContext.current().getCallingAccount();
|
||||
String errorSuffix = (callingAccount != null && callingAccount.getType() == Account.Type.ADMIN) ?
|
||||
String.format("Failure: %s", e.getMessage()) :
|
||||
|
|
@ -1365,6 +1378,7 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac
|
|||
|
||||
final HypervisorGuru hvGuru = _hvGuruMgr.getGuru(vm.getHypervisorType());
|
||||
|
||||
Throwable lastKnownError = null;
|
||||
boolean canRetry = true;
|
||||
ExcludeList avoids = null;
|
||||
try {
|
||||
|
|
@ -1388,7 +1402,8 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac
|
|||
|
||||
int retry = StartRetry.value();
|
||||
while (retry-- != 0) {
|
||||
logger.debug("Instance start attempt #{}", (StartRetry.value() - retry));
|
||||
int attemptNumber = StartRetry.value() - retry;
|
||||
logger.debug("Instance start attempt #{}", attemptNumber);
|
||||
|
||||
if (reuseVolume) {
|
||||
final List<VolumeVO> vols = _volsDao.findReadyRootVolumesByInstance(vm.getId());
|
||||
|
|
@ -1454,8 +1469,13 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac
|
|||
reuseVolume = false;
|
||||
continue;
|
||||
}
|
||||
throw new InsufficientServerCapacityException("Unable to create a deployment for " + vmProfile, DataCenter.class, plan.getDataCenterId(),
|
||||
areAffinityGroupsAssociated(vmProfile));
|
||||
String message = String.format("Unable to create a deployment for %s after %s attempts", vmProfile, attemptNumber);
|
||||
if (canExposeError(account) && lastKnownError != null) {
|
||||
message += String.format(" Last known error: %s", lastKnownError.getMessage());
|
||||
throw new CloudRuntimeException(message, lastKnownError);
|
||||
} else {
|
||||
throw new InsufficientServerCapacityException(message, DataCenter.class, plan.getDataCenterId(), areAffinityGroupsAssociated(vmProfile));
|
||||
}
|
||||
}
|
||||
|
||||
avoids.addHost(dest.getHost().getId());
|
||||
|
|
@ -1623,11 +1643,15 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac
|
|||
throw new ExecutionException("Unable to start VM:" + vm.getUuid() + " due to error in finalizeStart, not retrying");
|
||||
}
|
||||
}
|
||||
logger.info("Unable to start VM on {} due to {}", dest.getHost(), (startAnswer == null ? " no start answer" : startAnswer.getDetails()));
|
||||
String msg = String.format("Unable to start VM on %s due to %s", dest.getHost(), startAnswer == null ? "no start command answer" : startAnswer.getDetails());
|
||||
lastKnownError = new ExecutionException(msg);
|
||||
|
||||
if (startAnswer != null && startAnswer.getContextParam("stopRetry") != null) {
|
||||
logger.error(msg, lastKnownError);
|
||||
break;
|
||||
}
|
||||
|
||||
logger.debug(msg, lastKnownError);
|
||||
} catch (OperationTimedoutException e) {
|
||||
logger.debug("Unable to send the start command to host {} failed to start VM: {}", dest.getHost(), vm);
|
||||
if (e.isActive()) {
|
||||
|
|
@ -1637,6 +1661,7 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac
|
|||
throw new AgentUnavailableException("Unable to start " + vm.getHostName(), destHostId, e);
|
||||
} catch (final ResourceUnavailableException e) {
|
||||
logger.warn("Unable to contact resource.", e);
|
||||
lastKnownError = e;
|
||||
if (!avoids.add(e)) {
|
||||
if (e.getScope() == Volume.class || e.getScope() == Nic.class) {
|
||||
throw e;
|
||||
|
|
@ -1693,10 +1718,22 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac
|
|||
}
|
||||
|
||||
if (startedVm == null) {
|
||||
throw new CloudRuntimeException("Unable to start Instance '" + vm.getHostName() + "' (" + vm.getUuid() + "), see management server log for details");
|
||||
String messageTmpl = "Unable to start Instance '%s' (%s)%s";
|
||||
String details;
|
||||
if (canExposeError(account) && lastKnownError != null) {
|
||||
details = ": " + lastKnownError.getMessage();
|
||||
} else {
|
||||
details = ", see management server log for details";
|
||||
}
|
||||
String message = String.format(messageTmpl, vm.getHostName(), vm.getUuid(), details);
|
||||
throw new CloudRuntimeException(message, lastKnownError);
|
||||
}
|
||||
}
|
||||
|
||||
private boolean canExposeError(Account account) {
|
||||
return (account != null && account.getType() == Account.Type.ADMIN) || Boolean.TRUE.equals(EXPOSE_ERRORS_TO_USER.value());
|
||||
}
|
||||
|
||||
protected void updateStartCommandWithExternalDetails(Host host, VirtualMachineTO vmTO, StartCommand command) {
|
||||
if (!HypervisorType.External.equals(host.getHypervisorType())) {
|
||||
return;
|
||||
|
|
@ -2180,7 +2217,6 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac
|
|||
protected boolean sendStop(final VirtualMachineGuru guru, final VirtualMachineProfile profile, final boolean force, final boolean checkBeforeCleanup) {
|
||||
final VirtualMachine vm = profile.getVirtualMachine();
|
||||
Map<String, Boolean> vlanToPersistenceMap = getVlanToPersistenceMapForVM(vm.getId());
|
||||
|
||||
StopCommand stpCmd = new StopCommand(vm, getExecuteInSequence(vm.getHypervisorType()), checkBeforeCleanup);
|
||||
updateStopCommandForExternalHypervisorType(vm.getHypervisorType(), profile, stpCmd);
|
||||
if (MapUtils.isNotEmpty(vlanToPersistenceMap)) {
|
||||
|
|
@ -5239,9 +5275,20 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac
|
|||
|
||||
private void saveCustomOfferingDetails(long vmId, ServiceOffering serviceOffering) {
|
||||
Map<String, String> details = vmInstanceDetailsDao.listDetailsKeyPairs(vmId);
|
||||
details.put(UsageEventVO.DynamicParameters.cpuNumber.name(), serviceOffering.getCpu().toString());
|
||||
details.put(UsageEventVO.DynamicParameters.cpuSpeed.name(), serviceOffering.getSpeed().toString());
|
||||
details.put(UsageEventVO.DynamicParameters.memory.name(), serviceOffering.getRamSize().toString());
|
||||
|
||||
// We need to restore only the customizable parameters. If we save a parameter that is not customizable and attempt
|
||||
// to restore a VM snapshot, com.cloud.vm.UserVmManagerImpl.validateCustomParameters will fail.
|
||||
ServiceOffering unfilledOffering = _serviceOfferingDao.findByIdIncludingRemoved(serviceOffering.getId());
|
||||
if (unfilledOffering.getCpu() == null) {
|
||||
details.put(UsageEventVO.DynamicParameters.cpuNumber.name(), serviceOffering.getCpu().toString());
|
||||
}
|
||||
if (unfilledOffering.getSpeed() == null) {
|
||||
details.put(UsageEventVO.DynamicParameters.cpuSpeed.name(), serviceOffering.getSpeed().toString());
|
||||
}
|
||||
if (unfilledOffering.getRamSize() == null) {
|
||||
details.put(UsageEventVO.DynamicParameters.memory.name(), serviceOffering.getRamSize().toString());
|
||||
}
|
||||
|
||||
List<VMInstanceDetailVO> detailList = new ArrayList<>();
|
||||
for (Map.Entry<String, String> entry: details.entrySet()) {
|
||||
VMInstanceDetailVO detailVO = new VMInstanceDetailVO(vmId, entry.getKey(), entry.getValue(), true);
|
||||
|
|
@ -6270,6 +6317,80 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac
|
|||
_jobMgr.marshallResultObject(result));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean updateVmNic(VirtualMachine vm, Nic nic, Boolean enabled) {
|
||||
Outcome<VirtualMachine> outcome = updateVmNicThroughJobQueue(vm, nic, enabled);
|
||||
|
||||
retrieveVmFromJobOutcome(outcome, vm.getUuid(), "updateVmNic");
|
||||
|
||||
try {
|
||||
Object jobResult = retrieveResultFromJobOutcomeAndThrowExceptionIfNeeded(outcome);
|
||||
if (jobResult instanceof Boolean) {
|
||||
return BooleanUtils.isTrue((Boolean) jobResult);
|
||||
}
|
||||
} catch (ResourceUnavailableException | InsufficientCapacityException ex) {
|
||||
throw new CloudRuntimeException(String.format("Exception while updating VM [%s] NIC. Check the logs for more information.", vm.getUuid()));
|
||||
}
|
||||
throw new CloudRuntimeException("Unexpected job execution result.");
|
||||
}
|
||||
|
||||
private boolean orchestrateUpdateVmNic(final VirtualMachine vm, final Nic nic, final Boolean enabled) throws ResourceUnavailableException {
|
||||
if (vm.getState() == State.Running) {
|
||||
try {
|
||||
UpdateVmNicCommand updateVmNicCmd = new UpdateVmNicCommand(nic.getMacAddress(), vm.getName(), enabled);
|
||||
Commands cmds = new Commands(Command.OnError.Stop);
|
||||
cmds.addCommand("updatevmnic", updateVmNicCmd);
|
||||
|
||||
_agentMgr.send(vm.getHostId(), cmds);
|
||||
|
||||
UpdateVmNicAnswer updateVmNicAnswer = cmds.getAnswer(UpdateVmNicAnswer.class);
|
||||
if (updateVmNicAnswer == null || !updateVmNicAnswer.getResult()) {
|
||||
logger.warn("Unable to update VM %s NIC [{}].", vm.getName(), nic.getUuid());
|
||||
return false;
|
||||
}
|
||||
} catch (final OperationTimedoutException e) {
|
||||
throw new AgentUnavailableException(String.format("Unable to update NIC %s for VM %s.", nic.getUuid(), vm.getUuid()), vm.getHostId(), e);
|
||||
}
|
||||
}
|
||||
|
||||
NicVO nicVo = _nicsDao.findById(nic.getId());
|
||||
nicVo.setEnabled(enabled);
|
||||
_nicsDao.persist(nicVo);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public Outcome<VirtualMachine> updateVmNicThroughJobQueue(final VirtualMachine vm, final Nic nic, final Boolean isNicEnabled) {
|
||||
Long vmId = vm.getId();
|
||||
String commandName = VmWorkUpdateNic.class.getName();
|
||||
Pair<VmWorkJobVO, Long> pendingWorkJob = retrievePendingWorkJob(vmId, commandName);
|
||||
|
||||
VmWorkJobVO workJob = pendingWorkJob.first();
|
||||
|
||||
if (workJob == null) {
|
||||
Pair<VmWorkJobVO, VmWork> newVmWorkJobAndInfo = createWorkJobAndWorkInfo(commandName, vmId);
|
||||
|
||||
workJob = newVmWorkJobAndInfo.first();
|
||||
VmWorkUpdateNic workInfo = new VmWorkUpdateNic(newVmWorkJobAndInfo.second(), nic.getId(), isNicEnabled);
|
||||
|
||||
setCmdInfoAndSubmitAsyncJob(workJob, workInfo, vmId);
|
||||
}
|
||||
AsyncJobExecutionContext.getCurrentExecutionContext().joinJob(workJob.getId());
|
||||
|
||||
return new VmJobVirtualMachineOutcome(workJob, vmId);
|
||||
}
|
||||
|
||||
@ReflectionUse
|
||||
private Pair<JobInfo.Status, String> orchestrateUpdateVmNic(final VmWorkUpdateNic work) throws Exception {
|
||||
VMInstanceVO vm = findVmById(work.getVmId());
|
||||
final NicVO nic = _entityMgr.findById(NicVO.class, work.getNicId());
|
||||
if (nic == null) {
|
||||
throw new CloudRuntimeException(String.format("Unable to find NIC with ID %s.", work.getNicId()));
|
||||
}
|
||||
final boolean result = orchestrateUpdateVmNic(vm, nic, work.isEnabled());
|
||||
return new Pair<>(JobInfo.Status.SUCCEEDED, _jobMgr.marshallResultObject(result));
|
||||
}
|
||||
|
||||
private Pair<Long, Long> findClusterAndHostIdForVmFromVolumes(long vmId) {
|
||||
Long clusterId = null;
|
||||
Long hostId = null;
|
||||
|
|
|
|||
|
|
@ -0,0 +1,38 @@
|
|||
// 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.vm;
|
||||
|
||||
public class VmWorkUpdateNic extends VmWork {
|
||||
private static final long serialVersionUID = -8957066627929113278L;
|
||||
|
||||
Long nicId;
|
||||
Boolean enabled;
|
||||
|
||||
public VmWorkUpdateNic(VmWork vmWork, Long nicId, Boolean enabled) {
|
||||
super(vmWork);
|
||||
this.nicId = nicId;
|
||||
this.enabled = enabled;
|
||||
}
|
||||
|
||||
public Long getNicId() {
|
||||
return nicId;
|
||||
}
|
||||
|
||||
public Boolean isEnabled() {
|
||||
return enabled;
|
||||
}
|
||||
}
|
||||
|
|
@ -58,6 +58,7 @@ import org.apache.cloudstack.framework.messagebus.PublishScope;
|
|||
import org.apache.cloudstack.managed.context.ManagedContextRunnable;
|
||||
import org.apache.cloudstack.network.RoutedIpv4Manager;
|
||||
import org.apache.cloudstack.network.dao.NetworkPermissionDao;
|
||||
import org.apache.cloudstack.reservation.dao.ReservationDao;
|
||||
import org.apache.commons.collections.CollectionUtils;
|
||||
import org.apache.commons.lang3.BooleanUtils;
|
||||
import org.apache.commons.lang3.ObjectUtils;
|
||||
|
|
@ -86,6 +87,7 @@ import com.cloud.api.query.dao.DomainRouterJoinDao;
|
|||
import com.cloud.api.query.vo.DomainRouterJoinVO;
|
||||
import com.cloud.bgp.BGPService;
|
||||
import com.cloud.configuration.ConfigurationManager;
|
||||
import com.cloud.configuration.Resource;
|
||||
import com.cloud.configuration.Resource.ResourceType;
|
||||
import com.cloud.dc.ASNumberVO;
|
||||
import com.cloud.dc.ClusterVO;
|
||||
|
|
@ -214,6 +216,7 @@ import com.cloud.offerings.dao.NetworkOfferingDao;
|
|||
import com.cloud.offerings.dao.NetworkOfferingDetailsDao;
|
||||
import com.cloud.offerings.dao.NetworkOfferingServiceMapDao;
|
||||
import com.cloud.resource.ResourceManager;
|
||||
import com.cloud.resourcelimit.CheckedReservation;
|
||||
import com.cloud.server.ManagementServer;
|
||||
import com.cloud.user.Account;
|
||||
import com.cloud.user.ResourceLimitService;
|
||||
|
|
@ -447,6 +450,8 @@ public class NetworkOrchestrator extends ManagerBase implements NetworkOrchestra
|
|||
ClusterDao clusterDao;
|
||||
@Inject
|
||||
RoutedIpv4Manager routedIpv4Manager;
|
||||
@Inject
|
||||
private ReservationDao reservationDao;
|
||||
|
||||
protected StateMachine2<Network.State, Network.Event, Network> _stateMachine;
|
||||
ScheduledExecutorService _executor;
|
||||
|
|
@ -2326,7 +2331,8 @@ public class NetworkOrchestrator extends ManagerBase implements NetworkOrchestra
|
|||
for (final NetworkElement element : networkElements) {
|
||||
if (providersToImplement.contains(element.getProvider())) {
|
||||
if (!_networkModel.isProviderEnabledInPhysicalNetwork(_networkModel.getPhysicalNetworkId(network), element.getProvider().getName())) {
|
||||
throw new CloudRuntimeException(String.format("Service provider %s either doesn't exist or is not enabled in physical network: %s", element.getProvider().getName(), _physicalNetworkDao.findById(network.getPhysicalNetworkId())));
|
||||
throw new CloudRuntimeException(String.format("Service provider %s either doesn't exist or is not enabled in physical network: %s",
|
||||
element.getProvider().getName(), _physicalNetworkDao.findById(network.getPhysicalNetworkId())));
|
||||
}
|
||||
if (element instanceof NetworkMigrationResponder) {
|
||||
if (!((NetworkMigrationResponder) element).prepareMigration(profile, network, vm, dest, context)) {
|
||||
|
|
@ -2633,6 +2639,10 @@ public class NetworkOrchestrator extends ManagerBase implements NetworkOrchestra
|
|||
|
||||
final NetworkGuru guru = AdapterBase.getAdapterByName(networkGurus, network.getGuruName());
|
||||
guru.deallocate(network, profile, vm);
|
||||
if (nic.getReservationStrategy() == Nic.ReservationStrategy.Create) {
|
||||
applyProfileToNicForRelease(nic, profile);
|
||||
_nicDao.update(nic.getId(), nic);
|
||||
}
|
||||
if (BooleanUtils.isNotTrue(preserveNics)) {
|
||||
_nicDao.remove(nic.getId());
|
||||
}
|
||||
|
|
@ -2747,12 +2757,6 @@ public class NetworkOrchestrator extends ManagerBase implements NetworkOrchestra
|
|||
return null;
|
||||
}
|
||||
|
||||
final boolean updateResourceCount = resourceCountNeedsUpdate(ntwkOff, aclType);
|
||||
//check resource limits
|
||||
if (updateResourceCount) {
|
||||
_resourceLimitMgr.checkResourceLimit(owner, ResourceType.network, isDisplayNetworkEnabled);
|
||||
}
|
||||
|
||||
// Validate network offering
|
||||
if (ntwkOff.getState() != NetworkOffering.State.Enabled) {
|
||||
// see NetworkOfferingVO
|
||||
|
|
@ -2771,6 +2775,8 @@ public class NetworkOrchestrator extends ManagerBase implements NetworkOrchestra
|
|||
|
||||
boolean ipv6 = false;
|
||||
|
||||
try (CheckedReservation networkReservation = new CheckedReservation(owner, domainId, Resource.ResourceType.network, null, null, 1L, reservationDao, _resourceLimitMgr)) {
|
||||
|
||||
if (StringUtils.isNoneBlank(ip6Gateway, ip6Cidr)) {
|
||||
ipv6 = true;
|
||||
}
|
||||
|
|
@ -3110,8 +3116,8 @@ public class NetworkOrchestrator extends ManagerBase implements NetworkOrchestra
|
|||
}
|
||||
}
|
||||
|
||||
if (updateResourceCount) {
|
||||
_resourceLimitMgr.incrementResourceCount(owner.getId(), ResourceType.network, isDisplayNetworkEnabled);
|
||||
if (isResourceCountUpdateNeeded(ntwkOff)) {
|
||||
changeAccountResourceCountOrRecalculateDomainResourceCount(owner.getAccountId(), domainId, isDisplayNetworkEnabled, true);
|
||||
}
|
||||
UsageEventUtils.publishNetworkCreation(network);
|
||||
|
||||
|
|
@ -3122,6 +3128,7 @@ public class NetworkOrchestrator extends ManagerBase implements NetworkOrchestra
|
|||
CallContext.current().setEventDetails("Network ID: " + network.getUuid());
|
||||
CallContext.current().putContextParameter(Network.class, network.getUuid());
|
||||
return network;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -3487,9 +3494,8 @@ public class NetworkOrchestrator extends ManagerBase implements NetworkOrchestra
|
|||
}
|
||||
|
||||
final NetworkOffering ntwkOff = _entityMgr.findById(NetworkOffering.class, networkFinal.getNetworkOfferingId());
|
||||
final boolean updateResourceCount = resourceCountNeedsUpdate(ntwkOff, networkFinal.getAclType());
|
||||
if (updateResourceCount) {
|
||||
_resourceLimitMgr.decrementResourceCount(networkFinal.getAccountId(), ResourceType.network, networkFinal.getDisplayNetwork());
|
||||
if (isResourceCountUpdateNeeded(ntwkOff)) {
|
||||
changeAccountResourceCountOrRecalculateDomainResourceCount(networkFinal.getAccountId(), networkFinal.getDomainId(), networkFinal.getDisplayNetwork(), false);
|
||||
}
|
||||
}
|
||||
return deletedVlans.second();
|
||||
|
|
@ -3512,6 +3518,23 @@ public class NetworkOrchestrator extends ManagerBase implements NetworkOrchestra
|
|||
return success;
|
||||
}
|
||||
|
||||
/**
|
||||
* If it is a shared network with {@link ACLType#Domain}, it will belong to account {@link Account#ACCOUNT_ID_SYSTEM} and the resources will be not incremented for the
|
||||
* domain. Therefore, we force the recalculation of the domain's resource count in this case. Otherwise, it will change the count for the account owner.
|
||||
* @param incrementAccountResourceCount If true, the account resource count will be incremented by 1; otherwise, it will decremented by 1.
|
||||
*/
|
||||
private void changeAccountResourceCountOrRecalculateDomainResourceCount(Long accountId, Long domainId, boolean displayNetwork, boolean incrementAccountResourceCount) {
|
||||
if (Account.ACCOUNT_ID_SYSTEM == accountId && ObjectUtils.isNotEmpty(domainId)) {
|
||||
_resourceLimitMgr.recalculateDomainResourceCount(domainId, ResourceType.network, null);
|
||||
} else {
|
||||
if (incrementAccountResourceCount) {
|
||||
_resourceLimitMgr.incrementResourceCount(accountId, ResourceType.network, displayNetwork);
|
||||
} else {
|
||||
_resourceLimitMgr.decrementResourceCount(accountId, ResourceType.network, displayNetwork);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void publishDeletedVlanRanges(List<VlanVO> deletedVlanRangeToPublish) {
|
||||
if (CollectionUtils.isNotEmpty(deletedVlanRangeToPublish)) {
|
||||
for (VlanVO vlan : deletedVlanRangeToPublish) {
|
||||
|
|
@ -3521,10 +3544,8 @@ public class NetworkOrchestrator extends ManagerBase implements NetworkOrchestra
|
|||
}
|
||||
|
||||
@Override
|
||||
public boolean resourceCountNeedsUpdate(final NetworkOffering ntwkOff, final ACLType aclType) {
|
||||
//Update resource count only for Isolated account specific non-system networks
|
||||
final boolean updateResourceCount = ntwkOff.getGuestType() == GuestType.Isolated && !ntwkOff.isSystemOnly() && aclType == ACLType.Account;
|
||||
return updateResourceCount;
|
||||
public boolean isResourceCountUpdateNeeded(NetworkOffering networkOffering) {
|
||||
return !networkOffering.isSystemOnly();
|
||||
}
|
||||
|
||||
protected Pair<Boolean, List<VlanVO>> deleteVlansInNetwork(final NetworkVO network, final long userId, final Account callerAccount) {
|
||||
|
|
|
|||
|
|
@ -40,6 +40,7 @@ import javax.naming.ConfigurationException;
|
|||
|
||||
import com.cloud.deploy.DeploymentClusterPlanner;
|
||||
import com.cloud.exception.ResourceAllocationException;
|
||||
import com.cloud.resourcelimit.ReservationHelper;
|
||||
import com.cloud.storage.DiskOfferingVO;
|
||||
import com.cloud.storage.VMTemplateVO;
|
||||
import com.cloud.storage.dao.VMTemplateDao;
|
||||
|
|
@ -82,6 +83,7 @@ import org.apache.cloudstack.framework.jobs.AsyncJobManager;
|
|||
import org.apache.cloudstack.framework.jobs.impl.AsyncJobVO;
|
||||
import org.apache.cloudstack.resourcedetail.DiskOfferingDetailVO;
|
||||
import org.apache.cloudstack.resourcedetail.dao.DiskOfferingDetailsDao;
|
||||
import org.apache.cloudstack.resourcelimit.Reserver;
|
||||
import org.apache.cloudstack.secret.PassphraseVO;
|
||||
import org.apache.cloudstack.secret.dao.PassphraseDao;
|
||||
import org.apache.cloudstack.snapshot.SnapshotHelper;
|
||||
|
|
@ -862,7 +864,7 @@ public class VolumeOrchestrator extends ManagerBase implements VolumeOrchestrati
|
|||
@ActionEvent(eventType = EventTypes.EVENT_VOLUME_CREATE, eventDescription = "creating volume", create = true)
|
||||
@Override
|
||||
public DiskProfile allocateRawVolume(Type type, String name, DiskOffering offering, Long size, Long minIops, Long maxIops, VirtualMachine vm, VirtualMachineTemplate template, Account owner,
|
||||
Long deviceId) {
|
||||
Long deviceId, boolean incrementResourceCount) {
|
||||
if (size == null) {
|
||||
size = offering.getDiskSize();
|
||||
} else {
|
||||
|
|
@ -901,7 +903,7 @@ public class VolumeOrchestrator extends ManagerBase implements VolumeOrchestrati
|
|||
saveVolumeDetails(offering.getId(), vol.getId());
|
||||
|
||||
// Save usage event and update resource count for user vm volumes
|
||||
if (vm.getType() == VirtualMachine.Type.User) {
|
||||
if (vm.getType() == VirtualMachine.Type.User && incrementResourceCount) {
|
||||
UsageEventUtils.publishUsageEvent(EventTypes.EVENT_VOLUME_CREATE, vol.getAccountId(), vol.getDataCenterId(), vol.getId(), vol.getName(), offering.getId(), null, size,
|
||||
Volume.class.getName(), vol.getUuid(), vol.getInstanceId(), vol.isDisplayVolume());
|
||||
_resourceLimitMgr.incrementVolumeResourceCount(vm.getAccountId(), vol.isDisplayVolume(), vol.getSize(), offering);
|
||||
|
|
@ -1938,14 +1940,20 @@ public class VolumeOrchestrator extends ManagerBase implements VolumeOrchestrati
|
|||
template == null ? null : template.getSize(),
|
||||
vol.getPassphraseId() != null);
|
||||
|
||||
if (newSize != vol.getSize()) {
|
||||
DiskOfferingVO diskOffering = diskOfferingDao.findByIdIncludingRemoved(vol.getDiskOfferingId());
|
||||
if (newSize == vol.getSize()) {
|
||||
return;
|
||||
}
|
||||
|
||||
DiskOfferingVO diskOffering = diskOfferingDao.findByIdIncludingRemoved(vol.getDiskOfferingId());
|
||||
|
||||
List<Reserver> reservations = new ArrayList<>();
|
||||
try {
|
||||
VMInstanceVO vm = vol.getInstanceId() != null ? vmInstanceDao.findById(vol.getInstanceId()) : null;
|
||||
if (vm == null || vm.getType() == VirtualMachine.Type.User) {
|
||||
// Update resource count for user vm volumes when volume is attached
|
||||
if (newSize > vol.getSize()) {
|
||||
_resourceLimitMgr.checkPrimaryStorageResourceLimit(_accountMgr.getActiveAccountById(vol.getAccountId()),
|
||||
vol.isDisplay(), newSize - vol.getSize(), diskOffering);
|
||||
vol.isDisplay(), newSize - vol.getSize(), diskOffering, reservations);
|
||||
_resourceLimitMgr.incrementVolumePrimaryStorageResourceCount(vol.getAccountId(), vol.isDisplay(),
|
||||
newSize - vol.getSize(), diskOffering);
|
||||
} else {
|
||||
|
|
@ -1953,9 +1961,11 @@ public class VolumeOrchestrator extends ManagerBase implements VolumeOrchestrati
|
|||
vol.getSize() - newSize, diskOffering);
|
||||
}
|
||||
}
|
||||
vol.setSize(newSize);
|
||||
_volsDao.persist(vol);
|
||||
} finally {
|
||||
ReservationHelper.closeAll(reservations);
|
||||
}
|
||||
vol.setSize(newSize);
|
||||
_volsDao.persist(vol);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
|||
|
|
@ -27,6 +27,6 @@ public interface AccountVlanMapDao extends GenericDao<AccountVlanMapVO, Long> {
|
|||
|
||||
public List<AccountVlanMapVO> listAccountVlanMapsByVlan(long vlanDbId);
|
||||
|
||||
public AccountVlanMapVO findAccountVlanMap(long accountId, long vlanDbId);
|
||||
public AccountVlanMapVO findAccountVlanMap(Long accountId, long vlanDbId);
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -48,9 +48,9 @@ public class AccountVlanMapDaoImpl extends GenericDaoBase<AccountVlanMapVO, Long
|
|||
}
|
||||
|
||||
@Override
|
||||
public AccountVlanMapVO findAccountVlanMap(long accountId, long vlanDbId) {
|
||||
public AccountVlanMapVO findAccountVlanMap(Long accountId, long vlanDbId) {
|
||||
SearchCriteria<AccountVlanMapVO> sc = AccountVlanSearch.create();
|
||||
sc.setParameters("accountId", accountId);
|
||||
sc.setParametersIfNotNull("accountId", accountId);
|
||||
sc.setParameters("vlanDbId", vlanDbId);
|
||||
return findOneIncludingRemovedBy(sc);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -24,5 +24,5 @@ import com.cloud.utils.db.GenericDao;
|
|||
public interface DomainVlanMapDao extends GenericDao<DomainVlanMapVO, Long> {
|
||||
public List<DomainVlanMapVO> listDomainVlanMapsByDomain(long domainId);
|
||||
public List<DomainVlanMapVO> listDomainVlanMapsByVlan(long vlanDbId);
|
||||
public DomainVlanMapVO findDomainVlanMap(long domainId, long vlanDbId);
|
||||
public DomainVlanMapVO findDomainVlanMap(Long domainId, long vlanDbId);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -46,9 +46,9 @@ public class DomainVlanMapDaoImpl extends GenericDaoBase<DomainVlanMapVO, Long>
|
|||
}
|
||||
|
||||
@Override
|
||||
public DomainVlanMapVO findDomainVlanMap(long domainId, long vlanDbId) {
|
||||
public DomainVlanMapVO findDomainVlanMap(Long domainId, long vlanDbId) {
|
||||
SearchCriteria<DomainVlanMapVO> sc = DomainVlanSearch.create();
|
||||
sc.setParameters("domainId", domainId);
|
||||
sc.setParametersIfNotNull("domainId", domainId);
|
||||
sc.setParameters("vlanDbId", vlanDbId);
|
||||
return findOneIncludingRemovedBy(sc);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -262,7 +262,7 @@ public class DomainDaoImpl extends GenericDaoBase<DomainVO, Long> implements Dom
|
|||
SearchCriteria<DomainVO> sc = DomainPairSearch.create();
|
||||
sc.setParameters("id", parentId, childId);
|
||||
|
||||
List<DomainVO> domainPair = listBy(sc);
|
||||
List<DomainVO> domainPair = listIncludingRemovedBy(sc);
|
||||
|
||||
if ((domainPair != null) && (domainPair.size() == 2)) {
|
||||
DomainVO d1 = domainPair.get(0);
|
||||
|
|
|
|||
|
|
@ -45,4 +45,9 @@ public interface HostTagsDao extends GenericDao<HostTagVO, Long> {
|
|||
HostTagResponse newHostTagResponse(HostTagVO hostTag);
|
||||
|
||||
List<HostTagVO> searchByIds(Long... hostTagIds);
|
||||
|
||||
/**
|
||||
* List all host tags defined on hosts within a cluster
|
||||
*/
|
||||
List<String> listByClusterId(Long clusterId);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -23,6 +23,7 @@ import org.apache.cloudstack.api.response.HostTagResponse;
|
|||
import org.apache.cloudstack.framework.config.ConfigKey;
|
||||
import org.apache.cloudstack.framework.config.Configurable;
|
||||
import org.apache.cloudstack.framework.config.dao.ConfigurationDao;
|
||||
import org.apache.commons.collections4.CollectionUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
|
|
@ -43,9 +44,12 @@ public class HostTagsDaoImpl extends GenericDaoBase<HostTagVO, Long> implements
|
|||
private final SearchBuilder<HostTagVO> stSearch;
|
||||
private final SearchBuilder<HostTagVO> tagIdsearch;
|
||||
private final SearchBuilder<HostTagVO> ImplicitTagsSearch;
|
||||
private final GenericSearchBuilder<HostTagVO, String> tagSearch;
|
||||
|
||||
@Inject
|
||||
private ConfigurationDao _configDao;
|
||||
@Inject
|
||||
private HostDao hostDao;
|
||||
|
||||
public HostTagsDaoImpl() {
|
||||
HostSearch = createSearchBuilder();
|
||||
|
|
@ -72,6 +76,11 @@ public class HostTagsDaoImpl extends GenericDaoBase<HostTagVO, Long> implements
|
|||
ImplicitTagsSearch.and("hostId", ImplicitTagsSearch.entity().getHostId(), SearchCriteria.Op.EQ);
|
||||
ImplicitTagsSearch.and("isImplicit", ImplicitTagsSearch.entity().getIsImplicit(), SearchCriteria.Op.EQ);
|
||||
ImplicitTagsSearch.done();
|
||||
|
||||
tagSearch = createSearchBuilder(String.class);
|
||||
tagSearch.selectFields(tagSearch.entity().getTag());
|
||||
tagSearch.and("hostIdIN", tagSearch.entity().getHostId(), SearchCriteria.Op.IN);
|
||||
tagSearch.done();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -235,4 +244,15 @@ public class HostTagsDaoImpl extends GenericDaoBase<HostTagVO, Long> implements
|
|||
|
||||
return tagList;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> listByClusterId(Long clusterId) {
|
||||
List<Long> hostIds = hostDao.listIdsByClusterId(clusterId);
|
||||
if (CollectionUtils.isEmpty(hostIds)) {
|
||||
return new ArrayList<>();
|
||||
}
|
||||
SearchCriteria<String> sc = tagSearch.create();
|
||||
sc.setParameters("hostIdIN", hostIds.toArray());
|
||||
return customSearch(sc, null);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -193,6 +193,7 @@ public class NetworkDaoImpl extends GenericDaoBase<NetworkVO, Long>implements Ne
|
|||
PersistentNetworkSearch.and("id", PersistentNetworkSearch.entity().getId(), Op.NEQ);
|
||||
PersistentNetworkSearch.and("guestType", PersistentNetworkSearch.entity().getGuestType(), Op.IN);
|
||||
PersistentNetworkSearch.and("broadcastUri", PersistentNetworkSearch.entity().getBroadcastUri(), Op.EQ);
|
||||
PersistentNetworkSearch.and("dc", PersistentNetworkSearch.entity().getDataCenterId(), Op.EQ);
|
||||
PersistentNetworkSearch.and("removed", PersistentNetworkSearch.entity().getRemoved(), Op.NULL);
|
||||
final SearchBuilder<NetworkOfferingVO> persistentNtwkOffJoin = _ntwkOffDao.createSearchBuilder();
|
||||
persistentNtwkOffJoin.and("persistent", persistentNtwkOffJoin.entity().isPersistent(), Op.EQ);
|
||||
|
|
|
|||
|
|
@ -35,7 +35,7 @@ public interface GuestOSDao extends GenericDao<GuestOSVO, Long> {
|
|||
|
||||
List<GuestOSVO> listByDisplayName(String displayName);
|
||||
|
||||
Pair<List<? extends GuestOS>, Integer> listGuestOSByCriteria(Long startIndex, Long pageSize, Long id, Long osCategoryId, String description, String keyword, Boolean forDisplay);
|
||||
Pair<List<? extends GuestOS>, Integer> listGuestOSByCriteria(Long startIndex, Long pageSize, List<Long> ids, Long osCategoryId, String description, String keyword, Boolean forDisplay);
|
||||
|
||||
List<Long> listIdsByCategoryId(final long categoryId);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -125,12 +125,12 @@ public class GuestOSDaoImpl extends GenericDaoBase<GuestOSVO, Long> implements G
|
|||
return listBy(sc);
|
||||
}
|
||||
|
||||
public Pair<List<? extends GuestOS>, Integer> listGuestOSByCriteria(Long startIndex, Long pageSize, Long id, Long osCategoryId, String description, String keyword, Boolean forDisplay) {
|
||||
public Pair<List<? extends GuestOS>, Integer> listGuestOSByCriteria(Long startIndex, Long pageSize, List<Long> ids, Long osCategoryId, String description, String keyword, Boolean forDisplay) {
|
||||
final Filter searchFilter = new Filter(GuestOSVO.class, "displayName", true, startIndex, pageSize);
|
||||
final SearchCriteria<GuestOSVO> sc = createSearchCriteria();
|
||||
|
||||
if (id != null) {
|
||||
sc.addAnd("id", SearchCriteria.Op.EQ, id);
|
||||
if (CollectionUtils.isNotEmpty(ids)) {
|
||||
sc.addAnd("id", SearchCriteria.Op.IN, ids.toArray());
|
||||
}
|
||||
|
||||
if (osCategoryId != null) {
|
||||
|
|
|
|||
|
|
@ -170,6 +170,7 @@ public class SnapshotDaoImpl extends GenericDaoBase<SnapshotVO, Long> implements
|
|||
CountSnapshotsByAccount.select(null, Func.COUNT, null);
|
||||
CountSnapshotsByAccount.and("account", CountSnapshotsByAccount.entity().getAccountId(), SearchCriteria.Op.EQ);
|
||||
CountSnapshotsByAccount.and("status", CountSnapshotsByAccount.entity().getState(), SearchCriteria.Op.NIN);
|
||||
CountSnapshotsByAccount.and("snapshotTypeNEQ", CountSnapshotsByAccount.entity().getSnapshotType(), SearchCriteria.Op.NIN);
|
||||
CountSnapshotsByAccount.and("removed", CountSnapshotsByAccount.entity().getRemoved(), SearchCriteria.Op.NULL);
|
||||
CountSnapshotsByAccount.done();
|
||||
|
||||
|
|
@ -220,6 +221,7 @@ public class SnapshotDaoImpl extends GenericDaoBase<SnapshotVO, Long> implements
|
|||
SearchCriteria<Long> sc = CountSnapshotsByAccount.create();
|
||||
sc.setParameters("account", accountId);
|
||||
sc.setParameters("status", State.Error, State.Destroyed);
|
||||
sc.setParameters("snapshotTypeNEQ", Snapshot.Type.GROUP.ordinal());
|
||||
return customSearch(sc, null).get(0);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -166,4 +166,12 @@ public interface VolumeDao extends GenericDao<VolumeVO, Long>, StateDao<Volume.S
|
|||
int getVolumeCountByOfferingId(long diskOfferingId);
|
||||
|
||||
VolumeVO findByLastIdAndState(long lastVolumeId, Volume.State...states);
|
||||
|
||||
/**
|
||||
* Retrieves volume by its externalId
|
||||
*
|
||||
* @param externalUuid
|
||||
* @return Volume Object of matching search criteria
|
||||
*/
|
||||
VolumeVO findByExternalUuid(String externalUuid);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -74,6 +74,7 @@ public class VolumeDaoImpl extends GenericDaoBase<VolumeVO, Long> implements Vol
|
|||
private final SearchBuilder<VolumeVO> storeAndInstallPathSearch;
|
||||
private final SearchBuilder<VolumeVO> volumeIdSearch;
|
||||
protected GenericSearchBuilder<VolumeVO, Long> CountByAccount;
|
||||
protected final SearchBuilder<VolumeVO> ExternalUuidSearch;
|
||||
protected GenericSearchBuilder<VolumeVO, SumCount> primaryStorageSearch;
|
||||
protected GenericSearchBuilder<VolumeVO, SumCount> primaryStorageSearch2;
|
||||
protected GenericSearchBuilder<VolumeVO, SumCount> secondaryStorageSearch;
|
||||
|
|
@ -459,6 +460,10 @@ public class VolumeDaoImpl extends GenericDaoBase<VolumeVO, Long> implements Vol
|
|||
CountByAccount.and("idNIN", CountByAccount.entity().getId(), Op.NIN);
|
||||
CountByAccount.done();
|
||||
|
||||
ExternalUuidSearch = createSearchBuilder();
|
||||
ExternalUuidSearch.and("externalUuid", ExternalUuidSearch.entity().getExternalUuid(), Op.EQ);
|
||||
ExternalUuidSearch.done();
|
||||
|
||||
primaryStorageSearch = createSearchBuilder(SumCount.class);
|
||||
primaryStorageSearch.select("sum", Func.SUM, primaryStorageSearch.entity().getSize());
|
||||
primaryStorageSearch.and("accountId", primaryStorageSearch.entity().getAccountId(), Op.EQ);
|
||||
|
|
@ -934,4 +939,11 @@ public class VolumeDaoImpl extends GenericDaoBase<VolumeVO, Long> implements Vol
|
|||
sc.and(sc.entity().getState(), SearchCriteria.Op.IN, (Object[]) states);
|
||||
return sc.find();
|
||||
}
|
||||
|
||||
@Override
|
||||
public VolumeVO findByExternalUuid(String externalUuid) {
|
||||
SearchCriteria<VolumeVO> sc = ExternalUuidSearch.create();
|
||||
sc.setParameters("externalUuid", externalUuid);
|
||||
return findOneBy(sc);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,6 +16,14 @@
|
|||
// under the License.
|
||||
package com.cloud.upgrade.dao;
|
||||
|
||||
import org.apache.cloudstack.vm.UnmanagedVMsManager;
|
||||
|
||||
import java.sql.Connection;
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.ResultSet;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class Upgrade42200to42210 extends DbUpgradeAbstractImpl implements DbUpgrade, DbUpgradeSystemVmTemplate {
|
||||
|
||||
@Override
|
||||
|
|
@ -27,4 +35,47 @@ public class Upgrade42200to42210 extends DbUpgradeAbstractImpl implements DbUpgr
|
|||
public String getUpgradedVersion() {
|
||||
return "4.22.1.0";
|
||||
}
|
||||
|
||||
@Override
|
||||
public void performDataMigration(Connection conn) {
|
||||
removeDuplicateKVMImportTemplates(conn);
|
||||
}
|
||||
|
||||
private void removeDuplicateKVMImportTemplates(Connection conn) {
|
||||
List<Long> templateIds = new ArrayList<>();
|
||||
try (PreparedStatement selectStmt = conn.prepareStatement(String.format("SELECT id FROM cloud.vm_template WHERE name='%s' ORDER BY id ASC", UnmanagedVMsManager.KVM_VM_IMPORT_DEFAULT_TEMPLATE_NAME))) {
|
||||
ResultSet rs = selectStmt.executeQuery();
|
||||
while (rs.next()) {
|
||||
templateIds.add(rs.getLong(1));
|
||||
}
|
||||
|
||||
if (templateIds.size() <= 1) {
|
||||
return;
|
||||
}
|
||||
|
||||
logger.info("Removing duplicate template " + UnmanagedVMsManager.KVM_VM_IMPORT_DEFAULT_TEMPLATE_NAME + " entries");
|
||||
Long firstTemplateId = templateIds.get(0);
|
||||
|
||||
String updateTemplateSql = "UPDATE cloud.vm_instance SET vm_template_id = ? WHERE vm_template_id = ?";
|
||||
String deleteTemplateSql = "DELETE FROM cloud.vm_template WHERE id = ?";
|
||||
|
||||
try (PreparedStatement updateTemplateStmt = conn.prepareStatement(updateTemplateSql);
|
||||
PreparedStatement deleteTemplateStmt = conn.prepareStatement(deleteTemplateSql)) {
|
||||
for (int i = 1; i < templateIds.size(); i++) {
|
||||
Long duplicateTemplateId = templateIds.get(i);
|
||||
|
||||
// Update VM references
|
||||
updateTemplateStmt.setLong(1, firstTemplateId);
|
||||
updateTemplateStmt.setLong(2, duplicateTemplateId);
|
||||
updateTemplateStmt.executeUpdate();
|
||||
|
||||
// Delete duplicate dummy template
|
||||
deleteTemplateStmt.setLong(1, duplicateTemplateId);
|
||||
deleteTemplateStmt.executeUpdate();
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
logger.warn("Failed to remove duplicate template " + UnmanagedVMsManager.KVM_VM_IMPORT_DEFAULT_TEMPLATE_NAME + " entries", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -17,7 +17,12 @@
|
|||
package com.cloud.upgrade.dao;
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.sql.Connection;
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
|
||||
import com.cloud.utils.crypt.DBEncryptionUtil;
|
||||
import com.cloud.utils.exception.CloudRuntimeException;
|
||||
|
||||
public class Upgrade42210to42300 extends DbUpgradeAbstractImpl implements DbUpgrade, DbUpgradeSystemVmTemplate {
|
||||
|
|
@ -42,4 +47,46 @@ public class Upgrade42210to42300 extends DbUpgradeAbstractImpl implements DbUpgr
|
|||
|
||||
return new InputStream[] {script};
|
||||
}
|
||||
|
||||
@Override
|
||||
public void performDataMigration(Connection conn) {
|
||||
unhideJsInterpretationEnabled(conn);
|
||||
}
|
||||
|
||||
protected void unhideJsInterpretationEnabled(Connection conn) {
|
||||
String value = getJsInterpretationEnabled(conn);
|
||||
if (value != null) {
|
||||
updateJsInterpretationEnabledFields(conn, value);
|
||||
}
|
||||
}
|
||||
|
||||
protected String getJsInterpretationEnabled(Connection conn) {
|
||||
String query = "SELECT value FROM cloud.configuration WHERE name = 'js.interpretation.enabled' AND category = 'Hidden';";
|
||||
|
||||
try (PreparedStatement pstmt = conn.prepareStatement(query)) {
|
||||
ResultSet rs = pstmt.executeQuery();
|
||||
if (rs.next()) {
|
||||
return rs.getString("value");
|
||||
}
|
||||
logger.debug("Unable to retrieve value of hidden configuration 'js.interpretation.enabled'. The configuration may already be unhidden.");
|
||||
return null;
|
||||
} catch (SQLException e) {
|
||||
throw new CloudRuntimeException("Error while retrieving value of hidden configuration 'js.interpretation.enabled'.", e);
|
||||
}
|
||||
}
|
||||
|
||||
protected void updateJsInterpretationEnabledFields(Connection conn, String encryptedValue) {
|
||||
String query = "UPDATE cloud.configuration SET value = ?, category = 'System', component = 'JsInterpreter', is_dynamic = 1 WHERE name = 'js.interpretation.enabled';";
|
||||
|
||||
try (PreparedStatement pstmt = conn.prepareStatement(query)) {
|
||||
String decryptedValue = DBEncryptionUtil.decrypt(encryptedValue);
|
||||
logger.info("Updating setting 'js.interpretation.enabled' to decrypted value [{}], category 'System', component 'JsInterpreter', and is_dynamic '1'.", decryptedValue);
|
||||
pstmt.setString(1, decryptedValue);
|
||||
pstmt.executeUpdate();
|
||||
} catch (SQLException e) {
|
||||
throw new CloudRuntimeException("Error while unhiding configuration 'js.interpretation.enabled'.", e);
|
||||
} catch (CloudRuntimeException e) {
|
||||
logger.warn("Error while decrypting configuration 'js.interpretation.enabled'. The configuration may already be decrypted.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -131,6 +131,9 @@ public class NicVO implements Nic {
|
|||
@Column(name = "mtu")
|
||||
Integer mtu;
|
||||
|
||||
@Column(name = "enabled")
|
||||
boolean enabled;
|
||||
|
||||
@Transient
|
||||
transient String nsxLogicalSwitchUuid;
|
||||
|
||||
|
|
@ -143,6 +146,7 @@ public class NicVO implements Nic {
|
|||
this.networkId = configurationId;
|
||||
this.state = State.Allocated;
|
||||
this.vmType = vmType;
|
||||
this.enabled = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -397,6 +401,14 @@ public class NicVO implements Nic {
|
|||
this.nsxLogicalSwitchPortUuid = nsxLogicalSwitchPortUuid;
|
||||
}
|
||||
|
||||
public boolean isEnabled() {
|
||||
return enabled;
|
||||
}
|
||||
|
||||
public void setEnabled(boolean enabled) {
|
||||
this.enabled = enabled;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return new HashCodeBuilder(17, 31).append(id).toHashCode();
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@ import java.util.Date;
|
|||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import com.cloud.hypervisor.Hypervisor;
|
||||
import com.cloud.utils.Pair;
|
||||
|
|
@ -192,4 +193,8 @@ public interface VMInstanceDao extends GenericDao<VMInstanceVO, Long>, StateDao<
|
|||
int getVmCountByOfferingNotInDomain(Long serviceOfferingId, List<Long> domainIds);
|
||||
|
||||
List<VMInstanceVO> listByIdsIncludingRemoved(List<Long> ids);
|
||||
|
||||
List<VMInstanceVO> listDeleteProtectedVmsByAccountId(long accountId);
|
||||
|
||||
List<VMInstanceVO> listDeleteProtectedVmsByDomainIds(Set<Long> domainIds);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -25,11 +25,13 @@ import java.util.Date;
|
|||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import javax.annotation.PostConstruct;
|
||||
import javax.inject.Inject;
|
||||
|
||||
import org.apache.cloudstack.api.ApiConstants;
|
||||
import org.apache.commons.collections.CollectionUtils;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
|
|
@ -106,6 +108,8 @@ public class VMInstanceDaoImpl extends GenericDaoBase<VMInstanceVO, Long> implem
|
|||
protected SearchBuilder<VMInstanceVO> IdsPowerStateSelectSearch;
|
||||
GenericSearchBuilder<VMInstanceVO, Integer> CountByOfferingId;
|
||||
GenericSearchBuilder<VMInstanceVO, Integer> CountUserVmNotInDomain;
|
||||
SearchBuilder<VMInstanceVO> DeleteProtectedVmSearchByAccount;
|
||||
SearchBuilder<VMInstanceVO> DeleteProtectedVmSearchByDomainIds;
|
||||
|
||||
@Inject
|
||||
ResourceTagDao tagsDao;
|
||||
|
|
@ -368,6 +372,19 @@ public class VMInstanceDaoImpl extends GenericDaoBase<VMInstanceVO, Long> implem
|
|||
CountUserVmNotInDomain.and("domainIdsNotIn", CountUserVmNotInDomain.entity().getDomainId(), Op.NIN);
|
||||
CountUserVmNotInDomain.done();
|
||||
|
||||
DeleteProtectedVmSearchByAccount = createSearchBuilder();
|
||||
DeleteProtectedVmSearchByAccount.selectFields(DeleteProtectedVmSearchByAccount.entity().getUuid());
|
||||
DeleteProtectedVmSearchByAccount.and(ApiConstants.ACCOUNT_ID, DeleteProtectedVmSearchByAccount.entity().getAccountId(), Op.EQ);
|
||||
DeleteProtectedVmSearchByAccount.and(ApiConstants.DELETE_PROTECTION, DeleteProtectedVmSearchByAccount.entity().isDeleteProtection(), Op.EQ);
|
||||
DeleteProtectedVmSearchByAccount.and(ApiConstants.REMOVED, DeleteProtectedVmSearchByAccount.entity().getRemoved(), Op.NULL);
|
||||
DeleteProtectedVmSearchByAccount.done();
|
||||
|
||||
DeleteProtectedVmSearchByDomainIds = createSearchBuilder();
|
||||
DeleteProtectedVmSearchByDomainIds.selectFields(DeleteProtectedVmSearchByDomainIds.entity().getUuid());
|
||||
DeleteProtectedVmSearchByDomainIds.and(ApiConstants.DOMAIN_IDS, DeleteProtectedVmSearchByDomainIds.entity().getDomainId(), Op.IN);
|
||||
DeleteProtectedVmSearchByDomainIds.and(ApiConstants.DELETE_PROTECTION, DeleteProtectedVmSearchByDomainIds.entity().isDeleteProtection(), Op.EQ);
|
||||
DeleteProtectedVmSearchByDomainIds.and(ApiConstants.REMOVED, DeleteProtectedVmSearchByDomainIds.entity().getRemoved(), Op.NULL);
|
||||
DeleteProtectedVmSearchByDomainIds.done();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -1296,4 +1313,22 @@ public class VMInstanceDaoImpl extends GenericDaoBase<VMInstanceVO, Long> implem
|
|||
sc.setParameters("ids", ids.toArray());
|
||||
return listIncludingRemovedBy(sc);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<VMInstanceVO> listDeleteProtectedVmsByAccountId(long accountId) {
|
||||
SearchCriteria<VMInstanceVO> sc = DeleteProtectedVmSearchByAccount.create();
|
||||
sc.setParameters(ApiConstants.ACCOUNT_ID, accountId);
|
||||
sc.setParameters(ApiConstants.DELETE_PROTECTION, true);
|
||||
Filter filter = new Filter(VMInstanceVO.class, null, false, 0L, 10L);
|
||||
return listBy(sc, filter);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<VMInstanceVO> listDeleteProtectedVmsByDomainIds(Set<Long> domainIds) {
|
||||
SearchCriteria<VMInstanceVO> sc = DeleteProtectedVmSearchByDomainIds.create();
|
||||
sc.setParameters(ApiConstants.DOMAIN_IDS, domainIds.toArray());
|
||||
sc.setParameters(ApiConstants.DELETE_PROTECTION, true);
|
||||
Filter filter = new Filter(VMInstanceVO.class, null, false, 0L, 10L);
|
||||
return listBy(sc, filter);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -21,20 +21,14 @@ import java.util.Date;
|
|||
import java.util.List;
|
||||
|
||||
import com.cloud.utils.DateUtil;
|
||||
import org.apache.cloudstack.api.response.BackupScheduleResponse;
|
||||
import org.apache.cloudstack.backup.BackupSchedule;
|
||||
import org.apache.cloudstack.backup.BackupScheduleVO;
|
||||
|
||||
import com.cloud.utils.db.GenericDao;
|
||||
|
||||
public interface BackupScheduleDao extends GenericDao<BackupScheduleVO, Long> {
|
||||
BackupScheduleVO findByVM(Long vmId);
|
||||
|
||||
List<BackupScheduleVO> listByVM(Long vmId);
|
||||
|
||||
BackupScheduleVO findByVMAndIntervalType(Long vmId, DateUtil.IntervalType intervalType);
|
||||
|
||||
List<BackupScheduleVO> getSchedulesToExecute(Date currentTimestamp);
|
||||
|
||||
BackupScheduleResponse newBackupScheduleResponse(BackupSchedule schedule);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -17,28 +17,23 @@
|
|||
|
||||
package org.apache.cloudstack.backup.dao;
|
||||
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.SQLException;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
import javax.annotation.PostConstruct;
|
||||
import javax.inject.Inject;
|
||||
|
||||
import com.cloud.utils.DateUtil;
|
||||
import org.apache.cloudstack.api.response.BackupScheduleResponse;
|
||||
import org.apache.cloudstack.backup.BackupSchedule;
|
||||
import com.cloud.utils.db.DB;
|
||||
import com.cloud.utils.db.TransactionLegacy;
|
||||
import org.apache.cloudstack.backup.BackupScheduleVO;
|
||||
|
||||
import com.cloud.utils.db.GenericDaoBase;
|
||||
import com.cloud.utils.db.SearchBuilder;
|
||||
import com.cloud.utils.db.SearchCriteria;
|
||||
import com.cloud.vm.VMInstanceVO;
|
||||
import com.cloud.vm.dao.VMInstanceDao;
|
||||
|
||||
public class BackupScheduleDaoImpl extends GenericDaoBase<BackupScheduleVO, Long> implements BackupScheduleDao {
|
||||
|
||||
@Inject
|
||||
VMInstanceDao vmInstanceDao;
|
||||
|
||||
private SearchBuilder<BackupScheduleVO> backupScheduleSearch;
|
||||
private SearchBuilder<BackupScheduleVO> executableSchedulesSearch;
|
||||
|
||||
|
|
@ -59,13 +54,6 @@ public class BackupScheduleDaoImpl extends GenericDaoBase<BackupScheduleVO, Long
|
|||
executableSchedulesSearch.done();
|
||||
}
|
||||
|
||||
@Override
|
||||
public BackupScheduleVO findByVM(Long vmId) {
|
||||
SearchCriteria<BackupScheduleVO> sc = backupScheduleSearch.create();
|
||||
sc.setParameters("vm_id", vmId);
|
||||
return findOneBy(sc);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<BackupScheduleVO> listByVM(Long vmId) {
|
||||
SearchCriteria<BackupScheduleVO> sc = backupScheduleSearch.create();
|
||||
|
|
@ -88,21 +76,19 @@ public class BackupScheduleDaoImpl extends GenericDaoBase<BackupScheduleVO, Long
|
|||
return listBy(sc);
|
||||
}
|
||||
|
||||
@DB
|
||||
@Override
|
||||
public BackupScheduleResponse newBackupScheduleResponse(BackupSchedule schedule) {
|
||||
VMInstanceVO vm = vmInstanceDao.findByIdIncludingRemoved(schedule.getVmId());
|
||||
BackupScheduleResponse response = new BackupScheduleResponse();
|
||||
response.setId(schedule.getUuid());
|
||||
response.setVmId(vm.getUuid());
|
||||
response.setVmName(vm.getHostName());
|
||||
response.setIntervalType(schedule.getScheduleType());
|
||||
response.setSchedule(schedule.getSchedule());
|
||||
response.setTimezone(schedule.getTimezone());
|
||||
response.setMaxBackups(schedule.getMaxBackups());
|
||||
if (schedule.getQuiesceVM() != null) {
|
||||
response.setQuiesceVM(schedule.getQuiesceVM());
|
||||
public boolean remove(Long id) {
|
||||
String sql = "UPDATE backups SET backup_schedule_id = NULL WHERE backup_schedule_id = ?";
|
||||
TransactionLegacy transaction = TransactionLegacy.currentTxn();
|
||||
try {
|
||||
PreparedStatement preparedStatement = transaction.prepareAutoCloseStatement(sql);
|
||||
preparedStatement.setLong(1, id);
|
||||
preparedStatement.executeUpdate();
|
||||
return super.remove(id);
|
||||
} catch (SQLException e) {
|
||||
logger.warn("Unable to clean up backup schedules references from the backups table.", e);
|
||||
return false;
|
||||
}
|
||||
response.setObjectName("backupschedule");
|
||||
return response;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -51,6 +51,8 @@ StateDao<ObjectInDataStoreStateMachine.State, ObjectInDataStoreStateMachine.Even
|
|||
|
||||
SnapshotDataStoreVO findBySnapshotIdAndDataStoreRoleAndState(long snapshotId, DataStoreRole role, ObjectInDataStoreStateMachine.State state);
|
||||
|
||||
List<SnapshotDataStoreVO> listBySnapshotIdAndDataStoreRoleAndStateIn(long snapshotId, DataStoreRole role, ObjectInDataStoreStateMachine.State... state);
|
||||
|
||||
List<SnapshotDataStoreVO> listReadyByVolumeIdAndCheckpointPathNotNull(long volumeId);
|
||||
|
||||
SnapshotDataStoreVO findOneBySnapshotId(long snapshotId, long zoneId);
|
||||
|
|
|
|||
|
|
@ -67,7 +67,8 @@ public class SnapshotDataStoreDaoImpl extends GenericDaoBase<SnapshotDataStoreVO
|
|||
private SearchBuilder<SnapshotDataStoreVO> searchFilteringStoreIdEqStoreRoleEqStateNeqRefCntNeq;
|
||||
protected SearchBuilder<SnapshotDataStoreVO> searchFilteringStoreIdEqStateEqStoreRoleEqIdEqUpdateCountEqSnapshotIdEqVolumeIdEq;
|
||||
private SearchBuilder<SnapshotDataStoreVO> stateSearch;
|
||||
private SearchBuilder<SnapshotDataStoreVO> idStateNeqSearch;
|
||||
private SearchBuilder<SnapshotDataStoreVO> idStateNinSearch;
|
||||
private SearchBuilder<SnapshotDataStoreVO> idEqRoleEqStateInSearch;
|
||||
protected SearchBuilder<SnapshotVO> snapshotVOSearch;
|
||||
private SearchBuilder<SnapshotDataStoreVO> snapshotCreatedSearch;
|
||||
private SearchBuilder<SnapshotDataStoreVO> dataStoreAndInstallPathSearch;
|
||||
|
|
@ -146,10 +147,15 @@ public class SnapshotDataStoreDaoImpl extends GenericDaoBase<SnapshotDataStoreVO
|
|||
stateSearch.done();
|
||||
|
||||
|
||||
idStateNeqSearch = createSearchBuilder();
|
||||
idStateNeqSearch.and(SNAPSHOT_ID, idStateNeqSearch.entity().getSnapshotId(), SearchCriteria.Op.EQ);
|
||||
idStateNeqSearch.and(STATE, idStateNeqSearch.entity().getState(), SearchCriteria.Op.NEQ);
|
||||
idStateNeqSearch.done();
|
||||
idStateNinSearch = createSearchBuilder();
|
||||
idStateNinSearch.and(SNAPSHOT_ID, idStateNinSearch.entity().getSnapshotId(), SearchCriteria.Op.EQ);
|
||||
idStateNinSearch.and(STATE, idStateNinSearch.entity().getState(), SearchCriteria.Op.NOTIN);
|
||||
idStateNinSearch.done();
|
||||
|
||||
idEqRoleEqStateInSearch = createSearchBuilder();
|
||||
idEqRoleEqStateInSearch.and(SNAPSHOT_ID, idEqRoleEqStateInSearch.entity().getSnapshotId(), SearchCriteria.Op.EQ);
|
||||
idEqRoleEqStateInSearch.and(STORE_ROLE, idEqRoleEqStateInSearch.entity().getRole(), SearchCriteria.Op.EQ);
|
||||
idEqRoleEqStateInSearch.and(STATE, idEqRoleEqStateInSearch.entity().getState(), SearchCriteria.Op.IN);
|
||||
|
||||
snapshotVOSearch = snapshotDao.createSearchBuilder();
|
||||
snapshotVOSearch.and(VOLUME_ID, snapshotVOSearch.entity().getVolumeId(), SearchCriteria.Op.EQ);
|
||||
|
|
@ -387,6 +393,15 @@ public class SnapshotDataStoreDaoImpl extends GenericDaoBase<SnapshotDataStoreVO
|
|||
return findOneBy(sc);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<SnapshotDataStoreVO> listBySnapshotIdAndDataStoreRoleAndStateIn(long snapshotId, DataStoreRole role, State... state) {
|
||||
SearchCriteria<SnapshotDataStoreVO> sc = idEqRoleEqStateInSearch.create();
|
||||
sc.setParameters(SNAPSHOT_ID, snapshotId);
|
||||
sc.setParameters(STORE_ROLE, role);
|
||||
sc.setParameters(STATE, (Object[])state);
|
||||
return listBy(sc);
|
||||
}
|
||||
|
||||
@Override
|
||||
public SnapshotDataStoreVO findOneBySnapshotId(long snapshotId, long zoneId) {
|
||||
try (TransactionLegacy transactionLegacy = TransactionLegacy.currentTxn()) {
|
||||
|
|
@ -480,7 +495,7 @@ public class SnapshotDataStoreDaoImpl extends GenericDaoBase<SnapshotDataStoreVO
|
|||
|
||||
@Override
|
||||
public List<SnapshotDataStoreVO> findBySnapshotIdWithNonDestroyedState(long snapshotId) {
|
||||
SearchCriteria<SnapshotDataStoreVO> sc = idStateNeqSearch.create();
|
||||
SearchCriteria<SnapshotDataStoreVO> sc = idStateNinSearch.create();
|
||||
sc.setParameters(SNAPSHOT_ID, snapshotId);
|
||||
sc.setParameters(STATE, State.Destroyed.name());
|
||||
return listBy(sc);
|
||||
|
|
@ -488,7 +503,7 @@ public class SnapshotDataStoreDaoImpl extends GenericDaoBase<SnapshotDataStoreVO
|
|||
|
||||
@Override
|
||||
public List<SnapshotDataStoreVO> findBySnapshotIdAndNotInDestroyedHiddenState(long snapshotId) {
|
||||
SearchCriteria<SnapshotDataStoreVO> sc = idStateNeqSearch.create();
|
||||
SearchCriteria<SnapshotDataStoreVO> sc = idStateNinSearch.create();
|
||||
sc.setParameters(SNAPSHOT_ID, snapshotId);
|
||||
sc.setParameters(STATE, State.Destroyed.name(), State.Hidden.name());
|
||||
return listBy(sc);
|
||||
|
|
|
|||
|
|
@ -687,22 +687,23 @@ CREATE TABLE IF NOT EXISTS `cloud`.`backup_details` (
|
|||
UPDATE `cloud`.`backups` b
|
||||
INNER JOIN `cloud`.`vm_instance` vm ON b.vm_id = vm.id
|
||||
SET b.backed_volumes = (
|
||||
SELECT CONCAT("[",
|
||||
GROUP_CONCAT(
|
||||
CONCAT(
|
||||
"{\"uuid\":\"", v.uuid, "\",",
|
||||
"\"type\":\"", v.volume_type, "\",",
|
||||
"\"size\":", v.`size`, ",",
|
||||
"\"path\":\"", IFNULL(v.path, 'null'), "\",",
|
||||
"\"deviceId\":", IFNULL(v.device_id, 'null'), ",",
|
||||
"\"diskOfferingId\":\"", doff.uuid, "\",",
|
||||
"\"minIops\":", IFNULL(v.min_iops, 'null'), ",",
|
||||
"\"maxIops\":", IFNULL(v.max_iops, 'null'),
|
||||
"}"
|
||||
)
|
||||
SEPARATOR ","
|
||||
SELECT COALESCE(
|
||||
CAST(
|
||||
JSON_ARRAYAGG(
|
||||
JSON_OBJECT(
|
||||
'uuid', v.uuid,
|
||||
'type', v.volume_type,
|
||||
'size', v.size,
|
||||
'path', v.path,
|
||||
'deviceId', v.device_id,
|
||||
'diskOfferingId', doff.uuid,
|
||||
'minIops', v.min_iops,
|
||||
'maxIops', v.max_iops
|
||||
)
|
||||
) AS CHAR
|
||||
),
|
||||
"]")
|
||||
'[]'
|
||||
)
|
||||
FROM `cloud`.`volumes` v
|
||||
LEFT JOIN `cloud`.`disk_offering` doff ON v.disk_offering_id = doff.id
|
||||
WHERE v.instance_id = vm.id
|
||||
|
|
@ -711,22 +712,23 @@ SET b.backed_volumes = (
|
|||
-- Add diskOfferingId, deviceId, minIops and maxIops to backup_volumes in vm_instance table
|
||||
UPDATE `cloud`.`vm_instance` vm
|
||||
SET vm.backup_volumes = (
|
||||
SELECT CONCAT("[",
|
||||
GROUP_CONCAT(
|
||||
CONCAT(
|
||||
"{\"uuid\":\"", v.uuid, "\",",
|
||||
"\"type\":\"", v.volume_type, "\",",
|
||||
"\"size\":", v.`size`, ",",
|
||||
"\"path\":\"", IFNULL(v.path, 'null'), "\",",
|
||||
"\"deviceId\":", IFNULL(v.device_id, 'null'), ",",
|
||||
"\"diskOfferingId\":\"", doff.uuid, "\",",
|
||||
"\"minIops\":", IFNULL(v.min_iops, 'null'), ",",
|
||||
"\"maxIops\":", IFNULL(v.max_iops, 'null'),
|
||||
"}"
|
||||
)
|
||||
SEPARATOR ","
|
||||
SELECT COALESCE(
|
||||
CAST(
|
||||
JSON_ARRAYAGG(
|
||||
JSON_OBJECT(
|
||||
'uuid', v.uuid,
|
||||
'type', v.volume_type,
|
||||
'size', v.size,
|
||||
'path', v.path,
|
||||
'deviceId', v.device_id,
|
||||
'diskOfferingId', doff.uuid,
|
||||
'minIops', v.min_iops,
|
||||
'maxIops', v.max_iops
|
||||
)
|
||||
) AS CHAR
|
||||
),
|
||||
"]")
|
||||
'[]'
|
||||
)
|
||||
FROM `cloud`.`volumes` v
|
||||
LEFT JOIN `cloud`.`disk_offering` doff ON v.disk_offering_id = doff.id
|
||||
WHERE v.instance_id = vm.id
|
||||
|
|
|
|||
|
|
@ -33,3 +33,23 @@ UPDATE `cloud`.`alert` SET type = 34 WHERE name = 'ALERT.VR.PRIVATE.IFACE.MTU';
|
|||
|
||||
-- Update configuration 'kvm.ssh.to.agent' description and is_dynamic fields
|
||||
UPDATE `cloud`.`configuration` SET description = 'True if the management server will restart the agent service via SSH into the KVM hosts after or during maintenance operations', is_dynamic = 1 WHERE name = 'kvm.ssh.to.agent';
|
||||
|
||||
-- Sanitize legacy network-level addressing fields for Public networks
|
||||
UPDATE `cloud`.`networks`
|
||||
SET `broadcast_uri` = NULL,
|
||||
`gateway` = NULL,
|
||||
`cidr` = NULL,
|
||||
`ip6_gateway` = NULL,
|
||||
`ip6_cidr` = NULL
|
||||
WHERE `traffic_type` = 'Public';
|
||||
|
||||
UPDATE `cloud`.`vm_template` SET guest_os_id = 99 WHERE name = 'kvm-default-vm-import-dummy-template';
|
||||
|
||||
-- Update existing vm_template records with NULL type to "USER"
|
||||
UPDATE `cloud`.`vm_template` SET `type` = 'USER' WHERE `type` IS NULL;
|
||||
|
||||
-- remove unused config item
|
||||
DELETE FROM `cloud`.`configuration` WHERE name = 'consoleproxy.cmd.port';
|
||||
|
||||
-- Drops the unused "backup_interval_type" column of the "cloud.backups" table
|
||||
ALTER TABLE `cloud`.`backups` DROP COLUMN `backup_interval_type`;
|
||||
|
|
|
|||
|
|
@ -115,5 +115,8 @@ CALL `cloud`.`IDEMPOTENT_UPDATE_API_PERMISSION`('Resource Admin', 'deleteUserKey
|
|||
-- Add conserve mode for VPC offerings
|
||||
CALL `cloud`.`IDEMPOTENT_ADD_COLUMN`('cloud.vpc_offerings','conserve_mode', 'tinyint(1) unsigned NULL DEFAULT 0 COMMENT ''True if the VPC offering is IP conserve mode enabled, allowing public IP services to be used across multiple VPC tiers'' ');
|
||||
|
||||
--- Disable/enable NICs
|
||||
CALL `cloud`.`IDEMPOTENT_ADD_COLUMN`('cloud.nics','enabled', 'TINYINT(1) NOT NULL DEFAULT 1 COMMENT ''Indicates whether the NIC is enabled or not'' ');
|
||||
|
||||
-- Add description for secondary IP addresses
|
||||
CALL `cloud`.`IDEMPOTENT_ADD_COLUMN`('cloud.nic_secondary_ips','description', 'varchar(2048) DEFAULT NULL');
|
||||
|
|
@ -76,6 +76,7 @@ select
|
|||
nics.broadcast_uri broadcast_uri,
|
||||
nics.isolation_uri isolation_uri,
|
||||
nics.mtu mtu,
|
||||
nics.enabled is_nic_enabled,
|
||||
vpc.id vpc_id,
|
||||
vpc.uuid vpc_uuid,
|
||||
vpc.name vpc_name,
|
||||
|
|
|
|||
|
|
@ -79,6 +79,7 @@ SELECT
|
|||
`vm_template`.`format` AS `template_format`,
|
||||
`vm_template`.`display_text` AS `template_display_text`,
|
||||
`vm_template`.`enable_password` AS `password_enabled`,
|
||||
`vm_template`.`extension_id` AS `template_extension_id`,
|
||||
`iso`.`id` AS `iso_id`,
|
||||
`iso`.`uuid` AS `iso_uuid`,
|
||||
`iso`.`name` AS `iso_name`,
|
||||
|
|
@ -141,6 +142,7 @@ SELECT
|
|||
`nics`.`mac_address` AS `mac_address`,
|
||||
`nics`.`broadcast_uri` AS `broadcast_uri`,
|
||||
`nics`.`isolation_uri` AS `isolation_uri`,
|
||||
`nics`.`enabled` AS `is_nic_enabled`,
|
||||
`vpc`.`id` AS `vpc_id`,
|
||||
`vpc`.`uuid` AS `vpc_uuid`,
|
||||
`networks`.`uuid` AS `network_uuid`,
|
||||
|
|
|
|||
|
|
@ -0,0 +1,48 @@
|
|||
-- 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.
|
||||
|
||||
-- cloud_usage.quota_summary_view source
|
||||
|
||||
-- Create view for quota summary
|
||||
DROP VIEW IF EXISTS `cloud_usage`.`quota_summary_view`;
|
||||
CREATE VIEW `cloud_usage`.`quota_summary_view` AS
|
||||
SELECT
|
||||
cloud_usage.quota_account.account_id AS account_id,
|
||||
cloud_usage.quota_account.quota_balance AS quota_balance,
|
||||
cloud_usage.quota_account.quota_balance_date AS quota_balance_date,
|
||||
cloud_usage.quota_account.quota_enforce AS quota_enforce,
|
||||
cloud_usage.quota_account.quota_min_balance AS quota_min_balance,
|
||||
cloud_usage.quota_account.quota_alert_date AS quota_alert_date,
|
||||
cloud_usage.quota_account.quota_alert_type AS quota_alert_type,
|
||||
cloud_usage.quota_account.last_statement_date AS last_statement_date,
|
||||
cloud.account.uuid AS account_uuid,
|
||||
cloud.account.account_name AS account_name,
|
||||
cloud.account.state AS account_state,
|
||||
cloud.account.removed AS account_removed,
|
||||
cloud.domain.id AS domain_id,
|
||||
cloud.domain.uuid AS domain_uuid,
|
||||
cloud.domain.name AS domain_name,
|
||||
cloud.domain.path AS domain_path,
|
||||
cloud.domain.removed AS domain_removed,
|
||||
cloud.projects.uuid AS project_uuid,
|
||||
cloud.projects.name AS project_name,
|
||||
cloud.projects.removed AS project_removed
|
||||
FROM
|
||||
cloud_usage.quota_account
|
||||
INNER JOIN cloud.account ON (cloud.account.id = cloud_usage.quota_account.account_id)
|
||||
INNER JOIN cloud.domain ON (cloud.domain.id = cloud.account.domain_id)
|
||||
LEFT JOIN cloud.projects ON (cloud.account.type = 5 AND cloud.account.id = cloud.projects.project_account_id);
|
||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue