Home | History | Annotate | Download | only in config
      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