Skip to content

Application

penvm.app.boot

Boot support for PENVM world/network.

Booter

Provides PENVM network boot support from configuration file.

Source code in penvm/src/app/penvm/app/boot.py
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
class Booter:
    """Provides PENVM network boot support from configuration file."""

    def __init__(
        self,
        configfilename: str,
        networkname: str,
        release: str,
    ):
        """Initialize.

        Args:
            configfilename: Configuration file name.
            networkname: Network name.
            release: PENVM release.
        """
        self.configfilename = configfilename
        self.networkname = networkname
        self.release = release

        self.world = None
        self.network = None
        self.env = None

    def boot(self):
        """Boot."""
        try:
            self.world = World(filename=self.configfilename)
            self.network = self.world.get_network(self.networkname)
            # print(f"{self.networkname=}")
            if self.network == None or self.network.get_targets() in [None, []]:
                raise Exception(f"network ({self.networkname}) not found")
            self.network.boot()

            machines = self.network.get_machines()
            if machines in [None, []]:
                raise Exception("no machines")
            if None in machines:
                raise Exception("not all machines found")

            self.release = self.release or self.world.get_meta("release") or get_version_string()
            if self.release == None:
                raise Exception(f"could not determine release value")

            releasepath = os.path.expanduser(f"~/.penvm/releases/{self.release}")
            releaselibs = ":".join([f"{releasepath}/{name}" for name in ["penvmlib-client"]])

            # patch env
            self.env = os.environ.copy()
            PENVM_AUTO_NETWORK = str(self.network)
            PYTHONPATH = self.env.get("PYTHONPATH")
            if PYTHONPATH != None:
                PYTHONPATH = f"{releaselibs}:{PYTHONPATH}"
            else:
                PYTHONPATH = releaselibs

            self.env["PENVM_AUTO_NETWORK"] = PENVM_AUTO_NETWORK
            self.env["PENVM_RELEASE"] = self.release
            self.env["PYTHONPATH"] = PYTHONPATH
        except Exception as e:
            raise
        finally:
            pass

    def shell(
        self,
        path: str,
    ):
        """Start shell with environment."""
        try:
            try:
                sp = subprocess.Popen(
                    [path],
                    pass_fds=[0, 1, 2],
                    env=self.env,
                )
            except Exception as e:
                raise Exception(f"failed to start shell ({path})")

            try:
                # close streams
                sys.stdin.close()
                sys.stdout.close()
                sys.stderr.close()

                # close fds
                os.close(0)
                os.close(1)
                os.close(2)
            except Exception as e:
                raise Exception("failed to close streams/fds")

            os.waitpid(sp.pid, 0)
        except Exception as e:
            raise

    def wait(self, secs: int = 1000000):
        """Wait indefinitely."""
        time.sleep(secs)

__init__(configfilename, networkname, release)

Initialize.

Parameters:

Name Type Description Default
configfilename str

Configuration file name.

required
networkname str

Network name.

required
release str

PENVM release.

required
Source code in penvm/src/app/penvm/app/boot.py
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
def __init__(
    self,
    configfilename: str,
    networkname: str,
    release: str,
):
    """Initialize.

    Args:
        configfilename: Configuration file name.
        networkname: Network name.
        release: PENVM release.
    """
    self.configfilename = configfilename
    self.networkname = networkname
    self.release = release

    self.world = None
    self.network = None
    self.env = None

boot()

Boot.

Source code in penvm/src/app/penvm/app/boot.py
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
def boot(self):
    """Boot."""
    try:
        self.world = World(filename=self.configfilename)
        self.network = self.world.get_network(self.networkname)
        # print(f"{self.networkname=}")
        if self.network == None or self.network.get_targets() in [None, []]:
            raise Exception(f"network ({self.networkname}) not found")
        self.network.boot()

        machines = self.network.get_machines()
        if machines in [None, []]:
            raise Exception("no machines")
        if None in machines:
            raise Exception("not all machines found")

        self.release = self.release or self.world.get_meta("release") or get_version_string()
        if self.release == None:
            raise Exception(f"could not determine release value")

        releasepath = os.path.expanduser(f"~/.penvm/releases/{self.release}")
        releaselibs = ":".join([f"{releasepath}/{name}" for name in ["penvmlib-client"]])

        # patch env
        self.env = os.environ.copy()
        PENVM_AUTO_NETWORK = str(self.network)
        PYTHONPATH = self.env.get("PYTHONPATH")
        if PYTHONPATH != None:
            PYTHONPATH = f"{releaselibs}:{PYTHONPATH}"
        else:
            PYTHONPATH = releaselibs

        self.env["PENVM_AUTO_NETWORK"] = PENVM_AUTO_NETWORK
        self.env["PENVM_RELEASE"] = self.release
        self.env["PYTHONPATH"] = PYTHONPATH
    except Exception as e:
        raise
    finally:
        pass

shell(path)

Start shell with environment.

Source code in penvm/src/app/penvm/app/boot.py
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
def shell(
    self,
    path: str,
):
    """Start shell with environment."""
    try:
        try:
            sp = subprocess.Popen(
                [path],
                pass_fds=[0, 1, 2],
                env=self.env,
            )
        except Exception as e:
            raise Exception(f"failed to start shell ({path})")

        try:
            # close streams
            sys.stdin.close()
            sys.stdout.close()
            sys.stderr.close()

            # close fds
            os.close(0)
            os.close(1)
            os.close(2)
        except Exception as e:
            raise Exception("failed to close streams/fds")

        os.waitpid(sp.pid, 0)
    except Exception as e:
        raise

wait(secs=1000000)

Wait indefinitely.

Source code in penvm/src/app/penvm/app/boot.py
130
131
132
def wait(self, secs: int = 1000000):
    """Wait indefinitely."""
    time.sleep(secs)
You are on penvm.dev