Merge release branch 4.22 to main

* 4.22:
      VM Deployment using snapshot in new zone (#13178)
      Change exception treatment on incremental snapshot wait (#12665)
      Move checkRoleEscalation outside DB transaction in createAccount (#13044)
      Fix/flasharray delete rename destroy patch conflict (#13049)
      Fix VPC network offerings listing in isolated network creation form (#12645)
      systemvm: accept ipv6 established/related return traffic (#13173)
      update debian change log
      Updating pom.xml version numbers for release 4.22.2.0-SNAPSHOT
      Updating pom.xml version numbers for release 4.22.1.0
      Update suse15 packaging spec, use qemu-ovmf-x86_64 package instead of edk2-ovmf for agent (#13133)
      Change disk-only VM snapshot removal message (#11182)
      Update mysql java connector version to 8.4.0 (matching version for MySQL 8.4) (#12640)
      adaptive: honor user-provided capacityBytes when provider stats are unavailable (#13059)
      Flexibilize public IP selection (#11076)
This commit is contained in:
Fabricio Duarte 2026-05-22 10:30:01 -03:00
commit 67b849f3ef
35 changed files with 1428 additions and 386 deletions

View File

@ -283,7 +283,7 @@ jobs:
# https://github.com/actions/runner-images/blob/main/images/linux/Ubuntu2004-Readme.md#mysql
sudo apt-get install -y mysql-server
sudo systemctl start mysql
sudo mysql -uroot -proot -e "ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY ''; FLUSH PRIVILEGES;"
sudo mysql -uroot -proot -e "ALTER USER 'root'@'localhost' IDENTIFIED WITH caching_sha2_password BY ''; FLUSH PRIVILEGES;"
sudo systemctl restart mysql
sudo mysql -uroot -e "SELECT VERSION();"

18
debian/changelog vendored
View File

@ -2,14 +2,20 @@ cloudstack (4.23.0.0-SNAPSHOT) unstable; urgency=low
* Update the version to 4.23.0.0-SNAPSHOT
-- the Apache CloudStack project <dev@cloudstack.apache.org> Fri, 22 May 2026 10:20:00 -0300
cloudstack (4.22.1.0) unstable; urgency=low
* Update the version to 4.22.1.0
-- the Apache CloudStack project <dev@cloudstack.apache.org> Mon, 11 May 2026 20:26:07 +0530
cloudstack (4.22.0.0) unstable; urgency=low
* Update the version to 4.22.0.0
-- the Apache CloudStack project <dev@cloudstack.apache.org> Thu, 30 Oct 2025 19:23:55 +0530
cloudstack (4.23.0.0-SNAPSHOT-SNAPSHOT) unstable; urgency=low
* Update the version to 4.23.0.0-SNAPSHOT-SNAPSHOT
-- the Apache CloudStack project <dev@cloudstack.apache.org> Thu, Aug 28 11:58:36 2025 +0530
cloudstack (4.21.0.0) unstable; urgency=low
* Update the version to 4.21.0.0

View File

@ -19,9 +19,21 @@ package com.cloud.network.dao;
import com.cloud.network.vo.PublicIpQuarantineVO;
import com.cloud.utils.db.GenericDao;
import java.util.Date;
import java.util.List;
public interface PublicIpQuarantineDao extends GenericDao<PublicIpQuarantineVO, Long> {
PublicIpQuarantineVO findByPublicIpAddressId(long publicIpAddressId);
PublicIpQuarantineVO findByIpAddress(String publicIpAddress);
/**
* Returns a list of public IP addresses that are actively quarantined at the specified date and the previous owner differs from the specified user.
*
* @param userId used to check against the IP's previous owner;
* @param date used to check if the quarantine is active;
* @return a list of PublicIpQuarantineVOs.
*/
List<PublicIpQuarantineVO> listQuarantinedIpAddressesToUser(Long userId, Date date);
}

View File

@ -26,6 +26,8 @@ import org.springframework.stereotype.Component;
import javax.annotation.PostConstruct;
import javax.inject.Inject;
import java.util.Date;
import java.util.List;
@Component
public class PublicIpQuarantineDaoImpl extends GenericDaoBase<PublicIpQuarantineVO, Long> implements PublicIpQuarantineDao {
@ -33,6 +35,8 @@ public class PublicIpQuarantineDaoImpl extends GenericDaoBase<PublicIpQuarantine
private SearchBuilder<IPAddressVO> ipAddressSearchBuilder;
private SearchBuilder<PublicIpQuarantineVO> quarantinedIpAddressesSearch;
@Inject
IPAddressDao ipAddressDao;
@ -47,8 +51,16 @@ public class PublicIpQuarantineDaoImpl extends GenericDaoBase<PublicIpQuarantine
publicIpAddressByIdSearch.join("quarantineJoin", ipAddressSearchBuilder, ipAddressSearchBuilder.entity().getId(),
publicIpAddressByIdSearch.entity().getPublicIpAddressId(), JoinBuilder.JoinType.INNER);
quarantinedIpAddressesSearch = createSearchBuilder();
quarantinedIpAddressesSearch.and("previousOwnerId", quarantinedIpAddressesSearch.entity().getPreviousOwnerId(), SearchCriteria.Op.NEQ);
quarantinedIpAddressesSearch.and();
quarantinedIpAddressesSearch.op("removedIsNull", quarantinedIpAddressesSearch.entity().getRemoved(), SearchCriteria.Op.NULL);
quarantinedIpAddressesSearch.and("endDate", quarantinedIpAddressesSearch.entity().getEndDate(), SearchCriteria.Op.GT);
quarantinedIpAddressesSearch.cp();
ipAddressSearchBuilder.done();
publicIpAddressByIdSearch.done();
quarantinedIpAddressesSearch.done();
}
@Override
@ -68,4 +80,14 @@ public class PublicIpQuarantineDaoImpl extends GenericDaoBase<PublicIpQuarantine
return findOneBy(sc, filter);
}
@Override
public List<PublicIpQuarantineVO> listQuarantinedIpAddressesToUser(Long userId, Date date) {
SearchCriteria<PublicIpQuarantineVO> sc = quarantinedIpAddressesSearch.create();
sc.setParameters("previousOwnerId", userId);
sc.setParameters("endDate", date);
return searchIncludingRemoved(sc, null, false, false);
}
}

View File

@ -117,7 +117,7 @@ Requires: ipset
Requires: perl
Requires: rsync
Requires: cifs-utils
Requires: edk2-ovmf
Requires: (edk2-ovmf or qemu-ovmf-x86_64)
Requires: swtpm
Requires: (python3-libvirt or python3-libvirt-python)
Requires: (qemu-img or qemu-tools)

View File

@ -1 +0,0 @@
el8

View File

@ -0,0 +1 @@
../el8/cloud-ipallocator.rc

View File

@ -0,0 +1 @@
../el8/cloud.limits

750
packaging/suse15/cloud.spec Normal file
View File

@ -0,0 +1,750 @@
# 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.
%define __os_install_post %{nil}
%global debug_package %{nil}
%global __requires_exclude libc\\.so\\..*|libc\\.so\\.6\\(GLIBC_.*\\)
%define _binaries_in_noarch_packages_terminate_build 0
# DISABLE the post-percentinstall java repacking and line number stripping
# we need to find a way to just disable the java repacking and line number stripping, but not the autodeps
Name: cloudstack
Summary: CloudStack IaaS Platform
#http://fedoraproject.org/wiki/PackageNamingGuidelines#Pre-Release_packages
%define _maventag %{_fullver}
Release: %{_rel}
Version: %{_ver}
License: ASL 2.0
Vendor: Apache CloudStack <dev@cloudstack.apache.org>
Packager: Apache CloudStack <dev@cloudstack.apache.org>
Group: System Environment/Libraries
# FIXME do groups for every single one of the subpackages
Source0: %{name}-%{_maventag}.tgz
BuildRoot: %{_tmppath}/%{name}-%{_maventag}-%{release}-build
BuildArch: noarch
BuildRequires: (java-11-openjdk-devel or java-17-openjdk-devel or java-21-openjdk-devel)
#BuildRequires: ws-commons-util
BuildRequires: jpackage-utils
BuildRequires: gcc
BuildRequires: glibc-devel
BuildRequires: /usr/bin/mkisofs
BuildRequires: python3-setuptools
BuildRequires: wget
BuildRequires: nodejs
%description
CloudStack is a highly-scalable elastic, open source,
intelligent IaaS cloud implementation.
%package management
Summary: CloudStack management server UI
Requires: (java-17-openjdk or java-21-openjdk)
Requires: (tzdata-java or timezone-java)
Requires: python3
Requires: bash
Requires: gawk
Requires: which
Requires: file
Requires: tar
Requires: bzip2
Requires: gzip
Requires: unzip
Requires: (/sbin/mount.nfs or /usr/sbin/mount.nfs)
Requires: (openssh-clients or openssh)
Requires: (nfs-utils or nfs-client)
Requires: iproute
Requires: wget
Requires: (mysql or mariadb or mysql8.4)
Requires: sudo
Requires: /sbin/service
Requires: /sbin/chkconfig
Requires: /usr/bin/ssh-keygen
Requires: (genisoimage or mkisofs or xorrisofs)
Requires: ipmitool
Requires: %{name}-common = %{_ver}
Requires: (iptables-services or iptables)
Requires: rng-tools
Requires: (qemu-img or qemu-tools)
Requires: python3-pip
Requires: python3-six
Requires: python3-protobuf
Requires: python3-setuptools
Requires: (libgcrypt > 1.8.3 or libgcrypt20)
Group: System Environment/Libraries
%description management
The CloudStack management server is the central point of coordination,
management, and intelligence in CloudStack.
%package common
Summary: Apache CloudStack common files and scripts
Requires: python3
Group: System Environment/Libraries
%description common
The Apache CloudStack files shared between agent and management server
%global __requires_exclude libc\\.so\\..*|libc\\.so\\.6\\(GLIBC_.*\\)|^(libuuid\\.so\\.1|/usr/bin/python)$
%package agent
Summary: CloudStack Agent for KVM hypervisors
Requires: (openssh-clients or openssh)
Requires: (java-17-openjdk or java-21-openjdk)
Requires: (tzdata-java or timezone-java)
Requires: %{name}-common = %{_ver}
Requires: libvirt
Requires: libvirt-daemon-driver-storage-rbd
Requires: ebtables
Requires: iptables
Requires: ethtool
Requires: (net-tools or net-tools-deprecated)
Requires: iproute
Requires: ipset
Requires: perl
Requires: rsync
Requires: cifs-utils
Requires: (edk2-ovmf or qemu-ovmf-x86_64)
Requires: swtpm
Requires: (python3-libvirt or python3-libvirt-python)
Requires: (qemu-img or qemu-tools)
Requires: qemu-kvm
Requires: cryptsetup
Requires: rng-tools
Requires: (libgcrypt > 1.8.3 or libgcrypt20)
Requires: (selinux-tools if selinux-tools)
Requires: sysstat
Provides: cloud-agent
Group: System Environment/Libraries
%description agent
The CloudStack agent for KVM hypervisors
%package baremetal-agent
Summary: CloudStack baremetal agent
Requires: tftp-server
Requires: xinetd
Requires: syslinux
Requires: chkconfig
Requires: dhcp
Requires: httpd
Group: System Environment/Libraries
%description baremetal-agent
The CloudStack baremetal agent
%package usage
Summary: CloudStack Usage calculation server
Requires: (java-17-openjdk or java-21-openjdk)
Requires: (tzdata-java or timezone-java)
Group: System Environment/Libraries
%description usage
The CloudStack usage calculation service
%package ui
Summary: CloudStack UI
Group: System Environment/Libraries
%description ui
The CloudStack UI
%package marvin
Summary: Apache CloudStack Marvin library
Requires: python3-pip
Requires: gcc
Requires: python3-devel
Requires: libffi-devel
Requires: openssl-devel
Group: System Environment/Libraries
%description marvin
Apache CloudStack Marvin library
%package integration-tests
Summary: Apache CloudStack Marvin integration tests
Requires: %{name}-marvin = %{_ver}
Group: System Environment/Libraries
%description integration-tests
Apache CloudStack Marvin integration tests
%if "%{_ossnoss}" == "noredist"
%package mysql-ha
Summary: Apache CloudStack Balancing Strategy for MySQL
Group: System Environmnet/Libraries
%description mysql-ha
Apache CloudStack Balancing Strategy for MySQL
%endif
%prep
echo Doing CloudStack build
%setup -q -n %{name}-%{_maventag}
%build
cp packaging/suse15/replace.properties build/replace.properties
echo VERSION=%{_maventag} >> build/replace.properties
echo PACKAGE=%{name} >> build/replace.properties
touch build/gitrev.txt
echo $(git rev-parse HEAD) > build/gitrev.txt
if [ "%{_ossnoss}" == "NOREDIST" -o "%{_ossnoss}" == "noredist" ] ; then
echo "Adding noredist flag to the maven build"
FLAGS="$FLAGS -Dnoredist"
fi
if [ "%{_sim}" == "SIMULATOR" -o "%{_sim}" == "simulator" ] ; then
echo "Adding simulator flag to the maven build"
FLAGS="$FLAGS -Dsimulator"
fi
if [ \"%{_temp}\" != "" ]; then
echo "Adding flags to package requested templates"
FLAGS="$FLAGS `rpm --eval %{?_temp}`"
fi
mvn -Psystemvm,developer $FLAGS clean package
cd ui && npm install && npm run build && cd ..
%install
[ ${RPM_BUILD_ROOT} != "/" ] && rm -rf ${RPM_BUILD_ROOT}
# Common directories
mkdir -p ${RPM_BUILD_ROOT}%{_bindir}
mkdir -p ${RPM_BUILD_ROOT}%{_localstatedir}/log/%{name}/agent
mkdir -p ${RPM_BUILD_ROOT}%{_localstatedir}/log/%{name}/ipallocator
mkdir -p ${RPM_BUILD_ROOT}%{_localstatedir}/cache/%{name}/management/work
mkdir -p ${RPM_BUILD_ROOT}%{_localstatedir}/cache/%{name}/management/temp
mkdir -p ${RPM_BUILD_ROOT}%{_localstatedir}/%{name}/mnt
mkdir -p ${RPM_BUILD_ROOT}%{_localstatedir}/%{name}/management
mkdir -p ${RPM_BUILD_ROOT}%{_initrddir}
mkdir -p ${RPM_BUILD_ROOT}%{_sysconfdir}/default
mkdir -p ${RPM_BUILD_ROOT}%{_sysconfdir}/profile.d
mkdir -p ${RPM_BUILD_ROOT}%{_sysconfdir}/sudoers.d
# Common
mkdir -p ${RPM_BUILD_ROOT}%{_datadir}/%{name}-common/scripts
mkdir -p ${RPM_BUILD_ROOT}%{_datadir}/%{name}-common/vms
mkdir -p ${RPM_BUILD_ROOT}%{_datadir}/%{name}-common/python-site
mkdir -p ${RPM_BUILD_ROOT}/usr/bin
cp -r scripts/* ${RPM_BUILD_ROOT}%{_datadir}/%{name}-common/scripts
install -D systemvm/dist/* ${RPM_BUILD_ROOT}%{_datadir}/%{name}-common/vms/
install python/lib/cloud_utils.py ${RPM_BUILD_ROOT}%{_datadir}/%{name}-common/python-site/cloud_utils.py
cp -r python/lib/cloudutils ${RPM_BUILD_ROOT}%{_datadir}/%{name}-common/python-site/
python3 -m py_compile ${RPM_BUILD_ROOT}%{_datadir}/%{name}-common/python-site/cloud_utils.py
python3 -m compileall ${RPM_BUILD_ROOT}%{_datadir}/%{name}-common/python-site/cloudutils
cp build/gitrev.txt ${RPM_BUILD_ROOT}%{_datadir}/%{name}-common/scripts
cp packaging/suse15/cloudstack-sccs ${RPM_BUILD_ROOT}/usr/bin
mkdir -p ${RPM_BUILD_ROOT}%{_datadir}/%{name}-common/scripts/network/cisco
cp -r plugins/network-elements/cisco-vnmc/src/main/scripts/network/cisco/* ${RPM_BUILD_ROOT}%{_datadir}/%{name}-common/scripts/network/cisco
# Management
mkdir -p ${RPM_BUILD_ROOT}%{_datadir}/%{name}-management/
mkdir -p ${RPM_BUILD_ROOT}%{_datadir}/%{name}-management/lib
mkdir -p ${RPM_BUILD_ROOT}%{_datadir}/%{name}-management/setup
mkdir -p ${RPM_BUILD_ROOT}%{_datadir}/%{name}-management/cks/conf
mkdir -p ${RPM_BUILD_ROOT}%{_localstatedir}/log/%{name}/management
mkdir -p ${RPM_BUILD_ROOT}%{_sysconfdir}/%{name}/management
mkdir -p ${RPM_BUILD_ROOT}%{_sysconfdir}/systemd/system/%{name}-management.service.d
mkdir -p ${RPM_BUILD_ROOT}%{_localstatedir}/run
mkdir -p ${RPM_BUILD_ROOT}%{_datadir}/%{name}-management/setup/wheel
# Setup Jetty
ln -sf /etc/%{name}/management ${RPM_BUILD_ROOT}%{_datadir}/%{name}-management/conf
ln -sf /var/log/%{name}/management ${RPM_BUILD_ROOT}%{_datadir}/%{name}-management/logs
install -D client/target/utilities/bin/cloud-migrate-databases ${RPM_BUILD_ROOT}%{_bindir}/%{name}-migrate-databases
install -D client/target/utilities/bin/cloud-set-guest-password ${RPM_BUILD_ROOT}%{_bindir}/%{name}-set-guest-password
install -D client/target/utilities/bin/cloud-set-guest-sshkey ${RPM_BUILD_ROOT}%{_bindir}/%{name}-set-guest-sshkey
install -D client/target/utilities/bin/cloud-setup-databases ${RPM_BUILD_ROOT}%{_bindir}/%{name}-setup-databases
install -D client/target/utilities/bin/cloud-setup-encryption ${RPM_BUILD_ROOT}%{_bindir}/%{name}-setup-encryption
install -D client/target/utilities/bin/cloud-setup-management ${RPM_BUILD_ROOT}%{_bindir}/%{name}-setup-management
install -D client/target/utilities/bin/cloud-setup-baremetal ${RPM_BUILD_ROOT}%{_bindir}/%{name}-setup-baremetal
install -D client/target/utilities/bin/cloud-sysvmadm ${RPM_BUILD_ROOT}%{_bindir}/%{name}-sysvmadm
install -D client/target/utilities/bin/cloud-update-xenserver-licenses ${RPM_BUILD_ROOT}%{_bindir}/%{name}-update-xenserver-licenses
# Bundle cmk in cloudstack-management
wget https://github.com/apache/cloudstack-cloudmonkey/releases/latest/download/cmk.linux.x86-64 -O ${RPM_BUILD_ROOT}%{_bindir}/cmk
chmod +x ${RPM_BUILD_ROOT}%{_bindir}/cmk
cp -r client/target/utilities/scripts/db/* ${RPM_BUILD_ROOT}%{_datadir}/%{name}-management/setup
cp -r plugins/integrations/kubernetes-service/src/main/resources/conf/* ${RPM_BUILD_ROOT}%{_datadir}/%{name}-management/cks/conf
cp -r client/target/cloud-client-ui-%{_maventag}.jar ${RPM_BUILD_ROOT}%{_datadir}/%{name}-management/
cp -r client/target/classes/META-INF/webapp ${RPM_BUILD_ROOT}%{_datadir}/%{name}-management/webapp
cp ui/dist/config.json ${RPM_BUILD_ROOT}%{_sysconfdir}/%{name}/management/
cp -r ui/dist/* ${RPM_BUILD_ROOT}%{_datadir}/%{name}-management/webapp/
rm -f ${RPM_BUILD_ROOT}%{_datadir}/%{name}-management/webapp/config.json
ln -sf /etc/%{name}/management/config.json ${RPM_BUILD_ROOT}%{_datadir}/%{name}-management/webapp/config.json
mv ${RPM_BUILD_ROOT}%{_datadir}/%{name}-management/cloud-client-ui-%{_maventag}.jar ${RPM_BUILD_ROOT}%{_datadir}/%{name}-management/lib/cloudstack-%{_maventag}.jar
cp client/target/lib/*jar ${RPM_BUILD_ROOT}%{_datadir}/%{name}-management/lib/
# Don't package the scripts in the management webapp
rm -rf ${RPM_BUILD_ROOT}%{_datadir}/%{name}-management/webapps/client/WEB-INF/classes/scripts
rm -rf ${RPM_BUILD_ROOT}%{_datadir}/%{name}-management/webapps/client/WEB-INF/classes/vms
for name in db.properties server.properties log4j-cloud.xml environment.properties java.security.ciphers
do
cp client/target/conf/$name ${RPM_BUILD_ROOT}%{_sysconfdir}/%{name}/management/$name
done
ln -sf log4j-cloud.xml ${RPM_BUILD_ROOT}%{_sysconfdir}/%{name}/management/log4j2.xml
install python/bindir/cloud-external-ipallocator.py ${RPM_BUILD_ROOT}%{_bindir}/%{name}-external-ipallocator.py
install -D client/target/pythonlibs/jasypt-1.9.3.jar ${RPM_BUILD_ROOT}%{_datadir}/%{name}-common/lib/jasypt-1.9.3.jar
install -D utils/target/cloud-utils-%{_maventag}-bundled.jar ${RPM_BUILD_ROOT}%{_datadir}/%{name}-common/lib/%{name}-utils.jar
install -D packaging/suse15/cloud-ipallocator.rc ${RPM_BUILD_ROOT}%{_initrddir}/%{name}-ipallocator
install -D packaging/suse15/cloud.limits ${RPM_BUILD_ROOT}%{_sysconfdir}/security/limits.d/cloud
install -D packaging/suse15/filelimit.conf ${RPM_BUILD_ROOT}%{_sysconfdir}/systemd/system/%{name}-management.service.d
install -D packaging/systemd/cloudstack-management.service ${RPM_BUILD_ROOT}%{_unitdir}/%{name}-management.service
install -D packaging/systemd/cloudstack-management.default ${RPM_BUILD_ROOT}%{_sysconfdir}/default/%{name}-management
install -D server/target/conf/cloudstack-sudoers ${RPM_BUILD_ROOT}%{_sysconfdir}/sudoers.d/%{name}-management
touch ${RPM_BUILD_ROOT}%{_localstatedir}/run/%{name}-management.pid
#install -D server/target/conf/cloudstack-catalina.logrotate ${RPM_BUILD_ROOT}%{_sysconfdir}/logrotate.d/%{name}-catalina
install -D server/target/conf/cloudstack-management.logrotate ${RPM_BUILD_ROOT}%{_sysconfdir}/logrotate.d/%{name}-management
install -D plugins/integrations/kubernetes-service/src/main/resources/conf/etcd-node.yml ${RPM_BUILD_ROOT}%{_datadir}/%{name}-management/cks/conf/etcd-node.yml
install -D plugins/integrations/kubernetes-service/src/main/resources/conf/k8s-control-node.yml ${RPM_BUILD_ROOT}%{_datadir}/%{name}-management/cks/conf/k8s-control-node.yml
install -D plugins/integrations/kubernetes-service/src/main/resources/conf/k8s-control-node-add.yml ${RPM_BUILD_ROOT}%{_datadir}/%{name}-management/cks/conf/k8s-control-node-add.yml
install -D plugins/integrations/kubernetes-service/src/main/resources/conf/k8s-node.yml ${RPM_BUILD_ROOT}%{_datadir}/%{name}-management/cks/conf/k8s-node.yml
# SystemVM template
mkdir -p ${RPM_BUILD_ROOT}%{_datadir}/%{name}-management/templates/systemvm
cp -r engine/schema/dist/systemvm-templates/* ${RPM_BUILD_ROOT}%{_datadir}/%{name}-management/templates/systemvm
rm -rf ${RPM_BUILD_ROOT}%{_datadir}/%{name}-management/templates/systemvm/sha512sum.txt
# Sample Extensions
mkdir -p ${RPM_BUILD_ROOT}%{_sysconfdir}/%{name}/extensions
cp -r extensions/* ${RPM_BUILD_ROOT}%{_sysconfdir}/%{name}/extensions
ln -sf %{_sysconfdir}/%{name}/extensions ${RPM_BUILD_ROOT}%{_datadir}/%{name}-management/extensions
# UI
mkdir -p ${RPM_BUILD_ROOT}%{_sysconfdir}/%{name}/ui
mkdir -p ${RPM_BUILD_ROOT}%{_datadir}/%{name}-ui/
cp -r client/target/classes/META-INF/webapp/WEB-INF ${RPM_BUILD_ROOT}%{_datadir}/%{name}-ui
cp ui/dist/config.json ${RPM_BUILD_ROOT}%{_sysconfdir}/%{name}/ui/
cp -r ui/dist/* ${RPM_BUILD_ROOT}%{_datadir}/%{name}-ui/
rm -f ${RPM_BUILD_ROOT}%{_datadir}/%{name}-ui/config.json
ln -sf /etc/%{name}/ui/config.json ${RPM_BUILD_ROOT}%{_datadir}/%{name}-ui/config.json
# Package mysql-connector-python (bundled to avoid dependency on external community repo)
# Version 8.0.31 is the last version supporting Python 3.6 (EL8)
wget -P ${RPM_BUILD_ROOT}%{_datadir}/%{name}-management/setup/wheel https://files.pythonhosted.org/packages/08/1f/42d74bae9dd6dcfec67c9ed0f3fa482b1ae5ac5f117ca82ab589ecb3ca19/mysql_connector_python-8.0.31-py2.py3-none-any.whl
# Version 8.3.0 supports Python 3.8 to 3.12 (EL9, EL10)
wget -P ${RPM_BUILD_ROOT}%{_datadir}/%{name}-management/setup/wheel https://files.pythonhosted.org/packages/53/ed/26a4b8cacb8852c6fd97d2d58a7f2591c41989807ea82bd8d9725a4e6937/mysql_connector_python-8.3.0-py2.py3-none-any.whl
chmod 440 ${RPM_BUILD_ROOT}%{_sysconfdir}/sudoers.d/%{name}-management
chmod 770 ${RPM_BUILD_ROOT}%{_localstatedir}/%{name}/mnt
chmod 770 ${RPM_BUILD_ROOT}%{_localstatedir}/%{name}/management
chmod 770 ${RPM_BUILD_ROOT}%{_localstatedir}/cache/%{name}/management/work
chmod 770 ${RPM_BUILD_ROOT}%{_localstatedir}/cache/%{name}/management/temp
chmod 770 ${RPM_BUILD_ROOT}%{_localstatedir}/log/%{name}/management
chmod 770 ${RPM_BUILD_ROOT}%{_localstatedir}/log/%{name}/agent
# KVM Agent
mkdir -p ${RPM_BUILD_ROOT}%{_sysconfdir}/%{name}/agent
mkdir -p ${RPM_BUILD_ROOT}%{_localstatedir}/log/%{name}/agent
mkdir -p ${RPM_BUILD_ROOT}%{_datadir}/%{name}-agent/lib
mkdir -p ${RPM_BUILD_ROOT}%{_datadir}/%{name}-agent/plugins
install -D packaging/systemd/cloudstack-agent.service ${RPM_BUILD_ROOT}%{_unitdir}/%{name}-agent.service
install -D packaging/systemd/cloudstack-rolling-maintenance@.service ${RPM_BUILD_ROOT}%{_unitdir}/%{name}-rolling-maintenance@.service
install -D packaging/systemd/cloudstack-agent.default ${RPM_BUILD_ROOT}%{_sysconfdir}/default/%{name}-agent
install -D agent/target/transformed/agent.properties ${RPM_BUILD_ROOT}%{_sysconfdir}/%{name}/agent/agent.properties
install -D agent/target/transformed/uefi.properties ${RPM_BUILD_ROOT}%{_sysconfdir}/%{name}/agent/uefi.properties
install -D agent/target/transformed/environment.properties ${RPM_BUILD_ROOT}%{_sysconfdir}/%{name}/agent/environment.properties
install -D agent/target/transformed/log4j-cloud.xml ${RPM_BUILD_ROOT}%{_sysconfdir}/%{name}/agent/log4j-cloud.xml
install -D agent/target/transformed/cloud-setup-agent ${RPM_BUILD_ROOT}%{_bindir}/%{name}-setup-agent
install -D agent/target/transformed/cloudstack-agent-upgrade ${RPM_BUILD_ROOT}%{_bindir}/%{name}-agent-upgrade
install -D agent/target/transformed/cloud-guest-tool ${RPM_BUILD_ROOT}%{_bindir}/%{name}-guest-tool
install -D agent/target/transformed/libvirtqemuhook ${RPM_BUILD_ROOT}%{_datadir}/%{name}-agent/lib/libvirtqemuhook
install -D agent/target/transformed/rolling-maintenance ${RPM_BUILD_ROOT}%{_datadir}/%{name}-agent/lib/rolling-maintenance
install -D agent/target/transformed/cloud-ssh ${RPM_BUILD_ROOT}%{_bindir}/%{name}-ssh
install -D agent/target/transformed/cloudstack-agent-profile.sh ${RPM_BUILD_ROOT}%{_sysconfdir}/profile.d/%{name}-agent-profile.sh
install -D agent/target/transformed/cloudstack-agent.logrotate ${RPM_BUILD_ROOT}%{_sysconfdir}/logrotate.d/%{name}-agent
install -D plugins/hypervisors/kvm/target/cloud-plugin-hypervisor-kvm-%{_maventag}.jar ${RPM_BUILD_ROOT}%{_datadir}/%name-agent/lib/cloud-plugin-hypervisor-kvm-%{_maventag}.jar
cp plugins/hypervisors/kvm/target/dependencies/* ${RPM_BUILD_ROOT}%{_datadir}/%{name}-agent/lib
cp plugins/storage/volume/storpool/target/*.jar ${RPM_BUILD_ROOT}%{_datadir}/%{name}-agent/lib
cp plugins/storage/volume/linstor/target/*.jar ${RPM_BUILD_ROOT}%{_datadir}/%{name}-agent/lib
# Usage server
mkdir -p ${RPM_BUILD_ROOT}%{_sysconfdir}/%{name}/usage
mkdir -p ${RPM_BUILD_ROOT}%{_datadir}/%{name}-usage/lib
install -D usage/target/cloud-usage-%{_maventag}.jar ${RPM_BUILD_ROOT}%{_datadir}/%{name}-usage/cloud-usage-%{_maventag}.jar
install -D usage/target/transformed/db.properties ${RPM_BUILD_ROOT}%{_sysconfdir}/%{name}/usage/db.properties
install -D usage/target/transformed/log4j-cloud_usage.xml ${RPM_BUILD_ROOT}%{_sysconfdir}/%{name}/usage/log4j-cloud.xml
cp usage/target/dependencies/* ${RPM_BUILD_ROOT}%{_datadir}/%{name}-usage/lib/
cp client/target/lib/mysql*jar ${RPM_BUILD_ROOT}%{_datadir}/%{name}-usage/lib/
install -D packaging/systemd/cloudstack-usage.service ${RPM_BUILD_ROOT}%{_unitdir}/%{name}-usage.service
install -D packaging/systemd/cloudstack-usage.default ${RPM_BUILD_ROOT}%{_sysconfdir}/default/%{name}-usage
mkdir -p ${RPM_BUILD_ROOT}%{_localstatedir}/log/%{name}/usage/
install -D usage/target/transformed/cloudstack-usage.logrotate ${RPM_BUILD_ROOT}%{_sysconfdir}/logrotate.d/%{name}-usage
# Marvin
mkdir -p ${RPM_BUILD_ROOT}%{_datadir}/%{name}-marvin
cp tools/marvin/dist/Marvin-*.tar.gz ${RPM_BUILD_ROOT}%{_datadir}/%{name}-marvin/
# integration-tests
mkdir -p ${RPM_BUILD_ROOT}%{_datadir}/%{name}-integration-tests
cp -r test/integration/* ${RPM_BUILD_ROOT}%{_datadir}/%{name}-integration-tests/
# MYSQL HA
if [ "x%{_ossnoss}" == "xnoredist" ] ; then
mkdir -p ${RPM_BUILD_ROOT}%{_datadir}/%{name}-mysql-ha/lib
cp -r plugins/database/mysql-ha/target/cloud-plugin-database-mysqlha-%{_maventag}.jar ${RPM_BUILD_ROOT}%{_datadir}/%{name}-mysql-ha/lib
fi
#License files from whisker
install -D tools/whisker/NOTICE ${RPM_BUILD_ROOT}%{_defaultdocdir}/%{name}-management-%{version}/NOTICE
install -D tools/whisker/LICENSE ${RPM_BUILD_ROOT}%{_defaultdocdir}/%{name}-management-%{version}/LICENSE
install -D tools/whisker/NOTICE ${RPM_BUILD_ROOT}%{_defaultdocdir}/%{name}-common-%{version}/NOTICE
install -D tools/whisker/LICENSE ${RPM_BUILD_ROOT}%{_defaultdocdir}/%{name}-common-%{version}/LICENSE
install -D tools/whisker/NOTICE ${RPM_BUILD_ROOT}%{_defaultdocdir}/%{name}-agent-%{version}/NOTICE
install -D tools/whisker/LICENSE ${RPM_BUILD_ROOT}%{_defaultdocdir}/%{name}-agent-%{version}/LICENSE
install -D tools/whisker/NOTICE ${RPM_BUILD_ROOT}%{_defaultdocdir}/%{name}-usage-%{version}/NOTICE
install -D tools/whisker/LICENSE ${RPM_BUILD_ROOT}%{_defaultdocdir}/%{name}-usage-%{version}/LICENSE
install -D tools/whisker/NOTICE ${RPM_BUILD_ROOT}%{_defaultdocdir}/%{name}-ui-%{version}/NOTICE
install -D tools/whisker/LICENSE ${RPM_BUILD_ROOT}%{_defaultdocdir}/%{name}-ui-%{version}/LICENSE
install -D tools/whisker/NOTICE ${RPM_BUILD_ROOT}%{_defaultdocdir}/%{name}-marvin-%{version}/NOTICE
install -D tools/whisker/LICENSE ${RPM_BUILD_ROOT}%{_defaultdocdir}/%{name}-marvin-%{version}/LICENSE
install -D tools/whisker/NOTICE ${RPM_BUILD_ROOT}%{_defaultdocdir}/%{name}-integration-tests-%{version}/NOTICE
install -D tools/whisker/LICENSE ${RPM_BUILD_ROOT}%{_defaultdocdir}/%{name}-integration-tests-%{version}/LICENSE
%clean
[ ${RPM_BUILD_ROOT} != "/" ] && rm -rf ${RPM_BUILD_ROOT}
%posttrans common
unalias cp
python_dir=$(python3 -c "from distutils.sysconfig import get_python_lib; print(get_python_lib(1))")
if [ ! -z $python_dir ];then
cp -f -r /usr/share/cloudstack-common/python-site/* $python_dir/
fi
%preun management
/usr/bin/systemctl stop cloudstack-management || true
/usr/bin/systemctl disable cloudstack-management || true
%pre management
id cloud > /dev/null 2>&1 || /usr/sbin/useradd -M -U -c "CloudStack unprivileged user" \
-r -s /bin/sh -d %{_localstatedir}/cloudstack/management cloud || true
rm -rf %{_localstatedir}/cache/cloudstack
# in case of upgrade to 4.9+ copy commands.properties if not exists in /etc/cloudstack/management/
if [ "$1" == "2" ] ; then
if [ -f "%{_datadir}/%{name}-management/webapps/client/WEB-INF/classes/commands.properties" ] && [ ! -f "%{_sysconfdir}/%{name}/management/commands.properties" ] ; then
cp -p %{_datadir}/%{name}-management/webapps/client/WEB-INF/classes/commands.properties %{_sysconfdir}/%{name}/management/commands.properties
fi
fi
# Remove old tomcat symlinks and env config file
if [ -L "%{_datadir}/%{name}-management/lib" ]
then
rm -f %{_datadir}/%{name}-management/bin
rm -f %{_datadir}/%{name}-management/lib
rm -f %{_datadir}/%{name}-management/temp
rm -f %{_datadir}/%{name}-management/work
rm -f %{_sysconfdir}/default/%{name}-management
fi
%post management
# Install mysql-connector-python wheel
# Detect Python version to install compatible wheel
if python3 -c 'import sys; sys.exit(0 if sys.version_info >= (3, 7) else 1)'; then
pip3 install %{_datadir}/%{name}-management/setup/wheel/mysql_connector_python-8.3.0-py2.py3-none-any.whl
else
pip3 install %{_datadir}/%{name}-management/setup/wheel/mysql_connector_python-8.0.31-py2.py3-none-any.whl
fi
/usr/bin/systemctl enable cloudstack-management > /dev/null 2>&1 || true
/usr/bin/systemctl enable --now rngd > /dev/null 2>&1 || true
grep -s -q "db.cloud.driver=jdbc:mysql" "%{_sysconfdir}/%{name}/management/db.properties" || sed -i -e "\$adb.cloud.driver=jdbc:mysql" "%{_sysconfdir}/%{name}/management/db.properties"
grep -s -q "db.usage.driver=jdbc:mysql" "%{_sysconfdir}/%{name}/management/db.properties" || sed -i -e "\$adb.usage.driver=jdbc:mysql" "%{_sysconfdir}/%{name}/management/db.properties"
grep -s -q "db.simulator.driver=jdbc:mysql" "%{_sysconfdir}/%{name}/management/db.properties" || sed -i -e "\$adb.simulator.driver=jdbc:mysql" "%{_sysconfdir}/%{name}/management/db.properties"
# Update DB properties having master and slave(s), with source and replica(s) respectively (for inclusiveness)
grep -s -q "^db.cloud.slaves=" "%{_sysconfdir}/%{name}/management/db.properties" && sed -i "s/^db.cloud.slaves=/db.cloud.replicas=/g" "%{_sysconfdir}/%{name}/management/db.properties"
grep -s -q "^db.cloud.secondsBeforeRetryMaster=" "%{_sysconfdir}/%{name}/management/db.properties" && sed -i "s/^db.cloud.secondsBeforeRetryMaster=/db.cloud.secondsBeforeRetrySource=/g" "%{_sysconfdir}/%{name}/management/db.properties"
grep -s -q "^db.cloud.queriesBeforeRetryMaster=" "%{_sysconfdir}/%{name}/management/db.properties" && sed -i "s/^db.cloud.queriesBeforeRetryMaster=/db.cloud.queriesBeforeRetrySource=/g" "%{_sysconfdir}/%{name}/management/db.properties"
grep -s -q "^db.usage.slaves=" "%{_sysconfdir}/%{name}/management/db.properties" && sed -i "s/^db.usage.slaves=/db.usage.replicas=/g" "%{_sysconfdir}/%{name}/management/db.properties"
grep -s -q "^db.usage.secondsBeforeRetryMaster=" "%{_sysconfdir}/%{name}/management/db.properties" && sed -i "s/^db.usage.secondsBeforeRetryMaster=/db.usage.secondsBeforeRetrySource=/g" "%{_sysconfdir}/%{name}/management/db.properties"
grep -s -q "^db.usage.queriesBeforeRetryMaster=" "%{_sysconfdir}/%{name}/management/db.properties" && sed -i "s/^db.usage.queriesBeforeRetryMaster=/db.usage.queriesBeforeRetrySource=/g" "%{_sysconfdir}/%{name}/management/db.properties"
if [ ! -f %{_datadir}/cloudstack-common/scripts/vm/hypervisor/xenserver/vhd-util ] ; then
echo Please download vhd-util from http://download.cloudstack.org/tools/vhd-util and put it in
echo %{_datadir}/cloudstack-common/scripts/vm/hypervisor/xenserver/
fi
if [ -f %{_sysconfdir}/sysconfig/%{name}-management ] ; then
rm -f %{_sysconfdir}/sysconfig/%{name}-management
fi
chown -R cloud:cloud /var/log/cloudstack/management
chown -R cloud:cloud /usr/share/cloudstack-management/templates
find /usr/share/cloudstack-management/templates -type d -exec chmod 0770 {} \;
systemctl daemon-reload
%posttrans management
# Print help message
if [ -f "/usr/share/cloudstack-common/scripts/installer/cloudstack-help-text" ];then
sed -i "s,^ACS_VERSION=.*,ACS_VERSION=%{_maventag},g" /usr/share/cloudstack-common/scripts/installer/cloudstack-help-text
/usr/share/cloudstack-common/scripts/installer/cloudstack-help-text management
fi
%preun agent
/sbin/service cloudstack-agent stop || true
if [ "$1" == "0" ] ; then
/sbin/chkconfig --del cloudstack-agent > /dev/null 2>&1 || true
fi
%pre agent
# save old configs if they exist (for upgrade). Otherwise we may lose them
# when the old packages are erased. There are a lot of properties files here.
if [ -d "%{_sysconfdir}/cloud" ] ; then
mv %{_sysconfdir}/cloud %{_sysconfdir}/cloud.rpmsave
fi
%posttrans agent
if [ "$1" == "2" ] ; then
echo "Running %{_bindir}/%{name}-agent-upgrade to update bridge name for upgrade from CloudStack 4.0.x (and before) to CloudStack 4.1 (and later)"
%{_bindir}/%{name}-agent-upgrade
fi
if [ ! -d %{_sysconfdir}/libvirt/hooks ] ; then
mkdir %{_sysconfdir}/libvirt/hooks
fi
cp -a ${RPM_BUILD_ROOT}%{_datadir}/%{name}-agent/lib/libvirtqemuhook %{_sysconfdir}/libvirt/hooks/qemu
mkdir -m 0755 -p /usr/share/cloudstack-agent/tmp
/usr/bin/systemctl restart libvirtd
/usr/bin/systemctl enable cloudstack-agent > /dev/null 2>&1 || true
/usr/bin/systemctl enable cloudstack-rolling-maintenance@p > /dev/null 2>&1 || true
/usr/bin/systemctl enable --now rngd > /dev/null 2>&1 || true
# if saved agent.properties from upgrade exist, copy them over
if [ -f "%{_sysconfdir}/cloud.rpmsave/agent/agent.properties" ]; then
mv %{_sysconfdir}/%{name}/agent/agent.properties %{_sysconfdir}/%{name}/agent/agent.properties.rpmnew
cp -p %{_sysconfdir}/cloud.rpmsave/agent/agent.properties %{_sysconfdir}/%{name}/agent
# make sure we only do this on the first install of this RPM, don't want to overwrite on a reinstall
mv %{_sysconfdir}/cloud.rpmsave/agent/agent.properties %{_sysconfdir}/cloud.rpmsave/agent/agent.properties.rpmsave
fi
# if saved uefi.properties from upgrade exist, copy them over
if [ -f "%{_sysconfdir}/cloud.rpmsave/agent/uefi.properties" ]; then
mv %{_sysconfdir}/%{name}/agent/uefi.properties %{_sysconfdir}/%{name}/agent/uefi.properties.rpmnew
cp -p %{_sysconfdir}/cloud.rpmsave/agent/uefi.properties %{_sysconfdir}/%{name}/agent
# make sure we only do this on the first install of this RPM, don't want to overwrite on a reinstall
mv %{_sysconfdir}/cloud.rpmsave/agent/uefi.properties %{_sysconfdir}/cloud.rpmsave/agent/uefi.properties.rpmsave
fi
systemctl daemon-reload
# Print help message
if [ -f "/usr/share/cloudstack-common/scripts/installer/cloudstack-help-text" ];then
sed -i "s,^ACS_VERSION=.*,ACS_VERSION=%{_maventag},g" /usr/share/cloudstack-common/scripts/installer/cloudstack-help-text
/usr/share/cloudstack-common/scripts/installer/cloudstack-help-text agent
fi
%pre usage
id cloud > /dev/null 2>&1 || /usr/sbin/useradd -M -U -c "CloudStack unprivileged user" \
-r -s /bin/sh -d %{_localstatedir}/cloudstack/management cloud|| true
%preun usage
/sbin/service cloudstack-usage stop || true
if [ "$1" == "0" ] ; then
/sbin/chkconfig --del cloudstack-usage > /dev/null 2>&1 || true
fi
%post usage
if [ -f "%{_sysconfdir}/%{name}/management/db.properties" ]; then
echo "Replacing usage server's db.properties with a link to the management server's db.properties"
rm -f %{_sysconfdir}/%{name}/usage/db.properties
ln -s %{_sysconfdir}/%{name}/management/db.properties %{_sysconfdir}/%{name}/usage/db.properties
/usr/bin/systemctl enable cloudstack-usage > /dev/null 2>&1 || true
fi
if [ -f "%{_sysconfdir}/%{name}/management/key" ]; then
echo "Replacing usage server's key with a link to the management server's key"
rm -f %{_sysconfdir}/%{name}/usage/key
ln -s %{_sysconfdir}/%{name}/management/key %{_sysconfdir}/%{name}/usage/key
fi
if [ ! -f "%{_sysconfdir}/%{name}/usage/key" ]; then
ln -s %{_sysconfdir}/%{name}/management/key %{_sysconfdir}/%{name}/usage/key
fi
mkdir -p /usr/local/libexec
if [ ! -f "/usr/local/libexec/sanity-check-last-id" ]; then
echo 1 > /usr/local/libexec/sanity-check-last-id
fi
chown cloud:cloud /usr/local/libexec/sanity-check-last-id
%posttrans usage
# Print help message
if [ -f "/usr/share/cloudstack-common/scripts/installer/cloudstack-help-text" ];then
sed -i "s,^ACS_VERSION=.*,ACS_VERSION=%{_maventag},g" /usr/share/cloudstack-common/scripts/installer/cloudstack-help-text
/usr/share/cloudstack-common/scripts/installer/cloudstack-help-text usage
fi
%post marvin
pip3 install --upgrade https://files.pythonhosted.org/packages/08/1f/42d74bae9dd6dcfec67c9ed0f3fa482b1ae5ac5f117ca82ab589ecb3ca19/mysql_connector_python-8.0.31-py2.py3-none-any.whl
pip3 install --upgrade /usr/share/cloudstack-marvin/Marvin-*.tar.gz
#No default permission as the permission setup is complex
%files management
%defattr(-,root,root,-)
%dir %{_datadir}/%{name}-management
%dir %attr(0770,root,cloud) %{_localstatedir}/%{name}/mnt
%dir %attr(0770,cloud,cloud) %{_localstatedir}/%{name}/management
%dir %attr(0770,root,cloud) %{_localstatedir}/cache/%{name}/management
%dir %attr(0770,root,cloud) %{_localstatedir}/log/%{name}/management
%config(noreplace) %{_sysconfdir}/default/%{name}-management
%config(noreplace) %{_sysconfdir}/sudoers.d/%{name}-management
%config(noreplace) %{_sysconfdir}/security/limits.d/cloud
%config(noreplace) %{_sysconfdir}/systemd/system/%{name}-management.service.d
%config(noreplace) %attr(0640,root,cloud) %{_sysconfdir}/%{name}/management/db.properties
%config(noreplace) %attr(0640,root,cloud) %{_sysconfdir}/%{name}/management/server.properties
%config(noreplace) %attr(0640,root,cloud) %{_sysconfdir}/%{name}/management/config.json
%config(noreplace) %{_sysconfdir}/%{name}/management/log4j-cloud.xml
%config(noreplace) %{_sysconfdir}/%{name}/management/log4j2.xml
%config(noreplace) %{_sysconfdir}/%{name}/management/environment.properties
%config(noreplace) %{_sysconfdir}/%{name}/management/java.security.ciphers
%config(noreplace) %attr(0644,root,root) %{_sysconfdir}/logrotate.d/%{name}-management
%attr(0644,root,root) %{_unitdir}/%{name}-management.service
%attr(0755,cloud,cloud) %{_localstatedir}/run/%{name}-management.pid
%attr(0755,root,root) %{_bindir}/%{name}-setup-management
%attr(0755,root,root) %{_bindir}/%{name}-update-xenserver-licenses
%{_datadir}/%{name}-management/conf
%{_datadir}/%{name}-management/lib/*.jar
%{_datadir}/%{name}-management/logs
%{_datadir}/%{name}-management/templates
%{_datadir}/%{name}-management/extensions
%attr(0755,root,root) %{_bindir}/%{name}-setup-databases
%attr(0755,root,root) %{_bindir}/%{name}-migrate-databases
%attr(0755,root,root) %{_bindir}/%{name}-set-guest-password
%attr(0755,root,root) %{_bindir}/%{name}-set-guest-sshkey
%attr(0755,root,root) %{_bindir}/%{name}-sysvmadm
%attr(0755,root,root) %{_bindir}/%{name}-setup-encryption
%attr(0755,root,root) %{_bindir}/cmk
%{_datadir}/%{name}-management/cks/conf/*.yml
%{_datadir}/%{name}-management/setup/*.sql
%{_datadir}/%{name}-management/setup/*.sh
%{_datadir}/%{name}-management/setup/server-setup.xml
%{_datadir}/%{name}-management/webapp/*
%dir %attr(0770, cloud, cloud) %{_datadir}/%{name}-management/templates
%dir %attr(0770, cloud, cloud) %{_datadir}/%{name}-management/templates/systemvm
%attr(0644, cloud, cloud) %{_datadir}/%{name}-management/templates/systemvm/*
%attr(0755,root,root) %{_bindir}/%{name}-external-ipallocator.py
%attr(0755,root,root) %{_initrddir}/%{name}-ipallocator
%dir %attr(0770,root,root) %{_localstatedir}/log/%{name}/ipallocator
%{_defaultdocdir}/%{name}-management-%{version}/LICENSE
%{_defaultdocdir}/%{name}-management-%{version}/NOTICE
%{_datadir}/%{name}-management/setup/wheel/*.whl
%dir %attr(0755,cloud,cloud) %{_sysconfdir}/%{name}/extensions
%attr(0755,cloud,cloud) %{_sysconfdir}/%{name}/extensions/*
%files agent
%attr(0755,root,root) %{_bindir}/%{name}-setup-agent
%attr(0755,root,root) %{_bindir}/%{name}-agent-upgrade
%attr(0755,root,root) %{_bindir}/%{name}-guest-tool
%attr(0755,root,root) %{_bindir}/%{name}-ssh
%attr(0644,root,root) %{_unitdir}/%{name}-agent.service
%attr(0644,root,root) %{_unitdir}/%{name}-rolling-maintenance@.service
%config(noreplace) %{_sysconfdir}/default/%{name}-agent
%attr(0644,root,root) %{_sysconfdir}/profile.d/%{name}-agent-profile.sh
%config(noreplace) %attr(0644,root,root) %{_sysconfdir}/logrotate.d/%{name}-agent
%attr(0755,root,root) %{_datadir}/%{name}-common/scripts/network/cisco
%config(noreplace) %{_sysconfdir}/%{name}/agent
%dir %{_localstatedir}/log/%{name}/agent
%attr(0644,root,root) %{_datadir}/%{name}-agent/lib/*.jar
%attr(0755,root,root) %{_datadir}/%{name}-agent/lib/libvirtqemuhook
%attr(0755,root,root) %{_datadir}/%{name}-agent/lib/rolling-maintenance
%dir %{_datadir}/%{name}-agent/plugins
%{_defaultdocdir}/%{name}-agent-%{version}/LICENSE
%{_defaultdocdir}/%{name}-agent-%{version}/NOTICE
%files common
%dir %attr(0755,root,root) %{_datadir}/%{name}-common/python-site/cloudutils
%dir %attr(0755,root,root) %{_datadir}/%{name}-common/vms
%attr(0755,root,root) %{_datadir}/%{name}-common/scripts
%attr(0755,root,root) /usr/bin/cloudstack-sccs
%attr(0644, root, root) %{_datadir}/%{name}-common/vms/agent.zip
%attr(0644, root, root) %{_datadir}/%{name}-common/vms/cloud-scripts.tgz
%attr(0644, root, root) %{_datadir}/%{name}-common/vms/patch-sysvms.sh
%attr(0644,root,root) %{_datadir}/%{name}-common/python-site/cloud_utils.py
%attr(0644,root,root) %{_datadir}/%{name}-common/python-site/__pycache__/*
%attr(0644,root,root) %{_datadir}/%{name}-common/python-site/cloudutils/*
%attr(0644, root, root) %{_datadir}/%{name}-common/lib/jasypt-1.9.3.jar
%attr(0644, root, root) %{_datadir}/%{name}-common/lib/%{name}-utils.jar
%{_defaultdocdir}/%{name}-common-%{version}/LICENSE
%{_defaultdocdir}/%{name}-common-%{version}/NOTICE
%files ui
%config(noreplace) %attr(0640,root,cloud) %{_sysconfdir}/%{name}/ui/config.json
%{_datadir}/%{name}-ui/*
%{_defaultdocdir}/%{name}-ui-%{version}/LICENSE
%{_defaultdocdir}/%{name}-ui-%{version}/NOTICE
%files usage
%attr(0644,root,root) %{_unitdir}/%{name}-usage.service
%config(noreplace) %{_sysconfdir}/default/%{name}-usage
%config(noreplace) %attr(0644,root,root) %{_sysconfdir}/logrotate.d/%{name}-usage
%attr(0644,root,root) %{_datadir}/%{name}-usage/*.jar
%attr(0644,root,root) %{_datadir}/%{name}-usage/lib/*.jar
%dir %attr(0770,root,cloud) %{_localstatedir}/log/%{name}/usage
%attr(0644,root,root) %{_sysconfdir}/%{name}/usage/db.properties
%attr(0644,root,root) %{_sysconfdir}/%{name}/usage/log4j-cloud.xml
%{_defaultdocdir}/%{name}-usage-%{version}/LICENSE
%{_defaultdocdir}/%{name}-usage-%{version}/NOTICE
%files marvin
%attr(0644,root,root) %{_datadir}/%{name}-marvin/Marvin*.tar.gz
%{_defaultdocdir}/%{name}-marvin-%{version}/LICENSE
%{_defaultdocdir}/%{name}-marvin-%{version}/NOTICE
%files integration-tests
%attr(0755,root,root) %{_datadir}/%{name}-integration-tests/*
%{_defaultdocdir}/%{name}-integration-tests-%{version}/LICENSE
%{_defaultdocdir}/%{name}-integration-tests-%{version}/NOTICE
%if "%{_ossnoss}" == "noredist"
%files mysql-ha
%defattr(0644,cloud,cloud,0755)
%attr(0644,root,root) %{_datadir}/%{name}-mysql-ha/lib/*
%endif
%files baremetal-agent
%attr(0755,root,root) %{_bindir}/cloudstack-setup-baremetal
%changelog
* Thu Dec 22 2022 Rohit Yadav <rohit@apache.org> 4.18.0
- Add support for EL9
* Fri Oct 14 2022 Daan Hoogland <daan.hoogland@gmail.com> 4.18.0
- initialising sanity check pointer file
* Tue Jun 29 2021 David Jumani <dj.davidjumani1994@gmail.com> 4.16.0
- Adding SUSE 15 support
* Thu Apr 30 2015 Rohit Yadav <bhaisaab@apache.org> 4.6.0
- Remove awsapi package
* Wed Nov 19 2014 Hugo Trippaers <hugo@apache.org> 4.6.0
- Create a specific spec for CentOS 7
* Fri Jul 4 2014 Hugo Trippaers <hugo@apache.org> 4.5.0
- Add a package for the mysql ha module
* Fri Oct 5 2012 Hugo Trippaers <hugo@apache.org> 4.1.0
- new style spec file

View File

@ -0,0 +1 @@
../el8/cloudstack-agent.te

View File

@ -0,0 +1 @@
../el8/cloudstack-sccs

View File

@ -0,0 +1 @@
../el8/filelimit.conf

View File

@ -0,0 +1,65 @@
# 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.
DBUSER=cloud
DBPW=cloud
DBROOTPW=
MSLOG=vmops.log
APISERVERLOG=api.log
DBHOST=localhost
DBDRIVER=jdbc:mysql
COMPONENTS-SPEC=components-premium.xml
REMOTEHOST=localhost
AGENTCLASSPATH=
AGENTLOG=/var/log/cloudstack/agent/agent.log
AGENTLOGDIR=/var/log/cloudstack/agent/
AGENTSYSCONFDIR=/etc/cloudstack/agent
APISERVERLOG=/var/log/cloudstack/management/apilog.log
BINDIR=/usr/bin
COMMONLIBDIR=/usr/share/cloudstack-common
CONFIGUREVARS=
DEPSCLASSPATH=
DOCDIR=
IPALOCATORLOG=/var/log/cloudstack/management/ipallocator.log
JAVADIR=/usr/share/java
LIBEXECDIR=/usr/libexec
LOCKDIR=/var/lock
MSCLASSPATH=
MSCONF=/etc/cloudstack/management
MSENVIRON=/usr/share/cloudstack-management
MSLOG=/var/log/cloudstack/management/management-server.log
MSLOGDIR=/var/log/cloudstack/management/
MSMNTDIR=/var/cloudstack/mnt
MSUSER=cloud
PIDDIR=/var/run
PLUGINJAVADIR=/usr/share/cloudstack-management/plugin
PREMIUMJAVADIR=/usr/share/cloudstack-management/premium
PYTHONDIR=/usr/share/cloudstack-common/python-site/
SERVERSYSCONFDIR=/etc/sysconfig
SETUPDATADIR=/usr/share/cloudstack-management/setup
SYSCONFDIR=/etc/sysconfig
SYSTEMCLASSPATH=
SYSTEMJARS=
USAGECLASSPATH=
USAGELOG=/var/log/cloudstack/usage/usage.log
USAGESYSCONFDIR=/etc/sysconfig
EXTENSIONSDEPLOYMENTMODE=production
GUESTNVRAMTEMPLATELEGACY=/usr/share/qemu/ovmf-x86_64-vars.bin
GUESTLOADERLEGACY=/usr/share/qemu/ovmf-x86_64-code.bin
GUESTNVRAMTEMPLATESECURE=/usr/share/qemu/ovmf-x86_64-ms-vars.bin
GUESTLOADERSECURE=/usr/share/qemu/ovmf-x86_64-ms-code.bin
GUESTNVRAMPATH=/var/lib/libvirt/qemu/nvram/

View File

@ -17,7 +17,7 @@
JAVA_OPTS="-Djava.security.properties=/etc/cloudstack/management/java.security.ciphers -Djava.awt.headless=true -Xmx2G -XX:+UseParallelGC -XX:MaxGCPauseMillis=500 -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/var/log/cloudstack/management/ -XX:ErrorFile=/var/log/cloudstack/management/cloudstack-management.err --add-opens=java.base/java.lang=ALL-UNNAMED --add-exports=java.base/sun.security.x509=ALL-UNNAMED"
CLASSPATH="/usr/share/cloudstack-management/lib/*:/etc/cloudstack/management:/usr/share/cloudstack-common:/usr/share/cloudstack-management/setup:/usr/share/cloudstack-management:/usr/share/java/mysql-connector-java.jar:/usr/share/cloudstack-mysql-ha/lib/*"
CLASSPATH="/usr/share/cloudstack-management/lib/*:/etc/cloudstack/management:/usr/share/cloudstack-common:/usr/share/cloudstack-management/setup:/usr/share/cloudstack-management:/usr/share/cloudstack-mysql-ha/lib/*"
BOOTSTRAP_CLASS=org.apache.cloudstack.ServerDaemon

View File

@ -17,7 +17,7 @@
JAVA_OPTS="-Xms256m -Xmx2048m --add-opens=java.base/java.lang=ALL-UNNAMED"
CLASSPATH="/usr/share/cloudstack-usage/*:/usr/share/cloudstack-usage/lib/*:/usr/share/cloudstack-mysql-ha/lib/*:/etc/cloudstack/usage:/usr/share/java/mysql-connector-java.jar"
CLASSPATH="/usr/share/cloudstack-usage/*:/usr/share/cloudstack-usage/lib/*:/usr/share/cloudstack-mysql-ha/lib/*:/etc/cloudstack/usage"
JAVA_CLASS=com.cloud.usage.UsageServer

View File

@ -2047,7 +2047,7 @@ public class KVMStorageProcessor implements StorageProcessor {
try {
Thread.sleep(10000);
} catch (InterruptedException e) {
throw new CloudRuntimeException(e);
logger.trace("Thread that was tracking the progress for backup of VM [{}] was interrupted. Ignoring.", vmName);
}
}

View File

@ -217,13 +217,14 @@ public class AdaptiveDataStoreLifeCycleImpl extends BasePrimaryDataStoreLifeCycl
// validate the provided details are correct/valid for the provider
api.validate();
// if we have user-provided capacity bytes, validate they do not exceed the manaaged storage capacity bytes
// User-provided capacityBytes always wins; validate against storage stats only when
// the provider could actually report them. If the provider cannot (empty pod with no
// footprint, no quota set, transient probe failure), fall through and use what the
// user supplied rather than failing the whole registration.
ProviderVolumeStorageStats stats = api.getManagedStorageStats();
if (capacityBytes != null && capacityBytes != 0 && stats != null) {
if (stats.getCapacityInBytes() > 0) {
if (stats.getCapacityInBytes() < capacityBytes) {
throw new InvalidParameterValueException("Capacity bytes provided exceeds the capacity of the storage endpoint: provided by user: " + capacityBytes + ", storage capacity from storage provider: " + stats.getCapacityInBytes());
}
if (capacityBytes != null && capacityBytes > 0) {
if (stats != null && stats.getCapacityInBytes() > 0 && stats.getCapacityInBytes() < capacityBytes) {
throw new InvalidParameterValueException("Provided capacity bytes exceed the capacity of the storage endpoint: provided by user: " + capacityBytes + ", storage capacity from storage provider: " + stats.getCapacityInBytes());
}
parameters.setCapacityBytes(capacityBytes);
}

View File

@ -23,7 +23,8 @@ import java.net.URL;
import java.security.KeyManagementException;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.text.SimpleDateFormat;
import java.time.ZoneOffset;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
@ -88,6 +89,9 @@ public class FlashArrayAdapter implements ProviderAdapter {
static final ObjectMapper mapper = new ObjectMapper();
public String pod = null;
public String hostgroup = null;
private static final DateTimeFormatter DELETION_TIMESTAMP_FORMAT =
DateTimeFormatter.ofPattern("yyyyMMddHHmmss").withZone(ZoneOffset.UTC);
private String username;
private String password;
private String accessToken;
@ -200,28 +204,63 @@ public class FlashArrayAdapter implements ProviderAdapter {
@Override
public void delete(ProviderAdapterContext context, ProviderAdapterDataObject dataObject) {
// first make sure we are disconnected
removeVlunsAll(context, pod, dataObject.getExternalName());
String fullName = normalizeName(pod, dataObject.getExternalName());
FlashArrayVolume volume = new FlashArrayVolume();
// Snapshots live under /volume-snapshots and already use the array's
// reserved form <volume>.<suffix>, which legitimately contains ".".
// The stricter [A-Za-z0-9_-] naming rule applies to regular volume
// names and free-form rename targets, not to these reserved snapshot
// names. Since FlashArray snapshot names are system-defined rather
// than arbitrary rename targets, we skip the usual timestamped rename
// and only mark snapshots destroyed; the array's own ".N" suffix
// already disambiguates them in the recycle bin.
if (dataObject.getType() == ProviderAdapterDataObject.Type.SNAPSHOT) {
try {
FlashArrayVolume destroy = new FlashArrayVolume();
destroy.setDestroyed(true);
PATCH("/volume-snapshots?names=" + fullName, destroy, new TypeReference<FlashArrayList<FlashArrayVolume>>() {
});
} catch (CloudRuntimeException e) {
String msg = e.getMessage();
if (msg != null && (msg.contains("No such volume or snapshot")
|| msg.contains("Volume does not exist"))) {
return;
}
throw e;
}
return;
}
// rename as we delete so it doesn't conflict if the template or volume is ever recreated
// pure keeps the volume(s) around in a Destroyed bucket for a period of time post delete
String timestamp = new SimpleDateFormat("yyyyMMddHHmmss").format(new java.util.Date());
volume.setExternalName(fullName + "-" + timestamp);
// first make sure we are disconnected
removeVlunsAll(context, pod, dataObject.getExternalName());
// Rename then destroy: FlashArray keeps destroyed volumes in a recycle
// bin (default 24h) from which they can be recovered. Renaming with a
// deletion timestamp gives operators a forensic trail when browsing the
// array - they can see when each destroyed copy was deleted on the
// CloudStack side. FlashArray rejects a single PATCH that combines
// {name, destroyed}, so the rename and the destroy must be issued as
// two separate requests each carrying only its own field.
// Use UTC so the rename suffix is stable regardless of the management
// server's local timezone or DST changes - operators correlating the
// CloudStack delete event with the array's audit log get a consistent
// wall-clock value.
String timestamp = DELETION_TIMESTAMP_FORMAT.format(java.time.Instant.now());
String renamedName = fullName + "-" + timestamp;
try {
PATCH("/volumes?names=" + fullName, volume, new TypeReference<FlashArrayList<FlashArrayVolume>>() {
FlashArrayVolume rename = new FlashArrayVolume();
rename.setExternalName(renamedName);
PATCH("/volumes?names=" + fullName, rename, new TypeReference<FlashArrayList<FlashArrayVolume>>() {
});
// now delete it with new name
volume.setDestroyed(true);
PATCH("/volumes?names=" + fullName + "-" + timestamp, volume, new TypeReference<FlashArrayList<FlashArrayVolume>>() {
FlashArrayVolume destroy = new FlashArrayVolume();
destroy.setDestroyed(true);
PATCH("/volumes?names=" + renamedName, destroy, new TypeReference<FlashArrayList<FlashArrayVolume>>() {
});
} catch (CloudRuntimeException e) {
if (e.toString().contains("Volume does not exist")) {
String msg = e.getMessage();
if (msg != null && msg.contains("Volume does not exist")) {
return;
} else {
throw e;

View File

@ -170,7 +170,7 @@
<cs.libvirt-java.version>0.5.3</cs.libvirt-java.version>
<cs.mail.version>1.5.0-b01</cs.mail.version>
<cs.mustache.version>0.9.14</cs.mustache.version>
<cs.mysql.version>8.0.33</cs.mysql.version>
<cs.mysql.version>8.4.0</cs.mysql.version>
<cs.neethi.version>2.0.4</cs.neethi.version>
<cs.nitro.version>10.1</cs.nitro.version>
<cs.opensaml.version>2.6.6</cs.opensaml.version>

View File

@ -539,6 +539,9 @@ public class IpAddressManagerImpl extends ManagerBase implements IpAddressManage
AssignIpAddressSearch.and("allocated", AssignIpAddressSearch.entity().getAllocatedTime(), Op.NULL);
AssignIpAddressSearch.and("vlanId", AssignIpAddressSearch.entity().getVlanId(), Op.IN);
AssignIpAddressSearch.and("forSystemVms", AssignIpAddressSearch.entity().isForSystemVms(), Op.EQ);
AssignIpAddressSearch.and("id", AssignIpAddressSearch.entity().getId(), Op.NIN);
AssignIpAddressSearch.and("requestedAddress", AssignIpAddressSearch.entity().getAddress(), Op.EQ);
AssignIpAddressSearch.and("routerAddress", AssignIpAddressSearch.entity().getAddress(), Op.NEQ);
SearchBuilder<VlanVO> vlanSearch = _vlanDao.createSearchBuilder();
vlanSearch.and("type", vlanSearch.entity().getVlanType(), Op.EQ);
@ -945,10 +948,23 @@ public class IpAddressManagerImpl extends ManagerBase implements IpAddressManage
if (podId != null) {
sc = AssignIpAddressFromPodVlanSearch.create();
sc.setJoinParameters("podVlanMapSB", "podId", podId);
errorMessage.append(" pod id=" + podId);
errorMessage.append(" pod id=").append(podId);
} else {
sc = AssignIpAddressSearch.create();
errorMessage.append(" zone id=" + dcId);
errorMessage.append(" zone id=").append(dcId);
}
if (lockOneRow) {
logger.debug("Listing quarantined public IPs to ignore on search for public IP for system VM. The IPs ignored will be the ones that: were not associated to account [{}]; were not removed yet; and with quarantine end dates after [{}].", owner.getUuid(), new Date());
List<PublicIpQuarantineVO> quarantinedAddresses = publicIpQuarantineDao.listQuarantinedIpAddressesToUser(owner.getId(), new Date());
List<Long> quarantinedAddressesIDs = quarantinedAddresses.stream().map(PublicIpQuarantineVO::getPublicIpAddressId).collect(Collectors.toList());
logger.debug("Found addresses with the following IDs: [{}] that will be ignored when searching for available public IPs.", quarantinedAddressesIDs);
if (CollectionUtils.isNotEmpty(quarantinedAddressesIDs)) {
sc.setParameters("id", quarantinedAddressesIDs.toArray());
}
}
sc.setParameters("dc", dcId);
@ -956,11 +972,11 @@ public class IpAddressManagerImpl extends ManagerBase implements IpAddressManage
// for direct network take ip addresses only from the vlans belonging to the network
if (vlanUse == VlanType.DirectAttached) {
sc.setJoinParameters("vlan", "networkId", guestNetworkId);
errorMessage.append(", network id=" + guestNetworkId);
errorMessage.append(", network id=").append(guestNetworkId);
}
if (requestedGateway != null) {
sc.setJoinParameters("vlan", "vlanGateway", requestedGateway);
errorMessage.append(", requested gateway=" + requestedGateway);
errorMessage.append(", requested gateway=").append(requestedGateway);
}
sc.setJoinParameters("vlan", "type", vlanUse);
@ -970,38 +986,39 @@ public class IpAddressManagerImpl extends ManagerBase implements IpAddressManage
NetworkDetailVO routerIpDetail = _networkDetailsDao.findDetail(network.getId(), ApiConstants.ROUTER_IP);
routerIpAddress = routerIpDetail != null ? routerIpDetail.getValue() : null;
}
if (requestedIp != null) {
sc.addAnd("address", SearchCriteria.Op.EQ, requestedIp);
errorMessage.append(": requested ip " + requestedIp + " is not available");
sc.setParameters("requestedAddress", requestedIp);
errorMessage.append(": requested ip ").append(requestedIp).append(" is not available");
} else if (routerIpAddress != null) {
sc.addAnd("address", Op.NEQ, routerIpAddress);
sc.setParameters("routerAddress", routerIpAddress);
}
boolean ascOrder = ! forSystemVms;
Filter filter = new Filter(IPAddressVO.class, "forSystemVms", ascOrder, 0l, 1l);
Filter filter = new Filter(IPAddressVO.class, "forSystemVms", ascOrder, 0L, 1L);
filter.addOrderBy(IPAddressVO.class,"vlanId", true);
List<IPAddressVO> addrs = new ArrayList<>();
List<IPAddressVO> addresses = new ArrayList<>();
if (forSystemVms) {
// Get Public IPs for system vms in dedicated ranges
sc.setParameters("forSystemVms", true);
if (lockOneRow) {
addrs = _ipAddressDao.lockRows(sc, filter, true);
addresses = _ipAddressDao.lockRows(sc, filter, true);
} else {
addrs = new ArrayList<>(_ipAddressDao.search(sc, null));
addresses = new ArrayList<>(_ipAddressDao.search(sc, null));
}
}
if ((!lockOneRow || (lockOneRow && CollectionUtils.isEmpty(addrs))) &&
if ((!lockOneRow || (lockOneRow && CollectionUtils.isEmpty(addresses))) &&
!(forSystemVms && SystemVmPublicIpReservationModeStrictness.value())) {
sc.setParameters("forSystemVms", false);
// If owner has dedicated Public IP ranges, fetch IP from the dedicated range
// Otherwise fetch IP from the system pool
// Checking if network is null in the case of system VM's. At the time of allocation of IP address to systemVm, no network is present.
if (network == null || !(network.getGuestType() == GuestType.Shared && zone.getNetworkType() == NetworkType.Advanced)) {
List<AccountVlanMapVO> maps = _accountVlanMapDao.listAccountVlanMapsByAccount(owner.getId());
for (AccountVlanMapVO map : maps) {
List<AccountVlanMapVO> accountVlanMaps = _accountVlanMapDao.listAccountVlanMapsByAccount(owner.getId());
for (AccountVlanMapVO map : accountVlanMaps) {
if (vlanDbIds == null || vlanDbIds.contains(map.getVlanDbId()))
dedicatedVlanDbIds.add(map.getVlanDbId());
}
@ -1020,10 +1037,10 @@ public class IpAddressManagerImpl extends ManagerBase implements IpAddressManage
if (!dedicatedVlanDbIds.isEmpty()) {
fetchFromDedicatedRange = true;
sc.setParameters("vlanId", dedicatedVlanDbIds.toArray());
errorMessage.append(", vlanId id=" + Arrays.toString(dedicatedVlanDbIds.toArray()));
errorMessage.append(", vlanId id=").append(Arrays.toString(dedicatedVlanDbIds.toArray()));
} else if (!nonDedicatedVlanDbIds.isEmpty()) {
sc.setParameters("vlanId", nonDedicatedVlanDbIds.toArray());
errorMessage.append(", vlanId id=" + Arrays.toString(nonDedicatedVlanDbIds.toArray()));
errorMessage.append(", vlanId id=").append(Arrays.toString(nonDedicatedVlanDbIds.toArray()));
} else {
if (podId != null) {
InsufficientAddressCapacityException ex = new InsufficientAddressCapacityException("Insufficient address capacity", Pod.class, podId);
@ -1037,13 +1054,13 @@ public class IpAddressManagerImpl extends ManagerBase implements IpAddressManage
}
}
if (lockOneRow) {
addrs = _ipAddressDao.lockRows(sc, filter, true);
addresses = _ipAddressDao.lockRows(sc, filter, true);
} else {
addrs = new ArrayList<>(_ipAddressDao.search(sc, null));
addresses = new ArrayList<>(_ipAddressDao.search(sc, null));
}
// If all the dedicated IPs of the owner are in use fetch an IP from the system pool
if ((!lockOneRow || (lockOneRow && addrs.size() == 0)) && fetchFromDedicatedRange && vlanUse == VlanType.VirtualNetwork) {
if ((!lockOneRow || (lockOneRow && addresses.isEmpty())) && fetchFromDedicatedRange && vlanUse == VlanType.VirtualNetwork) {
// Verify if account is allowed to acquire IPs from the system
boolean useSystemIps = UseSystemPublicIps.valueIn(owner.getId());
if (useSystemIps && !nonDedicatedVlanDbIds.isEmpty()) {
@ -1051,15 +1068,15 @@ public class IpAddressManagerImpl extends ManagerBase implements IpAddressManage
sc.setParameters("vlanId", nonDedicatedVlanDbIds.toArray());
errorMessage.append(", vlanId id=" + Arrays.toString(nonDedicatedVlanDbIds.toArray()));
if (lockOneRow) {
addrs = _ipAddressDao.lockRows(sc, filter, true);
addresses = _ipAddressDao.lockRows(sc, filter, true);
} else {
addrs.addAll(_ipAddressDao.search(sc, null));
addresses.addAll(_ipAddressDao.search(sc, null));
}
}
}
}
if (lockOneRow && addrs.size() == 0) {
if (lockOneRow && addresses.isEmpty()) {
if (podId != null) {
InsufficientAddressCapacityException ex = new InsufficientAddressCapacityException("Insufficient address capacity", Pod.class, podId);
// for now, we hardcode the table names, but we should ideally do a lookup for the tablename from the VO object.
@ -1073,13 +1090,12 @@ public class IpAddressManagerImpl extends ManagerBase implements IpAddressManage
}
if (lockOneRow) {
assert (addrs.size() == 1) : "Return size is incorrect: " + addrs.size();
IpAddress ipAddress = addrs.get(0);
boolean ipCanBeAllocated = canPublicIpAddressBeAllocated(ipAddress, owner);
IPAddressVO allocatableIp = addresses.get(0);
if (!ipCanBeAllocated) {
throw new InsufficientAddressCapacityException(String.format("Failed to allocate public IP address [%s] as it is in quarantine.", ipAddress.getAddress()),
DataCenter.class, dcId);
boolean isPublicIpAllocatable = canPublicIpAddressBeAllocated(allocatableIp, owner);
if (!isPublicIpAllocatable) {
throw new InsufficientAddressCapacityException(String.format("Failed to allocate public IP [%s] as it is in quarantine.", allocatableIp.getAddress()), DataCenter.class, dcId);
}
}
@ -1088,12 +1104,12 @@ public class IpAddressManagerImpl extends ManagerBase implements IpAddressManage
try {
_resourceLimitMgr.checkResourceLimit(owner, ResourceType.public_ip);
} catch (ResourceAllocationException ex) {
logger.warn("Failed to allocate resource of type " + ex.getResourceType() + " for account " + owner);
logger.warn("Failed to allocate resource of type {} for account {}", ex.getResourceType(), owner);
throw new AccountLimitException("Maximum number of public IP addresses for account: " + owner.getAccountName() + " has been exceeded.");
}
}
return addrs;
return addresses;
}
@DB
@ -2558,26 +2574,27 @@ public class IpAddressManagerImpl extends ManagerBase implements IpAddressManage
PublicIpQuarantineVO publicIpQuarantineVO = publicIpQuarantineDao.findByPublicIpAddressId(ip.getId());
if (publicIpQuarantineVO == null) {
logger.debug(String.format("Public IP address [%s] is not in quarantine; therefore, it is allowed to be allocated.", ip));
logger.debug("Public IP address [{}] is not in quarantine; therefore, it is allowed to be allocated.", ip);
return true;
}
if (!isPublicIpAddressStillInQuarantine(publicIpQuarantineVO, new Date())) {
logger.debug(String.format("Public IP address [%s] is no longer in quarantine; therefore, it is allowed to be allocated.", ip));
logger.debug("Public IP address [{}] is no longer in quarantine; therefore, it is allowed to be allocated.", ip);
removePublicIpAddressFromQuarantine(publicIpQuarantineVO.getId(), "IP was removed from quarantine because it was no longer in quarantine.");
return true;
}
Account previousOwner = _accountMgr.getAccount(publicIpQuarantineVO.getPreviousOwnerId());
if (Objects.equals(previousOwner.getUuid(), newOwner.getUuid())) {
logger.debug(String.format("Public IP address [%s] is in quarantine; however, the Public IP previous owner [%s] is the same as the new owner [%s]; therefore the IP" +
" can be allocated. The public IP address will be removed from quarantine.", ip, previousOwner, newOwner));
logger.debug("Public IP address [{}] is in quarantine; however, the Public IP previous owner [{}] is the same as the new owner [{}]; therefore the IP" +
" can be allocated. The public IP address will be removed from quarantine.", ip, previousOwner, newOwner);
removePublicIpAddressFromQuarantine(publicIpQuarantineVO.getId(), "IP was removed from quarantine because it has been allocated by the previous owner");
return true;
}
logger.error(String.format("Public IP address [%s] is in quarantine and the previous owner [%s] is different than the new owner [%s]; therefore, the IP cannot be " +
"allocated.", ip, previousOwner, newOwner));
logger.error("Public IP address [{}] is in quarantine and the previous owner [{}] is different than the new owner [{}]; therefore, the IP cannot be " +
"allocated.", ip, previousOwner, newOwner);
return false;
}
@ -2628,7 +2645,7 @@ public class IpAddressManagerImpl extends ManagerBase implements IpAddressManage
publicIpQuarantineVO.setRemovalReason(removalReason);
publicIpQuarantineVO.setRemoverAccountId(removerAccountId);
logger.debug(String.format("Removing public IP Address [%s] from quarantine by updating the removed date to [%s].", ipAddress, removedDate));
logger.debug("Removing public IP Address [{}] from quarantine by updating the removed date to [{}].", ipAddress, removedDate);
publicIpQuarantineDao.persist(publicIpQuarantineVO);
}

View File

@ -1389,20 +1389,19 @@ public class AccountManagerImpl extends ManagerBase implements AccountManager, M
final String accountNameFinal = accountName;
final Long domainIdFinal = domainId;
final String accountUUIDFinal = accountUUID;
final String resolvedAccountUUID = accountUUID != null ? accountUUID : UUID.randomUUID().toString();
// Check role escalation before the transaction this is a read-only check
// that iterates all API commands and doesn't need a write transaction open.
AccountVO requestedAccount = new AccountVO(accountNameFinal, domainIdFinal, networkDomain, accountType, roleId, resolvedAccountUUID);
checkRoleEscalation(getCurrentCallingAccount(), requestedAccount);
Pair<Long, Account> pair = Transaction.execute(new TransactionCallback<>() {
@Override
public Pair<Long, Account> doInTransaction(TransactionStatus status) {
// create account
String accountUUID = accountUUIDFinal;
if (accountUUID == null) {
accountUUID = UUID.randomUUID().toString();
}
AccountVO account = createAccount(accountNameFinal, accountType, roleId, domainIdFinal, networkDomain, details, accountUUID);
AccountVO account = createAccount(accountNameFinal, accountType, roleId, domainIdFinal, networkDomain, details, resolvedAccountUUID);
long accountId = account.getId();
checkRoleEscalation(getCurrentCallingAccount(), account);
// create the first user for the account
UserVO user = createUser(accountId, userName, password, firstName, lastName, email, timezone, userUUID, source);

View File

@ -156,7 +156,6 @@ import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.collections.MapUtils;
import org.apache.commons.lang.math.NumberUtils;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.builder.ToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle;
import org.jetbrains.annotations.NotNull;
@ -377,6 +376,7 @@ import com.cloud.utils.DateUtil;
import com.cloud.utils.Journal;
import com.cloud.utils.NumbersUtil;
import com.cloud.utils.Pair;
import com.cloud.utils.StringUtils;
import com.cloud.utils.component.ComponentContext;
import com.cloud.utils.component.ManagerBase;
import com.cloud.utils.concurrency.NamedThreadFactory;
@ -890,10 +890,10 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir
}
private boolean resetVMPasswordInternal(Long vmId, String password) throws ResourceUnavailableException, InsufficientCapacityException {
Long userId = CallContext.current().getCallingUserId();
long userId = CallContext.current().getCallingUserId();
VMInstanceVO vmInstance = _vmDao.findById(vmId);
if (password == null || password.equals("")) {
if (StringUtils.isEmpty(password)) {
return false;
}
@ -1078,7 +1078,7 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir
}
private boolean resetVMSSHKeyInternal(Long vmId, String sshPublicKeys, String keypairnames) throws ResourceUnavailableException, InsufficientCapacityException {
Long userId = CallContext.current().getCallingUserId();
long userId = CallContext.current().getCallingUserId();
VMInstanceVO vmInstance = _vmDao.findById(vmId);
VMTemplateVO template = _templateDao.findByIdIncludingRemoved(vmInstance.getTemplateId());
@ -1250,7 +1250,7 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir
if (vmInstance == null) {
throw new InvalidParameterValueException("unable to find an Instance with id " + vmId);
} else if (!(vmInstance.getState().equals(State.Stopped))) {
throw new InvalidParameterValueException("Unable to upgrade Instance " + vmInstance.toString() + " " + " in state " + vmInstance.getState()
throw new InvalidParameterValueException("Unable to upgrade Instance " + vmInstance + " " + " in state " + vmInstance.getState()
+ "; make sure the Instance is stopped");
}
@ -1743,7 +1743,7 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir
oldNetworkOfferingId = oldDefaultNetwork.getNetworkOfferingId();
}
NicVO existingVO = _nicDao.findById(existing.id);
Integer chosenID = nic.getDeviceId();
int chosenID = nic.getDeviceId();
Integer existingID = existing.getDeviceId();
Network newdefault = null;
@ -2172,14 +2172,14 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir
// Check vm flag
if (!vmInstance.isDynamicallyScalable()) {
throw new CloudRuntimeException(String.format("Unable to scale %s as it does not have tools to support dynamic scaling.", vmInstance.toString()));
throw new CloudRuntimeException(String.format("Unable to scale %s as it does not have tools to support dynamic scaling.", vmInstance));
}
// Check disable threshold for cluster is not crossed
HostVO host = _hostDao.findById(vmInstance.getHostId());
_hostDao.loadDetails(host);
if (_capacityMgr.checkIfClusterCrossesThreshold(host.getClusterId(), cpuDiff, memoryDiff)) {
throw new CloudRuntimeException(String.format("Unable to scale %s due to insufficient resources.", vmInstance.toString()));
throw new CloudRuntimeException(String.format("Unable to scale %s due to insufficient resources.", vmInstance));
}
while (retry-- != 0) { // It's != so that it can match -1.
@ -2227,7 +2227,7 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir
success = true;
return success;
} catch (InsufficientCapacityException | ResourceUnavailableException | ConcurrentOperationException e) {
logger.error(String.format("Unable to scale %s due to [%s].", vmInstance.toString(), e.getMessage()), e);
logger.error(String.format("Unable to scale %s due to [%s].", vmInstance, e.getMessage()), e);
} finally {
if (!success) {
// Decrement CPU and Memory count accordingly.
@ -4545,7 +4545,7 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir
}
NetworkOffering ntwkOffering = _networkOfferingDao.findById(network.getNetworkOfferingId());
Long physicalNetworkId = _networkModel.findPhysicalNetworkId(zone.getId(), ntwkOffering.getTags(), ntwkOffering.getTrafficType());
long physicalNetworkId = _networkModel.findPhysicalNetworkId(zone.getId(), ntwkOffering.getTags(), ntwkOffering.getTrafficType());
String provider = _ntwkSrvcDao.getProviderForServiceInNetwork(network.getId(), Service.Connectivity);
if (!_networkModel.isProviderEnabledInPhysicalNetwork(physicalNetworkId, provider)) {
@ -4763,7 +4763,7 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir
}
if (customParameters.containsKey(VmDetailConstants.ROOT_DISK_SIZE)) {
Long rootDiskSize = NumbersUtil.parseLong(customParameters.get(VmDetailConstants.ROOT_DISK_SIZE), -1);
long rootDiskSize = NumbersUtil.parseLong(customParameters.get(VmDetailConstants.ROOT_DISK_SIZE), -1);
if (rootDiskSize <= 0) {
throw new InvalidParameterValueException("Root disk size should be a positive number.");
}
@ -4882,7 +4882,7 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir
final Map<String, Map<Integer, String>> extraDhcpOptionMap, final Map<Long, DiskOffering> dataDiskTemplateToDiskOfferingMap,
final Map<String, String> userVmOVFPropertiesMap, final VirtualMachine.PowerState powerState, final boolean dynamicScalingEnabled, String vmType, final Long rootDiskOfferingId, String sshkeypairs,
List<VmDiskInfo> dataDiskInfoList, Volume volume, Snapshot snapshot) throws InsufficientCapacityException {
Long selectedGuestOsId = guestOsId != null ? guestOsId : template.getGuestOSId();
long selectedGuestOsId = guestOsId != null ? guestOsId : template.getGuestOSId();
UserVmVO vm = new UserVmVO(id, instanceName, displayName, template.getId(), hypervisorType, selectedGuestOsId, offering.isOfferHA(),
offering.getLimitCpuUse(), owner.getDomainId(), owner.getId(), userId, offering.getId(), userData, userDataId, userDataDetails, hostName);
vm.setUuid(uuidName);
@ -5441,7 +5441,7 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir
if (dc.getDns2() != null) {
buf.append(" dns2=").append(dc.getDns2());
}
logger.info("cmdline details: "+ buf.toString());
logger.info("cmdline details: "+ buf);
}
@Override
@ -5701,7 +5701,7 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir
public UserVm stopVirtualMachine(long vmId, boolean forced) throws ConcurrentOperationException {
// Input validation
Account caller = CallContext.current().getCallingAccount();
Long userId = CallContext.current().getCallingUserId();
long userId = CallContext.current().getCallingUserId();
// if account is removed, return error
if (caller != null && caller.getRemoved() != null) {
@ -6473,7 +6473,13 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir
}
_accountMgr.checkAccess(caller, null, true, snapshot);
VolumeInfo volumeOfSnapshot = getVolume(snapshot.getVolumeId(), templateId, true);
templateId = volumeOfSnapshot.getTemplateId();
if (volumeOfSnapshot != null) {
templateId = volumeOfSnapshot.getTemplateId();
} else if (templateId == null) {
throw new InvalidParameterValueException(
"Could not determine template from snapshot id=" + cmd.getSnapshotId() +
"; the source volume no longer exists. Please specify a templateId.");
}
}
VirtualMachineTemplate template = null;
@ -6755,7 +6761,9 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir
private VolumeInfo getVolume(long id, Long templateId, boolean isSnapshot) {
VolumeInfo volume = volFactory.getVolume(id);
if (volume != null) {
if (volume.getDataStore() == null || !ScopeType.ZONE.equals(volume.getDataStore().getScope().getScopeType())) {
if (!isSnapshot
&& (volume.getDataStore() == null
|| !ScopeType.ZONE.equals(volume.getDataStore().getScope().getScopeType()))) {
throw new InvalidParameterValueException("Deployment of virtual machine is supported only for Zone-wide storage pools");
}
checkIfVolumeTemplateIsTheSameAsTheProvided(volume, templateId);
@ -6971,7 +6979,7 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir
} else if (hypervisorType.equals(HypervisorType.VMware)) {
persistExtraConfigVmware(decodedUrl, vm);
} else {
String msg = String.format("This hypervisor %s is not supported for use with this feature", hypervisorType.toString());
String msg = String.format("This hypervisor %s is not supported for use with this feature", hypervisorType);
throw new CloudRuntimeException(msg);
}
}
@ -7317,7 +7325,7 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir
vm.setLastHostId(null); // Last host does not have higher priority in vm migration
final ServiceOfferingVO offering = serviceOfferingDao.findById(vm.getId(), vm.getServiceOfferingId());
final VirtualMachineProfile profile = new VirtualMachineProfileImpl(vm, null, offering, null, null);
final Long srcHostId = srcHost.getId();
final long srcHostId = srcHost.getId();
final Host host = _hostDao.findById(srcHostId);
ExcludeList excludes = new ExcludeList();
excludes.addHost(srcHostId);
@ -7970,7 +7978,7 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir
Long domainId = cmd.getDomainId();
Long projectId = cmd.getProjectId();
Long oldAccountId = vm.getAccountId();
long oldAccountId = vm.getAccountId();
String newAccountName = cmd.getAccountName();
final Account oldAccount = _accountService.getActiveAccountById(oldAccountId);
final Account newAccount = _accountMgr.finalizeOwner(caller, newAccountName, domainId, projectId);
@ -8599,7 +8607,7 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir
protected void addDefaultSecurityGroupToSecurityGroupIdList(Account newAccount, List<Long> securityGroupIdList) {
logger.debug("Adding default security group to security group list if not already in it.");
Long newAccountId = newAccount.getId();
long newAccountId = newAccount.getId();
SecurityGroup defaultGroup = _securityGroupMgr.getDefaultSecurityGroup(newAccountId);
boolean defaultGroupPresent = false;
@ -8746,7 +8754,7 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir
logger.trace("Creating an applicable network to create the VM.");
NetworkVO defaultNetwork;
Long zoneId = zone.getId();
long zoneId = zone.getId();
Account caller = CallContext.current().getCallingAccount();
NetworkOfferingVO requiredOffering = getOfferingWithRequiredAvailabilityForNetworkCreation();
String requiredOfferingTags = requiredOffering.getTags();
@ -9506,7 +9514,7 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir
}
logger.debug("Found {} no. of volumes of type {} for vm with VM ID {}", listVolumes.size(), type, vm);
for (VolumeVO volume : listVolumes) {
Long volumeId = volume.getId();
long volumeId = volume.getId();
logger.debug("Checking status of snapshots for Volume: {}", volume);
List<SnapshotVO> ongoingSnapshots = _snapshotDao.listByStatus(volumeId, Snapshot.State.Creating, Snapshot.State.CreatedOnPrimary, Snapshot.State.BackingUp);
int ongoingSnapshotsCount = ongoingSnapshots.size();
@ -9525,12 +9533,12 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir
for (VolumeVO volume : volumes) {
if (volume.getInstanceId() == null || vmId != volume.getInstanceId() || volume.getVolumeType() != Volume.Type.DATADISK) {
sb.append(volume.toString() + "; ");
sb.append(volume + "; ");
}
}
if (!StringUtils.isEmpty(sb.toString())) {
throw new InvalidParameterValueException("The following supplied volumes are not DATADISK attached to the VM: " + sb.toString());
throw new InvalidParameterValueException("The following supplied volumes are not DATADISK attached to the VM: " + sb);
}
}
@ -9538,7 +9546,7 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir
for (VolumeVO volume : volumes) {
if (!(volume.getVolumeType() == Volume.Type.ROOT || volume.getVolumeType() == Volume.Type.DATADISK)) {
throw new InvalidParameterValueException("Please specify volume of type " + Volume.Type.DATADISK.toString() + " or " + Volume.Type.ROOT.toString());
throw new InvalidParameterValueException("Please specify volume of type " + Volume.Type.DATADISK + " or " + Volume.Type.ROOT);
}
if (volume.isDeleteProtection()) {
throw new InvalidParameterValueException(String.format(
@ -9632,7 +9640,7 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir
final String uuidName = _uuidMgr.generateUuid(UserVm.class, null);
final Host lastHost = powerState != VirtualMachine.PowerState.PowerOn ? host : null;
final Boolean dynamicScalingEnabled = checkIfDynamicScalingCanBeEnabled(null, serviceOffering, template, zone.getId());
final boolean dynamicScalingEnabled = checkIfDynamicScalingCanBeEnabled(null, serviceOffering, template, zone.getId());
return commitUserVm(true, zone, host, lastHost, template, hostName, displayName, owner,
null, null, userData, null, null, isDisplayVm, keyboard,
accountId, userId, serviceOffering, template.getFormat().equals(ImageFormat.ISO), guestOsId, sshPublicKeys, networkNicMap,
@ -9694,7 +9702,7 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir
}
private void checkRootDiskSizeAgainstBackup(Long instanceVolumeSize,DiskOffering rootDiskOffering, Long backupVolumeSize) {
Long instanceRootDiskSize = rootDiskOffering.isCustomized() ? instanceVolumeSize : rootDiskOffering.getDiskSize() / GiB_TO_BYTES;
long instanceRootDiskSize = rootDiskOffering.isCustomized() ? instanceVolumeSize : rootDiskOffering.getDiskSize() / GiB_TO_BYTES;
if (instanceRootDiskSize < backupVolumeSize) {
throw new InvalidParameterValueException(
String.format("Instance volume root disk size %d[GiB] cannot be less than the backed-up volume size %d[GiB].",
@ -9771,7 +9779,7 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir
Long size = cmd.getSize();
Long diskOfferingId = cmd.getDiskOfferingId();
Boolean isIso = template.getFormat().equals(ImageFormat.ISO);
boolean isIso = template.getFormat().equals(ImageFormat.ISO);
if (diskOfferingId != null) {
if (!isIso) {
throw new InvalidParameterValueException(ApiConstants.DISK_OFFERING_ID + " parameter is supported for creating instance from backup only for ISO. For creating VMs with templates, please use the parameter " + ApiConstants.DATADISKS_DETAILS);

View File

@ -356,6 +356,7 @@ public class IpAddressManagerTest {
Mockito.when(ipAddressMock.getId()).thenReturn(dummyID);
Mockito.when(publicIpQuarantineDaoMock.findByPublicIpAddressId(Mockito.anyLong())).thenReturn(publicIpQuarantineVOMock);
Mockito.doReturn(false).when(ipAddressManager).isPublicIpAddressStillInQuarantine(Mockito.any(PublicIpQuarantineVO.class), Mockito.any(Date.class));
Mockito.doNothing().when(ipAddressManager).removePublicIpAddressFromQuarantine(Mockito.anyLong(), Mockito.anyString());
boolean result = ipAddressManager.canPublicIpAddressBeAllocated(ipAddressMock, newOwnerMock);

File diff suppressed because it is too large Load Diff

View File

@ -104,9 +104,10 @@ CP=./
CP=${CP}$PATHSEP$CATALINA_HOME/conf
# Add mysql jar from mysql-connector-java package to CP
# Add mysql jar from mysql-connector-j package to CP
# for Jenkins
CP=${CP}${PATHSEP}/usr/share/java/mysql-connector-java.jar
MYSQL_CONNECTOR_VERSION = '8.4.0'
CP=${CP}${PATHSEP}/usr/share/java/mysql-connector-j-${MYSQL_CONNECTOR_VERSION}.jar
for file in $CATALINA_HOME/webapps/client/WEB-INF/lib/*.jar
do

View File

@ -232,7 +232,7 @@ class CsNetfilters(object):
if hook == "input" or hook == "output":
CsHelper.execute("nft add rule %s %s %s icmpv6 type { echo-request, echo-reply, \
nd-neighbor-solicit, nd-router-advert, nd-neighbor-advert } accept" % (address_family, table, chain))
elif hook == "forward":
if hook == "input" or hook == "forward":
CsHelper.execute("nft add rule %s %s %s ct state established,related accept" % (address_family, table, chain))
def add_ip4_chain(self, address_family, table, chain, hook, action):

View File

@ -85,7 +85,7 @@ class TestQuarantineIPs(cloudstackTestCase):
self.services["root_admin"]["roletype"])
"""
Set public.ip.address.quarantine.duration to 60 minutes
Set public.ip.address.quarantine.duration to 1 minute
"""
update_configuration_cmd = updateConfiguration.updateConfigurationCmd()
update_configuration_cmd.name = "public.ip.address.quarantine.duration"
@ -168,8 +168,7 @@ class TestQuarantineIPs(cloudstackTestCase):
zoneid=self.zone.id,
vpcid=root_vpc.id,
ipaddress=ip_address)
self.assertIn(f"Failed to allocate public IP address [{ip_address}] as it is in quarantine.",
exception.exception.errorMsg)
self.assertIn("errorCode: 533", exception.exception.errorMsg)
# Owner should be able to allocate its IP in quarantine
public_ip = PublicIPAddress.create(self.domain_admin_apiclient,
@ -267,8 +266,7 @@ class TestQuarantineIPs(cloudstackTestCase):
zoneid=self.zone.id,
networkid=root_network.id,
ipaddress=ip_address)
self.assertIn(f"Failed to allocate public IP address [{ip_address}] as it is in quarantine.",
exception.exception.errorMsg)
self.assertIn("errorCode: 533", exception.exception.errorMsg)
# Owner should be able to allocate its IP in quarantine
public_ip = PublicIPAddress.create(self.domain_admin_apiclient,

View File

@ -58,7 +58,7 @@ RUN mvn -Pdeveloper -Dsimulator -DskipTests clean install
RUN find /var/lib/mysql -type f -exec touch {} \; && \
(/usr/bin/mysqld_safe &) && \
sleep 5; \
mysql -e "ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password by ''" --connect-expired-password; \
mysql -e "ALTER USER 'root'@'localhost' IDENTIFIED WITH caching_sha2_password by ''" --connect-expired-password; \
mvn -Pdeveloper -pl developer -Ddeploydb; \
mvn -Pdeveloper -pl developer -Ddeploydb-simulator; \
MARVIN_FILE=`find /root/tools/marvin/dist/ -name "Marvin*.tar.gz"`; \

View File

@ -46,7 +46,7 @@ setup(name="Marvin",
"marvin.sandbox.basic"],
license="LICENSE.txt",
install_requires=[
"mysql-connector-python <= 8.0.30",
"mysql-connector-python <= 8.4.0",
"requests >= 2.2.1",
"paramiko >= 1.13.0",
"nose >= 1.3.3",

View File

@ -3077,6 +3077,7 @@
"message.action.unmanage.volume": "Please confirm that you want to unmanage the Volume.",
"message.action.unmanage.volumes": "Please confirm that you want to unmanage the Volumes.",
"message.action.vmsnapshot.delete": "Please confirm that you want to delete this Instance Snapshot. <br>Please notice that the Instance will be paused before the Snapshot deletion, and resumed after deletion, if it runs on KVM.",
"message.action.vmsnapshot.disk-only.delete": "Please confirm that you want to delete this Instance Snapshot.",
"message.activate.project": "Are you sure you want to activate this project?",
"message.add.custom.action.parameters": "Parameters to be made available while running the custom action.",
"message.add.egress.rule.failed": "Adding new egress rule failed.",
@ -4167,6 +4168,7 @@
"message.warn.importing.instance.without.nic": "WARNING: This Instance is being imported without NICs and many Network resources will not be available. Consider creating a NIC via vCenter before importing or as soon as the Instance is imported. For KVM host, allocate a NIC to Instance after import.",
"message.warn.select.template": "Please select a Template for Registration.",
"message.warn.zone.mtu.update": "Please note that this limit won't affect pre-existing Network's MTU settings",
"message.warn.vpc.offerings": "VPC offerings will only be shown if the selected account has at least one VPC.",
"message.webhook.deliveries.time.filter": "Webhook deliveries list can be filtered based on date-time. Select 'Custom' for specifying start and end date range.",
"message.webhook.filter.add": "Webhook deliveries can be controlled using filters (currently by Event type). Please select the parameters to add to the applied filters list.",
"message.zone.creation.complete": "Zone creation complete.",

View File

@ -2765,9 +2765,9 @@
"message.action.unmanage.instance": "Por favor, confirme que voc\u00ea deseja parar de gerenciar a inst\u00e2ncia.",
"message.action.unmanage.instances": "Por favor, confirme que voc\u00ea deseja parar de gerenciar as inst\u00e2ncias.",
"message.action.unmanage.virtualmachine": "Por favor, confirme que voc\u00ea deseja parar de gerenciar a VM.",
"message.action.vmsnapshot.delete": "Por favor, confirme que voc\u00ea deseja excluir esta snapshot de VM.",
"message.action.unmanage.volume": "Por favor, confirme que voc\u00ea deseja parar de gerenciar o Volume.",
"message.action.unmanage.volumes": "Por favor, confirme que voc\u00ea deseja parar de gerenciar os Volumes.",
"message.action.vmsnapshot.delete": "Por favor, confirme que voc\u00ea deseja excluir esta snapshot de VM. <br>Saiba que caso a instância execute em um hypervisor KVM, ela será pausada antes da deleç\u00e3o, e continuada após a deleç\u00e3o.",
"message.action.vmsnapshot.disk-only.delete": "Por favor, confirme que voc\u00ea deseja excluir esta snapshot de VM.",
"message.activate.project": "Voc\u00ea tem certeza que deseja ativar este projeto?",
"message.add.egress.rule.failed": "Falha ao adicionar uma nova regra de sa\u00edda",

View File

@ -536,7 +536,12 @@ export default {
api: 'deleteVMSnapshot',
icon: 'delete-outlined',
label: 'label.action.vmsnapshot.delete',
message: 'message.action.vmsnapshot.delete',
message: (record) => {
if (record.hypervisor !== 'KVM' || record.type === 'Disk') {
return 'message.action.vmsnapshot.disk-only.delete'
}
return 'message.action.vmsnapshot.delete'
},
dataView: true,
show: (record) => { return ['Ready', 'Expunging', 'Error'].includes(record.state) },
args: ['vmsnapshotid'],

View File

@ -214,7 +214,7 @@
:spinning="actionLoading"
v-ctrl-enter="handleSubmit"
>
<span v-if="currentAction.message">
<span v-if="currentAction.messageString">
<div v-if="selectedRowKeys.length > 0">
<a-alert
v-if="['delete-outlined', 'DeleteOutlined', 'poweroff-outlined', 'PoweroffOutlined'].includes(currentAction.icon)"
@ -226,7 +226,7 @@
style="padding-left: 5px"
v-html="`<b>${selectedRowKeys.length} ` + $t('label.items.selected') + `. </b>`"
/>
<span v-html="currentAction.message" />
<span v-html="currentAction.messageString" />
</template>
</a-alert>
<a-alert
@ -238,14 +238,14 @@
v-if="selectedRowKeys.length > 0"
v-html="`<b>${selectedRowKeys.length} ` + $t('label.items.selected') + `. </b>`"
/>
<span v-html="currentAction.message" />
<span v-html="currentAction.messageString" />
</template>
</a-alert>
</div>
<div v-else>
<a-alert type="warning">
<template #message>
<span v-html="currentAction.message" />
<span v-html="currentAction.messageString" />
</template>
</a-alert>
</div>
@ -1384,9 +1384,11 @@ export default {
this.currentAction.paramFilters = []
if ('message' in action) {
if (typeof action.message === 'function') {
action.message = action.message(action.resource)
action.messageString = action.message(action.resource)
} else {
action.messageString = action.message
}
action.message = Array.isArray(action.message) ? this.$t(...action.message) : this.$t(action.message)
action.messageString = Array.isArray(action.messageString) ? this.$t(...action.messageString) : this.$t(action.messageString)
}
this.getArgs(action, isGroupAction, paramFields)
this.getFilters(action, isGroupAction, paramFields)

View File

@ -96,6 +96,11 @@
{{ opt.displaytext || opt.name || opt.description }}
</a-select-option>
</a-select>
<a-alert type="warning" v-if="!this.hasVPC">
<template #message>
<span v-html="$t('message.warn.vpc.offerings')"/>
</template>
</a-alert>
</a-form-item>
<a-form-item ref="asnumber" name="asnumber" v-if="isASNumberRequired()">
<template #label>
@ -378,7 +383,8 @@ export default {
setMTU: false,
asNumberLoading: false,
selectedAsNumber: 0,
asNumbersZone: []
asNumbersZone: [],
hasVPC: true
}
},
watch: {
@ -526,13 +532,17 @@ export default {
if (this.vpc !== null) { // from VPC section
this.fetchNetworkOfferingData(true)
} else { // from guest network section
var params = {}
const params = {
account: this.owner.account,
projectid: this.owner.projectid,
domainid: this.owner.domainid
}
this.networkOfferingLoading = true
if ('listVPCs' in this.$store.getters.apis) {
getAPI('listVPCs', params).then(json => {
const listVPCs = json.listvpcsresponse.vpc
var vpcAvailable = this.arrayHasItems(listVPCs)
if (vpcAvailable === false) {
this.hasVPC = this.arrayHasItems(listVPCs)
if (!this.hasVPC) {
this.fetchNetworkOfferingData(false)
} else {
this.fetchNetworkOfferingData()
@ -545,7 +555,7 @@ export default {
},
fetchNetworkOfferingData (forVpc) {
this.networkOfferingLoading = true
var params = {
const params = {
zoneid: this.selectedZone.id,
guestiptype: 'Isolated',
state: 'Enabled'
@ -588,7 +598,7 @@ export default {
},
fetchVpcData () {
this.vpcLoading = true
var params = {
const params = {
listAll: true,
details: 'min'
}

View File

@ -289,7 +289,7 @@ public class UsageSanityChecker {
}
/**
* usage something like: /usr/bin/java -Xmx2G -cp /usr/share/cloudstack-usage/*:/usr/share/cloudstack-usage/lib/*:/usr/share/cloudstack-mysql-ha/lib/*:/etc/cloudstack/usage:/usr/share/java/mysql-connector-java.jar:/usr/share/cloudstack-common com.cloud.usage.UsageSanityChecker
* usage something like: /usr/bin/java -Xmx2G -cp /usr/share/cloudstack-usage/*:/usr/share/cloudstack-usage/lib/*:/usr/share/cloudstack-mysql-ha/lib/*:/etc/cloudstack/usage:/usr/share/cloudstack-common com.cloud.usage.UsageSanityChecker
* @param args none
*/
public static void main(String[] args) {