Commit 3f1c5abc authored by Duggan, John's avatar Duggan, John
Browse files

Add code-server to GUI, Bastion SSH proxy still isn't working yet :(

parent 132f8aa0
Loading
Loading
Loading
Loading
Loading
+477 −274

File changed.

Preview size limit exceeded, changes collapsed.

+1 −0
Original line number Diff line number Diff line
@@ -17,6 +17,7 @@ default = {features = ["dev"], solve-group = "default"}
production = {features = [], solve-group = "default"}

[tool.pixi.dependencies]
code-server = "*"

[tool.pixi.pypi-dependencies]
ips-fastran-gui = { path = ".", editable = true }
+1 −1
Original line number Diff line number Diff line
@@ -54,7 +54,7 @@ class Config(BaseModel):
    )

    # SSH Proxy filesystem parameters
    proxy_command: str = Field(default="", title="SSH Proxy Command")
    username: str = Field(default="", title="NERSC Username")
    sshproxy_key: str = Field(
        default="",
        title="NERSC sshproxy Key",
+6 −7
Original line number Diff line number Diff line
@@ -7,7 +7,7 @@ from typing import Any, Dict, List

from authlib.jose import JsonWebKey
from fsspec import filesystem
from paramiko import ProxyCommand, RSAKey
from paramiko import RSAKey
from sfapi_client import Client
from sfapi_client.compute import Machine
from sfapi_client.jobs import JobState
@@ -31,12 +31,12 @@ class SuperfacilityTool:
            self.model.resource_params.client_id, JsonWebKey.import_key(self.model.resource_params.private_key)
        )
        self.file_tree: Dict[str, Any] = {}
        self.perlmutter = self.client.compute(Machine.perlmutter)
        self.user = self.client.user()
        self.perlmutter: Any = None
        self.user: Any = None
        self.job: Any = None

        self.output_directory = ".results"
        self.working_directory = os.path.join("/global/u2", self.user.name[0], self.user.name)
        self.working_directory = os.path.join("/global/u2", self.model.config.username, self.model.config.username)

    def cancel(self) -> None:
        if not self.job:
@@ -58,7 +58,6 @@ class SuperfacilityTool:
            return

        self.job.update()
        print(f"Job state refreshed: {self.job.state}")

        match self.job.state:
            case JobState.RUNNING:
@@ -95,8 +94,7 @@ class SuperfacilityTool:
            "ssh",
            host="dtn.nersc.gov",
            pkey=RSAKey.from_private_key(StringIO(self.model.config.sshproxy_key)),
            sock=ProxyCommand(self.model.config.proxy_command) if self.model.config.proxy_command else None,
            username=self.user.name,
            username=self.model.config.username,
        )

        self.file_tree = {}
@@ -140,6 +138,7 @@ class SuperfacilityTool:
            self.model.execution.stderr = self.read_file("ips.err")

    def run(self, *args: Any, **kwargs: Any) -> None:
        self.perlmutter = self.client.compute(Machine.perlmutter)
        hours, minutes = divmod(self.model.resource_params.time_limit, 60)

        self.copy_input_files(self.model.config.input_files)
+0 −37
Original line number Diff line number Diff line
@@ -24,8 +24,6 @@ class ViewState(BaseModel):
    errors: List[str] = Field(default=[])
    results_disabled: bool = Field(default=False)
    input_file_path: str = Field(default=os.getenv("HOME", os.getcwd()), title="Path to Input Files")
    editor_content: str = Field(default="")
    editor_path: str = Field(default="")
    updating: bool = Field(default=False)


@@ -68,30 +66,6 @@ class MainViewModel:
        self.config_bind.update_in_view(self.model.config)
        self.plot_json_bind.update_in_view(self.model.plot_json.model_dump_json(indent=2))

    def on_change_file(self, json_data: str) -> None:
        # Monaco fires input events with internal data that need to be ignored.
        if "_vts" in json_data:
            return

        self.view_state.errors = []
        try:
            self.view_state.editor_content = json_data
            self.model.set_file_contents(
                self.view_state.editor_path,
                os.path.relpath(self.view_state.editor_path, self.view_state.input_file_path),
                json_data,
            )
        except ValidationError as e:
            for error in e.errors():
                msg = ""
                if error["loc"]:
                    msg += f"{error['loc'][0]}: "
                msg += error["msg"]

                self.view_state.errors.append(msg)

        self.view_state_bind.update_in_view(self.view_state)

    def on_change_config(self, results: Dict[str, Any]) -> None:
        if results["updated"]:
            # You can take actions in Python when specific fields are changed here.
@@ -133,17 +107,6 @@ class MainViewModel:
            self.view_state.active_tab = "3"
            self.view_state_bind.update_in_view(self.view_state)

    def edit_file(self, path: List[str]) -> None:
        if not path:
            return

        file = self.model.get_file_from_path(path[0])

        self.view_state.editor_content = file["content"]
        self.view_state.editor_path = file["path"]

        self.view_state_bind.update_in_view(self.view_state)

    def _connect(self, *args: Any, **kwargs: Any) -> None:
        self.ips_fastran.prepare_tool()

Loading