vmsnap
Version:
A Node based backup and backup rotation tool for KVM domains.
2 lines (1 loc) • 2.02 kB
JavaScript
import{sep as l}from"path";import{readdir as k,stat as m}from"fs/promises";import w from"pretty-bytes";import{createError as g,fileExists as d,parseArrayParam as z}from"./general.js";import{findBitmaps as T}from"./qemu-img.js";import{fetchAllDomains as E,findCheckpoints as N}from"./virsh.js";import{FREQUENCY_MONTHLY as b,getBackupFolder as D}from"./libnbdbackup.js";import{ERR_DOMAINS as O}from"../vmsnap.js";export const STATUS_OK=0,STATUS_INCONSISTENT=1,STATUSES=new Map([[STATUS_OK,"OK"],[STATUS_INCONSISTENT,"INCONSISTENT"]]);const I=5,v=async(o,i=void 0,r=b,s=!1)=>{const a={},e=await z(o,E);if(e.length===0)throw g(`No matching domains found for: ${o}`,O);let t={};for(const p of e){const f=await N(p);t.checkpoints=[];for(const n of f)t.checkpoints.push(n);const S=await T(p);t.disks=[];let c={};for(const n of S){c.disk=n.disk,c.virtualSize=h(n.virtualSize,s),c.actualSize=h(n.actualSize,s),c.bitmaps=[];for(const $ of n.bitmaps)c.bitmaps.push($.name);t.disks.push(c),c={}}t.overallStatus=y(t),i&&typeof i=="string"&&(await R(p,t,i,r,s),t.overallStatus===STATUS_OK&&t.backupDirStats.checkpoints!==t.checkpoints.length&&(t.overallStatus=STATUS_INCONSISTENT)),a[p]=t,t={}}return a},h=(o,i=!1)=>i?w(o):o,R=async(o,i,r,s,a=!1)=>{const e={path:null,totalFiles:0,checkpoints:0,totalSize:0},t=`${r}${l}${o}${l}${D(s)}`;e.path=t;const p=`${t}${l}checkpoints`;if(await d(t)&&await d(p)){const f=await k(`${t}${l}checkpoints`);let S,c=0;for(const n of f)S=await m(`${t}${l}checkpoints${l}${n}`),c+=S.size;e.totalFiles=f.length,e.checkpoints=f.length,e.totalSize=c,await u(e,t)}i.backupDirStats={...e,totalSize:h(e.totalSize,a)}},y=o=>{let i=STATUS_OK;const r=o.checkpoints;let s=[];for(const a of o.disks)if(s=a.bitmaps,r.length!==s.length){i=STATUS_INCONSISTENT;break}return i},u=async(o,i,r=0)=>{if(r===I)throw new Error(`Recursion limit reached for ${i}`);let s,a;for(const e of await k(i))a=`${i}${l}${e}`,s=await m(a),s.isDirectory()&&await u(o,a,++r),o.totalFiles++,o.totalSize+=s.size};export{v as getStatus};