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