Add third-party skeletal features

This PR starts the third-party repo-add, delete, list skeletal features
for swupd. This PR also add support for configure flag
to build third-party optionally for swupd, off by default.

Repo Add:
 sudo swupd 3rd-party add <repo_name> <URL>
Repo Remove:
 sudo swupd 3rd-party remove <repo_name>
Repos List:
 sudo swupd 3rd-party list

Signed-off-by: Karthik Prabhu Vinod <karthik.prabhu.vinod@intel.com>
This commit is contained in:
Karthik Prabhu Vinod
2019-10-31 10:23:00 -07:00
parent bf4cdc03a0
commit 8069064c43
12 changed files with 526 additions and 33 deletions
+1 -1
View File
@@ -80,7 +80,7 @@ install:
# Ubuntu's default umask is 0002, but this break's swupd hash calculations.
before_script:
- autoreconf --verbose --warnings=none --install --force
- ./configure CFLAGS="$CFLAGS -fsanitize=address -Werror" --prefix=/usr --with-fallback-capaths=$TRAVIS_BUILD_DIR/swupd_test_certificates --with-systemdsystemunitdir=/usr/lib/systemd/system --with-config-file-path=./testconfig
- ./configure CFLAGS="$CFLAGS -fsanitize=address -Werror" --prefix=/usr --enable-third-party --with-fallback-capaths=$TRAVIS_BUILD_DIR/swupd_test_certificates --with-systemdsystemunitdir=/usr/lib/systemd/system --with-config-file-path=./testconfig
- sudo find test/functional -exec chmod g-w {} \;
- make &&
sudo sh -c 'umask 0022 && make install' &&
+5
View File
@@ -32,6 +32,11 @@ bin_PROGRAMS = swupd
AM_CPPFLAGS = $(AM_CFLAGS) $(libarchive_CFLAGS)
swupd_SOURCES = \
src/3rd_party_add.c \
src/3rd_party.c \
src/3rd_party_internal.h \
src/3rd_party_list.c \
src/3rd_party_remove.c \
src/alias.c \
src/alias.h \
src/autoupdate.c \
+20
View File
@@ -72,6 +72,25 @@ AS_IF(
[SIGVERIFICATION="no"]
)
AC_ARG_ENABLE(
[third-party],
[AS_HELP_STRING([--enable-third-party], [Enable 3rd-party (disabled by default)])]
)
THIRDPARTY="no"
AS_IF(
[test "x$enable_third_party" = "xyes"],
[AC_DEFINE(THIRDPARTY, 1, [Enable third party])
THIRDPARTY="yes"],
[THIRDPARTY="no"]
)
AH_TEMPLATE([THIRDPARTY_REPO_PREFIX], [prefix path for third party repos])
AS_IF(
[test "$enable_third_party" = "yes"],
[AC_DEFINE([THIRDPARTY_REPO_PREFIX], ["/opt/user-repo/"])]
)
AC_ARG_ENABLE(
[tests],
[AS_HELP_STRING([--disable-tests], [Do not enable unit or functional test framework (enabled by default)])]
@@ -383,6 +402,7 @@ Configuration to build swupd-client:
Version URL: ${VERSIONURL}
Format Identifier: ${FORMATID}
Signature verification: ${SIGVERIFICATION}
Third party: ${THIRDPARTY}
Update certificate path: ${cert_path}
Configuration file path(s): ${config_file_path}
Use bzip compression: ${BZIP}
+110
View File
@@ -0,0 +1,110 @@
/*
* Software Updater - client side
*
* Copyright © 2019 Intel Corporation.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, version 2 or later of the License.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#define _GNU_SOURCE
#include "config.h"
#include "swupd.h"
#include "swupd_internal.h"
#ifdef THIRDPARTY
static struct subcmd third_party_commands[] = {
{ "add", "Add third party repo", third_party_add_main },
{ "remove", "Remove third party repo", third_party_remove_main },
{ "list", "List third party repo", third_party_list_main },
{ 0 }
};
static void print_help(const char *name)
{
print("Usage:\n");
print(" or %s SUBCOMMAND [OPTION...]\n\n", basename((char *)name));
print("Help Options:\n");
print(" -h, --help Show help options\n");
print("Subcommands:\n");
struct subcmd *entry = third_party_commands;
while (entry->name != NULL) {
print(" %-20s %-30s\n", entry->name, entry->doc);
entry++;
}
print("\n");
print("To view subcommand options, run `%s SUBCOMMAND --help'\n", basename((char *)name));
}
static const struct option prog_opts[] = {
{ "help", no_argument, 0, 'h' },
{ 0 }
};
static int parse_options(int argc, char **argv, int *index)
{
int opt;
int ret;
/* The leading "-" in the optstring is required to preserve option parsing order */
while ((opt = getopt_long(argc, argv, "-h", prog_opts, NULL)) != -1) {
switch (opt) {
case 'h':
print_help(argv[0]);
exit(EXIT_SUCCESS);
case '\01':
/* found a subcommand, or a random non-option argument */
ret = subcmd_index(optarg, third_party_commands);
if (ret < 0) {
error("unrecognized subcommand `%s'\n\n",
optarg);
goto error;
} else {
*index = ret;
return 0;
}
case '?':
/* for unknown options, an error message is printed automatically */
info("\n");
goto error;
default:
/* should be unreachable */
break;
}
}
/* no subcommands implies -h/--help */
print_help(argv[0]);
exit(EXIT_SUCCESS);
error:
print_help(argv[0]);
return -1;
}
enum swupd_code third_party_main(int argc, char **argv)
{
int index = 0, ret;
if (parse_options(argc, argv, &index) < 0) {
return SWUPD_INVALID_OPTION;
}
optind = 0;
ret = third_party_commands[index].mainfunc(argc - 1, argv + 1);
return ret;
}
#endif
+94
View File
@@ -0,0 +1,94 @@
/*
* Software Updater - client side
*
* Copyright © 2019 Intel Corporation.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, version 2 or later of the License.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#define _GNU_SOURCE
#include "3rd_party_internal.h"
#include "config.h"
#ifdef THIRDPARTY
static void print_help(void)
{
print("Usage:\n");
print(" swupd 3rd-party add [repo-name] [repo-URL]\n\n");
global_print_help();
print("\n");
}
static const struct global_options opts = {
NULL,
0,
NULL,
print_help,
};
static bool parse_options(int argc, char **argv)
{
#define EXACT_ARG_COUNT 2
int ind = global_parse_options(argc, argv, &opts);
if (ind < 0) {
return false;
}
if (argc == 1) {
error("The positional args: repo-name and URL are missing\n\n");
return false;
} else if (argc == 2) {
error("The positional args: repo-URL is missing\n\n");
return false;
}
/* Ensure that repo add only expects only two args: repo-name, repo-url */
if ((argc - ind) != EXACT_ARG_COUNT) {
error("Unexpected arguments\n\n");
return false;
}
return true;
}
enum swupd_code third_party_add_main(int argc, char **argv)
{
enum swupd_code ret = SWUPD_OK;
const int step_in_third_party_add = 1;
if (!parse_options(argc, argv)) {
print_help();
return SWUPD_INVALID_OPTION;
}
progress_init_steps("third-party", step_in_third_party_add);
ret = swupd_init(SWUPD_NO_ROOT);
if (ret != SWUPD_OK) {
goto finish;
}
/* TODO implement */
swupd_deinit();
finish:
progress_finish_steps(ret);
return ret;
}
#endif
+26
View File
@@ -0,0 +1,26 @@
#ifndef __THIRD_PARTY_INTERNAL_H
#define __THIRD_PARTY_INTERNAL_H
#include "swupd.h"
/**
* @file
* @brief Common functions which can be used by 3rd-party add,
* remove, list
*/
#ifdef __cplusplus
extern "C" {
#endif
#ifdef THIRDPARTY
/* TODO Implement */
#endif
#ifdef __cplusplus
}
#endif
#endif
+83
View File
@@ -0,0 +1,83 @@
/*
* Software Updater - client side
*
* Copyright © 2019 Intel Corporation.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, version 2 or later of the License.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#define _GNU_SOURCE
#include "3rd_party_internal.h"
#include "config.h"
#ifdef THIRDPARTY
static void print_help(void)
{
print("Usage:\n");
print(" swupd 3rd-party list\n\n");
global_print_help();
print("\n");
}
static const struct global_options opts = {
NULL,
0,
NULL,
print_help,
};
static bool parse_options(int argc, char **argv)
{
int ind = global_parse_options(argc, argv, &opts);
if (ind < 0) {
return false;
}
if (argc > ind) {
error("Unexpected arguments\n\n");
return false;
}
return true;
}
enum swupd_code third_party_list_main(int argc, char **argv)
{
enum swupd_code ret = SWUPD_OK;
const int step_in_third_party_list = 1;
if (!parse_options(argc, argv)) {
print_help();
return SWUPD_INVALID_OPTION;
}
progress_init_steps("third-party", step_in_third_party_list);
ret = swupd_init(SWUPD_NO_ROOT);
if (ret != SWUPD_OK) {
goto finish;
}
/* TODO Implement */
swupd_deinit();
finish:
progress_finish_steps(ret);
return ret;
}
#endif
+90
View File
@@ -0,0 +1,90 @@
/*
* Software Updater - client side
*
* Copyright © 2019 Intel Corporation.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, version 2 or later of the License.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#define _GNU_SOURCE
#include "3rd_party_internal.h"
#include "config.h"
#ifdef THIRDPARTY
static void print_help(void)
{
print("Usage:\n");
print(" swupd 3rd-party remove [repo-name]\n\n");
global_print_help();
print("\n");
}
static const struct global_options opts = {
NULL,
0,
NULL,
print_help,
};
static bool parse_options(int argc, char **argv)
{
#define EXACT_ARG_COUNT 1
int ind = global_parse_options(argc, argv, &opts);
if (ind < 0) {
return false;
}
if (argc == 1) {
error("The positional args: repo-name is missing\n\n");
return false;
}
/* Ensure that repo remove only expects only one arg: repo-name */
if ((argc - ind) != EXACT_ARG_COUNT) {
error("Unexpected arguments\n\n");
return false;
}
return true;
}
enum swupd_code third_party_remove_main(int argc, char **argv)
{
enum swupd_code ret = SWUPD_OK;
const int step_in_third_party_remove = 1;
if (!parse_options(argc, argv)) {
print_help();
return SWUPD_INVALID_OPTION;
}
progress_init_steps("third-party", step_in_third_party_remove);
ret = swupd_init(SWUPD_NO_ROOT);
if (ret != SWUPD_OK) {
goto finish;
}
/* TODO Implement */
swupd_deinit();
finish:
progress_finish_steps(ret);
return ret;
}
#endif
+4 -31
View File
@@ -28,12 +28,6 @@
#include "swupd_build_opts.h"
#include "swupd_internal.h"
struct subcmd {
char *name;
char *doc;
enum swupd_code (*mainfunc)(int, char **);
};
static enum swupd_code external_search_main(int argc, char **argv)
{
int ret;
@@ -49,7 +43,7 @@ static enum swupd_code external_search_main(int argc, char **argv)
// TODO(castulo): remove the superseded command from the help menu by end of November 2019,
// so it is not visible but the command must remain available in the back so we don't break users
static struct subcmd commands[] = {
static struct subcmd main_commands[] = {
{ "info", "Show the version and the update URLs", info_main },
{ "autoupdate", "Enable/disable automatic system updates", autoupdate_main },
{ "check-update", "Check if a new OS version is available", check_update_main },
@@ -91,7 +85,7 @@ static void print_help(const char *name)
print(" -v, --version Output version information and exit\n\n");
print("Subcommands:\n");
struct subcmd *entry = commands;
struct subcmd *entry = main_commands;
while (entry->name != NULL) {
print(" %-20s %-30s\n", entry->name, entry->doc);
@@ -115,27 +109,6 @@ static void print_compile_opts(void)
info("Compile-time configuration:\n%s\n", BUILD_CONFIGURE);
}
static int subcmd_index(char *arg)
{
struct subcmd *entry = commands;
int i = 0;
size_t input_len;
size_t cmd_len;
input_len = strlen(arg);
while (entry->name != NULL) {
cmd_len = strlen(entry->name);
if (cmd_len == input_len && strcmp(arg, entry->name) == 0) {
return i;
}
entry++;
i++;
}
return -1;
}
static int parse_options(int argc, char **argv, int *index)
{
int opt;
@@ -153,7 +126,7 @@ static int parse_options(int argc, char **argv, int *index)
exit(EXIT_SUCCESS);
case '\01':
/* found a subcommand, or a random non-option argument */
ret = subcmd_index(optarg);
ret = subcmd_index(optarg, main_commands);
if (ret < 0) {
error("unrecognized subcommand `%s'\n\n",
optarg);
@@ -204,7 +177,7 @@ int main(int argc, char **argv)
*/
optind = 0;
ret = commands[index].mainfunc(argc - 1, argv + 1);
ret = main_commands[index].mainfunc(argc - 1, argv + 1);
return ret;
}
+54
View File
@@ -1,6 +1,9 @@
#ifndef __SWUPD_INTERNAL__
#define __SWUPD_INTERNAL__
#include <stddef.h>
#include <string.h>
#ifdef __cplusplus
extern "C" {
#endif
@@ -22,6 +25,57 @@ enum swupd_code repair_main(int argc, char **argv);
enum swupd_code diagnose_main(int argc, char **argv);
enum swupd_code bundle_info_main(int argc, char **argv);
enum swupd_code verify_main(int argc, char **argv);
enum swupd_code third_party_main(int argc, char **argv);
/**
* @brief Creates a new third-party repo under THIRDPARTY_REPO_PREFIX
* if it does not exist
*
* @return SWUPD_OK on success
*/
extern enum swupd_code third_party_add_main(int argc, char **argv);
/**
* @brief Removes a third-party repo under THIRDPARTY_REPO_PREFIX
* if it does exist
*
* @return SWUPD_OK on success
*/
extern enum swupd_code third_party_remove_main(int argc, char **argv);
/**
* @brief Lists all the third-party repos under THIRDPARTY_REPO_PREFIX
*
* @return SWUPD_OK on success
*/
extern enum swupd_code third_party_list_main(int argc, char **argv);
struct subcmd {
char *name;
char *doc;
enum swupd_code (*mainfunc)(int, char **);
};
static inline int subcmd_index(char *arg, struct subcmd *commands)
{
struct subcmd *entry = commands;
int i = 0;
size_t input_len;
size_t cmd_len;
input_len = strlen(arg);
while (entry->name != NULL) {
cmd_len = strlen(entry->name);
if (cmd_len == input_len && strcmp(arg, entry->name) == 0) {
return i;
}
entry++;
i++;
}
return -1;
}
#ifdef __cplusplus
}
+12 -1
View File
@@ -28,7 +28,9 @@ _swupd()
for ((i=COMP_CWORD-1;i>=0;i--))
do case "${COMP_WORDS[$i]}" in
("$1")
opts="--help --version autoupdate bundle-add bundle-remove bundle-list hashdump update diagnose check-update search search-file info clean mirror os-install repair verify "
opts="--help --version autoupdate bundle-add bundle-remove
bundle-list hashdump update diagnose check-update search
search-file info clean mirror os-install repair verify 3rd-party"
break;;
("info")
opts="$global "
@@ -81,6 +83,15 @@ _swupd()
("verify")
opts="$global --version --manifest --fix --picky --picky-tree --picky-whitelist --install --quick --force --install "
break;;
("3rd-party")
opts="$global add remove list"
break;;
("add")
opts="$global --repo"
break;;
("remove")
opts="$global --repo"
break;;
esac
done
# Add in additional completion options if we need to
+27
View File
@@ -175,6 +175,7 @@ if [[ -n "$state" ]]; then
"mirror:Configure mirror url for swupd content"
"clean:Clean cached files"
"hashdump:Dump the HMAC hash of a file"
"3rd-party: Indicate Swupd to use user's third party repo"
)
_describe -t subcmds 'swupd subcommand' subcmds && ret=0
;;
@@ -183,6 +184,32 @@ if [[ -n "$state" ]]; then
info)
_arguments $global_opts && ret=0
;;
3rd-party)
local -a thirdparty; thirdparty=(
$global_opt
'(help)list[List third party repo(s)]'
'(help)remove[Remove third party repo]'
'(help)add[Add third party repo]'
_arguments $thirdparty && ret=0
;;
add)
local -a add; add=(
$global_opt
'(help)Positional arg: [repo-name]'
'(help)Positional arg: [repo-url]'
_arguments $add && ret=0
;;
remove)
local -a remove; remove=(
$global_opt
'(help)Positional arg: [repo-name]'
_arguments $remove && ret=0
;;
list)
local -a list; list=(
$global_opt
_arguments $list && ret=0
;;
autoupdate)
local -a autoupdates; autoupdates=(
$global_opts