17 oct. 2018

[Singularity] commandes build, exec et shell

build

La commande build permet de télécharger des containers existants, de les convertir d'un format à l'autre, ou encore de construire un container à partir d'un fichier recette (recipe).

Nous allons voir premièrement, comment récupérer un container déjà existant et le modifier puis nous verrons comment en construire un à partir d'un fichier recette. Mais d'abord, un petit tour de la commande build avec help :
$ singularity help build
Build a new Singularity container
Usage:
  singularity build [local options...]
Description:
  IMAGE PATH:
  When Singularity builds the container, output can be one of a few formats:
      default:    The compressed Singularity read only image format (default)
      sandbox:    This is a read-write container within a directory structure
  note: It is a common workflow to use the "sandbox" mode for development of the
  container, and then build it as a default Singularity image for production
  use. The default format is immutable.
  BUILD SPEC:
  The build spec target is a definition (def) file, local image, or URI that can
  be used to create a Singularity container. Several different local target
  formats exist:
      def file  : This is a recipe for building a container (examples below)
      directory:  A directory structure containing a (ch)root file system
      image:      A local image on your machine (will convert to sif if
                  it is legacy format)
  Targets can also be remote and defined by a URI of the following formats:
      library://  an image library (default https://cloud.sylabs.io/library)
      docker://   a Docker registry (default Docker Hub)
      shub://     a Singularity registry (default Singularity Hub)
Options:
      --builder string    remote Build Service URL (default
                          "https://build.sylabs.io")
  -d, --detached          submit build job and print nuild ID (no
                          real-time logs and requires --remote)
  -F, --force             delete and overwrite an image if it currently exists
  -h, --help              help for build
      --json              interpret build definition as JSON
      --library string    container Library URL (default
                          "https://library.sylabs.io")
  -T, --notest            build without running tests in %test section
  -r, --remote            build image remotely (does not require root)
  -s, --sandbox           build image as sandbox format (chroot directory
                          structure)
      --section strings   only run specific section(s) of deffile (setup,
                          post, files, environment, test, labels, none)
                          (default [all])
  -u, --update            run definition over existing container (skips header)
[...]
  COMMANDS:
      Build a sif file from a Singularity recipe file:
          $ singularity build /tmp/debian0.sif /path/to/debian.def
      Build a sif image from the Library:
          $ singularity build /tmp/debian1.sif library://debian:latest
      Build a base sandbox from DockerHub, make changes to it, then build sif
          $ singularity build --sandbox /tmp/debian docker://debian:latest
          $ singularity exec --writable /tmp/debian apt-get install python
          $ singularity build /tmp/debian2.sif /tmp/debian

Construire une image depuis une image existante

Contrairement à pull, qui récupère des containers sans possibilité directe de le modifié. La commande build permet de l'importer en mode bac à sable (sandbox).
La différence entre ces deux mode est que le mode writable simple va nous permettre d'écrire directement dans un container singularity, le mode sandbox permet d'avoir accès au container directement depuis le système de fichier, ce qui peut être pratique.

Récupération d'un container simplement (comme pull)
$ sudo singularity build debian_library.sif library://debian:latest
WARNING: Authentication token file not found : Only pulls of public images will succeed
INFO:    Starting build...
 40.36 MiB / 40.36 MiB [===================================================================================================================================================================] 100.00% 1.99 MiB/s 20s
INFO:    Creating SIF file...
INFO:    Build complete: debian_library.sif
$ singularity shell debian_library.sif
Singularity debian_library.sif:/data/singularity/build> apt-get update
Reading package lists... Done
E: List directory /var/lib/apt/lists/partial is missing. - Acquire (30: Read-only file system)

On constate que le système est en readonly (comme pour un pull)

Récupération d'un container en mode bac à sable (writable)
$ sudo singularity build --sandbox debian_library library://debian:latest
WARNING: Authentication token file not found : Only pulls of public images will succeed
INFO:    Starting build...
 40.36 MiB / 40.36 MiB [===================================================================================================================================================================] 100.00% 1.08 MiB/s 37s
INFO:    Creating sandbox directory...
INFO:    Build complete: debian_library
pour faire des actions, nous pouvons utiliser les commandes exec ou shell.

Exec

Il existe des applications différentes à la commande exec :
Examples:
  $ singularity exec /tmp/debian.sif cat /etc/debian_version
  $ singularity exec /tmp/debian.sif python ./hello_world.py
  $ cat hello_world.py | singularity exec /tmp/debian.sif python
  $ sudo singularity exec --writable /tmp/debian.sif apt-get update
  $ singularity exec instance://my_instance ps -ef
  $ singularity exec library://centos cat /etc/os-release
pour en savoir plus:
$ singularity help exec 
cependant nous allons montrer par l'exemple les étapes suivantes :

Mise à jour apt :
$ singularity exec --writable debian_library apt-get update -y
E: Could not open lock file /var/lib/dpkg/lock - open (13: Permission denied)
E: Unable to lock the administration directory (/var/lib/dpkg/), are you root?

on constate qu'il faut avoir les droits root pour modifier l'image (dés qu'il s'agit d'écrire de dans), utilisons sudo:
$ sudo singularity exec --writable debian_library apt-get update
Get:1 http://security.debian.org/debian-security stretch/updates InRelease [94.3 kB]
Ign:2 http://cdn-fastly.deb.debian.org/debian stretch InRelease         
Get:3 http://cdn-fastly.deb.debian.org/debian stretch-updates InRelease [91.0 kB]
[...]                                                                                                                                                                       
Reading package lists... Done
cela fonctionne mieux !
Maintenant installons un package (ex: python3)
$ sudo singularity exec --writable debian_library apt-get install python3
$ singularity help shell
[...]
Description:
  singularity shell supports the following formats:
  *.sif               Singularity Image Format (SIF). Native to Singularity 3.0+
  
  *.sqsh              SquashFS format.  Native to Singularity 2.4+
  *.img               ext3 format. Native to Singularity versions < 2.4.
  directory/          sandbox format. Directory containing a valid root file 
                      system and optionally Singularity meta-data.
  instance://*        A local running instance of a container. (See the instance
                      command group.)
  library://*         A container hosted on a Library (default 
                      https://cloud.sylabs.io/library)
  docker://*          A container hosted on Docker Hub
  shub://*            A container hosted on Singularity Hub
[...]
Examples:
  $ singularity shell /tmp/Debian.sif
  Singularity/Debian.sif> pwd
  /home/gmk/test
  Singularity/Debian.sif> exit
  $ singularity shell -C /tmp/Debian.sif
  Singularity/Debian.sif> pwd
  /home/gmk
  Singularity/Debian.sif> ls -l
  total 0
  Singularity/Debian.sif> exit
  $ sudo singularity shell -w /tmp/Debian.sif
  $ sudo singularity shell --writable /tmp/Debian.sif
  $ singularity shell instance://my_instance
  $ singularity shell instance://my_instance
  Singularity: Invoking an interactive shell within container...
  Singularity container:~> ps -ef
  UID        PID  PPID  C STIME TTY          TIME CMD
  ubuntu       1     0  0 20:00 ?        00:00:00 /usr/local/bin/singularity/bin/sinit
  ubuntu       2     0  0 20:01 pts/8    00:00:00 /bin/bash --norc
  ubuntu       3     2  0 20:02 pts/8    00:00:00 ps -ef
Pas mal de possibilités s'offre à
Reading package lists... Done
Building dependency tree     
Reading state information... Done
The following additional packages will be installed:
[...]
Testons la commande python3 suite à l'installation du package
$ singularity exec debian_library python3
Python 3.5.3 (default, Sep 27 2018, 17:25:39)
[GCC 6.3.0 20170516] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>>
Il n'y a pas '--writable' car nous n'avons pas besoin d'écrire dans le container Singularity, mais juste utilisé une application

Shell

Maintenant utilisons la commande shell, celle-ci permet d'accèder à un shell dans le container singularity.

Pour accèder en shell au container sandbox en écriture:
$ sudo singularity shell --writable debian_library
Singularity debian_library:/data/singularity/build> 
C'est tout. Ensuite on peut faire comme si on était dans un shell classique.
Singularity debian_library:~> ifconfig
bash: ifconfig: command not found
Singularity debian_library:~> apt-get install net-tools
Reading package lists... Done
Building dependency tree     
Reading state information... Done
The following NEW packages will be installed:
  net-tools
[...]
Singularity debian_library:~> ifconfig
Pour plus d'info, la commande help :
$ singularity help shell
[...]
Description:
  singularity shell supports the following formats:
  *.sif               Singularity Image Format (SIF). Native to Singularity 3.0+
 
  *.sqsh              SquashFS format.  Native to Singularity 2.4+
  *.img               ext3 format. Native to Singularity versions < 2.4.
  directory/          sandbox format. Directory containing a valid root file
                      system and optionally Singularity meta-data.
  instance://*        A local running instance of a container. (See the instance
                      command group.)
  library://*         A container hosted on a Library (default
                      https://cloud.sylabs.io/library)
  docker://*          A container hosted on Docker Hub
  shub://*            A container hosted on Singularity Hub
[...]
Examples:
  $ singularity shell /tmp/Debian.sif
  Singularity/Debian.sif> pwd
  /home/gmk/test
  Singularity/Debian.sif> exit
  $ singularity shell -C /tmp/Debian.sif
  Singularity/Debian.sif> pwd
  /home/gmk
  Singularity/Debian.sif> ls -l
  total 0
  Singularity/Debian.sif> exit
  $ sudo singularity shell -w /tmp/Debian.sif
  $ sudo singularity shell --writable /tmp/Debian.sif
  $ singularity shell instance://my_instance
  $ singularity shell instance://my_instance
  Singularity: Invoking an interactive shell within container...
  Singularity container:~> ps -ef
  UID        PID  PPID  C STIME TTY          TIME CMD
  ubuntu       1     0  0 20:00 ?        00:00:00 /usr/local/bin/singularity/bin/sinit
  ubuntu       2     0  0 20:01 pts/8    00:00:00 /bin/bash --norc
  ubuntu       3     2  0 20:02 pts/8    00:00:00 ps -ef
Pas mal de possibilités s'offre à vous.

16 oct. 2018

[Singularity] commande run et run-help

La commande run permet de lancer le "runscript" se trouvant dans le container Singularity.
$ singularity help run
Launch a runscript within container
Usage:
  singularity run [run options...]
Description:
  This command will launch a Singularity container and execute a runscript
  if one is defined for that container. The runscript is a metadata file within
  the container that contains shell commands. If the file is present (and
  executable) then this command will execute that file within the container
  automatically. All arguments following the container name will be passed
  directly to the runscript.
  singularity run accepts the following container formats:
  *.sif               Singularity Image Format (SIF). Native to Singularity 3.0+

  *.sqsh              SquashFS format.  Native to Singularity 2.4+
  *.img               ext3 format. Native to Singularity versions < 2.4.
  directory/          sandbox format. Directory containing a valid root file
                      system and optionally Singularity meta-data.
  instance://*        A local running instance of a container. (See the instance
                      command group.)
  library://*         A container hosted on a Library (default
                      https://cloud.sylabs.io/library)
  docker://*          A container hosted on Docker Hub
  shub://*            A container hosted on Singularity Hub
Options:
      --add-caps string        a comma separated capability list to add
      --allow-setuid           allow setuid binaries in container (root only)
      --app string             set an application to run inside a container
      --apply-cgroups string   apply cgroups from file for container
                               processes (requires root privileges)
  -B, --bind strings           a user-bind path specification.  spec has
                               the format src[:dest[:opts]], where src and
                               dest are outside and inside paths.  If dest
                               is not given, it is set equal to src.
                               Mount options ('opts') may be specified as
                               'ro' (read-only) or 'rw' (read/write, which
                               is the default). Multiple bind paths can be
                               given by a comma separated list.
  -e, --cleanenv               clean environment before running container
  -c, --contain                use minimal /dev and empty other
                               directories (e.g. /tmp and $HOME) instead
                               of sharing filesystems from your host
  -C, --containall             contain not only file systems, but also
                               PID, IPC, and environment
      --dns string             list of DNS server separated by commas to
                               add in resolv.conf
      --drop-caps string       a comma separated capability list to drop
  -h, --help                   help for run
  -H, --home string            a home directory specification.  spec can
                               either be a src path or src:dest pair.  src
                               is the source path of the home directory
                               outside the container and dest overrides
                               the home directory within the container.
                               (default "/home/omicuser")
      --hostname string        set container hostname
  -i, --ipc                    run container in a new IPC namespace
      --keep-privs             let root user keep privileges in container
  -n, --net                    run container in a new network namespace
                               (sets up a bridge network interface by default)
      --network string         specify desired network type separated by
                               commas, each network will bring up a
                               dedicated interface inside container
                               (default "bridge")
      --network-args strings   specify network arguments to pass to CNI plugins
      --no-home                do NOT mount users home directory if home
                               is not the current working directory
      --no-init                do NOT start shim process with --pid
      --no-privs               drop all privileges from root user in container
      --nv                     enable experimental Nvidia support
  -o, --overlay strings        use an overlayFS image for persistent data
                               storage or as read-only layer of container
  -p, --pid                    run container in a new PID namespace
      --pwd string             initial working directory for payload
                               process inside the container
  -S, --scratch strings        include a scratch directory within the
                               container that is linked to a temporary dir
                               (use -W to force location)
      --security strings       enable security features (SELinux,
                               Apparmor, Seccomp)
  -u, --userns                 run container in a new user namespace,
                               allowing Singularity to run completely
                               unprivileged on recent kernels. This may
                               not support every feature of Singularity.
      --uts                    run container in a new UTS namespace
  -W, --workdir string         working directory to be used for /tmp,
                               /var/tmp and $HOME (if -c/--contain was
                               also used)
  -w, --writable               by default all Singularity containers are
                               available as read only. This option makes
                               the file system accessible as read/write.
      --writable-tmpfs         makes the file system accessible as
                               read-write with non persistent data (with
                               overlay support only)

Examples:
  # Here we see that the runscript prints "Hello world: "
  $ singularity exec /tmp/debian.sif cat /singularity
  #!/bin/sh
  echo "Hello world: "
  # It runs with our inputs when we run the image
  $ singularity run /tmp/debian.sif one two three
  Hello world: one two three
  # Note that this does the same thing
  $ ./tmp/debian.sif one two three
Il existe aussi la command run-help qui permet d'afficher l'aide interne au container (si le mainteneur du container l'a mise) :
$ singularity help run-help
Display help for container if available
Usage:
  singularity run-help
Description:
  The 'run-help' command will display a help text file for a container if
  available.
Options:
  -h, --help   help for run-help

Examples:
  $ cat my_container.def
  Bootstrap: docker
  From: busybox
  %help
      Some help for this container
  $ sudo singularity build my_container.sif my_container.def
  Using container recipe deffile: my_container.def
  [...snip...]
  Cleaning up...
  $ singularity run-help my_container.sif
    Some help for this container
Nous pouvons tester dans notre cas, suite à la récupération du container singularity-rstudio_latest.sif récupérer préalablement (voir article sur la commande pull : https://astunix.blogspot.com/2018/10/singularity-commande-pull.html):
$ singularity run-help singularity-rstudio_latest.sif

  This will run RStudio Server
Lançons le runscript du container RStudio server :
$ singularity -v run singularity-rstudio_latest.sif
VERBOSE: Set messagelevel to: 4
VERBOSE: Container runtime
VERBOSE: Check if we are running as setuid
VERBOSE: Spawn scontainer stage 1
VERBOSE: Get root privileges
VERBOSE: Execute scontainer stage 1
VERBOSE: Get root privileges
VERBOSE: Create mount namespace
VERBOSE: Spawn smaster process
VERBOSE: Spawn scontainer stage 2
VERBOSE: Create mount namespace
VERBOSE: Spawn RPC server
VERBOSE: Execute smaster process
VERBOSE: Found 'bind path' = /etc/localtime, /etc/localtime
VERBOSE: Found 'bind path' = /etc/hosts, /etc/hosts
VERBOSE: Serve RPC requests
VERBOSE: Checking for template passwd file: /usr/local/var/singularity/mnt/session/rootfs/etc/passwd
VERBOSE: Creating passwd content
VERBOSE: Creating template passwd file and appending user data: /usr/local/var/singularity/mnt/session/rootfs/etc/passwd
VERBOSE: Checking for template group file: /usr/local/var/singularity/mnt/session/rootfs/etc/group
VERBOSE: Creating group content
VERBOSE: Execute scontainer stage 2

D'autres applications existent pour cette commande run, nous y reviendrons plus tard.

[Singularity] commande pull

La commande pull permet de récupérer des containers depuis des URL spécifiques.

Un petit tour sur la page d'aide :
$ singularity help pull
Pull a container from a URI
Usage:
  singularity pull [pull options...]
Description:
  The 'pull' command allows you to download or build a container from a given
  URI.  Supported URIs include:
  library: Pull an image from the currently configured library
      library://[user[collection/[container[:tag]]]]
  docker: Pull an image from Docker Hub
      docker://user/image:tag
   
  shub: Pull an image from Singularity Hub to CWD
      shub://user/image:tag
Options:
  -F, --force            overwrite an image file if it exists
  -h, --help             help for pull
      --library string   the library to pull from (default
                         "https://library.sylabs.io")

Examples:
  From Sylabs cloud library
  $ singularity pull library://alpine:latest
  From Docker
  $ singularity pull docker://tensorflow/tensorflow:latest
  From Shub
  $ singularity pull shub://vsoch/singularity-images
Nous pouvons constater qu'il y a la possibilité de récupérer des containers depuis 3 sources différentes :


Sylabs cloud étant nouveau, nous pouvons nous poser la question concernant la subsistance de Shub dans le futur ou être intégrer  à la bibliothèque Sylab.

Essayons de télécharger plusieurs containers depuis les 3 sources :

Sylab Library :
$ singularity pull library://dtrudg/linux/debian
 40.36 MiB / 40.36 MiB [=================================================================================================================================================================] 100.00% 983.38 KiB/s 42s
Docker : préalablement choisir le container sur https://hub.docker.com
$ singularity pull docker://ubuntu:latest
INFO:    Starting build...
Getting image source signatures
Copying blob sha256:124c757242f88002a858c23fc79f8262f9587fa30fd92507e586ad074afb42b6
 30.29 MiB / 30.29 MiB [====================================================] 3s
Copying blob sha256:9d866f8bde2a0d607a6d17edc0fbd5e00b58306efc2b0a57e0ba72f269e7c6be
 849 B / 849 B [============================================================] 0s
Copying blob sha256:fa3f2f277e67c5cbbf1dac21dc27111a60d3cd2ef494d94aa1515d3319f2a245
 469 B / 469 B [============================================================] 0s
Copying blob sha256:398d32b153e84fe343f0c5b07d65e89b05551aae6cb8b3a03bb2b662976eb3b8
 853 B / 853 B [============================================================] 0s
Copying blob sha256:afde35469481d2bc446d649a7a3d099147bbf7696b66333e76a411686b617ea1
 163 B / 163 B [============================================================] 0s
Copying config sha256:eaed126a557b4b992c2368ae07586921ecc1cf58eefdfd8dc82ea4f67efcfb11
 2.62 KiB / 2.62 KiB [======================================================] 0s
Writing manifest to image destination
Storing signatures
INFO:    Creating SIF file...
INFO:    Build complete: ubuntu_latest.sif
On constate à la fin une conversion du fichier au format singularity (sif).

SHUB : préalablement choisir le container sur https://www.singularity-hub.org
$ singularity pull shub://nickjer/singularity-rstudio
 281.44 MiB / 281.44 MiB [=================================================================================================================================================================] 100.00% 9.18 MiB/s 30s

Nous pouvons constater que dans le répertoire courant les containers sont bien présents :
$ file *
debian_latest.sif:              a /usr/bin/env run-singularity script executable (binary data)
singularity-rstudio_latest.sif: a /usr/bin/env run-singularity script executable (binary data)
ubuntu_latest.sif:              a /usr/bin/env run-singularity script executable (binary data)

[Singularity] commande search

La commande search permet de rechercher des containers dans la bibliothèque de Sylabs (https://library.sylabs.io).

La page d'aide de la commande :
$ singularity help search
Search the library
Usage:
  singularity search [search options...]
Description:
  The Singularity search command allows you to search within a container library
  of your choosing.  The container library defaults to
  https://library.sylabs.io when no other library argument is given.
Options:
  -h, --help             help for search
      --library string   URI for library to search (default
                         "https://library.sylabs.io")

Examples:
  $ singularity search lolcow
Dans notre cas, nous allons chercher un container Debian (chaine de caractère 'debian' recherchée):
$ singularity search debian
No users found for 'debian'
No collections found for 'debian'
Found 2 containers for 'debian'
library://dtrudg/linux/debian
Tags: 9 9.4 latest stretch testing unstable
library://library/default/debian
Tags: 7 8 9 latest

[Containers] Nouvelle version de Singularity

La nouvelle version de Singularity : 3.0 est arrivée. Petit tour du propriétaire.

Singularity est un logiciel de conteneurisation, multi-plateforme, gratuit dont le code source est ouvert (licence BSD 3 clauses). Il est développé en C (et en GO).
Il est développé par la société Sylabs à l'initiative de Gregory Kurtzer.

Comme Docker, Singularity est un logiciel de conteneurisation. Cependant sa conception est orienté pour une application scientifique et supercalculateur (HPC pour High-Performance Computing).
Singularity offre tout de même la possibilité d'utiliser des images Docker ce qui permet de bénéficier de la bibliothèque Docker qui n'est pas négligeable.

La page de Singularity : https://www.sylabs.io/singularity/about/

L'annonce de la nouvelle version : https://www.sylabs.io/2018/10/sylabs-announces-new-release-of-singularity-to-expand-current-ecosystem-of-resources-that-tackles-todays-most-demanding-workloads/

Installation
Pour installer Singularity. Pour le moment pas de packages pré-compiler, il s'agit de récupérer les sources et de les compiler. Tout est très bien expliqué ici : https://www.sylabs.io/guides/3.0/user-guide/quick_start.html

Une fois l'installation réalisée, voyons un peu ce que la commande singularity offre comme possibilités :
$ singularity version
v3.0.0-35-gf86a7721 
$ singularity help
Linux container platform optimized for High Performance Computing (HPC) and
Enterprise Performance Computing (EPC)
Usage:
  singularity [global options...]
Description:
  Singularity containers provide an application virtualization layer enabling
  mobility of compute via both application and environment portability. With
  Singularity one is capable of building a root file system that runs on any
  other Linux system where Singularity is installed.
Options:
  -d, --debug              print debugging information (highest verbosity)
  -h, --help               help for singularity
  -q, --quiet              suppress normal output
  -s, --silent             only print errors
  -t, --tokenfile string   path to the file holding your sylabs
                           authentication token (default
                           "/root/.singularity/sylabs-token")
  -v, --verbose            print additional information
Available Commands:
  build       Build a new Singularity container
  capability  Manage Linux capabilities on containers
  exec        Execute a command within container
  help        Help about any command
  inspect     Display metadata for container if available
  instance    Manage containers running in the background
  keys        Manage OpenPGP key stores
  pull        Pull a container from a URI
  push        Push a container to a Library URI
  run         Launch a runscript within container
  run-help    Display help for container if available
  search      Search the library
  shell       Run a Bourne shell within container
  sign        Attach cryptographic signatures to container
  test        Run defined tests for this particular container
  verify      Verify cryptographic signatures on container
  version     Show application version
Examples:
  $ singularity help
      Additional help for any Singularity subcommand can be seen by appending
      the subcommand name to the above command.

For additional help or support, please visit https://www.sylabs.io/docs/
Contrairement à la version 2.6, la commande image semble avoir disparue mais nous avons des nouvelles fonctionnalités SECU telles que surlignées ci-dessus (capability, keys, sign, search, verify).

Je vais faire sur ce blog une revue de Singularity. Quelques astuces en perspectives à ceux qui aimeraient s'initier à Singularity.

12 oct. 2018

[Linux] permission acl

Comment mettre des permission sur un dossier et qu'elles soit appliquées après lors des prochaines créations

? utiliser les ACL (Access Control Lists)

pour installer le systeme d'acl:

sudo aptitude install acl
ensuite pour permettre d'avoir les droits en lecture+écriture+execution (rwx) pour le groupe et seulement lecture+execution (rx) pour les autres (others) :

chmod g+s /path/to/directory  //set gid 
setfacl -m g::rwx /path/to/directory  //set group to rwx default 
setfacl -m o::rx /path/to/directory   //set other
vérifier :
getfacl /path/to/directory
Output:
# file: ..//path/to/directory

# owner: 
# group: media
# flags: -s-
user::rwx
group::rwx
other::r-x
default:user::rwx
default:group::rwx
default:other::r-x
source (modifiées) : https://unix.stackexchange.com/questions/1314/how-to-set-default-file-permissions-for-all-folders-files-in-a-directory