goosebit 0.2.4__py3-none-any.whl → 0.2.6__py3-none-any.whl

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 (96) hide show
  1. goosebit/__init__.py +56 -6
  2. goosebit/api/telemetry/metrics.py +1 -5
  3. goosebit/api/v1/devices/device/responses.py +1 -0
  4. goosebit/api/v1/devices/device/routes.py +8 -8
  5. goosebit/api/v1/devices/requests.py +20 -0
  6. goosebit/api/v1/devices/routes.py +83 -8
  7. goosebit/api/v1/download/routes.py +14 -3
  8. goosebit/api/v1/rollouts/routes.py +5 -4
  9. goosebit/api/v1/routes.py +2 -1
  10. goosebit/api/v1/settings/routes.py +14 -0
  11. goosebit/api/v1/settings/users/__init__.py +1 -0
  12. goosebit/api/v1/settings/users/requests.py +16 -0
  13. goosebit/api/v1/settings/users/responses.py +7 -0
  14. goosebit/api/v1/settings/users/routes.py +56 -0
  15. goosebit/api/v1/software/routes.py +18 -14
  16. goosebit/auth/__init__.py +54 -14
  17. goosebit/auth/permissions.py +80 -0
  18. goosebit/db/config.py +57 -1
  19. goosebit/db/migrations/models/1_20241109151811_update.py +11 -0
  20. goosebit/db/migrations/models/2_20241121113728_update.py +11 -0
  21. goosebit/db/migrations/models/3_20241121140210_update.py +11 -0
  22. goosebit/db/migrations/models/4_20250324110331_update.py +16 -0
  23. goosebit/db/migrations/models/4_20250402085235_rename_uuid_to_id.py +11 -0
  24. goosebit/db/migrations/models/5_20250619090242_null_feed.py +83 -0
  25. goosebit/db/models.py +22 -7
  26. goosebit/db/pg_ssl_context.py +51 -0
  27. goosebit/device_manager.py +262 -0
  28. goosebit/plugins/__init__.py +32 -0
  29. goosebit/schema/devices.py +9 -6
  30. goosebit/schema/plugins.py +67 -0
  31. goosebit/schema/updates.py +15 -0
  32. goosebit/schema/users.py +9 -0
  33. goosebit/settings/__init__.py +0 -3
  34. goosebit/settings/schema.py +62 -14
  35. goosebit/storage/__init__.py +62 -0
  36. goosebit/storage/base.py +14 -0
  37. goosebit/storage/filesystem.py +111 -0
  38. goosebit/storage/s3.py +104 -0
  39. goosebit/ui/bff/common/columns.py +50 -0
  40. goosebit/ui/bff/common/requests.py +3 -15
  41. goosebit/ui/bff/common/responses.py +17 -0
  42. goosebit/ui/bff/devices/device/__init__.py +1 -0
  43. goosebit/ui/bff/devices/device/routes.py +17 -0
  44. goosebit/ui/bff/devices/requests.py +1 -0
  45. goosebit/ui/bff/devices/responses.py +6 -2
  46. goosebit/ui/bff/devices/routes.py +71 -17
  47. goosebit/ui/bff/download/routes.py +14 -3
  48. goosebit/ui/bff/rollouts/responses.py +6 -2
  49. goosebit/ui/bff/rollouts/routes.py +32 -4
  50. goosebit/ui/bff/routes.py +6 -3
  51. goosebit/ui/bff/settings/__init__.py +1 -0
  52. goosebit/ui/bff/settings/routes.py +20 -0
  53. goosebit/ui/bff/settings/users/__init__.py +1 -0
  54. goosebit/ui/bff/settings/users/responses.py +33 -0
  55. goosebit/ui/bff/settings/users/routes.py +80 -0
  56. goosebit/ui/bff/software/responses.py +19 -9
  57. goosebit/ui/bff/software/routes.py +40 -12
  58. goosebit/ui/nav.py +12 -2
  59. goosebit/ui/routes.py +70 -26
  60. goosebit/ui/static/js/devices.js +72 -80
  61. goosebit/ui/static/js/login.js +21 -5
  62. goosebit/ui/static/js/logs.js +7 -22
  63. goosebit/ui/static/js/rollouts.js +39 -35
  64. goosebit/ui/static/js/settings.js +322 -0
  65. goosebit/ui/static/js/setup.js +28 -0
  66. goosebit/ui/static/js/software.js +127 -127
  67. goosebit/ui/static/js/util.js +45 -4
  68. goosebit/ui/templates/__init__.py +10 -1
  69. goosebit/ui/templates/devices.html.jinja +0 -20
  70. goosebit/ui/templates/login.html.jinja +5 -0
  71. goosebit/ui/templates/nav.html.jinja +26 -7
  72. goosebit/ui/templates/rollouts.html.jinja +4 -22
  73. goosebit/ui/templates/settings.html.jinja +88 -0
  74. goosebit/ui/templates/setup.html.jinja +71 -0
  75. goosebit/ui/templates/software.html.jinja +0 -11
  76. goosebit/updater/controller/v1/routes.py +120 -72
  77. goosebit/updater/routes.py +86 -7
  78. goosebit/updates/__init__.py +24 -31
  79. goosebit/updates/swdesc.py +15 -8
  80. goosebit/users/__init__.py +63 -0
  81. goosebit/util/__init__.py +0 -0
  82. goosebit/util/path.py +42 -0
  83. goosebit/util/version.py +92 -0
  84. goosebit-0.2.6.dist-info/METADATA +280 -0
  85. goosebit-0.2.6.dist-info/RECORD +133 -0
  86. {goosebit-0.2.4.dist-info → goosebit-0.2.6.dist-info}/WHEEL +1 -1
  87. goosebit-0.2.6.dist-info/entry_points.txt +3 -0
  88. goosebit/realtime/logs.py +0 -42
  89. goosebit/realtime/routes.py +0 -13
  90. goosebit/ui/static/js/index.js +0 -155
  91. goosebit/ui/templates/index.html.jinja +0 -25
  92. goosebit/updater/manager.py +0 -357
  93. goosebit-0.2.4.dist-info/METADATA +0 -181
  94. goosebit-0.2.4.dist-info/RECORD +0 -98
  95. /goosebit/{realtime → api/v1/settings}/__init__.py +0 -0
  96. {goosebit-0.2.4.dist-info → goosebit-0.2.6.dist-info}/LICENSE +0 -0
@@ -1,181 +0,0 @@
1
- Metadata-Version: 2.1
2
- Name: goosebit
3
- Version: 0.2.4
4
- Summary:
5
- Author: Upstream Data
6
- Author-email: brett@upstreamdata.ca
7
- Requires-Python: >=3.11,<4.0
8
- Classifier: Programming Language :: Python :: 3
9
- Classifier: Programming Language :: Python :: 3.11
10
- Classifier: Programming Language :: Python :: 3.12
11
- Provides-Extra: postgresql
12
- Requires-Dist: aerich (>=0.7.2,<0.8.0)
13
- Requires-Dist: aiocache (>=0.12.2,<0.13.0)
14
- Requires-Dist: argon2-cffi (>=23.1.0,<24.0.0)
15
- Requires-Dist: asyncpg (>=0.29.0,<0.30.0) ; extra == "postgresql"
16
- Requires-Dist: fastapi[uvicorn] (>=0.111.0,<0.112.0)
17
- Requires-Dist: httpx (>=0.27.0,<0.28.0)
18
- Requires-Dist: itsdangerous (>=2.2.0,<3.0.0)
19
- Requires-Dist: jinja2 (>=3.1.4,<4.0.0)
20
- Requires-Dist: joserfc (>=1.0.0,<2.0.0)
21
- Requires-Dist: libconf (>=2.0.1,<3.0.0)
22
- Requires-Dist: opentelemetry-distro (>=0.47b0,<0.48)
23
- Requires-Dist: opentelemetry-exporter-prometheus (>=0.47b0,<0.48)
24
- Requires-Dist: opentelemetry-instrumentation-fastapi (>=0.47b0,<0.48)
25
- Requires-Dist: pydantic-settings (>=2.4.0,<3.0.0)
26
- Requires-Dist: python-multipart (>=0.0.9,<0.0.10)
27
- Requires-Dist: semver (>=3.0.2,<4.0.0)
28
- Requires-Dist: tortoise-orm (>=0.21.4,<0.22.0)
29
- Requires-Dist: websockets (>=12.0,<13.0)
30
- Description-Content-Type: text/markdown
31
-
32
- # gooseBit
33
-
34
- <img src="docs/img/goosebit-logo.png" style="width: 100px; height: 100px; display: block;">
35
-
36
- ---
37
-
38
- A simplistic, opinionated remote update server implementing hawkBit™'s [DDI API](https://eclipse.dev/hawkbit/apis/ddi_api/).
39
-
40
- ## Quick Start
41
-
42
- ### Installation
43
-
44
- 1. Install dependencies using [Poetry](https://python-poetry.org/):
45
-
46
- ```bash
47
- poetry install
48
- ```
49
-
50
- 2. Create the database:
51
-
52
- ```bash
53
- poetry run aerich init -t goosebit.db.config
54
- poetry run aerich upgrade
55
- ```
56
-
57
- 3. Launch gooseBit:
58
- ```bash
59
- python main.py
60
- ```
61
-
62
- ### Initial Configuration
63
-
64
- Before running gooseBit for the first time, update the default credentials in `settings.yaml`. The default login for testing purposes is:
65
-
66
- - **Username:** `admin@goosebit.local`
67
- - **Password:** `admin`
68
-
69
- ## Assumptions
70
-
71
- - Devices use [SWUpdate](https://swupdate.org) for managing software updates.
72
-
73
- ## Features
74
-
75
- ### Device Registry
76
-
77
- When a device connects to gooseBit for the first time, it is automatically added to the device registry. The server will then request the device's configuration data, including:
78
-
79
- - `hw_model` and `hw_revision`: Used to match compatible software.
80
- - `sw_version`: Indicates the currently installed software version.
81
-
82
- The registry tracks each device's status, including the last online timestamp, installed software version, update state, and more.
83
-
84
- ### Software Repository
85
-
86
- Software packages (`*.swu` files) can be hosted directly on the gooseBit server or on an external server. gooseBit parses the software metadata to determine compatibility with specific hardware models and revisions.
87
-
88
- ### Device Update Modes
89
-
90
- Devices can be configured with different update modes. The default mode is `Rollout`.
91
-
92
- #### 1. Manual Update to Specified Software
93
-
94
- Assign specific software to a device manually. Once installed, no further updates will be triggered.
95
-
96
- #### 2. Automatic Update to Latest Software
97
-
98
- Automatically updates the device to the latest compatible software, based on the reported `hw_model` and `hw_revision`. Note: versions are interpreted as [SemVer](https://semver.org) versions.
99
-
100
- #### 3. Software Rollout
101
-
102
- Rollouts target all devices with a specified "feed" value, ensuring that the assigned software is installed on all matching devices. Rollouts also track success and error rates, with future plans for automatic aborts. If multiple rollouts exist for the same feed, the most recent rollout takes precedence.
103
-
104
- ### Pause Updates
105
-
106
- Devices can be pinned to their current software version, preventing any updates from being applied.
107
-
108
- ### Real-time Update Logs
109
-
110
- While updates are in progress, gooseBit captures real-time logs, which are accessible through the device repository.
111
-
112
- ## Development
113
-
114
- ### Database
115
-
116
- Create or upgrade database
117
-
118
- ```bash
119
- poetry run aerich upgrade
120
- ```
121
-
122
- After a model change create the migration
123
-
124
- ```bash
125
- poetry run aerich migrate
126
- ```
127
-
128
- ### Code formatting and linting
129
-
130
- Code is formatted using different tools
131
-
132
- - black and isort for `*.py`
133
- - biomejs for `*.js`, `*.json`
134
- - prettier for `*.html`, `*.md`, `*.yml`, `*.yaml`
135
-
136
- Code is linted using different tools as well
137
-
138
- - flake8 for `*.py`
139
- - biomejs for `*.js`
140
-
141
- Best to have pre-commit install git hooks that run all those tools before a commit:
142
-
143
- ```bash
144
- poetry run pre-commit install
145
- ```
146
-
147
- To manually apply the hooks to all files use:
148
-
149
- ```bash
150
- pre-commit run --all-files
151
- ```
152
-
153
- ### Testing
154
-
155
- Tests are implemented using pytest. To run all tests
156
-
157
- ```bash
158
- poetry run pytest
159
- ```
160
-
161
- ### Structure
162
-
163
- The structure of gooseBit is as follows:
164
-
165
- - `api`: Files for the API.
166
- - `ui`: Files for the UI.
167
- - `bff`: Backend for frontend API.
168
- - `static`: Static files.
169
- - `templates`: Jinja2 formatted templates.
170
- - `nav`: Navbar handler.
171
- - `updater`: DDI API handler and device update manager.
172
- - `updates`: SWUpdate file parsing.
173
- - `realtime`: Realtime API functionality with websockets.
174
- - `auth`: Authentication functions and permission handling.
175
- - `models`: Database models.
176
- - `db`: Database config and initialization.
177
- - `schema`: Pydantic models used for API type hinting.
178
- - `settings`: Settings loader and handler.
179
- - `telemetry`: Telemetry data handlers.
180
- - `routes`: Routes for a giving endpoint, including the router.
181
-
@@ -1,98 +0,0 @@
1
- goosebit/__init__.py,sha256=ty8VdDubrAwegJpU43SHo2wLeO2GrbkAdpaqu_iId_Q,3529
2
- goosebit/__main__.py,sha256=ezSLOobcrbnBspFOSbyjuATEdk8B3aAj9cgEu647ujk,161
3
- goosebit/api/__init__.py,sha256=4RRIzqC6KbCESIC9Vc6G4iAa28IWQH4KROTGd2S4AoI,41
4
- goosebit/api/responses.py,sha256=HXLpFgL-iv5Ts6LKa3AMt1XGV1GbDE5GzjK66_3Gz5o,84
5
- goosebit/api/routes.py,sha256=KOA1r8Ripl9nhZV4gZpuQrRi0fG9I3VEqcAAMeBGqBk,272
6
- goosebit/api/telemetry/__init__.py,sha256=4RRIzqC6KbCESIC9Vc6G4iAa28IWQH4KROTGd2S4AoI,41
7
- goosebit/api/telemetry/metrics.py,sha256=aJ2viqBcxU41wJ0tDwPXj0Dsv6YEHaWv7EBDqkUilGI,791
8
- goosebit/api/telemetry/prometheus/__init__.py,sha256=nvVtx3DsqBhoXE4Y4L6k7nYoQTl1VV0afyVW2YHLQGs,83
9
- goosebit/api/telemetry/prometheus/readers.py,sha256=TKD7LT-lYS53xdt-tLMxqyWAeya62299cJtok9Q2MSE,104
10
- goosebit/api/telemetry/prometheus/routes.py,sha256=91TNk_pbxi5BfCLo_OVojubL9kxFuL84dJ55RmsZ0eE,676
11
- goosebit/api/telemetry/routes.py,sha256=nuv9bClyo_P8TAkcp3huqxZoUn-ATlRAMnl0OXbWNpw,217
12
- goosebit/api/v1/__init__.py,sha256=4RRIzqC6KbCESIC9Vc6G4iAa28IWQH4KROTGd2S4AoI,41
13
- goosebit/api/v1/devices/__init__.py,sha256=kzt5TBA-bJmDZFXYPohggbMOW7GhklyflaRKZNC0yDY,42
14
- goosebit/api/v1/devices/device/__init__.py,sha256=kzt5TBA-bJmDZFXYPohggbMOW7GhklyflaRKZNC0yDY,42
15
- goosebit/api/v1/devices/device/responses.py,sha256=THIPMzc6mwl7GmIXuqAeLLesFHfssvPrMJeHe8tV4mA,222
16
- goosebit/api/v1/devices/device/routes.py,sha256=SGw6qSBK0hJyjJAXHNgGa5PAy0z4JREQKslpRGN8IT0,1169
17
- goosebit/api/v1/devices/requests.py,sha256=zx9eWXQanqBnmy-XboA_lrzInfx9ozOB4vG2jRTwnJA,131
18
- goosebit/api/v1/devices/responses.py,sha256=NmaxpXKJ_YsQ92mvoTXG8HYB39_HLFmZaHo_uvXFmhg,185
19
- goosebit/api/v1/devices/routes.py,sha256=t9MbKyiT-CLhQWk1DSFcF_Pvuy9pJsBIsRob6yxqj0g,1067
20
- goosebit/api/v1/download/__init__.py,sha256=kzt5TBA-bJmDZFXYPohggbMOW7GhklyflaRKZNC0yDY,42
21
- goosebit/api/v1/download/routes.py,sha256=wdeXA-dGO4D9FxaUP6OnUSW4_2NZhi_VgIxMcSRL2x4,675
22
- goosebit/api/v1/rollouts/__init__.py,sha256=4RRIzqC6KbCESIC9Vc6G4iAa28IWQH4KROTGd2S4AoI,41
23
- goosebit/api/v1/rollouts/requests.py,sha256=EF1VUwaK-f-2SSKxl2klKrMGfBkBo72iWKtw3cAzzW0,257
24
- goosebit/api/v1/rollouts/responses.py,sha256=yKljabI1wQB6MXNXrF4aIi5csKRCo0A96RqTW6OwAjE,311
25
- goosebit/api/v1/rollouts/routes.py,sha256=afUQTjzrpLbHA68CEpMDMZ93C6-jp8JLrdjUEYUFm7o,1927
26
- goosebit/api/v1/routes.py,sha256=g9vL0VOuFSdNG3FnK3y_03trwv4X2OLN9ustJeCgc58,272
27
- goosebit/api/v1/software/__init__.py,sha256=4RRIzqC6KbCESIC9Vc6G4iAa28IWQH4KROTGd2S4AoI,41
28
- goosebit/api/v1/software/requests.py,sha256=visd81BMeWDKJADcC10NBJDs7Z3xQC-5nod9z_WHiPg,101
29
- goosebit/api/v1/software/responses.py,sha256=l41-JWqyJmmEslXkx4NEJsGOqMrAB__nBUZS3E_9le0,192
30
- goosebit/api/v1/software/routes.py,sha256=r8lSPg1eQajPF6990DwnbJpDsuzW53rC5ktLuG3zyjA,3209
31
- goosebit/auth/__init__.py,sha256=WqvVHPAlvH_Tf8G9STcD--eE_JDfIcPLbX9Q7mhPJhk,4605
32
- goosebit/db/__init__.py,sha256=ktnV4302iWzzTr-3oHXv3ud-23qTcAJ4tPLAXyTZZJw,462
33
- goosebit/db/config.py,sha256=YCtF52lQ5bEVtKsrqkSzQpbKmCbD79O8Tz0RE4thV3c,220
34
- goosebit/db/migrations/models/0_20240830054046_init.py,sha256=EBig7b0-AOWt_AE10rQf_0ZrserjKTm0r53wYInK5Co,5526
35
- goosebit/db/models.py,sha256=UGwcTScSxyBzu7d7YVlYkc1NKkTktOO9dMiYbxCw_BQ,5009
36
- goosebit/realtime/__init__.py,sha256=4RRIzqC6KbCESIC9Vc6G4iAa28IWQH4KROTGd2S4AoI,41
37
- goosebit/realtime/logs.py,sha256=JJ6bfVKzux9n3mXaUFoQhH2krGCpW7U1VzaloNmiORY,1223
38
- goosebit/realtime/routes.py,sha256=yLHrA-BHHU5cpUNvxAPVxWC3KcB9aUrV31HT_th24Ls,265
39
- goosebit/schema/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
40
- goosebit/schema/devices.py,sha256=icHFjfVsqiYaWB8xheoBPXABK7hmmsq3jyAW3tzZ9nw,2652
41
- goosebit/schema/rollouts.py,sha256=Kp--XRC39SDs1bKf59q8fBHzitoW88ZMN1GVlbCQotQ,882
42
- goosebit/schema/software.py,sha256=W02rA0guQ7zeeVMTdwxt6EjCnTdf-9JewVJRqdN_GK0,951
43
- goosebit/settings/__init__.py,sha256=UkJa_G_VJckNf16Em0zz8sXgEi5pzxHFvZ96oa9MC3k,360
44
- goosebit/settings/const.py,sha256=hOpeA9pGmbU4V4mqcfhpHV7cmEjf2GIenmzCSz2Jpj8,779
45
- goosebit/settings/schema.py,sha256=T6MntOkM6Pbf98dQHZoEVUADwKpeJqCrFDc40ufCiG4,2543
46
- goosebit/ui/__init__.py,sha256=4RRIzqC6KbCESIC9Vc6G4iAa28IWQH4KROTGd2S4AoI,41
47
- goosebit/ui/bff/__init__.py,sha256=4RRIzqC6KbCESIC9Vc6G4iAa28IWQH4KROTGd2S4AoI,41
48
- goosebit/ui/bff/common/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
49
- goosebit/ui/bff/common/requests.py,sha256=KoC2jRXcGdKAgDvsX-N2_tkXCYIw8YnaHHgVEO0nEs0,1499
50
- goosebit/ui/bff/common/util.py,sha256=_hz89EFLAL1UvbIvJJJSF80PL4T1mz1Vk7354wHBzOE,1144
51
- goosebit/ui/bff/devices/__init__.py,sha256=4RRIzqC6KbCESIC9Vc6G4iAa28IWQH4KROTGd2S4AoI,41
52
- goosebit/ui/bff/devices/requests.py,sha256=YbTUsyVLQZaUnn3dJ6AQe0mZl_H5aQC6QKCRxhCjGJc,286
53
- goosebit/ui/bff/devices/responses.py,sha256=ERzXIEYCozUYE2Npp89rj7GlEXvzUHhLGt4ywRK91XI,1140
54
- goosebit/ui/bff/devices/routes.py,sha256=cX0eEZhjmlRZQmBtr9w75ssYhDGEr66nVf72nqwXOKA,2877
55
- goosebit/ui/bff/download/__init__.py,sha256=kzt5TBA-bJmDZFXYPohggbMOW7GhklyflaRKZNC0yDY,42
56
- goosebit/ui/bff/download/routes.py,sha256=wdeXA-dGO4D9FxaUP6OnUSW4_2NZhi_VgIxMcSRL2x4,675
57
- goosebit/ui/bff/rollouts/__init__.py,sha256=4RRIzqC6KbCESIC9Vc6G4iAa28IWQH4KROTGd2S4AoI,41
58
- goosebit/ui/bff/rollouts/responses.py,sha256=QnTtlPLqY6S9gs5-duw3rov5X1LAa5KuieniYzUf9zg,1112
59
- goosebit/ui/bff/rollouts/routes.py,sha256=ZO-mkDzTgzssBtIbhOqSxrPgZYMVPsMW4EXw3f8YA1o,1553
60
- goosebit/ui/bff/routes.py,sha256=dq0fHXBiJfERzvUhvR4KVYCK3Ogf0Gb9wMSpzQanDac,323
61
- goosebit/ui/bff/software/__init__.py,sha256=4RRIzqC6KbCESIC9Vc6G4iAa28IWQH4KROTGd2S4AoI,41
62
- goosebit/ui/bff/software/responses.py,sha256=ynur0zdslI8s7rhsLHZJ63veDJc4MBDRQPH7YOqu3cs,1292
63
- goosebit/ui/bff/software/routes.py,sha256=xwLsI6wTJzu_-eWAV1f8DlEWw67i22LK72D-uYLRMu0,3220
64
- goosebit/ui/nav.py,sha256=l-MCY2AN5v6jDCSDZoka3qjQ2_24SjLqUi1dYtxCjIM,378
65
- goosebit/ui/routes.py,sha256=6SizNvgDwuFIX7_ywwvOncNRQoslizVr2OoqFA37TPg,2143
66
- goosebit/ui/static/__init__.py,sha256=AsZiM3h9chQ_YaBbAD6TVFf0244Q9DetkDMl70q8swQ,135
67
- goosebit/ui/static/favicon.ico,sha256=MKAqEjW7F1-j2dmW4s08y4U0dFteIlU7rpLKakU0Lxk,4286
68
- goosebit/ui/static/favicon.svg,sha256=8zvM7o2Ob3YmTEV6Rj7rCTgSajvY6wIaAQAAjWwlDsw,8733
69
- goosebit/ui/static/js/devices.js,sha256=ZKMw6gv5xhBbEGMd17r5gogEayR82cB7-9y7z7T-Czc,14611
70
- goosebit/ui/static/js/index.js,sha256=ldsPX0PpGB1vkYEfMY05tYEgG6iCif3tx60aaAc3URY,5515
71
- goosebit/ui/static/js/login.js,sha256=9qlXki3udm5CmAO8UXUJe94Kc_-SJekdKjfH9TzJhgk,579
72
- goosebit/ui/static/js/logs.js,sha256=DgOWLKUvK-mM-oYRA0JJTIhtiCiegb5qCJ7pE9H2I3k,863
73
- goosebit/ui/static/js/rollouts.js,sha256=yQEiwWEy1ZuslTeE6P9YS8YY0YbGcKnIVYakm2M7wr8,7470
74
- goosebit/ui/static/js/software.js,sha256=H9P4RjizC2EhL6Otjv4-iLnESdi3IvQYhWFvM4ddjaQ,8907
75
- goosebit/ui/static/js/util.js,sha256=j-dsuiqG9FXhrIeYw4DLDeDURxsVEtu7aclMFQuWEA4,4042
76
- goosebit/ui/static/svg/goosebit-logo.svg,sha256=8zvM7o2Ob3YmTEV6Rj7rCTgSajvY6wIaAQAAjWwlDsw,8733
77
- goosebit/ui/templates/__init__.py,sha256=xHCio6TnuNnYKLOZ3VhvbxyJPZ2ddzTSle_RmiuLrrA,378
78
- goosebit/ui/templates/devices.html.jinja,sha256=aA2H0rJS3fu6oEx5aPNYji_eeNMHGb9NlQ8ho67Tuno,6608
79
- goosebit/ui/templates/index.html.jinja,sha256=SDROkbhSRX6-pdET-yikfnrcfNKZR5zPhY2ByrSdAy4,907
80
- goosebit/ui/templates/login.html.jinja,sha256=eQX1ypZ5iJ2L4v4lw8VB7GKluUjUYmpoUyUy8jY98Og,3050
81
- goosebit/ui/templates/logs.html.jinja,sha256=JLHogVHWcP_Y321dd-gHexNqix-PFfGVpEKbNmzsMU8,1310
82
- goosebit/ui/templates/nav.html.jinja,sha256=s56I5-iGac3LaMXM836eLC6Z5LsoE9EC3RBvZZyOCME,5264
83
- goosebit/ui/templates/rollouts.html.jinja,sha256=s9kIxRYO8OypqIQH8tQUwZJDDjsex89piuV4kh1eqwE,4728
84
- goosebit/ui/templates/software.html.jinja,sha256=CTIeNkPMJMvtDVWbcKl_BjvtAFV3bskpCcNg-lCJIZM,7551
85
- goosebit/updater/__init__.py,sha256=4RRIzqC6KbCESIC9Vc6G4iAa28IWQH4KROTGd2S4AoI,41
86
- goosebit/updater/controller/__init__.py,sha256=4RRIzqC6KbCESIC9Vc6G4iAa28IWQH4KROTGd2S4AoI,41
87
- goosebit/updater/controller/routes.py,sha256=8CnLb-kDuO-yFeWdu4apIyctCf9OzvJ011Az3QDGemU,123
88
- goosebit/updater/controller/v1/__init__.py,sha256=4RRIzqC6KbCESIC9Vc6G4iAa28IWQH4KROTGd2S4AoI,41
89
- goosebit/updater/controller/v1/routes.py,sha256=pR8c1xHjpYXQBdKb9r9J73muEeR1FeRJTWzo6asJWC4,7251
90
- goosebit/updater/controller/v1/schema.py,sha256=NwSyPx3A38iFabfOfzaVtxPozJQNacikP5WOhxMHqdg,1228
91
- goosebit/updater/manager.py,sha256=1aEPqrQwUTkYsMERk5nJnkllMuijcqXcayQetmn6L6A,11755
92
- goosebit/updater/routes.py,sha256=GfjbSdFYaw28B8b7hByOPN8BMIbaGvbz4CbG1jQCmP8,515
93
- goosebit/updates/__init__.py,sha256=RIq3m7x0-ByWjU21llKZSnj4a0Hg27iSNMfO1G4Kjwc,4284
94
- goosebit/updates/swdesc.py,sha256=gRbx2q9EJv-QpCGo2JmP1zLDM1GNp_vTULXbIJbexRM,3123
95
- goosebit-0.2.4.dist-info/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
96
- goosebit-0.2.4.dist-info/METADATA,sha256=WvIHdnyr1D8S6FYnk17LYlmtwwwfosnKoWO37POH7vc,5504
97
- goosebit-0.2.4.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
98
- goosebit-0.2.4.dist-info/RECORD,,
File without changes