@@ -70,6 +70,7 @@ static enum {
7070 ARG_ENTRY_TOKEN_AUTO ,
7171} arg_entry_token_type = ARG_ENTRY_TOKEN_AUTO ;
7272static char * arg_entry_token = NULL ;
73+ static JsonFormatFlags arg_json_format_flags = JSON_FORMAT_OFF ;
7374
7475STATIC_DESTRUCTOR_REGISTER (arg_esp_path , freep );
7576STATIC_DESTRUCTOR_REGISTER (arg_xbootldr_path , freep );
@@ -686,7 +687,7 @@ static int status_entries(
686687 const char * xbootldr_path ,
687688 sd_id128_t xbootldr_partition_uuid ) {
688689
689- _cleanup_ (boot_config_free ) BootConfig config = {} ;
690+ _cleanup_ (boot_config_free ) BootConfig config = BOOT_CONFIG_NULL ;
690691 sd_id128_t dollar_boot_partition_uuid ;
691692 const char * dollar_boot_path ;
692693 int r ;
@@ -708,7 +709,11 @@ static int status_entries(
708709 SD_ID128_FORMAT_VAL (dollar_boot_partition_uuid ));
709710 printf ("\n\n" );
710711
711- r = boot_entries_load_config (esp_path , xbootldr_path , & config );
712+ r = boot_config_load (& config , esp_path , xbootldr_path );
713+ if (r < 0 )
714+ return r ;
715+
716+ r = boot_config_select_special_entries (& config );
712717 if (r < 0 )
713718 return r ;
714719
@@ -718,7 +723,7 @@ static int status_entries(
718723 printf ("Default Boot Loader Entry:\n" );
719724
720725 r = boot_entry_show (
721- config . entries + config . default_entry ,
726+ boot_config_default_entry ( & config ) ,
722727 /* show_as_default= */ false,
723728 /* show_as_selected= */ false,
724729 /* show_discovered= */ false);
@@ -1420,6 +1425,8 @@ static int help(int argc, char *argv[], void *userdata) {
14201425 " Create $BOOT/ENTRY-TOKEN/ directory\n"
14211426 " --entry-token=machine-id|os-id|os-image-id|auto|literal:…\n"
14221427 " Entry token to use for this installation\n"
1428+ " --json=pretty|short|off\n"
1429+ " Generate JSON output\n"
14231430 "\nSee the %2$s for details.\n" ,
14241431 program_invocation_short_name ,
14251432 link ,
@@ -1441,6 +1448,7 @@ static int parse_argv(int argc, char *argv[]) {
14411448 ARG_GRACEFUL ,
14421449 ARG_MAKE_ENTRY_DIRECTORY ,
14431450 ARG_ENTRY_TOKEN ,
1451+ ARG_JSON ,
14441452 };
14451453
14461454 static const struct option options [] = {
@@ -1458,6 +1466,7 @@ static int parse_argv(int argc, char *argv[]) {
14581466 { "make-entry-directory" , required_argument , NULL , ARG_MAKE_ENTRY_DIRECTORY },
14591467 { "make-machine-id-directory" , required_argument , NULL , ARG_MAKE_ENTRY_DIRECTORY }, /* Compatibility alias */
14601468 { "entry-token" , required_argument , NULL , ARG_ENTRY_TOKEN },
1469+ { "json" , required_argument , NULL , ARG_JSON },
14611470 {}
14621471 };
14631472
@@ -1552,6 +1561,13 @@ static int parse_argv(int argc, char *argv[]) {
15521561 }
15531562 break ;
15541563
1564+ case ARG_JSON :
1565+ r = parse_json_argument (optarg , & arg_json_format_flags );
1566+ if (r <= 0 )
1567+ return r ;
1568+
1569+ break ;
1570+
15551571 case '?' :
15561572 return - EINVAL ;
15571573
@@ -1776,7 +1792,7 @@ static int verb_status(int argc, char *argv[], void *userdata) {
17761792}
17771793
17781794static int verb_list (int argc , char * argv [], void * userdata ) {
1779- _cleanup_ (boot_config_free ) BootConfig config = {} ;
1795+ _cleanup_ (boot_config_free ) BootConfig config = BOOT_CONFIG_NULL ;
17801796 _cleanup_strv_free_ char * * efi_entries = NULL ;
17811797 dev_t esp_devid = 0 , xbootldr_devid = 0 ;
17821798 int r ;
@@ -1800,7 +1816,7 @@ static int verb_list(int argc, char *argv[], void *userdata) {
18001816 /* If XBOOTLDR and ESP actually refer to the same block device, suppress XBOOTLDR, since it would find the same entries twice */
18011817 bool same = arg_esp_path && arg_xbootldr_path && devid_set_and_equal (esp_devid , xbootldr_devid );
18021818
1803- r = boot_entries_load_config ( arg_esp_path , same ? NULL : arg_xbootldr_path , & config );
1819+ r = boot_config_load ( & config , arg_esp_path , same ? NULL : arg_xbootldr_path );
18041820 if (r < 0 )
18051821 return r ;
18061822
@@ -1810,9 +1826,50 @@ static int verb_list(int argc, char *argv[], void *userdata) {
18101826 else if (r < 0 )
18111827 log_warning_errno (r , "Failed to determine entries reported by boot loader, ignoring: %m" );
18121828 else
1813- (void ) boot_entries_augment_from_loader (& config , efi_entries , /* only_auto= */ false);
1829+ (void ) boot_config_augment_from_loader (& config , efi_entries , /* only_auto= */ false);
1830+
1831+ r = boot_config_select_special_entries (& config );
1832+ if (r < 0 )
1833+ return r ;
1834+
1835+ if (!FLAGS_SET (arg_json_format_flags , JSON_FORMAT_OFF )) {
1836+
1837+ pager_open (arg_pager_flags );
1838+
1839+ for (size_t i = 0 ; i < config .n_entries ; i ++ ) {
1840+ _cleanup_free_ char * opts = NULL ;
1841+ BootEntry * e = config .entries + i ;
1842+ _cleanup_ (json_variant_unrefp ) JsonVariant * v = NULL ;
1843+
1844+ if (!strv_isempty (e -> options )) {
1845+ opts = strv_join (e -> options , " " );
1846+ if (!opts )
1847+ return log_oom ();
1848+ }
1849+
1850+ r = json_build (& v , JSON_BUILD_OBJECT (
1851+ JSON_BUILD_PAIR_CONDITION (e -> id , "id" , JSON_BUILD_STRING (e -> id )),
1852+ JSON_BUILD_PAIR_CONDITION (e -> path , "path" , JSON_BUILD_STRING (e -> path )),
1853+ JSON_BUILD_PAIR_CONDITION (e -> root , "root" , JSON_BUILD_STRING (e -> root )),
1854+ JSON_BUILD_PAIR_CONDITION (e -> title , "title" , JSON_BUILD_STRING (e -> title )),
1855+ JSON_BUILD_PAIR_CONDITION (boot_entry_title (e ), "showTitle" , JSON_BUILD_STRING (boot_entry_title (e ))),
1856+ JSON_BUILD_PAIR_CONDITION (e -> sort_key , "sortKey" , JSON_BUILD_STRING (e -> sort_key )),
1857+ JSON_BUILD_PAIR_CONDITION (e -> version , "version" , JSON_BUILD_STRING (e -> version )),
1858+ JSON_BUILD_PAIR_CONDITION (e -> machine_id , "machineId" , JSON_BUILD_STRING (e -> machine_id )),
1859+ JSON_BUILD_PAIR_CONDITION (e -> architecture , "architecture" , JSON_BUILD_STRING (e -> architecture )),
1860+ JSON_BUILD_PAIR_CONDITION (opts , "options" , JSON_BUILD_STRING (opts )),
1861+ JSON_BUILD_PAIR_CONDITION (e -> kernel , "linux" , JSON_BUILD_STRING (e -> kernel )),
1862+ JSON_BUILD_PAIR_CONDITION (e -> efi , "efi" , JSON_BUILD_STRING (e -> efi )),
1863+ JSON_BUILD_PAIR_CONDITION (!strv_isempty (e -> initrd ), "initrd" , JSON_BUILD_STRV (e -> initrd )),
1864+ JSON_BUILD_PAIR_CONDITION (e -> device_tree , "devicetree" , JSON_BUILD_STRING (e -> device_tree )),
1865+ JSON_BUILD_PAIR_CONDITION (!strv_isempty (e -> device_tree_overlay ), "devicetreeOverlay" , JSON_BUILD_STRV (e -> device_tree_overlay ))));
1866+ if (r < 0 )
1867+ return log_oom ();
1868+
1869+ json_variant_dump (v , arg_json_format_flags , stdout , NULL );
1870+ }
18141871
1815- if (config .n_entries == 0 )
1872+ } else if (config .n_entries == 0 )
18161873 log_info ("No boot loader entries found." );
18171874 else {
18181875 pager_open (arg_pager_flags );
0 commit comments