stephb9959
2023-02-08 20:38:05 -08:00
parent 865ad612e6
commit cb2f9a91b5
7 changed files with 187 additions and 7 deletions

2
build
View File

@@ -1 +1 @@
11
12

View File

@@ -2525,6 +2525,17 @@ paths:
type: boolean
default: false
required: false
- in: query
name: revisionsAvailable
schema:
type: boolean
default: false
required: false
- in: query
name: revision
schema:
type: string
required: false
requestBody:
description: Information used to modify the new venue
content:

View File

@@ -208,6 +208,52 @@ namespace OpenWifi{
InternalError(RESTAPI::Errors::RecordNotCreated);
}
/*
* Get all the device types for the devices in the venue
* For each unique device type, get all the firmwares that apply for it
* create the intersection of all resulting firmwares
* create a list ordered in 3 types
* - Releases
* - RC of releases
* - Dev
*
* We obtain the revision by stripping and trimming the revision field previous to the "/"
* The sets should be built on the revision and the URI of the images, all per devicetype
*/
enum class RevisionTypes {
release,
release_candidate,
development
};
RevisionTypes RevisionIdentify(const std::string &r) {
auto it = r.find_first_of('/');
if(it==std::string::npos) {
return RevisionTypes::development;
}
++it;
if(r.find("TIP-devel-", it)!=std::string::npos) {
return RevisionTypes::development;
}
if(r.find("-rc", it)!=std::string::npos) {
return RevisionTypes::release_candidate;
}
if(r.find("TIP-v", it)!=std::string::npos) {
return RevisionTypes::release;
}
return RevisionTypes::development;
}
std::uint64_t RevisionDate(const std::string &R, const std::vector<FMSObjects::Firmware> &F) {
for(const auto &f:F) {
if(f.revision==R)
return f.imageDate;
}
return 0;
}
void RESTAPI_venue_handler::DoPut() {
std::string UUID = GetBinding("uuid", "");
@@ -241,12 +287,92 @@ namespace OpenWifi{
}
if(GetBoolParameter("upgradeAllDevices")) {
if(GetBoolParameter("revisionsAvailable")) {
std::set<std::string> DeviceTypes;
for (const auto &serialNumber: Existing.devices) {
ProvObjects::InventoryTag Device;
if (StorageService()->InventoryDB().GetRecord("serialNumber", serialNumber, Device)) {
DeviceTypes.insert(Device.deviceType);
}
}
// Get all the revisions for all the device types
using FirmwareList = std::vector<FMSObjects::Firmware>;
using FirmwareRevisions = std::set<std::string>;
std::map<std::string, FirmwareList> AllFMs;
FirmwareRevisions AllRevisions;
bool first_pass = true;
for (const auto &device_type: DeviceTypes) {
FirmwareList list;
if (SDK::FMS::Firmware::GetDeviceTypeFirmwares(device_type, list)) {
AllFMs[device_type] = list;
FirmwareRevisions DeviceRevisions;
if (first_pass) {
for (const auto &revision: list) {
AllRevisions.insert(revision.revision);
}
} else {
FirmwareRevisions DeviceTypeRevisions;
for (const auto &revision: list) {
DeviceTypeRevisions.insert(revision.revision);
}
FirmwareRevisions NewRevisions;
std::set_intersection(AllRevisions.begin(), AllRevisions.end(),
DeviceTypeRevisions.begin(), DeviceTypeRevisions.end(),
std::inserter(NewRevisions, NewRevisions.begin()));
AllRevisions = NewRevisions;
}
}
first_pass = false;
}
// OK we start the solution map with Our first device, and then we
Poco::JSON::Array Releases, ReleaseCandidates, DevelReleases;
for (const auto &revision: AllRevisions) {
auto Date = AllFMs.begin()->second.begin()->imageDate;
switch (RevisionIdentify(revision)) {
case RevisionTypes::release_candidate: {
Poco::JSON::Object E;
E.set("revision",revision);
E.set("date",Date);
ReleaseCandidates.add(E);
}
break;
case RevisionTypes::release: {
Poco::JSON::Object E;
E.set("revision",revision);
E.set("date",Date);
Releases.add(E);
}
break;
case RevisionTypes::development:
default: {
Poco::JSON::Object E;
E.set("revision",revision);
E.set("date",Date);
DevelReleases.add(E);
}
}
}
Poco::JSON::Object Answer;
Answer.set("releases", Releases);
Answer.set("releasesCandidates", ReleaseCandidates);
Answer.set("releases", DevelReleases);
return ReturnObject(Answer);
}
ProvObjects::SerialNumberList SNL;
auto Revision = GetParameter("revision","");
if(Revision.empty()) {
return BadRequest(RESTAPI::Errors::MissingOrInvalidParameters);
}
Poco::JSON::Object Answer;
SNL.serialNumbers = Existing.devices;
auto JobId = MicroServiceCreateUUID();
Types::StringVec Parameters{UUID};;
Types::StringVec Parameters{UUID, Revision};;
auto NewJob = new VenueUpgrade(JobId,"VenueFirmwareUpgrade", Parameters, 0, UserInfo_.userinfo, Logger());
JobController()->AddJob(dynamic_cast<Job*>(NewJob));
SNL.to_json(Answer);

View File

@@ -15,9 +15,10 @@
namespace OpenWifi {
class VenueDeviceUpgrade : public Poco::Runnable {
public:
VenueDeviceUpgrade(const std::string &UUID, const std::string &venue, const ProvObjects::DeviceRules &Rules, Poco::Logger &L) :
VenueDeviceUpgrade(const std::string &UUID, const std::string &venue, const std::string &revision, const ProvObjects::DeviceRules &Rules, Poco::Logger &L) :
uuid_(UUID),
venue_(venue),
revision_(revision),
rules_(Rules),
Logger_(L) {
}
@@ -37,12 +38,12 @@ namespace OpenWifi {
}
FMSObjects::Firmware F;
if(SDK::FMS::Firmware::GetLatest(Device.deviceType,Device.deviceRules.rcOnly=="yes",F)) {
if(SDK::FMS::Firmware::GetFirmware(Device.deviceType,revision_,F)) {
if (SDK::GW::Device::Upgrade(nullptr, Device.serialNumber, 0, F.uri)) {
Logger().debug(fmt::format("{}: Upgraded.",Device.serialNumber));
Logger().debug(fmt::format("{}: Upgraded to {}.",Device.serialNumber, revision_));
upgraded_++;
} else {
poco_information(Logger(),fmt::format("{}: Not Upgraded.", Device.serialNumber));
poco_information(Logger(),fmt::format("{}: Not Upgraded to {}.", Device.serialNumber, revision_));
not_connected_++;
}
} else {
@@ -65,6 +66,7 @@ namespace OpenWifi {
private:
std::string uuid_;
std::string venue_;
std::string revision_;
ProvObjects::DeviceRules rules_;
Poco::Logger &Logger_;
inline Poco::Logger & Logger() { return Logger_; }
@@ -81,6 +83,7 @@ namespace OpenWifi {
Utils::SetThreadName("venue-upgr");
auto VenueUUID_ = Parameter(0);
auto Revision_ = Parameter(1);
ProvWebSocketNotifications::VenueFWUpgradeList_t N;
@@ -101,7 +104,7 @@ namespace OpenWifi {
StorageService()->VenueDB().EvaluateDeviceRules(Venue.info.id, Rules);
for(const auto &uuid:Venue.devices) {
auto NewTask = new VenueDeviceUpgrade(uuid, Venue.info.name, Rules, Logger());
auto NewTask = new VenueDeviceUpgrade(uuid, Venue.info.name, Revision_, Rules, Logger());
bool TaskAdded = false;
while (!TaskAdded) {
if (Pool_.available()) {

View File

@@ -251,6 +251,7 @@ namespace OpenWifi::RESTAPI::Errors {
static const struct msg CertificateTransferEntityNoLongerExists{1167,"The entity tied to this transfer no longer seems to exist."};
static const struct msg CannotRollBackDueToDigiCert{1168,"The change could not be rolled back at this time. Please try later."};
static const struct msg CertificateTransferAlreadyRolledBack{1169,"The certificate has already been rolled back."};
static const struct msg FirmwareBDInProgress{1170,"Firmware DB update already in progress."};
}

View File

@@ -32,6 +32,43 @@ namespace OpenWifi::SDK::FMS {
return false;
}
bool GetDeviceTypeFirmwares(const std::string &device_type, std::vector<FMSObjects::Firmware> & FirmWares) {
static const std::string EndPoint{"/api/v1/firmwares"};
OpenWifi::OpenAPIRequestGet API( uSERVICE_FIRMWARE,
EndPoint,
{
{ "deviceType", device_type}
},
50000);
auto CallResponse = Poco::makeShared<Poco::JSON::Object>();
auto StatusCode = API.Do(CallResponse);
if( StatusCode == Poco::Net::HTTPResponse::HTTP_OK) {
Poco::JSON::Array::Ptr FirmwareArr = CallResponse->getArray("firmwares");
for(uint64_t i=0;i<FirmwareArr->size();i++) {
FMSObjects::Firmware F;
F.from_json(FirmwareArr->getObject(i));
FirmWares.emplace_back(F);
}
return true;
}
return false;
}
bool GetFirmware(const std::string &device_type, const std::string & revision, FMSObjects::Firmware & Firmware) {
std::vector<FMSObjects::Firmware> Firmwares;
if(GetDeviceTypeFirmwares(device_type,Firmwares)) {
for(const auto &firmware:Firmwares) {
if(firmware.revision==revision) {
Firmware = firmware;
return true;
}
}
}
return false;
}
}
};

View File

@@ -10,6 +10,8 @@ namespace OpenWifi::SDK::FMS {
namespace Firmware {
bool GetLatest(const std::string &device_type, bool RCOnly, FMSObjects::Firmware & FirmWare);
bool GetDeviceTypeFirmwares(const std::string &device_type, std::vector<FMSObjects::Firmware> & FirmWares);
bool GetFirmware(const std::string &device_type, const std::string & revision, FMSObjects::Firmware & FirmWare);
}
};