Skip to content

Commit 4338494

Browse files
authored
Merge feature branch feature/easier-pool-join (#6305)
2 parents f219fe1 + 5edbf0a commit 4338494

35 files changed

+798
-257
lines changed

ocaml/idl/datamodel.ml

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11016,6 +11016,15 @@ let http_actions =
1101611016
; ( "get_repository"
1101711017
, (Get, Constants.get_repository_uri, false, [], _R_LOCAL_ROOT_ONLY, [])
1101811018
)
11019+
; ( "get_enabled_repository"
11020+
, ( Get
11021+
, Constants.get_enabled_repository_uri
11022+
, false
11023+
, []
11024+
, _R_POOL_OP ++ _R_CLIENT_CERT
11025+
, []
11026+
)
11027+
)
1101911028
; ( "get_host_updates"
1102011029
, ( Get
1102111030
, Constants.get_host_updates_uri
@@ -11059,7 +11068,6 @@ let public_http_actions_with_no_rbac_check =
1105911068
; "post_jsonrpc"
1106011069
; "post_jsonrpc_options"
1106111070
; "get_pool_update_download"
11062-
; "get_repository"
1106311071
]
1106411072

1106511073
(* permissions not associated with any object message or field *)

ocaml/idl/datamodel_errors.ml

Lines changed: 22 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1924,11 +1924,29 @@ let _ =
19241924
error Api_errors.bundle_repo_not_enabled []
19251925
~doc:"Cannot sync bundle as the bundle repository is not enabled." () ;
19261926
error Api_errors.can_not_sync_updates []
1927-
~doc:"Cannot sync updates as the bundle repository is enabled." () ;
1928-
error Api_errors.bundle_repo_should_be_single_enabled []
19291927
~doc:
1930-
"If the bundle repository is enabled, it should be the only one enabled \
1931-
repository of the pool."
1928+
"The currently enabled repositories do not support synchronization of \
1929+
updates."
1930+
() ;
1931+
error Api_errors.can_not_periodic_sync_updates []
1932+
~doc:
1933+
"The currently enabled repositories do not support periodic automatic \
1934+
updates."
1935+
() ;
1936+
error Api_errors.repo_should_be_single_one_enabled []
1937+
~doc:
1938+
"If the bundle repository or remote_pool repository is enabled, it \
1939+
should be the only enabled repository of the pool."
1940+
() ;
1941+
error Api_errors.update_syncing_remote_pool_coordinator_connection_failed []
1942+
~doc:
1943+
"There was an error connecting to the remote pool coordinator while \
1944+
syncing updates from it."
1945+
() ;
1946+
error Api_errors.update_syncing_remote_pool_coordinator_service_failed []
1947+
~doc:
1948+
"There was an error connecting to the server while syncing updates from \
1949+
it. The service contacted didn't reply properly."
19321950
() ;
19331951
error Api_errors.repository_is_in_use [] ~doc:"The repository is in use." () ;
19341952
error Api_errors.repository_cleanup_failed []

ocaml/idl/datamodel_pool.ml

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1282,6 +1282,20 @@ let sync_updates =
12821282
; param_release= numbered_release "1.329.0"
12831283
; param_default= Some (VString "")
12841284
}
1285+
; {
1286+
param_type= String
1287+
; param_name= "username"
1288+
; param_doc= "The username of the remote pool"
1289+
; param_release= numbered_release "25.6.0-next"
1290+
; param_default= Some (VString "")
1291+
}
1292+
; {
1293+
param_type= String
1294+
; param_name= "password"
1295+
; param_doc= "The password of the remote pool"
1296+
; param_release= numbered_release "25.6.0-next"
1297+
; param_default= Some (VString "")
1298+
}
12851299
]
12861300
~result:(String, "The SHA256 hash of updateinfo.xml.gz")
12871301
~allowed_roles:(_R_POOL_OP ++ _R_CLIENT_CERT)

ocaml/idl/datamodel_repository.ml

Lines changed: 31 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ let origin =
2424
, [
2525
("remote", "The origin of the repository is a remote one")
2626
; ("bundle", "The origin of the repository is a local bundle file")
27+
; ("remote_pool", "The origin of the repository is a remote pool")
2728
]
2829
)
2930

@@ -94,6 +95,29 @@ let introduce_bundle =
9495
~allowed_roles:(_R_POOL_OP ++ _R_CLIENT_CERT)
9596
()
9697

98+
let introduce_remote_pool =
99+
call ~name:"introduce_remote_pool" ~in_oss_since:None ~lifecycle:[]
100+
~doc:"Add the configuration for a new remote pool repository"
101+
~params:
102+
[
103+
(String, "name_label", "The name of the repository")
104+
; (String, "name_description", "The description of the repository")
105+
; ( String
106+
, "binary_url"
107+
, "Base URL of binary packages in the local repository of this remote \
108+
pool in https://<coordinator-ip>"
109+
^ Constants.get_enabled_repository_uri
110+
^ " format"
111+
)
112+
; ( String
113+
, "certificate"
114+
, "The host certificate of the coordinator of the remote pool"
115+
)
116+
]
117+
~result:(Ref _repository, "The ref of the created repository record.")
118+
~allowed_roles:(_R_POOL_OP ++ _R_CLIENT_CERT)
119+
()
120+
97121
let forget =
98122
call ~name:"forget" ~in_oss_since:None
99123
~lifecycle:[(Published, "1.301.0", "")]
@@ -173,6 +197,7 @@ let t =
173197
[
174198
introduce
175199
; introduce_bundle
200+
; introduce_remote_pool
176201
; forget
177202
; apply
178203
; set_gpgkey_path
@@ -223,8 +248,12 @@ let t =
223248
"The file name of the GPG public key of this repository"
224249
; field ~qualifier:StaticRO ~lifecycle:[] ~ty:origin "origin"
225250
~default_value:(Some (VEnum "remote"))
226-
"The origin of the repository. 'remote' if the origin of the \
251+
"The origin of this repository. 'remote' if the origin of the \
227252
repository is a remote one, 'bundle' if the origin of the \
228-
repository is a local bundle file."
253+
repository is a local bundle file, 'remote_pool' if the origin of \
254+
the repository is a remote pool"
255+
; field ~qualifier:StaticRO ~lifecycle:[] ~ty:String
256+
~default_value:(Some (VString "")) "certificate"
257+
"The certificate of the host which hosts this repository"
229258
]
230259
()

ocaml/idl/schematest.ml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ let hash x = Digest.string x |> Digest.to_hex
33
(* BEWARE: if this changes, check that schema has been bumped accordingly in
44
ocaml/idl/datamodel_common.ml, usually schema_minor_vsn *)
55

6-
let last_known_schema_hash = "6f6230f87a92572b68ebd742196ffd0e"
6+
let last_known_schema_hash = "05ac9223f9c17b07b12e328d5dc3db52"
77

88
let current_schema_hash : string =
99
let open Datamodel_types in

ocaml/libs/stunnel/stunnel.ml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -157,6 +157,9 @@ let pool =
157157
; cert_bundle_path= "/etc/stunnel/xapi-pool-ca-bundle.pem"
158158
}
159159
160+
let external_host ext_host_cert_file =
161+
{sni= None; verify= VerifyPeer; cert_bundle_path= ext_host_cert_file}
162+
160163
let debug_conf_of_bool verbose : string =
161164
if verbose then "debug=authpriv.7" else "debug=authpriv.5"
162165

ocaml/libs/stunnel/stunnel.mli

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,8 @@ val appliance : verification_config
5959

6060
val pool : verification_config
6161

62+
val external_host : string -> verification_config
63+
6264
val with_connect :
6365
?unique_id:int
6466
-> ?use_fork_exec_helper:bool

ocaml/libs/stunnel/stunnel_client.ml

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,12 @@ let set_verify_by_default = function
2626
D.info "enabling default tls verification" ;
2727
verify := true
2828

29-
let pool () = match !verify with true -> Some Stunnel.pool | false -> None
29+
let get_verification_config config =
30+
match !verify with true -> Some config | false -> None
3031

31-
let appliance () =
32-
match !verify with true -> Some Stunnel.appliance | false -> None
32+
let pool () = get_verification_config Stunnel.pool
33+
34+
let appliance () = get_verification_config Stunnel.appliance
35+
36+
let external_host cert_file =
37+
Stunnel.external_host cert_file |> get_verification_config

ocaml/libs/stunnel/stunnel_client.mli

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,3 +19,5 @@ val set_verify_by_default : bool -> unit
1919
val pool : unit -> Stunnel.verification_config option
2020

2121
val appliance : unit -> Stunnel.verification_config option
22+
23+
val external_host : string -> Stunnel.verification_config option

ocaml/tests/test_pool_repository.ml

Lines changed: 82 additions & 80 deletions
Original file line numberDiff line numberDiff line change
@@ -14,101 +14,103 @@
1414

1515
module T = Test_common
1616

17-
let test_set_remote_and_bundle_repos () =
17+
let on_repositories f =
1818
let __context = T.make_test_database () in
19-
let name_label = "remote" in
20-
let name_description = "remote" in
21-
let binary_url = "https://repo.example.com" in
19+
let pool = Helpers.get_pool ~__context in
20+
let binary_url_1 = "https://repo.example.com" in
21+
let binary_url_2 = "https://1.1.1.1/repository/enabled" in
2222
let source_url = "https://repo-src.example.com" in
23-
let gpgkey_path = "" in
2423
let ref_remote =
25-
Repository.introduce ~__context ~name_label ~name_description ~binary_url
26-
~source_url ~update:true ~gpgkey_path
24+
Repository.introduce ~__context ~name_label:"remote"
25+
~name_description:"remote" ~binary_url:binary_url_1 ~source_url
26+
~update:true ~gpgkey_path:""
2727
in
2828
let ref_bundle =
2929
Repository.introduce_bundle ~__context ~name_label:"bundle"
3030
~name_description:"bundle"
3131
in
32-
let self = Helpers.get_pool ~__context in
33-
Alcotest.check_raises "test_set_remote_and_bundle_repos"
34-
Api_errors.(Server_error (bundle_repo_should_be_single_enabled, []))
35-
(fun () ->
36-
Xapi_pool.set_repositories ~__context ~self
37-
~value:[ref_remote; ref_bundle]
38-
)
39-
40-
let test_add_bundle_repo () =
41-
let __context = T.make_test_database () in
42-
let name_label = "remote" in
43-
let name_description = "remote" in
44-
let binary_url = "https://repo.example.com" in
45-
let source_url = "https://repo-src.example.com" in
46-
let gpgkey_path = "" in
47-
let ref_remote =
48-
Repository.introduce ~__context ~name_label ~name_description ~binary_url
49-
~source_url ~update:true ~gpgkey_path
32+
let ref_remote_pool =
33+
Repository.introduce_remote_pool ~__context ~name_label:"remote_pool"
34+
~binary_url:binary_url_2 ~name_description:"remote_pool" ~certificate:""
5035
in
51-
let ref_bundle =
52-
Repository.introduce_bundle ~__context ~name_label:"bundle"
53-
~name_description:"bundle"
54-
in
55-
let self = Helpers.get_pool ~__context in
56-
Alcotest.check_raises "test_add_bundle_repo"
57-
Api_errors.(Server_error (bundle_repo_should_be_single_enabled, []))
58-
(fun () ->
59-
Xapi_pool.set_repositories ~__context ~self ~value:[ref_remote] ;
60-
Xapi_pool.add_repository ~__context ~self ~value:ref_bundle
61-
)
36+
f __context pool ref_remote ref_bundle ref_remote_pool
6237

63-
let test_add_remote_repo () =
64-
let __context = T.make_test_database () in
65-
let name_label = "remote" in
66-
let name_description = "remote" in
67-
let binary_url = "https://repo.example.com" in
68-
let source_url = "https://repo-src.example.com" in
69-
let gpgkey_path = "" in
70-
let ref_remote =
71-
Repository.introduce ~__context ~name_label ~name_description ~binary_url
72-
~source_url ~update:true ~gpgkey_path
73-
in
74-
let ref_bundle =
75-
Repository.introduce_bundle ~__context ~name_label:"bundle"
76-
~name_description:"bundle"
77-
in
78-
let self = Helpers.get_pool ~__context in
79-
Alcotest.check_raises "test_add_remote_repo"
80-
Api_errors.(Server_error (bundle_repo_should_be_single_enabled, []))
81-
(fun () ->
38+
let test_set_repositories () =
39+
on_repositories (fun __context self ref_remote ref_bundle ref_remote_pool ->
40+
Xapi_pool.set_repositories ~__context ~self ~value:[ref_remote] ;
8241
Xapi_pool.set_repositories ~__context ~self ~value:[ref_bundle] ;
83-
Xapi_pool.add_repository ~__context ~self ~value:ref_remote
84-
)
42+
Xapi_pool.set_repositories ~__context ~self ~value:[ref_remote_pool] ;
43+
Alcotest.check_raises "test_set_repositories_1"
44+
Api_errors.(Server_error (repo_should_be_single_one_enabled, []))
45+
(fun () ->
46+
Xapi_pool.set_repositories ~__context ~self
47+
~value:[ref_remote; ref_bundle]
48+
) ;
49+
Alcotest.check_raises "test_set_repositories_2"
50+
Api_errors.(Server_error (repo_should_be_single_one_enabled, []))
51+
(fun () ->
52+
Xapi_pool.set_repositories ~__context ~self
53+
~value:[ref_remote_pool; ref_bundle]
54+
) ;
55+
Alcotest.check_raises "test_set_repositories_3"
56+
Api_errors.(Server_error (repo_should_be_single_one_enabled, []))
57+
(fun () ->
58+
Xapi_pool.set_repositories ~__context ~self
59+
~value:[ref_remote; ref_remote_pool]
60+
)
61+
)
8562

86-
let test_can_not_enable_bundle_repo_auto_sync () =
87-
let __context = T.make_test_database () in
88-
let ref_bundle =
89-
Repository.introduce_bundle ~__context ~name_label:"bundle"
90-
~name_description:"bundle"
91-
in
92-
let self = Helpers.get_pool ~__context in
93-
Alcotest.check_raises "test_can_not_enable_bundle_repo_auto_sync"
94-
Api_errors.(Server_error (can_not_sync_updates, []))
95-
(fun () ->
96-
Xapi_pool.set_repositories ~__context ~self ~value:[ref_bundle] ;
97-
Xapi_pool.set_update_sync_enabled ~__context ~self ~value:true
98-
)
63+
let test_add_repository () =
64+
on_repositories (fun __context self ref_remote ref_bundle ref_remote_pool ->
65+
Alcotest.check_raises "test_add_repository_1"
66+
Api_errors.(Server_error (repo_should_be_single_one_enabled, []))
67+
(fun () ->
68+
Xapi_pool.set_repositories ~__context ~self ~value:[ref_remote] ;
69+
Xapi_pool.add_repository ~__context ~self ~value:ref_bundle
70+
) ;
71+
Alcotest.check_raises "test_add_repository_2"
72+
Api_errors.(Server_error (repo_should_be_single_one_enabled, []))
73+
(fun () ->
74+
Xapi_pool.set_repositories ~__context ~self ~value:[ref_remote] ;
75+
Xapi_pool.add_repository ~__context ~self ~value:ref_remote_pool
76+
) ;
77+
Alcotest.check_raises "test_add_repository_3"
78+
Api_errors.(Server_error (repo_should_be_single_one_enabled, []))
79+
(fun () ->
80+
Xapi_pool.set_repositories ~__context ~self ~value:[ref_remote_pool] ;
81+
Xapi_pool.add_repository ~__context ~self ~value:ref_bundle
82+
) ;
83+
Alcotest.check_raises "test_add_repository_4"
84+
Api_errors.(Server_error (repo_should_be_single_one_enabled, []))
85+
(fun () ->
86+
Xapi_pool.set_repositories ~__context ~self ~value:[ref_bundle] ;
87+
Xapi_pool.add_repository ~__context ~self ~value:ref_remote_pool
88+
)
89+
)
90+
91+
let test_enable_periodic_repo_sync () =
92+
on_repositories (fun __context self ref_remote ref_bundle ref_remote_pool ->
93+
Xapi_pool.set_repositories ~__context ~self ~value:[ref_remote] ;
94+
Xapi_pool.set_update_sync_enabled ~__context ~self ~value:true ;
95+
Alcotest.check_raises "test_enable_periodic_repo_sync_1"
96+
Api_errors.(Server_error (can_not_periodic_sync_updates, []))
97+
(fun () ->
98+
Xapi_pool.set_repositories ~__context ~self ~value:[ref_bundle] ;
99+
Xapi_pool.set_update_sync_enabled ~__context ~self ~value:true
100+
) ;
101+
Alcotest.check_raises "test_enable_periodic_repo_sync_2"
102+
Api_errors.(Server_error (can_not_periodic_sync_updates, []))
103+
(fun () ->
104+
Xapi_pool.set_repositories ~__context ~self ~value:[ref_remote_pool] ;
105+
Xapi_pool.set_update_sync_enabled ~__context ~self ~value:true
106+
)
107+
)
99108

100109
let test =
101110
[
102-
( "test_set_remote_and_bundle_repos"
103-
, `Quick
104-
, test_set_remote_and_bundle_repos
105-
)
106-
; ("test_add_bundle_repo", `Quick, test_add_bundle_repo)
107-
; ("test_add_remote_repo", `Quick, test_add_remote_repo)
108-
; ( "test_can_not_enable_bundle_repo_auto_sync"
109-
, `Quick
110-
, test_can_not_enable_bundle_repo_auto_sync
111-
)
111+
("test_set_repositories", `Quick, test_set_repositories)
112+
; ("test_add_repository", `Quick, test_add_repository)
113+
; ("test_enable_periodic_repo_sync", `Quick, test_enable_periodic_repo_sync)
112114
]
113115

114116
let () =

0 commit comments

Comments
 (0)