Guía de migración de la API v1alpha2 de Cloud Genomics

La API de v1alpha2 es obsoleta y se la dará de baja más adelante en 2018. En esta guía se describe cómo migrar las definiciones de canalización de la API v1alpha2 a la v2alpha1. La API v2alpha tiene un rendimiento considerablemente mejor; sin embargo, en esta guía solo se describen los pasos mínimos necesarios para traducir las solicitudes de v1alpha2.

Además de este documento, se encuentra disponible una herramienta de código abierto que migra automáticamente las solicitudes de v1alpha2. Esta herramienta lee una solicitud de v1alpha2 de la entrada estándar, aplica las transformaciones que se describen a continuación y escribe una solicitud de v2alpha1 en la salida estándar.

Diferencias clave en v2alpha1

Existen algunas diferencias clave que es importante comprender en la API v2alpha1:

  1. Se pueden ejecutar varios contenedores en una sola solicitud de canalización. Se puede utilizar la misma imagen o varias imágenes. Un mensaje Action define cada ejecución de contenedor.

  2. La localización y la deslocalización (la copia de archivos en la VM y desde la VM, respectivamente) ya no es una parte fija de la API. En su lugar, las acciones deben agregarse a la canalización y las acciones llevan a cabo estas funciones.

  3. El registro en Cloud Storage ya no se proporciona como una parte fija de la API, aunque se brinda más información durante la ejecución que en la API v1alpha2. Si se necesitan registros adicionales, se debe agregar una acción a la canalización que copia los registros de la VM.

  4. Se ha quitado la división entre una definición de canalización y los parámetros de entrada/salida, lo que simplifica de manera significativa la solicitud.

  5. Los siguientes alcances ya no se habilitan de manera automática para la cuenta de servicio que se utiliza para acceder a los datos y los servicios, por lo tanto, deben habilitarse en forma manual si así lo requiere la canalización:

    • https://www.googleapis.com/auth/compute
    • https://www.googleapis.com/auth/devstorage.full_control
    • https://www.googleapis.com/auth/logging.write
    • https://www.googleapis.com/auth/monitoring.write

Cómo migrar las solicitudes

El proceso de migración de solicitudes de v1alpha2 a la API nueva consiste principalmente en unir el único comando de Docker especificado por el usuario a una serie de acciones para realizar la localización, la deslocalización y el registro. Este proceso se describe en detalle en las secciones que figuran a continuación.

Recursos

Los recursos se especifican en dos partes en la API v1alpha2: EphemeralPipeline y PipelineArgs. Estas dos especificaciones deben combinarse antes de que se traduzcan en una objeto Resources de v2alpha1. La estrategia más simple es anular cualquier valor especificado en la canalización efímera con el valor especificado en los argumentos de la canalización.

Una vez que los recursos se combinan, la mayoría de los campos se asignan directamente a sus contrapartes en el objeto Resources.

Una excepción significativa es la string del tipo de máquina, que debe generarse según los campos minimumCpuCores y minimumRamGb en la solicitud de v1alpha2.

Se pueden utilizar nombres de tipo de máquina estándar (por ejemplo, n1-standard-1) o tipos personalizados (por ejemplo, custom-1-4096). Si se especifica un tipo personalizado que se asigna directamente a un tipo estándar más económico, Compute Engine utilizará el tipo estándar automáticamente.

La forma más sencilla de migrar los valores existentes a los tipos de máquina es tomar la cantidad mínima de núcleos de CPU y RAM especificados y generar un tipo personalizado de máquina (N-M personalizado), en donde N es la cantidad de núcleos y M es la cantidad de megabytes de RAM. Por lo general, esto asignará máquinas menos costosas, aunque algunas canalizaciones pueden fallar si no se solicitaron las cantidades mínimas suficientes.

Ejemplo: Cómo asignar valores mínimos de CPU y RAM a un tipo personalizado de máquina

v1alpha2v2alpha1

{
  'ephemeralPipeline': {
    'resources': {
      'minimumCpuCores': 1,
      'minimumRamGb': 4
    }
  },
  'pipelineArgs': {
    'resources': {
      'minimumRamGb': 8,
      'preemptible': true
    }
  }
}

{
  'pipeline': {
    'resources': {
      'virtualMachine': {
        'machineType': 'custom-1-8192',
        'preemptible': true
      }
    }
  }
}

Localización

Para realizar la localización de la misma manera que la API v1alpha2, se debe traducir cada entrada en el campo inputParameters. Ten en cuenta que las secciones inputParameters y pipelineArgs en la solicitud de v1alpha2 deben combinarse.

Ejemplo: Parámetro de entrada simple

En el ejemplo que figura a continuación, se muestra cómo convertir un parámetro de entrada simple (no se copia ningún archivo). En este caso, el valor simplemente debe agregarse a la asignación environment de la canalización para que se exponga como una variable de entorno al contenedor.

v1alpha2v2alpha1

{
  'ephemeralPipeline': {
    'inputParameters': [
      {
        'name': 'SHARDS',
        'defaultValue': '1'
      },
    ],
  },
  'pipelineArgs': {
    'SHARDS': '2',
  }
}

{
  'pipeline': {
    'environment': {
      'SHARDS': '2'
    }
  }
}

Ejemplo: Cómo copiar un archivo de entrada

En el ejemplo que figura a continuación, se muestra un parámetro de entrada que utiliza localCopy. En este caso, se debe generar un nombre de archivo local único y asignarlo a la variable de entorno apropiada, y se debe agregar una acción que invoque el comando gsutil para copiar el archivo en la VM.

Ten en cuenta que el disco data adjunto debe activarse en la acción que copia el archivo, así como en cualquier acción que espera utilizar el archivo.

v1alpha2v2alpha1

{
  'ephemeralPipeline': {
    'inputParameters': [
      {
        'name': 'INPUT1',
        'defaultValue': 'gs://DIRECTORY/FILE'
        'localCopy': {
          'path': 'test',
          'disk': 'data'
        }
      }
   ],
   'resources': {
     'disks': [
       {
         'name': 'data',
         'mountPoint': '/data'
       }
     ]
   }
 }
}

{
  'pipeline': {
     'environment': {
       'INPUT1': '/data/input1'
     },
    'actions': [
      {
        'imageUri': 'google/cloud-sdk',
        'commands': [
          'sh', '-c', 'gsutil cp gs:/DIRECTORY/FILE $INPUT1'
        ]
        'mounts': [
          {
            'disk': 'data',
            'path': '/data'
          }
        ]
      }
    ]
    'resources': {
      'virtualMachine': {
        'disks': [
           {
             'name': 'data'
           }
        ]
      }
    }
  }
}

Cómo ejecutar el comando de usuario

Una vez que se hayan agregado las acciones de localización requeridas, se debe generar una sola acción desde un ejecutor v1alpha2 especificado por el usuario. Esto implica traducir los parámetros DockerExecutor en una acción.

Ten en cuenta que la API v1alpha2 ejecutó comandos con el uso de bash. Esto no se requiere en v2alpha1, pero es recomendable cuando se migran canalizaciones para evitar resultados inesperados. En particular, se requiere el uso de bash para provocar la expansión de la variable de entorno.

Ejemplo: Cómo ejecutar el comando especificado por el usuario con un shell

v1alpha2v2alpha1

{
  'ephemeralPipeline': {
    'executor': {
      'imageName': 'ubuntu',
      'cmd': 'echo hello world'
    }
  }
}

{
  'pipeline': {
    'actions': [
      {
        'imageUri': 'ubuntu',
        'commands': [
          'bash', '-c', 'echo hello world'
        ]
      }
    ]
  }
}

Deslocalización

Después de agregar la acción que ejecuta el comando de usuario, se deben agregar acciones adicionales para cualquier outputParameters. Estas acciones copiarán los datos de la VM en Cloud Storage.

Estas acciones deben tener la marca ALWAYS_RUN especificada para garantizar que se ejecuten incluso si falla el comando de usuario. Normalmente, una vez que la acción falla, la canalización deja de ejecutarse. Dado que un archivo de salida parcial puede ser útil, las acciones de deslocalización deben ejecutarse siempre. Consulta la documentación de referencia de Action para obtener el conjunto completo de marcas disponibles.

Ejemplo: Cómo copiar un archivo de salida

v1alpha2v2alpha1

{
  'ephemeralPipeline': {
    'outputParameters': [
      {
        'name': 'OUTPUT1',
        'defaultValue': 'gs://DIRECTORY/FILE'
        'localCopy': {
          'path': 'test',
          'disk': 'data'
        }
      }
   ],
   'resources': {
     'disks': [
       {
         'name': 'data',
         'mountPoint': '/data'
       }
     ]
   }
 }
}

{
  'pipeline': {
     'environment': {
       'INPUT1': '/data/input1'
     },
    'actions': [
      {
        'imageUri': 'google/cloud-sdk',
        'commands': [
          'sh', '-c', 'gsutil cp $OUTPUT1 gs://DIRECTORY/FILE'
        ]
        'flags': [
          'ALWAYS_RUN'
        ],
        'mounts': [
          {
            'disk': 'data',
            'path': '/data'
          }
        ]
      }
    ]
    'resources': {
      'virtualMachine': {
        'disks': [
           {
             'name': 'data'
           }
        ]
      }
    }
  }
}

Registros

Por último, después de las acciones de deslocalización, los registros deben copiarse de la VM en Cloud Storage. Para lograr una compatibilidad total con la API v1alpha2, esto debe realizarse cada pocos minutos en segundo plano. Sin embargo, la mayoría de los usuarios solo necesitarán consultar los registros una vez que se complete la canalización y bastará con ver una sola acción.

Los registros se almacenan en el directorio especial /google (y siempre activado en solo lectura). Consulta la documentación de referencia de Action para obtener una descripción detalla de este directorio.

Ejemplo: Cómo copiar los registros en Cloud Storage al final de la canalización

En este ejemplo, los registros se copian de la VM una vez como una acción final que se marca como ALWAYS_RUN (porque los registros pueden ser particularmente interesantes para las canalizaciones con errores).

v1alpha2v2alpha1

{
  'ephemeralPipeline': {
    'logging': {
      'gcsPath': 'gs://DIRECTORY/FILE'
    }
 }
}

{
  'pipeline': {
    'actions': [
      {
        'imageUri': 'google/cloud-sdk',
        'commands': [
          'sh', '-c', 'gsutil cp /google/logs/output gs://DIRECTORY/FILE'
        ],
        'flags': [
          'ALWAYS_RUN'
        ]
      }
    ]
  }
}

Ejemplo: Cómo copiar periódicamente los registros en Cloud Storage

En este ejemplo, los registros se copian de la VM cada minuto como una acción en segundo plano (una característica nueva en la API v2alpha1).

v1alpha2v2alpha1

{
  'ephemeralPipeline': {
    'logging': {
      'gcsPath': 'gs://DIRECTORY/FILE'
    }
 }
}

{
  'pipeline': {
    'actions': [
      {
        'imageUri': 'google/cloud-sdk',
        'commands': [
          'sh', '-c', 'while true; sleep 1m; gsutil cp /google/logs/output gs://DIRECTORY/FILE; done'
        ],
        'flags': [
          'RUN_IN_BACKGROUND'
        ]
      }
    ]
  }
}

Cómo leer la información de estado

En general, el estado de la operación se expone de manera similar a través de la API de Long Running Operations estándar. Cada canalización en ejecución tiene un campo done que indica si se ha completado. Cuando este campo indica que se ha realizado la operación, se propagarán los campos error o response.

Eventos

La API v2alpha1 expone una transmisión de eventos procesable. El conjunto de eventos difiere de la API v1alpha2. En la tabla que figura a continuación, se describe cómo asignar las descripciones de eventos v1alpha2 a la información que expone la API v2alpha1 (cuando sea posible).

v1alpha2 v2alpha1
start El primer PullStartedEvent.
pulling-image PullStartedEvent se emite cuando se inicia cada extracción. PullStoppedEvent se emite cuando se detiene cada extracción.
running-docker Para cada acción, se genera un ContainerStartedEvent cuando se inicia el contenedor y se genera un ContainerStoppedEvent cuando se sale del contenedor.
localizing-files
delocalizing-files
Debido a que la localización es simplemente otra invocación de contenedor, ContainerStartedEvent y ContainerStoppedEvent pueden utilizarse junto con las etiquetas por acción.
fail Se genera un FailedEvent.
ok No hay un evento correspondiente, pero el campo done de la operación se configura en true con un error vacío.

Cómo acceder a los contenedores

En la API v2alpha1, no puedes acceder directamente con SSH a los contenedores en ejecución. Sin embargo, pueden acceder a los contenedores mediante la ejecución de un servidor SSH separado como una acción en segundo plano. El servidor se ejecuta en la misma red que los otros contenedores y puede comunicarse con ellos. Para ejecutar el servidor separado, inícialo como una acción en segundo plano (mediante el uso de la marca RUN_IN_BACKGROUND) antes de ejecutar cualquier otra acción.

Ejemplo: Cómo iniciar un contenedor SSH como una acción en segundo plano

v2alpha1

{
  'pipeline': {
    'actions': [
      {
        'imageUri': 'gcr.io/cloud-genomics-pipelines/tools',
        'entrypoint': 'ssh-server',
        'flags': [
          'RUN_IN_BACKGROUND'
        ],
        "portMappings": {
          "22": 22
        }
      }
    ]
  }
}
¿Te ha resultado útil esta página? Enviar comentarios:

Enviar comentarios sobre...