This repository has been archived on 2025-12-25. You can view files and clone it. You cannot open issues or pull requests or push a commit.
Files
qmi-cloud/qmi-cloud-cli/jobs/stop5.js
Manuel Romero 5b6cb73b09 vm1 stuff
2021-10-04 16:54:48 +02:00

180 lines
6.2 KiB
JavaScript

var myArgs = process.argv.slice(2);
if ( myArgs.length < 2 ) {
console.log("Missing args", myArgs);
process.exit(0);
}
const IS_REAL = myArgs[1] !== 'test';
const WARNING_DAYS = 1;
// ---
const db = require('qmi-cloud-common/mongo');
const sendEmail = require("qmi-cloud-common/send-email");
const moment = require('moment');
const cli = require('qmi-cloud-common/cli');
function timeRunningIs24x7(p) {
let runningFromTime = p.runningFrom? new Date(p.runningFrom).getTime() : new Date(p.created).getTime();
let totalRunningFromTime = Math.abs(new Date().getTime() - runningFromTime);
let duration = moment.duration(totalRunningFromTime);
p.duration = {
hours: Math.floor(duration.asHours()),
complete: Math.floor(duration.asDays()) +"d "+duration.hours()+"h "+duration.minutes()
};
}
function timeRunningOnSchedule(p) {
let runningFromTime = p.runningFrom? new Date(p.runningFrom).getTime() : new Date(p.created).getTime();
let totalRunningTime = p.timeRunning*1000*60;
let now = new Date();
totalRunningTime = totalRunningTime + Math.abs(now.getTime() - runningFromTime);
let duration = moment.duration(totalRunningTime);
p.duration = {
hours: Math.floor(duration.asHours()),
complete: Math.floor(duration.asDays()) +"d "+duration.hours()+"h "+duration.minutes()
};
}
function timeRunningOnSchedule2(p) {
let startTimestamp = p.startDateOnSchedule? new Date(p.startDateOnSchedule).getTime() : 0;
let endTimestamp = p.endDateOnSchedule? new Date(p.endDateOnSchedule).getTime() : 0;
let totalTimeOnschedule = Math.abs(endTimestamp - startTimestamp);
let duration = moment.duration(totalTimeOnschedule);
p.duration = {
hours: Math.floor(duration.asHours()),
complete: Math.floor(duration.asDays()) +"d "+duration.hours()+"h "+duration.minutes()
};
}
async function asyncForEach(array, callback) {
for (let index = 0; index < array.length; index++) {
await callback(array[index], index, array);
}
}
async function init(type) {
var cb;
var filter = {
"isDestroyed": false,
"isDeleted": false,
"statusVms": "Running",
"vmImage": { "$exists": true },
"vmImage.vm1": { "$exists": true }
};
if ( type === "warning" ) {
filter.pendingNextAction = { $ne: "stopVms" };
cb = doSendEmailWarning;
} else if ( type === "exec" ) {
filter.pendingNextAction = "stopVms";
cb = doStop;
} else {
console.log("Invalid 'type'. Do nothing.");
return;
}
let provisions = await db.provision.get(filter);
await asyncForEach(provisions.results, async function(p) {
//Only if 24x7
let typeSchedule = "24x7";
let periodDays = p._scenarioDoc.allowed24x7RunningDays;
if ( !p.schedule || p.schedule.is24x7 ) {
// 24x7
timeRunningIs24x7(p);
periodDays = p._scenarioDoc.allowed24x7RunningDays;
} else if ( p.schedule && !p.schedule.is24x7 ) {
// OnSchedule
timeRunningOnSchedule2(p);
typeSchedule = 'OnSchedule';
periodDays = p._scenarioDoc.allowedOnScheduleRunningDays;
}
let limit;
if ( type === "warning" ) {
limit = 24*(periodDays-WARNING_DAYS);
} else if ( type === "exec" ) {
limit = 24*periodDays;
}
if (!IS_REAL) {
console.log(`${p._id} - (${typeSchedule}) - limit: ${limit} hs - actual duration: ${p.duration.hours} hs`);
}
if ( p.duration && p.duration.hours >= limit) {
await cb(p, limit, typeSchedule);
}
});
}
const doSendEmailWarning = async function(p, limit, typeSchedule) {
if ( p.pendingNextAction === 'stopVms') {
console.log(`Warning email Stop already sent. Wait for pending action to complete.`);
} else {
let msg = `Send warning STOP email - ${p.user.displayName} (${p.user.upn}) about provision '${p._scenarioDoc.title}' (${p._id} - ${typeSchedule}) being 'Running' more than ${limit} hours, (exactly ${p.duration.complete})`;
console.log(msg);
if ( IS_REAL ) {
db.event.add({ user: p.user._id, provision: p._id, type: 'vms.warning-stop' });
await db.provision.update(p._id, {"pendingNextAction": "stopVms"});
await db.notification.add({ provision: p._id.toString(), type: 'warningStop', message: msg });
await sendEmail.sendWillStopIn24(p, p._scenarioDoc, Math.floor(limit/24), WARNING_DAYS);
}
}
};
const doStop = async function(p, limit, typeSchedule) {
try {
let msg = `VMs stopped - ${p.user.displayName} (${p.user.upn}) about provision '${p._scenarioDoc.title}' (${p._id} - ${typeSchedule}) being 'Running' more than ${limit} hours, (exactly ${p.duration.complete})`
console.log(msg);
if ( IS_REAL ) {
if (p.schedule){
//Disable Divvy
await db.schedule.update(p.schedule._id, {"isStartupTimeEnable": false});
await cli.updateVmsTags(p._id, {
"24x7": false,
"StartupTime": false,
"ShutdownTime": false
});
}
//Stop VMs indefinitely
db.event.add({ user: p.user._id, provision: p._id, type: 'vms.exec-stop' });
await cli.deallocate(p._id, true);
await db.notification.add({ provision: p._id.toString(), type: 'stop', message: msg });
}
} catch (error) {
console.log("doStop Error", error);
await db.provision.update(p._id, {"statusVms": "Error_Stopping"});
}
};
function check(type) {
init(type).then(function(){
db.mongoose.connection.close()
process.exit(0);
}).catch(function(e){
db.mongoose.connection.close()
console.log("Error", e);
process.exit(0);
});
}
// --------------------------------
switch (myArgs[0]) {
case 'warning':
check("warning");
break;
case 'exec':
check("exec");
break;
default:
console.log('Sorry, that is not something I know how to do.');
process.exit(0);
}