En este documento, se describe cómo instalar y configurar el proveedor de IBM Symphony para Compute Engine. Aprenderás a configurar Pub/Sub para supervisar los eventos de instancias de máquina virtual (VM), compilar e instalar el complemento del proveedor, y configurar la instancia del proveedor en tu entorno de fábrica de hosts de Symphony.
Para obtener más información sobre los conectores de Symphony para Google Cloud, consulta Integrate IBM Spectrum Symphony with Google Cloud.
Antes de comenzar
Para instalar el proveedor de Symphony para Compute Engine, debes tener los siguientes recursos:
- Un clúster de IBM Spectrum Symphony en ejecución con el servicio de fábrica de hosts habilitado. Tienes el nombre de host de tu host principal de IBM Spectrum Symphony.
- Una cuenta de servicio dedicada con los roles necesarios Para obtener más información sobre cómo crear esta cuenta de servicio, consulta Crea una cuenta de servicio.
Una regla de firewall que configuraste para permitir la comunicación entre el host principal de Symphony y Compute Engine. Por ejemplo:
gcloud compute firewall-rules create allow-symphony-primary-to-compute \ --project=PROJECT_ID \ --direction=INGRESS \ --priority=1000 \ --network=NETWORK_NAME \ --allow=all \ --source-tags=NETWORK_TAGS_MASTER \ --target-tags=NETWORK_TAGS gcloud compute firewall-rules create allow-symphony-compute-to-primary \ --project=PROJECT_ID \ --direction=INGRESS \ --priority=1000 \ --network=NETWORK_NAME \ --allow=all \ --source-tags=NETWORK_TAGS \ --target-tags=NETWORK_TAGS_MASTERReemplaza lo siguiente:
PROJECT_ID: Es el ID de tu proyecto de Google Cloud.NETWORK_NAME: Es el nombre de la red de VPC en la que se implementan tus recursos de Symphony.NETWORK_TAGS_MASTER: Es la etiqueta de red aplicada a la VM del host principal de Symphony.NETWORK_TAGS: Es la etiqueta de red aplicada a las VMs de los nodos de procesamiento de Symphony.
Para obtener más información, consulta Crea reglas de firewall de VPC.
Roles obligatorios
Para obtener los permisos que necesitas para crear y administrar instancias que usan una cuenta de servicio, pídele a tu administrador que te otorgue los siguientes roles de IAM en el proyecto:
-
Administrador de instancias de Compute (v1) (
roles/compute.instanceAdmin.v1) -
Usuario de la cuenta de servicio (
roles/iam.serviceAccountUser)
Para obtener más información sobre cómo otorgar roles, consulta Administra el acceso a proyectos, carpetas y organizaciones.
También puedes obtener los permisos necesarios a través de roles personalizados o cualquier otro rol predefinido.
Prepara tu entorno de Compute Engine
Para permitir que la fábrica de hosts de Symphony cree y administre VMs, debes configurar varios recursos de Google Cloud :
Plantilla de instancias: Es un plano que define la configuración de las VMs de procesamiento de Symphony que crea la fábrica de hosts.
Grupo de instancias administrado (MIG): Es un grupo de VMs idénticas que se crean con una plantilla de instancias. La fábrica de hosts ajusta la escala de este grupo agregando o quitando VMs según la demanda de la carga de trabajo.
Tema y suscripción de Pub/Sub: Un servicio de mensajería que notifica al proveedor de Symphony sobre los eventos del ciclo de vida de la VM, como las interrupciones o las eliminaciones. Este servicio permite que el proveedor mantenga un estado preciso del clúster.
Crea una plantilla de instancias
Crea una plantilla de instancias para los hosts de procesamiento de Symphony con el comando gcloud compute instance-templates create. Esta plantilla define las propiedades de las VMs que crea. Estas VMs deben tener instalado Symphony. Puedes usar una imagen con Symphony preinstalado o usar una secuencia de comandos de inicio para instalar Symphony después de crear las VMs. Para obtener información sobre la instalación de Symphony en una VM de host de procesamiento, consulta Instalación en un host de procesamiento de Linux en la documentación de IBM.
gcloud compute instance-templates create INSTANCE_TEMPLATE_NAME \
--machine-type=MACHINE_TYPE \
--network-interface=nic-type=GVNIC,stack-type=IPV4_ONLY,subnet=SUBNET_NAME,no-address \
--instance-template-region=REGION \
--service-account=SERVICE_ACCOUNT_EMAIL \
--scopes=https://www.googleapis.com/auth/devstorage.read_only,https://www.googleapis.com/auth/logging.write,https://www.googleapis.com/auth/monitoring.write,https://www.googleapis.com/auth/service.management.readonly,https://www.googleapis.com/auth/servicecontrol,https://www.googleapis.com/auth/trace.append \
--tags=NETWORK_TAGS \
--create-disk=auto-delete=yes,boot=yes,device-name=INSTANCE_TEMPLATE_NAME,image-family=rocky-linux-9,image-project=rocky-linux-cloud,mode=rw,size=20,type=pd-balanced \
--shielded-secure-boot \
--shielded-vtpm \
--shielded-integrity-monitoring
Reemplaza lo siguiente:
INSTANCE_TEMPLATE_NAME: Un nombre para tu nueva plantilla de instanciasMACHINE_TYPE: Es el tipo de máquina para tus instancias de procesamiento. Para obtener más información, consulta Crea una VM con un tipo personalizado de máquina.SUBNET_NAME: Es el nombre de la subred para tus instancias. Para obtener más información, consulta Cómo ver la configuración de red de una instancia.SERVICE_ACCOUNT_EMAIL: Es el correo electrónico de la cuenta de servicio que configuraste en la sección Antes de comenzar. Asegúrate de que esta cuenta de servicio tenga los roles especificados en la sección Roles obligatorios.REGION: Es la región de Google Cloud en la que deseas crear tus recursos.NETWORK_TAGS: Es una etiqueta de red que se aplicará a tus instancias y que se puede usar para reglas de firewall, por ejemplo,symphony-compute.
Crea un grupo de instancias administrado
Crea un grupo de instancias administrado (MIG) con la plantilla de instancias del paso anterior. El proveedor de la fábrica de hosts ajusta la escala de este grupo agregando o quitando instancias según la demanda de la carga de trabajo.
gcloud compute instance-groups managed create INSTANCE_GROUP_NAME \
--project=PROJECT_ID \
--base-instance-name=INSTANCE_GROUP_NAME \
--template=projects/PROJECT_ID/regions/REGION/instanceTemplates/INSTANCE_TEMPLATE_NAME \
--size=0 \
--zone=ZONE
--default-action-on-vm-failure=repair \
--no-force-update-on-repair \
--standby-policy-mode=manual \
--list-managed-instances-results=pageless
Reemplaza lo siguiente:
INSTANCE_GROUP_NAME: Es el nombre que elegiste para el grupo de instancias administrado.PROJECT_ID: Es el ID de tu proyecto de Google Cloud. Para obtener más información, consulta Cómo encontrar el nombre, el número y el ID del proyecto.INSTANCE_TEMPLATE_NAME: Es el nombre de la plantilla de instancias que creaste en el paso anterior.REGION: Es la región en la que se encuentran tus recursos, comous-east.ZONE: Es la zona dentro de la región seleccionada, comoa.
Para obtener más información sobre cómo crear MIG, consulta Crea un MIG en una sola zona.
Configura Pub/Sub
Para permitir que el proveedor de Symphony reciba notificaciones sobre los eventos del ciclo de vida de la VM, configura un tema y una suscripción de Pub/Sub:
En tu host principal de Symphony, configura las siguientes variables de entorno:
export GCP_PROJECT=PROJECT_ID export PUBSUB_TOPIC=PUBSUB_TOPICReemplaza lo siguiente:
PROJECT_ID: Es el ID de tu proyecto de Google Cloud .PUBSUB_TOPIC: Es un nombre para tu tema deGoogle Cloud , comohf-gce-vm-events.
Crea un tema de Pub/Sub:
gcloud pubsub topics create $PUBSUB_TOPICUsa el comando gcloud logging sinks create para crear un receptor de registros que exporte los registros de auditoría a Pub/Sub:
gcloud logging sinks create ${PUBSUB_TOPIC}-sink \ pubsub.googleapis.com/projects/${GCP_PROJECT}/topics/${PUBSUB_TOPIC} \ --log-filter=" logName=\"projects/${GCP_PROJECT}/logs/cloudaudit.googleapis.com%2Factivity\" resource.type=(\"gce_instance_group_manager\" OR \"gce_instance\") protoPayload.methodName=( \"v1.compute.instanceGroupManagers.createInstances\" OR \"v1.compute.instanceGroupManagers.deleteInstances\" OR \"v1.compute.instances.insert\" OR \"v1.compute.instances.delete\" ) " \ --description="Exports MIG VM create/delete audit logs to Pub/Sub"El resultado de este comando incluye una cuenta de servicio que usarás en el siguiente paso.
Otorga el rol de Publicador de Pub/Sub (
roles/pubsub.publisher) a la cuenta de servicio del paso anterior:gcloud pubsub topics add-iam-policy-binding $PUBSUB_TOPIC \ --member="serviceAccount:LOGGING_SINK_SERVICE_ACCOUNT" \ --role="roles/pubsub.publisher"Reemplaza
LOGGING_SINK_SERVICE_ACCOUNTpor el nombre de la cuenta de servicio del resultado de la creación del receptor de registros.Crea una suscripción para recibir los registros:
gcloud pubsub subscriptions create ${PUBSUB_TOPIC}-sub \ --topic=${PUBSUB_TOPIC}Verifica que tu cuenta de servicio tenga los permisos correctos para suscribirse a la suscripción:
gcloud pubsub subscriptions add-iam-policy-binding ${PUBSUB_TOPIC}-sub \ --member="serviceAccount:SERVICE_ACCOUNT_EMAIL" \ --role="roles/pubsub.subscriber"Reemplaza
SERVICE_ACCOUNT_EMAILpor el correo electrónico de la cuenta de servicio que administra tu grupo de instancias. Esta es la misma cuenta de servicio que configuraste en la sección Antes de comenzar.
Se completó la configuración de Pub/Sub. Para obtener más información sobre cómo configurar Pub/Sub, consulta Publica y recibe mensajes en Pub/Sub con Google Cloud CLI.
Carga las variables de entorno de la fábrica de host
Antes de configurar o administrar los servicios de la fábrica de hosts, debes cargar las variables de entorno de Symphony en tu sesión de shell. En la VM del host principal de Symphony, ejecuta el siguiente comando:
source INSTALL_FOLDER/profile.platform
Reemplaza INSTALL_FOLDER por la ruta de acceso a tu carpeta de instalación. La ruta de acceso predeterminada a la carpeta de instalación de Symphony es /opt/ibm/spectrumcomputing. Si instalaste Symphony en otra ubicación, usa la ruta de acceso correcta para tu entorno.
Este comando ejecuta la secuencia de comandos profile.platform, que exporta variables de entorno esenciales, como $EGO_TOP y $HF_TOP, y agrega las herramientas de línea de comandos de Symphony a PATH de tu shell. Debes ejecutar este comando para cada sesión de terminal nueva para asegurarte de que el entorno esté configurado correctamente.
Instala el complemento del proveedor
Para integrar el proveedor de Compute Engine con el servicio de fábrica de host de Symphony, instala el complemento del proveedor compilado previamente desde el paquete RPM o compila el proveedor desde el código fuente.
Instala el complemento del proveedor precompilado
Para instalar el complemento del proveedor con paquetes RPM, sigue estos pasos en tu host principal de Symphony:
Agrega el repositorio
yumpara los conectores de Google Cloud Symphony:sudo tee /etc/yum.repos.d/google-cloud-symphony-connector.repo << EOM [google-cloud-symphony-connector] name=Google Cloud Symphony Connector baseurl=https://packages.cloud.google.com/yum/repos/google-cloud-symphony-connector-x86-64 enabled=1 gpgcheck=0 repo_gpgcheck=0 gpgkey=https://packages.cloud.google.com/yum/doc/yum-key.gpg https://packages.cloud.google.com/yum/doc/rpm-package-key.gpg EOMInstala el paquete del proveedor para Compute Engine:
sudo yum install -y hf-gcpgce-provider.x86_64
El paquete RPM instala los ejecutables y las secuencias de comandos del proveedor en los directorios correctos para el servicio de fábrica del host de Symphony. Después de la instalación, la estructura de directorios se ve de la siguiente manera:
├── bin
│ └── hf-gce
└── scripts
├── getAvailableTemplates.sh
├── getRequestStatus.sh
├── getReturnRequests.sh
├── requestMachines.sh
└── requestReturnMachines.sh
Compila el proveedor a partir del código fuente
Para compilar e instalar el ejecutable de la CLI en el directorio bin del directorio del complemento del proveedor, sigue estos pasos:
Clona el repositorio de
symphony-gcp-connectordesde GitHub:git clone https://github.com/GoogleCloudPlatform/symphony-gcp-connector.gitNavega al directorio
hf-provideren tu proyecto:cd PROJECT_ROOT/hf-providerReemplaza
PROJECT_ROOTpor la ruta de acceso al directorio de nivel superior que contiene el directorio hf-provider, como/home/user/symphony-gcp-connector.Si no tienes instalado
uv, hazlo:pip install uvCrea un entorno virtual de Python con
uv:uv venvActiva el entorno virtual:
source .venv/bin/activateInstala las dependencias necesarias del proyecto:
uv pip install .Instala PyInstaller, que agrupa la aplicación de Python en un ejecutable independiente:
uv pip install pyinstallerCrea la CLI de
hf-gcepara los clústeres de Compute Engine:uv run pyinstaller hf-gce.spec --cleanPara verificar la instalación, ejecuta el comando
--helppara un archivo ejecutable. Es posible que veas un error si no configuras las variables de entorno necesarias.dist/hf-gce --helpCopia el archivo ejecutable en el directorio
bindel complemento del proveedor:mkdir -p ${HF_TOP}/${HF_VERSION}/providerplugins/gcpgce/bin cp dist/hf-gce ${HF_TOP}/${HF_VERSION}/providerplugins/gcpgce/bin/Copia las secuencias de comandos en el directorio
scriptsdel complemento del proveedor:cp -R ./resources/gce_cli/1.2/providerplugins/gcpgce/scripts ${HF_TOP}/${HF_VERSION}/providerplugins/gcpgce/El SO debe admitir la versión de Python que se usa para compilar los ejecutables. Los ejecutables se probaron con Python 3.9.6.
Después de la instalación, la estructura de directorios del complemento del proveedor es similar a este ejemplo:
├── bin
│ └── hf-gce
└── scripts
├── getAvailableTemplates.sh
├── getRequestStatus.sh
├── getReturnRequests.sh
├── requestMachines.sh
└── requestReturnMachines.sh
Habilita el complemento del proveedor
Para habilitar el complemento del proveedor de Compute Engine, regístralo en la configuración de la fábrica del host:
Abre el archivo
$HF_TOP/conf/providerplugins/hostProviderPlugins.json.La variable de entorno
$HF_TOPse define en tu entorno cuando usas el comando source. El valor es la ruta de acceso al directorio de instalación de nivel superior para el servicio de fábrica de hosts de IBM Spectrum Symphony.Agrega una sección del complemento del proveedor
gcpgce:{ "name": "gcpgce", "enabled": 1, "scriptPath": "${HF_TOP}/${HF_VERSION}/providerplugins/gcpgce/scripts/" }Si usas la versión 1.2 del complemento del proveedor con el valor predeterminado para
$HF_TOP, el valor descriptPathresultante esINSTALL_FOLDER/hostfactory/1.2/providerplugins/gcpgce/scripts/.
Configura una instancia del proveedor
Para configurar el proveedor de Compute Engine para tu entorno, crea una instancia del proveedor.
Configura el directorio para la instancia del proveedor:
Si compilaste el proveedor desde el código fuente, debes crear el directorio y los archivos de configuración de forma manual:
mkdir -p $HF_TOP/conf/providers/gcpgceinst/Si instalaste con RPM, este directorio ya existe y contiene archivos de configuración de ejemplo. Copia los archivos de ejemplo para crear tu configuración:
cp $HF_TOP/conf/providers/gcpgceinst/gcpgceinstprov_config.json.dist $HF_TOP/conf/providers/gcpgceinst/gcpgceinstprov_config.json cp $HF_TOP/conf/providers/gcpgceinst/gcpgceinstprov_templates.json.dist $HF_TOP/conf/providers/gcpgceinst/gcpgceinstprov_templates.json
En el directorio
$HF_TOP/conf/providers/gcpgceinst/, crea o edita un archivogcpgceinstprov_config.json. Este archivo contiene la configuración principal del proveedor. El proveedor admite las siguientes variables de configuración. En esta configuración, debes especificar las variables que no tienen un valor predeterminado.Nombre de la variable Descripción Valor predeterminado HF_DBDIRUbicación en la que este proveedor almacena su base de datos de estado. Se define en el entorno de HostFactory como $HF_DBDIR.HF_TEMPLATES_FILENAMEEs el nombre del archivo de plantillas. gcpgceinstprov_templates.jsonGCP_CREDENTIALS_FILEUbicación del archivo de credenciales de la cuenta de servicio Google Cloud . La aplicación usa las credenciales predeterminadas si no especificas este valor. GCP_PROJECT_IDID del Google Cloud proyecto. Ninguno GCP_INSTANCE_PREFIXEs una cadena para anteponer a todos los hosts creados por este proveedor. sym-LOGFILEUbicación del archivo de registro al que el proveedor envía los registros. Un archivo con un nombre generado, ubicado en el directorio definido por la variable de entorno HostFactory HF_PROVIDER_LOGDIR.LOG_LEVELEl nivel de registro de Python WARNINGPUBSUB_TIMEOUTSi el evento de Pub/Sub más reciente es anterior a esta duración (en segundos), el objeto de escucha de Pub/Sub se desconecta. Este tiempo de espera solo se aplica cuando el objeto de escucha de eventos de Pub/Sub se inicia automáticamente. De lo contrario, el objeto de escucha se ejecuta de forma indefinida y el administrador debe controlar el ciclo de vida. 600PUBSUB_TOPICEs el nombre del tema de Pub/Sub. Esta variable solo se usa para la retrocompatibilidad. hf-gce-vm-eventsPUBSUB_SUBSCRIPTIONEs el nombre de la suscripción a Pub/Sub que se supervisará para detectar eventos de VM. hf-gce-vm-events-subPUBSUB_LOCKFILEEs el nombre del archivo que indica si el objeto de escucha de eventos de Pub/Sub está activo. /tmp/sym_hf_gcp_pubsub.lockPUBSUB_AUTOLAUNCHSi se configura como true, el proveedor intenta iniciar automáticamente el objeto de escucha de eventos de Pub/Sub. Si esfalse, debes iniciar el objeto de escucha de eventos de Pub/Sub con el método que elijas, con el comandohf-gce monitorEvents.trueEn el siguiente ejemplo, se muestra una configuración básica:
{ "GCP_PROJECT_ID": "PROJECT_ID", "LOG_LEVEL":"INFO", "PUBSUB_SUBSCRIPTION": "PUBSUB_SUBSCRIPTION", "PUBSUB_TIMEOUT": 100 }Reemplaza lo siguiente:
PROJECT_ID: Es el ID de tu proyecto de Google Cloud .PUBSUB_SUBSCRIPTION: Es el nombre de la suscripción a Pub/Sub que creaste para supervisar los eventos de la VM. Para obtener más información, consulta Configura Pub/Sub.
En el mismo directorio, crea o edita un archivo
gcpgceinstprov_templates.json. Este archivo define las plantillas para las VMs que puede crear el proveedor. Los atributos de la plantilla deben alinearse con la configuración del grupo de instancias de asistencia.- Si instalaste con RPM, usa el archivo
gcpgceinstprov_templates.jsonque creaste en los pasos anteriores como punto de partida. Si compilaste desde la fuente, usa la siguiente plantilla de ejemplo:
{ "templates": [ { "templateId": "template-gcp-01", "maxNumber": 10, "attributes": { "type": [ "String", "X86_64" ], "ncpus": [ "Numeric", "1" ], "nram": [ "Numeric", "1024" ] }, "gcp_zone": "GCP_ZONE", "gcp_instance_group": "INSTANCE_GROUP_NAME" } ] }Reemplaza lo siguiente:
GCP_ZONE: Es la zona Google Cloud en la que se encuentra tu grupo de instancias, comous-central1-a.INSTANCE_GROUP_NAME: Es el nombre del grupo de instancias que administra el proveedor, comosymphony-compute-ig.
- Si instalaste con RPM, usa el archivo
Después de crear estos archivos, verifica que el directorio de la instancia del proveedor sea similar a este ejemplo:
├── gcpgceinstprov_config.json └── gcpgceinstprov_templates.json
Habilita la instancia del proveedor
Para activar la instancia del proveedor, habilítala en el archivo de configuración de la fábrica de host:
Abre el archivo
$HF_TOP/conf/providers/hostProviders.json.Agrega una sección de instancia del proveedor
gcpgceinst:{ "name": "gcpgceinst", "enabled": 1, "plugin": "gcpgce", "confPath": "${HF_CONFDIR}/providers/gcpgceinst/", "workPath": "${HF_WORKDIR}/providers/gcpgceinst/", "logPath": "${HF_LOGDIR}/" }Cuando configuras tu sesión de shell con
source command, esta secuencia de comandos establece estas variables para que apunten a los subdirectorios correctos dentro de tu instalación de Symphony. Luego, el servicio de fábrica de host usa estas variables para construir las rutas completas en el tiempo de ejecución.
Habilita la instancia del solicitante
Para permitir que un componente específico de Symphony use el proveedor de Compute Engine para aprovisionar recursos, habilítalo para ese solicitante.
Abre el archivo
$HF_TOP/conf/requestors/hostRequestors.json.En la instancia del solicitante adecuada, agrega
gcpgceinstal parámetroproviders:"providers": ["gcpgceinst"],El valor del proveedor debe coincidir con el nombre del proveedor que usas en Habilita la instancia del proveedor.
Inicia el servicio de Host Factory
Para aplicar los cambios de configuración, inicia el servicio de Host Factory. En la VM host principal de Symphony, accede como administrador del clúster y, luego, inicia el servicio:
sed -i -e "s|MANUAL|AUTOMATIC|g" $EGO_ESRVDIR/esc/conf/services/hostfactory.xml
egosh user logon -u "SYMPHONY_USERNAME -x "SYMPHONY_PASSWORD
egosh service start HostFactory
Reemplaza lo siguiente:
SYMPHONY_USERNAME: Es el nombre de usuario de Symphony para la autenticación.SYMPHONY_PASSWORD: La contraseña del usuario de Symphony.
Probar conectores
Crea una solicitud de recursos para probar el proveedor de Compute Engine.
Para ello, usa uno de los siguientes métodos:
GUI de Symphony: Para obtener instrucciones sobre cómo crear una solicitud de recursos con la GUI de Symphony, consulta Cómo programar manualmente solicitudes y devoluciones de hosts en la nube en la documentación de IBM.
API de REST: Para crear una solicitud de recursos con la API de REST, sigue estos pasos:
Busca el host y el puerto de la API de REST de la fábrica de hosts:
egosh client view REST_HOST_FACTORY_URLEl resultado es similar al siguiente ejemplo:
CLIENT NAME: REST_HOST_FACTORY_URL DESCRIPTION: http://sym2.us-central1-c.c.symphonygcp.internal:9080/platform/rest/hostfactory/ TTL : 0 LOCATION : 40531@10.0.0.33 USER : Admin CHANNEL INFORMATION: CHANNEL STATE 9 CONNECTEDPara crear una solicitud de recurso con la API de REST, usa el siguiente comando:
HOST=PRIMARY_HOST PORT=PORT TEMPLATE_NAME=INSTANCE_TEMPLATE_NAME PROVIDER_NAME=gcpgceinst curl -X POST -u "SYMPHONY_USER:SYMPHONY_PASSWORD" -H "Content-Type: application/json" -d "{ \"demand_hosts\": [ { \"prov_name\": \"$PROVIDER_NAME\", \"template_name\": \"$TEMPLATE_NAME\", \"ninstances\": 1 } ] }" \ http://$HOST:$PORT/platform/rest/hostfactory/requestor/admin/requestReemplaza lo siguiente:
PRIMARY_HOST: Es el nombre de host de tu host principal del resultado del comando anterior.PORT: El número de puerto de tu host principal del resultado del comando anterior, como9080.SYMPHONY_TEMPLATE_ID: EltemplateIddefinido en el archivogcpgceinstprov_templates.json, comotemplate-gcp-01.SYMPHONY_USER: Es el usuario de Symphony para la autenticación.SYMPHONY_PASSWORD: Es la contraseña del usuario de Symphony.
Si se ejecuta de forma correcta, el resultado será similar al siguiente ejemplo:
{"scheduled_request_id":["SD-641ef442-1f9e-40ae-ae16-90e152ed60d2"]}