001    /*
002     * LocalSandbox.java
003     *
004     * Created on October 26, 2005, 2:39 PM
005     *
006     * This file is part of the STAR Scheduler.
007     * Copyright (c) 2003-2006 STAR Collaboration - Brookhaven National Laboratory
008     *
009     * STAR Scheduler is free software; you can redistribute it and/or modify
010     * it under the terms of the GNU General Public License as published by
011     * the Free Software Foundation; either version 2 of the License, or
012     * (at your option) any later version.
013     *
014     * STAR Scheduler is distributed in the hope that it will be useful,
015     * but WITHOUT ANY WARRANTY; without even the implied warranty of
016     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
017     * GNU General Public License for more details.
018     *
019     * You should have received a copy of the GNU General Public License
020     * along with STAR Scheduler; if not, write to the Free Software
021     * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
022     */
023    
024    package gov.bnl.star.offline.scheduler.util.sandbox;
025    import gov.bnl.star.offline.scheduler.util.sandbox.Sandbox;
026    import gov.bnl.star.offline.scheduler.util.FilesystemToolkit;
027    import gov.bnl.star.offline.scheduler.util.ConfigToolkit;
028    import gov.bnl.star.offline.scheduler.request.Request;
029    import gov.bnl.star.offline.scheduler.Job;
030    import gov.bnl.star.offline.scheduler.ComponentLibrary;
031    
032    import java.net.URL;
033    import java.util.List;
034    import java.util.ArrayList;
035    
036    import org.apache.log4j.Logger;
037    
038    /**
039     * The simplest implementation of the sandbox used to copy or link files in the simplest way possible without complex packing/compression schemes.
040     * @author  Levente Hajdu
041     */
042    public class LocalSandbox implements Sandbox{ 
043        
044         static private Logger log = Logger.getLogger(FilesystemToolkit.class.getName());
045        
046        private boolean fileWhereNotAdded = true; 
047        
048        /** Creates a new instance of LocalSandbox */
049        public LocalSandbox() {
050        }
051        
052        public String CopyCommand(SandboxPackage packageObj) {
053            
054            return "";
055        }
056        
057        public boolean MakePackage(SandboxPackage packageObj, Request request) {
058            return true;
059        }
060        
061        public boolean PackageExists(SandboxPackage packageObj) {
062            return true;
063        }
064        
065        public void Sandbox() {
066        }
067        
068        /** Write the command with which to setup the users sandbox. 
069         *  @param packageObj The sandbox package for which the commmand is needed
070         *  @param job The job of which the command is being written
071         *  @return the sandbox setup command as a string
072         **/
073        public String installCommand(SandboxPackage packageObj, Job job) {
074            
075            
076            //If this is a grid job there is no need for the sandbox coammand
077            if(ComponentLibrary.getInstance().getComponent("SUMS_FLAG_FORCE_GRID") != null ) return "";
078            if(! ConfigToolkit.getToolkit().isLocalQueue(job.getQueueObj())) return "";
079            
080             
081            
082              String lncommand = ConfigToolkit.findProgram("ln", job);
083    ///////////////////////////find the location of "ln" TODO: This should be placed in a common member func. base class as it is also in the zip class     
084    //        boolean foundProgram = false;
085    //        String lncommand = "/bin/ln";
086    //        if (job.getQueueObj().getBatchSystem().getSite().getProgramLocations() != null){
087    //            if (job.getQueueObj().getBatchSystem().getSite().getProgramLocations().containsKey("ln")){
088    //                lncommand = (String) job.getQueueObj().getBatchSystem().getSite().getProgramLocations().get("ln");
089    //                foundProgram = true;
090    //            } 
091    //        }
092    //        
093    //        if(! foundProgram){
094    //            System.out.println("\nWarning the program locations table could not find a record for program \"ln\" at site " + job.getQueueObj().getBatchSystem().getSite().getSiteName());
095    //        }
096            
097    ///////////////////Get the install dir //ToDo: This code sould realy be moved to setinstalldir 
098            String installDir = packageObj.getInstalldir();
099            
100            
101            
102           // String installDirBuffer = packageObj.getInstalldir();
103            
104            if(installDir == null){  //if nothing is stated use $SCRATCH
105                installDir = "$SCRATCH";
106            }
107            else {
108                installDir = installDir.trim();
109                if(installDir.length() > 0){
110                    installDir = installDir.replaceFirst("/$","");  //if the string has a size bogger then zero use this value, but strip of the last / if any. 
111                }
112                else{
113                    log.error("The install dir for the sand box is unclear, using $SCRATCH");
114                    installDir = "$SCRATCH";
115                }    
116            }
117            
118            
119            /*
120            else if(packageObj.getInstalldir().compareTo("\\$.*") == 0){ // if the path is an inv. ver. just leave it 
121                installDir = packageObj.getInstalldir();
122            }
123            else if(packageObj.getInstalldir().startsWith(System.getProperty("file.separator"))){ //if the path is absolute, just leave it  
124                installDir = packageObj.getInstalldir();
125            }
126            else{
127                installDir = "$SCRATCH" + System.getProperty("file.separator") + packageObj.getInstalldir(); //if the path is relative, then it is relative to $SCRATCH  
128            }
129             */
130               
131    ///////////////////////Make an ln command from every file in the package
132            List files = new ArrayList(); 
133            for(int i = 0; i != packageObj.getFiles().size(); i++ ) files.add( packageObj.getFiles().get(i)); //copy all items from the packages file list the files array
134            for(int i = 0; i != packageObj.getDirectorys().size(); i++ ) files.add( packageObj.getDirectorys().get(i)); //copy all items from the packages directory list the files array
135            
136            String inInstallCommand = "echo '.... building sandbox'\n" +
137                                      "setenv pwd `pwd` \n";    
138            
139            
140            for(int i = 0; i != files.size(); i ++){
141                URL file = (URL) files.get(i);
142                String fileNameAndPath = file.getFile().trim();
143                
144                /* Deactivated because output is ugly
145                if(! FilesystemToolkit.checkIfFileExists(file ,true) ){
146                    System.out.println("\nWarning: The existence of the file or directory \" " + file.getFile() + "\" could not be validated. Please check that that the element exists. ");
147                }*/
148    
149                
150                //If a file is relative to the current working directory, then when it is linked keep that relative path.  
151                //if( file.getFile().matches("^\\./.*/..*$")){
152                
153                
154                //split file into name and path
155                String path = "./";
156                String name = null;
157                boolean isAbsolutePath = fileNameAndPath.startsWith("/");
158                
159             
160                int lastSlash = fileNameAndPath.lastIndexOf('/');
161                if(lastSlash != -1){ //if it has at lest on slash
162                    path = fileNameAndPath.substring(0, lastSlash + 1);  //get the path
163                    if(! fileNameAndPath.endsWith("/"))  //check that it has a name
164                        name = fileNameAndPath.substring(lastSlash + 1, fileNameAndPath.length()); //split the name off of the path  
165                }
166                else{ //if it has no slah in the string this is a name
167                    name = fileNameAndPath;
168                }
169                
170    
171                log.debug("Bulding sandbox:\n" +
172                "user file string = " + fileNameAndPath + "\n" +
173                "isAbsolutePath = " + isAbsolutePath + "\n" +
174                "path = " + path + "\n" +
175                "name = " + ((name != null) ?  name : "no_name") + "\n" +
176                "installdir = " + installDir +  "\n" +
177                "see .csh for full command\n" );
178    
179                
180                //build the install command  
181                
182                if(! isAbsolutePath){ //only needed for rel. paths
183                    inInstallCommand  =  inInstallCommand +  "mkdir -p "+installDir+"/" + path + "\n" ;
184                }
185               
186                       
187                        
188                 inInstallCommand  =  inInstallCommand + "foreach object ( `find " + path;
189                                     
190                if(name != null) inInstallCommand  =  inInstallCommand + " -name '" + name + "'";
191                        
192                inInstallCommand  =  inInstallCommand + " -maxdepth 1` ) \n" +
193                " \n" +
194                " \n" +
195                "          if($object != '" + path +"') then \n" +  //#only needed for rel \n"
196                " \n" +
197                "                 foreach DIRObject ( `find $object`) \n" +
198                " \n";
199                
200                
201               if(isAbsolutePath){
202                    
203                inInstallCommand  =  inInstallCommand +    
204                //"                        #used for abs path \n" +
205                "                        setenv NewLink  "+installDir+"/`echo $DIRObject  | sed 's|" + path + "||'` \n";   
206                    
207               }else{
208                    
209                inInstallCommand  =  inInstallCommand + 
210                //"                        #use for rel paths \n" +
211                "                        setenv  NewLink  "+installDir+"/$DIRObject \n";
212                }
213                        
214                        
215                inInstallCommand  =  inInstallCommand + " \n" +
216                "                        if(! -e $NewLink) then \n" +
217                "                             if(-f $DIRObject) then \n" +
218               // "                                   #echo " + lncommand+" -s  $DIRObject  $NewLink \n" +      
219               // "                                   #"+lncommand+" -s  $DIRObject  $NewLink \n" + 
220               // "                                   echo "+lncommand+" -s  `echo './blabla/bli/bli1' | sed \"s|\\(^[^/]\\)\\(.*\\)|$pwd/\\1\\2|\"`  $NewLink \n" +
221                "                                   "+lncommand+" -s  `echo $DIRObject | sed \"s|\\(^[^/]\\)\\(.*\\)|$pwd/\\1\\2|\"`  $NewLink \n" +
222                "                             else \n" +
223                "                                   mkdir -p   $NewLink \n" +
224                //"                                   echo mkdir -p   $NewLink \n" +                    
225                "                             endif \n" +
226                "                        endif \n" +
227                "               end \n" +
228                " \n" +
229                " \n" +
230                "        endif \n" +
231                " \n" +
232                "end \n" ;
233                
234                
235                
236                
237                
238                
239                /*
240                if(file.getFile().startsWith("/")){ //this is an absolute path
241                    String relativePath = file.getFile().replaceAll("(^\\.)(/)(.*)(/.*$)", "$2$3");
242                    inInstallCommand = inInstallCommand + "/bin/mkdir -p " + installDir + relativePath + "\n";
243                    inInstallCommand = inInstallCommand + lncommand + " -s " + stripRelativePath(file) + " " + installDir + relativePath + "\n";  
244                }else{
245    
246                    inInstallCommand = inInstallCommand + lncommand + " -s " + stripRelativePath(file) + " " + installDir + "\n";
247                }
248                */
249            
250                
251                if(fileWhereNotAdded){
252                    this.addSandboxedFiles(file.getFile()); //Add this file to the main list of files that need to be moved along with the job.
253                    fileWhereNotAdded = false;
254                }
255                
256            }
257            
258    
259            
260            
261            
262           // return   "setenv tempSCRATCH \"$SCRATCH\"  \n setenv  SCRATCH /star/u/lbhajdu/junk  \n  " +  inInstallCommand + " \n setenv  SCRATCH \"$tempSCRATCH\"  \n  ";
263            return inInstallCommand;
264        }
265        
266        
267        /* no longer used 
268        public static String stripRelativePath(URL file){
269            
270            if(file.getFile().matches("(^\\.)(/)(.*$)")){
271                return file.getFile().replaceAll("(^\\.)(/)(.*$)", "`/bin/pwd`$2$3");   
272            }
273            else if(file.getFile().matches("[^/]*")){ //if it is just the file name add pwd 
274                return "`/bin/pwd`/" + file.getFile();
275            }
276            else return file.getFile(); //if it's an abs path just return it as is without any changes
277            
278        }
279        */
280        
281        
282        
283        
284        List Packages = new ArrayList();
285        
286        public void addPackage(SandboxPackage sandboxPackage) { Packages.add(sandboxPackage); }
287        public List getPackages() { return Packages; }
288        public void setPackages(java.util.List packages) { this.Packages = Packages; }
289        
290        List SandboxedFiles = new ArrayList();
291        /* Gets the files that the sand box has packed. */
292        public List getSandboxedFiles(){ return SandboxedFiles; }
293        /* Sets the files that the sand box has packed. */
294        public void setSandboxedFiles(List SandboxedFiles){ this.SandboxedFiles = SandboxedFiles; }
295        /* Adds a file to the list of sandboxed files. */
296        public void addSandboxedFiles(String file){ SandboxedFiles.add(file); }
297        
298        public String InitializationCommands() { return "";}
299        
300    }