Skip to content

Commit afa82e4

Browse files
committed
fix tracing remote shells
1 parent 043adad commit afa82e4

File tree

5 files changed

+60
-12
lines changed

5 files changed

+60
-12
lines changed

qDup/src/main/java/io/hyperfoil/tools/qdup/shell/AbstractShell.java

Lines changed: 21 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -133,7 +133,7 @@ public AbstractShell(String name,Host host, String setupCommand, ScheduledThread
133133
this.host = host;
134134
this.setupCommand = setupCommand;
135135
this.executor = executor;
136-
this.trace=false;
136+
137137

138138
shellLock = new Semaphore(1);
139139
lineObservers = new ConcurrentHashMap<>();
@@ -149,13 +149,18 @@ public AbstractShell(String name,Host host, String setupCommand, ScheduledThread
149149
sessionStreams = new SessionStreams(getName(),executor);
150150
this.filter = filter;
151151
this.isPromptShell = new HashMap<>();
152+
this.trace = trace;
152153
}
153154

154155
abstract PrintStream connectShell();
155156
abstract void updateSessionStream(SessionStreams sessionStreams);
156157
final void setSessionStreams(SessionStreams sessionStreams){
157158
//TODO copy prompts from original sessionStreams to new sessionStreams
158159
this.sessionStreams.sharePrompts(sessionStreams);
160+
if(this.sessionStreams.hasTrace()){
161+
sessionStreams.setTrace(this.sessionStreams.getTraceName());
162+
}
163+
159164
this.sessionStreams = sessionStreams;
160165
updateSessionStream(sessionStreams);
161166
//trying fix shSync after setSessionStreams is called
@@ -165,6 +170,7 @@ final void setSessionStreams(SessionStreams sessionStreams){
165170
}
166171

167172

173+
168174
}
169175
SessionStreams getSessionStreams(){return this.sessionStreams;}
170176

@@ -197,17 +203,26 @@ public boolean connect(){
197203
//TODO need to replace lambda with method access for changes to sessionStream to be visible
198204
semaphoreCallback = (name) -> {
199205
String output = getShOutput(true);
206+
if(isTracing()){
207+
208+
}
200209
//TODO use atomic boolean to set expecting response and check for true before release?
201210
if(permits() == 0) {
202211
shellLock.release();
203212
if (isTracing()) {
204213
try {
205-
sessionStreams.getTrace().write("RELEASE".getBytes());
214+
sessionStreams.getTrace().write(("RELEASE "+"\n").getBytes());
206215
} catch (IOException e) {
207216
}
208217
}
209218
} else {
210219
//this should only happen if reconnected
220+
if (isTracing()) {
221+
try {
222+
sessionStreams.getTrace().write(("RECONNECT "+permits()+"\n").getBytes());
223+
} catch (IOException e) {
224+
}
225+
}
211226
logger.debug("skipping release, suspect reconnect "+permits());
212227
}
213228
shObservers(output,name);
@@ -221,6 +236,7 @@ public boolean connect(){
221236
addPrompt(getHost().getPrompt(), getHost().isShell());
222237
}
223238
sessionStreams.addPromptCallback(this.semaphoreCallback);
239+
224240
commandStream = connectShell();
225241
if(commandStream == null){
226242
if(getHost().hasAlias()){
@@ -271,6 +287,7 @@ public boolean connect(){
271287
rtrn = isOpen();
272288
}
273289
if(rtrn){
290+
setTrace(trace);
274291
rtrn = postConnect();
275292
}
276293
if(!rtrn){//something went wrong in post connect, this shell is no good
@@ -605,7 +622,7 @@ private boolean reconnect(){
605622
return isOpen() && isReady();
606623
}
607624

608-
public void setTrace(boolean trace) throws IOException {
625+
public void setTrace(boolean trace) {
609626
this.trace = trace;
610627
if (trace) {
611628
String path = hasName() ? getName() : getHost().toString();
@@ -669,7 +686,7 @@ public int permits() {
669686
return shellLock.availablePermits();
670687
}
671688
public boolean isTracing() {
672-
return sessionStreams!=null && sessionStreams.hasTrace();
689+
return trace && sessionStreams!=null && sessionStreams.hasTrace();
673690
}
674691

675692
public String getShOutput(boolean flush){

qDup/src/main/java/io/hyperfoil/tools/qdup/shell/ContainerShell.java

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -209,6 +209,7 @@ PrintStream connectShell() {
209209
).output();
210210
if(Host.isContainerId(cid)) {
211211
containerId = cid;
212+
connectSetContainerId = true;
212213
}
213214
}
214215
if( rtrn == null ){//did not set rtrn from the cidfile or didn't have one
@@ -222,6 +223,7 @@ PrintStream connectShell() {
222223
}
223224
if( rtrn == null && Host.isContainerId(response.output().trim())) {//command returned something or above failed to set the return
224225
containerId = response.output().trim();
226+
connectSetContainerId = true;
225227
}
226228
}
227229
}
@@ -321,6 +323,9 @@ PrintStream connectShell() {
321323
if(rtrn == null){
322324
String message = responses.stream().map(cr->cr.name+"\ncommand: "+cr.command+"\ntimeout: "+cr.response.timedOut()+"\noutput:\n"+cr.response.output()).collect(Collectors.joining("\n"));
323325
logger.errorf("%s failed to connect %s. Attempted:%n%s",getName(),getHost().getSafeString(),message);
326+
}else{
327+
//TODO I do not think this is necessary, it breaks shell.sh
328+
//getSessionStreams().getSuffixStream().removeConsumer(shell.semaphoreCallback);
324329
}
325330
return rtrn;
326331
}
@@ -340,15 +345,16 @@ public boolean postConnect(){
340345
getHost().setNeedStopContainer(true);
341346
containerId = unameN;
342347
} else {
343-
SyncResponse hostnameResponse = shellShSync("cat /etc/hostname", "cat-hostname", 10);
348+
SyncResponse hostnameResponse = shSync("cat /etc/hostname",null,10); //shellShSync("cat /etc/hostname", "cat-hostname", 10);
344349
if (Host.isContainerId(hostnameResponse.output().trim())) {
345350
getHost().setContainerId(hostnameResponse.output().trim());
346351
containerId = hostnameResponse.output().trim();
352+
getHost().setNeedStopContainer(true);
347353
}
348354
}
349355
}
350356
}
351-
String unameN = shell.shSync(GET_HOST_OR_CONTAINER_ID);
357+
String unameN = shSync(GET_HOST_OR_CONTAINER_ID); //shell.shSync(GET_HOST_OR_CONTAINER_ID);
352358
//it should always be 0...
353359
if(getHost().getContainerLock().availablePermits() == 0){
354360
getHost().getContainerLock().release();

qDup/src/main/java/io/hyperfoil/tools/qdup/stream/SessionStreams.java

Lines changed: 19 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,9 @@ public ByteArrayOutputStream getShStream() {
5656
* shStream - stores the write buffer for a command
5757
* promptStream - watches for suffixes and sends a prompt response (Y/n, Ok?, ...)
5858
*/
59+
60+
private String traceName;
61+
5962
public SessionStreams(String name, ScheduledThreadPoolExecutor executor){
6063
super(name);
6164
shStream = new ByteArrayOutputStream();
@@ -103,7 +106,9 @@ public void write(int b) throws IOException {
103106
@Override
104107
public void write(byte b[], int off, int len) throws IOException {
105108
if(hasTrace()){
106-
trace("[--qdup--]");
109+
trace("[>>qdup["+off+","+len+"]--]\n");
110+
trace(MultiStream.printByteCharacters(b,off,len));
111+
trace("\n[<<qdup["+off+","+len+"]--]\n");
107112
}
108113
super.write(b,off,len);
109114
//escapeFilteredStream.write(b,off,len);
@@ -174,15 +179,23 @@ public void setName(String name){
174179
public boolean hasTrace(){
175180
return escapeFilteredStream.hasStream("trace");
176181
}
177-
public void setTrace(String traceName) throws IOException{
182+
public String getTraceName(){return traceName;}
183+
public void setTrace(String traceName){
178184
if(!hasTrace()){
185+
this.traceName = traceName;
179186
try {
180187
String tDir = System.getProperty("java.io.tmpdir");
181188
logger.info("streamtracing " + traceName + " to " + tDir);
182-
String rawTracePath = Files.createFile(Paths.get(tDir, "qdup." + traceName + ".raw.log")).toAbsolutePath().toString();
183-
FileOutputStream rawTraceStream = new FileOutputStream(rawTracePath);
184-
String efsTracePath = Files.createFile(Paths.get(tDir, "qdup." + traceName + ".efs.log")).toAbsolutePath().toString();
185-
FileOutputStream efsTraceStream = new FileOutputStream(efsTracePath);
189+
Path rawTracePath = Paths.get(tDir, "qdup." + traceName + ".raw.log");
190+
if(!Files.exists(rawTracePath)){
191+
Files.createFile(rawTracePath);
192+
}
193+
FileOutputStream rawTraceStream = new FileOutputStream(rawTracePath.toFile());
194+
Path efsTracePath = Paths.get(tDir, "qdup." + traceName + ".efs.log");
195+
if(!Files.exists(efsTracePath)){
196+
Files.createFile(efsTracePath);
197+
}
198+
FileOutputStream efsTraceStream = new FileOutputStream(efsTracePath.toFile());
186199
escapeFilteredStream.addStream("trace", efsTraceStream);
187200
addStream("trace", rawTraceStream);
188201
}catch(Exception e){

qDup/src/main/java/io/hyperfoil/tools/qdup/stream/SuffixStream.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -151,6 +151,7 @@ public Map<String,String> getReplacements(){
151151
public void addConsumer(Consumer<String> consumer){
152152
consumers.add(consumer);
153153
}
154+
public List<Consumer<String>> getConsumers(){return Collections.unmodifiableList(consumers);}
154155
public boolean hasConsumers(){return !consumers.isEmpty();}
155156
public void removeConsumer(Consumer<String> consumer){
156157
consumers.remove(consumer);

qDup/src/test/java/io/hyperfoil/tools/qdup/shell/AbstractShellTest.java

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,4 +46,15 @@ public void getShell_sshShell(){
4646
assertTrue("shell should be ready",shell.isReady());
4747
assertTrue("shell should be SshShell but was "+shell.getClass().getSimpleName(),shell instanceof SshShell);
4848
}
49+
50+
@Test
51+
public void isTracing(){
52+
Host host = getHost();
53+
AbstractShell shell = AbstractShell.getShell("tracingShell",host,new ScheduledThreadPoolExecutor(2),new SecretFilter(),true);
54+
55+
boolean isTracing = shell.isTracing();
56+
assertTrue(isTracing);
57+
String path = shell.getSessionStreams().getTraceName();
58+
shell.shSync("env");
59+
}
4960
}

0 commit comments

Comments
 (0)