fn parse_args<'a>() -> ArgMatches<'a> {
    clap::App::new(PROGRAM_NAME)
        .version("0.1")
        .author("From Container Solutions")
        .about(PROGRAM_DESC)
        .arg(
            Arg::with_name("host")
                .long("host")
                .value_name("host")
                .help("Sets the name of the host or interface to start Trow on. Defaults to 0.0.0.0")
                .takes_value(true),
        )
        .arg(
            Arg::with_name("port")
                .long("port")
                .value_name("port")
                .help("The port that trow will listen on. Defaults to 8443 with TLS, 8000 without.")
                .takes_value(true),
        )
        .arg(
            Arg::with_name("no-tls")
                .long("no-tls")
                .help("Turns off TLS. Normally only used in development and debugging. If used in production, make sure you understand the risks.")
        )
        .arg(
            Arg::with_name("cert")
                .short("c")
                .long("cert")
                .value_name("cert")
                .help(&format!("Path to TLS certificate. Defaults to {}.", DEFAULT_CERT_PATH))
                .takes_value(true),
        )
        .arg(
            Arg::with_name("key")
                .short("k")
                .long("key")
                .value_name("key")
                .help(&format!("Path to TLS private key. Defaults to {}.", DEFAULT_KEY_PATH))
                .takes_value(true),
        )
        .arg(
            Arg::with_name("data-dir")
                .short("d")
                .long("data-dir")
                .value_name("data_dir")
                .help("Directory to store images and metadata in.")
                .takes_value(true),
        )
        .arg(
            Arg::with_name("names")
            .short("n")
            .long("names")
            .value_name("names")
            .help("Host names for registry. Used in validation callbacks. Separate with comma or use quotes and spaces")
            .takes_value(true),
        )
        .arg(
            Arg::with_name("dry-run")
            .long("dry-run")
            .value_name("dry_run")
            .help("Don't acutally run Trow, just validate arguments. For testing purposes.")
            .takes_value(false),
        )
        .arg(
            Arg::with_name("allow-docker-official")
            .long("allow-docker-official")
            .value_name("allow_docker_official")
            .help("Docker official images (e.g. the debian base image) will be allowed in validation callbacks.")
            .takes_value(false)
        )
        .arg(
            Arg::with_name("deny-k8s-images")
            .long("deny-k8s-images")
            .value_name("deny_k8s_images")
            .help("By default, validation callbacks will allow various Kubernetes system images by default.
This option will deny those images; be careful as this may disable cluster installation and updates.")
            .takes_value(false)
        )
        .arg(
            Arg::with_name("allow-prefixes")
            .long("allow-prefixes")
            .value_name("allow_prefixes")
            .help("Images that begin with any of the listed prefixes will be allowed in validation callbaks.
Separate with a comma or use quotes and spaces. 
For example 'quay.io/coreos,myhost.com/' will match quay.io/coreos/etcd and myhost.com/myimage/myrepo:tag. 
Use docker.io as the hostname for the Docker Hub.")
            .takes_value(true)
        )
        .arg(
            Arg::with_name("allow-images")
            .long("allow-images")
            .value_name("allow_images")
            .help("Images that match a full name in the list will be allowed in validation callbacks.
Separate with a comma or use quotes and spaces. Include the hostname. 
For example 'quay.io/coreos/etcd:latest'. Use docker.io as the hostname for the Docker Hub.")
            .takes_value(true)
        )

        .arg(
            Arg::with_name("disallow-local-prefixes")
            .long("disallow-local-prefixes")
            .value_name("disallow_local_prefixes")
            .help("Disallow local images that match the prefix _not_ including any host name.
For example 'beta' will match myhost.com/beta/myapp assuming myhost.com is the name of this registry.")
            .takes_value(true)
        )
        .arg(
            Arg::with_name("disallow-local-images")
            .long("disallow-local-images")
            .value_name("disallow_local_images")
            .help("Disallow local images that match the full name _not_ including any host name.
For example 'beta/myapp:tag' will match myhost.com/beta/myapp:tag assuming myhost.com is the name of this registry.")
            .takes_value(true)
        )
        .arg(
            Arg::with_name("user")
            .long("user")
            .short("u")
            .value_name("user")
            .help("Set the username that can be used to access Trow (e.g. via docker login).
Must be used with --password or --password-file")
            .takes_value(true)
        )
        .arg(
            Arg::with_name("password")
            .long("password")
            .short("p")
            .value_name("password")
            .help("Set the password that can be used to access Trow (e.g. via docker login).
Must be used with --user")
            .takes_value(true)
        )
        .arg(
            Arg::with_name("password-file")
            .long("password-file")
            .value_name("password-file")
            .help("Location of file with password that can be used to access Trow (e.g. via docker login).
Must be used with --user")
            .takes_value(true)
        )
        .arg(
            Arg::with_name("version")
            .long("version")
            .short("v")
            .value_name("version")
            .help("Get the version number of Trow")
            .takes_value(false)
        )
        .arg(
            Arg::with_name("proxy-registry-config-dir")
                .long("proxy-registry-config-dir")
                .value_name("proxy-registry-config-dir")
                .help("Local directory with configuration for proxy any registry at f/${registryCfgDir}/<repo_name> to anyregistry.xyz/<repo_name>. Downloaded images will be cached.
Directory should contain sub directories which should correspond to ${registryCfgDir}.
Each of them contains file .dockerconfigjson which should be in format as of kubernetes.io/dockerconfigjson.
The intention is to directly support mounting k8s secrets (imagePullSecrets) in kubernetes and act as proxy according to their configuration.
As of now config dir is parsed each request, to be able  to reflect changes in secrets. It may change in future."
                )
                .takes_value(true)
        )
        .arg(
            Arg::with_name("proxy-docker-hub")
            .long("proxy-docker-hub")
            .value_name("proxy-docker-hub")
            .help("Proxies repos at f/docker/<repo_name> to docker.io/<repo_name>. Downloaded images will be cached.")
            .takes_value(false)
        )
        .arg(
            Arg::with_name("hub-user")
            .long("hub-user")
            .value_name("hub-user")
            .help("Set the username for accessing the Docker Hub, used when proxying Docker Hub images.
Must be used with --hub-token or --hub-token-file")
            .takes_value(true)
        )
        .arg(
            Arg::with_name("hub-token")
            .long("hub-token")
            .value_name("hub-token")
            .help("Set the token for accessing the Docker Hub, used when proxying Docker Hub images")
            .takes_value(true)
        )
        .arg(
            Arg::with_name("hub-token-file")
            .long("hub-token-file")
            .value_name("hub-token-file")
            .help("Location of file with token that can be used for accessing the Docker Hub, used when proxying Docker Hub images")
            .takes_value(true)
        )
        .arg(
            Arg::with_name("enable-cors")
                .long("enable-cors")
                .help("Enable Cross-Origin Resource Sharing(CORS) requests. Used to allow access from web apps (e.g. GUIs).")
        )
        .arg(
            Arg::with_name("max-manifest-size")
            .long("max-manifest-size")
            .value_name("max-manifest-size")
            .help("Maximum size in mebibytes of manifest file that can be uploaded. This is JSON metada, so usually relatively small.")
            .takes_value(true)
        )
        .arg(
            Arg::with_name("max-blob-size")
            .long("max-blob-size")
            .value_name("max-blob-size")
            .help("Maximum size in mebibytes of \"blob\" that can be uploaded (a single layer of an image). This can be very large in some images (GBs).")
            .takes_value(true)
        )
        .get_matches()
}
/*
  Responsible for configuring and starting the Trow registry.

  Parses command line arguments and returns ArgMatches object.

  Will cause the program to exit if error or on help/version argument.
*/
Responsible for configuring and starting the Trow registry.
Parses command line arguments and returns ArgMatches object.

Will cause the program to exit if error or on help/version argument.
Responsible for configuring and starting the Trow registry . Parses command line arguments and returns ArgMatches object . Will cause the program to exit if error or on help / version argument .
fn parse_args<'a>() -> ArgMatches<'a> {
    clap::App::new(PROGRAM_NAME)
        .version("0.1")
        .author("From Container Solutions")
        .about(PROGRAM_DESC)
        .arg(
            Arg::with_name("host")
                .long("host")
                .value_name("host")
                .help("Sets the name of the host or interface to start Trow on. Defaults to 0.0.0.0")
                .takes_value(true),
        )
        .arg(
            Arg::with_name("port")
                .long("port")
                .value_name("port")
                .help("The port that trow will listen on. Defaults to 8443 with TLS, 8000 without.")
                .takes_value(true),
        )
        .arg(
            Arg::with_name("no-tls")
                .long("no-tls")
                .help("Turns off TLS. Normally only used in development and debugging. If used in production, make sure you understand the risks.")
        )
        .arg(
            Arg::with_name("cert")
                .short("c")
                .long("cert")
                .value_name("cert")
                .help(&format!("Path to TLS certificate. Defaults to {}.", DEFAULT_CERT_PATH))
                .takes_value(true),
        )
        .arg(
            Arg::with_name("key")
                .short("k")
                .long("key")
                .value_name("key")
                .help(&format!("Path to TLS private key. Defaults to {}.", DEFAULT_KEY_PATH))
                .takes_value(true),
        )
        .arg(
            Arg::with_name("data-dir")
                .short("d")
                .long("data-dir")
                .value_name("data_dir")
                .help("Directory to store images and metadata in.")
                .takes_value(true),
        )
        .arg(
            Arg::with_name("names")
            .short("n")
            .long("names")
            .value_name("names")
            .help("Host names for registry. Used in validation callbacks. Separate with comma or use quotes and spaces")
            .takes_value(true),
        )
        .arg(
            Arg::with_name("dry-run")
            .long("dry-run")
            .value_name("dry_run")
            .help("Don't acutally run Trow, just validate arguments. For testing purposes.")
            .takes_value(false),
        )
        .arg(
            Arg::with_name("allow-docker-official")
            .long("allow-docker-official")
            .value_name("allow_docker_official")
            .help("Docker official images (e.g. the debian base image) will be allowed in validation callbacks.")
            .takes_value(false)
        )
        .arg(
            Arg::with_name("deny-k8s-images")
            .long("deny-k8s-images")
            .value_name("deny_k8s_images")
            .help("By default, validation callbacks will allow various Kubernetes system images by default.
This option will deny those images; be careful as this may disable cluster installation and updates.")
            .takes_value(false)
        )
        .arg(
            Arg::with_name("allow-prefixes")
            .long("allow-prefixes")
            .value_name("allow_prefixes")
            .help("Images that begin with any of the listed prefixes will be allowed in validation callbaks.
Separate with a comma or use quotes and spaces. 
For example 'quay.io/coreos,myhost.com/' will match quay.io/coreos/etcd and myhost.com/myimage/myrepo:tag. 
Use docker.io as the hostname for the Docker Hub.")
            .takes_value(true)
        )
        .arg(
            Arg::with_name("allow-images")
            .long("allow-images")
            .value_name("allow_images")
            .help("Images that match a full name in the list will be allowed in validation callbacks.
Separate with a comma or use quotes and spaces. Include the hostname. 
For example 'quay.io/coreos/etcd:latest'. Use docker.io as the hostname for the Docker Hub.")
            .takes_value(true)
        )
        .arg(
            Arg::with_name("disallow-local-prefixes")
            .long("disallow-local-prefixes")
            .value_name("disallow_local_prefixes")
            .help("Disallow local images that match the prefix _not_ including any host name.
For example 'beta' will match myhost.com/beta/myapp assuming myhost.com is the name of this registry.")
            .takes_value(true)
        )
        .arg(
            Arg::with_name("disallow-local-images")
            .long("disallow-local-images")
            .value_name("disallow_local_images")
            .help("Disallow local images that match the full name _not_ including any host name.
For example 'beta/myapp:tag' will match myhost.com/beta/myapp:tag assuming myhost.com is the name of this registry.")
            .takes_value(true)
        )
        .arg(
            Arg::with_name("user")
            .long("user")
            .short("u")
            .value_name("user")
            .help("Set the username that can be used to access Trow (e.g. via docker login).
Must be used with --password or --password-file")
            .takes_value(true)
        )
        .arg(
            Arg::with_name("password")
            .long("password")
            .short("p")
            .value_name("password")
            .help("Set the password that can be used to access Trow (e.g. via docker login).
Must be used with --user")
            .takes_value(true)
        )
        .arg(
            Arg::with_name("password-file")
            .long("password-file")
            .value_name("password-file")
            .help("Location of file with password that can be used to access Trow (e.g. via docker login).
Must be used with --user")
            .takes_value(true)
        )
        .arg(
            Arg::with_name("version")
            .long("version")
            .short("v")
            .value_name("version")
            .help("Get the version number of Trow")
            .takes_value(false)
        )
        .arg(
            Arg::with_name("proxy-registry-config-dir")
                .long("proxy-registry-config-dir")
                .value_name("proxy-registry-config-dir")
                .help("Local directory with configuration for proxy any registry at f/${registryCfgDir}/<repo_name> to anyregistry.xyz/<repo_name>. Downloaded images will be cached.
Directory should contain sub directories which should correspond to ${registryCfgDir}.
Each of them contains file .dockerconfigjson which should be in format as of kubernetes.io/dockerconfigjson.
The intention is to directly support mounting k8s secrets (imagePullSecrets) in kubernetes and act as proxy according to their configuration.
As of now config dir is parsed each request, to be able  to reflect changes in secrets. It may change in future."
                )
                .takes_value(true)
        )
        .arg(
            Arg::with_name("proxy-docker-hub")
            .long("proxy-docker-hub")
            .value_name("proxy-docker-hub")
            .help("Proxies repos at f/docker/<repo_name> to docker.io/<repo_name>. Downloaded images will be cached.")
            .takes_value(false)
        )
        .arg(
            Arg::with_name("hub-user")
            .long("hub-user")
            .value_name("hub-user")
            .help("Set the username for accessing the Docker Hub, used when proxying Docker Hub images.
Must be used with --hub-token or --hub-token-file")
            .takes_value(true)
        )
        .arg(
            Arg::with_name("hub-token")
            .long("hub-token")
            .value_name("hub-token")
            .help("Set the token for accessing the Docker Hub, used when proxying Docker Hub images")
            .takes_value(true)
        )
        .arg(
            Arg::with_name("hub-token-file")
            .long("hub-token-file")
            .value_name("hub-token-file")
            .help("Location of file with token that can be used for accessing the Docker Hub, used when proxying Docker Hub images")
            .takes_value(true)
        )
        .arg(
            Arg::with_name("enable-cors")
                .long("enable-cors")
                .help("Enable Cross-Origin Resource Sharing(CORS) requests. Used to allow access from web apps (e.g. GUIs).")
        )
        .arg(
            Arg::with_name("max-manifest-size")
            .long("max-manifest-size")
            .value_name("max-manifest-size")
            .help("Maximum size in mebibytes of manifest file that can be uploaded. This is JSON metada, so usually relatively small.")
            .takes_value(true)
        )
        .arg(
            Arg::with_name("max-blob-size")
            .long("max-blob-size")
            .value_name("max-blob-size")
            .help("Maximum size in mebibytes of \"blob\" that can be uploaded (a single layer of an image). This can be very large in some images (GBs).")
            .takes_value(true)
        )
        .get_matches()
}
fn parse_args < ' a > ( ) -> ArgMatches < ' a > { clap :: App :: new ( PROGRAM_NAME ) . version ( " " ) . author ( " " ) . about ( PROGRAM_DESC ) . arg ( Arg :: with_name ( " " ) . long ( " " ) . value_name ( " " ) . help ( " " ) . takes_value ( true ) , ) . arg ( Arg :: with_name ( " " ) . long ( " " ) . value_name ( " " ) . help ( " " ) . takes_value ( true ) , ) . arg ( Arg :: with_name ( " " ) . long ( " " ) . help ( " " ) ) . arg ( Arg :: with_name ( " " ) . short ( " " ) . long ( " " ) . value_name ( " " ) . help ( & format ! ( " " DEFAULT_CERT_PATH ) ) . takes_value ( true ) , ) . arg ( Arg :: with_name ( " " ) . short ( " " ) . long ( " " ) . value_name ( " " ) . help ( & format ! ( " " DEFAULT_KEY_PATH ) ) . takes_value ( true ) , ) . arg ( Arg :: with_name ( " " ) . short ( " " ) . long ( " " ) . value_name ( " " ) . help ( " " ) . takes_value ( true ) , ) . arg ( Arg :: with_name ( " " ) . short ( " " ) . long ( " " ) . value_name ( " " ) . help ( " " ) . takes_value ( true ) , ) . arg ( Arg :: with_name ( " " ) . long ( " " ) . value_name ( " " ) . help ( " " ) . takes_value ( false ) , ) . arg ( Arg :: with_name ( " " ) . long ( " " ) . value_name ( " " ) . help ( " " ) . takes_value ( false ) ) . arg ( Arg :: with_name ( " " ) . long ( " " ) . value_name ( " " ) . help ( " " ) . takes_value ( false ) ) . arg ( Arg :: with_name ( " " ) . long ( " " ) . value_name ( " " ) . help ( " " ) . takes_value ( true ) ) . arg ( Arg :: with_name ( " " ) . long ( " " ) . value_name ( " " ) . help ( " " ) . takes_value ( true ) ) . arg ( Arg :: with_name ( " " ) . long ( " " ) . value_name ( " " ) . help ( " " ) . takes_value ( true ) ) . arg ( Arg :: with_name ( " " ) . long ( " " ) . value_name ( " " ) . help ( " " ) . takes_value ( true ) ) . arg ( Arg :: with_name ( " " ) . long ( " " ) . short ( " " ) . value_name ( " " ) . help ( " " ) . takes_value ( true ) ) . arg ( Arg :: with_name ( " " ) . long ( " " ) . short ( " " ) . value_name ( " " ) . help ( " " ) . takes_value ( true ) ) . arg ( Arg :: with_name ( " " ) . long ( " " ) . value_name ( " " ) . help ( " " ) . takes_value ( true ) ) . arg ( Arg :: with_name ( " " ) . long ( " " ) . short ( " " ) . value_name ( " " ) . help ( " " ) . takes_value ( false ) ) . arg ( Arg :: with_name ( " " ) . long ( " " ) . value_name ( " " ) . help ( " " ) . takes_value ( true ) ) . arg ( Arg :: with_name ( " " ) . long ( " " ) . value_name ( " " ) . help ( " " ) . takes_value ( false ) ) . arg ( Arg :: with_name ( " " ) . long ( " " ) . value_name ( " " ) . help ( " " ) . takes_value ( true ) ) . arg ( Arg :: with_name ( " " ) . long ( " " ) . value_name ( " " ) . help ( " " ) . takes_value ( true ) ) . arg ( Arg :: with_name ( " " ) . long ( " " ) . value_name ( " " ) . help ( " " ) . takes_value ( true ) ) . arg ( Arg :: with_name ( " " ) . long ( " " ) . help ( " " ) ) . arg ( Arg :: with_name ( " " ) . long ( " " ) . value_name ( " " ) . help ( " " ) . takes_value ( true ) ) . arg ( Arg :: with_name ( " " ) . long ( " " ) . value_name ( " " ) . help ( " \" \" " ) . takes_value ( true ) ) . get_matches ( ) }
Responsible for configuring and starting the Trow registry.
Responsible for configuring and starting the Trow registry .