Yandex.Cloud
:
De acuerdo con el cronograma, cree discos SNAPSHOT en la instancia utilizada. Al mismo tiempo, debería ser posible marcar los discos que necesitan copia de seguridad y los que no.
Subtareas:
- Las instantáneas de más de n días deben eliminarse automáticamente del almacenamiento. Además, debería ser posible cambiar n.
- Las instantáneas deben tener un título legible por humanos. Y haga coincidir el siguiente patrón:
% %- %-% %
De modo que, si es necesario, era obvio para una persona de qué desplegar autos nuevos. (en la versión final, se implementa mediante un script bash separado ejecutado desde una máquina de terceros).
Progreso:
No hay una función regular en Y.cloud que realice esta tarea.
La solución es implementarlo a expensas de la función dentro de Y.cloud, para ahorrar recursos. Para crear instantáneas, se escribió una función en NodeJS12
const ycsdk = require("yandex-cloud/api/compute/v1");
const FOLDER_ID = process.env.FOLDER_ID;
async function handler(event, context) {
const snapshotService = new ycsdk.SnapshotService();
const diskService = new ycsdk.DiskService();
const diskList = await diskService.list({
folderId: FOLDER_ID,
});
for (const disk of diskList.disks) {
if ('snapshot' in disk.labels) {
snapshotService.create({
folderId: FOLDER_ID,
diskId: disk.id
});
}
}
}
exports.handler = handler;
* Al llamar a esta función, debe pasar FODLER_ID a través del entorno y especificar la cuenta de servicio.
A continuación, se agrega una llamada programada a esta función. Y la tarea está resuelta.
Subtarea 1.
Inicialmente se decidió hacerlo a través de la misma función NodeJS12
Lógica de trabajo: analizar la fecha de creación de la instantánea, compararla con la diferencia entre la fecha actual yn, y si se supera el límite eliminarla.
Para hacer esto, consulte la documentación oficial y vea que el parámetro CreatedAt debe ser del tipo cadena.
OKAY. Estamos escribiendo una función que eliminará las instantáneas que tengan menos de 1 hora desde el nacimiento (para la prueba). Lanzamos. No obtenemos nada. Nada en absoluto. No es un error en el campo de salida de error, sino la acción que necesitamos.
Iteración 1.
const ycsdk = require("yandex-cloud/api/compute/v1");
const FOLDER_ID = process.env.FOLDER_ID;
const date = new Date();
date.setHours( date.getHours() - 1 );
async function handler(event, context) {
const snapshotService = new ycsdk.SnapshotService();
const {snapshots} = await snapshotService.list({folderId: FOLDER_ID});
for ( let snapshot in snapshots ) {
const dateSnapshot = new Date( snapshot.createdAt );
if ( dateSnapshot.getTime() > date.getTime() ) snapshotService.delete({snapshotId: snapshot.id});
}
}
exports.handler = handler;
Iteración 2. Cambie la
función para que muestre un mensaje de respuesta en el cuerpo del error.
const ycsdk = require("yandex-cloud/api/compute/v1");
const FOLDER_ID = process.env.FOLDER_ID;
const date = new Date();
date.setHours( date.getHours() - 1 );
async function handler(event, context) {
const snapshotService = new ycsdk.SnapshotService();
const {snapshots} = await snapshotService.list({folderId: FOLDER_ID});
throw Error( JSON.stringify( snapshots ) );
}
exports.handler = handler;
:
«"errorMessage": "[{\"labels\":{},\"productIds\":[],\"id\":\"fd813o0n3p753lhqphie\",\"folderId\":\"b1gfub3omefcfvchsd0f\",\"createdAt\":{\"seconds\":{\"low\":1594137358,\"high\":0,\"unsigned\":false}},\"diskSize\":{\"low\":1073741824,\"high\":0,\"unsigned\":false},\"status\":2,\"sourceDiskId\":\"ef3ivjn6340h9e8incbq\"},…..»
Habiendo peinado cuál, vemos lo siguiente:
{
"labels": {},
"productIds": [],
"id": "fd813o0n3p753lhqphie",
"folderId": "b1gfub3omefcfvchsd0f",
"createdAt": {
"seconds": {
"low": 1594137358,
"high": 0,
"unsigned": false
}
De aquí sacamos una conclusión. CreatedAt no es una cadena sino un objeto.
Iteración 3.
Estamos intentando trabajar con CreatedAt. Cambiamos la función.
const ycsdk = require("yandex-cloud/api/compute/v1");
const FOLDER_ID = process.env.FOLDER_ID;
const date = new Date();
date.setHours( date.getHours() - 1 );
async function handler(event, context) {
const snapshotService = new ycsdk.SnapshotService();
const {snapshots} = await snapshotService.list({folderId: FOLDER_ID});
for ( let snapshot in snapshots ) {
if ( snapshot.createdAt.seconds.low > date.getTime() / 1000 ) {
snapshotService.delete({snapshotId: snapshot.id});
}
}
}
exports.handler = handler;
Obtenemos el error:
{
"errorMessage": "Cannot read property 'seconds' of undefined",
"errorType": "TypeError",
"stackTrace": [
{
"function": "Runtime.handler",
"file": "/function/code/index.js",
"line": 14,
"column": 29
}
]
El error nos dice que estamos tratando de tomar la propiedad de segundos de un objeto inexistente, aunque previamente observamos la salida de las propiedades del
"createdAt":{"seconds":{"low":1594137358,"high":0,"unsigned":false}}
objeto de respuesta de Iteración 4.
const ycsdk = require("yandex-cloud/api/compute/v1");
const FOLDER_ID = process.env.FOLDER_ID;
const date = new Date();
date.setHours( date.getHours() - 1 );
async function handler(event, context) {
const snapshotService = new ycsdk.SnapshotService();
const {snapshots} = await snapshotService.list({folderId: FOLDER_ID});
for ( let i = 0; i < 5; i++ ) {
throw Error( JSON.stringify( snapshots[i].createdAt ) );
}
}
exports.handler = handler;
Obtenemos el error:
{
"errorMessage": "{\"seconds\":{\"low\":1594137358,\"high\":0,\"unsigned\":false}}",
"errorType": "Error",
"stackTrace": [
{
"function": "Runtime.handler",
"file": "/function/code/index.js",
"line": 13,
"column": 11
}
]
}
Se redujo el ciclo a 5 iteraciones para mayor comodidad.
Iteración 5.
const ycsdk = require("yandex-cloud/api/compute/v1");
const FOLDER_ID = process.env.FOLDER_ID;
const date = new Date();
date.setHours( date.getHours() - 1 );
async function handler(event, context) {
const snapshotService = new ycsdk.SnapshotService();
const {snapshots} = await snapshotService.list({folderId: FOLDER_ID});
const list = [];
list.push( date.getTime() / 1000 );
for ( let i in snapshots ) {
const d = new Date( snapshots[i].createdAt );
list.push( d.getTime() / 1000 );
}
throw Error( JSON.stringify( list ) );
}
exports.handler = handler;
;
Obtenemos el error:
{
"errorMessage": "[1594135869.705,null,null,null,null,null,null,null]",
"errorType": "Error",
"stackTrace": [
{
"function": "Runtime.handler",
"file": "/function/code/index.js",
"line": 18,
"column": 9
}
]
}
Esta respuesta nos dice que la función Date no pudo analizar la cadena de propiedad supuestamente createdAt, que debería contener la fecha y la hora como una cadena, según la documentación.
Total: en la plataforma Yandex Cloud, se encontró otra discrepancia entre la documentación y el estado real de las cosas. Si tiene la misma tarea que la mía, no tiene que dedicarle todo un día de trabajo.