package hudson.plugins.disk_usage; import hudson.FilePath; import hudson.XmlFile; import hudson.model.AbstractBuild; import hudson.model.AbstractProject; import hudson.model.Action; import hudson.model.BuildBadgeAction; import hudson.model.ItemGroup; import hudson.model.Node; import hudson.model.ProminentProjectAction; import hudson.model.Run; import hudson.model.TopLevelItem; import java.io.File; import java.io.IOException; import java.util.Map; import java.util.Set; import java.util.logging.Level; import java.util.logging.Logger; import jenkins.model.RunAction2; import org.kohsuke.stapler.export.ExportedBean; /** * Disk usage information for a single build * @author dvrzalik */ //TODO really implementsProminentProjectAction??? @ExportedBean(defaultVisibility = 1) public class BuildDiskUsageAction implements ProminentProjectAction, BuildBadgeAction, RunAction2 { @Deprecated Long buildDiskUsage; AbstractBuild build; @Deprecated DiskUsage diskUsage; public BuildDiskUsageAction(AbstractBuild build) { this.build = build; DiskUsageProperty property = (DiskUsageProperty) build.getProject().getProperty(DiskUsageProperty.class); if(property==null){ DiskUsageUtil.addProperty(build.getProject()); property = (DiskUsageProperty) build.getProject().getProperty(DiskUsageProperty.class); } //DiskUsageBuildInformation information = property.getDiskUsageBuildInformation(build.getId()); } public String getIconFileName() { return null; } public String getDisplayName() { return Messages.DisplayName(); } public String getUrlName() { return Messages.UrlName(); } public void setDiskUsage(Long size) throws IOException{ AbstractProject project = build.getProject(); DiskUsageProperty property = (DiskUsageProperty) project.getProperty(DiskUsageProperty.class); if(property==null){ DiskUsageUtil.addProperty(project); property = (DiskUsageProperty) project.getProperty(DiskUsageProperty.class); } DiskUsageBuildInformation information = property.getDiskUsageBuildInformation(build.getId()); if(information!=null){ information.setSize(size); } else{ property.getDiskUsage().addBuildInformation(new DiskUsageBuildInformation(build.getId(), build.getTimeInMillis(), build.getNumber(), size, build.isKeepLog()), build); } property.saveDiskUsage(); ProjectDiskUsageAction action = project.getAction(ProjectDiskUsageAction.class); if(action!=null){ action.actualizeCashedBuildsData(); } } /** * @return Disk usage of the build (included child builds) */ public Long getDiskUsage() { AbstractProject project = build.getProject(); DiskUsageProperty property = (DiskUsageProperty) project.getProperty(DiskUsageProperty.class); if(property==null){ DiskUsageUtil.addProperty(project); property = (DiskUsageProperty) project.getProperty(DiskUsageProperty.class); } return property.getDiskUsageOfBuild(build.getId()); } public Long getAllDiskUsage(){ Long buildsDiskUsage = getDiskUsage(); AbstractProject project = build.getProject(); if(project instanceof ItemGroup){ buildsDiskUsage += getBuildsDiskUsageAllSubItems((ItemGroup)project); } return buildsDiskUsage; } public String getBuildUsageString(){ return DiskUsageUtil.getSizeString(getAllDiskUsage()); } private Long getBuildsDiskUsageAllSubItems(ItemGroup group){ Long buildsDiskUsage = 0l; for(Object item: group.getItems()){ if(item instanceof ItemGroup){ buildsDiskUsage += getBuildsDiskUsageAllSubItems((ItemGroup)item); } else{ if(item instanceof AbstractProject){ AbstractProject project = (AbstractProject) item; DiskUsageProperty property = (DiskUsageProperty) project.getProperty(DiskUsageProperty.class); if(property==null){ DiskUsageUtil.addProperty(project); property = (DiskUsageProperty) project.getProperty(DiskUsageProperty.class); } Set<DiskUsageBuildInformation> informations = property.getDiskUsageOfBuilds(); for(DiskUsageBuildInformation information : informations){ if(information.getNumber() == build.getNumber()){ buildsDiskUsage += information.getSize(); } } } } } return buildsDiskUsage; } public Object readResolve() { //for keeping backward compatibility if(diskUsage!=null){ buildDiskUsage = diskUsage.buildUsage; Node node = build.getBuiltOn(); if(node!=null && diskUsage.wsUsage!=null && diskUsage.wsUsage > 0){ DiskUsageProperty property = (DiskUsageProperty) build.getProject().getProperty(DiskUsageProperty.class); AbstractProject project = build.getProject().getRootProject(); if(property!=null && (project instanceof TopLevelItem)){ FilePath workspace = build.getWorkspace(); if(workspace==null){ workspace = node.getWorkspaceFor((TopLevelItem)project); } Map<String,Long> paths = property.getSlaveWorkspaceUsage().get(node.getDisplayName()); Long size = null; if(paths!=null){ size = paths.get(workspace.getRemote()); } try { //previous data about workspace was quite tricky, so check if there is such workspace and size were not recounted if(workspace.exists() && size!=null && size>0){ property.putSlaveWorkspaceSize(node, node.getWorkspaceFor((TopLevelItem)project).getRemote(), diskUsage.wsUsage); } } catch (IOException ex) { Logger.getLogger(BuildDiskUsageAction.class.getName()).log(Level.WARNING, null, ex); } catch (InterruptedException ex) { Logger.getLogger(BuildDiskUsageAction.class.getName()).log(Level.WARNING, null, ex); } } } diskUsage=null; } return this; } @Override public void onAttached(Run<?, ?> r) { //no action is needed } @Override public void onLoad(Run<?, ?> r) { DiskUsageProperty property = (DiskUsageProperty) build.getProject().getProperty(DiskUsageProperty.class); long size = 0L; if(buildDiskUsage != null){ size = buildDiskUsage; } if(property==null){ return; } //backward compatibility BuildDiskUsageAction action = null; for(Action a : build.getActions()){ if(a instanceof BuildDiskUsageAction){ action = (BuildDiskUsageAction) a; if(action.buildDiskUsage != null){ size=action.buildDiskUsage; } } } DiskUsageBuildInformation information = property.getDiskUsageBuildInformation(build.getNumber()); //Transient actions can be created even during deletion of job Boolean isLocked = DiskUsageUtil.isKeepLog(build); if(information==null && build.getRootDir().exists()){ if(isLocked==null){ isLocked=false; } property.getDiskUsage().addBuildInformation(new DiskUsageBuildInformation(build.getId(),build.getTimeInMillis(), build.getNumber(), size, isLocked), build); } else{ if(information!=null && !(build.getProject() instanceof ItemGroup)){ //check if lock is still valide //not for ItemGroup, because MatrixProject causes recursion if(isLocked!=null && information.isLocked()!= isLocked){ information.setLockState(isLocked); property.getDiskUsage().save(); } } } if(action!=null || buildDiskUsage!=null){ property.getDiskUsageBuildInformation(build.getNumber()).setSize(buildDiskUsage); buildDiskUsage=null; //remove old action, now it is added by transition action factor build.getActions().remove(action); try { build.save(); } catch (IOException ex) { Logger.getLogger(BuildDiskUsageAction.class.getName()).log(Level.SEVERE, null, ex); } } } }