genode/repos/gems/include/depot/archive.h
Norman Feske ac68073ffc depot_download: support downloading index files
With this commit, the 'installation' input of the depot-download
subsystem accepts <index> nodes in addition to <archive> nodes. Each
index node refers to one index file specified via the 'path' attribute.

This commit also improves the tracking of failure states. Once an
installation job failed (due to a download of verification error),
it won't get re-scheduled. In the past, such failure states were not kept
across subsequent import iterations, which could result in infinite
re-attempts when an installation contained archives from multiple users.
The the progress of the download process is now reflected by the
"progress" attribute on the download manager's state report, which
allows the final report to contain the list of installed/failed archives
along with the overall progress/completed state. The detection of the
latter is important for the sculpt manager for reattempting the
deployment of the completed packages.

The patch enhances the depot_download.run script to stress the new
abilities. In particular, the scenario downloads a mix of index files
(one present, one missing) and archives, from two different depot users
(genodelabs and nfeske).

Issue #3172
2019-02-28 11:34:06 +01:00

118 lines
2.5 KiB
C++

/*
* \brief Utilities to handle depot-archive paths
* \author Norman Feske
* \date 2017-12-18
*/
/*
* Copyright (C) 2017 Genode Labs GmbH
*
* This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU Affero General Public License version 3.
*/
#ifndef _INCLUDE__DEPOT__ARCHIVE_H_
#define _INCLUDE__DEPOT__ARCHIVE_H_
/* Genode includes */
#include <util/string.h>
namespace Depot {
using namespace Genode;
struct Archive;
}
struct Depot::Archive
{
typedef String<100> Path;
typedef String<64> User;
typedef String<80> Name;
typedef String<40> Version;
enum Type { PKG, RAW, SRC };
struct Unknown_archive_type : Exception { };
/**
* Return Nth path element
*
* The first path element corresponds to n == 0.
*/
template <typename STRING>
static STRING _path_element(Path const &path, unsigned n)
{
char const *s = path.string();
/* skip 'n' path elements */
for (; n > 0; n--) {
/* search '/' */
while (*s && *s != '/')
s++;
if (*s == 0)
return STRING();
/* skip '/' */
s++;
}
/* find '/' marking the end of the path element */
unsigned i = 0;
while (s[i] != 0 && s[i] != '/')
i++;
return STRING(Cstring(s, i));
}
/**
* Return archive user of depot-local path
*/
static User user(Path const &path) { return _path_element<User>(path, 0); }
/**
* Return archive type of depot-local path
*
* \throw Unknown_archive_type
*/
static Type type(Path const &path)
{
typedef String<8> Name;
Name const name = _path_element<Name>(path, 1);
if (name == "src") return SRC;
if (name == "pkg") return PKG;
if (name == "raw") return RAW;
throw Unknown_archive_type();
}
/**
* Return true if 'path' refers to an index file
*/
static bool index(Path const &path)
{
return _path_element<Name>(path, 1) == "index";
}
static Name name (Path const &path) { return _path_element<Name>(path, 2); }
static Version version (Path const &path) { return _path_element<Version>(path, 3); }
static Version index_version(Path const &path) { return _path_element<Version>(path, 2); }
/**
* Return name of compressed file to download for the given depot path
*
* Archives are shipped as tar.xz files whereas index files are shipped
* as xz-compressed files.
*/
static Archive::Path download_file_path(Archive::Path path)
{
return Archive::index(path) ? Archive::Path(path, ".xz")
: Archive::Path(path, ".tar.xz");
}
};
#endif /* _INCLUDE__DEPOT__ARCHIVE_H_ */