diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 4e8f60f..4cbff28 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -42,7 +42,7 @@ website_job: extends: - .gitlab_native_build_job needs: - - job: x86_64-ubuntu-2204-container + - job: x86_64-ubuntu-2404-container optional: true script: - ant docs @@ -52,7 +52,8 @@ website_job: paths: - website variables: - NAME: ubuntu-2204 + NAME: ubuntu-2404 + TARGET_BASE_IMAGE: docker.io/library/ubuntu:24.04 pages: stage: pages diff --git a/README.in b/README.in index 15eddbc..d043b0a 100644 --- a/README.in +++ b/README.in @@ -15,5 +15,5 @@ By default the installs it to /usr/share/java/@version@.jar 5. There is full javadoc for the API in /usr/share/javadoc/libvirt-java-@version@/ -6. The full API can be found at https://libvirt.org/html/libvirt-libvirt.html +6. The full API can be found at https://libvirt.org/html/index.html diff --git a/build.properties b/build.properties index 3988131..e5eb1e3 100644 --- a/build.properties +++ b/build.properties @@ -1,6 +1,6 @@ -version=0.5.3 +version=0.5.4 release=1 -libvirt.required=0.9.12 +libvirt.required=1.1.0 java.required=1.8.0 java.target=1.8 java.source=1.8 diff --git a/ci/buildenv/almalinux-10.sh b/ci/buildenv/almalinux-10.sh new file mode 100644 index 0000000..5f912df --- /dev/null +++ b/ci/buildenv/almalinux-10.sh @@ -0,0 +1,28 @@ +# THIS FILE WAS AUTO-GENERATED +# +# $ lcitool manifest ci/manifest.yml +# +# https://gitlab.com/libvirt/libvirt-ci + +function install_buildenv() { + dnf --quiet update -y + dnf --quiet install 'dnf-command(config-manager)' -y + dnf --quiet config-manager --set-enabled -y crb + dnf --quiet install -y epel-release + dnf --quiet install almalinux-release-devel -y + dnf --quiet config-manager --set-enabled -y devel + dnf --quiet install -y \ + ant \ + ant-junit \ + ca-certificates \ + git \ + glibc-langpack-en \ + java-25-openjdk-headless \ + jna \ + junit \ + libvirt-devel \ + rpm-build + rpm -qa | sort > /packages.txt +} + +export LANG="en_US.UTF-8" diff --git a/ci/buildenv/almalinux-8.sh b/ci/buildenv/almalinux-8.sh deleted file mode 100644 index 4478e4f..0000000 --- a/ci/buildenv/almalinux-8.sh +++ /dev/null @@ -1,25 +0,0 @@ -# THIS FILE WAS AUTO-GENERATED -# -# $ lcitool manifest ci/manifest.yml -# -# https://gitlab.com/libvirt/libvirt-ci - -function install_buildenv() { - dnf update -y - dnf install 'dnf-command(config-manager)' -y - dnf config-manager --set-enabled -y powertools - dnf install -y centos-release-advanced-virtualization - dnf install -y epel-release - dnf install -y \ - ant \ - ca-certificates \ - git \ - glibc-langpack-en \ - java-11-openjdk-headless \ - jna \ - libvirt-devel \ - rpm-build - rpm -qa | sort > /packages.txt -} - -export LANG="en_US.UTF-8" diff --git a/ci/buildenv/almalinux-9.sh b/ci/buildenv/almalinux-9.sh new file mode 100644 index 0000000..5f912df --- /dev/null +++ b/ci/buildenv/almalinux-9.sh @@ -0,0 +1,28 @@ +# THIS FILE WAS AUTO-GENERATED +# +# $ lcitool manifest ci/manifest.yml +# +# https://gitlab.com/libvirt/libvirt-ci + +function install_buildenv() { + dnf --quiet update -y + dnf --quiet install 'dnf-command(config-manager)' -y + dnf --quiet config-manager --set-enabled -y crb + dnf --quiet install -y epel-release + dnf --quiet install almalinux-release-devel -y + dnf --quiet config-manager --set-enabled -y devel + dnf --quiet install -y \ + ant \ + ant-junit \ + ca-certificates \ + git \ + glibc-langpack-en \ + java-25-openjdk-headless \ + jna \ + junit \ + libvirt-devel \ + rpm-build + rpm -qa | sort > /packages.txt +} + +export LANG="en_US.UTF-8" diff --git a/ci/buildenv/centos-stream-10.sh b/ci/buildenv/centos-stream-10.sh new file mode 100644 index 0000000..4fb85f8 --- /dev/null +++ b/ci/buildenv/centos-stream-10.sh @@ -0,0 +1,26 @@ +# THIS FILE WAS AUTO-GENERATED +# +# $ lcitool manifest ci/manifest.yml +# +# https://gitlab.com/libvirt/libvirt-ci + +function install_buildenv() { + dnf --quiet distro-sync -y + dnf --quiet install 'dnf-command(config-manager)' -y + dnf --quiet config-manager --set-enabled -y crb + dnf --quiet install -y epel-release + dnf --quiet install -y \ + ant \ + ant-junit \ + ca-certificates \ + git \ + glibc-langpack-en \ + java-25-openjdk-headless \ + jna \ + junit \ + libvirt-devel \ + rpm-build + rpm -qa | sort > /packages.txt +} + +export LANG="en_US.UTF-8" diff --git a/ci/buildenv/centos-stream-8.sh b/ci/buildenv/centos-stream-8.sh deleted file mode 100644 index a78bbc6..0000000 --- a/ci/buildenv/centos-stream-8.sh +++ /dev/null @@ -1,26 +0,0 @@ -# THIS FILE WAS AUTO-GENERATED -# -# $ lcitool manifest ci/manifest.yml -# -# https://gitlab.com/libvirt/libvirt-ci - -function install_buildenv() { - dnf distro-sync -y - dnf install 'dnf-command(config-manager)' -y - dnf config-manager --set-enabled -y powertools - dnf install -y centos-release-advanced-virtualization - dnf install -y epel-release - dnf install -y epel-next-release - dnf install -y \ - ant \ - ca-certificates \ - git \ - glibc-langpack-en \ - java-11-openjdk-headless \ - jna \ - libvirt-devel \ - rpm-build - rpm -qa | sort > /packages.txt -} - -export LANG="en_US.UTF-8" diff --git a/ci/buildenv/centos-stream-9.sh b/ci/buildenv/centos-stream-9.sh new file mode 100644 index 0000000..ee7baf9 --- /dev/null +++ b/ci/buildenv/centos-stream-9.sh @@ -0,0 +1,27 @@ +# THIS FILE WAS AUTO-GENERATED +# +# $ lcitool manifest ci/manifest.yml +# +# https://gitlab.com/libvirt/libvirt-ci + +function install_buildenv() { + dnf --quiet distro-sync -y + dnf --quiet install 'dnf-command(config-manager)' -y + dnf --quiet config-manager --set-enabled -y crb + dnf --quiet install -y epel-release + dnf --quiet install -y epel-next-release + dnf --quiet install -y \ + ant \ + ant-junit \ + ca-certificates \ + git \ + glibc-langpack-en \ + java-25-openjdk-headless \ + jna \ + junit \ + libvirt-devel \ + rpm-build + rpm -qa | sort > /packages.txt +} + +export LANG="en_US.UTF-8" diff --git a/ci/buildenv/debian-11.sh b/ci/buildenv/debian-12.sh similarity index 100% rename from ci/buildenv/debian-11.sh rename to ci/buildenv/debian-12.sh diff --git a/ci/buildenv/ubuntu-2004.sh b/ci/buildenv/debian-13.sh similarity index 94% rename from ci/buildenv/ubuntu-2004.sh rename to ci/buildenv/debian-13.sh index d2f6a77..080ad4f 100644 --- a/ci/buildenv/ubuntu-2004.sh +++ b/ci/buildenv/debian-13.sh @@ -17,7 +17,7 @@ function install_buildenv() { libjna-java \ libvirt-dev \ locales \ - openjdk-17-jdk-headless + openjdk-25-jdk-headless sed -Ei 's,^# (en_US\.UTF-8 .*)$,\1,' /etc/locale.gen dpkg-reconfigure locales dpkg-query --showformat '${Package}_${Version}_${Architecture}\n' --show > /packages.txt diff --git a/ci/buildenv/debian-sid.sh b/ci/buildenv/debian-sid.sh index d2f6a77..080ad4f 100644 --- a/ci/buildenv/debian-sid.sh +++ b/ci/buildenv/debian-sid.sh @@ -17,7 +17,7 @@ function install_buildenv() { libjna-java \ libvirt-dev \ locales \ - openjdk-17-jdk-headless + openjdk-25-jdk-headless sed -Ei 's,^# (en_US\.UTF-8 .*)$,\1,' /etc/locale.gen dpkg-reconfigure locales dpkg-query --showformat '${Package}_${Version}_${Architecture}\n' --show > /packages.txt diff --git a/ci/buildenv/fedora-38.sh b/ci/buildenv/fedora-38.sh deleted file mode 100644 index 46b5102..0000000 --- a/ci/buildenv/fedora-38.sh +++ /dev/null @@ -1,23 +0,0 @@ -# THIS FILE WAS AUTO-GENERATED -# -# $ lcitool manifest ci/manifest.yml -# -# https://gitlab.com/libvirt/libvirt-ci - -function install_buildenv() { - dnf update -y - dnf install -y \ - ant \ - ant-junit \ - ca-certificates \ - git \ - glibc-langpack-en \ - java-11-openjdk-headless \ - jna \ - junit \ - libvirt-devel \ - rpm-build - rpm -qa | sort > /packages.txt -} - -export LANG="en_US.UTF-8" diff --git a/ci/buildenv/fedora-39.sh b/ci/buildenv/fedora-39.sh deleted file mode 100644 index 46b5102..0000000 --- a/ci/buildenv/fedora-39.sh +++ /dev/null @@ -1,23 +0,0 @@ -# THIS FILE WAS AUTO-GENERATED -# -# $ lcitool manifest ci/manifest.yml -# -# https://gitlab.com/libvirt/libvirt-ci - -function install_buildenv() { - dnf update -y - dnf install -y \ - ant \ - ant-junit \ - ca-certificates \ - git \ - glibc-langpack-en \ - java-11-openjdk-headless \ - jna \ - junit \ - libvirt-devel \ - rpm-build - rpm -qa | sort > /packages.txt -} - -export LANG="en_US.UTF-8" diff --git a/ci/buildenv/fedora-43.sh b/ci/buildenv/fedora-43.sh new file mode 100644 index 0000000..3f711b3 --- /dev/null +++ b/ci/buildenv/fedora-43.sh @@ -0,0 +1,23 @@ +# THIS FILE WAS AUTO-GENERATED +# +# $ lcitool manifest ci/manifest.yml +# +# https://gitlab.com/libvirt/libvirt-ci + +function install_buildenv() { + dnf --quiet update -y + dnf --quiet install -y \ + ant \ + ant-junit \ + ca-certificates \ + git \ + glibc-langpack-en \ + java-25-openjdk-headless \ + jna \ + junit \ + libvirt-devel \ + rpm-build + rpm -qa | sort > /packages.txt +} + +export LANG="en_US.UTF-8" diff --git a/ci/buildenv/fedora-44.sh b/ci/buildenv/fedora-44.sh new file mode 100644 index 0000000..3f711b3 --- /dev/null +++ b/ci/buildenv/fedora-44.sh @@ -0,0 +1,23 @@ +# THIS FILE WAS AUTO-GENERATED +# +# $ lcitool manifest ci/manifest.yml +# +# https://gitlab.com/libvirt/libvirt-ci + +function install_buildenv() { + dnf --quiet update -y + dnf --quiet install -y \ + ant \ + ant-junit \ + ca-certificates \ + git \ + glibc-langpack-en \ + java-25-openjdk-headless \ + jna \ + junit \ + libvirt-devel \ + rpm-build + rpm -qa | sort > /packages.txt +} + +export LANG="en_US.UTF-8" diff --git a/ci/buildenv/fedora-rawhide.sh b/ci/buildenv/fedora-rawhide.sh index 1ba76e7..d082b18 100644 --- a/ci/buildenv/fedora-rawhide.sh +++ b/ci/buildenv/fedora-rawhide.sh @@ -5,19 +5,19 @@ # https://gitlab.com/libvirt/libvirt-ci function install_buildenv() { - dnf update -y --nogpgcheck fedora-gpg-keys - dnf distro-sync -y - dnf install -y \ - ant \ - ant-junit \ - ca-certificates \ - git \ - glibc-langpack-en \ - java-11-openjdk-headless \ - jna \ - junit \ - libvirt-devel \ - rpm-build + dnf --quiet update -y --nogpgcheck fedora-gpg-keys + dnf --quiet distro-sync -y + dnf --quiet install -y \ + ant \ + ant-junit \ + ca-certificates \ + git \ + glibc-langpack-en \ + java-25-openjdk-headless \ + jna \ + junit \ + libvirt-devel \ + rpm-build rpm -qa | sort > /packages.txt } diff --git a/ci/buildenv/opensuse-leap-15.sh b/ci/buildenv/opensuse-leap-15.sh index e0a14fb..9cfdf13 100644 --- a/ci/buildenv/opensuse-leap-15.sh +++ b/ci/buildenv/opensuse-leap-15.sh @@ -6,13 +6,14 @@ function install_buildenv() { zypper update -y + zypper addrepo -fc https://download.opensuse.org/update/leap/15.6/backports/openSUSE:Backports:SLE-15-SP6:Update.repo zypper install -y \ ant \ ant-junit \ ca-certificates \ git \ glibc-locale \ - java-11-openjdk-headless \ + java-21-openjdk-headless \ jna \ junit \ libvirt-devel \ diff --git a/ci/buildenv/ubuntu-2404.sh b/ci/buildenv/ubuntu-2404.sh new file mode 100644 index 0000000..080ad4f --- /dev/null +++ b/ci/buildenv/ubuntu-2404.sh @@ -0,0 +1,26 @@ +# THIS FILE WAS AUTO-GENERATED +# +# $ lcitool manifest ci/manifest.yml +# +# https://gitlab.com/libvirt/libvirt-ci + +function install_buildenv() { + export DEBIAN_FRONTEND=noninteractive + apt-get update + apt-get dist-upgrade -y + apt-get install --no-install-recommends -y \ + ant \ + ant-optional \ + ca-certificates \ + git \ + junit \ + libjna-java \ + libvirt-dev \ + locales \ + openjdk-25-jdk-headless + sed -Ei 's,^# (en_US\.UTF-8 .*)$,\1,' /etc/locale.gen + dpkg-reconfigure locales + dpkg-query --showformat '${Package}_${Version}_${Architecture}\n' --show > /packages.txt +} + +export LANG="en_US.UTF-8" diff --git a/ci/buildenv/ubuntu-2204.sh b/ci/buildenv/ubuntu-2604.sh similarity index 97% rename from ci/buildenv/ubuntu-2204.sh rename to ci/buildenv/ubuntu-2604.sh index a022f83..5e48d75 100644 --- a/ci/buildenv/ubuntu-2204.sh +++ b/ci/buildenv/ubuntu-2604.sh @@ -32,7 +32,7 @@ function install_buildenv() { make \ meson \ ninja-build \ - openjdk-17-jdk-headless \ + openjdk-25-jdk-headless \ perl-base \ pkgconf \ python3 \ diff --git a/ci/containers/almalinux-10.Dockerfile b/ci/containers/almalinux-10.Dockerfile new file mode 100644 index 0000000..8965e23 --- /dev/null +++ b/ci/containers/almalinux-10.Dockerfile @@ -0,0 +1,30 @@ +# THIS FILE WAS AUTO-GENERATED +# +# $ lcitool manifest ci/manifest.yml +# +# https://gitlab.com/libvirt/libvirt-ci + +FROM docker.io/library/almalinux:10 + +RUN dnf --quiet update -y && \ + dnf --quiet install 'dnf-command(config-manager)' -y && \ + dnf --quiet config-manager --set-enabled -y crb && \ + dnf --quiet install -y epel-release && \ + dnf --quiet install almalinux-release-devel -y && \ + dnf --quiet config-manager --set-enabled -y devel && \ + dnf --quiet install -y \ + ant \ + ant-junit \ + ca-certificates \ + git \ + glibc-langpack-en \ + java-25-openjdk-headless \ + jna \ + junit \ + libvirt-devel \ + rpm-build && \ + dnf --quiet autoremove -y && \ + dnf --quiet clean all -y && \ + rpm -qa | sort > /packages.txt + +ENV LANG="en_US.UTF-8" diff --git a/ci/containers/almalinux-8.Dockerfile b/ci/containers/almalinux-8.Dockerfile deleted file mode 100644 index 644e254..0000000 --- a/ci/containers/almalinux-8.Dockerfile +++ /dev/null @@ -1,27 +0,0 @@ -# THIS FILE WAS AUTO-GENERATED -# -# $ lcitool manifest ci/manifest.yml -# -# https://gitlab.com/libvirt/libvirt-ci - -FROM docker.io/library/almalinux:8 - -RUN dnf update -y && \ - dnf install 'dnf-command(config-manager)' -y && \ - dnf config-manager --set-enabled -y powertools && \ - dnf install -y centos-release-advanced-virtualization && \ - dnf install -y epel-release && \ - dnf install -y \ - ant \ - ca-certificates \ - git \ - glibc-langpack-en \ - java-11-openjdk-headless \ - jna \ - libvirt-devel \ - rpm-build && \ - dnf autoremove -y && \ - dnf clean all -y && \ - rpm -qa | sort > /packages.txt - -ENV LANG "en_US.UTF-8" diff --git a/ci/containers/almalinux-9.Dockerfile b/ci/containers/almalinux-9.Dockerfile new file mode 100644 index 0000000..cc5d74f --- /dev/null +++ b/ci/containers/almalinux-9.Dockerfile @@ -0,0 +1,30 @@ +# THIS FILE WAS AUTO-GENERATED +# +# $ lcitool manifest ci/manifest.yml +# +# https://gitlab.com/libvirt/libvirt-ci + +FROM docker.io/library/almalinux:9 + +RUN dnf --quiet update -y && \ + dnf --quiet install 'dnf-command(config-manager)' -y && \ + dnf --quiet config-manager --set-enabled -y crb && \ + dnf --quiet install -y epel-release && \ + dnf --quiet install almalinux-release-devel -y && \ + dnf --quiet config-manager --set-enabled -y devel && \ + dnf --quiet install -y \ + ant \ + ant-junit \ + ca-certificates \ + git \ + glibc-langpack-en \ + java-25-openjdk-headless \ + jna \ + junit \ + libvirt-devel \ + rpm-build && \ + dnf --quiet autoremove -y && \ + dnf --quiet clean all -y && \ + rpm -qa | sort > /packages.txt + +ENV LANG="en_US.UTF-8" diff --git a/ci/containers/centos-stream-10.Dockerfile b/ci/containers/centos-stream-10.Dockerfile new file mode 100644 index 0000000..a71bb8d --- /dev/null +++ b/ci/containers/centos-stream-10.Dockerfile @@ -0,0 +1,28 @@ +# THIS FILE WAS AUTO-GENERATED +# +# $ lcitool manifest ci/manifest.yml +# +# https://gitlab.com/libvirt/libvirt-ci + +FROM quay.io/centos/centos:stream10 + +RUN dnf --quiet distro-sync -y && \ + dnf --quiet install 'dnf-command(config-manager)' -y && \ + dnf --quiet config-manager --set-enabled -y crb && \ + dnf --quiet install -y epel-release && \ + dnf --quiet install -y \ + ant \ + ant-junit \ + ca-certificates \ + git \ + glibc-langpack-en \ + java-25-openjdk-headless \ + jna \ + junit \ + libvirt-devel \ + rpm-build && \ + dnf --quiet autoremove -y && \ + dnf --quiet clean all -y && \ + rpm -qa | sort > /packages.txt + +ENV LANG="en_US.UTF-8" diff --git a/ci/containers/centos-stream-8.Dockerfile b/ci/containers/centos-stream-8.Dockerfile deleted file mode 100644 index 715f7c3..0000000 --- a/ci/containers/centos-stream-8.Dockerfile +++ /dev/null @@ -1,28 +0,0 @@ -# THIS FILE WAS AUTO-GENERATED -# -# $ lcitool manifest ci/manifest.yml -# -# https://gitlab.com/libvirt/libvirt-ci - -FROM quay.io/centos/centos:stream8 - -RUN dnf distro-sync -y && \ - dnf install 'dnf-command(config-manager)' -y && \ - dnf config-manager --set-enabled -y powertools && \ - dnf install -y centos-release-advanced-virtualization && \ - dnf install -y epel-release && \ - dnf install -y epel-next-release && \ - dnf install -y \ - ant \ - ca-certificates \ - git \ - glibc-langpack-en \ - java-11-openjdk-headless \ - jna \ - libvirt-devel \ - rpm-build && \ - dnf autoremove -y && \ - dnf clean all -y && \ - rpm -qa | sort > /packages.txt - -ENV LANG "en_US.UTF-8" diff --git a/ci/containers/centos-stream-9.Dockerfile b/ci/containers/centos-stream-9.Dockerfile new file mode 100644 index 0000000..ca2acbf --- /dev/null +++ b/ci/containers/centos-stream-9.Dockerfile @@ -0,0 +1,29 @@ +# THIS FILE WAS AUTO-GENERATED +# +# $ lcitool manifest ci/manifest.yml +# +# https://gitlab.com/libvirt/libvirt-ci + +FROM quay.io/centos/centos:stream9 + +RUN dnf --quiet distro-sync -y && \ + dnf --quiet install 'dnf-command(config-manager)' -y && \ + dnf --quiet config-manager --set-enabled -y crb && \ + dnf --quiet install -y epel-release && \ + dnf --quiet install -y epel-next-release && \ + dnf --quiet install -y \ + ant \ + ant-junit \ + ca-certificates \ + git \ + glibc-langpack-en \ + java-25-openjdk-headless \ + jna \ + junit \ + libvirt-devel \ + rpm-build && \ + dnf --quiet autoremove -y && \ + dnf --quiet clean all -y && \ + rpm -qa | sort > /packages.txt + +ENV LANG="en_US.UTF-8" diff --git a/ci/containers/debian-11.Dockerfile b/ci/containers/debian-12.Dockerfile similarity index 93% rename from ci/containers/debian-11.Dockerfile rename to ci/containers/debian-12.Dockerfile index ea3520b..c7477ab 100644 --- a/ci/containers/debian-11.Dockerfile +++ b/ci/containers/debian-12.Dockerfile @@ -4,7 +4,7 @@ # # https://gitlab.com/libvirt/libvirt-ci -FROM docker.io/library/debian:11-slim +FROM docker.io/library/debian:12-slim RUN export DEBIAN_FRONTEND=noninteractive && \ apt-get update && \ @@ -26,4 +26,4 @@ RUN export DEBIAN_FRONTEND=noninteractive && \ dpkg-reconfigure locales && \ dpkg-query --showformat '${Package}_${Version}_${Architecture}\n' --show > /packages.txt -ENV LANG "en_US.UTF-8" +ENV LANG="en_US.UTF-8" diff --git a/ci/containers/debian-13.Dockerfile b/ci/containers/debian-13.Dockerfile new file mode 100644 index 0000000..f39fb98 --- /dev/null +++ b/ci/containers/debian-13.Dockerfile @@ -0,0 +1,29 @@ +# THIS FILE WAS AUTO-GENERATED +# +# $ lcitool manifest ci/manifest.yml +# +# https://gitlab.com/libvirt/libvirt-ci + +FROM docker.io/library/debian:13-slim + +RUN export DEBIAN_FRONTEND=noninteractive && \ + apt-get update && \ + apt-get install -y eatmydata && \ + eatmydata apt-get dist-upgrade -y && \ + eatmydata apt-get install --no-install-recommends -y \ + ant \ + ant-optional \ + ca-certificates \ + git \ + junit \ + libjna-java \ + libvirt-dev \ + locales \ + openjdk-25-jdk-headless && \ + eatmydata apt-get autoremove -y && \ + eatmydata apt-get autoclean -y && \ + sed -Ei 's,^# (en_US\.UTF-8 .*)$,\1,' /etc/locale.gen && \ + dpkg-reconfigure locales && \ + dpkg-query --showformat '${Package}_${Version}_${Architecture}\n' --show > /packages.txt + +ENV LANG="en_US.UTF-8" diff --git a/ci/containers/debian-sid.Dockerfile b/ci/containers/debian-sid.Dockerfile index 03d2f57..4faeaf7 100644 --- a/ci/containers/debian-sid.Dockerfile +++ b/ci/containers/debian-sid.Dockerfile @@ -19,11 +19,11 @@ RUN export DEBIAN_FRONTEND=noninteractive && \ libjna-java \ libvirt-dev \ locales \ - openjdk-17-jdk-headless && \ + openjdk-25-jdk-headless && \ eatmydata apt-get autoremove -y && \ eatmydata apt-get autoclean -y && \ sed -Ei 's,^# (en_US\.UTF-8 .*)$,\1,' /etc/locale.gen && \ dpkg-reconfigure locales && \ dpkg-query --showformat '${Package}_${Version}_${Architecture}\n' --show > /packages.txt -ENV LANG "en_US.UTF-8" +ENV LANG="en_US.UTF-8" diff --git a/ci/containers/fedora-38.Dockerfile b/ci/containers/fedora-38.Dockerfile deleted file mode 100644 index c53703a..0000000 --- a/ci/containers/fedora-38.Dockerfile +++ /dev/null @@ -1,35 +0,0 @@ -# THIS FILE WAS AUTO-GENERATED -# -# $ lcitool manifest ci/manifest.yml -# -# https://gitlab.com/libvirt/libvirt-ci - -FROM registry.fedoraproject.org/fedora:38 - -RUN dnf install -y nosync && \ - printf '#!/bin/sh\n\ -if test -d /usr/lib64\n\ -then\n\ - export LD_PRELOAD=/usr/lib64/nosync/nosync.so\n\ -else\n\ - export LD_PRELOAD=/usr/lib/nosync/nosync.so\n\ -fi\n\ -exec "$@"\n' > /usr/bin/nosync && \ - chmod +x /usr/bin/nosync && \ - nosync dnf update -y && \ - nosync dnf install -y \ - ant \ - ant-junit \ - ca-certificates \ - git \ - glibc-langpack-en \ - java-11-openjdk-headless \ - jna \ - junit \ - libvirt-devel \ - rpm-build && \ - nosync dnf autoremove -y && \ - nosync dnf clean all -y && \ - rpm -qa | sort > /packages.txt - -ENV LANG "en_US.UTF-8" diff --git a/ci/containers/fedora-39.Dockerfile b/ci/containers/fedora-39.Dockerfile deleted file mode 100644 index 9cb7d0b..0000000 --- a/ci/containers/fedora-39.Dockerfile +++ /dev/null @@ -1,35 +0,0 @@ -# THIS FILE WAS AUTO-GENERATED -# -# $ lcitool manifest ci/manifest.yml -# -# https://gitlab.com/libvirt/libvirt-ci - -FROM registry.fedoraproject.org/fedora:39 - -RUN dnf install -y nosync && \ - printf '#!/bin/sh\n\ -if test -d /usr/lib64\n\ -then\n\ - export LD_PRELOAD=/usr/lib64/nosync/nosync.so\n\ -else\n\ - export LD_PRELOAD=/usr/lib/nosync/nosync.so\n\ -fi\n\ -exec "$@"\n' > /usr/bin/nosync && \ - chmod +x /usr/bin/nosync && \ - nosync dnf update -y && \ - nosync dnf install -y \ - ant \ - ant-junit \ - ca-certificates \ - git \ - glibc-langpack-en \ - java-11-openjdk-headless \ - jna \ - junit \ - libvirt-devel \ - rpm-build && \ - nosync dnf autoremove -y && \ - nosync dnf clean all -y && \ - rpm -qa | sort > /packages.txt - -ENV LANG "en_US.UTF-8" diff --git a/ci/containers/fedora-43.Dockerfile b/ci/containers/fedora-43.Dockerfile new file mode 100644 index 0000000..f6f7bd9 --- /dev/null +++ b/ci/containers/fedora-43.Dockerfile @@ -0,0 +1,35 @@ +# THIS FILE WAS AUTO-GENERATED +# +# $ lcitool manifest ci/manifest.yml +# +# https://gitlab.com/libvirt/libvirt-ci + +FROM registry.fedoraproject.org/fedora:43 + +RUN dnf --quiet install -y nosync && \ + printf '#!/bin/sh\n\ +if test -d /usr/lib64\n\ +then\n\ + export LD_PRELOAD=/usr/lib64/nosync/nosync.so\n\ +else\n\ + export LD_PRELOAD=/usr/lib/nosync/nosync.so\n\ +fi\n\ +exec "$@"\n' > /usr/bin/nosync && \ + chmod +x /usr/bin/nosync && \ + nosync dnf --quiet update -y && \ + nosync dnf --quiet install -y \ + ant \ + ant-junit \ + ca-certificates \ + git \ + glibc-langpack-en \ + java-25-openjdk-headless \ + jna \ + junit \ + libvirt-devel \ + rpm-build && \ + nosync dnf --quiet autoremove -y && \ + nosync dnf --quiet clean all -y && \ + rpm -qa | sort > /packages.txt + +ENV LANG="en_US.UTF-8" diff --git a/ci/containers/fedora-44.Dockerfile b/ci/containers/fedora-44.Dockerfile new file mode 100644 index 0000000..471d596 --- /dev/null +++ b/ci/containers/fedora-44.Dockerfile @@ -0,0 +1,35 @@ +# THIS FILE WAS AUTO-GENERATED +# +# $ lcitool manifest ci/manifest.yml +# +# https://gitlab.com/libvirt/libvirt-ci + +FROM registry.fedoraproject.org/fedora:44 + +RUN dnf --quiet install -y nosync && \ + printf '#!/bin/sh\n\ +if test -d /usr/lib64\n\ +then\n\ + export LD_PRELOAD=/usr/lib64/nosync/nosync.so\n\ +else\n\ + export LD_PRELOAD=/usr/lib/nosync/nosync.so\n\ +fi\n\ +exec "$@"\n' > /usr/bin/nosync && \ + chmod +x /usr/bin/nosync && \ + nosync dnf --quiet update -y && \ + nosync dnf --quiet install -y \ + ant \ + ant-junit \ + ca-certificates \ + git \ + glibc-langpack-en \ + java-25-openjdk-headless \ + jna \ + junit \ + libvirt-devel \ + rpm-build && \ + nosync dnf --quiet autoremove -y && \ + nosync dnf --quiet clean all -y && \ + rpm -qa | sort > /packages.txt + +ENV LANG="en_US.UTF-8" diff --git a/ci/containers/fedora-rawhide.Dockerfile b/ci/containers/fedora-rawhide.Dockerfile index 8fb86c0..9d56455 100644 --- a/ci/containers/fedora-rawhide.Dockerfile +++ b/ci/containers/fedora-rawhide.Dockerfile @@ -6,8 +6,8 @@ FROM registry.fedoraproject.org/fedora:rawhide -RUN dnf update -y --nogpgcheck fedora-gpg-keys && \ - dnf install -y nosync && \ +RUN dnf --quiet update -y --nogpgcheck fedora-gpg-keys && \ + dnf --quiet install -y nosync && \ printf '#!/bin/sh\n\ if test -d /usr/lib64\n\ then\n\ @@ -17,20 +17,20 @@ else\n\ fi\n\ exec "$@"\n' > /usr/bin/nosync && \ chmod +x /usr/bin/nosync && \ - nosync dnf distro-sync -y && \ - nosync dnf install -y \ - ant \ - ant-junit \ - ca-certificates \ - git \ - glibc-langpack-en \ - java-11-openjdk-headless \ - jna \ - junit \ - libvirt-devel \ - rpm-build && \ - nosync dnf autoremove -y && \ - nosync dnf clean all -y && \ + nosync dnf --quiet distro-sync -y && \ + nosync dnf --quiet install -y \ + ant \ + ant-junit \ + ca-certificates \ + git \ + glibc-langpack-en \ + java-25-openjdk-headless \ + jna \ + junit \ + libvirt-devel \ + rpm-build && \ + nosync dnf --quiet autoremove -y && \ + nosync dnf --quiet clean all -y && \ rpm -qa | sort > /packages.txt -ENV LANG "en_US.UTF-8" +ENV LANG="en_US.UTF-8" diff --git a/ci/containers/opensuse-leap-15.Dockerfile b/ci/containers/opensuse-leap-15.Dockerfile index 263f09f..a5c2dd0 100644 --- a/ci/containers/opensuse-leap-15.Dockerfile +++ b/ci/containers/opensuse-leap-15.Dockerfile @@ -4,16 +4,17 @@ # # https://gitlab.com/libvirt/libvirt-ci -FROM registry.opensuse.org/opensuse/leap:15.5 +FROM registry.opensuse.org/opensuse/leap:15.6 RUN zypper update -y && \ + zypper addrepo -fc https://download.opensuse.org/update/leap/15.6/backports/openSUSE:Backports:SLE-15-SP6:Update.repo && \ zypper install -y \ ant \ ant-junit \ ca-certificates \ git \ glibc-locale \ - java-11-openjdk-headless \ + java-21-openjdk-headless \ jna \ junit \ libvirt-devel \ @@ -21,4 +22,4 @@ RUN zypper update -y && \ zypper clean --all && \ rpm -qa | sort > /packages.txt -ENV LANG "en_US.UTF-8" +ENV LANG="en_US.UTF-8" diff --git a/ci/containers/ubuntu-2004.Dockerfile b/ci/containers/ubuntu-2404.Dockerfile similarity index 88% rename from ci/containers/ubuntu-2004.Dockerfile rename to ci/containers/ubuntu-2404.Dockerfile index 6a39f5e..d612945 100644 --- a/ci/containers/ubuntu-2004.Dockerfile +++ b/ci/containers/ubuntu-2404.Dockerfile @@ -4,7 +4,7 @@ # # https://gitlab.com/libvirt/libvirt-ci -FROM docker.io/library/ubuntu:20.04 +FROM docker.io/library/ubuntu:24.04 RUN export DEBIAN_FRONTEND=noninteractive && \ apt-get update && \ @@ -19,11 +19,11 @@ RUN export DEBIAN_FRONTEND=noninteractive && \ libjna-java \ libvirt-dev \ locales \ - openjdk-17-jdk-headless && \ + openjdk-25-jdk-headless && \ eatmydata apt-get autoremove -y && \ eatmydata apt-get autoclean -y && \ sed -Ei 's,^# (en_US\.UTF-8 .*)$,\1,' /etc/locale.gen && \ dpkg-reconfigure locales && \ dpkg-query --showformat '${Package}_${Version}_${Architecture}\n' --show > /packages.txt -ENV LANG "en_US.UTF-8" +ENV LANG="en_US.UTF-8" diff --git a/ci/containers/ubuntu-2204.Dockerfile b/ci/containers/ubuntu-2604.Dockerfile similarity index 88% rename from ci/containers/ubuntu-2204.Dockerfile rename to ci/containers/ubuntu-2604.Dockerfile index 6390620..36bbe6c 100644 --- a/ci/containers/ubuntu-2204.Dockerfile +++ b/ci/containers/ubuntu-2604.Dockerfile @@ -4,7 +4,7 @@ # # https://gitlab.com/libvirt/libvirt-ci -FROM docker.io/library/ubuntu:22.04 +FROM docker.io/library/ubuntu:26.04 RUN export DEBIAN_FRONTEND=noninteractive && \ apt-get update && \ @@ -34,7 +34,7 @@ RUN export DEBIAN_FRONTEND=noninteractive && \ make \ meson \ ninja-build \ - openjdk-17-jdk-headless \ + openjdk-25-jdk-headless \ perl-base \ pkgconf \ python3 \ @@ -50,8 +50,8 @@ RUN export DEBIAN_FRONTEND=noninteractive && \ ln -s /usr/bin/ccache /usr/libexec/ccache-wrappers/cc && \ ln -s /usr/bin/ccache /usr/libexec/ccache-wrappers/gcc -ENV CCACHE_WRAPPERSDIR "/usr/libexec/ccache-wrappers" -ENV LANG "en_US.UTF-8" -ENV MAKE "/usr/bin/make" -ENV NINJA "/usr/bin/ninja" -ENV PYTHON "/usr/bin/python3" +ENV CCACHE_WRAPPERSDIR="/usr/libexec/ccache-wrappers" +ENV LANG="en_US.UTF-8" +ENV MAKE="/usr/bin/make" +ENV NINJA="/usr/bin/ninja" +ENV PYTHON="/usr/bin/python3" diff --git a/ci/gitlab.yml b/ci/gitlab.yml index 7bb68b8..0e6de9f 100644 --- a/ci/gitlab.yml +++ b/ci/gitlab.yml @@ -11,8 +11,11 @@ # - RUN_PIPELINE - force creation of a CI pipeline when # pushing to a branch in a forked repository. Official # CI pipelines are triggered when merge requests are -# created/updated. Setting this variable to a non-empty -# value allows CI testing prior to opening a merge request. +# created/updated. Setting this variable allows CI +# testing prior to opening a merge request. A value +# of "0" will create the pipeline but leave all jobs +# to be manually started, while "1" will immediately +# run all default jobs. # # - RUN_PIPELINE_UPSTREAM_ENV - same semantics as RUN_PIPELINE, # but uses the CI environment (containers) from the upstream project @@ -38,11 +41,13 @@ # # Aliases can be set for common usage # -# $ git config --local alias.push-ci "push -o ci.variable=RUN_PIPELINE=1" +# $ git config --local alias.push-ci "push -o ci.variable=RUN_PIPELINE=0" +# $ git config --local alias.push-ci-now "push -o ci.variable=RUN_PIPELINE=1" # # Allowing the less verbose invocation # -# $ git push-ci +# $ git push-ci (create pipeline but don't start jobs) +# $ git push-ci-now (create pipeline and start default jobs) # # Pipeline variables can also be set in the repository # pipeline config globally, or set against scheduled pipelines @@ -50,6 +55,7 @@ variables: RUN_UPSTREAM_NAMESPACE: libvirt + CONTAINER_UPSTREAM_NAMESPACE: libvirt FF_SCRIPT_SECTIONS: 1 diff --git a/ci/gitlab/build-templates.yml b/ci/gitlab/build-templates.yml index fae09ac..d4ce66f 100644 --- a/ci/gitlab/build-templates.yml +++ b/ci/gitlab/build-templates.yml @@ -32,10 +32,11 @@ then source ci/buildenv/$NAME.sh ; install_buildenv ; + else + cat /packages.txt ; fi - - cat /packages.txt variables: - IMAGE: $CI_REGISTRY/$RUN_UPSTREAM_NAMESPACE/libvirt-java/ci-$NAME:latest + IMAGE: $CI_REGISTRY/$CONTAINER_UPSTREAM_NAMESPACE/libvirt-java/ci-$NAME:latest rules: ### PUSH events @@ -47,19 +48,27 @@ when: on_success # forks: pushes to a branch when a pipeline run in upstream env is explicitly requested - - if: '$CI_PROJECT_NAMESPACE != $RUN_UPSTREAM_NAMESPACE && $CI_PIPELINE_SOURCE == "push" && $RUN_PIPELINE_UPSTREAM_ENV && $JOB_OPTIONAL' + - if: '$CI_PROJECT_NAMESPACE != $RUN_UPSTREAM_NAMESPACE && $CI_PIPELINE_SOURCE == "push" && $RUN_PIPELINE_UPSTREAM_ENV == "0"' when: manual allow_failure: true - - if: '$CI_PROJECT_NAMESPACE != $RUN_UPSTREAM_NAMESPACE && $CI_PIPELINE_SOURCE == "push" && $RUN_PIPELINE_UPSTREAM_ENV' + - if: '$CI_PROJECT_NAMESPACE != $RUN_UPSTREAM_NAMESPACE && $CI_PIPELINE_SOURCE == "push" && $RUN_PIPELINE_UPSTREAM_ENV == "1" && $JOB_OPTIONAL' + when: manual + allow_failure: true + - if: '$CI_PROJECT_NAMESPACE != $RUN_UPSTREAM_NAMESPACE && $CI_PIPELINE_SOURCE == "push" && $RUN_PIPELINE_UPSTREAM_ENV == "1"' when: on_success # forks: pushes to branches with pipeline requested - - if: '$CI_PROJECT_NAMESPACE != $RUN_UPSTREAM_NAMESPACE && $CI_PIPELINE_SOURCE == "push" && $RUN_PIPELINE && $JOB_OPTIONAL' + - if: '$CI_PROJECT_NAMESPACE != $RUN_UPSTREAM_NAMESPACE && $CI_PIPELINE_SOURCE == "push" && $RUN_PIPELINE == "0"' + when: manual + allow_failure: true + variables: + IMAGE: $TARGET_BASE_IMAGE + - if: '$CI_PROJECT_NAMESPACE != $RUN_UPSTREAM_NAMESPACE && $CI_PIPELINE_SOURCE == "push" && $RUN_PIPELINE == "1" && $JOB_OPTIONAL' when: manual allow_failure: true variables: IMAGE: $TARGET_BASE_IMAGE - - if: '$CI_PROJECT_NAMESPACE != $RUN_UPSTREAM_NAMESPACE && $CI_PIPELINE_SOURCE == "push" && $RUN_PIPELINE' + - if: '$CI_PROJECT_NAMESPACE != $RUN_UPSTREAM_NAMESPACE && $CI_PIPELINE_SOURCE == "push" && $RUN_PIPELINE == "1"' when: on_success variables: IMAGE: $TARGET_BASE_IMAGE diff --git a/ci/gitlab/builds.yml b/ci/gitlab/builds.yml index bb513af..96f600c 100644 --- a/ci/gitlab/builds.yml +++ b/ci/gitlab/builds.yml @@ -7,39 +7,74 @@ # Native build jobs -x86_64-almalinux-8: +x86_64-almalinux-9: extends: .native_build_job needs: - - job: x86_64-almalinux-8-container + - job: x86_64-almalinux-9-container optional: true allow_failure: false variables: - NAME: almalinux-8 - TARGET_BASE_IMAGE: docker.io/library/almalinux:8 + NAME: almalinux-9 + TARGET_BASE_IMAGE: docker.io/library/almalinux:9 TESTS: skip -x86_64-centos-stream-8: +x86_64-almalinux-10: extends: .native_build_job needs: - - job: x86_64-centos-stream-8-container + - job: x86_64-almalinux-10-container optional: true allow_failure: false variables: - NAME: centos-stream-8 - TARGET_BASE_IMAGE: quay.io/centos/centos:stream8 + NAME: almalinux-10 + TARGET_BASE_IMAGE: docker.io/library/almalinux:10 TESTS: skip -x86_64-debian-11: +x86_64-centos-stream-9: extends: .native_build_job needs: - - job: x86_64-debian-11-container + - job: x86_64-centos-stream-9-container optional: true allow_failure: false variables: - NAME: debian-11 - TARGET_BASE_IMAGE: docker.io/library/debian:11-slim + NAME: centos-stream-9 + TARGET_BASE_IMAGE: quay.io/centos/centos:stream9 + TESTS: skip + + +x86_64-centos-stream-10: + extends: .native_build_job + needs: + - job: x86_64-centos-stream-10-container + optional: true + allow_failure: false + variables: + NAME: centos-stream-10 + TARGET_BASE_IMAGE: quay.io/centos/centos:stream10 + TESTS: skip + + +x86_64-debian-12: + extends: .native_build_job + needs: + - job: x86_64-debian-12-container + optional: true + allow_failure: false + variables: + NAME: debian-12 + TARGET_BASE_IMAGE: docker.io/library/debian:12-slim + + +x86_64-debian-13: + extends: .native_build_job + needs: + - job: x86_64-debian-13-container + optional: true + allow_failure: false + variables: + NAME: debian-13 + TARGET_BASE_IMAGE: docker.io/library/debian:13-slim x86_64-debian-sid: @@ -47,32 +82,32 @@ x86_64-debian-sid: needs: - job: x86_64-debian-sid-container optional: true - allow_failure: false + allow_failure: true variables: NAME: debian-sid TARGET_BASE_IMAGE: docker.io/library/debian:sid-slim -x86_64-fedora-38: +x86_64-fedora-43: extends: .native_build_job needs: - - job: x86_64-fedora-38-container + - job: x86_64-fedora-43-container optional: true allow_failure: false variables: - NAME: fedora-38 - TARGET_BASE_IMAGE: registry.fedoraproject.org/fedora:38 + NAME: fedora-43 + TARGET_BASE_IMAGE: registry.fedoraproject.org/fedora:43 -x86_64-fedora-39: +x86_64-fedora-44: extends: .native_build_job needs: - - job: x86_64-fedora-39-container + - job: x86_64-fedora-44-container optional: true allow_failure: false variables: - NAME: fedora-39 - TARGET_BASE_IMAGE: registry.fedoraproject.org/fedora:39 + NAME: fedora-44 + TARGET_BASE_IMAGE: registry.fedoraproject.org/fedora:44 x86_64-fedora-rawhide: @@ -80,7 +115,7 @@ x86_64-fedora-rawhide: needs: - job: x86_64-fedora-rawhide-container optional: true - allow_failure: false + allow_failure: true variables: NAME: fedora-rawhide TARGET_BASE_IMAGE: registry.fedoraproject.org/fedora:rawhide @@ -94,37 +129,37 @@ x86_64-opensuse-leap-15: allow_failure: false variables: NAME: opensuse-leap-15 - TARGET_BASE_IMAGE: registry.opensuse.org/opensuse/leap:15.5 + TARGET_BASE_IMAGE: registry.opensuse.org/opensuse/leap:15.6 -x86_64-ubuntu-2004: +x86_64-ubuntu-2404: extends: .native_build_job needs: - - job: x86_64-ubuntu-2004-container + - job: x86_64-ubuntu-2404-container optional: true allow_failure: false variables: - NAME: ubuntu-2004 - TARGET_BASE_IMAGE: docker.io/library/ubuntu:20.04 + NAME: ubuntu-2404 + TARGET_BASE_IMAGE: docker.io/library/ubuntu:24.04 -x86_64-ubuntu-2204: +x86_64-ubuntu-2604: extends: .native_build_job needs: - - job: x86_64-ubuntu-2204-container + - job: x86_64-ubuntu-2604-container optional: true allow_failure: false variables: - NAME: ubuntu-2204 - TARGET_BASE_IMAGE: docker.io/library/ubuntu:22.04 + NAME: ubuntu-2604 + TARGET_BASE_IMAGE: docker.io/library/ubuntu:26.04 -x86_64-ubuntu-2204-git: +x86_64-ubuntu-2604-git: extends: .native_git_build_job needs: - - job: x86_64-ubuntu-2204-container + - job: x86_64-ubuntu-2604-container optional: true allow_failure: false variables: - NAME: ubuntu-2204 - TARGET_BASE_IMAGE: docker.io/library/ubuntu:22.04 + NAME: ubuntu-2604 + TARGET_BASE_IMAGE: docker.io/library/ubuntu:26.04 diff --git a/ci/gitlab/containers.yml b/ci/gitlab/containers.yml index d58bdc6..1111353 100644 --- a/ci/gitlab/containers.yml +++ b/ci/gitlab/containers.yml @@ -7,51 +7,72 @@ # Native container jobs -x86_64-almalinux-8-container: +x86_64-almalinux-9-container: extends: .container_job allow_failure: false variables: - NAME: almalinux-8 + NAME: almalinux-9 -x86_64-centos-stream-8-container: +x86_64-almalinux-10-container: extends: .container_job allow_failure: false variables: - NAME: centos-stream-8 + NAME: almalinux-10 -x86_64-debian-11-container: +x86_64-centos-stream-9-container: extends: .container_job allow_failure: false variables: - NAME: debian-11 + NAME: centos-stream-9 -x86_64-debian-sid-container: +x86_64-centos-stream-10-container: extends: .container_job allow_failure: false + variables: + NAME: centos-stream-10 + + +x86_64-debian-12-container: + extends: .container_job + allow_failure: false + variables: + NAME: debian-12 + + +x86_64-debian-13-container: + extends: .container_job + allow_failure: false + variables: + NAME: debian-13 + + +x86_64-debian-sid-container: + extends: .container_job + allow_failure: true variables: NAME: debian-sid -x86_64-fedora-38-container: +x86_64-fedora-43-container: extends: .container_job allow_failure: false variables: - NAME: fedora-38 + NAME: fedora-43 -x86_64-fedora-39-container: +x86_64-fedora-44-container: extends: .container_job allow_failure: false variables: - NAME: fedora-39 + NAME: fedora-44 x86_64-fedora-rawhide-container: extends: .container_job - allow_failure: false + allow_failure: true variables: NAME: fedora-rawhide @@ -63,15 +84,15 @@ x86_64-opensuse-leap-15-container: NAME: opensuse-leap-15 -x86_64-ubuntu-2004-container: +x86_64-ubuntu-2404-container: extends: .container_job allow_failure: false variables: - NAME: ubuntu-2004 + NAME: ubuntu-2404 -x86_64-ubuntu-2204-container: +x86_64-ubuntu-2604-container: extends: .container_job allow_failure: false variables: - NAME: ubuntu-2204 + NAME: ubuntu-2604 diff --git a/ci/gitlab/sanity-checks.yml b/ci/gitlab/sanity-checks.yml index d2b1768..b568015 100644 --- a/ci/gitlab/sanity-checks.yml +++ b/ci/gitlab/sanity-checks.yml @@ -18,9 +18,13 @@ check-dco: when: on_success # forks: pushes to branches with pipeline requested (including upstream env pipelines) - - if: '$CI_PROJECT_NAMESPACE != $RUN_UPSTREAM_NAMESPACE && $CI_PIPELINE_SOURCE == "push" && $CI_COMMIT_BRANCH && $RUN_PIPELINE' + - if: '$CI_PROJECT_NAMESPACE != $RUN_UPSTREAM_NAMESPACE && $CI_PIPELINE_SOURCE == "push" && $CI_COMMIT_BRANCH && $RUN_PIPELINE == "0"' + when: manual + - if: '$CI_PROJECT_NAMESPACE != $RUN_UPSTREAM_NAMESPACE && $CI_PIPELINE_SOURCE == "push" && $CI_COMMIT_BRANCH && $RUN_PIPELINE == "1"' when: on_success - - if: '$CI_PROJECT_NAMESPACE != $RUN_UPSTREAM_NAMESPACE && $CI_PIPELINE_SOURCE == "push" && $CI_COMMIT_BRANCH && $RUN_PIPELINE_UPSTREAM_ENV' + - if: '$CI_PROJECT_NAMESPACE != $RUN_UPSTREAM_NAMESPACE && $CI_PIPELINE_SOURCE == "push" && $CI_COMMIT_BRANCH && $RUN_PIPELINE_UPSTREAM_ENV == "0"' + when: manual + - if: '$CI_PROJECT_NAMESPACE != $RUN_UPSTREAM_NAMESPACE && $CI_PIPELINE_SOURCE == "push" && $CI_COMMIT_BRANCH && $RUN_PIPELINE_UPSTREAM_ENV == "1"' when: on_success # upstream+forks: that's all folks diff --git a/ci/manifest.yml b/ci/manifest.yml index 098263a..61ecc39 100644 --- a/ci/manifest.yml +++ b/ci/manifest.yml @@ -1,43 +1,57 @@ projects: - libvirt-java - - libvirt+dist + - https://gitlab.com/libvirt/libvirt/-/raw/master/ci/lcitool/projects/libvirt+dist.yml gitlab: namespace: libvirt project: libvirt-java targets: - almalinux-8: + almalinux-9: jobs: - arch: x86_64 variables: TESTS: skip - centos-stream-8: + almalinux-10: jobs: - arch: x86_64 variables: TESTS: skip - debian-11: x86_64 + centos-stream-9: + jobs: + - arch: x86_64 + variables: + TESTS: skip + + centos-stream-10: + jobs: + - arch: x86_64 + variables: + TESTS: skip + + debian-12: x86_64 + + debian-13: x86_64 debian-sid: x86_64 - fedora-38: x86_64 + fedora-43: x86_64 - fedora-39: x86_64 + fedora-44: x86_64 fedora-rawhide: x86_64 opensuse-leap-15: x86_64 - ubuntu-2004: x86_64 + ubuntu-2404: x86_64 - ubuntu-2204: + ubuntu-2604: projects: - libvirt-java - - libvirt+dist - - libvirt+minimal + - https://gitlab.com/libvirt/libvirt/-/raw/master/ci/lcitool/projects/libvirt+minimal.yml + - https://gitlab.com/libvirt/libvirt/-/raw/master/ci/lcitool/projects/libvirt+dist.yml jobs: - arch: x86_64 diff --git a/pom.xml.in b/pom.xml.in index eb9d026..8a79696 100644 --- a/pom.xml.in +++ b/pom.xml.in @@ -27,7 +27,7 @@ net.java.dev.jna jna provided - [3.4.1,5.5.0] + [3.4.1,5.19.1] diff --git a/src/main/java/org/libvirt/Connect.java b/src/main/java/org/libvirt/Connect.java index 28f7a6c..3019cf6 100644 --- a/src/main/java/org/libvirt/Connect.java +++ b/src/main/java/org/libvirt/Connect.java @@ -18,9 +18,11 @@ import static org.libvirt.BitFlagsHelper.OR; import com.sun.jna.Memory; +import com.sun.jna.Native; import com.sun.jna.NativeLong; import com.sun.jna.Pointer; import com.sun.jna.ptr.LongByReference; +import com.sun.jna.ptr.PointerByReference; /** * The Connect object represents a connection to a local or remote @@ -100,7 +102,11 @@ private interface DomainEventID { int METADATA_CHANGE = 23; int BLOCK_THRESHOLD = 24; int MEMORY_FAILURE = 25; - int LAST = 26; + int MEMORY_DEVICE_SIZE_CHANGE = 26; + int NIC_MAC_CHANGE = 27; + int VCPU_REMOVED = 28; + int CHANNEL_LIFECYCLE = 29; + int LAST = 30; } public enum OpenFlags implements BitFlags { @@ -144,7 +150,7 @@ public static final class ConnectListAllDomainsFlags { * Get the version of a connection. * * @see Libvirt + * href="https://libvirt.org/html/libvirt-libvirt-host.html#virConnectGetLibVersion">Libvirt * Documentation * @param conn * the connection to use. @@ -187,7 +193,7 @@ public static byte[] createUUIDBytes(final int[] uuid) { * Get the libvirt library version of this connection. * * @see Libvirt + * href="https://libvirt.org/html/libvirt-libvirt-host.html#virConnectGetLibVersion">Libvirt * Documentation * @return The version of libvirt used by the daemon running on * the connected host in the format {@code major * @@ -471,7 +477,7 @@ public void unregisterCloseListener() throws LibvirtException { * Compares the given CPU description with the host CPU * * @see Libvirt + * href="https://libvirt.org/html/libvirt-libvirt-host.html#virConnectCompareCPU">Libvirt * Documentation * @param xmlDesc * @return comparison result according to enum CPUCompareResult @@ -512,7 +518,7 @@ public Device deviceLookupByName(final String name) throws LibvirtException { /** * Launches a new Linux guest domain. The domain is based on an XML * description similar to the one returned by virDomainGetXMLDesc(). This - * function may require priviledged access to the hypervisor. + * function may require privileged access to the hypervisor. * * @param xmlDesc * the Domain description in XML @@ -568,7 +574,7 @@ public Domain domainDefineXML(final String xmlDesc) throws LibvirtException { * @throws LibvirtException * * @see - * + * virConnectDomainEventDeregisterAny */ private void domainEventDeregister(final int eventID, final EventListener l) @@ -644,6 +650,21 @@ public void eventCallback(final ConnectionPointer virConnectPtr, domainEventRegister(domain, DomainEventID.BLOCK_JOB_2, virCB, cb); } + /** + * Adds the specified Block Job listener to receive Block Job events + * for domains of this connection. + * + * @see + * + virConnectDomainEventRegisterAny + * @param l + * the Block job listener + * @throws LibvirtException on failure + */ + public void addBlockJobListener(final BlockJobListener l) throws LibvirtException { + domainEventRegister(null, l); + } + void domainEventRegister(final Domain domain, final IOErrorListener cb) throws LibvirtException { if (cb == null) { @@ -681,8 +702,8 @@ public void eventCallback(final ConnectionPointer virConnectPtr, * for domains of this connection. * * @see - * - Libvirt Documentation + * + virConnectDomainEventRegisterAny * @param l * the I/O error listener * @throws LibvirtException on failure @@ -794,7 +815,7 @@ public int eventCallback(ConnectionPointer virConnectPtr, DomainPointer virDomai * @see Domain#addAgentLifecycleListener * @see * - virConnectDomainEventRegisterAny + virConnectDomainEventRegisterAny */ public void addAgentLifecycleListener(final AgentLifecycleListener cb) throws LibvirtException { domainEventRegister(null, cb); @@ -810,7 +831,7 @@ public void addAgentLifecycleListener(final AgentLifecycleListener cb) throws Li * @see #removeLifecycleListener * @see Domain#addLifecycleListener * @see - * + * virConnectDomainEventRegisterAny */ public void addLifecycleListener(final LifecycleListener l) @@ -882,7 +903,7 @@ public void eventCallback(final ConnectionPointer virConnectPtr, * @see #removePMSuspendListener * @see Domain#addPMSuspendListener * @see - * + * virConnectDomainEventRegisterAny * * @since 1.5.2 @@ -899,7 +920,7 @@ public void addPMSuspendListener(final PMSuspendListener l) throws LibvirtExcept * @throws LibvirtException * * @see - * + * virConnectDomainEventDeregisterAny * * @since 1.5.2 @@ -918,7 +939,7 @@ public void removePMSuspendListener(final PMSuspendListener l) throws LibvirtExc * @see #removePMWakeupListener * @see Domain#addPMWakeupListener * @see - * + * virConnectDomainEventRegisterAny * * @since 1.5.2 @@ -935,7 +956,7 @@ public void addPMWakeupListener(final PMWakeupListener l) throws LibvirtExceptio * @throws LibvirtException * * @see - * + * virConnectDomainEventDeregisterAny */ public void removePMWakeupListener(final PMWakeupListener l) throws LibvirtException { @@ -950,7 +971,7 @@ public void removePMWakeupListener(final PMWakeupListener l) throws LibvirtExcep * @throws LibvirtException * * @see - * + * virConnectDomainEventDeregisterAny */ public void removeLifecycleListener(final LifecycleListener l) throws LibvirtException { @@ -966,7 +987,7 @@ public void removeLifecycleListener(final LifecycleListener l) throws LibvirtExc * * @see * - virConnectDomainEventDeregisterAny + virConnectDomainEventDeregisterAny */ public void removeAgentLifecycleListener(final AgentLifecycleListener l) throws LibvirtException { domainEventDeregister(DomainEventID.AGENT_LIFECYCLE, l); @@ -979,9 +1000,10 @@ public void removeAgentLifecycleListener(final AgentLifecycleListener l) throws * @param l the reboot listener * @throws LibvirtException on failure * + * @see #removeRebootListener * @see Domain#addRebootListener * @see - * + * virConnectDomainEventRegisterAny * @since 1.5.2 */ @@ -990,12 +1012,31 @@ public void addRebootListener(final RebootListener l) throws LibvirtException { } /** - * Removes the specified Block Job listener so that it no longer - * receives events - * @param l - * @throws LibvirtException + * Removes the specified reboot listener so that it no longer + * receives reboot events. + * + * @param l the reboot listener + * @throws LibvirtException + * + * @see + * + virConnectDomainEventDeregisterAny */ + public void removeRebootListener(final RebootListener l) throws LibvirtException { + domainEventDeregister(DomainEventID.REBOOT, l); + } + /** + * Removes the specified Block Job listener so that it no longer + * receives Block Job events. + * + * @param l the block job listener + * @throws LibvirtException + * + * @see + * + virConnectDomainEventDeregisterAny + */ public void removeBlockJobListener(final BlockJobListener l) throws LibvirtException { domainEventDeregister(DomainEventID.BLOCK_JOB_2, l); } @@ -1008,7 +1049,7 @@ public void removeBlockJobListener(final BlockJobListener l) throws LibvirtExcep * @throws LibvirtException * * @see - * + * virConnectDomainEventDeregisterAny */ public void removeIOErrorListener(final IOErrorListener l) throws LibvirtException { @@ -1296,7 +1337,7 @@ public String getURI() throws LibvirtException { /** * Gets the version level of the Hypervisor running. This may work only with - * hypervisor call, i.e. with priviledged access to the hypervisor, not with + * hypervisor call, i.e. with privileged access to the hypervisor, not with * a Read-Only connection. If the version can't be extracted by lack of * capacities returns 0. * @@ -1352,7 +1393,7 @@ public Interface interfaceLookupByName(final String name) * Determine if the connection is encrypted * * @see - * + * Libvirt Documentation * @return 1 if encrypted, 0 if not encrypted * @throws LibvirtException @@ -1365,7 +1406,7 @@ public int isEncrypted() throws LibvirtException { * Determine if the connection is secure * * @see - * + * Libvirt Documentation * @return 1 if secure, 0 if not secure * @throws LibvirtException @@ -1499,17 +1540,121 @@ public Domain[] listAllDomains(int flags) throws LibvirtException { DomainByReference domainByReference = new DomainByReference(); int domainsCount = processError(libvirt.virConnectListAllDomains(vcp, domainByReference, flags)); - Pointer[] pointerArray = domainByReference.getValue().getPointerArray(0, domainsCount); - if (domainsCount > 0) { - Domain[] domains = new Domain[domainsCount]; - for (int i = 0; i < domainsCount; i++) { - domains[i] = new Domain(this, new DomainPointer(pointerArray[i])); - } + Pointer pointer = domainByReference.getValue(); + Domain[] domains = new Domain[domainsCount]; + for (int i = 0; i < domainsCount; i++) { + domains[i] = new Domain(this, new DomainPointer(pointer.getPointer(i * Native.POINTER_SIZE))); + } + Library.free(pointer); + + return domains; + } + + /** + * Query statistics for all domains on this connection in a single RPC call. + * + *

Wraps + * + * {@code virConnectGetAllDomainStats} (since libvirt 1.2.8). + * + *

Each returned record carries a {@link Domain} whose reference count + * has been incremented; callers are responsible for freeing those domain + * handles when done (e.g. via {@link Domain#free()}). + * + * @param stats bitwise-OR of {@link DomainStats} constants selecting the + * stats groups to retrieve, or {@code 0} for all groups + * supported by the hypervisor + * @param flags bitwise-OR of {@link ConnectGetAllDomainStatsFlags} + * constants + * @return an array of per-domain stats records; empty if no domain + * matched the filter + * @throws LibvirtException on libvirt error + */ + public DomainStatsRecord[] getAllDomainStats(int stats, int flags) + throws LibvirtException { + PointerByReference out = new PointerByReference(); + int count = processError(libvirt.virConnectGetAllDomainStats(vcp, stats, out, flags)); + return unpackStatsRecords(out.getValue(), count); + } - return domains; + /** + * Query statistics for a specific list of domains in a single RPC call. + * + *

Wraps + * + * {@code virDomainListGetStats} (since libvirt 1.2.8). + * + *

All domains must belong to this connection. Each returned record + * carries a {@link Domain} whose reference count has been incremented; + * callers are responsible for freeing those domain handles when done. + * + * @param domains the domains to query; must not be {@code null}, and + * every element must be non-{@code null} + * @param stats bitwise-OR of {@link DomainStats} constants selecting + * the stats groups to retrieve, or {@code 0} for all + * groups supported by the hypervisor + * @param flags bitwise-OR of {@link ConnectGetAllDomainStatsFlags} + * constants + * @return an array of per-domain stats records; may contain fewer + * entries than {@code domains} if stats could not be fetched + * for some of them + * @throws LibvirtException on libvirt error + */ + public DomainStatsRecord[] getDomainListStats(Domain[] domains, + int stats, + int flags) + throws LibvirtException { + // libvirt expects a NULL-terminated array. + DomainPointer[] doms = new DomainPointer[domains.length + 1]; + for (int i = 0; i < domains.length; i++) { + doms[i] = domains[i].vdp; } + doms[domains.length] = null; + + PointerByReference out = new PointerByReference(); + int count = processError(libvirt.virDomainListGetStats(doms, stats, out, flags)); + return unpackStatsRecords(out.getValue(), count); + } - return new Domain[]{}; + private DomainStatsRecord[] unpackStatsRecords(Pointer listBase, int count) + throws LibvirtException { + if (count <= 0 || listBase == null) { + return new DomainStatsRecord[0]; + } + DomainStatsRecord[] result = new DomainStatsRecord[count]; + boolean success = false; + try { + for (int i = 0; i < count; i++) { + Pointer recPtr = listBase.getPointer((long) i * Native.POINTER_SIZE); + virDomainStatsRecord rec = new virDomainStatsRecord(recPtr); + // Marshal params before bumping the refcount so a failure + // here leaves no ref to undo. + TypedParameter[] params = TypedParameter.toArray(rec.params, rec.nparams); + // virDomainStatsRecordListFree will drop the original ref on + // rec.dom, so bump it here before handing the pointer to our + // Java-side Domain wrapper. + Domain dom = Domain.constructIncRef(this, rec.dom); + result[i] = new DomainStatsRecord(dom, params); + } + success = true; + return result; + } finally { + if (!success) { + // Undo the refs we bumped on earlier iterations; otherwise + // virDomainStatsRecordListFree below drops the *original* + // refs and leaves our +1 stranded. + for (DomainStatsRecord rec : result) { + if (rec != null) { + try { + rec.domain.free(); + } catch (LibvirtException ignored) { + // best-effort cleanup during error unwind + } + } + } + } + libvirt.virDomainStatsRecordListFree(listBase); + } } /** @@ -1648,7 +1793,7 @@ public Network networkDefineXML(final String xmlDesc) throws LibvirtException { * @return the new filer * @throws LibvirtException * @see - * + * Libvirt Documentation */ public NetworkFilter networkFilterDefineXML(final String xmlDesc) @@ -1665,7 +1810,7 @@ public NetworkFilter networkFilterDefineXML(final String xmlDesc) * @return network filter object * @throws LibvirtException * @see - * + * Libvirt Documentation */ public NetworkFilter networkFilterLookupByName(final String name) @@ -1986,7 +2131,7 @@ public void setConnectionErrorCallback(final Libvirt.VirErrorCallback callback) /** * change the amount of memory reserved to Domain0. Domain0 is the domain - * where the application runs. This function may requires priviledged access + * where the application runs. This function may requires privileged access * to the hypervisor. * * @param memory diff --git a/src/main/java/org/libvirt/ConnectGetAllDomainStatsFlags.java b/src/main/java/org/libvirt/ConnectGetAllDomainStatsFlags.java new file mode 100644 index 0000000..24107cc --- /dev/null +++ b/src/main/java/org/libvirt/ConnectGetAllDomainStatsFlags.java @@ -0,0 +1,50 @@ +package org.libvirt; + +/** + * Bit flags for {@link Connect#getAllDomainStats(int, int)} and + * {@link Connect#getDomainListStats(Domain[], int, int)}. + * + *

Matches the {@code VIR_CONNECT_GET_ALL_DOMAINS_STATS_*} constants + * from libvirt. + * + * @see + * virConnectGetAllDomainStatsFlags + */ +public final class ConnectGetAllDomainStatsFlags { + + /** Include active domains. */ + public static final int ACTIVE = 1 << 0; + + /** Include inactive domains. */ + public static final int INACTIVE = 1 << 1; + + /** Include persistent domains. */ + public static final int PERSISTENT = 1 << 2; + + /** Include transient domains. */ + public static final int TRANSIENT = 1 << 3; + + /** Include running domains. */ + public static final int RUNNING = 1 << 4; + + /** Include paused domains. */ + public static final int PAUSED = 1 << 5; + + /** Include shutoff domains. */ + public static final int SHUTOFF = 1 << 6; + + /** Include domains in other states. */ + public static final int OTHER = 1 << 7; + + /** Skip domains whose lock cannot be acquired immediately. */ + public static final int NOWAIT = 1 << 29; + + /** Expand block stats to cover backing chains. */ + public static final int BACKING = 1 << 30; + + /** Fail if any requested stats group is not supported by the daemon. */ + public static final int ENFORCE_STATS = 1 << 31; + + private ConnectGetAllDomainStatsFlags() { + } +} diff --git a/src/main/java/org/libvirt/Domain.java b/src/main/java/org/libvirt/Domain.java index 72a9225..3318a80 100644 --- a/src/main/java/org/libvirt/Domain.java +++ b/src/main/java/org/libvirt/Domain.java @@ -16,6 +16,7 @@ import org.libvirt.event.RebootListener; import org.libvirt.jna.CString; import org.libvirt.jna.CStringByReference; +import org.libvirt.jna.DomainCheckpointPointer; import org.libvirt.jna.DomainPointer; import org.libvirt.jna.DomainSnapshotPointer; import org.libvirt.jna.Libvirt; @@ -57,6 +58,132 @@ private static int bit(final int i) { * TODO: get generated constants from libvirt */ + public static final class JobOperation { + /** + * @see + * Libvirt Documentation + */ + public static final int UNKNOWN = 0; + /** + * @see + * Libvirt Documentation + */ + public static final int START = 1; + + /** + * @see + * Libvirt Documentation + */ + public static final int SAVE = 2; + /** + * @see + * Libvirt Documentation + */ + public static final int RESTORE = 3; + + /** + * @see + * Libvirt Documentation + */ + public static final int MIGRATION_IN = 4; + + /** + * @see + * Libvirt Documentation + */ + public static final int MIGRATION_OUT = 5; + /** + * @see + * Libvirt Documentation + */ + public static final int SNAPSHOT = 6; + + /** + * @see + * Libvirt Documentation + */ + public static final int SNAPSHOT_REVERT = 7; + + /** + * @see + * Libvirt Documentation + */ + public static final int DUMP = 8; + + /** + * @see + * Libvirt Documentation + */ + public static final int BACKUP = 9; + + /** + * @see + * Libvirt Documentation + */ + public static final int SNAPSHOT_DELETE = 10; + /** + * @see + * Libvirt Documentation + */ + public static final int LAST = 11; + } + + public static final class BlockJobType { + /** + * Placeholder + * + * @see + * Libvirt Documentation + */ + public static int UNKNOWN = 0; + + /** + * Block Pull (virDomainBlockPull, or virDomainBlockRebase without flags), job ends on completion + * + * @see + * Libvirt Documentation + */ + public static int PULL = 1; + + /** + * Block Copy (virDomainBlockCopy, or virDomainBlockRebase with flags), job exists as long as mirroring is active + * + * @see + * Libvirt Documentation + */ + public static int COPY = 2; + + /** + * Block Commit (virDomainBlockCommit without flags), job ends on completion + * + * @see + * Libvirt Documentation + */ + public static int COMMIT = 3; + + /** + * Active Block Commit (virDomainBlockCommit with flags), job exists as long as sync is active + * + * @see + * Libvirt Documentation + */ + public static int ACTIVE_COMMIT = 4; + + /** + * Backup (virDomainBackupBegin) + * + * @see + * Libvirt Documentation + */ + public static int BACKUP = 5; + + /** + * @see + * Libvirt Documentation + */ + public static int LAST = 6; + } + public static final class BlockCommitFlags { /** NULL base means next backing file, not whole chain */ public static int SHALLOW = bit(0); @@ -123,7 +250,7 @@ public static final class BlockCopyParameters { /** * Contains multiple constants that defines "virDomainMigrate* params" multiple field. * @see Libvirt domain documentation., and - * libvirt-domain.h. + * libvirt-domain.h */ public static final class DomainMigrateParameters { /** @@ -135,6 +262,18 @@ public static final class DomainMigrateParameters { */ public static final String VIR_MIGRATE_PARAM_MIGRATE_DISKS = "migrate_disks"; + /** + * List the block devices for which zero detection (to avoid transferring zero blocks, for + * storage where it can't be probed) is to be enabled. This may increase CPU overhead of + * the migration. Destination image will be sparse only when the disk 'discard' option is + * set to 'unmap'. At the moment this is only supported by the QEMU driver but not for + * the tunnelled migration. + * + * @see + * Libvirt Documentation + */ + public static final String VIR_MIGRATE_PARAM_MIGRATE_DISKS_DETECT_ZEROES = "migrate_disks_detect_zeroes"; + /** * The new configuration to be used for the domain on the destination host as * TYPED_PARAM_STRING. The configuration must include an identical set of @@ -333,10 +472,36 @@ public static final class BlockJobAbortFlags { } public static final class BlockResizeFlags { - /** - * size is in bytes instead of KiB - */ - public static final int BYTES = 1; + /** size is in bytes instead of KiB **/ + public static final int BYTES = bit(0); + + /** resize to full the capacity of the source **/ + public static final int CAPACITY = bit(1); + } + + public static final class JobType { + /** No job is active **/ + public static int NONE = bit(0); + + /** Job with a finite completion time **/ + public static int BOUNDED = bit(1); + + /** Job without a finite completion time **/ + public static int UNBOUNDED = bit(2); + + /** Job has finished, but isn't cleaned up **/ + public static int COMPLETED = bit(3); + + /** Job hit error, but isn't cleaned up **/ + public static int FAILED = bit(4); + + /** Job was aborted, but isn't cleaned up **/ + public static int CANCELLED = bit(5); + } + + public static final class GetJobStatsFlags { + public static int COMPLETED = bit(0); + public static int KEEP_COMPLETED = bit(1); } public static final class CreateFlags { @@ -357,6 +522,9 @@ public static final class CreateFlags { /** Validate the XML document against schema */ public static final int VALIDATE = bit(4); + + /** Re-initialize NVRAM/varstore from template */ + public static final int RESET_NVRAM = bit(5); } public static final class InterfaceAddressesSource { @@ -452,6 +620,17 @@ public static final class MigrateFlags { * network connections */ public static final int PARALLEL = bit(17); + /** Force the guest writes which happen when copying disk images + * for non-shared storage migration to be synchronously written to + * the destination. */ + public static final int NON_SHARED_SYNCHRONOUS_WRITES = bit(18); + + /** Resume migration which failed in post-copy phase */ + public static final int POSTCOPY_RESUME = bit(19); + + /** Use zero-copy mechanism for migrating memory pages */ + public static final int ZEROCOPY = bit(20); + } public static final class XMLFlags { @@ -496,6 +675,101 @@ public static final class RebootFlags { public static final int PARAVIRT = bit(4); } + public static final class DomainBackupBeginFlags { + /** + * reuse separately provided images + * + * @see + * Libvirt Documentation + */ + public static final int REUSE_EXTERNAL = bit(0); + } + + public static final class DomainGetJobStatsFlags { + /** + * return stats of a recently completed job + * + * @see + * Libvirt Documentation + */ + public static final int COMPLETED = bit(0); + + /** + * don't remove completed stats when reading them + * + * @see + * Libvirt Documentation + */ + public static final int KEEP_COMPLETED = bit(1); + } + + public static final class CheckpointCreateFlags { + + /** Restore or alter metadata (Since: 5.6.0) + * + * @see + * Libvirt Documentation + */ + public static final int REDEFINE = bit(0); + + /** use guest agent to quiesce all mounted file + * systems within the domain (Since: 5.6.0) + * + * @see + * Libvirt Documentation + */ + public static final int QUIESCE = bit(1); + + /** validate disk data state when redefining + * a checkpoint (Since: 6.10.0) + * + * @see + * Libvirt Documentation + */ + public static final int REDEFINE_VALIDATE = bit(2); + } + + public static final class CheckpointListFlags { + + /** List all descendants, not just children, when + * listing a checkpoint (Since: 5.6.0) + * + * @see + * Libvirt Documentation + */ + public static final int DESCENDANTS = bit(0); + + /** Filter by checkpoints with no parents, when + * listing a domain (Since: 5.6.0) + * + * @see + * Libvirt Documentation + */ + public static final int ROOTS = bit(0); + + /** Ensure parents occur before children in + * the resulting list (Since: 5.6.0) + * + * @see + * Libvirt Documentation + */ + public static final int TOPOLOGICAL = bit(1); + + /** Filter by checkpoints with no children (Since: 5.6.0) + * + * @see + * Libvirt Documentation + */ + public static final int LEAVES = bit(2); + + /** Filter by checkpoints that have children (Since: 5.6.0) + * + * @see + * Libvirt Documentation + */ + public static final int NO_LEAVES = bit(3); + } + public static final class SnapshotCreateFlags { /** Restore or alter metadata */ @@ -590,7 +864,6 @@ public static final class DeviceModifyFlags { public static final int FORCE = bit(2); } - public static final class VcpuFlags { public static final int CONFIG = ModificationImpact.CONFIG; public static final int CURRENT = ModificationImpact.CURRENT; @@ -606,6 +879,15 @@ public static final class VcpuFlags { public static final int HOTPLUGGABLE = bit(4); } + public static final class MemoryModFlags { + public static final int CONFIG = ModificationImpact.CONFIG; + public static final int CURRENT = ModificationImpact.CURRENT; + public static final int LIVE = ModificationImpact.LIVE; + + /** Max rather than current count */ + public static final int MAXIMUM = bit(2); + } + public static final class DomainSetUserPasswordFlags { /** Password is not encrypted */ public static final int DOMAIN_PASSWORD_NOT_ENCRYPTED = 0; @@ -613,6 +895,19 @@ public static final class DomainSetUserPasswordFlags { public static final int DOMAIN_PASSWORD_ENCRYPTED = bit(1); } + public static final class CoreDumpFlags { + /** crash after dump **/ + public static final int CRASH = bit(0); + /** live dump **/ + public static final int LIVE = bit(1); + /** avoid file system cache pollution **/ + public static final int BYPASS_CACHE = bit(2); + /** reset domain after dump finishes **/ + public static final int RESET = bit(3); + /** use dump-guest-memory **/ + public static final int MEMORY_ONLY = bit(4); + } + /** the native virDomainPtr. */ DomainPointer vdp; @@ -713,7 +1008,7 @@ static Domain constructIncRef(final Connect virConnect, final DomainPointer vdp) * aborted. * * @see Libvirt + * href="https://libvirt.org/html/libvirt-libvirt-domain.html#virDomainAbortJob">Libvirt * Documentation * @return ignore (always 0) * @throws LibvirtException @@ -726,7 +1021,7 @@ public int abortJob() throws LibvirtException { * Creates a virtual device attachment to backend. * * @see Libvirt + * href="https://libvirt.org/html/libvirt-libvirt-domain.html#virDomainAttachDevice">Libvirt * Documentation * @param xmlDesc * XML description of one device @@ -752,6 +1047,35 @@ public void attachDeviceFlags(final String xmlDesc, final int flags) processError(libvirt.virDomainAttachDeviceFlags(vdp, xmlDesc, flags)); } + /** + * Start a point-in-time backup job for the specified disks of a running domain. + * + * @see + * Libvirt Documentation + * @param backupXML contains details about the backup in the top-level element + * @param checkpointXML description of a checkpoint to create or null + * @param flags the an OR'ed set of {@link DomainBackupBeginFlags} + * @throws LibvirtException + */ + public void backupBegin(final String backupXML, final String checkpointXML, int flags) + throws LibvirtException { + processError(libvirt.virDomainBackupBegin(vdp, backupXML, checkpointXML, flags)); + } + + /** + * Queries the configuration of the active backup job. + * @see + Libvirt Documentation + * @param flags extra flags; not used yet, so callers should always pass 0 + * @returnthe XML document + * @throws LibvirtException + */ + public String getBackupXMLDesc(final int flags) throws LibvirtException { + CString result = libvirt.virDomainBackupGetXMLDesc(vdp, flags); + processError(result); + return result.toString(); + } + /** * This function migrates domain's live block device (disk) to another * block device. @@ -824,6 +1148,7 @@ public DomainBlockInfo blockInfo(final String path) throws LibvirtException { public void blockPeek(final String disk, final long offset, final ByteBuffer buffer) throws LibvirtException { SizeT size = new SizeT(); + long currentOffset = offset; // older libvirt has a limitation on the size of data // transferred per request in the remote driver. So, split @@ -834,9 +1159,10 @@ public void blockPeek(final String disk, final long offset, size.setValue(req); - processError(libvirt.virDomainBlockPeek(this.vdp, disk, offset, size, buffer, 0)); + processError(libvirt.virDomainBlockPeek(this.vdp, disk, currentOffset, size, buffer, 0)); buffer.position(buffer.position() + req); + currentOffset += req; } while (buffer.hasRemaining()); assert buffer.position() == buffer.limit(); @@ -895,7 +1221,7 @@ public void blockResize(final String disk, final long size, final int flags) * @throws LibvirtException */ public void blockCommit(String disk, String base, String top, long bandwidth, int flags) throws LibvirtException { - processError(libvirt.virDomainBlockCommit(vdp, disk, base, top, bandwidth, flags)); + processError(libvirt.virDomainBlockCommit(vdp, disk, base, top, new NativeLong(bandwidth), flags)); } /** @@ -976,7 +1302,7 @@ public int create(final int flags) throws LibvirtException { * Destroys this domain object. The running instance is shutdown if not down * already and all resources used by it are given back to the hypervisor. * The data structure is freed and should not be used thereafter if the call - * does not return an error. This function may requires priviledged access + * does not return an error. This function may require privileged access * * @throws LibvirtException */ @@ -988,7 +1314,7 @@ public void destroy() throws LibvirtException { * Destroys a virtual device attachment to backend. * * @see Libvirt + * href="https://libvirt.org/html/libvirt-libvirt-domain.html#virDomainDetachDevice">Libvirt * Documentation * @param xmlDesc * XML description of one device @@ -1002,7 +1328,7 @@ public void detachDevice(final String xmlDesc) throws LibvirtException { * Destroys a virtual device attachment to backend. * * @see Libvirt + * href="https://libvirt.org/html/libvirt-libvirt-domain.html#virDomainDetachDeviceFlags">Libvirt * Documentation * @param xmlDesc * XML description of one device @@ -1073,7 +1399,7 @@ public int getID() throws LibvirtException { * extracted. * * @see Libvirt + * href="https://libvirt.org/html/libvirt-libvirt-domain.html#virDomainGetInfo">Libvirt * Documentation * * @return a DomainInfo object describing this domain @@ -1090,9 +1416,9 @@ public DomainInfo getInfo() throws LibvirtException { * return an error if the domain is not active. * * @see Libvirt + * href="https://libvirt.org/html/libvirt-libvirt-domain.html#virDomainGetJobInfo">Libvirt * Documentation - * @return a DomainJobInfo object describing this domain + * @return a DomainJobInfo object * @throws LibvirtException */ public DomainJobInfo getJobInfo() throws LibvirtException { @@ -1101,10 +1427,33 @@ public DomainJobInfo getJobInfo() throws LibvirtException { return new DomainJobInfo(vInfo); } + /** + * Extract information about progress of a background job on a domain. Will + * return an error if the domain is not active. + * + * @see Libvirt + * Documentation + * @param flags + * flags + * @return a DomainJobStats object + * @throws LibvirtException + */ + public DomainJobStats getJobStats(final int flags) throws LibvirtException { + IntByReference type = new IntByReference(); + PointerByReference params = new PointerByReference(); + IntByReference nParams = new IntByReference(); + + processError(libvirt.virDomainGetJobStats(vdp, type, params, nParams, flags)); + + TypedParameter[] stats = TypedParameter.fromPointer(params.getValue(), nParams.getValue()); + return new DomainJobStats(type.getValue(), stats); + } + /** * Retrieve the maximum amount of physical memory allocated to a domain. * - * @return the memory in kilobytes + * @return the memory size in kibibytes (blocks of 1024 bytes) * @throws LibvirtException */ public long getMaxMemory() throws LibvirtException { @@ -1136,7 +1485,7 @@ public int getMaxVcpus() throws LibvirtException { * @throws LibvirtException */ public String getMetadata(int type, String uri, int flags) throws LibvirtException { - return processError(libvirt.virDomainGetMetadata(vdp, type, uri, flags)); + return processError(libvirt.virDomainGetMetadata(vdp, type, uri, flags)).toString(); } /** @@ -1306,7 +1655,7 @@ public String getXMLDesc(final int flags) throws LibvirtException { /** * Determine if the domain has a snapshot * - * @see Libvirt Documentation * @return 1 if running, 0 if inactive * @throws LibvirtException @@ -1318,7 +1667,7 @@ public int hasCurrentSnapshot() throws LibvirtException { /** * Determine if the domain has a managed save image * - * @see Libvirt Documentation * @return 0 if no image is present, 1 if an image is present, and -1 in * case of error @@ -1406,7 +1755,7 @@ public DomainInterfaceStats interfaceStats(final String path) * Determine if the domain is currently running * * @see Libvirt + * href="https://libvirt.org/html/libvirt-libvirt-domain.html#virDomainIsActive">Libvirt * Documentation * @return 1 if running, 0 if inactive * @throws LibvirtException @@ -1420,7 +1769,7 @@ public int isActive() throws LibvirtException { * will still exist after shutting down * * @see Libvirt + * href="https://libvirt.org/html/libvirt-libvirt-domain.html#virDomainIsPersistent">Libvirt * Documentation * @return 1 if persistent, 0 if transient * @throws LibvirtException @@ -1441,7 +1790,7 @@ public boolean isUpdated() throws LibvirtException { * suspend a domain and save its memory contents to a file on disk. * * @see Libvirt + * href="https://libvirt.org/html/libvirt-libvirt-domain.html#virDomainManagedSave">Libvirt * Documentation * @return always 0 * @throws LibvirtException @@ -1454,7 +1803,7 @@ public int managedSave() throws LibvirtException { * Remove any managed save images from the domain * * @see Libvirt + * href="https://libvirt.org/html/libvirt-libvirt-domain.html#virDomainManagedSaveRemove">Libvirt * Documentation * @return always 0 * @throws LibvirtException @@ -1486,6 +1835,7 @@ public void memoryPeek(final long start, final ByteBuffer buffer, final MemoryAddressMode mode) throws LibvirtException { SizeT size = new SizeT(); + long currentStart = start; // older libvirt has a limitation on the size of data // transferred per request in the remote driver. So, split @@ -1496,14 +1846,37 @@ public void memoryPeek(final long start, final ByteBuffer buffer, size.setValue(req); - processError(libvirt.virDomainMemoryPeek(this.vdp, start, size, buffer, mode.getValue())); + processError(libvirt.virDomainMemoryPeek(this.vdp, currentStart, size, buffer, mode.getValue())); buffer.position(buffer.position() + req); + currentStart += req; } while (buffer.hasRemaining()); assert buffer.position() == buffer.limit(); } + /** + * This function provides cpu statistics for the domain. + * + * @param start_cpu + * which cpu to start with, or -1 for summary + * @param ncpus + * how many cpus to query + * @return the collection of stats + * @throws LibvirtException + */ + public TypedParameter[] getCPUStats(final int start_cpu, final int ncpus) + throws LibvirtException { + int number = processError(libvirt.virDomainGetCPUStats(vdp, null, 0, start_cpu, ncpus, 0)); + virTypedParameter[] params = new virTypedParameter[number * ncpus]; + int result = processError(libvirt.virDomainGetCPUStats(vdp, params, number, start_cpu, ncpus, 0)); + TypedParameter[] returnStats = new TypedParameter[result * ncpus]; + for (int x = 0; x < result * ncpus; x++) { + returnStats[x] = TypedParameter.create(params[x]); + } + return returnStats; + } + /** * This function provides memory statistics for the domain. * @@ -1671,6 +2044,11 @@ public Domain migrate(final Connect dconn, final long flags, * after the returned domain object is no longer needed. *

* For more informations, please @see virDomainMigrate3 + * + * @deprecated + * use {@link migrate(Connect, TypedParameter[], int) + * migrate(Connect, TypedParameter[], int)} + * instaed * @param dconn * destination host (a Connect object) * @param params @@ -1684,10 +2062,52 @@ public Domain migrate(final Connect dconn, final long flags, * connection (dconn). * @throws LibvirtException */ + @Deprecated public Domain migrate(final Connect dconn, final TypedParameter[] params, long flags) throws LibvirtException { assert params != null : "migrate Typed parameters cannot be null"; virTypedParameter[] virTypedParameters = generateNativeVirTypedParameters(params); - DomainPointer newPtr = processError(libvirt.virDomainMigrate3(vdp, dconn.vcp, virTypedParameters, params.length, new NativeLong(flags))); + DomainPointer newPtr = processError(libvirt.virDomainMigrate3(vdp, dconn.vcp, virTypedParameters, params.length, (int)flags)); + return new Domain(dconn, newPtr); + } + + /** + * Migrate the domain object from its current host to the destination host + * given by {@code dconn} (a connection to the destination host). + *

See {@link DomainMigrateParameters DomainMigrateParameters} for + * detailed description of individual {@code params}. + *

See {@link MigrateFlags MigrateFlags} documentation for description + * of individual {@code flags}. {@link MigrateFlags#TUNNELED TUNNELED} + * and {@link MigrateFlags#PEER2PEER PEER2PEER} are not supported by this + * API, use {@link migrateToURI(String, TypedParameter[], int) + * migrateToURI(String, TypedParameter[], int)} instead. + *

There are many limitations on migration imposed by the underlying + * technology - for example it may not be possible to migrate between + * different processors even with the same architecture, or between different + * types of hypervisor. + *

{@link free} should be used to free the resources + * after the returned domain object is no longer needed. + * + * @see + * virDomainMigrate3 + * + * @param dconn + * destination host (a Connect object) + * @param params + * (optional) migration parameters + * + * @param flags + * bitwise-OR of {@link MigrateFlags MigrateFlags} + * @return + * the new domain object if the migration was successful. Note that + * the new domain object exists in the scope of the destination + * connection ({@code dconn}). + * @throws LibvirtException on failure + */ + public Domain migrate(final Connect dconn, final TypedParameter[] params, int flags) throws LibvirtException { + assert params != null : "migrate Typed parameters cannot be null"; + virTypedParameter[] virTypedParameters = generateNativeVirTypedParameters(params); + DomainPointer newPtr = processError(libvirt.virDomainMigrate3(vdp, dconn.vcp, virTypedParameters, params.length, flags)); return new Domain(dconn, newPtr); } @@ -1723,7 +2143,7 @@ private virTypedParameter[] generateNativeVirTypedParameters(TypedParameter[] pa * at the end of live migration. * * @see LIbvirt + * href="https://libvirt.org/html/libvirt-libvirt-domain.html#virDomainMigrateSetMaxDowntime">LIbvirt * Documentation * @param downtime * the time to be down @@ -1747,7 +2167,42 @@ public int migrateSetMaxDowntime(final long downtime) * flag is set in flags). * * @see + * href="https://libvirt.org/html/libvirt-libvirt-domain.html#virDomainMigrateToURI"> + * virDomainMigrateToURI + * + * @param dconnuri + * (optional) URI for target libvirtd if @flags includes PEER2PEER + * @param params + * (optional) Migration parameters + * @param flags + * Controls the migrate + * @return 0 if successful + * @throws LibvirtException + */ + public int migrateToURI(final String dconnuri, + final TypedParameter[] params, + final int flags) + throws LibvirtException { + assert params != null : "migrate Typed parameters cannot be null"; + virTypedParameter[] input = generateNativeVirTypedParameters(params); + return processError(libvirt.virDomainMigrateToURI3(vdp, dconnuri, + input, input.length, + flags)); + } + + /** + * Migrate the domain object from its current host to the destination + * denoted by a given URI. + *

+ * The destination is given either in dconnuri (if the + * {@link MigrateFlags#PEER2PEER PEER2PEER} + * is flag set), or in miguri (if neither the + * {@link MigrateFlags#PEER2PEER PEER2PEER} nor the + * {@link MigrateFlags#TUNNELED TUNNELED} migration + * flag is set in flags). + * + * @see * virDomainMigrateToURI * * @param dconnuri @@ -1779,7 +2234,7 @@ dxml, new NativeLong(flags), * given by duri. * * @see + * href="https://libvirt.org/html/libvirt-libvirt-domain.html#virDomainMigrateToURI"> * virDomainMigrateToURI * * @param uri @@ -1831,7 +2286,7 @@ public void PMwakeup() throws LibvirtException { /** * Dynamically changes the real CPUs which can be allocated to a virtual - * CPU. This function requires priviledged access to the hypervisor. + * CPU. This function requires privileged access to the hypervisor. * * @param vcpu * virtual cpu number @@ -1880,7 +2335,7 @@ public void resume() throws LibvirtException { * Adds a callback to receive notifications of Block Job events * * @see Libvirt + * href="https://libvirt.org/html/libvirt-libvirt-domain.html#virConnectDomainEventRegisterAny">Libvirt * Documentation * @param cb * @throws LibvirtException @@ -1904,7 +2359,7 @@ public void removeBlockJobListener(final BlockJobListener cb) throws LibvirtExce * occurring on this domain. * * @see Libvirt + * href="https://libvirt.org/html/libvirt-libvirt-domain.html#virConnectDomainEventRegisterAny">Libvirt * Documentation * @param cb * the IOErrorCallback instance @@ -1922,7 +2377,7 @@ public void addIOErrorListener(final IOErrorListener cb) throws LibvirtException * * @see Connect#addRebootListener * @see virConnectDomainEventRegisterAny * @since 1.5.2 */ @@ -1956,7 +2411,7 @@ public void addAgentLifecycleListener(final AgentLifecycleListener cb) throws Li * @see Connect#addLifecycleListener * @see Connect#removeLifecycleListener * @see virConnectDomainEventRegisterAny */ public void addLifecycleListener(final LifecycleListener l) @@ -1973,7 +2428,7 @@ public void addLifecycleListener(final LifecycleListener l) * @see Connect#removePMWakeupListener * @see Connect#addPMWakeupListener * @see virConnectDomainEventRegisterAny * * @since 1.5.2 @@ -1992,7 +2447,7 @@ public void addPMWakeupListener(final PMWakeupListener l) * @see Connect#removePMSuspendListener * @see Connect#addPMSuspendListener * @see virConnectDomainEventRegisterAny * * @since 1.5.2 @@ -2013,7 +2468,7 @@ public void reset() throws LibvirtException { * Revert the domain to a given snapshot. * * @see Libvirt Documentation * @param snapshot * the snapshot to revert to @@ -2061,10 +2516,10 @@ public void setAutostart(final boolean autostart) throws LibvirtException { /** * * Dynamically change the maximum amount of physical memory allocated to a - * domain. This function requires priviledged access to the hypervisor. + * domain. This function requires privileged access to the hypervisor. * * @param memory - * the amount memory in kilobytes + * the memory size in kibibytes (blocks of 1024 bytes) * @throws LibvirtException */ public void setMaxMemory(final long memory) throws LibvirtException { @@ -2073,17 +2528,46 @@ public void setMaxMemory(final long memory) throws LibvirtException { /** * Dynamically changes the target amount of physical memory allocated to - * this domain. This function may requires priviledged access to the + * this domain. This function may require privileged access to the * hypervisor. * * @param memory - * in kilobytes + * the memory size in kibibytes (blocks of 1024 bytes) * @throws LibvirtException */ public void setMemory(final long memory) throws LibvirtException { processError(libvirt.virDomainSetMemory(vdp, new NativeLong(memory))); } + /** + * Dynamically changes the target amount of physical memory allocated to + * this domain. This function may require privileged access to the + * hypervisor. + * + * @param memory + * the memory size in kibibytes (blocks of 1024 bytes) + * @param flags + * see {@link MemoryModFlags} + * @throws LibvirtException + */ + public void setMemoryFlags(final long memory, final int flags) throws LibvirtException { + processError(libvirt.virDomainSetMemoryFlags(vdp, new NativeLong(memory), flags)); + } + + /** + * Dynamically changes the domain memory balloon driver statistics + * collection period. + * + * @param period + * collection period in seconds; 0 disables collection + * @param flags + * see {@link ModificationImpact} + * @throws LibvirtException + */ + public void setMemoryStatsPeriod(final int period, final int flags) throws LibvirtException { + processError(libvirt.virDomainSetMemoryStatsPeriod(vdp, period, flags)); + } + /** * Sets the appropriate domain element given by type to the value of metadata. * @@ -2196,12 +2680,147 @@ public void shutdown() throws LibvirtException { processError(libvirt.virDomainShutdown(vdp)); } + /** + * Creates a new checkpoint of a domain based on the checkpoint xml contained in + * xmlDesc. + * + * @see Libvirt + * Documentation + * @param xmlDesc + * string containing an XML description of the checkpoint + * @param flags + * flags for creating the checkpoint, see the {@link CheckpointCreateFlags} for the flag options + * @return the checkpoint + * @throws LibvirtException + */ + public DomainCheckpoint checkpointCreateXML(final String xmlDesc, final int flags) + throws LibvirtException { + DomainCheckpointPointer ptr = processError(libvirt.virDomainCheckpointCreateXML(vdp, xmlDesc, flags)); + return new DomainCheckpoint(virConnect, ptr); + } + + /** + * Creates a new checkpoint of a domain based on the checkpoint xml contained in + * xmlDesc. + *

+ * This is just a convenience method, it has the same effect + * as calling {@code checkpointCreateXML(xmlDesc, 0);}. + * + * @see #checkpointCreateXML(String, int) + * @see Libvirt + * Documentation + * @param xmlDesc + * string containing an XML description of the checkpoint + * @return the checkpoint, or null on Error + * @throws LibvirtException + */ + public DomainCheckpoint checkpointCreateXML(final String xmlDesc) + throws LibvirtException { + return checkpointCreateXML(xmlDesc, 0); + } + + /** + * Array of domain checkpoints for the given domain. + * + * @see Libvirt + * Documentation + * + * @param flags + * flags for list the checkpoint, see the {@link CheckpointListFlags} for the flag options + * @return Array with domain checkpoints of the given domain + * @throws LibvirtException + */ + public DomainCheckpoint[] listAllCheckpoints(int flags) throws LibvirtException { + PointerByReference checkpoints = new PointerByReference(); + int count = libvirt.virDomainListAllCheckpoints(vdp, checkpoints, flags); + if (checkpoints.getValue() == null) { + if (count != 0) { + processError(count); + throw new IllegalStateException("virDomainListAllCheckpoints returned " + count); + } + return new DomainCheckpoint[0]; + } + + try { + if (count < 0) { + processError(count); + throw new IllegalStateException("virDomainListAllCheckpoints returned " + count); + } + DomainCheckpoint[] result = new DomainCheckpoint[count]; + Pointer arrayPtr = checkpoints.getValue(); + for (int i = 0; i < count; i++) { + Pointer p = arrayPtr.getPointer((long) i * Native.POINTER_SIZE); + result[i] = new DomainCheckpoint(virConnect, new DomainCheckpointPointer(p)); + } + return result; + } finally { + Library.free(checkpoints.getValue()); + } + } + + /** + * Retrieve a checkpoint based on its name + * + * @see Libvirt + * Documentation + * @param name + * name for the domain checkpoint + * @return The domain checkpoint or null in case of not found + * @throws LibvirtException + */ + public DomainCheckpoint checkpointLookupByName(final String name) + throws LibvirtException { + DomainCheckpointPointer ptr = libvirt.virDomainCheckpointLookupByName(vdp, name, 0); + if (ptr == null) { + return null; + } + return new DomainCheckpoint(virConnect, ptr); + } + + /** + * Array of domain checkpoint names for the given domain. With the option to pass flags. + * + * This is a helper function, internally, call to listAllCheckpoints(flags), and it only get the names. + * @param flags {@link CheckpointListFlags} + * @return Array of names, or null if an error + * @throws LibvirtException + */ + public String[] checkpointListNames(final int flags) throws LibvirtException { + DomainCheckpoint[] checkpoints = listAllCheckpoints(flags); + if(checkpoints.length > 0) { + String[] names = new String[checkpoints.length]; + for(int i = 0; i < checkpoints.length; i++) { + names[i] = checkpoints[i].getName(); + } + return names; + } + return Library.NO_STRINGS; + } + + /** + * Array of domain checkpoint names for the given domain. + *

+ * This is just a convenience method, it has the same effect + * as calling {@code checkpointListNames(0);}. + * + * @see #checkpointListNames(int) + * @return The list of names, or null if an error + * @throws LibvirtException + */ + public String[] checkpointListNames() throws LibvirtException { + return checkpointListNames(0); + } + /** * Creates a new snapshot of a domain based on the snapshot xml contained in * xmlDesc. * * @see Libvirt + * href="https://libvirt.org/html/libvirt-libvirt-domain-snapshot.html#virDomainSnapshotCreateXML">Libvirt * Documentation * @param xmlDesc * string containing an XML description of the domain @@ -2225,7 +2844,7 @@ public DomainSnapshot snapshotCreateXML(final String xmlDesc, final int flags) * * @see #snapshotCreateXML(String, int) * @see Libvirt + * href="https://libvirt.org/html/libvirt-libvirt-domain-snapshot.html#virDomainSnapshotCreateXML">Libvirt * Documentation * @param xmlDesc * string containing an XML description of the domain @@ -2241,7 +2860,7 @@ public DomainSnapshot snapshotCreateXML(final String xmlDesc) * Get the current snapshot for a domain, if any. * * @see Libvirt + * href="https://libvirt.org/html/libvirt-libvirt-domain-snapshot.html#virDomainSnapshotCurrent">Libvirt * Documentation * @return the snapshot * @throws LibvirtException @@ -2255,7 +2874,7 @@ public DomainSnapshot snapshotCurrent() throws LibvirtException { * Collect the list of domain snapshots for the given domain. With the option to pass flags * * @see Libvirt + * href="https://libvirt.org/html/libvirt-libvirt-domain-snapshot.html#virDomainSnapshotListNames">Libvirt * Documentation * @param flags {@link SnapshotListFlags} * @return The list of names, or null if an error @@ -2281,7 +2900,7 @@ public String[] snapshotListNames(final int flags) throws LibvirtException { * * @see #snapshotListNames(int) * @see + * href="https://libvirt.org/html/libvirt-libvirt-domain-snapshot.html#virDomainSnapshotListNames"> * virDomainSnapshotListNames * @return The list of names, or null if an error * @throws LibvirtException @@ -2294,7 +2913,7 @@ public String[] snapshotListNames() throws LibvirtException { * Retrieve a snapshot by name * * @see Libvirt + * href="https://libvirt.org/html/libvirt-libvirt-domain-snapshot.html#virDomainSnapshotLookupByName">Libvirt * Documentation * @param name * the name @@ -2311,7 +2930,7 @@ public DomainSnapshot snapshotLookupByName(final String name) * Provides the number of domain snapshots for this domain.. * * @see Libvirt + * href="https://libvirt.org/html/libvirt-libvirt-domain-snapshot.html#virDomainSnapshotNum">Libvirt * Documentation */ public int snapshotNum() throws LibvirtException { @@ -2322,7 +2941,7 @@ public int snapshotNum() throws LibvirtException { * Suspends this active domain, the process is frozen without further access * to CPU resources and I/O but the memory used by the domain at the * hypervisor level will stay allocated. Use Domain.resume() to reactivate - * the domain. This function requires priviledged access. + * the domain. This function requires privileged access. * * @throws LibvirtException */ @@ -2343,7 +2962,7 @@ public void undefine() throws LibvirtException { * Undefines this domain but does not stop if it it is running. * With option for passing flags * - * @see + * @see Libvirt Documentation * @param flags * flags for undefining the domain. @@ -2357,7 +2976,7 @@ public void undefine(final int flags) throws LibvirtException { /** * Change a virtual device on a domain * - * @see + * @see Libvirt Documentation * @param xml * the xml to update with @@ -2371,6 +2990,18 @@ public int updateDeviceFlags(final String xml, final int flags) return processError(libvirt.virDomainUpdateDeviceFlags(vdp, xml, flags)); } + /** + * Send NMI to the guest + * + *@see Libvirt + * Documentation + * @throws LibvirtException + */ + public void injectNMI() throws LibvirtException { + processError(libvirt.virDomainInjectNMI(vdp, 0)); + } + /** * Commands for Qemu Guest Agent helper daemon * diff --git a/src/main/java/org/libvirt/DomainBlockJobInfo.java b/src/main/java/org/libvirt/DomainBlockJobInfo.java index 72894a4..0e7c746 100644 --- a/src/main/java/org/libvirt/DomainBlockJobInfo.java +++ b/src/main/java/org/libvirt/DomainBlockJobInfo.java @@ -13,7 +13,7 @@ public DomainBlockJobInfo() { public DomainBlockJobInfo(final virDomainBlockJobInfo virInfo) { type = virInfo.type; - bandwidth = virInfo.bandwidth; + bandwidth = virInfo.bandwidth.longValue(); cur = virInfo.cur; end = virInfo.end; } diff --git a/src/main/java/org/libvirt/DomainCheckpoint.java b/src/main/java/org/libvirt/DomainCheckpoint.java new file mode 100644 index 0000000..708ae88 --- /dev/null +++ b/src/main/java/org/libvirt/DomainCheckpoint.java @@ -0,0 +1,252 @@ +package org.libvirt; + +import org.libvirt.jna.DomainCheckpointPointer; + +import com.sun.jna.Pointer; +import com.sun.jna.ptr.PointerByReference; + +import static org.libvirt.Library.libvirt; + +import org.libvirt.Domain.CheckpointListFlags; + +import com.sun.jna.Native; + + +import static org.libvirt.ErrorHandler.processError; + +public class DomainCheckpoint { + + private static int bit(final int i) { + return 1 << i; + } + + public static final class CheckpointDeleteFlags { + /** + * Also delete children (Since: 5.6.0) + * + * @see + * Libvirt Documentation + */ + public static final int CHILDREN = bit(0); + + /** + * Delete just metadata (Since: 5.6.0) + * + * @see + * Libvirt Documentation + */ + public static final int METADATA_ONLY = bit(1); + + /** + * Delete just children (Since: 5.6.0) + * + * @see + * Libvirt Documentation + */ + public static final int CHILDREN_ONLY = bit(2); + } + + public static final class XMLFlags { + /** Include sensitive data (Since: 5.6.0) + * + * @see + * Libvirt Documentation + */ + public static final int SECURE = bit(0); + + /** Supress subelement (Since: 5.6.0) + * + * @see + * Libvirt Documentation + */ + public static final int NO_DOMAIN = bit(1); + + /** Include dynamic per- size (Since: 5.6.0) + * + * @see + * Libvirt Documentation + */ + public static final int XML_SIZE = bit(2); + } + + /** + * the native virDomainCheckpointPtr. + */ + DomainCheckpointPointer vdcp; + + /** + * The Connect Object that represents the Hypervisor of this Domain Checkpoint + */ + private final Connect virConnect; + + + /** + * Constructs a DomainCheckpoint object from a known native DomainCheckpointPointer, and a + * Connect object. + * + * @param virConnect + * the Domain's hypervisor + * @param vdcp + * the native virDomainCheckpointPtr + */ + public DomainCheckpoint(final Connect virConnect, + final DomainCheckpointPointer vdcp) { + this.vdcp = vdcp; + this.virConnect = virConnect; + } + + /** + * Delete the domain checkpoint + * + * @see Libvirt + * Documentation + * @param flags see {@link CheckpointDeleteFlags} + * controls the deletion + * @return ignore (always 0) + * @throws LibvirtException + */ + public int delete(final int flags) throws LibvirtException { + int success = 0; + if (vdcp != null) { + success = processError(libvirt.virDomainCheckpointDelete(vdcp, flags)); + } + + return success; + } + + @Override + protected void finalize() throws LibvirtException { + free(); + } + + /** + * Frees this domaincheckpoint object. The running instance is kept alive. The data + * structure is freed and should not be used thereafter. + * + * @throws LibvirtException + * @return number of references left (>= 0) + */ + public int free() throws LibvirtException { + int success = 0; + if (vdcp != null) { + success = processError(libvirt.virDomainCheckpointFree(vdcp)); + vdcp = null; + } + + return success; + } + + /** + * Fetches an XML document describing attributes of the domain checkpoint, without + * security-sensitive data. + * + * @see + * Libvirt Documentation + * @return the XML document + * @throws org.libvirt.LibvirtException + */ + public String getXMLDesc() throws LibvirtException { + return getXMLDesc(0); + } + + /** + * Fetches an XML document describing attributes of the domain checkpoint. + * + * @see + * Libvirt Documentation + * @param flags see {@link XMLFlags} + * controls the information + * @return the XML document + * @throws org.libvirt.LibvirtException + */ + public String getXMLDesc(final int flags) throws LibvirtException { + return processError(libvirt.virDomainCheckpointGetXMLDesc(vdcp, flags)).toString(); + } + + /** + * Get the public name for that checkpoint + * + * @return the name, null if there is no name + * @throws LibvirtException + */ + public String getName() throws LibvirtException { + return processError(libvirt.virDomainCheckpointGetName(vdcp)); + } + + /** + * Array of domain checkpoints children for the given domain checkpoint. + * + * @see Libvirt + * Documentation + * @param flags + * flags for list the checkpoints, see the {@link CheckpointListFlags} for the flag options + * @return Array with children checkpoints of the given domain checkpoint + * @throws LibvirtException + */ + public DomainCheckpoint[] listAllChildren(int flags) throws LibvirtException { + PointerByReference checkpoints = new PointerByReference(); + int count = libvirt.virDomainCheckpointListAllChildren(vdcp, checkpoints, flags); + if (checkpoints.getValue() == null) { + if (count != 0) { + processError(count); + throw new IllegalStateException("virDomainListAllCheckpoints returned " + count); + } + return new DomainCheckpoint[0]; + } + DomainCheckpoint[] result = new DomainCheckpoint[count]; + try { + if (count < 0) { + processError(count); + throw new IllegalStateException("virDomainListAllCheckpoints returned " + count); + } + + Pointer arrayPtr = checkpoints.getValue(); + for (int i = 0; i < count; i++) { + Pointer p = arrayPtr.getPointer((long) i * Native.POINTER_SIZE); + result[i] = new DomainCheckpoint(virConnect, new DomainCheckpointPointer(p)); + } + + return result; + } finally { + Library.free(checkpoints.getValue()); + } + } + + /** + * Get the parent checkpoint for checkpoint, if any. + * + * @see Libvirt + * Documentation + * @param flags + * extra flags + * @return a domain checkpoint or null if the given domain checkpoint is root + * @throws LibvirtException + */ + public DomainCheckpoint getParent(int flags) throws LibvirtException { + DomainCheckpointPointer parent = libvirt.virDomainCheckpointGetParent(vdcp, flags); + if(parent == null) + return null; + return new DomainCheckpoint(virConnect, parent); + } + + /** + * Get the parent checkpoint for checkpoint, if any. + * + * This is just a convenience method, it has the same effect + * as calling {@code getParent(0);}. + * + * @see #getParent(int) + * @see Libvirt + * Documentation + * @return a domain checkpoint or null if the given domain checkpoint is root + * @throws LibvirtException + */ + public DomainCheckpoint getParent() throws LibvirtException { + return getParent(0); + } + +} diff --git a/src/main/java/org/libvirt/DomainInfo.java b/src/main/java/org/libvirt/DomainInfo.java index 4b64524..1c8e244 100644 --- a/src/main/java/org/libvirt/DomainInfo.java +++ b/src/main/java/org/libvirt/DomainInfo.java @@ -79,7 +79,7 @@ public DomainInfo(final virDomainInfo info) { maxMem = info.maxMem.longValue(); memory = info.memory.longValue(); nrVirtCpu = info.nrVirtCpu; - state = DomainState.values()[info.state]; + state = DomainState.values()[info.state & 0xFF]; } @Override diff --git a/src/main/java/org/libvirt/DomainJobStats.java b/src/main/java/org/libvirt/DomainJobStats.java new file mode 100644 index 0000000..7972283 --- /dev/null +++ b/src/main/java/org/libvirt/DomainJobStats.java @@ -0,0 +1,11 @@ +package org.libvirt; + +public class DomainJobStats { + public int type; + public TypedParameter[] stats; + + public DomainJobStats(int type, TypedParameter[] stats) { + this.type = type; + this.stats = stats; + } +} diff --git a/src/main/java/org/libvirt/DomainSnapshot.java b/src/main/java/org/libvirt/DomainSnapshot.java index 09bdaef..14e1302 100644 --- a/src/main/java/org/libvirt/DomainSnapshot.java +++ b/src/main/java/org/libvirt/DomainSnapshot.java @@ -40,7 +40,7 @@ public DomainSnapshot(final Connect virConnect, * Delete the Snapshot * * @see Libvirt + * href="https://libvirt.org/html/libvirt-libvirt-domain-snapshot.html#virDomainSnapshotDelete">Libvirt * Documentation * @param flags see {@link SnapshotDeleteFlags} * controls the deletion diff --git a/src/main/java/org/libvirt/DomainStats.java b/src/main/java/org/libvirt/DomainStats.java new file mode 100644 index 0000000..6a5b28d --- /dev/null +++ b/src/main/java/org/libvirt/DomainStats.java @@ -0,0 +1,50 @@ +package org.libvirt; + +/** + * Bit flags selecting which stats groups {@link + * Connect#getAllDomainStats(int, int)} (and {@link + * Connect#getDomainListStats(Domain[], int, int)}) should return. + * + *

Matches the {@code VIR_DOMAIN_STATS_*} constants from libvirt. + * + * @see + * virDomainStatsTypes + */ +public final class DomainStats { + + /** Domain state. */ + public static final int STATE = 1 << 0; + + /** CPU totals. */ + public static final int CPU_TOTAL = 1 << 1; + + /** Balloon memory. */ + public static final int BALLOON = 1 << 2; + + /** Per-vCPU stats. */ + public static final int VCPU = 1 << 3; + + /** Network interface stats. */ + public static final int INTERFACE = 1 << 4; + + /** Block device stats. */ + public static final int BLOCK = 1 << 5; + + /** Performance event stats. */ + public static final int PERF = 1 << 6; + + /** IOThread stats. */ + public static final int IOTHREAD = 1 << 7; + + /** Memory stats. */ + public static final int MEMORY = 1 << 8; + + /** Dirty rate stats. */ + public static final int DIRTYRATE = 1 << 9; + + /** Hypervisor-specific VM stats. */ + public static final int VM = 1 << 10; + + private DomainStats() { + } +} diff --git a/src/main/java/org/libvirt/DomainStatsRecord.java b/src/main/java/org/libvirt/DomainStatsRecord.java new file mode 100644 index 0000000..d2af60a --- /dev/null +++ b/src/main/java/org/libvirt/DomainStatsRecord.java @@ -0,0 +1,23 @@ +package org.libvirt; + +/** + * A single record returned by + * {@link Connect#getAllDomainStats(int, int)} or + * {@link Connect#getDomainListStats(Domain[], int, int)}. + * + *

Carries the {@link Domain} the stats describe and the typed parameters + * for that domain, in the order returned by libvirt (for example + * {@code "state.state"}, {@code "cpu.time"}, {@code "block.0.rd.bytes"}). + * + *

The {@code Domain} reference is owned by the caller and must be freed + * (e.g. via {@link Domain#free()}) once the record is no longer needed. + */ +public class DomainStatsRecord { + public Domain domain; + public TypedParameter[] params; + + public DomainStatsRecord(Domain domain, TypedParameter[] params) { + this.domain = domain; + this.params = params; + } +} diff --git a/src/main/java/org/libvirt/ErrorException.java b/src/main/java/org/libvirt/ErrorException.java index 86b3314..8d30ecf 100644 --- a/src/main/java/org/libvirt/ErrorException.java +++ b/src/main/java/org/libvirt/ErrorException.java @@ -7,6 +7,7 @@ * @author stoty * @deprecated */ +@Deprecated public class ErrorException extends Exception { private static final long serialVersionUID = -4329050530233404971L; diff --git a/src/main/java/org/libvirt/Interface.java b/src/main/java/org/libvirt/Interface.java index 1cec980..a69577e 100644 --- a/src/main/java/org/libvirt/Interface.java +++ b/src/main/java/org/libvirt/Interface.java @@ -129,7 +129,7 @@ public String getXMLDescription(final int flags) throws LibvirtException { * Determine if the interface is currently running * * @see Libvirt + * href="https://libvirt.org/html/libvirt-libvirt-interface.html#virInterfaceIsActive">Libvirt * Documentation * @return 1 if running, 0 if inactive * @throws LibvirtException diff --git a/src/main/java/org/libvirt/MemoryStatistic.java b/src/main/java/org/libvirt/MemoryStatistic.java index d89db4d..4385bde 100644 --- a/src/main/java/org/libvirt/MemoryStatistic.java +++ b/src/main/java/org/libvirt/MemoryStatistic.java @@ -7,6 +7,36 @@ public class MemoryStatistic { protected int tag; protected long val; + public static final class MemoryStatisticTags { + public static final int SWAP_IN = 0; + + public static final int SWAP_OUT = 1; + + public static final int MAJOR_FAULT = 2; + + public static final int MINOR_FAULT = 3; + + public static final int UNUSED = 4; + + public static final int AVAILABLE = 5; + + public static final int ACTUAL_BALLOON = 6; + + public static final int RSS = 7; + + public static final int USABLE = 8; + + public static final int LAST_UPDATE = 9; + + public static final int DISK_CACHES = 10; + + public static final int PGALLOC = 11; + + public static final int HUGETLB_PGFAIL = 12; + + public static final int NR = 13; + } + public MemoryStatistic(final virDomainMemoryStats stat) { tag = stat.tag; val = stat.val; diff --git a/src/main/java/org/libvirt/Network.java b/src/main/java/org/libvirt/Network.java index ec038ed..87fec6b 100644 --- a/src/main/java/org/libvirt/Network.java +++ b/src/main/java/org/libvirt/Network.java @@ -55,7 +55,7 @@ public void create() throws LibvirtException { * Destroy this network object. The running instance is shutdown if not down * already and all resources used by it are given back to the hypervisor. * The object becomes invalid and should not be used thereafter if the call - * does not return an error. This function may require priviledged access + * does not return an error. This function may require privileged access * * @throws LibvirtException */ @@ -173,7 +173,7 @@ public String getXMLDesc(final int flags) throws LibvirtException { * Determine if the network is currently running * * @see Libvirt + * href="https://libvirt.org/html/libvirt-libvirt-network.html#virNetworkIsActive">Libvirt * Documentation * @return 1 if running, 0 if inactive, -1 on error * @throws LibvirtException @@ -187,7 +187,7 @@ public int isActive() throws LibvirtException { * will still exist after shutting down * * @see Libvirt + * href="https://libvirt.org/html/libvirt-libvirt-network.html#virNetworkIsPersistent">Libvirt * Documentation * @return 1 if persistent, 0 if transient, -1 on error * @throws LibvirtException diff --git a/src/main/java/org/libvirt/NetworkFilter.java b/src/main/java/org/libvirt/NetworkFilter.java index c67bdcb..6d58ab9 100644 --- a/src/main/java/org/libvirt/NetworkFilter.java +++ b/src/main/java/org/libvirt/NetworkFilter.java @@ -86,7 +86,7 @@ public String getUUIDString() throws LibvirtException { * * @throws org.libvirt.LibvirtException * @see Libvirt + * href="https://libvirt.org/html/libvirt-libvirt-nwfilter.html#virNWFilterGetXMLDesc">Libvirt * Documentation * @return the XML document */ diff --git a/src/main/java/org/libvirt/StoragePool.java b/src/main/java/org/libvirt/StoragePool.java index 1ee4b40..fe87eb7 100644 --- a/src/main/java/org/libvirt/StoragePool.java +++ b/src/main/java/org/libvirt/StoragePool.java @@ -221,7 +221,7 @@ public String getXMLDesc(final int flags) throws LibvirtException { * Determine if the storage pool is currently running * * @see Libvirt + * href="https://libvirt.org/html/libvirt-libvirt-storage.html#virStoragePoolIsActive">Libvirt * Documentation * @return 1 if running, 0 if inactive * @throws LibvirtException @@ -235,7 +235,7 @@ public int isActive() throws LibvirtException { * it will still exist after shutting down * * @see + * href="https://libvirt.org/html/libvirt-libvirt-storage.html#virStoragePoolIsPersistent"> Libvirt Documentation * @return 1 if persistent, 0 if transient * @throws LibvirtException diff --git a/src/main/java/org/libvirt/StorageVol.java b/src/main/java/org/libvirt/StorageVol.java index 01e24d7..d26a8f8 100644 --- a/src/main/java/org/libvirt/StorageVol.java +++ b/src/main/java/org/libvirt/StorageVol.java @@ -204,7 +204,7 @@ public StoragePool storagePoolLookupByVolume() throws LibvirtException { /** * Ensure data previously on a volume is not accessible to future reads * - * @see + * @see Libvirt Documentation * @return ignore (always 0) * @throws LibvirtException @@ -216,7 +216,7 @@ public int wipe() throws LibvirtException { /** * Resize a volume * - * @see + * @see Libvirt Documentation * @param capacity * new capacity for volume diff --git a/src/main/java/org/libvirt/StorageVolInfo.java b/src/main/java/org/libvirt/StorageVolInfo.java index 52aa5ab..705fc84 100644 --- a/src/main/java/org/libvirt/StorageVolInfo.java +++ b/src/main/java/org/libvirt/StorageVolInfo.java @@ -15,7 +15,23 @@ public enum VirStorageVolType { /** * Block based volumes */ - VIR_STORAGE_VOL_BLOCK + VIR_STORAGE_VOL_BLOCK, + /** + * Directory-passthrough based volume + */ + VIR_STORAGE_VOL_DIR, + /** + * Network volumes like RBD (RADOS Block Device) + */ + VIR_STORAGE_VOL_NETWORK, + /** + * Network accessible directory that can contain other network volumes + */ + VIR_STORAGE_VOL_NETDIR, + /** + * Ploop based volumes + */ + VIR_STORAGE_VOL_PLOOP } /** @@ -49,6 +65,18 @@ public enum VirStorageVolType { case 1: this.type = VirStorageVolType.VIR_STORAGE_VOL_BLOCK; break; + case 2: + this.type = VirStorageVolType.VIR_STORAGE_VOL_DIR; + break; + case 3: + this.type = VirStorageVolType.VIR_STORAGE_VOL_NETWORK; + break; + case 4: + this.type = VirStorageVolType.VIR_STORAGE_VOL_NETDIR; + break; + case 5: + this.type = VirStorageVolType.VIR_STORAGE_VOL_PLOOP; + break; default: assert false; } diff --git a/src/main/java/org/libvirt/Stream.java b/src/main/java/org/libvirt/Stream.java index 3b6f0ed..8050357 100644 --- a/src/main/java/org/libvirt/Stream.java +++ b/src/main/java/org/libvirt/Stream.java @@ -126,7 +126,7 @@ public int abort() throws LibvirtException { * readable. * * @see Libvirt + * href="https://libvirt.org/html/libvirt-libvirt-stream.html#virStreamEventAddCallback">Libvirt * Docs * @param events * the events to monitor @@ -285,7 +285,7 @@ public boolean isOpen() { /** * Batch receive method * - * @see virStreamRecvAll + * @see virStreamRecvAll * @param handler * the callback handler * @return ignore (always 0) @@ -299,7 +299,7 @@ public int receiveAll(final Libvirt.VirStreamSinkFunc handler) /** * Remove an event callback from the stream * - * @see Libvirt Docs + * @see Libvirt Docs * @return ignore (always 0) * @throws LibvirtException */ @@ -331,7 +331,7 @@ protected int send(final ByteBuffer buffer) throws LibvirtException { * Batch send method * * @see Libvirt + * href="https://libvirt.org/html/libvirt-libvirt-stream.html#virStreamSendAll">Libvirt * Documentation * @param handler * the callback handler @@ -346,7 +346,7 @@ public int sendAll(final Libvirt.VirStreamSourceFunc handler) /** * Changes the set of events to monitor for a stream. * - * @see Libvirt Docs + * @see Libvirt Docs * @param events * the events to monitor * @return ignore (always 0) diff --git a/src/main/java/org/libvirt/TypedParameter.java b/src/main/java/org/libvirt/TypedParameter.java index 4474d65..6427df2 100644 --- a/src/main/java/org/libvirt/TypedParameter.java +++ b/src/main/java/org/libvirt/TypedParameter.java @@ -1,22 +1,22 @@ package org.libvirt; import com.sun.jna.Native; +import com.sun.jna.Pointer; import org.libvirt.jna.Libvirt; import org.libvirt.jna.virTypedParameter; import org.libvirt.jna.virTypedParameterValue; -import java.io.UnsupportedEncodingException; import java.nio.charset.StandardCharsets; import java.util.Arrays; public abstract class TypedParameter { - protected static final int TYPED_PARAM_INT = 1; - protected static final int TYPED_PARAM_UINT = 2; - protected static final int TYPED_PARAM_LONG = 3; - protected static final int TYPED_PARAM_ULONG = 4; - protected static final int TYPED_PARAM_DOUBLE = 5; - protected static final int TYPED_PARAM_BOOLEAN = 6; - protected static final int TYPED_PARAM_STRING = 7; + protected static final int TYPED_PARAM_INT = virTypedParameter.TYPED_PARAM_INT; + protected static final int TYPED_PARAM_UINT = virTypedParameter.TYPED_PARAM_UINT; + protected static final int TYPED_PARAM_LONG = virTypedParameter.TYPED_PARAM_LONG; + protected static final int TYPED_PARAM_ULONG = virTypedParameter.TYPED_PARAM_ULONG; + protected static final int TYPED_PARAM_DOUBLE = virTypedParameter.TYPED_PARAM_DOUBLE; + protected static final int TYPED_PARAM_BOOLEAN = virTypedParameter.TYPED_PARAM_BOOLEAN; + protected static final int TYPED_PARAM_STRING = virTypedParameter.TYPED_PARAM_STRING; /** * Parameter name @@ -44,6 +44,8 @@ public abstract class TypedParameter { */ public abstract String getValueAsString(); + private static final TypedParameter[] EMPTY = new TypedParameter[0]; + public static TypedParameter create(final virTypedParameter vParam) { TypedParameter returnValue = null; if (vParam != null) { @@ -126,4 +128,34 @@ public static byte[] copyOf(final byte[] original, final int length) { System.arraycopy(original, 0, returnValue, 0, originalLength); return returnValue; } + + public static TypedParameter[] fromPointer(Pointer ptr, int n) { + TypedParameter[] stats = toArray(ptr, n); + if (n != 0) { + Libvirt.INSTANCE.virTypedParamsFree(ptr, n); + } + return stats; + } + + /** + * Convert a native virTypedParameter array to Java {@link TypedParameter} + * objects without releasing the native memory. + * + *

Use this when the native array is owned by another allocator (for + * example, {@code virConnectGetAllDomainStats}, whose records are freed + * by {@code virDomainStatsRecordListFree}). + */ + public static TypedParameter[] toArray(Pointer ptr, int n) { + if (n == 0 || ptr == null) { + return EMPTY; + } + virTypedParameter param = new virTypedParameter(ptr); + param.read(); + virTypedParameter[] params = (virTypedParameter[]) param.toArray(n); + TypedParameter[] stats = new TypedParameter[n]; + for (int i = 0; i < n; i++) { + stats[i] = TypedParameter.create(params[i]); + } + return stats; + } } diff --git a/src/main/java/org/libvirt/event/LifecycleListener.java b/src/main/java/org/libvirt/event/LifecycleListener.java index d7e9806..469d4a2 100644 --- a/src/main/java/org/libvirt/event/LifecycleListener.java +++ b/src/main/java/org/libvirt/event/LifecycleListener.java @@ -5,7 +5,7 @@ /** * Interface for receiving events occurring on a domain. * - * @see + * @see virConnectDomainEventCallback */ public interface LifecycleListener extends EventListener { diff --git a/src/main/java/org/libvirt/jna/DomainCheckpointPointer.java b/src/main/java/org/libvirt/jna/DomainCheckpointPointer.java new file mode 100644 index 0000000..2716e80 --- /dev/null +++ b/src/main/java/org/libvirt/jna/DomainCheckpointPointer.java @@ -0,0 +1,18 @@ +package org.libvirt.jna; + +import com.sun.jna.Pointer; +import com.sun.jna.PointerType; + +/** + * Pointer class to provide type safety to the jna interface. + */ +public class DomainCheckpointPointer extends PointerType { + + public DomainCheckpointPointer() { + } + + public DomainCheckpointPointer(Pointer p) { + super(p); + } +} + diff --git a/src/main/java/org/libvirt/jna/Libvirt.java b/src/main/java/org/libvirt/jna/Libvirt.java index 8cd6448..af64bf7 100644 --- a/src/main/java/org/libvirt/jna/Libvirt.java +++ b/src/main/java/org/libvirt/jna/Libvirt.java @@ -18,13 +18,11 @@ /** * The libvirt interface which is exposed via JNA. The complete API is - * documented at https://libvirt.org/html/libvirt-libvirt.html. + * documented at https://libvirt.org/html/index.html . * * Known api calls to be missing * LIBVIRT_0.1.0 * virDefaultErrorFunc - * virConnCopyLastError - * virFreeError * * LIBVIRT_0_5.0 * virEventRegisterImpl @@ -312,6 +310,7 @@ int virGetVersion(LongByReference libVer, String type, LongByReference typeVer); int virInitialize(); int virCopyLastError(virError error); + int virResetError(virError error); virError virGetLastError(); void virResetLastError(); void virSetErrorFunc(Pointer userData, VirErrorCallback callback); @@ -325,8 +324,10 @@ int virGetVersion(LongByReference libVer, String type, int virDomainAttachDevice(DomainPointer virDomainPtr, String deviceXML); int virDomainAttachDeviceFlags(DomainPointer virDomainPtr, String deviceXML, int flags); + int virDomainBackupBegin(DomainPointer virDomainPtr, String backupXML, String checkpointXML, int flags); + CString virDomainBackupGetXMLDesc(DomainPointer virDomainPtr, int flags); int virDomainBlockCommit(DomainPointer virDomainPtr, String disk, - String base, String top, long bandwidth, int flags); + String base, String top, NativeLong bandwidth, int flags); int virDomainBlockCopy(DomainPointer virDomainPtr, String disk, String deviceXML, virTypedParameter[] params, int nparams, int flags); @@ -359,9 +360,11 @@ int virDomainGetBlockInfo(DomainPointer virDomainPtr, String path, int virDomainGetID(DomainPointer virDomainPtr); int virDomainGetInfo(DomainPointer virDomainPtr, virDomainInfo vInfo); int virDomainGetJobInfo(DomainPointer virDomainPtr, virDomainJobInfo vInfo); + int virDomainGetJobStats(DomainPointer virDomainPtr, IntByReference type, PointerByReference params, + IntByReference nparams, int flags); NativeLong virDomainGetMaxMemory(DomainPointer virDomainPtr); int virDomainGetMaxVcpus(DomainPointer virDomainPtr); - String virDomainGetMetadata(DomainPointer virDomainPtr, int type, String uri, int flags); + CString virDomainGetMetadata(DomainPointer virDomainPtr, int type, String uri, int flags); String virDomainGetName(DomainPointer virDomainPtr); CString virDomainGetOSType(DomainPointer virDomainPtr); int virDomainGetSchedulerParameters(DomainPointer virDomainPtr, @@ -378,6 +381,7 @@ int virDomainGetVcpus(DomainPointer virDomainPtr, virVcpuInfo[] info, CString virDomainGetXMLDesc(DomainPointer virDomainPtr, int flags); int virDomainHasCurrentSnapshot(DomainPointer virDomainPtr, int flags); int virDomainHasManagedSaveImage(DomainPointer virDomainPtr, int flags); + int virDomainInjectNMI(DomainPointer virDomainPtr, int flags); int virDomainInterfaceAddresses(DomainPointer virDomainPtr, PointerByReference ifaces, int source, int flags); int virDomainInterfaceFree(virDomainInterface.Ptr pointer); int virDomainInterfaceStats(DomainPointer virDomainPtr, String path, @@ -404,11 +408,23 @@ DomainPointer virDomainMigrate2(DomainPointer virDomainPtr, ConnectionPointer virConnectPtr, String dxml, NativeLong flags, String dname, String uri, NativeLong bandwidth); + /** + * @deprecated use {@link virDomainMigrate3(DomainPointer, + * ConnectionPointer, virTypedParameter[], int, int) + * virDomainMigrate3(DomainPointer, ConnectionPointer, + * virTypedParameter[], int, int)} instead. + */ + @Deprecated DomainPointer virDomainMigrate3(DomainPointer virDomainPtr, ConnectionPointer virConnectPtr, virTypedParameter[] params, int nparams, NativeLong flags); + DomainPointer virDomainMigrate3(DomainPointer virDomainPtr, + ConnectionPointer virConnectPtr, + virTypedParameter[] params, + int nparams, + int flags); int virDomainMigrateSetMaxDowntime(DomainPointer virDomainPtr, long downtime, int flags); int virDomainMigrateToURI(DomainPointer virDomainPtr, String duri, @@ -417,8 +433,14 @@ int virDomainMigrateToURI2(DomainPointer virDomainPtr, String dconnuri, String miguri, String dxml, NativeLong flags, String dname, NativeLong bandwidth); + int virDomainMigrateToURI3(DomainPointer virDomainPtr, + String dconnuri, + virTypedParameter[] params, int nparams, + int flags); int virDomainMemoryStats(DomainPointer virDomainPtr, virDomainMemoryStats[] stats, int nrStats, int flags); + int virDomainGetCPUStats(DomainPointer virDomainPtr, + virTypedParameter[] params, int nparams, int start_cpu, int ncpus, int flags); int virDomainPinVcpu(DomainPointer virDomainPtr, int vcpu, byte[] cpumap, int maplen); int virDomainPMSuspendForDuration(DomainPointer virDomainPtr, @@ -438,6 +460,8 @@ CString virDomainScreenshot(DomainPointer virDomainPtr, int virDomainSetAutostart(DomainPointer virDomainPtr, int autoStart); int virDomainSetMaxMemory(DomainPointer virDomainPtr, NativeLong maxMemory); int virDomainSetMemory(DomainPointer virDomainPtr, NativeLong maxMemory); + int virDomainSetMemoryFlags(DomainPointer virDomainPtr, NativeLong maxMemory, int flags); + int virDomainSetMemoryStatsPeriod(DomainPointer virDomainPtr, int period, int flags); int virDomainSetMetadata(DomainPointer domain, int type, String metadata, String key, String uri, int flags); int virDomainSetSchedulerParameters(DomainPointer virDomainPtr, @@ -616,6 +640,31 @@ int virStreamSendAll(StreamPointer virStreamPtr, int virStreamRecvAll(StreamPointer virStreamPtr, Libvirt.VirStreamSinkFunc handler, Pointer opaque); + //DomainCheckpoint Methods + String virDomainCheckpointGetName(DomainCheckpointPointer virDomainCheckpointPtr); + DomainPointer virDomainCheckpointGetDomain(DomainCheckpointPointer virDomainCheckpointPtr); + ConnectionPointer virDomainCheckpointGetConnect(DomainCheckpointPointer checkpoint); + DomainCheckpointPointer virDomainCheckpointCreateXML(DomainPointer virDomainPtr, + String xmlDesc, int flags); + CString virDomainCheckpointGetXMLDesc(DomainCheckpointPointer virDomainCheckpointPtr, + int flags); + int virDomainListAllCheckpoints(DomainPointer virDomainPtr, + PointerByReference virDomainCheckpointsPtr, + int flags); + int virDomainCheckpointListAllChildren(DomainCheckpointPointer virDomainCheckpointPtr, + PointerByReference virDomainCheckpointChildrenPtr, + int flags); + DomainCheckpointPointer virDomainCheckpointLookupByName(DomainPointer virDomainPtr, + String name, int flags); + DomainCheckpointPointer virDomainCheckpointGetParent(DomainCheckpointPointer virDomainCheckpointPtr, + int flags); + int virDomainCheckpointDelete(DomainCheckpointPointer virDomainCheckpointPtr, + int flags); + + int virDomainCheckpointRef(DomainCheckpointPointer checkpoint); + + int virDomainCheckpointFree(DomainCheckpointPointer virDomainCheckpointPtr); + //DomainSnapshot Methods DomainSnapshotPointer virDomainSnapshotCreateXML(DomainPointer virDomainPtr, String xmlDesc, int flags); @@ -656,4 +705,17 @@ int virEventAddTimeout(int milliSeconds, VirEventTimeoutCallback cb, int virDomainSetUserPassword(DomainPointer virDomainPtr, String user, String password, int flags); + + void virTypedParamsFree(Pointer params, int nparams); + + // Bulk domain stats (libvirt 1.2.8+) + int virConnectGetAllDomainStats(ConnectionPointer virConnectPtr, + int stats, + PointerByReference retStats, + int flags); + int virDomainListGetStats(DomainPointer[] doms, + int stats, + PointerByReference retStats, + int flags); + void virDomainStatsRecordListFree(Pointer statsList); } diff --git a/src/main/java/org/libvirt/jna/virDomainBlockJobInfo.java b/src/main/java/org/libvirt/jna/virDomainBlockJobInfo.java index b85671d..aa0dda0 100644 --- a/src/main/java/org/libvirt/jna/virDomainBlockJobInfo.java +++ b/src/main/java/org/libvirt/jna/virDomainBlockJobInfo.java @@ -1,5 +1,6 @@ package org.libvirt.jna; +import com.sun.jna.NativeLong; import com.sun.jna.Structure; import java.util.Arrays; @@ -7,7 +8,7 @@ public class virDomainBlockJobInfo extends Structure { public int type; - public long bandwidth; + public NativeLong bandwidth; public long cur; public long end; diff --git a/src/main/java/org/libvirt/jna/virDomainInfo.java b/src/main/java/org/libvirt/jna/virDomainInfo.java index ffb4e99..4e80c43 100644 --- a/src/main/java/org/libvirt/jna/virDomainInfo.java +++ b/src/main/java/org/libvirt/jna/virDomainInfo.java @@ -10,7 +10,7 @@ * JNA mapping for the virDomainInfo structure */ public class virDomainInfo extends Structure { - public int state; + public byte state; public NativeLong maxMem; public NativeLong memory; public short nrVirtCpu; diff --git a/src/main/java/org/libvirt/jna/virDomainStatsRecord.java b/src/main/java/org/libvirt/jna/virDomainStatsRecord.java new file mode 100644 index 0000000..912211c --- /dev/null +++ b/src/main/java/org/libvirt/jna/virDomainStatsRecord.java @@ -0,0 +1,35 @@ +package org.libvirt.jna; + +import com.sun.jna.Pointer; +import com.sun.jna.Structure; + +import java.util.Arrays; +import java.util.List; + +/** + * JNA mapping for the virDomainStatsRecord structure. + * + * Used with virConnectGetAllDomainStats and virDomainListGetStats. + */ +public class virDomainStatsRecord extends Structure { + public DomainPointer dom; + public Pointer params; + public int nparams; + + public virDomainStatsRecord() { + super(); + } + + public virDomainStatsRecord(Pointer p) { + super(p); + read(); + } + + private static final List FIELDS = Arrays.asList( + "dom", "params", "nparams"); + + @Override + protected List getFieldOrder() { + return FIELDS; + } +} diff --git a/src/main/java/org/libvirt/jna/virTypedParameter.java b/src/main/java/org/libvirt/jna/virTypedParameter.java index 992ffad..6a5fd78 100644 --- a/src/main/java/org/libvirt/jna/virTypedParameter.java +++ b/src/main/java/org/libvirt/jna/virTypedParameter.java @@ -1,5 +1,6 @@ package org.libvirt.jna; +import com.sun.jna.Pointer; import com.sun.jna.Structure; import java.util.Arrays; @@ -12,10 +13,34 @@ * virMemoryParameter since Libvirt 0.9.2. */ public class virTypedParameter extends Structure { + public static final int TYPED_PARAM_INT = 1; + public static final int TYPED_PARAM_UINT = 2; + public static final int TYPED_PARAM_LONG = 3; + public static final int TYPED_PARAM_ULONG = 4; + public static final int TYPED_PARAM_DOUBLE = 5; + public static final int TYPED_PARAM_BOOLEAN = 6; + public static final int TYPED_PARAM_STRING = 7; + public byte[] field = new byte[Libvirt.VIR_TYPED_PARAM_FIELD_LENGTH]; public int type; public virTypedParameterValue value; + public virTypedParameter(){ + super(); + } + + public virTypedParameter(Pointer p) { + super(p); + } + + @Override + public void read() { + super.read(); + if (type == TYPED_PARAM_STRING) { + value.readField("s"); + } + } + private static final List FIELDS = Arrays.asList( "field", "type", "value"); diff --git a/src/test/java/org/libvirt/TestJavaBindings.java b/src/test/java/org/libvirt/TestJavaBindings.java index 79173c4..fc35bd0 100644 --- a/src/test/java/org/libvirt/TestJavaBindings.java +++ b/src/test/java/org/libvirt/TestJavaBindings.java @@ -1,5 +1,6 @@ package org.libvirt; +import org.libvirt.Domain.CheckpointListFlags; import org.libvirt.event.*; import java.nio.ByteBuffer; @@ -8,6 +9,7 @@ import java.util.ArrayList; import java.util.Collection; import java.util.List; +import java.util.Map; import java.util.UUID; import java.util.regex.Pattern; @@ -61,7 +63,7 @@ public void testConnection() throws Exception { assertEquals("conn.getVersion()", 2, conn.getVersion()); assertTrue("conn.isAlive", conn.isAlive()); assertTrue("conn.isEncrypted", conn.isEncrypted() == 0); - assertTrue("conn.isSecure", conn.isSecure() == 1); + assertTrue("conn.isSecure", conn.isSecure() == 1); } /* @@ -83,6 +85,7 @@ public void testNodeInfo() throws Exception { assertEquals("nodeInfo.model", "i686", nodeInfo.model); assertEquals("nodeInfo.memory", 3145728, nodeInfo.memory); assertEquals("nodeInfo.cpus", 16, nodeInfo.cpus); + assertEquals("nodeInfo.mhz", 1400, nodeInfo.mhz); assertEquals("nodeInfo.nodes", 2, nodeInfo.nodes); assertEquals("nodeInfo.sockets", 2, nodeInfo.sockets); assertEquals("nodeInfo.cores", 2, nodeInfo.cores); @@ -110,8 +113,8 @@ public void testNetworkCreate() throws Exception { assertEquals("Number of defined networks", 1, conn.numOfDefinedNetworks()); assertEquals("Number of listed defined networks", 1, conn.listDefinedNetworks().length); assertTrue("Network1 should not be persistent", network1.isPersistent() == 0); - assertTrue("Network1 should not be active", network1.isActive() == 1); - assertTrue("Network2 should be active", network2.isActive() == 0); + assertTrue("Network1 should not be active", network1.isActive() == 1); + assertTrue("Network2 should be active", network2.isActive() == 0); this.validateNetworkData(network2); this.validateNetworkData(conn.networkLookupByName("deftest")); this.validateNetworkData(conn.networkLookupByUUID(UUIDArray)); @@ -149,7 +152,9 @@ public void testDomainCreate() throws Exception { Domain dom2 = conn.domainCreateLinux("" + " createst" + " 004b96e1-2d78-c30f-5aa5-f03c87d21e67" + " 8388608" + " 2" + " hvm" + " restart" - + " destroy" + " restart" + "", 0); + + " destroy" + " restart" + + " " + " " + " " + + "", 0); UUID dom2UUID = UUID.fromString("004b96e1-2d78-c30f-5aa5-f03c87d21e67"); assertEquals("Number of domains", 2, conn.numOfDomains()); @@ -157,8 +162,8 @@ public void testDomainCreate() throws Exception { assertEquals("Number of defined domains", 1, conn.numOfDefinedDomains()); assertEquals("Number of listed defined domains", 1, conn.listDefinedDomains().length); assertTrue("Domain1 should be persistent", dom1.isPersistent() == 1); - assertTrue("Domain1 should not be active", dom1.isActive() == 0); - assertTrue("Domain2 should be active", dom2.isActive() == 1); + assertTrue("Domain1 should not be active", dom1.isActive() == 0); + assertTrue("Domain2 should be active", dom2.isActive() == 1); this.validateDomainData(dom2); this.validateDomainData(conn.domainLookupByName("createst")); this.validateDomainData(conn.domainLookupByUUID(UUIDArray)); @@ -187,15 +192,78 @@ private void validateDomainData(Domain dom) throws Exception { System.out.println(c.getTypeAsString() + ":" + c.field + ":" + c.getValueAsString()); } - dom.getSchedulerParameters() ; - + dom.getSchedulerParameters(); + SchedUintParameter[] pars = new SchedUintParameter[1]; pars[0] = new SchedUintParameter(); pars[0].field = "weight"; pars[0].value = 100; dom.setSchedulerParameters(pars); - - dom.getSchedulerParameters() ; + + dom.getSchedulerParameters(); + + TypedParameter[] cpuStats = dom.getCPUStats(-1, 1); + assertEquals(3, cpuStats.length); + assertEquals("cpu_time", cpuStats[0].field); + assertEquals("48772617035", cpuStats[0].getValueAsString()); + assertEquals("user_time", cpuStats[1].field); + assertEquals("5540000000", cpuStats[1].getValueAsString()); + assertEquals("system_time", cpuStats[2].field); + assertEquals("6460000000", cpuStats[2].getValueAsString()); + + TypedParameter[] perCpuStats0 = dom.getCPUStats(0, 1); + assertEquals(2, perCpuStats0.length); + assertEquals("cpu_time", perCpuStats0[0].field); + assertEquals("24386308517", perCpuStats0[0].getValueAsString()); + assertEquals("vcpu_time", perCpuStats0[1].field); + assertEquals("23151740627", perCpuStats0[1].getValueAsString()); + + TypedParameter[] perCpuStats1 = dom.getCPUStats(1, 1); + assertEquals(2, perCpuStats1.length); + assertEquals("cpu_time", perCpuStats1[0].field); + assertEquals("24386308518", perCpuStats1[0].getValueAsString()); + assertEquals("vcpu_time", perCpuStats1[1].field); + assertEquals("23151740628", perCpuStats1[1].getValueAsString()); + + TypedParameter[] perCpuStats = dom.getCPUStats(0, 2); + assertEquals(4, perCpuStats.length); + assertEquals("cpu_time", perCpuStats[0].field); + assertEquals("24386308517", perCpuStats[0].getValueAsString()); + assertEquals("vcpu_time", perCpuStats[1].field); + assertEquals("23151740627", perCpuStats[1].getValueAsString()); + assertEquals("cpu_time", perCpuStats[2].field); + assertEquals("24386308518", perCpuStats[2].getValueAsString()); + assertEquals("vcpu_time", perCpuStats[3].field); + assertEquals("23151740628", perCpuStats[3].getValueAsString()); + + MemoryStatistic[] memStats = dom.memoryStats(15); + assertEquals(13, memStats.length); + assertEquals(6, memStats[0].getTag()); + assertEquals(8388608, memStats[0].getValue()); + assertEquals(0, memStats[1].getTag()); + assertEquals(0, memStats[1].getValue()); + assertEquals(1, memStats[2].getTag()); + assertEquals(0, memStats[2].getValue()); + assertEquals(2, memStats[3].getTag()); + assertEquals(0, memStats[3].getValue()); + assertEquals(3, memStats[4].getTag()); + assertEquals(0, memStats[4].getValue()); + assertEquals(4, memStats[5].getTag()); + assertEquals(8388608 / 2, memStats[5].getValue()); + assertEquals(5, memStats[6].getTag()); + assertEquals(8388608, memStats[6].getValue()); + assertEquals(8, memStats[7].getTag()); + assertEquals(8388608 / 2, memStats[7].getValue()); + assertEquals(9, memStats[8].getTag()); + assertEquals(627319920, memStats[8].getValue()); + assertEquals(10, memStats[9].getTag()); + assertEquals(8388608 / 8, memStats[9].getValue()); + assertEquals(11, memStats[10].getTag()); + assertEquals(0, memStats[10].getValue()); + assertEquals(12, memStats[11].getTag()); + assertEquals(0, memStats[11].getValue()); + assertEquals(7, memStats[12].getTag()); + assertEquals(8388608 / 2, memStats[12].getValue()); } public void testInterfaces() throws Exception { @@ -207,7 +275,7 @@ public void testInterfaces() throws Exception { assertEquals("virtInterfaceGetName", "eth1", virtInt.getName()); assertEquals("virtInterfaceGetMACString", "aa:bb:cc:dd:ee:ff", virtInt.getMACString()); assertNotNull("virtInterfaceGetXMLDesc", virtInt.getXMLDescription(0)); - assertTrue("virInterfaceIsActive", virtInt.isActive() == 1); + assertTrue("virInterfaceIsActive", virtInt.isActive() == 1); System.out.println(virtInt.getXMLDescription(0)); String newXML = "" + "" @@ -234,7 +302,7 @@ public void testAccessAfterClose() throws Exception { } assertNotNull(virException); } - + public void testStoragePool() throws Exception { StoragePool pool1 = conn.storagePoolDefineXML("" + " pool1" @@ -245,14 +313,14 @@ public void testStoragePool() throws Exception { + "", 0) ; StoragePool defaultPool = conn.storagePoolLookupByName("default-pool"); assertEquals("numOfStoragePools:", 1, conn.numOfStoragePools()); - assertEquals("numOfDefinedStoragePools:", 1, conn.numOfDefinedStoragePools()); + assertEquals("numOfDefinedStoragePools:", 1, conn.numOfDefinedStoragePools()); assertNotNull("The pool should not be null", pool1); - assertNotNull("The default pool should not be null", defaultPool); + assertNotNull("The default pool should not be null", defaultPool); assertEquals("The names should match", defaultPool.getName(), "default-pool"); - assertEquals("The uids should match", pool1.getUUIDString(), "004c96e1-2d78-c30f-5aa5-f03c87d21e67"); + assertEquals("The uids should match", pool1.getUUIDString(), "004c96e1-2d78-c30f-5aa5-f03c87d21e67"); assertTrue("pool1 should be persistent", pool1.isPersistent() == 1); - assertTrue("pool1 should not be active", pool1.isActive() == 0); - assertTrue("Domain2 should be active", defaultPool.isActive() == 1); + assertTrue("pool1 should not be active", pool1.isActive() == 0); + assertTrue("Domain2 should be active", defaultPool.isActive() == 1); } public void testDomainEvents() throws Exception { @@ -401,4 +469,310 @@ public void testDomainInterfaceAddresses() throws LibvirtException { dom.undefine(); } } + + /** + * Helper function to create test domains + * @param domainName - Domain name + * @return Domain created + * @throws LibvirtException + */ + private Domain createDomainToCheckpointTest(String domainName) throws LibvirtException{ + String domainXML = "\n" + + " " + domainName + "\n" + + " 512\n" + + " 1\n" + + " \n" + + " hvm\n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + ""; + + Domain domain = conn.domainDefineXML(domainXML); + return domain; + } + + /** + * Check if throw an error when try to create a checkpoint in a inactive domain + * @throws LibvirtException + */ + public void testDomainCheckpointCreateThrowError() throws LibvirtException { + Domain domain = createDomainToCheckpointTest("test-vm-checkpoint-create-throw-error"); + String domainCheckpointXML = "\n" + + "\n" + + " test-checkpoint-create-1\n" + + " \n" + + " \n" + + " \n" + + " \n" + + "\n"; + LibvirtException virException = null; + try { + domain.checkpointCreateXML(domainCheckpointXML, 0); + fail("Exception should be raised because the checkpoint can not perform in a stopped domain"); + } catch(LibvirtException e) { + virException = e; + } + assertNotNull(virException); + } + + /** + * Check methods to create and destroy checkpoints of a domain + * @throws LibvirtException + */ + public void testDomainCheckpointCreateAndDestroy() throws LibvirtException { + Domain domain = createDomainToCheckpointTest("test-vm-checkpoint-create"); + domain.create(); + assertEquals("The virtual machine should not have checkpoints", 0, domain.listAllCheckpoints(0).length); + String domainCheckpointXML = "\n" + + "\n" + + " test-checkpoint-create-1\n" + + " \n" + + " \n" + + " \n" + + " \n" + + "\n"; + DomainCheckpoint domainCheckpoint1 = domain.checkpointCreateXML(domainCheckpointXML, 0); + + assertEquals("The checkpoint was not created", 1, domain.listAllCheckpoints(0).length); + domainCheckpointXML = "\n" + + "\n" + + " test-checkpoint-create-2\n" + + " \n" + + " \n" + + " \n" + + " \n" + + "\n"; + DomainCheckpoint domainCheckpoint2 = domain.checkpointCreateXML(domainCheckpointXML, 0); + assertEquals("The second checkpoint was not created", 2, domain.listAllCheckpoints(0).length); + domainCheckpoint2.delete(DomainCheckpoint.CheckpointDeleteFlags.CHILDREN); + assertEquals("The checkpoint 2 was not deleted", 1, domain.listAllCheckpoints(0).length); + domainCheckpoint1.delete(DomainCheckpoint.CheckpointDeleteFlags.CHILDREN); + assertEquals("The checkpoint 1 was not deleted", 0, domain.listAllCheckpoints(0).length); + } + + /** + * Check methods inside DomainCheckpoint class, like getName, getXMLDesc,... + * @throws LibvirtException + */ + public void testDomainCheckpointMethods() throws LibvirtException { + Domain domain = createDomainToCheckpointTest("test-vm-checkpoint-methods"); + domain.create(); + String domainCheckpointXML = "\n" + + "\n" + + " test-checkpoint-methods-1\n" + + " \n" + + " \n" + + " \n" + + " \n" + + "\n"; + DomainCheckpoint domainCheckpoint = domain.checkpointCreateXML(domainCheckpointXML, 0); + assertEquals("The names should match", "test-checkpoint-methods-1", domainCheckpoint.getName()); + + + String domainCheckpointXMLDesc = domainCheckpoint.getXMLDesc(0); + assertTrue("The XML should contain the tag ", domainCheckpointXMLDesc.contains("")); + assertTrue("The XML should contain the name of checkpoint", domainCheckpointXMLDesc.contains("test-checkpoint-methods-1")); + assertTrue("The XML should contain one of disks to perform the checkpoint", domainCheckpointXMLDesc.contains("vda")); + } + + /** + * Check methods with hierarchy, like listAllChildren, getParent, etc. + * @throws LibvirtException + */ + public void testDomainCheckpointHierarchy() throws LibvirtException { + int NUM_CHECKPOINTS = 10; // Should be bigger than 2 + Domain domain = createDomainToCheckpointTest("test-vm-checkpoint-testDomainCheckpointHierarchy"); + domain.create(); + DomainCheckpoint[] testCheckpoints = new DomainCheckpoint[NUM_CHECKPOINTS]; + String baseCheckpointName = "test-checkpoint-"; + for(int i = 0; i < NUM_CHECKPOINTS; i++) { + String domainCheckpointXML = "\n" + + " " + baseCheckpointName + i + " \n"; // We avoid disks subelement to write less code + testCheckpoints[i] = domain.checkpointCreateXML(domainCheckpointXML, 0); + } + + // Test the lookup function + DomainCheckpoint checkpointLookedup = domain.checkpointLookupByName("test-checkpoint-1"); + // Check if the parent is "test-checkpoint-0" + assertEquals(testCheckpoints[0].getName(), checkpointLookedup.getParent(0).getName()); + + + DomainCheckpoint checkpointNotCreated = domain.checkpointLookupByName("not-created-checkpoint"); + assertNull(checkpointNotCreated); + + // Get all checkpoints in topological order + DomainCheckpoint[] domainCheckpoints = domain.listAllCheckpoints(CheckpointListFlags.TOPOLOGICAL); + assertEquals("One checkpoint was not created", NUM_CHECKPOINTS, domainCheckpoints.length); + // The checkpoints order should be the same. + for (int i = 0; i < NUM_CHECKPOINTS; i++) { + assertEquals("The created checkpoints order should be the same - " + i, testCheckpoints[i].getName(), domainCheckpoints[i].getName()); + } + assertNull(testCheckpoints[0].getParent(0)); + for (int i = 1; i < NUM_CHECKPOINTS; i++) { + assertEquals(domainCheckpoints[i-1].getName(), domainCheckpoints[i].getParent(0).getName()); + } + + // Check checkpointListNames function + String[] checkpointNames = domain.checkpointListNames(CheckpointListFlags.TOPOLOGICAL); + assertEquals("One checkpoint was not created", NUM_CHECKPOINTS, checkpointNames.length); + // The checkpoints order should be the same. + for (int i = 0; i < NUM_CHECKPOINTS; i++) { + assertEquals("The created checkpoints order should be the same - " + i, testCheckpoints[i].getName(), checkpointNames[i]); + } + + // Check listAllChildren function + DomainCheckpoint[] childrenFromFirst = domainCheckpoints[0].listAllChildren(CheckpointListFlags.DESCENDANTS); + assertEquals("One checkpoint was not created", NUM_CHECKPOINTS - 1, childrenFromFirst.length); + for(int i = 1; i < NUM_CHECKPOINTS; i++) { + assertEquals(childrenFromFirst[i-1].getName(), domainCheckpoints[i].getName()); + } + } + + public void testDomainBackupBegin() throws LibvirtException { + /** + * The driver test:///default is not compatible with virBackupBegin function. + * Discomment the test and put your own values and run. + */ + // String connectionURI = "qemu+ssh://root@fgar-libvirt/system"; + // String domainName = "deb12-1"; + // String checkpointName = "test-backup-begin-checkpoint"; + + /** + * In this test: + * - uses your local connection to search the domain. + * - Init backup of given domain. + * - Check if created correctly. + * - Delete the created checkpoint previously. + */ + + // Connect connToThisTest = new Connect(connectionURI, false); + + + // Domain domain = connToThisTest.domainLookupByName(domainName); + // assertEquals("The test domain should not have any domain checkpoint", 0, domain.listAllCheckpoints(0).length); + + // String backupXML = "\n" + // + // " \n" + // + // " \n" + // + // " \n" + // + // " \n" + // + // " \n" + // + // " \n" + // + // " \n" + // + // " \n" + // + // " \n" + // + // ""; + + + // String checkpointXML = "\n" + + // " " + checkpointName + "\n" + + // " \n" + + // " \n" + + // " \n" + + // " \n" + + // "\n"; + // domain.backupBegin(backupXML, checkpointXML, 0); + // DomainCheckpoint domainCheckpoint = domain.checkpointLookupByName(checkpointName); + // assertEquals(checkpointName, domainCheckpoint.getName()); + // try { + // Thread.sleep(2000); + // } catch (InterruptedException e) { + // e.printStackTrace(); + // } + // Map jobStats = domain.getJobStats(0); + // assertTrue("The jobStats should have the key 'operation'", jobStats.containsKey("operation")); + // assertEquals("The job type should be backup", Domain.JobOperation.BACKUP +"", jobStats.get("operation").getValueAsString()); + // domain.abortJob(); + // domainCheckpoint.delete(DomainCheckpoint.CheckpointDeleteFlags.CHILDREN); + // assertEquals("The checkpoint should be removed", 0, domain.listAllCheckpoints(0).length); + } + + public void testGetAllDomainStats() throws LibvirtException { + DomainStatsRecord[] records = conn.getAllDomainStats(DomainStats.STATE, 0); + try { + assertTrue("test:///default should expose at least one domain", + records.length >= 1); + + boolean foundState = false; + for (DomainStatsRecord rec : records) { + assertNotNull("record.domain must not be null", rec.domain); + assertNotNull("record.params must not be null", rec.params); + // The bulk-stats domain handle must outlive + // virDomainStatsRecordListFree -- i.e. calling APIs on it + // here must not blow up. + assertNotNull("domain name should be reachable after free", + rec.domain.getName()); + assertNotNull("domain UUID should be reachable after free", + rec.domain.getUUIDString()); + for (TypedParameter p : rec.params) { + if ("state.state".equals(p.field)) { + foundState = true; + assertTrue("state.state should be an int parameter", + p instanceof TypedIntParameter); + } + } + } + assertTrue("At least one record should carry 'state.state'", + foundState); + } finally { + for (DomainStatsRecord rec : records) { + rec.domain.free(); + } + } + } + + public void testGetAllDomainStatsActiveOnly() throws LibvirtException { + DomainStatsRecord[] records = conn.getAllDomainStats( + DomainStats.STATE, + ConnectGetAllDomainStatsFlags.ACTIVE); + try { + for (DomainStatsRecord rec : records) { + assertEquals("Only active domains should be returned", + 1, rec.domain.isActive()); + } + } finally { + for (DomainStatsRecord rec : records) { + rec.domain.free(); + } + } + } + + public void testGetDomainListStats() throws LibvirtException { + Domain[] all = conn.listAllDomains(0); + try { + assertTrue("test:///default should expose at least one domain", + all.length >= 1); + + DomainStatsRecord[] records = + conn.getDomainListStats(all, DomainStats.STATE, 0); + try { + assertEquals("Record count should match domain count", + all.length, records.length); + for (DomainStatsRecord rec : records) { + assertNotNull(rec.domain.getUUIDString()); + } + } finally { + for (DomainStatsRecord rec : records) { + rec.domain.free(); + } + } + } finally { + for (Domain d : all) { + d.free(); + } + } + } }