]>
git.ipfire.org Git - pakfire.git/blob - pakfire/util.py
2 ###############################################################################
4 # Pakfire - The IPFire package management system #
5 # Copyright (C) 2011 Pakfire development team #
7 # This program is free software: you can redistribute it and/or modify #
8 # it under the terms of the GNU General Public License as published by #
9 # the Free Software Foundation, either version 3 of the License, or #
10 # (at your option) any later version. #
12 # This program is distributed in the hope that it will be useful, #
13 # but WITHOUT ANY WARRANTY; without even the implied warranty of #
14 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
15 # GNU General Public License for more details. #
17 # You should have received a copy of the GNU General Public License #
18 # along with this program. If not, see <http://www.gnu.org/licenses/>. #
20 ###############################################################################
22 from __future__
import division
39 from constants
import *
42 # Import binary version of version_compare
43 from _pakfire
import version_compare
45 def cli_is_interactive():
47 Say weather a shell is interactive or not.
49 if sys
.stdin
.isatty() and sys
.stdout
.isatty() and sys
.stderr
.isatty():
54 def ask_user(question
):
56 Ask the user the question, he or she can answer with yes or no.
58 This function returns True for "yes" and False for "no".
60 If the software is running in a non-inteactive shell, no question
61 is asked at all and the answer is always "yes".
63 if not cli_is_interactive():
66 print _("%s [y/N]") % question
,
68 print # Just an empty line.
70 return ret
in ("y", "Y", "z", "Z", "j", "J")
72 def random_string(length
=20):
75 for i
in range(length
):
76 s
+= random
.choice(string
.letters
)
81 class Bar(progressbar
.Bar
):
82 def update(self
, pbar
, width
):
83 percent
= pbar
.percentage()
87 cwidth
= width
- len(self
.left
) - len(self
.right
)
88 marked_width
= int(percent
* cwidth
/ 100)
89 m
= self
._format
_marker
(pbar
)
90 bar
= (self
.left
+ (m
*marked_width
).ljust(cwidth
) + self
.right
)
93 def make_progress(message
, maxval
, eta
=True):
94 # Return nothing if stdout is not a terminal.
95 if not sys
.stdout
.isatty():
102 Bar(left
="[", right
="]"),
107 widgets
+= [progressbar
.ETA(), " ",]
112 pb
= progressbar
.ProgressBar(widgets
=widgets
, maxval
=maxval
)
117 def rm(path
, *args
, **kargs
):
119 version of shutil.rmtree that ignores no-such-file-or-directory errors,
120 and tries harder if it finds immutable files
123 failedFilename
= None
127 shutil
.rmtree(path
, *args
, **kargs
)
129 if e
.errno
== 2: # no such file or directory
131 elif e
.errno
==1 or e
.errno
==13:
133 if failedFilename
== e
.filename
:
135 failedFilename
= e
.filename
136 os
.system("chattr -R -i %s" % path
)
140 def ioctl_GWINSZ(fd
):
142 cr
= struct
.unpack("hh", fcntl
.ioctl(fd
, termios
.TIOCGWINSZ
, "1234"))
149 cr
= ioctl_GWINSZ(0) or ioctl_GWINSZ(1) or ioctl_GWINSZ(2)
153 fd
= os
.open(os
.ctermid(), os
.O_RDONLY
)
154 cr
= ioctl_GWINSZ(fd
)
161 cr
= (os
.environ
['LINES'], os
.environ
['COLUMNS'])
165 return int(cr
[1]), int(cr
[0])
170 # If s is negative, we save the sign and run the calculation with the
171 # absolute value of s.
176 units
= (" ", "k", "M", "G", "T")
179 while s
>= 1024 and unit
< len(units
):
183 return "%d %s" % (int(s
) * sign
, units
[unit
])
186 return "%02d:%02d" % (s
// 60, s
% 60)
189 return "%sB/s" % format_size(s
)
191 def calc_hash1(filename
=None, data
=None):
196 buf
= f
.read(BUFFER_SIZE
)
199 buf
= f
.read(BUFFER_SIZE
)
208 def text_wrap(s
, length
=65):
215 for line
in s
.splitlines():
219 words
+= line
.split()
225 # An empty words means a line break.
228 lines
.append(" ".join(line
))
233 if len(" ".join(line
)) + len(word
) >= length
:
234 lines
.append(" ".join(line
))
236 words
.insert(0, word
)
241 lines
.append(" ".join(line
))
245 #return "\n".join(lines)
248 def orphans_kill(root
, killsig
=signal
.SIGTERM
):
250 kill off anything that is still chrooted.
252 logging
.debug("Killing orphans...")
254 for fn
in [d
for d
in os
.listdir("/proc") if d
.isdigit()]:
256 r
= os
.readlink("/proc/%s/root" % fn
)
257 if os
.path
.realpath(root
) == os
.path
.realpath(r
):
258 logging
.warning("Process ID %s is still running in chroot. Killing..." % fn
)
261 os
.kill(pid
, killsig
)
266 def scriptlet_interpreter(scriptlet
):
268 This function returns the interpreter of a scriptlet.
273 for line
in scriptlet
.splitlines():
274 if line
.startswith("#!/"):
275 interpreter
= line
[2:]
276 interpreter
= interpreter
.split()[0]
281 def calc_parallelism():
283 Calculate how many processes to run
286 We take the log10(number of processors) * factor
288 num
= os
.sysconf("SC_NPROCESSORS_CONF")
292 return int(round(math
.log10(num
) * 26))