diff --git a/Makefile-tests.am b/Makefile-tests.am index 6878a30c..e5caa686 100644 --- a/Makefile-tests.am +++ b/Makefile-tests.am @@ -36,6 +36,7 @@ testfiles = test-basic \ test-pull-metalink \ test-pull-resume \ test-gpg-signed-commit \ + test-admin-upgrade-unconfigured \ test-admin-deploy-syslinux \ test-admin-deploy-2 \ test-admin-deploy-karg \ diff --git a/src/libostree/ostree-sysroot-upgrader.c b/src/libostree/ostree-sysroot-upgrader.c index 315b7cff..81f5ff2b 100644 --- a/src/libostree/ostree-sysroot-upgrader.c +++ b/src/libostree/ostree-sysroot-upgrader.c @@ -42,6 +42,7 @@ struct OstreeSysrootUpgrader { OstreeSysroot *sysroot; char *osname; + OstreeSysrootUpgraderFlags flags; OstreeDeployment *merge_deployment; GKeyFile *origin; @@ -55,7 +56,8 @@ enum { PROP_0, PROP_SYSROOT, - PROP_OSNAME + PROP_OSNAME, + PROP_FLAGS }; static void ostree_sysroot_upgrader_initable_iface_init (GInitableIface *iface); @@ -70,6 +72,19 @@ parse_refspec (OstreeSysrootUpgrader *self, { gboolean ret = FALSE; gs_free char *origin_refspec = NULL; + gs_free char *unconfigured_state = NULL; + + if ((self->flags & OSTREE_SYSROOT_UPGRADER_FLAGS_IGNORE_UNCONFIGURED) == 0) + { + /* If explicit action by the OS creator is requried to upgrade, print their text as an error */ + unconfigured_state = g_key_file_get_string (self->origin, "origin", "unconfigured-state", NULL); + if (unconfigured_state) + { + g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, + "origin unconfigured-state: %s", unconfigured_state); + goto out; + } + } origin_refspec = g_key_file_get_string (self->origin, "origin", "refspec", NULL); if (!origin_refspec) @@ -191,6 +206,9 @@ ostree_sysroot_upgrader_set_property (GObject *object, case PROP_OSNAME: self->osname = g_value_dup_string (value); break; + case PROP_FLAGS: + self->flags = g_value_get_flags (value); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -213,6 +231,9 @@ ostree_sysroot_upgrader_get_property (GObject *object, case PROP_OSNAME: g_value_set_string (value, self->osname); break; + case PROP_FLAGS: + g_value_set_flags (value, self->flags); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -249,6 +270,13 @@ ostree_sysroot_upgrader_class_init (OstreeSysrootUpgraderClass *klass) PROP_OSNAME, g_param_spec_string ("osname", "", "", NULL, G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); + + g_object_class_install_property (object_class, + PROP_FLAGS, + g_param_spec_flags ("flags", "", "", + ostree_sysroot_upgrader_flags_get_type (), + 0, + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); } static void @@ -288,6 +316,25 @@ ostree_sysroot_upgrader_new_for_os (OstreeSysroot *sysroot, "sysroot", sysroot, "osname", osname, NULL); } +/** + * ostree_sysroot_upgrader_new_for_os_with_flags: + * @sysroot: An #OstreeSysroot + * @osname: (allow-none): Operating system name + * @flags: Flags + * + * Returns: (transfer full): An upgrader + */ +OstreeSysrootUpgrader * +ostree_sysroot_upgrader_new_for_os_with_flags (OstreeSysroot *sysroot, + const char *osname, + OstreeSysrootUpgraderFlags flags, + GCancellable *cancellable, + GError **error) +{ + return g_initable_new (OSTREE_TYPE_SYSROOT_UPGRADER, cancellable, error, + "sysroot", sysroot, "osname", osname, "flags", flags, NULL); +} + /** * ostree_sysroot_upgrader_get_origin: * @self: Sysroot @@ -544,3 +591,22 @@ ostree_sysroot_upgrader_deploy (OstreeSysrootUpgrader *self, out: return ret; } + +GType +ostree_sysroot_upgrader_flags_get_type (void) +{ + static volatile gsize g_define_type_id__volatile = 0; + + if (g_once_init_enter (&g_define_type_id__volatile)) + { + static const GFlagsValue values[] = { + { OSTREE_SYSROOT_UPGRADER_FLAGS_IGNORE_UNCONFIGURED, "OSTREE_SYSROOT_UPGRADER_FLAGS_IGNORE_UNCONFIGURED", "ignore-unconfigured" }, + { 0, NULL, NULL } + }; + GType g_define_type_id = + g_flags_register_static (g_intern_static_string ("OstreeSysrootUpgraderFlags"), values); + g_once_init_leave (&g_define_type_id__volatile, g_define_type_id); + } + + return g_define_type_id__volatile; +} diff --git a/src/libostree/ostree-sysroot-upgrader.h b/src/libostree/ostree-sysroot-upgrader.h index cf601248..a3b664b1 100644 --- a/src/libostree/ostree-sysroot-upgrader.h +++ b/src/libostree/ostree-sysroot-upgrader.h @@ -30,8 +30,22 @@ G_BEGIN_DECLS #define OSTREE_IS_SYSROOT_UPGRADER(obj) \ (G_TYPE_CHECK_INSTANCE_TYPE ((obj), OSTREE_TYPE_SYSROOT_UPGRADER)) +/** + * OstreeSysrootUpgraderFlags: + * @OSTREE_SYSROOT_UPGRADER_FLAGS_NONE: No options + * @OSTREE_SYSROOT_UPGRADER_FLAGS_IGNORE_UNCONFIGURED: Do not error if the origin has an unconfigured-state key + * + * Flags controlling operation of an #OstreeSysrootUpgrader. + */ +typedef enum { + OSTREE_SYSROOT_UPGRADER_FLAGS_NONE = (1 << 0), + OSTREE_SYSROOT_UPGRADER_FLAGS_IGNORE_UNCONFIGURED = (1 << 1), +} OstreeSysrootUpgraderFlags; + GType ostree_sysroot_upgrader_get_type (void); +GType ostree_sysroot_upgrader_flags_get_type (void); + OstreeSysrootUpgrader *ostree_sysroot_upgrader_new (OstreeSysroot *sysroot, GCancellable *cancellable, GError **error); @@ -41,6 +55,12 @@ OstreeSysrootUpgrader *ostree_sysroot_upgrader_new_for_os (OstreeSysroot *sysroo GCancellable *cancellable, GError **error); +OstreeSysrootUpgrader *ostree_sysroot_upgrader_new_for_os_with_flags (OstreeSysroot *sysroot, + const char *osname, + OstreeSysrootUpgraderFlags flags, + GCancellable *cancellable, + GError **error); + GKeyFile *ostree_sysroot_upgrader_get_origin (OstreeSysrootUpgrader *self); gboolean ostree_sysroot_upgrader_set_origin (OstreeSysrootUpgrader *self, GKeyFile *origin, GCancellable *cancellable, GError **error); diff --git a/src/ostree/ot-admin-builtin-switch.c b/src/ostree/ot-admin-builtin-switch.c index a6a18626..5995e33b 100644 --- a/src/ostree/ot-admin-builtin-switch.c +++ b/src/ostree/ot-admin-builtin-switch.c @@ -82,8 +82,9 @@ ot_admin_builtin_switch (int argc, char **argv, OstreeSysroot *sysroot, GCancell if (!ostree_sysroot_load (sysroot, cancellable, error)) goto out; - upgrader = ostree_sysroot_upgrader_new_for_os (sysroot, opt_osname, - cancellable, error); + upgrader = ostree_sysroot_upgrader_new_for_os_with_flags (sysroot, opt_osname, + OSTREE_SYSROOT_UPGRADER_FLAGS_IGNORE_UNCONFIGURED, + cancellable, error); if (!upgrader) goto out; diff --git a/tests/test-admin-upgrade-unconfigured.sh b/tests/test-admin-upgrade-unconfigured.sh new file mode 100644 index 00000000..821fa101 --- /dev/null +++ b/tests/test-admin-upgrade-unconfigured.sh @@ -0,0 +1,51 @@ +#!/bin/bash +# +# Copyright (C) 2014 Colin Walters +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2 of the License, or (at your option) any later version. +# +# This library 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 +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the +# Free Software Foundation, Inc., 59 Temple Place - Suite 330, +# Boston, MA 02111-1307, USA. + +set -e + +. $(dirname $0)/libtest.sh + +echo "1..1" + +setup_os_repository "archive-z2" "syslinux" + +echo "ok setup" + +echo "1..2" + +ostree --repo=sysroot/ostree/repo pull-local --remote=testos testos-repo testos/buildmaster/x86_64-runtime +rev=$(ostree --repo=sysroot/ostree/repo rev-parse testos/buildmaster/x86_64-runtime) +export rev +echo "rev=${rev}" +# This initial deployment gets kicked off with some kernel arguments +ostree admin --sysroot=sysroot deploy --karg=root=LABEL=MOO --karg=quiet --os=testos testos:testos/buildmaster/x86_64-runtime +echo "unconfigured-state=Use \"subscription-manager\" to enable online updates for example.com OS" >> sysroot/ostree/deploy/testos/deploy/${rev}.0.origin + +ostree --repo=sysroot/ostree/repo remote add --set=gpg-verify=false testos file://$(pwd)/testos-repo testos/buildmaster/x86_64-runtime +if ostree admin --sysroot=sysroot upgrade --os=testos 2>err.txt; then + assert_not_reached "upgrade unexpectedly succeeded" +fi +assert_file_has_content err.txt "Use.*subscription.*online" + +echo "ok error" + +ostree --repo=sysroot/ostree/repo remote add --set=gpg-verify=false otheros file://$(pwd)/testos-repo testos/buildmaster/x86_64-runtime +ostree admin --sysroot=sysroot switch --os=testos otheros:testos/buildmaster/x86_64-runtime + +echo "ok switch"