From 62201478aa44921d3a596f469432211c9adbb38a Mon Sep 17 00:00:00 2001 From: Bengang Yuan Date: Mon, 15 Jul 2024 10:48:33 +0800 Subject: [PATCH] CP-49212: Update datamodel for non-CDN update Add a field "origin" in "repository" to indicate the origin of the repository. It's an enum type with 2 values: "remote" and "bundle". Signed-off-by: Bengang Yuan --- ocaml/idl/datamodel_repository.ml | 38 +++++++++++++++++++++++-- ocaml/idl/schematest.ml | 2 +- ocaml/xapi-cli-server/cli_frontend.ml | 11 ++++++- ocaml/xapi-cli-server/cli_operations.ml | 15 ++++++++-- ocaml/xapi-cli-server/record_util.ml | 2 ++ ocaml/xapi-cli-server/records.ml | 5 ++++ ocaml/xapi/message_forwarding.ml | 6 ++++ ocaml/xapi/repository.ml | 35 +++++++++++++++++++---- ocaml/xapi/repository.mli | 6 ++++ ocaml/xapi/repository_helpers.ml | 16 +++++++---- ocaml/xapi/xapi_globs.ml | 4 +++ 11 files changed, 123 insertions(+), 17 deletions(-) diff --git a/ocaml/idl/datamodel_repository.ml b/ocaml/idl/datamodel_repository.ml index 02b17f509e0..114242d913f 100644 --- a/ocaml/idl/datamodel_repository.ml +++ b/ocaml/idl/datamodel_repository.ml @@ -18,10 +18,19 @@ open Datamodel_roles let lifecycle = [(Lifecycle.Published, "1.301.0", "")] +let origin = + Enum + ( "origin" + , [ + ("remote", "The origin of the repository is a remote one") + ; ("bundle", "The origin of the repository is a local bundle file") + ] + ) + let introduce = call ~name:"introduce" ~in_oss_since:None ~lifecycle:[(Published, "1.301.0", "")] - ~doc:"Add the configuration for a new repository" + ~doc:"Add the configuration for a new remote repository" ~versioned_params: [ { @@ -73,6 +82,18 @@ let introduce = ~allowed_roles:(_R_POOL_OP ++ _R_CLIENT_CERT) () +let introduce_bundle = + call ~name:"introduce_bundle" ~in_oss_since:None ~lifecycle:[] + ~doc:"Add the configuration for a new bundle repository" + ~params: + [ + (String, "name_label", "The name of the repository") + ; (String, "name_description", "The description of the repository") + ] + ~result:(Ref _repository, "The ref of the created repository record.") + ~allowed_roles:(_R_POOL_OP ++ _R_CLIENT_CERT) + () + let forget = call ~name:"forget" ~in_oss_since:None ~lifecycle:[(Published, "1.301.0", "")] @@ -148,7 +169,15 @@ let t = ~lifecycle:[(Published, "1.301.0", "")] ~persist:PersistEverything ~in_oss_since:None ~messages_default_allowed_roles:(_R_POOL_OP ++ _R_CLIENT_CERT) - ~messages:[introduce; forget; apply; set_gpgkey_path; apply_livepatch] + ~messages: + [ + introduce + ; introduce_bundle + ; forget + ; apply + ; set_gpgkey_path + ; apply_livepatch + ] ~contents: [ uid _repository ~lifecycle:[(Published, "1.301.0", "")] @@ -187,5 +216,10 @@ let t = ; field ~qualifier:StaticRO ~lifecycle:[] ~ty:String ~default_value:(Some (VString "")) "gpgkey_path" "The file name of the GPG public key of this repository" + ; field ~qualifier:StaticRO ~lifecycle:[] ~ty:origin "origin" + ~default_value:(Some (VEnum "remote")) + "The origin of the repository. 'remote' if the origin of the \ + repository is a remote one, 'bundle' if the origin of the \ + repository is a local bundle file." ] () diff --git a/ocaml/idl/schematest.ml b/ocaml/idl/schematest.ml index 4ba16fbfe1c..6091444dcc9 100644 --- a/ocaml/idl/schematest.ml +++ b/ocaml/idl/schematest.ml @@ -3,7 +3,7 @@ let hash x = Digest.string x |> Digest.to_hex (* BEWARE: if this changes, check that schema has been bumped accordingly in ocaml/idl/datamodel_common.ml, usually schema_minor_vsn *) -let last_known_schema_hash = "7885f7b085e4a5e32977a4b222030412" +let last_known_schema_hash = "2a6baa01032827a321845b264c6aaae4" let current_schema_hash : string = let open Datamodel_types in diff --git a/ocaml/xapi-cli-server/cli_frontend.ml b/ocaml/xapi-cli-server/cli_frontend.ml index 1c71177c3c8..e735d4793ca 100644 --- a/ocaml/xapi-cli-server/cli_frontend.ml +++ b/ocaml/xapi-cli-server/cli_frontend.ml @@ -3659,11 +3659,20 @@ let rec cmdtable_data : (string * cmd_spec) list = , { reqd= ["name-label"; "binary-url"; "source-url"; "update"] ; optn= ["name-description"; "gpgkey-path"] - ; help= "Add the configuration for a new repository." + ; help= "Add the configuration for a new remote repository." ; implementation= No_fd Cli_operations.Repository.introduce ; flags= [] } ) + ; ( "repository-introduce-bundle" + , { + reqd= ["name-label"] + ; optn= ["name-description"] + ; help= "Add the configuration for a new bundle repository." + ; implementation= No_fd Cli_operations.Repository.introduce_bundle + ; flags= [] + } + ) ; ( "repository-forget" , { reqd= ["uuid"] diff --git a/ocaml/xapi-cli-server/cli_operations.ml b/ocaml/xapi-cli-server/cli_operations.ml index 83f10a7a46d..93d0c69f41f 100644 --- a/ocaml/xapi-cli-server/cli_operations.ml +++ b/ocaml/xapi-cli-server/cli_operations.ml @@ -1318,6 +1318,7 @@ let gen_cmds rpc session_id = ; "hash" ; "up-to-date" ; "gpgkey-path" + ; "origin" ] rpc session_id ) @@ -7934,9 +7935,7 @@ end module Repository = struct let introduce printer rpc session_id params = let name_label = List.assoc "name-label" params in - let name_description = - try List.assoc "name-description" params with Not_found -> "" - in + let name_description = get_param params "name-description" ~default:"" in let binary_url = List.assoc "binary-url" params in let source_url = List.assoc "source-url" params in let update = get_bool_param params "update" in @@ -7948,6 +7947,16 @@ module Repository = struct let uuid = Client.Repository.get_uuid ~rpc ~session_id ~self:ref in printer (Cli_printer.PList [uuid]) + let introduce_bundle printer rpc session_id params = + let name_label = List.assoc "name-label" params in + let name_description = get_param params "name-description" ~default:"" in + let ref = + Client.Repository.introduce_bundle ~rpc ~session_id ~name_label + ~name_description + in + let uuid = Client.Repository.get_uuid ~rpc ~session_id ~self:ref in + printer (Cli_printer.PList [uuid]) + let forget _printer rpc session_id params = let ref = Client.Repository.get_by_uuid ~rpc ~session_id diff --git a/ocaml/xapi-cli-server/record_util.ml b/ocaml/xapi-cli-server/record_util.ml index 105615fedfd..8e0bb1aaef2 100644 --- a/ocaml/xapi-cli-server/record_util.ml +++ b/ocaml/xapi-cli-server/record_util.ml @@ -1145,3 +1145,5 @@ let vm_placement_policy_of_string a = `anti_affinity | s -> record_failure "Invalid VM placement policy, got %s" s + +let repo_origin_to_string = function `remote -> "remote" | `bundle -> "bundle" diff --git a/ocaml/xapi-cli-server/records.ml b/ocaml/xapi-cli-server/records.ml index abcd5f3fb1c..f75809bf592 100644 --- a/ocaml/xapi-cli-server/records.ml +++ b/ocaml/xapi-cli-server/records.ml @@ -5370,6 +5370,11 @@ let repository_record rpc session_id repository = ~value:x ) () + ; make_field ~name:"origin" + ~get:(fun () -> + Record_util.repo_origin_to_string (x ()).API.repository_origin + ) + () ] } diff --git a/ocaml/xapi/message_forwarding.ml b/ocaml/xapi/message_forwarding.ml index 34e420259b8..716274759ee 100644 --- a/ocaml/xapi/message_forwarding.ml +++ b/ocaml/xapi/message_forwarding.ml @@ -6560,6 +6560,12 @@ functor Local.Repository.introduce ~__context ~name_label ~name_description ~binary_url ~source_url ~update ~gpgkey_path + let introduce_bundle ~__context ~name_label ~name_description = + info "Repository.introduce_bundle: name = '%s'; name_description = '%s'" + name_label name_description ; + Local.Repository.introduce_bundle ~__context ~name_label + ~name_description + let forget ~__context ~self = info "Repository.forget: self = '%s'" (repository_uuid ~__context self) ; Local.Repository.forget ~__context ~self diff --git a/ocaml/xapi/repository.ml b/ocaml/xapi/repository.ml index bd63984c0a1..b3c2266d8ae 100644 --- a/ocaml/xapi/repository.ml +++ b/ocaml/xapi/repository.ml @@ -44,7 +44,22 @@ let introduce ~__context ~name_label ~name_description ~binary_url ~source_url ) ) ; create_repository_record ~__context ~name_label ~name_description ~binary_url - ~source_url ~update ~gpgkey_path + ~source_url ~update ~gpgkey_path ~origin:`remote + +let introduce_bundle ~__context ~name_label ~name_description = + Db.Repository.get_all ~__context + |> List.iter (fun ref -> + if + name_label = Db.Repository.get_name_label ~__context ~self:ref + || Db.Repository.get_origin ~__context ~self:ref = `bundle + then + raise + Api_errors.( + Server_error (repository_already_exists, [Ref.string_of ref]) + ) + ) ; + create_repository_record ~__context ~name_label ~name_description + ~binary_url:"" ~source_url:"" ~update:true ~gpgkey_path:"" ~origin:`bundle let forget ~__context ~self = let pool = Helpers.get_pool ~__context in @@ -112,8 +127,18 @@ let sync ~__context ~self ~token ~token_id = try let repo_name = get_remote_repository_name ~__context ~self in remove_repo_conf_file repo_name ; - let binary_url = Db.Repository.get_binary_url ~__context ~self in - let source_url = Db.Repository.get_source_url ~__context ~self in + let binary_url, source_url = + match Db.Repository.get_origin ~__context ~self with + | `remote -> + ( Db.Repository.get_binary_url ~__context ~self + , Some (Db.Repository.get_source_url ~__context ~self) + ) + | `bundle -> + let uri = + Uri.make ~scheme:"file" ~path:!Xapi_globs.bundle_repository_dir () + in + (Uri.to_string uri, None) + in let gpgkey_path = match Db.Repository.get_gpgkey_path ~__context ~self with | "" -> @@ -122,8 +147,8 @@ let sync ~__context ~self ~token ~token_id = s in let write_initial_yum_config () = - write_yum_config ~source_url:(Some source_url) ~binary_url - ~repo_gpgcheck:true ~gpgkey_path ~repo_name + write_yum_config ~source_url ~binary_url ~repo_gpgcheck:true ~gpgkey_path + ~repo_name in write_initial_yum_config () ; clean_yum_cache repo_name ; diff --git a/ocaml/xapi/repository.mli b/ocaml/xapi/repository.mli index 8b8ee7e09cd..e7bddad8bad 100644 --- a/ocaml/xapi/repository.mli +++ b/ocaml/xapi/repository.mli @@ -22,6 +22,12 @@ val introduce : -> gpgkey_path:string -> [`Repository] API.Ref.t +val introduce_bundle : + __context:Context.t + -> name_label:string + -> name_description:string + -> [`Repository] API.Ref.t + val forget : __context:Context.t -> self:[`Repository] API.Ref.t -> unit val cleanup_all_pool_repositories : unit -> unit diff --git a/ocaml/xapi/repository_helpers.ml b/ocaml/xapi/repository_helpers.ml index f67e8647822..71bf53ed1e3 100644 --- a/ocaml/xapi/repository_helpers.ml +++ b/ocaml/xapi/repository_helpers.ml @@ -134,11 +134,12 @@ module GuidanceSet = struct end let create_repository_record ~__context ~name_label ~name_description - ~binary_url ~source_url ~update ~gpgkey_path = + ~binary_url ~source_url ~update ~gpgkey_path ~origin = let ref = Ref.make () in let uuid = Uuidx.(to_string (make ())) in Db.Repository.create ~__context ~ref ~uuid ~name_label ~name_description - ~binary_url ~source_url ~update ~hash:"" ~up_to_date:false ~gpgkey_path ; + ~binary_url ~source_url ~update ~hash:"" ~up_to_date:false ~gpgkey_path + ~origin ; ref module DomainNameIncludeIP = struct @@ -377,9 +378,14 @@ let get_repository_name ~__context ~self = Db.Repository.get_uuid ~__context ~self let get_remote_repository_name ~__context ~self = - !Xapi_globs.remote_repository_prefix - ^ "-" - ^ get_repository_name ~__context ~self + let prefix = + match Db.Repository.get_origin ~__context ~self with + | `remote -> + !Xapi_globs.remote_repository_prefix + | `bundle -> + !Xapi_globs.bundle_repository_prefix + in + prefix ^ "-" ^ get_repository_name ~__context ~self let get_local_repository_name ~__context ~self = !Xapi_globs.local_repository_prefix diff --git a/ocaml/xapi/xapi_globs.ml b/ocaml/xapi/xapi_globs.ml index 1e03882ead1..a21226cf075 100644 --- a/ocaml/xapi/xapi_globs.ml +++ b/ocaml/xapi/xapi_globs.ml @@ -925,6 +925,8 @@ let yum_repos_config_dir = ref "/etc/yum.repos.d" let remote_repository_prefix = ref "remote" +let bundle_repository_prefix = ref "bundle" + let local_repository_prefix = ref "local" let yum_config_manager_cmd = ref "/usr/bin/yum-config-manager" @@ -945,6 +947,8 @@ let repository_gpgkey_name = ref "" let repository_gpgcheck = ref true +let bundle_repository_dir = ref "/var/xapi/bundle-repo" + let observer_config_dir = "/etc/xensource/observer" let ignore_vtpm_unimplemented = ref false