mirror of
https://github.com/genodelabs/genode.git
synced 2024-12-21 14:37:50 +00:00
depot_download: produce 'state' report
The state report reflects the progress of downloading, verifying, and extracting archives. For the download step, it includes the progress as reported by fetchurl.
This commit is contained in:
parent
a529a35ce6
commit
c21e5863b9
@ -32,6 +32,8 @@
|
||||
report="dynamic -> state"/>
|
||||
<policy label="manager -> verified"
|
||||
report="dynamic -> verify -> result"/>
|
||||
<policy label="manager -> fetchurl_progress"
|
||||
report="dynamic -> fetchurl -> progress"/>
|
||||
</config>
|
||||
</start>
|
||||
|
||||
@ -81,11 +83,13 @@
|
||||
<resource name="RAM" quantum="1M"/>
|
||||
<config/>
|
||||
<route>
|
||||
<service name="Report" label="state"> <parent label="state"/> </service>
|
||||
<service name="Report"> <child name="report_rom"/> </service>
|
||||
<service name="ROM" label="dependencies"> <child name="report_rom"/> </service>
|
||||
<service name="ROM" label="user"> <child name="report_rom"/> </service>
|
||||
<service name="ROM" label="init_state"> <child name="report_rom"/> </service>
|
||||
<service name="ROM" label="verified"> <child name="report_rom"/> </service>
|
||||
<service name="ROM" label="dependencies"> <child name="report_rom"/> </service>
|
||||
<service name="ROM" label="user"> <child name="report_rom"/> </service>
|
||||
<service name="ROM" label="init_state"> <child name="report_rom"/> </service>
|
||||
<service name="ROM" label="verified"> <child name="report_rom"/> </service>
|
||||
<service name="ROM" label="fetchurl_progress"> <child name="report_rom"/> </service>
|
||||
<any-service> <parent/> <any-child/> </any-service>
|
||||
</route>
|
||||
</start>
|
||||
@ -95,7 +99,6 @@
|
||||
<binary name="init"/>
|
||||
<route>
|
||||
<service name="ROM" label="config"> <child name="report_rom"/> </service>
|
||||
<service name="Report" label="fetchurl -> progress"> <parent/> </service>
|
||||
<service name="Report"> <child name="report_rom"/> </service>
|
||||
<service name="File_system" label="depot"> <child name="depot_ro"/> </service>
|
||||
<service name="File_system" label="depot_rw"> <parent label="depot"/> </service>
|
||||
|
@ -102,6 +102,7 @@ append config {
|
||||
<route>
|
||||
<service name="ROM" label="config">
|
||||
<parent label="depot_download.config"/> </service>
|
||||
<service name="Report"> <child name="report_rom"/> </service>
|
||||
<service name="File_system"> <child name="vfs"/> </service>
|
||||
<any-service> <parent/> <any-child/> </any-service>
|
||||
</route>
|
||||
|
@ -16,6 +16,7 @@
|
||||
|
||||
/* Genode includes */
|
||||
#include <util/xml_node.h>
|
||||
#include <util/xml_generator.h>
|
||||
#include <base/registry.h>
|
||||
#include <base/allocator.h>
|
||||
|
||||
@ -29,6 +30,22 @@ namespace Depot_download_manager {
|
||||
|
||||
class Depot_download_manager::Import
|
||||
{
|
||||
public:
|
||||
|
||||
/**
|
||||
* Interface for obtaining the download progress for a given archive
|
||||
*/
|
||||
struct Download_progress : Interface
|
||||
{
|
||||
struct Info
|
||||
{
|
||||
typedef String<32> Bytes;
|
||||
Bytes total, now;
|
||||
};
|
||||
|
||||
virtual Info download_progress(Archive::Path const &) const = 0;
|
||||
};
|
||||
|
||||
private:
|
||||
|
||||
struct Item
|
||||
@ -49,6 +66,18 @@ class Depot_download_manager::Import
|
||||
:
|
||||
_element(registry, *this), path(path)
|
||||
{ }
|
||||
|
||||
char const *state_text() const
|
||||
{
|
||||
switch (state) {
|
||||
case DOWNLOAD_IN_PROGRESS: return "download";
|
||||
case DOWNLOAD_COMPLETE: return "verify";
|
||||
case VERIFIED: return "extract";
|
||||
case VERIFICATION_FAILED: return "verification failed";
|
||||
case UNPACKED: return "done";
|
||||
};
|
||||
return "";
|
||||
}
|
||||
};
|
||||
|
||||
Allocator &_alloc;
|
||||
@ -171,6 +200,23 @@ class Depot_download_manager::Import
|
||||
if (item.state == Item::VERIFIED)
|
||||
item.state = Item::UNPACKED; });
|
||||
}
|
||||
|
||||
void report(Xml_generator &xml, Download_progress const &progress) const
|
||||
{
|
||||
_items.for_each([&] (Item const &item) {
|
||||
xml.node("archive", [&] () {
|
||||
xml.attribute("path", item.path);
|
||||
xml.attribute("state", item.state_text());
|
||||
|
||||
if (item.state == Item::DOWNLOAD_IN_PROGRESS) {
|
||||
Download_progress::Info const info =
|
||||
progress.download_progress(item.path);
|
||||
xml.attribute("total", info.total);
|
||||
xml.attribute("now", info.now);
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
#endif /* _IMPORT_H_ */
|
||||
|
@ -50,15 +50,16 @@ struct Depot_download_manager::Child_exit_state
|
||||
};
|
||||
|
||||
|
||||
struct Depot_download_manager::Main
|
||||
struct Depot_download_manager::Main : Import::Download_progress
|
||||
{
|
||||
Env &_env;
|
||||
|
||||
Heap _heap { _env.ram(), _env.rm() };
|
||||
|
||||
Attached_rom_dataspace _installation { _env, "installation" };
|
||||
Attached_rom_dataspace _dependencies { _env, "dependencies" };
|
||||
Attached_rom_dataspace _init_state { _env, "init_state" };
|
||||
Attached_rom_dataspace _installation { _env, "installation" };
|
||||
Attached_rom_dataspace _dependencies { _env, "dependencies" };
|
||||
Attached_rom_dataspace _init_state { _env, "init_state" };
|
||||
Attached_rom_dataspace _fetchurl_progress { _env, "fetchurl_progress" };
|
||||
|
||||
/**
|
||||
* User identity, from which current downloads are fetched
|
||||
@ -89,6 +90,8 @@ struct Depot_download_manager::Main
|
||||
|
||||
Expanding_reporter _init_config { _env, "config", "init_config" };
|
||||
|
||||
Expanding_reporter _state_reporter { _env, "state", "state" };
|
||||
|
||||
/**
|
||||
* Version counters, used to enforce the restart or reconfiguration of
|
||||
* components.
|
||||
@ -100,6 +103,32 @@ struct Depot_download_manager::Main
|
||||
|
||||
Constructible<Import> _import { };
|
||||
|
||||
/**
|
||||
* Download_progress interface
|
||||
*/
|
||||
Info download_progress(Archive::Path const &path) const
|
||||
{
|
||||
Info result { Info::Bytes(), Info::Bytes() };
|
||||
try {
|
||||
Url const url_path(_current_user_url(), "/", path, ".tar.xz");
|
||||
|
||||
/* search fetchurl progress report for matching 'url_path' */
|
||||
_fetchurl_progress.xml().for_each_sub_node("fetch", [&] (Xml_node fetch) {
|
||||
if (fetch.attribute_value("url", Url()) == url_path)
|
||||
result = { .total = fetch.attribute_value("total", Info::Bytes()),
|
||||
.now = fetch.attribute_value("now", Info::Bytes()) }; });
|
||||
|
||||
} catch (Invalid_download_url) { }
|
||||
return result;
|
||||
}
|
||||
|
||||
void _update_state_report()
|
||||
{
|
||||
_state_reporter.generate([&] (Xml_generator &xml) {
|
||||
if (_import.constructed())
|
||||
_import->report(xml, *this); });
|
||||
}
|
||||
|
||||
void _generate_init_config(Xml_generator &);
|
||||
|
||||
void _generate_init_config()
|
||||
@ -127,13 +156,23 @@ struct Depot_download_manager::Main
|
||||
|
||||
void _handle_init_state();
|
||||
|
||||
Signal_handler<Main> _fetchurl_progress_handler {
|
||||
_env.ep(), *this, &Main::_handle_fetchurl_progress };
|
||||
|
||||
void _handle_fetchurl_progress()
|
||||
{
|
||||
_fetchurl_progress.update();
|
||||
_update_state_report();
|
||||
}
|
||||
|
||||
Main(Env &env) : _env(env)
|
||||
{
|
||||
_dependencies.sigh(_query_result_handler);
|
||||
_current_user.sigh(_query_result_handler);
|
||||
_init_state .sigh(_init_state_handler);
|
||||
_verified .sigh(_init_state_handler);
|
||||
_installation.sigh(_installation_handler);
|
||||
_dependencies .sigh(_query_result_handler);
|
||||
_current_user .sigh(_query_result_handler);
|
||||
_init_state .sigh(_init_state_handler);
|
||||
_verified .sigh(_init_state_handler);
|
||||
_installation .sigh(_installation_handler);
|
||||
_fetchurl_progress.sigh(_fetchurl_progress_handler);
|
||||
|
||||
_generate_init_config();
|
||||
}
|
||||
@ -225,6 +264,7 @@ void Depot_download_manager::Main::_handle_query_result()
|
||||
|
||||
if (!dependencies.has_sub_node("missing")) {
|
||||
log("installation complete.");
|
||||
_update_state_report();
|
||||
return;
|
||||
}
|
||||
|
||||
@ -241,6 +281,7 @@ void Depot_download_manager::Main::_handle_query_result()
|
||||
|
||||
/* start new import */
|
||||
_import.construct(_heap, _current_user_name(), _dependencies.xml());
|
||||
_update_state_report();
|
||||
|
||||
/* spawn fetchurl */
|
||||
_generate_init_config();
|
||||
@ -324,6 +365,10 @@ void Depot_download_manager::Main::_handle_init_state()
|
||||
}
|
||||
}
|
||||
|
||||
/* report before destructing '_import' to avoid empty intermediate reports */
|
||||
if (reconfigure_init)
|
||||
_update_state_report();
|
||||
|
||||
if (import_finished)
|
||||
_import.destruct();
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user