summaryrefslogtreecommitdiffstats
path: root/pym/portage/_emirrordist/DeletionTask.py
blob: 7d10957face6381438a1d105e640fa6a6e773b10 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
# Copyright 2013 Gentoo Foundation
# Distributed under the terms of the GNU General Public License v2

import errno
import logging

from portage import os
from portage.util._async.FileCopier import FileCopier
from _emerge.CompositeTask import CompositeTask

class DeletionTask(CompositeTask):

	__slots__ = ('distfile', 'config')

	def _start(self):

		distfile_path = os.path.join(
			self.config.options.distfiles, self.distfile)

		if self.config.options.recycle_dir is not None:
			distfile_path = os.path.join(self.config.options.distfiles, self.distfile)
			recycle_path = os.path.join(
				self.config.options.recycle_dir, self.distfile)
			if self.config.options.dry_run:
				logging.info(("dry-run: move '%s' from "
					"distfiles to recycle") % self.distfile)
			else:
				logging.debug(("move '%s' from "
					"distfiles to recycle") % self.distfile)
				try:
					os.rename(distfile_path, recycle_path)
				except OSError as e:
					if e.errno != errno.EXDEV:
						logging.error(("rename %s from distfiles to "
							"recycle failed: %s") % (self.distfile, e))
				else:
					self.returncode = os.EX_OK
					self._async_wait()
					return

				self._start_task(
					FileCopier(src_path=distfile_path,
						dest_path=recycle_path,
						background=False),
					self._recycle_copier_exit)
				return

		success = True

		if self.config.options.dry_run:
			logging.info(("dry-run: delete '%s' from "
				"distfiles") % self.distfile)
		else:
			logging.debug(("delete '%s' from "
				"distfiles") % self.distfile)
			try:
				os.unlink(distfile_path)
			except OSError as e:
				if e.errno not in (errno.ENOENT, errno.ESTALE):
					logging.error("%s unlink failed in distfiles: %s" %
						(self.distfile, e))
					success = False

		if success:
			self._success()
			self.returncode = os.EX_OK
		else:
			self.returncode = 1

		self._async_wait()

	def _recycle_copier_exit(self, copier):

		self._assert_current(copier)
		if self._was_cancelled():
			self.wait()
			return

		success = True
		if copier.returncode == os.EX_OK:

			try:
				os.unlink(copier.src_path)
			except OSError as e:
				if e.errno not in (errno.ENOENT, errno.ESTALE):
					logging.error("%s unlink failed in distfiles: %s" %
						(self.distfile, e))
					success = False

		else:
			logging.error(("%s copy from distfiles "
				"to recycle failed: %s") % (self.distfile, e))
			success = False

		if success:
			self._success()
			self.returncode = os.EX_OK
		else:
			self.returncode = 1

		self._current_task = None
		self.wait()

	def _success(self):

		cpv = "unknown"
		if self.config.distfiles_db is not None:
			cpv = self.config.distfiles_db.get(self.distfile, cpv)

		self.config.delete_count += 1
		self.config.log_success("%s\t%s\tremoved" % (cpv, self.distfile))

		if self.config.distfiles_db is not None:
			try:
				del self.config.distfiles_db[self.distfile]
			except KeyError:
				pass
			else:
				logging.debug(("drop '%s' from "
					"distfiles db") % self.distfile)

		if self.config.deletion_db is not None:
			try:
				del self.config.deletion_db[self.distfile]
			except KeyError:
				pass
			else:
				logging.debug(("drop '%s' from "
					"deletion db") % self.distfile)