Commit 388187bf authored by Rogers, David's avatar Rogers, David
Browse files

Merge branch 'link_upload' into 'main'

Moved download into podman and added action.sequence_rules

See merge request !1
parents 0aab68e3 4b868c56
Loading
Loading
Loading
Loading
+9 −1
Original line number Diff line number Diff line
from .container import Container
from .container_env import ContainerEnv
from .action import Return, Script, Shell, Upload, Download
from .action import (
    Action,
    Return,
    Script,
    Shell,
    Upload,
    Download,
    sequence_rules
)
+35 −16
Original line number Diff line number Diff line
@@ -7,7 +7,7 @@ from pydantic import BaseModel, Field

from .container import Container
from .container_env import ContainerEnv
from .podman import runcmd
import contaminate.podman as podman

class AReturn(BaseModel):
    action_type : Literal["return"] = "return"
@@ -31,25 +31,31 @@ class AShell(BaseModel):
        return c.run_shell(self.script)

class AUpload(BaseModel):
    """ Note: paths in Upload and Download
        must be strings, since docker uses ending '/'
        to denote moving inside a directory, as opposed to
        overwriting.
    """
    action_type : Literal["upload"] = "upload"
    src         : Path # local
    dst         : Path # remote
    src         : str # local
    dst         : str # remote
    extract     : bool = False # use ADD instead of COPY

    def __call__(self, c : Container) -> Container:
        cmd = f"COPY {self.src} {self.dst}"
        src = podman.quote(self.src)
        dst = podman.quote(self.dst)
        cmd = f'COPY ["{src}", "{dst}"]'
        if self.extract:
            cmd = f"ADD {self.src} {self.dst}"
            cmd = f'ADD ["{src}", "{dst}"]'
        return c.run_cmd(cmd)

class ADownload(BaseModel):
    action_type : Literal["download"] = "download"
    src         : Path # remote
    dst         : Path # local
    src         : str # remote
    dst         : str # local

    def __call__(self, c : Container) -> Container:
        runcmd("podman", "cp",
               f"{c.name}:{self.src}", self.dst)
        podman.download(c.name, self.src, self.dst)
        return c

ActionT = Annotated[
@@ -90,11 +96,24 @@ def Script(script : str) -> Action:
def Shell(script : str) -> Action:
    return Action(AShell(script = script))

def Upload(src : Union[str,Path], dst : Union[str,Path],
def Upload(src : str, dst : str,
           extract : bool = False) -> Action:
    return Action(AUpload(src=Path(src),
                          dst=Path(dst), extract=extract))

def Download(src : Union[str,Path], dst : Union[str,Path]
             ) -> Action:
    return Action(ADownload(src=Path(src), dst=Path(dst)))
    return Action(AUpload(src=src,
                          dst=dst, extract=extract))

def Download(src : str, dst : str) -> Action:
    return Action(ADownload(src=src, dst=dst))

# Run a sequence of rules, saving a json state ea. time.
def sequence_rules(rules : dict[str, Action], *steps : str) -> Container:
    C = None
    for s in steps:
        result = Path(s + ".json")
        if result.exists():
            C = Container.load(result)
        else:
            assert C is not None, f"Starting file '{result}' not present."
            C = C.run( rules[s], name = s )
            C.store(result)
    assert C is not None, "Empty rule set."
    return C
+6 −0
Original line number Diff line number Diff line
@@ -5,6 +5,9 @@ import os
import string
from pathlib import Path

def quote(s) -> str:
    return str(s).replace("\\", "\\\\").replace('"', '\"')

def to_oneliner(cmds):
    # process end-of-lines
    shell = ""
@@ -79,3 +82,6 @@ def build(name : str,
        if fname != "":
            os.remove(fname)
    return "\n".join(ans)

def download(name, src, dst):
    runcmd("podman", "cp", f"{c.name}:{self.src}", self.dst)