Fonctionnement des sous-répertoires

Présentation

Cette section fournit des informations sur le fonctionnement des sous-répertoires dans gsutil. La plupart des utilisateurs n'ont probablement pas besoin d'en avoir connaissance et peuvent simplement exécuter les commandes (comme "cp -r") compatibles avec les sous-répertoires. Cette documentation supplémentaire permet aux utilisateurs intéressés de comprendre comment gsutil gère les sous-répertoires différemment de la plupart des outils basés sur une IUG ou sur le Web (par exemple, raisons pour lesquelles ces outils créent des objets "dir_$folder$"), et de connaître les implications en termes de coûts et de performances de l'approche gsutil.

gsutil fournit une structure hiérarchique sous forme d'arborescence de fichiers au-dessus de l'espace de noms "unique" accepté par le service Cloud Storage. Pour le service, gs://your-bucket/abc/def.txt est simplement un objet dont le nom contient des caractères "/". Le répertoire "abc" n'existe pas. Il s'agit du nom d'un seul objet. Considérez le schéma suivant :

https://cloud.google.com/storage/images/gsutil-subdirectories.svg

Il illustre comment gsutil fournit une vue hiérarchique des objets d'un bucket.

gsutil reflète l'arborescence de fichiers hiérarchique en appliquant diverses règles, afin que la dénomination fonctionne comme prévu. Par exemple, pour déterminer si une URL de destination doit être traitée comme un nom d'objet ou comme la racine d'un répertoire dans lequel les objets doivent être copiés, gsutil applique les règles suivantes :

  1. Si l'objet de destination se termine par le caractère "/", gsutil le traite comme un répertoire. Par exemple, si vous exécutez la commande suivante :

    gsutil cp your-file gs://your-bucket/abc/
    

    gsutil crée l'objet gs://your-bucket/abc/your-file.

  2. Si l'objet de destination est XYZ et qu'un objet appelé XYZ_$folder$ existe, gsutil considère que XYZ est un répertoire. Par exemple, si vous exécutez la commande suivante :

    gsutil cp your-file gs://your-bucket/abc
    

    En considérant qu'il existe un objet appelé abc_$folder$, gsutil crée l'objet gs://your-bucket/abc/your-file.

  3. Si vous tentez de copier plusieurs fichiers sources dans une URL de destination, gsutil considère que l'URL de destination est un répertoire. Par exemple, si vous exécutez la commande suivante :

    gsutil cp -r your-dir gs://your-bucket/abc
    

    gsutil crée des objets tels que gs://your-bucket/abc/your-dir/file1, etc. (en supposant que file1 est un fichier situé dans le répertoire source your-dir).

  4. Si aucune des règles ci-dessus ne s'applique, gsutil répertorie les buckets pour déterminer si la cible de l'opération est un préfixe correspondant à la chaîne spécifiée. Par exemple, si vous exécutez la commande suivante :

    gsutil cp your-file gs://your-bucket/abc
    

    gsutil envoie une requête de création de liste de buckets pour le bucket désigné, en utilisant le délimiteur "/" et le préfixe "abc". Il examine ensuite les résultats de la liste de buckets et identifie si le bucket contient des objets dont le chemin d'accès commence par gs://your-bucket/abc/ afin de déterminer si la cible doit être traitée comme un nom d'objet ou de répertoire. Cela a un impact sur le nom de l'objet que vous créez : si la vérification ci-dessus indique qu'il existe un répertoire "abc", l'objet gs://your-bucket/abc/your-file est créé. Sinon, vous obtenez l'objet gs://your-bucket/abc. Pour en savoir plus, consultez la section "Construction des noms" sur la page consacrée à gsutil help cp.

Cette approche basée sur des règles diffère du fonctionnement de nombreux outils, qui créent des objets pour mettre en évidence l'existence de dossiers (par exemple, "dir_$folder$"). gsutil comprend plusieurs conventions utilisées par ces outils, mais ne requiert pas d'objets servant de repère pour mettre en œuvre un comportement de dénomination cohérent avec les commandes UNIX.

L'un des inconvénients de l'approche de dénomination des sous-répertoires gsutil est qu'elle nécessite une liste de buckets supplémentaire avant d'exécuter la commande cp ou mv requise. Toutefois, ces listes sont relativement peu coûteuses, car elles utilisent des paramètres de délimiteur et de préfixe pour limiter les données de résultat. De plus, gsutil n'envoie qu'une seule requête de création de liste de buckets par commande cp/mv. Par conséquent, le coût de la liste des buckets sur tous les objets transférés est amorti (par exemple, lors de la copie récursive d'un répertoire sur le cloud).

Possibilité étonnante de nommer un sous-répertoire de destination

L'approche basée sur des règles présentée ci-dessus, qui permet de déterminer comment les chemins de destination sont construits, peut s'avérer surprenante. Supposons que vous commencez par importer tous les éléments d'un répertoire local dans un "sous-répertoire" de bucket qui n'existe pas encore :

gsutil cp -r ./your-dir/* gs://your-bucket/new

où des répertoires se trouvent dans votre répertoire your-dir (à savoir dir1 et dir2). La première fois que vous exécutez cette commande, celle-ci crée les objets suivants :

gs://your-bucket/new/dir1/abc
gs://your-bucket/new/dir2/abc

car gs://your-bucket/new n'existe pas encore. Si vous exécutez à nouveau la même commande, les objets supplémentaires suivants sont créés du fait que gs://your-bucket/new existe maintenant :

gs://your-bucket/new/your-dir/dir1/abc
gs://your-bucket/new/your-dir/dir2/abc

Au-delà du fait que ce comportement de dénomination peut vous surprendre, vous devez être particulièrement prudent si vous rédigez des scripts d'importations gsutil avec une boucle de nouvelle tentative. Si vous procédez ainsi et que la première tentative copie certains fichiers, mais pas tous, la deuxième tentative identifie un sous-répertoire source existant et renvoie le problème de dénomination décrit ci-dessus.

Il existe plusieurs façons d'éviter ce problème :

1. Exécutez la commande "gsutil rsync". Étant donné que rsync n'utilise pas les règles de dénomination des répertoires définies par cp, la commande s'exécute de manière cohérente, que le sous-répertoire de destination existe ou non.

2. Si l'utilisation de rsync n'est pas adaptée à votre cas, vous pouvez commencer par créer un objet "espace réservé" pour établir que la destination est un sous-répertoire, en exécutant une commande telle que la suivante :

gsutil cp some-file gs://your-bucket/new/placeholder

À ce stade, l'exécution de la commande "gsutil cp -r" mentionnée ci-dessus considère que gs://your-bucket/new est un sous-répertoire. Une fois que vous disposez d'au moins un objet dans ce sous-répertoire, vous pouvez supprimer l'objet d'espace réservé. Les importations suivantes dans ce sous-répertoire continueront à fonctionner avec les règles de dénomination attendues.