• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

yast / yast-autoinstallation / 13494013411

24 Feb 2025 08:44AM UTC coverage: 69.018% (+0.03%) from 68.993%
13494013411

push

github

web-flow
Merge pull request #881 from yast/merge_SLE-15-SP7

Added pervasive encryption fields (master)

6429 of 9315 relevant lines covered (69.02%)

10.35 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

63.48
/src/modules/AutoInstall.rb
1
# File:  modules/AutoInstall.ycp
2
# Package:  Auto-installation
3
# Summary:  Auto-installation related functions module
4
# Author:  Anas Nashif <nashif@suse.de>
5
#
6
# $Id$
7
require "yast"
1✔
8
require "autoinstall/pkg_gpg_check_handler"
1✔
9
require "autoinstall/dialogs/question"
1✔
10
require "installation/autoinst_issues"
1✔
11

12
module Yast
1✔
13
  class AutoInstallClass < Module
1✔
14
    include Yast::Logger
1✔
15

16
    # @return [::Installation::AutoinstIssues::List] AutoYaST issues list
17
    attr_accessor :issues_list
1✔
18

19
    def main
1✔
20
      textdomain "autoinst"
4✔
21

22
      Yast.import "Profile"
4✔
23
      Yast.import "Mode"
4✔
24
      Yast.import "Stage"
4✔
25
      Yast.import "AddOnProduct"
4✔
26
      Yast.import "AutoInstallRules"
4✔
27
      Yast.import "AutoinstConfig"
4✔
28
      Yast.import "AutoinstGeneral"
4✔
29
      Yast.import "Report"
4✔
30
      Yast.import "TFTP"
4✔
31

32
      @autoconf = false
4✔
33
      @issues_list = ::Installation::AutoinstIssues::List.new
4✔
34

35
      AutoInstall()
4✔
36
    end
37

38
    def callbackTrue_boolean_string(_dummy)
1✔
39
      true
×
40
    end
41

42
    def callbackFalse_boolean_string(_dummy)
1✔
43
      false
×
44
    end
45

46
    def callbackTrue_boolean_string_integer(_dummy, _dummy2)
1✔
47
      true
×
48
    end
49

50
    def callbackFalse_boolean_string_integer(_dummy, _dummy2)
1✔
51
      false
×
52
    end
53

54
    def callback_void_map(_dummy_map)
1✔
55
      nil
×
56
    end
57

58
    def callbackTrue_boolean_map(_dummy_map)
1✔
59
      true
×
60
    end
61

62
    def callbackFalse_boolean_map(_dummy_map)
1✔
63
      false
×
64
    end
65

66
    def callbackTrue_boolean_map_integer(_dummy_map, _dummy)
1✔
67
      true
×
68
    end
69

70
    def callbackFalse_boolean_map_integer(_dummy_map, _dummy)
1✔
71
      false
×
72
    end
73

74
    def callbackTrue_boolean_string_map_integer(_dummy, _dummy_map, _dummy_int)
1✔
75
      true
×
76
    end
77

78
    def callbackFalse_boolean_string_map_integer(_dummy, _dummy_map, _dummy_int)
1✔
79
      false
×
80
    end
81

82
    def callbackTrue_boolean_string_string(_dummy1, _dummy2)
1✔
83
      true
×
84
    end
85

86
    def callbackFalse_boolean_string_string(_dummy1, _dummy2)
1✔
87
      false
×
88
    end
89

90
    def callbackTrue_boolean_string_string_integer(_dummy1, _dummy2, _dummy3)
1✔
91
      true
×
92
    end
93

94
    def callbackFalse_boolean_string_string_integer(_dummy1, _dummy2, _dummy3)
1✔
95
      false
×
96
    end
97

98
    def callbackTrue_boolean_string_string_string(_dummy1, _dummy2, _dummy3)
1✔
99
      true
×
100
    end
101

102
    def callbackFalse_boolean_string_string_string(_dummy1, _dummy2, _dummy3)
1✔
103
      false
×
104
    end
105

106
    # Read saved data in continue mode
107
    # @return [Boolean] true on success
108
    def Continue
1✔
109
      #
110
      # First check if there are some other control files availabe
111
      # i.e. for post-installation only
112
      #
113
      if SCR.Read(path(".target.size"), AutoinstConfig.autoconf_file) == -1
×
114
        ret = Profile.ReadProfileStructure(AutoinstConfig.parsedControlFile)
×
115
        if Profile.current == {} || !ret
×
116
          Builtins.y2milestone("No saved autoinstall data found")
×
117
          false
×
118
        else
119
          Builtins.y2milestone("Found and read saved autoinst data")
×
120
          SCR.Execute(path(".target.remove"), AutoinstConfig.parsedControlFile)
×
121
          true
×
122
        end
123
      else
124
        Builtins.y2milestone(
×
125
          "XML Post installation data found: %1",
126
          AutoinstConfig.autoconf_file
127
        )
128
        ret = Profile.ReadXML(AutoinstConfig.autoconf_file)
×
129
        SCR.Execute(
×
130
          path(".target.bash"),
131
          Builtins.sformat(
132
            "/bin/mv %1 %2",
133
            AutoinstConfig.autoconf_file,
134
            AutoinstConfig.cache
135
          )
136
        )
137
        ret
×
138
      end
139
    end
140

141
    # Constructer
142
    # @return [void]
143
    def AutoInstall
1✔
144
      if Stage.cont
4✔
145
        ret = Continue()
×
146
        if ret && Ops.greater_than(Builtins.size(Profile.current), 0)
×
147
          if Mode.autoupgrade
×
148
            Builtins.y2milestone(
×
149
              "AutoYaST upgrade mode already set, keeping it"
150
            )
151
          else
152
            Builtins.y2milestone("Enabling Auto-Installation mode")
×
153
            Mode.SetMode("autoinstallation")
×
154
          end
155
        elsif Mode.autoinst
×
156
          Builtins.y2milestone(
×
157
            "No autoyast data found, switching back to manual installation"
158
          )
159
          Mode.SetMode("installation")
×
160
        elsif Mode.autoupgrade
×
161
          Builtins.y2milestone(
×
162
            "No autoyast data found, switching back to manual update"
163
          )
164
          Mode.SetMode("update")
×
165
        end
166
      elsif Stage.initial
4✔
167
        if SCR.Read(path(".target.size"), AutoinstConfig.xml_tmpfile) != -1 &&
×
168
            Builtins.size(Profile.current) == 0
169
          Builtins.y2milestone("autoyast: %1 found", AutoinstConfig.xml_tmpfile)
×
170
          # Profile is available and it has not been parsed yet.
171
          Profile.ReadXML(AutoinstConfig.xml_tmpfile)
×
172
        end
173
      end
174
      nil
4✔
175
    end
176

177
    # Save configuration
178
    # @return [Boolean] true on success
179
    def Save
1✔
180
      if Mode.autoinst || Mode.autoupgrade
×
181
        Profile.SaveProfileStructure(AutoinstConfig.parsedControlFile)
×
182
      else
183
        true
×
184
      end
185
    end
186

187
    # Finish Auto-Installation by saving misc files
188
    # @param [String] destdir
189
    # @return [void]
190
    def Finish(destdir)
1✔
191
      dircontents = Convert.to_list(
1✔
192
        SCR.Read(
193
          path(".target.dir"),
194
          Ops.add(AutoinstConfig.tmpDir, "/pre-scripts/")
195
        )
196
      )
197
      if Ops.greater_than(Builtins.size(dircontents), 0)
1✔
198
        SCR.Execute(
1✔
199
          path(".target.bash"),
200
          Ops.add(
201
            Ops.add(
202
              Ops.add(
203
                Ops.add("/bin/cp ", AutoinstConfig.tmpDir),
204
                "/pre-scripts/* "
205
              ),
206
              destdir
207
            ),
208
            AutoinstConfig.scripts_dir
209
          )
210
        )
211
        SCR.Execute(
1✔
212
          path(".target.bash"),
213
          Ops.add(
214
            Ops.add(
215
              Ops.add(
216
                Ops.add("/bin/cp ", AutoinstConfig.tmpDir),
217
                "/pre-scripts/logs/* "
218
              ),
219
              destdir
220
            ),
221
            AutoinstConfig.logs_dir
222
          )
223
        )
224
      end
225

226
      # copying ask-scripts and corresponding log files
227
      # to /var/adm/autoinstall
228
      SCR.Execute(path(".target.bash"),
1✔
229
        "/bin/cp #{AutoinstConfig.tmpDir}/ask-scripts/logs/*"\
230
        " #{destdir}#{AutoinstConfig.logs_dir}")
231
      SCR.Execute(path(".target.bash"),
1✔
232
        "/bin/cp #{AutoinstConfig.tmpDir}/ask-scripts/*"\
233
        " #{destdir}#{AutoinstConfig.scripts_dir}")
234
      SCR.Execute(path(".target.bash"),
1✔
235
        "/bin/cp #{AutoinstConfig.tmpDir}/ask-default-value-scripts/*"\
236
        " #{destdir}#{AutoinstConfig.scripts_dir}")
237

238
      SCR.Execute(
1✔
239
        path(".target.bash"),
240
        Builtins.sformat(
241
          "/bin/cp %1 %2%3",
242
          AutoinstConfig.profile_path,
243
          destdir,
244
          AutoinstConfig.xml_file
245
        )
246
      )
247
      SCR.Execute(
1✔
248
        path(".target.bash"),
249
        Builtins.sformat(
250
          "/bin/chmod 700 %1%2",
251
          destdir,
252
          AutoinstConfig.xml_file
253
        )
254
      )
255

256
      SCR.Execute(
1✔
257
        path(".target.bash"),
258
        Builtins.sformat(
259
          "/bin/cp %1 %2%3",
260
          Ops.add(AutoinstConfig.profile_dir, "/pre-autoinst.xml"),
261
          destdir,
262
          AutoinstConfig.cache
263
        )
264
      )
265
      SCR.Execute(
1✔
266
        path(".target.bash"),
267
        Builtins.sformat(
268
          "/bin/chmod 700 %1%2",
269
          destdir,
270
          Ops.add(AutoinstConfig.cache, "/pre-autoinst.xml")
271
        )
272
      )
273

274
      # Saving postpartitioning-scripts scripts/logs
275
      postpart_dir = AutoinstConfig.tmpDir + "/postpartitioning-scripts"
1✔
276
      if Yast::FileUtils.Exists(postpart_dir)
1✔
277
        SCR.Execute(
×
278
          path(".target.bash"),
279
          "/bin/cp #{postpart_dir}/* #{destdir}#{AutoinstConfig.scripts_dir}"
280
        )
281
        SCR.Execute(
×
282
          path(".target.bash"),
283
          "/bin/cp #{postpart_dir}/logs/* #{destdir}#{AutoinstConfig.logs_dir}"
284
        )
285
      end
286

287
      nil
1✔
288
    end
289

290
    # Put PXE file on the boot server using tftp
291
    # @return true on success
292
    def PXELocalBoot
1✔
293
      tmpdir = Convert.to_string(SCR.Read(path(".target.tmpdir")))
×
294
      hexfile = Builtins.sformat("%1/%2", tmpdir, AutoInstallRules.hostid)
×
295
      pxe = Ops.get_map(Profile.current, "pxe", {})
×
296
      dest_file = Ops.get_string(pxe, "filename", AutoInstallRules.hostid)
×
297
      if dest_file == "__MAC__"
×
298
        mac = AutoInstallRules.mac
×
299
        dest_file = Builtins.sformat(
×
300
          "01-%1-%2-%3-%4-%5-%6",
301
          Builtins.substring(mac, 0, 2),
302
          Builtins.substring(mac, 2, 2),
303
          Builtins.substring(mac, 4, 2),
304
          Builtins.substring(mac, 6, 2),
305
          Builtins.substring(mac, 8, 2),
306
          Builtins.substring(mac, 10, 2)
307
        )
308
      end
309
      server = Ops.get_string(pxe, "tftp-server", "")
×
310
      if server != "" && Ops.get_boolean(pxe, "pxe_localboot", false)
×
311
        Builtins.y2milestone(
×
312
          "putting pxe local boot file '%2' on server :%1",
313
          server,
314
          dest_file
315
        )
316
        config = Ops.get_string(pxe, "pxelinux-config", "")
×
317
        dir = Ops.get_string(pxe, "pxelinux-dir", "pxelinux.cfg")
×
318
        config = "DEFAULT linux\nLABEL linux\n  localboot 0" if config == ""
×
319

320
        SCR.Write(path(".target.string"), hexfile, config)
×
321

322
        return TFTP.Put(server, Ops.add(Ops.add(dir, "/"), dest_file), hexfile)
×
323
      end
324
      true
×
325
    end
326

327
    # Implement pkgGpgCheck callback
328
    #
329
    # @param [Hash] data Output from `pkgGpgCheck` callback.
330
    # @option data [String] "CheckPackageResult" Check result code according to libzypp.
331
    # @option data [String] "Package" Package's name.
332
    # @option data [String] "Localpath" Path to RPM file.
333
    # @option data [String] "RepoMediaUrl" Media URL.
334
    #   (it should match `media_url` key in AutoYaST profile).
335
    # @return [String] "I" if the package should be accepted; otherwise
336
    #   a blank string is returned (so no decision is made).
337
    def pkg_gpg_check(data)
1✔
338
      log.debug("pkgGpgCheck data: #{data}")
2✔
339
      checker = PkgGpgCheckHandler.new(
2✔
340
        data, Yast::AutoinstGeneral.signature_handling, Yast::AddOnProduct.add_on_products
341
      )
342
      accept = checker.accept?
2✔
343
      log.info("PkgGpgCheckerHandler for #{data["Package"]} returned #{accept}")
2✔
344
      accept ? "I" : ""
2✔
345
    end
346

347
    # Checking for valid imported values and there is an fatal error
348
    # we will stop the installation.
349
    #
350
    # @return [Boolean] True if the proposal is valid or the user accepted an invalid one.
351
    def valid_imported_values
1✔
352
      return true if @issues_list.empty?
32✔
353

354
      report_settings = Report.Export
2✔
355
      if @issues_list.fatal?
2✔
356
        # On fatal errors, the message should be displayed
357
        level = :error
1✔
358
        buttons_set = :abort
1✔
359
        display_message = true
1✔
360
        log_message = report_settings["errors"]["log"]
1✔
361
        timeout = report_settings["errors"]["timeout"]
1✔
362
      else
363
        # On non-fatal issues, obey report settings for warnings
364
        level = :warn
1✔
365
        buttons_set = :question
1✔
366
        display_message = report_settings["warnings"]["show"]
1✔
367
        log_message = report_settings["warnings"]["log"]
1✔
368
        timeout = report_settings["warnings"]["timeout"]
1✔
369
      end
370

371
      presenter = ::Installation::AutoinstIssues::IssuesPresenter.new(@issues_list)
2✔
372

373
      # Showing issues onetime only.
374
      @issues_list = ::Installation::AutoinstIssues::List.new
2✔
375

376
      log.send(level, presenter.to_plain) if log_message
2✔
377
      return true unless display_message
2✔
378

379
      dialog = Y2Autoinstallation::Dialogs::Question.new(
2✔
380
        _("AutoYaST configuration file check"),
381
        presenter.to_html,
382
        timeout:     timeout,
383
        buttons_set: buttons_set
384
      )
385
      dialog.run == :ok
2✔
386
    end
387

388
    publish variable: :autoconf, type: "boolean"
1✔
389
    publish function: :callbackTrue_boolean_string, type: "boolean (string)"
1✔
390
    publish function: :callbackFalse_boolean_string, type: "boolean (string)"
1✔
391
    publish function: :callbackTrue_boolean_string_integer, type: "boolean (string, integer)"
1✔
392
    publish function: :callbackFalse_boolean_string_integer, type: "boolean (string, integer)"
1✔
393
    publish function: :callback_void_map, type: "void (map <string, any>)"
1✔
394
    publish function: :callbackTrue_boolean_map, type: "boolean (map <string, any>)"
1✔
395
    publish function: :callbackFalse_boolean_map, type: "boolean (map <string, any>)"
1✔
396
    publish function: :callbackTrue_boolean_map_integer,
1✔
397
      type:     "boolean (map <string, any>, integer)"
398
    publish function: :callbackFalse_boolean_map_integer,
1✔
399
      type:     "boolean (map <string, any>, integer)"
400
    publish function: :callbackTrue_boolean_string_map_integer,
1✔
401
      type:     "boolean (string, map <string, any>, integer)"
402
    publish function: :callbackFalse_boolean_string_map_integer,
1✔
403
      type:     "boolean (string, map <string, any>, integer)"
404
    publish function: :callbackTrue_boolean_string_string, type: "boolean (string, string)"
1✔
405
    publish function: :callbackFalse_boolean_string_string, type: "boolean (string, string)"
1✔
406
    publish function: :callbackTrue_boolean_string_string_integer,
1✔
407
      type:     "boolean (string, string, integer)"
408
    publish function: :callbackFalse_boolean_string_string_integer,
1✔
409
      type:     "boolean (string, string, integer)"
410
    publish function: :callbackTrue_boolean_string_string_string,
1✔
411
      type:     "boolean (string, string, string)"
412
    publish function: :callbackFalse_boolean_string_string_string,
1✔
413
      type:     "boolean (string, string, string)"
414
    publish function: :Continue, type: "boolean ()"
1✔
415
    publish function: :AutoInstall, type: "void ()"
1✔
416
    publish function: :Save, type: "boolean ()"
1✔
417
    publish function: :Finish, type: "void (string)"
1✔
418
    publish function: :PXELocalBoot, type: "boolean ()"
1✔
419
    publish function: :pkg_gpg_check, type: "string (map)"
1✔
420
  end
421

422
  AutoInstall = AutoInstallClass.new
1✔
423
  AutoInstall.main
1✔
424
end
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc