Compare commits

...

87 Commits

Author SHA1 Message Date
Thomas Lamprecht
b80838a2fc bump version to 5.4-15
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2020-05-12 17:42:57 +02:00
Thomas Lamprecht
6763226345 followup log messages nits
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2020-05-12 17:40:20 +02:00
Thomas Lamprecht
797ba64009 pve5to6: refactor out apt-cache package installed checks
for potential reuse in the future and makes the real check easier to
read

Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2020-05-12 15:43:18 +02:00
Dominik Csapak
a08419739e pve5to6: add check for ovmf vms with potentially broken efi disk
we wrongly mapped some efidisks into the vm, and fixed it in pve6
this potentially needs manual intervention, so warn the user about
which vms might be affected

Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
2020-05-12 14:18:34 +02:00
Dominik Csapak
aa517822d6 pve5to6: add check for stock debian kernel package
on current debian buster, stock kernel images recommend
firmware-linux-free which conflict with our pve-firmware package
which leads to apt wanting to remove promxox-ve

check for the meta package in the update check script

Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
2020-05-12 14:18:34 +02:00
Dominik Csapak
74f2df2f5f ui: fix missing htmlEncodes
username can include some special characters, so we have
to escape them

backport from pve6

Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
2020-05-12 14:18:34 +02:00
Thomas Lamprecht
e5bdba1d9c bump version to 5.4-14
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2020-04-21 18:20:02 +02:00
Thomas Lamprecht
22e1b9473f use https links to our sites
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
(cherry picked from commit 2dc23b7e2ea493a4f79f7cdca7c7b635eb8c50e0)
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2020-04-21 18:13:56 +02:00
Thomas Lamprecht
ff4200481c add PVE 5.4 End-of-Life notice
since pve 5.4 goes out of support in July, add a notice at the top with
a link to the faq, where the EOL dates are and also the upgrade
process is described and linked in short.

Originally-by: Dominik Csapak <d.csapak@proxmox.com>
(cherry picked from commit cc9b37b8113dd3770e56d68955df714b81814c65)
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2020-04-21 12:49:42 +02:00
Thomas Lamprecht
4a326edd52 bump version to 5.4-13
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2019-07-26 10:15:08 +02:00
Thomas Lamprecht
bbd6506b7a fixup building pvecfg, ensure that the package release is available
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2019-07-26 10:14:38 +02:00
Thomas Lamprecht
8c030a5df4 bump version to 5.4-12
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2019-07-25 10:11:55 +02:00
Thomas Lamprecht
0ac0c01b14 buildsys: use dpkg-dev makefile helpers for pkg info
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
(cherry picked from commit bcef9bde68a920a4d204beb8ec1d5f334f7fbb78)
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2019-07-25 10:11:55 +02:00
Thomas Lamprecht
9462dbb422 remove unused ext-pve.css
not used since commit 5783c7f4ddbeeddb7038f40c94908b0f3a6b5fa7 from
2016...

Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
(cherry picked from commit 194745b924d8fbda70a3bccdd9724defb7a2633d)
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2019-07-25 09:30:07 +02:00
Thomas Lamprecht
12511b123d 5to6: cleanup cert check and make more general
If we need to add other types or increases the min size this makes it
easier as it's just a schematic definition.

Also just do a pass/fail on each cert, so drop the last "summary
pass".

Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
(cherry picked from commit 6c7e4ab4e24592a8dfa5dac3f5047064e17254f2)
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2019-07-25 09:29:56 +02:00
Alwin Antreich
70effe2709 pve5to6: cert: check certificates key size
Debian Buster raised the default security level (1 -> 2) for TLS
connections.

This moves from the 80 bit security level to the 112 bit security level
and will require 2048 bit or larger RSA and DHE keys, 224 bit or larger
ECC keys, and SHA-2.

Signed-off-by: Alwin Antreich <a.antreich@proxmox.com>
(cherry picked from commit 501f8505210553093243db6d279f936498e76124)
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2019-07-25 09:29:52 +02:00
Alwin Antreich
c6966f357b pvenode: add public key size & type to cert info
Signed-off-by: Alwin Antreich <a.antreich@proxmox.com>
(cherry picked from commit ee3fd393c4721b6c68d7adb47bb498976235d82f)
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2019-07-25 09:29:48 +02:00
Alwin Antreich
3103cd9a41 gui: cert: add public key type & size to certs view
by default the fields are hidden

Signed-off-by: Alwin Antreich <a.antreich@proxmox.com>
(cherry picked from commit 1007cf29d984d74bd7893bc3a4e6fe2b26f50e4e)
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2019-07-25 09:29:43 +02:00
Thomas Lamprecht
70b8b9f55d bump version to 5.4-11
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2019-07-09 09:55:31 +02:00
Dominik Csapak
6c6a16a1ab gui: show 0 for max_relocate/restart correctly
0 || '1' will always return '1'

Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
(cherry picked from commit 92b89add8d09efc864fbd03fc9aab6a1d63c5736)
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2019-07-08 19:22:52 +02:00
Dominik Csapak
ec4cd7ce25 fix #2267: delete address(6) and netmas(6) with cidr(6)
otherwise a user cannot delete an ip from an interface

Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
(cherry picked from commit b350268a1b59ed6513d5ad7b05bee3f55ca5afab)
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2019-07-08 19:20:39 +02:00
Fabian Grünbichler
e0505600dd 5to6: make corosync totem checks more verbose
to avoid just printing the subheader with no results

Signed-off-by: Fabian Grünbichler <f.gruenbichler@proxmox.com>
(cherry picked from commit c4bc94bb7b019e3c5a4518eda55883bb989146c5)
2019-07-08 18:27:23 +02:00
Fabian Grünbichler
77f8b8414f 5to6: add more corosync subheaders
to improve readability

Signed-off-by: Fabian Grünbichler <f.gruenbichler@proxmox.com>
(cherry picked from commit 5684da54dc15fb2a5bb26fdef95db67cea836a21)
2019-07-08 18:27:23 +02:00
Fabian Grünbichler
a6524bbec2 5to6: fail if a corosync node has neither ring0 nor ring1 defined
Signed-off-by: Fabian Grünbichler <f.gruenbichler@proxmox.com>
(cherry picked from commit e6b956df7bb1522e0cf47e2afb3dbb609a88b750)
2019-07-08 18:27:23 +02:00
Fabian Grünbichler
b3a6a2aebe 5to6: reword/-structure corosync message
and fix a typo as well

Signed-off-by: Fabian Grünbichler <f.gruenbichler@proxmox.com>
(cherry picked from commit 388a505104eae0d8c6389b247aba7eca713b03ba)
2019-07-08 18:27:23 +02:00
Fabian Grünbichler
b78378f3cc 5to6: attempt to resolve corosync rings
and only fail if unable to

Signed-off-by: Fabian Grünbichler <f.gruenbichler@proxmox.com>

(backported from commit 669211d8bbb0857275669068fcbf62560782b888)

use local copy of resolve_hostname_like_corosync instead of
pve-cluster's.

Signed-off-by: Fabian Grünbichler <f.gruenbichler@proxmox.com>
2019-07-08 18:27:23 +02:00
Fabian Grünbichler
e9ad9ab43f 5to6: add Corosync resolve helper
copied from PVE 6.x's pve-cluster.

since Corosync 2.x has a different default value for ip_version, we
don't want to backport this for general usage in PVE::Corosync. the
check here needs the default of Corosync 3.x, since that is what we
upgrade to.

Signed-off-by: Fabian Grünbichler <f.gruenbichler@proxmox.com>
2019-07-08 18:27:23 +02:00
Thomas Lamprecht
a8b2fd71bd bump version to 5.4-10
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2019-07-04 15:35:49 +02:00
Thomas Lamprecht
64ef936327 5to6: only tell to solve problems if fails are present
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
(cherry picked from commit be1072fb3bee0c15fbe67637289ab39adf64b6d7)
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2019-07-04 15:32:44 +02:00
Thomas Lamprecht
e35e351f12 5to6: improve final note on errors and/or warning a bit
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
(cherry picked from commit a14a5aaf678d9f5ba6235616b091684a9042cf4a)
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2019-07-04 15:31:08 +02:00
Thomas Lamprecht
0e25ab8057 5to6: fiy typo: s/detailled/detailed/
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
(cherry picked from commit 71f6edacdf6f5694f10a196626b950c66665d121)
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2019-07-04 15:23:42 +02:00
Thomas Lamprecht
e5196e8489 5to6: check common services pveproxy pvedaemon pvestatd
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
(cherry picked from commit 0192b0a2c2d5e2debb8e0a3e9279e73399e288ec)
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2019-07-04 15:22:13 +02:00
Thomas Lamprecht
57d9636122 5to6: add log_systemd_unit_state and use for pve-cluster and corosync
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
(cherry picked from commit fa1c414e265c1fe47673c069a114cbc9199d8347)
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2019-07-04 15:22:13 +02:00
Thomas Lamprecht
b60916cc2c 5to6: import run_command
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
(cherry picked from commit a82c200a9e11033f0f696a0af6bb5e6d522ca883)
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2019-07-04 15:22:13 +02:00
Thomas Lamprecht
084625c29f 5to6: clarify "cluster quorate" message a bit
As this is the state from the pmxcfs

Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
(cherry picked from commit 88d757d0c02fe62f57432a133e222a0fbd057e4e)
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2019-07-04 15:22:13 +02:00
Thomas Lamprecht
a6fc492a8b 5to6: fixup: really set $total_votes to 0 if not defined
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
(cherry picked from commit 176116b22ffae4993f5b3e25977ea08c6aca4dc9)
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2019-07-04 15:22:13 +02:00
Fabian Grünbichler
02e79accf9 5to6: drop detailed quorumtool output
since we already print most of that anyway, and it is rather long.

Signed-off-by: Fabian Grünbichler <f.gruenbichler@proxmox.com>
(cherry picked from commit 3456f2fc9d3094af3a0c7bdbe7a55abfd16ff380)
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2019-07-04 15:22:13 +02:00
Fabian Grünbichler
fbcc77375f 5to6: more quorum / vote checking
handle expected votes set to non-standard value, and try to adjust
calculations for qdevice setups.

Signed-off-by: Fabian Grünbichler <f.gruenbichler@proxmox.com>
(cherry picked from commit f6c6aa2b046b6b580855bab633a7ff1f94e3028a)
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2019-07-04 15:22:13 +02:00
Fabian Grünbichler
7a6994bc37 5to6: quote some Ceph flags/options
to improve readability

Signed-off-by: Fabian Grünbichler <f.gruenbichler@proxmox.com>
(cherry picked from commit 8ac5d4a50064f8d4c0e3abd6023fd2dee46331d3)
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2019-07-04 11:40:28 +02:00
Fabian Grünbichler
a500f71b44 5to6: check for ceph global keyring config
which causes issues after upgrading to Nautilus.

Signed-off-by: Fabian Grünbichler <f.gruenbichler@proxmox.com>
(cherry picked from commit 974a1b58548eb6f63541b311166c81a46fb4dc35)
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2019-07-04 11:40:28 +02:00
Thomas Lamprecht
6cc9ab6128 5to6: followup: also detect ceph conf keys separated with -
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
(cherry picked from commit 09250673d60b34febd220944c2a904758cf91618)
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2019-07-04 11:27:54 +02:00
Thomas Lamprecht
90ec2ddb9e 5to6: ceph mon host check: switch config check from defined to hash values exist
we can get here if a empty (or one with just comments) ceph.conf
exists

Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
(cherry picked from commit 153d6912879b0053af54a9218e10aa57ed43fc96)
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2019-07-04 11:27:54 +02:00
Thomas Lamprecht
8ade3b35fa 5to6: ceph global mon host check: also detect mon-host
and adapt message a bit

Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
(cherry picked from commit f696b0c355d0e9400da7f10530a957ede2b4e433)
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2019-07-04 11:27:54 +02:00
Dominik Csapak
c0d772c434 pve5to6: check ipv6/ipv4 settings in ceph.conf
having ipv6 enabled while not disabling ipv4 prevents
nautilus osds to start if no ipv4 network is given (because they
are trying to bind to both ip families and die if one of them
is not found)

Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
(cherry picked from commit 9e98f1fecf1c09811239b2c6183107a00b149de0)
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2019-07-04 11:27:54 +02:00
Dominik Csapak
42bbe3edd1 pve5to6: check ceph config for mon_host line
this already works on luminous, so it does not harm to add it already,
and is recommended when both msgr1 and msgr2 is activated in nautilus

Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
(cherry picked from commit 4731f493c3484d5ea95dee7978678779189ef779)
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2019-07-04 11:27:54 +02:00
Fabian Grünbichler
a75241fb90 5to6: invert check for noout for nautilus
mainly because it looks strange to get a warning after the upgrade is
finished and noout has been removed again

Signed-off-by: Fabian Grünbichler <f.gruenbichler@proxmox.com>
(cherry picked from commit 600a106ba0c47150c29f87561d480d4b89085d41)
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2019-07-04 09:41:30 +02:00
Thomas Lamprecht
33866e3cdc 5to6: followup: still include nodename in IP check
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
(cherry picked from commit eb7dae8bba7f57abdf16d3843ce6716786d04bf8)
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2019-07-04 09:41:30 +02:00
Fabian Grünbichler
f94e33c0e1 5to6: reuse $nodename
Signed-off-by: Fabian Grünbichler <f.gruenbichler@proxmox.com>
(cherry picked from commit 473a71d246492941b17d003decc8d2c1e7d5b01a)
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2019-07-04 09:41:30 +02:00
Fabian Grünbichler
329cf22a70 5to6: improve some log messages
Signed-off-by: Fabian Grünbichler <f.gruenbichler@proxmox.com>
(cherry picked from commit 1760de9011fdfbc3f734c3039125d46176586545)
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2019-07-04 09:41:30 +02:00
Thomas Lamprecht
92c64229a9 5to6: followup sheepdog message
do not suggest that we ever supported it as first class storage, it
was always just a experimental support and upstream is
EOL/unmaintained now.

Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
(cherry picked from commit 95c3dc246008b64cdc66e77f08a4862f531e7f0a)
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2019-07-04 09:41:30 +02:00
Fabian Grünbichler
cd77216038 5to6: add check for configured Sheepdog storages
Signed-off-by: Fabian Grünbichler <f.gruenbichler@proxmox.com>
(cherry picked from commit 1f16530be97b27c0674d6e1d7b842844a5d20043)
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2019-07-04 09:41:30 +02:00
Thomas Lamprecht
dc7eea012c 5to6: improve ceph warning on non OK state
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2019-07-03 13:14:05 +02:00
Thomas Lamprecht
22ad5ba62e pve5to6: be a bit more verbose for misc. checks
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
(cherry picked from commit 5a7a3630d770604a0d187190a6e9e6046048eb65)
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2019-07-02 12:10:48 +02:00
Thomas Lamprecht
450957c08a pve5to6: followup: improve coding style and outputs a bit
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
(cherry picked from commit 6e41184b1a7af21523380c7cb5080462d89bbcf4)
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2019-07-02 12:10:48 +02:00
Dominik Csapak
eb7fda9966 pve5to6: list vms with active vmx/svm flag
list all vms with either max/host cputype or vmx/svm explicitely set
(this can only happen in the args)

give a general message if none is found at the moment (and do not warn)

Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
(cherry picked from commit e739e0ba6724d41f2a912796b68833ebdc8baadd)
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2019-07-02 12:10:48 +02:00
Thomas Lamprecht
663ae4d86b 5to6: get_pkg: cache version list
this is a short running script, so the version list can be re-used,
the chance that there where updates in between are slim and racy
anyway. IF getting the versions did not succeeded, we still retry on
every call though, simpler and ensures a warning is printed in the
caller check vicinity.

Makes script noticeable faster.

Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2019-06-28 08:46:00 +02:00
Thomas Lamprecht
86a3955d78 5to6: followup kernel version checks, make compatible with PVE 5
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2019-06-28 08:35:45 +02:00
Fabian Grünbichler
5d2ae29215 5to6: add check for scanned simple OSDs
only as a warning, since this will also trigger a Ceph health warning
and is easily recoverable.

Signed-off-by: Fabian Grünbichler <f.gruenbichler@proxmox.com>
2019-06-28 08:35:45 +02:00
Fabian Grünbichler
7f4b3ea551 5to6: add check for running kernel version
Signed-off-by: Fabian Grünbichler <f.gruenbichler@proxmox.com>
2019-06-28 08:35:45 +02:00
Thomas Lamprecht
eba7c6f165 bump version to 5.4-9
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2019-06-27 20:29:40 +02:00
Thomas Lamprecht
ebd4de69d4 pve5to6: improve is-node-IP active check
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2019-06-27 19:48:36 +02:00
Thomas Lamprecht
f814c077d8 pve5to6: add total count in summary
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2019-06-27 19:48:36 +02:00
Thomas Lamprecht
52d469afde pve5to6: align summary counters
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2019-06-27 19:48:36 +02:00
Thomas Lamprecht
3f5db7faac pve5to6: list packages with updates in new line
with two spaces indentation, like apt does

Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2019-06-27 19:48:36 +02:00
Thomas Lamprecht
6afec5dab9 pve5to6: versions: detect if already upgraded
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2019-06-27 19:48:36 +02:00
Thomas Lamprecht
f3d40afa75 pve5to6: add and use print_header
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2019-06-27 19:48:36 +02:00
Thomas Lamprecht
89abf04dfe pve5to6: make this a simple CLI command
with this it's enough to call `pve5to6`, no (sub)command needed

Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2019-06-27 19:48:36 +02:00
Mira Limbeck
b0a8f08b82 move check_kvm_nested call to check_misc
Signed-off-by: Mira Limbeck <m.limbeck@proxmox.com>
2019-06-27 19:48:36 +02:00
Mira Limbeck
9c2f3b7394 pve5to6: add IP check to misc
Adds the same check we run in pve-cluster before joining a node to make
sure the hostname resolves to a configured IP.

Signed-off-by: Mira Limbeck <m.limbeck@proxmox.com>
2019-06-27 19:48:36 +02:00
Dominik Csapak
7bf30805db pve5to6: add check for nested kvm
this warns the user that he cannot live migrate VMs with svm/vmx to PVE6 when
the nested parameter of the kvm module is on

Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
2019-06-26 18:30:10 +02:00
Fabian Grünbichler
23bba5a415 5to6 add color support
Signed-off-by: Fabian Grünbichler <f.gruenbichler@proxmox.com>
2019-06-26 18:30:10 +02:00
Fabian Grünbichler
5d100641d5 5to6: fix ssh config check
in case the config file does not exist at all.

Signed-off-by: Fabian Grünbichler <f.gruenbichler@proxmox.com>
2019-06-26 18:30:10 +02:00
Thomas Lamprecht
f112796621 bump version to 5.4-8
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2019-06-25 12:52:04 +02:00
Thomas Lamprecht
4719a0751f ui: workspace: cope better with upgrade related false positive 401 HTTP codes
While we nowadays can work much better with package upgrades relating
the cluster stack it still happens that a pve-cluster upgrade can
produce a false-positive 401 (auth failure) code for a currently
valid ticket, e.g., because a pmxcfs lock was requested but the
pmxcfs was currently not mounted due an upgrade triggered restart.

A frequent case for a few false positive 401 is also a cluster
creation, especially if not done over the web GUI.

Thus add a counter, which gets set to 0 on each successful login or
ticket renewal and gets increased on each 401 error. Only show the
logged out window if we get five or more 401 responses. While 5 may
sound a bit much one needs to remember that we always have quite a
few API call in flight (resource update store, stores from current
panel ...) and thus, if one got really auth denied it will still show
quite fast (1 to 5 seconds, depending on which panel is currently
opened). Further, the backend naturally does not allows to do
anything during this time, this has no security implications
whatsoever.

Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2019-06-25 11:42:29 +02:00
Thomas Lamprecht
5b17681098 pve5to6: avoid Use of uninitialized value $osd_flags in pattern match
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
(cherry picked from commit b8b6003fde296c00ac1f798311e46bcc1a47ed65)
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2019-06-25 10:16:06 +02:00
Thomas Lamprecht
ed5110fd83 pve5to6 will never be a POD based man page, fake it for now
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
(cherry picked from commit 09df2aac59f255dc48fbbca5c2299b89e6015663)
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2019-06-25 10:16:00 +02:00
Thomas Lamprecht
8ad498b81f followups: pve5to6
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
(cherry picked from commit f72c8f8c1c7e5bd52e98da36cc5f6464b614bae2)
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2019-06-25 10:15:56 +02:00
Fabian Grünbichler
c62eb5b28f upgrade checklist
Signed-off-by: Fabian Grünbichler <f.gruenbichler@proxmox.com>
(cherry picked from commit a5d0627800ac98cf60ade5469ba19327d5cfbdae)
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2019-06-25 10:15:51 +02:00
Fabian Grünbichler
83b778c9ba Ceph: add get_cluster_versions helper
to make 'ceph versions' and 'ceph XX versions' accessible.

Signed-off-by: Fabian Grünbichler <f.gruenbichler@proxmox.com>
(cherry picked from commit 5b10325d4a3bc3fa0686719bfb6b8fdb40487469)
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2019-06-25 10:15:47 +02:00
Thomas Lamprecht
5d1eb21efd bin/make: fix pod2man generation
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
(cherry picked from commit 3331257e0fbc0acbcc55df338b4ca9b1d9558eba)
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2019-06-25 10:11:40 +02:00
Thomas Lamprecht
5a3acc0fd0 bump version to 5.4-7
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2019-06-07 16:50:40 +02:00
Thomas Lamprecht
92572ead6d gui: vm: add CPU flag selector with tri-state awareness
This allows to select the tri-state (enforce on, enforce off, default
from QEMU+CPU Model) for each CPU flag independently.

For this a grid with a widgetcolumn is used hosting tree radio
buttons for each state. They're marked '+' for enforce on, '-' for
enforce off and the default has no label, as it isn't easy to add in
such a way that it does not confuses people and does not looks
completely ugly.. But, to help people which have a hard time figuring
out what the states mean, a fake column was added showing the current
selected state's outcome in words.

For show casing the new nice interface add all currently supported
flags from out API-
It could be worth to add some selected CPU model awareness, so that
flags are only enabled if they can make sense with the selected
model. But one should be able to add this relative easily with this
as base.

The hardcoded flag lists is not ideal, we should try to generate this
in the future, but here already qemu-server is lacking and this is
rather independent of the fact and can be done later one just fine
too.

Note that this /is/ an *advanced* feature so not visible for all
directly, while I try to document in short what a flag does it surely
isn't perfect and to short to explain all nuances, they should give
enough pointers to know if it's relevant at all (amd / intel cpu) and
for what one should research

Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2019-06-07 16:24:26 +02:00
Thomas Lamprecht
79adddfba4 d/rules: enable parallel builds
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2019-06-07 16:24:26 +02:00
Thomas Lamprecht
a3a0977f2b Revert "buildsys: use dpkg-dev makefile helpers for pkg info"
As we'd need to also cherry-pick commit
b597d23d354665ddea247c3ad54ece1b84921768 to make this correct, but
it is more or less a API breakage which we cannot backport in
stable-5 so don't do that but revert this one here, bummer.

This reverts commit 69179449a9976429d62b495e1071bb531a0ee366.
2019-06-07 16:24:26 +02:00
Thomas Lamprecht
ea0ad09426 gui: ostypes: include 5.x in Linux series and reword to range
Make clear thet the 5.x is also supported and reword a bit as
"5.X/4.X/3.X/2.6" is a bit hard to read, so use "5.X - 2.6"

Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2019-06-06 16:22:21 +02:00
Thomas Lamprecht
69179449a9 buildsys: use dpkg-dev makefile helpers for pkg info
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2019-06-06 16:22:21 +02:00
Dominik Csapak
138507bd3b fix #2223: fix set_button_status isCDRom
value is not always a string (depending on the value that changed),
so we have to convert it to a string to have a 'match' function

Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
(cherry picked from commit 177b83abb390667b22423a3dd486479a66ecc69d)
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2019-05-31 11:05:14 +02:00
30 changed files with 1232 additions and 318 deletions

View File

@ -1,18 +1,20 @@
include /usr/share/dpkg/pkg-info.mk
include /usr/share/dpkg/architecture.mk
include defines.mk
export SOURCE_DATE_EPOCH ?= $(shell dpkg-parsechangelog -STimestamp)
export VERSION=${DEB_VERSION_UPSTREAM}
export PACKAGERELEASE=$(shell dpkg-parsechangelog -SVersion | cut -d- -f2)
DESTDIR=
SUBDIRS = aplinfo PVE bin www services configs network-hooks test
ARCH:=$(shell dpkg-architecture -qDEB_BUILD_ARCH)
GITVERSION:=$(shell git rev-parse HEAD)
# possibly set via debian/rules(.env)
REPOID?=$(shell git rev-parse --short=8 HEAD)
DEB=${PACKAGE}_${VERSION}-${PACKAGERELEASE}_${ARCH}.deb
DEB=${PACKAGE}_${DEB_VERSION_UPSTREAM_REVISION}_${DEB_BUILD_ARCH}.deb
all: ${SUBDIRS}
set -e && for i in ${SUBDIRS}; do ${MAKE} -C $$i; done

View File

@ -435,6 +435,13 @@ __PACKAGE__->register_method({
delete $ifaces->{$iface}->{$k};
@$families = grep(!/^inet$/, @$families) if $k eq 'address';
@$families = grep(!/^inet6$/, @$families) if $k eq 'address6';
if ($k eq 'cidr') {
delete $ifaces->{$iface}->{netmask};
delete $ifaces->{$iface}->{address};
} elsif ($k eq 'cidr6') {
delete $ifaces->{$iface}->{netmask6};
delete $ifaces->{$iface}->{address6};
}
}
$map_cidr_to_address_netmask->($param);

View File

@ -1,6 +1,6 @@
include ../../defines.mk
SOURCES=vzdump.pm pvesubscription.pm pveceph.pm pveam.pm pvesr.pm pvenode.pm pvesh.pm
SOURCES=vzdump.pm pvesubscription.pm pveceph.pm pveam.pm pvesr.pm pvenode.pm pvesh.pm pve5to6.pm
all:

846
PVE/CLI/pve5to6.pm Normal file
View File

@ -0,0 +1,846 @@
package PVE::CLI::pve5to6;
use strict;
use warnings;
use PVE::API2::APT;
use PVE::API2::Ceph;
use PVE::API2::LXC;
use PVE::API2::Qemu;
use PVE::API2::Certificates;
use PVE::Ceph::Tools;
use PVE::Cluster;
use PVE::Corosync;
use PVE::INotify;
use PVE::JSONSchema;
use PVE::RPCEnvironment;
use PVE::Storage;
use PVE::Tools qw(run_command $IPV4RE $IPV6RE);
use PVE::QemuServer;
use PVE::QemuConfig;
use AptPkg::Cache;
use Socket qw(AF_INET AF_INET6 inet_ntop);
use Term::ANSIColor;
use PVE::CLIHandler;
use base qw(PVE::CLIHandler);
my $nodename = PVE::INotify::nodename();
sub setup_environment {
PVE::RPCEnvironment->setup_default_cli_env();
}
my $min_pve_major = 5;
my $min_pve_minor = 4;
my $min_pve_pkgrel = 2;
my $counters = {
pass => 0,
skip => 0,
warn => 0,
fail => 0,
};
my $log_line = sub {
my ($level, $line) = @_;
$counters->{$level}++ if defined($level) && defined($counters->{$level});
print uc($level), ': ' if defined($level);
print "$line\n";
};
sub log_pass {
print color('green');
$log_line->('pass', @_);
print color('reset');
}
sub log_info {
$log_line->('info', @_);
}
sub log_skip {
$log_line->('skip', @_);
}
sub log_warn {
print color('yellow');
$log_line->('warn', @_);
print color('reset');
}
sub log_fail {
print color('red');
$log_line->('fail', @_);
print color('reset');
}
my $print_header_first = 1;
sub print_header {
my ($h) = @_;
print "\n" if !$print_header_first;
print "= $h =\n\n";
$print_header_first = 0;
}
my $get_systemd_unit_state = sub {
my ($unit) = @_;
my $state;
my $filter_output = sub {
$state = shift;
chomp $state;
};
eval {
run_command(['systemctl', 'is-enabled', "$unit"], outfunc => $filter_output, noerr => 1);
return if !defined($state);
run_command(['systemctl', 'is-active', "$unit"], outfunc => $filter_output, noerr => 1);
};
return $state // 'unknown';
};
my $log_systemd_unit_state = sub {
my ($unit, $no_fail_on_inactive) = @_;
my $log_method = \&log_warn;
my $state = $get_systemd_unit_state->($unit);
if ($state eq 'active') {
$log_method = \&log_pass;
} elsif ($state eq 'inactive') {
$log_method = $no_fail_on_inactive ? \&log_warn : \&log_fail;
} elsif ($state eq 'failed') {
$log_method = \&log_fail;
}
$log_method->("systemd unit '$unit' is in state '$state'");
};
my $versions;
my $get_pkg = sub {
my ($pkg) = @_;
$versions = eval { PVE::API2::APT->versions({ node => $nodename }) } if !defined($versions);
if (!defined($versions)) {
my $msg = "unable to retrieve package version information";
$msg .= "- $@" if $@;
log_fail("$msg");
return undef;
}
my $pkgs = [ grep { $_->{Package} eq $pkg } @$versions ];
if (!defined $pkgs || $pkgs == 0) {
log_fail("unable to determine installed $pkg version.");
return undef;
} else {
return $pkgs->[0];
}
};
my $apt_cache;
my $get_apt_package_state = sub {
my ($pkg) = @_;
if (!$apt_cache) {
if (!($apt_cache = AptPkg::Cache->new())) {
log_fail("unable to initialize AptPkg::Cache\n"); # should not happen at all
return undef;
}
}
my $p = $apt_cache->{'linux-image-amd64'};
if ($p) {
return $p->{SelectedState};
}
return undef;
};
my $is_pkg_installed = sub {
my ($pkg) = @_;
my $state = $get_apt_package_state->($pkg);
return undef if !defined($state); # better die?
return lc($state) eq 'install';
};
# taken from pve-cluster 6.0-4
my $resolve_hostname_like_corosync = sub {
my ($hostname, $corosync_conf) = @_;
my $corosync_strategy = $corosync_conf->{main}->{totem}->{ip_version};
$corosync_strategy = lc ($corosync_strategy // "ipv6-4");
my $match_ip_and_version = sub {
my ($addr) = @_;
return undef if !defined($addr);
if ($addr =~ m/^$IPV4RE$/) {
return ($addr, 4);
} elsif ($addr =~ m/^$IPV6RE$/) {
return ($addr, 6);
}
return undef;
};
my ($resolved_ip, $ip_version) = $match_ip_and_version->($hostname);
return ($resolved_ip, $ip_version) if defined($resolved_ip);
my $resolved_ip4;
my $resolved_ip6;
my @resolved_raw;
eval { @resolved_raw = PVE::Tools::getaddrinfo_all($hostname); };
return undef if ($@ || !@resolved_raw);
foreach my $socket_info (@resolved_raw) {
next if !$socket_info->{addr};
my ($family, undef, $host) = PVE::Tools::unpack_sockaddr_in46($socket_info->{addr});
if ($family == AF_INET && !defined($resolved_ip4)) {
$resolved_ip4 = inet_ntop(AF_INET, $host);
} elsif ($family == AF_INET6 && !defined($resolved_ip6)) {
$resolved_ip6 = inet_ntop(AF_INET6, $host);
}
last if defined($resolved_ip4) && defined($resolved_ip6);
}
# corosync_strategy specifies the order in which IP addresses are resolved
# by corosync. We need to match that order, to ensure we create firewall
# rules for the correct address family.
if ($corosync_strategy eq "ipv4") {
$resolved_ip = $resolved_ip4;
} elsif ($corosync_strategy eq "ipv6") {
$resolved_ip = $resolved_ip6;
} elsif ($corosync_strategy eq "ipv6-4") {
$resolved_ip = $resolved_ip6 // $resolved_ip4;
} elsif ($corosync_strategy eq "ipv4-6") {
$resolved_ip = $resolved_ip4 // $resolved_ip6;
}
return $match_ip_and_version->($resolved_ip);
};
sub check_pve_packages {
print_header("CHECKING VERSION INFORMATION FOR PVE PACKAGES");
print "Checking for package updates..\n";
my $updates = eval { PVE::API2::APT->list_updates({ node => $nodename }); };
if (!defined($updates)) {
log_warn("$@") if $@;
log_fail("unable to retrieve list of package updates!");
} elsif (@$updates > 0) {
my $pkgs = join(', ', map { $_->{Package} } @$updates);
log_warn("updates for the following packages are available:\n $pkgs");
} else {
log_pass("all packages uptodate");
}
print "\nChecking proxmox-ve package version..\n";
if (defined(my $proxmox_ve = $get_pkg->('proxmox-ve'))) {
my $min_pve_ver = "$min_pve_major.$min_pve_minor-$min_pve_pkgrel";
my ($maj, $min, $pkgrel) = $proxmox_ve->{OldVersion} =~ m/^(\d+)\.(\d+)-(\d+)/;
my $upgraded = 0;
if ($maj > $min_pve_major) {
log_pass("already upgraded to Proxmox VE " . ($min_pve_major + 1));
$upgraded = 1;
} elsif ($maj >= $min_pve_major && $min >= $min_pve_minor && $pkgrel >= $min_pve_pkgrel) {
log_pass("proxmox-ve package has version >= $min_pve_ver");
} else {
log_fail("proxmox-ve package is too old, please upgrade to >= $min_pve_ver!");
}
my ($krunning, $kinstalled) = (qr/5\./, 'pve-kernel-5.0');
if (!$upgraded) {
($krunning, $kinstalled) = (qr/4\.15/, 'pve-kernel-4.15');
}
print "\nChecking running kernel version..\n";
my $kernel_ver = $proxmox_ve->{RunningKernel};
if (!defined($kernel_ver)) {
log_fail("unable to determine running kernel version.");
} elsif ($kernel_ver =~ /^$krunning/) {
log_pass("expected running kernel '$kernel_ver'.");
} elsif ($get_pkg->($kinstalled)) {
log_warn("expected kernel '$kinstalled' intalled but not yet rebooted!");
} else {
log_warn("unexpected running and installed kernel '$kernel_ver'.");
}
}
print "\nChecking for installed stock Debian Kernel..\n";
if ($is_pkg_installed->('linux-image-amd64')) {
log_fail("Stock Debian kernel package installed. Please remove package 'linux-image-amd64'.");
} else {
log_pass("Stock Debian kernel package not installed.");
}
}
sub get_vms_with_vmx {
my $res = {
cpu => [],
flag => [],
};
my $vmlist = PVE::QemuServer::vzlist();
foreach my $vmid ( sort { $a <=> $b } keys %$vmlist ) {
my $pid = $vmlist->{$vmid}->{pid};
next if !$pid; # skip not running vms
my $cmdline = eval { PVE::Tools::file_get_contents("/proc/$pid/cmdline") };
if ($cmdline) {
my @args = split(/\0/, $cmdline);
for (my $i = 0; $i < scalar(@args); $i++) {
next if !$args[$i] || $args[$i] !~ m/^-?-cpu$/;
my $cpuarg = $args[$i+1];
if ($cpuarg =~ m/^(host|max)/) {
push @{$res->{cpu}}, $vmid;
} elsif ($cpuarg =~ m/\+(vmx|svm)/) {
push @{$res->{flag}}, $vmid;
}
}
}
}
$res = undef if (scalar(@{$res->{cpu}}) + scalar(@{$res->{flag}})) <= 0;
return $res;
}
sub check_kvm_nested {
log_info("Checking KVM nesting support, which breaks live migration for VMs using it..");
my $module_sysdir = "/sys/module";
if (-e "$module_sysdir/kvm_amd") {
$module_sysdir .= "/kvm_amd/parameters";
} elsif (-e "$module_sysdir/kvm_intel") {
$module_sysdir .= "/kvm_intel/parameters";
} else {
log_skip("no kvm module found");
return;
}
if (-f "$module_sysdir/nested") {
my $val = eval { PVE::Tools::file_read_firstline("$module_sysdir/nested") };
if ($val && $val =~ m/Y|1/) {
my $list = get_vms_with_vmx();
if (!defined($list)) {
log_pass("KVM nested parameter set, but currently no VM with a 'vmx' or 'svm' flag is running.");
} else {
my $warnmsg = "KVM nested enabled. It will not be possible to live migrate the following running VMs to PVE 6:\n";
if (@{$list->{cpu}}) {
$warnmsg .= " VMID(s) with cputype 'host' or 'max': " . join(',', @{$list->{cpu}}) . "\n";
}
if (@{$list->{flag}}) {
$warnmsg .= " VMID(s) with enforced cpu flag 'vmx' or 'svm': " . join(',', @{$list->{flag}}) . "\n";
}
log_warn($warnmsg);
}
} else {
log_pass("KVM nested parameter not set.")
}
} else {
log_skip("KVM nested parameter not found.");
}
}
sub check_vms_with_uefi {
log_info("Checking VMs with OVMF enabled and bad efidisk sizes...");
my $vmlist = PVE::QemuServer::vzlist();
my $vms = [];
foreach my $vmid ( sort { $a <=> $b } keys %$vmlist ) {
my $conf = PVE::QemuConfig->load_config($vmid);
if ($conf->{bios} && $conf->{bios} eq 'ovmf' && $conf->{efidisk0}) {
my $disk = PVE::QemuServer::parse_drive('efidisk0', $conf->{efidisk0});
if (!defined($disk->{size}) || $disk->{size} > 128*1024) {
# all efidisks bigger than the default 128k and those
# without size in the config
push @$vms, $vmid;
} elsif ($disk->{file} !~ /\.(raw|qcow2|vmdk)$/) {
# all efidisks not on file storage
push @$vms, $vmid;
}
}
}
if (scalar(@$vms) > 0) {
my $warnmsg = "VMs with OVMF configured and problematic EFI disks: \n";
$warnmsg .= " " . join(',', @$vms);
$warnmsg .= "\nThere may be manual intervention required. For details see:\n";
$warnmsg .= "<https://pve.proxmox.com/wiki/Upgrade_from_5.x_to_6.0#Known_upgrade_issues>";
log_warn($warnmsg);
} else {
log_pass("No VMs with OVMF and problematic efidisk found.");
}
}
sub check_storage_health {
print_header("CHECKING CONFIGURED STORAGES");
my $cfg = PVE::Storage::config();
my $ctime = time();
my $info = PVE::Storage::storage_info($cfg);
foreach my $storeid (keys %$info) {
my $d = $info->{$storeid};
if ($d->{enabled}) {
if ($d->{type} eq 'sheepdog') {
log_fail("storage '$storeid' of type 'sheepdog' is enabled - experimental sheepdog support dropped in PVE 6")
} elsif ($d->{active}) {
log_pass("storage '$storeid' enabled and active.");
} else {
log_warn("storage '$storeid' enabled but not active!");
}
} else {
log_skip("storage '$storeid' disabled.");
}
}
}
sub check_cluster_corosync {
print_header("CHECKING CLUSTER HEALTH/SETTINGS");
if (!PVE::Corosync::check_conf_exists(1)) {
log_skip("standalone node.");
return;
}
$log_systemd_unit_state->('pve-cluster.service');
$log_systemd_unit_state->('corosync.service');
if (PVE::Cluster::check_cfs_quorum(1)) {
log_pass("Cluster Filesystem is quorate.");
} else {
log_fail("Cluster Filesystem readonly, lost quorum?!");
}
my $conf = PVE::Cluster::cfs_read_file('corosync.conf');
my $conf_nodelist = PVE::Corosync::nodelist($conf);
my $node_votes = 0;
print "\nAnalzying quorum settings and state..\n";
if (!defined($conf_nodelist)) {
log_fail("unable to retrieve nodelist from corosync.conf");
} else {
if (grep { $conf_nodelist->{$_}->{quorum_votes} != 1 } keys %$conf_nodelist) {
log_warn("non-default quorum_votes distribution detected!");
}
map { $node_votes += $conf_nodelist->{$_}->{quorum_votes} // 0 } keys %$conf_nodelist;
}
my ($expected_votes, $total_votes);
my $filter_output = sub {
my $line = shift;
($expected_votes) = $line =~ /^Expected votes:\s*(\d+)\s*$/
if !defined($expected_votes);
($total_votes) = $line =~ /^Total votes:\s*(\d+)\s*$/
if !defined($total_votes);
};
eval {
run_command(['corosync-quorumtool', '-s'], outfunc => $filter_output, noerr => 1);
};
if (!defined($expected_votes)) {
log_fail("unable to get expected number of votes, setting to 0.");
$expected_votes = 0;
}
if (!defined($total_votes)) {
log_fail("unable to get expected number of votes, setting to 0.");
$total_votes = 0;
}
my $cfs_nodelist = PVE::Cluster::get_clinfo()->{nodelist};
my $offline_nodes = grep { $cfs_nodelist->{$_}->{online} != 1 } keys %$cfs_nodelist;
if ($offline_nodes > 0) {
log_fail("$offline_nodes nodes are offline!");
}
my $qdevice_votes = 0;
if (my $qdevice_setup = $conf->{main}->{quorum}->{device}) {
$qdevice_votes = $qdevice_setup->{votes} // 1;
}
log_info("configured votes - nodes: $node_votes");
log_info("configured votes - qdevice: $qdevice_votes");
log_info("current expected votes: $expected_votes");
log_info("current total votes: $total_votes");
log_warn("expected votes set to non-standard value '$expected_votes'.")
if $expected_votes != $node_votes + $qdevice_votes;
log_warn("total votes < expected votes: $total_votes/$expected_votes!")
if $total_votes < $expected_votes;
my $conf_nodelist_count = scalar(keys %$conf_nodelist);
my $cfs_nodelist_count = scalar(keys %$cfs_nodelist);
log_warn("cluster consists of less than three nodes!")
if $conf_nodelist_count < 3 && $conf_nodelist_count + $qdevice_votes < 3;
log_fail("corosync.conf ($conf_nodelist_count) and pmxcfs ($cfs_nodelist_count) don't agree about size of nodelist.")
if $conf_nodelist_count != $cfs_nodelist_count;
print "\nChecking nodelist entries..\n";
foreach my $cs_node (keys %$conf_nodelist) {
my $entry = $conf_nodelist->{$cs_node};
log_fail("$cs_node: no name entry in corosync.conf.")
if !defined($entry->{name});
log_fail("$cs_node: no nodeid configured in corosync.conf.")
if !defined($entry->{nodeid});
log_fail("$cs_node: neither ring0_addr nor ring1_addr defined in corosync.conf.")
if !defined($entry->{ring0_addr}) && !defined($entry->{ring1_addr});
my $verify_ring_ip = sub {
my $key = shift;
my $ring = $entry->{$key};
if (defined($ring)) {
my ($resolved_ip, undef) = $resolve_hostname_like_corosync->($ring, $conf);
if (defined($resolved_ip)) {
if ($resolved_ip ne $ring) {
log_warn("$cs_node: $key '$ring' resolves to '$resolved_ip'.\n Consider replacing it with the currently resolved IP address.");
} else {
log_pass("$cs_node: $key is configured to use IP address '$ring'");
}
} else {
log_fail("$cs_node: unable to resolve $key '$ring' to an IP address according to Corosync's resolve strategy - cluster will potentially fail with Corosync 3.x/kronosnet!");
}
}
};
$verify_ring_ip->('ring0_addr');
$verify_ring_ip->('ring1_addr');
}
print "\nChecking totem settings..\n";
my $totem = $conf->{main}->{totem};
my $transport = $totem->{transport};
if (defined($transport)) {
if ($transport ne 'knet') {
log_fail("Corosync transport explicitly set to '$transport' instead of implicit default!");
} else {
log_pass("Corosync transport set to '$transport'.");
}
} else {
log_pass("Corosync transport set to implicit default.");
}
if ((!defined($totem->{secauth}) || $totem->{secauth} ne 'on') && (!defined($totem->{crypto_cipher}) || $totem->{crypto_cipher} eq 'none')) {
log_fail("Corosync authentication/encryption is not explicitly enabled (secauth / crypto_cipher / crypto_hash)!");
} else {
if (defined($totem->{crypto_cipher}) && $totem->{crypto_cipher} eq '3des') {
log_fail("Corosync encryption cipher set to '3des', no longer supported in Corosync 3.x!");
} else {
log_pass("Corosync encryption and authentication enabled.");
}
}
print "\n";
log_info("run 'pvecm status' to get detailed cluster status..");
print_header("CHECKING INSTALLED COROSYNC VERSION");
if (defined(my $corosync = $get_pkg->('corosync'))) {
if ($corosync->{OldVersion} =~ m/^2\./) {
log_fail("corosync 2.x installed, cluster-wide upgrade to 3.x needed!");
} elsif ($corosync->{OldVersion} =~ m/^3\./) {
log_pass("corosync 3.x installed.");
} else {
log_fail("unexpected corosync version installed: $corosync->{OldVersion}!");
}
}
}
sub check_ceph {
print_header("CHECKING HYPER-CONVERGED CEPH STATUS");
if (PVE::Ceph::Tools::check_ceph_inited(1)) {
log_info("hyper-converged ceph setup detected!");
} else {
log_skip("no hyper-converged ceph setup detected!");
return;
}
log_info("getting Ceph status/health information..");
my $ceph_status = eval { PVE::API2::Ceph->status({ node => $nodename }); };
my $osd_flags = eval { PVE::API2::Ceph->get_flags({ node => $nodename }); };
my $noout_wanted = 1;
my $noout = $osd_flags =~ m/noout/ if $osd_flags;
if (!$ceph_status || !$ceph_status->{health}) {
log_fail("unable to determine Ceph status!");
} else {
my $ceph_health = $ceph_status->{health}->{status};
if (!$ceph_health) {
log_fail("unable to determine Ceph health!");
} elsif ($ceph_health eq 'HEALTH_OK') {
log_pass("Ceph health reported as 'HEALTH_OK'.");
} elsif ($ceph_health eq 'HEALTH_WARN' && $noout && (keys %{$ceph_status->{health}->{checks}} == 1)) {
log_pass("Ceph health reported as 'HEALTH_WARN' with a single failing check and 'noout' flag set.");
} else {
log_warn("Ceph health reported as '$ceph_health'.\n Use the PVE ".
"dashboard or 'ceph -s' to determine the specific issues and try to resolve them.");
}
}
log_info("getting Ceph OSD flags..");
eval {
if (!$osd_flags) {
log_fail("unable to get Ceph OSD flags!");
} else {
if ($osd_flags =~ m/recovery_deletes/ && $osd_flags =~ m/purged_snapdirs/) {
log_pass("all PGs have been scrubbed at least once while running Ceph Luminous.");
} else {
log_fail("missing 'recovery_deletes' and/or 'purged_snapdirs' flag, scrub of all PGs required before upgrading to Nautilus!");
}
}
};
log_info("getting Ceph daemon versions..");
my $ceph_versions = eval { PVE::Ceph::Tools::get_cluster_versions(undef, 1); };
if (!$ceph_versions) {
log_fail("unable to determine Ceph daemon versions!");
} else {
my $services = [
{ 'key' => 'mon', 'name' => 'monitor' },
{ 'key' => 'mgr', 'name' => 'manager' },
{ 'key' => 'mds', 'name' => 'MDS' },
{ 'key' => 'osd', 'name' => 'OSD' },
];
foreach my $service (@$services) {
my $name = $service->{name};
if (my $service_versions = $ceph_versions->{$service->{key}}) {
if (keys %$service_versions == 0) {
log_skip("no running instances detected for daemon type $name.");
} elsif (keys %$service_versions == 1) {
log_pass("single running version detected for daemon type $name.");
} else {
log_warn("multiple running versions detected for daemon type $name!");
}
} else {
log_skip("unable to determine versions of running Ceph $name instances.");
}
}
my $overall_versions = $ceph_versions->{overall};
if (!$overall_versions) {
log_warn("unable to determine overall Ceph daemon versions!");
} elsif (keys %$overall_versions == 1) {
log_pass("single running overall version detected for all Ceph daemon types.");
if ((keys %$overall_versions)[0] =~ /^ceph version 14\./) {
$noout_wanted = 0;
}
} else {
log_warn("overall version mismatch detected, check 'ceph versions' output for details!");
}
}
if ($noout) {
if ($noout_wanted) {
log_pass("'noout' flag set to prevent rebalancing during cluster-wide upgrades.");
} else {
log_warn("'noout' flag set, Ceph cluster upgrade seems finished.");
}
} elsif ($noout_wanted) {
log_warn("'noout' flag not set - recommended to prevent rebalancing during upgrades.");
}
log_info("checking Ceph config..");
my $conf = PVE::Cluster::cfs_read_file('ceph.conf');
if (%$conf) {
my $global = $conf->{global};
my $global_monhost = $global->{mon_host} // $global->{"mon host"} // $global->{"mon-host"};
if (!defined($global_monhost)) {
log_warn("No 'mon_host' entry found in ceph config.\n It's recommended to add mon_host with all monitor addresses (without ports) to the global section.");
} else {
log_pass("Found 'mon_host' entry.");
}
my $ipv6 = $global->{ms_bind_ipv6} // $global->{"ms bind ipv6"} // $global->{"ms-bind-ipv6"};
if ($ipv6) {
my $ipv4 = $global->{ms_bind_ipv4} // $global->{"ms bind ipv4"} // $global->{"ms-bind-ipv4"};
if ($ipv6 eq 'true' && (!defined($ipv4) || $ipv4 ne 'false')) {
log_warn("'ms_bind_ipv6' is enabled but 'ms_bind_ipv4' is not disabled.\n Make sure to disable 'ms_bind_ipv4' for ipv6 only clusters, or add an ipv4 network to public/cluster network.");
} else {
log_pass("'ms_bind_ipv6' is enabled and 'ms_bind_ipv4' disabled");
}
} else {
log_pass("'ms_bind_ipv6' not enabled");
}
if (defined($global->{keyring})) {
log_warn("[global] config section contains 'keyring' option, which will prevent services from starting with Nautilus.\n Move 'keyring' option to [client] section instead.");
} else {
log_pass("no 'keyring' option in [global] section found.");
}
} else {
log_warn("Empty ceph config found");
}
my $local_ceph_ver = PVE::Ceph::Tools::get_local_version(1);
if (defined($local_ceph_ver)) {
if ($local_ceph_ver == 14) {
my $scanned_osds = PVE::Tools::dir_glob_regex('/etc/ceph/osd', '^.*\.json$');
if (-e '/var/lib/ceph/osd/' && !defined($scanned_osds)) {
log_warn("local Ceph version is Nautilus, local OSDs detected, but no conversion from ceph-disk to ceph-volume done (yet).");
}
}
} else {
log_fail("unable to determine local Ceph version.");
}
}
sub check_misc {
print_header("MISCELLANEOUS CHECKS");
my $ssh_config = eval { PVE::Tools::file_get_contents('/root/.ssh/config') };
if (defined($ssh_config)) {
log_fail("Unsupported SSH Cipher configured for root in /root/.ssh/config: $1")
if $ssh_config =~ /^Ciphers .*(blowfish|arcfour|3des).*$/m;
} else {
log_skip("No SSH config file found.");
}
log_info("Checking common daemon services..");
$log_systemd_unit_state->('pveproxy.service');
$log_systemd_unit_state->('pvedaemon.service');
$log_systemd_unit_state->('pvestatd.service');
my $root_free = PVE::Tools::df('/', 10);
log_warn("Less than 2G free space on root file system.")
if defined($root_free) && $root_free->{avail} < 2*1024*1024*1024;
log_info("Checking for running guests..");
my $running_guests = 0;
my $vms = eval { PVE::API2::Qemu->vmlist({ node => $nodename }) };
log_warn("Failed to retrieve information about this node's VMs - $@") if $@;
$running_guests += grep { $_->{status} eq 'running' } @$vms if defined($vms);
my $cts = eval { PVE::API2::LXC->vmlist({ node => $nodename }) };
log_warn("Failed to retrieve information about this node's CTs - $@") if $@;
$running_guests += grep { $_->{status} eq 'running' } @$cts if defined($cts);
if ($running_guests > 0) {
log_warn("$running_guests running guest(s) detected - consider migrating or stopping them.")
} else {
log_pass("no running guest detected.")
}
log_info("Checking if the local node's hostname '$nodename' is resolvable..");
my $local_ip = eval { PVE::Network::get_ip_from_hostname($nodename) };
if ($@) {
log_warn("Failed to resolve hostname '$nodename' to IP - $@");
} else {
log_info("Checking if resolved IP is configured on local node..");
my $cidr = Net::IP::ip_is_ipv6($local_ip) ? "$local_ip/128" : "$local_ip/32";
my $configured_ips = PVE::Network::get_local_ip_from_cidr($cidr);
my $ip_count = scalar(@$configured_ips);
if ($ip_count <= 0) {
log_fail("Resolved node IP '$local_ip' not configured or active for '$nodename'");
} elsif ($ip_count > 1) {
log_warn("Resolved node IP '$local_ip' active on multiple ($ip_count) interfaces!");
} else {
log_pass("Resolved node IP '$local_ip' configured and active on single interface.");
}
}
log_info("Check node certificate's RSA key size");
my $certs = PVE::API2::Certificates->info({ node => $nodename });
my $certs_check = {
'rsaEncryption' => {
minsize => 2048,
name => 'RSA',
},
'id-ecPublicKey' => {
minsize => 224,
name => 'ECC',
},
};
my $certs_check_failed = 0;
foreach my $cert (@$certs) {
my ($type, $size, $fn) = $cert->@{qw(public-key-type public-key-bits filename)};
if (!defined($type) || !defined($size)) {
log_warn("'$fn': cannot check certificate, failed to get it's type or size!");
}
my $check = $certs_check->{$type};
if (!defined($check)) {
log_warn("'$fn': certificate's public key type '$type' unknown, check Debian Busters release notes");
next;
}
if ($size < $check->{minsize}) {
log_fail("'$fn', certificate's $check->{name} public key size is less than 2048 bit");
$certs_check_failed = 1;
} else {
log_pass("Certificate '$fn' passed Debian Busters security level for TLS connections ($size >= 2048)");
}
}
check_kvm_nested();
check_vms_with_uefi();
}
__PACKAGE__->register_method ({
name => 'checklist',
path => 'checklist',
method => 'GET',
description => 'Check (pre-/post-)upgrade conditions.',
parameters => {
additionalProperties => 0,
properties => {
},
},
returns => { type => 'null' },
code => sub {
my ($param) = @_;
check_pve_packages();
check_cluster_corosync();
check_ceph();
check_storage_health();
check_misc();
print_header("SUMMARY");
my $total = 0;
$total += $_ for values %$counters;
print "TOTAL: $total\n";
print colored("PASSED: $counters->{pass}\n", 'green');
print "SKIPPED: $counters->{skip}\n";
print colored("WARNINGS: $counters->{warn}\n", 'yellow');
print colored("FAILURES: $counters->{fail}\n", 'red');
if ($counters->{warn} > 0 || $counters->{fail} > 0) {
my $color = $counters->{fail} > 0 ? 'red' : 'yellow';
print colored("\nATTENTION: Please check the output for detailed information!\n", $color);
print colored("Try to solve the problems one at a time and then run this checklist tool again.\n", $color) if $counters->{fail} > 0;
}
return undef;
}});
our $cmddef = [ __PACKAGE__, 'checklist', [], {}];
# for now drop all unknown params and just check
@ARGV = ();
1;

View File

@ -123,7 +123,7 @@ __PACKAGE__->register_method({
my $print_cert_info = sub {
my ($schema, $cert, $options) = @_;
my $order = [qw(filename fingerprint subject issuer notbefore notafter san)];
my $order = [qw(filename fingerprint subject issuer notbefore notafter public-key-type public-key-bits san)];
PVE::CLIFormatter::print_api_result(
$cert, $schema, $order, { %$options, noheader => 1, sort_key => 0 });
};

View File

@ -57,6 +57,14 @@ sub get_local_version {
return undef;
}
sub get_cluster_versions {
my ($service, $noerr) = @_;
my $rados = PVE::RADOS->new();
my $cmd = $service ? "$service versions" : 'versions';
return $rados->mon_command({ prefix => $cmd });
}
sub get_config {
my $key = shift;

View File

@ -7,7 +7,7 @@ PERL_DOC_INC_DIRS=..
include /usr/share/pve-doc-generator/pve-doc-generator.mk
SERVICES = pvestatd pveproxy pvedaemon spiceproxy
CLITOOLS = vzdump pvesubscription pveceph pveam pvesr pvenode pvesh
CLITOOLS = vzdump pvesubscription pveceph pveam pvesr pvenode pvesh pve5to6
SCRIPTS = \
${SERVICES} \
@ -41,13 +41,16 @@ all: ${SERVICE_MANS} ${CLI_MANS} pvemailforward
%.1: %.1.pod
rm -f $@
cat $<|pod2man -n $* -s 1 -r ${VERSION} -c "Proxmox Documentation" >$@.tmp
cat $<|pod2man -n $* -s 1 -r ${VERSION} -c"Proxmox Documentation" - >$@.tmp
mv $@.tmp $@
%.1.pod:
podselect $* > $@.tmp
mv $@.tmp $@
pve5to6.1:
echo ".TH pve5to6 1" > $@
pveversion.1.pod: pveversion
pveupgrade.1.pod: pveupgrade
pvereport.1.pod: pvereport

8
bin/pve5to6 Executable file
View File

@ -0,0 +1,8 @@
#!/usr/bin/perl
use strict;
use warnings;
use PVE::CLI::pve5to6;
PVE::CLI::pve5to6->run_cli_handler();

78
debian/changelog vendored
View File

@ -1,3 +1,81 @@
pve-manager (5.4-15) unstable; urgency=medium
* pve5to6: check for potential problematic EFI disk for VMs using OVMF
* pve5to6: check for problematic stock Debian kernel package
* ui: improve encoding user-id
-- Proxmox Support Team <support@proxmox.com> Tue, 12 May 2020 17:42:54 +0200
pve-manager (5.4-14) unstable; urgency=medium
* switch links to https
* warn about the Proxmox VE 5.4 End-Of-Life date July 2020 to give users a
more upfront notice to be able to upgrade in time.
-- Proxmox Support Team <support@proxmox.com> Tue, 21 Apr 2020 18:19:37 +0200
pve-manager (5.4-13) unstable; urgency=medium
* fix building pvecfg, ensure that the package release is available
-- Proxmox Support Team <support@proxmox.com> Fri, 26 Jul 2019 10:14:56 +0200
pve-manager (5.4-12) unstable; urgency=medium
* pve5to6 upgrade checklist tool: check if certificates key size hold ub to
Busters TLS Standards
* add certification type and size infor to Web GUI, API and pvenode
CLI tool
-- Proxmox Support Team <support@proxmox.com> Thu, 25 Jul 2019 09:33:05 +0200
pve-manager (5.4-11) unstable; urgency=medium
* fix #2267: delete address(6) and netmas(6) with cidr(6)
* gui: HA: show 0 for max_relocate/restart correctly in overview
* further improve PVE 5 to 6 checklist script
-- Proxmox Support Team <support@proxmox.com> Tue, 09 Jul 2019 09:52:19 +0200
pve-manager (5.4-10) unstable; urgency=medium
* further improve PVE 5 to 6 checklist script
-- Proxmox Support Team <support@proxmox.com> Thu, 04 Jul 2019 15:33:20 +0200
pve-manager (5.4-9) unstable; urgency=medium
* improve PVE 5 to 6 checklist script
-- Proxmox Support Team <support@proxmox.com> Thu, 27 Jun 2019 20:29:07 +0200
pve-manager (5.4-8) unstable; urgency=medium
* add initial pve5to6 upgrade assistant
* ui: workspace: cope better with upgrade related false positive 401
HTTP codes
-- Proxmox Support Team <support@proxmox.com> Tue, 25 Jun 2019 12:51:54 +0200
pve-manager (5.4-7) unstable; urgency=medium
* ui: firewall log ratelimit: fix default value
* fix #2223: fix set_button_status isCDRom
* gui: ostypes: include 5.x in Linux series and reword to range
* gui: vm: add CPU flag selector with tri-state awareness
-- Proxmox Support Team <support@proxmox.com> Fri, 07 Jun 2019 16:48:24 +0200
pve-manager (5.4-6) unstable; urgency=medium
* gui: node: change syslog to JournalView and new (mini-)journal api

2
debian/rules vendored
View File

@ -14,4 +14,4 @@ override_dh_fixperms:
dh_fixperms -Xpvemailforward -Xvar/log/pveproxy
%:
dh $@ --with=systemd
dh $@ --with=systemd --parallel

View File

@ -1,6 +1,4 @@
VERSION=5.4
PACKAGE=pve-manager
PACKAGERELEASE=6
BINDIR=${DESTDIR}/usr/bin
PERLLIBDIR=${DESTDIR}/usr/share/perl5

View File

@ -1,261 +0,0 @@
/* force same grid cell heigh */
.x-grid-cell-inner {
line-height: 13px;
}
.x-grid-row-loading {
background-color: #fff;
background: no-repeat center center;
background-image:url(../ext4/resources/themes/images/default/shared/loading-balls.gif);
}
.x-grid-row-console {
background-color: #fff;
background: no-repeat center center;
background-image:url(../images/display.png);
}
.x-grid-checkheader {
height: 14px;
background-image: url(../images/unchecked.png);
background-position: 50% -2px;
background-repeat: no-repeat;
background-color: transparent;
}
.x-grid-checkheader-checked {
background-image: url(../images/checked.png);
}
.x-grid-checkheader-editor .x-form-cb-wrap {
text-align: center;
}
.x-selectable, .x-selectable * {
-moz-user-select: text!important;
-khtml-user-select: text!important;
}
.pve-itype-icon-virt-viewer,
.pve-itype-icon-tigervnc,
.pve-itype-icon-novnc,
.pve-itype-icon-display,
.pve-itype-icon-memory,
.pve-itype-icon-processor,
.pve-itype-icon-network,
.pve-itype-icon-network-server,
.pve-itype-icon-keyboard,
.pve-itype-icon-cdrom,
.pve-itype-icon-qemu,
.pve-itype-icon-qemu-template,
.pve-itype-icon-qemu-running,
.pve-itype-icon-lxc,
.pve-itype-icon-lxc-template,
.pve-itype-icon-lxc-running,
.pve-itype-icon-swap,
.pve-itype-icon-node,
.pve-itype-icon-node-running,
.pve-itype-icon-storage,
.pve-itype-icon-pool,
.pve-itype-icon-itype
{
background-repeat: no-repeat;
background-position:3px center;
padding-left: 20px;
}
.pve-itype-icon-qemu,
.x-tree-node-computer,
.x-grid-tree-node-expanded .x-tree-node-computer
{
background-image:url(../images/computer.png);
}
.pve-itype-icon-qemu,
.x-tree-node-computer,
.x-grid-tree-node-expanded .x-tree-node-computer
{
background-image:url(../images/computer.png);
}
.pve-itype-icon-qemu-running,
.x-tree-node-computer-running,
.x-grid-tree-node-expanded .x-tree-node-computer-running
{
background-image:url(../images/computer-on.png);
}
.pve-itype-icon-qemu-template,
.x-tree-node-computer-template,
.x-grid-tree-node-expanded .x-tree-node-computer-template
{
background-image:url(../images/computer-template.png);
}
.pve-itype-icon-lxc,
.x-tree-node-lxc,
.x-grid-tree-node-expanded .x-tree-node-lxc
{
background-image:url(../images/lxc-off.png);
}
.pve-itype-icon-lxc-template,
.x-tree-node-lxc-template,
.x-grid-tree-node-expanded .x-tree-node-lxc-template
{
background-image:url(../images/computer-template.png);
}
.pve-itype-icon-swap,
.x-tree-node-lxc-swap,
.x-grid-tree-node-expanded .x-tree-lxc-swap
{
background-image:url(../images/swap.png);
}
.pve-itype-icon-lxc-running,
.x-tree-node-lxc-running,
.x-grid-tree-node-expanded .x-tree-node-lxc-running
{
background-image:url(../images/lxc-on.png);
}
.pve-itype-icon-node,
.x-tree-node-server,
.x-grid-tree-node-expanded .x-tree-node-server
{
background-image:url(../images/network-server-off.png);
}
.pve-itype-icon-node-running,
.x-tree-node-server-running,
.x-grid-tree-node-expanded .x-tree-node-server-running
{
background-image:url(../images/network-server-on.png);
}
.pve-itype-icon-storage,
.x-tree-node-harddisk,
.x-grid-tree-node-expanded .x-tree-node-harddisk
{
background-image:url(../images/drive-harddisk.png);
}
.x-tree-node-snapshot,
.x-grid-tree-node-expanded .x-tree-node-snapshot
{
background-image:url(../images/snapshot.png);
}
.pve-itype-icon-pool,
.x-tree-node-pool,
.x-grid-tree-node-expanded .x-tree-node-pool
{
background-image:url(../images/connect_established.png);
}
.pve-itype-icon-itype
{
background-image:url(../ext4/resources/themes/images/default/tree/folder.gif);
}
.pve-itype-icon-network-server
{
background-image:url(../images/network-server.png);
}
.pve-itype-icon-network
{
background-image:url(../images/network.png);
}
.pve-itype-icon-keyboard
{
background-image:url(../images/keyboard.png);
}
.pve-itype-icon-cdrom
{
background-image:url(../images/cdrom.png);
}
.pve-itype-icon-memory
{
background-image:url(../images/memory.png);
}
.pve-itype-icon-processor
{
background-image:url(../images/processor.png);
}
.pve-itype-icon-display
{
background-image:url(../images/display.png);
}
.pve-itype-icon-tigervnc
{
background-image:url(../images/tigervnc.png);
}
.pve-itype-icon-novnc
{
background-image:url(../images/novnc.png);
}
.pve-itype-icon-virt-viewer
{
background-image:url(../images/virt-viewer.png);
}
.pve-bar-wrap
{
}
.pve-bar-border
{
padding: 0px;
background-color: #C0C0C0;
border: 1px solid #000000;
width: 50px;
height: 6px;
}
.pve-bar-inner
{
background-color: #00C000;
border:0px;
height:6px;
}
.pve-largebar-border
{
position:relative;
padding:0px;
background-color:#C0C0C0;
border:1px solid #000000;
width:200px;
height:12px;
}
.pve-largebar-inner
{
background-color: #00C000;
border:0px;
height:12px;
}
.pve-largebar-text
{
position:absolute;
top:0px;
left:0px;
text-align:center;
line-height: 12px;
font-size: 11px;
border:0px;
width:200px;
height:12px;
}

View File

@ -538,6 +538,12 @@ table.osds td:first-of-type {
cursor: pointer;
}
.eolicon {
position: relative;
float: left;
margin-right: 5px;
}
.x-grid-filters-filtered-column{
font-style: italic;
font-weight: bold;
@ -594,4 +600,4 @@ table.osds td:first-of-type {
.install-mask {
background-color: rgb(245, 245, 245);
color: #000;
}
}

View File

@ -61,6 +61,7 @@ JSSRC= \
form/GlobalSearchField.js \
form/QemuBiosSelector.js \
form/VMSelector.js \
form/VMCPUFlagSelector.js \
form/USBSelector.js \
form/CalendarEvent.js \
form/CephPoolSelector.js \

View File

@ -46,11 +46,11 @@ Ext.define('PVE.Utils', { utilities: {
'p': gettext('Premium')
},
noSubKeyHtml: 'You do not have a valid subscription for this server. Please visit <a target="_blank" href="http://www.proxmox.com/products/proxmox-ve/subscription-service-plans">www.proxmox.com</a> to get a list of available options.',
noSubKeyHtml: 'You do not have a valid subscription for this server. Please visit <a target="_blank" href="https://www.proxmox.com/products/proxmox-ve/subscription-service-plans">www.proxmox.com</a> to get a list of available options.',
kvm_ostypes: {
'Linux': [
{ desc: '4.X/3.X/2.6 Kernel', val: 'l26' },
{ desc: '5.x - 2.6 Kernel', val: 'l26' },
{ desc: '2.4 Kernel', val: 'l24' }
],
'Microsoft Windows': [

View File

@ -27,6 +27,7 @@ Ext.define('PVE.Workspace', {
if (loginData.cap) {
Ext.state.Manager.set('GuiCap', loginData.cap);
}
me.response401count = 0;
me.onLogin(loginData);
},
@ -60,7 +61,12 @@ Ext.define('PVE.Workspace', {
// fixme: what about other errors
Ext.Ajax.on('requestexception', function(conn, response, options) {
if (response.status == 401 && !PVE.Utils.silenceAuthFailures) { // auth failure
me.showLogin();
// don't immediately show as logged out to cope better with some big
// upgrades, which may temporarily produce a false positive 401 err
me.response401count++;
if (me.response401count > 5) {
me.showLogin();
}
}
});
@ -164,7 +170,7 @@ Ext.define('PVE.StdWorkspace', {
var ui = me.query('#userinfo')[0];
if (Proxmox.UserName) {
var msg = Ext.String.format(gettext("You are logged in as {0}"), "'" + Proxmox.UserName + "'");
var msg = Ext.String.format(gettext("You are logged in as {0}"), "'" + Ext.String.htmlEncode(Proxmox.UserName) + "'");
ui.update('<div class="x-unselectable" style="white-space:nowrap;">' + msg + '</div>');
} else {
ui.update('');
@ -291,7 +297,7 @@ Ext.define('PVE.StdWorkspace', {
margin: '2 0 2 5',
items: [
{
html: '<a class="x-unselectable" target=_blank href="http://www.proxmox.com">' +
html: '<a class="x-unselectable" target=_blank href="https://www.proxmox.com">' +
'<img style="padding-top:4px;padding-right:5px" src="/pve2/images/proxmox_logo.png"/></a>'
},
{
@ -306,6 +312,20 @@ Ext.define('PVE.StdWorkspace', {
{
flex: 1
},
{
id: 'eolannouncement',
padding: '0 0 0 15',
html: '<a href="https://pve.proxmox.com/wiki/FAQ#faq-support-table" target="_blank">'+
'<i class="fa eolicon critical fa-exclamation-triangle" style="font-size: 1.5em;"></i> ' +
'Support for Proxmox VE 5.4 ends on 31.07.2020</a>',
autoEl: {
tag: 'div',
'data-qtip': gettext("You won't get any security fixes after the End-Of-Life date. Please consider upgrading.")
}
},
{
flex: 1
},
{
pack: 'end',
id: 'userinfo',

View File

@ -111,7 +111,7 @@ Ext.define('PVE.dc.ACLView', {
return '@' + ugid;
}
return ugid;
return Ext.String.htmlEncode(ugid);
};
var columns = [

View File

@ -68,6 +68,7 @@ Ext.define('PVE.dc.Log', {
{
header: gettext("User name"),
dataIndex: 'user',
renderer: Ext.String.htmlEncode,
width: 150
},
{
@ -79,6 +80,7 @@ Ext.define('PVE.dc.Log', {
{
header: gettext("Message"),
dataIndex: 'msg',
renderer: Ext.String.htmlEncode,
flex: 1
}
],

View File

@ -6,9 +6,9 @@ Ext.define('PVE.dc.Support', {
invalidHtml: '<h1>No valid subscription</h1>' + PVE.Utils.noSubKeyHtml,
communityHtml: 'Please use the public community <a target="_blank" href="http://forum.proxmox.com">forum</a> for any questions.',
communityHtml: 'Please use the public community <a target="_blank" href="https://forum.proxmox.com">forum</a> for any questions.',
activeHtml: 'Please use our <a target="_blank" href="https://my.proxmox.com">support portal</a> for any questions. You can also use the public community <a target="_blank" href="http://forum.proxmox.com">forum</a> to get additional information.',
activeHtml: 'Please use our <a target="_blank" href="https://my.proxmox.com">support portal</a> for any questions. You can also use the public community <a target="_blank" href="https://forum.proxmox.com">forum</a> to get additional information.',
bugzillaHtml: '<h1>Bug Tracking</h1>Our bug tracking system is available <a target="_blank" href="https://bugzilla.proxmox.com">here</a>.',

View File

@ -368,6 +368,7 @@ Ext.define('PVE.window.TFAEdit', {
{
xtype: 'displayfield',
fieldLabel: gettext('User name'),
renderer: Ext.String.htmlEncode,
cbind: {
value: '{userid}'
}

View File

@ -101,6 +101,7 @@ Ext.define('PVE.dc.Tasks', {
{
header: gettext("User name"),
dataIndex: 'user',
renderer: Ext.String.htmlEncode,
width: 150
},
{

View File

@ -72,6 +72,7 @@ Ext.define('PVE.dc.UserEdit', {
name: 'userid',
fieldLabel: gettext('User name'),
value: me.userid,
renderer: Ext.String.htmlEncode,
allowBlank: false,
submitValue: me.isCreate ? true : false
},

View File

@ -110,11 +110,11 @@ Ext.define('PVE.dc.UserView', {
];
var render_username = function(userid) {
return userid.match(/^(.+)(@[^@]+)$/)[1];
return Ext.String.htmlEncode(userid.match(/^(.+)(@[^@]+)$/)[1]);
};
var render_realm = function(userid) {
return userid.match(/@([^@]+)$/)[1];
return Ext.String.htmlEncode(userid.match(/@([^@]+)$/)[1]);
};
Ext.apply(me, {

View File

@ -29,6 +29,7 @@ Ext.define('PVE.form.UserSelector', {
header: gettext('User'),
sortable: true,
dataIndex: 'userid',
renderer: Ext.String.htmlEncode,
flex: 1
},
{

View File

@ -0,0 +1,174 @@
/*jslint confusion: true*/
Ext.define('PVE.form.VMCPUFlagSelector', {
extend: 'Ext.grid.Panel',
alias: 'widget.vmcpuflagselector',
mixins: {
field: 'Ext.form.field.Field'
},
disableSelection: true,
columnLines: false,
selectable: false,
hideHeaders: true,
scrollable: 'y',
height: 200,
unkownFlags: [],
store: {
type: 'store',
fields: ['flag', { name: 'state', defaultValue: '=' }, 'desc'],
data: [
// FIXME: let qemu-server host this and autogenerate or get from API call??
{ flag: 'md-clear', desc: 'Required to let the guest OS know if MDS is mitigated correctly' },
{ flag: 'pcid', desc: 'Meltdown fix cost reduction on Westmere, Sandy-, and IvyBridge Intel CPUs' },
{ flag: 'spec-ctrl', desc: 'Allows improved Spectre mitigation with Intel CPUs' },
{ flag: 'ssbd', desc: 'Protection for "Speculative Store Bypass" for Intel models' },
{ flag: 'ibpb', desc: 'Allows improved Spectre mitigation with AMD CPUs' },
{ flag: 'virt-ssbd', desc: 'Basis for "Speculative Store Bypass" protection for AMD models' },
{ flag: 'amd-ssbd', desc: 'Improves Spectre mitigation performance with AMD CPUs, best used with "virt-ssbd"' },
{ flag: 'amd-no-ssb', desc: 'Notifies guest OS that host is not vulnerable for Spectre on AMD CPUs' },
{ flag: 'pdpe1gb', desc: 'Allow guest OS to use 1GB size pages, if host HW supports it' }
],
listeners: {
update: function() {
this.commitChanges();
}
}
},
getValue: function() {
var me = this;
var store = me.getStore();
var flags = '';
// ExtJS does not has a nice getAllRecords interface for stores :/
store.queryBy(Ext.returnTrue).each(function(rec) {
var s = rec.get('state');
if (s && s !== '=') {
var f = rec.get('flag');
if (flags === '') {
flags = s + f;
} else {
flags += ';' + s + f;
}
}
});
flags += me.unkownFlags.join(';');
return flags;
},
setValue: function(value) {
var me = this;
var store = me.getStore();
me.value = value || '';
me.unkownFlags = [];
me.getStore().queryBy(Ext.returnTrue).each(function(rec) {
rec.set('state', '=');
});
var flags = value ? value.split(';') : [];
flags.forEach(function(flag) {
var sign = flag.substr(0, 1);
flag = flag.substr(1);
var rec = store.findRecord('flag', flag);
if (rec !== null) {
rec.set('state', sign);
} else {
me.unkownFlags.push(flag);
}
});
store.reload();
var res = me.mixins.field.setValue.call(me, value);
return res;
},
columns: [
{
dataIndex: 'state',
renderer: function(v) {
switch(v) {
case '=': return 'Default';
case '-': return 'Off';
case '+': return 'On';
default: return 'Unknown';
}
},
width: 65
},
{
xtype: 'widgetcolumn',
dataIndex: 'state',
width: 95,
onWidgetAttach: function (column, widget, record) {
var val = record.get('state') || '=';
widget.down('[inputValue=' + val + ']').setValue(true);
// TODO: disable if selected CPU model and flag are incompatible
},
widget: {
xtype: 'radiogroup',
hideLabel: true,
layout: 'hbox',
validateOnChange: false,
value: '=',
listeners: {
change: function(f, value) {
var v = Object.values(value)[0];
f.getWidgetRecord().set('state', v);
var view = this.up('grid');
view.dirty = view.getValue() !== view.originalValue;
view.checkDirty();
//view.checkChange();
}
},
items: [
{
boxLabel: '-',
boxLabelAlign: 'before',
inputValue: '-'
},
{
checked: true,
inputValue: '='
},
{
boxLabel: '+',
inputValue: '+'
}
]
}
},
{
dataIndex: 'flag',
width: 100
},
{
dataIndex: 'desc',
cellWrap: true,
flex: 1
}
],
initComponent: function() {
var me = this;
// static class store, thus gets not recreated, so ensure defaults are set!
me.getStore().data.forEach(function(v) {
v.state = '=';
});
me.value = me.originalValue = '';
me.callParent(arguments);
}
});

View File

@ -146,7 +146,10 @@ Ext.define('PVE.ha.ResourcesView', {
width: 100,
sortable: true,
renderer: function(v) {
return v || '1';
if (v === undefined) {
return '1';
}
return v;
},
dataIndex: 'max_restart'
},
@ -155,7 +158,10 @@ Ext.define('PVE.ha.ResourcesView', {
width: 100,
sortable: true,
renderer: function(v) {
return v || '1';
if (v === undefined) {
return '1';
}
return v;
},
dataIndex: 'max_relocate'
},

View File

@ -57,6 +57,16 @@ Ext.define('PVE.node.CertificateViewer', {
fieldLabel: gettext('Subject'),
name: 'subject'
},
{
xtype: 'displayfield',
fieldLabel: gettext('Public Key Type'),
name: 'public-key-type'
},
{
xtype: 'displayfield',
fieldLabel: gettext('Public Key Size'),
name: 'public-key-bits'
},
{
xtype: 'displayfield',
fieldLabel: gettext('Valid Since'),
@ -220,7 +230,7 @@ Ext.define('PVE.node.CertUpload', {
Ext.define('pve-certificate', {
extend: 'Ext.data.Model',
fields: [ 'filename', 'fingerprint', 'issuer', 'notafter', 'notbefore', 'subject', 'san' ],
fields: [ 'filename', 'fingerprint', 'issuer', 'notafter', 'notbefore', 'subject', 'san', 'public-key-bits', 'public-key-type' ],
idProperty: 'filename'
});
@ -293,6 +303,18 @@ Ext.define('PVE.node.Certificates', {
flex: 1,
dataIndex: 'subject'
},
{
header: gettext('Public Key Alogrithm'),
flex: 1,
dataIndex: 'public-key-type',
hidden: true
},
{
header: gettext('Public Key Size'),
flex: 1,
dataIndex: 'public-key-bits',
hidden: true
},
{
header: gettext('Valid Since'),
width: 150,

View File

@ -575,7 +575,7 @@ Ext.define('PVE.qemu.HardwareView', {
var rowdef = rows[key];
var pending = rec.data['delete'] || me.hasPendingChanges(key);
var isCDRom = (value && !!value.match(/media=cdrom/));
var isCDRom = (value && !!value.toString().match(/media=cdrom/));
var isUnusedDisk = key.match(/^unused\d+/);
var isUsedDisk = !isUnusedDisk &&
rowdef.tdCls == 'pve-itype-icon-storage' &&

View File

@ -42,16 +42,11 @@ Ext.define('PVE.qemu.ProcessorInputPanel', {
// build the cpu options:
me.cpu.cputype = values.cputype;
var flags = [];
['pcid', 'spec-ctrl'].forEach(function(flag) {
if (values[flag]) {
flags.push('+' + flag.toString());
}
delete values[flag];
});
me.cpu.flags = flags.length ? flags.join(';') : undefined;
if (values.flags) {
me.cpu.flags = values.flags;
} else {
delete me.cpu.flags;
}
delete values.cputype;
delete values.flags;
@ -141,7 +136,10 @@ Ext.define('PVE.qemu.ProcessorInputPanel', {
fieldLabel: gettext('CPU limit'),
allowBlank: true,
emptyText: gettext('unlimited')
},
}
],
advancedColumn2: [
{
xtype: 'proxmoxintegerfield',
name: 'cpuunits',
@ -151,27 +149,22 @@ Ext.define('PVE.qemu.ProcessorInputPanel', {
value: '1024',
deleteEmpty: true,
allowBlank: true
}
],
advancedColumn2: [
},
{
xtype: 'proxmoxcheckbox',
fieldLabel: gettext('Enable NUMA'),
name: 'numa',
uncheckedValue: 0
}
],
advancedColumnB: [
{
xtype: 'label',
text: 'Extra CPU Flags:'
},
{
xtype: 'proxmoxcheckbox',
fieldLabel: 'PCID',
name: 'pcid',
uncheckedValue: 0
},
{
xtype: 'proxmoxcheckbox',
fieldLabel: 'SPEC-CTRL',
name: 'spec-ctrl',
uncheckedValue: 0
xtype: 'vmcpuflagselector',
name: 'flags'
}
]
});
@ -179,6 +172,8 @@ Ext.define('PVE.qemu.ProcessorInputPanel', {
Ext.define('PVE.qemu.ProcessorEdit', {
extend: 'Proxmox.window.Edit',
width: 700,
initComponent : function() {
var me = this;
@ -200,12 +195,7 @@ Ext.define('PVE.qemu.ProcessorEdit', {
ipanel.cpu = cpu;
data.cputype = cpu.cputype;
if (cpu.flags) {
var flags = cpu.flags.split(';');
flags.forEach(function(flag) {
var sign = flag.substr(0,1);
flag = flag.substr(1);
data[flag] = (sign === '+');
});
data.flags = cpu.flags;
}
}
me.setValues(data);

View File

@ -36,7 +36,7 @@ Ext.define('PVE.window.Settings', {
var sp = Ext.state.Manager.getProvider();
var username = sp.get('login-username') || Proxmox.Utils.noneText;
me.lookupReference('savedUserName').setValue(username);
me.lookupReference('savedUserName').setValue(Ext.String.htmlEncode(username));
var settings = ['fontSize', 'fontFamily', 'letterSpacing', 'lineHeight'];
settings.forEach(function(setting) {