function doAPIRequestWithCallback (meth, mod, func, handler, errorHandler, args) { 'use strict'; let oReq = new XMLHttpRequest(); oReq.onreadystatechange = function() { if (this.readyState === XMLHttpRequest.DONE) { if( this.status === 200 ) { handler(this.responseText); } else { errorHandler(meth, mod, func, this.status, this.responseText); } } } let argarr = [ `module=${mod}`, `function=${func}` ]; if( typeof args === 'object' ) { Object.keys(args).forEach( function(argument) { argarr.push(`${argument}=${args[argument]}`); }); } let argstr = argarr.join("&"); if( meth === 'GET' ) { oReq.open( meth, `api.cgi?${argstr}`, true ); oReq.send(); } else if ( meth === 'POST' ) { oReq.open( meth, "api.cgi", true ); oReq.setRequestHeader( "Content-type", "application/x-www-form-urlencoded" ); oReq.send(argstr); } return false; } function generalErrorHandler(meth, mod, func, code, txt) { console.log(txt); alert(`${meth} call to Troglodyne::API::${mod}::${func} failed with error code ${code}! Please see the JS console for details.`); return false; } function safeParseJSON(txt) { let obj = {}; try { obj = JSON.parse(txt); } catch(e) { console.log(txt); return { "error": e }; } return obj; } function versionHandler (resp) { 'use strict'; let obj = safeParseJSON(resp); if(obj.result === 1) { // Construct version warning/display let pgVersion = obj.data.installed_version.major + '.' + obj.data.installed_version.minor; let elem = document.getElementById('psqlVersion'); let html = `${pgVersion}`; if( parseFloat(pgVersion) < parseFloat(obj.data.minimum_supported_version) ) { elem.classList.add('callout', 'callout-danger'); html += ' -- You are using a version of PostgreSQL Server that is no longer supported by '; html += 'postgresql.org!
'; if( obj.data.eol_versions.hasOwnProperty(pgVersion) ) { html += "EOL -- " + new Date(obj.data.eol_versions[pgVersion].EOL * 1000).toLocaleString( undefined, { year: 'numeric', month: 'long', day: 'numeric' } ) + "
"; } html += "Immediate upgrade is recommended."; } elem.innerHTML = html; // Now let's build the table let rows = ''; for ( var version of Object.keys(obj.data.available_versions).sort(function(a,b) { return parseFloat(b) - parseFloat(a) }) ) { if( parseFloat(pgVersion) >= parseFloat(version) ) { continue; } rows += ` ${version} ${new Date(obj.data.available_versions[version].release * 1000).toLocaleString(undefined, { year: 'numeric', month: 'long', day: 'numeric' })} ${new Date(obj.data.available_versions[version].EOL * 1000).toLocaleString(undefined, { year: 'numeric', month: 'long', day: 'numeric' })} `; } if( !rows.length ) { rows = 'No newer versions are currently available for install. '; rows += 'Click here for more information.'; rows += ''; } document.getElementById('loadingCell').remove(); document.querySelector('#upgradeForm > table > tbody').innerHTML = rows; } else { console.log(obj.error); } } function doInstallScroller (resp) { 'use strict'; let obj = safeParseJSON(resp); let upgradeWell = document.getElementById('upgradeWell'); let submitBtn = document.getElementById('submit'); if(obj.result === 1) { if(obj.data.exit_code !== 0) { upgradeWell.textContent += obj.data.last_yum_command + " reported nonzero exit code (" + obj.data.exit_code + "):\n[STDOUT] " + obj.data.stdout + "\n[STDERR] " + obj.data.stderr; submitBtn.textContent = 'Re-Try'; submitBtn.disabled = false; return false; } if(obj.data.already_installed) { upgradeWell.textContent += obj.data.last_yum_command + " reports the community repository is already installed: " + obj.data.stdout; } else { upgradeWell.textContent += obj.data.last_yum_command + "\n" + obj.data.stdout; } // Ok, now kick off actual install TODO use WebSocket? upgradeWell.textContent += "\nNow proceeding with install of PostgreSQL " + window.selectedVersion + "...\n"; doAPIRequestWithCallback( 'POST', 'Postgres', 'start_postgres_install', handlePGInstall, generalErrorHandler, { "version": window.selectedVersion } ); } else { console.log(obj.error); upgradeWell.textContent += "Installlation of community repositories failed:" + obj.error; submitBtn.textContent = 'Re-Try'; submitBtn.disabled = false; } return false; } function handlePGInstall (resp) { 'use strict'; let obj = safeParseJSON(resp); let upgradeWell = document.getElementById('upgradeWell'); let submitBtn = document.getElementById('submit'); if(obj.result === 1) { upgradeWell.textContent += `Attaching to log file ${obj.data.log} from process #${obj.data.pid}...\n\n`; doAPIRequestWithCallback( 'GET', 'Postgres', 'get_latest_upgradelog_messages', roadRoller, generalErrorHandler, { "pid": obj.data.pid, "log": obj.data.log, "start": 0 } ); } else { upgradeWell.textContent += `Installlation PostgreSQL ${window.selectedVersion} failed: ${obj.error}`; submitBtn.textContent = 'Re-Try'; submitBtn.disabled = false; } return false; } // 8 seconds have passed function roadRoller (resp) { 'use strict'; let obj = safeParseJSON(resp); let upgradeWell = document.getElementById('upgradeWell'); let submitBtn = document.getElementById('submit'); if(obj.result === 1) { // Paste in new content if(obj.data['new_content'].length > 0) { upgradeWell.textContent += obj.data['new_content']; upgradeWell.scrollTo(0,upgradeWell.scrollHeight); } if(obj.data['in_progress']) { // Not done yet, keep going doAPIRequestWithCallback( 'GET', 'Postgres', 'get_latest_upgradelog_messages', roadRoller, generalErrorHandler, { "pid": obj.metadata['input_args'].pid, "log": obj.metadata['input_args'].log, "start": obj.data['next'] } ); } else { // Do something based on the end status if(+obj.data['child_exit']) { upgradeWell.textContent += `Installation of PostgreSQL ${window.selectedVersion} failed: Subprocess exited ${obj.data['child_exit']}`; upgradeWell.scrollTo(0,upgradeWell.scrollHeight); submitBtn.textContent = 'Re-Try'; submitBtn.disabled = false; return; } upgradeWell.textContent += `Installation of PostgreSQL ${window.selectedVersion} completed successfully!`; upgradeWell.scrollTo(0,upgradeWell.scrollHeight); submitBtn.textContent = 'All done, please refresh the page.'; } } else { upgradeWell.textContent += `Installation of PostgreSQL ${window.selectedVersion} failed: ${obj.error}`; upgradeWell.scrollTo(0,upgradeWell.scrollHeight); submitBtn.textContent = 'Re-Try'; submitBtn.disabled = false; } } window.doUpgrade = function () { 'use strict'; let form = new FormData(upgradeForm); window.selectedVersion = form.get('selectedVersion'); document.getElementById('upgradeTitle').textContent = "Install Progress for PostgreSQL " + window.selectedVersion; let submitBtn = document.getElementById('submit'); submitBtn.disabled = true; submitBtn.innerHTML = ''; let upgradeWell = document.getElementById('upgradeWell'); upgradeWell.textContent = 'Ensuring that the PostgreSQL Community repository is installed...\n'; upgradeWell.style.display = "block"; upgradeForm.style.display = "none"; doAPIRequestWithCallback( 'GET', 'Postgres', 'enable_community_repositories', doInstallScroller, generalErrorHandler ); return false; } // Now kickoff the page load post bits document.getElementById('submit').disabled = true; doAPIRequestWithCallback( 'GET', 'Postgres', 'get_postgresql_versions', versionHandler, generalErrorHandler );