rtems-proxy 0.6.0__tar.gz → 0.6.2__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (48) hide show
  1. {rtems_proxy-0.6.0 → rtems_proxy-0.6.2}/PKG-INFO +1 -1
  2. {rtems_proxy-0.6.0 → rtems_proxy-0.6.2}/src/rtems_proxy/__main__.py +13 -5
  3. {rtems_proxy-0.6.0 → rtems_proxy-0.6.2}/src/rtems_proxy/_version.py +2 -2
  4. rtems_proxy-0.6.2/src/rtems_proxy/copy.py +56 -0
  5. {rtems_proxy-0.6.0 → rtems_proxy-0.6.2}/src/rtems_proxy/rsync.sh.jinja +10 -2
  6. {rtems_proxy-0.6.0 → rtems_proxy-0.6.2}/src/rtems_proxy/telnet.py +21 -18
  7. {rtems_proxy-0.6.0 → rtems_proxy-0.6.2}/src/rtems_proxy.egg-info/PKG-INFO +1 -1
  8. rtems_proxy-0.6.0/src/rtems_proxy/copy.py +0 -56
  9. {rtems_proxy-0.6.0 → rtems_proxy-0.6.2}/.copier-answers.yml +0 -0
  10. {rtems_proxy-0.6.0 → rtems_proxy-0.6.2}/.devcontainer/devcontainer.json +0 -0
  11. {rtems_proxy-0.6.0 → rtems_proxy-0.6.2}/.github/CONTRIBUTING.md +0 -0
  12. {rtems_proxy-0.6.0 → rtems_proxy-0.6.2}/.github/ISSUE_TEMPLATE/bug_report.md +0 -0
  13. {rtems_proxy-0.6.0 → rtems_proxy-0.6.2}/.github/ISSUE_TEMPLATE/issue.md +0 -0
  14. {rtems_proxy-0.6.0 → rtems_proxy-0.6.2}/.github/PULL_REQUEST_TEMPLATE/pull_request_template.md +0 -0
  15. {rtems_proxy-0.6.0 → rtems_proxy-0.6.2}/.github/actions/install_requirements/action.yml +0 -0
  16. {rtems_proxy-0.6.0 → rtems_proxy-0.6.2}/.github/dependabot.yml +0 -0
  17. {rtems_proxy-0.6.0 → rtems_proxy-0.6.2}/.github/pages/index.html +0 -0
  18. {rtems_proxy-0.6.0 → rtems_proxy-0.6.2}/.github/pages/make_switcher.py +0 -0
  19. {rtems_proxy-0.6.0 → rtems_proxy-0.6.2}/.github/workflows/_check.yml +0 -0
  20. {rtems_proxy-0.6.0 → rtems_proxy-0.6.2}/.github/workflows/_dist.yml +0 -0
  21. {rtems_proxy-0.6.0 → rtems_proxy-0.6.2}/.github/workflows/_pypi.yml +0 -0
  22. {rtems_proxy-0.6.0 → rtems_proxy-0.6.2}/.github/workflows/_release.yml +0 -0
  23. {rtems_proxy-0.6.0 → rtems_proxy-0.6.2}/.github/workflows/_test.yml +0 -0
  24. {rtems_proxy-0.6.0 → rtems_proxy-0.6.2}/.github/workflows/_tox.yml +0 -0
  25. {rtems_proxy-0.6.0 → rtems_proxy-0.6.2}/.github/workflows/ci.yml +0 -0
  26. {rtems_proxy-0.6.0 → rtems_proxy-0.6.2}/.gitignore +0 -0
  27. {rtems_proxy-0.6.0 → rtems_proxy-0.6.2}/.pre-commit-config.yaml +0 -0
  28. {rtems_proxy-0.6.0 → rtems_proxy-0.6.2}/.vscode/extensions.json +0 -0
  29. {rtems_proxy-0.6.0 → rtems_proxy-0.6.2}/.vscode/launch.json +0 -0
  30. {rtems_proxy-0.6.0 → rtems_proxy-0.6.2}/.vscode/settings.json +0 -0
  31. {rtems_proxy-0.6.0 → rtems_proxy-0.6.2}/.vscode/tasks.json +0 -0
  32. {rtems_proxy-0.6.0 → rtems_proxy-0.6.2}/Dockerfile +0 -0
  33. {rtems_proxy-0.6.0 → rtems_proxy-0.6.2}/LICENSE +0 -0
  34. {rtems_proxy-0.6.0 → rtems_proxy-0.6.2}/README.md +0 -0
  35. {rtems_proxy-0.6.0 → rtems_proxy-0.6.2}/proxy-start.sh +0 -0
  36. {rtems_proxy-0.6.0 → rtems_proxy-0.6.2}/pyproject.toml +0 -0
  37. {rtems_proxy-0.6.0 → rtems_proxy-0.6.2}/requirements.txt +0 -0
  38. {rtems_proxy-0.6.0 → rtems_proxy-0.6.2}/setup.cfg +0 -0
  39. {rtems_proxy-0.6.0 → rtems_proxy-0.6.2}/src/rtems_proxy/__init__.py +0 -0
  40. {rtems_proxy-0.6.0 → rtems_proxy-0.6.2}/src/rtems_proxy/globals.py +0 -0
  41. {rtems_proxy-0.6.0 → rtems_proxy-0.6.2}/src/rtems_proxy/utils.py +0 -0
  42. {rtems_proxy-0.6.0 → rtems_proxy-0.6.2}/src/rtems_proxy.egg-info/SOURCES.txt +0 -0
  43. {rtems_proxy-0.6.0 → rtems_proxy-0.6.2}/src/rtems_proxy.egg-info/dependency_links.txt +0 -0
  44. {rtems_proxy-0.6.0 → rtems_proxy-0.6.2}/src/rtems_proxy.egg-info/entry_points.txt +0 -0
  45. {rtems_proxy-0.6.0 → rtems_proxy-0.6.2}/src/rtems_proxy.egg-info/requires.txt +0 -0
  46. {rtems_proxy-0.6.0 → rtems_proxy-0.6.2}/src/rtems_proxy.egg-info/top_level.txt +0 -0
  47. {rtems_proxy-0.6.0 → rtems_proxy-0.6.2}/tests/conftest.py +0 -0
  48. {rtems_proxy-0.6.0 → rtems_proxy-0.6.2}/tests/test_cli.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: rtems-proxy
3
- Version: 0.6.0
3
+ Version: 0.6.2
4
4
  Summary: Support for a K8S proxy container in controlling and monitoring RTEMS EPICS IOCs
5
5
  Author-email: Giles Knap <giles.knap@diamond.ac.uk>
6
6
  License: Apache License
@@ -7,7 +7,7 @@ from ruamel.yaml import YAML
7
7
  from . import __version__
8
8
  from .copy import copy_rtems
9
9
  from .globals import GLOBALS
10
- from .telnet import ioc_connect
10
+ from .telnet import ioc_connect, report
11
11
 
12
12
  __all__ = ["main"]
13
13
 
@@ -40,6 +40,9 @@ def start(
40
40
  copy: bool = typer.Option(
41
41
  True, "--copy/--no-copy", help="copy binaries before connecting"
42
42
  ),
43
+ connect: bool = typer.Option(
44
+ True, "--connect/--no-connect", help="connect to the IOC console"
45
+ ),
43
46
  reboot: bool = typer.Option(
44
47
  True, "--reboot/--no-reboot", help="reboot the IOC first"
45
48
  ),
@@ -55,16 +58,21 @@ def start(
55
58
  it detects that EPICS_HOST_ARCH==RTEMS-beatnik
56
59
 
57
60
  args:
58
- copy: Copy the RTEMS binaries to the IOCs TFTP and NFS directories first
59
- reboot: Reboot the IOC once the binaries are copied and the connection is made
61
+ copy: Copy the RTEMS binaries to the IOCs TFTP and NFS directories first
62
+ connect: Connect to the IOC console after rebooting
63
+ reboot: Reboot the IOC once the binaries are copied and the connection is
64
+ made. Ignored if connect is False.
60
65
  """
61
- print(
66
+ report(
62
67
  f"Remote control startup of RTEMS IOC {GLOBALS.IOC_NAME}"
63
68
  f" at {GLOBALS.RTEMS_IOC_IP}"
64
69
  )
65
70
  if copy:
66
71
  copy_rtems()
67
- ioc_connect(GLOBALS.RTEMS_CONSOLE, reboot=reboot)
72
+ if connect:
73
+ ioc_connect(GLOBALS.RTEMS_CONSOLE, reboot=reboot)
74
+ else:
75
+ report("IOC console connection disabled. ")
68
76
 
69
77
 
70
78
  @cli.command()
@@ -12,5 +12,5 @@ __version__: str
12
12
  __version_tuple__: VERSION_TUPLE
13
13
  version_tuple: VERSION_TUPLE
14
14
 
15
- __version__ = version = '0.6.0'
16
- __version_tuple__ = version_tuple = (0, 6, 0)
15
+ __version__ = version = '0.6.2'
16
+ __version_tuple__ = version_tuple = (0, 6, 2)
@@ -0,0 +1,56 @@
1
+ """
2
+ functions for moving IOC assets into position for a remote IOC to access
3
+ """
4
+
5
+ import re
6
+ import shutil
7
+ from pathlib import Path
8
+
9
+ from .globals import GLOBALS
10
+
11
+
12
+ def copy_rtems():
13
+ """
14
+ Copy RTEMS binaries to a location where the RTEMS IOC can access them
15
+
16
+ IMPORTANT: local_root and nfs_root are different perspectives on the same
17
+ folder.
18
+ local_root: where the IOC files will be placed from the
19
+ perspective of this IOC proxy service. This IOC proxy will
20
+ populate the folder for use by the RTEMS crate.
21
+ nfs_root: where the IOC files will be found from the perspective of a
22
+ a client to the nfsv2-tftp service. i.e. where the RTEMS crate
23
+ will look for them using NFS.
24
+ """
25
+ local_root = GLOBALS.RTEMS_TFTP_PATH
26
+ nfs_root = Path("/iocs") / GLOBALS.IOC_NAME
27
+
28
+ # where to copy the Generic IOC folder to. This will contain the IOC binary
29
+ # and the files
30
+ dest_ioc = local_root / "ioc"
31
+ # where to copy the generated runtime assets to. This will contain
32
+ # st.cmd and ioc.db
33
+ dest_runtime = local_root / "runtime"
34
+
35
+ # TODO - perhaps do protocol files in this fashion for linux IOCs too,
36
+ # in which case this needs to go somewhere generic
37
+ protocol_folder = GLOBALS.RUNTIME / "protocol"
38
+ protocol_folder.mkdir(parents=True, exist_ok=True)
39
+ protocol_files = GLOBALS.SUPPORT.glob("**/*.proto*")
40
+ for proto_file in protocol_files:
41
+ dest = protocol_folder / proto_file.name
42
+ shutil.copy(proto_file, dest)
43
+
44
+ # copy all the files needed for runtime into the PVC that is being shared
45
+ # over nfs/tftp by the nfsv2-tftp service
46
+ for folder in ["bin", "dbd"]:
47
+ shutil.copytree(
48
+ GLOBALS.IOC.readlink() / folder, dest_ioc / folder, dirs_exist_ok=True
49
+ )
50
+ shutil.copytree(GLOBALS.RUNTIME, dest_runtime, dirs_exist_ok=True)
51
+
52
+ # because we moved the ioc files we need to fix up startup script paths
53
+ startup = dest_runtime / "st.cmd"
54
+ cmd_txt = startup.read_text()
55
+ cmd_txt = re.sub("/epics/", f"{str(nfs_root)}/", cmd_txt)
56
+ startup.write_text(cmd_txt)
@@ -43,8 +43,16 @@ echo "
43
43
 
44
44
  while true; do
45
45
  inotifywait -e modify,create,delete,move -r $RTEMS_TFTP_PATH
46
- rsync -rt --delete /$RTEMS_TFTP_PATH/ \
47
- "rsync://$RTEMS_TFTP_IP:12002/files/$IOC_NAME/"
46
+ echo 'rsyncing files to server'
47
+ date
48
+ for i in 1 2 3 ; do
49
+ # repeat because inotify fires on the first change of several
50
+ # don't copy the huge ioc binary file with symbols
51
+ rsync -rim --exclude bin/RTEMS-beatnik/ioc --delete /$RTEMS_TFTP_PATH/ \
52
+ "rsync://$RTEMS_TFTP_IP:12002/files/$IOC_NAME/"
53
+ sleep 1
54
+ done
55
+ echo 'rsync complete'
48
56
  done
49
57
  " > /tmp/rsync-background.sh
50
58
  chmod +x /tmp/rsync-background.sh
@@ -48,18 +48,12 @@ class TelnetRTEMS:
48
48
  signal.signal(signal.SIGINT, self.terminate)
49
49
  signal.signal(signal.SIGTERM, self.terminate)
50
50
 
51
- def report(self, message):
52
- """
53
- print a message that is noticeable amongst all the other output
54
- """
55
- print(f"\n>>>> {message} <<<<\n")
56
-
57
51
  def terminate(self, signum, frame):
58
52
  """
59
53
  Allow the user to terminate the connection with ctrl-c while the
60
54
  pexpect child is running (but not once interactive telnet is started)
61
55
  """
62
- self.report("Terminating")
56
+ report("Terminating")
63
57
  exit(0)
64
58
 
65
59
  def connect(self):
@@ -83,7 +77,7 @@ class TelnetRTEMS:
83
77
  # if we timeout looking for failed connection that is good
84
78
  pass
85
79
  else:
86
- print(">> Cannot connect to remote IOC, connection in use? <<")
80
+ report("Cannot connect to remote IOC, connection in use?")
87
81
  raise CannotConnect
88
82
 
89
83
  def check_prompt(self, retries=5) -> RtemsState:
@@ -108,16 +102,16 @@ class TelnetRTEMS:
108
102
  # current state unknown. wait and retry
109
103
  sleep(15)
110
104
  else:
111
- self.report("Currently in bootloader")
105
+ report("Currently in bootloader")
112
106
  return RtemsState.MOT
113
107
  else:
114
- self.report("Currently in IOC shell")
108
+ report("Currently in IOC shell")
115
109
  return RtemsState.IOC
116
110
 
117
- self.report("Retrying get current status")
111
+ report("Retrying get current status")
118
112
  retries -= 1
119
113
 
120
- self.report("Current state UNKNOWN")
114
+ report("Current state UNKNOWN")
121
115
  raise CannotConnect("Current state of remote IOC unknown")
122
116
 
123
117
  def reboot(self, into: RtemsState):
@@ -127,7 +121,7 @@ class TelnetRTEMS:
127
121
  """
128
122
  assert self._child, "must call connect before reboot"
129
123
 
130
- self.report(f"Rebooting into {into.name}")
124
+ report(f"Rebooting into {into.name}")
131
125
  current_state = self.check_prompt()
132
126
  if current_state == RtemsState.MOT:
133
127
  self._child.sendline("reset")
@@ -162,8 +156,6 @@ class TelnetRTEMS:
162
156
  self.reboot(RtemsState.IOC)
163
157
  self._child.expect(self.IOC_STARTED, timeout=50)
164
158
 
165
- self.report("press enter for IOC shell prompt")
166
-
167
159
  def get_boot_prompt(self):
168
160
  """
169
161
  Get to the bootloader prompt, if the IOC shell is running then exit
@@ -177,7 +169,7 @@ class TelnetRTEMS:
177
169
  self.reboot(RtemsState.MOT)
178
170
  self._child.expect(self.MOT_PROMPT, timeout=20)
179
171
 
180
- self.report("press enter for bootloader prompt")
172
+ report("press enter for bootloader prompt")
181
173
 
182
174
  def close(self):
183
175
  if self._child:
@@ -188,6 +180,13 @@ class TelnetRTEMS:
188
180
  self.close()
189
181
 
190
182
 
183
+ def report(message):
184
+ """
185
+ print a message that is noticeable amongst all the other output
186
+ """
187
+ print(f"\n>>>> {message} <<<<\n")
188
+
189
+
191
190
  def ioc_connect(host_and_port: str, reboot: bool = False):
192
191
  """
193
192
  Entrypoint to make a connection to an RTEMS IOC over telnet.
@@ -201,10 +200,14 @@ def ioc_connect(host_and_port: str, reboot: bool = False):
201
200
 
202
201
  try:
203
202
  telnet.connect()
204
- telnet.get_epics_prompt()
203
+ if reboot:
204
+ telnet.get_epics_prompt()
205
+ else:
206
+ report("Auto reboot disabled. Skipping reboot")
205
207
  except (CannotConnect, pexpect.exceptions.TIMEOUT):
206
- print("\n\nNot Connected. Exiting...")
208
+ report("Connection failed. Exiting")
207
209
  telnet.close()
208
210
  else:
209
211
  telnet.close()
212
+ report("Connecting to IOC console, hit enter for a prompt")
210
213
  run_command(telnet.command)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: rtems-proxy
3
- Version: 0.6.0
3
+ Version: 0.6.2
4
4
  Summary: Support for a K8S proxy container in controlling and monitoring RTEMS EPICS IOCs
5
5
  Author-email: Giles Knap <giles.knap@diamond.ac.uk>
6
6
  License: Apache License
@@ -1,56 +0,0 @@
1
- """
2
- functions for moving IOC assets into position for a remote IOC to access
3
- """
4
-
5
- import re
6
- import shutil
7
- from pathlib import Path
8
-
9
- from .globals import GLOBALS
10
-
11
-
12
- def copy_rtems():
13
- """
14
- Copy RTEMS binaries to a location where the RTEMS IOC can access them
15
- """
16
- # root of pvc mount into which we copy the IOC files for the RTEMS IOC to access
17
- root = GLOBALS.RTEMS_TFTP_PATH
18
- # root of the path that the RTEMS IOC expects to find the IOC files
19
- RTEMS_TFTP_PATH = Path("/iocs") / GLOBALS.IOC_NAME
20
- # where to copy the Generic IOC folder to (at present only holds the dbd folder)
21
- ioc_dest = root / "ioc"
22
- # where to copy the generated runtime assets to (st.cmd and ioc.db)
23
- dest_runtime = root / "runtime"
24
-
25
- # TODO - perhaps do this for linux IOCs too - in which case this needs
26
- # to go somewhere generic
27
- protocol_folder = GLOBALS.RUNTIME / "protocol"
28
- protocol_folder.mkdir(parents=True, exist_ok=True)
29
- protocol_files = GLOBALS.SUPPORT.glob("**/*.proto*")
30
- for proto_file in protocol_files:
31
- dest = protocol_folder / proto_file.name
32
- shutil.copy(proto_file, dest)
33
-
34
- # move all the files needed for runtime into the PVC that is being shared
35
- # over nfs/tftp by the nfsv2-tftp service
36
- ioc_src = GLOBALS.IOC.readlink()
37
- dbd_src = ioc_src / "dbd"
38
- dbd_dest = ioc_dest / "dbd"
39
- binary = Path("bin/RTEMS-beatnik/ioc.boot")
40
- bin_rtems_src = ioc_src / binary
41
- bin_rtems_dest = ioc_dest / binary
42
- bin_rtems_dest.parent.mkdir(parents=True, exist_ok=True)
43
-
44
- shutil.copytree(dbd_src, dbd_dest, symlinks=True, dirs_exist_ok=True)
45
- shutil.copy(bin_rtems_src, bin_rtems_dest)
46
- shutil.copytree(GLOBALS.RUNTIME, dest_runtime, dirs_exist_ok=True)
47
-
48
- # because we moved the ioc files we need to fix up startup script paths
49
- startup = dest_runtime / "st.cmd"
50
- cmd_txt = startup.read_text()
51
- cmd_txt = re.sub("/epics/", f"{str(RTEMS_TFTP_PATH)}/", cmd_txt)
52
- # also fix up the protocol path to point to protocol_folder
53
- cmd_txt = (
54
- cmd_txt + f'\nepicsEnvSet("STREAM_PROTOCOL_PATH", "{str(protocol_folder)}")\n'
55
- )
56
- startup.write_text(cmd_txt)
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes