1 /* 2 * Copyright (C) 2017 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 package com.android.tradefed.config; 17 18 import com.android.tradefed.log.LogUtil.CLog; 19 import com.android.tradefed.sandbox.ISandbox; 20 import com.android.tradefed.sandbox.SandboxConfigDump.DumpCmd; 21 import com.android.tradefed.sandbox.SandboxConfigUtil; 22 import com.android.tradefed.sandbox.SandboxConfigurationException; 23 import com.android.tradefed.util.FileUtil; 24 import com.android.tradefed.util.IRunUtil; 25 import com.android.tradefed.util.keystore.IKeyStoreClient; 26 27 import java.io.File; 28 import java.io.IOException; 29 import java.util.Map; 30 31 /** Special Configuration factory to handle creation of configurations for Sandboxing purpose. */ 32 public class SandboxConfigurationFactory extends ConfigurationFactory { 33 34 private static SandboxConfigurationFactory sInstance = null; 35 36 /** Get the singleton {@link IConfigurationFactory} instance. */ 37 public static SandboxConfigurationFactory getInstance() { 38 if (sInstance == null) { 39 sInstance = new SandboxConfigurationFactory(); 40 } 41 return sInstance; 42 } 43 44 /** {@inheritDoc} */ 45 @Override 46 protected ConfigurationDef getConfigurationDef( 47 String name, boolean isGlobal, Map<String, String> templateMap) 48 throws ConfigurationException { 49 // TODO: Extend ConfigurationDef to possibly create a different IConfiguration type and 50 // handle more elegantly the parent/subprocess incompatibilities. 51 ConfigurationDef def = new ConfigurationDef(name); 52 new ConfigLoader(isGlobal).loadConfiguration(name, def, null, templateMap); 53 return def; 54 } 55 56 /** 57 * Create a {@link IConfiguration} based on the command line and sandbox provided. 58 * 59 * @param args the command line for the run. 60 * @param keyStoreClient the {@link IKeyStoreClient} where to load the key from. 61 * @param sandbox the {@link ISandbox} used for the run. 62 * @param runUtil the {@link IRunUtil} to run commands. 63 * @return a {@link IConfiguration} valid for the sandbox. 64 * @throws ConfigurationException 65 */ 66 public IConfiguration createConfigurationFromArgs( 67 String[] args, IKeyStoreClient keyStoreClient, ISandbox sandbox, IRunUtil runUtil) 68 throws ConfigurationException { 69 IConfiguration config = null; 70 File xmlConfig = null; 71 File globalConfig = null; 72 try { 73 runUtil.unsetEnvVariable(GlobalConfiguration.GLOBAL_CONFIG_VARIABLE); 74 // Dump the NON_VERSIONED part of the configuration against the current TF and not the 75 // sandboxed environment. 76 globalConfig = SandboxConfigUtil.dumpFilteredGlobalConfig(); 77 xmlConfig = 78 SandboxConfigUtil.dumpConfigForVersion( 79 createClasspath(), 80 runUtil, 81 args, 82 DumpCmd.NON_VERSIONED_CONFIG, 83 globalConfig); 84 // Get the non version part of the configuration in order to do proper allocation 85 // of devices and such. 86 config = 87 super.createConfigurationFromArgs( 88 new String[] {xmlConfig.getAbsolutePath()}, null, keyStoreClient); 89 // Reset the command line to the original one. 90 config.setCommandLine(args); 91 config.setConfigurationObject(Configuration.SANDBOX_TYPE_NAME, sandbox); 92 } catch (SandboxConfigurationException e) { 93 // Handle the thin launcher mode: Configuration does not exists in parent version yet. 94 config = sandbox.createThinLauncherConfig(args, keyStoreClient, runUtil, globalConfig); 95 if (config == null) { 96 // Rethrow the original exception. 97 CLog.e(e); 98 throw e; 99 } 100 } catch (IOException e) { 101 CLog.e(e); 102 throw new ConfigurationException("Failed to dump global config.", e); 103 } catch (ConfigurationException e) { 104 CLog.e(e); 105 throw e; 106 } finally { 107 if (config == null) { 108 // In case of error, tear down the sandbox. 109 sandbox.tearDown(); 110 } 111 FileUtil.deleteFile(globalConfig); 112 FileUtil.deleteFile(xmlConfig); 113 } 114 return config; 115 } 116 117 /** Returns the classpath of the current running Tradefed. */ 118 private String createClasspath() throws ConfigurationException { 119 // Get the classpath property. 120 String classpathStr = System.getProperty("java.class.path"); 121 if (classpathStr == null) { 122 throw new ConfigurationException( 123 "Could not find the classpath property: java.class.path"); 124 } 125 return classpathStr; 126 } 127 } 128