OpenWISP的固件升级模块
项目描述
OpenWISP的固件升级模块。
特性:
存储每个升级操作的详细信息,可以在设备页面上查看
自动重试可恢复失败(例如,由于间歇性互联网连接导致的固件镜像上传问题)
执行最终检查以确定升级是否成功完成
防止使用相同的固件镜像意外进行多次升级
单设备升级
批量升级
可以将固件镜像分为类别
可配置的超时时间
要获取OpenWISP模块和架构的更完整概述,请参阅OpenWISP架构概述。
想要帮助OpenWISP吗? 在此了解如何帮助我们成长。
安装说明
要求
Python >= 3.7
openwisp-controller (及其依赖项) >= 1.0.0
安装依赖项
安装spatialite和sqlite
sudo apt-get install sqlite3 libsqlite3-dev openssl libssl-dev
sudo apt-get install gdal-bin libproj-dev libgeos-dev libspatialite-dev
设置(集成到现有Django项目中)
按照openwisp-controller的设置说明进行操作,然后添加以下设置。
INSTALLED_APPS = [
# django apps
# all-auth
'django.contrib.sites',
'openwisp_users.accounts',
'allauth',
'allauth.account',
'django_extensions',
'private_storage',
# openwisp2 modules
'openwisp_controller.pki',
'openwisp_controller.config',
'openwisp_controller.connection',
'openwisp_controller.geo',
'openwisp_firmware_upgrader',
'openwisp_users',
'openwisp_notifications',
'openwisp_ipam',
# openwisp2 admin theme (must be loaded here)
'openwisp_utils.admin_theme',
# admin
'django.contrib.admin',
'django.forms',
# other dependencies
'sortedm2m',
'reversion',
'leaflet',
'flat_json_widget',
# rest framework
'rest_framework',
'rest_framework.authtoken',
'rest_framework_gis',
'django_filters',
'drf_yasg',
# channels
'channels',
]
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
PRIVATE_STORAGE_ROOT = os.path.join(MEDIA_ROOT, 'firmware')
根URLconf (urls.py) 应该看起来像以下示例
from django.conf import settings
from django.contrib import admin
from django.conf.urls import include, url
from django.contrib.staticfiles.urls import staticfiles_urlpatterns
urlpatterns = [
path('admin/', admin.site.urls),
path('', include('openwisp_controller.urls')),
path('', redirect_view, name='index'),
path('', include('openwisp_firmware_upgrader.urls')),
path('api/v1/', include((get_api_urls(), 'users'), namespace='users')),
path('api/v1/', include('openwisp_utils.api.urls')),
]
urlpatterns += staticfiles_urlpatterns()
开发版安装
安装您的分支仓库
git clone git://github.com/<your_fork>/openwisp-firmware-upgrader
cd openwisp-firmware-upgrader/
python setup.py develop
安装测试要求
pip install -r requirements-test.txt
创建数据库
cd tests/
./manage.py migrate
./manage.py createsuperuser
启动开发服务器
./manage.py runserver 0.0.0.0:8000
您可以通过http://127.0.0.1:8000/admin/访问管理员界面。
使用以下命令运行celery和celery-beat(需要单独的终端窗口)
# (cd tests)
celery -A openwisp2 worker -l info
celery -A openwisp2 beat -l info
使用以下命令运行测试
# run qa checks
./run-qa-checks
# standard tests
./runtests.py
# tests for the sample app
SAMPLE_APP=1 ./runtests.py --keepdb --failfast
在运行上一个示例的最后一行时,环境变量SAMPLE_APP激活了位于/tests/openwisp2/sample_firmware_upgrader/的应用程序,这是一个简单的Django应用程序,仅用于测试其可扩展性,有关此概念的信息,请参阅以下部分。
快速入门指南
要求
运行至少OpenWRT 12.09 Attitude Adjustment的设备,在测试中,OpenWRT的旧版本根本无法工作
设备必须有足够的空闲RAM才能将新图像上传到/tmp
1. 创建类别
通过转到“固件管理 > 固件类别 > 添加固件类别”来为您固件图像创建一个类别,如果您的网络中只使用一种固件类型,您可以将该类别命名为“默认”或“标准”。
如果您使用具有不同功能的多个固件图像,为每种固件类型创建一个类别,例如
WiFi
SDN路由器
LoRa网关
为了仅在特定固件类别上执行大规模升级,例如当新的LoRa 网关固件可用时,这是必要的。
2. 创建构建对象
通过访问固件管理 > 固件构建 > 添加固件构建来创建一个构建对象,构建对象与固件类别相关,并收集为系统支持的不同硬件模型编译的不同固件镜像。
版本字段表示固件版本,变更日志字段是可选的,但我们建议填写它以帮助操作员了解每个版本之间的差异。
构建模型的一个重要但可选字段是操作系统标识符,该字段应与在设备注册期间自动填充的操作系统字段的值匹配,例如:OpenWrt 19.07-SNAPSHOT r11061-6ffd4d8a4d。它被固件升级模块用于自动为现有设备或当新设备注册时创建DeviceFirmware对象。一个DeviceFirmware对象代表设备与固件镜像之间的关系,它基本上告诉我们哪个固件镜像安装在该设备上。
要找出要使用的确切值,您应该在设备上进行测试闪存并将它注册到系统中,或者您应该解压缩固件镜像以检查生成的值。
如果您不确定要使用哪个操作系统标识符,只需将其留空,以后当您找到时再填写。
现在保存构建对象以创建它。
3. 将图片上传到构建中
现在是将图像添加到构建的时间了,我们建议一次添加一个图像。或者可以使用REST API来自动化此步骤。
如果您使用的是不在图像类型列表中的硬件模型,如果该硬件模型由OpenWRT官方支持,您可以发送拉取请求以添加它,否则您可以使用设置 OPENWISP_CUSTOM_OPENWRT_IMAGES来添加它。
4. 对特定设备进行固件升级
一旦新的构建准备就绪,已在系统中创建,并且其图像已上传,那么就是最终升级我们设备的时候了。
要执行单个设备的升级,请导航到设备详细信息,然后转到“固件”标签。
如果您在第2步中正确填写了操作系统标识符,您应该有类似上面的情况:在这个例子中,设备正在使用版本1.0,我们希望将其升级到版本2.0,一旦选择了新的固件镜像,我们只需单击保存,然后设备页面将出现一个新标签,允许我们查看升级过程中的情况。
目前,升级信息的更新还不是异步的,所以您将需要定期重新加载页面以查找新的信息。这将在未来的版本中得到解决。
5. 执行批量升级
首先,请确保以下先决条件得到满足:
系统配置正确
新固件镜像按预期工作
您已经尝试过多次单个设备的升级。
在这个阶段,您可以尝试以下操作进行大规模升级:
转到构建列表页面
选择包含您想要升级的设备最新固件镜像的构建
单击“升级与所选构建相关的设备”。
此时,您应该看到一个摘要页面,它将告知您将要升级哪些设备,您可以确认操作或取消。
一旦操作被确认,您将被重定向到一个页面,您可以在此页面上监控升级操作的进度。
目前,升级信息的更新还不是异步的,所以您将需要定期重新加载页面以查找新的信息。这将在未来的版本中得到解决。
自动设备固件检测
OpenWISP 固件升级器 维护一个数据结构,用于将固件镜像文件映射到板卡名称,称为 OPENWRT_FIRMWARE_IMAGE_MAP。
以下是从 OPENWRT_FIRMWARE_IMAGE_MAP 中的一个示例固件镜像项目。
{
# Firmware image file name.
'ar71xx-generic-cf-e320n-v2-squashfs-sysupgrade.bin': {
# Human readable name of the model which is displayed on
# the UI
'label': 'COMFAST CF-E320N v2 (OpenWRT 19.07 and earlier)',
# Tupe of board names with which the different versions
# of the hardware are identified on OpenWrt
'boards': ('COMFAST CF-E320N v2',),
}
}
当设备在 OpenWISP 上注册时,openwisp-config 代理 从 /tmp/sysinfo/model 读取设备板卡名称并发送到 OpenWISP。该值随后保存在 Device.model 字段中。 OpenWISP 固件升级器 使用此字段来自动检测设备的正确固件镜像。
使用 OPENWISP_CUSTOM_OPENWRT_IMAGES 设置在您的项目中添加额外的固件镜像。
编写自定义固件升级类
您可以为其他固件操作系统或基于自定义 OpenWrt 的固件编写自定义升级器。
以下是一个自定义 OpenWrt 固件升级器类的示例
from openwisp_firmware_upgrader.upgraders.openwrt import OpenWrt
class CustomOpenWrtBasedFirmware(OpenWrt):
# this firmware uses a custom upgrade command
UPGRADE_COMMAND = 'upgrade_firmware.sh --keep-config'
# it takes somewhat more time to boot so it needs more time
RECONNECT_DELAY = 150
RECONNECT_RETRY_DELAY = 5
RECONNECT_MAX_RETRIES = 20
def get_remote_path(self, image):
return '/tmp/firmware.img'
def get_upgrade_command(self, path):
return self.UPGRADE_COMMAND
您需要将自定义升级器类放置在应用程序的 python 路径中,然后将此路径添加到 OPENWISP_FIRMWARE_UPGRADERS_MAP 设置中。
REST API
要启用 API,设置 OPENWISP_FIRMWARE_UPGRADER_API 必须设置为 True。
实时文档
一个通用的实时 API 文档(遵循 OpenAPI 规范)在 /api/v1/docs/。
可浏览的Web界面
此外,在浏览器中直接打开以下 列出的端点 将显示 Django-REST-Framework 的可浏览 API 接口,这使得查找每个端点的详细信息更加容易。
身份验证
请参阅 openwisp-users: 使用用户令牌进行认证。
分页
所有 list 端点都支持 page_size 参数,该参数允许与 page 参数一起分页结果。
GET /api/v1/firmware-upgrader/build/?page_size=10
GET /api/v1/firmware-upgrader/build/?page_size=10&page=2
按组织slug进行筛选
大多数端点允许通过组织缩写进行筛选,例如
GET /api/v1/firmware-upgrader/build/?organization=org-slug
端点列表
由于详细说明包含在每个点的 实时文档 和 可浏览网页 中,因此这里我们只提供可用的端点列表,有关更多信息,请在浏览器中打开端点的 URL。
列出批量升级操作
GET /api/v1/firmware-upgrader/batch-upgrade-operation/
获取批量升级操作详情
GET /api/v1/firmware-upgrader/batch-upgrade-operation/{id}/
列出固件构建
GET /api/v1/firmware-upgrader/build/
创建固件构建
POST /api/v1/firmware-upgrader/build/
获取固件构建详情
GET /api/v1/firmware-upgrader/build/{id}/
更改固件构建的详细信息
PUT /api/v1/firmware-upgrader/build/{id}/
修补固件构建的详细信息
PATCH /api/v1/firmware-upgrader/build/{id}/
删除固件构建
DELETE /api/v1/firmware-upgrader/build/{id}/
获取固件构建图像列表
GET /api/v1/firmware-upgrader/build/{id}/image/
将新的固件图像上传到构建中
POST /api/v1/firmware-upgrader/build/{id}/image/
获取固件图像详情
GET /api/v1/firmware-upgrader/build/{build_pk}/image/{id}/
删除固件图像
DELETE /api/v1/firmware-upgrader/build/{build_pk}/image/{id}/
下载固件图像
GET /api/v1/firmware-upgrader/build/{build_pk}/image/{id}/download/
执行批量升级
升级与指定构建 ID 相关的所有设备。
POST /api/v1/firmware-upgrader/build/{id}/upgrade/
批量升级的Dry-run
返回一个表示将使用 POST 升级的 DeviceFirmware 和 Device 实例的列表。
仅当不存在将要升级的设备的 DeviceFirmware 对象时,才指示 Device 对象。
GET /api/v1/firmware-upgrader/build/{id}/upgrade/
列出固件类别
GET /api/v1/firmware-upgrader/category/
创建新的固件类别
POST /api/v1/firmware-upgrader/category/
获取固件类别详情
GET /api/v1/firmware-upgrader/category/{id}/
更改固件类别的详细信息
PUT /api/v1/firmware-upgrader/category/{id}/
修补固件类别的详细信息
PATCH /api/v1/firmware-upgrader/category/{id}/
删除固件类别
DELETE /api/v1/firmware-upgrader/category/{id}/
设置
OPENWISP_FIRMWARE_UPGRADER_RETRY_OPTIONS
类型: |
dict |
默认值: |
见下文 |
# default value of OPENWISP_FIRMWARE_UPGRADER_RETRY_OPTIONS:
dict(
max_retries=4,
retry_backoff=60,
retry_backoff_max=600,
retry_jitter=True,
)
固件升级过程中发生可恢复故障时的重试设置。
默认情况下,如果升级操作在固件烧录之前失败(例如:由于在上传镜像期间的网络问题),则升级操作将重试 4 次,采用指数随机退避和最大延迟 10 分钟。
有关这些设置的更多信息,请参阅 Celery 关于已知错误自动重试的文档。
OPENWISP_FIRMWARE_UPGRADER_TASK_TIMEOUT
类型: |
int |
默认值: |
600 |
执行固件升级的后台任务的超时时间。
如果由于某种意外原因,升级在 10 分钟以上仍然卡住,则升级操作将被标记为失败,并将终止任务。
这种情况不应该发生,但在使用后台任务时,设置全局任务超时是一种最佳实践,因为它可以防止意外错误导致特定任务挂起,从而迅速填满后台队列的所有可用槽位,阻止其他任务执行,最终对应用程序的其他部分产生负面影响。
OPENWISP_CUSTOM_OPENWRT_IMAGES
类型: |
元组 |
默认值: |
None |
此设置可用于扩展包含在 OpenWISP 固件升级器 中的固件映像类型列表。此设置适用于添加对自定义 OpenWrt 映像的支持。
OPENWISP_CUSTOM_OPENWRT_IMAGES = (
(
# Firmware image file name.
'customimage-squashfs-sysupgrade.bin', {
# Human readable name of the model which is displayed on
# the UI
'label': 'Custom WAP-1200',
# Tuple of board names with which the different versions of
# the hardware are identified on OpenWrt
'boards': ('CWAP1200',)
}
),
)
请参阅此文档的“设备固件自动检测”部分,了解 OpenWISP 固件升级器 如何在升级中使用此设置。
OPENWISP_FIRMWARE_UPGRADER_MAX_FILE_SIZE
类型: |
int |
默认值: |
30 * 1024 * 1024(30 MB) |
此设置可用于设置固件映像的最大大小限制,例如
OPENWISP_FIRMWARE_UPGRADER_MAX_FILE_SIZE = 40 * 1024 * 1024 # 40MB
注意事项:
值必须以字节为单位指定。None 表示无限。
OPENWISP_FIRMWARE_UPGRADER_API
类型: |
布尔型 |
默认值: |
True |
指示固件升级器 API 是否启用。
OPENWISP_FIRMWARE_UPGRADER_OPENWRT_SETTINGS
类型: |
dict |
默认值: |
{} |
允许更改默认 OpenWRT 升级器设置,例如
OPENWISP_FIRMWARE_UPGRADER_OPENWRT_SETTINGS = {
'reconnect_delay': 120,
'reconnect_retry_delay': 20,
'reconnect_max_retries': 15,
'upgrade_timeout': 90,
}
reconnect_delay:在启动升级命令后,在再次尝试连接到设备之前等待的秒数;重新连接步骤是必要的,用于验证升级是否成功完成;默认为 120 秒
reconnect_retry_delay:重新连接尝试失败后等待的秒数;默认为 20 秒
reconnect_max_retries:最大重新连接尝试次数,默认为 15 次尝试
upgrade_timeout:在设备上启动升级命令后,在关闭 shell 会话之前等待的秒数,这对于升级命令挂起很有用(在较老的 OpenWRT 版本中会发生这种情况);默认为 90 秒
OPENWISP_FIRMWARE_API_BASEURL
类型: |
dict |
默认值: |
/(指向同一服务器) |
如果您在另一个域上有独立的 openwisp-firmware-upgrader API 实例,则可以使用此选项更改映像下载 URL 的基础,这将使您能够指向您的 API 服务器域,例如值: https://myfirmware.myapp.com。
OPENWISP_FIRMWARE_UPGRADERS_MAP
类型: |
dict |
默认值: |
|
一个将更新策略映射到升级器的字典。
如果您想使用自定义更新策略,则需要使用此设置提供一个条目,其中包含您的更新策略类路径作为键。
如果您需要使用 自定义升级器类,则需要使用此设置提供一个条目,其中包含您的升级器类路径作为值。
OPENWISP_FIRMWARE_PRIVATE_STORAGE_INSTANCE
类型: |
字符串 |
默认值: |
openwisp_firmware_upgrader.private_storage.storage.file_system_private_storage |
指向 private_storage 中的任何存储类实例的点路径。此实例用于存储固件映像文件。
默认情况下,使用 private_storage.storage.files.PrivateFileSystemStorage 实例。
扩展openwisp-firmware-upgrader
OpenWISP 项目的核心价值观之一是 软件可重用性,因此 OpenWISP 固件升级器 提供了一组基类,可以导入、扩展和重用以创建衍生应用程序。
为了实现您自己的 OpenWISP 固件升级器 版本,您需要执行本节中描述的步骤。
如有疑问,测试项目 和 示例应用程序 中的代码将为您提供真实来源:只需复制并修改此代码,以获取 OpenWISP 固件升级器 的基本衍生版本。
前提:如果您计划使用此模块的定制版本,我们建议从一开始就使用它,因为将数据从默认模块迁移到您的扩展版本可能会耗时。
1. 初始化您的自定义模块
您需要做的第一件事是创建一个新 django 应用,该应用将包含您的自定义版本 OpenWISP 固件升级器。
django 应用本质上就是一个 python 包(一个 python 脚本目录),在以下示例中,我们将此 django 应用称为 myupgrader,但您可以根据需要命名。
django-admin startapp myupgrader
请注意,上述命令必须从您的 PYTHON_PATH 可用目录中调用,这样您就可以将结果导入到您的项目中。
现在,您需要将 myupgrader 添加到您的 settings.py 中的 INSTALLED_APPS,并确保已移除 openwisp_firmware_upgrader。
INSTALLED_APPS = [
# ... other apps ...
# 'openwisp_firmware_upgrader' <-- comment out or delete this line
'myupgrader'
]
有关如何与 django 项目和 django 应用一起工作的更多信息,请参阅 django 文档。
2. 安装 openwisp-firmware-upgrader
安装(并将 openwisp-firmware-upgrader 添加到您的项目需求中)
pip install openwisp-firmware-upgrader
3. 添加 EXTENDED_APPS
将以下内容添加到您的 settings.py
EXTENDED_APPS = ['openwisp_firmware_upgrader']
4. 添加 openwisp_utils.staticfiles.DependencyFinder
将 openwisp_utils.staticfiles.DependencyFinder 添加到您的 settings.py 中的 STATICFILES_FINDERS
STATICFILES_FINDERS = [
'django.contrib.staticfiles.finders.FileSystemFinder',
'django.contrib.staticfiles.finders.AppDirectoriesFinder',
'openwisp_utils.staticfiles.DependencyFinder',
]
5. 添加 openwisp_utils.loaders.DependencyLoader
将 openwisp_utils.loaders.DependencyLoader 添加到您的 settings.py 中的 TEMPLATES
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'OPTIONS': {
'loaders': [
'django.template.loaders.filesystem.Loader',
'django.template.loaders.app_directories.Loader',
'openwisp_utils.loaders.DependencyLoader',
],
'context_processors': [
'django.template.context_processors.debug',
'django.template.context_processors.request',
'django.contrib.auth.context_processors.auth',
'django.contrib.messages.context_processors.messages',
],
},
}
]
6. 继承AppConfig类
请参考测试项目的示例应用中的以下文件
您必须在您的项目中复制并适配这些代码。
有关 AppConfig 概念的更多信息,请参阅 django 文档中的“Applications”部分。
7. 创建您的自定义模型
为了展示示例,我们在测试项目的示例应用的 models 中添加了一个简单的“详细信息”字段。
您可以在类似的 models.py 文件中添加字段。
注意:有关如何使用、扩展或开发模型的疑问,请参阅 django 文档中的“Models”部分。
8. 添加交换器配置
创建模型后,将以下内容添加到您的 settings.py
# Setting models for swapper module
FIRMWARE_UPGRADER_CATEGORY_MODEL = 'myupgrader.Category'
FIRMWARE_UPGRADER_BUILD_MODEL = 'myupgrader.Build'
FIRMWARE_UPGRADER_FIRMWAREIMAGE_MODEL = 'myupgrader.FirmwareImage'
FIRMWARE_UPGRADER_DEVICEFIRMWARE_MODEL = 'myupgrader.DeviceFirmware'
FIRMWARE_UPGRADER_BATCHUPGRADEOPERATION_MODEL = 'myupgrader.BatchUpgradeOperation'
FIRMWARE_UPGRADER_UPGRADEOPERATION_MODEL = 'myupgrader.UpgradeOperation'
将 myupgrader 替换为步骤 1 中选择的名称。
9. 创建数据库迁移
创建并应用数据库迁移
./manage.py makemigrations ./manage.py migrate
有关更多信息,请参阅 django 文档中的“Migrations”部分。
10. 创建管理员界面
请参考示例应用的 admin.py 文件。
要向管理员引入更改,您可以通过以下两种主要方式之一进行。
注意:有关 django 管理员如何工作或如何进行自定义的更多信息,请参阅 django 文档中的“The django admin site”部分。
1. Monkey修补
如果您需要添加的更改相对较小,您可以使用 monkey patching。
例如
from openwisp_firmware_upgrader.admin import ( # noqa
BatchUpgradeOperationAdmin,
BuildAdmin,
CategoryAdmin,
)
BuildAdmin.list_display.insert(1, 'my_custom_field')
BuildAdmin.ordering = ['-my_custom_field']
2. 继承admin类
如果您需要引入重大更改,并且不想使用 monkey patching,您可以按照以下步骤进行
from django.contrib import admin
from openwisp_firmware_upgrader.admin import (
BatchUpgradeOperationAdmin as BaseBatchUpgradeOperationAdmin,
BuildAdmin as BaseBuildAdmin,
CategoryAdmin as BaseCategoryAdmin,
)
from openwisp_firmware_upgrader.swapper import load_model
BatchUpgradeOperation = load_model('BatchUpgradeOperation')
Build = load_model('Build')
Category = load_model('Category')
DeviceFirmware = load_model('DeviceFirmware')
FirmwareImage = load_model('FirmwareImage')
UpgradeOperation = load_model('UpgradeOperation')
admin.site.unregister(BatchUpgradeOperation)
admin.site.unregister(Build)
admin.site.unregister(Category)
class BatchUpgradeOperationAdmin(BaseBatchUpgradeOperationAdmin):
# add your changes here
class BuildAdmin(BaseBuildAdmin):
# add your changes here
class CategoryAdmin(BaseCategoryAdmin):
# add your changes here
11. 创建根URL配置
请参考测试项目的 urls.py 文件。
有关 django 中 URL 配置的更多信息,请参阅 django 文档中的“URL dispatcher”部分。
12. 创建celery.py
请参考测试项目中 celery.py 文件。
有关 celery 在 django 中使用的更多信息,请参阅 celery 文档中的“使用 Django 的第一步”部分。
13. 导入自动化测试
在基于此模块开发自定义应用程序时,最好也导入和运行基本测试,以确保您引入的更改不会破坏 OpenWISP 固件升级器 的某些现有功能。
如果您需要添加破坏性更改,可以覆盖基本类中定义的测试以测试您自己的行为。
查看示例应用程序的测试以了解如何操作。
然后您可以使用以下命令运行测试
# the --parallel flag is optional ./manage.py test --parallel myupgrader
将 myupgrader 替换为步骤 1 中选择的名称。
有关 django 中自动化测试的更多信息,请参阅 “Django 测试”。
可以继承和扩展的其他基类
以下步骤不是必需的,而是为了更高级的定制。
FirmwareImageDownloadView
此视图控制固件镜像的存储方式以及谁有权下载它们。
完整的 Python 路径为:openwisp_firmware_upgrader.private_storage.FirmwareImageDownloadView。
如果您想扩展此视图,您必须执行以下附加步骤。
步骤 1. 导入并扩展视图
# myupgrader/views.py
from openwisp_firmware_upgrader.private_storage import (
FirmwareImageDownloadView as BaseFirmwareImageDownloadView
)
class FirmwareImageDownloadView(BaseFirmwareImageDownloadView):
# add your customizations here ...
pass
步骤 2: 从您的根 urls.py 文件中删除以下行
path('firmware/', include('openwisp_firmware_upgrader.private_storage.urls')),
步骤 3: 在 urls.py 文件中添加指向您的自定义视图的 URL 路由
# urls.py
from myupgrader.views import FirmwareImageDownloadView
urlpatterns = [
# ... other URLs
path('<your-custom-path>', FirmwareImageDownloadView.as_view(), name='serve_private_file',),
]
有关 django 视图的更多信息,请参阅 django 文档中的“基于类的视图”部分。
API视图
如果您需要自定义 API 视图的行为,所遵循的程序类似于在FirmwareImageDownloadView中描述的程序,不同之处在于您可能还需要创建自己的 序列化器(如果需要)。
API 代码存储在 openwisp_firmware_upgrader.api 中,并使用 django-rest-framework 构建。
有关 Django REST Framework API 视图的更多信息,请参阅 Django REST Framework 文档中的“通用视图”部分。
贡献
请参阅 OpenWISP 贡献指南。
支持
查看 OpenWISP 支持渠道。
变更日志
查看 变更日志。
许可证
查看 许可协议。
项目详情
下载文件
下载适合您的平台的文件。如果您不确定选择哪个,请了解更多关于 安装包 的信息。
源分布
构建分布
散列值 for openwisp_firmware_upgrader-1.0.1-py2.py3-none-any.whl
算法 | 散列摘要 | |
---|---|---|
SHA256 | 48f20c54b882917c7631681689f5b83c62807378d94d0fd4b79a5d5c1db776a5 |
|
MD5 | d156dd3c0771e7f68a23ab79eb822abf |
|
BLAKE2b-256 | cc97cb6f2fa40eb3e72578fd06af07db61047e5ec60f4035b6cc5c1a3b80d835 |