4577 |
19 Sep 17 |
nicklas |
1 |
package net.sf.basedb.relax.plugins; |
4577 |
19 Sep 17 |
nicklas |
2 |
|
5250 |
18 Jan 19 |
nicklas |
3 |
import java.io.ByteArrayOutputStream; |
4577 |
19 Sep 17 |
nicklas |
4 |
import java.io.IOException; |
5250 |
18 Jan 19 |
nicklas |
5 |
import java.io.InputStream; |
4577 |
19 Sep 17 |
nicklas |
6 |
import java.io.OutputStreamWriter; |
4577 |
19 Sep 17 |
nicklas |
7 |
import java.io.Writer; |
4577 |
19 Sep 17 |
nicklas |
8 |
import java.nio.charset.Charset; |
4577 |
19 Sep 17 |
nicklas |
9 |
import java.util.Date; |
4577 |
19 Sep 17 |
nicklas |
10 |
import java.util.Map; |
4577 |
19 Sep 17 |
nicklas |
11 |
import java.util.Set; |
4577 |
19 Sep 17 |
nicklas |
12 |
import java.util.TreeMap; |
4577 |
19 Sep 17 |
nicklas |
13 |
import java.util.TreeSet; |
4577 |
19 Sep 17 |
nicklas |
14 |
|
4577 |
19 Sep 17 |
nicklas |
15 |
import org.json.simple.JSONArray; |
4577 |
19 Sep 17 |
nicklas |
16 |
import org.json.simple.JSONObject; |
4577 |
19 Sep 17 |
nicklas |
17 |
|
4577 |
19 Sep 17 |
nicklas |
18 |
import net.sf.basedb.core.DbControl; |
4577 |
19 Sep 17 |
nicklas |
19 |
import net.sf.basedb.core.FileServer; |
4577 |
19 Sep 17 |
nicklas |
20 |
import net.sf.basedb.core.plugin.ExportOutputStream; |
4577 |
19 Sep 17 |
nicklas |
21 |
import net.sf.basedb.opengrid.ScriptBuilder; |
4577 |
19 Sep 17 |
nicklas |
22 |
import net.sf.basedb.relax.Relax; |
4608 |
03 Oct 17 |
nicklas |
23 |
import net.sf.basedb.relax.ServerMode; |
4577 |
19 Sep 17 |
nicklas |
24 |
import net.sf.basedb.relax.bash.ScriptUtil; |
4577 |
19 Sep 17 |
nicklas |
25 |
import net.sf.basedb.relax.dao.Fileserver; |
4577 |
19 Sep 17 |
nicklas |
26 |
import net.sf.basedb.util.FileUtil; |
4577 |
19 Sep 17 |
nicklas |
27 |
|
4577 |
19 Sep 17 |
nicklas |
28 |
/** |
4577 |
19 Sep 17 |
nicklas |
A special writer implementation for creating bash scripts |
4577 |
19 Sep 17 |
nicklas |
intended to be executed manually in order to sync released |
4577 |
19 Sep 17 |
nicklas |
data files between the release-archive and level3-archive. |
4577 |
19 Sep 17 |
nicklas |
32 |
|
4577 |
19 Sep 17 |
nicklas |
Three scripts are created: |
4577 |
19 Sep 17 |
nicklas |
34 |
|
4577 |
19 Sep 17 |
nicklas |
* mkdirs.sh: Creates the directory structure that is needed for the release |
4577 |
19 Sep 17 |
nicklas |
* rsync.sh: Copy files from the release archive to the level 3 archive |
4577 |
19 Sep 17 |
nicklas |
37 |
|
4577 |
19 Sep 17 |
nicklas |
@author nicklas |
4577 |
19 Sep 17 |
nicklas |
39 |
*/ |
4577 |
19 Sep 17 |
nicklas |
40 |
public class ScriptWriter |
4577 |
19 Sep 17 |
nicklas |
41 |
{ |
4577 |
19 Sep 17 |
nicklas |
42 |
|
4577 |
19 Sep 17 |
nicklas |
43 |
private final FileServer releaseArchive; |
4577 |
19 Sep 17 |
nicklas |
44 |
private final ReleaseWriterOptions options; |
4577 |
19 Sep 17 |
nicklas |
45 |
|
4577 |
19 Sep 17 |
nicklas |
46 |
private final Set<String> pathsToCreate; |
4577 |
19 Sep 17 |
nicklas |
47 |
private final Map<String, String> filesToSync; |
4577 |
19 Sep 17 |
nicklas |
48 |
|
4577 |
19 Sep 17 |
nicklas |
49 |
public ScriptWriter(DbControl dc, ReleaseWriterOptions options) |
4577 |
19 Sep 17 |
nicklas |
50 |
{ |
4608 |
03 Oct 17 |
nicklas |
51 |
this.releaseArchive = Relax.getServerMode() == ServerMode.RELAX ? Fileserver.RELEASE_ARCHIVE.load(dc) : Fileserver.LEVEL3_ARCHIVE.load(dc); |
4577 |
19 Sep 17 |
nicklas |
52 |
this.pathsToCreate = new TreeSet<>(); |
4577 |
19 Sep 17 |
nicklas |
53 |
this.filesToSync = new TreeMap<>(); |
4577 |
19 Sep 17 |
nicklas |
54 |
this.options = options; |
4577 |
19 Sep 17 |
nicklas |
55 |
} |
4577 |
19 Sep 17 |
nicklas |
56 |
|
4577 |
19 Sep 17 |
nicklas |
57 |
/** |
4577 |
19 Sep 17 |
nicklas |
Add a directory that should be created as part of this release. |
4577 |
19 Sep 17 |
nicklas |
59 |
*/ |
4577 |
19 Sep 17 |
nicklas |
60 |
public void addMkDir(String path) |
4577 |
19 Sep 17 |
nicklas |
61 |
{ |
4577 |
19 Sep 17 |
nicklas |
62 |
if (path != null) |
4577 |
19 Sep 17 |
nicklas |
63 |
{ |
4577 |
19 Sep 17 |
nicklas |
64 |
ScriptUtil.checkValidPath(path, true, false); |
4577 |
19 Sep 17 |
nicklas |
65 |
pathsToCreate.add(path); |
4577 |
19 Sep 17 |
nicklas |
66 |
} |
4577 |
19 Sep 17 |
nicklas |
67 |
} |
4577 |
19 Sep 17 |
nicklas |
68 |
|
4577 |
19 Sep 17 |
nicklas |
69 |
/** |
4577 |
19 Sep 17 |
nicklas |
Add files that are part of this release. The given path |
4577 |
19 Sep 17 |
nicklas |
is automatically added to {@link #addMkDir(String)}. |
4577 |
19 Sep 17 |
nicklas |
The list of files will checked with {@link OutputLocation#findReleasedFile(String)} |
4577 |
19 Sep 17 |
nicklas |
to determine if a symbolic link should be created or if the file should be |
4577 |
19 Sep 17 |
nicklas |
copied from the project archive. |
4577 |
19 Sep 17 |
nicklas |
75 |
|
4577 |
19 Sep 17 |
nicklas |
@param releasePath Path on the release server |
4577 |
19 Sep 17 |
nicklas |
@param jsonFiles |
4577 |
19 Sep 17 |
nicklas |
78 |
*/ |
4577 |
19 Sep 17 |
nicklas |
79 |
public void addFiles(String releasePath, JSONArray jsonFiles) |
4577 |
19 Sep 17 |
nicklas |
80 |
{ |
4577 |
19 Sep 17 |
nicklas |
81 |
addMkDir(releasePath); |
4577 |
19 Sep 17 |
nicklas |
82 |
|
4577 |
19 Sep 17 |
nicklas |
83 |
if (!releasePath.endsWith("/")) releasePath += "/"; |
4577 |
19 Sep 17 |
nicklas |
84 |
|
4577 |
19 Sep 17 |
nicklas |
85 |
for (int fileNo = 0; fileNo < jsonFiles.size(); fileNo++) |
4577 |
19 Sep 17 |
nicklas |
86 |
{ |
4577 |
19 Sep 17 |
nicklas |
87 |
JSONObject jsonFile = (JSONObject)jsonFiles.get(fileNo); |
4577 |
19 Sep 17 |
nicklas |
88 |
String filename = (String)jsonFile.get("name"); |
4577 |
19 Sep 17 |
nicklas |
89 |
String sourcePath = (String)jsonFile.get("path"); |
4577 |
19 Sep 17 |
nicklas |
90 |
if (sourcePath != null && filename != null) |
4577 |
19 Sep 17 |
nicklas |
91 |
{ |
4577 |
19 Sep 17 |
nicklas |
// The path to this file in the release directory |
4577 |
19 Sep 17 |
nicklas |
93 |
String pathToReleaseFile = releasePath + ScriptUtil.checkValidFilename(filename); |
4577 |
19 Sep 17 |
nicklas |
94 |
String pathToOriginalFile = ScriptUtil.checkValidPath(sourcePath, false, false); |
4577 |
19 Sep 17 |
nicklas |
95 |
filesToSync.put(pathToReleaseFile, pathToOriginalFile); |
4577 |
19 Sep 17 |
nicklas |
96 |
} |
4577 |
19 Sep 17 |
nicklas |
97 |
} |
4577 |
19 Sep 17 |
nicklas |
98 |
} |
4577 |
19 Sep 17 |
nicklas |
99 |
|
4577 |
19 Sep 17 |
nicklas |
100 |
public void writeScripts(FileServerOutputLocation location) |
4577 |
19 Sep 17 |
nicklas |
101 |
{ |
5250 |
18 Jan 19 |
nicklas |
102 |
ScriptBuilder releaseInfo = new ScriptBuilder(); |
5250 |
18 Jan 19 |
nicklas |
103 |
addScriptInfo(releaseInfo); |
5250 |
18 Jan 19 |
nicklas |
104 |
|
4577 |
19 Sep 17 |
nicklas |
/* MKDIRS */ |
5250 |
18 Jan 19 |
nicklas |
106 |
String mkdirs = getTextFile("/net/sf/basedb/relax/bash/mkdirs-template.sh"); |
5250 |
18 Jan 19 |
nicklas |
107 |
mkdirs = mkdirs.replace("<<RELEASEINFO>>", releaseInfo.toString()); |
5250 |
18 Jan 19 |
nicklas |
108 |
mkdirs = mkdirs.replace("<<NUMPATHS>>", Integer.toString(pathsToCreate.size())); |
5250 |
18 Jan 19 |
nicklas |
109 |
ScriptBuilder createPath = new ScriptBuilder(); |
4577 |
19 Sep 17 |
nicklas |
110 |
for (String path : pathsToCreate) |
4577 |
19 Sep 17 |
nicklas |
111 |
{ |
4577 |
19 Sep 17 |
nicklas |
112 |
if (!path.startsWith("/")) path = "/" + path; |
5250 |
18 Jan 19 |
nicklas |
113 |
createPath.cmd("createPath \"" + path + "\""); |
4577 |
19 Sep 17 |
nicklas |
114 |
} |
5250 |
18 Jan 19 |
nicklas |
115 |
mkdirs = mkdirs.replace("<<SCRIPT>>", createPath.toString()); |
5250 |
18 Jan 19 |
nicklas |
116 |
writeScript(location, "/mkdirs.sh", mkdirs); |
4577 |
19 Sep 17 |
nicklas |
117 |
|
4577 |
19 Sep 17 |
nicklas |
/* RSYNC */ |
5250 |
18 Jan 19 |
nicklas |
119 |
String rsync = getTextFile("/net/sf/basedb/relax/bash/rsync-template.sh"); |
5250 |
18 Jan 19 |
nicklas |
120 |
rsync = rsync.replace("<<RELEASEINFO>>", releaseInfo.toString()); |
5250 |
18 Jan 19 |
nicklas |
121 |
rsync = rsync.replace("<<NUMFILES>>", Integer.toString(filesToSync.size())); |
5250 |
18 Jan 19 |
nicklas |
122 |
|
4770 |
18 Apr 18 |
nicklas |
123 |
String releaseArchiveHost = releaseArchive.getHost(); |
4770 |
18 Apr 18 |
nicklas |
124 |
String releaseArchivePortOption = ""; |
4770 |
18 Apr 18 |
nicklas |
125 |
if (releaseArchiveHost.contains(":")) |
4770 |
18 Apr 18 |
nicklas |
126 |
{ |
4770 |
18 Apr 18 |
nicklas |
127 |
int i = releaseArchiveHost.lastIndexOf(':'); |
4770 |
18 Apr 18 |
nicklas |
128 |
releaseArchivePortOption = " -e 'ssh -p " + ScriptUtil.checkValidScriptParameter(releaseArchiveHost.substring(i+1)) + "'"; |
4770 |
18 Apr 18 |
nicklas |
129 |
releaseArchiveHost = releaseArchiveHost.substring(0, i); |
4770 |
18 Apr 18 |
nicklas |
130 |
} |
5250 |
18 Jan 19 |
nicklas |
131 |
|
4770 |
18 Apr 18 |
nicklas |
132 |
ScriptUtil.checkValidScriptParameter(releaseArchiveHost); |
4577 |
19 Sep 17 |
nicklas |
133 |
String releaseArchivePath = ScriptUtil.checkValidPath(releaseArchive.getRootPath(), true, false); |
5250 |
18 Jan 19 |
nicklas |
134 |
|
5250 |
18 Jan 19 |
nicklas |
135 |
rsync = rsync.replace("<<RSYNCOPTIONS>>", "-aiL"+releaseArchivePortOption); |
5250 |
18 Jan 19 |
nicklas |
136 |
rsync = rsync.replace("<<DEFAULTRELEASEARCHIVE>>", releaseArchiveHost + ":" + releaseArchivePath); |
5250 |
18 Jan 19 |
nicklas |
137 |
ScriptBuilder syncFile = new ScriptBuilder(); |
4577 |
19 Sep 17 |
nicklas |
138 |
for (Map.Entry<String, String> entry : filesToSync.entrySet()) |
4577 |
19 Sep 17 |
nicklas |
139 |
{ |
4577 |
19 Sep 17 |
nicklas |
140 |
String destPath = entry.getKey(); |
4577 |
19 Sep 17 |
nicklas |
141 |
String srcPath = entry.getValue(); |
5250 |
18 Jan 19 |
nicklas |
142 |
syncFile.cmd("syncFile \"" + srcPath + "\" \""+destPath + "\""); |
4577 |
19 Sep 17 |
nicklas |
143 |
} |
5250 |
18 Jan 19 |
nicklas |
144 |
rsync = rsync.replace("<<SCRIPT>>", syncFile.toString()); |
4577 |
19 Sep 17 |
nicklas |
145 |
writeScript(location, "/rsync.sh", rsync.toString()); |
4577 |
19 Sep 17 |
nicklas |
146 |
} |
4577 |
19 Sep 17 |
nicklas |
147 |
|
4577 |
19 Sep 17 |
nicklas |
148 |
private void writeScript(FileServerOutputLocation location, String scriptPath, String script) |
4577 |
19 Sep 17 |
nicklas |
149 |
{ |
4577 |
19 Sep 17 |
nicklas |
150 |
ExportOutputStream out = null; |
4577 |
19 Sep 17 |
nicklas |
151 |
try |
4577 |
19 Sep 17 |
nicklas |
152 |
{ |
4577 |
19 Sep 17 |
nicklas |
153 |
out = location.getOutputStream(scriptPath, true); |
4577 |
19 Sep 17 |
nicklas |
154 |
out.setCharacterSet("UTF-8"); |
4577 |
19 Sep 17 |
nicklas |
155 |
out.setMimeType("text/x-shellscript"); |
4577 |
19 Sep 17 |
nicklas |
156 |
Writer writer = new OutputStreamWriter(out, Charset.forName("UTF-8")); |
4577 |
19 Sep 17 |
nicklas |
157 |
writer.write(script); |
4577 |
19 Sep 17 |
nicklas |
158 |
writer.flush(); |
4577 |
19 Sep 17 |
nicklas |
159 |
out.flush(); |
4577 |
19 Sep 17 |
nicklas |
160 |
writer.close(); |
4577 |
19 Sep 17 |
nicklas |
161 |
} |
4577 |
19 Sep 17 |
nicklas |
162 |
catch (IOException ex) |
4577 |
19 Sep 17 |
nicklas |
163 |
{ |
4577 |
19 Sep 17 |
nicklas |
164 |
throw new RuntimeException(ex); |
4577 |
19 Sep 17 |
nicklas |
165 |
} |
4577 |
19 Sep 17 |
nicklas |
166 |
finally |
4577 |
19 Sep 17 |
nicklas |
167 |
{ |
4577 |
19 Sep 17 |
nicklas |
168 |
FileUtil.close(out); |
4577 |
19 Sep 17 |
nicklas |
169 |
} |
4577 |
19 Sep 17 |
nicklas |
170 |
|
4577 |
19 Sep 17 |
nicklas |
171 |
} |
4577 |
19 Sep 17 |
nicklas |
172 |
|
4577 |
19 Sep 17 |
nicklas |
173 |
private void addScriptInfo(ScriptBuilder script) |
4577 |
19 Sep 17 |
nicklas |
174 |
{ |
4577 |
19 Sep 17 |
nicklas |
175 |
script.comment("Created by : Relax " + Relax.VERSION); |
4577 |
19 Sep 17 |
nicklas |
176 |
script.comment("Created at : " + Relax.CONVERTER_DATETIME_TO_STRING_WITH_SEPARATOR.convert(new Date())); |
4577 |
19 Sep 17 |
nicklas |
177 |
script.comment("Item list : " + options.getList().getName()); |
4577 |
19 Sep 17 |
nicklas |
178 |
script.comment("Release : " + options.getVersion()); |
4577 |
19 Sep 17 |
nicklas |
179 |
script.comment(""); |
4577 |
19 Sep 17 |
nicklas |
180 |
} |
4577 |
19 Sep 17 |
nicklas |
181 |
|
5250 |
18 Jan 19 |
nicklas |
182 |
private String getTextFile(String path) |
5250 |
18 Jan 19 |
nicklas |
183 |
{ |
5250 |
18 Jan 19 |
nicklas |
184 |
String readme = null; |
5250 |
18 Jan 19 |
nicklas |
185 |
InputStream in = null; |
5250 |
18 Jan 19 |
nicklas |
186 |
ByteArrayOutputStream buffer = new ByteArrayOutputStream(2048); |
5250 |
18 Jan 19 |
nicklas |
187 |
try |
5250 |
18 Jan 19 |
nicklas |
188 |
{ |
5250 |
18 Jan 19 |
nicklas |
189 |
in = getClass().getResourceAsStream(path); |
5250 |
18 Jan 19 |
nicklas |
190 |
FileUtil.copy(in, buffer); |
5250 |
18 Jan 19 |
nicklas |
191 |
readme = buffer.toString("UTF-8"); |
5250 |
18 Jan 19 |
nicklas |
192 |
} |
5250 |
18 Jan 19 |
nicklas |
193 |
catch (IOException ex) |
5250 |
18 Jan 19 |
nicklas |
194 |
{ |
5250 |
18 Jan 19 |
nicklas |
195 |
throw new RuntimeException(ex); |
5250 |
18 Jan 19 |
nicklas |
196 |
} |
5250 |
18 Jan 19 |
nicklas |
197 |
finally |
5250 |
18 Jan 19 |
nicklas |
198 |
{ |
5250 |
18 Jan 19 |
nicklas |
199 |
FileUtil.close(in); |
5250 |
18 Jan 19 |
nicklas |
200 |
} |
5250 |
18 Jan 19 |
nicklas |
201 |
return readme; |
5250 |
18 Jan 19 |
nicklas |
202 |
} |
5250 |
18 Jan 19 |
nicklas |
203 |
|
4577 |
19 Sep 17 |
nicklas |
204 |
} |