]>
git.ipfire.org Git - people/stevee/pakfire.git/blob - src/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 log
= logging
.getLogger("pakfire")
41 from constants
import *
44 # Import binary version of version_compare and capability functions
45 from _pakfire
import version_compare
, get_capabilities
, set_capabilities
, personality
47 def cli_is_interactive():
49 Say weather a shell is interactive or not.
51 if sys
.stdin
.isatty() and sys
.stdout
.isatty() and sys
.stderr
.isatty():
56 def ask_user(question
):
58 Ask the user the question, he or she can answer with yes or no.
60 This function returns True for "yes" and False for "no".
62 If the software is running in a non-inteactive shell, no question
63 is asked at all and the answer is always "yes".
65 if not cli_is_interactive():
68 print _("%s [y/N]") % question
,
70 print # Just an empty line.
72 return ret
in ("y", "Y", "z", "Z", "j", "J")
74 def random_string(length
=20):
77 for i
in range(length
):
78 s
+= random
.choice(string
.letters
)
82 def make_progress(message
, maxval
, eta
=True, speed
=False):
83 # Return nothing if stdout is not a terminal.
84 if not sys
.stdout
.isatty():
91 progressbar
.Bar(left
="[", right
="]"),
97 progressbar
.Percentage(), " ",
98 progressbar
.FileTransferSpeed(), " "
102 widgets
+= [progressbar
.ETA(), " ",]
107 pb
= progressbar
.ProgressBar(widgets
=widgets
, maxval
=maxval
)
112 def rm(path
, *args
, **kargs
):
114 version of shutil.rmtree that ignores no-such-file-or-directory errors,
115 and tries harder if it finds immutable files
118 failedFilename
= None
122 shutil
.rmtree(path
, *args
, **kargs
)
124 if e
.errno
== 2: # no such file or directory
126 elif e
.errno
==1 or e
.errno
==13:
128 if failedFilename
== e
.filename
:
130 failedFilename
= e
.filename
131 os
.system("chattr -R -i %s" % path
)
135 def ioctl_GWINSZ(fd
):
137 cr
= struct
.unpack("hh", fcntl
.ioctl(fd
, termios
.TIOCGWINSZ
, "1234"))
144 cr
= ioctl_GWINSZ(0) or ioctl_GWINSZ(1) or ioctl_GWINSZ(2)
148 fd
= os
.open(os
.ctermid(), os
.O_RDONLY
)
149 cr
= ioctl_GWINSZ(fd
)
156 cr
= (os
.environ
['LINES'], os
.environ
['COLUMNS'])
160 return int(cr
[1]), int(cr
[0])
165 # If s is negative, we save the sign and run the calculation with the
166 # absolute value of s.
171 units
= (" ", "k", "M", "G", "T")
174 while s
>= 1024 and unit
< len(units
):
178 return "%d%s" % (round(s
) * sign
, units
[unit
])
181 return "%02d:%02d" % (s
// 60, s
% 60)
184 return "%sB/s" % format_size(s
)
186 def calc_hash1(filename
=None, data
=None):
187 h
= hashlib
.new("sha1")
191 buf
= f
.read(BUFFER_SIZE
)
194 buf
= f
.read(BUFFER_SIZE
)
203 def text_wrap(s
, length
=65):
210 for line
in s
.splitlines():
214 words
+= line
.split()
220 # An empty words means a line break.
223 lines
.append(" ".join(line
))
228 if len(" ".join(line
)) + len(word
) >= length
:
229 lines
.append(" ".join(line
))
231 words
.insert(0, word
)
236 lines
.append(" ".join(line
))
240 #return "\n".join(lines)
243 def orphans_kill(root
, killsig
=signal
.SIGTERM
):
245 kill off anything that is still chrooted.
247 log
.debug(_("Killing orphans..."))
250 for fn
in [d
for d
in os
.listdir("/proc") if d
.isdigit()]:
252 r
= os
.readlink("/proc/%s/root" % fn
)
253 if os
.path
.realpath(root
) == os
.path
.realpath(r
):
254 log
.warning(_("Process ID %s is still running in chroot. Killing...") % fn
)
258 os
.kill(pid
, killsig
)
263 # If something was killed, wait a couple of seconds to make sure all file descriptors
264 # are closed and we can proceed with umounting the filesystems.
266 log
.warning(_("Waiting for processes to terminate..."))
269 # Calling ourself again to make sure all processes were killed.
270 orphans_kill(root
, killsig
=killsig
)
272 def scriptlet_interpreter(scriptlet
):
274 This function returns the interpreter of a scriptlet.
279 for line
in scriptlet
.splitlines():
280 if line
.startswith("#!/"):
281 interpreter
= line
[2:]
282 interpreter
= interpreter
.split()[0]