1 --- steam-launcher/bin_steamdeps.py.orig 2020-06-15 16:29:37.582721048 +0200
2 +++ steam-launcher/bin_steamdeps.py 2020-06-15 16:58:54.551881214 +0200
4 # This is the set of supported dependency formats
5 SUPPORTED_STEAM_DEPENDENCY_VERSION = ['1']
8 +ARCH = "i686" # updated during package build
15 + "libc6:i386": "@libc.so.6(GLIBC_2.15)",
16 + "libc6:amd64": "@libc.so.6(GLIBC_2.15)(64bit)",
18 + # different libGL implementation pull different drivers & dependencies
19 + "libgl1-mesa-dri:i386": "@libGL.so.1",
20 + "libgl1-mesa-glx:i386": "@libGL.so.1",
24 + PLD_PACKAGE_MAP["libgl1-mesa-dri"] = "@libGL.so.1()(64bit)"
25 + PLD_PACKAGE_MAP["libgl1-mesa-glx"] = "@libGL.so.1()(64bit)"
27 + PLD_PACKAGE_MAP["libgl1-mesa-dri"] = "@libGL.so.1"
28 + PLD_PACKAGE_MAP["libgl1-mesa-glx"] = "@libGL.so.1"
37 +PLD_PKGNAME_RE = re.compile(r"^(.*)-([^-]*)-([^-]*?)(?:\.([^-]*))?$")
39 +PLD_CONFIG_FN = "/etc/sysconfig/steam-launcher"
42 +def pld_get_config():
43 + """Load the sysconfig file. Accept shell-like syntax."""
45 + if _config is not None:
49 + with open(PLD_CONFIG_FN) as config_f:
50 + for line in config_f:
52 + if not line or line.startswith("#"):
55 + print >>sys.stderr, "{0}: syntax error: {1!r}".format(PLD_CONFIG_FN, line)
57 + key, value = line.split("=", 1)
59 + value = value.strip()
60 + if value.startswith('"'):
61 + if value.endswith('"'):
64 + print >>sys.stderr, "{0}: syntax error: {1!r}".format(PLD_CONFIG_FN, line)
67 + except IOError as err:
68 + print >>sys.stderr, "{0}: {1}".format(PLD_CONFIG_FN, err)
72 +def pld_config_enabled(variable, default=False):
73 + config = pld_get_config()
74 + value = config.get(variable, default)
75 + if value in (True, False):
77 + return value.lower() in ("yes", "true", "on")
79 +def pld_config_get(variable, default=None):
80 + config = pld_get_config()
81 + return config.get(variable, default)
84 # Get the current package architecture
85 # This may be different than the actual architecture for the case of i386
86 # chroot environments on amd64 hosts.
88 +# PLD: use the architecture the steam-launcher package was built for
91 Get the current architecture
96 - _arch = subprocess.check_output(
97 - ['dpkg', '--print-architecture']).decode("utf-8").strip()
99 + return PLD_ARCH_MAP[ARCH]
109 # Check to see if another package Provides this package
110 # N.B. Version checks are not supported on virtual packages
112 def is_provided(pkgname):
114 - process = subprocess.Popen(['apt-cache', 'showpkg', pkgname],
115 - stdout=subprocess.PIPE,
116 - stderr=subprocess.PIPE)
117 - pattern = re.compile(r'^Reverse Provides:')
119 - for line in process.stdout:
120 - if re.match(pattern, str(line, 'utf-8')):
121 - for provider in process.stdout:
122 - (name, version) = provider.split()
123 - providers[name] = version
124 - for provider in providers.keys():
125 - if has_package(provider):
128 - except (OSError, FileNotFoundError):
132 + pkgname, arch = pkgname.split(":", 1)
136 + if pkgname.startswith("@"):
137 + pkgname = pkgname[1:]
139 + process = subprocess.Popen(['rpm', '-q', '--what-provides', pkgname],
140 + stdout=subprocess.PIPE, stderr=subprocess.PIPE)
141 + for line in process.stdout:
142 + line = line.decode( "utf-8" ).strip()
143 + match = PLD_PKGNAME_RE.match(line)
144 + if ( match is None ):
146 + pkg_arch = match.group(4)
147 + if arch and pkg_arch and PLD_ARCH_MAP[pkg_arch] != arch:
148 + print("bad arch {0!r}!={1!r}".format(PLD_ARCH_MAP[pkg_arch], arch))
156 return is_provided(self.name)
158 for (op, version) in self.version_conditions:
159 - if subprocess.call(['dpkg', '--compare-versions', self.installed,
160 - op, version]) != 0:
162 + rc = subprocess.call(['rpmvercmp', self.installed, version], stdout=open("/dev/null","w") )
163 + if op in ("=", "==") and rc != 0:
165 + if op == ">" and rc != 1:
167 + if op == ">=" and rc not in (0, 1):
169 + if op == "<" and rc != 2:
171 + if op == "<=" and rc not in (0, 2):
179 def has_package(package):
180 - process = subprocess.Popen(['dpkg', '-l', package], stdout=subprocess.PIPE,
181 - stderr=subprocess.PIPE)
182 - installed_pattern = re.compile(r"^\Si\s+([^\s]+)\s+([^\s]+)")
183 - for line in process.stdout:
184 - line = line.decode("utf-8").strip()
185 - match = re.match(installed_pattern, line)
192 + return is_provided(package)
199 def remap_package(name):
204 @@ -218,10 +285,13 @@
206 if "DISPLAY" in os.environ:
209 - ["gnome-terminal", "--disable-factory", "-t", title, "-e"]),
210 + # PLD: --disable-factory doesn't work any more
211 + #("gnome-terminal",
212 + # ["gnome-terminal", "--disable-factory", "-t", title, "-e"]),
214 ["konsole", "--nofork", "-p", "tabtitle=" + title, "-e"]),
216 + ["Terminal", "--disable-server", "--title"+title, "-x"]),
218 ["xterm", "-bg", "#383635", "-fg", "#d1cfcd", "-T", title, "-e"]),
222 for (program, commandLine) in programs:
223 if subprocess.call(['which', program],
224 - stdout=subprocess.PIPE) == 0:
225 + stdout=subprocess.PIPE, stderr=open("/dev/null", "w")) == 0:
228 # Fallback if no GUI terminal program is available
229 @@ -245,17 +315,21 @@
230 to do this, but nothing that exists yet does what we need.
233 - package_list = " ".join([package.name for package in packages])
235 # Create a temporary file to hold the installation completion status
236 (fd, status_file) = tempfile.mkstemp()
239 + # Create a poldek pset file to allow installing virtual deps
240 + psetFile = tempfile.NamedTemporaryFile("w")
241 + for package in packages:
242 + print >> psetFile, package.name
245 # Create a script to run, in a secure way
246 (fd, script_file) = tempfile.mkstemp()
247 - script = """#!/bin/sh
248 + script = """#!/bin/sh{sh_flag}
252 # If your host file is misconfigured in certain circumstances this
253 # can cause sudo to block for a while, which causes gksudo to go into
254 # limbo and never return.
255 @@ -272,31 +346,30 @@
263 Steam needs to install these additional packages:
269 -# Check to make sure 64-bit systems can get 32-bit packages
270 -if [ "$(dpkg --print-architecture)" = "amd64" ] && \
271 - ! dpkg --print-foreign-architectures | grep i386 >/dev/null; then
272 - sudo dpkg --add-architecture i386
274 +[ -n "{sudo}" ] && check_sudo
276 # Update the package list, showing progress
277 -sudo apt-get update | while read line; do echo -n "."; done
278 +{sudo} poldek {poldek_options} --up
281 # Install the packages!
282 -sudo apt-get install %s
284 +{sudo} poldek {poldek_options} -u --pset={pset}
285 +echo $? >{status_file}
286 echo -n "Press return to continue: "
288 -""" % (", ".join([package.name for package in packages]), package_list,
291 + pkg_list = ", ".join( [ package.name for package in packages ] ),
292 + pset=psetFile.name,
293 + status_file=statusFile,
294 + sh_flag=" -x" if pld_config_enabled("DEBUG") else "",
295 + sudo="sudo" if pld_config_enabled("USE_SUDO") else "",
296 + poldek_options=pld_config_get("POLDEK_OPTIONS", ""))
297 os.write(fd, script.encode("utf-8"))
299 os.chmod(script_file, (stat.S_IRUSR | stat.S_IWUSR | stat.S_IXUSR))
301 except KeyboardInterrupt:
303 os.unlink(script_file)
306 # Read the status out of the file, since if we ran the script in a
307 # terminal the process status will be whether the terminal started
310 os.unlink(status_file)
313 + print("\nWARNING: dependencies install failed!\n")
318 @@ -345,11 +422,11 @@
319 "STEAM_DEPENDENCY_VERSION"])
322 - # Make sure we can use dpkg on this system.
323 + # Make sure we can use rpm on this system.
325 - subprocess.call(['dpkg', '--version'], stdout=subprocess.PIPE)
326 + subprocess.call(['rpm', '--version'], stdout=subprocess.PIPE)
327 except FileNotFoundError:
328 - sys.stderr.write("Couldn't find dpkg, please update steamdeps for "
329 + sys.stderr.write("Couldn't find rpm, please update steamdeps for "
330 "your distribution.\n")
334 sys.stderr.write("Usage: %s dependencies.txt\n" % sys.argv[0])
337 - # Make sure we can open the file
338 + # disable steam runtime, so their libs won't conflict our binaries
339 + os.unsetenv("LD_LIBRARY_PATH")
340 + os.unsetenv("LD_PRELOAD")
342 + # Make sure we can open the file
344 fp = open(sys.argv[1])
345 except Exception as e:
346 @@ -404,10 +485,20 @@
349 for section in line.split("|"):
350 - package = create_package(section)
351 + pld_pkg = PLD_PACKAGE_MAP.get(section, section)
355 + package = create_package( pld_pkg )
359 + if package.name in packages:
360 + existing = packages[package.name]
361 + if existing.version_conditions == package.version_conditions:
362 + row.append( existing )
365 packages[package.name] = package
368 @@ -435,22 +526,28 @@
369 if "COLUMNS" in os.environ:
370 del os.environ["COLUMNS"]
372 - process = subprocess.Popen(['dpkg', '-l'] + list(packages.keys()),
373 - stdout=subprocess.PIPE, stderr=subprocess.PIPE)
374 - installed_pattern = re.compile(r"^\Si\s+([^\s]+)\s+([^\s]+)")
375 + pkg_names = [name.split(":", 1)[0] for name in packages.keys() if not name.startswith("@")]
376 + process = subprocess.Popen( ['rpm', '-q'] + pkg_names, stdout=subprocess.PIPE, stderr=subprocess.PIPE )
377 for line in process.stdout:
378 line = line.decode("utf-8").strip()
379 - match = re.match(installed_pattern, line)
380 + match = PLD_PKGNAME_RE.match(line)
384 name = match.group(1)
385 if name not in packages:
386 - name = get_full_package_name(name)
388 + arch = PLD_ARCH_MAP[match.group(4)]
389 + name = "{0}:{1}".format(name, arch)
391 + name = getFullPackageName( name )
392 + if name not in packages:
394 packages[name].set_installed(match.group(2))
396 # See which ones need to be installed
398 + consider_installed = pld_config_get("INSTALLED", "").split()
400 for row in dependencies:
407 - needed.append(row[0])
408 + if row[0].name not in consider_installed:
409 + needed.add( row[0] )
411 + print("Considering {0} already installed".format(row[0].name))
413 # If we have anything to install, do it!
416 print("Package %s needs to be installed" % package.name,
419 - return update_packages(needed)
420 + if pld_config_enabled("INSTALL_PACKAGES", True):
421 + print("Installing packages as configured through {0}...".format(PLD_CONFIG_FN))
422 + return updatePackages( needed )
424 + print("\nWARNING: Dependencies missing, but package install disabled through {0}\n".format(PLD_CONFIG_FN))