]>
Commit | Line | Data |
---|---|---|
12696415 JP |
1 | --- steam-launcher/bin_steamdeps.py.orig 2020-07-29 17:44:37.000000000 +0200 |
2 | +++ steam-launcher/bin_steamdeps.py 2020-07-29 19:54:23.553743588 +0200 | |
3 | @@ -34,8 +34,80 @@ | |
7b16f921 | 4 | # This is the set of supported dependency formats |
2837397a | 5 | SUPPORTED_STEAM_DEPENDENCY_VERSION = ['1'] |
7b16f921 | 6 | |
2837397a | 7 | -_arch = None |
12696415 | 8 | - |
7b16f921 | 9 | +ARCH = "i686" # updated during package build |
12696415 | 10 | + |
7b16f921 JK |
11 | +PLD_PACKAGE_MAP = { |
12 | + "python-apt": None, | |
13 | + "xz-utils": "xz", | |
14 | + | |
15 | + "libc6": "glibc", | |
16 | + "libc6:i386": "@libc.so.6(GLIBC_2.15)", | |
17 | + "libc6:amd64": "@libc.so.6(GLIBC_2.15)(64bit)", | |
18 | + | |
19 | + # different libGL implementation pull different drivers & dependencies | |
20 | + "libgl1-mesa-dri:i386": "@libGL.so.1", | |
21 | + "libgl1-mesa-glx:i386": "@libGL.so.1", | |
22 | + } | |
23 | + | |
24 | +if "64" in ARCH: | |
25 | + PLD_PACKAGE_MAP["libgl1-mesa-dri"] = "@libGL.so.1()(64bit)" | |
26 | + PLD_PACKAGE_MAP["libgl1-mesa-glx"] = "@libGL.so.1()(64bit)" | |
27 | +else: | |
28 | + PLD_PACKAGE_MAP["libgl1-mesa-dri"] = "@libGL.so.1" | |
29 | + PLD_PACKAGE_MAP["libgl1-mesa-glx"] = "@libGL.so.1" | |
30 | + | |
31 | +PLD_ARCH_MAP = { | |
32 | + "x86_64": "amd64", | |
33 | + "i486": "i386", | |
34 | + "i586": "i386", | |
35 | + "i686": "i386", | |
36 | + } | |
37 | + | |
38 | +PLD_PKGNAME_RE = re.compile(r"^(.*)-([^-]*)-([^-]*?)(?:\.([^-]*))?$") | |
d58e2a57 JK |
39 | + |
40 | +PLD_CONFIG_FN = "/etc/sysconfig/steam-launcher" | |
41 | + | |
42 | +_config = None | |
43 | +def pld_get_config(): | |
2837397a JP |
44 | + """Load the sysconfig file. Accept shell-like syntax.""" |
45 | + global _config | |
46 | + if _config is not None: | |
47 | + return _config | |
48 | + config = {} | |
49 | + try: | |
50 | + with open(PLD_CONFIG_FN) as config_f: | |
51 | + for line in config_f: | |
52 | + line = line.strip() | |
53 | + if not line or line.startswith("#"): | |
54 | + continue | |
55 | + if "=" not in line: | |
56 | + print >>sys.stderr, "{0}: syntax error: {1!r}".format(PLD_CONFIG_FN, line) | |
57 | + continue | |
58 | + key, value = line.split("=", 1) | |
59 | + key = key.strip() | |
60 | + value = value.strip() | |
61 | + if value.startswith('"'): | |
62 | + if value.endswith('"'): | |
63 | + value = value[1:-1] | |
64 | + else: | |
65 | + print >>sys.stderr, "{0}: syntax error: {1!r}".format(PLD_CONFIG_FN, line) | |
66 | + continue | |
67 | + config[key] = value | |
68 | + except IOError as err: | |
69 | + print >>sys.stderr, "{0}: {1}".format(PLD_CONFIG_FN, err) | |
70 | + _config = config | |
71 | + return config | |
d58e2a57 JK |
72 | + |
73 | +def pld_config_enabled(variable, default=False): | |
2837397a JP |
74 | + config = pld_get_config() |
75 | + value = config.get(variable, default) | |
76 | + if value in (True, False): | |
77 | + return value | |
78 | + return value.lower() in ("yes", "true", "on") | |
d58e2a57 JK |
79 | + |
80 | +def pld_config_get(variable, default=None): | |
2837397a JP |
81 | + config = pld_get_config() |
82 | + return config.get(variable, default) | |
83 | ||
12696415 JP |
84 | class OsRelease: |
85 | def __init__(self): | |
86 | @@ -100,17 +172,12 @@ | |
7b16f921 JK |
87 | # This may be different than the actual architecture for the case of i386 |
88 | # chroot environments on amd64 hosts. | |
2837397a | 89 | # |
7b16f921 | 90 | +# PLD: use the architecture the steam-launcher package was built for |
2837397a JP |
91 | def get_arch(): |
92 | """ | |
93 | Get the current architecture | |
94 | """ | |
95 | - global _arch | |
7b16f921 | 96 | - |
2837397a JP |
97 | - if _arch is None: |
98 | - _arch = subprocess.check_output( | |
99 | - ['dpkg', '--print-architecture']).decode("utf-8").strip() | |
100 | - return _arch | |
12696415 | 101 | - |
2837397a JP |
102 | + return PLD_ARCH_MAP[ARCH] |
103 | ||
7b16f921 | 104 | ### |
12696415 JP |
105 | def get_full_package_name(name): |
106 | @@ -126,16 +193,27 @@ | |
7b16f921 JK |
107 | # N.B. Version checks are not supported on virtual packages |
108 | # | |
2837397a | 109 | def is_provided(pkgname): |
c8145d11 JP |
110 | - """ |
111 | - Check to see if another package Provides this package | |
112 | - """ | |
113 | - cache = apt.Cache() | |
114 | - pkgs = cache.get_providing_packages(pkgname) | |
115 | - for pkg in pkgs: | |
116 | - if pkg.is_installed: | |
117 | - return True | |
2837397a JP |
118 | - return False |
119 | + if ":" in pkgname: | |
120 | + pkgname, arch = pkgname.split(":", 1) | |
121 | + else: | |
122 | + arch = None | |
c8145d11 | 123 | |
2837397a JP |
124 | + if pkgname.startswith("@"): |
125 | + pkgname = pkgname[1:] | |
c8145d11 | 126 | + |
2837397a JP |
127 | + process = subprocess.Popen(['rpm', '-q', '--what-provides', pkgname], |
128 | + stdout=subprocess.PIPE, stderr=subprocess.PIPE) | |
129 | + for line in process.stdout: | |
130 | + line = line.decode( "utf-8" ).strip() | |
131 | + match = PLD_PKGNAME_RE.match(line) | |
132 | + if ( match is None ): | |
133 | + continue | |
134 | + pkg_arch = match.group(4) | |
135 | + if arch and pkg_arch and PLD_ARCH_MAP[pkg_arch] != arch: | |
136 | + print("bad arch {0!r}!={1!r}".format(PLD_ARCH_MAP[pkg_arch], arch)) | |
137 | + continue | |
138 | + return True | |
139 | + return False | |
7b16f921 JK |
140 | |
141 | ### | |
142 | class Package: | |
12696415 | 143 | @@ -157,9 +235,17 @@ |
2837397a | 144 | return is_provided(self.name) |
7b16f921 | 145 | |
2837397a JP |
146 | for (op, version) in self.version_conditions: |
147 | - if subprocess.call(['dpkg', '--compare-versions', self.installed, | |
148 | - op, version]) != 0: | |
149 | - return False | |
7b16f921 JK |
150 | + rc = subprocess.call(['rpmvercmp', self.installed, version], stdout=open("/dev/null","w") ) |
151 | + if op in ("=", "==") and rc != 0: | |
152 | + return False | |
153 | + if op == ">" and rc != 1: | |
154 | + return False | |
d58e2a57 | 155 | + if op == ">=" and rc not in (0, 1): |
7b16f921 JK |
156 | + return False |
157 | + if op == "<" and rc != 2: | |
158 | + return False | |
d58e2a57 | 159 | + if op == "<=" and rc not in (0, 2): |
7b16f921 JK |
160 | + return False |
161 | ||
2837397a | 162 | return True |
7b16f921 | 163 | |
12696415 | 164 | @@ -185,6 +271,7 @@ |
7b16f921 | 165 | |
2837397a JP |
166 | |
167 | def remap_package(name): | |
168 | + return name | |
169 | if name in ( | |
170 | 'python-apt', | |
171 | ): | |
12696415 | 172 | @@ -289,6 +376,8 @@ |
2837397a | 173 | programs = [ |
2837397a JP |
174 | ("konsole", |
175 | ["konsole", "--nofork", "-p", "tabtitle=" + title, "-e"]), | |
176 | + ("Terminal", | |
177 | + ["Terminal", "--disable-server", "--title"+title, "-x"]), | |
178 | ("xterm", | |
179 | ["xterm", "-bg", "#383635", "-fg", "#d1cfcd", "-T", title, "-e"]), | |
c8145d11 | 180 | ("x-terminal-emulator", |
12696415 | 181 | @@ -305,7 +394,7 @@ |
2837397a JP |
182 | ] |
183 | for (program, commandLine) in programs: | |
184 | if subprocess.call(['which', program], | |
185 | - stdout=subprocess.PIPE) == 0: | |
186 | + stdout=subprocess.PIPE, stderr=open("/dev/null", "w")) == 0: | |
187 | return commandLine | |
188 | ||
189 | # Fallback if no GUI terminal program is available | |
12696415 | 190 | @@ -320,17 +409,21 @@ |
2837397a JP |
191 | to do this, but nothing that exists yet does what we need. |
192 | """ | |
193 | ||
194 | - package_list = " ".join([package.name for package in packages]) | |
7b16f921 | 195 | - |
2837397a JP |
196 | # Create a temporary file to hold the installation completion status |
197 | (fd, status_file) = tempfile.mkstemp() | |
198 | os.close(fd) | |
199 | ||
200 | + # Create a poldek pset file to allow installing virtual deps | |
201 | + psetFile = tempfile.NamedTemporaryFile("w") | |
202 | + for package in packages: | |
203 | + print >> psetFile, package.name | |
204 | + psetFile.flush() | |
7b16f921 | 205 | + |
2837397a JP |
206 | # Create a script to run, in a secure way |
207 | (fd, script_file) = tempfile.mkstemp() | |
208 | - script = """#!/bin/sh | |
209 | + script = """#!/bin/sh{sh_flag} | |
d58e2a57 JK |
210 | check_sudo() |
211 | -{ | |
212 | +{{ | |
213 | # If your host file is misconfigured in certain circumstances this | |
214 | # can cause sudo to block for a while, which causes gksudo to go into | |
215 | # limbo and never return. | |
12696415 | 216 | @@ -347,31 +440,30 @@ |
d58e2a57 JK |
217 | else |
218 | return 0 | |
219 | fi | |
220 | -} | |
221 | +}} | |
7b16f921 | 222 | |
d58e2a57 | 223 | cat <<__EOF__ |
2837397a JP |
224 | Steam needs to install these additional packages: |
225 | - %s | |
226 | + {pkg_list} | |
d58e2a57 JK |
227 | __EOF__ |
228 | -check_sudo | |
229 | - | |
7b16f921 | 230 | -# Check to make sure 64-bit systems can get 32-bit packages |
2837397a JP |
231 | -if [ "$(dpkg --print-architecture)" = "amd64" ] && \ |
232 | - ! dpkg --print-foreign-architectures | grep i386 >/dev/null; then | |
7b16f921 JK |
233 | - sudo dpkg --add-architecture i386 |
234 | -fi | |
d58e2a57 JK |
235 | +[ -n "{sudo}" ] && check_sudo |
236 | ||
7b16f921 JK |
237 | # Update the package list, showing progress |
238 | -sudo apt-get update | while read line; do echo -n "."; done | |
d58e2a57 | 239 | +{sudo} poldek {poldek_options} --up |
7b16f921 JK |
240 | echo |
241 | ||
242 | # Install the packages! | |
243 | -sudo apt-get install %s | |
d58e2a57 JK |
244 | -echo $? >%s |
245 | +{sudo} poldek {poldek_options} -u --pset={pset} | |
246 | +echo $? >{status_file} | |
7b16f921 JK |
247 | echo -n "Press return to continue: " |
248 | read line | |
2837397a JP |
249 | -""" % (", ".join([package.name for package in packages]), package_list, |
250 | - status_file) | |
d58e2a57 | 251 | +""".format( |
2837397a JP |
252 | + pkg_list = ", ".join( [ package.name for package in packages ] ), |
253 | + pset=psetFile.name, | |
254 | + status_file=statusFile, | |
255 | + sh_flag=" -x" if pld_config_enabled("DEBUG") else "", | |
256 | + sudo="sudo" if pld_config_enabled("USE_SUDO") else "", | |
257 | + poldek_options=pld_config_get("POLDEK_OPTIONS", "")) | |
258 | os.write(fd, script.encode("utf-8")) | |
259 | os.close(fd) | |
260 | os.chmod(script_file, (stat.S_IRUSR | stat.S_IWUSR | stat.S_IXUSR)) | |
12696415 | 261 | @@ -382,6 +474,7 @@ |
2837397a JP |
262 | except KeyboardInterrupt: |
263 | pass | |
264 | os.unlink(script_file) | |
265 | + psetFile.close() | |
266 | ||
267 | # Read the status out of the file, since if we ran the script in a | |
268 | # terminal the process status will be whether the terminal started | |
12696415 | 269 | @@ -393,6 +486,9 @@ |
2837397a JP |
270 | |
271 | os.unlink(status_file) | |
272 | ||
273 | + if status: | |
274 | + print("\nWARNING: dependencies install failed!\n") | |
d58e2a57 | 275 | + |
2837397a JP |
276 | return status |
277 | ||
278 | ||
12696415 | 279 | @@ -419,11 +515,11 @@ |
2837397a JP |
280 | "STEAM_DEPENDENCY_VERSION"]) |
281 | return False | |
282 | ||
283 | - # Make sure we can use dpkg on this system. | |
284 | + # Make sure we can use rpm on this system. | |
285 | try: | |
286 | - subprocess.call(['dpkg', '--version'], stdout=subprocess.PIPE) | |
287 | + subprocess.call(['rpm', '--version'], stdout=subprocess.PIPE) | |
288 | except FileNotFoundError: | |
289 | - sys.stderr.write("Couldn't find dpkg, please update steamdeps for " | |
290 | + sys.stderr.write("Couldn't find rpm, please update steamdeps for " | |
291 | "your distribution.\n") | |
292 | return False | |
293 | ||
12696415 JP |
294 | @@ -457,7 +553,11 @@ |
295 | os_release.dump() | |
296 | return 0 | |
2837397a JP |
297 | |
298 | - # Make sure we can open the file | |
299 | + # disable steam runtime, so their libs won't conflict our binaries | |
300 | + os.unsetenv("LD_LIBRARY_PATH") | |
301 | + os.unsetenv("LD_PRELOAD") | |
e0f04824 JK |
302 | + |
303 | + # Make sure we can open the file | |
2837397a | 304 | try: |
12696415 | 305 | fp = open(args.dependencies) |
2837397a | 306 | except Exception as e: |
12696415 | 307 | @@ -496,10 +596,20 @@ |
2837397a JP |
308 | |
309 | row = [] | |
310 | for section in line.split("|"): | |
311 | - package = create_package(section) | |
312 | + pld_pkg = PLD_PACKAGE_MAP.get(section, section) | |
313 | + if not pld_pkg: | |
314 | + continue | |
7b16f921 | 315 | + |
2837397a JP |
316 | + package = create_package( pld_pkg ) |
317 | if package is None: | |
318 | continue | |
319 | ||
320 | + if package.name in packages: | |
321 | + existing = packages[package.name] | |
322 | + if existing.version_conditions == package.version_conditions: | |
323 | + row.append( existing ) | |
324 | + continue | |
7b16f921 | 325 | + |
2837397a JP |
326 | packages[package.name] = package |
327 | row.append(package) | |
328 | ||
12696415 | 329 | @@ -544,22 +654,28 @@ |
2837397a JP |
330 | if "COLUMNS" in os.environ: |
331 | del os.environ["COLUMNS"] | |
332 | ||
333 | - process = subprocess.Popen(['dpkg', '-l'] + list(packages.keys()), | |
334 | - stdout=subprocess.PIPE, stderr=subprocess.PIPE) | |
335 | - installed_pattern = re.compile(r"^\Si\s+([^\s]+)\s+([^\s]+)") | |
336 | + pkg_names = [name.split(":", 1)[0] for name in packages.keys() if not name.startswith("@")] | |
337 | + process = subprocess.Popen( ['rpm', '-q'] + pkg_names, stdout=subprocess.PIPE, stderr=subprocess.PIPE ) | |
338 | for line in process.stdout: | |
339 | line = line.decode("utf-8").strip() | |
340 | - match = re.match(installed_pattern, line) | |
341 | + match = PLD_PKGNAME_RE.match(line) | |
342 | if match is None: | |
343 | continue | |
344 | ||
345 | name = match.group(1) | |
346 | if name not in packages: | |
347 | - name = get_full_package_name(name) | |
348 | + if match.group(4): | |
349 | + arch = PLD_ARCH_MAP[match.group(4)] | |
350 | + name = "{0}:{1}".format(name, arch) | |
351 | + else: | |
352 | + name = getFullPackageName( name ) | |
353 | + if name not in packages: | |
354 | + continue | |
355 | packages[name].set_installed(match.group(2)) | |
356 | ||
357 | # See which ones need to be installed | |
358 | - needed = [] | |
359 | + consider_installed = pld_config_get("INSTALLED", "").split() | |
360 | + needed = set() | |
361 | for row in dependencies: | |
362 | if len(row) == 0: | |
363 | continue | |
12696415 | 364 | @@ -570,7 +686,10 @@ |
2837397a JP |
365 | satisfied = True |
366 | break | |
367 | if not satisfied: | |
368 | - needed.append(row[0]) | |
369 | + if row[0].name not in consider_installed: | |
370 | + needed.add( row[0] ) | |
371 | + else: | |
372 | + print("Considering {0} already installed".format(row[0].name)) | |
373 | ||
374 | # If we have anything to install, do it! | |
375 | if len(needed) > 0: | |
12696415 JP |
376 | @@ -587,7 +706,12 @@ |
377 | if args.dry_run: | |
378 | return 1 | |
379 | else: | |
380 | - return update_packages(needed) | |
381 | + if pld_config_enabled("INSTALL_PACKAGES", True): | |
382 | + print("Installing packages as configured through {0}...".format(PLD_CONFIG_FN)) | |
383 | + return updatePackages( needed ) | |
384 | + else: | |
385 | + print("\nWARNING: Dependencies missing, but package install disabled through {0}\n".format(PLD_CONFIG_FN)) | |
386 | + return 1 | |
2837397a JP |
387 | else: |
388 | return 0 | |
d58e2a57 | 389 |