Skip to content

Commit 13a2dc0

Browse files
authored
Merge pull request xapi-project#226 from gaborigloi/ely-merge
Merge commits from the (current) master branch that should go into Ely. Commits have been re-based and old merge commits have been removed.
2 parents b0ef782 + efda7f0 commit 13a2dc0

16 files changed

+114
-29
lines changed

.gitarchive-info

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
Changeset: $Format:%H$
2+
Commit date: $Format:%cD$

.gitattributes

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
.gitarchive-info export-subst

ocaml/idl/datamodel.ml

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1208,11 +1208,11 @@ let _ =
12081208
~doc:"This update has already been applied to all hosts in the pool." ();
12091209
error Api_errors.update_precheck_failed_unknown_error [ "update"; "info" ]
12101210
~doc:"The update precheck stage failed with an unknown error." ();
1211-
error Api_errors.update_precheck_failed_prerequisite_missing [ "update"; "info" ]
1211+
error Api_errors.update_precheck_failed_prerequisite_missing [ "update"; "prerequisite_update" ]
12121212
~doc:"The update precheck stage failed: prerequisite update(s) are missing." ();
1213-
error Api_errors.update_precheck_failed_conflict_present ["update"; "info"]
1214-
~doc:"The update precheck stage failed: conflicting updates are present." ();
1215-
error Api_errors.update_precheck_failed_wrong_server_version ["update"; "info"]
1213+
error Api_errors.update_precheck_failed_conflict_present ["update"; "conflict_update"]
1214+
~doc:"The update precheck stage failed: conflicting update(s) are present." ();
1215+
error Api_errors.update_precheck_failed_wrong_server_version ["update"; "installed_version"; "required_version "]
12161216
~doc:"The update precheck stage failed: the server is of an incorrect version." ();
12171217
error Api_errors.update_precheck_failed_out_of_space ["update"; "available_space"; "required_space "]
12181218
~doc:"The update precheck stage failed: the server does not have enough space." ();
@@ -3241,10 +3241,11 @@ let host_set_localdb_key = call
32413241

32423242
let host_refresh_pack_info = call
32433243
~name:"refresh_pack_info"
3244-
~in_product_since:rel_midnight_ride
32453244
~doc:"Refresh the list of installed Supplemental Packs."
32463245
~params:[Ref _host, "host", "The Host to modify"]
32473246
~allowed_roles:_R_POOL_OP
3247+
~lifecycle:[Published, rel_midnight_ride, "";
3248+
Deprecated, rel_ely, "Use Pool_update.resync_host instead"]
32483249
()
32493250

32503251
(* ------------------------------------------------------------------------------------------------------------

ocaml/xapi/cli_frontend.ml

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -959,6 +959,15 @@ let rec cmdtable_data : (string*cmd_spec) list =
959959
flags=[];
960960
};
961961

962+
"update-resync-host",
963+
{
964+
reqd=["host-uuid"];
965+
optn=[];
966+
help="Refreshes Host.updates";
967+
implementation=No_fd Cli_operations.update_resync_host;
968+
flags=[Hidden];
969+
};
970+
962971
"user-password-change",
963972
{
964973
reqd=["new"];

ocaml/xapi/cli_operations.ml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4837,3 +4837,8 @@ let update_destroy printer rpc session_id params =
48374837
let uuid = List.assoc "uuid" params in
48384838
let ref = Client.Pool_update.get_by_uuid rpc session_id uuid in
48394839
Client.Pool_update.destroy rpc session_id ref
4840+
4841+
let update_resync_host printer rpc session_id params =
4842+
let uuid = List.assoc "host-uuid" params in
4843+
let host = Client.Host.get_by_uuid rpc session_id uuid in
4844+
Client.Pool_update.resync_host rpc session_id host

ocaml/xapi/xapi_pool_patch.ml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,7 @@ let pool_patch_upload_handler (req: Http.Request.t) s _ =
6565
Db.Task.set_result ~__context ~self:(Context.get_task_id __context) ~value:(Ref.string_of patch);
6666
TaskHelper.complete ~__context None
6767
with e ->
68+
Client.VDI.destroy rpc session_id vdi;
6869
TaskHelper.failed ~__context e
6970
end
7071
| None ->

ocaml/xapi/xapi_pool_update.ml

Lines changed: 32 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -144,20 +144,27 @@ let detach ~__context ~self =
144144
detach_helper ~__context ~uuid ~vdi
145145

146146
let with_api_errors f x =
147+
let errinfo = "Please upload a valid package." in
147148
try f x
148149
with
149150
| Smint.Command_failed(ret, status, stdout_log, stderr_log)
150151
| Smint.Command_killed(ret, status, stdout_log, stderr_log) ->
151152
let msg = Printf.sprintf "Smint.Command_{failed,killed} ret = %d; status = %s; stdout = %s; stderr = %s"
152153
ret status stdout_log stderr_log in
153-
raise (Api_errors.Server_error (Api_errors.internal_error, [msg]))
154+
error "%s" msg;
155+
raise (Api_errors.Server_error (Api_errors.invalid_update, [errinfo]))
156+
| e ->
157+
let msg = ExnHelper.string_of_exn e in
158+
error "%s" msg;
159+
raise (Api_errors.Server_error (Api_errors.invalid_update, [errinfo]))
154160

155161
(* yum confif example
156162
[main]
157163
keepcache=0
158164
reposdir=/dev/null
159165
gpgcheck=$signed
160166
repo_gpgcheck=$signed
167+
installonlypkgs=
161168
162169
[$label]
163170
name=$label
@@ -170,9 +177,19 @@ let create_yum_config ~__context ~self ~url =
170177
let signed = String.length key <> 0 in
171178
let signed_index = if signed then 1 else 0 in
172179
let name_label = Db.Pool_update.get_name_label ~__context ~self in
173-
(Printf.sprintf ("[main]\nkeepcache=0\nreposdir=/dev/null\ngpgcheck=%d\nrepo_gpgcheck=%d\n\n") signed_index signed_index)
174-
^(Printf.sprintf ("[%s]\nname=%s\nbaseurl=%s\n") name_label name_label url)
175-
^(if signed then Printf.sprintf ("gpgkey=file:///etc/pki/rpm-gpg/%s") key else "")
180+
String.concat "\n"
181+
[ "[main]"
182+
; "keepcache=0"
183+
; "reposdir=/dev/null"
184+
; Printf.sprintf "gpgcheck=%d" signed_index
185+
; Printf.sprintf "repo_gpgcheck=%d" signed_index
186+
; "installonlypkgs="
187+
; ""
188+
; Printf.sprintf "[%s]" name_label
189+
; Printf.sprintf "name=%s" name_label
190+
; Printf.sprintf "baseurl=%s" url
191+
; if signed then Printf.sprintf ("gpgkey=file:///etc/pki/rpm-gpg/%s") key else ""
192+
]
176193

177194
let attach_helper ~__context ~uuid ~vdi =
178195
let host = Helpers.get_localhost ~__context in
@@ -445,7 +462,17 @@ let resync_host ~__context ~host =
445462
) update_refs;
446463
Create_misc.create_updates_requiring_reboot_info ~__context ~host
447464
end
448-
else Db.Host.set_updates ~__context ~self:host ~value:[]
465+
else Db.Host.set_updates ~__context ~self:host ~value:[];
466+
467+
(* Remove any pool_patch objects that don't have a corresponding pool_update object *)
468+
Db.Pool_patch.get_all ~__context
469+
|> List.filter (fun self -> Db.Pool_patch.get_pool_update ~__context ~self = Ref.null)
470+
|> List.iter (fun self -> Db.Pool_patch.destroy ~__context ~self);
471+
472+
(* Clean updates that don't have a corresponding patch record *)
473+
Db.Pool_update.get_all ~__context
474+
|> List.filter (fun self -> Xapi_pool_patch.pool_patch_of_update ~__context self = Ref.null)
475+
|> List.iter (fun self -> destroy ~__context ~self)
449476

450477
let pool_update_download_handler (req: Request.t) s _ =
451478
debug "pool_update.pool_update_download_handler URL %s" req.Request.uri;

scripts/OMakefile

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,3 @@ install:
132132
mkdir -p $(DESTDIR)/etc/cron.d
133133
$(IDATA) xapi-logrotate.cron $(DESTDIR)/etc/cron.d/xapi-logrotate.cron
134134
mkdir -p $(DESTDIR)/opt/xensource/gpg
135-
$(IDATA) gpg/secring.gpg $(DESTDIR)/opt/xensource/gpg/
136-
$(IDATA) gpg/pubring.gpg $(DESTDIR)/opt/xensource/gpg/
137-
$(IDATA) gpg/trustdb.gpg $(DESTDIR)/opt/xensource/gpg/

scripts/extensions/pool_update.apply

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,9 @@ def failure_message(code, params):
4545

4646
def execute_apply(session, update_package, yum_conf_file):
4747
cmd = ['yum', 'install', '-y', '--noplugins', '-c', yum_conf_file, update_package]
48-
p = subprocess.Popen(cmd, shell=False, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, close_fds=True)
48+
yum_env = os.environ.copy()
49+
yum_env['LANG'] = 'C'
50+
p = subprocess.Popen(cmd, shell=False, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, close_fds=True, env=yum_env)
4951
output, _ = p.communicate()
5052
xcp.logger.info('pool_update.apply %r returncode=%r output=%r', cmd, p.returncode, output)
5153
if p.returncode != 0:

scripts/extensions/pool_update.precheck

Lines changed: 38 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -25,11 +25,14 @@ UPDATE_PRECHECK_FAILED_PREREQUISITE_MISSING = 'UPDATE_PRECHECK_FAILED_PREREQUISI
2525
UPDATE_PRECHECK_FAILED_CONFLICT_PRESENT = 'UPDATE_PRECHECK_FAILED_CONFLICT_PRESENT'
2626
UPDATE_PRECHECK_FAILED_WRONG_SERVER_VERSION = 'UPDATE_PRECHECK_FAILED_WRONG_SERVER_VERSION'
2727
UPDATE_PRECHECK_FAILED_OUT_OF_SPACE = 'UPDATE_PRECHECK_FAILED_OUT_OF_SPACE'
28+
UPDATE_PREFIX = 'update-'
2829
INVALID_UPDATE = 'INVALID_UPDATE'
2930
CANNOT_FIND_UPDATE = 'CANNOT_FIND_UPDATE'
3031
ERROR_MESSAGE_START = 'Error: '
3132
ERROR_MESSAGE_END = 'You could try '
32-
ERROR_MESSAGE_CONFLICT = ' conflicts with '
33+
ERROR_MESSAGE_CONFLICTS_WITH = ' conflicts with '
34+
ERROR_MESSAGE_CONFLICTS = 'conflicts '
35+
ERROR_MESSAGE_PROCESSING_CONFLICT = '--> Processing Conflict:'
3336
ERROR_MESSAGE_PREREQUISITE = 'Requires: '
3437
ERROR_MESSAGE_VERSION_REQUIRED = 'Requires: '
3538
ERROR_MESSAGE_VERSION_INSTALLED = 'Installed: '
@@ -80,7 +83,9 @@ def execute_precheck(session, control_package, yum_conf_file, update_precheck_fi
8083
'PATCH_PRECHECK_LIVEPATCH_INCOMPLETE': 'ok_livepatch_incomplete',
8184
'PATCH_PRECHECK_LIVEPATCH_NOT_APPLICABLE': 'ok'}
8285
cmd = ['yum', 'install', '-y', '--noplugins', '-c', yum_conf_file, control_package]
83-
p = subprocess.Popen(cmd, shell=False, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, close_fds=True)
86+
yum_env = os.environ.copy()
87+
yum_env['LANG'] = 'C'
88+
p = subprocess.Popen(cmd, shell=False, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, close_fds=True, env=yum_env)
8489
output, _ = p.communicate()
8590
xcp.logger.info('pool_update.precheck %r returncode=%r output=%r', cmd, p.returncode, output)
8691
if p.returncode != 0:
@@ -91,15 +96,38 @@ def execute_precheck(session, control_package, yum_conf_file, update_precheck_fi
9196
if m:
9297
errmsg = m.group()
9398
errmsg = re.sub(ERROR_MESSAGE_END + '.+', '', errmsg, flags=re.DOTALL)
94-
errmsg = re.sub('\n +', ' ', errmsg, flags=re.DOTALL)
95-
if ERROR_MESSAGE_CONFLICT in errmsg:
96-
raise ConflictPresent(errmsg)
99+
precheckfailure_msg = re.sub('\n +', ' ', errmsg, flags=re.DOTALL)
100+
if ERROR_MESSAGE_CONFLICTS_WITH in errmsg and ERROR_MESSAGE_PROCESSING_CONFLICT in output:
101+
regex = ERROR_MESSAGE_PROCESSING_CONFLICT + '(.*)' + ERROR_MESSAGE_CONFLICTS + UPDATE_PREFIX + '(.+?)\n'
102+
conflict_tuples = re.findall(regex, output)
103+
if len(conflict_tuples) > 0:
104+
conflict_updates = ''
105+
for tuple in conflict_tuples:
106+
conflict_updates += tuple[1] + ' '
107+
raise ConflictPresent(conflict_updates.rstrip())
108+
else:
109+
raise PrecheckFailure(precheckfailure_msg)
97110
elif ERROR_MESSAGE_VERSION_REQUIRED in errmsg and ERROR_MESSAGE_VERSION_INSTALLED in errmsg:
98-
raise WrongServerVersion(errmsg)
111+
regex = ERROR_MESSAGE_VERSION_REQUIRED + '(.+?)\n.+ {2,2}(.+)$'
112+
match = re.search(regex, errmsg, flags=re.DOTALL)
113+
if match:
114+
required_version = match.group(1).rstrip()
115+
installed_version = match.group(2).rstrip()
116+
raise WrongServerVersion(required_version, installed_version)
117+
else:
118+
raise PrecheckFailure(precheckfailure_msg)
99119
elif ERROR_MESSAGE_PREREQUISITE in errmsg:
100-
raise PrerequisiteMissing(errmsg)
120+
regex = ERROR_MESSAGE_PREREQUISITE + UPDATE_PREFIX + '(.+?)\n'
121+
prerequisite_list = re.findall(regex, errmsg)
122+
if len(prerequisite_list) > 0:
123+
prerequisite_updates = ''
124+
for prerequisite in prerequisite_list:
125+
prerequisite_updates += prerequisite + ' '
126+
raise PrerequisiteMissing(prerequisite_updates.rstrip())
127+
else:
128+
raise PrecheckFailure(precheckfailure_msg)
101129
else:
102-
raise PrecheckFailure(errmsg)
130+
raise PrecheckFailure(precheckfailure_msg)
103131
else:
104132
raise PrecheckFailure()
105133
else:
@@ -180,7 +208,8 @@ if __name__ == '__main__':
180208
except ConflictPresent as e:
181209
print(failure_message(UPDATE_PRECHECK_FAILED_CONFLICT_PRESENT, [update_package, str(e)]))
182210
except WrongServerVersion as e:
183-
print(failure_message(UPDATE_PRECHECK_FAILED_WRONG_SERVER_VERSION, [update_package, str(e)]))
211+
required_version, installed_version = e.args
212+
print(failure_message(UPDATE_PRECHECK_FAILED_WRONG_SERVER_VERSION, [update_package, installed_version, required_version]))
184213
except InvalidUpdate as e:
185214
print(failure_message(INVALID_UPDATE, [update_package, str(e)]))
186215
except Exception as e:

0 commit comments

Comments
 (0)