This is an automated email from the ASF dual-hosted git repository. dahn pushed a commit to branch 4.20 in repository https://gitbox.apache.org/repos/asf/cloudstack.git
commit b7f0aac5194b3df3d67ce6ece0beecdfa04cce44 Merge: ac19379c967 ed1b145a3a0 Author: Daan Hoogland <d...@onecht.net> AuthorDate: Fri Dec 20 14:34:39 2024 +0100 Merge branch '4.19' into 4.20 .../main/java/com/cloud/vm/VmDetailConstants.java | 1 + .../java/com/cloud/agent/manager/AgentAttache.java | 10 +- packaging/el8/cloud.spec | 3 + packaging/el8/filelimit.conf | 20 ++++ .../kvm/resource/LibvirtComputingResource.java | 89 +++++++++------- .../LibvirtGetVmIpAddressCommandWrapper.java | 3 + .../LibvirtPrepareForMigrationCommandWrapper.java | 2 +- ...tupDirectDownloadCertificateCommandWrapper.java | 4 + .../wrapper/LibvirtStartCommandWrapper.java | 2 +- .../kvm/storage/IscsiAdmStorageAdaptor.java | 2 +- .../kvm/storage/IscsiAdmStoragePool.java | 2 +- .../kvm/storage/KVMStoragePoolManager.java | 9 +- .../kvm/storage/LibvirtStorageAdaptor.java | 2 +- .../kvm/storage/ManagedNfsStorageAdaptor.java | 2 +- .../kvm/storage/MultipathSCSIAdapterBase.java | 2 +- .../hypervisor/kvm/storage/MultipathSCSIPool.java | 2 +- .../kvm/storage/ScaleIOStorageAdaptor.java | 4 +- .../hypervisor/kvm/storage/ScaleIOStoragePool.java | 2 +- .../hypervisor/kvm/storage/StorageAdaptor.java | 11 +- .../kvm/resource/LibvirtComputingResourceTest.java | 10 +- .../kvm/storage/ScaleIOStoragePoolTest.java | 2 +- .../CitrixGetVmIpAddressCommandWrapper.java | 15 ++- plugins/storage/volume/linstor/CHANGELOG.md | 12 +++ .../kvm/storage/LinstorStorageAdaptor.java | 33 ++++-- .../hypervisor/kvm/storage/LinstorStoragePool.java | 42 ++++++-- .../kvm/storage/StorPoolStorageAdaptor.java | 2 +- .../kvm/storage/StorPoolStoragePool.java | 2 +- .../network/element/ConfigDriveNetworkElement.java | 43 ++++++-- .../network/element/VirtualRouterElement.java | 2 +- .../java/com/cloud/user/AccountManagerImpl.java | 41 ++++--- .../main/java/com/cloud/vm/UserVmManagerImpl.java | 12 +-- .../direct/download/DirectDownloadManagerImpl.java | 11 +- .../com/cloud/user/AccountManagerImplTest.java | 118 ++++++++++++++++++++- systemvm/debian/opt/cloud/bin/configure.py | 2 +- .../main/java/com/cloud/utils/net/NetUtils.java | 10 +- 35 files changed, 400 insertions(+), 129 deletions(-) diff --cc packaging/el8/cloud.spec index f9d6fd1ce87,00000000000..eb03cfe0df4 mode 100644,000000..100644 --- a/packaging/el8/cloud.spec +++ b/packaging/el8/cloud.spec @@@ -1,705 -1,0 +1,708 @@@ +# 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} + +# 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 <d...@cloudstack.apache.org> +Packager: Apache CloudStack <d...@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 + +BuildRequires: (java-11-openjdk-devel or java-17-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 +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 +Requires: (openssh-clients or openssh) +Requires: (nfs-utils or nfs-client) +Requires: iproute +Requires: wget +Requires: mysql +Requires: sudo +Requires: /sbin/service +Requires: /sbin/chkconfig +Requires: /usr/bin/ssh-keygen +Requires: (genisoimage or mkisofs) +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-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 ^(libuuid\\.so\\.1|/usr/bin/python)$ + +%package agent +Summary: CloudStack Agent for KVM hypervisors +Requires: (openssh-clients or openssh) +Requires: java-17-openjdk +Requires: tzdata-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: (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 qemu-tools) +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 +Requires: tzdata-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/el8/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/el8/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}%{_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 +CMK_REL=$(wget -O - "https://api.github.com/repos/apache/cloudstack-cloudmonkey/releases" 2>/dev/null | jq -r '.[0].tag_name') +wget https://github.com/apache/cloudstack-cloudmonkey/releases/download/$CMK_REL/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 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/el8/cloud-ipallocator.rc ${RPM_BUILD_ROOT}%{_initrddir}/%{name}-ipallocator +install -D packaging/el8/cloud.limits ${RPM_BUILD_ROOT}%{_sysconfdir}/security/limits.d/cloud ++install -D packaging/el8/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 + +# 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/md5sum.txt + +# 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 +wget -P ${RPM_BUILD_ROOT}%{_datadir}/%{name}-management/setup/wheel https://files.pythonhosted.org/packages/ee/ff/48bde5c0f013094d729fe4b0316ba2a24774b3ff1c52d924a8a4cb04078a/six-1.15.0-py2.py3-none-any.whl +wget -P ${RPM_BUILD_ROOT}%{_datadir}/%{name}-management/setup/wheel https://files.pythonhosted.org/packages/e9/93/4860cebd5ad3ff2664ad3c966490ccb46e3b88458b2095145bca11727ca4/setuptools-47.3.1-py3-none-any.whl +wget -P ${RPM_BUILD_ROOT}%{_datadir}/%{name}-management/setup/wheel https://files.pythonhosted.org/packages/32/27/1141a8232723dcb10a595cc0ce4321dcbbd5215300bf4acfc142343205bf/protobuf-3.19.6-py2.py3-none-any.whl +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 + +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/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 +pip3 install %{_datadir}/%{name}-management/setup/wheel/six-1.15.0-py2.py3-none-any.whl %{_datadir}/%{name}-management/setup/wheel/setuptools-47.3.1-py3-none-any.whl %{_datadir}/%{name}-management/setup/wheel/protobuf-3.19.6-py2.py3-none-any.whl %{_datadir}/%{name}-management/setup/wheel/mysql_connector_python-8.0.31-py2.py3-none-any.whl + +/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 + +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 configs 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 + +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 +%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/setup/*.sql +%{_datadir}/%{name}-management/setup/*.sh +%{_datadir}/%{name}-management/setup/server-setup.xml +%{_datadir}/%{name}-management/webapp/* +%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 + +%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 <ro...@apache.org> 4.18.0 +- Add support for EL9 + +* Fri Oct 14 2022 Daan Hoogland <daan.hoogl...@gmail.com> 4.18.0 +- initialising sanity check pointer file + +* Tue Jun 29 2021 David Jumani <dj.davidjumani1...@gmail.com> 4.16.0 +- Adding SUSE 15 support + +* Thu Apr 30 2015 Rohit Yadav <bhais...@apache.org> 4.6.0 +- Remove awsapi package + +* Wed Nov 19 2014 Hugo Trippaers <h...@apache.org> 4.6.0 +- Create a specific spec for CentOS 7 + +* Fri Jul 4 2014 Hugo Trippaers <h...@apache.org> 4.5.0 +- Add a package for the mysql ha module + +* Fri Oct 5 2012 Hugo Trippaers <h...@apache.org> 4.1.0 +- new style spec file diff --cc packaging/el8/filelimit.conf index 00000000000,7a8a835e3fe..7a8a835e3fe mode 000000,100644..100644 --- a/packaging/el8/filelimit.conf +++ b/packaging/el8/filelimit.conf diff --cc plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/LibvirtComputingResource.java index 7374d46edd6,f9d56f8301d..ca3395be5dc --- a/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/LibvirtComputingResource.java +++ b/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/LibvirtComputingResource.java @@@ -1031,7 -1016,7 +1031,7 @@@ public class LibvirtComputingResource e hostHealthCheckScriptPath = AgentPropertiesFileHandler.getPropertyValue(AgentProperties.HEALTH_CHECK_SCRIPT_PATH); if (StringUtils.isNotBlank(hostHealthCheckScriptPath) && !new File(hostHealthCheckScriptPath).exists()) { - logger.info(String.format("Unable to find the host health check script at: %s, " + - s_logger.info(String.format("Unable to find the host health check script at: %s, " + ++ LOGGER.info(String.format("Unable to find the host health check script at: %s, " + "discarding it", hostHealthCheckScriptPath)); } @@@ -2796,11 -2781,11 +2796,11 @@@ if (hostCpuMaxCapacity > 0) { int updatedCpuShares = (int) Math.ceil((requestedCpuShares * CGROUP_V2_UPPER_LIMIT) / (double) hostCpuMaxCapacity); - logger.debug(String.format("This host utilizes cgroupv2 (as the max shares value is [%s]), thus, the VM requested shares of [%s] will be converted to " + - s_logger.debug(String.format("This host utilizes cgroupv2 (as the max shares value is [%s]), thus, the VM requested shares of [%s] will be converted to " + ++ LOGGER.debug(String.format("This host utilizes cgroupv2 (as the max shares value is [%s]), thus, the VM requested shares of [%s] will be converted to " + "consider the host limits; the new CPU shares value is [%s].", hostCpuMaxCapacity, requestedCpuShares, updatedCpuShares)); return updatedCpuShares; } - logger.debug(String.format("This host does not have a maximum CPU shares set; therefore, this host utilizes cgroupv1 and the VM requested CPU shares [%s] will not be " + - s_logger.debug(String.format("This host does not have a maximum CPU shares set; therefore, this host utilizes cgroupv1 and the VM requested CPU shares [%s] will not be " + ++ LOGGER.debug(String.format("This host does not have a maximum CPU shares set; therefore, this host utilizes cgroupv1 and the VM requested CPU shares [%s] will not be " + "converted.", requestedCpuShares)); return requestedCpuShares; } @@@ -2926,12 -2909,12 +2926,12 @@@ protected long getCurrentMemAccordingToMemBallooning(VirtualMachineTO vmTO, long maxRam) { long retVal = maxRam; if (noMemBalloon) { - s_logger.warn(String.format("Setting VM's [%s] current memory as max memory [%s] due to memory ballooning is disabled. If you are using a custom service offering, verify if memory ballooning really should be disabled.", vmTO.toString(), maxRam)); + LOGGER.warn(String.format("Setting VM's [%s] current memory as max memory [%s] due to memory ballooning is disabled. If you are using a custom service offering, verify if memory ballooning really should be disabled.", vmTO.toString(), maxRam)); } else if (vmTO != null && vmTO.getType() != VirtualMachine.Type.User) { - s_logger.warn(String.format("Setting System VM's [%s] current memory as max memory [%s].", vmTO.toString(), maxRam)); + LOGGER.warn(String.format("Setting System VM's [%s] current memory as max memory [%s].", vmTO.toString(), maxRam)); } else { long minRam = ByteScaleUtils.bytesToKibibytes(vmTO.getMinRam()); - logger.debug(String.format("Setting VM's [%s] current memory as min memory [%s] due to memory ballooning is enabled.", vmTO.toString(), minRam)); - s_logger.debug(String.format("Setting VM's [%s] current memory as min memory [%s] due to memory ballooning is enabled.", vmTO.toString(), minRam)); ++ LOGGER.debug(String.format("Setting VM's [%s] current memory as min memory [%s] due to memory ballooning is enabled.", vmTO.toString(), minRam)); retVal = minRam; } return retVal; @@@ -3283,7 -3260,7 +3284,7 @@@ * (ii) Libvirt >= 6.3.0 */ public void setDiskIoDriver(DiskDef disk, IoDriverPolicy ioDriver) { - logger.debug(String.format("Disk IO driver policy [%s]. The host supports the io_uring policy [%s]", ioDriver, enableIoUring)); - s_logger.debug(String.format("Disk IO driver policy [%s]. The host supports the io_uring policy [%s]", ioDriver, enableIoUring)); ++ LOGGER.debug(String.format("Disk IO driver policy [%s]. The host supports the io_uring policy [%s]", ioDriver, enableIoUring)); if (ioDriver != null) { if (IoDriverPolicy.IO_URING != ioDriver) { disk.setIoDriver(ioDriver); @@@ -3426,13 -3403,15 +3427,15 @@@ } if (configdrive != null) { try { - s_logger.debug(String.format("Detaching ConfigDrive ISO of the VM %s, at path %s", vmName, configdrive.getDiskPath())); ++ LOGGER.debug(String.format("Detaching ConfigDrive ISO of the VM %s, at path %s", vmName, configdrive.getDiskPath())); String result = attachOrDetachISO(conn, vmName, configdrive.getDiskPath(), false, CONFIG_DRIVE_ISO_DEVICE_ID); if (result != null) { - LOGGER.warn("Detach ConfigDrive ISO with result: " + result); - s_logger.warn(String.format("Detach ConfigDrive ISO of the VM %s, at path %s with %s: ", vmName, configdrive.getDiskPath(), result)); ++ LOGGER.warn("Detach ConfigDrive ISO of the VM {}, at path {} with result: {}", vmName, configdrive.getDiskPath(), result); } - s_logger.debug(String.format("Attaching ConfigDrive ISO of the VM %s, at path %s", vmName, configdrive.getDiskPath())); ++ LOGGER.debug(String.format("Attaching ConfigDrive ISO of the VM %s, at path %s", vmName, configdrive.getDiskPath())); result = attachOrDetachISO(conn, vmName, configdrive.getDiskPath(), true, CONFIG_DRIVE_ISO_DEVICE_ID); if (result != null) { - LOGGER.warn("Attach ConfigDrive ISO with result: " + result); - s_logger.warn(String.format("Attach ConfigDrive ISO of the VM %s, at path %s with %s: ", vmName, configdrive.getDiskPath(), result)); ++ LOGGER.warn("Attach ConfigDrive ISO of the VM {}, at path {} with result: {}", vmName, configdrive.getDiskPath(), result); } } catch (final LibvirtException | InternalErrorException | URISyntaxException e) { final String msg = "Detach and attach ConfigDrive ISO failed due to " + e.toString(); @@@ -3640,19 -3619,19 +3647,19 @@@ */ private HealthCheckResult getHostHealthCheckResult() { if (StringUtils.isBlank(hostHealthCheckScriptPath)) { - logger.debug("Host health check script path is not specified"); - s_logger.debug("Host health check script path is not specified"); ++ LOGGER.debug("Host health check script path is not specified"); return HealthCheckResult.IGNORE; } File script = new File(hostHealthCheckScriptPath); if (!script.exists() || !script.isFile() || !script.canExecute()) { - logger.warn(String.format("The host health check script file set at: %s cannot be executed, " + - s_logger.warn(String.format("The host health check script file set at: %s cannot be executed, " + ++ LOGGER.warn(String.format("The host health check script file set at: %s cannot be executed, " + "reason: %s", hostHealthCheckScriptPath, !script.exists() ? "file does not exist" : "please check file permissions to execute this file")); return HealthCheckResult.IGNORE; } int exitCode = executeBashScriptAndRetrieveExitValue(hostHealthCheckScriptPath); - if (logger.isDebugEnabled()) { - logger.debug(String.format("Host health check script exit code: %s", exitCode)); - if (s_logger.isDebugEnabled()) { - s_logger.debug(String.format("Host health check script exit code: %s", exitCode)); ++ if (LOGGER.isDebugEnabled()) { ++ LOGGER.debug(String.format("Host health check script exit code: %s", exitCode)); } return retrieveHealthCheckResultFromExitCode(exitCode); } @@@ -3761,17 -3724,17 +3768,17 @@@ */ protected void calculateHostCpuMaxCapacity(int cpuCores, Long cpuSpeed) { String output = Script.runSimpleBashScript(COMMAND_GET_CGROUP_HOST_VERSION); - logger.info(String.format("Host uses control group [%s].", output)); - s_logger.info(String.format("Host uses control group [%s].", output)); ++ LOGGER.info(String.format("Host uses control group [%s].", output)); if (!CGROUP_V2.equals(output)) { - logger.info(String.format("Setting host CPU max capacity to 0, as it uses cgroup v1.", getHostCpuMaxCapacity())); - s_logger.info(String.format("Setting host CPU max capacity to 0, as it uses cgroup v1.", getHostCpuMaxCapacity())); ++ LOGGER.info(String.format("Setting host CPU max capacity to 0, as it uses cgroup v1.", getHostCpuMaxCapacity())); setHostCpuMaxCapacity(0); return; } - logger.info(String.format("Calculating the max shares of the host.")); - s_logger.info(String.format("Calculating the max shares of the host.")); ++ LOGGER.info(String.format("Calculating the max shares of the host.")); setHostCpuMaxCapacity(cpuCores * cpuSpeed.intValue()); - logger.info(String.format("The max shares of the host is [%d].", getHostCpuMaxCapacity())); - s_logger.info(String.format("The max shares of the host is [%d].", getHostCpuMaxCapacity())); ++ LOGGER.info(String.format("The max shares of the host is [%d].", getHostCpuMaxCapacity())); } private StartupStorageCommand createLocalStoragePool(String localStoragePath, String localStorageUUID, StartupRoutingCommand cmd) { @@@ -3834,7 -3797,7 +3841,7 @@@ String sourcePath = null; try { String mountResult = Script.runSimpleBashScript("mount | grep \"" + diskPath + "\""); - logger.debug("Got mount result for " + diskPath + "\n\n" + mountResult); - s_logger.debug("Got mount result for " + diskPath + "\n\n" + mountResult); ++ LOGGER.debug("Got mount result for " + diskPath + "\n\n" + mountResult); if (StringUtils.isNotEmpty(mountResult)) { String[] res = mountResult.strip().split(" "); if (res[0].contains(":")) { @@@ -3851,7 -3814,7 +3858,7 @@@ return new Pair<>(sourceHostIp, sourcePath); } } catch (Exception ex) { - logger.warn("Failed to list source host and IP for " + diskPath + ex.toString()); - s_logger.warn("Failed to list source host and IP for " + diskPath + ex.toString()); ++ LOGGER.warn("Failed to list source host and IP for " + diskPath + ex.toString()); } return null; } @@@ -3864,14 -3827,14 +3871,14 @@@ domainNames.add(names[i]); } } catch (final LibvirtException e) { - logger.warn("Failed to list defined domains", e); - s_logger.warn("Failed to list defined domains", e); ++ LOGGER.warn("Failed to list defined domains", e); } int[] ids = null; try { ids = conn.listDomains(); } catch (final LibvirtException e) { - logger.warn("Failed to list domains", e); - s_logger.warn("Failed to list domains", e); ++ LOGGER.warn("Failed to list domains", e); return domainNames; } @@@ -4959,7 -4862,7 +4966,7 @@@ public boolean setupTungstenVRouter(final String oper, final String inf, final String subnet, final String route, final String vrf) { - final Script cmd = new Script(setupTungstenVrouterPath, timeout, logger); - final Script cmd = new Script(setupTungstenVrouterPath, timeout, s_logger); ++ final Script cmd = new Script(setupTungstenVrouterPath, timeout, LOGGER); cmd.add(oper); cmd.add(inf); cmd.add(subnet); @@@ -4972,7 -4875,7 +4979,7 @@@ public boolean updateTungstenLoadbalancerStats(final String lbUuid, final String lbStatsPort, final String lbStatsUri, final String lbStatsAuth) { - final Script cmd = new Script(updateTungstenLoadbalancerStatsPath, timeout, logger); - final Script cmd = new Script(updateTungstenLoadbalancerStatsPath, timeout, s_logger); ++ final Script cmd = new Script(updateTungstenLoadbalancerStatsPath, timeout, LOGGER); cmd.add(lbUuid); cmd.add(lbStatsPort); cmd.add(lbStatsUri); @@@ -4984,7 -4887,7 +4991,7 @@@ public boolean updateTungstenLoadbalancerSsl(final String lbUuid, final String sslCertName, final String certificateKey, final String privateKey, final String privateIp, final String port) { - final Script cmd = new Script(updateTungstenLoadbalancerSslPath, timeout, logger); - final Script cmd = new Script(updateTungstenLoadbalancerSslPath, timeout, s_logger); ++ final Script cmd = new Script(updateTungstenLoadbalancerSslPath, timeout, LOGGER); cmd.add(lbUuid); cmd.add(sslCertName); cmd.add(certificateKey); @@@ -4997,7 -4900,7 +5004,7 @@@ } public boolean setupTfRoute(final String privateIpAddress, final String fromNetwork, final String toNetwork) { - final Script setupTfRouteScript = new Script(routerProxyPath, timeout, logger); - final Script setupTfRouteScript = new Script(routerProxyPath, timeout, s_logger); ++ final Script setupTfRouteScript = new Script(routerProxyPath, timeout, LOGGER); setupTfRouteScript.add("setup_tf_route.py"); setupTfRouteScript.add(privateIpAddress); setupTfRouteScript.add(fromNetwork); @@@ -5006,7 -4909,7 +5013,7 @@@ final OutputInterpreter.OneLineParser setupTfRouteParser = new OutputInterpreter.OneLineParser(); final String result = setupTfRouteScript.execute(setupTfRouteParser); if (result != null) { - logger.debug("Failed to execute setup TF Route:" + result); - s_logger.debug("Failed to execute setup TF Route:" + result); ++ LOGGER.debug("Failed to execute setup TF Route:" + result); return false; } return true; @@@ -5525,7 -5411,7 +5532,7 @@@ interfaceDef.setMultiQueueNumber(nicMultiqueueNumberInteger); } } catch (NumberFormatException ex) { - logger.warn(String.format("VM details %s is not a valid integer value %s", VmDetailConstants.NIC_MULTIQUEUE_NUMBER, nicMultiqueueNumber)); - s_logger.warn(String.format("VM details %s is not a valid integer value %s", VmDetailConstants.NIC_MULTIQUEUE_NUMBER, nicMultiqueueNumber)); ++ LOGGER.warn(String.format("VM details %s is not a valid integer value %s", VmDetailConstants.NIC_MULTIQUEUE_NUMBER, nicMultiqueueNumber)); } } String nicPackedEnabled = details.get(VmDetailConstants.NIC_PACKED_VIRTQUEUES_ENABLED); @@@ -5533,7 -5419,7 +5540,7 @@@ try { interfaceDef.setPackedVirtQueues(Boolean.valueOf(nicPackedEnabled)); } catch (NumberFormatException ex) { - logger.warn(String.format("VM details %s is not a valid Boolean value %s", VmDetailConstants.NIC_PACKED_VIRTQUEUES_ENABLED, nicPackedEnabled)); - s_logger.warn(String.format("VM details %s is not a valid Boolean value %s", VmDetailConstants.NIC_PACKED_VIRTQUEUES_ENABLED, nicPackedEnabled)); ++ LOGGER.warn(String.format("VM details %s is not a valid Boolean value %s", VmDetailConstants.NIC_PACKED_VIRTQUEUES_ENABLED, nicPackedEnabled)); } } } @@@ -5548,11 -5434,11 +5555,11 @@@ command.append(remoteFile); command.append(" " + tmpPath); command.append(outputFile); - logger.debug(String.format("Converting remote disk file: %s, output file: %s%s (timeout: %d secs)", remoteFile, tmpPath, outputFile, timeoutInSecs)); - s_logger.debug(String.format("Converting remote disk file: %s, output file: %s%s (timeout: %d secs)", remoteFile, tmpPath, outputFile, timeoutInSecs)); ++ LOGGER.debug(String.format("Converting remote disk file: %s, output file: %s%s (timeout: %d secs)", remoteFile, tmpPath, outputFile, timeoutInSecs)); SshHelper.sshExecute(srcIp, 22, username, null, password, command.toString(), timeoutInSecs * 1000); - logger.debug("Copying converted remote disk file " + outputFile + " to: " + localDir); - s_logger.debug("Copying converted remote disk file " + outputFile + " to: " + localDir); ++ LOGGER.debug("Copying converted remote disk file " + outputFile + " to: " + localDir); SshHelper.scpFrom(srcIp, 22, username, null, password, localDir, tmpPath + outputFile); - logger.debug("Successfully copied converted remote disk file to: " + localDir + "/" + outputFile); - s_logger.debug("Successfully copied converted remote disk file to: " + localDir + "/" + outputFile); ++ LOGGER.debug("Successfully copied converted remote disk file to: " + localDir + "/" + outputFile); return outputFile; } catch (Exception e) { try { diff --cc plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/storage/IscsiAdmStorageAdaptor.java index 09cdad64ace,9288ca2750c..6185c69032f --- a/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/storage/IscsiAdmStorageAdaptor.java +++ b/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/storage/IscsiAdmStorageAdaptor.java @@@ -84,9 -79,9 +84,9 @@@ public class IscsiAdmStorageAdaptor imp } @Override - public boolean connectPhysicalDisk(String volumeUuid, KVMStoragePool pool, Map<String, String> details) { + public boolean connectPhysicalDisk(String volumeUuid, KVMStoragePool pool, Map<String, String> details, boolean isVMMigrate) { // ex. sudo iscsiadm -m node -T iqn.2012-03.com.test:volume1 -p 192.168.233.10:3260 -o new - Script iScsiAdmCmd = new Script(true, "iscsiadm", 0, s_logger); + Script iScsiAdmCmd = new Script(true, "iscsiadm", 0, logger); iScsiAdmCmd.add("-m", "node"); iScsiAdmCmd.add("-T", getIqn(volumeUuid)); diff --cc plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/storage/KVMStoragePoolManager.java index 4e76030d06f,2bd068b6c8f..e27547acbb2 --- a/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/storage/KVMStoragePoolManager.java +++ b/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/storage/KVMStoragePoolManager.java @@@ -187,10 -159,10 +187,10 @@@ public class KVMStoragePoolManager KVMStoragePool pool = getStoragePool(store.getPoolType(), store.getUuid()); StorageAdaptor adaptor = getStorageAdaptor(pool.getType()); - result = adaptor.connectPhysicalDisk(vol.getPath(), pool, disk.getDetails()); + result = adaptor.connectPhysicalDisk(vol.getPath(), pool, disk.getDetails(), isVMMigrate); if (!result) { - s_logger.error("Failed to connect disks via vm spec for vm: " + vmName + " volume:" + vol.toString()); + logger.error("Failed to connect disks via vm spec for vm: " + vmName + " volume:" + vol.toString()); return result; } } @@@ -315,6 -287,7 +315,7 @@@ URI storageUri = null; try { - s_logger.debug("Get storage pool by uri: " + uri); ++ logger.debug("Get storage pool by uri: " + uri); storageUri = new URI(uri); } catch (URISyntaxException e) { throw new CloudRuntimeException(e.toString()); diff --cc plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/storage/ScaleIOStorageAdaptor.java index 7477d768e9a,ab9533c075e..335ea0d03d2 --- a/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/storage/ScaleIOStorageAdaptor.java +++ b/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/storage/ScaleIOStorageAdaptor.java @@@ -224,9 -221,9 +224,9 @@@ public class ScaleIOStorageAdaptor impl } @Override - public boolean connectPhysicalDisk(String volumePath, KVMStoragePool pool, Map<String, String> details) { + public boolean connectPhysicalDisk(String volumePath, KVMStoragePool pool, Map<String, String> details, boolean isMigration) { if (StringUtils.isEmpty(volumePath) || pool == null) { - LOGGER.error("Unable to connect physical disk due to insufficient data"); + logger.error("Unable to connect physical disk due to insufficient data"); throw new CloudRuntimeException("Unable to connect physical disk due to insufficient data"); } diff --cc plugins/hypervisors/xenserver/src/main/java/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/CitrixGetVmIpAddressCommandWrapper.java index a324ec1bdad,e03708faf86..dceeec17fb3 --- a/plugins/hypervisors/xenserver/src/main/java/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/CitrixGetVmIpAddressCommandWrapper.java +++ b/plugins/hypervisors/xenserver/src/main/java/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/CitrixGetVmIpAddressCommandWrapper.java @@@ -61,17 -63,16 +61,17 @@@ public final class CitrixGetVmIpAddress } if (vmIp != null) { - logger.debug("VM " +vmName + " ip address got retrieved "+vmIp); - s_logger.debug("VM " + vmName + " IP address got retrieved " + vmIp); ++ logger.debug("VM {} ip address got retrieved {}", vmName, vmIp); result = true; return new Answer(command, result, vmIp); } + - }catch (Types.XenAPIException e) { - logger.debug("Got exception in GetVmIpAddressCommand "+ e.getMessage()); - errorMsg = "Failed to retrived vm ip addr, exception: "+e.getMessage(); - }catch (XmlRpcException e) { - logger.debug("Got exception in GetVmIpAddressCommand "+ e.getMessage()); - errorMsg = "Failed to retrived vm ip addr, exception: "+e.getMessage(); + } catch (Types.XenAPIException e) { - s_logger.debug("Got exception in GetVmIpAddressCommand " + e.getMessage()); - errorMsg = "Failed to retrieve vm ip addr, exception: " + e.getMessage(); ++ logger.debug("Got exception in GetVmIpAddressCommand " + e.getMessage()); ++ errorMsg = "Failed to retrived vm ip addr, exception: " + e.getMessage(); + } catch (XmlRpcException e) { - s_logger.debug("Got exception in GetVmIpAddressCommand " + e.getMessage()); - errorMsg = "Failed to retrieve vm ip addr, exception: " + e.getMessage(); ++ logger.debug("Got exception in GetVmIpAddressCommand " + e.getMessage()); ++ errorMsg = "Failed to retrived vm ip addr, exception: " + e.getMessage(); } return new Answer(command, result, errorMsg); diff --cc plugins/storage/volume/linstor/src/main/java/com/cloud/hypervisor/kvm/storage/LinstorStorageAdaptor.java index 8d99af0dd20,9b7a376e8f2..292e939de49 --- a/plugins/storage/volume/linstor/src/main/java/com/cloud/hypervisor/kvm/storage/LinstorStorageAdaptor.java +++ b/plugins/storage/volume/linstor/src/main/java/com/cloud/hypervisor/kvm/storage/LinstorStorageAdaptor.java @@@ -277,6 -274,7 +278,7 @@@ public class LinstorStorageAdaptor impl * @throws ApiException if any problem connecting to the Linstor controller */ private void allow2PrimariesIfInUse(DevelopersApi api, String rscName) throws ApiException { - s_logger.debug("enabling allow-two-primaries"); ++ logger.debug("enabling allow-two-primaries"); String inUseNode = LinstorUtil.isResourceInUse(api, rscName); if (inUseNode != null && !inUseNode.equalsIgnoreCase(localNodeName)) { // allow 2 primaries for live migration, should be removed by disconnect on the other end @@@ -292,11 -290,12 +294,12 @@@ } @Override - public boolean connectPhysicalDisk(String volumePath, KVMStoragePool pool, Map<String, String> details) + public boolean connectPhysicalDisk( + String volumePath, KVMStoragePool pool, Map<String, String> details, boolean isVMMigration) { - s_logger.debug(String.format("Linstor: connectPhysicalDisk %s:%s -> %s", pool.getUuid(), volumePath, details)); + logger.debug("Linstor: connectPhysicalDisk {}:{} -> {}", pool.getUuid(), volumePath, details); if (volumePath == null) { - s_logger.warn("volumePath is null, ignoring"); + logger.warn("volumePath is null, ignoring"); return false; } @@@ -315,12 -314,13 +318,13 @@@ throw new CloudRuntimeException(apiEx.getBestMessage(), apiEx); } - try - { - allow2PrimariesIfInUse(api, rscName); - } catch (ApiException apiEx) { - logger.error(apiEx); - // do not fail here as adding allow-two-primaries property is only a problem while live migrating + if (isVMMigration) { + try { + allow2PrimariesIfInUse(api, rscName); + } catch (ApiException apiEx) { - s_logger.error(apiEx); ++ logger.error(apiEx); + // do not fail here as adding allow-two-primaries property is only a problem while live migrating + } } return true; } @@@ -716,4 -716,19 +720,19 @@@ throw new CloudRuntimeException(apiEx.getBestMessage(), apiEx); } } + + public boolean isNodeOnline(LinstorStoragePool pool, String nodeName) { + DevelopersApi linstorApi = getLinstorAPI(pool); + try { + List<Node> node = linstorApi.nodeList(Collections.singletonList(nodeName), Collections.emptyList(), null, null); + if (node == null || node.isEmpty()) { + return false; + } + + return Node.ConnectionStatusEnum.ONLINE.equals(node.get(0).getConnectionStatus()); + } catch (ApiException apiEx) { - s_logger.error(apiEx.getMessage()); ++ logger.error(apiEx.getMessage()); + throw new CloudRuntimeException(apiEx.getBestMessage(), apiEx); + } + } } diff --cc plugins/storage/volume/linstor/src/main/java/com/cloud/hypervisor/kvm/storage/LinstorStoragePool.java index 2d6801049a3,3907bae7f79..bb354bec9b4 --- a/plugins/storage/volume/linstor/src/main/java/com/cloud/hypervisor/kvm/storage/LinstorStoragePool.java +++ b/plugins/storage/volume/linstor/src/main/java/com/cloud/hypervisor/kvm/storage/LinstorStoragePool.java @@@ -294,8 -311,20 +312,20 @@@ public class LinstorStoragePool impleme } } } - LOGGER.warn(String.format("checkDrbdSetupStatusOutput: no resource connected to %s.", otherNodeName)); - return false; + boolean otherNodeOnline = false; + if (connectionFound) { - s_logger.warn(String.format( ++ LOGGER.warn(String.format( + "checkingHeartBeat: connection found, but not in state 'Connected' to %s", otherNodeName)); + } else { - s_logger.warn(String.format( ++ LOGGER.warn(String.format( + "checkingHeartBeat: no resource connected to %s, checking LINSTOR", otherNodeName)); + otherNodeOnline = checkLinstorNodeOnline(otherNodeName); + } - s_logger.info(String.format( ++ LOGGER.info(String.format( + "checkingHeartBeat: other node %s is %s.", + otherNodeName, + otherNodeOnline ? "online on controller" : "down")); + return otherNodeOnline; } private String executeDrbdEventsNow(OutputInterpreter.AllLinesParser parser) { diff --cc plugins/storage/volume/storpool/src/main/java/com/cloud/hypervisor/kvm/storage/StorPoolStorageAdaptor.java index de3886f6294,4091be10470..d68e9cbd110 --- a/plugins/storage/volume/storpool/src/main/java/com/cloud/hypervisor/kvm/storage/StorPoolStorageAdaptor.java +++ b/plugins/storage/volume/storpool/src/main/java/com/cloud/hypervisor/kvm/storage/StorPoolStorageAdaptor.java @@@ -249,10 -244,10 +249,10 @@@ public class StorPoolStorageAdaptor imp } @Override - public boolean connectPhysicalDisk(String volumeUuid, KVMStoragePool pool, Map<String, String> details) { + public boolean connectPhysicalDisk(String volumeUuid, KVMStoragePool pool, Map<String, String> details, boolean isVMMigrate) { SP_LOG("StorPoolStorageAdaptor.connectPhysicalDisk: uuid=%s, pool=%s", volumeUuid, pool); - log.debug(String.format("connectPhysicalDisk: uuid=%s, pool=%s", volumeUuid, pool)); + LOGGER.debug(String.format("connectPhysicalDisk: uuid=%s, pool=%s", volumeUuid, pool)); return attachOrDetachVolume("attach", "volume", volumeUuid); } diff --cc server/src/main/java/com/cloud/network/element/ConfigDriveNetworkElement.java index 3449f1f5d00,38d71b9c507..5d468d95e4c --- a/server/src/main/java/com/cloud/network/element/ConfigDriveNetworkElement.java +++ b/server/src/main/java/com/cloud/network/element/ConfigDriveNetworkElement.java @@@ -345,19 -341,16 +345,19 @@@ public class ConfigDriveNetworkElement try { if (isConfigDriveIsoOnHostCache(vm.getId())) { vm.setConfigDriveLocation(Location.HOST); - configureConfigDriveData(vm, nic, dest); - - // Create the config drive on dest host cache - createConfigDriveIsoOnHostCache(nic, vm, dest.getHost().getId()); + if (configureConfigDriveData(vm, nic, dest)) { + // Create the config drive on dest host cache + createConfigDriveIsoOnHostCache(vm, dest.getHost().getId()); + } } else { vm.setConfigDriveLocation(getConfigDriveLocation(vm.getId())); - addPasswordAndUserdata(network, nic, vm, dest, context); + boolean result = addPasswordAndUserdata(network, nic, vm, dest, context); + if (result) { + createConfigDriveIso(nic, vm, dest, null); + } } } catch (InsufficientCapacityException | ResourceUnavailableException e) { - LOG.error("Failed to add config disk drive due to: ", e); + logger.error("Failed to add config disk drive due to: ", e); return false; } } @@@ -549,9 -553,7 +560,9 @@@ final String isoFileName = ConfigDrive.configIsoFileName(profile.getInstanceName()); final String isoPath = ConfigDrive.createConfigDrivePath(profile.getInstanceName()); - List<NicProfile> nicProfiles = _networkOrchestrationService.getNicProfiles(nic.getVirtualMachineId(), profile.getHypervisorType()); - final String isoData = ConfigDriveBuilder.buildConfigDrive(profile.getVmData(), isoFileName, profile.getConfigDriveLabel(), customUserdataParamMap); ++ List<NicProfile> nicProfiles = _networkOrchestrationService.getNicProfiles(profile.getVirtualMachine().getId(), profile.getHypervisorType()); + final Map<Long, List<Service>> supportedServices = getSupportedServicesByElementForNetwork(nicProfiles); + final String isoData = ConfigDriveBuilder.buildConfigDrive(nicProfiles, profile.getVmData(), isoFileName, profile.getConfigDriveLabel(), customUserdataParamMap, supportedServices); final HandleConfigDriveIsoCommand configDriveIsoCommand = new HandleConfigDriveIsoCommand(isoPath, isoData, null, false, true, true); final HandleConfigDriveIsoAnswer answer = (HandleConfigDriveIsoAnswer) agentManager.easySend(hostId, configDriveIsoCommand); diff --cc server/src/main/java/com/cloud/vm/UserVmManagerImpl.java index 04b64dd80a3,94034da4c8f..ce2e5585a09 --- a/server/src/main/java/com/cloud/vm/UserVmManagerImpl.java +++ b/server/src/main/java/com/cloud/vm/UserVmManagerImpl.java @@@ -766,7 -773,7 +764,7 @@@ public class UserVmManagerImpl extends boolean decrementCount = true; try { - logger.debug("Trying for vm "+ vmId +" nic Id "+nicId +" ip retrieval ..."); - s_logger.debug(String.format("Trying IP retrieval for VM %s (%d), nic Id %d", vmName, vmId, nicId)); ++ logger.debug("Trying IP retrieval for VM {} ({}), nic Id {}", vmName, vmId, nicId); Answer answer = _agentMgr.send(hostId, cmd); NicVO nic = _nicDao.findById(nicId); if (answer.getResult()) { @@@ -777,7 -784,7 +775,7 @@@ if (nic != null) { nic.setIPv4Address(vmIp); _nicDao.update(nicId, nic); - logger.debug("Vm "+ vmId +" IP "+vmIp +" got retrieved successfully"); - s_logger.debug(String.format("VM %s (%d) - IP %s retrieved successfully", vmName, vmId, vmIp)); ++ logger.debug("VM {} ({}) - IP {} retrieved successfully", vmName, vmId, vmIp); vmIdCountMap.remove(nicId); decrementCount = false; ActionEventUtils.onActionEvent(User.UID_SYSTEM, Account.ACCOUNT_ID_SYSTEM, @@@ -793,7 -800,7 +791,7 @@@ _nicDao.update(nicId, nic); } if (answer.getDetails() != null) { - logger.debug("Failed to get vm ip for Vm "+ vmId + answer.getDetails()); - s_logger.debug(String.format("Failed to get IP for VM %s (%d), details: %s", vmName, vmId, answer.getDetails())); ++ logger.debug("Failed to get vm ip for Vm {} ({}), details: {}", vmName, vmId, answer.getDetails()); } } } catch (OperationTimedoutException e) { @@@ -804,7 -811,7 +802,7 @@@ if (decrementCount) { VmAndCountDetails vmAndCount = vmIdCountMap.get(nicId); vmAndCount.decrementCount(); - logger.debug("Ip is not retrieved for VM " + vmId +" nic "+nicId + " ... decremented count to "+vmAndCount.getRetrievalCount()); - s_logger.debug(String.format("IP is not retrieved for VM %s (%d), nic %d ... decremented count to %d", vmName, vmId, nicId, vmAndCount.getRetrievalCount())); ++ logger.debug("Ip is not retrieved for VM {} ({}) nic {} ... decremented count to {}", vmName, vmId, nicId, vmAndCount.getRetrievalCount()); vmIdCountMap.put(nicId, vmAndCount); } } diff --cc server/src/test/java/com/cloud/user/AccountManagerImplTest.java index 645c9e5aa67,ed0a123d4a3..3f66c6017a4 --- a/server/src/test/java/com/cloud/user/AccountManagerImplTest.java +++ b/server/src/test/java/com/cloud/user/AccountManagerImplTest.java @@@ -26,12 -26,11 +26,15 @@@ import java.util.HashMap import java.util.List; import java.util.Map; +import com.cloud.event.ActionEventUtils; ++ + import org.apache.cloudstack.acl.ControlledEntity; + import org.apache.cloudstack.acl.Role; + import org.apache.cloudstack.acl.RoleService; + import org.apache.cloudstack.acl.RoleType; import org.apache.cloudstack.acl.SecurityChecker.AccessType; +import org.apache.cloudstack.api.command.admin.account.UpdateAccountCmd; +import org.apache.cloudstack.api.command.admin.user.DeleteUserCmd; - - import org.apache.cloudstack.acl.ControlledEntity; import org.apache.cloudstack.api.command.admin.user.GetUserKeysCmd; import org.apache.cloudstack.api.command.admin.user.UpdateUserCmd; import org.apache.cloudstack.api.response.UserTwoFactorAuthenticationSetupResponse; @@@ -47,11 -45,9 +50,12 @@@ import org.junit.Test import org.junit.runner.RunWith; import org.mockito.InOrder; import org.mockito.Mock; +import org.mockito.MockedStatic; import org.mockito.Mockito; import org.mockito.junit.MockitoJUnitRunner; + +import org.springframework.beans.factory.NoSuchBeanDefinitionException; + import com.cloud.acl.DomainChecker; import com.cloud.api.auth.SetupUserTwoFactorAuthenticationCmd; import com.cloud.domain.Domain; @@@ -1207,22 -1084,120 +1213,130 @@@ public class AccountManagerImplTest ext } @Test - public void deleteAndCleanupUserTestRemovesUserFromProjects() { - long userId = userVoMock.getId(); - Mockito.doNothing().when(_projectAccountDao).removeUserFromProjects(userId); - - accountManagerImpl.deleteAndCleanupUser(userVoMock); + public void testDeleteWebhooksForAccount() { + try (MockedStatic<ComponentContext> mockedComponentContext = Mockito.mockStatic(ComponentContext.class)) { + WebhookHelper webhookHelper = Mockito.mock(WebhookHelper.class); + Mockito.doNothing().when(webhookHelper).deleteWebhooksForAccount(Mockito.anyLong()); + mockedComponentContext.when(() -> ComponentContext.getDelegateComponentOfType(WebhookHelper.class)) + .thenReturn(webhookHelper); + accountManagerImpl.deleteWebhooksForAccount(1L); + } + } - Mockito.verify(_projectAccountDao).removeUserFromProjects(userId); + @Test + public void testDeleteWebhooksForAccountNoBean() { + try (MockedStatic<ComponentContext> mockedComponentContext = Mockito.mockStatic(ComponentContext.class)) { + mockedComponentContext.when(() -> ComponentContext.getDelegateComponentOfType(WebhookHelper.class)) + .thenThrow(NoSuchBeanDefinitionException.class); + accountManagerImpl.deleteWebhooksForAccount(1L); + } } + + @Test(expected = PermissionDeniedException.class) + public void testValidateRoleChangeUnknownCaller() { + Account account = Mockito.mock(Account.class); + Mockito.when(account.getRoleId()).thenReturn(1L); + Role role = Mockito.mock(Role.class); + Mockito.when(role.getRoleType()).thenReturn(RoleType.Unknown); + Account caller = Mockito.mock(Account.class); + Mockito.when(caller.getRoleId()).thenReturn(2L); + Mockito.when(roleService.findRole(2L)).thenReturn(role); + accountManagerImpl.validateRoleChange(account, Mockito.mock(Role.class), caller); + } + + @Test(expected = PermissionDeniedException.class) + public void testValidateRoleChangeUnknownNewRole() { + Account account = Mockito.mock(Account.class); + Mockito.when(account.getRoleId()).thenReturn(1L); + Role newRole = Mockito.mock(Role.class); + Mockito.when(newRole.getRoleType()).thenReturn(RoleType.Unknown); + Role callerRole = Mockito.mock(Role.class); + Mockito.when(callerRole.getRoleType()).thenReturn(RoleType.DomainAdmin); + Account caller = Mockito.mock(Account.class); + Mockito.when(caller.getRoleId()).thenReturn(2L); + Mockito.when(roleService.findRole(2L)).thenReturn(callerRole); + accountManagerImpl.validateRoleChange(account, newRole, caller); + } + + @Test + public void testValidateRoleNewRoleSameCaller() { + Account account = Mockito.mock(Account.class); + Mockito.when(account.getRoleId()).thenReturn(1L); + Role currentRole = Mockito.mock(Role.class); + Mockito.when(currentRole.getRoleType()).thenReturn(RoleType.User); + Mockito.when(roleService.findRole(1L)).thenReturn(currentRole); + Role newRole = Mockito.mock(Role.class); + Mockito.when(newRole.getRoleType()).thenReturn(RoleType.DomainAdmin); + Role callerRole = Mockito.mock(Role.class); + Mockito.when(callerRole.getRoleType()).thenReturn(RoleType.DomainAdmin); + Account caller = Mockito.mock(Account.class); + Mockito.when(caller.getRoleId()).thenReturn(2L); + Mockito.when(roleService.findRole(2L)).thenReturn(callerRole); + accountManagerImpl.validateRoleChange(account, newRole, caller); + } + + @Test + public void testValidateRoleCurrentRoleSameCaller() { + Account account = Mockito.mock(Account.class); + Mockito.when(account.getRoleId()).thenReturn(1L); + Role accountRole = Mockito.mock(Role.class); + Mockito.when(accountRole.getRoleType()).thenReturn(RoleType.DomainAdmin); + Role newRole = Mockito.mock(Role.class); + Mockito.when(newRole.getRoleType()).thenReturn(RoleType.User); + Role callerRole = Mockito.mock(Role.class); + Mockito.when(callerRole.getRoleType()).thenReturn(RoleType.DomainAdmin); + Account caller = Mockito.mock(Account.class); + Mockito.when(caller.getRoleId()).thenReturn(2L); + Mockito.when(roleService.findRole(1L)).thenReturn(accountRole); + Mockito.when(roleService.findRole(2L)).thenReturn(callerRole); + accountManagerImpl.validateRoleChange(account, newRole, caller); + } + + @Test(expected = PermissionDeniedException.class) + public void testValidateRoleNewRoleHigherCaller() { + Account account = Mockito.mock(Account.class); + Mockito.when(account.getRoleId()).thenReturn(1L); + Role newRole = Mockito.mock(Role.class); + Mockito.when(newRole.getRoleType()).thenReturn(RoleType.Admin); + Role callerRole = Mockito.mock(Role.class); + Mockito.when(callerRole.getRoleType()).thenReturn(RoleType.DomainAdmin); + Account caller = Mockito.mock(Account.class); + Mockito.when(caller.getRoleId()).thenReturn(2L); + Mockito.when(roleService.findRole(2L)).thenReturn(callerRole); + accountManagerImpl.validateRoleChange(account, newRole, caller); + } + + @Test + public void testValidateRoleNewRoleLowerCaller() { + Account account = Mockito.mock(Account.class); + Mockito.when(account.getRoleId()).thenReturn(1L); + Role newRole = Mockito.mock(Role.class); + Mockito.when(newRole.getRoleType()).thenReturn(RoleType.User); + Role accountRole = Mockito.mock(Role.class); + Mockito.when(accountRole.getRoleType()).thenReturn(RoleType.User); + Role callerRole = Mockito.mock(Role.class); + Mockito.when(callerRole.getRoleType()).thenReturn(RoleType.DomainAdmin); + Account caller = Mockito.mock(Account.class); + Mockito.when(caller.getRoleId()).thenReturn(2L); + Mockito.when(roleService.findRole(1L)).thenReturn(accountRole); + Mockito.when(roleService.findRole(2L)).thenReturn(callerRole); + accountManagerImpl.validateRoleChange(account, newRole, caller); + } + + @Test(expected = PermissionDeniedException.class) + public void testValidateRoleAdminCannotEscalateAdminFromNonRootDomain() { + Account account = Mockito.mock(Account.class); + Mockito.when(account.getRoleId()).thenReturn(1L); + Mockito.when(account.getDomainId()).thenReturn(2L); + Role newRole = Mockito.mock(Role.class); + Mockito.when(newRole.getRoleType()).thenReturn(RoleType.Admin); + Role accountRole = Mockito.mock(Role.class); + Role callerRole = Mockito.mock(Role.class); + Mockito.when(callerRole.getRoleType()).thenReturn(RoleType.Admin); + Account caller = Mockito.mock(Account.class); + Mockito.when(caller.getRoleId()).thenReturn(2L); + Mockito.when(roleService.findRole(1L)).thenReturn(accountRole); + Mockito.when(roleService.findRole(2L)).thenReturn(callerRole); + accountManagerImpl.validateRoleChange(account, newRole, caller); + } } diff --cc utils/src/main/java/com/cloud/utils/net/NetUtils.java index 7abe64b0433,2703deaad64..500e2401fca --- a/utils/src/main/java/com/cloud/utils/net/NetUtils.java +++ b/utils/src/main/java/com/cloud/utils/net/NetUtils.java @@@ -1062,16 -1063,16 +1066,16 @@@ public class NetUtils // If it's a host name, don't allow to start with digit if (hostName.length() > 63 || hostName.length() < 1) { - s_logger.warn("Domain name label must be between 1 and 63 characters long"); + LOGGER.warn("Domain name label must be between 1 and 63 characters long"); return false; - } else if (!hostName.toLowerCase().matches("[a-z0-9-]*")) { + } else if (!HOSTNAME_PATTERN.matcher(hostName).matches()) { - s_logger.warn("Domain name label may contain only the ASCII letters 'a' through 'z' (in a case-insensitive manner)"); + LOGGER.warn("Domain name label may contain only the ASCII letters 'a' through 'z' (in a case-insensitive manner)"); return false; } else if (hostName.startsWith("-") || hostName.endsWith("-")) { - LOGGER.warn("Domain name label can not start with a hyphen and digit, and must not end with a hyphen"); - s_logger.warn("Domain name label can not start or end with a hyphen"); ++ LOGGER.warn("Domain name label can not start or end with a hyphen"); return false; - } else if (isHostName && hostName.matches("^[0-9-].*")) { + } else if (isHostName && START_HOSTNAME_PATTERN.matcher(hostName).matches()) { - s_logger.warn("Host name can't start with digit"); + LOGGER.warn("Host name can't start with digit"); return false; }