如何在 Cloud Functions 中将文件名传递给 VM?

问题描述

文件成功上传到给定的 Google Cloud Storage 存储桶(“Object Finalize”)后,我想设置一个触发器,让正在运行的 VM 中可以访问此文件名。

一个标准的 Cloud Functions 函数可以在文件上传时进行监听,触发器 google.storage.object.finalize:

def hello_gcs(event,context):
    """Background Cloud Function to be triggered by Cloud Storage.
       This generic function logs relevant data when a file is changed.

    Args:
        event (dict):  The dictionary with data specific to this type of event.
                       The `data` field contains a description of the event in
                       the Cloud Storage `object` format described here:
                       https://cloud.google.com/storage/docs/json_api/v1/objects#resource
        context (google.cloud.functions.Context): Metadata of triggering event.
    Returns:
        None; the output is written to Stackdriver Logging
    """

    print('Event ID: {}'.format(context.event_id))
    print('Event type: {}'.format(context.event_type))
    print('Bucket: {}'.format(event['bucket']))
    print('File: {}'.format(event['name']))
    print('Metageneration: {}'.format(event['Metageneration']))
    print('Created: {}'.format(event['timeCreated']))
    print('Updated: {}'.format(event['updated']))

https://cloud.google.com/functions/docs/calling/storage#functions-calling-storage-python

(我使用 Python,但我很乐意使用提供的任何其他语言)

假设我有一个名为“my-instance”的虚拟机:有没有办法将文件名从 event['name'] 传递到虚拟机,以便虚拟机中的代码可以访问它?

还有其他 SO 问题讨论了如何直接从 Cloud Storage 读取文件,例如Read csv from Google Cloud storage to pandas dataframe

import pandas as pd
import gcsfs

fs = gcsfs.GCSFileSystem(project='my-project')
with fs.open('bucket/path.csv') as f:
    df = pd.read_csv(f)

但是如何将文件名从 google.storage.object.finalize 传递到 VM 以运行此代码

解决方法

您有 2 种解决方案可以在您的 VM 中实现此功能:拉取或推送解决方案。

推送

这是最明显的。在您的 VM 上创建一个网络服务器并从您的 Cloud Function 调用它(如果您的 VM 上只有一个私有 IP,请使用无服务器 VPC 连接器来访问它,这最终不是问题)。网络服务器从 Cloud Functions 获取调用,并执行获取文件所需的操作,并在您的 VM 上触发您的代码。

这是另一种解决方案。您可以在正在运行的 VM 上编写 compute engine metadata。然后,在您的 VM 上,在您运行的代码中,您必须检查此计算引擎元数据以查看是否已注册新条目。正确处理文件后清除元数据。


在这两种情况下,您都需要更新正在运行的代码才能收到新事件的通知。


编辑 1

如果您使用启动脚本,您有两种解决方案:

  1. 要么使用 Cloud Functions 的新文件名更新启动脚本,然后启动 VM。文件名直接在脚本中,可以按原样处理。
  2. 或者使用您的 Cloud Functions 使用新文件名更新元数据服务器,然后启动 VM。启动脚本必须检查元数据值以获取文件名并对其进行处理