├── README.md
├── src
└── main
│ ├── resources
│ ├── com
│ │ └── surenpi
│ │ │ └── jenkins
│ │ │ └── loadbalance
│ │ │ ├── ResourceRestriction
│ │ │ ├── config.properties
│ │ │ ├── config_zh_CN.properties
│ │ │ └── config.jelly
│ │ │ └── BalanceProjectProperty
│ │ │ ├── help-disk.html
│ │ │ ├── help-disk_zh_CN.html
│ │ │ ├── help-memory_zh_CN.html
│ │ │ ├── help-memory.html
│ │ │ ├── help-config_zh_CN.html
│ │ │ ├── config.properties
│ │ │ ├── help-config.html
│ │ │ ├── config_zh_CN.properties
│ │ │ └── config.groovy
│ └── index.jelly
│ └── java
│ └── com
│ └── surenpi
│ └── jenkins
│ └── loadbalance
│ ├── Unit.java
│ ├── ResourceRestriction.java
│ └── BalanceProjectProperty.java
├── .gitignore
├── LICENSE
└── pom.xml
/README.md:
--------------------------------------------------------------------------------
1 | # loadbalance.plugin
--------------------------------------------------------------------------------
/src/main/resources/com/surenpi/jenkins/loadbalance/ResourceRestriction/config.properties:
--------------------------------------------------------------------------------
1 | ResourceRestriction=ResourceRestriction
--------------------------------------------------------------------------------
/src/main/resources/index.jelly:
--------------------------------------------------------------------------------
1 |
2 |
3 | Jenkins agent load balance.
4 |
5 |
--------------------------------------------------------------------------------
/src/main/resources/com/surenpi/jenkins/loadbalance/BalanceProjectProperty/help-disk.html:
--------------------------------------------------------------------------------
1 |
2 | The default unit is G.
3 |
--------------------------------------------------------------------------------
/src/main/resources/com/surenpi/jenkins/loadbalance/BalanceProjectProperty/help-disk_zh_CN.html:
--------------------------------------------------------------------------------
1 |
2 | 默认的单位是:千兆(G)。
3 |
--------------------------------------------------------------------------------
/src/main/resources/com/surenpi/jenkins/loadbalance/BalanceProjectProperty/help-memory_zh_CN.html:
--------------------------------------------------------------------------------
1 |
2 | 默认的单位是:兆(M)。
3 |
--------------------------------------------------------------------------------
/src/main/resources/com/surenpi/jenkins/loadbalance/BalanceProjectProperty/help-memory.html:
--------------------------------------------------------------------------------
1 |
2 | The default unit is M.
3 |
--------------------------------------------------------------------------------
/src/main/resources/com/surenpi/jenkins/loadbalance/ResourceRestriction/config_zh_CN.properties:
--------------------------------------------------------------------------------
1 | ResourceRestriction=\u8d44\u6e90\u9650\u5236
--------------------------------------------------------------------------------
/src/main/resources/com/surenpi/jenkins/loadbalance/BalanceProjectProperty/help-config_zh_CN.html:
--------------------------------------------------------------------------------
1 |
2 | 你可以指定任务所需要的计算资源,例如:内存和磁盘大小。
3 |
--------------------------------------------------------------------------------
/src/main/resources/com/surenpi/jenkins/loadbalance/BalanceProjectProperty/config.properties:
--------------------------------------------------------------------------------
1 | agent.load=Agent Load
2 | agent.load.memory=Memory
3 | agent.load.disk=Disk
4 | agent.load.unit=Unit
5 |
--------------------------------------------------------------------------------
/src/main/resources/com/surenpi/jenkins/loadbalance/BalanceProjectProperty/help-config.html:
--------------------------------------------------------------------------------
1 |
2 | You can specified job's compute resource restriction. Such as memory and disk space.
3 |
--------------------------------------------------------------------------------
/src/main/resources/com/surenpi/jenkins/loadbalance/BalanceProjectProperty/config_zh_CN.properties:
--------------------------------------------------------------------------------
1 | agent.load=\u6267\u884C\u8282\u70B9\u8D1F\u8F7D
2 | agent.load.memory=\u5185\u5B58
3 | agent.load.disk=\u78C1\u76D8
4 | agent.load.unit=\u5355\u4f4d
5 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Compiled class file
2 | *.class
3 |
4 | # Log file
5 | *.log
6 |
7 | # BlueJ files
8 | *.ctxt
9 |
10 | # Mobile Tools for Java (J2ME)
11 | .mtj.tmp/
12 |
13 | # Package Files #
14 | *.jar
15 | *.war
16 | *.ear
17 | *.zip
18 | *.tar.gz
19 | *.rar
20 |
21 | # virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
22 | hs_err_pid*
23 | /target/
24 |
25 | # Eclipse stuff
26 | .classpath
27 | .project
28 | .settings
29 |
30 | # Idea stuff
31 | .idea
32 |
33 | # Jenkins work dir
34 | work
35 |
--------------------------------------------------------------------------------
/src/main/resources/com/surenpi/jenkins/loadbalance/BalanceProjectProperty/config.groovy:
--------------------------------------------------------------------------------
1 | package com.surenpi.jenkins.loadbalance;
2 |
3 | import static com.surenpi.jenkins.loadbalance.BalanceProjectProperty.DescriptorImpl.AGENT_LOAD;
4 |
5 | def f = namespace(lib.FormTagLib);
6 |
7 | f.optionalBlock(name: AGENT_LOAD, title: _('agent.load'), checked: instance != null) {
8 | f.entry(field: 'memory', title: _('agent.load.memory')) {
9 | f.textbox()
10 | }
11 |
12 | f.entry(field: 'disk', title: _('agent.load.disk')) {
13 | f.textbox()
14 | }
15 |
16 | f.advanced() {
17 | f.entry(field: 'memoryUnit', title: _('agent.load.unit')) {
18 | f.select()
19 | }
20 |
21 | f.entry(field: 'diskUnit', title: _('agent.load.unit')) {
22 | f.select()
23 | }
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2018
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/src/main/resources/com/surenpi/jenkins/loadbalance/ResourceRestriction/config.jelly:
--------------------------------------------------------------------------------
1 |
24 |
25 |
26 |
27 |
28 |
29 |
--------------------------------------------------------------------------------
/src/main/java/com/surenpi/jenkins/loadbalance/Unit.java:
--------------------------------------------------------------------------------
1 | package com.surenpi.jenkins.loadbalance;
2 |
3 | import java.util.*;
4 |
5 | /**
6 | * @author suren
7 | */
8 | public enum Unit
9 | {
10 | K(1024), M(1048576), G(1073741824);
11 |
12 | private long origin;
13 | Unit(long origin)
14 | {
15 | this.origin = origin;
16 | }
17 |
18 | public static List list()
19 | {
20 | return list(new Comparator()
21 | {
22 | @Override
23 | public int compare(String o1, String o2)
24 | {
25 | long diff = Unit.valueOf(o1).getOrigin() - Unit.valueOf(o2).getOrigin();
26 | return diff > 0 ? 1 : (diff == 0 ? 0 : -1);
27 | }
28 | });
29 | }
30 |
31 | public static List list(Comparator comparator)
32 | {
33 | List items = new ArrayList<>();
34 | for(Unit unit : Unit.values())
35 | {
36 | items.add(unit.name());
37 | }
38 |
39 | if(comparator != null)
40 | {
41 | items.sort(comparator);
42 | }
43 |
44 | return items;
45 | }
46 |
47 | public static Map map()
48 | {
49 | Unit[] units = Unit.values();
50 |
51 | Map map = new TreeMap<>();
52 | for(Unit unit : Unit.values())
53 | {
54 | map.put(unit.name(), unit.name());
55 | }
56 |
57 | return map;
58 | }
59 |
60 | public long getOrigin()
61 | {
62 | return origin;
63 | }
64 |
65 | public void setOrigin(long origin)
66 | {
67 | this.origin = origin;
68 | }
69 | }
--------------------------------------------------------------------------------
/src/main/java/com/surenpi/jenkins/loadbalance/ResourceRestriction.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Project Name:job-restrictions-plugin
3 | * File Name:ResourceRestriction.java
4 | * Package Name:com.synopsys.arc.jenkinsci.plugins.jobrestrictions.jobs
5 | * Date:Feb 9, 20186:33:08 PM
6 | * Authos:surenpi
7 | *
8 | */
9 | package com.surenpi.jenkins.loadbalance;
10 |
11 | import com.synopsys.arc.jenkinsci.plugins.jobrestrictions.restrictions.JobRestriction;
12 | import com.synopsys.arc.jenkinsci.plugins.jobrestrictions.restrictions.JobRestrictionDescriptor;
13 | import hudson.Extension;
14 | import hudson.FilePath;
15 | import hudson.model.Job;
16 | import hudson.model.Project;
17 | import hudson.model.Queue.BuildableItem;
18 | import hudson.model.Run;
19 | import org.kohsuke.stapler.DataBoundConstructor;
20 |
21 | import java.io.IOException;
22 |
23 | /**
24 | * @author surenpi
25 | */
26 | public class ResourceRestriction extends JobRestriction {
27 |
28 | private boolean loadBalanceRestriction;
29 |
30 | @DataBoundConstructor
31 | public ResourceRestriction(boolean loadBalanceRestriction)
32 | {
33 | this.loadBalanceRestriction = loadBalanceRestriction;
34 | }
35 |
36 | public boolean isLoadBalanceRestriction()
37 | {
38 | return loadBalanceRestriction;
39 | }
40 |
41 | /**
42 | * @see com.synopsys.arc.jenkinsci.plugins.jobrestrictions.restrictions.JobRestriction#canTake(BuildableItem)
43 | */
44 | @Override
45 | public boolean canTake(BuildableItem item)
46 | {
47 | if(item.task instanceof Project)
48 | {
49 | Project project = (Project) item.task;
50 |
51 | return canTake(project);
52 | }
53 |
54 | return true;
55 | }
56 |
57 | /**
58 | * @see com.synopsys.arc.jenkinsci.plugins.jobrestrictions.restrictions.JobRestriction#canTake(Run)
59 | */
60 | @Override
61 | public boolean canTake(Run run) {
62 | return canTake(run.getParent());
63 | }
64 |
65 | private boolean canTake(Job job)
66 | {
67 | BalanceProjectProperty balance = (BalanceProjectProperty)
68 | job.getProperty(BalanceProjectProperty.class);
69 |
70 | if(loadBalanceRestriction)
71 | {
72 | long memory = balance.getMemory() * balance.getMemoryUnit().getOrigin();
73 | long disk = balance.getDisk() * balance.getDiskUnit().getOrigin();
74 |
75 | Runtime runtime = Runtime.getRuntime();
76 | if(runtime.freeMemory() < memory)
77 | {
78 | return false;
79 | }
80 |
81 | FilePath path = new FilePath(job.getBuildDir());
82 | try
83 | {
84 | long usableDiskSpace = path.getUsableDiskSpace();
85 | if(usableDiskSpace < disk)
86 | {
87 | return false;
88 | }
89 | }
90 | catch (IOException e)
91 | {
92 | e.printStackTrace();
93 | }
94 | catch (InterruptedException e)
95 | {
96 | e.printStackTrace();
97 | }
98 | }
99 |
100 | return true;
101 | }
102 |
103 | @Extension
104 | public static class DescriptorImpl extends JobRestrictionDescriptor
105 | {
106 | @Override
107 | public String getDisplayName()
108 | {
109 | return "ResourceRestriction";
110 | }
111 | }
112 |
113 | }
114 |
--------------------------------------------------------------------------------
/src/main/java/com/surenpi/jenkins/loadbalance/BalanceProjectProperty.java:
--------------------------------------------------------------------------------
1 | package com.surenpi.jenkins.loadbalance;
2 |
3 | import hudson.Extension;
4 | import hudson.model.Job;
5 | import hudson.model.JobProperty;
6 | import hudson.model.JobPropertyDescriptor;
7 | import hudson.util.ListBoxModel;
8 | import jenkins.model.ParameterizedJobMixIn;
9 | import net.sf.json.JSONObject;
10 | import org.kohsuke.stapler.DataBoundConstructor;
11 | import org.kohsuke.stapler.DataBoundSetter;
12 | import org.kohsuke.stapler.StaplerRequest;
13 |
14 | import javax.annotation.Nonnull;
15 | import java.util.Comparator;
16 | import java.util.List;
17 | import java.util.logging.Logger;
18 |
19 | /**
20 | * @author suren
21 | */
22 | public final class BalanceProjectProperty extends JobProperty>
23 | {
24 | private long memory;
25 | private long disk;
26 | private Unit memoryUnit;
27 | private Unit diskUnit;
28 |
29 | @DataBoundConstructor
30 | public BalanceProjectProperty() {}
31 |
32 | @Extension
33 | public static final class DescriptorImpl extends JobPropertyDescriptor
34 | {
35 | public static final String AGENT_LOAD = "agent_load";
36 |
37 | public boolean isApplicable(Class extends Job> jobType) {
38 | return ParameterizedJobMixIn.ParameterizedJob.class.isAssignableFrom(jobType);
39 | }
40 |
41 | @Nonnull
42 | @Override
43 | public String getDisplayName()
44 | {
45 | return "Agent Load";
46 | }
47 |
48 | @Override
49 | public JobProperty> newInstance(StaplerRequest req, JSONObject formData) throws FormException {
50 | BalanceProjectProperty tpp = req.bindJSON(
51 | BalanceProjectProperty.class,
52 | formData.getJSONObject(AGENT_LOAD)
53 | );
54 |
55 | if (tpp == null) {
56 | LOGGER.fine("Couldn't bind JSON");
57 | return null;
58 | }
59 |
60 | return tpp;
61 | }
62 |
63 | public ListBoxModel doFillDiskUnitItems()
64 | {
65 | return sortedUnits(new Comparator()
66 | {
67 | @Override
68 | public int compare(String o1, String o2)
69 | {
70 | return Unit.valueOf(o1).equals(Unit.G) ? 1 : 0;
71 | }
72 | });
73 | }
74 |
75 | public ListBoxModel doFillMemoryUnitItems()
76 | {
77 | return sortedUnits(new Comparator()
78 | {
79 | @Override
80 | public int compare(String o1, String o2)
81 | {
82 | return Unit.valueOf(o1).equals(Unit.M) ? 1 : 0;
83 | }
84 | });
85 | }
86 |
87 | private ListBoxModel sortedUnits(Comparator comparator)
88 | {
89 | ListBoxModel listBoxModel = new ListBoxModel();
90 |
91 | List items = Unit.list();
92 | items.sort(comparator);
93 |
94 | for(String item : items)
95 | {
96 | listBoxModel.add(item);
97 | }
98 |
99 | return listBoxModel;
100 | }
101 | }
102 |
103 | public long getMemory()
104 | {
105 | return memory;
106 | }
107 |
108 | @DataBoundSetter
109 | public void setMemory(long memory)
110 | {
111 | this.memory = memory;
112 | }
113 |
114 | public long getDisk()
115 | {
116 | return disk;
117 | }
118 |
119 | @DataBoundSetter
120 | public void setDisk(long disk)
121 | {
122 | this.disk = disk;
123 | }
124 |
125 | public Unit getMemoryUnit()
126 | {
127 | return memoryUnit;
128 | }
129 |
130 | @DataBoundSetter
131 | public void setMemoryUnit(Unit memoryUnit)
132 | {
133 | this.memoryUnit = memoryUnit;
134 | }
135 |
136 | public Unit getDiskUnit()
137 | {
138 | return diskUnit;
139 | }
140 |
141 | @DataBoundSetter
142 | public void setDiskUnit(Unit diskUnit)
143 | {
144 | this.diskUnit = diskUnit;
145 | }
146 |
147 | private static final Logger LOGGER = Logger.getLogger(BalanceProjectProperty.class.getName());
148 | }
--------------------------------------------------------------------------------
/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 4.0.0
4 |
5 | org.jenkins-ci.plugins
6 | plugin
7 | 3.4
8 |
9 |
10 |
11 | com.surenpi.jenkins
12 | agent-loadbalance
13 | 1.1-SNAPSHOT
14 |
15 | hpi
16 |
17 | 2.7.3
18 | 8
19 | false
20 |
21 |
22 | Agent LoadBalance Plugin
23 | Agent LoadBalance Plugin
24 |
25 |
26 |
27 | MIT License
28 | https://opensource.org/licenses/MIT
29 |
30 |
31 |
32 |
33 |
34 | org.jenkins-ci.plugins
35 | structs
36 | 1.7
37 |
38 |
39 | org.jenkins-ci.plugins.workflow
40 | workflow-step-api
41 | 2.12
42 | test
43 |
44 |
45 | org.jenkins-ci.plugins.workflow
46 | workflow-cps
47 | 2.39
48 | test
49 |
50 |
51 | org.jenkins-ci.plugins.workflow
52 | workflow-job
53 | 2.11.2
54 | test
55 |
56 |
57 | org.jenkins-ci.plugins.workflow
58 | workflow-basic-steps
59 | 2.6
60 | test
61 |
62 |
63 | org.jenkins-ci.plugins.workflow
64 | workflow-durable-task-step
65 | 2.13
66 | test
67 |
68 |
69 | org.jenkins-ci.plugins.workflow
70 | workflow-api
71 | 2.20
72 | test
73 |
74 |
75 | org.jenkins-ci.plugins.workflow
76 | workflow-support
77 | 2.14
78 | test
79 |
80 |
81 |
82 | com.synopsys.arc.jenkinsci.plugins
83 | job-restrictions
84 | 0.6
85 |
86 |
87 |
88 |
89 |
90 | surenpi
91 | SuRen
92 | zxjlwt@126.com
93 |
94 |
95 |
96 | https://wiki.jenkins.io/display/JENKINS/Agent+LoadBalance+Plugin
97 |
98 | scm:git:git://github.com/jenkinsci/${project.artifactId}-plugin.git
99 | scm:git:git@github.com:jenkinsci/${project.artifactId}-plugin.git
100 | https://github.com/jenkinsci/${project.artifactId}-plugin
101 | HEAD
102 |
103 |
104 |
105 |
106 | repo.jenkins-ci.org
107 | https://repo.jenkins-ci.org/public/
108 |
109 |
110 |
111 |
112 | repo.jenkins-ci.org
113 | https://repo.jenkins-ci.org/public/
114 |
115 |
116 |
117 |
--------------------------------------------------------------------------------