stack_and_upgrade_controller.js 61 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869
  1. /**
  2. * Licensed to the Apache Software Foundation (ASF) under one
  3. * or more contributor license agreements. See the NOTICE file
  4. * distributed with this work for additional information
  5. * regarding copyright ownership. The ASF licenses this file
  6. * to you under the Apache License, Version 2.0 (the
  7. * "License"); you may not use this file except in compliance
  8. * with the License. You may obtain a copy of the License at
  9. *
  10. * http://www.apache.org/licenses/LICENSE-2.0
  11. *
  12. * Unless required by applicable law or agreed to in writing, software
  13. * distributed under the License is distributed on an "AS IS" BASIS,
  14. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  15. * See the License for the specific language governing permissions and
  16. * limitations under the License.
  17. */
  18. var App = require('app');
  19. var stringUtils = require('utils/string_utils');
  20. App.MainAdminStackAndUpgradeController = Em.Controller.extend(App.LocalStorage, {
  21. name: 'mainAdminStackAndUpgradeController',
  22. /**
  23. * @type {boolean}
  24. */
  25. isLoaded: false,
  26. /**
  27. * @type {object}
  28. * @default null
  29. */
  30. upgradeData: null,
  31. /**
  32. * @type {number}
  33. * @default null
  34. */
  35. upgradeId: null,
  36. /**
  37. * @type {string}
  38. * @default null
  39. */
  40. upgradeVersion: null,
  41. /**
  42. * @type {string}
  43. * @default null
  44. */
  45. upgradeType: null,
  46. /**
  47. * @type {boolean}
  48. * @default true
  49. */
  50. downgradeAllowed: true,
  51. /**
  52. * @type {string}
  53. * @default null
  54. */
  55. upgradeTypeDisplayName: null,
  56. /**
  57. * @type {object}
  58. * @default null
  59. */
  60. failuresTolerance: null,
  61. /**
  62. * @type {boolean}
  63. * @default false
  64. */
  65. isDowngrade: false,
  66. /**
  67. * flag which indicate that upgrade suspended
  68. * @type {boolean}
  69. * @default false
  70. */
  71. isSuspended: false,
  72. /**
  73. * version that currently applied to server
  74. * should be plain object, because stored to localStorage
  75. * @type {object|null}
  76. */
  77. currentVersion: null,
  78. /**
  79. * versions to which cluster could be upgraded
  80. * @type {Array}
  81. */
  82. targetVersions: [],
  83. /**
  84. * @type {object}
  85. * @default null
  86. */
  87. slaveComponentStructuredInfo: null,
  88. /**
  89. * @type {Array}
  90. */
  91. serviceCheckFailuresServicenames: [],
  92. /**
  93. * methods through which cluster could be upgraded, "allowed" indicated if the method is allowed
  94. * by stack upgrade path
  95. * @type {Array}
  96. */
  97. upgradeMethods: [
  98. Em.Object.create({
  99. displayName: Em.I18n.t('admin.stackVersions.version.upgrade.upgradeOptions.RU.title'),
  100. type: 'ROLLING',
  101. icon: "icon-dashboard",
  102. description: Em.I18n.t('admin.stackVersions.version.upgrade.upgradeOptions.RU.description'),
  103. selected: false,
  104. allowed: true,
  105. isCheckComplete: false,
  106. isCheckRequestInProgress: false,
  107. precheckResultsMessage: '',
  108. precheckResultsTitle: '',
  109. action: ''
  110. }),
  111. Em.Object.create({
  112. displayName: Em.I18n.t('admin.stackVersions.version.upgrade.upgradeOptions.EU.title'),
  113. type: 'NON_ROLLING',
  114. icon: "icon-bolt",
  115. description: Em.I18n.t('admin.stackVersions.version.upgrade.upgradeOptions.EU.description'),
  116. selected: false,
  117. allowed: true,
  118. isCheckComplete: false,
  119. isCheckRequestInProgress: false,
  120. precheckResultsMessage: '',
  121. precheckResultsTitle: '',
  122. action: ''
  123. })
  124. ],
  125. /**
  126. * pre-check messages map
  127. * @type {object}
  128. */
  129. preCheckMessages: {
  130. 'WARNING': {
  131. template: 'admin.stackUpgrade.preCheck.warning.message',
  132. precheckResultsMessageClass: 'ORANGE',
  133. isPrecheckFailed: false,
  134. precheckResultsMessageIconClass: 'icon-warning-sign'
  135. },
  136. 'BYPASS': {
  137. template: 'admin.stackUpgrade.preCheck.bypass.message',
  138. precheckResultsMessageClass: 'RED',
  139. isPrecheckFailed: false,
  140. precheckResultsMessageIconClass: 'icon-remove',
  141. bypassedFailures: true
  142. },
  143. 'FAIL': {
  144. template: 'admin.stackUpgrade.preCheck.fail.message',
  145. precheckResultsMessageClass: 'RED',
  146. isPrecheckFailed: true,
  147. precheckResultsMessageIconClass: 'icon-remove'
  148. }
  149. },
  150. runningCheckRequests: [],
  151. /**
  152. * @type {boolean} true if some request that should disable actions is in progress
  153. */
  154. requestInProgress: false,
  155. /**
  156. * @type {number} repo id, request for which is currently in progress
  157. */
  158. requestInProgressRepoId: null,
  159. /**
  160. * @type {boolean} true while no updated upgrade info is loaded after retry
  161. */
  162. isRetryPending: false,
  163. /**
  164. * properties that stored to localStorage to resume wizard progress
  165. */
  166. wizardStorageProperties: [
  167. 'upgradeId',
  168. 'upgradeVersion',
  169. 'currentVersion',
  170. 'upgradeTypeDisplayName',
  171. 'upgradeType',
  172. 'failuresTolerance',
  173. 'isDowngrade',
  174. 'downgradeAllowed',
  175. 'isSuspended'
  176. ],
  177. /**
  178. * mutable properties of Upgrade Task
  179. * @type {Array}
  180. */
  181. taskDetailsProperties: ['status', 'stdout', 'stderr', 'error_log', 'host_name', 'output_log'],
  182. /**
  183. * Context for Finalize item
  184. * @type {string}
  185. */
  186. finalizeContext: 'Confirm Finalize',
  187. /**
  188. * Context for Slave component failures manual item
  189. * @type {string}
  190. */
  191. slaveFailuresContext: "Check Component Versions",
  192. /**
  193. * Context for Service check (may include slave component) failures manual item
  194. * @type {string}
  195. */
  196. serviceCheckFailuresContext: "Verifying Skipped Failures",
  197. /**
  198. * Check if current item is Finalize
  199. * @type {boolean}
  200. */
  201. isFinalizeItem: false,
  202. isLoadUpgradeDataPending: false,
  203. /**
  204. * path to the mock json
  205. * @type {String}
  206. */
  207. mockRepoUrl: '/data/stack_versions/repo_versions_all.json',
  208. /**
  209. * api to get RepoVersions
  210. * @type {String}
  211. */
  212. realRepoUrl: function () {
  213. return App.get('apiPrefix') + App.get('stackVersionURL') +
  214. '/compatible_repository_versions?fields=*,operating_systems/*,operating_systems/repositories/*';
  215. }.property('App.stackVersionURL'),
  216. /**
  217. * path to the mock json
  218. * @type {String}
  219. */
  220. mockStackUrl: '/data/stack_versions/stack_version_all.json',
  221. /**
  222. * api to get ClusterStackVersions with repository_versions (use to init data load)
  223. * @type {String}
  224. */
  225. realStackUrl: function () {
  226. return App.get('apiPrefix') + '/clusters/' + App.get('clusterName') +
  227. '/stack_versions?fields=*,repository_versions/*,repository_versions/operating_systems/OperatingSystems/*,repository_versions/operating_systems/repositories/*';
  228. }.property('App.clusterName'),
  229. /**
  230. * api to get ClusterStackVersions without repository_versions (use to update data)
  231. * @type {String}
  232. */
  233. realUpdateUrl: function () {
  234. return App.get('apiPrefix') + '/clusters/' + App.get('clusterName') + '/stack_versions?fields=ClusterStackVersions/*';
  235. }.property('App.clusterName'),
  236. /**
  237. * Determines if list of services with checks that failed and were skipped by user during the upgrade is loaded
  238. * @type {boolean}
  239. */
  240. areSkippedServiceChecksLoaded: false,
  241. /**
  242. * List of services with checks that failed and were skipped by user during the upgrade
  243. * @type {array}
  244. */
  245. skippedServiceChecks: [],
  246. /**
  247. * status of tasks/items/groups which should be grayed out and disabled
  248. * @type {Array}
  249. */
  250. nonActiveStates: ['PENDING', 'ABORTED'],
  251. /**
  252. * status of Upgrade request
  253. * @type {string}
  254. */
  255. requestStatus: function () {
  256. if (this.get('upgradeData.Upgrade') && App.get('upgradeSuspended')) {
  257. return 'SUSPENDED';
  258. } else if (this.get('upgradeData.Upgrade')){
  259. return this.get('upgradeData.Upgrade.request_status');
  260. } else {
  261. return '';
  262. }
  263. }.property('upgradeData.Upgrade.request_status', 'App.upgradeSuspended'),
  264. init: function () {
  265. this.initDBProperties();
  266. },
  267. /**
  268. * restore data from localStorage
  269. */
  270. initDBProperties: function () {
  271. var props = this.getDBProperties(this.get('wizardStorageProperties'));
  272. Em.keys(props).forEach(function (k) {
  273. if (!Em.isNone(props[k])) {
  274. this.set(k, props[k]);
  275. }
  276. }, this);
  277. },
  278. /**
  279. * load all data:
  280. * - upgrade data
  281. * - stack versions
  282. * - repo versions
  283. */
  284. load: function () {
  285. var dfd = $.Deferred();
  286. var self = this;
  287. this.loadUpgradeData(true).done(function() {
  288. self.loadStackVersionsToModel(true).done(function () {
  289. self.loadRepoVersionsToModel().done(function() {
  290. var currentVersion = App.StackVersion.find().findProperty('state', 'CURRENT');
  291. if (currentVersion) {
  292. self.set('currentVersion', {
  293. repository_version: currentVersion.get('repositoryVersion.repositoryVersion'),
  294. repository_name: currentVersion.get('repositoryVersion.displayName')
  295. });
  296. }
  297. dfd.resolve();
  298. });
  299. });
  300. });
  301. return dfd.promise();
  302. },
  303. /**
  304. * load upgrade tasks by upgrade id
  305. * @return {$.Deferred}
  306. * @param {boolean} onlyState
  307. */
  308. loadUpgradeData: function (onlyState) {
  309. var upgradeId = this.get('upgradeId'),
  310. deferred = $.Deferred(),
  311. self = this;
  312. if (Em.isNone(upgradeId)) {
  313. deferred.resolve();
  314. } else {
  315. this.set('isLoadUpgradeDataPending', true);
  316. App.ajax.send({
  317. name: (onlyState) ? 'admin.upgrade.state' : 'admin.upgrade.data',
  318. sender: this,
  319. data: {
  320. id: upgradeId
  321. },
  322. success: 'loadUpgradeDataSuccessCallback'
  323. }).then(deferred.resolve).complete(function () {
  324. self.set('isLoadUpgradeDataPending', false);
  325. });
  326. }
  327. return deferred.promise();
  328. },
  329. /**
  330. * parse and push upgrade tasks to controller
  331. * @param data
  332. */
  333. loadUpgradeDataSuccessCallback: function (data) {
  334. if (Em.isNone(data)) return;
  335. App.set('upgradeState', data.Upgrade.request_status);
  336. this.setDBProperty('upgradeState', data.Upgrade.request_status);
  337. this.set('isSuspended', data.Upgrade.suspended);
  338. this.setDBProperty('isSuspended', data.Upgrade.suspended);
  339. if (data.upgrade_groups) {
  340. this.updateUpgradeData(data);
  341. }
  342. if (this.get('isRetryPending') && data.Upgrade.request_status !== 'ABORTED') {
  343. this.setProperties({
  344. requestInProgress: false,
  345. isRetryPending: false
  346. });
  347. }
  348. },
  349. /**
  350. * update data of Upgrade
  351. * @param {object} newData
  352. */
  353. updateUpgradeData: function (newData) {
  354. var oldData = this.get('upgradeData'),
  355. nonActiveStates = this.get('nonActiveStates'),
  356. groupsMap = {},
  357. itemsMap = {};
  358. if (Em.isNone(oldData) || (newData.upgrade_groups.length !== oldData.upgradeGroups.length)) {
  359. this.initUpgradeData(newData);
  360. } else {
  361. //create entities maps
  362. newData.upgrade_groups.forEach(function (newGroup) {
  363. groupsMap[newGroup.UpgradeGroup.group_id] = newGroup.UpgradeGroup;
  364. newGroup.upgrade_items.forEach(function (item) {
  365. itemsMap[item.UpgradeItem.stage_id] = item.UpgradeItem;
  366. })
  367. });
  368. //update existed entities with new data
  369. oldData.upgradeGroups.forEach(function (oldGroup) {
  370. oldGroup.set('status', groupsMap[oldGroup.get('group_id')].status);
  371. oldGroup.set('display_status', groupsMap[oldGroup.get('group_id')].display_status);
  372. oldGroup.set('progress_percent', groupsMap[oldGroup.get('group_id')].progress_percent);
  373. oldGroup.set('completed_task_count', groupsMap[oldGroup.get('group_id')].completed_task_count);
  374. oldGroup.upgradeItems.forEach(function (item) {
  375. item.set('status', itemsMap[item.get('stage_id')].status);
  376. item.set('display_status', itemsMap[item.get('stage_id')].display_status);
  377. item.set('progress_percent', itemsMap[item.get('stage_id')].progress_percent);
  378. });
  379. var hasExpandableItems = oldGroup.upgradeItems.some(function (item) {
  380. return !nonActiveStates.contains(item.get('status'));
  381. });
  382. oldGroup.set('hasExpandableItems', hasExpandableItems);
  383. });
  384. oldData.set('Upgrade', newData.Upgrade);
  385. }
  386. },
  387. /**
  388. * change structure of Upgrade
  389. * In order to maintain nested views in template object should have direct link to its properties, for example
  390. * item.UpgradeItem.<properties> -> item.<properties>
  391. * @param {object} newData
  392. */
  393. initUpgradeData: function (newData) {
  394. var upgradeGroups = [],
  395. nonActiveStates = this.get('nonActiveStates');
  396. //wrap all entities into App.upgradeEntity
  397. newData.upgrade_groups.forEach(function (newGroup) {
  398. var hasExpandableItems = newGroup.upgrade_items.some(function (item) {
  399. return !nonActiveStates.contains(item.UpgradeItem.status);
  400. }),
  401. oldGroup = App.upgradeEntity.create({type: 'GROUP', hasExpandableItems: hasExpandableItems}, newGroup.UpgradeGroup),
  402. upgradeItems = [];
  403. newGroup.upgrade_items.forEach(function (item) {
  404. var oldItem = App.upgradeEntity.create({type: 'ITEM'}, item.UpgradeItem);
  405. this.formatMessages(oldItem);
  406. oldItem.set('tasks', []);
  407. upgradeItems.pushObject(oldItem);
  408. }, this);
  409. upgradeItems.reverse();
  410. oldGroup.set('upgradeItems', upgradeItems);
  411. upgradeGroups.pushObject(oldGroup);
  412. }, this);
  413. upgradeGroups.reverse();
  414. this.set('upgradeData', Em.Object.create({
  415. upgradeGroups: upgradeGroups,
  416. Upgrade: newData.Upgrade
  417. }));
  418. this.set('downgradeAllowed', newData.Upgrade.downgrade_allowed);
  419. this.setDBProperty('downgradeAllowed', newData.Upgrade.downgrade_allowed);
  420. },
  421. /**
  422. * format upgrade item text
  423. * @param {App.upgradeEntity} oldItem
  424. */
  425. formatMessages: function (oldItem) {
  426. var text = oldItem.get('text');
  427. var messages = [];
  428. try {
  429. var messageArray = JSON.parse(text);
  430. for (var i = 0; i < messageArray.length; i++) {
  431. messages.push(messageArray[i].message);
  432. }
  433. oldItem.set('text', messages.join(' '));
  434. } catch (err) {
  435. console.warn('Upgrade Item has malformed text');
  436. }
  437. oldItem.set('messages', messages);
  438. },
  439. /**
  440. * request Upgrade Item and its tasks from server
  441. * @param {Em.Object} item
  442. * @param {Function} customCallback
  443. * @return {$.ajax}
  444. */
  445. getUpgradeItem: function (item, customCallback) {
  446. return App.ajax.send({
  447. name: 'admin.upgrade.upgrade_item',
  448. sender: this,
  449. data: {
  450. upgradeId: item.get('request_id'),
  451. groupId: item.get('group_id'),
  452. stageId: item.get('stage_id')
  453. },
  454. success: customCallback || 'getUpgradeItemSuccessCallback'
  455. });
  456. },
  457. /**
  458. * success callback of <code>getTasks</code>
  459. * @param {object} data
  460. */
  461. getUpgradeItemSuccessCallback: function (data) {
  462. this.get('upgradeData.upgradeGroups').forEach(function (group) {
  463. if (group.get('group_id') === data.UpgradeItem.group_id) {
  464. group.get('upgradeItems').forEach(function (item) {
  465. if (item.get('stage_id') === data.UpgradeItem.stage_id) {
  466. if (item.get('tasks.length')) {
  467. data.tasks.forEach(function (task) {
  468. var currentTask = item.get('tasks').findProperty('id', task.Tasks.id);
  469. this.get('taskDetailsProperties').forEach(function (property) {
  470. currentTask.set(property, task.Tasks[property]);
  471. }, this);
  472. }, this);
  473. } else {
  474. var tasks = [];
  475. data.tasks.forEach(function (task) {
  476. tasks.pushObject(App.upgradeEntity.create({type: 'TASK'}, task.Tasks));
  477. });
  478. item.set('tasks', tasks);
  479. }
  480. item.set('isTasksLoaded', true);
  481. }
  482. }, this);
  483. }
  484. }, this);
  485. },
  486. /**
  487. * Failures info may includes service_check and host_component failures. These two types should be displayed separately.
  488. */
  489. getServiceCheckItemSuccessCallback: function(data) {
  490. var task = data.tasks[0];
  491. var info = {
  492. hosts: [],
  493. host_detail: {}
  494. };
  495. if (task && task.Tasks && task.Tasks.structured_out && task.Tasks.structured_out.failures) {
  496. this.set('serviceCheckFailuresServicenames', task.Tasks.structured_out.failures.service_check || []);
  497. if (task.Tasks.structured_out.failures.host_component) {
  498. for (var hostname in task.Tasks.structured_out.failures.host_component){
  499. info.hosts.push(hostname);
  500. }
  501. info.host_detail = task.Tasks.structured_out.failures.host_component;
  502. }
  503. this.set('slaveComponentStructuredInfo', info);
  504. }
  505. },
  506. getSlaveComponentItemSuccessCallback: function(data) {
  507. var info = data.tasks[0];
  508. if (info && info.Tasks && info.Tasks.structured_out) {
  509. this.set('slaveComponentStructuredInfo', info.Tasks.structured_out);
  510. }
  511. },
  512. /**
  513. * downgrade confirmation popup
  514. * @param {object} event
  515. */
  516. confirmDowngrade: function (event) {
  517. var self = this;
  518. var currentVersion = this.get('currentVersion');
  519. return App.showConfirmationPopup(
  520. function() {
  521. self.downgrade.call(self, currentVersion, event);
  522. },
  523. Em.I18n.t('admin.stackUpgrade.downgrade.body').format(currentVersion.repository_name),
  524. null,
  525. Em.I18n.t('admin.stackUpgrade.dialog.downgrade.header').format(currentVersion.repository_name),
  526. Em.I18n.t('admin.stackUpgrade.downgrade.proceed')
  527. );
  528. },
  529. /**
  530. * make call to start downgrade process
  531. * @param {object} currentVersion
  532. * @param {object} event
  533. */
  534. downgrade: function (currentVersion, event) {
  535. var self = this;
  536. this.set('requestInProgress', true);
  537. this.abortUpgrade().done(function() {
  538. self.startDowngrade(currentVersion);
  539. });
  540. },
  541. /**
  542. * abort upgrade (in order to start Downgrade)
  543. */
  544. abortUpgrade: function () {
  545. var errorCallback = this.get('isDowngrade') ? 'abortDowngradeErrorCallback' : 'abortUpgradeErrorCallback';
  546. return App.ajax.send({
  547. name: 'admin.upgrade.abort',
  548. sender: this,
  549. data: {
  550. upgradeId: this.get('upgradeId'),
  551. isDowngrade: this.get('isDowngrade')
  552. },
  553. error: errorCallback
  554. });
  555. },
  556. /**
  557. * just request ro start downgrade,
  558. * should be performed only if <code>abortUpgrade<code> was completed
  559. */
  560. startDowngrade: function(currentVersion) {
  561. App.ajax.send({
  562. name: 'admin.downgrade.start',
  563. sender: this,
  564. data: {
  565. from: App.RepositoryVersion.find().findProperty('displayName', this.get('upgradeVersion')).get('repositoryVersion'),
  566. value: currentVersion.repository_version,
  567. label: currentVersion.repository_name,
  568. isDowngrade: true,
  569. upgradeType: this.get('upgradeType')
  570. },
  571. success: 'upgradeSuccessCallback',
  572. callback: function() {
  573. this.sender.set('requestInProgress', false);
  574. }
  575. });
  576. },
  577. /**
  578. * suspend upgrade (in order to restart it later)
  579. */
  580. abortUpgradeWithSuspend: function () {
  581. var errorCallback = this.get('isDowngrade') ? 'abortDowngradeErrorCallback' : 'abortUpgradeErrorCallback';
  582. return App.ajax.send({
  583. name: 'admin.upgrade.suspend',
  584. sender: this,
  585. data: {
  586. upgradeId: this.get('upgradeId'),
  587. isDowngrade: this.get('isDowngrade')
  588. },
  589. error: errorCallback
  590. });
  591. },
  592. /**
  593. * error callback of <code>abortUpgrade()</code>
  594. * @param {object} data
  595. */
  596. abortUpgradeErrorCallback: function (data) {
  597. var header = Em.I18n.t('admin.stackUpgrade.state.paused.fail.header');
  598. var body = Em.I18n.t('admin.stackUpgrade.state.paused.fail.body');
  599. if (data && data.responseText) {
  600. try {
  601. var json = $.parseJSON(data.responseText);
  602. body = body + ' ' + json.message;
  603. } catch (err) {}
  604. }
  605. App.showAlertPopup(header, body);
  606. },
  607. /**
  608. * error callback of <code>abortDowngrade()</code>
  609. * @param {object} data
  610. */
  611. abortDowngradeErrorCallback: function (data) {
  612. var header = Em.I18n.t('admin.stackDowngrade.state.paused.fail.header');
  613. var body = Em.I18n.t('admin.stackDowngrade.state.paused.fail.body');
  614. if(data && data.responseText){
  615. try {
  616. var json = $.parseJSON(data.responseText);
  617. body = body + ' ' + json.message;
  618. } catch (err) {}
  619. }
  620. App.showAlertPopup(header, body);
  621. },
  622. retryUpgrade: function () {
  623. this.setProperties({
  624. requestInProgress: true,
  625. isRetryPending: true
  626. });
  627. return App.ajax.send({
  628. name: 'admin.upgrade.retry',
  629. sender: this,
  630. data: {
  631. upgradeId: this.get('upgradeId')
  632. }
  633. });
  634. },
  635. /**
  636. * make call to start upgrade process and show popup with current progress
  637. * @param {object} version
  638. */
  639. upgrade: function (version) {
  640. this.set('requestInProgress', true);
  641. App.ajax.send({
  642. name: 'admin.upgrade.start',
  643. sender: this,
  644. data: version,
  645. success: 'upgradeSuccessCallback',
  646. error: 'upgradeErrorCallback',
  647. callback: function() {
  648. this.sender.set('requestInProgress', false);
  649. }
  650. });
  651. this.setDBProperty('currentVersion', this.get('currentVersion'));
  652. // Show a "preparing the upgrade..." dialog in case the api call returns too slow
  653. if (App.router.get('currentState.name') != 'stackUpgrade') {
  654. this.showPreparingUpgradeIndicator();
  655. }
  656. },
  657. /**
  658. * Should progress bar be displayed when preparing upgrade,
  659. * should show after Upgrade Options window and before Upgrade Wizard
  660. * @method showPreparingUpgradeIndicator
  661. */
  662. showPreparingUpgradeIndicator: function () {
  663. return App.ModalPopup.show({
  664. header: '',
  665. showFooter: false,
  666. showCloseButton: false,
  667. bodyClass: Em.View.extend({
  668. templateName: require('templates/wizard/step8/step8_log_popup'),
  669. controllerBinding: 'App.router.mainAdminStackAndUpgradeController',
  670. /**
  671. * Css-property for progress-bar
  672. * @type {string}
  673. */
  674. barWidth: 'width: 100%;',
  675. progressBarClass: 'progress progress-striped active log_popup',
  676. /**
  677. * Popup-message
  678. * @type {string}
  679. */
  680. message: Em.I18n.t('admin.stackUpgrade.dialog.prepareUpgrade.header'),
  681. /**
  682. * Hide popup when upgrade wizard is open
  683. * @method autoHide
  684. */
  685. autoHide: function () {
  686. if (!this.get('controller.requestInProgress')) {
  687. this.get('parentView').hide();
  688. }
  689. }.observes('controller.requestInProgress')
  690. })
  691. });
  692. },
  693. /**
  694. * error callback of <code>upgrade()</code>
  695. * @param {object} data
  696. */
  697. upgradeErrorCallback: function (data) {
  698. var header = Em.I18n.t('admin.stackVersions.upgrade.start.fail.title');
  699. var body = "";
  700. if (data && data.responseText) {
  701. try {
  702. var json = $.parseJSON(data.responseText);
  703. body = json.message;
  704. } catch (err) {}
  705. }
  706. App.showAlertPopup(header, body);
  707. },
  708. /**
  709. * success callback of <code>upgrade()</code>
  710. * @param {object} data
  711. */
  712. upgradeSuccessCallback: function (data, opt, params) {
  713. this.set('upgradeData', null);
  714. this.set('upgradeId', data.resources[0].Upgrade.request_id);
  715. this.set('upgradeVersion', params.label);
  716. this.set('isDowngrade', !!params.isDowngrade);
  717. var upgradeMethod = this.get('upgradeMethods').findProperty('type', params.type);
  718. var upgradeTypeDisplayName = null;
  719. var upgradeType = null;
  720. if (upgradeMethod) {
  721. upgradeTypeDisplayName = upgradeMethod.get('displayName');
  722. upgradeType = upgradeMethod.get('type');
  723. }
  724. this.set('upgradeType', upgradeType);
  725. this.set('upgradeTypeDisplayName', upgradeTypeDisplayName);
  726. this.set('failuresTolerance', Em.Object.create({
  727. skipComponentFailures: params.skipComponentFailures == 'true',
  728. skipSCFailures: params.skipSCFailures == 'true'
  729. }));
  730. this.setDBProperties({
  731. upgradeVersion: params.label,
  732. upgradeId: data.resources[0].Upgrade.request_id,
  733. upgradeState: 'PENDING',
  734. isDowngrade: !!params.isDowngrade,
  735. upgradeType: upgradeType,
  736. upgradeTypeDisplayName: upgradeTypeDisplayName,
  737. failuresTolerance: Em.Object.create({
  738. skipComponentFailures: params.skipComponentFailures == 'true',
  739. skipSCFailures: params.skipSCFailures == 'true'
  740. })
  741. });
  742. App.set('upgradeState', 'PENDING');
  743. App.clusterStatus.setClusterStatus({
  744. wizardControllerName: this.get('name'),
  745. localdb: App.db.data
  746. });
  747. this.load();
  748. this.openUpgradeDialog();
  749. },
  750. /**
  751. * success callback of updating upgrade options including failures tolerance. etc
  752. * @param {object} data
  753. */
  754. updateOptionsSuccessCallback: function (data, opt, params) {
  755. this.set('failuresTolerance', Em.Object.create({
  756. skipComponentFailures: params.skipComponentFailures == 'true',
  757. skipSCFailures: params.skipSCFailures == 'true'
  758. }));
  759. },
  760. /**
  761. * run upgrade checks and add results to each method object and set selected method
  762. * @param {Em.Object} version
  763. */
  764. runUpgradeMethodChecks: function(version) {
  765. this.get('upgradeMethods').forEach(function (method) {
  766. if (method.get('allowed')) {
  767. this.runPreUpgradeCheckOnly({
  768. value: version.get('repositoryVersion'),
  769. label: version.get('displayName'),
  770. type: method.get('type')
  771. });
  772. } else {
  773. //if method not supported in current stack version, mark as check completed
  774. method.setProperties({
  775. isCheckComplete: false,
  776. isCheckRequestInProgress: false,
  777. action: ''
  778. });
  779. }
  780. }, this);
  781. },
  782. getConfigsWarnings: function (configsMergeWarning) {
  783. var configs = [];
  784. if (configsMergeWarning && Em.get(configsMergeWarning, 'UpgradeChecks.status') === 'WARNING') {
  785. var configsMergeCheckData = Em.get(configsMergeWarning, 'UpgradeChecks.failed_detail');
  786. if (configsMergeCheckData && Em.isArray(configsMergeCheckData)) {
  787. configs = configsMergeCheckData.map(function (item) {
  788. var isDeprecated = Em.isNone(item.new_stack_value),
  789. willBeRemoved = Em.isNone(item.result_value);
  790. return {
  791. type: item.type,
  792. name: item.property,
  793. currentValue: item.current,
  794. recommendedValue: isDeprecated ? Em.I18n.t('popup.clusterCheck.Upgrade.configsMerge.deprecated') : item.new_stack_value,
  795. isDeprecated: isDeprecated,
  796. resultingValue: willBeRemoved ? Em.I18n.t('popup.clusterCheck.Upgrade.configsMerge.willBeRemoved') : item.result_value,
  797. willBeRemoved: willBeRemoved
  798. };
  799. });
  800. }
  801. }
  802. return configs;
  803. },
  804. /**
  805. * Open upgrade options window: upgrade type and failures tolerance
  806. * @param {boolean} isInUpgradeWizard
  807. * @param {object} version
  808. * @return App.ModalPopup
  809. */
  810. upgradeOptions: function (isInUpgradeWizard, version) {
  811. var self = this,
  812. upgradeMethods = this.get('upgradeMethods'),
  813. runningCheckRequests = this.get('runningCheckRequests');
  814. if (!isInUpgradeWizard) {
  815. upgradeMethods.setEach('isCheckRequestInProgress', true);
  816. upgradeMethods.setEach('selected', false);
  817. var request = this.getSupportedUpgradeTypes(Ember.Object.create({
  818. stackName: App.get('currentStackVersion').split('-')[0],
  819. stackVersion: App.get('currentStackVersion').split('-')[1],
  820. toVersion: version.get('repositoryVersion')
  821. })).done(function () {
  822. if (App.get('router.currentState.name') === 'versions' && App.get('router.currentState.parentState.name') === 'stackAndUpgrade') {
  823. self.runUpgradeMethodChecks(version);
  824. }
  825. }).always(function () {
  826. self.set('runningCheckRequests', runningCheckRequests.rejectProperty('type', 'ALL'));
  827. });
  828. request.type = 'ALL';
  829. this.get('runningCheckRequests').push(request);
  830. }
  831. return App.ModalPopup.show({
  832. encodeBody: false,
  833. primary: isInUpgradeWizard ? Em.I18n.t('ok') : Em.I18n.t('common.proceed'),
  834. primaryClass: 'btn-success',
  835. classNames: ['upgrade-options-popup'],
  836. header: Em.I18n.t('admin.stackVersions.version.upgrade.upgradeOptions.header'),
  837. bodyClass: Em.View.extend({
  838. templateName: require('templates/main/admin/stack_upgrade/upgrade_options'),
  839. didInsertElement: function () {
  840. App.tooltip($(".failure-tolerance-tooltip"), {
  841. placement: "top",
  842. title: Em.I18n.t('admin.stackVersions.version.upgrade.upgradeOptions.tolerance.tooltip')
  843. });
  844. Em.run.later(this, function () {
  845. App.tooltip($(".thumbnail.check-failed"), {
  846. placement: "bottom",
  847. title: Em.I18n.t('admin.stackVersions.version.upgrade.upgradeOptions.preCheck.failed.tooltip')
  848. });
  849. App.tooltip($(".not-allowed-by-version"), {
  850. placement: "bottom",
  851. title: Em.I18n.t('admin.stackVersions.version.upgrade.upgradeOptions.notAllowed')
  852. });
  853. }, 1000);
  854. },
  855. upgradeMethods: function () {
  856. self.updateSelectedMethod(isInUpgradeWizard);
  857. return self.get('upgradeMethods');
  858. }.property().volatile(),
  859. isInUpgradeWizard: isInUpgradeWizard,
  860. versionText: isInUpgradeWizard ? '' : Em.I18n.t('admin.stackVersions.version.upgrade.upgradeOptions.bodyMsg.version').format(version.get('displayName')),
  861. selectMethod: function (event) {
  862. if (isInUpgradeWizard || !event.context.get('allowed') || event.context.get('isPrecheckFailed')) return;
  863. var selectedMethod = event.context;
  864. self.updateSelectedMethod(isInUpgradeWizard);
  865. self.get('upgradeMethods').forEach(function (method) {
  866. method.set('selected', false);
  867. });
  868. selectedMethod.set('selected', true);
  869. this.set('parentView.selectedMethod', selectedMethod);
  870. },
  871. runAction: function (event) {
  872. var method = event.context,
  873. action = method.get('action');
  874. if (action) {
  875. this.get(action)(event);
  876. }
  877. },
  878. rerunCheck: function (event) {
  879. self.runPreUpgradeCheckOnly({
  880. value: version.get('repositoryVersion'),
  881. label: version.get('displayName'),
  882. type: event.context.get('type')
  883. });
  884. },
  885. openMessage: function (event) {
  886. if (isInUpgradeWizard || !event.context.get('allowed')) return;
  887. var data = event.context.get('precheckResultsData');
  888. var failTitle = Em.I18n.t('popup.clusterCheck.Upgrade.fail.title');
  889. var failAlert = new Em.Handlebars.SafeString(Em.I18n.t('popup.clusterCheck.Upgrade.fail.alert'));
  890. var bypassedFailures = data.items.filterProperty('UpgradeChecks.status', 'BYPASS').length > 0;
  891. if (data.items.filterProperty('UpgradeChecks.status', 'ERROR').length == 0 && bypassedFailures) {
  892. failTitle = Em.I18n.t('popup.clusterCheck.Upgrade.bypassed-failures.title');
  893. failAlert = new Em.Handlebars.SafeString(Em.I18n.t('popup.clusterCheck.Upgrade.bypassed-failures.alert'));
  894. }
  895. var header = Em.I18n.t('popup.clusterCheck.Upgrade.header').format(version.get('displayName')),
  896. warningTitle = Em.I18n.t('popup.clusterCheck.Upgrade.warning.title'),
  897. warningAlert = new Em.Handlebars.SafeString(Em.I18n.t('popup.clusterCheck.Upgrade.warning.alert')),
  898. configsMergeWarning = data.items.findProperty('UpgradeChecks.id', "CONFIG_MERGE"),
  899. popupData = {
  900. items: data.items.rejectProperty('UpgradeChecks.id', 'CONFIG_MERGE')
  901. },
  902. configs = self.getConfigsWarnings(configsMergeWarning);
  903. App.showClusterCheckPopup(popupData, {
  904. header: header,
  905. failTitle: failTitle,
  906. failAlert: failAlert,
  907. warningTitle: warningTitle,
  908. warningAlert: warningAlert,
  909. primary: Em.I18n.t('admin.stackVersions.version.upgrade.upgradeOptions.preCheck.rerun'),
  910. secondary: Em.I18n.t('common.cancel'),
  911. bypassedFailures: bypassedFailures,
  912. callback: function () {
  913. self.runPreUpgradeCheckOnly.call(self, {
  914. value: version.get('repositoryVersion'),
  915. label: version.get('displayName'),
  916. type: event.context.get('type')
  917. });
  918. }
  919. }, configs, version.get('displayName'));
  920. }
  921. }),
  922. /**
  923. * @type {Em.Object}
  924. * @default null
  925. */
  926. selectedMethod: null,
  927. skipComponentFailures: self.get('failuresTolerance.skipComponentFailures'),
  928. skipSCFailures: self.get('failuresTolerance.skipSCFailures'),
  929. disablePrimary: function () {
  930. if (isInUpgradeWizard) return false;
  931. var selectedMethod = this.get('selectedMethod');
  932. return (selectedMethod ? (selectedMethod.get('isPrecheckFailed') || selectedMethod.get('isCheckRequestInProgress')) : true);
  933. }.property('selectedMethod', 'selectedMethod.isPrecheckFailed', 'selectedMethod.isCheckRequestInProgress'),
  934. onPrimary: function () {
  935. this.hide();
  936. if (isInUpgradeWizard) {
  937. return App.ajax.send({
  938. name: 'admin.upgrade.update.options',
  939. sender: self,
  940. data: {
  941. upgradeId: self.get('upgradeId'),
  942. skipComponentFailures: Boolean(this.get('skipComponentFailures')).toString(),
  943. skipSCFailures: Boolean(this.get('skipSCFailures')).toString()
  944. },
  945. success: 'updateOptionsSuccessCallback'
  946. });
  947. } else {
  948. var upgradeMethod = self.get('upgradeMethods').findProperty('selected');
  949. version.upgradeType = upgradeMethod.get('type');
  950. version.upgradeTypeDisplayName = upgradeMethod.get('displayName');
  951. version.skipComponentFailures = this.get('skipComponentFailures');
  952. version.skipSCFailures = this.get('skipSCFailures');
  953. var fromVersion = self.get('upgradeVersion') || App.RepositoryVersion.find().findProperty('status', 'CURRENT').get('displayName');
  954. var toVersion = version.get('displayName');
  955. var bodyMessage = Em.Object.create({
  956. confirmButton: Em.I18n.t('yes'),
  957. confirmMsg: upgradeMethod.get('type') === 'ROLLING' ?
  958. Em.I18n.t('admin.stackVersions.version.upgrade.upgradeOptions.RU.confirm.msg').format(fromVersion, toVersion) :
  959. Em.I18n.t('admin.stackVersions.version.upgrade.upgradeOptions.EU.confirm.msg').format(fromVersion, toVersion)
  960. });
  961. return App.showConfirmationFeedBackPopup(function (query) {
  962. return self.runPreUpgradeCheck.call(self, version);
  963. }, bodyMessage);
  964. }
  965. }
  966. });
  967. },
  968. /**
  969. * open upgrade options from upgrade wizard
  970. */
  971. openUpgradeOptions: function () {
  972. if (this.get('isDowngrade')) return;
  973. this.upgradeOptions(true, null);
  974. },
  975. /**
  976. * upgrade confirmation popup including upgrade options: upgrade type and failures tolerance
  977. * @param {object} version
  978. * @return App.ModalPopup
  979. */
  980. confirmUpgrade: function (version) {
  981. this.upgradeOptions(false, version);
  982. },
  983. /**
  984. * send request for pre upgrade check only
  985. */
  986. runPreUpgradeCheckOnly: function (data) {
  987. if (App.get('supports.preUpgradeCheck')) {
  988. var method = this.get('upgradeMethods').findProperty('type', data.type);
  989. method.setProperties({
  990. isCheckComplete: false,
  991. isCheckRequestInProgress: true,
  992. action: ''
  993. });
  994. var request = App.ajax.send({
  995. name: "admin.upgrade.pre_upgrade_check",
  996. sender: this,
  997. data: data,
  998. success: 'runPreUpgradeCheckOnlySuccess',
  999. error: 'runPreUpgradeCheckOnlyError',
  1000. callback: function () {
  1001. var runningCheckRequests = this.sender.get('runningCheckRequests');
  1002. method.set('isCheckRequestInProgress', false);
  1003. this.sender.set('runningCheckRequests', runningCheckRequests.rejectProperty('type', this.data.type));
  1004. }
  1005. });
  1006. request.type = data.type;
  1007. this.get('runningCheckRequests').push(request);
  1008. }
  1009. },
  1010. /**
  1011. * send request to get available upgrade tye names
  1012. */
  1013. getSupportedUpgradeTypes: function(data) {
  1014. return App.ajax.send({
  1015. name: "admin.upgrade.get_supported_upgradeTypes",
  1016. sender: this,
  1017. data: data,
  1018. success: "getSupportedUpgradeTypesSuccess"
  1019. });
  1020. },
  1021. /**
  1022. * success callback of <code>getSupportedUpgradeTypes()</code>
  1023. * @param data {object}
  1024. */
  1025. getSupportedUpgradeTypesSuccess: function (data) {
  1026. var supportedUpgradeTypes = data.items[0] && data.items[0].CompatibleRepositoryVersions.upgrade_types;
  1027. this.get('upgradeMethods').forEach(function (method) {
  1028. method.set('allowed', Boolean(supportedUpgradeTypes && supportedUpgradeTypes.contains(method.get('type'))));
  1029. });
  1030. },
  1031. /**
  1032. * success callback of <code>runPreUpgradeCheckOnly()</code>
  1033. * Show a message how many fails/warnings/bypass/passed
  1034. * on clicking that message a popup window show up
  1035. * @param data {object}
  1036. * @param opt {object}
  1037. * @param params {object}
  1038. */
  1039. runPreUpgradeCheckOnlySuccess: function (data, opt, params) {
  1040. var properties = {
  1041. precheckResultsTitle: Em.I18n.t('admin.stackVersions.version.upgrade.upgradeOptions.preCheck.msg.title'),
  1042. precheckResultsData: data,
  1043. isCheckComplete: true,
  1044. action: 'openMessage',
  1045. precheckResultsMessage: '',
  1046. recheckResultsMessageClass: 'GREEN',
  1047. isPrecheckFailed: false,
  1048. precheckResultsMessageIconClass: 'icon-ok',
  1049. bypassedFailures: false
  1050. };
  1051. Object.keys(this.get('preCheckMessages')).forEach(function(status) {
  1052. if (data.items.someProperty('UpgradeChecks.status', status)) {
  1053. properties = this.formatPreCheckMessage(status, data, properties);
  1054. }
  1055. }, this);
  1056. if (!properties.precheckResultsMessage) {
  1057. properties.precheckResultsMessage = Em.I18n.t('admin.stackVersions.version.upgrade.upgradeOptions.preCheck.allPassed');
  1058. }
  1059. this.get('upgradeMethods').findProperty('type', params.type).setProperties(properties);
  1060. this.updateSelectedMethod(false);
  1061. this.addPrecheckMessageTooltip();
  1062. },
  1063. /**
  1064. * @method formatPreCheckMessage
  1065. * @param {string} type
  1066. * @param {object} data
  1067. * @param {object} defaults
  1068. * @returns {object}
  1069. */
  1070. formatPreCheckMessage: function(type, data, defaults) {
  1071. var length = data.items.filterProperty('UpgradeChecks.status', type).length;
  1072. var properties = this.get('preCheckMessages')[type] || {};
  1073. var message = Em.I18n.t(properties.template).format(length, defaults.precheckResultsMessage);
  1074. defaults = $.extend(defaults, properties);
  1075. delete defaults.template;
  1076. defaults.precheckResultsMessage = message;
  1077. return defaults;
  1078. },
  1079. addPrecheckMessageTooltip: function() {
  1080. Em.run.later(this, function () {
  1081. // add tooltip for the type with preCheck errors
  1082. App.tooltip($(".thumbnail.check-failed"), {
  1083. placement: "bottom",
  1084. title: Em.I18n.t('admin.stackVersions.version.upgrade.upgradeOptions.preCheck.failed.tooltip')
  1085. });
  1086. // destroy the tooltip for the type wo preCheck errors
  1087. $(".thumbnail").not(".check-failed").not(".not-allowed-by-version").tooltip("destroy");
  1088. }, 1000);
  1089. },
  1090. runPreUpgradeCheckOnlyError: function (request, ajaxOptions, error, data, params) {
  1091. var method = this.get('upgradeMethods').findProperty('type', params.type);
  1092. method.setProperties({
  1093. precheckResultsMessage: Em.I18n.t('admin.stackVersions.version.upgrade.upgradeOptions.preCheck.msg.failed.link'),
  1094. precheckResultsTitle: Em.I18n.t('admin.stackVersions.version.upgrade.upgradeOptions.preCheck.msg.failed.title'),
  1095. precheckResultsMessageClass: 'RED',
  1096. isPrecheckFailed: true,
  1097. precheckResultsMessageIconClass: 'icon-warning-sign',
  1098. action: 'rerunCheck'
  1099. });
  1100. },
  1101. /**
  1102. * In Upgrade Wizard: update which method already been selected on open
  1103. * Not in upgrade wizard: de-select the method with pre-check errors
  1104. * @param isInUpgradeWizard {boolean}
  1105. */
  1106. updateSelectedMethod: function (isInUpgradeWizard) {
  1107. if (isInUpgradeWizard) {
  1108. this.get('upgradeMethods').forEach(function (method) {
  1109. method.set('selected', method.get('type') === this.get('upgradeType'));
  1110. }, this);
  1111. } else {
  1112. var ruMethod = this.get('upgradeMethods').findProperty('type', 'ROLLING');
  1113. var euMethod = this.get('upgradeMethods').findProperty('type', 'NON_ROLLING');
  1114. if (ruMethod && ruMethod.get('isPrecheckFailed')) ruMethod.set('selected', false);
  1115. if (euMethod && euMethod.get('isPrecheckFailed')) euMethod.set('selected', false);
  1116. }
  1117. },
  1118. /**
  1119. * send request for pre upgrade check
  1120. * @param version
  1121. */
  1122. runPreUpgradeCheck: function(version) {
  1123. var params = {
  1124. value: version.get('repositoryVersion'),
  1125. label: version.get('displayName'),
  1126. type: version.get('upgradeType'),
  1127. skipComponentFailures: version.get('skipComponentFailures') ? 'true' : 'false',
  1128. skipSCFailures: version.get('skipSCFailures') ? 'true' : 'false'
  1129. };
  1130. if (App.get('supports.preUpgradeCheck')) {
  1131. this.set('requestInProgress', true);
  1132. App.ajax.send({
  1133. name: "admin.upgrade.pre_upgrade_check",
  1134. sender: this,
  1135. data: params,
  1136. success: "runPreUpgradeCheckSuccess",
  1137. error: "runPreUpgradeCheckError"
  1138. });
  1139. } else {
  1140. this.upgrade(params);
  1141. }
  1142. },
  1143. /**
  1144. * success callback of <code>runPreUpgradeCheckSuccess()</code>
  1145. * if there are some fails - it shows popup else run upgrade
  1146. * @param data {object}
  1147. * @param opt {object}
  1148. * @param params {object}
  1149. * @returns {App.ModalPopup|undefined}
  1150. */
  1151. runPreUpgradeCheckSuccess: function (data, opt, params) {
  1152. var self = this;
  1153. if (data.items.someProperty('UpgradeChecks.status', 'FAIL') || data.items.someProperty('UpgradeChecks.status', 'WARNING') || data.items.someProperty('UpgradeChecks.status', 'BYPASS')) {
  1154. this.set('requestInProgress', false);
  1155. var hasFails = data.items.someProperty('UpgradeChecks.status', 'FAIL'),
  1156. header = Em.I18n.t('popup.clusterCheck.Upgrade.header').format(params.label),
  1157. failTitle = Em.I18n.t('popup.clusterCheck.Upgrade.fail.title'),
  1158. failAlert = new Em.Handlebars.SafeString(Em.I18n.t('popup.clusterCheck.Upgrade.fail.alert')),
  1159. warningTitle = Em.I18n.t('popup.clusterCheck.Upgrade.warning.title'),
  1160. warningAlert = new Em.Handlebars.SafeString(Em.I18n.t('popup.clusterCheck.Upgrade.warning.alert')),
  1161. bypassedFailures = data.items.someProperty('UpgradeChecks.status', 'BYPASS').length > 0,
  1162. configsMergeWarning = data.items.findProperty('UpgradeChecks.id', 'CONFIG_MERGE'),
  1163. popupData = {
  1164. items: data.items.rejectProperty('UpgradeChecks.id', 'CONFIG_MERGE')
  1165. },
  1166. configs = this.getConfigsWarnings(configsMergeWarning);
  1167. App.showClusterCheckPopup(popupData, {
  1168. header: header,
  1169. failTitle: failTitle,
  1170. failAlert: failAlert,
  1171. warningTitle: warningTitle,
  1172. warningAlert: warningAlert,
  1173. bypassedFailures: bypassedFailures,
  1174. noCallbackCondition: hasFails,
  1175. callback: function () {
  1176. self.upgrade(params);
  1177. }
  1178. }, configs, params.label);
  1179. } else {
  1180. this.upgrade(params);
  1181. }
  1182. },
  1183. runPreUpgradeCheckError: function() {
  1184. this.set('requestInProgress', false);
  1185. },
  1186. confirmRetryUpgrade: function (version) {
  1187. var self = this;
  1188. return App.showConfirmationPopup(
  1189. function () {
  1190. self.retryUpgrade();
  1191. },
  1192. Em.I18n.t('admin.stackUpgrade.upgrade.retry.confirm.body').format(version.get('displayName')),
  1193. null,
  1194. Em.I18n.t('admin.stackUpgrade.dialog.header').format(version.get('upgradeTypeDislayName'), version.get('displayName'))
  1195. );
  1196. },
  1197. confirmRetryDowngrade: function () {
  1198. var self = this,
  1199. currentVersion = this.get('currentVersion');
  1200. return App.showConfirmationPopup(
  1201. function() {
  1202. self.retryUpgrade();
  1203. },
  1204. Em.I18n.t('admin.stackUpgrade.downgrade.retry.body').format(currentVersion.repository_name),
  1205. null,
  1206. Em.I18n.t('admin.stackUpgrade.dialog.downgrade.header').format(currentVersion.repository_name),
  1207. Em.I18n.t('admin.stackUpgrade.downgrade.proceed')
  1208. );
  1209. },
  1210. /**
  1211. * confirmation popup before install repository version
  1212. */
  1213. installRepoVersionConfirmation: function (repo) {
  1214. var self = this;
  1215. return App.showConfirmationPopup(function () {
  1216. self.installRepoVersion(repo);
  1217. },
  1218. Em.I18n.t('admin.stackVersions.version.install.confirm').format(repo.get('displayName'))
  1219. );
  1220. },
  1221. /**
  1222. * sends request to install repoVersion to the cluster
  1223. * and create clusterStackVersion resourse
  1224. * @param {Em.Object} repo
  1225. * @return {$.ajax}
  1226. * @method installRepoVersion
  1227. */
  1228. installRepoVersion: function (repo) {
  1229. this.set('requestInProgress', true);
  1230. this.set('requestInProgressRepoId', repo.get('id'));
  1231. var data = {
  1232. ClusterStackVersions: {
  1233. stack: repo.get('stackVersionType'),
  1234. version: repo.get('stackVersionNumber'),
  1235. repository_version: repo.get('repositoryVersion')
  1236. },
  1237. id: repo.get('id')
  1238. };
  1239. return App.ajax.send({
  1240. name: 'admin.stack_version.install.repo_version',
  1241. sender: this,
  1242. data: data,
  1243. success: 'installRepoVersionSuccess',
  1244. error: 'installRepoVersionError',
  1245. callback: function() {
  1246. this.sender.set('requestInProgress', false);
  1247. this.sender.set('requestInProgressRepoId', null);
  1248. }
  1249. });
  1250. },
  1251. /**
  1252. * transform repo data into json for
  1253. * saving changes to repository version
  1254. * @param {Em.Object} repo
  1255. * @returns {{operating_systems: Array}}
  1256. */
  1257. prepareRepoForSaving: function(repo) {
  1258. var repoVersion = { "operating_systems": [] };
  1259. var ambari_managed_repositories = !repo.get('useRedhatSatellite');
  1260. repo.get('operatingSystems').forEach(function (os, k) {
  1261. repoVersion.operating_systems.push({
  1262. "OperatingSystems": {
  1263. "os_type": os.get("osType"),
  1264. "ambari_managed_repositories": ambari_managed_repositories
  1265. },
  1266. "repositories": []
  1267. });
  1268. os.get('repositories').forEach(function (repository) {
  1269. repoVersion.operating_systems[k].repositories.push({
  1270. "Repositories": {
  1271. "base_url": repository.get('baseUrl'),
  1272. "repo_id": repository.get('repoId'),
  1273. "repo_name": repository.get('repoName')
  1274. }
  1275. });
  1276. });
  1277. });
  1278. return repoVersion;
  1279. },
  1280. /**
  1281. * Return stack version for the repo object
  1282. * @param {Em.Object} repo
  1283. * */
  1284. getStackVersionNumber: function(repo){
  1285. var stackVersionNumber = repo.get('stackVersion');
  1286. if(null == stackVersionNumber)
  1287. stackVersionNumber = App.get('currentStackVersion');
  1288. return stackVersionNumber;
  1289. },
  1290. /**
  1291. * perform validation if <code>skip<code> is false and run save if
  1292. * validation successfull or run save without validation is <code>skip<code> is true
  1293. * @param {Em.Object} repo
  1294. * @param {boolean} skip
  1295. * @returns {$.Deferred}
  1296. */
  1297. saveRepoOS: function (repo, skip) {
  1298. var self = this;
  1299. var deferred = $.Deferred();
  1300. this.validateRepoVersions(repo, skip).done(function(data) {
  1301. if (data.length > 0) {
  1302. deferred.resolve(data);
  1303. } else {
  1304. var repoVersion = self.prepareRepoForSaving(repo);
  1305. var stackVersionNumber = self.getStackVersionNumber(repo);
  1306. App.ajax.send({
  1307. name: 'admin.stack_versions.edit.repo',
  1308. sender: this,
  1309. data: {
  1310. stackName: App.get('currentStackName'),
  1311. stackVersion: stackVersionNumber,
  1312. repoVersionId: repo.get('repoVersionId'),
  1313. repoVersion: repoVersion
  1314. }
  1315. }).success(function() {
  1316. deferred.resolve([]);
  1317. });
  1318. }
  1319. });
  1320. return deferred.promise();
  1321. },
  1322. /**
  1323. * send request for validation for each repository
  1324. * @param {Em.Object} repo
  1325. * @param {boolean} skip
  1326. * @returns {*}
  1327. */
  1328. validateRepoVersions: function(repo, skip) {
  1329. var deferred = $.Deferred(),
  1330. totalCalls = 0,
  1331. invalidUrls = [];
  1332. if (skip) {
  1333. deferred.resolve(invalidUrls);
  1334. } else {
  1335. var stackVersionNumber = this.getStackVersionNumber(repo);
  1336. repo.get('operatingSystems').forEach(function (os) {
  1337. if (os.get('isSelected')) {
  1338. os.get('repositories').forEach(function (repo) {
  1339. totalCalls++;
  1340. App.ajax.send({
  1341. name: 'admin.stack_versions.validate.repo',
  1342. sender: this,
  1343. data: {
  1344. repo: repo,
  1345. repoId: repo.get('repoId'),
  1346. baseUrl: repo.get('baseUrl'),
  1347. osType: os.get('osType'),
  1348. stackName: App.get('currentStackName'),
  1349. stackVersion: stackVersionNumber
  1350. }
  1351. })
  1352. .success(function () {
  1353. totalCalls--;
  1354. if (totalCalls === 0) deferred.resolve(invalidUrls);
  1355. })
  1356. .error(function () {
  1357. repo.set('hasError', true);
  1358. invalidUrls.push(repo);
  1359. totalCalls--;
  1360. if (totalCalls === 0) deferred.resolve(invalidUrls);
  1361. });
  1362. });
  1363. } else {
  1364. return deferred.resolve(invalidUrls);
  1365. }
  1366. });
  1367. }
  1368. return deferred.promise();
  1369. },
  1370. /**
  1371. * success callback for <code>installRepoVersion()<code>
  1372. * saves request id to the db
  1373. * @param data
  1374. * @param opt
  1375. * @param params
  1376. * @method installStackVersionSuccess
  1377. */
  1378. installRepoVersionSuccess: function (data, opt, params) {
  1379. if (data && data.statusText === "timeout") {
  1380. App.showAlertPopup(Em.I18n.t('admin.stackVersions.upgrade.installPackage.fail.title'), Em.I18n.t('admin.stackVersions.upgrade.installPackage.fail.timeout'));
  1381. return false;
  1382. }
  1383. var version = App.RepositoryVersion.find(params.id);
  1384. App.db.set('repoVersionInstall', 'id', [data.Requests.id]);
  1385. App.clusterStatus.setClusterStatus({
  1386. wizardControllerName: this.get('name'),
  1387. localdb: App.db.data
  1388. });
  1389. version.set('defaultStatus', 'INSTALLING');
  1390. if (version.get('stackVersion')) {
  1391. version.set('stackVersion.state', 'INSTALLING');
  1392. }
  1393. },
  1394. /**
  1395. * error callback for <code>installRepoVersion()<code>
  1396. * show the error message
  1397. * @param data
  1398. * @method installStackVersionSuccess
  1399. */
  1400. installRepoVersionError: function (data) {
  1401. var header = Em.I18n.t('admin.stackVersions.upgrade.installPackage.fail.title');
  1402. var body = "";
  1403. if (data && data.responseText) {
  1404. try {
  1405. var json = $.parseJSON(data.responseText);
  1406. body = json.message;
  1407. } catch (err) {}
  1408. }
  1409. if (data && data.statusText === "timeout") {
  1410. body = Em.I18n.t('admin.stackVersions.upgrade.installPackage.fail.timeout');
  1411. }
  1412. App.showAlertPopup(header, body);
  1413. },
  1414. /**
  1415. * opens a popup with installations state per host
  1416. * @param {Em.Object} version
  1417. * @method showProgressPopup
  1418. */
  1419. showProgressPopup: function(version) {
  1420. var popupTitle = Em.I18n.t('admin.stackVersions.details.install.hosts.popup.title').format(version.get('displayName'));
  1421. var requestIds = App.get('testMode') ? [1] : App.db.get('repoVersionInstall', 'id');
  1422. var hostProgressPopupController = App.router.get('highAvailabilityProgressPopupController');
  1423. hostProgressPopupController.initPopup(popupTitle, requestIds, this);
  1424. },
  1425. /**
  1426. * reset upgradeState to INIT when upgrade is COMPLETED
  1427. * and clean auxiliary data
  1428. */
  1429. finish: function () {
  1430. if (App.get('upgradeState') === 'COMPLETED') {
  1431. var upgradeVersion = this.get('upgradeVersion') && this.get('upgradeVersion').match(/[a-zA-Z]+\-\d+\.\d+/);
  1432. this.setDBProperties({
  1433. upgradeId: undefined,
  1434. upgradeState: 'INIT',
  1435. upgradeVersion: undefined,
  1436. currentVersion: undefined,
  1437. upgradeTypeDisplayName: undefined,
  1438. upgradeType: undefined,
  1439. failuresTolerance: undefined,
  1440. isDowngrade: undefined,
  1441. downgradeAllowed: undefined
  1442. });
  1443. App.clusterStatus.setClusterStatus({
  1444. localdb: App.db.data
  1445. });
  1446. if (upgradeVersion && upgradeVersion[0]) {
  1447. App.set('currentStackVersion', upgradeVersion[0]);
  1448. }
  1449. App.set('upgradeState', 'INIT');
  1450. }
  1451. }.observes('App.upgradeState'),
  1452. /**
  1453. * Check <code>App.upgradeState</code> for HOLDING
  1454. * If it is, send request to check if current item is Finalize
  1455. * @method updateFinalize
  1456. */
  1457. updateFinalize: function () {
  1458. var upgradeState = App.get('upgradeState');
  1459. if (upgradeState === 'HOLDING') {
  1460. return App.ajax.send({
  1461. name: 'admin.upgrade.finalizeContext',
  1462. sender: this,
  1463. success: 'updateFinalizeSuccessCallback',
  1464. error: 'updateFinalizeErrorCallback'
  1465. })
  1466. }
  1467. else {
  1468. this.set('isFinalizeItem', false);
  1469. }
  1470. }.observes('App.upgradeState'),
  1471. /**
  1472. *
  1473. * @param {object|null} data
  1474. * @method updateFinalizeSuccessCallback
  1475. */
  1476. updateFinalizeSuccessCallback: function (data) {
  1477. var context = data ? Em.get(data, 'items.firstObject.upgrade_groups.firstObject.upgrade_items.firstObject.UpgradeItem.context') : '';
  1478. this.set('isFinalizeItem', context === this.get('finalizeContext'));
  1479. },
  1480. updateFinalizeErrorCallback: function() {
  1481. this.set('isFinalizeItem', false);
  1482. },
  1483. /**
  1484. * show dialog with tasks of upgrade
  1485. * @return {App.ModalPopup}
  1486. */
  1487. openUpgradeDialog: function () {
  1488. App.router.transitionTo('admin.stackUpgrade');
  1489. },
  1490. /**
  1491. * returns url to get data for repoVersion or clusterStackVersion
  1492. * @param {Boolean} stack true if load clusterStackVersion
  1493. * @param {Boolean} fullLoad true if load all data
  1494. * @returns {String}
  1495. * @method getUrl
  1496. */
  1497. getUrl: function(stack, fullLoad) {
  1498. if (App.get('testMode')) {
  1499. return stack ? this.get('mockStackUrl') : this.get('mockRepoUrl')
  1500. } else {
  1501. if (fullLoad) {
  1502. return stack ? this.get('realStackUrl') : this.get('realRepoUrl');
  1503. } else {
  1504. return this.get('realUpdateUrl');
  1505. }
  1506. }
  1507. },
  1508. /**
  1509. * get stack versions from server and push it to model
  1510. * @return {*}
  1511. * @method loadStackVersionsToModel
  1512. */
  1513. loadStackVersionsToModel: function (fullLoad) {
  1514. var dfd = $.Deferred();
  1515. App.HttpClient.get(this.getUrl(true, fullLoad), App.stackVersionMapper, {
  1516. complete: function () {
  1517. dfd.resolve();
  1518. }
  1519. });
  1520. return dfd.promise();
  1521. },
  1522. /**
  1523. * get repo versions from server and push it to model
  1524. * @return {*}
  1525. * @params {Boolean} isUpdate - if true loads part of data that need to be updated
  1526. * @method loadRepoVersionsToModel()
  1527. */
  1528. loadRepoVersionsToModel: function () {
  1529. var dfd = $.Deferred();
  1530. App.HttpClient.get(this.getUrl(false, true), App.repoVersionMapper, {
  1531. complete: function () {
  1532. dfd.resolve();
  1533. }
  1534. });
  1535. return dfd.promise();
  1536. },
  1537. /**
  1538. * set status to Upgrade item
  1539. * @param item
  1540. * @param status
  1541. */
  1542. setUpgradeItemStatus: function(item, status) {
  1543. this.set('requestInProgress', true);
  1544. return App.ajax.send({
  1545. name: 'admin.upgrade.upgradeItem.setState',
  1546. sender: this,
  1547. data: {
  1548. upgradeId: item.get('request_id'),
  1549. itemId: item.get('stage_id'),
  1550. groupId: item.get('group_id'),
  1551. status: status
  1552. },
  1553. callback: function() {
  1554. this.sender.set('requestInProgress', false);
  1555. }
  1556. }).done(function () {
  1557. item.set('status', status);
  1558. });
  1559. },
  1560. currentVersionObserver: function () {
  1561. var versionNumber = this.get('currentVersion.repository_version');
  1562. var currentVersionObject = App.RepositoryVersion.find().findProperty('status', 'CURRENT');
  1563. var versionName = currentVersionObject && currentVersionObject.get('stackVersionType');
  1564. App.set('isStormMetricsSupported', versionName != 'HDP' || stringUtils.compareVersions(versionNumber, '2.2.2') > -1 || !versionNumber);
  1565. }.observes('currentVersion.repository_version'),
  1566. /**
  1567. * get the installed repositories of HDP from server
  1568. */
  1569. loadRepositories: function () {
  1570. if (App.router.get('clusterController.isLoaded')) {
  1571. var nameVersionCombo = App.get('currentStackVersion');
  1572. var stackName = nameVersionCombo.split('-')[0];
  1573. var stackVersion = nameVersionCombo.split('-')[1];
  1574. App.ajax.send({
  1575. name: 'cluster.load_repositories',
  1576. sender: this,
  1577. data: {
  1578. stackName: stackName,
  1579. stackVersion: stackVersion
  1580. },
  1581. success: 'loadRepositoriesSuccessCallback',
  1582. error: 'loadRepositoriesErrorCallback'
  1583. });
  1584. }
  1585. }.observes('App.router.clusterController.isLoaded'),
  1586. loadRepositoriesSuccessCallback: function (data) {
  1587. var allRepos = [];
  1588. data.items.forEach(function (os) {
  1589. os.repositories.forEach(function (repository) {
  1590. var osType = repository.Repositories.os_type;
  1591. var repo = Em.Object.create({
  1592. baseUrl: repository.Repositories.base_url,
  1593. osType: osType,
  1594. repoId: repository.Repositories.repo_id,
  1595. repoName : repository.Repositories.repo_name,
  1596. stackName : repository.Repositories.stack_name,
  1597. stackVersion : repository.Repositories.stack_version,
  1598. isFirst: false
  1599. });
  1600. var group = allRepos.findProperty('name', osType);
  1601. if (!group) {
  1602. group = {
  1603. name: osType,
  1604. repositories: []
  1605. };
  1606. repo.set('isFirst', true);
  1607. allRepos.push(group);
  1608. }
  1609. group.repositories.push(repo);
  1610. });
  1611. }, this);
  1612. allRepos.stackVersion = App.get('currentStackVersionNumber');
  1613. this.set('allRepos', allRepos);
  1614. },
  1615. loadRepositoriesErrorCallback: function (request, ajaxOptions, error) {
  1616. },
  1617. /**
  1618. * @returns {$.ajax}
  1619. */
  1620. suspendUpgrade: function () {
  1621. var self = this;
  1622. return this.abortUpgradeWithSuspend().done(function () {
  1623. App.set('upgradeState', 'ABORTED');
  1624. self.setDBProperty('upgradeState', 'ABORTED');
  1625. App.clusterStatus.setClusterStatus({
  1626. wizardControllerName: self.get('name'),
  1627. localdb: App.db.data
  1628. });
  1629. });
  1630. },
  1631. /**
  1632. * @returns {$.ajax}
  1633. */
  1634. resumeUpgrade: function() {
  1635. var self = this;
  1636. this.retryUpgrade().done(function () {
  1637. App.set('upgradeState', 'PENDING');
  1638. App.propertyDidChange('upgradeSuspended');
  1639. self.setDBProperty('upgradeState', 'PENDING');
  1640. App.clusterStatus.setClusterStatus({
  1641. wizardControllerName: self.get('name'),
  1642. localdb: App.db.data
  1643. });
  1644. });
  1645. },
  1646. /**
  1647. * restore last Upgrade data
  1648. * @param {object} lastUpgradeData
  1649. */
  1650. restoreLastUpgrade: function(lastUpgradeData) {
  1651. var self = this;
  1652. var upgradeType = this.get('upgradeMethods').findProperty('type', lastUpgradeData.Upgrade.upgrade_type);
  1653. this.setDBProperties({
  1654. upgradeId: lastUpgradeData.Upgrade.request_id,
  1655. isDowngrade: lastUpgradeData.Upgrade.direction === 'DOWNGRADE',
  1656. upgradeState: lastUpgradeData.Upgrade.request_status,
  1657. upgradeType: lastUpgradeData.Upgrade.upgrade_type,
  1658. downgradeAllowed: lastUpgradeData.Upgrade.downgrade_allowed,
  1659. upgradeTypeDisplayName: upgradeType.get('displayName'),
  1660. failuresTolerance: Em.Object.create({
  1661. skipComponentFailures: lastUpgradeData.Upgrade.skip_failures,
  1662. skipSCFailures: lastUpgradeData.Upgrade.skip_service_check_failures
  1663. })
  1664. });
  1665. this.loadRepoVersionsToModel().done(function () {
  1666. var toVersion = App.RepositoryVersion.find().findProperty('repositoryVersion', lastUpgradeData.Upgrade.to_version);
  1667. self.setDBProperty('upgradeVersion', toVersion && toVersion.get('displayName'));
  1668. self.initDBProperties();
  1669. self.loadUpgradeData(true);
  1670. });
  1671. },
  1672. /**
  1673. * Build table from configs list and open new window to show this table
  1674. * @param configs
  1675. */
  1676. openConfigsInNewWindow: function (configs) {
  1677. var newWindow;
  1678. var output = '';
  1679. output += '<table style="text-align: left;"><thead><tr>' +
  1680. '<th>' + Em.I18n.t('popup.clusterCheck.Upgrade.configsMerge.configType') + '</th>' +
  1681. '<th>' + Em.I18n.t('popup.clusterCheck.Upgrade.configsMerge.propertyName') + '</th>' +
  1682. '<th>' + Em.I18n.t('popup.clusterCheck.Upgrade.configsMerge.currentValue') + '</th>' +
  1683. '<th>' + Em.I18n.t('popup.clusterCheck.Upgrade.configsMerge.recommendedValue') + '</th>' +
  1684. '<th>' + Em.I18n.t('popup.clusterCheck.Upgrade.configsMerge.resultingValue') + '</th>' +
  1685. '</tr></thead><tbody>';
  1686. configs.context.forEach(function (config) {
  1687. output += '<tr>' +
  1688. '<td>' + config.type + '</td>' +
  1689. '<td>' + config.name + '</td>' +
  1690. '<td>' + config.currentValue + '</td>' +
  1691. '<td>' + config.recommendedValue + '</td>' +
  1692. '<td>' + config.resultingValue + '</td>' +
  1693. '</tr>';
  1694. });
  1695. output += '</tbody></table>';
  1696. newWindow = window.open();
  1697. newWindow.document.write(output);
  1698. newWindow.focus();
  1699. },
  1700. /**
  1701. * load version for services to display on Choose Services page
  1702. * should load from VersionDefinition endpoint
  1703. */
  1704. loadServiceVersionFromVersionDefinitions: function () {
  1705. return App.ajax.send({
  1706. name: 'cluster.load_current_repo_stack_services',
  1707. sender: this,
  1708. data: {
  1709. clusterName: App.get('clusterName')
  1710. },
  1711. success: 'loadServiceVersionFromVersionDefinitionsSuccessCallback',
  1712. error: 'loadServiceVersionFromVersionDefinitionsErrorCallback'
  1713. });
  1714. },
  1715. serviceVersionsMap: {},
  1716. /**
  1717. * @param {object|null} jsonData
  1718. */
  1719. loadServiceVersionFromVersionDefinitionsSuccessCallback: function (jsonData) {
  1720. var rv = jsonData.items[0].repository_versions[0].RepositoryVersions;
  1721. var map = this.get('serviceVersionsMap');
  1722. if (rv) {
  1723. rv.stack_services.forEach(function (item) {
  1724. map[item.name] = item.versions[0];
  1725. });
  1726. }
  1727. },
  1728. loadServiceVersionFromVersionDefinitionsErrorCallback: function (request, ajaxOptions, error) {}
  1729. });