Hello community,

here is the log from the commit of package linuxrc for openSUSE:Factory checked 
in at 2019-10-28 16:45:33
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/linuxrc (Old)
 and      /work/SRC/openSUSE:Factory/.linuxrc.new.2990 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "linuxrc"

Mon Oct 28 16:45:33 2019 rev:274 rq:742160 version:7.0.0

Changes:
--------
--- /work/SRC/openSUSE:Factory/linuxrc/linuxrc.changes  2019-09-27 
14:44:19.821407266 +0200
+++ /work/SRC/openSUSE:Factory/.linuxrc.new.2990/linuxrc.changes        
2019-10-28 16:45:48.996658917 +0100
@@ -1,0 +2,19 @@
+Wed Oct 23 13:46:25 UTC 2019 - wfe...@opensuse.org
+
+- merge gh#openSUSE/linuxrc#196
+- show debug info also on console device
+- fix reading slp data
+- show both autoyast and autoyast2 options on linuxrc info page
+- support autoyast-style URL syntax
+- read and parse autoyast file
+- add needed entries to global config struct
+- add new autoyast.parse key
+- parse autoyast/autoyast2 options and add new autoyast url schemes
+- activate new autoyast code
+- fix parsing linuxrc options embedded in AutoYaST file (bsc#1145574)
+- document autoyast option behavior
+- small additions to autoyast handling doc
+- support autoyast url schemes in linuxrc
+- 7.0.0
+
+--------------------------------------------------------------------

Old:
----
  linuxrc-6.0.15.tar.xz

New:
----
  linuxrc-7.0.0.tar.xz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ linuxrc.spec ++++++
--- /var/tmp/diff_new_pack.bXcVVm/_old  2019-10-28 16:45:49.596659680 +0100
+++ /var/tmp/diff_new_pack.bXcVVm/_new  2019-10-28 16:45:49.604659691 +0100
@@ -17,7 +17,7 @@
 
 
 Name:           linuxrc
-Version:        6.0.15
+Version:        7.0.0
 Release:        0
 Summary:        SUSE Installation Program
 License:        GPL-3.0+

++++++ linuxrc-6.0.15.tar.xz -> linuxrc-7.0.0.tar.xz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/linuxrc-6.0.15/VERSION new/linuxrc-7.0.0/VERSION
--- old/linuxrc-6.0.15/VERSION  2019-09-24 15:39:06.000000000 +0200
+++ new/linuxrc-7.0.0/VERSION   2019-10-23 15:46:25.000000000 +0200
@@ -1 +1 @@
-6.0.15
+7.0.0
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/linuxrc-6.0.15/auto2.c new/linuxrc-7.0.0/auto2.c
--- old/linuxrc-6.0.15/auto2.c  2019-09-24 15:39:06.000000000 +0200
+++ new/linuxrc-7.0.0/auto2.c   2019-10-23 15:46:25.000000000 +0200
@@ -36,11 +36,13 @@
 
 static int driver_is_active(hd_t *hd);
 static void auto2_progress(char *pos, char *msg);
+static void auto2_read_repo_file(url_t *url, char *src, char *dst);
 static void auto2_read_repo_files(url_t *url);
 static void auto2_read_repomd_files(url_t *url);
 static char *auto2_splash_name(void);
 
 static int test_and_add_dud(url_t *url);
+static void auto2_read_autoyast(url_t *url);
 
 
 /*
@@ -364,31 +366,9 @@
   }
 
   /*
-   * load autoyast file unless the user has specified an autoyast option
-   * -- ok this sounds weird but actually makes sense...
+   * load autoyast file; prefer autoyast option over autoyast2
    */
-  if(config.autoyast2 && !config.autoyast) {
-    url = url_set(config.autoyast2);
-    log_show_maybe(!url->quiet, "Downloading AutoYaST file: %s\n", 
config.autoyast2);
-
-    err = url_read_file_anywhere(url, NULL, NULL, "/download/autoinst.xml", 
NULL, URL_FLAG_PROGRESS + URL_FLAG_NODIGEST);
-    url_umount(url);
-    url_free(url);
-    if(!err) {
-      log_info("setting AutoYaST option to file:///download/autoinst.xml\n");
-      str_copy(&config.autoyast, "file:///download/autoinst.xml");
-      /* parse it:
-       * you can embed linuxrc options between lines with '# 
{start,end}_linuxrc_conf';
-       * otherwise the file content is ignored
-       */
-      log_info("parsing AutoYaST file\n");
-      file_read_info_file("file:/download/autoinst.xml", kf_cfg);
-      net_update_ifcfg(IFCFG_IFUP);
-    }
-    else {
-      log_show_maybe(!url->quiet, "Failed to download AutoYaST file.\n");
-    }
-  }
+  auto2_read_autoyast(config.url.autoyast && config.autoyast_parse ? 
config.url.autoyast : config.url.autoyast2);
 
   /* load & run driverupdates */
   if(config.update.urls) {
@@ -863,6 +843,28 @@
   return console;
 }
 
+/*
+ * Read a single file from repo directory.
+ *
+ * Be careful not to replace an existing file unless we successfully got
+ * a new version.
+ */
+void auto2_read_repo_file(url_t *url, char *src, char *dst)
+{
+  char *tmp_file = NULL;
+
+  str_copy(&tmp_file, new_download());
+  if(
+    !url_read_file(url, NULL, src, tmp_file, NULL, URL_FLAG_NODIGEST + 
URL_FLAG_OPTIONAL) &&
+    util_check_exist(tmp_file)
+  ) {
+    rename(tmp_file, dst);
+    log_info("mv %s -> %s\n", tmp_file, dst);
+  }
+
+  str_copy(&tmp_file, NULL);
+}
+
 
 /*
  * Get various files from repositrory for yast's convenience.
@@ -870,9 +872,7 @@
 void auto2_read_repo_files(url_t *url)
 {
   int i;
-  char *tmp_file = NULL;
   static char *default_list[][2] = {
-    { "/autoinst.xml", "/tmp/autoinst.xml" },
     { "/control.xml", "/control.xml" },
     { "/license.tar.gz", "/license.tar.gz" },
     { "/media.1/info.txt", "/info.txt" },
@@ -881,29 +881,37 @@
   };
 
   for(i = 0; i < sizeof default_list / sizeof *default_list; i++) {
-    // be careful not to replace an existing file unless we successfully got
-    // a new version
-    str_copy(&tmp_file, new_download());
+    auto2_read_repo_file(url, default_list[i][0], default_list[i][1]);
+  }
+
+  char *autoyast_file = NULL;
+
+  if(config.url.autoyast) {
     if(
-      !url_read_file(url, NULL, default_list[i][0], tmp_file, NULL, 
URL_FLAG_NODIGEST + URL_FLAG_OPTIONAL) &&
-      util_check_exist(tmp_file)
+      config.url.autoyast->scheme == inst_rel &&
+      config.autoyast_parse
     ) {
-      rename(tmp_file, default_list[i][1]);
-      log_info("mv %s -> %s\n", tmp_file, default_list[i][1]);
+      log_show_maybe(!config.url.autoyast->quiet, "AutoYaST file in repo: 
%s\n", url_print(config.url.autoyast, 5));
+
+      if(!config.url.autoyast->is.dir) {
+        autoyast_file = config.url.autoyast->path;
+      }
     }
   }
+  else {
+    autoyast_file = "/autoinst.xml";
+  }
 
-  str_copy(&tmp_file, NULL);
+  if(autoyast_file) {
+    auto2_read_repo_file(url, autoyast_file, "/tmp/autoinst.xml");
 
-  if(!config.autoyast) {
     if(util_check_exist("/tmp/autoinst.xml")) rename("/tmp/autoinst.xml", 
"/autoinst.xml");
+
     if(util_check_exist("/autoinst.xml")) {
-      log_info("setting AutoYaST option to file:///autoinst.xml\n");
-      str_copy(&config.autoyast, "file:///autoinst.xml");
-      /* parse it:
-       * you can embed linuxrc options between lines with '# 
{start,end}_linuxrc_conf';
-       * otherwise the file content is ignored
-       */
+      log_info("setting AutoYaST option to file:/autoinst.xml\n");
+      url_free(config.url.autoyast);
+      config.url.autoyast = url_set("file:/autoinst.xml");
+      // parse for embedded linuxrc options in <info_file> element
       log_info("parsing AutoYaST file\n");
       file_read_info_file("file:/autoinst.xml", kf_cfg);
       net_update_ifcfg(IFCFG_IFUP);
@@ -920,31 +928,18 @@
 void auto2_read_repomd_files(url_t *url)
 {
   int i;
-  char *tmp_file = NULL;
   static char *default_list[][2] = {
     { "license", "/license.tar.gz" },
     { "/README.BETA", "/README.BETA" }
   };
 
   for(i = 0; i < sizeof default_list / sizeof *default_list; i++) {
-    // be careful not to replace an existing file unless we successfully got
-    // a new version
-
     // get real file name
     slist_t *sl = slist_getentry(config.repomd_data, default_list[i][0]);
     if(!sl) continue;
 
-    str_copy(&tmp_file, new_download());
-    if(
-      !url_read_file(url, NULL, sl->value, tmp_file, NULL, URL_FLAG_NODIGEST) 
&&
-      util_check_exist(tmp_file)
-    ) {
-      rename(tmp_file, default_list[i][1]);
-      log_info("mv %s -> %s\n", tmp_file, default_list[i][1]);
-    }
+    auto2_read_repo_file(url, sl->value, default_list[i][1]);
   }
-
-  str_copy(&tmp_file, NULL);
 }
 
 
@@ -1242,3 +1237,55 @@
   return err;
 }
 
+
+/*
+ * Read autoyast file from url and parse it.
+ *
+ * If the autoyast url points to a directory, nothing is read but the
+ * function tries to mount the directory to ensure it exists. This is
+ * basically done to search for the correct medium.
+ */
+void auto2_read_autoyast(url_t *url)
+{
+  if(!url) return;
+
+  // rel url is taken care of in auto2_read_repo_files()
+  if(url->scheme == inst_rel) return;
+
+  /*
+   * If the AutoYaST url is a directory we have to very its existence
+   * somehow.
+   *
+   * That works for mountable url schemes.
+   *
+   * For the rest (http(s), (t)ftp) we'll just assume it works.
+   */
+  if(url->is.dir) {
+    /*
+     * do nothing but
+     *   - ensure network is set up
+     *   - the correct disk device has been identified
+     */
+    if(url->is.mountable) {
+      url_mount(url, NULL, NULL);
+      url_umount(url);
+    }
+
+    return;
+  }
+
+  log_show_maybe(!url->quiet, "Downloading AutoYaST file: %s\n", url->str);
+
+  int err = url_read_file_anywhere(url, NULL, NULL, "/download/autoinst.xml", 
NULL, URL_FLAG_PROGRESS + URL_FLAG_NODIGEST);
+  url_umount(url);
+
+  if(!err) {
+    // parse for embedded linuxrc options in <info_file> element
+    log_info("parsing AutoYaST file\n");
+    file_read_info_file("file:/download/autoinst.xml", kf_cfg);
+    net_update_ifcfg(IFCFG_IFUP);
+  }
+  else {
+    log_show_maybe(!url->quiet, "Failed to download AutoYaST file.\n");
+  }
+}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/linuxrc-6.0.15/changelog new/linuxrc-7.0.0/changelog
--- old/linuxrc-6.0.15/changelog        2019-09-24 15:39:06.000000000 +0200
+++ new/linuxrc-7.0.0/changelog 2019-10-23 15:46:25.000000000 +0200
@@ -1,3 +1,18 @@
+2019-10-23:    7.0.0
+       - merge gh#openSUSE/linuxrc#196
+       - show debug info also on console device
+       - fix reading slp data
+       - show both autoyast and autoyast2 options on linuxrc info page
+       - support autoyast-style URL syntax
+       - read and parse autoyast file
+       - add needed entries to global config struct
+       - add new autoyast.parse key
+       - parse autoyast/autoyast2 options and add new autoyast url schemes
+       - activate new autoyast code
+       - fix parsing linuxrc options embedded in AutoYaST file (bsc#1145574)
+       - document autoyast option behavior
+       - small additions to autoyast handling doc
+
 2019-09-24:    6.0.15
        - merge gh#openSUSE/linuxrc#195
        - add support for compressed modules
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/linuxrc-6.0.15/file.c new/linuxrc-7.0.0/file.c
--- old/linuxrc-6.0.15/file.c   2019-09-24 15:39:06.000000000 +0200
+++ new/linuxrc-7.0.0/file.c    2019-10-23 15:46:25.000000000 +0200
@@ -117,6 +117,9 @@
   { key_screenmap,      "Screenmap",      kf_none                        },
   { key_fontmagic,      "Fontmagic",      kf_none                        },
   { key_autoyast,       "AutoYaST",       kf_cfg + kf_cmd_early          },
+  { key_autoyast,       "AY",             kf_cfg + kf_cmd_early          },
+  { key_autoyast_parse, "AutoYaSTParse",  kf_cfg + kf_cmd_early          },
+  { key_autoyast_parse, "AYParse",        kf_cfg + kf_cmd_early          },
   { key_autoyast2,      "AutoYaST2",      kf_cfg + kf_cmd_early          },
   { key_linuxrc,        "linuxrc",        kf_cfg + kf_cmd_early          },
   { key_forceinsmod,    "ForceInsmod",    kf_cfg + kf_cmd                },
@@ -350,11 +353,16 @@
   { "exec",      inst_exec          },
   { "rel",       inst_rel           },
   { "disk",      inst_disk          },
-  { "extern",    inst_extern        },
+  { "usb",       inst_usb           },
+  { "label",     inst_label         },
   /* add new inst modes _here_! */
+  { "extern",    inst_extern        },
+  /* the following are just aliases */
   { "harddisk",  inst_hd            },
   { "cdrom",     inst_cdrom         },
   { "cifs",      inst_smb           },
+  { "device",    inst_disk          },
+  { "relurl",    inst_rel           },
 #if defined(__s390__) || defined(__s390x__)
   { "osa",      di_390net_osa      },
   { "ctc",      di_390net_ctc      },
@@ -627,20 +635,29 @@
   unsigned u;
   FILE *w;
 
-  /* maybe it's an AutoYaST XML file */
+  /*
+   * Maybe it's an AutoYaST XML file.
+   *
+   * If so, try limiting the scope to lines in first '<info_file>' element.
+   */
   for(f = f0; f; f = f->next) {
-    if(f->key == key_comment && !strcmp(f->value, "start_linuxrc_conf")) {
-      is_xml = 1;
-      f0 = f->next;
-      break;
+    if(f->key == key_none) {
+      if(!strncmp(f->key_str, "<info_file", sizeof "<info_file" - 1)) {
+        is_xml = 1;
+        f0 = f->next;
+        break;
+      }
+      if(!strcmp(f->key_str, "</profile>")) {
+        is_xml = 1;
+      }
     }
   }
 
   for(f = f0; f; f = f->next) {
     if(
       is_xml &&
-      f->key == key_comment &&
-      !strcmp(f->value, "end_linuxrc_conf")
+      f->key == key_none &&
+      !strcmp(f->key_str, "</info_file>")
     ) {
       break;
     }
@@ -843,12 +860,24 @@
         break;
 
       case key_autoyast:
-        str_copy(&config.autoyast, *f->value ? f->value : "default");
+        config.url.autoyast = url_free(config.url.autoyast);
+        if(strcmp(f->value, "default")) {
+          config.url.autoyast = url_set(f->value);
+          // if it's an SLP url, add 'autoyast' service query per default
+          if(config.url.autoyast->scheme == inst_slp) {
+            slist_setentry(&config.url.autoyast->query, "service", "autoyast", 
0);
+          }
+        }
         config.manual = 0;
         break;
 
       case key_autoyast2:
-        str_copy(&config.autoyast2, *f->value ? f->value : NULL);
+        url_free(config.url.autoyast2);
+        config.url.autoyast2 = url_set(f->value);
+        break;
+
+      case key_autoyast_parse:
+        if(f->is.numeric) config.autoyast_parse = f->nvalue;
         break;
 
       case key_info:
@@ -1087,11 +1116,20 @@
         }
         slist_free(sl0);
 
+        config.log.dest[1].level =
+          config.debug ? LOG_LEVEL_SHOW | LOG_LEVEL_INFO | LOG_LEVEL_DEBUG | 
LOG_TIMESTAMP : LOG_LEVEL_INFO;
+
         if(config.error_trace) {
           config.log.dest[2].level |= LOG_CALLER;
+          if(config.debug) {
+            config.log.dest[1].level |= LOG_CALLER;
+          }
         }
         else {
           config.log.dest[2].level &= ~LOG_CALLER;
+          if(config.debug) {
+            config.log.dest[1].level &= ~LOG_CALLER;
+          }
         }
         break;
 
@@ -1919,13 +1957,18 @@
   file_write_str(f, key_updatedir, config.update.dir);
   file_write_num(f, key_yast2update, config.update.ask || config.update.count 
? 1 : 0);
   file_write_num(f, key_textmode, config.textmode);
-  file_write_str(f, key_autoyast, config.autoyast);
+  if(config.url.autoyast) {
+    log_info("final autoyast url: %s\n", url_print(config.url.autoyast, 0));
+    file_write_str(f, key_autoyast,
+      config.autoyast_parse ? url_print(config.url.autoyast, 5) : 
config.url.autoyast->str
+    );
+  }
   /*
    * autoyast + upgrade = autoupgrade
    *
    * autoyast uses a different config var to trigger updates for historical 
reasons
    */
-  if(config.autoyast && config.upgrade) {
+  if(config.url.autoyast && config.upgrade) {
     fprintf(f, "AutoUpgrade: 1\n");
   }
   file_write_num(f, key_memfree, config.memoryXXX.current >> 10);      // 
convention: in kB
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/linuxrc-6.0.15/file.h new/linuxrc-7.0.0/file.h
--- old/linuxrc-6.0.15/file.h   2019-09-24 15:39:06.000000000 +0200
+++ new/linuxrc-7.0.0/file.h    2019-10-23 15:46:25.000000000 +0200
@@ -56,7 +56,7 @@
   key_withipoib, key_upgrade, key_media_upgrade, key_ifcfg, key_defaultinstall,
   key_nanny, key_vlanid,
   key_sshkey, key_systemboot, key_sethostname, key_debugshell, key_self_update,
-  key_ibft_devices, key_linuxrc_core, key_norepo, key_auto_assembly
+  key_ibft_devices, key_linuxrc_core, key_norepo, key_auto_assembly, 
key_autoyast_parse
 } file_key_t;
 
 typedef enum {
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/linuxrc-6.0.15/global.h new/linuxrc-7.0.0/global.h
--- old/linuxrc-6.0.15/global.h 2019-09-24 15:39:06.000000000 +0200
+++ new/linuxrc-7.0.0/global.h  2019-10-23 15:46:25.000000000 +0200
@@ -185,7 +185,7 @@
   inst_none = 0, inst_file, inst_nfs, inst_ftp, inst_smb,
   inst_http, inst_https, inst_tftp, inst_cdrom, inst_floppy, inst_hd,
   inst_dvd, inst_cdwithnet, inst_net, inst_slp, inst_exec,
-  inst_rel, inst_disk,
+  inst_rel, inst_disk, inst_usb, inst_label,
   inst_extern ///< must be last
 } instmode_t;
 
@@ -265,6 +265,7 @@
 typedef struct {
   char *str;
   instmode_t scheme;
+  instmode_t orig_scheme;
   char *server;
   char *share;
   char *path;
@@ -287,6 +288,7 @@
     unsigned mountable:1;      /**< scheme is mountable */
     unsigned cdrom:1;          /**< device is cdrom */
     unsigned file:1;           /**< path points to file (not to directory) */
+    unsigned dir:1;            /**< path points to directory (not to file ) */
     unsigned wlan:1;           /**< wlan interface */
     unsigned blockdev:1;       /**< needs block device */
     unsigned nodevneeded:1;    /**< does not need any device */
@@ -446,6 +448,7 @@
   unsigned repomd:1;           /**< install repo is repo-md */
   unsigned norepo:1;            /**< disable repo location check, expect YaST 
*/
   unsigned auto_assembly:1;    /**< enable MD/RAID auto-assembly */
+  unsigned autoyast_parse:1;   /**< analyse autoyast parameter */
   struct {
     unsigned check:1;          /**< check for braille displays and start brld 
if found */
     char *dev;                 /**< braille device */
@@ -465,8 +468,6 @@
     slist_t *file;             /**< 'info' file name */
     unsigned add_cmdline:1;    /**< parse cmdline, too */
   } info;
-  char *autoyast;              /**< yast autoinstall parameter */
-  char *autoyast2;             /**< yast autoinstall parameter, loaded by 
linuxrc */
   char *yepurl;                        /**< just pass it to yast */
   char *supporturl;            /**< just pass it to yast */
   slist_t *linuxrc;            /**< 'linuxrc' parameters */
@@ -540,6 +541,8 @@
     url_t *install;            /**< install url */
     url_t *instsys;            /**< instsys url */
     url_t *proxy;              /**< proxy url */
+    url_t *autoyast;           /**< yast autoinstall parameter */
+    url_t *autoyast2;          /**< alternative yast autoinstall parameter */
   } url;
 
   struct {                     /**< libblkid related things */
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/linuxrc-6.0.15/linuxrc.c new/linuxrc-7.0.0/linuxrc.c
--- old/linuxrc-6.0.15/linuxrc.c        2019-09-24 15:39:06.000000000 +0200
+++ new/linuxrc-7.0.0/linuxrc.c 2019-10-23 15:46:25.000000000 +0200
@@ -801,6 +801,7 @@
   config.devtmpfs = 1;
   config.kexec = 2;            /* kexec if necessary, with user dialog */
   config.auto_assembly = 0;    /* default to disable MD/RAID auto-assembly 
(bsc#1132688) */
+  config.autoyast_parse = 1;   /* analyse autoyast option and read autoyast 
file */
 
   // defaults for self-update feature
   config.self_update_url = NULL;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/linuxrc-6.0.15/linuxrc_and_autoyast.md 
new/linuxrc-7.0.0/linuxrc_and_autoyast.md
--- old/linuxrc-6.0.15/linuxrc_and_autoyast.md  1970-01-01 01:00:00.000000000 
+0100
+++ new/linuxrc-7.0.0/linuxrc_and_autoyast.md   2019-10-23 15:46:25.000000000 
+0200
@@ -0,0 +1,78 @@
+# AutoYaST handling in linuxrc
+
+## Why?
+
+AutoYaST is something very specific to YaST and linuxrc has nothing to do
+with it. So why would it have to deal with it at all?
+
+In fact, linuxrc did ignore the `autoyast` boot option for a long time and
+just passed it on via `/etc/install.inf` to yast.
+
+There are several reasons why linuxrc has to get involved:
+
+1. You can embed linuxrc options into the AutoYaST config
+  https://doc.opensuse.org/projects/autoyast/#invoking_autoinst.linuxrc.
+
+2. An AutoYaST config file `/autoinst.xml` is searched for and auto-loaded 
from a disk with label `OEMDRV`.
+
+3. There is the expectation that using `autoyast=ftp://foo/bar` (or any 
network URL)  causes linuxrc
+  to implicitly set up the network; much like `install=URL` or`dud=URL` does.
+
+For 3. to work linuxrc has to download the AutoYaST file to be sure the
+network setup has been done correctly.
+
+For 2. (and partly 1.) there had been the `autoyast2` option. But that was
+limited to linuxrc-style URLs and did not make any attempt to deal with
+AutoYaST rules.
+
+The main obstacles so far to get it right were:
+
+- AutoYaST has its own idiosyncratic set of URL schemes
+- it's not obvious which file should actually be loaded when AutoYaST rules 
come into play
+
+## Implementation
+
+1. linuxrc supports all AutoYaST URL schemes (see [References](#references) 
below); this
+implies you can also use AutoYaST-style URLs in other places in linuxrc
+2. linuxrc downloads the AutoYaST config file and parses it for linuxrc 
options - unless it's
+a rules-based setup
+3. linuxrc converts the URL used with the `autoyast` option into the canonical 
AutoYaST format and
+passes this on via `/etc/install.inf`; this means you can use both 
linuxrc-style and AutoYaST-style URLs
+in linuxrc
+4. if the AutoYaST URL ends with a `/` (pointing to a directory) linuxrc
+assumes this to be a rules-based setup; for URLs with a mountable scheme,
+linuxrc goes looking for the specified directory; for all other URL schemes
+linuxrc does nothing and simply passes the URL on to YaST
+5. for URL schemes `usb` and `label` linuxrc identifies the device and 
converts the URL to a `device` scheme
+to ensure AutoYaST reads the same config; but if linuxrc could not find the 
AutoYaST file at
+the specified location, the original URL is passed
+6. for the `slp` scheme, linuxrc does the URL query and offers the user a
+selection dialog; the selected URL is then passed on to YaST; this makes the
+`slp` scheme work as documented (with `descr=XXX` query parameter) - which
+so far did not work
+7. linuxrc implicitly looks for an AutoYaST config file `autoinst.xml` in the 
repository directory; the
+file is downloaded as `/autoinst.xml` and a link to it passed on to YaST 
(using a `file` URL)
+8. there is not really an `autoyast=default` option; if this option is used, 
it just clears any previous
+autoyast setting; the reason is that `autoyast=default` is the default - 
linuxrc **always** looks for
+an AutoYaST config in the repository as described in 7.; see also
+https://en.opensuse.org/SDB:Linuxrc#AutoYaST_Profile_Handling
+9. as this is a major change and issues are likely to show up, there is a boot 
option to get back
+the old behavior: `autoyast.parse=0` - with this the `autoyast` option is left 
alone and just passed
+on to YaST
+10. the `autoyast2` option still exists for compatibility; it is ignored when 
`autoyast` is used
+11. there's a short alias `ay` for the `autoyast` option
+
+## References
+
+AutoYaST URL scheme doc
+
+- https://doc.opensuse.org/projects/autoyast/#Commandline.ay
+
+Understanding AutoYaST rules handling
+
+- https://doc.opensuse.org/projects/autoyast/#handlingrules
+
+Implementation of AutoYaST config file reading in YaST
+
+- 
https://github.com/yast/yast-installation/blob/master/src/lib/transfer/file_from_url.rb
+- 
https://github.com/yast/yast-autoinstallation/blob/master/src/modules/AutoinstConfig.rb
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/linuxrc-6.0.15/slp.c new/linuxrc-7.0.0/slp.c
--- old/linuxrc-6.0.15/slp.c    2019-09-24 15:39:06.000000000 +0200
+++ new/linuxrc-7.0.0/slp.c     2019-10-23 15:46:25.000000000 +0200
@@ -112,8 +112,8 @@
   int s, l, l2, l3;
   int xid, al;
   char *d;
-  unsigned char sendbuf[8000];
-  unsigned char recvbuf[8000];
+  unsigned char sendbuf[0x10000];
+  unsigned char recvbuf[0x10000];
   unsigned char *bp, *end;
 
   xid = nextxid;
@@ -184,8 +184,8 @@
 
 char *slp_get_install(url_t *url)
 {
-  unsigned char sendbuf[8000];
-  unsigned char recvbuf[80000];
+  unsigned char sendbuf[0x100000];
+  unsigned char recvbuf[0x100000];
   unsigned char *bp, *end, *service, service_key[256];
   int xid, l, s, l2, l3, ec, comma, ulen, i, acnt, service_key_len;
   struct sockaddr_in mysa;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/linuxrc-6.0.15/url.c new/linuxrc-7.0.0/url.c
--- old/linuxrc-6.0.15/url.c    2019-09-24 15:39:06.000000000 +0200
+++ new/linuxrc-7.0.0/url.c     2019-10-23 15:46:25.000000000 +0200
@@ -60,6 +60,11 @@
 static int url_setup_device(url_t *url);
 static int url_setup_interface(url_t *url);
 static int url_setup_slp(url_t *url);
+static void fixup_url_rel(url_t *url);
+static void fixup_url_usb(url_t *url);
+static void fixup_url_label(url_t *url);
+static void skip_slashes(char **str);
+static void skip_not_slashes(char **str);
 static void url_parse_instsys_config(char *file);
 static slist_t *url_instsys_lookup(char *key, slist_t **sl_ll);
 static char *url_instsys_config(char *path);
@@ -73,6 +78,7 @@
 static hd_t *sort_a_bit(hd_t *hd_list);
 static int link_detected(hd_t *hd);
 static char *url_print_zypp(url_t *url);
+static char *url_print_autoyast(url_t *url);
 static void digests_init(url_data_t *url_data);
 static void digests_done(url_data_t *url_data);
 static void digests_process(url_data_t *url_data, void *buffer, size_t len);
@@ -347,12 +353,36 @@
 
 
 /*
- * scheme://domain;user:password@server:port/path?query
+ * Parse URL string.
+ *
+ * Return a freshly allocated url_t structure.
+ *
+ * A URL looks like: scheme://domain;user:password@server:port/path?query.
  *
- * cifs: path = share/path
- * disk: path = [device/]path
+ * For a general URL syntax overview, see
+ *   - https://tools.ietf.org/html/rfc3986#section-3
+ *   - https://tools.ietf.org/html/rfc1738 (older, with more examples)
+ *
+ * Notes:
+ *   - 'path' is prefixed with the share name ('share/path') for SMB/CIFS
+ *   - 'path' may optionally be prefixed with the device name ('device/path')
+ *     for URLs referring to local block devices
+ *   - 'domain' (aka workgroup) and 'share' are only relevant for SMB/CIFS
+ *
+ * Special AutoYaST URL schemes (note the *two* slashes ('//'):
+ *   - device://dev/path
+ *     -> is mapped to disk:/path?device=dev
+ *   - relurl://path
+ *     -> is mapped to rel:path
+ *   - usb://path
+ *     -> is mapped to disk:/path?device=disk/\*usb*
+ *   - label://label/path
+ *     -> is mapped to disk:/path?device=disk/by-label/label
+ *
+ *   Additionally, zero up to three consecutive slashes are acceptable at
+ *   the beginning of the URL as long as the meaning is unambiguous (e.g.
+ *   'label:foo').
  */
-
 url_t *url_set(char *str)
 {
   url_t *url = calloc(1, sizeof *url);
@@ -400,13 +430,12 @@
     }
   }
   else {
-    // FIXME: should always be 'rel'
-    i = file_sym2num(str);
-    if(i >= 0) {
+    i = url_scheme2id(str);
+    if(i > 0) {
       url->scheme = i;
       url->path = strdup("");
     }
-    else if(i == -1) {
+    else {
       url->scheme = inst_rel;
       url->path = strdup(str);
     }
@@ -485,6 +514,15 @@
     }
   }
 
+  url->orig_scheme = url->scheme;
+
+  /* adjust some url schemes to support autoyast syntax */
+  fixup_url_rel(url);
+  fixup_url_usb(url);
+  fixup_url_label(url);
+
+  url->is.blockdev = url_is_blockdev(url->scheme);
+
   /* local storage device: allow path to begin with device name */
   if(
     url->is.blockdev &&
@@ -535,6 +573,7 @@
 
   if((sl = slist_getentry(url->query, "type"))) {
     url->is.file = strcmp(sl->value, "file") ? 0 : 1;
+    url->is.dir = strcmp(sl->value, "dir") ? 0 : 1;
   }
 
   if((sl = slist_getentry(url->query, "all"))) {
@@ -547,8 +586,6 @@
 
   url->is.mountable = url_is_mountable(url->scheme);
 
-  url->is.blockdev = url_is_blockdev(url->scheme);
-
   url->is.network = url_is_network(url->scheme);
 
   url->is.nodevneeded = !(url->is.network || url->is.blockdev);
@@ -572,10 +609,21 @@
     }
   }
 
+  /* if URL path ends with '/', assume directory */
+  if(!url->is.file) {
+    if(url->path && *url->path && url->path[strlen(url->path) - 1] == '/') {
+      url->is.dir = 1;
+    }
+  }
+
   log_debug("url = %s\n", url->str);
 
   if(config.debug >= 2) {
-    log_debug("  scheme = %s (%d)", url_scheme2name(url->scheme), url->scheme);
+    log_debug(
+      "  scheme = %s (%d), orig scheme = %s (%d)",
+      url_scheme2name(url->scheme), url->scheme,
+      url_scheme2name(url->orig_scheme), url->orig_scheme
+    );
     if(url->server) log_debug(", server = \"%s\"", url->server);
     if(url->port) log_debug(", port = %u", url->port);
     if(url->path) log_debug(", path = \"%s\"", url->path);
@@ -597,8 +645,8 @@
     }
 
     log_debug(
-      "  network = %u, blockdev = %u, mountable = %u, file = %u, all = %u, 
quiet = %u\n",
-      url->is.network, url->is.blockdev, url->is.mountable, url->is.file,
+      "  network = %u, blockdev = %u, mountable = %u, file = %u, dir = %u, all 
= %u, quiet = %u\n",
+      url->is.network, url->is.blockdev, url->is.mountable, url->is.file, 
url->is.dir,
       url->search_all, url->quiet
     );
 
@@ -610,6 +658,9 @@
         log_debug("    %s = \"%s\"\n", sl->key, sl->value);
       }
     }
+
+    log_debug("url (zypp format) = %s\n", url_print(url, 4));
+    log_debug("url (ay format) = %s\n", url_print(url, 5));
   }
 
   return url;
@@ -617,6 +668,119 @@
 
 
 /*
+ * Fix up autoyast 'rel' url scheme.
+ *
+ *   - relurl://foo/bar
+ *
+ * Note the '//'.
+ */
+void fixup_url_rel(url_t *url)
+{
+  if(
+    url->scheme == inst_rel &&
+    url->server &&
+    url->path
+  ) {
+    if(!*url->path) {
+      free(url->path);
+      url->path = url->server;
+      url->server = NULL;
+    }
+    else {
+      strprintf(&url->path, "%s/%s", url->server, url->path);
+      str_copy(&url->server, NULL);
+    }
+  }
+}
+
+
+/*
+ * Fix up autoyast 'usb' url scheme.
+ *
+ *   - usb://foo/bar
+ *
+ * Note the '//'.
+ *
+ * 'usb' is translated to the 'disk' url scheme with a suitable '?device=XXX'
+ * query parameter added to take care of matching only usb devices.
+ */
+void fixup_url_usb(url_t *url)
+{
+  if(url->scheme != inst_usb) return;
+
+  url->scheme = inst_disk;
+  slist_setentry(&url->query, "device", "disk/*usb*", 1);
+
+  if(url->server && url->path) {
+    if(!*url->path) {
+      free(url->path);
+      url->path = url->server;
+      url->server = NULL;
+    }
+    else {
+      strprintf(&url->path, "%s/%s", url->server, url->path);
+      str_copy(&url->server, NULL);
+    }
+  }
+}
+
+
+/*
+ * Handle autoyast 'label' scheme.
+ *
+ *   - label://label/foo/bar
+ *
+ * 'label' is translated to the 'disk' url scheme with a suitable '?device=XXX'
+ * query parameter added to take care of matching the label.
+ */
+void fixup_url_label(url_t *url)
+{
+  if(url->scheme != inst_label) return;
+
+  url->scheme = inst_disk;
+
+  if(url->server) {
+    slist_t *sl = slist_setentry(&url->query, "device", NULL, 1);
+    strprintf(&sl->value, "disk/by-label/%s", url->server);
+    slist_setentry(&url->query, "label", url->server, 1);
+  }
+  else if(url->path) {
+    char *s = url->path;
+    skip_slashes(&s);
+    if(*s) {
+      char *t = s;
+      skip_not_slashes(&t);
+      if(t != s) {
+        if(*t) *t++ = 0;
+        slist_t *sl = slist_setentry(&url->query, "device", NULL, 1);
+        strprintf(&sl->value, "disk/by-label/%s", s);
+        slist_setentry(&url->query, "label", s, 1);
+        str_copy(&url->path, t);
+      }
+    }
+  }
+}
+
+
+/*
+ * Skip sequence of slashes ('/').
+ */
+void skip_slashes(char **str)
+{
+  while(**str && **str == '/') (*str)++;
+}
+
+
+/*
+ * Skip sequence of non-slashes (not '/').
+ */
+void skip_not_slashes(char **str)
+{
+  while(**str && **str != '/') (*str)++;
+}
+
+
+/*
  * Print url to string.
  *
  * scheme://domain;user:password@server:port/path?query
@@ -627,6 +791,7 @@
  *   2: with device
  *   3: like 2, but remove 'rel:' scheme
  *   4: in zypp format
+ *   5: in autoyast format
  */
 char *url_print(url_t *url, int format)
 {
@@ -642,6 +807,8 @@
 
   if(format == 4) return url_print_zypp(url);
 
+  if(format == 5) return url_print_autoyast(url);
+
   if(format != 3 || url->scheme != inst_rel) {
     strprintf(&buf, "%s:", url_scheme2name(url->scheme));
   }
@@ -694,6 +861,14 @@
   }
 
   if(format == 0) {
+    // basically for the slp scheme
+    static char *params[] = { "service", "descr" };
+    slist_t *sl;
+    for (int i = 0; i < sizeof params / sizeof *params; i++) {
+      if((sl = slist_getentry(url->query, params[i]))) {
+        strprintf(&buf, "%s%c%s=%s", buf, q++ ? '&' : '?', sl->key, sl->value);
+      }
+    }
     if(config.debug >= 2 && url->used.hwaddr) {
       strprintf(&buf, "%s%chwaddr=%s", buf, q++ ? '&' : '?', url->used.hwaddr);
     }
@@ -835,6 +1010,107 @@
 }
 
 
+/*
+ * Convert URL to AutoYAST format.
+ *
+ * url scheme doc
+ *   - https://doc.opensuse.org/projects/autoyast/#Commandline.ay
+ *
+ * actual implementation
+ *   - 
https://github.com/yast/yast-installation/blob/master/src/lib/transfer/file_from_url.rb
+ *   - 
https://github.com/yast/yast-autoinstallation/blob/master/src/modules/AutoinstConfig.rb
+ */
+char *url_print_autoyast(url_t *url)
+{
+  static char *buf = NULL, *s;
+  char *path = NULL, *file = NULL;
+  int scheme;
+
+  str_copy(&buf, NULL);
+
+  str_copy(&path, url->path);
+
+  if(url->is.file && path) {
+    if((file = strrchr(path, '/')) && *file) {
+      *file++ = 0;
+    }
+    else {
+      file = NULL;
+    }
+  }
+
+  scheme = url->scheme;
+
+  if(url->is.blockdev) {
+    strprintf(&buf, "device://");
+    if(url->used.device) {
+      strprintf(&buf, "%s%s", buf, short_dev(url->used.device));
+    }
+    else if(url->orig_scheme == inst_usb) {
+      strprintf(&buf, "usb:/");
+    }
+    else if(url->orig_scheme == inst_label) {
+      slist_t *sl;
+      strprintf(&buf, "label://");
+      if((sl = slist_getentry(url->query, "label"))) {
+        strprintf(&buf, "%s%s", buf, sl->value);
+      }
+    }
+  }
+  else if(scheme == inst_rel) {
+    strprintf(&buf, "relurl:/");
+  }
+  else if(scheme == inst_file) {
+    strprintf(&buf, "file://");
+  }
+  else if(scheme == inst_slp) {
+    strprintf(&buf, "slp");
+  }
+  else {
+    strprintf(&buf, "%s:", url_scheme2name(scheme));
+  }
+
+  if(url->domain || url->user || url->password || url->server || url->port) {
+    strprintf(&buf, "%s//", buf);
+    if(url->domain) strprintf(&buf, "%s%s;", buf, url->domain);
+    if(url->user) {
+      s = curl_easy_escape(NULL, url->user, 0);
+      strprintf(&buf, "%s%s", buf, s);
+      curl_free(s);
+    }
+    if(url->password) {
+      s = curl_easy_escape(NULL, url->password, 0);
+      strprintf(&buf, "%s:%s", buf, s);
+      curl_free(s);
+    }
+    if(url->user || url->password) strprintf(&buf, "%s@", buf);
+    if(url->server) {
+      if(strchr(url->server, ':')) {
+        strprintf(&buf, "%s[%s]", buf, url->server);
+      }
+      else {
+        strprintf(&buf, "%s%s", buf, url->server);
+      }
+    }
+    if(url->port) strprintf(&buf, "%s:%u", buf, url->port);
+  }
+
+  if(url->share) strprintf(&buf, "%s/%s", buf, url->share);
+
+  if(path && url->scheme != inst_slp) {
+    strprintf(&buf, "%s/%s%s",
+      buf,
+      url->scheme == inst_ftp && *path == '/' ? "%2F" : "",
+      *path == '/' ? path + 1 : path
+    );
+  }
+
+  str_copy(&path, NULL);
+
+  return buf;
+}
+
+
 char *url_print2(url_t *url, char *file)
 {
   static char *buf = NULL, *s = "";
@@ -3425,7 +3701,11 @@
 
   i = file_sym2num(scheme);
 
-  if(i >= 0) return i;
+  if(i >= 0) {
+    char *str = url_scheme2name(i);
+    // ensure it really matches the expected scheme
+    if(str && !strcmp(str, scheme)) return i;
+  }
 
   if(util_check_exist2("/scripts/url", scheme) == 'd') {
     char *attr = NULL, *attr_val;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/linuxrc-6.0.15/util.c new/linuxrc-7.0.0/util.c
--- old/linuxrc-6.0.15/util.c   2019-09-24 15:39:06.000000000 +0200
+++ new/linuxrc-7.0.0/util.c    2019-10-23 15:46:25.000000000 +0200
@@ -1247,8 +1247,15 @@
     slist_append_str(&sl0, buf);
   }
 
-  if(config.autoyast) {
-    sprintf(buf, "autoyast = %s", config.autoyast);
+  if((s = url_print(config.url.autoyast, 0))) {
+    slist_append_str(&sl0, "autoyast url:");
+    sprintf(buf, "  %s", s);
+    slist_append_str(&sl0, buf);
+  }
+
+  if((s = url_print(config.url.autoyast2, 0))) {
+    slist_append_str(&sl0, "autoyast2 url:");
+    sprintf(buf, "  %s", s);
     slist_append_str(&sl0, buf);
   }
 


Reply via email to