Skip to content

Commit 0965298

Browse files
committed
CP-45921: Use dnf as package manager for XS9
Given XS9 has updated to dnf and no yum is available, xapi will choose package manager basing on following - If dnf exists, use dnf - otherwise, fallback to yum xapi just presume dnf or yum is available in the system. Because xapi decides to use dnf or yum according to the running environment, this commit is compatible with yum/xs8 and dnf/xs9 Signed-off-by: Lin Liu <[email protected]>
1 parent 6626e2c commit 0965298

File tree

7 files changed

+192
-42
lines changed

7 files changed

+192
-42
lines changed

ocaml/tests/suite_alcotest.ml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,4 +71,5 @@ let () =
7171
@ Test_session.tests
7272
@ Test_xapi_cmd_result.tests
7373
@ Test_extauth_plugin_ADwinbind.tests
74+
@ Test_pkg_mgr.tests
7475
)

ocaml/tests/test_pkg_mgr.ml

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
open Pkg_mgr
2+
3+
let test_default_to_dnf =
4+
(* mock dnf binary to /bin/sh, to ensure exists and decouple dnf dependencies*)
5+
Xapi_globs.dnf_cmd := "/bin/sh" ;
6+
let check exp () =
7+
let ac = Pkg_mgr.pmgr_cmd () in
8+
let msg = Printf.sprintf "exp: %s <-> got: %s" exp ac in
9+
Alcotest.(check string) msg exp ac
10+
in
11+
[
12+
( Printf.sprintf "unit -> %s" !Xapi_globs.dnf_cmd
13+
, `Quick
14+
, check !Xapi_globs.dnf_cmd
15+
)
16+
]
17+
18+
let test_add_sub_cmd =
19+
Xapi_globs.dnf_cmd := "/bin/sh" ;
20+
let params = ["--disablerepo=*"; "--enablerepo=test"] in
21+
let str_parms = String.concat " " params in
22+
let check inp exp () =
23+
let ac = add_sub_cmd inp params in
24+
let str_ac = String.concat " " ac in
25+
let msg =
26+
Printf.sprintf "%s %s -> %s" (dnf_sub_cmd_to_string inp) str_parms str_ac
27+
in
28+
Alcotest.(check string) msg exp str_ac
29+
in
30+
[
31+
(Reposync, ["reposync"] @ params)
32+
; (Repoconfig, ["config-manager"] @ params)
33+
; (Repoquery, ["repoquery"] @ params)
34+
]
35+
|> List.map (fun (x, y) -> (x, String.concat " " y))
36+
|> List.map (fun (inp, exp) -> ("<omit inp>", `Quick, check inp exp))
37+
38+
let tests =
39+
[
40+
("test_use_dnf_as_defualt", test_default_to_dnf)
41+
; ("test_add_sub_cmd", test_add_sub_cmd)
42+
]

ocaml/xapi/pkg_mgr.ml

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
type t = Yum | Dnf
2+
3+
type sub_cmd = Reposync | Repoconfig | Repoquery
4+
5+
(* Cache current package manager, so no need to check every time*)
6+
let pmgr = ref None
7+
8+
let active () =
9+
match !pmgr with
10+
| None -> (
11+
match Sys.file_exists !Xapi_globs.dnf_cmd with
12+
| true ->
13+
pmgr := Some Dnf ;
14+
Dnf
15+
| false ->
16+
pmgr := Some Yum ;
17+
Yum
18+
)
19+
| Some mgr' ->
20+
mgr'
21+
22+
let dnf_sub_cmd_to_string = function
23+
| Reposync ->
24+
"reposync"
25+
| Repoconfig ->
26+
"config-manager"
27+
| Repoquery ->
28+
"repoquery"
29+
30+
let pmgr_cmd () =
31+
match active () with Dnf -> !Xapi_globs.dnf_cmd | Yum -> !Xapi_globs.yum_cmd
32+
33+
let reposync_cmd () =
34+
match active () with
35+
| Dnf ->
36+
!Xapi_globs.dnf_cmd
37+
| Yum ->
38+
!Xapi_globs.reposync_cmd
39+
40+
let repoquery_cmd () =
41+
match active () with
42+
| Dnf ->
43+
!Xapi_globs.dnf_cmd
44+
| Yum ->
45+
!Xapi_globs.repoquery_cmd
46+
47+
let repoconfig_cmd () =
48+
match active () with
49+
| Dnf ->
50+
!Xapi_globs.dnf_cmd
51+
| Yum ->
52+
!Xapi_globs.yum_config_manager_cmd
53+
54+
let plugins () = match active () with Dnf -> [] | Yum -> ["--plugins"]
55+
56+
let add_sub_cmd sub_cmd params =
57+
(match active () with Dnf -> [dnf_sub_cmd_to_string sub_cmd] | Yum -> [])
58+
@ params

ocaml/xapi/repository.ml

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -128,9 +128,11 @@ let sync ~__context ~self ~token ~token_id =
128128
write_initial_yum_config () ;
129129
clean_yum_cache repo_name ;
130130
(* Remove imported YUM repository GPG key *)
131-
Xapi_stdext_unix.Unixext.rm_rec (get_repo_config repo_name "gpgdir") ;
131+
if Pkg_mgr.(active () = Yum) then
132+
Xapi_stdext_unix.Unixext.rm_rec (get_repo_config repo_name "gpgdir") ;
132133
Xapi_stdext_pervasives.Pervasiveext.finally
133134
(fun () ->
135+
let open Pkg_mgr in
134136
with_access_token ~token ~token_id @@ fun token_path ->
135137
(* Configure proxy and token *)
136138
let token_param =
@@ -152,11 +154,11 @@ let sync ~__context ~self ~token ~token_id =
152154
; token_param
153155
; repo_name
154156
]
157+
|> add_sub_cmd Repoconfig
155158
in
156159
ignore
157160
(Helpers.call_script ~log_output:Helpers.On_failure
158-
!Xapi_globs.yum_config_manager_cmd
159-
config_params
161+
(repoconfig_cmd ()) config_params
160162
) ;
161163

162164
(* Import YUM repository GPG key to check metadata in reposync *)
@@ -168,7 +170,7 @@ let sync ~__context ~self ~token ~token_id =
168170
; "makecache"
169171
]
170172
in
171-
ignore (Helpers.call_script !Xapi_globs.yum_cmd makecache_params) ;
173+
ignore (Helpers.call_script (pmgr_cmd ()) makecache_params) ;
172174

173175
(* Sync with remote repository *)
174176
let sync_params =
@@ -178,14 +180,16 @@ let sync ~__context ~self ~token ~token_id =
178180
; "--downloadcomps"
179181
; "--download-metadata"
180182
; "--delete"
181-
; "--plugins"
182183
; "--newest-only"
183184
; Printf.sprintf "--repoid=%s" repo_name
184185
]
186+
@ plugins ()
187+
|> add_sub_cmd Reposync
185188
in
189+
186190
Unixext.mkdir_rec !Xapi_globs.local_pool_repo_dir 0o700 ;
187191
clean_yum_cache repo_name ;
188-
ignore (Helpers.call_script !Xapi_globs.reposync_cmd sync_params)
192+
ignore (Helpers.call_script (reposync_cmd ()) sync_params)
189193
)
190194
(fun () ->
191195
(* Rewrite repo conf file as initial content to remove credential related info,
@@ -595,7 +599,7 @@ let apply ~__context ~host =
595599
; "upgrade"
596600
]
597601
in
598-
try ignore (Helpers.call_script !Xapi_globs.yum_cmd params)
602+
try ignore (Helpers.call_script (Pkg_mgr.pmgr_cmd ()) params)
599603
with e ->
600604
let host' = Ref.string_of host in
601605
error "Failed to apply updates on host ref='%s': %s" host'

ocaml/xapi/repository_helpers.ml

Lines changed: 75 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -274,9 +274,18 @@ let with_updateinfo_xml gz_path f =
274274
let clean_yum_cache name =
275275
try
276276
let params =
277-
["--disablerepo=*"; Printf.sprintf "--enablerepo=%s" name; "clean"; "all"]
277+
match name with
278+
| "*" ->
279+
["clean"; "all"]
280+
| _ ->
281+
[
282+
"--disablerepo=*"
283+
; Printf.sprintf "--enablerepo=%s" name
284+
; "clean"
285+
; "all"
286+
]
278287
in
279-
ignore (Helpers.call_script !Xapi_globs.yum_cmd params)
288+
ignore (Helpers.call_script (Pkg_mgr.pmgr_cmd ()) params)
280289
with e ->
281290
warn "Unable to clean YUM cache for %s: %s" name (ExnHelper.string_of_exn e)
282291

@@ -349,8 +358,12 @@ let write_yum_config ~source_url ~binary_url ~repo_gpgcheck ~gpgkey_path
349358
)
350359

351360
let get_repo_config repo_name config_name =
352-
let config_params = [repo_name] in
353-
Helpers.call_script !Xapi_globs.yum_config_manager_cmd config_params
361+
let open Pkg_mgr in
362+
let config_params =
363+
(match active () with Yum -> [] | Dnf -> ["--dump"]) @ [repo_name]
364+
|> add_sub_cmd Repoconfig
365+
in
366+
Helpers.call_script (repoconfig_cmd ()) config_params
354367
|> Astring.String.cuts ~sep:"\n"
355368
|> List.filter_map (fun kv ->
356369
let prefix = Printf.sprintf "%s = " config_name in
@@ -434,12 +447,10 @@ let with_local_repositories ~__context f =
434447
(only to access the repo mirror in the coordinator!) *)
435448
; repo_name
436449
]
450+
|> Pkg_mgr.add_sub_cmd Pkg_mgr.Repoconfig
437451
in
438452
ignore
439-
(Helpers.call_script
440-
!Xapi_globs.yum_config_manager_cmd
441-
config_params
442-
) ;
453+
(Helpers.call_script (Pkg_mgr.repoconfig_cmd ()) config_params) ;
443454
repo_name
444455
)
445456
enabled
@@ -484,20 +495,22 @@ let parse_updateinfo_list acc line =
484495
acc
485496

486497
let is_obsoleted pkg_name repositories =
498+
let open Pkg_mgr in
487499
let params =
488500
[
489501
"-a"
490-
; "--plugins"
491502
; "--disablerepo=*"
492503
; Printf.sprintf "--enablerepo=%s" (String.concat "," repositories)
493504
; "--whatobsoletes"
494505
; pkg_name
495506
; "--qf"
496507
; "%{name}"
497508
]
509+
@ plugins ()
510+
|> add_sub_cmd Repoquery
498511
in
499512
match
500-
Helpers.call_script !Xapi_globs.repoquery_cmd params
513+
Helpers.call_script (repoquery_cmd ()) params
501514
|> Astring.String.cuts ~sep:"\n" ~empty:false
502515
with
503516
| [] ->
@@ -523,7 +536,7 @@ let get_pkgs_from_yum_updateinfo_list sub_command repositories =
523536
; sub_command
524537
]
525538
in
526-
Helpers.call_script !Xapi_globs.yum_cmd params
539+
Helpers.call_script (Pkg_mgr.pmgr_cmd ()) params
527540
|> assert_yum_error
528541
|> Astring.String.cuts ~sep:"\n"
529542
|> List.map (fun x ->
@@ -698,9 +711,20 @@ let parse_line_of_repoquery acc line =
698711
acc
699712

700713
let get_installed_pkgs () =
714+
let open Pkg_mgr in
701715
let fmt = get_repoquery_fmt () in
702-
let params = ["-a"; "--pkgnarrow=installed"; "--qf"; fmt] in
703-
Helpers.call_script !Xapi_globs.repoquery_cmd params
716+
let params =
717+
(["-a"; "--qf"; fmt]
718+
@
719+
match active () with
720+
| Yum ->
721+
["--pkgnarrow=installed"]
722+
| Dnf ->
723+
["--installed"]
724+
)
725+
|> add_sub_cmd Repoquery
726+
in
727+
Helpers.call_script (repoquery_cmd ()) params
704728
|> Astring.String.cuts ~sep:"\n"
705729
|> List.map (fun x ->
706730
debug "repoquery installed: %s" x ;
@@ -710,19 +734,27 @@ let get_installed_pkgs () =
710734
|> List.map (fun (pkg, _) -> (Pkg.to_name_arch_string pkg, pkg))
711735

712736
let get_pkgs_from_repoquery pkg_narrow repositories =
737+
let open Pkg_mgr in
713738
let fmt = get_repoquery_fmt () in
714739
let params =
715-
[
716-
"-a"
717-
; "--plugins"
718-
; "--disablerepo=*"
719-
; Printf.sprintf "--enablerepo=%s" (String.concat "," repositories)
720-
; Printf.sprintf "--pkgnarrow=%s" pkg_narrow
721-
; "--qf"
722-
; fmt
723-
]
740+
([
741+
"-a"
742+
; "--disablerepo=*"
743+
; Printf.sprintf "--enablerepo=%s" (String.concat "," repositories)
744+
; "--qf"
745+
; fmt
746+
]
747+
@
748+
match active () with
749+
| Yum ->
750+
[Printf.sprintf "--pkgnarrow=%s" pkg_narrow; "--plugins"]
751+
| Dnf ->
752+
[Printf.sprintf "--%s" pkg_narrow]
753+
)
754+
|> add_sub_cmd Repoquery
724755
in
725-
Helpers.call_script !Xapi_globs.repoquery_cmd params
756+
757+
Helpers.call_script (repoquery_cmd ()) params
726758
|> Astring.String.cuts ~sep:"\n"
727759
|> List.map (fun x ->
728760
debug "repoquery available: %s" x ;
@@ -731,9 +763,13 @@ let get_pkgs_from_repoquery pkg_narrow repositories =
731763
|> List.fold_left parse_line_of_repoquery []
732764

733765
let get_updates_from_repoquery repositories =
766+
let open Pkg_mgr in
767+
let updates_arg =
768+
match active () with Yum -> "updates" | Dnf -> "upgrades"
769+
in
734770
List.iter (fun r -> clean_yum_cache r) repositories ;
735771
(* Use 'updates' to decrease the number of packages to apply 'is_obsoleted' *)
736-
let updates = get_pkgs_from_repoquery "updates" repositories in
772+
let updates = get_pkgs_from_repoquery updates_arg repositories in
737773
(* 'new_updates' are a list of RPM packages to be installed, rather than updated *)
738774
let new_updates =
739775
get_pkgs_from_repoquery "available" repositories
@@ -936,20 +972,25 @@ module YumUpgradeOutput = struct
936972
end
937973

938974
let get_updates_from_yum_upgrade_dry_run repositories =
975+
let open Pkg_mgr in
939976
let params =
940-
[
941-
"--disablerepo=*"
942-
; Printf.sprintf "--enablerepo=%s" (String.concat "," repositories)
943-
; "--assumeno"
944-
; "--quiet"
945-
; "upgrade"
946-
]
977+
(match active () with Dnf -> [] | Yum -> ["--quiet"])
978+
@ [
979+
"--disablerepo=*"
980+
; Printf.sprintf "--enablerepo=%s" (String.concat "," repositories)
981+
; "--assumeno"
982+
; "upgrade"
983+
]
947984
in
948-
match Forkhelpers.execute_command_get_output !Xapi_globs.yum_cmd params with
985+
match Forkhelpers.execute_command_get_output (pmgr_cmd ()) params with
949986
| _, _ ->
950987
Some []
951-
| exception Forkhelpers.Spawn_internal_error (stderr, _, Unix.WEXITED 1) -> (
952-
stderr |> YumUpgradeOutput.parse_output_of_dry_run |> function
988+
| exception Forkhelpers.Spawn_internal_error (stderr, stdout, Unix.WEXITED 1)
989+
-> (
990+
(*Yum put the details to stderr while dnf to stdout*)
991+
(match active () with Yum -> stderr | Dnf -> stdout)
992+
|> YumUpgradeOutput.parse_output_of_dry_run
993+
|> function
953994
| Ok (pkgs, Some txn_file) ->
954995
Unixext.unlink_safe txn_file ;
955996
Some pkgs

ocaml/xapi/xapi_globs.ml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -909,6 +909,8 @@ let repository_domain_name_allowlist = ref []
909909

910910
let yum_cmd = ref "/usr/bin/yum"
911911

912+
let dnf_cmd = ref "/usr/bin/dnf"
913+
912914
let kpatch_cmd = ref "/usr/sbin/kpatch"
913915

914916
let xen_livepatch_cmd = ref "/usr/sbin/xen-livepatch"

ocaml/xapi/xapi_pool.ml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3406,7 +3406,9 @@ let sync_updates ~__context ~self ~force ~token ~token_id =
34063406
|> List.iter (fun repo ->
34073407
if force then cleanup_pool_repo ~__context ~self:repo ;
34083408
sync ~__context ~self:repo ~token ~token_id ;
3409-
create_pool_repository ~__context ~self:repo
3409+
if Pkg_mgr.(active () = Yum) then
3410+
(*Dnf sync all the metadata and updateinfo, no need to re-create repo*)
3411+
create_pool_repository ~__context ~self:repo
34103412
) ;
34113413
let checksum = set_available_updates ~__context in
34123414
Db.Pool.set_last_update_sync ~__context ~self ~value:(Date.now ()) ;

0 commit comments

Comments
 (0)