[java-identity-provider] 07/11: IDP-1499 New V4 Installer: First cut of install task
Rod Widdowson
rdw at steadingsoftware.com
Fri Oct 11 11:08:30 EDT 2019
This is an automated email from the git hooks/post-receive script.
rdw pushed a commit to branch master
in repository java-identity-provider.
View the commit online:
http://git.shibboleth.net/view/?p=java-identity-provider.git;a=commit;h=071ea3c9363e968c1c58d42b8c48f0e50ce84ad8
commit 071ea3c9363e968c1c58d42b8c48f0e50ce84ad8
Author: Rod Widdowson <rdw at steadingsoftware.com>
AuthorDate: Fri Oct 11 14:05:48 2019 +0100
IDP-1499 New V4 Installer: First cut of install task
https://issues.shibboleth.net/jira/browse/IDP-1499
Includes
- Most of the install work (metdata, reprotect still tbd)
- Separate InstallProperties (extensible) from CurrentInstallState (not)
- Silly test program to drive this
- Eclipse-local debugging
---
idp-installer/pom.xml | 18 +-
.../net/shibboleth/idp/installer/impl/AntRun.java | 74 ++++++
.../shibboleth/idp/installer/impl/BuildWar.java | 16 +-
...opyDistributions.java => CopyDistribution.java} | 52 ++--
.../idp/installer/impl/CurrentInstallState.java | 115 +++++++++
.../idp/installer/impl/InstallerProperties.java | 113 ++++-----
.../idp/installer/impl/InstallerSupport.java | 7 +-
.../idp/installer/impl/KeyManagement.java | 85 +++++--
.../idp/installer/impl/PropertiesWithComments.java | 37 ++-
.../shibboleth/idp/installer/impl/V4Install.java | 266 +++++++++++++++++++++
.../shibboleth/idp/installer/{ => impl}/Test.java | 0
11 files changed, 666 insertions(+), 117 deletions(-)
diff --git a/idp-installer/pom.xml b/idp-installer/pom.xml
index b27c49f..998811e 100644
--- a/idp-installer/pom.xml
+++ b/idp-installer/pom.xml
@@ -47,12 +47,6 @@
<scope>compile</scope><!-- normally runtime -->
</dependency>
-<!-- <dependency>
- <groupId>ch.qos.logback</groupId>
- <artifactId>logback-classic</artifactId>
- <scope>compile</scope>
- </dependency> -->
-
<dependency>
<groupId>${opensaml.groupId}</groupId>
<artifactId>opensaml-core</artifactId>
@@ -113,7 +107,17 @@
<artifactId>opensaml-saml-impl</artifactId>
<scope>test</scope>
</dependency>
-
+ <dependency>
+ <groupId>org.bouncycastle</groupId>
+ <artifactId>bcprov-jdk15on</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.bouncycastle</groupId>
+ <artifactId>bcpkix-jdk15on</artifactId>
+ <scope>test</scope>
+ </dependency>
+
<!-- Managed Dependencies -->
</dependencies>
diff --git a/idp-installer/src/main/java/net/shibboleth/idp/installer/impl/AntRun.java b/idp-installer/src/main/java/net/shibboleth/idp/installer/impl/AntRun.java
new file mode 100644
index 0000000..f3729f6
--- /dev/null
+++ b/idp-installer/src/main/java/net/shibboleth/idp/installer/impl/AntRun.java
@@ -0,0 +1,74 @@
+/*
+ * Licensed to the University Corporation for Advanced Internet Development,
+ * Inc. (UCAID) under one or more contributor license agreements. See the
+ * NOTICE file distributed with this work for additional information regarding
+ * copyright ownership. The UCAID licenses this file to You under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package net.shibboleth.idp.installer.impl;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import net.shibboleth.utilities.java.support.component.ComponentInitializationException;
+
+/**
+ * code to tode over durig testing.
+ */
+public final class AntRun {
+
+ /** hidden Constructor. */
+ private AntRun() {}
+
+ /** simulate the ant tasks.
+ * @param args what
+ * @throws ComponentInitializationException
+ */
+ public static void main(final String[] args) throws ComponentInitializationException {
+ final Logger log = LoggerFactory.getLogger(AntRun.class);
+ if (args.length !=1) {
+ log.error("One Parameter only {}", (Object[]) args);
+ return;
+ }
+ boolean copyInstall = false;
+ boolean doInstall = false;
+ if ("install".equals(args[0])) {
+ copyInstall = true;
+ doInstall = true;
+ } else if ("install-nocopy".equals(args[0])) {
+ doInstall = true;
+ } else if (!"build-war".equals(args[0])) {
+ log.error("Parameter must be \"install\", \"install-nocopy\" or \"build-war\" was \"{}\"", args[0]);
+ return;
+ }
+ final InstallerProperties ip = new InstallerProperties(!copyInstall);
+ ip.initialize();
+ final CurrentInstallState is = new CurrentInstallState(ip);
+ is.initialize();
+
+ if (copyInstall) {
+ final CopyDistribution dist = new CopyDistribution(ip, is);
+ dist.execute();
+ }
+
+ if (doInstall) {
+ final V4Install inst = new V4Install(ip, is);
+ inst.execute();
+ }
+
+ final BuildWar bw = new BuildWar(ip, is);
+ bw.execute();
+
+ }
+
+}
diff --git a/idp-installer/src/main/java/net/shibboleth/idp/installer/impl/BuildWar.java b/idp-installer/src/main/java/net/shibboleth/idp/installer/impl/BuildWar.java
index 53ab077..9537fe2 100644
--- a/idp-installer/src/main/java/net/shibboleth/idp/installer/impl/BuildWar.java
+++ b/idp-installer/src/main/java/net/shibboleth/idp/installer/impl/BuildWar.java
@@ -26,6 +26,9 @@ import org.apache.tools.ant.taskdefs.Jar;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import net.shibboleth.utilities.java.support.component.AbstractInitializableComponent;
+import net.shibboleth.utilities.java.support.component.ComponentSupport;
+
/** Code to build the war file during an install or on request.<p/>
* This code<ul>
* <li>Deletes any old detritus</li>
@@ -36,7 +39,7 @@ import org.slf4j.LoggerFactory;
* <li>Deletes webapp.tmp</li>
* </ul>
*/
-public class BuildWar {
+public class BuildWar extends AbstractInitializableComponent {
/** Log. */
private final Logger log = LoggerFactory.getLogger(BuildWar.class);
@@ -44,11 +47,18 @@ public class BuildWar {
/** Properties for the job. */
private final InstallerProperties installerProps;
+ /** Current Install. */
+ private final CurrentInstallState currentState;
+
/** Constructor.
* @param props The environment for the work.
+ * @param installState Where we are right now.
*/
- public BuildWar(final InstallerProperties props) {
+ public BuildWar(final InstallerProperties props, final CurrentInstallState installState) {
+ ComponentSupport.ifNotInitializedThrowUninitializedComponentException(props);
+ ComponentSupport.ifNotInitializedThrowUninitializedComponentException(installState);
installerProps = props;
+ currentState = installState;
}
/** Method to do the work of building the war.
@@ -58,7 +68,7 @@ public class BuildWar {
final Path target = installerProps.getTargetDir();
final Path warFile = target.resolve("war").resolve("idp.war");
- log.info("Rebuilding {}", warFile.toAbsolutePath());
+ log.info("Rebuilding {}, Version", warFile.toAbsolutePath(), currentState.getInstalledVersion());
try {
DeletingVisitor.deleteTree(target.resolve("webpapp"));
} catch (final IOException e) {
diff --git a/idp-installer/src/main/java/net/shibboleth/idp/installer/impl/CopyDistributions.java b/idp-installer/src/main/java/net/shibboleth/idp/installer/impl/CopyDistribution.java
similarity index 78%
rename from idp-installer/src/main/java/net/shibboleth/idp/installer/impl/CopyDistributions.java
rename to idp-installer/src/main/java/net/shibboleth/idp/installer/impl/CopyDistribution.java
index 48a377d..bff7c1d 100644
--- a/idp-installer/src/main/java/net/shibboleth/idp/installer/impl/CopyDistributions.java
+++ b/idp-installer/src/main/java/net/shibboleth/idp/installer/impl/CopyDistribution.java
@@ -20,41 +20,49 @@ package net.shibboleth.idp.installer.impl;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
+import java.text.SimpleDateFormat;
import java.time.Instant;
+import java.util.Date;
+
+import javax.annotation.Nonnull;
import org.apache.tools.ant.BuildException;
import org.apache.tools.ant.taskdefs.Copy;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import net.shibboleth.utilities.java.support.component.AbstractInitializableComponent;
+import net.shibboleth.utilities.java.support.component.ComponentSupport;
+
/**
* Copy the distribution to its final location.
*/
-public final class CopyDistributions {
+public final class CopyDistribution extends AbstractInitializableComponent {
/** Log. */
- private final Logger log = LoggerFactory.getLogger(CopyDistributions.class);
+ private final Logger log = LoggerFactory.getLogger(CopyDistribution.class);
/** Properties for the job. */
- private final InstallerProperties installerProps;
+ @Nonnull private final InstallerProperties installerProps;
/** Constructor.
* @param props The environment for the work.
+ * @param installState Where we are right now.
*/
- public CopyDistributions(final InstallerProperties props) {
+ public CopyDistribution(@Nonnull final InstallerProperties props, @Nonnull final CurrentInstallState installState) {
+ ComponentSupport.ifNotInitializedThrowUninitializedComponentException(props);
+ ComponentSupport.ifNotInitializedThrowUninitializedComponentException(installState);
installerProps = props;
}
/** Copy the distribution from the dstribution to its new location.
- * @param ip what drives the install.
* @throws BuildException if badness occurs
*/
- public void execute(final InstallerProperties ip) throws BuildException {
+ public void execute() throws BuildException {
backupOld();
deleteOld();
copyDist();
copyBinDocSystem();
- createUserFolders();
}
/** Helper for the {@link #backupOld(InstallerProperties)} method.
@@ -73,7 +81,8 @@ public final class CopyDistributions {
* @throws BuildException if badness occurs
*/
protected void backupOld() throws BuildException {
- final Path backup = installerProps.getTargetDir().resolve("Old-" + Instant.now().toString());
+ final SimpleDateFormat fmt = new SimpleDateFormat("'old-'yyyy-MM-dd-HH-mm-ss");
+ final Path backup = installerProps.getTargetDir().resolve(fmt.format(Date.from(Instant.now())));
InstallerSupport.createDirectory(backup);
backup(installerProps.getTargetDir().resolve("edit-webapp"), backup.resolve("edit-webapp"));
backup(installerProps.getTargetDir().resolve("doc"), backup.resolve("doc"));
@@ -85,9 +94,10 @@ public final class CopyDistributions {
*/
private void delete(final Path what) {
if (!Files.exists(what)) {
- log.debug("{} doesn't exist, ignoring", what);
- } else if (Files.isDirectory(what)) {
- throw new BuildException("Corrupt install " + what + " is not a directory");
+ log.debug("{} doesn't exist, nothing to delete", what);
+ } else if (!Files.isDirectory(what)) {
+ log.error("Corrupt install {} is not a directory", what);
+ throw new BuildException("Corrupt install - not a directory");
} else {
log.debug("Deleteing {} ", what);
try {
@@ -108,7 +118,7 @@ public final class CopyDistributions {
delete(installerProps.getTargetDir().resolve("doc"));
final Path system = installerProps.getTargetDir().resolve("system");
if (Files.exists(system)) {
- log.debug("Clearing {} readonly (id Windows)", system);
+ log.debug("Clearing {} readonly (if Windows)", system);
InstallerSupport.setReadOnly(system, false);
}
delete(system);
@@ -136,7 +146,7 @@ public final class CopyDistributions {
protected void copyDist() {
final Path dist = installerProps.getTargetDir().resolve("dist");
InstallerSupport.createDirectory(dist);
- final Path src = installerProps.getSourceDir().resolve("dist");
+ final Path src = installerProps.getSourceDir();
if (!Files.exists(src)) {
log.error("Source distribution {} not found", src);
throw new BuildException("Source distribution not found");
@@ -156,20 +166,4 @@ public final class CopyDistributions {
distCopy(installerProps.getSourceDir(), installerProps.getTargetDir(), "doc");
distCopy(installerProps.getSourceDir(), installerProps.getTargetDir(), "system");
}
-
- /** Create (if they do not exist) the user editable folders, suitable for
- * later population during update or install.
- * @throws BuildException if badness occurs
- */
- protected void createUserFolders() {
- final Path target = installerProps.getTargetDir();
- InstallerSupport.createDirectory(target.resolve("conf"));
- InstallerSupport.createDirectory(target.resolve("credentials"));
- InstallerSupport.createDirectory(target.resolve("flows"));
- InstallerSupport.createDirectory(target.resolve("logs"));
- InstallerSupport.createDirectory(target.resolve("messages"));
- InstallerSupport.createDirectory(target.resolve("metadata"));
- InstallerSupport.createDirectory(target.resolve("views"));
- InstallerSupport.createDirectory(target.resolve("war"));
- }
}
diff --git a/idp-installer/src/main/java/net/shibboleth/idp/installer/impl/CurrentInstallState.java b/idp-installer/src/main/java/net/shibboleth/idp/installer/impl/CurrentInstallState.java
new file mode 100644
index 0000000..7eb918b
--- /dev/null
+++ b/idp-installer/src/main/java/net/shibboleth/idp/installer/impl/CurrentInstallState.java
@@ -0,0 +1,115 @@
+/*
+ * Licensed to the University Corporation for Advanced Internet Development,
+ * Inc. (UCAID) under one or more contributor license agreements. See the
+ * NOTICE file distributed with this work for additional information regarding
+ * copyright ownership. The UCAID licenses this file to You under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package net.shibboleth.idp.installer.impl;
+
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.util.Properties;
+
+import javax.annotation.Nullable;
+
+import org.apache.tools.ant.BuildException;
+import org.slf4j.LoggerFactory;
+
+import net.shibboleth.utilities.java.support.component.AbstractInitializableComponent;
+import net.shibboleth.utilities.java.support.component.ComponentInitializationException;
+
+/** Tells the installers about the current install state. */
+final class CurrentInstallState extends AbstractInitializableComponent {
+
+ /** Where we are installing to. */
+ private final Path targetDir;
+
+ /** Whether the IdP properties file exists.*/
+ private boolean idpPropertiesPresent;
+
+ /** Whether the LDAP properties file exists.*/
+ private boolean ldapPropertiesPresent;
+
+ /** Old Version. */
+ private String oldVersion;
+
+ /** Constructor.
+ * @param installerProps the installer situation.
+ */
+ protected CurrentInstallState(final InstallerProperties installerProps) {
+ targetDir = installerProps.getTargetDir();
+ }
+
+ /** {@inheritDoc} */
+ protected void doInitialize() throws ComponentInitializationException {
+ super.doInitialize();
+ idpPropertiesPresent = Files.exists(targetDir.resolve("conf").resolve("idp.properties"));
+ ldapPropertiesPresent = Files.exists(targetDir.resolve("conf").resolve("ldap.properties"));
+ final Path conf = targetDir.resolve("conf");
+ if (!Files.exists(conf.resolve("relying-party.xml"))) {
+ // No relying party, no install
+ oldVersion = null;
+ return;
+ }
+
+ if (!Files.exists(conf.resolve("idp.properties"))) {
+ throw new ComponentInitializationException("V2 Installation detected");
+ }
+
+ final Path currentInstall = targetDir.resolve("dist").resolve(InstallerSupport.VERSION_NAME);
+ if (!Files.exists(currentInstall)) {
+ oldVersion= "3";
+ return;
+ }
+ final Properties vers = new Properties(1);
+ try {
+ vers.load(new FileInputStream(currentInstall.toFile()));
+ } catch (final IOException e) {
+ LoggerFactory.getLogger(CurrentInstallState.class).
+ error("Could not load {}", currentInstall.toAbsolutePath(), e);
+ throw new ComponentInitializationException(e);
+ }
+ oldVersion = vers.getProperty(InstallerSupport.VERSION_NAME);
+ if (null == oldVersion) {
+ LoggerFactory.getLogger(CurrentInstallState.class).
+ error("Failed loading {}", currentInstall.toAbsolutePath());
+ throw new ComponentInitializationException("File " + InstallerSupport.VERSION_NAME +
+ " did not contain property " + InstallerSupport.VERSION_NAME);
+ }
+ }
+
+ /** What is the installer version.
+ * @return "3" for a V3 install, null for a new install or the value we write during last install.
+ * @throws BuildException if we find an inconsiostency
+ */
+ @Nullable protected String getInstalledVersion() {
+ return oldVersion;
+ }
+
+ /** Was idp.properties present in the target file when we started the install?
+ * @return if it was.
+ */
+ protected boolean isIdPPropertiesPresent() {
+ return idpPropertiesPresent;
+ }
+
+ /** Was ldapp.properties present in the target file when we started the install?
+ * @return if it was.
+ */
+ protected boolean isLDAPPropertiesPresent() {
+ return ldapPropertiesPresent;
+ }
+}
diff --git a/idp-installer/src/main/java/net/shibboleth/idp/installer/impl/InstallerProperties.java b/idp-installer/src/main/java/net/shibboleth/idp/installer/impl/InstallerProperties.java
index 62c2671..b2c917a 100644
--- a/idp-installer/src/main/java/net/shibboleth/idp/installer/impl/InstallerProperties.java
+++ b/idp-installer/src/main/java/net/shibboleth/idp/installer/impl/InstallerProperties.java
@@ -35,6 +35,7 @@ import javax.annotation.Nullable;
import org.apache.tools.ant.BuildException;
import org.apache.tools.ant.input.DefaultInputHandler;
import org.apache.tools.ant.input.InputRequest;
+import org.apache.tools.ant.launch.Launcher;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -67,12 +68,9 @@ import net.shibboleth.utilities.java.support.component.ComponentSupport;
* services.merge.properties: The name of a property file to merge with services.properties</li>
* <li> if idp.is.V2 is set, then this file should contain a line setting
* idp.service.relyingparty.resources=shibboleth.LegacyRelyingPartyResolverResources</li></ul>
- * <li> nameid.merge.properties: The name of a property file to merge with saml-nameid.properties.
- * If idp.is.V2 is set, then this file should contain lines enabling legacy nameid generation
* <li> idp.property.file: The name of a property file to fill in some or all of the above.
This file is deleted after processing.</li>
* <li> idp.no.tidy: Do not delete the two above files (debug only)</li>
- * <li> idp.jetty.config: Copy jetty configuration from distribution (Unsupported)</li>
* <li> ldap.merge.properties: The name of a property file to merge with ldap.properties</li>
* <li> idp.conf.filemode (default "600"): The permissions to mark the files in conf with (UNIX only).</li>
* <li> idp.conf.credentials.filemode (default "600"): The permissions to mark the files in conf with (UNIX only).</li>
@@ -82,11 +80,17 @@ import net.shibboleth.utilities.java.support.component.ComponentSupport;
public class InstallerProperties extends AbstractInitializableComponent {
/** The base directory, inherited and shared with ant. */
- public static final String ANT_BASE_DIR = "ant.home";
+ public static final String ANT_BASE_DIR = Launcher.ANTHOME_PROPERTY;
/** The name of a property file to fill in some or all of the above. This file is deleted after processing. */
public static final String PROPERTY_SOURCE_FILE = "idp.property.file";
+ /** The name of a property file to merge with idp.properties. */
+ public static final String IDP_PROPERTIES_MERGE = "idp.merge.properties";
+
+ /** The name of a property file to merge with ldap.properties. */
+ public static final String LDAP_PROPERTIES_MERGE = "ldap.merge.properties";
+
/** Where to install to. Default is basedir */
public static final String TARGET_DIR = "idp.target.dir";
@@ -114,9 +118,12 @@ public class InstallerProperties extends AbstractInitializableComponent {
/** The sealer alias to use. */
public static final String SEALER_ALIAS = "idp.sealer.alias";
- /** The sealer alias to use. */
+ /** The the key size to generate. */
public static final String KEY_SIZE = "idp.keysize";
+ /** Whether to tidy up after ourselves. */
+ public static final String NO_TIDY = "idp.no.tidy";
+
/** Class logger. */
@Nonnull private final Logger log = LoggerFactory.getLogger(InstallerProperties.class);
@@ -126,9 +133,6 @@ public class InstallerProperties extends AbstractInitializableComponent {
/** The properties driving the install. */
@NonnullAfterInit private Properties installerProperties;
- /** The file specified in the system file idp.property.file (if present). */
- @Nullable private File idpPropertyFile;
-
/** The target Directory. */
private Path targetDir;
@@ -144,11 +148,6 @@ public class InstallerProperties extends AbstractInitializableComponent {
/** The entity ID. */
private String entityID;
- /** Old Version. */
- private String oldVersion;
- /** Have done the work aroun the old version ?*/
- private boolean oldVersionDefinitive;
-
/** Hostname. */
private String hostname;
@@ -167,8 +166,8 @@ public class InstallerProperties extends AbstractInitializableComponent {
/** Key Size. (for signing, encryption and backchannel). */
private int keySize;
- /** Whether the properties file exists.*/
- private boolean idpPropertiesPresent;
+ /** whether to tidy up. */
+ private boolean tidy = true;
/**
* Constructor.
@@ -195,6 +194,7 @@ public class InstallerProperties extends AbstractInitializableComponent {
throw new ComponentInitializationException(ANT_BASE_DIR + " must exist");
}
log.debug("base dir {}", baseDir);
+ tidy = installerProperties.get(NO_TIDY) == null;
if (installerProperties.containsKey(PROPERTY_SOURCE_FILE)) {
final Path file = baseDir.resolve(installerProperties.getProperty(PROPERTY_SOURCE_FILE));
@@ -204,14 +204,17 @@ public class InstallerProperties extends AbstractInitializableComponent {
}
log.debug("Loading properties from {}", file.toAbsolutePath());
- idpPropertyFile = file.toFile();
+ /** The file specified in the system file idp.property.file (if present). */
+ final File idpPropertyFile = file.toFile();
try {
installerProperties.load(new FileInputStream(idpPropertyFile));
} catch (final IOException e) {
log.error("Could not load {}", file.toAbsolutePath(), e);
throw new ComponentInitializationException(e);
}
- idpPropertyFile.deleteOnExit();
+ if (tidy) {
+ idpPropertyFile.deleteOnExit();
+ }
}
String value = installerProperties.getProperty(NO_PROMPT);
@@ -219,7 +222,7 @@ public class InstallerProperties extends AbstractInitializableComponent {
if (needSourceDir) {
value = getValue(SOURCE_DIR, "Source (Distribution) Directory (press <enter> to accept default):",
- () -> antBase);
+ () -> baseDir.toString());
srcDir = Path.of(value);
log.debug("Source directory {}", srcDir.toAbsolutePath());
}
@@ -229,7 +232,6 @@ public class InstallerProperties extends AbstractInitializableComponent {
} else {
keySize = Integer.parseInt(installerProperties.getProperty(KEY_SIZE));
}
- idpPropertiesPresent = Files.exists(getTargetDir().resolve("conf").resolve("idp.properties"));
}
/** Lookup a property. If it isn't defined then ask the user (if we are allowed)
@@ -312,43 +314,6 @@ public class InstallerProperties extends AbstractInitializableComponent {
return srcDir;
}
- /** What is the installer version.
- * @return "3" for a V3 install, null for a new install or the value we write during last install.
- */
- @Nullable public String getInstallerVersion() {
- if (oldVersionDefinitive) {
- return oldVersion;
- }
- oldVersionDefinitive = true;
- final Path conf = getTargetDir().resolve("conf");
- if (!Files.exists(conf.resolve("relying-party.xml"))) {
- // No relying party, no install
- oldVersion = null;
- return null;
- }
- if (!Files.exists(conf.resolve("idp.properties"))) {
- throw new BuildException("V2 Installation detected");
- }
-
- final Path currentInstall = getTargetDir().resolve("dist").resolve(InstallerSupport.VERSION_NAME);
- if (!Files.exists(currentInstall)) {
- oldVersion= "3";
- return oldVersion;
- }
- final Properties vers = new Properties(1);
- try {
- vers.load(new FileInputStream(currentInstall.toFile()));
- } catch (final IOException e) {
- log.error("Could not load {}", currentInstall.toAbsolutePath(), e);
- throw new BuildException(e);
- }
- oldVersion = vers.getProperty(InstallerSupport.VERSION_NAME);
- if (null == oldVersion) {
- throw new BuildException("File " + InstallerSupport.VERSION_NAME +
- " did not contain property " + InstallerSupport.VERSION_NAME);
- }
- return oldVersion;
- }
/** Get the host name for this install. Defaults to information pulled from the network.
* @return the host name.*/
@@ -498,10 +463,38 @@ public class InstallerProperties extends AbstractInitializableComponent {
return keySize;
}
- /** Was idp.properties present in the target file when we started the install?
- * @return if it was.
+ /** Get the property file as a File, or null if it doesn't exist.
+ * Also delete it at the end if we are deleting.
+ * @param propName the name to lookup;
+ * @return null if the property is not provided a {@link File} otherwise
+ * @throws BuildException if the property is supplied but the file doesn't exist.
+ */
+ private File getMergePropertiesFile(final String propName) throws BuildException {
+ final String propValue = installerProperties.getProperty(propName);
+ if (propValue == null) {
+ return null;
+ }
+ final Path path = baseDir.resolve(propValue);
+ if (!Files.exists(path)) {
+ log.error("Could not find specified property file {}", path );
+ throw new BuildException("Property file not found");
+ }
+ return path.toFile();
+ }
+
+ /** Get the file pointed to by {@link #IDP_PROPERTIES_MERGE}.
+ * @return the file or null if it wasn't specified
+ * @throws BuildException if the property is supplied but the file doesn't exist.
+ */
+ public File getIdPMergePropertiesFile() throws BuildException {
+ return getMergePropertiesFile(IDP_PROPERTIES_MERGE);
+ }
+
+ /** Get the file pointed to by {@link #LDAP_PROPERTIES_MERGE}.
+ * @return the file or null if it wasn't specified
+ * @throws BuildException if the property is supplied but the file doesn't exist.
*/
- public boolean isIdPPropertiesPresent() {
- return idpPropertiesPresent;
+ public File getLDAPMergePropertiesFile() throws BuildException {
+ return getMergePropertiesFile(LDAP_PROPERTIES_MERGE);
}
}
diff --git a/idp-installer/src/main/java/net/shibboleth/idp/installer/impl/InstallerSupport.java b/idp-installer/src/main/java/net/shibboleth/idp/installer/impl/InstallerSupport.java
index e8bb479..dd9fb2b 100644
--- a/idp-installer/src/main/java/net/shibboleth/idp/installer/impl/InstallerSupport.java
+++ b/idp-installer/src/main/java/net/shibboleth/idp/installer/impl/InstallerSupport.java
@@ -40,6 +40,9 @@ public final class InstallerSupport {
/** The name of the file and the property with the current V4 installation value.*/
public static final String VERSION_NAME = "idp.installed.version";
+ /** The name of the file and the property with the previous installation value.*/
+ public static final String PREVIOUS_VERSION_NAME = "idp.previous.installed.version";
+
/** A psuedo ant-project as parent. */
public static final Project ANT_PROJECT = new Project();
@@ -53,7 +56,7 @@ public final class InstallerSupport {
protected static void createDirectory(final Path dir) throws BuildException{
if (!Files.exists(dir)) {
try {
- Files.createDirectory(dir);
+ Files.createDirectories(dir);
LOG.debug("Created directory {}", dir);
} catch (final IOException e) {
LOG.error("Could no create {}", dir, e);
@@ -108,7 +111,7 @@ public final class InstallerSupport {
copy.addFileset(fromSet);
copy.setProject(ANT_PROJECT);
copy.execute();
- LOG.debug("Copied not-previously existing files from {} to {}", from, to);
+ LOG.debug("Copied not-previously-existing files from {} to {}", from, to);
}
diff --git a/idp-installer/src/main/java/net/shibboleth/idp/installer/impl/KeyManagement.java b/idp-installer/src/main/java/net/shibboleth/idp/installer/impl/KeyManagement.java
index e97575b..3133372 100644
--- a/idp-installer/src/main/java/net/shibboleth/idp/installer/impl/KeyManagement.java
+++ b/idp-installer/src/main/java/net/shibboleth/idp/installer/impl/KeyManagement.java
@@ -21,57 +21,82 @@ import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Collections;
+import javax.annotation.Nonnull;
+
import org.apache.tools.ant.BuildException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import net.shibboleth.utilities.java.support.component.AbstractInitializableComponent;
+import net.shibboleth.utilities.java.support.component.ComponentSupport;
import net.shibboleth.utilities.java.support.security.BasicKeystoreKeyStrategyTool;
import net.shibboleth.utilities.java.support.security.SelfSignedCertificateGenerator;
/**
* Create (if needs be) all the keys needed by an install.
*/
-public class KeyManagement {
+final class KeyManagement extends AbstractInitializableComponent {
/** Log. */
private final Logger log = LoggerFactory.getLogger(KeyManagement.class);
/** Properties for the job. */
- private final InstallerProperties installerProps;
+ @Nonnull private final InstallerProperties installerProps;
+
+ /** Current Install. */
+ @Nonnull private final CurrentInstallState currentState;
+
+ /** Did we create idp-signing.*?*/
+ private boolean createdSigning;
+
+ /** Did we create idp-encryption.*?*/
+ private boolean createdEncryption;
+
+ /** Did we create idp-backchannel.*?*/
+ private boolean createdBackchannel;
+
+ /** Did we create sealer.*?*/
+ private boolean createdSealer;
/** Constructor.
- * @param props The environment for the work.
+ * @param props The properties to drive the installs.
+ * @param installState - about where we installing into.
*/
- public KeyManagement(final InstallerProperties props) {
+ protected KeyManagement(@Nonnull final InstallerProperties props, @Nonnull final CurrentInstallState installState) {
+ ComponentSupport.ifNotInitializedThrowUninitializedComponentException(props);
+ ComponentSupport.ifNotInitializedThrowUninitializedComponentException(installState);
installerProps = props;
+ currentState = installState;
}
/** Create any keys that are needed.
* @throws BuildException if badness occurs
*/
- public void execute() throws BuildException {
- generateKey("idp-signing");
- generateKey("idp-encryption");
+ protected void execute() throws BuildException {
+ createdSigning = generateKey("idp-signing");
+ createdEncryption = generateKey("idp-encryption");
generateKeyStore();
generateSealer();
}
/** Helper method for {@link #manageKeys(InstallerProperties)} to generate a crt and key file.
* @param fileBase the partial file name
+ * @return true iff the file pair was created
* @throws BuildException if badness occurrs.
*/
- private void generateKey(final String fileBase) throws BuildException {
+ private boolean generateKey(final String fileBase) throws BuildException {
final Path credentials = installerProps.getTargetDir().resolve("credentials");
final Path key = credentials.resolve(fileBase+".key");
final Path crt = credentials.resolve(fileBase+".crt");
if (Files.exists(key) && Files.exists(crt)) {
- if (!installerProps.isIdPPropertiesPresent()) {
+ if (!currentState.isIdPPropertiesPresent()) {
log.error("key files {} and {} exist but idp.properties does not", key, crt);
throw new BuildException("Invalid key file configuration");
}
log.debug("keys files {} and {} exist. Not generating", key, crt);
- } else if (installerProps.isIdPPropertiesPresent()) {
+ return false;
+ } else if (currentState.isIdPPropertiesPresent()) {
log.error("idp.properties exists but key files {} and/or {} do not", key, crt);
throw new BuildException("Invalid key file configuration");
} else if (Files.exists(key) || Files.exists(crt)) {
@@ -93,6 +118,8 @@ public class KeyManagement {
throw new BuildException("Error Building Self Signed Cert", e);
}
}
+ log.debug("... Done");
+ return true;
}
/** Helper method for {@link #manageKeys(InstallerProperties)} to generate the backchannel keystore.
@@ -104,12 +131,12 @@ public class KeyManagement {
final Path crt = credentials.resolve("idp-backchannel.crt");
if (Files.exists(keyStore) && Files.exists(crt)) {
- if (!installerProps.isIdPPropertiesPresent()) {
+ if (!currentState.isIdPPropertiesPresent()) {
log.error("Key store files {} and {} exist but idp.properties does not", keyStore, crt);
throw new BuildException("Invalid key file configuration");
}
log.debug("Keys store files {} and {} exist. Not generating", keyStore, crt);
- } else if (installerProps.isIdPPropertiesPresent()) {
+ } else if (currentState.isIdPPropertiesPresent()) {
log.error("idp.properties exists but key store files {} and/or {} do not", keyStore, crt);
throw new BuildException("Invalid key file configuration");
} else if (Files.exists(keyStore) || Files.exists(crt)) {
@@ -131,6 +158,7 @@ public class KeyManagement {
log.error("Error building backchannel ketsyore files", e);
throw new BuildException("Error Building Backchannel Key Store", e);
}
+ createdBackchannel = true;
}
}
@@ -143,12 +171,12 @@ public class KeyManagement {
final Path versionFile = credentials.resolve("sealer.kver");
if (Files.exists(sealer) && Files.exists(versionFile)) {
- if (!installerProps.isIdPPropertiesPresent()) {
+ if (!currentState.isIdPPropertiesPresent()) {
log.error("Cookie encryption files {} and {} exist but idp.properties does not", sealer, versionFile);
throw new BuildException("Invalid Cookie encryption file configuration");
}
log.debug("Cookie encryption files {} and {} exists. Not generating.", sealer, versionFile);
- } else if (installerProps.isIdPPropertiesPresent()) {
+ } else if (currentState.isIdPPropertiesPresent()) {
log.error("idp.properties exists but cookie encryption files {} do not", sealer, versionFile);
throw new BuildException("Invalid key file configuration");
} else if (Files.exists(sealer) || Files.exists(versionFile)) {
@@ -168,6 +196,35 @@ public class KeyManagement {
log.error("Error building cookie encryption files", e);
throw new BuildException("Error Building Cookie Encryption", e);
}
+ createdSealer = true;
}
}
+
+ /** Did we create idp-signing.*?
+ * @return whether we did
+ */
+ public boolean isCreatedSigning() {
+ return createdSigning;
+ }
+
+ /** Did we create idp-encryption.*?
+ * @return whether we did
+ */
+ public boolean isCreatedEncryption() {
+ return createdEncryption;
+ }
+
+ /** Did we create idp-backchannel.*?
+ * @return whether we did
+ */
+ public boolean isCreatedBackchannel() {
+ return createdBackchannel;
+ }
+
+ /** Did we create sealer.*?
+ * @return whether we did
+ */
+ public boolean isCreatedSealer() {
+ return createdSealer;
+ }
}
diff --git a/idp-installer/src/main/java/net/shibboleth/idp/installer/impl/PropertiesWithComments.java b/idp-installer/src/main/java/net/shibboleth/idp/installer/impl/PropertiesWithComments.java
index 84353fc..e5b036d 100644
--- a/idp-installer/src/main/java/net/shibboleth/idp/installer/impl/PropertiesWithComments.java
+++ b/idp-installer/src/main/java/net/shibboleth/idp/installer/impl/PropertiesWithComments.java
@@ -40,7 +40,7 @@ import net.shibboleth.utilities.java.support.primitive.StringSupport;
* A package which is similar to Properties, but allows comments to be preserved. We use the Properties package to parse
* the non-comment lines.
*/
-public class PropertiesWithComments {
+public final class PropertiesWithComments {
/**
* The contents.
@@ -54,7 +54,7 @@ public class PropertiesWithComments {
private Map<String, CommentedProperty> properties;
/** Name Replacement info. */
- private final Properties nameReplacement = new Properties();
+ private final Properties nameReplacement;
/** Have we loaded data?.
*
@@ -62,6 +62,27 @@ public class PropertiesWithComments {
* */
private boolean loadedData;
+ /** Legacy Constructor. */
+ public PropertiesWithComments() {
+ nameReplacement = new Properties();
+ }
+
+ /** Constructor.
+ * @param replacements what to set.
+ */
+ public PropertiesWithComments(final Properties replacements) {
+ nameReplacement = replacements;
+ }
+
+ /** Constructor.
+ * @param input what to set.
+ * @throws IOException id the stream could not be loaded
+ */
+ public PropertiesWithComments(final InputStream input) throws IOException {
+ nameReplacement = new Properties();
+ nameReplacement.load(input);
+ }
+
/**
* Add a property, either as a key/value pair or as a key/comment pair.
*
@@ -191,6 +212,18 @@ public class PropertiesWithComments {
}
}
+ /** Perform a mass replacement from the supplied {@link Properties}.
+ * @param replacements what to replace.
+ */
+ public void replaceProperties(final Properties replacements) {
+ for (final Object propName:replacements.keySet()) {
+ if (propName instanceof String) {
+ final String name = (String) propName;
+ replaceProperty(name, replacements.getProperty(name));
+ }
+ }
+ }
+
/**
* Replace the supplied property or stuff it at the bottom of the list.
*
diff --git a/idp-installer/src/main/java/net/shibboleth/idp/installer/impl/V4Install.java b/idp-installer/src/main/java/net/shibboleth/idp/installer/impl/V4Install.java
new file mode 100644
index 0000000..5a8350a
--- /dev/null
+++ b/idp-installer/src/main/java/net/shibboleth/idp/installer/impl/V4Install.java
@@ -0,0 +1,266 @@
+/*
+ * Licensed to the University Corporation for Advanced Internet Development,
+ * Inc. (UCAID) under one or more contributor license agreements. See the
+ * NOTICE file distributed with this work for additional information regarding
+ * copyright ownership. The UCAID licenses this file to You under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package net.shibboleth.idp.installer.impl;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.util.Properties;
+
+import javax.annotation.Nonnull;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.taskdefs.Copy;
+import org.joda.time.Instant;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import net.shibboleth.idp.Version;
+import net.shibboleth.utilities.java.support.component.AbstractInitializableComponent;
+import net.shibboleth.utilities.java.support.component.ComponentSupport;
+
+/** Code to do most of the V4 Install.
+ */
+public class V4Install extends AbstractInitializableComponent {
+
+ /** Log. */
+ private final Logger log = LoggerFactory.getLogger(V4Install.class);
+
+ /** Installer Properties. */
+ @Nonnull private final InstallerProperties installerProps;
+
+ /** Current Install. */
+ @Nonnull private final CurrentInstallState currentState;
+
+ /** Constructor.
+ * @param props The properties to drive the installs.
+ * @param installState The current install.
+ */
+ public V4Install(@Nonnull final InstallerProperties props, @Nonnull final CurrentInstallState installState) {
+ ComponentSupport.ifNotInitializedThrowUninitializedComponentException(props);
+ ComponentSupport.ifNotInitializedThrowUninitializedComponentException(installState);
+ installerProps = props;
+ currentState = installState;
+ }
+
+ /** Method to do the work. It assumes that the distribution has been copied.
+ * @throws BuildException if unexpected badness occurs.
+ */
+ public void execute() throws BuildException {
+ handleVersioning();
+ // To keep the UI order the same as the V3 Installer
+ //installerProps.getEntityID();
+ //installerProps.getScope();
+ createUserDirectories();
+ final KeyManagement keys = new KeyManagement(installerProps, currentState);
+ keys.execute();
+ populatePropertyFiles(keys.isCreatedSealer());
+ handleEditWebApp();
+ populateUserDirectories();
+ generateMetadata();
+ reprotect();
+ }
+
+ /** Report the to be installed and (if there is one) current versions.
+ * Write to be installed version to the dist folder.
+ * @throws BuildException if the write fails
+ */
+ protected void handleVersioning() throws BuildException {
+ final String installedVersion = currentState.getInstalledVersion();
+ String currentVersion = Version.getVersion();
+ if (null == currentVersion) {
+ currentVersion = "4Generic";
+ }
+ if (null == installedVersion) {
+ log.info("New Install. Version: {}", currentVersion);
+ } else if (currentVersion == installedVersion) {
+ log.info("Reinstall of version {}", currentVersion);
+ } else {
+ log.info("Update from version {} to version {}", installedVersion, currentVersion);
+ }
+ try {
+ final Properties vers = new Properties();
+ vers.setProperty(InstallerSupport.VERSION_NAME, currentVersion);
+ vers.setProperty(InstallerSupport.PREVIOUS_VERSION_NAME, installedVersion==null?"":installedVersion);
+ final OutputStream out = new FileOutputStream(
+ installerProps.getTargetDir().resolve("dist").resolve(InstallerSupport.VERSION_NAME).toFile());
+ vers.store(out, "Version file written at " + Instant.now());
+ } catch (final IOException e) {
+ throw new BuildException("Couldn't write versiining information", e);
+ }
+ }
+
+ /** Create (if they do not exist) the user editable folders, suitable for
+ * later population during update or install.
+ * @throws BuildException if badness occurs
+ */
+ protected void createUserDirectories() throws BuildException {
+ final Path target = installerProps.getTargetDir();
+ InstallerSupport.createDirectory(target.resolve("conf"));
+ InstallerSupport.createDirectory(target.resolve("credentials"));
+ InstallerSupport.createDirectory(target.resolve("flows"));
+ InstallerSupport.createDirectory(target.resolve("logs"));
+ InstallerSupport.createDirectory(target.resolve("messages"));
+ InstallerSupport.createDirectory(target.resolve("metadata"));
+ InstallerSupport.createDirectory(target.resolve("views"));
+ InstallerSupport.createDirectory(target.resolve("war"));
+ }
+
+ /** Create the properties we need to replace when we merge idp.properties.
+ * @param sealerCreated have we just created a sealer
+ * @return what we need to replace
+ */
+ private Properties getIdPReplacements(final boolean sealerCreated) {
+ final Properties result = new Properties();
+ if (sealerCreated) {
+ result.setProperty("idp.sealer.storePassword", installerProps.getSealerPassword());
+ result.setProperty("idp.sealer.keyPassword", installerProps.getSealerPassword());
+ }
+ result.setProperty("idp.entityID", installerProps.getEntityID());
+ result.setProperty("idp.scope", installerProps.getScope());
+ return result;
+ }
+
+ /** Create (if they do not exist) propertyFiles. (idp.properties, ldap.properties).
+ * This *MUST* happen before {@link #populateUserDirectories(InstallerProperties)} or it will not be effective.
+ * Note that in V3 serice.properties and nameid.properties but we do not any more.
+ * @param sealerCreated have we just created a sealer
+ * @throws BuildException if badness occurs
+ */
+ // CheckStyle: CyclomaticComplexity OFF
+ protected void populatePropertyFiles(final boolean sealerCreated) throws BuildException {
+ final Path conf = installerProps.getTargetDir().resolve("conf");
+ final Path dstConf = installerProps.getTargetDir().resolve("dist").resolve("conf");
+ if (!currentState.isIdPPropertiesPresent()) {
+ // We have to populate it
+ try {
+ final Path target = conf.resolve("idp.properties");
+ if (Files.exists(target)) {
+ throw new BuildException("Internal error - idp.properties");
+ }
+ final File mergeFile = installerProps.getIdPMergePropertiesFile();
+ final Path source = dstConf.resolve("idp.properties");
+ if (!Files.exists(source)) {
+ throw new BuildException("missing idp.properties in dist");
+ }
+ final PropertiesWithComments propertiesToReWrite = new PropertiesWithComments();
+ final Properties replacements;
+ if (mergeFile != null) {
+ log.debug("Creating {} from {} and {}", target, source, mergeFile);
+ replacements = new Properties();
+ replacements.load(new FileInputStream(mergeFile));
+ } else {
+ replacements = getIdPReplacements(sealerCreated);
+ log.debug("Creating {} from {} and {}", target, source, replacements);
+ }
+ propertiesToReWrite.load(new FileInputStream(source.toFile()));
+ propertiesToReWrite.replaceProperties(replacements);
+ propertiesToReWrite.store(new FileOutputStream(target.toFile()));
+ } catch (final IOException e) {
+ throw new BuildException("Failed to generate idp.properties", e);
+ }
+ }
+
+ final File ldapMergeFile = installerProps.getLDAPMergePropertiesFile();
+ if (ldapMergeFile != null && !currentState.isLDAPPropertiesPresent() ) {
+ try {
+ final Path target = conf.resolve("ldap.properties");
+ if (Files.exists(target)) {
+ throw new BuildException("Internal error - ldap.properties");
+ }
+ final Path source = dstConf.resolve("ldap.properties");
+ if (!Files.exists(source)) {
+ throw new BuildException("missing ldap.properties in dist");
+ }
+ log.debug("Creating {} from {} and {}", target, source, ldapMergeFile);
+ final PropertiesWithComments propertiesToReWrite = new PropertiesWithComments();
+ final Properties replacements = new Properties();
+ replacements.load(new FileInputStream(ldapMergeFile));
+ propertiesToReWrite.load(new FileInputStream(source.toFile()));
+ propertiesToReWrite.replaceProperties(replacements);
+ propertiesToReWrite.store(new FileOutputStream(target.toFile()));
+ } catch (final IOException e) {
+ throw new BuildException("Failed to generate ldap.properties", e);
+ }
+ }
+ }
+ // CheckStyle: CyclomaticComplexity ON
+
+ /** Create and populate (if it does not exist) edit-webapp.
+ * @throws BuildException if badness occurs
+ */
+ protected void handleEditWebApp() throws BuildException {
+ final Path editWebApp = installerProps.getTargetDir().resolve("edit-webapp");
+ if (Files.exists(editWebApp)) {
+ return;
+ }
+ InstallerSupport.createDirectory(editWebApp);
+ final Path css = editWebApp.resolve("css");
+ InstallerSupport.createDirectory(css);
+ final Path images = editWebApp.resolve("images");
+ InstallerSupport.createDirectory(images);
+ InstallerSupport.createDirectory(editWebApp.resolve("WEB-INF"));
+ InstallerSupport.createDirectory(editWebApp.resolve("WEB-INF").resolve("lib"));
+ InstallerSupport.createDirectory(editWebApp.resolve("WEB-INF").resolve("classes"));
+ final Path distEditWebApp = installerProps.getTargetDir().resolve("dist").resolve("webapp");
+ final Copy cssCopy = InstallerSupport.getCopyTask(distEditWebApp.resolve("css"), css);
+ cssCopy.setFailOnError(false);
+ cssCopy.execute();
+ final Copy imagesCopy = InstallerSupport.getCopyTask(distEditWebApp.resolve("images"), images);
+ imagesCopy.setFailOnError(false);
+ imagesCopy.execute();
+ }
+
+ /** Create and populate (if they not exist) the "user visible" folders.
+ * (conf, flows, messages, views, logs)
+ * @throws BuildException if badness occurs
+ */
+ protected void populateUserDirectories() throws BuildException {
+ final Path targetBase = installerProps.getTargetDir();
+ final Path distBase = targetBase.resolve("dist");
+ InstallerSupport.copyDirIfNotPresent(distBase.resolve("conf"), targetBase.resolve("conf"));
+ InstallerSupport.copyDirIfNotPresent(distBase.resolve("flows"), targetBase.resolve("flows"));
+ InstallerSupport.copyDirIfNotPresent(distBase.resolve("views"), targetBase.resolve("views"));
+ InstallerSupport.copyDirIfNotPresent(distBase.resolve("messages"), targetBase.resolve("messages"));
+ InstallerSupport.createDirectory(targetBase.resolve("logs"));
+ }
+
+ /** Create and populate (if it does not exist) the "metadata/idp-metadata.xml" file.
+ * @throws BuildException if badness occurs
+ */
+ protected void generateMetadata() throws BuildException {
+ final Path parentDir = installerProps.getTargetDir().resolve("metadata");
+ final Path metadataFile = parentDir.resolve("idp-metadata");
+ if (Files.exists(metadataFile)) {
+ return;
+ }
+ log.warn("Metadata Implementation still pending");
+ }
+
+ /** Set the protection on the files.
+ * @throws BuildException if badness occurs
+ */
+ protected void reprotect() throws BuildException {
+ log.warn("Reprotect Implementation still pending");
+ }
+
+}
diff --git a/idp-installer/src/test/java/net/shibboleth/idp/installer/Test.java b/idp-installer/src/test/java/net/shibboleth/idp/installer/impl/Test.java
similarity index 100%
rename from idp-installer/src/test/java/net/shibboleth/idp/installer/Test.java
rename to idp-installer/src/test/java/net/shibboleth/idp/installer/impl/Test.java
--
To stop receiving notification emails like this one, please contact
the administrator of this repository.
More information about the commits
mailing list