Class: Yast::PackageClass

Inherits:
Module
  • Object
show all
Extended by:
Forwardable
Includes:
Logger
Defined in:
library/packages/src/modules/Package.rb

Overview

This module implements support to query, install and remove packages.

Prefer Package to PackageSystem

Depending on the mode, this module decides if it should interact with PackageSystem (libzypp) or PackageAI (AutoYaST). For instance, if you open a module in the AutoYaST UI, calling to #CheckAndInstallPackages does not install the package for real. Instead, it adds the package to the list of packages to include in the profile. However, when running on other modes (normal, installation, etc.), it just installs the package.

Overriding default behavior

There might a scenario where you want to force Package to work with the real packages. For instance, while reading the configuration during a clone_system operation: the mode is still autoinst_config but you are dealing with the underlying system. In those cases, you can force Package to work with PackageSystem.

If you are accessing this module through YCP (for instance, using Perl), you cannot pass the :target option. If you need to specify this option, please consider using PackageSystem or PackageAI functions directly.

See https://bugzilla.suse.com/show_bug.cgi?id=1196963 for further details.

Examples:

Forcing to check for packages on the underlying system

Yast::Package.Installed("firewalld", target: :system)

Instance Method Summary collapse

Instance Method Details

#AskPackages(packs, install) ⇒ Object

Asks the user if the given packages should be installed or removed

It only makes sense in CommandLine mode.

Parameters:

  • packs (Array<String>)

    List of packages to install/remove

  • install (Boolean)

    True to install the packages, false to remove them



291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
# File 'library/packages/src/modules/Package.rb', line 291

def AskPackages(packs, install)
  packs = deep_copy(packs)
  pkgs = Builtins.mergestring(packs, ", ")
  text = if install
    # the message is followed by list of required packages
    _("These packages need to be installed:")
  else
    # the message is followed by list of required packages
    _("These packages need to be removed:")
  end

  text += " " + pkgs

  CommandLine.Print(text)

  CommandLine.YesNo
end

#Available(package) ⇒ Boolean

Determines whether the package is available or not

This method checks whether any available package provides the given "package".

Parameters:

  • package (String)

    Package name

Returns:

  • (Boolean)

    true if the package is available; false otherwise

See Also:



# File 'library/packages/src/modules/Package.rb', line 75

#AvailableAll(packages) ⇒ Boolean

Are all of these packages available?

Parameters:

  • packages (Array<String>)

    list of packages

Returns:

  • (Boolean)

    true if yes (nil = an error occurred)



230
231
232
233
234
235
236
237
238
239
240
241
242
243
# File 'library/packages/src/modules/Package.rb', line 230

def AvailableAll(packages)
  packages = deep_copy(packages)
  error = false

  which = Builtins.find(packages) do |p|
    avail = Available(p)
    error = true if avail.nil?
    !avail
  end

  return nil if error

  which.nil?
end

#AvailableAny(packages) ⇒ Boolean

Is any of these packages available?

Parameters:

  • packages (Array<String>)

    list of packages

Returns:

  • (Boolean)

    true if yes (nil = an error occurred)



248
249
250
251
252
253
254
255
256
257
258
259
260
261
# File 'library/packages/src/modules/Package.rb', line 248

def AvailableAny(packages)
  packages = deep_copy(packages)
  error = false

  which = Builtins.find(packages) do |p|
    avail = Available(p)
    error = true if avail.nil?
    avail
  end

  return nil if error

  !which.nil?
end

#CheckAndInstallPackages(packages) ⇒ Boolean

Check if packages are installed

Install them if they are not and user approves installation

false otherwise

Parameters:

  • packages (Array<String>)

    list of packages to check (and install)

Returns:

  • (Boolean)

    true if installation succeeded or packages were installed,



148
149
150
151
152
153
# File 'library/packages/src/modules/Package.rb', line 148

def CheckAndInstallPackages(packages)
  return true if Mode.config
  return true if InstalledAll(packages)

  InstallAll(packages)
end

#CheckAndInstallPackagesInteractive(packages) ⇒ Boolean

Check if packages are installed

Install them if they are not and user approves installation If installation fails (or wasn't allowed), ask user if he wants to continue

before or user decided to continue, false otherwise

Parameters:

  • packages (Array<String>)

    a list of packages to check (and install)

Returns:

  • (Boolean)

    true if installation succeeded, packages were installed



164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
# File 'library/packages/src/modules/Package.rb', line 164

def CheckAndInstallPackagesInteractive(packages)
  success = CheckAndInstallPackages(packages)
  return true if success

  if !LastOperationCanceled()
    if Mode.commandline
      # error report
      Report.Error(_("Installing required packages failed."))
    else
      Popup.ContinueCancel(
        # continue/cancel popup
        _(
          "Installing required packages failed. If you continue\n" \
          "without installing required packages,\n" \
          "YaST may not work properly.\n"
        )
      )
    end
  elsif Mode.commandline
    Report.Error(
      # error report
      _("Cannot continue without installing required packages.")
    )
  else
    Popup.ContinueCancel(
      # continue/cancel popup
      _(
        "If you continue without installing required \npackages, YaST may not work properly.\n"
      )
    )
  end
end

#DoInstall(packages) ⇒ Boolean

Installs the given packages

Parameters:

  • packages (Array<String>)

    Name of the packages to install

Returns:

  • (Boolean)

    true if packages were successfully installed



# File 'library/packages/src/modules/Package.rb', line 93

#DoInstallAndRemove(toinstall, toremove) ⇒ Boolean

Install and remove packages in one go

Parameters:

  • toinstall (Array<String>)

    Name of the packages to install

  • toremove (Array<String>)

    Name of the packages to remove

Returns:

  • (Boolean)

    true on success



210
211
212
213
214
215
216
217
218
219
220
# File 'library/packages/src/modules/Package.rb', line 210

def DoInstallAndRemove(toinstall, toremove)
  ret = backend.DoInstallAndRemove(toinstall, toremove)
  return false unless ret

  if !InstalledAll(toinstall)
    log.error("Required packages have not been installed")
    return false
  end

  true
end

#DoRemove(packages) ⇒ Boolean

Removes the given packages

Parameters:

  • packages (Array<String>)

    Name of the packages to remove

Returns:

  • (Boolean)

    true if packages were successfully removed



# File 'library/packages/src/modules/Package.rb', line 98

#Install(package) ⇒ Boolean

Installs a package

Parameters:

  • package (String)

    package to be installed

Returns:

  • (Boolean)

    true on success



402
403
404
# File 'library/packages/src/modules/Package.rb', line 402

def Install(package)
  InstallMsg(package, nil)
end

#InstallAll(packages) ⇒ Boolean

Installs a list of packages

Parameters:

  • packages (Array<String>)

    list of packages to be installed

Returns:

  • (Boolean)

    true on success



410
411
412
413
# File 'library/packages/src/modules/Package.rb', line 410

def InstallAll(packages)
  packages = deep_copy(packages)
  InstallAllMsg(packages, nil)
end

#InstallAllMsg(packages, message) ⇒ Object

Install list of packages with a custom text message

Parameters:

  • packages (Array<String>)

    The list packages to be installed

  • message (String)

    custom text message

Returns:

  • True on success



376
377
378
379
# File 'library/packages/src/modules/Package.rb', line 376

def InstallAllMsg(packages, message)
  packages = deep_copy(packages)
  PackageDialog(packages, true, message)
end

#Installed(package, target: nil) ⇒ Boolean

Determines whether the package is provided or not

This method checks whether any installed package provides the given "package".

Parameters:

  • package (String)

    Package name

  • target (Symbol, nil) (defaults to: nil)

    :autoinst or :system. If it is nil, it guesses the backend depending on the mode.

Returns:

  • (Boolean)

    true if the package exists; false otherwise

See Also:



124
125
126
# File 'library/packages/src/modules/Package.rb', line 124

def Installed(package, target: nil)
  find_backend(target).Installed(package)
end

#InstalledAll(packages, target: nil) ⇒ Boolean

Are all of these packages installed?

Parameters:

  • packages (Array<String>)

    list of packages

  • target (Symbol, nil) (defaults to: nil)

    :autoinst or :system. If it is nil, it guesses the backend depending on the mode.

Returns:

  • (Boolean)

    true if yes



268
269
270
271
272
# File 'library/packages/src/modules/Package.rb', line 268

def InstalledAll(packages, target: nil)
  packages = deep_copy(packages)
  which = Builtins.find(packages) { |p| !Installed(p, target: target) }
  which.nil?
end

#InstalledAny(packages, target: nil) ⇒ Boolean

Is any of these packages installed?

Parameters:

  • packages (Array<String>)

    list of packages

  • target (Symbol, nil) (defaults to: nil)

    :autoinst or :system. If it is nil, it guesses the backend depending on the mode.

Returns:

  • (Boolean)

    true if yes



279
280
281
282
283
# File 'library/packages/src/modules/Package.rb', line 279

def InstalledAny(packages, target: nil)
  packages = deep_copy(packages)
  which = Builtins.find(packages) { |p| Installed(p, target: target) }
  !which.nil?
end

#InstallKernel(kernel_modules) ⇒ Boolean

Installs the given kernel modules

Parameters:

  • kernel_modules (Array<String>)

    Names of the kernel modules to install

Returns:

  • (Boolean)

    true on success



107
108
109
110
111
112
113
# File 'library/packages/src/modules/Package.rb', line 107

def main
  textdomain "base"

  @last_op_canceled = false
  @installed_packages = []
  @removed_packages = []
end

#InstallMsg(package, message) ⇒ Object

Install a package with a custom text message

Parameters:

  • package (String)

    to be installed

  • message (String)

    custom text message

Returns:

  • True on success



368
369
370
# File 'library/packages/src/modules/Package.rb', line 368

def InstallMsg(package, message)
  PackageDialog([package], true, message)
end

#IsTransactionalSystemBoolean

Return if system is transactional and does not support direct package install

Returns:

  • (Boolean)


442
443
444
445
446
447
448
449
450
451
452
453
# File 'library/packages/src/modules/Package.rb', line 442

def IsTransactionalSystem
  return @transactional unless @transactional.nil?

  mounts = SCR.Read(path(".proc.mounts"))
  root = mounts.find { |m| m["file"] == WFM.scr_root }
  log.info "root in mounts #{root.inspect}"

  raise "Failed to find #{WFM.scr_root} at /proc/mounts" unless root

  # check if there are ro keyword in mount
  @transactional = /(?:^|,)ro(?:,|$)/.match?(root["mntops"])
end

#LastOperationCanceledObject

Return result of the last operation Use immediately after calling any Package*:: function

Returns:

  • true if it last operation was canceled



435
436
437
# File 'library/packages/src/modules/Package.rb', line 435

def LastOperationCanceled
  @last_op_canceled
end

#mainObject



107
108
109
110
111
112
113
# File 'library/packages/src/modules/Package.rb', line 107

def main
  textdomain "base"

  @last_op_canceled = false
  @installed_packages = []
  @removed_packages = []
end

#PackageAvailable(package) ⇒ Boolean

Determines whether the package with the given name is available

This method check just the package's name.

Parameters:

  • package (String)

    Package name

Returns:

  • (Boolean)

    true if the package is available; false otherwise

See Also:



# File 'library/packages/src/modules/Package.rb', line 84

#PackageDialog(packages, install, message) ⇒ Object

Main package installatio|removal dialog

Parameters:

  • packages (Array<String>)

    list of packages

  • install (Boolean)

    true if install, false if remove

  • message (String)

    optional installation|removal text (nil -> standard will be used)

Returns:

  • true on success



314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
# File 'library/packages/src/modules/Package.rb', line 314

def PackageDialog(packages, install, message)
  log.info "Asking for packages: #{packages}"
  packs = Builtins.filter(packages) do |package|
    install ? !Installed(package) : Installed(package)
  end
  log.info "Remaining packages: #{packs}"

  return true if packs.empty?

  check_transactional_system!(packs, install ? :install : :remove)

  # Popup Text
  text = _("These packages need to be installed:") + "<p>"
  # Popup Text
  text = _("These packages need to be removed:") + "<p>" if install == false

  Builtins.foreach(packs) do |p|
    text = Ops.add(text, Builtins.sformat("%1<br>", p))
  end

  text = Builtins.sformat(message, Builtins.mergestring(packs, ", ")) if !message.nil?

  doit = if Mode.commandline
    CommandLine.Interactive ? AskPackages(packs, install) : true
  else
    Popup.AnyQuestionRichText(
      "",
      text,
      40,
      10,
      # labels changed for bug #215195
      #  Label::ContinueButton (), Label::CancelButton (),
      # push button label
      install ? Label.InstallButton : _("&Uninstall"),
      Label.CancelButton,
      :focus_yes
    )
  end

  if doit
    @last_op_canceled = false
    return DoRemove(packs) if install == false

    return DoInstall(packs)
  end

  @last_op_canceled = true
  false
end

#PackageInstalled(package, target: nil) ⇒ Boolean

Determines whether the package is installed or not

This method check just the package's name.

Parameters:

  • package (String)

    Package name

  • target (Symbol, nil) (defaults to: nil)

    :autoinst or :system. If it is nil, it guesses the backend depending on the mode.

Returns:

  • (Boolean)

    true if the package exists; false otherwise

See Also:



137
138
139
# File 'library/packages/src/modules/Package.rb', line 137

def PackageInstalled(package, target: nil)
  find_backend(target).PackageInstalled(package)
end

#Remove(package) ⇒ Boolean

Removes a package

Parameters:

  • package (String)

    package to be removed

Returns:

  • (Boolean)

    true on success



419
420
421
# File 'library/packages/src/modules/Package.rb', line 419

def Remove(package)
  RemoveMsg(package, nil)
end

#RemoveAll(packages) ⇒ Boolean

Removes a list of packages

Parameters:

  • packages (Array<String>)

    list of packages to be removed

Returns:

  • (Boolean)

    true on success



427
428
429
430
# File 'library/packages/src/modules/Package.rb', line 427

def RemoveAll(packages)
  packages = deep_copy(packages)
  RemoveAllMsg(packages, nil)
end

#RemoveAllMsg(packages, message) ⇒ Object

Remove a list of packages with a custom text message

Parameters:

  • packages (Array<String>)

    The list of packages to be removed

  • message (String)

    custom text message

Returns:

  • True on success



393
394
395
396
# File 'library/packages/src/modules/Package.rb', line 393

def RemoveAllMsg(packages, message)
  packages = deep_copy(packages)
  PackageDialog(packages, false, message)
end

#RemoveMsg(package, message) ⇒ Object

Remove a package with a custom text message

Parameters:

  • package (String)

    package to be removed

  • message (String)

    custom text message

Returns:

  • True on success



385
386
387
# File 'library/packages/src/modules/Package.rb', line 385

def RemoveMsg(package, message)
  PackageDialog([package], false, message)
end

#resetObject



222
223
224
225
# File 'library/packages/src/modules/Package.rb', line 222

def reset
  @installed_packages.clear
  @removed_packages.clear
end