ECS: Cómo configurar y utilizar S3 AWS CLI

Summary: Cuando utilice la CLI de AWS para probar escenarios de clientes en los que utilicen la CLI de AWS con ECS para confirmar la funcionalidad y la compatibilidad, consulte siempre la Guía de acceso a datos de ECS para las llamadas a la API compatibles con AWS S3 de ECS. ...

This article applies to This article does not apply to This article is not tied to any specific product. Not all product versions are identified in this article.

Instructions

La interfaz de línea de comandos de AWS (AWS CLI) es una herramienta de AWS que se puede utilizar para probar los comandos de alto nivel de S3 y los comandos de nivel de API de S3 (s3api)

De alto nivel, los comandos de AWS S3 (enlace externo) admiten operaciones comunes de depósitos, como la creación, el listado y la eliminación de depósitos. Cómo descargar e instalar la herramienta; todos los comandos de alto nivel compatibles se pueden obtener en el conjunto de comandos mediante el comando aws s3api help.

S3URI: Representa la ubicación de un objeto, un prefijo o un depósito de S3: se debe escribir en el formato s3://mybucket/mykey Dónde mybucket es t especificado en el cubo de S3, mykey es la clave de S3 especificada. El argumento path debe comenzar con s3://

Los comandos de aws s3api (enlace externo) de nivel de API se encuentran en el conjunto de recomendaciones de s3api. Estos comandos de la API de S3 proporcionan acceso a los metadatos del depósito, como la ACL del depósito, la política del depósito y las políticas de ciclo de vida, por mencionar algunos. Todas las llamadas a la API compatibles se pueden obtener en el conjunto de comandos mediante el comando aws s3api help.

  • La AWS CLI utiliza automáticamente hasta 10 subprocesos para cargar archivos o partes durante las cargas de forma predeterminada
  • La AWS CLI utiliza automáticamente cargas de multipart_threshold para archivos >= 8 MB de tamaño de archivo, multipart_chunksize

Descargue e instale las instrucciones.

  1. Versiones https://github.com/aws/aws-cli/releases (Enlace externo)
  2. Descargar e instalar el paquete de la CLI de AWS
# curl "https://s3.amazonaws.com/aws-cli/awscli-bundle.zip" -o "awscli-bundle.zip"
  1. Extraer paquete
# unzip awscli-bundle.zip
  1. Ejecute el comando de instalación
# sudo /awscli-bundle/install -i /usr/local/aws -b /usr/local/bin/aws
  1. Confirmar versión
# aws version
Output:
      aws-cli/2.0.33 Python/3.7.3 Linux/4.15.0-109-generic botocore/2.0.0dev37

Configuración de la AWS CLI

En esta sección, se explican los pasos básicos para configurar la CLI de AWS para su uso con ECS S3 mediante el usuario de objetos de ECS. En esta sección, se supone que el depósito y el usuario de objetos ya se crearon en ECS. Las credenciales y el archivo de configuración se actualizan cuando ejecuta el comando aws configure.

El archivo de credenciales se encuentra aquí ~/.aws/credentials. El archivo de credenciales almacena los detalles del perfil del usuario (ID de clave de acceso y claves de acceso secretas), el archivo de configuración almacena la región y los detalles del formato de salida.

Obligatorio:
  • ID de clave de acceso: Usuario de objetos de ECS
  • Clave de acceso secreta: Clave secreta
Pasos:
  1. En este ejemplo, se crea un nombre de perfil mc_s3
# aws configure --profile mc_s3
Prompt:

    AWS Access Key ID [None]: mc_s3
    AWS Secret Access Key [None]: 1guFemRLSgqFau6uKzIVAZJu5+PS+S8qO7rvEsi7
    Default region name [None]: 
    Default output format [None]: json
  1. Enumerar todos los perfiles (list-properties disponible en AWS CLI v2)
# aws configure list-properties
Output:
    mc_s3
    ad_uid1
# aws configure list
Output:
		  Name                    Value             Type    Location
		  ----                    -----             ----    --------
	   profile                <not set>             None    None
	access_key     ****************c_s3 shared-credentials-file    
	secret_key     ****************Esi7 shared-credentials-file    
		region                               config-file    ~/.aws/config
  1. Perfil específico de la lista
# aws configure get aws_access_key_id --profile mc_s3
Output:
      mc_s3
Dealing with SSL connections and error on self signed certificate.  ( [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: self signed certificate (_ssl.c:1056))
  1. Si utiliza comandos en 9021, la opción de la CLI de AWS --no-verify-ssl es necesario para omitir el error de certificado autofirmado.
# aws --profile mc_s3 --endpoint=https://ecshop:9021 s3api list-buckets
Output:
     SSL validation failed for https://ecshop:9021/mc_s3_bkt?acl [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: self signed certificate (_ssl.c:1056)
  • Ejecute el comando con --no-verify Opción para omitir este error
# aws --profile mc_s3 --endpoint=https://ecshop:9021 s3api list-buckets --no-verify-ssl --output text
Output:
      
    /usr/local/aws-cli/v2/2.0.33/dist/urllib3/connectionpool.py:986: InsecureRequestWarning: Unverified HTTPS request is being made to host 'ecshop'. Adding certificate verification is strongly advised. See: https://urllib3.readthedocs.io/en/latest/advanced-usage.html#ssl-warnings

    BUCKETS 2020-02-24T21:24:29.440000+00:00        mc_s3_bkt
    BUCKETS 2020-05-06T17:23:48.870000+00:00        mc_s3_bkt2_backup
    BUCKETS 2020-05-06T21:16:13.344000+00:00        mc_s3_bkt_nfs
    OWNER   mc_s3   mc_s3
  • La segunda opción sería descargar el certificado autofirmado de ECS guardado en formato PEM y usar el --ca-bundle opción
  • Utilice OpenSSL a fin de obtener el certificado de ECS para el acceso a datos de objetos en el puerto 9021, copie el contenido del certificado mediante su editor favorito y guarde los encabezados de certificado según el ejemplo que se muestra a continuación.
# openssl s_client -connect ecshop:9021
Dónde ecshop es la IP o el nombre de host de los nodos de ECS y xxxxxx debe ser el certificado completo en su entorno.
Output:

    -----BEGIN CERTIFICATE----- 
    Xxxxxxxxx
    xxxxxxxxx
    ...
    ...
    -----END CERTIFICATE-----
  1. Enumerar depósitos en la tabla Amigable con la opción ca-bundle donde el certificado se guarda en el nombre de archivo PEM ecshop_cert_pem 
# aws --profile mc_s3 --endpoint=https://ecshop:9021 s3api list-buckets  --ca-bundle ecshop_cert.pem  --output table
Output:
    -------------------------------------------------------------
    |                        ListBuckets                        |
    +-----------------------------------------------------------+
    ||                         Buckets                         ||
    |+-----------------------------------+---------------------+|
    ||           CreationDate            |        Name         ||
    |+-----------------------------------+---------------------+|
    ||  2020-02-24T21:24:29.440000+00:00 |  mc_s3_bkt          ||
    ||  2020-05-06T17:23:48.870000+00:00 |  mc_s3_bkt2_backup  ||
    ||  2020-05-06T21:16:13.344000+00:00 |  mc_s3_bkt_nfs      ||
    |+-----------------------------------+---------------------+|
    ||                          Owner                          ||
    |+-----------------------------------+---------------------+|
    ||            DisplayName            |         ID          ||
    |+-----------------------------------+---------------------+|
    ||  mc_s3                            |  mc_s3              ||
    |+-----------------------------------+---------------------+|

Operaciones básicas de S3

https://docs.aws.amazon.com/cli/latest/userguide/cli-services-s3-commands.html (Enlace externo)
Ajuste del rendimiento
  • max_concurrent_requests: la cantidad máxima de solicitudes simultáneas
  • max_queue_size: el número máximo de tareas en la cola de tareas
  • multipart_threshold: el umbral de tamaño que utiliza la CLI para las transferencias de múltiples partes de archivos individuales.
  • multipart_chunksize: cuando se utilizan transferencias de varias partes, este es el tamaño de fragmento que utiliza la CLI para las transferencias de varias partes de archivos individuales.
  • max_bandwidth - El ancho de banda máximo que se consume para cargar y descargar datos hacia y desde Amazon S3.
Se guarda en el archivo de configuración como ejemplo:
# cat .aws/config
Output:
    [profile mc_s3]
    output = json
    s3 =
            endpoint_url = http://ecshop:9020

              max_concurrent_requests = 20
              max_queue_size = 1000
              multipart_threshold = 64MB
              multipart_chunksize = 16MB
              max_bandwidth = 50MB/s
              addressing_style = auto 
Con aws configure set Comando para establecer parámetros para ajustar las velocidades de carga
$ aws configure set default.s3.max_concurrent_requests 20
$ aws configure set default.s3.max_queue_size 10000
$ aws configure set default.s3.multipart_threshold 64MB
$ aws configure set default.s3.multipart_chunksize 16MB
$ aws configure set default.s3.max_bandwidth 50MB/s
$ aws configure set default.s3.addressing_style auto
Pasos: 
  1. Crear depósito mediante s3 mb command
# aws --profile mc_s3 --endpoint http://ecshop:9020 s3 mb s3://s3_bkt
Output:
    make_bucket: s3_bkt
  1. Enumere los depósitos que utilizan s3 ls y s3api list-buckets Los conjuntos de comandos enumeran los depósitos, para cualquier otra operación (denominadas en S3 como "prefijos") (enlace externo) en un depósito
# aws --profile mc_s3 --endpoint http://ecshop:9020 s3 ls
Output:
   2020-07-29 20:34:24 s3_bkt

  #  aws --profile mc_s3 --endpoint http://ecshop:9020 s3api list-buckets
#  aws --profile mc_s3 --endpoint http://ecshop:9020 s3api list-buckets
Output:		
	 aws --profile mc_s3 --endpoint http://ecshop:9020 s3api list-buckets
	{
		"Buckets": [
			{
				"Name": "mc_s3_bkt",
				"CreationDate": "2020-02-24T21:24:29.440000+00:00"
			},
			{
				"Name": "mc_s3_bkt2_backup",
				"CreationDate": "2020-05-06T17:23:48.870000+00:00"
			},
			{
				"Name": "mc_s3_bkt_nfs",
				"CreationDate": "2020-05-06T21:16:13.344000+00:00"
			},
			{
				"Name": "s3_bkt",
				"CreationDate": "2020-07-30T00:34:24.147000+00:00"
			},
  1.  Creación y carga de archivos para pruebas 
  • Ejemplo de creación de archivos de 1 MB y 4 MB
# dd if=/dev/zero of=1MB_output.file bs=1024 count=1024
# dd if=/dev/zero of=4MB_output.file bs=1024 count=4096
  • Ejemplo de creación de un archivo grande de 2 GB
# dd if=/dev/urandom of=bigfile_2GB bs=1024k count=2048
  • Cargue un archivo de 1 MB en el depósito s3_bkt
# aws --profile mc_s3 --endpoint http://ecshop:9020 s3 cp 1MB_output.file s3://s3_bkt
Output:
    upload: ./1MB_output.file to s3://s3_bkt/1MB_output.file
  1. Enumere los archivos en el depósito, s3_bkt Uso del nombre de perfil mc_s3 con s3 lss3api list-objects Conjuntos de comandos 
# aws --profile mc_s3 --endpoint http://ecshop:9020 s3 ls s3://s3_bkt
Output:
2020-07-29 20:39:43   16.0 MiB 16MB_output.file
2020-07-29 20:37:25    1.0 MiB 1MB_output.file
2020-07-29 20:39:23    4.0 MiB 4MB_output.file
 # aws --profile mc_s3 --endpoint http://ecshop:9020 s3api list-objects --bucket s3_bkt
Output:
	{
		"Contents": [
			{
				"Key": "16MB_output.file",
				"LastModified": "2020-07-30T00:39:43.125000+00:00",
				"ETag": "\"3a2d20e2e504fe056bbaae5b4c2351fd-2\"",
				"Size": 16777216,
				"StorageClass": "STANDARD",
				"Owner": {
					"DisplayName": "mc_s3",
					"ID": "mc_s3"
				}
			},
			{
				"Key": "1MB_output.file",
				"LastModified": "2020-07-30T00:37:25.033000+00:00",
				"ETag": "\"b6d81b360a5672d80c27430f39153e2c\"",
				"Size": 1048576,
				"StorageClass": "STANDARD",
				"Owner": {
					"DisplayName": "mc_s3",
					"ID": "mc_s3"
				}
			},
  1. Enumeración de versiones de objetos
# aws --profile mc_s3 --endpoint http://ecshop:9020 s3api list-object-versions --bucket s3_bkt --output text
  1. Descargue el archivo 1MB_output.file desde s3_bkt al directorio /tmp en la máquina local.
# aws --profile mc_s3 --endpoint http://ecshop:9020 s3 cp s3://s3_bkt/1MB_output.file /tmp/
Output:
     download: s3://s3_bkt/1MB_output.file to ../../tmp/1MB_output.file
  1. Compruebe la ACL de un archivo 1MB_output.file en formato YAML para obtener resultados con fines de legibilidad
# aws --profile mc_s3 --endpoint http://ecshop:9020 s3api get-object-acl --bucket s3_bkt --key 1MB_output.file  --output yaml
Output:
        
    Grants:
    - Grantee:
        DisplayName: mc_s3
        ID: mc_s3
        Type: CanonicalUser
      Permission: FULL_CONTROL
    Owner:
      DisplayName: mc_s3
      ID: mc_s3
  1. Compruebe la ACL del depósito en el depósito s3_bkt
# aws --profile mc_s3 --endpoint http://ecshop:9020 s3api get-bucket-acl --bucket s3_bkt --output yaml
Output:      
    Grants:
    - Grantee:
        DisplayName: mc_s3
        ID: mc_s3
        Type: CanonicalUser
      Permission: FULL_CONTROL
    Owner:
      DisplayName: mc_s3
      ID: mc_s3
  1. Compruebe la versión del depósito o habilite el control de versiones en el depósito
# aws --profile mc_s3 --endpoint http://ecshop:9020 s3api get-bucket-versioning --bucket s3_bkt
Output:

    {
        "Status": "Enabled"
    }
  1. Iniciar la carga de varias partes mediante el nivel de API de s3api con un archivo grande 
  1. Cree un archivo de 5 GB:
# time dd if=/dev/urandom of=bigfile_5GB bs=1024k count=5096
  1. Iniciar carga
# aws --profile mc_s3 --endpoint http://ecshop:9020 s3api create-multipart-upload --bucket s3_bkt --key bigfile_5GB
Output:

    {
        "Bucket": "s3_bkt",
        "Key": "bigfile_5GB",
        "UploadId": "27cb6c45ab5c4c838fb5893263d871d3"
    }
  1. Enumerar las cargas incompletas de archivos de múltiples partes https://aws.amazon.com/premiumsupport/knowledge-center/s3-multipart-upload-cli/ (Enlace externo)
# aws --profile mc_s3 --endpoint http://ecshop:9020 s3api list-multipart-uploads --bucket s3_bkt
Output:

	{
	    "Uploads": [
	        {
	            "UploadId": "27cb6c45ab5c4c838fb5893263d871d3",
	            "Key": "bigfile_5GB",
	            "Initiated": "2020-07-31T01:10:56.323000+00:00",
	            "StorageClass": "STANDARD",
	            "Owner": {
	                "DisplayName": "mc_s3",
	                "ID": "mc_s3"
	            }
	        }
	    ]
	}
  1. Mejorar s3 cp Recomendaciones de rendimiento de comando a depósito para archivos grandes con el fin de iniciar cargas de varias partes y cambiar subprocesos simultáneos, consulte más arriba en Ajuste del rendimiento.
  1. Realice una copia de depósito a depósito para copiar file.txt en mc_s3_bkt como s3_bkt Uso de S3api 
# aws --profile mc_s3 --endpoint http://ecshop:9020 s3api copy-object --copy-source mc_s3_bkt/file.txt --key file.txt --bucket s3_bkt
Output:
{
    "VersionId": "1596159769267",
    "CopyObjectResult": {
        "ETag": "\"c789e490a90359de2bd3b09d7e957cfd-128\"",
        "LastModified": "2020-07-31T01:42:49.267000+00:00"
    }
}
  1. Enumerar archivos (objetos o claves) en un depósito 
# aws --profile mc_s3 --endpoint http://ecshop:9020 s3 ls s3://s3_bkt/file.txt --human-readable  summarize
Output:
      2020-07-30 21:42:49    1.0 GiB file.txt
  1. Copiar un archivo de S3_bkt como mc_s3_bkt Uso del conjunto de comandos de alto nivel de cp de S3
El siguiente comando cp copia un único objeto de S3 en un depósito y una clave especificados:
# aws --profile mc_s3 --endpoint http://ecshop:9020 s3 cp s3://s3_bkt/file.txt s3://mc_s3_bkt/file2.txt
       Output:
         copy: s3://s3_bkt/file.txt to s3://mc_s3_bkt/file2.txt
  1. Comprobar si el control de versiones está habilitado en el depósito s3_bkt
# aws --profile mc_s3 --endpoint http://ecshop:9020 s3api get-bucket-versioning --bucket s3_bkt
Output: 

      {
          "Status": "Enabled"
      }
  1. Eliminar depósito mediante s3 rb Comando (el comando no tiene resultado)
# aws --profile mc_s3 --endpoint http://ecshop:9020 s3 rm s3://s3_bkt2
  1. En el siguiente ejemplo, se eliminan todos los objetos y las subcarpetas del depósito y, a continuación, se quita el depósito. (si el control de versiones está habilitado, este comando no elimina objetos de versión (revise LDS, políticas de ciclo de vida)
# aws s3 rb s3://bucket-name --force
  1. Habilitar el control de versiones en el depósito s3_bkt Uso del conjunto de comandos de nivel de API de S3API (el comando no tiene resultado)
# aws --profile mc_s3 --endpoint http://ecshop:9020 s3api put-bucket-versioning --bucket s3_bkt --versioning-configuration Status=Enabled 
  1. Aplicación de la política de ciclo de vida Generar plantilla (consulte la guía de acceso a datos de ECS) La CLI de AWS requiere el formato json para la política de ciclo de vida
# aws --profile mc_s3 --endpoint http://ecshop:9020 s3api put-bucket-lifecycle-configuration --generate-cli-skeleton input --bucket s3_bkt
  1. Aplique la política de vida útil en el depósito. Para obtener más detalles, consulte la Guía de acceso a datos de ECS
Crear política para AbortIncompleteMultipartUpload, NoncurrentVersionExpiration, and ExpiredObjectDeleteMarker and NoncurrentDays por vencer después de 7 días.
#  aws --profile mc_s3 --endpoint http://ecshop:9020 s3api put-bucket-lifecycle --bucket s3_bkt --lifecycle-configuration file://s3_bkt_lifecycle.json
Output:

{
   "Rules": [
   {
      "ID": "expire-non-current-and-dmarkers-and-mpu",
      "Status": "Enabled",
      "Prefix": "/",
      "Expiration": {
         "ExpiredObjectDeleteMarker": true
      },
      "AbortIncompleteMultipartUpload": {
         "DaysAfterInitiation": 7
      },
      "NoncurrentVersionExpiration": {
         "NoncurrentDays": 7
      }
   }
   ]
}
  1. Política de ciclo de vida útil GET
# aws --profile mc_s3 --endpoint http://ecshop:9020 s3api get-bucket-lifecycle --bucket s3_bkt
Output:

{
    "Rules": [
        {
            "Expiration": {
                "Days": 10
            },
            "ID": "DeleteVersion-musa",
            "Prefix": "",
            "Status": "Enabled",
            "NoncurrentVersionExpiration": {
                "NoncurrentDays": 10
            }
        }
    ]
}
  1. Etiquetado de objetos mediante pares de valores clave 
  1. Escriba un archivo. 
$ aws s3 cp file.txt s3://mc_s3_bkt/aws/tag.txt  --profile mc_s3_emea --endpoint  http://emea:9020
upload: ./file.txt to s3://mc_s3_bkt/aws/tag.txt
  1. Add tag (este comando no se ha generado si se ejecutó correctamente. 
    Comando de una sola línea:
$ aws s3api put-object-tagging --profile mc_s3_emea --bucket mc_s3_bkt --key aws/tag.txt --tagging '{"TagSet": [{ "Key": "Product", "Value": "ECS" }]}' --endpoint-url http://emea:9020

Copiar y pegar en varias líneas: 

$ aws s3api put-object-tagging \
	 --profile mc_s3_emea \
     --bucket mc_s3_bkt \
     --key aws/tag.txt \
     --tagging '{"TagSet": [{ "Key": "Product", "Value": "ECS" }]}' \
    --endpoint-url http://emea:9020
  1. Obtenga la etiqueta del objeto.
$ aws s3api get-object-tagging --profile mc_s3_emea --bucket mc_s3_bkt --key aws/tag.txt --endpoint http://emea:9020

{
    "TagSet": [
        {
            "Key": "Product",
            "Value": "ECS"
        }
    ]
}
  1. Adición de varios valores de etiquetas 'key:value' - forma abreviada
$ aws s3api put-object-tagging --profile mc_s3_emea --bucket mc_s3_bkt --key aws/tag5.txt --tagging '{"TagSet": [{ "Key": "Product", "Value": "ECS 3.6.1.2" },{"Key": "Company", "Value": "Dell Technologies"}]}' --endpoint-url http://emea:9020
  1. Obtenga la etiqueta del objeto.
$ aws s3api get-object-tagging --profile mc_s3_emea --bucket mc_s3_bkt --key aws/tag5.txt
{
    "TagSet": [
        {
            "Key": "Product",
            "Value": "ECS 3.6.1.2"
        },
        {
            "Key": "Company",
            "Value": "Dell Technologies"
        }
    ]
}
  1. Bloqueo de objetos de S3
ECS le permite almacenar objetos mediante un modelo write-once-read-many (WORM) a través del bloqueo de objetos de S3. Esta función evita que los objetos se eliminen o sobrescriban durante un tiempo especificado o de manera indefinida.
 
Nota:
  • La función de bloqueo de objetos de S3 de ECS solo soporta los depósitos habilitados para el control de versiones.
  • No hay ninguna interfaz de usuario de ECS para el bloqueo de objetos. Se puede acceder a ella a través de las API de bloqueo de objetos de ECS.
  • Los objetos bloqueados están protegidos contra eliminaciones de ciclo de vida
  • El depósito no puede estar habilitado para el sistema de archivos
  • El bloqueo de objetos funciona con usuarios de IAM y no con usuarios heredados 
  • Habilita el bloqueo de objetos en el depósito, habilita automáticamente el control de versiones 
  • Se requiere un parche si ADO está habilitado y se abordará en ECS 3.7. Consulte el artículo ECS: Deshabilitación de la función de bloqueo de objetos en ECS para IBM Content Manager


Para establecer un bloqueo de objetos en un depósito.
La opción Use put-object-lock-configuration se utiliza con la CLI de AWS.

Consulte: https://docs.aws.amazon.com/AmazonS3/latest/userguide/object-lock-overview.html
put-object-lock-configuration — Referencia de comandos (amazon.com) de la AWS CLI 1.22.24 (enlace externo)

  • Para establecer una configuración de bloqueo de objetos en un depósito
The following put-object-lock-configuration example sets a 1-day object lock on the specified bucket.

$ aws s3api put-object-lock-configuration \
	--profile iam1 \
    --bucket iam-bucket \
    --object-lock-configuration '{ "ObjectLockEnabled": "Enabled", "Rule": { "DefaultRetention": { "Mode": "COMPLIANCE", "Days": 1 }}}'

Este comando no produce ningún resultado.

  • put-object-legal-hold
$ aws s3api put-object-legal-hold --endpoint http://<hostname>:<port_number> --profile iam1 --bucket iam-bucket --key file1.txt --legal-hold "Status=ON"
where:
	--profile: name of profile is profile confirmed in .aws credentials file
	--bucket: Bucket name
	--key: Object name
	--legal-hold: ON or OFF
	--version-id: specifies the version id of the object for Versioned 
	--endpoint: ECS IP and port 9020 or 90201
  • get-object-legal-hold
$ aws s3api get-object-legal-hold --endpoint http://<hostname>:<port_number> --profile iam1 --bucket iam-bucket --key file1.txt
where:
	--bucket: Bucket name
	--key: Object name
	--version-id: specifies the version id of the object
	--endpoint: ECS IP and port 9020 or 90201

Affected Products

Elastic Cloud Storage

Products

ECS Appliance, ECS Appliance Hardware Series, ECS Appliance Software with Encryption, Elastic Cloud Storage
Article Properties
Article Number: 000020564
Article Type: How To
Last Modified: 02 Oct 2025
Version:  6
Find answers to your questions from other Dell users
Support Services
Check if your device is covered by Support Services.