changeset 2527:edf71d9262f8

Copy IPC properties file to world-readable location at runtime Reviewed-by: jerboaa Review-thread: http://icedtea.classpath.org/pipermail/thermostat/2016-November/021565.html
author Elliott Baron <ebaron@redhat.com>
date Tue, 15 Nov 2016 18:18:31 -0500
parents 7bfcfb7e5c1e
children 3c990cdff9ad
files agent/command/src/main/java/com/redhat/thermostat/agent/command/internal/Activator.java agent/command/src/main/java/com/redhat/thermostat/agent/command/internal/CommandChannelDelegate.java agent/command/src/test/java/com/redhat/thermostat/agent/command/internal/CommandChannelDelegateTest.java agent/core/src/main/java/com/redhat/thermostat/agent/internal/Activator.java agent/core/src/main/java/com/redhat/thermostat/utils/management/internal/MXBeanConnectionPoolImpl.java agent/core/src/test/java/com/redhat/thermostat/utils/management/internal/MXBeanConnectionPoolImplTest.java agent/ipc/server/pom.xml agent/ipc/server/src/main/java/com/redhat/thermostat/agent/ipc/server/AgentIPCService.java agent/ipc/server/src/main/java/com/redhat/thermostat/agent/ipc/server/ServerTransport.java agent/ipc/server/src/main/java/com/redhat/thermostat/agent/ipc/server/internal/Activator.java agent/ipc/server/src/main/java/com/redhat/thermostat/agent/ipc/server/internal/AgentIPCServiceImpl.java agent/ipc/server/src/test/java/com/redhat/thermostat/agent/ipc/server/internal/ActivatorTest.java agent/ipc/server/src/test/java/com/redhat/thermostat/agent/ipc/server/internal/AgentIPCServiceImplTest.java vm-byteman/agent/src/main/java/com/redhat/thermostat/vm/byteman/agent/internal/BytemanAttacher.java vm-byteman/agent/src/main/java/com/redhat/thermostat/vm/byteman/agent/internal/BytemanRequestReceiver.java vm-byteman/agent/src/test/java/com/redhat/thermostat/vm/byteman/agent/internal/BytemanAgentAttachManagerTest.java vm-byteman/agent/src/test/java/com/redhat/thermostat/vm/byteman/agent/internal/BytemanAttacherTest.java vm-byteman/agent/src/test/java/com/redhat/thermostat/vm/byteman/agent/internal/BytemanRequestReceiverTest.java
diffstat 18 files changed, 215 insertions(+), 66 deletions(-) [+]
line wrap: on
line diff
--- a/agent/command/src/main/java/com/redhat/thermostat/agent/command/internal/Activator.java	Tue Nov 15 15:59:46 2016 -0500
+++ b/agent/command/src/main/java/com/redhat/thermostat/agent/command/internal/Activator.java	Tue Nov 15 18:18:31 2016 -0500
@@ -77,7 +77,7 @@
                 SSLConfiguration sslConf = services.get(SSLConfiguration.class);
                 AgentIPCService ipcService = services.get(AgentIPCService.class);
                 CommandChannelDelegate confServer = new CommandChannelDelegate(receivers, sslConf, 
-                        paths.getSystemBinRoot(), ipcService, paths.getUserIPCConfigurationFile());
+                        paths.getSystemBinRoot(), ipcService);
                 confServerRegistration = context.registerService(ConfigurationServer.class.getName(), confServer, null);
             }
 
--- a/agent/command/src/main/java/com/redhat/thermostat/agent/command/internal/CommandChannelDelegate.java	Tue Nov 15 15:59:46 2016 -0500
+++ b/agent/command/src/main/java/com/redhat/thermostat/agent/command/internal/CommandChannelDelegate.java	Tue Nov 15 18:18:31 2016 -0500
@@ -90,7 +90,6 @@
     private final StorageGetter storageGetter;
     private final File binPath;
     private final AgentIPCService ipcService;
-    private final File ipcConfig;
     private final CountDownLatch readyLatch;
     private final SSLConfigurationEncoder sslEncoder;
     private final AgentRequestDecoder requestDecoder;
@@ -102,15 +101,15 @@
     private AtomicInteger state;
     
     CommandChannelDelegate(ReceiverRegistry receivers, SSLConfiguration sslConf, File binPath,
-            AgentIPCService ipcService, File ipcConfig) {
-        this(receivers, sslConf, binPath, ipcService, ipcConfig, new CountDownLatch(1), new SSLConfigurationEncoder(), 
+            AgentIPCService ipcService) {
+        this(receivers, sslConf, binPath, ipcService, new CountDownLatch(1), new SSLConfigurationEncoder(), 
                 new AgentRequestDecoder(), new AgentResponseEncoder(), new StorageGetter(), new ProcessUserInfoBuilder(), 
                 new FileSystemUtils(), new ProcessCreator());
     }
 
     /** For testing only */
     CommandChannelDelegate(ReceiverRegistry receivers, SSLConfiguration sslConf, File binPath, 
-            AgentIPCService ipcService, File ipcConfig, CountDownLatch readyLatch, SSLConfigurationEncoder sslEncoder, 
+            AgentIPCService ipcService, CountDownLatch readyLatch, SSLConfigurationEncoder sslEncoder, 
             AgentRequestDecoder requestDecoder, AgentResponseEncoder responseEncoder, StorageGetter getter, 
             ProcessUserInfoBuilder userInfoBuilder, FileSystemUtils fsUtils, ProcessCreator procCreator) {
         this.storageGetter = getter;
@@ -118,7 +117,6 @@
         this.sslConf = sslConf;
         this.binPath = binPath;
         this.ipcService = ipcService;
-        this.ipcConfig = ipcConfig;
         this.readyLatch = readyLatch;
         this.sslEncoder = sslEncoder;
         this.requestDecoder = requestDecoder;
@@ -226,6 +224,7 @@
     }
     
     private void startServer(String hostname, int port) throws IOException {
+        File ipcConfig = ipcService.getConfigurationFile();
         String[] processArgs = OS.IS_UNIX
                 ? new String[]{ binPath.getAbsolutePath() + File.separator + CMD_NAME, hostname,
                                 String.valueOf(port), ipcConfig.getAbsolutePath() }
--- a/agent/command/src/test/java/com/redhat/thermostat/agent/command/internal/CommandChannelDelegateTest.java	Tue Nov 15 15:59:46 2016 -0500
+++ b/agent/command/src/test/java/com/redhat/thermostat/agent/command/internal/CommandChannelDelegateTest.java	Tue Nov 15 18:18:31 2016 -0500
@@ -142,11 +142,12 @@
         when(sslConfEncoder.encodeAsJson(sslConf)).thenReturn(ENCODED_SSL_CONFIG);
         
         when(processCreator.startProcess(any(ProcessBuilder.class))).thenReturn(process);
+        when(ipcService.getConfigurationFile()).thenReturn(ipcConfig);
         
         latch = mock(CountDownLatch.class);
         fsUtils = mock(FileSystemUtils.class);
         userInfoBuilder = mock(ProcessUserInfoBuilder.class);
-        delegate = new CommandChannelDelegate(receivers, sslConf, binPath, ipcService, ipcConfig, 
+        delegate = new CommandChannelDelegate(receivers, sslConf, binPath, ipcService, 
                 latch, sslConfEncoder, requestDecoder, responseEncoder, storageGetter, userInfoBuilder, 
                 fsUtils, processCreator);
         
--- a/agent/core/src/main/java/com/redhat/thermostat/agent/internal/Activator.java	Tue Nov 15 15:59:46 2016 -0500
+++ b/agent/core/src/main/java/com/redhat/thermostat/agent/internal/Activator.java	Tue Nov 15 18:18:31 2016 -0500
@@ -120,8 +120,7 @@
                 AgentIPCService ipcService = services.get(AgentIPCService.class);
                 CommonPaths paths = services.get(CommonPaths.class);
                 UserNameUtil util = services.get(UserNameUtil.class);
-                pool = new MXBeanConnectionPoolImpl(paths.getSystemBinRoot(), util, 
-                    ipcService, paths.getUserIPCConfigurationFile());
+                pool = new MXBeanConnectionPoolImpl(paths.getSystemBinRoot(), util, ipcService);
                 context.registerService(MXBeanConnectionPool.class, pool, null);
                 // Used only internally
                 context.registerService(MXBeanConnectionPoolControl.class, pool, null);
--- a/agent/core/src/main/java/com/redhat/thermostat/utils/management/internal/MXBeanConnectionPoolImpl.java	Tue Nov 15 15:59:46 2016 -0500
+++ b/agent/core/src/main/java/com/redhat/thermostat/utils/management/internal/MXBeanConnectionPoolImpl.java	Tue Nov 15 18:18:31 2016 -0500
@@ -79,7 +79,6 @@
     private final File binPath;
     private final ProcessUserInfoBuilder userInfoBuilder;
     private final AgentIPCService ipcService;
-    private final File ipcConfigFile;
     private final FileSystemUtils fsUtils;
     // Keep track of IPC servers we created
     private final Set<String> ipcServerNames;
@@ -94,20 +93,18 @@
     private MXBeanConnectionPoolEntry currentNewEntry;
     private boolean started;
 
-    public MXBeanConnectionPoolImpl(File binPath, UserNameUtil userNameUtil, 
-            AgentIPCService ipcService, File ipcConfigFile) {
+    public MXBeanConnectionPoolImpl(File binPath, UserNameUtil userNameUtil, AgentIPCService ipcService) {
         this(new ConnectorCreator(), binPath, new ProcessUserInfoBuilder(new ProcDataSource(), userNameUtil), 
-                ipcService, ipcConfigFile, new FileSystemUtils());
+                ipcService, new FileSystemUtils());
     }
 
     MXBeanConnectionPoolImpl(ConnectorCreator connectorCreator, File binPath, ProcessUserInfoBuilder userInfoBuilder, 
-            AgentIPCService ipcService, File ipcConfigFile, FileSystemUtils fsUtils) {
+            AgentIPCService ipcService, FileSystemUtils fsUtils) {
         this.pool = new HashMap<>();
         this.creator = connectorCreator;
         this.binPath = binPath;
         this.userInfoBuilder = userInfoBuilder;
         this.ipcService = ipcService;
-        this.ipcConfigFile = ipcConfigFile;
         this.fsUtils = fsUtils;
         this.currentNewEntry = null;
         this.started = false;
@@ -227,7 +224,8 @@
                 pool.put(pid, data);
                 
                 // Start agent proxy which will send the JMX service URL to the IPC server we created
-                AgentProxyClient proxy = creator.createAgentProxy(pid, username, binPath, ipcConfigFile, serverName);
+                File configFile = ipcService.getConfigurationFile();
+                AgentProxyClient proxy = creator.createAgentProxy(pid, username, binPath, configFile, serverName);
                 proxy.runProcess(); // Process completed when this returns
                 
                 // Block until we get a JMX service URL, or Exception
--- a/agent/core/src/test/java/com/redhat/thermostat/utils/management/internal/MXBeanConnectionPoolImplTest.java	Tue Nov 15 15:59:46 2016 -0500
+++ b/agent/core/src/test/java/com/redhat/thermostat/utils/management/internal/MXBeanConnectionPoolImplTest.java	Tue Nov 15 18:18:31 2016 -0500
@@ -110,7 +110,8 @@
         principal = mock(UserPrincipal.class);
         when(lookup.lookupPrincipalByName("Test")).thenReturn(principal);
 
-        pool = new MXBeanConnectionPoolImpl(creator, binDir, builder, ipcService, ipcConfigFile, fsUtils);
+        when(ipcService.getConfigurationFile()).thenReturn(ipcConfigFile);
+        pool = new MXBeanConnectionPoolImpl(creator, binDir, builder, ipcService, fsUtils);
     }
     
     @Test
--- a/agent/ipc/server/pom.xml	Tue Nov 15 15:59:46 2016 -0500
+++ b/agent/ipc/server/pom.xml	Tue Nov 15 18:18:31 2016 -0500
@@ -77,6 +77,11 @@
     </dependency>
     <dependency>
       <groupId>com.redhat.thermostat</groupId>
+      <artifactId>thermostat-storage-core</artifactId>
+      <version>${project.version}</version>
+    </dependency>
+    <dependency>
+      <groupId>com.redhat.thermostat</groupId>
       <artifactId>thermostat-agent-ipc-common</artifactId>
       <version>${project.version}</version>
     </dependency>
--- a/agent/ipc/server/src/main/java/com/redhat/thermostat/agent/ipc/server/AgentIPCService.java	Tue Nov 15 15:59:46 2016 -0500
+++ b/agent/ipc/server/src/main/java/com/redhat/thermostat/agent/ipc/server/AgentIPCService.java	Tue Nov 15 18:18:31 2016 -0500
@@ -36,6 +36,7 @@
 
 package com.redhat.thermostat.agent.ipc.server;
 
+import java.io.File;
 import java.io.IOException;
 import java.nio.file.attribute.UserPrincipal;
 
@@ -90,4 +91,12 @@
      */
     void destroyServer(String name) throws IOException;
     
+    /**
+     * Returns the configuration file used by this IPC service. This file contains properties used
+     * to exchange information between the server-side and client-side IPC services.
+     * @return the configuration file
+     * @throws IOException if the configuration file cannot be obtained or the IPC service fails to start
+     */
+    File getConfigurationFile() throws IOException;
+    
 }
--- a/agent/ipc/server/src/main/java/com/redhat/thermostat/agent/ipc/server/ServerTransport.java	Tue Nov 15 15:59:46 2016 -0500
+++ b/agent/ipc/server/src/main/java/com/redhat/thermostat/agent/ipc/server/ServerTransport.java	Tue Nov 15 18:18:31 2016 -0500
@@ -37,6 +37,7 @@
 package com.redhat.thermostat.agent.ipc.server;
 
 import java.io.IOException;
+import java.nio.file.attribute.UserPrincipal;
 
 import com.redhat.thermostat.agent.ipc.common.internal.IPCProperties;
 import com.redhat.thermostat.agent.ipc.common.internal.IPCType;
@@ -45,7 +46,27 @@
  * non-API interface mirroring AgentIPCService that provides IPC mechanism-specific
  * implementations of AgentIPCService's API methods
  */
-public interface ServerTransport extends AgentIPCService {
+public interface ServerTransport {
+    
+    /**
+     * @see AgentIPCService#createServer(String, ThermostatIPCCallbacks)
+     */
+    void createServer(String name, ThermostatIPCCallbacks callbacks) throws IOException;
+    
+    /**
+     * @see AgentIPCService#createServer(String, ThermostatIPCCallbacks, UserPrincipal)
+     */
+    void createServer(String name, ThermostatIPCCallbacks callbacks, UserPrincipal owner) throws IOException;
+    
+    /**
+     * @see AgentIPCService#serverExists(String)
+     */
+    boolean serverExists(String name) throws IOException;
+    
+    /**
+     * @see AgentIPCService#destroyServer(String)
+     */
+    void destroyServer(String name) throws IOException;
     
     void start(IPCProperties props) throws IOException;
     
--- a/agent/ipc/server/src/main/java/com/redhat/thermostat/agent/ipc/server/internal/Activator.java	Tue Nov 15 15:59:46 2016 -0500
+++ b/agent/ipc/server/src/main/java/com/redhat/thermostat/agent/ipc/server/internal/Activator.java	Tue Nov 15 18:18:31 2016 -0500
@@ -43,13 +43,15 @@
 
 import org.osgi.framework.BundleActivator;
 import org.osgi.framework.BundleContext;
-import org.osgi.framework.ServiceReference;
 import org.osgi.framework.ServiceRegistration;
-import org.osgi.util.tracker.ServiceTracker;
 
 import com.redhat.thermostat.agent.ipc.server.AgentIPCService;
+import com.redhat.thermostat.common.MultipleServiceTracker;
+import com.redhat.thermostat.common.MultipleServiceTracker.Action;
+import com.redhat.thermostat.common.MultipleServiceTracker.DependencyProvider;
 import com.redhat.thermostat.common.utils.LoggingUtils;
 import com.redhat.thermostat.shared.config.CommonPaths;
+import com.redhat.thermostat.storage.core.WriterID;
 
 public class Activator implements BundleActivator {
     
@@ -57,22 +59,25 @@
     
     private ServerIPCPropertiesBuilder propBuilder;
     private AgentIPCServiceImpl ipcService;
-    private ServiceTracker tracker;
+    private MultipleServiceTracker tracker;
     private ServiceRegistration reg;
     
-    public void start(BundleContext context) throws Exception {
+    public void start(final BundleContext context) throws Exception {
         propBuilder = new ServerIPCPropertiesBuilder(context);
-        tracker = new ServiceTracker(context, CommonPaths.class.getName(), null) {
+        Class<?>[] deps = new Class<?>[] { CommonPaths.class, WriterID.class };
+        tracker = new MultipleServiceTracker(context, deps, new Action() {
+            
             @Override
-            public Object addingService(ServiceReference reference) {
-                CommonPaths paths = (CommonPaths) super.addingService(reference);
+            public void dependenciesAvailable(DependencyProvider services) {
+                CommonPaths paths = (CommonPaths) services.get(CommonPaths.class);
+                WriterID writerID = (WriterID) services.get(WriterID.class);
                 File propFile = paths.getUserIPCConfigurationFile();
-                ipcService = new AgentIPCServiceImpl(propBuilder, context, propFile);
+                ipcService = new AgentIPCServiceImpl(propBuilder, context, propFile, writerID);
                 reg = context.registerService(AgentIPCService.class.getName(), ipcService, null);
-                return paths;
             }
+
             @Override
-            public void removedService(ServiceReference reference, Object service) {
+            public void dependenciesUnavailable() {
                 if (reg != null) {
                     try {
                         ipcService.shutdown();
@@ -82,9 +87,8 @@
                     reg.unregister();
                     reg = null;
                 }
-                super.removedService(reference, service);
             }
-        };
+        });
         
         tracker.open();
     }
--- a/agent/ipc/server/src/main/java/com/redhat/thermostat/agent/ipc/server/internal/AgentIPCServiceImpl.java	Tue Nov 15 15:59:46 2016 -0500
+++ b/agent/ipc/server/src/main/java/com/redhat/thermostat/agent/ipc/server/internal/AgentIPCServiceImpl.java	Tue Nov 15 18:18:31 2016 -0500
@@ -38,6 +38,9 @@
 
 import java.io.File;
 import java.io.IOException;
+import java.nio.file.CopyOption;
+import java.nio.file.Files;
+import java.nio.file.Path;
 import java.nio.file.attribute.UserPrincipal;
 import java.util.HashMap;
 import java.util.Map;
@@ -51,27 +54,35 @@
 import com.redhat.thermostat.agent.ipc.server.AgentIPCService;
 import com.redhat.thermostat.agent.ipc.server.ServerTransport;
 import com.redhat.thermostat.agent.ipc.server.ThermostatIPCCallbacks;
+import com.redhat.thermostat.storage.core.WriterID;
 
 class AgentIPCServiceImpl implements AgentIPCService {
     
+    static final String RUNTIME_IPC_CONFIG_PREFIX = "thermostat-ipc.properties.";
+    
     private final ServerIPCPropertiesBuilder propBuilder;
     private final ServiceTracker transportTracker;
     // Access/modification of this field should by synchronized
     private final Map<IPCType, ServerTransport> transports;
+    // IPC configuration residing in USER_THERMOSTAT_HOME
     private final File propFile;
+    private final WriterID writerID;
     private final FileHelper helper;
     
     private ServerTransport transport;
     private IPCProperties props;
     private boolean started;
     
-    AgentIPCServiceImpl(ServerIPCPropertiesBuilder propBuilder, BundleContext context, File propFile) {
-        this(propBuilder, context, propFile, new FileHelper());
+    AgentIPCServiceImpl(ServerIPCPropertiesBuilder propBuilder, BundleContext context, File propFile, 
+            WriterID writerID) {
+        this(propBuilder, context, propFile, writerID, new FileHelper());
     }
             
-    AgentIPCServiceImpl(ServerIPCPropertiesBuilder propBuilder, BundleContext context, File propFile, FileHelper helper) {
+    AgentIPCServiceImpl(ServerIPCPropertiesBuilder propBuilder, BundleContext context, File propFile, 
+            WriterID writerID, FileHelper helper) {
         this.propBuilder = propBuilder;
         this.propFile = propFile;
+        this.writerID = writerID;
         this.transports = new HashMap<>();
         this.helper = helper;
         this.started = false;
@@ -171,7 +182,23 @@
             IPCConfigurationWriter writer = helper.getConfigurationWriter(propFile);
             writer.write();
         }
-        return propBuilder.getProperties(propFile);
+        
+        // Copy read-only copy of IPC properties file to a world-readable location
+        String destDirPath = helper.getSystemProperty("java.io.tmpdir");
+        if (destDirPath == null) {
+            throw new IOException("Required system property \"java.io.tmpdir\" is not defined");
+        }
+        File destDir = helper.getFile(destDirPath);
+        
+        // Append agent ID to IPC config filename
+        String filename = RUNTIME_IPC_CONFIG_PREFIX.concat(writerID.getWriterID());
+        File runtimeIpcConfig = helper.getFile(destDir, filename);
+        runtimeIpcConfig.deleteOnExit();
+        
+        // Copy config file to destination
+        helper.copy(propFile.toPath(), runtimeIpcConfig.toPath());
+        
+        return propBuilder.getProperties(runtimeIpcConfig);
     }
     
     // Helper class for testing purposes
@@ -182,6 +209,18 @@
         IPCConfigurationWriter getConfigurationWriter(File configFile) {
             return new IPCConfigurationWriter(configFile);
         }
+        String getSystemProperty(String key) {
+            return System.getProperty(key);
+        }
+        File getFile(File parent, String name) {
+            return new File(parent, name);
+        }
+        File getFile(String path) {
+            return new File(path);
+        }
+        Path copy(Path src, Path dst, CopyOption... options) throws IOException {
+            return Files.copy(src, dst, options);
+        }
     }
 
     // For testing purposes only
@@ -192,4 +231,13 @@
         }
     }
 
+    @Override
+    public File getConfigurationFile() throws IOException {
+        // Start the service if not already started
+        if (!started) {
+            startService();
+        }
+        return props.getPropertiesFile();
+    }
+
 }
--- a/agent/ipc/server/src/test/java/com/redhat/thermostat/agent/ipc/server/internal/ActivatorTest.java	Tue Nov 15 15:59:46 2016 -0500
+++ b/agent/ipc/server/src/test/java/com/redhat/thermostat/agent/ipc/server/internal/ActivatorTest.java	Tue Nov 15 18:18:31 2016 -0500
@@ -46,6 +46,7 @@
 
 import com.redhat.thermostat.agent.ipc.server.AgentIPCService;
 import com.redhat.thermostat.shared.config.CommonPaths;
+import com.redhat.thermostat.storage.core.WriterID;
 import com.redhat.thermostat.testutils.StubBundleContext;
 
 public class ActivatorTest {
@@ -70,6 +71,8 @@
         
         CommonPaths paths = mock(CommonPaths.class);
         context.registerService(CommonPaths.class, paths, null);
+        WriterID writerID = mock(WriterID.class);
+        context.registerService(WriterID.class, writerID, null);
 
         Activator activator = new Activator();
 
@@ -78,7 +81,7 @@
         activator.stop(context);
 
         assertEquals(0, context.getServiceListeners().size());
-        assertEquals(1, context.getAllServices().size());
+        assertEquals(2, context.getAllServices().size());
     }
     
     @Test
--- a/agent/ipc/server/src/test/java/com/redhat/thermostat/agent/ipc/server/internal/AgentIPCServiceImplTest.java	Tue Nov 15 15:59:46 2016 -0500
+++ b/agent/ipc/server/src/test/java/com/redhat/thermostat/agent/ipc/server/internal/AgentIPCServiceImplTest.java	Tue Nov 15 18:18:31 2016 -0500
@@ -47,6 +47,7 @@
 
 import java.io.File;
 import java.io.IOException;
+import java.nio.file.Path;
 import java.nio.file.attribute.UserPrincipal;
 import java.util.Map;
 
@@ -59,17 +60,25 @@
 import com.redhat.thermostat.agent.ipc.server.ServerTransport;
 import com.redhat.thermostat.agent.ipc.server.ThermostatIPCCallbacks;
 import com.redhat.thermostat.agent.ipc.server.internal.AgentIPCServiceImpl.FileHelper;
+import com.redhat.thermostat.storage.core.WriterID;
 import com.redhat.thermostat.testutils.StubBundleContext;
 
 public class AgentIPCServiceImplTest {
 
     private static final String SERVER_NAME = "test";
+    private static final String TMPDIR = "/path/to/tmp";
+    private static final String AGENT_ID = "myAgentId";
     
     private ServerTransport transport;
     private IPCProperties props;
     private FileHelper helper;
     private IPCConfigurationWriter writer;
-    private File propFile;
+    private File userPropFile;
+    private File tmpdirFile;
+    private File runtimePropFile;
+    private Path userPropPath;
+    private Path runtimePropPath;
+    private WriterID writerID;
     private ServerIPCPropertiesBuilder propBuilder;
     private StubBundleContext context;
     
@@ -78,14 +87,25 @@
         context = new StubBundleContext();
         transport = mock(ServerTransport.class);
         when(transport.getType()).thenReturn(IPCType.UNKNOWN);
-        propFile = mock(File.class);
+        userPropFile = mock(File.class);
+        userPropPath = mock(Path.class);
+        when(userPropFile.toPath()).thenReturn(userPropPath);
         propBuilder = mock(ServerIPCPropertiesBuilder.class);
         props = mock(IPCProperties.class);
         when(props.getType()).thenReturn(IPCType.UNKNOWN);
-        when(propBuilder.getProperties(propFile)).thenReturn(props);
+        runtimePropFile = mock(File.class);
+        when(propBuilder.getProperties(runtimePropFile)).thenReturn(props);
+        runtimePropPath = mock(Path.class);
+        when(runtimePropFile.toPath()).thenReturn(runtimePropPath);
+        writerID = mock(WriterID.class);
+        when(writerID.getWriterID()).thenReturn(AGENT_ID);
         helper = mock(FileHelper.class);
         writer = mock(IPCConfigurationWriter.class);
-        when(helper.getConfigurationWriter(propFile)).thenReturn(writer);
+        when(helper.getConfigurationWriter(userPropFile)).thenReturn(writer);
+        when(helper.getSystemProperty("java.io.tmpdir")).thenReturn(TMPDIR);
+        tmpdirFile = mock(File.class);
+        when(helper.getFile(TMPDIR)).thenReturn(tmpdirFile);
+        when(helper.getFile(tmpdirFile, AgentIPCServiceImpl.RUNTIME_IPC_CONFIG_PREFIX + AGENT_ID)).thenReturn(runtimePropFile);
     }
 
     @Test
@@ -102,9 +122,38 @@
         verify(writer).write();
         verify(transport).createServer(SERVER_NAME, callbacks);
     }
+    
+    @Test
+    public void testStartCreatesRuntimePropertyFile() throws Exception {
+        context.registerService(ServerTransport.class.getName(), transport, null);
+        AgentIPCServiceImpl service = createService();
+        ThermostatIPCCallbacks callbacks = mock(ThermostatIPCCallbacks.class);
+        
+        assertFalse(service.isStarted());
+        service.createServer(SERVER_NAME, callbacks);
+        assertTrue(service.isStarted());
+        
+        verify(helper).getSystemProperty("java.io.tmpdir");
+        verify(helper).getFile(TMPDIR);
+        verify(helper).getFile(tmpdirFile, AgentIPCServiceImpl.RUNTIME_IPC_CONFIG_PREFIX + AGENT_ID);
+        verify(helper).copy(userPropPath, runtimePropPath);
+        verify(runtimePropFile).deleteOnExit();
+    }
+    
+    @Test(expected=IOException.class)
+    public void testUndefinedTmpdirThrowsException() throws Exception {
+        when(helper.getSystemProperty("java.io.tmpdir")).thenReturn(null);
+        
+        context.registerService(ServerTransport.class.getName(), transport, null);
+        AgentIPCServiceImpl service = createService();
+        ThermostatIPCCallbacks callbacks = mock(ThermostatIPCCallbacks.class);
+        
+        assertFalse(service.isStarted());
+        service.createServer(SERVER_NAME, callbacks);
+    }
 
     private AgentIPCServiceImpl createService() {
-        return new AgentIPCServiceImpl(propBuilder, context, propFile, helper);
+        return new AgentIPCServiceImpl(propBuilder, context, userPropFile, writerID, helper);
     }
     
     @Test
@@ -141,7 +190,7 @@
     public void testCreateServerFileExists() throws Exception {
         context.registerService(ServerTransport.class.getName(), transport, null);
         AgentIPCServiceImpl service = createService();
-        when(helper.configFileExists(propFile)).thenReturn(true);
+        when(helper.configFileExists(userPropFile)).thenReturn(true);
         ThermostatIPCCallbacks callbacks = mock(ThermostatIPCCallbacks.class);
         
         assertFalse(service.isStarted());
--- a/vm-byteman/agent/src/main/java/com/redhat/thermostat/vm/byteman/agent/internal/BytemanAttacher.java	Tue Nov 15 15:59:46 2016 -0500
+++ b/vm-byteman/agent/src/main/java/com/redhat/thermostat/vm/byteman/agent/internal/BytemanAttacher.java	Tue Nov 15 18:18:31 2016 -0500
@@ -36,6 +36,7 @@
 
 package com.redhat.thermostat.vm.byteman.agent.internal;
 
+import java.io.File;
 import java.io.FileNotFoundException;
 import java.io.IOException;
 import java.net.ServerSocket;
@@ -47,9 +48,9 @@
 
 import org.jboss.byteman.agent.install.Install;
 
+import com.redhat.thermostat.agent.ipc.server.AgentIPCService;
 import com.redhat.thermostat.agent.utils.ProcessChecker;
 import com.redhat.thermostat.common.utils.LoggingUtils;
-import com.redhat.thermostat.shared.config.CommonPaths;
 import com.sun.tools.attach.AgentInitializationException;
 import com.sun.tools.attach.AgentLoadException;
 import com.sun.tools.attach.AttachNotSupportedException;
@@ -72,16 +73,16 @@
     };
     private final BtmInstallHelper installer;
     private final ProcessChecker processChecker;
-    private final CommonPaths paths;
+    private final AgentIPCService ipcService;
     
-    BytemanAttacher(CommonPaths paths) {
-        this(new BtmInstallHelper(), new ProcessChecker(), paths);
+    BytemanAttacher(AgentIPCService ipcProps) {
+        this(new BtmInstallHelper(), new ProcessChecker(), ipcProps);
     }
     
-    BytemanAttacher(BtmInstallHelper installer, ProcessChecker processChecker, CommonPaths paths) {
+    BytemanAttacher(BtmInstallHelper installer, ProcessChecker processChecker, AgentIPCService ipcService) {
         this.installer = installer;
         this.processChecker = processChecker;
-        this.paths = paths;
+        this.ipcService = ipcService;
     }
     
     
@@ -122,11 +123,12 @@
 
     // Note:  Setting properties will not work if they don't start with the
     //        byteman prefix. Namely, "org.jboss.byteman."
-    private String[] buildBytemanInstallProps(VmSocketIdentifier sockIdentifier, int port) {
+    private String[] buildBytemanInstallProps(VmSocketIdentifier sockIdentifier, int port) throws IOException {
         List<String> properties = new ArrayList<>();
         properties.addAll(Arrays.asList(BYTEMAN_STATIC_INSTALL_PROPS));
         String socketNameProperty = THERMOSTAT_HELPER_SOCKET_NAME_PROPERTY + "=" + sockIdentifier.getName();
-        String ipcSocketDirProperty = THERMOSTAT_IPC_CONFIG_NAME_PROPERTY + "=" + paths.getUserIPCConfigurationFile().getAbsolutePath();
+        File ipcConfig = ipcService.getConfigurationFile();
+        String ipcSocketDirProperty = THERMOSTAT_IPC_CONFIG_NAME_PROPERTY + "=" + ipcConfig.getAbsolutePath();
         String agentPortProperty = BYTEMAN_AGENT_PORT_PROPERTY + "=" + Integer.valueOf(port).toString();
         properties.add(socketNameProperty);
         properties.add(ipcSocketDirProperty);
--- a/vm-byteman/agent/src/main/java/com/redhat/thermostat/vm/byteman/agent/internal/BytemanRequestReceiver.java	Tue Nov 15 15:59:46 2016 -0500
+++ b/vm-byteman/agent/src/main/java/com/redhat/thermostat/vm/byteman/agent/internal/BytemanRequestReceiver.java	Tue Nov 15 18:18:31 2016 -0500
@@ -134,23 +134,23 @@
     
     protected void bindCommonPaths(CommonPaths paths) {
         attachManager.setPaths(paths);
-        BytemanAttacher bmAttacher = new BytemanAttacher(paths);
-        attachManager.setAttacher(bmAttacher);
     }
     
     protected void unbindCommonPaths(CommonPaths paths) {
         // helper jars don't strictly need unsetting so we don't
         // call setPaths(null)
-        attachManager.setAttacher(null);
     }
     
     protected void bindAgentIpcService(AgentIPCService ipcService) {
         IPCEndpointsManager ipcEndpointsManager = new IPCEndpointsManager(ipcService);
         attachManager.setIpcManager(ipcEndpointsManager);
+        BytemanAttacher bmAttacher = new BytemanAttacher(ipcService);
+        attachManager.setAttacher(bmAttacher);
     }
     
     protected void unbindAgentIpcService(AgentIPCService ipcService) {
         attachManager.setIpcManager(null);
+        attachManager.setAttacher(null);
     }
     
     protected void bindUserNameUtil(UserNameUtil userNameUtil) {
--- a/vm-byteman/agent/src/test/java/com/redhat/thermostat/vm/byteman/agent/internal/BytemanAgentAttachManagerTest.java	Tue Nov 15 15:59:46 2016 -0500
+++ b/vm-byteman/agent/src/test/java/com/redhat/thermostat/vm/byteman/agent/internal/BytemanAgentAttachManagerTest.java	Tue Nov 15 18:18:31 2016 -0500
@@ -61,9 +61,9 @@
 import org.junit.Test;
 import org.mockito.ArgumentCaptor;
 
+import com.redhat.thermostat.agent.ipc.server.AgentIPCService;
 import com.redhat.thermostat.agent.ipc.server.ThermostatIPCCallbacks;
 import com.redhat.thermostat.agent.utils.ProcessChecker;
-import com.redhat.thermostat.shared.config.CommonPaths;
 import com.redhat.thermostat.storage.core.VmId;
 import com.redhat.thermostat.storage.core.WriterID;
 import com.redhat.thermostat.vm.byteman.agent.internal.BytemanAgentAttachManager.FileSystemUtils;
@@ -280,7 +280,7 @@
     
     @SuppressWarnings("unchecked")
     private BytemanAttacher getFailureAttacher() throws Exception {
-        CommonPaths paths = mock(CommonPaths.class);
+        AgentIPCService ipcService = mock(AgentIPCService.class);
         BtmInstallHelper failInstaller = mock(BtmInstallHelper.class);
         when(failInstaller.install(any(String.class),
                                    any(boolean.class),
@@ -288,9 +288,9 @@
                                    any(String.class),
                                    any(int.class),
                                    any(String[].class))).thenThrow(IOException.class);
-        when(paths.getUserIPCConfigurationFile()).thenReturn(mock(File.class));
+        when(ipcService.getConfigurationFile()).thenReturn(mock(File.class));
         ProcessChecker processChecker = mock(ProcessChecker.class);
-        BytemanAttacher failAttacher = new BytemanAttacher(failInstaller, processChecker, paths);
+        BytemanAttacher failAttacher = new BytemanAttacher(failInstaller, processChecker, ipcService);
         return failAttacher;
     }
 
--- a/vm-byteman/agent/src/test/java/com/redhat/thermostat/vm/byteman/agent/internal/BytemanAttacherTest.java	Tue Nov 15 15:59:46 2016 -0500
+++ b/vm-byteman/agent/src/test/java/com/redhat/thermostat/vm/byteman/agent/internal/BytemanAttacherTest.java	Tue Nov 15 18:18:31 2016 -0500
@@ -55,8 +55,8 @@
 import org.junit.Test;
 import org.mockito.ArgumentCaptor;
 
+import com.redhat.thermostat.agent.ipc.server.AgentIPCService;
 import com.redhat.thermostat.agent.utils.ProcessChecker;
-import com.redhat.thermostat.shared.config.CommonPaths;
 import com.redhat.thermostat.vm.byteman.agent.internal.BytemanAttacher.BtmInstallHelper;
 import com.redhat.thermostat.vm.byteman.agent.internal.BytemanAttacher.InstallResult;
 
@@ -74,7 +74,7 @@
             System.err.println("Usage: java BytemanAttacherTest <PID_OF_JVM>");
             System.exit(1);
         }
-        BytemanAttacher attacher = new BytemanAttacher(mock(CommonPaths.class));
+        BytemanAttacher attacher = new BytemanAttacher(mock(AgentIPCService.class));
         BytemanAgentInfo info = attacher.attach("barVmId", Integer.parseInt(args[0]), "fooAgent");
         if (info != null) {
             System.out.println("Byteman agent attached successfully");
@@ -84,17 +84,17 @@
         }
     }
     
-    private CommonPaths paths;
+    private AgentIPCService ipcService;
     private String filePath;
     private ProcessChecker processChecker;
     
     @Before
-    public void setup() {
+    public void setup() throws Exception {
         filePath = "/path/to/run/data";
-        paths = mock(CommonPaths.class);
+        ipcService = mock(AgentIPCService.class);
         File mockFile = mock(File.class);
         when(mockFile.getAbsolutePath()).thenReturn(filePath);
-        when(paths.getUserIPCConfigurationFile()).thenReturn(mockFile);
+        when(ipcService.getConfigurationFile()).thenReturn(mockFile);
 
         processChecker = mock(ProcessChecker.class);
         when(processChecker.exists(anyInt())).thenReturn(false);
@@ -106,7 +106,7 @@
         when(installer.install(any(String.class), any(boolean.class), any(boolean.class), any(String.class), any(int.class), any(String[].class)))
             .thenReturn(new InstallResult(8888, true));
         ArgumentCaptor<String[]> propsCaptor = ArgumentCaptor.forClass(String[].class);
-        BytemanAttacher attacher = new BytemanAttacher(installer, processChecker, paths);
+        BytemanAttacher attacher = new BytemanAttacher(installer, processChecker, ipcService);
         attacher.attach("testVmId", 9999, "fooAgent");
         verify(installer).install(eq(Integer.toString(9999)), eq(true), eq(false), eq((String)null), any(int.class), propsCaptor.capture());
         Map<String, String> properties = buildMapFromStringProps(propsCaptor.getValue());
@@ -134,7 +134,7 @@
         BtmInstallHelper installer = mock(BtmInstallHelper.class);
         when(installer.install(any(String.class), any(boolean.class), any(boolean.class), any(String.class), any(int.class), any(String[].class)))
             .thenReturn(new InstallResult(port, true));
-        BytemanAttacher attacher = new BytemanAttacher(installer, mock(ProcessChecker.class), paths);
+        BytemanAttacher attacher = new BytemanAttacher(installer, mock(ProcessChecker.class), ipcService);
         
         int somePid = 3222;
         BytemanAgentInfo info = attacher.attach("someVmId", somePid, "someAgent");
@@ -162,7 +162,7 @@
         IOException ioe = new IOException(exceptionMsg);
         when(installer.install(any(String.class), any(Boolean.class), any(Boolean.class), any(String.class), any(Integer.class), any(String[].class))).thenThrow(ioe);
 
-        BytemanAttacher attacher = new BytemanAttacher(installer, processChecker, paths);
+        BytemanAttacher attacher = new BytemanAttacher(installer, processChecker, ipcService);
         BytemanAgentInfo info = attacher.attach("someVmId", -1, "someAgent");
         assertNotNull(info);
         assertTrue(info.isAttachFailedNoSuchProcess());
--- a/vm-byteman/agent/src/test/java/com/redhat/thermostat/vm/byteman/agent/internal/BytemanRequestReceiverTest.java	Tue Nov 15 15:59:46 2016 -0500
+++ b/vm-byteman/agent/src/test/java/com/redhat/thermostat/vm/byteman/agent/internal/BytemanRequestReceiverTest.java	Tue Nov 15 18:18:31 2016 -0500
@@ -57,6 +57,7 @@
 import org.junit.Test;
 import org.mockito.ArgumentCaptor;
 
+import com.redhat.thermostat.agent.ipc.server.AgentIPCService;
 import com.redhat.thermostat.common.command.Request;
 import com.redhat.thermostat.common.command.Request.RequestType;
 import com.redhat.thermostat.common.command.Response;
@@ -216,8 +217,17 @@
         BytemanRequestReceiver receiver = new BytemanRequestReceiver(attachManager);
         CommonPaths paths = mock(CommonPaths.class);
         receiver.bindCommonPaths(paths);
+        verify(attachManager).setPaths(paths);
+    }
+    
+    @Test
+    public void testBindAgentIPCService() {
+        BytemanAgentAttachManager attachManager = mock(BytemanAgentAttachManager.class);
+        BytemanRequestReceiver receiver = new BytemanRequestReceiver(attachManager);
+        AgentIPCService ipcService = mock(AgentIPCService.class);
+        receiver.bindAgentIpcService(ipcService);
+        verify(attachManager).setIpcManager(any(IPCEndpointsManager.class));
         verify(attachManager).setAttacher(any(BytemanAttacher.class));
-        verify(attachManager).setPaths(paths);
     }
 
     @SuppressWarnings("unchecked")