stack_and_upgrade_controller.js 50 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542
  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. * version that currently applied to server
  68. * should be plain object, because stored to localStorage
  69. * @type {object|null}
  70. */
  71. currentVersion: null,
  72. /**
  73. * versions to which cluster could be upgraded
  74. * @type {Array}
  75. */
  76. targetVersions: [],
  77. /**
  78. * @type {object}
  79. * @default null
  80. */
  81. slaveComponentStructuredInfo: null,
  82. /**
  83. * @type {Array}
  84. */
  85. serviceCheckFailuresServicenames: [],
  86. /**
  87. * methods through which cluster could be upgraded, "allowed" indicated if the method is allowed
  88. * by stack upgrade path
  89. * @type {Array}
  90. */
  91. upgradeMethods: [
  92. Em.Object.create({
  93. displayName: Em.I18n.t('admin.stackVersions.version.upgrade.upgradeOptions.RU.title'),
  94. type: 'ROLLING',
  95. icon: "icon-dashboard",
  96. description: Em.I18n.t('admin.stackVersions.version.upgrade.upgradeOptions.RU.description'),
  97. selected: false,
  98. allowed: true
  99. }),
  100. Em.Object.create({
  101. displayName: Em.I18n.t('admin.stackVersions.version.upgrade.upgradeOptions.EU.title'),
  102. type: 'NON_ROLLING',
  103. icon: "icon-bolt",
  104. description: Em.I18n.t('admin.stackVersions.version.upgrade.upgradeOptions.EU.description'),
  105. selected: false,
  106. allowed: true
  107. })
  108. ],
  109. /**
  110. * @type {boolean} true if some request that should disable actions is in progress
  111. */
  112. requestInProgress: false,
  113. /**
  114. * @type {boolean} true while no updated upgrade info is loaded after retry
  115. */
  116. isRetryPending: false,
  117. /**
  118. * properties that stored to localStorage to resume wizard progress
  119. */
  120. wizardStorageProperties: [
  121. 'upgradeId',
  122. 'upgradeVersion',
  123. 'currentVersion',
  124. 'upgradeTypeDisplayName',
  125. 'upgradeType',
  126. 'failuresTolerance',
  127. 'isDowngrade',
  128. 'downgradeAllowed',
  129. 'isSuspended'
  130. ],
  131. /**
  132. * mutable properties of Upgrade Task
  133. * @type {Array}
  134. */
  135. taskDetailsProperties: ['status', 'stdout', 'stderr', 'error_log', 'host_name', 'output_log'],
  136. /**
  137. * Context for Finalize item
  138. * @type {string}
  139. */
  140. finalizeContext: 'Confirm Finalize',
  141. /**
  142. * Context for Slave component failures manual item
  143. * @type {string}
  144. */
  145. slaveFailuresContext: "Check Component Versions",
  146. /**
  147. * Context for Service check (may include slave component) failures manual item
  148. * @type {string}
  149. */
  150. serviceCheckFailuresContext: "Verifying Skipped Failures",
  151. /**
  152. * Check if current item is Finalize
  153. * @type {boolean}
  154. */
  155. isFinalizeItem: false,
  156. isLoadUpgradeDataPending: false,
  157. /**
  158. * path to the mock json
  159. * @type {String}
  160. */
  161. mockRepoUrl: '/data/stack_versions/repo_versions_all.json',
  162. /**
  163. * api to get RepoVersions
  164. * @type {String}
  165. */
  166. realRepoUrl: function () {
  167. return App.get('apiPrefix') + App.get('stackVersionURL') +
  168. '/compatible_repository_versions?fields=*,operating_systems/*,operating_systems/repositories/*';
  169. }.property('App.stackVersionURL'),
  170. /**
  171. * path to the mock json
  172. * @type {String}
  173. */
  174. mockStackUrl: '/data/stack_versions/stack_version_all.json',
  175. /**
  176. * api to get ClusterStackVersions with repository_versions (use to init data load)
  177. * @type {String}
  178. */
  179. realStackUrl: function () {
  180. return App.get('apiPrefix') + '/clusters/' + App.get('clusterName') +
  181. '/stack_versions?fields=*,repository_versions/*,repository_versions/operating_systems/repositories/*';
  182. }.property('App.clusterName'),
  183. /**
  184. * api to get ClusterStackVersions without repository_versions (use to update data)
  185. * @type {String}
  186. */
  187. realUpdateUrl: function () {
  188. return App.get('apiPrefix') + '/clusters/' + App.get('clusterName') + '/stack_versions?fields=ClusterStackVersions/*';
  189. }.property('App.clusterName'),
  190. /**
  191. * Determines if list of services with checks that failed and were skipped by user during the upgrade is loaded
  192. * @type {boolean}
  193. */
  194. areSkippedServiceChecksLoaded: false,
  195. /**
  196. * List of services with checks that failed and were skipped by user during the upgrade
  197. * @type {array}
  198. */
  199. skippedServiceChecks: [],
  200. /**
  201. * status of tasks/items/groups which should be grayed out and disabled
  202. * @type {Array}
  203. */
  204. nonActiveStates: ['PENDING', 'ABORTED'],
  205. /**
  206. * status of Upgrade request
  207. * @type {string}
  208. */
  209. requestStatus: function () {
  210. if (this.get('isSuspended')) {
  211. return 'SUSPENDED';
  212. } else if (this.get('upgradeData.Upgrade')){
  213. return this.get('upgradeData.Upgrade.request_status');
  214. } else {
  215. return '';
  216. }
  217. }.property('isSuspended', 'upgradeData.Upgrade.request_status'),
  218. init: function () {
  219. this.initDBProperties();
  220. },
  221. /**
  222. * restore data from localStorage
  223. */
  224. initDBProperties: function () {
  225. var props = this.getDBProperties(this.get('wizardStorageProperties'));
  226. Em.keys(props).forEach(function (k) {
  227. if (!Em.isNone(props[k])) {
  228. this.set(k, props[k]);
  229. }
  230. }, this);
  231. },
  232. /**
  233. * load all data:
  234. * - upgrade data
  235. * - stack versions
  236. * - repo versions
  237. */
  238. load: function () {
  239. var dfd = $.Deferred();
  240. var self = this;
  241. this.loadUpgradeData(true).done(function() {
  242. self.loadStackVersionsToModel(true).done(function () {
  243. self.loadRepoVersionsToModel().done(function() {
  244. var currentVersion = App.StackVersion.find().findProperty('state', 'CURRENT');
  245. if (currentVersion) {
  246. self.set('currentVersion', {
  247. repository_version: currentVersion.get('repositoryVersion.repositoryVersion'),
  248. repository_name: currentVersion.get('repositoryVersion.displayName')
  249. });
  250. }
  251. dfd.resolve();
  252. });
  253. });
  254. });
  255. return dfd.promise();
  256. },
  257. /**
  258. * load upgrade tasks by upgrade id
  259. * @return {$.Deferred}
  260. * @param {boolean} onlyState
  261. */
  262. loadUpgradeData: function (onlyState) {
  263. var upgradeId = this.get('upgradeId'),
  264. deferred = $.Deferred(),
  265. self = this;
  266. if (Em.isNone(upgradeId)) {
  267. deferred.resolve();
  268. } else {
  269. this.set('isLoadUpgradeDataPending', true);
  270. App.ajax.send({
  271. name: (onlyState) ? 'admin.upgrade.state' : 'admin.upgrade.data',
  272. sender: this,
  273. data: {
  274. id: upgradeId
  275. },
  276. success: 'loadUpgradeDataSuccessCallback'
  277. }).then(deferred.resolve).complete(function () {
  278. self.set('isLoadUpgradeDataPending', false);
  279. });
  280. }
  281. return deferred.promise();
  282. },
  283. /**
  284. * parse and push upgrade tasks to controller
  285. * @param data
  286. */
  287. loadUpgradeDataSuccessCallback: function (data) {
  288. if (Em.isNone(data)) return;
  289. App.set('upgradeState', data.Upgrade.request_status);
  290. this.setDBProperty('upgradeState', data.Upgrade.request_status);
  291. if (data.upgrade_groups) {
  292. this.updateUpgradeData(data);
  293. }
  294. if (this.get('isRetryPending') && data.Upgrade.request_status != 'ABORTED') {
  295. this.setProperties({
  296. requestInProgress: false,
  297. isRetryPending: false
  298. });
  299. }
  300. },
  301. /**
  302. * update data of Upgrade
  303. * @param {object} newData
  304. */
  305. updateUpgradeData: function (newData) {
  306. var oldData = this.get('upgradeData'),
  307. nonActiveStates = this.get('nonActiveStates'),
  308. groupsMap = {},
  309. itemsMap = {};
  310. if (Em.isNone(oldData) || (newData.upgrade_groups.length !== oldData.upgradeGroups.length)) {
  311. this.initUpgradeData(newData);
  312. } else {
  313. //create entities maps
  314. newData.upgrade_groups.forEach(function (newGroup) {
  315. groupsMap[newGroup.UpgradeGroup.group_id] = newGroup.UpgradeGroup;
  316. newGroup.upgrade_items.forEach(function (item) {
  317. itemsMap[item.UpgradeItem.stage_id] = item.UpgradeItem;
  318. })
  319. });
  320. //update existed entities with new data
  321. oldData.upgradeGroups.forEach(function (oldGroup) {
  322. oldGroup.set('status', groupsMap[oldGroup.get('group_id')].status);
  323. oldGroup.set('progress_percent', groupsMap[oldGroup.get('group_id')].progress_percent);
  324. oldGroup.set('completed_task_count', groupsMap[oldGroup.get('group_id')].completed_task_count);
  325. oldGroup.upgradeItems.forEach(function (item) {
  326. item.set('status', itemsMap[item.get('stage_id')].status);
  327. item.set('progress_percent', itemsMap[item.get('stage_id')].progress_percent);
  328. });
  329. var hasExpandableItems = oldGroup.upgradeItems.some(function (item) {
  330. return !nonActiveStates.contains(item.get('status'));
  331. });
  332. oldGroup.set('hasExpandableItems', hasExpandableItems);
  333. });
  334. oldData.set('Upgrade', newData.Upgrade);
  335. }
  336. },
  337. /**
  338. * change structure of Upgrade
  339. * In order to maintain nested views in template object should have direct link to its properties, for example
  340. * item.UpgradeItem.<properties> -> item.<properties>
  341. * @param {object} newData
  342. */
  343. initUpgradeData: function (newData) {
  344. var upgradeGroups = [],
  345. nonActiveStates = this.get('nonActiveStates');
  346. //wrap all entities into App.upgradeEntity
  347. newData.upgrade_groups.forEach(function (newGroup) {
  348. var hasExpandableItems = newGroup.upgrade_items.some(function (item) {
  349. return !nonActiveStates.contains(item.UpgradeItem.status);
  350. }),
  351. oldGroup = App.upgradeEntity.create({type: 'GROUP', hasExpandableItems: hasExpandableItems}, newGroup.UpgradeGroup),
  352. upgradeItems = [];
  353. newGroup.upgrade_items.forEach(function (item) {
  354. var oldItem = App.upgradeEntity.create({type: 'ITEM'}, item.UpgradeItem);
  355. oldItem.set('tasks', []);
  356. upgradeItems.pushObject(oldItem);
  357. });
  358. upgradeItems.reverse();
  359. oldGroup.set('upgradeItems', upgradeItems);
  360. upgradeGroups.pushObject(oldGroup);
  361. });
  362. upgradeGroups.reverse();
  363. this.set('upgradeData', Em.Object.create({
  364. upgradeGroups: upgradeGroups,
  365. Upgrade: newData.Upgrade
  366. }));
  367. this.set('downgradeAllowed', newData.Upgrade.downgrade_allowed);
  368. this.setDBProperty('downgradeAllowed', newData.Upgrade.downgrade_allowed);
  369. },
  370. /**
  371. * request Upgrade Item and its tasks from server
  372. * @param {Em.Object} item
  373. * @param {Function} customCallback
  374. * @return {$.ajax}
  375. */
  376. getUpgradeItem: function (item, customCallback) {
  377. return App.ajax.send({
  378. name: 'admin.upgrade.upgrade_item',
  379. sender: this,
  380. data: {
  381. upgradeId: item.get('request_id'),
  382. groupId: item.get('group_id'),
  383. stageId: item.get('stage_id')
  384. },
  385. success: customCallback || 'getUpgradeItemSuccessCallback'
  386. });
  387. },
  388. /**
  389. * success callback of <code>getTasks</code>
  390. * @param {object} data
  391. */
  392. getUpgradeItemSuccessCallback: function (data) {
  393. this.get('upgradeData.upgradeGroups').forEach(function (group) {
  394. if (group.get('group_id') === data.UpgradeItem.group_id) {
  395. group.get('upgradeItems').forEach(function (item) {
  396. if (item.get('stage_id') === data.UpgradeItem.stage_id) {
  397. if (item.get('tasks.length')) {
  398. item.set('isTasksLoaded', true);
  399. data.tasks.forEach(function (task) {
  400. var currentTask = item.get('tasks').findProperty('id', task.Tasks.id);
  401. this.get('taskDetailsProperties').forEach(function (property) {
  402. currentTask.set(property, task.Tasks[property]);
  403. }, this);
  404. }, this);
  405. } else {
  406. var tasks = [];
  407. data.tasks.forEach(function (task) {
  408. tasks.pushObject(App.upgradeEntity.create({type: 'TASK'}, task.Tasks));
  409. });
  410. item.set('tasks', tasks);
  411. }
  412. item.set('isTasksLoaded', true);
  413. }
  414. }, this);
  415. }
  416. }, this);
  417. },
  418. /**
  419. * Failures info may includes service_check and host_component failures. These two types should be displayed separately.
  420. */
  421. getServiceCheckItemSuccessCallback: function(data) {
  422. var task = data.tasks[0];
  423. var info = {
  424. hosts: [],
  425. host_detail: {}
  426. };
  427. if (task && task.Tasks && task.Tasks.structured_out && task.Tasks.structured_out.failures) {
  428. this.set('serviceCheckFailuresServicenames', task.Tasks.structured_out.failures.service_check || []);
  429. if (task.Tasks.structured_out.failures.host_component) {
  430. for (var hostname in task.Tasks.structured_out.failures.host_component){
  431. info.hosts.push(hostname);
  432. }
  433. info.host_detail = task.Tasks.structured_out.failures.host_component;
  434. }
  435. this.set('slaveComponentStructuredInfo', info);
  436. }
  437. },
  438. getSlaveComponentItemSuccessCallback: function(data) {
  439. var info = data.tasks[0];
  440. if (info && info.Tasks && info.Tasks.structured_out) {
  441. this.set('slaveComponentStructuredInfo', info.Tasks.structured_out);
  442. }
  443. },
  444. /**
  445. * downgrade confirmation popup
  446. * @param {object} event
  447. */
  448. confirmDowngrade: function (event) {
  449. var self = this;
  450. var currentVersion = this.get('currentVersion');
  451. return App.showConfirmationPopup(
  452. function() {
  453. self.downgrade.call(self, currentVersion, event);
  454. },
  455. Em.I18n.t('admin.stackUpgrade.downgrade.body').format(currentVersion.repository_name),
  456. null,
  457. Em.I18n.t('admin.stackUpgrade.dialog.downgrade.header').format(currentVersion.repository_name),
  458. Em.I18n.t('admin.stackUpgrade.downgrade.proceed')
  459. );
  460. },
  461. /**
  462. * make call to start downgrade process
  463. * @param {object} currentVersion
  464. * @param {object} event
  465. */
  466. downgrade: function (currentVersion, event) {
  467. this.set('requestInProgress', true);
  468. this.abortUpgrade();
  469. App.ajax.send({
  470. name: 'admin.downgrade.start',
  471. sender: this,
  472. data: {
  473. from: App.RepositoryVersion.find().findProperty('displayName', this.get('upgradeVersion')).get('repositoryVersion'),
  474. value: currentVersion.repository_version,
  475. label: currentVersion.repository_name,
  476. isDowngrade: true,
  477. upgradeType: this.get('upgradeType')
  478. },
  479. success: 'upgradeSuccessCallback',
  480. callback: function() {
  481. this.sender.set('requestInProgress', false);
  482. }
  483. });
  484. },
  485. /**
  486. * abort upgrade (in order to start Downgrade)
  487. */
  488. abortUpgrade: function () {
  489. return App.ajax.send({
  490. name: 'admin.upgrade.abort',
  491. sender: this,
  492. data: {
  493. upgradeId: this.get('upgradeId')
  494. }
  495. });
  496. },
  497. retryUpgrade: function () {
  498. this.setProperties({
  499. requestInProgress: true,
  500. isRetryPending: true
  501. });
  502. return App.ajax.send({
  503. name: 'admin.upgrade.retry',
  504. sender: this,
  505. data: {
  506. upgradeId: this.get('upgradeId')
  507. }
  508. });
  509. },
  510. /**
  511. * make call to start upgrade process and show popup with current progress
  512. * @param {object} version
  513. */
  514. upgrade: function (version) {
  515. this.set('requestInProgress', true);
  516. App.ajax.send({
  517. name: 'admin.upgrade.start',
  518. sender: this,
  519. data: version,
  520. success: 'upgradeSuccessCallback',
  521. callback: function() {
  522. this.sender.set('requestInProgress', false);
  523. }
  524. });
  525. this.setDBProperty('currentVersion', this.get('currentVersion'));
  526. },
  527. /**
  528. * success callback of <code>upgrade()</code>
  529. * @param {object} data
  530. */
  531. upgradeSuccessCallback: function (data, opt, params) {
  532. this.set('upgradeData', null);
  533. this.set('upgradeId', data.resources[0].Upgrade.request_id);
  534. this.set('upgradeVersion', params.label);
  535. this.set('isDowngrade', !!params.isDowngrade);
  536. var upgradeMethod = this.get('upgradeMethods').findProperty('type', params.type);
  537. var upgradeTypeDisplayName = null;
  538. var upgradeType = null;
  539. if (upgradeMethod) {
  540. upgradeTypeDisplayName = upgradeMethod.get('displayName');
  541. upgradeType = upgradeMethod.get('type');
  542. }
  543. this.set('upgradeType', upgradeType);
  544. this.set('upgradeTypeDisplayName', upgradeTypeDisplayName);
  545. this.set('failuresTolerance', Em.Object.create({
  546. skipComponentFailures: params.skipComponentFailures == 'true',
  547. skipSCFailures: params.skipSCFailures == 'true'
  548. }));
  549. this.setDBProperties({
  550. upgradeVersion: params.label,
  551. upgradeId: data.resources[0].Upgrade.request_id,
  552. upgradeState: 'PENDING',
  553. isDowngrade: !!params.isDowngrade,
  554. upgradeType: upgradeType,
  555. upgradeTypeDisplayName: upgradeTypeDisplayName,
  556. failuresTolerance: Em.Object.create({
  557. skipComponentFailures: params.skipComponentFailures == 'true',
  558. skipSCFailures: params.skipSCFailures == 'true'
  559. })
  560. });
  561. App.set('upgradeState', 'PENDING');
  562. App.clusterStatus.setClusterStatus({
  563. wizardControllerName: this.get('name'),
  564. localdb: App.db.data
  565. });
  566. this.load();
  567. this.openUpgradeDialog();
  568. },
  569. /**
  570. * success callback of updating upgrade options including failures tolerance. etc
  571. * @param {object} data
  572. */
  573. updateOptionsSuccessCallback: function (data, opt, params) {
  574. this.set('failuresTolerance', Em.Object.create({
  575. skipComponentFailures: params.skipComponentFailures == 'true',
  576. skipSCFailures: params.skipSCFailures == 'true'
  577. }));
  578. },
  579. /**
  580. * run upgrade checks and add results to each method object and set selected method
  581. * @param {Em.Object} version
  582. */
  583. runUpgradeMethodChecks: function(version) {
  584. this.get('upgradeMethods').forEach(function (method) {
  585. if (method.get('allowed')) {
  586. this.runPreUpgradeCheckOnly({
  587. value: version.get('repositoryVersion'),
  588. label: version.get('displayName'),
  589. type: method.get('type')
  590. });
  591. }
  592. }, this);
  593. },
  594. /**
  595. * Open upgrade options window: upgrade type and failures tolerance
  596. * @param {boolean} isInUpgradeWizard
  597. * @param {object} version
  598. * @return App.ModalPopup
  599. */
  600. upgradeOptions: function (isInUpgradeWizard, version) {
  601. var self = this;
  602. if (!isInUpgradeWizard) {
  603. this.getSupportedUpgradeTypes(Ember.Object.create({
  604. stackName: App.get('currentStackVersion').split('-')[0],
  605. stackVersion: App.get('currentStackVersion').split('-')[1],
  606. toVersion: version.get('repositoryVersion')
  607. })).done(function(){
  608. self.runUpgradeMethodChecks(version);
  609. });
  610. }
  611. return App.ModalPopup.show({
  612. encodeBody: false,
  613. primary: isInUpgradeWizard ? Em.I18n.t('ok') : Em.I18n.t('common.proceed'),
  614. primaryClass: 'btn-success',
  615. classNames: ['upgrade-options-popup'],
  616. header: Em.I18n.t('admin.stackVersions.version.upgrade.upgradeOptions.header'),
  617. bodyClass: Em.View.extend({
  618. templateName: require('templates/main/admin/stack_upgrade/upgrade_options'),
  619. didInsertElement: function () {
  620. App.tooltip($(".failure-tolerance-tooltip"), {
  621. placement: "top",
  622. title: Em.I18n.t('admin.stackVersions.version.upgrade.upgradeOptions.tolerance.tooltip')
  623. });
  624. App.tooltip($(".not-allowed-by-version"), {
  625. placement: "bottom",
  626. title: Em.I18n.t('admin.stackVersions.version.upgrade.upgradeOptions.notAllowed')
  627. });
  628. Em.run.later(this, function () {
  629. App.tooltip($(".thumbnail.check-failed"), {
  630. placement: "bottom",
  631. title: Em.I18n.t('admin.stackVersions.version.upgrade.upgradeOptions.preCheck.failed.tooltip')
  632. });
  633. }, 1000);
  634. },
  635. upgradeMethods: function () {
  636. self.updateSelectedMethod(isInUpgradeWizard);
  637. return self.get('upgradeMethods');
  638. }.property().volatile(),
  639. isInUpgradeWizard: isInUpgradeWizard,
  640. versionText: isInUpgradeWizard ? '' : Em.I18n.t('admin.stackVersions.version.upgrade.upgradeOptions.bodyMsg.version').format(version.get('displayName')),
  641. selectMethod: function (event) {
  642. if (isInUpgradeWizard || !event.context.get('allowed') || event.context.get('isPrecheckFailed')) return;
  643. var selectedMethod = event.context;
  644. self.updateSelectedMethod(isInUpgradeWizard);
  645. self.get('upgradeMethods').forEach(function (method) {
  646. method.set('selected', false);
  647. });
  648. selectedMethod.set('selected', true);
  649. this.set('parentView.selectedMethod', selectedMethod);
  650. },
  651. openMessage: function (event) {
  652. if (isInUpgradeWizard || !event.context.get('allowed')) return;
  653. var data = event.context.get('precheckResultsData');
  654. var header = Em.I18n.t('popup.clusterCheck.Upgrade.header').format(version.get('displayName')),
  655. failTitle = Em.I18n.t('popup.clusterCheck.Upgrade.fail.title'),
  656. failAlert = new Em.Handlebars.SafeString(Em.I18n.t('popup.clusterCheck.Upgrade.fail.alert')),
  657. warningTitle = Em.I18n.t('popup.clusterCheck.Upgrade.warning.title'),
  658. warningAlert = new Em.Handlebars.SafeString(Em.I18n.t('popup.clusterCheck.Upgrade.warning.alert')),
  659. configsMergeWarning = data.items.findProperty('UpgradeChecks.id', "CONFIG_MERGE"),
  660. configs = [];
  661. if (configsMergeWarning && Em.get(configsMergeWarning, 'UpgradeChecks.status') === 'WARNING') {
  662. var popupData = {
  663. items: data.items.rejectProperty('UpgradeChecks.id', 'CONFIG_MERGE')
  664. },
  665. configsMergeCheckData = Em.get(configsMergeWarning, 'UpgradeChecks.failed_detail');
  666. if (configsMergeCheckData) {
  667. configs = configsMergeCheckData.map(function (item) {
  668. var isDeprecated = Em.isNone(item.new_stack_value),
  669. willBeRemoved = Em.isNone(item.result_value);
  670. return {
  671. type: item.type,
  672. name: item.property,
  673. currentValue: item.current,
  674. recommendedValue: isDeprecated ? Em.I18n.t('popup.clusterCheck.Upgrade.configsMerge.deprecated') : item.new_stack_value,
  675. isDeprecated: isDeprecated,
  676. resultingValue: willBeRemoved ? Em.I18n.t('popup.clusterCheck.Upgrade.configsMerge.willBeRemoved') : item.result_value,
  677. willBeRemoved: willBeRemoved
  678. };
  679. });
  680. }
  681. }
  682. App.showClusterCheckPopup(popupData, {
  683. header: header,
  684. failTitle: failTitle,
  685. failAlert: failAlert,
  686. warningTitle: warningTitle,
  687. warningAlert: warningAlert,
  688. primary: Em.I18n.t('admin.stackVersions.version.upgrade.upgradeOptions.preCheck.rerun'),
  689. secondary: Em.I18n.t('common.cancel'),
  690. callback: function () {
  691. self.runPreUpgradeCheckOnly.call(self, {
  692. value: version.get('repositoryVersion'),
  693. label: version.get('displayName'),
  694. type: event.context.get('type')
  695. });
  696. }
  697. }, configs, version.get('displayName'));
  698. }
  699. }),
  700. /**
  701. * @type {Em.Object}
  702. * @default null
  703. */
  704. selectedMethod: null,
  705. skipComponentFailures: self.get('failuresTolerance.skipComponentFailures'),
  706. skipSCFailures: self.get('failuresTolerance.skipSCFailures'),
  707. disablePrimary: function () {
  708. if (isInUpgradeWizard) return false;
  709. var selectedMethod = self.get('upgradeMethods').findProperty('selected');
  710. return selectedMethod ? selectedMethod.get('isPrecheckFailed') : true;
  711. }.property('selectedMethod'),
  712. onPrimary: function () {
  713. this.hide();
  714. if (isInUpgradeWizard) {
  715. return App.ajax.send({
  716. name: 'admin.upgrade.update.options',
  717. sender: self,
  718. data: {
  719. upgradeId: self.get('upgradeId'),
  720. skipComponentFailures: Boolean(this.get('skipComponentFailures')).toString(),
  721. skipSCFailures: Boolean(this.get('skipSCFailures')).toString()
  722. },
  723. success: 'updateOptionsSuccessCallback'
  724. });
  725. } else {
  726. var upgradeMethod = self.get('upgradeMethods').findProperty('selected');
  727. version.upgradeType = upgradeMethod.get('type');
  728. version.upgradeTypeDisplayName = upgradeMethod.get('displayName');
  729. version.skipComponentFailures = this.get('skipComponentFailures');
  730. version.skipSCFailures = this.get('skipSCFailures');
  731. var fromVersion = self.get('upgradeVersion') || App.RepositoryVersion.find().findProperty('status', 'CURRENT').get('displayName');
  732. var toVersion = version.get('displayName');
  733. var bodyMessage = Em.Object.create({
  734. confirmButton: Em.I18n.t('yes'),
  735. confirmMsg: upgradeMethod.get('type') === 'ROLLING' ?
  736. Em.I18n.t('admin.stackVersions.version.upgrade.upgradeOptions.RU.confirm.msg').format(fromVersion, toVersion) :
  737. Em.I18n.t('admin.stackVersions.version.upgrade.upgradeOptions.EU.confirm.msg').format(fromVersion, toVersion)
  738. });
  739. return App.showConfirmationFeedBackPopup(function (query) {
  740. return self.runPreUpgradeCheck.call(self, version);
  741. }, bodyMessage);
  742. }
  743. }
  744. });
  745. },
  746. /**
  747. * open upgrade options from upgrade wizard
  748. */
  749. openUpgradeOptions: function () {
  750. if (this.get('isDowngrade')) return;
  751. this.upgradeOptions(true, null);
  752. },
  753. /**
  754. * upgrade confirmation popup including upgrade options: upgrade type and failures tolerance
  755. * @param {object} version
  756. * @return App.ModalPopup
  757. */
  758. confirmUpgrade: function (version) {
  759. this.upgradeOptions(false, version);
  760. },
  761. /**
  762. * send request for pre upgrade check only
  763. */
  764. runPreUpgradeCheckOnly: function(data) {
  765. if (App.get('supports.preUpgradeCheck')) {
  766. App.ajax.send({
  767. name: "admin.upgrade.pre_upgrade_check",
  768. sender: this,
  769. data: data,
  770. success: "runPreUpgradeCheckOnlySuccess",
  771. error: "runPreUpgradeCheckError"
  772. });
  773. }
  774. },
  775. /**
  776. * send request to get available upgrade tye names
  777. */
  778. getSupportedUpgradeTypes: function(data) {
  779. return App.ajax.send({
  780. name: "admin.upgrade.get_supported_upgradeTypes",
  781. sender: this,
  782. data: data,
  783. success: "getSupportedUpgradeTypesSuccess",
  784. error: "getSupportedUpgradeTypesError"
  785. });
  786. },
  787. /**
  788. * success callback of <code>getSupportedUpgradeTypes()</code>
  789. * @param data {object}
  790. */
  791. getSupportedUpgradeTypesSuccess: function (data) {
  792. var supportedUpgradeTypes = data.items[0] && data.items[0].CompatibleRepositoryVersions.upgrade_types;
  793. this.get('upgradeMethods').forEach(function (method) {
  794. method.set('allowed', supportedUpgradeTypes && !!supportedUpgradeTypes.contains(method.get('type')));
  795. });
  796. },
  797. /**
  798. * success callback of <code>runPreUpgradeCheckOnly()</code>
  799. * Show a message how many fails/warnings/passed
  800. * on clicking that message a popup window show up
  801. * @param data {object}
  802. * @param opt {object}
  803. * @param params {object}
  804. */
  805. runPreUpgradeCheckOnlySuccess: function (data, opt, params) {
  806. var self = this;
  807. var message = '';
  808. var messageClass = 'GREEN';
  809. var messageIconClass = 'icon-ok';
  810. if (data.items.someProperty('UpgradeChecks.status', 'WARNING')) {
  811. message = message + data.items.filterProperty('UpgradeChecks.status', 'WARNING').length + ' Warning ';
  812. messageClass = 'ORANGE';
  813. messageIconClass = 'icon-warning-sign';
  814. }
  815. if (data.items.someProperty('UpgradeChecks.status', 'FAIL')) {
  816. message = data.items.filterProperty('UpgradeChecks.status', 'FAIL').length + ' Required ' + message;
  817. messageClass = 'RED';
  818. messageIconClass = 'icon-remove';
  819. }
  820. if (!message) {
  821. message = Em.I18n.t('admin.stackVersions.version.upgrade.upgradeOptions.preCheck.allPassed');
  822. }
  823. var method = self.get('upgradeMethods').findProperty('type', params.type);
  824. method.set('precheckResultsMessage', message);
  825. method.set('precheckResultsMessageClass', messageClass);
  826. method.set('isPrecheckFailed', messageClass == 'RED');
  827. method.set('precheckResultsMessageIconClass', messageIconClass);
  828. method.set('precheckResultsData', data);
  829. this.updateSelectedMethod(false);
  830. Em.run.later(this, function () {
  831. // add tooltip for the type with preCheck errors
  832. App.tooltip($(".thumbnail.check-failed"), {
  833. placement: "bottom",
  834. title: Em.I18n.t('admin.stackVersions.version.upgrade.upgradeOptions.preCheck.failed.tooltip')
  835. });
  836. // destroy the tooltip for the type wo preCheck errors
  837. $(".thumbnail").not(".check-failed").not(".not-allowed-by-version").tooltip("destroy");
  838. }, 1000);
  839. },
  840. /**
  841. * In Upgrade Wizard: update which method already been selected on open
  842. * Not in upgrade wizard: de-select the method with pre-check errors
  843. * @param isInUpgradeWizard {boolean}
  844. */
  845. updateSelectedMethod: function(isInUpgradeWizard) {
  846. var self = this;
  847. if (isInUpgradeWizard) {
  848. this.get('upgradeMethods').forEach(function(method){
  849. if (method.get('type') == self.get('upgradeType')) {
  850. method.set('selected', true);
  851. } else {
  852. method.set('selected', false);
  853. }
  854. });
  855. } else {
  856. var ruMethod = this.get('upgradeMethods').findProperty('type', 'ROLLING');
  857. var euMethod = this.get('upgradeMethods').findProperty('type', 'NON_ROLLING');
  858. if (ruMethod && ruMethod.get('isPrecheckFailed')) ruMethod.set('selected', false);
  859. if (euMethod && euMethod.get('isPrecheckFailed')) euMethod.set('selected', false);
  860. }
  861. },
  862. /**
  863. * send request for pre upgrade check
  864. * @param version
  865. */
  866. runPreUpgradeCheck: function(version) {
  867. var params = {
  868. value: version.get('repositoryVersion'),
  869. label: version.get('displayName'),
  870. type: version.get('upgradeType'),
  871. skipComponentFailures: version.get('skipComponentFailures') ? 'true' : 'false',
  872. skipSCFailures: version.get('skipSCFailures') ? 'true' : 'false'
  873. };
  874. if (App.get('supports.preUpgradeCheck')) {
  875. this.set('requestInProgress', true);
  876. App.ajax.send({
  877. name: "admin.upgrade.pre_upgrade_check",
  878. sender: this,
  879. data: params,
  880. success: "runPreUpgradeCheckSuccess",
  881. error: "runPreUpgradeCheckError"
  882. });
  883. } else {
  884. this.upgrade(params);
  885. }
  886. },
  887. /**
  888. * success callback of <code>runPreUpgradeCheckSuccess()</code>
  889. * if there are some fails - it shows popup else run upgrade
  890. * @param data {object}
  891. * @param opt {object}
  892. * @param params {object}
  893. * @returns {App.ModalPopup|undefined}
  894. */
  895. runPreUpgradeCheckSuccess: function (data, opt, params) {
  896. var self = this;
  897. if (data.items.someProperty('UpgradeChecks.status', 'FAIL') || data.items.someProperty('UpgradeChecks.status', 'WARNING')) {
  898. this.set('requestInProgress', false);
  899. var hasFails = data.items.someProperty('UpgradeChecks.status', 'FAIL'),
  900. header = Em.I18n.t('popup.clusterCheck.Upgrade.header').format(params.label),
  901. failTitle = Em.I18n.t('popup.clusterCheck.Upgrade.fail.title'),
  902. failAlert = new Em.Handlebars.SafeString(Em.I18n.t('popup.clusterCheck.Upgrade.fail.alert')),
  903. warningTitle = Em.I18n.t('popup.clusterCheck.Upgrade.warning.title'),
  904. warningAlert = new Em.Handlebars.SafeString(Em.I18n.t('popup.clusterCheck.Upgrade.warning.alert')),
  905. configsMergeWarning = data.items.findProperty('UpgradeChecks.id', "CONFIG_MERGE"),
  906. configs = [];
  907. if (configsMergeWarning && Em.get(configsMergeWarning, 'UpgradeChecks.status') === 'WARNING') {
  908. data.items = data.items.rejectProperty('UpgradeChecks.id', 'CONFIG_MERGE');
  909. var configsMergeCheckData = Em.get(configsMergeWarning, 'UpgradeChecks.failed_detail');
  910. if (configsMergeCheckData) {
  911. configs = configsMergeCheckData.map(function (item) {
  912. var isDeprecated = Em.isNone(item.new_stack_value),
  913. willBeRemoved = Em.isNone(item.result_value);
  914. return {
  915. type: item.type,
  916. name: item.property,
  917. currentValue: item.current,
  918. recommendedValue: isDeprecated ? Em.I18n.t('popup.clusterCheck.Upgrade.configsMerge.deprecated') : item.new_stack_value,
  919. isDeprecated: isDeprecated,
  920. resultingValue: willBeRemoved ? Em.I18n.t('popup.clusterCheck.Upgrade.configsMerge.willBeRemoved') : item.result_value,
  921. willBeRemoved: willBeRemoved
  922. };
  923. });
  924. }
  925. }
  926. App.showClusterCheckPopup(data, {
  927. header: header,
  928. failTitle: failTitle,
  929. failAlert: failAlert,
  930. warningTitle: warningTitle,
  931. warningAlert: warningAlert,
  932. noCallbackCondition: hasFails,
  933. callback: function () {
  934. self.upgrade(params);
  935. }
  936. }, configs, params.label);
  937. } else {
  938. this.upgrade(params);
  939. }
  940. },
  941. runPreUpgradeCheckError: function() {
  942. this.set('requestInProgress', false);
  943. },
  944. confirmRetryUpgrade: function (version) {
  945. var self = this;
  946. return App.showConfirmationPopup(
  947. function () {
  948. self.retryUpgrade();
  949. },
  950. Em.I18n.t('admin.stackUpgrade.upgrade.retry.confirm.body').format(version.get('displayName')),
  951. null,
  952. Em.I18n.t('admin.stackUpgrade.dialog.header').format(version.get('upgradeTypeDislayName'), version.get('displayName'))
  953. );
  954. },
  955. confirmRetryDowngrade: function () {
  956. var self = this,
  957. currentVersion = this.get('currentVersion');
  958. return App.showConfirmationPopup(
  959. function() {
  960. self.retryUpgrade();
  961. },
  962. Em.I18n.t('admin.stackUpgrade.downgrade.retry.body').format(currentVersion.repository_name),
  963. null,
  964. Em.I18n.t('admin.stackUpgrade.dialog.downgrade.header').format(currentVersion.repository_name),
  965. Em.I18n.t('admin.stackUpgrade.downgrade.proceed')
  966. );
  967. },
  968. /**
  969. * confirmation popup before install repository version
  970. */
  971. installRepoVersionConfirmation: function (repo) {
  972. var self = this;
  973. return App.showConfirmationPopup(function () {
  974. self.installRepoVersion(repo);
  975. },
  976. Em.I18n.t('admin.stackVersions.version.install.confirm').format(repo.get('displayName'))
  977. );
  978. },
  979. /**
  980. * sends request to install repoVersion to the cluster
  981. * and create clusterStackVersion resourse
  982. * @param {Em.Object} repo
  983. * @return {$.ajax}
  984. * @method installRepoVersion
  985. */
  986. installRepoVersion: function (repo) {
  987. this.set('requestInProgress', true);
  988. var data = {
  989. ClusterStackVersions: {
  990. stack: repo.get('stackVersionType'),
  991. version: repo.get('stackVersionNumber'),
  992. repository_version: repo.get('repositoryVersion')
  993. },
  994. id: repo.get('id')
  995. };
  996. return App.ajax.send({
  997. name: 'admin.stack_version.install.repo_version',
  998. sender: this,
  999. data: data,
  1000. success: 'installRepoVersionSuccess',
  1001. callback: function() {
  1002. this.sender.set('requestInProgress', false);
  1003. }
  1004. });
  1005. },
  1006. /**
  1007. * transform repo data into json for
  1008. * saving changes to repository version
  1009. * @param {Em.Object} repo
  1010. * @returns {{operating_systems: Array}}
  1011. */
  1012. prepareRepoForSaving: function(repo) {
  1013. var repoVersion = { "operating_systems": [] };
  1014. repo.get('operatingSystems').forEach(function (os, k) {
  1015. repoVersion.operating_systems.push({
  1016. "OperatingSystems": {
  1017. "os_type": os.get("osType")
  1018. },
  1019. "repositories": []
  1020. });
  1021. os.get('repositories').forEach(function (repository) {
  1022. repoVersion.operating_systems[k].repositories.push({
  1023. "Repositories": {
  1024. "base_url": repository.get('baseUrl'),
  1025. "repo_id": repository.get('repoId'),
  1026. "repo_name": repository.get('repoName')
  1027. }
  1028. });
  1029. });
  1030. });
  1031. return repoVersion;
  1032. },
  1033. /**
  1034. * Return stack version for the repo object
  1035. * @param {Em.Object} repo
  1036. * */
  1037. getStackVersionNumber: function(repo){
  1038. var stackVersionNumber = repo.get('stackVersion');
  1039. if(null == stackVersionNumber)
  1040. stackVersionNumber = App.get('currentStackVersion');
  1041. return stackVersionNumber;
  1042. },
  1043. /**
  1044. * perform validation if <code>skip<code> is false and run save if
  1045. * validation successfull or run save without validation is <code>skip<code> is true
  1046. * @param {Em.Object} repo
  1047. * @param {boolean} skip
  1048. * @returns {$.Deferred}
  1049. */
  1050. saveRepoOS: function (repo, skip) {
  1051. var self = this;
  1052. var deferred = $.Deferred();
  1053. this.validateRepoVersions(repo, skip).done(function(data) {
  1054. if (data.length > 0) {
  1055. deferred.resolve(data);
  1056. } else {
  1057. var repoVersion = self.prepareRepoForSaving(repo);
  1058. var stackVersionNumber = self.getStackVersionNumber(repo);
  1059. App.ajax.send({
  1060. name: 'admin.stack_versions.edit.repo',
  1061. sender: this,
  1062. data: {
  1063. stackName: App.get('currentStackName'),
  1064. stackVersion: stackVersionNumber,
  1065. repoVersionId: repo.get('repoVersionId'),
  1066. repoVersion: repoVersion
  1067. }
  1068. }).success(function() {
  1069. deferred.resolve([]);
  1070. });
  1071. }
  1072. });
  1073. return deferred.promise();
  1074. },
  1075. /**
  1076. * send request for validation for each repository
  1077. * @param {Em.Object} repo
  1078. * @param {boolean} skip
  1079. * @returns {*}
  1080. */
  1081. validateRepoVersions: function(repo, skip) {
  1082. var deferred = $.Deferred(),
  1083. totalCalls = 0,
  1084. invalidUrls = [];
  1085. if (skip) {
  1086. deferred.resolve(invalidUrls);
  1087. } else {
  1088. var stackVersionNumber = this.getStackVersionNumber(repo);
  1089. repo.get('operatingSystems').forEach(function (os) {
  1090. if (os.get('isSelected')) {
  1091. os.get('repositories').forEach(function (repo) {
  1092. totalCalls++;
  1093. App.ajax.send({
  1094. name: 'admin.stack_versions.validate.repo',
  1095. sender: this,
  1096. data: {
  1097. repo: repo,
  1098. repoId: repo.get('repoId'),
  1099. baseUrl: repo.get('baseUrl'),
  1100. osType: os.get('osType'),
  1101. stackName: App.get('currentStackName'),
  1102. stackVersion: stackVersionNumber
  1103. }
  1104. })
  1105. .success(function () {
  1106. totalCalls--;
  1107. if (totalCalls === 0) deferred.resolve(invalidUrls);
  1108. })
  1109. .error(function () {
  1110. repo.set('hasError', true);
  1111. invalidUrls.push(repo);
  1112. totalCalls--;
  1113. if (totalCalls === 0) deferred.resolve(invalidUrls);
  1114. });
  1115. });
  1116. } else {
  1117. return deferred.resolve(invalidUrls);
  1118. }
  1119. });
  1120. }
  1121. return deferred.promise();
  1122. },
  1123. /**
  1124. * success callback for <code>installRepoVersion()<code>
  1125. * saves request id to the db
  1126. * @param data
  1127. * @param opt
  1128. * @param params
  1129. * @method installStackVersionSuccess
  1130. */
  1131. installRepoVersionSuccess: function (data, opt, params) {
  1132. var version = App.RepositoryVersion.find(params.id);
  1133. App.db.set('repoVersionInstall', 'id', [data.Requests.id]);
  1134. App.clusterStatus.setClusterStatus({
  1135. wizardControllerName: this.get('name'),
  1136. localdb: App.db.data
  1137. });
  1138. version.set('defaultStatus', 'INSTALLING');
  1139. if (version.get('stackVersion')) {
  1140. version.set('stackVersion.state', 'INSTALLING');
  1141. }
  1142. },
  1143. /**
  1144. * opens a popup with installations state per host
  1145. * @param {Em.Object} version
  1146. * @method showProgressPopup
  1147. */
  1148. showProgressPopup: function(version) {
  1149. var popupTitle = Em.I18n.t('admin.stackVersions.details.install.hosts.popup.title').format(version.get('displayName'));
  1150. var requestIds = App.get('testMode') ? [1] : App.db.get('repoVersionInstall', 'id');
  1151. var hostProgressPopupController = App.router.get('highAvailabilityProgressPopupController');
  1152. hostProgressPopupController.initPopup(popupTitle, requestIds, this);
  1153. },
  1154. /**
  1155. * reset upgradeState to INIT when upgrade is COMPLETED
  1156. * and clean auxiliary data
  1157. */
  1158. finish: function () {
  1159. if (App.get('upgradeState') === 'COMPLETED') {
  1160. var upgradeVersion = this.get('upgradeVersion') && this.get('upgradeVersion').match(/[a-zA-Z]+\-\d+\.\d+/);
  1161. this.setDBProperties({
  1162. upgradeId: undefined,
  1163. upgradeState: 'INIT',
  1164. upgradeVersion: undefined,
  1165. currentVersion: undefined,
  1166. upgradeTypeDisplayName: undefined,
  1167. upgradeType: undefined,
  1168. failuresTolerance: undefined,
  1169. isDowngrade: undefined,
  1170. downgradeAllowed: undefined
  1171. });
  1172. App.clusterStatus.setClusterStatus({
  1173. localdb: App.db.data
  1174. });
  1175. if (upgradeVersion && upgradeVersion[0]) {
  1176. App.set('currentStackVersion', upgradeVersion[0]);
  1177. }
  1178. App.set('upgradeState', 'INIT');
  1179. }
  1180. }.observes('App.upgradeState'),
  1181. /**
  1182. * Check <code>App.upgradeState</code> for HOLDING
  1183. * If it is, send request to check if current item is Finalize
  1184. * @method updateFinalize
  1185. */
  1186. updateFinalize: function () {
  1187. var upgradeState = App.get('upgradeState');
  1188. if (upgradeState === 'HOLDING') {
  1189. return App.ajax.send({
  1190. name: 'admin.upgrade.finalizeContext',
  1191. sender: this,
  1192. success: 'updateFinalizeSuccessCallback',
  1193. error: 'updateFinalizeErrorCallback'
  1194. })
  1195. }
  1196. else {
  1197. this.set('isFinalizeItem', false);
  1198. }
  1199. }.observes('App.upgradeState'),
  1200. /**
  1201. *
  1202. * @param {object|null} data
  1203. * @method updateFinalizeSuccessCallback
  1204. */
  1205. updateFinalizeSuccessCallback: function (data) {
  1206. var context = data ? Em.get(data, 'items.firstObject.upgrade_groups.firstObject.upgrade_items.firstObject.UpgradeItem.context') : '';
  1207. this.set('isFinalizeItem', context === this.get('finalizeContext'));
  1208. },
  1209. updateFinalizeErrorCallback: function() {
  1210. this.set('isFinalizeItem', false);
  1211. },
  1212. /**
  1213. * show dialog with tasks of upgrade
  1214. * @return {App.ModalPopup}
  1215. */
  1216. openUpgradeDialog: function () {
  1217. App.router.transitionTo('admin.stackUpgrade');
  1218. },
  1219. /**
  1220. * returns url to get data for repoVersion or clusterStackVersion
  1221. * @param {Boolean} stack true if load clusterStackVersion
  1222. * @param {Boolean} fullLoad true if load all data
  1223. * @returns {String}
  1224. * @method getUrl
  1225. */
  1226. getUrl: function(stack, fullLoad) {
  1227. if (App.get('testMode')) {
  1228. return stack ? this.get('mockStackUrl') : this.get('mockRepoUrl')
  1229. } else {
  1230. if (fullLoad) {
  1231. return stack ? this.get('realStackUrl') : this.get('realRepoUrl');
  1232. } else {
  1233. return this.get('realUpdateUrl');
  1234. }
  1235. }
  1236. },
  1237. /**
  1238. * get stack versions from server and push it to model
  1239. * @return {*}
  1240. * @method loadStackVersionsToModel
  1241. */
  1242. loadStackVersionsToModel: function (fullLoad) {
  1243. var dfd = $.Deferred();
  1244. App.HttpClient.get(this.getUrl(true, fullLoad), App.stackVersionMapper, {
  1245. complete: function () {
  1246. dfd.resolve();
  1247. }
  1248. });
  1249. return dfd.promise();
  1250. },
  1251. /**
  1252. * get repo versions from server and push it to model
  1253. * @return {*}
  1254. * @params {Boolean} isUpdate - if true loads part of data that need to be updated
  1255. * @method loadRepoVersionsToModel()
  1256. */
  1257. loadRepoVersionsToModel: function () {
  1258. var dfd = $.Deferred();
  1259. App.HttpClient.get(this.getUrl(false, true), App.repoVersionMapper, {
  1260. complete: function () {
  1261. dfd.resolve();
  1262. }
  1263. });
  1264. return dfd.promise();
  1265. },
  1266. /**
  1267. * set status to Upgrade item
  1268. * @param item
  1269. * @param status
  1270. */
  1271. setUpgradeItemStatus: function(item, status) {
  1272. this.set('requestInProgress', true);
  1273. return App.ajax.send({
  1274. name: 'admin.upgrade.upgradeItem.setState',
  1275. sender: this,
  1276. data: {
  1277. upgradeId: item.get('request_id'),
  1278. itemId: item.get('stage_id'),
  1279. groupId: item.get('group_id'),
  1280. status: status
  1281. },
  1282. callback: function() {
  1283. this.sender.set('requestInProgress', false);
  1284. }
  1285. }).done(function () {
  1286. item.set('status', status);
  1287. });
  1288. },
  1289. currentVersionObserver: function () {
  1290. var versionNumber = this.get('currentVersion.repository_version');
  1291. var currentVersionObject = App.RepositoryVersion.find().findProperty('status', 'CURRENT');
  1292. var versionName = currentVersionObject && currentVersionObject.get('stackVersionType');
  1293. App.set('isStormMetricsSupported', versionName != 'HDP' || stringUtils.compareVersions(versionNumber, '2.2.2') > -1 || !versionNumber);
  1294. }.observes('currentVersion.repository_version'),
  1295. /**
  1296. * get the installed repositories of HDP from server
  1297. */
  1298. loadRepositories: function () {
  1299. if (App.router.get('clusterController.isLoaded')) {
  1300. var nameVersionCombo = App.get('currentStackVersion');
  1301. var stackName = nameVersionCombo.split('-')[0];
  1302. var stackVersion = nameVersionCombo.split('-')[1];
  1303. App.ajax.send({
  1304. name: 'cluster.load_repositories',
  1305. sender: this,
  1306. data: {
  1307. stackName: stackName,
  1308. stackVersion: stackVersion
  1309. },
  1310. success: 'loadRepositoriesSuccessCallback',
  1311. error: 'loadRepositoriesErrorCallback'
  1312. });
  1313. }
  1314. }.observes('App.router.clusterController.isLoaded'),
  1315. loadRepositoriesSuccessCallback: function (data) {
  1316. var allRepos = [];
  1317. data.items.forEach(function (os) {
  1318. os.repositories.forEach(function (repository) {
  1319. var osType = repository.Repositories.os_type;
  1320. var repo = Em.Object.create({
  1321. baseUrl: repository.Repositories.base_url,
  1322. osType: osType,
  1323. repoId: repository.Repositories.repo_id,
  1324. repoName : repository.Repositories.repo_name,
  1325. stackName : repository.Repositories.stack_name,
  1326. stackVersion : repository.Repositories.stack_version,
  1327. isFirst: false
  1328. });
  1329. var group = allRepos.findProperty('name', osType);
  1330. if (!group) {
  1331. group = {
  1332. name: osType,
  1333. repositories: []
  1334. };
  1335. repo.set('isFirst', true);
  1336. allRepos.push(group);
  1337. }
  1338. group.repositories.push(repo);
  1339. });
  1340. }, this);
  1341. allRepos.stackVersion = App.get('currentStackVersionNumber');
  1342. this.set('allRepos', allRepos);
  1343. },
  1344. loadRepositoriesErrorCallback: function (request, ajaxOptions, error) {
  1345. },
  1346. /**
  1347. * @returns {$.ajax}
  1348. */
  1349. suspendUpgrade: function () {
  1350. var self = this;
  1351. return this.abortUpgrade().done(function () {
  1352. App.set('upgradeState', 'ABORTED');
  1353. self.set('isSuspended', true);
  1354. self.setDBProperty('upgradeState', 'ABORTED');
  1355. self.setDBProperty('isSuspended', true);
  1356. App.clusterStatus.setClusterStatus({
  1357. wizardControllerName: self.get('name'),
  1358. localdb: App.db.data
  1359. });
  1360. });
  1361. },
  1362. /**
  1363. * @returns {$.ajax}
  1364. */
  1365. resumeUpgrade: function() {
  1366. var self = this;
  1367. this.retryUpgrade().done(function () {
  1368. App.set('upgradeState', 'PENDING');
  1369. App.propertyDidChange('upgradeAborted');
  1370. self.set('isSuspended', false);
  1371. self.setDBProperty('upgradeState', 'PENDING');
  1372. self.setDBProperty('isSuspended', false);
  1373. App.clusterStatus.setClusterStatus({
  1374. wizardControllerName: self.get('name'),
  1375. localdb: App.db.data
  1376. });
  1377. });
  1378. },
  1379. /**
  1380. * restore last Upgrade data
  1381. * @param {object} lastUpgradeData
  1382. */
  1383. restoreLastUpgrade: function(lastUpgradeData) {
  1384. var self = this;
  1385. var upgradeType = this.get('upgradeMethods').findProperty('type', lastUpgradeData.Upgrade.upgrade_type);
  1386. this.setDBProperties({
  1387. upgradeId: lastUpgradeData.Upgrade.request_id,
  1388. isDowngrade: lastUpgradeData.Upgrade.direction === 'DOWNGRADE',
  1389. upgradeState: lastUpgradeData.Upgrade.request_status,
  1390. upgradeType: lastUpgradeData.Upgrade.upgrade_type,
  1391. downgradeAllowed: lastUpgradeData.Upgrade.downgrade_allowed,
  1392. upgradeTypeDisplayName: upgradeType.get('displayName'),
  1393. failuresTolerance: Em.Object.create({
  1394. skipComponentFailures: lastUpgradeData.Upgrade.skip_failures,
  1395. skipSCFailures: lastUpgradeData.Upgrade.skip_service_check_failures
  1396. })
  1397. });
  1398. this.loadRepoVersionsToModel().done(function () {
  1399. var toVersion = App.RepositoryVersion.find().findProperty('repositoryVersion', lastUpgradeData.Upgrade.to_version);
  1400. self.setDBProperty('upgradeVersion', toVersion && toVersion.get('displayName'));
  1401. self.initDBProperties();
  1402. self.loadUpgradeData(true);
  1403. });
  1404. },
  1405. /**
  1406. * Build table from configs list and open new window to show this table
  1407. * @param configs
  1408. */
  1409. openConfigsInNewWindow: function (configs) {
  1410. var newWindow;
  1411. var output = '';
  1412. output += '<table style="text-align: left;"><thead><tr>' +
  1413. '<th>' + Em.I18n.t('popup.clusterCheck.Upgrade.configsMerge.configType') + '</th>' +
  1414. '<th>' + Em.I18n.t('popup.clusterCheck.Upgrade.configsMerge.propertyName') + '</th>' +
  1415. '<th>' + Em.I18n.t('popup.clusterCheck.Upgrade.configsMerge.currentValue') + '</th>' +
  1416. '<th>' + Em.I18n.t('popup.clusterCheck.Upgrade.configsMerge.recommendedValue') + '</th>' +
  1417. '<th>' + Em.I18n.t('popup.clusterCheck.Upgrade.configsMerge.resultingValue') + '</th>' +
  1418. '</tr></thead><tbody>';
  1419. configs.context.forEach(function (config) {
  1420. output += '<tr>' +
  1421. '<td>' + config.type + '</td>' +
  1422. '<td>' + config.name + '</td>' +
  1423. '<td>' + config.currentValue + '</td>' +
  1424. '<td>' + config.recommendedValue + '</td>' +
  1425. '<td>' + config.resultingValue + '</td>' +
  1426. '</tr>';
  1427. });
  1428. output += '</tbody></table>';
  1429. newWindow = window.open();
  1430. newWindow.document.write(output);
  1431. newWindow.focus();
  1432. }
  1433. });