如何快速轻松地创建快照并自动将其删除

这个故事是关于我如何用2天的时间解决问题。在文档中发现差异,并且在Yandex中编写了Yandex云的真实世界,但是答案没有用。



Yandex.Cloud



任务:



根据计划,在使用的实例中创建SNAPSHOT磁盘。同时,应该可以标记需要备份的磁盘和不需要备份的磁盘。



子任务:



  • 早于n天的快照应自动从存储中删除。在这种情况下,应该可以更改n。
  • 快照必须具有易于阅读的标题。并匹配以下模式:



    %  %- %-%  %


这样一来,如果有必要,一个人就可以知道该如何部署新车。(在最终版本中,它是由第三方计算机执行的单独的bash脚本实现的)。



进度:



Y.cloud中没有执行此任务的标准功能。



解决方案是以牺牲Y.cloud自身内部功能为代价来实现它,以节省资源。为了创建快照,在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;


*调用此函数时,您需要通过环境传递FODLER_ID并指定服务帐户。



接下来,添加对该函数的预定调用。任务就解决了。



子任务1.



最初,决定通过相同的NodeJS12函数执行

此任务。



为此,请参考官方文档,并查看CreatedAt参数必须为字符串类型。



好。我们正在编写一个函数,该函数将删除出生后不到1小时的快照(用于测试)。我们启动。我们什么也没得到。没事不是错误输出字段中的错误,而是我们需要采取的措施。



迭代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;


迭代2.更改



功能,使其在错误正文中显示响应消息。



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\"},…..»


进行梳理后,我们将看到以下内容:



{
    "labels": {},
    "productIds": [],
    "id": "fd813o0n3p753lhqphie",
    "folderId": "b1gfub3omefcfvchsd0f",
    "createdAt": {
      "seconds": {
        "low": 1594137358,
        "high": 0,
        "unsigned": false
      }


从这里我们得出一个结论。CreatedAt不是字符串,而是对象。



迭代3。



我们正在尝试使用CreatedAt。我们改变功能。



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;


我们得到错误:



{
    "errorMessage": "Cannot read property 'seconds' of undefined",
    "errorType": "TypeError",
    "stackTrace": [
        {
            "function": "Runtime.handler",
            "file": "/function/code/index.js",
            "line": 14,
            "column": 29
        }
    ]


该错误告诉我们,尽管我们之前观察到了 "createdAt":{"seconds":{"low":1594137358,"high":0,"unsigned":false}}

迭代4响应对象的属性输出,但我们正在尝试从不存在的对象中获取seconds属性



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;


我们得到错误:



{
    "errorMessage": "{\"seconds\":{\"low\":1594137358,\"high\":0,\"unsigned\":false}}",
    "errorType": "Error",
    "stackTrace": [
        {
            "function": "Runtime.handler",
            "file": "/function/code/index.js",
            "line": 13,
            "column": 11
        }
    ]
}


为方便起见,将循环减少到5次迭代。



迭代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;
;


我们得到错误:



{
    "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
        }
    ]
}


这个答案告诉我们Date函数无法解析所谓的createdAt属性字符串,根据文档,该属性字符串应包含日期和时间作为字符串。



总计-在Yandex Cloud平台中,发现文档与实际状态之间存在另一个差异。如果您的任务与我的任务相同,则无需花费一整天的时间。



All Articles