-
Notifications
You must be signed in to change notification settings - Fork 26
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Signed-off-by: vsoch <vsoch@users.noreply.github.com>
- Loading branch information
Showing
12 changed files
with
942 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
# Store | ||
|
||
A store is a place to keep content. Different kinds of stores might require different | ||
metadata, but should expose common api functions. | ||
|
||
## Common Functions | ||
|
||
## Filestore | ||
|
||
A Filestore is a store on the filesystem. Specifically it should have an understanding of: | ||
|
||
- **root**: a filesystem path that is the root of the store | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,177 @@ | ||
__author__ = "Vanessa Sochat" | ||
__copyright__ = "Copyright 2021, Vanessa Sochat" | ||
__license__ = "MIT" | ||
|
||
import oras.utils | ||
from oras.logger import logger | ||
import docker | ||
import sys | ||
|
||
from oras.content import File, FileStore | ||
|
||
store = FileStore() | ||
|
||
def main(args, parser, extra, subparser): | ||
|
||
print("COPY") | ||
import IPython | ||
IPython.embed() | ||
|
||
|
||
# get the fromStr; it might also have a ':' to add options | ||
from_parts = args.from_string.split(":") | ||
to_parts = args.to_string.split(":") | ||
|
||
# Copying from files | ||
if from_parts[0] == "files": | ||
|
||
# Extra files provided in extra (need to test) | ||
descs = load_files(extra) | ||
|
||
# parse the manifest config | ||
manifest_config_parts = args.manifest_config.split(":") | ||
manifest_config_media_type = "" | ||
|
||
# If length is 1, we only have this | ||
manifest_config_path = manifest_config_parts[0] | ||
|
||
# if length is two, we also have the config media type | ||
if len(manifest_config_parts) == 2: | ||
manifest_config_media_type = manifest_config_parts[1] | ||
|
||
# Read in the manifest config | ||
from_file = File() | ||
|
||
""" | ||
from_file.add("", manifest_config_media_type, manifest_config_path) | ||
configDesc, err := fromFile.Add("", manifestConfigMediaType, manifestConfigPath) | ||
if err != nil { | ||
return fmt.Errorf("unable to load manifest config: %v", err) | ||
} | ||
if _, err := fromFile.GenerateManifest(ref, &configDesc, descs...); err != nil { | ||
return fmt.Errorf("unable to generate root manifest: %s", err) | ||
} | ||
rootDesc, rootManifest, err := fromFile.Ref(ref) | ||
if err != nil { | ||
return err | ||
} | ||
log.Debugf("root manifest: %s %v %s", ref, rootDesc, rootManifest) | ||
from = fromFile | ||
elif from_parts[0] == "registry": | ||
from, err = content.NewRegistry(opts) | ||
if err != nil { | ||
return fmt.Errorf("could not create registry target: %v", err) | ||
} | ||
elif from_parts[0] == "oci": | ||
from, err = content.NewOCI(fromParts[1]) | ||
if err != nil { | ||
return fmt.Errorf("could not read OCI layout at %s: %v", fromParts[1], err) | ||
} | ||
else: | ||
return fmt.Errorf("unknown from argyment: %s", from) | ||
if to_parts[0] == "flies": | ||
to = content.NewFile(toParts[1]) | ||
elif to_parts[0] == "registry": | ||
to, err = content.NewRegistry(opts) | ||
if err != nil { | ||
return fmt.Errorf("could not create registry target: %v", err) | ||
} | ||
elif to_parts[0] == 'oci': | ||
to, err = content.NewOCI(toParts[1]) | ||
if err != nil { | ||
return fmt.Errorf("could not read OCI layout at %s: %v", toParts[1], err) | ||
else: } | ||
return fmt.Errorf("unknown from argyment: %s", from) | ||
} | ||
if manifestConfig != "" && fromParts[0] != "files" { | ||
return fmt.Errorf("only specify --manifest-config when using --from files") | ||
} | ||
return runCopy(ref, from, to) | ||
}, | ||
} | ||
client = docker.DockerClient(tls=not args.insecure) | ||
password = args.password | ||
username = args.username | ||
# Read password from stdin | ||
if args.password_stdin: | ||
password = readline() | ||
# No password provided | ||
elif not password: | ||
# No username, try to get from stdin | ||
if not username: | ||
username = input("Username: ") | ||
# if we still don't have a username, we require a token | ||
if not username: | ||
prompt = "Token: " | ||
password = input("Token: ") | ||
if not password: | ||
logger.exit("token required") | ||
# If we do have a username, we just need a passowrd | ||
else: | ||
password = input("Password: ") | ||
if not password: | ||
logger.exit("password required") | ||
else: | ||
logger.warning( | ||
"WARNING! Using --password via the CLI is insecure. Use --password-stdin." | ||
) | ||
# Login | ||
# https://docker-py.readthedocs.io/en/stable/client.html?highlight=login#docker.client.DockerClient.login | ||
result = client.login( | ||
username=username, password=password, registry=args.hostname, dockercfg_path=args.config | ||
) | ||
logger.info(result["Status"]) | ||
""" | ||
|
||
|
||
func runCopy(ref string, from, to target.Target) error { | ||
desc, err := oras.Copy(context.Background(), from, ref, to, "") | ||
if err != nil { | ||
fmt.Fprintf(os.Stderr, "error: %v", err) | ||
os.Exit(1) | ||
} | ||
fmt.Printf("%#v\n", desc) | ||
return nil | ||
} | ||
|
||
def load_files(files): | ||
""" | ||
Load files into the store and return a list of descriptors | ||
""" | ||
# Keep a list of descriptors | ||
descs = [] | ||
for file_ref in files: | ||
filename, media_type = oras.utils.parse_file_ref(file_ref) | ||
name = os.path.abspath(filename) | ||
descs.append(store.add(name, media_type, filename)) | ||
|
||
return descs |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
__author__ = "Vanessa Sochat" | ||
__copyright__ = "Copyright 2021, Vanessa Sochat" | ||
__license__ = "MPL 2.0" | ||
|
||
|
||
def main(args, parser, extra, subparser): | ||
|
||
from shpc.main import get_client | ||
|
||
if args.install_recipe.startswith("gh://"): | ||
args.container_tech = "singularity-deploy" | ||
|
||
cli = get_client( | ||
quiet=args.quiet, | ||
settings_file=args.settings_file, | ||
module=args.module, | ||
container_tech=args.container_tech, | ||
) | ||
cli.install(args.install_recipe) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
__author__ = "Vanessa Sochat" | ||
__copyright__ = "Copyright 2021, Vanessa Sochat" | ||
__license__ = "MIT" | ||
|
||
import oras.defaults as defaults | ||
from oras.logger import logger | ||
from oras.main.config import AuthConfig | ||
import os | ||
import sys | ||
|
||
def resolve_hostname(hostname): | ||
""" | ||
Return the docker index server given an alias, otherwise return hostname as is | ||
""" | ||
if hostname in [defaults.registry.index_hostname, defaults.registry.index_name, defaults.registry.default_v2_registry['host']]: | ||
return defaults.registry.index_server | ||
return hostname | ||
|
||
def main(args, parser, extra, subparser): | ||
|
||
hostname = resolve_hostname(args.hostname) | ||
|
||
config = None | ||
for path in [os.path.expanduser("~/.docker/config.json"), os.path.expanduser("~/.dockercfg")]: | ||
if os.path.exists(path): | ||
config = path | ||
break | ||
|
||
# A user specified config over-rides default | ||
# This will exit with clear message if the config does not exist | ||
config = AuthConfig(args.config or config) | ||
config.logout(hostname) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
__author__ = "Vanessa Sochat" | ||
__copyright__ = "Copyright 2021, Vanessa Sochat" | ||
__license__ = "MPL 2.0" | ||
|
||
import shpc.main.container as container | ||
from shpc.logger import logger | ||
import re | ||
|
||
|
||
def main(args, parser, extra, subparser): | ||
|
||
# We currently support GitHub and Docker URIs | ||
if not re.search("^(gh|docker)", args.uri): | ||
logger.exit("unique resource identifier %s is not recognized." % args.uri) | ||
|
||
client = container.SingularityContainer() | ||
client.pull(args.uri, args.path) |
Oops, something went wrong.