Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
48 changes: 48 additions & 0 deletions ocaml/tests/test_pkg_mgr.ml
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,29 @@ let test_dnf_apply_upgrades =
)
]

let test_dnf_apply_group_upgrades =
[
( "<null>"
, `Quick
, check
{
cmd= !Xapi_globs.dnf_cmd
; params=
[
"-y"
; "--disablerepo=*"
; "--enablerepo=testrepo1,testrepo2"
; "group"
; "upgrade"
; "*"
]
}
(Pkg_mgr.Dnf_cmd.apply_group_upgrade
~repositories:["testrepo1"; "testrepo2"]
)
)
]

let test_yum_repo_query_installed =
[
( "<null>"
Expand Down Expand Up @@ -286,6 +309,29 @@ let test_yum_apply_upgrades =
)
]

let test_yum_apply_group_upgrades =
[
( "<null>"
, `Quick
, check
{
cmd= !Xapi_globs.yum_cmd
; params=
[
"-y"
; "--disablerepo=*"
; "--enablerepo=testrepo1,testrepo2"
; "group"
; "upgrade"
; "*"
]
}
(Pkg_mgr.Yum_cmd.apply_group_upgrade
~repositories:["testrepo1"; "testrepo2"]
)
)
]

let test_yum_repo_query_updates =
[
( "<null>"
Expand Down Expand Up @@ -320,13 +366,15 @@ let tests =
; ("test_dnf_cofig_repo", test_dnf_config_repo)
; ("test_dnf_sync_repo", test_dnf_sync_repo)
; ("test_dnf_apply_upgrades", test_dnf_apply_upgrades)
; ("test_dnf_apply_group_upgrades", test_dnf_apply_group_upgrades)
; ("test_yum_repo_query_installed", test_yum_repo_query_installed)
; ("test_yum_clean_all_cache", test_yum_clean_all_cache)
; ("test_yum_clean_repo_cache", test_yum_clean_repo_cache)
; ("test_yum_get_pkgs_from_updateinfo", test_yum_get_pkgs_from_updateinfo)
; ("test_yum_cofig_repo", test_yum_config_repo)
; ("test_yum_sync_repo", test_yum_sync_repo)
; ("test_yum_apply_upgrades", test_yum_apply_upgrades)
; ("test_yum_apply_group_upgrades", test_yum_apply_group_upgrades)
; ("test_yum_repo_query_updates", test_yum_repo_query_updates)
]

Expand Down
42 changes: 42 additions & 0 deletions ocaml/xapi/pkg_mgr.ml
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,9 @@ module type S = sig

val get_updates_from_upgrade_dry_run : repositories:string list -> cmd_line

val get_updates_from_group_upgrade_dry_run :
repositories:string list -> cmd_line

val is_obsoleted : pkg_name:string -> repositories:string list -> cmd_line

val repoquery_updates : repositories:string list -> cmd_line
Expand All @@ -52,6 +55,8 @@ module type S = sig
val sync_repo : repo_name:string -> cmd_line

val apply_upgrade : repositories:string list -> cmd_line

val apply_group_upgrade : repositories:string list -> cmd_line
end

module type Args = sig
Expand All @@ -71,6 +76,8 @@ module type Args = sig

val get_updates_from_upgrade_dry_run : string list -> string list

val get_updates_from_group_upgrade_dry_run : string list -> string list

val is_obsoleted : string -> string list -> string list

val repoquery_updates : string list -> string list
Expand All @@ -86,6 +93,8 @@ module type Args = sig
val sync_repo : string -> string list

val apply_upgrade : string list -> string list

val apply_group_upgrade : string list -> string list
end

let repoquery_sep = ":|"
Expand Down Expand Up @@ -125,6 +134,16 @@ module Common_args = struct
; "upgrade"
]

let get_updates_from_group_upgrade_dry_run repositories =
[
"--disablerepo=*"
; Printf.sprintf "--enablerepo=%s" (String.concat "," repositories)
; "--assumeno"
; "group"
; "upgrade"
; "*"
]

let repoquery repositories =
[
"--disablerepo=*"
Expand Down Expand Up @@ -161,6 +180,16 @@ module Common_args = struct
; Printf.sprintf "--enablerepo=%s" (String.concat "," repositories)
; "upgrade"
]

let apply_group_upgrade repositories =
[
"-y"
; "--disablerepo=*"
; Printf.sprintf "--enablerepo=%s" (String.concat "," repositories)
; "group"
; "upgrade"
; "*"
]
end

module Yum_args : Args = struct
Expand All @@ -179,6 +208,10 @@ module Yum_args : Args = struct
let get_updates_from_upgrade_dry_run repositories =
["--quiet"] @ Common_args.get_updates_from_upgrade_dry_run repositories

let get_updates_from_group_upgrade_dry_run repositories =
["--quiet"]
@ Common_args.get_updates_from_group_upgrade_dry_run repositories

let is_obsoleted pkg_name repositories =
["--all"] @ Common_args.is_obsoleted pkg_name repositories @ ["--plugins"]

Expand Down Expand Up @@ -283,6 +316,12 @@ module Cmd_line (M : Args) : S = struct
let get_updates_from_upgrade_dry_run ~repositories =
{cmd= M.pkg_cmd; params= M.get_updates_from_upgrade_dry_run repositories}

let get_updates_from_group_upgrade_dry_run ~repositories =
{
cmd= M.pkg_cmd
; params= M.get_updates_from_group_upgrade_dry_run repositories
}

let is_obsoleted ~pkg_name ~repositories =
{cmd= M.repoquery_cmd; params= M.is_obsoleted pkg_name repositories}

Expand All @@ -305,6 +344,9 @@ module Cmd_line (M : Args) : S = struct

let apply_upgrade ~repositories =
{cmd= M.pkg_cmd; params= M.apply_upgrade repositories}

let apply_group_upgrade ~repositories =
{cmd= M.pkg_cmd; params= M.apply_group_upgrade repositories}
end

module Yum_cmd = Cmd_line (Yum_args)
Expand Down
7 changes: 7 additions & 0 deletions ocaml/xapi/pkg_mgr.mli
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,10 @@ module type S = sig
val get_updates_from_upgrade_dry_run : repositories:string list -> cmd_line
(** Command line and arguments to dry run an upgrade, with repositories enabled *)

val get_updates_from_group_upgrade_dry_run :
repositories:string list -> cmd_line
(** Command line and arguments to dry run a group upgrade, with repositories enabled *)

val is_obsoleted : pkg_name:string -> repositories:string list -> cmd_line
(** Command line and arguments to check whether a package is obsoleted by any other
* package in given repositories *)
Expand All @@ -67,6 +71,9 @@ module type S = sig

val apply_upgrade : repositories:string list -> cmd_line
(** Command line and arguments to apply upgrades from repos *)

val apply_group_upgrade : repositories:string list -> cmd_line
(** Command line and arguments to apply group upgrades from repos *)
end

(** Exposed only for unittest, do not use the modules directly
Expand Down
27 changes: 24 additions & 3 deletions ocaml/xapi/repository.ml
Original file line number Diff line number Diff line change
Expand Up @@ -558,6 +558,20 @@ let get_host_updates_in_json ~__context ~installed =
let latest_updates' =
get_updates_from_yum_upgrade_dry_run repositories
in
let latest_updates_group' =
get_updates_from_yum_group_upgrade_dry_run repositories
in
let latest_updates_combined' =
match (latest_updates', latest_updates_group') with
| Some pkgs', Some group_pkgs' ->
Some (List.sort_uniq compare (pkgs' @ group_pkgs'))
| Some pkgs', None ->
Some pkgs'
| None, Some group_pkgs' ->
Some group_pkgs'
| None, None ->
None
in
let latest_updates'' = get_updates_from_repoquery repositories in
(* To ensure the updating function will not strand, use redundant
* functions to get the update/installation list.
Expand All @@ -569,7 +583,7 @@ let get_host_updates_in_json ~__context ~installed =
let fail_on_error = Xapi_fist.fail_on_error_in_yum_upgrade_dry_run () in
let latest_updates =
get_latest_updates_from_redundancy ~fail_on_error
~pkgs:latest_updates' ~fallback_pkgs:latest_updates''
~pkgs:latest_updates_combined' ~fallback_pkgs:latest_updates''
in
List.iter (fun r -> clean_yum_cache r) repositories ;
let latest_updates_in_json =
Expand Down Expand Up @@ -679,8 +693,15 @@ let get_pool_updates_in_json ~__context ~hosts =
let apply ~__context ~host =
(* This function runs on member host *)
with_local_repositories ~__context (fun repositories ->
let Pkg_mgr.{cmd; params} = Pkgs.apply_upgrade ~repositories in
try ignore (Helpers.call_script cmd params)
let upgrade () =
let Pkg_mgr.{cmd; params} = Pkgs.apply_upgrade ~repositories in
ignore (Helpers.call_script cmd params)
in
let group_upgrade () =
let Pkg_mgr.{cmd; params} = Pkgs.apply_group_upgrade ~repositories in
ignore (Helpers.call_script cmd params)
in
try upgrade () ; group_upgrade ()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Minor: If upgrade () success but group_upgrade () fail, we still get the error apply_updates_failed. But I think the update is partially applied. Would you consider adding a new error and log to distinguish it?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think that the consequences of failing in upgrade or group_upgrade are the same: some RPMs have been updated and some have not. The remedy is probably also the same: just try to apply again. So I think a separate error is not very useful.

with e ->
let host' = Ref.string_of host in
error "Failed to apply updates on host ref='%s': %s" host'
Expand Down
28 changes: 28 additions & 0 deletions ocaml/xapi/repository_helpers.ml
Original file line number Diff line number Diff line change
Expand Up @@ -771,8 +771,10 @@ module YumUpgradeOutput = struct
| false -> (
take_till is_eol <* end_of_line >>= function
| ( "Installing:"
| "Installing group/module packages:"
| "Updating:"
| "Upgrading:"
| "Upgrading groups:"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Minor: Will you test the new added lines for dry_run output parser in test_repository_helpers.ml?

| "Removing:"
| "Reinstalling:"
| "Downgrading:"
Expand Down Expand Up @@ -890,6 +892,7 @@ module YumUpgradeOutput = struct
|> List.filter (fun (section, _) ->
match section with
| "Installing:"
| "Installing group/module packages:"
| "Updating:"
| "Upgrading:"
| "Installing for dependencies:"
Expand Down Expand Up @@ -958,6 +961,31 @@ let get_updates_from_yum_upgrade_dry_run repositories =
error "%s" (ExnHelper.string_of_exn e) ;
None

let get_updates_from_yum_group_upgrade_dry_run repositories =
let Pkg_mgr.{cmd; params} =
Pkgs.get_updates_from_group_upgrade_dry_run ~repositories
in
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Seems same with get_updates_from_yum_upgrade_dry_run except for the {cmd; params}. Maybe can refactor to a common function.

match Forkhelpers.execute_command_get_output cmd params with
| _, _ ->
Some []
| exception Forkhelpers.Spawn_internal_error (stderr, stdout, Unix.WEXITED 1)
-> (
(*Yum put the details to stderr while dnf to stdout*)
(match Pkgs.manager with Yum -> stderr | Dnf -> stdout)
|> YumUpgradeOutput.parse_output_of_dry_run
|> function
| Ok (pkgs, Some txn_file) ->
Unixext.unlink_safe txn_file ;
Some pkgs
| Ok (pkgs, None) ->
Some pkgs
| Error msg ->
error "%s" msg ; None
)
| exception e ->
error "%s" (ExnHelper.string_of_exn e) ;
None

let get_latest_updates_from_redundancy ~fail_on_error ~pkgs ~fallback_pkgs =
let err = "Failed to parse output of 'yum upgrade (dry run)' correctly" in
let get_latest_updates_from_redundancy' ~fail_on_error ~pkgs ~fallback_pkgs =
Expand Down
Loading