View Javadoc
1   /*
2    * Copyright (C) 2007-2012 Argeo GmbH
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 org.argeo.maintenance.backup.vfs;
17  
18  import java.io.ByteArrayOutputStream;
19  import java.util.HashMap;
20  import java.util.Map;
21  
22  import org.apache.commons.exec.CommandLine;
23  import org.apache.commons.exec.DefaultExecutor;
24  import org.apache.commons.exec.ExecuteException;
25  import org.apache.commons.exec.ExecuteStreamHandler;
26  import org.apache.commons.exec.Executor;
27  import org.apache.commons.exec.PumpStreamHandler;
28  import org.apache.commons.io.IOUtils;
29  import org.apache.commons.logging.Log;
30  import org.apache.commons.logging.LogFactory;
31  import org.apache.commons.vfs2.FileContent;
32  import org.apache.commons.vfs2.FileObject;
33  import org.argeo.maintenance.MaintenanceException;
34  
35  /**
36   * Runs an OS command and save its standard output as a file. Typically used for
37   * MySQL or OpenLDAP dumps.
38   */
39  public class OsCallBackup extends AbstractAtomicBackup {
40  	private final static Log log = LogFactory.getLog(OsCallBackup.class);
41  
42  	private String command;
43  	private Map<String, String> variables = new HashMap<String, String>();
44  	private Executor executor = new DefaultExecutor();
45  
46  	private Map<String, String> environment = new HashMap<String, String>();
47  
48  	/** Name of the sudo user, root if "", not sudo if null */
49  	private String sudo = null;
50  
51  	public OsCallBackup() {
52  	}
53  
54  	public OsCallBackup(String name) {
55  		super(name);
56  	}
57  
58  	public OsCallBackup(String name, String command) {
59  		super(name);
60  		this.command = command;
61  	}
62  
63  	@Override
64  	public void writeBackup(FileObject targetFo) {
65  		String commandToUse = command;
66  
67  		// sudo
68  		if (sudo != null) {
69  			if (sudo.equals(""))
70  				commandToUse = "sudo " + commandToUse;
71  			else
72  				commandToUse = "sudo -u " + sudo + " " + commandToUse;
73  		}
74  
75  		CommandLine commandLine = CommandLine.parse(commandToUse, variables);
76  		ByteArrayOutputStream errBos = new ByteArrayOutputStream();
77  		if (log.isTraceEnabled())
78  			log.trace(commandLine.toString());
79  
80  		try {
81  			// stdout
82  			FileContent targetContent = targetFo.getContent();
83  			// stderr
84  			ExecuteStreamHandler streamHandler = new PumpStreamHandler(targetContent.getOutputStream(), errBos);
85  			executor.setStreamHandler(streamHandler);
86  			executor.execute(commandLine, environment);
87  		} catch (ExecuteException e) {
88  			byte[] err = errBos.toByteArray();
89  			String errStr = new String(err);
90  			throw new MaintenanceException("Process " + commandLine + " failed (" + e.getExitValue() + "): " + errStr, e);
91  		} catch (Exception e) {
92  			byte[] err = errBos.toByteArray();
93  			String errStr = new String(err);
94  			throw new MaintenanceException("Process " + commandLine + " failed: " + errStr, e);
95  		} finally {
96  			IOUtils.closeQuietly(errBos);
97  		}
98  	}
99  
100 	public void setCommand(String command) {
101 		this.command = command;
102 	}
103 
104 	protected String getCommand() {
105 		return command;
106 	}
107 
108 	/**
109 	 * A reference to the environment variables that will be passed to the
110 	 * process. Empty by default.
111 	 */
112 	protected Map<String, String> getEnvironment() {
113 		return environment;
114 	}
115 
116 	protected Map<String, String> getVariables() {
117 		return variables;
118 	}
119 
120 	public void setVariables(Map<String, String> variables) {
121 		this.variables = variables;
122 	}
123 
124 	public void setExecutor(Executor executor) {
125 		this.executor = executor;
126 	}
127 
128 	public void setSudo(String sudo) {
129 		this.sudo = sudo;
130 	}
131 
132 }