Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 8 additions & 2 deletions docs/ramalama-login.1.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,17 @@
ramalama\-login - login to remote registry

## SYNOPSIS
**ramalama login** [*options*]
**ramalama login** [*options*] [*registry*]

## DESCRIPTION
login to remote registry

## OPTIONS
Options are specific to registry types.

#### **--authfile**=*password*
path of the authentication file for OCI registries

#### **--help**, **-h**
show this help message and exit

Expand All @@ -21,7 +24,10 @@ password for registry
#### **--password-stdin**
take the password from stdin

#### **--token**
#### **--tls-verify**=*true*
require HTTPS and verify certificates when contacting OCI registries

#### **--token**=*token*
token to be passed to Model registry

#### **--username**, **-u**=*username*
Expand Down
20 changes: 15 additions & 5 deletions ramalama/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -150,22 +150,32 @@ def init_cli():
def login_parser(subparsers):
parser = subparsers.add_parser("login", help="login to remote registry")
# Do not run in a container
parser.add_argument("--authfile", help="path of the authentication file")
parser.add_argument("--container", default=False, action="store_false", help=argparse.SUPPRESS)
parser.add_argument("-p", "--password", dest="password", help="password for registry")
parser.add_argument(
"--password-stdin", dest="passwordstdin", action="store_true", help="take the password for registry from stdin"
)
parser.add_argument(
"--tls-verify",
dest="tlsverify",
default=True,
help="require HTTPS and verify certificates when contacting registries",
)
parser.add_argument("--token", dest="token", help="token for registry")
parser.add_argument("-u", "--username", dest="username", help="username for registry")
parser.add_argument("TRANSPORT", nargs="?", type=str, default="") # positional argument
parser.add_argument(
"REGISTRY", nargs="?", type=str, default="OCI Registry where AI models are stored"
) # positional argument
parser.set_defaults(func=login_cli)


def login_cli(args):
transport = args.TRANSPORT
if transport != "":
transport = os.getenv("RAMALAMA_TRANSPORT") + "://"
model = New(str(transport), args)
registry = args.REGISTRY
if registry != "":
registry = "oci://" + registry

model = New(str(registry), args)
return model.login(args)


Expand Down
23 changes: 15 additions & 8 deletions ramalama/oci.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,12 @@
from ramalama.model import Model
from ramalama.common import run_cmd, exec_cmd, perror, available

prefix = "oci://"


class OCI(Model):
def __init__(self, model, conman):
super().__init__(model.removeprefix("oci://").removeprefix("docker://"))
super().__init__(model.removeprefix(prefix).removeprefix("docker://"))
self.type = "OCI"
self.conman = conman
if available("omlmd"):
Expand All @@ -19,22 +21,27 @@ def __init__(self, model, conman):
self.omlmd = f"{i}/../../../bin/omlmd"
if os.path.exists(self.omlmd):
break
raise """\
raise NotImplementedError("""\
OCI models requires the omlmd module.
This module can be installed via PyPi tools like pip, pip3, pipx or via
distribution package managers like dnf or apt. Example:
pip install omlmd
"""
""")

def login(self, args):
conman_args = [self.conman, "login"]
if str(args.tlsverify).lower() == "false":
conman_args.extend([f"--tls-verify={args.tlsverify}"])
if args.authfile:
conman_args.extend([f"--authfile={args.authfile}"])
if args.username:
conman_args.extend(["--username", args.username])
conman_args.extend([f"--username={args.username}"])
if args.password:
conman_args.extend(["--password", args.password])
conman_args.extend([f"--password={args.password}"])
if args.passwordstdin:
conman_args.append("--password-stdin")
conman_args.append(args.TRANSPORT)
conman_args.append(args.REGISTRY.removeprefix(prefix))
print(" ".join(conman_args))
return exec_cmd(conman_args)

def logout(self, args):
Expand Down Expand Up @@ -77,8 +84,8 @@ def _build(self, source, target, args):
run_cmd([self.conman, "build", "-t", target, "-f", containerfile.name, contextdir], stdout=None)

def push(self, source, args):
target = self.model.removeprefix("oci://")
source = source.removeprefix("oci://")
target = self.model.removeprefix(prefix)
source = source.removeprefix(prefix)
if source != target:
try:
self._build(source, target, args)
Expand Down
17 changes: 17 additions & 0 deletions test/system/050-pull.bats
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
#!/usr/bin/env bats

load helpers
load helpers.registry
load setup_suite

# bats test_tags=distro-integration
@test "ramalama pull no model" {
Expand Down Expand Up @@ -54,4 +56,19 @@ load helpers
run_ramalama rm oci://quay.io/mmortari/gguf-py-example:v1
}

@test "ramalama use registry" {
skip_if_darwin
skip_if_docker
local registry=localhost:${PODMAN_LOGIN_REGISTRY_PORT}
local authfile=$RAMALAMA_TMPDIR/authfile.json

start_registry
run_ramalama login --authfile=$authfile \
--tls-verify=false \
--username ${PODMAN_LOGIN_USER} \
--password ${PODMAN_LOGIN_PASS} \
oci://$registry
stop_registry
}

# vim: filetype=sh
Loading