1   
  2   
  3   
  4   
  5   
  6   
  7   
  8   
  9   
 10   
 11   
 12   
 13   
 14   
 15   
 16  import os 
 17  import sys 
 18  import shutil 
 19   
 20  from twisted.internet import defer 
 21  from twisted.python import runtime, log 
 22   
 23  from buildslave import runprocess 
 24  from buildslave.commands import base, utils 
 27      """This is a Command which creates a directory. The args dict contains 
 28      the following keys: 
 29   
 30          - ['dir'] (required): subdirectory which the command will create, 
 31                                    relative to the builder dir 
 32   
 33      MakeDirectory creates the following status messages: 
 34          - {'rc': rc} : when the process has terminated 
 35      """ 
 36   
 37      header = "mkdir" 
 38   
 40          args = self.args 
 41           
 42          assert args['dir'] is not None 
 43          dirname = os.path.join(self.builder.basedir, args['dir']) 
 44   
 45          try: 
 46              if not os.path.isdir(dirname): 
 47                  os.makedirs(dirname) 
 48              self.sendStatus({'rc': 0}) 
 49          except: 
 50              self.sendStatus({'rc': 1}) 
   51   
 53      """This is a Command which removes a directory. The args dict contains 
 54      the following keys: 
 55   
 56          - ['dir'] (required): subdirectory which the command will create, 
 57                                relative to the builder dir. This argument 
 58                                can be either a single directory name as a string 
 59                                or list of directory names as a list. 
 60   
 61          - ['timeout']:  seconds of silence tolerated before we kill off the 
 62                          command 
 63   
 64          - ['maxTime']:  seconds before we kill off the command 
 65   
 66   
 67      RemoveDirectory creates the following status messages: 
 68          - {'rc': rc} : when the process has terminated 
 69      """ 
 70   
 71      header = "rmdir" 
 72       
 74          self.logEnviron = args.get('logEnviron',True) 
  75   
 76   
 77      @defer.deferredGenerator 
 79          args = self.args 
 80           
 81          assert args['dir'] is not None 
 82          dirnames = args['dir'] 
 83   
 84          self.timeout = args.get('timeout', 120) 
 85          self.maxTime = args.get('maxTime', None) 
 86          self.rc = 0 
 87          if type(dirnames) is list: 
 88              assert len(dirnames) != 0 
 89              for dirname in dirnames: 
 90                  wfd = defer.waitForDeferred(self.removeSingleDir(dirname)) 
 91                  yield wfd 
 92                  res = wfd.getResult() 
 93                   
 94                   
 95                   
 96                  if res != 0: 
 97                      self.rc = res 
 98          else: 
 99              wfd = defer.waitForDeferred(self.removeSingleDir(dirnames)) 
100              yield wfd 
101              self.rc = wfd.getResult() 
102   
103          self.sendStatus({'rc': self.rc}) 
 104   
106           
107          self.dir = os.path.join(self.builder.basedir, dirname) 
108          if runtime.platformType != "posix": 
109               
110               
111              utils.rmdirRecursive(self.dir) 
112              d = defer.succeed(0) 
113          else: 
114              d = self._clobber(None) 
115   
116          return d 
 117   
118 -    def _clobber(self, dummy, chmodDone = False): 
 135   
137          assert isinstance(rc, int) 
138          if rc == 0: 
139              return defer.succeed(0) 
140           
141   
142          command = ["chmod", "-Rf", "u+rwx", os.path.join(self.builder.basedir, self.dir)] 
143          if sys.platform.startswith('freebsd'): 
144               
145               
146               
147              command = ["find", os.path.join(self.builder.basedir, self.dir), 
148                                  '-exec', 'chmod', 'u+rwx', '{}', ';' ] 
149          c = runprocess.RunProcess(self.builder, command, self.builder.basedir, 
150                           sendRC=0, timeout=self.timeout, maxTime=self.maxTime, 
151                           logEnviron=self.logEnviron, usePTY=False) 
152   
153          self.command = c 
154          d = c.start() 
155          d.addCallback(lambda dummy: self._clobber(dummy, True)) 
156          return d 
  157   
159      """This is a Command which copies a directory. The args dict contains 
160      the following keys: 
161   
162          - ['fromdir'] (required): subdirectory which the command will copy, 
163                                    relative to the builder dir 
164          - ['todir'] (required): subdirectory which the command will create, 
165                                    relative to the builder dir 
166   
167          - ['timeout']:  seconds of silence tolerated before we kill off the 
168                          command 
169   
170          - ['maxTime']:  seconds before we kill off the command 
171   
172   
173      CopyDirectory creates the following status messages: 
174          - {'rc': rc} : when the process has terminated 
175      """ 
176   
177      header = "rmdir" 
178   
180          self.logEnviron = args.get('logEnviron',True) 
 181           
183          args = self.args 
184           
185           
186          assert args['todir'] is not None 
187          assert args['fromdir'] is not None 
188   
189          fromdir = os.path.join(self.builder.basedir, args['fromdir']) 
190          todir = os.path.join(self.builder.basedir, args['todir']) 
191   
192          self.timeout = args.get('timeout', 120) 
193          self.maxTime = args.get('maxTime', None) 
194   
195          if runtime.platformType != "posix": 
196              self.sendStatus({'header': "Since we're on a non-POSIX platform, " 
197              "we're not going to try to execute cp in a subprocess, but instead " 
198              "use shutil.copytree(), which will block until it is complete.  " 
199              "fromdir: %s, todir: %s\n" % (fromdir, todir)}) 
200              shutil.copytree(fromdir, todir) 
201              d = defer.succeed(0) 
202          else: 
203              if not os.path.exists(os.path.dirname(todir)): 
204                  os.makedirs(os.path.dirname(todir)) 
205              if os.path.exists(todir): 
206                   
207                  log.msg("cp target '%s' already exists -- cp will not do what you think!" % todir) 
208   
209              command = ['cp', '-R', '-P', '-p', fromdir, todir] 
210              c = runprocess.RunProcess(self.builder, command, self.builder.basedir, 
211                               sendRC=False, timeout=self.timeout, maxTime=self.maxTime, 
212                               logEnviron=self.logEnviron, usePTY=False) 
213              self.command = c 
214              d = c.start() 
215              d.addCallback(self._abandonOnFailure) 
216   
217           
218          d.addCallbacks(self._sendRC, self._checkAbandoned) 
219          return d 
  220   
222      """This is a command which stats a file on the slave. The args dict contains the following keys: 
223   
224          - ['file'] (required): file to stat 
225   
226      StatFile creates the following status messages: 
227          - {'rc': rc} : 0 if the file is found, 1 otherwise 
228          - {'stat': stat} : if the files is found, stat contains the result of os.stat 
229      """ 
230   
231      header = "stat" 
232   
 245