Adapt to new build system
authorMathieu Baudier <mbaudier@argeo.org>
Sat, 15 Oct 2022 10:25:39 +0000 (12:25 +0200)
committerMathieu Baudier <mbaudier@argeo.org>
Sat, 15 Oct 2022 10:25:39 +0000 (12:25 +0200)
76 files changed:
Makefile
Makefile-rcp.mk
branch.mk
cms/org.argeo.slc.cms/.classpath [deleted file]
cms/org.argeo.slc.cms/.project [deleted file]
cms/org.argeo.slc.cms/bnd.bnd [deleted file]
cms/org.argeo.slc.cms/build.properties [deleted file]
cms/org.argeo.slc.cms/src/org/argeo/slc/backup/vfs/AbstractAtomicBackup.java [deleted file]
cms/org.argeo.slc.cms/src/org/argeo/slc/backup/vfs/AtomicBackup.java [deleted file]
cms/org.argeo.slc.cms/src/org/argeo/slc/backup/vfs/BackupContext.java [deleted file]
cms/org.argeo.slc.cms/src/org/argeo/slc/backup/vfs/BackupFileSystemManager.java [deleted file]
cms/org.argeo.slc.cms/src/org/argeo/slc/backup/vfs/BackupPurge.java [deleted file]
cms/org.argeo.slc.cms/src/org/argeo/slc/backup/vfs/BackupUtils.java [deleted file]
cms/org.argeo.slc.cms/src/org/argeo/slc/backup/vfs/MaintenanceException.java [deleted file]
cms/org.argeo.slc.cms/src/org/argeo/slc/backup/vfs/MySqlBackup.java [deleted file]
cms/org.argeo.slc.cms/src/org/argeo/slc/backup/vfs/OpenLdapBackup.java [deleted file]
cms/org.argeo.slc.cms/src/org/argeo/slc/backup/vfs/OsCallBackup.java [deleted file]
cms/org.argeo.slc.cms/src/org/argeo/slc/backup/vfs/PostgreSqlBackup.java [deleted file]
cms/org.argeo.slc.cms/src/org/argeo/slc/backup/vfs/SimpleBackupContext.java [deleted file]
cms/org.argeo.slc.cms/src/org/argeo/slc/backup/vfs/SimpleBackupPurge.java [deleted file]
cms/org.argeo.slc.cms/src/org/argeo/slc/backup/vfs/SvnBackup.java [deleted file]
cms/org.argeo.slc.cms/src/org/argeo/slc/backup/vfs/SystemBackup.java [deleted file]
cms/org.argeo.slc.cms/src/org/argeo/slc/backup/vfs/package-info.java [deleted file]
cms/org.argeo.slc.cms/src/org/argeo/slc/cms/deploy/CmsDeployedSystem.java [deleted file]
cms/org.argeo.slc.cms/src/org/argeo/slc/cms/deploy/CmsDeploymentData.java [deleted file]
cms/org.argeo.slc.cms/src/org/argeo/slc/cms/deploy/CmsTargetData.java [deleted file]
cms/org.argeo.slc.cms/src/org/argeo/slc/cms/deploy/SimpleCmsDeploymentData.java [deleted file]
cms/org.argeo.slc.cms/src/org/argeo/slc/cms/deploy/SimpleCmsTargetData.java [deleted file]
cms/org.argeo.slc.cms/src/org/argeo/slc/cms/deploy/osgi/CmsOsgiDeployedSystem.java [deleted file]
cms/org.argeo.slc.cms/src/org/argeo/slc/cms/deploy/osgi/CmsOsgiDeployment.java [deleted file]
cms/org.argeo.slc.cms/src/org/argeo/slc/cms/distribution/A2Distribution.java [deleted file]
cms/org.argeo.slc.cms/src/org/argeo/slc/cms/distribution/A2ModuleDistribution.java [deleted file]
cms/org.argeo.slc.cms/src/org/argeo/slc/cms/httpclient3/HttpCredentialProvider.java [deleted file]
cms/org.argeo.slc.cms/src/org/argeo/slc/cms/httpclient3/SpnegoAuthScheme.java [deleted file]
cms/org.argeo.slc.cms/src/org/argeo/slc/cms/httpclient3/SpnegoCredentials.java [deleted file]
cms/org.argeo.slc.cms/src/org/argeo/slc/cms/httpclient3/jaas.cfg [deleted file]
cms/org.argeo.slc.cms/src/org/argeo/slc/cms/test/CmsSmokeTest.java [deleted file]
cnf/build.bnd [deleted file]
cnf/unstable.bnd [deleted file]
configure
org.argeo.slc.cms/.classpath [new file with mode: 0644]
org.argeo.slc.cms/.project [new file with mode: 0644]
org.argeo.slc.cms/bnd.bnd [new file with mode: 0644]
org.argeo.slc.cms/build.properties [new file with mode: 0644]
org.argeo.slc.cms/src/org/argeo/slc/backup/vfs/AbstractAtomicBackup.java [new file with mode: 0644]
org.argeo.slc.cms/src/org/argeo/slc/backup/vfs/AtomicBackup.java [new file with mode: 0644]
org.argeo.slc.cms/src/org/argeo/slc/backup/vfs/BackupContext.java [new file with mode: 0644]
org.argeo.slc.cms/src/org/argeo/slc/backup/vfs/BackupFileSystemManager.java [new file with mode: 0644]
org.argeo.slc.cms/src/org/argeo/slc/backup/vfs/BackupPurge.java [new file with mode: 0644]
org.argeo.slc.cms/src/org/argeo/slc/backup/vfs/BackupUtils.java [new file with mode: 0644]
org.argeo.slc.cms/src/org/argeo/slc/backup/vfs/MaintenanceException.java [new file with mode: 0644]
org.argeo.slc.cms/src/org/argeo/slc/backup/vfs/MySqlBackup.java [new file with mode: 0644]
org.argeo.slc.cms/src/org/argeo/slc/backup/vfs/OpenLdapBackup.java [new file with mode: 0644]
org.argeo.slc.cms/src/org/argeo/slc/backup/vfs/OsCallBackup.java [new file with mode: 0644]
org.argeo.slc.cms/src/org/argeo/slc/backup/vfs/PostgreSqlBackup.java [new file with mode: 0644]
org.argeo.slc.cms/src/org/argeo/slc/backup/vfs/SimpleBackupContext.java [new file with mode: 0644]
org.argeo.slc.cms/src/org/argeo/slc/backup/vfs/SimpleBackupPurge.java [new file with mode: 0644]
org.argeo.slc.cms/src/org/argeo/slc/backup/vfs/SvnBackup.java [new file with mode: 0644]
org.argeo.slc.cms/src/org/argeo/slc/backup/vfs/SystemBackup.java [new file with mode: 0644]
org.argeo.slc.cms/src/org/argeo/slc/backup/vfs/package-info.java [new file with mode: 0644]
org.argeo.slc.cms/src/org/argeo/slc/cms/deploy/CmsDeployedSystem.java [new file with mode: 0644]
org.argeo.slc.cms/src/org/argeo/slc/cms/deploy/CmsDeploymentData.java [new file with mode: 0644]
org.argeo.slc.cms/src/org/argeo/slc/cms/deploy/CmsTargetData.java [new file with mode: 0644]
org.argeo.slc.cms/src/org/argeo/slc/cms/deploy/SimpleCmsDeploymentData.java [new file with mode: 0644]
org.argeo.slc.cms/src/org/argeo/slc/cms/deploy/SimpleCmsTargetData.java [new file with mode: 0644]
org.argeo.slc.cms/src/org/argeo/slc/cms/deploy/osgi/CmsOsgiDeployedSystem.java [new file with mode: 0644]
org.argeo.slc.cms/src/org/argeo/slc/cms/deploy/osgi/CmsOsgiDeployment.java [new file with mode: 0644]
org.argeo.slc.cms/src/org/argeo/slc/cms/distribution/A2Distribution.java [new file with mode: 0644]
org.argeo.slc.cms/src/org/argeo/slc/cms/distribution/A2ModuleDistribution.java [new file with mode: 0644]
org.argeo.slc.cms/src/org/argeo/slc/cms/httpclient3/HttpCredentialProvider.java [new file with mode: 0644]
org.argeo.slc.cms/src/org/argeo/slc/cms/httpclient3/SpnegoAuthScheme.java [new file with mode: 0644]
org.argeo.slc.cms/src/org/argeo/slc/cms/httpclient3/SpnegoCredentials.java [new file with mode: 0644]
org.argeo.slc.cms/src/org/argeo/slc/cms/httpclient3/jaas.cfg [new file with mode: 0644]
org.argeo.slc.cms/src/org/argeo/slc/cms/test/CmsSmokeTest.java [new file with mode: 0644]
sdk/argeo-build
sdk/branches/unstable.bnd [new file with mode: 0644]

index 8ff57035fcf60494345c49f0f5c338d9265fcf6a..2ef8c78a891ba609286221fb3efa515fadf7d6b0 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -9,17 +9,12 @@ BUNDLES = \
 org.argeo.slc.api \
 org.argeo.slc.factory \
 org.argeo.slc.runtime \
-cms/org.argeo.slc.cms \
+org.argeo.slc.cms \
 swt/rap/org.argeo.tool.server \
 
-VPATH = .:cms:swt/rap
-
 clean:
        rm -rf $(BUILD_BASE)
 
-A2_OUTPUT = $(SDK_BUILD_BASE)/a2
-A2_BASE = $(A2_OUTPUT)
-
 DEP_CATEGORIES = \
 org.argeo.tp \
 org.argeo.tp.sdk \
@@ -33,6 +28,7 @@ org.argeo.tp.jcr \
 org.argeo.tp.formats \
 org.argeo.tp.gis \
 org.argeo.cms \
+org.argeo.cms.jcr \
 swt/rap/org.argeo.cms \
 
 GRAALVM_HOME = /opt/graalvm-ce
index ce890019949085c699df18e16a9e00afb4707ca0..77c25317b56e6e4f7f8cd7a48ce22281eb3f836e 100644 (file)
@@ -8,8 +8,6 @@ A2_CATEGORY = org.argeo.slc
 BUNDLES = \
 swt/rcp/org.argeo.tool.desktop \
 
-VPATH = .:cms:swt/rcp
-
 clean:
        rm -rf $(BUILD_BASE)
 
index a6f848887ccc40bb5bdd3db46d37140d94f544eb..afde0f838e8e39e2e2b5abe863169d7891a97131 100644 (file)
--- a/branch.mk
+++ b/branch.mk
@@ -1 +1 @@
-include $(SDK_SRC_BASE)/cnf/unstable.bnd
+BRANCH=unstable
\ No newline at end of file
diff --git a/cms/org.argeo.slc.cms/.classpath b/cms/org.argeo.slc.cms/.classpath
deleted file mode 100644 (file)
index 81fe078..0000000
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<classpath>
-       <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-17"/>
-       <classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
-       <classpathentry kind="src" path="src"/>
-       <classpathentry kind="output" path="bin"/>
-</classpath>
diff --git a/cms/org.argeo.slc.cms/.project b/cms/org.argeo.slc.cms/.project
deleted file mode 100644 (file)
index 95c8de1..0000000
+++ /dev/null
@@ -1,28 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<projectDescription>
-       <name>org.argeo.slc.cms</name>
-       <comment></comment>
-       <projects>
-       </projects>
-       <buildSpec>
-               <buildCommand>
-                       <name>org.eclipse.jdt.core.javabuilder</name>
-                       <arguments>
-                       </arguments>
-               </buildCommand>
-               <buildCommand>
-                       <name>org.eclipse.pde.ManifestBuilder</name>
-                       <arguments>
-                       </arguments>
-               </buildCommand>
-               <buildCommand>
-                       <name>org.eclipse.pde.SchemaBuilder</name>
-                       <arguments>
-                       </arguments>
-               </buildCommand>
-       </buildSpec>
-       <natures>
-               <nature>org.eclipse.pde.PluginNature</nature>
-               <nature>org.eclipse.jdt.core.javanature</nature>
-       </natures>
-</projectDescription>
diff --git a/cms/org.argeo.slc.cms/bnd.bnd b/cms/org.argeo.slc.cms/bnd.bnd
deleted file mode 100644 (file)
index 144bd1a..0000000
+++ /dev/null
@@ -1,4 +0,0 @@
-Import-Package: \
-org.apache.commons.logging,\
-org.osgi.*;version="0.0.0",\
-*
\ No newline at end of file
diff --git a/cms/org.argeo.slc.cms/build.properties b/cms/org.argeo.slc.cms/build.properties
deleted file mode 100644 (file)
index 5d082ea..0000000
+++ /dev/null
@@ -1,5 +0,0 @@
-source.. = src/
-output.. = bin/
-bin.includes = META-INF/,\
-               .
-additional.bundles = org.argeo.init
diff --git a/cms/org.argeo.slc.cms/src/org/argeo/slc/backup/vfs/AbstractAtomicBackup.java b/cms/org.argeo.slc.cms/src/org/argeo/slc/backup/vfs/AbstractAtomicBackup.java
deleted file mode 100644 (file)
index 6d55374..0000000
+++ /dev/null
@@ -1,82 +0,0 @@
-package org.argeo.slc.backup.vfs;
-
-import org.apache.commons.vfs2.FileObject;
-import org.apache.commons.vfs2.FileSystemManager;
-import org.apache.commons.vfs2.FileSystemOptions;
-import org.apache.commons.vfs2.provider.sftp.SftpFileSystemConfigBuilder;
-
-/**
- * Simplify atomic backups implementation, especially by managing VFS.
- */
-public abstract class AbstractAtomicBackup implements AtomicBackup {
-       private String name;
-       private String compression = "bz2";
-
-       protected abstract void writeBackup(FileObject targetFo);
-
-       public AbstractAtomicBackup() {
-       }
-
-       public AbstractAtomicBackup(String name) {
-               this.name = name;
-       }
-
-       public void init() {
-               if (name == null)
-                       throw new MaintenanceException("Atomic backup name must be set");
-       }
-
-       public void destroy() {
-
-       }
-
-       @Override
-       public String backup(FileSystemManager fileSystemManager,
-                       String backupsBase, BackupContext backupContext,
-                       FileSystemOptions opts) {
-               if (name == null)
-                       throw new MaintenanceException("Atomic backup name must be set");
-
-               FileObject targetFo = null;
-               try {
-                       if (backupsBase.startsWith("sftp:"))
-                               SftpFileSystemConfigBuilder.getInstance()
-                                               .setStrictHostKeyChecking(opts, "no");
-                       if (compression == null || compression.equals("none"))
-                               targetFo = fileSystemManager.resolveFile(backupsBase + '/'
-                                               + backupContext.getRelativeFolder() + '/' + name, opts);
-                       else if (compression.equals("bz2"))
-                               targetFo = fileSystemManager.resolveFile("bz2:" + backupsBase
-                                               + '/' + backupContext.getRelativeFolder() + '/' + name
-                                               + ".bz2" + "!" + name, opts);
-                       else if (compression.equals("gz"))
-                               targetFo = fileSystemManager.resolveFile("gz:" + backupsBase
-                                               + '/' + backupContext.getRelativeFolder() + '/' + name
-                                               + ".gz" + "!" + name, opts);
-                       else
-                               throw new MaintenanceException("Unsupported compression "
-                                               + compression);
-
-                       writeBackup(targetFo);
-
-                       return targetFo.toString();
-               } catch (Exception e) {
-                       throw new MaintenanceException("Cannot backup " + name + " to "
-                                       + targetFo, e);
-               } finally {
-                       BackupUtils.closeFOQuietly(targetFo);
-               }
-       }
-
-       public void setName(String name) {
-               this.name = name;
-       }
-
-       public String getName() {
-               return name;
-       }
-
-       public void setCompression(String compression) {
-               this.compression = compression;
-       }
-}
diff --git a/cms/org.argeo.slc.cms/src/org/argeo/slc/backup/vfs/AtomicBackup.java b/cms/org.argeo.slc.cms/src/org/argeo/slc/backup/vfs/AtomicBackup.java
deleted file mode 100644 (file)
index 0cfcfab..0000000
+++ /dev/null
@@ -1,22 +0,0 @@
-package org.argeo.slc.backup.vfs;
-
-import org.apache.commons.vfs2.FileSystemManager;
-import org.apache.commons.vfs2.FileSystemOptions;
-
-/** Performs the backup of a single component, typically a database dump */
-public interface AtomicBackup {
-       /** Name identifiying this backup */
-       public String getName();
-
-       /**
-        * Retrieves the data of the component in a format that allows to restore
-        * the component
-        * 
-        * @param backupContext
-        *            the context of this backup
-        * @return the VFS URI of the generated file or directory
-        */
-       public String backup(FileSystemManager fileSystemManager,
-                       String backupsBase, BackupContext backupContext,
-                       FileSystemOptions opts);
-}
diff --git a/cms/org.argeo.slc.cms/src/org/argeo/slc/backup/vfs/BackupContext.java b/cms/org.argeo.slc.cms/src/org/argeo/slc/backup/vfs/BackupContext.java
deleted file mode 100644 (file)
index 9c1140b..0000000
+++ /dev/null
@@ -1,25 +0,0 @@
-package org.argeo.slc.backup.vfs;
-
-import java.text.DateFormat;
-import java.util.Date;
-
-/**
- * Transient information of a given backup, centralizing common information such
- * as timestamp and location.
- */
-public interface BackupContext {
-       /** Backup date */
-       public Date getTimestamp();
-
-       /** Formatted backup date */
-       public String getTimestampAsString();
-
-       /** System name */
-       public String getSystemName();
-
-       /** Local base */
-       public String getRelativeFolder();
-
-       /** Date format */
-       public DateFormat getDateFormat();
-}
diff --git a/cms/org.argeo.slc.cms/src/org/argeo/slc/backup/vfs/BackupFileSystemManager.java b/cms/org.argeo.slc.cms/src/org/argeo/slc/backup/vfs/BackupFileSystemManager.java
deleted file mode 100644 (file)
index ad42dd3..0000000
+++ /dev/null
@@ -1,36 +0,0 @@
-package org.argeo.slc.backup.vfs;
-
-import org.apache.commons.vfs2.FileSystemException;
-import org.apache.commons.vfs2.impl.DefaultFileSystemManager;
-import org.apache.commons.vfs2.provider.bzip2.Bzip2FileProvider;
-import org.apache.commons.vfs2.provider.ftp.FtpFileProvider;
-import org.apache.commons.vfs2.provider.gzip.GzipFileProvider;
-import org.apache.commons.vfs2.provider.local.DefaultLocalFileProvider;
-import org.apache.commons.vfs2.provider.ram.RamFileProvider;
-import org.apache.commons.vfs2.provider.sftp.SftpFileProvider;
-import org.apache.commons.vfs2.provider.url.UrlFileProvider;
-
-/**
- * Programatically configured VFS file system manager which can be declared as a
- * bean and associated with a life cycle (methods
- * {@link DefaultFileSystemManager#init()} and
- * {@link DefaultFileSystemManager#close()}). Supports bz2, file, ram, gzip,
- * ftp, sftp
- */
-public class BackupFileSystemManager extends DefaultFileSystemManager {
-
-       public BackupFileSystemManager() {
-               super();
-               try {
-                       addProvider("file", new DefaultLocalFileProvider());
-                       addProvider("bz2", new Bzip2FileProvider());
-                       addProvider("ftp", new FtpFileProvider());
-                       addProvider("sftp", new SftpFileProvider());
-                       addProvider("gzip", new GzipFileProvider());
-                       addProvider("ram", new RamFileProvider());
-                       setDefaultProvider(new UrlFileProvider());
-               } catch (FileSystemException e) {
-                       throw new MaintenanceException("Cannot configure backup file provider", e);
-               }
-       }
-}
diff --git a/cms/org.argeo.slc.cms/src/org/argeo/slc/backup/vfs/BackupPurge.java b/cms/org.argeo.slc.cms/src/org/argeo/slc/backup/vfs/BackupPurge.java
deleted file mode 100644 (file)
index 1d07bbf..0000000
+++ /dev/null
@@ -1,18 +0,0 @@
-package org.argeo.slc.backup.vfs;
-
-import java.text.DateFormat;
-
-import org.apache.commons.vfs2.FileSystemManager;
-import org.apache.commons.vfs2.FileSystemOptions;
-
-/** Purges previous backups */
-public interface BackupPurge {
-       /**
-        * Purge the backups identified by these arguments. Although these are the
-        * same fields as a {@link BackupContext} we don't pass it as argument since
-        * we want to use this interface to purge remote backups as well (that is,
-        * with a different base), or outside the scope of a running backup.
-        */
-       public void purge(FileSystemManager fileSystemManager, String base,
-                       String name, DateFormat dateFormat, FileSystemOptions opts);
-}
diff --git a/cms/org.argeo.slc.cms/src/org/argeo/slc/backup/vfs/BackupUtils.java b/cms/org.argeo.slc.cms/src/org/argeo/slc/backup/vfs/BackupUtils.java
deleted file mode 100644 (file)
index bc4d0c8..0000000
+++ /dev/null
@@ -1,21 +0,0 @@
-package org.argeo.slc.backup.vfs;
-
-import org.apache.commons.vfs2.FileObject;
-
-/** Backup utilities */
-public class BackupUtils {
-       /** Close a file object quietly even if it is null or throws an exception. */
-       public static void closeFOQuietly(FileObject fo) {
-               if (fo != null) {
-                       try {
-                               fo.close();
-                       } catch (Exception e) {
-                               // silent
-                       }
-               }
-       }
-       
-       /** Prevents instantiation */
-       private BackupUtils() {
-       }
-}
diff --git a/cms/org.argeo.slc.cms/src/org/argeo/slc/backup/vfs/MaintenanceException.java b/cms/org.argeo.slc.cms/src/org/argeo/slc/backup/vfs/MaintenanceException.java
deleted file mode 100644 (file)
index 1532503..0000000
+++ /dev/null
@@ -1,15 +0,0 @@
-package org.argeo.slc.backup.vfs;
-
-@Deprecated
-class MaintenanceException extends RuntimeException {
-       private static final long serialVersionUID = -5770049663929537270L;
-
-       public MaintenanceException(String message, Throwable cause) {
-               super(message, cause);
-       }
-
-       public MaintenanceException(String message) {
-               super(message);
-       }
-
-}
diff --git a/cms/org.argeo.slc.cms/src/org/argeo/slc/backup/vfs/MySqlBackup.java b/cms/org.argeo.slc.cms/src/org/argeo/slc/backup/vfs/MySqlBackup.java
deleted file mode 100644 (file)
index 3f0e670..0000000
+++ /dev/null
@@ -1,59 +0,0 @@
-package org.argeo.slc.backup.vfs;
-
-import org.apache.commons.vfs2.FileObject;
-
-/** Backups a MySQL database using mysqldump. */
-public class MySqlBackup extends OsCallBackup {
-       private String mysqldumpLocation = "/usr/bin/mysqldump";
-
-       private String dbUser;
-       private String dbPassword;
-       private String dbName;
-
-       public MySqlBackup() {
-       }
-
-       public MySqlBackup(String dbUser, String dbPassword, String dbName) {
-               this.dbUser = dbUser;
-               this.dbPassword = dbPassword;
-               this.dbName = dbName;
-               init();
-       }
-
-       @Override
-       public void init() {
-               if (getName() == null)
-                       setName(dbName + ".mysql");
-               super.init();
-       }
-
-       @Override
-       public void writeBackup(FileObject targetFo) {
-               if (getCommand() == null)
-                       setCommand(mysqldumpLocation
-                                       + " --lock-tables --add-locks --add-drop-table"
-                                       + " -u ${dbUser} --password=${dbPassword} --databases ${dbName}");
-               getVariables().put("dbUser", dbUser);
-               getVariables().put("dbPassword", dbPassword);
-               getVariables().put("dbName", dbName);
-
-               super.writeBackup(targetFo);
-       }
-
-       public void setDbUser(String dbUser) {
-               this.dbUser = dbUser;
-       }
-
-       public void setDbPassword(String dbPassword) {
-               this.dbPassword = dbPassword;
-       }
-
-       public void setDbName(String dbName) {
-               this.dbName = dbName;
-       }
-
-       public void setMysqldumpLocation(String mysqldumpLocation) {
-               this.mysqldumpLocation = mysqldumpLocation;
-       }
-
-}
diff --git a/cms/org.argeo.slc.cms/src/org/argeo/slc/backup/vfs/OpenLdapBackup.java b/cms/org.argeo.slc.cms/src/org/argeo/slc/backup/vfs/OpenLdapBackup.java
deleted file mode 100644 (file)
index 31914bd..0000000
+++ /dev/null
@@ -1,46 +0,0 @@
-package org.argeo.slc.backup.vfs;
-
-import org.apache.commons.vfs2.FileObject;
-
-/** Backups an OpenLDAP server using slapcat */
-public class OpenLdapBackup extends OsCallBackup {
-       private String slapcatLocation = "/usr/sbin/slapcat";
-       private String slapdConfLocation = "/etc/openldap/slapd.conf";
-       private String baseDn;
-
-       public OpenLdapBackup() {
-               super();
-       }
-
-       public OpenLdapBackup(String baseDn) {
-               super();
-               this.baseDn = baseDn;
-       }
-
-       @Override
-       public void writeBackup(FileObject targetFo) {
-               if (baseDn == null)
-                       throw new MaintenanceException("Base DN must be set");
-
-               if (getCommand() == null)
-                       setCommand(slapcatLocation
-                                       + " -f ${slapdConfLocation} -b '${baseDn}'");
-               getVariables().put("slapdConfLocation", slapdConfLocation);
-               getVariables().put("baseDn", baseDn);
-
-               super.writeBackup(targetFo);
-       }
-
-       public void setSlapcatLocation(String slapcatLocation) {
-               this.slapcatLocation = slapcatLocation;
-       }
-
-       public void setSlapdConfLocation(String slapdConfLocation) {
-               this.slapdConfLocation = slapdConfLocation;
-       }
-
-       public void setBaseDn(String baseDn) {
-               this.baseDn = baseDn;
-       }
-
-}
diff --git a/cms/org.argeo.slc.cms/src/org/argeo/slc/backup/vfs/OsCallBackup.java b/cms/org.argeo.slc.cms/src/org/argeo/slc/backup/vfs/OsCallBackup.java
deleted file mode 100644 (file)
index 380dffe..0000000
+++ /dev/null
@@ -1,115 +0,0 @@
-package org.argeo.slc.backup.vfs;
-
-import java.io.ByteArrayOutputStream;
-import java.util.HashMap;
-import java.util.Map;
-
-import org.apache.commons.exec.CommandLine;
-import org.apache.commons.exec.DefaultExecutor;
-import org.apache.commons.exec.ExecuteException;
-import org.apache.commons.exec.ExecuteStreamHandler;
-import org.apache.commons.exec.Executor;
-import org.apache.commons.exec.PumpStreamHandler;
-import org.apache.commons.io.IOUtils;
-import org.apache.commons.vfs2.FileContent;
-import org.apache.commons.vfs2.FileObject;
-import org.argeo.api.cms.CmsLog;
-
-/**
- * Runs an OS command and save its standard output as a file. Typically used for
- * MySQL or OpenLDAP dumps.
- */
-public class OsCallBackup extends AbstractAtomicBackup {
-       private final static CmsLog log = CmsLog.getLog(OsCallBackup.class);
-
-       private String command;
-       private Map<String, String> variables = new HashMap<String, String>();
-       private Executor executor = new DefaultExecutor();
-
-       private Map<String, String> environment = new HashMap<String, String>();
-
-       /** Name of the sudo user, root if "", not sudo if null */
-       private String sudo = null;
-
-       public OsCallBackup() {
-       }
-
-       public OsCallBackup(String name) {
-               super(name);
-       }
-
-       public OsCallBackup(String name, String command) {
-               super(name);
-               this.command = command;
-       }
-
-       @Override
-       public void writeBackup(FileObject targetFo) {
-               String commandToUse = command;
-
-               // sudo
-               if (sudo != null) {
-                       if (sudo.equals(""))
-                               commandToUse = "sudo " + commandToUse;
-                       else
-                               commandToUse = "sudo -u " + sudo + " " + commandToUse;
-               }
-
-               CommandLine commandLine = CommandLine.parse(commandToUse, variables);
-               ByteArrayOutputStream errBos = new ByteArrayOutputStream();
-               if (log.isTraceEnabled())
-                       log.trace(commandLine.toString());
-
-               try {
-                       // stdout
-                       FileContent targetContent = targetFo.getContent();
-                       // stderr
-                       ExecuteStreamHandler streamHandler = new PumpStreamHandler(targetContent.getOutputStream(), errBos);
-                       executor.setStreamHandler(streamHandler);
-                       executor.execute(commandLine, environment);
-               } catch (ExecuteException e) {
-                       byte[] err = errBos.toByteArray();
-                       String errStr = new String(err);
-                       throw new MaintenanceException("Process " + commandLine + " failed (" + e.getExitValue() + "): " + errStr, e);
-               } catch (Exception e) {
-                       byte[] err = errBos.toByteArray();
-                       String errStr = new String(err);
-                       throw new MaintenanceException("Process " + commandLine + " failed: " + errStr, e);
-               } finally {
-                       IOUtils.closeQuietly(errBos);
-               }
-       }
-
-       public void setCommand(String command) {
-               this.command = command;
-       }
-
-       protected String getCommand() {
-               return command;
-       }
-
-       /**
-        * A reference to the environment variables that will be passed to the
-        * process. Empty by default.
-        */
-       protected Map<String, String> getEnvironment() {
-               return environment;
-       }
-
-       protected Map<String, String> getVariables() {
-               return variables;
-       }
-
-       public void setVariables(Map<String, String> variables) {
-               this.variables = variables;
-       }
-
-       public void setExecutor(Executor executor) {
-               this.executor = executor;
-       }
-
-       public void setSudo(String sudo) {
-               this.sudo = sudo;
-       }
-
-}
diff --git a/cms/org.argeo.slc.cms/src/org/argeo/slc/backup/vfs/PostgreSqlBackup.java b/cms/org.argeo.slc.cms/src/org/argeo/slc/backup/vfs/PostgreSqlBackup.java
deleted file mode 100644 (file)
index 613fd5a..0000000
+++ /dev/null
@@ -1,70 +0,0 @@
-package org.argeo.slc.backup.vfs;
-
-import org.apache.commons.vfs2.FileObject;
-
-/** Backups a PostgreSQL database using pg_dump. */
-public class PostgreSqlBackup extends OsCallBackup {
-       /**
-        * PostgreSQL password environment variable (see
-        * http://stackoverflow.com/questions
-        * /2893954/how-to-pass-in-password-to-pg-dump)
-        */
-       protected final static String PGPASSWORD = "PGPASSWORD";
-
-       private String pgDumpLocation = "/usr/bin/pg_dump";
-
-       private String dbUser;
-       private String dbPassword;
-       private String dbName;
-
-       public PostgreSqlBackup() {
-               super();
-       }
-
-       public PostgreSqlBackup(String dbUser, String dbPassword, String dbName) {
-               this.dbUser = dbUser;
-               this.dbPassword = dbPassword;
-               this.dbName = dbName;
-               init();
-       }
-
-       @Override
-       public void init() {
-               // disable compression since pg_dump is used with -Fc option
-               setCompression(null);
-
-               if (getName() == null)
-                       setName(dbName + ".pgdump");
-               super.init();
-       }
-
-       @Override
-       public void writeBackup(FileObject targetFo) {
-               if (getCommand() == null) {
-                       getEnvironment().put(PGPASSWORD, dbPassword);
-                       setCommand(pgDumpLocation + " -Fc" + " -U ${dbUser} ${dbName}");
-               }
-               getVariables().put("dbUser", dbUser);
-               getVariables().put("dbPassword", dbPassword);
-               getVariables().put("dbName", dbName);
-
-               super.writeBackup(targetFo);
-       }
-
-       public void setDbUser(String dbUser) {
-               this.dbUser = dbUser;
-       }
-
-       public void setDbPassword(String dbPassword) {
-               this.dbPassword = dbPassword;
-       }
-
-       public void setDbName(String dbName) {
-               this.dbName = dbName;
-       }
-
-       public void setPgDumpLocation(String mysqldumpLocation) {
-               this.pgDumpLocation = mysqldumpLocation;
-       }
-
-}
diff --git a/cms/org.argeo.slc.cms/src/org/argeo/slc/backup/vfs/SimpleBackupContext.java b/cms/org.argeo.slc.cms/src/org/argeo/slc/backup/vfs/SimpleBackupContext.java
deleted file mode 100644 (file)
index 9ee6871..0000000
+++ /dev/null
@@ -1,48 +0,0 @@
-package org.argeo.slc.backup.vfs;
-
-import java.text.DateFormat;
-import java.text.SimpleDateFormat;
-import java.util.Date;
-
-import org.apache.commons.vfs2.FileSystemManager;
-
-/** Simple implementation of a backup context */
-public class SimpleBackupContext implements BackupContext {
-       private DateFormat dateFormat = new SimpleDateFormat("yyyyMMdd_HHmm");
-       private final Date timestamp;
-       private final String name;
-
-       private final FileSystemManager fileSystemManager;
-
-       public SimpleBackupContext(FileSystemManager fileSystemManager,
-                       String backupsBase, String name) {
-               this.name = name;
-               this.timestamp = new Date();
-               this.fileSystemManager = fileSystemManager;
-       }
-
-       public Date getTimestamp() {
-               return timestamp;
-       }
-
-       public String getTimestampAsString() {
-               return dateFormat.format(timestamp);
-       }
-
-       public String getSystemName() {
-               return name;
-       }
-
-       public String getRelativeFolder() {
-               return name + '/' + getTimestampAsString();
-       }
-
-       public DateFormat getDateFormat() {
-               return dateFormat;
-       }
-
-       public FileSystemManager getFileSystemManager() {
-               return fileSystemManager;
-       }
-
-}
diff --git a/cms/org.argeo.slc.cms/src/org/argeo/slc/backup/vfs/SimpleBackupPurge.java b/cms/org.argeo.slc.cms/src/org/argeo/slc/backup/vfs/SimpleBackupPurge.java
deleted file mode 100644 (file)
index 0871109..0000000
+++ /dev/null
@@ -1,71 +0,0 @@
-package org.argeo.slc.backup.vfs;
-
-import java.text.DateFormat;
-import java.time.Period;
-import java.time.ZoneId;
-import java.time.ZonedDateTime;
-import java.util.Date;
-import java.util.SortedMap;
-import java.util.TreeMap;
-
-import org.apache.commons.vfs2.FileObject;
-import org.apache.commons.vfs2.FileSystemManager;
-import org.apache.commons.vfs2.FileSystemOptions;
-import org.apache.commons.vfs2.Selectors;
-import org.argeo.api.cms.CmsLog;
-
-/** Simple backup purge which keeps backups only for a given number of days */
-public class SimpleBackupPurge implements BackupPurge {
-       private final static CmsLog log = CmsLog.getLog(SimpleBackupPurge.class);
-
-       private Integer daysKept = 30;
-
-       @Override
-       public void purge(FileSystemManager fileSystemManager, String base, String name, DateFormat dateFormat,
-                       FileSystemOptions opts) {
-               try {
-                       ZonedDateTime nowDt = ZonedDateTime.now();
-                       FileObject baseFo = fileSystemManager.resolveFile(base + '/' + name, opts);
-
-                       SortedMap<ZonedDateTime, FileObject> toDelete = new TreeMap<ZonedDateTime, FileObject>();
-                       int backupCount = 0;
-
-                       // make sure base dir exists
-                       baseFo.createFolder();
-
-                       // scan backups and list those which should be deleted
-                       for (FileObject backupFo : baseFo.getChildren()) {
-                               String backupName = backupFo.getName().getBaseName();
-                               Date backupDate = dateFormat.parse(backupName);
-                               backupCount++;
-                               ZonedDateTime backupDt = ZonedDateTime.ofInstant(backupDate.toInstant(), ZoneId.systemDefault());
-                               Period sinceThen = Period.between(backupDt.toLocalDate(), nowDt.toLocalDate());
-                               // new Period(backupDt, nowDt);
-                               int days = sinceThen.getDays();
-                               // int days = sinceThen.getMinutes();
-                               if (days > daysKept) {
-                                       toDelete.put(backupDt, backupFo);
-                               }
-                       }
-
-                       if (toDelete.size() != 0 && toDelete.size() == backupCount) {
-                               // all backups would be deleted
-                               // but we want to keep at least one
-                               ZonedDateTime lastBackupDt = toDelete.firstKey();
-                               FileObject keptFo = toDelete.remove(lastBackupDt);
-                               log.warn("Backup " + keptFo + " kept although it is older than " + daysKept + " days.");
-                       }
-
-                       // delete old backups
-                       for (FileObject backupFo : toDelete.values()) {
-                               backupFo.delete(Selectors.SELECT_ALL);
-                               if (log.isDebugEnabled())
-                                       log.debug("Deleted backup " + backupFo);
-                       }
-               } catch (Exception e) {
-                       throw new MaintenanceException("Could not purge previous backups", e);
-               }
-
-       }
-
-}
diff --git a/cms/org.argeo.slc.cms/src/org/argeo/slc/backup/vfs/SvnBackup.java b/cms/org.argeo.slc.cms/src/org/argeo/slc/backup/vfs/SvnBackup.java
deleted file mode 100644 (file)
index ea9f844..0000000
+++ /dev/null
@@ -1,55 +0,0 @@
-package org.argeo.slc.backup.vfs;
-
-import java.io.File;
-
-import org.apache.commons.vfs2.FileObject;
-
-/** Backups a Subversion repository using svnadmin. */
-public class SvnBackup extends OsCallBackup {
-       private String svnadminLocation = "/usr/bin/svnadmin";
-
-       private String repoLocation;
-       private String repoName;
-
-       public SvnBackup() {
-       }
-
-       public SvnBackup(String repoLocation) {
-               this.repoLocation = repoLocation;
-               init();
-       }
-
-       @Override
-       public void init() {
-               // use directory as repo name
-               if (repoName == null)
-                       repoName = new File(repoLocation).getName();
-
-               if (getName() == null)
-                       setName(repoName + ".svndump");
-               super.init();
-       }
-
-       @Override
-       public void writeBackup(FileObject targetFo) {
-               if (getCommand() == null) {
-                       setCommand(svnadminLocation + " dump " + " ${repoLocation}");
-               }
-               getVariables().put("repoLocation", repoLocation);
-
-               super.writeBackup(targetFo);
-       }
-
-       public void setRepoLocation(String repoLocation) {
-               this.repoLocation = repoLocation;
-       }
-
-       public void setRepoName(String repoName) {
-               this.repoName = repoName;
-       }
-
-       public void setSvnadminLocation(String mysqldumpLocation) {
-               this.svnadminLocation = mysqldumpLocation;
-       }
-
-}
diff --git a/cms/org.argeo.slc.cms/src/org/argeo/slc/backup/vfs/SystemBackup.java b/cms/org.argeo.slc.cms/src/org/argeo/slc/backup/vfs/SystemBackup.java
deleted file mode 100644 (file)
index 7f23d72..0000000
+++ /dev/null
@@ -1,199 +0,0 @@
-package org.argeo.slc.backup.vfs;
-
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-import org.apache.commons.vfs2.FileObject;
-import org.apache.commons.vfs2.FileSystemException;
-import org.apache.commons.vfs2.FileSystemManager;
-import org.apache.commons.vfs2.FileSystemOptions;
-import org.apache.commons.vfs2.Selectors;
-import org.apache.commons.vfs2.UserAuthenticator;
-import org.apache.commons.vfs2.impl.DefaultFileSystemConfigBuilder;
-import org.argeo.api.cms.CmsLog;
-import org.argeo.util.LangUtils;
-
-/**
- * Combines multiple backups and transfer them to a remote location. Purges
- * remote and local data based on certain criteria.
- */
-public class SystemBackup implements Runnable {
-       private final static CmsLog log = CmsLog.getLog(SystemBackup.class);
-
-       private FileSystemManager fileSystemManager;
-       private UserAuthenticator userAuthenticator = null;
-
-       private String backupsBase;
-       private String systemName;
-
-       private List<AtomicBackup> atomicBackups = new ArrayList<AtomicBackup>();
-       private BackupPurge backupPurge = new SimpleBackupPurge();
-
-       private Map<String, UserAuthenticator> remoteBases = new HashMap<String, UserAuthenticator>();
-
-       @Override
-       public void run() {
-               if (atomicBackups.size() == 0)
-                       throw new MaintenanceException("No atomic backup listed");
-               List<String> failures = new ArrayList<String>();
-
-               SimpleBackupContext backupContext = new SimpleBackupContext(fileSystemManager, backupsBase, systemName);
-
-               // purge older backups
-               FileSystemOptions opts = new FileSystemOptions();
-               try {
-                       DefaultFileSystemConfigBuilder.getInstance().setUserAuthenticator(opts, userAuthenticator);
-               } catch (Exception e) {
-                       throw new MaintenanceException("Cannot create authentication", e);
-               }
-
-               try {
-
-                       backupPurge.purge(fileSystemManager, backupsBase, systemName, backupContext.getDateFormat(), opts);
-               } catch (Exception e) {
-                       failures.add("Purge " + backupsBase + " failed: " + e.getMessage());
-                       log.error("Purge of " + backupsBase + " failed", e);
-               }
-
-               // perform backup
-               for (AtomicBackup atomickBackup : atomicBackups) {
-                       try {
-                               String target = atomickBackup.backup(fileSystemManager, backupsBase, backupContext, opts);
-                               if (log.isDebugEnabled())
-                                       log.debug("Performed backup " + target);
-                       } catch (Exception e) {
-                               String msg = "Atomic backup " + atomickBackup.getName() + " failed: "
-                                               + LangUtils.chainCausesMessages(e);
-                               failures.add(msg);
-                               log.error(msg);
-                               if (log.isTraceEnabled())
-                                       log.trace("Stacktrace of atomic backup " + atomickBackup.getName() + " failure.", e);
-                       }
-               }
-
-               // dispatch to remote
-               for (String remoteBase : remoteBases.keySet()) {
-                       FileObject localBaseFo = null;
-                       FileObject remoteBaseFo = null;
-                       UserAuthenticator auth = remoteBases.get(remoteBase);
-
-                       // authentication
-                       FileSystemOptions remoteOpts = new FileSystemOptions();
-                       try {
-                               DefaultFileSystemConfigBuilder.getInstance().setUserAuthenticator(remoteOpts, auth);
-                               backupPurge.purge(fileSystemManager, remoteBase, systemName, backupContext.getDateFormat(), remoteOpts);
-                       } catch (Exception e) {
-                               failures.add("Purge " + remoteBase + " failed: " + e.getMessage());
-                               log.error("Cannot purge " + remoteBase, e);
-                       }
-
-                       try {
-                               localBaseFo = fileSystemManager.resolveFile(backupsBase + '/' + backupContext.getRelativeFolder(),
-                                               opts);
-                               remoteBaseFo = fileSystemManager.resolveFile(remoteBase + '/' + backupContext.getRelativeFolder(),
-                                               remoteOpts);
-                               remoteBaseFo.copyFrom(localBaseFo, Selectors.SELECT_ALL);
-                               if (log.isDebugEnabled())
-                                       log.debug("Copied backup to " + remoteBaseFo + " from " + localBaseFo);
-                               // }
-                       } catch (Exception e) {
-                               failures.add("Dispatch to " + remoteBase + " failed: " + e.getMessage());
-                               log.error("Cannot dispatch backups from " + backupContext.getRelativeFolder() + " to " + remoteBase, e);
-                       }
-                       BackupUtils.closeFOQuietly(localBaseFo);
-                       BackupUtils.closeFOQuietly(remoteBaseFo);
-               }
-
-               int failureCount = 0;
-               if (failures.size() > 0) {
-                       StringBuffer buf = new StringBuffer();
-                       for (String failure : failures) {
-                               buf.append('\n').append(failureCount).append(" - ").append(failure);
-                               failureCount++;
-                       }
-                       throw new MaintenanceException(failureCount + " error(s) when running the backup,"
-                                       + " check the logs and the backups as soon as possible." + buf);
-               }
-       }
-
-       public void setFileSystemManager(FileSystemManager fileSystemManager) {
-               this.fileSystemManager = fileSystemManager;
-       }
-
-       public void setBackupsBase(String backupsBase) {
-               this.backupsBase = backupsBase;
-       }
-
-       public void setSystemName(String name) {
-               this.systemName = name;
-       }
-
-       public void setAtomicBackups(List<AtomicBackup> atomicBackups) {
-               this.atomicBackups = atomicBackups;
-       }
-
-       public void setBackupPurge(BackupPurge backupPurge) {
-               this.backupPurge = backupPurge;
-       }
-
-       public void setUserAuthenticator(UserAuthenticator userAuthenticator) {
-               this.userAuthenticator = userAuthenticator;
-       }
-
-       public void setRemoteBases(Map<String, UserAuthenticator> remoteBases) {
-               this.remoteBases = remoteBases;
-       }
-
-       // public static void main(String args[]) {
-       // while (true) {
-       // try {
-       // StandardFileSystemManager fsm = new StandardFileSystemManager();
-       // fsm.init();
-       //
-       // SystemBackup systemBackup = new SystemBackup();
-       // systemBackup.setSystemName("mySystem");
-       // systemBackup
-       // .setBackupsBase("/home/mbaudier/dev/src/commons/server/runtime/org.argeo.server.core/target");
-       // systemBackup.setFileSystemManager(fsm);
-       //
-       // List<AtomicBackup> atomicBackups = new ArrayList<AtomicBackup>();
-       //
-       // MySqlBackup mySqlBackup = new MySqlBackup("root", "", "test");
-       // atomicBackups.add(mySqlBackup);
-       // PostgreSqlBackup postgreSqlBackup = new PostgreSqlBackup(
-       // "argeo", "argeo", "gis_template");
-       // atomicBackups.add(postgreSqlBackup);
-       // SvnBackup svnBackup = new SvnBackup(
-       // "/home/mbaudier/tmp/testsvnrepo");
-       // atomicBackups.add(svnBackup);
-       //
-       // systemBackup.setAtomicBackups(atomicBackups);
-       //
-       // Map<String, UserAuthenticator> remoteBases = new HashMap<String,
-       // UserAuthenticator>();
-       // StaticUserAuthenticator userAuthenticator = new StaticUserAuthenticator(
-       // null, "demo", "demo");
-       // remoteBases.put("sftp://localhost/home/mbaudier/test",
-       // userAuthenticator);
-       // systemBackup.setRemoteBases(remoteBases);
-       //
-       // systemBackup.run();
-       //
-       // fsm.close();
-       // } catch (FileSystemException e) {
-       // // TODO Auto-generated catch block
-       // e.printStackTrace();
-       // System.exit(1);
-       // }
-       //
-       // // wait
-       // try {
-       // Thread.sleep(120 * 1000);
-       // } catch (InterruptedException e) {
-       // e.printStackTrace();
-       // }
-       // }
-       // }
-}
diff --git a/cms/org.argeo.slc.cms/src/org/argeo/slc/backup/vfs/package-info.java b/cms/org.argeo.slc.cms/src/org/argeo/slc/backup/vfs/package-info.java
deleted file mode 100644 (file)
index f70499d..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-/** Argeo Node backup utilities based on Apache Commons VFS. */
-package org.argeo.slc.backup.vfs;
\ No newline at end of file
diff --git a/cms/org.argeo.slc.cms/src/org/argeo/slc/cms/deploy/CmsDeployedSystem.java b/cms/org.argeo.slc.cms/src/org/argeo/slc/cms/deploy/CmsDeployedSystem.java
deleted file mode 100644 (file)
index feec64f..0000000
+++ /dev/null
@@ -1,7 +0,0 @@
-package org.argeo.slc.cms.deploy;
-
-import org.argeo.slc.deploy.DeployedSystem;
-
-public interface CmsDeployedSystem extends DeployedSystem {
-
-}
diff --git a/cms/org.argeo.slc.cms/src/org/argeo/slc/cms/deploy/CmsDeploymentData.java b/cms/org.argeo.slc.cms/src/org/argeo/slc/cms/deploy/CmsDeploymentData.java
deleted file mode 100644 (file)
index 17cecd8..0000000
+++ /dev/null
@@ -1,9 +0,0 @@
-package org.argeo.slc.cms.deploy;
-
-import java.util.List;
-
-import org.argeo.slc.deploy.DeploymentData;
-
-public interface CmsDeploymentData extends DeploymentData {
-       List<String> getModulesToActivate(int startLevel);
-}
diff --git a/cms/org.argeo.slc.cms/src/org/argeo/slc/cms/deploy/CmsTargetData.java b/cms/org.argeo.slc.cms/src/org/argeo/slc/cms/deploy/CmsTargetData.java
deleted file mode 100644 (file)
index 4616b20..0000000
+++ /dev/null
@@ -1,12 +0,0 @@
-package org.argeo.slc.cms.deploy;
-
-import java.nio.file.Path;
-
-import org.argeo.slc.deploy.TargetData;
-
-public interface CmsTargetData extends TargetData {
-       Path getInstanceData();
-
-       Integer getHttpPort();
-
-}
diff --git a/cms/org.argeo.slc.cms/src/org/argeo/slc/cms/deploy/SimpleCmsDeploymentData.java b/cms/org.argeo.slc.cms/src/org/argeo/slc/cms/deploy/SimpleCmsDeploymentData.java
deleted file mode 100644 (file)
index c95f441..0000000
+++ /dev/null
@@ -1,17 +0,0 @@
-package org.argeo.slc.cms.deploy;
-
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Map;
-import java.util.TreeMap;
-
-public class SimpleCmsDeploymentData implements CmsDeploymentData {
-       private Map<Integer, List<String>> startLevels = new TreeMap<>();
-
-       @Override
-       public List<String> getModulesToActivate(int startLevel) {
-               startLevels.putIfAbsent(startLevel, new ArrayList<>());
-               return startLevels.get(startLevel);
-       }
-
-}
diff --git a/cms/org.argeo.slc.cms/src/org/argeo/slc/cms/deploy/SimpleCmsTargetData.java b/cms/org.argeo.slc.cms/src/org/argeo/slc/cms/deploy/SimpleCmsTargetData.java
deleted file mode 100644 (file)
index ecf17d6..0000000
+++ /dev/null
@@ -1,30 +0,0 @@
-package org.argeo.slc.cms.deploy;
-
-import java.nio.file.Path;
-
-public class SimpleCmsTargetData implements CmsTargetData {
-       private Path instanceData;
-       private Integer httpPort;
-
-       public SimpleCmsTargetData(Path instanceData, Integer httpPort) {
-               this.instanceData = instanceData;
-               this.httpPort = httpPort;
-       }
-
-       public Integer getHttpPort() {
-               return httpPort;
-       }
-
-       public void setHttpPort(Integer httpPort) {
-               this.httpPort = httpPort;
-       }
-
-       public Path getInstanceData() {
-               return instanceData;
-       }
-
-       public void setInstanceData(Path instanceData) {
-               this.instanceData = instanceData;
-       }
-
-}
diff --git a/cms/org.argeo.slc.cms/src/org/argeo/slc/cms/deploy/osgi/CmsOsgiDeployedSystem.java b/cms/org.argeo.slc.cms/src/org/argeo/slc/cms/deploy/osgi/CmsOsgiDeployedSystem.java
deleted file mode 100644 (file)
index 8de4354..0000000
+++ /dev/null
@@ -1,49 +0,0 @@
-package org.argeo.slc.cms.deploy.osgi;
-
-import org.argeo.slc.build.Distribution;
-import org.argeo.slc.build.ModularDistribution;
-import org.argeo.slc.cms.deploy.CmsDeployedSystem;
-import org.argeo.slc.cms.deploy.CmsDeploymentData;
-import org.argeo.slc.cms.deploy.CmsTargetData;
-import org.argeo.slc.deploy.DeploymentData;
-import org.argeo.slc.deploy.TargetData;
-import org.osgi.framework.BundleContext;
-
-public class CmsOsgiDeployedSystem implements CmsDeployedSystem {
-       private ModularDistribution distribution;
-       private CmsTargetData targetData;
-       private CmsDeploymentData deploymentData;
-
-       private BundleContext systemBundleContext;
-
-       public CmsOsgiDeployedSystem(BundleContext systemBundleContext, ModularDistribution distribution,
-                       CmsTargetData targetData, CmsDeploymentData deploymentData) {
-               this.systemBundleContext = systemBundleContext;
-
-               this.distribution = distribution;
-               this.targetData = targetData;
-               this.deploymentData = deploymentData;
-       }
-
-       @Override
-       public String getDeployedSystemId() {
-               // TODO Auto-generated method stub
-               return null;
-       }
-
-       @Override
-       public Distribution getDistribution() {
-               return distribution;
-       }
-
-       @Override
-       public DeploymentData getDeploymentData() {
-               return deploymentData;
-       }
-
-       @Override
-       public TargetData getTargetData() {
-               return targetData;
-       }
-
-}
diff --git a/cms/org.argeo.slc.cms/src/org/argeo/slc/cms/deploy/osgi/CmsOsgiDeployment.java b/cms/org.argeo.slc.cms/src/org/argeo/slc/cms/deploy/osgi/CmsOsgiDeployment.java
deleted file mode 100644 (file)
index 3c0cf7c..0000000
+++ /dev/null
@@ -1,182 +0,0 @@
-package org.argeo.slc.cms.deploy.osgi;
-
-import java.io.IOException;
-import java.lang.System.Logger;
-import java.lang.System.Logger.Level;
-import java.nio.file.Files;
-import java.nio.file.Path;
-import java.nio.file.Paths;
-import java.util.List;
-import java.util.Map;
-import java.util.StringJoiner;
-import java.util.TreeMap;
-
-import org.argeo.init.a2.A2Source;
-import org.argeo.init.a2.FsA2Source;
-import org.argeo.init.osgi.OsgiBoot;
-import org.argeo.init.osgi.OsgiRuntimeContext;
-import org.argeo.slc.WellKnownConstants;
-import org.argeo.slc.build.Distribution;
-import org.argeo.slc.cms.deploy.CmsDeployedSystem;
-import org.argeo.slc.cms.deploy.CmsDeploymentData;
-import org.argeo.slc.cms.deploy.CmsTargetData;
-import org.argeo.slc.cms.deploy.SimpleCmsDeploymentData;
-import org.argeo.slc.cms.deploy.SimpleCmsTargetData;
-import org.argeo.slc.cms.distribution.A2Distribution;
-import org.argeo.slc.deploy.DeployedSystem;
-import org.argeo.slc.deploy.Deployment;
-import org.argeo.slc.deploy.DeploymentData;
-import org.argeo.slc.deploy.TargetData;
-
-public class CmsOsgiDeployment implements Deployment {
-       private final static Logger logger = System.getLogger(CmsOsgiDeployment.class.getName());
-
-       private A2Distribution distribution;
-       private CmsTargetData targetData;
-       private CmsDeploymentData deploymentData;
-
-       private CmsDeployedSystem deployedSystem;
-
-       private OsgiRuntimeContext runtimeContext;
-
-       @Override
-       public void run() {
-               try {
-                       Map<String, String> config = new TreeMap<>();
-
-                       // sources
-                       StringJoiner sourcesProperty = new StringJoiner(",");
-                       for (A2Source a2Source : distribution.getA2Sources()) {
-                               sourcesProperty.add(a2Source.getUri().toString());
-                       }
-                       config.put(OsgiBoot.PROP_ARGEO_OSGI_SOURCES, sourcesProperty.toString());
-
-                       // target
-                       config.put(WellKnownConstants.OSGI_INSTANCE_AREA,
-                                       targetData.getInstanceData().toRealPath().toUri().toString());
-                       if (targetData.getHttpPort() != null) {
-                               config.put(WellKnownConstants.OSGI_HTTP_PORT, targetData.getHttpPort().toString());
-                       }
-
-                       Path configurationArea = Files.createTempDirectory("slc-cms-test");
-                       config.put(WellKnownConstants.OSGI_CONFIGURATION_AREA, configurationArea.toUri().toString());
-
-                       // modules activation
-                       for (int startLevel = 0; startLevel <= 6; startLevel++) {
-                               List<String> modules = deploymentData.getModulesToActivate(startLevel);
-                               if (modules.size() != 0) {
-                                       String startProperty = String.join(",", modules);
-                                       config.put(OsgiBoot.PROP_ARGEO_OSGI_START + "." + startLevel + ".node", startProperty);
-                               }
-                       }
-
-                       config.put("org.eclipse.equinox.http.jetty.autostart", "false");
-                       config.put("org.osgi.framework.bootdelegation",
-                                       "com.sun.jndi.ldap,com.sun.jndi.ldap.sasl,com.sun.security.jgss,com.sun.jndi.dns,com.sun.nio.file,com.sun.nio.sctp");
-                       config.put("eclipse.ignoreApp", "true");
-                       config.put("osgi.noShutdown", "true");
-
-//                     config.put("osgi.console", "true");
-
-                       // initialise
-                       for (String key : config.keySet()) {
-//                             System.out.println(key + "=" + config.get(key));
-                               logger.log(Level.INFO, () -> key + "=" + config.get(key));
-                       }
-
-                       runtimeContext = new OsgiRuntimeContext(config);
-                       runtimeContext.run();
-
-                       deployedSystem = new CmsOsgiDeployedSystem(runtimeContext.getFramework().getBundleContext(), distribution,
-                                       targetData, deploymentData);
-
-               } catch (Exception e) {
-                       throw new IllegalStateException("Cannot run OSGi deployment", e);
-               }
-
-       }
-
-       @Override
-       public DeployedSystem getDeployedSystem() {
-               return deployedSystem;
-       }
-
-       @Override
-       public void setTargetData(TargetData targetData) {
-               this.targetData = (CmsTargetData) targetData;
-       }
-
-       @Override
-       public void setDeploymentData(DeploymentData deploymentData) {
-               this.deploymentData = (CmsDeploymentData) deploymentData;
-       }
-
-       @Override
-       public void setDistribution(Distribution distribution) {
-               this.distribution = (A2Distribution) distribution;
-       }
-
-       public OsgiRuntimeContext getRuntimeContext() {
-               return runtimeContext;
-       }
-
-       public static void main(String[] args) {
-               try {
-                       Path userHome = Paths.get(System.getProperty("user.home"));
-
-                       // distribution
-                       Path a2Base = userHome.resolve("dev/git/unstable/output/a2");
-                       A2Distribution distribution = new A2Distribution();
-                       distribution.getA2Sources().add(new FsA2Source(a2Base));
-
-                       // target data
-                       Path instanceData = userHome.resolve("dev/git/unstable/argeo-slc/sdk/exec/cms-deployment/data");
-                       Files.createDirectories(instanceData);
-                       Integer httpPort = 7070;
-                       SimpleCmsTargetData targetData = new SimpleCmsTargetData(instanceData, httpPort);
-
-                       // deployment data
-                       SimpleCmsDeploymentData deploymentData = new SimpleCmsDeploymentData();
-                       deploymentData.getModulesToActivate(2).add("org.eclipse.equinox.http.servlet");
-                       deploymentData.getModulesToActivate(2).add("org.eclipse.equinox.cm");
-                       deploymentData.getModulesToActivate(2).add("org.apache.felix.scr");
-                       deploymentData.getModulesToActivate(2).add("org.eclipse.rap.rwt.osgi");
-
-                       deploymentData.getModulesToActivate(3).add("org.argeo.cms");
-
-                       deploymentData.getModulesToActivate(4).add("org.argeo.cms.servlet");
-                       deploymentData.getModulesToActivate(4).add("org.argeo.cms.ui.rap");
-                       deploymentData.getModulesToActivate(4).add("org.argeo.cms.jcr");
-
-                       deploymentData.getModulesToActivate(5).add("org.argeo.cms.e4.rap");
-
-                       CmsOsgiDeployment deployment = new CmsOsgiDeployment();
-                       deployment.setDistribution(distribution);
-                       deployment.setTargetData(targetData);
-                       deployment.setDeploymentData(deploymentData);
-                       deployment.run();
-
-                       boolean multiple = false;
-                       if (multiple) {
-
-                               Path instanceData2 = userHome.resolve("dev/git/unstable/argeo-slc/sdk/exec/cms-deployment2/data");
-                               Files.createDirectories(instanceData2);
-                               Integer httpPort2 = 7071;
-                               SimpleCmsTargetData targetData2 = new SimpleCmsTargetData(instanceData2, httpPort2);
-
-                               CmsOsgiDeployment deployment2 = new CmsOsgiDeployment();
-                               deployment2.setDistribution(distribution);
-                               deployment2.setTargetData(targetData2);
-                               deployment2.setDeploymentData(deploymentData);
-                               deployment2.run();
-                       }
-
-                       deployment.getRuntimeContext().waitForStop(0);
-
-               } catch (IOException | InterruptedException e) {
-                       e.printStackTrace();
-                       System.exit(1);
-               }
-       }
-
-}
diff --git a/cms/org.argeo.slc.cms/src/org/argeo/slc/cms/distribution/A2Distribution.java b/cms/org.argeo.slc.cms/src/org/argeo/slc/cms/distribution/A2Distribution.java
deleted file mode 100644 (file)
index 6c8bbe7..0000000
+++ /dev/null
@@ -1,75 +0,0 @@
-package org.argeo.slc.cms.distribution;
-
-import java.util.ArrayList;
-import java.util.Iterator;
-import java.util.List;
-
-import org.argeo.init.a2.A2Branch;
-import org.argeo.init.a2.A2Component;
-import org.argeo.init.a2.A2Contribution;
-import org.argeo.init.a2.A2Module;
-import org.argeo.init.a2.A2Source;
-import org.argeo.slc.CategoryNameVersion;
-import org.argeo.slc.DefaultCategoryNameVersion;
-import org.argeo.slc.NameVersion;
-import org.argeo.slc.build.Distribution;
-import org.argeo.slc.build.ModularDistribution;
-
-public class A2Distribution implements ModularDistribution {
-       private List<A2Source> a2Sources = new ArrayList<>();
-
-       @Override
-       public String getDistributionId() {
-               // TODO Auto-generated method stub
-               return null;
-       }
-
-       @Override
-       public String getName() {
-               // TODO Auto-generated method stub
-               return null;
-       }
-
-       @Override
-       public String getVersion() {
-               // TODO Auto-generated method stub
-               return null;
-       }
-
-       @Override
-       public Iterator<? extends NameVersion> nameVersions() {
-               List<CategoryNameVersion> nameVersions = new ArrayList<>();
-               for (A2Source a2Source : a2Sources) {
-                       for (A2Contribution a2Contribution : a2Source.listContributions(null)) {
-                               for (A2Component a2Component : a2Contribution.listComponents(null)) {
-                                       for (A2Branch a2Branch : a2Component.listBranches(null)) {
-                                               for (A2Module a2Module : a2Branch.listModules(null)) {
-                                                       CategoryNameVersion nameVersion = new DefaultCategoryNameVersion(a2Contribution.getId(),
-                                                                       a2Component.getId(), a2Module.getVersion().toString());
-                                                       nameVersions.add(nameVersion);
-                                               }
-                                       }
-                               }
-                       }
-               }
-               return nameVersions.iterator();
-       }
-
-       @Override
-       public Distribution getModuleDistribution(String moduleName, String moduleVersion) {
-               // TODO Auto-generated method stub
-               return null;
-       }
-
-       @Override
-       public Object getModulesDescriptor(String descriptorType) {
-               // TODO Auto-generated method stub
-               return null;
-       }
-
-       public List<A2Source> getA2Sources() {
-               return a2Sources;
-       }
-
-       
-}
diff --git a/cms/org.argeo.slc.cms/src/org/argeo/slc/cms/distribution/A2ModuleDistribution.java b/cms/org.argeo.slc.cms/src/org/argeo/slc/cms/distribution/A2ModuleDistribution.java
deleted file mode 100644 (file)
index cc7e681..0000000
+++ /dev/null
@@ -1,14 +0,0 @@
-package org.argeo.slc.cms.distribution;
-
-import org.argeo.init.a2.A2Module;
-import org.argeo.slc.build.Distribution;
-
-public class A2ModuleDistribution implements Distribution {
-       private A2Module a2Module;
-
-       @Override
-       public String getDistributionId() {
-               return a2Module.getCoordinates();
-       }
-
-}
diff --git a/cms/org.argeo.slc.cms/src/org/argeo/slc/cms/httpclient3/HttpCredentialProvider.java b/cms/org.argeo.slc.cms/src/org/argeo/slc/cms/httpclient3/HttpCredentialProvider.java
deleted file mode 100644 (file)
index 59cfc4f..0000000
+++ /dev/null
@@ -1,20 +0,0 @@
-package org.argeo.slc.cms.httpclient3;
-
-import org.apache.commons.httpclient.Credentials;
-import org.apache.commons.httpclient.auth.AuthScheme;
-import org.apache.commons.httpclient.auth.CredentialsNotAvailableException;
-import org.apache.commons.httpclient.auth.CredentialsProvider;
-
-/** SPNEGO credential provider */
-public class HttpCredentialProvider implements CredentialsProvider {
-
-       @Override
-       public Credentials getCredentials(AuthScheme scheme, String host, int port, boolean proxy)
-                       throws CredentialsNotAvailableException {
-               if (scheme instanceof SpnegoAuthScheme)
-                       return new SpnegoCredentials();
-               else
-                       throw new UnsupportedOperationException("Auth scheme " + scheme.getSchemeName() + " not supported");
-       }
-
-}
diff --git a/cms/org.argeo.slc.cms/src/org/argeo/slc/cms/httpclient3/SpnegoAuthScheme.java b/cms/org.argeo.slc.cms/src/org/argeo/slc/cms/httpclient3/SpnegoAuthScheme.java
deleted file mode 100644 (file)
index a28559a..0000000
+++ /dev/null
@@ -1,179 +0,0 @@
-package org.argeo.slc.cms.httpclient3;
-
-import java.net.URL;
-import java.security.PrivilegedExceptionAction;
-import java.util.ArrayList;
-
-import javax.security.auth.Subject;
-import javax.security.auth.login.LoginContext;
-
-import org.apache.commons.httpclient.Credentials;
-import org.apache.commons.httpclient.HttpClient;
-import org.apache.commons.httpclient.HttpMethod;
-import org.apache.commons.httpclient.auth.AuthPolicy;
-import org.apache.commons.httpclient.auth.AuthScheme;
-import org.apache.commons.httpclient.auth.AuthenticationException;
-import org.apache.commons.httpclient.auth.CredentialsProvider;
-import org.apache.commons.httpclient.auth.MalformedChallengeException;
-import org.apache.commons.httpclient.methods.GetMethod;
-import org.apache.commons.httpclient.params.DefaultHttpParams;
-import org.apache.commons.httpclient.params.HttpMethodParams;
-import org.apache.commons.httpclient.params.HttpParams;
-import org.argeo.cms.auth.RemoteAuthUtils;
-
-//// Register client-side SPNEGO auth scheme
-//AuthPolicy.registerAuthScheme(SpnegoAuthScheme.NAME, SpnegoAuthScheme.class);
-//HttpParams params = DefaultHttpParams.getDefaultParams();
-//ArrayList<String> schemes = new ArrayList<>();
-//schemes.add(SpnegoAuthScheme.NAME);// SPNEGO preferred
-//// schemes.add(AuthPolicy.BASIC);// incompatible with Basic
-//params.setParameter(AuthPolicy.AUTH_SCHEME_PRIORITY, schemes);
-//params.setParameter(CredentialsProvider.PROVIDER, new HttpCredentialProvider());
-//params.setParameter(HttpMethodParams.COOKIE_POLICY, KernelConstants.COOKIE_POLICY_BROWSER_COMPATIBILITY);
-//// params.setCookiePolicy(CookiePolicy.BROWSER_COMPATIBILITY);
-
-
-
-/** Implementation of the SPNEGO auth scheme. */
-public class SpnegoAuthScheme implements AuthScheme {
-//     private final static Log log = LogFactory.getLog(SpnegoAuthScheme.class);
-
-       public static final String NAME = "Negotiate";
-//     private final static Oid KERBEROS_OID;
-//     static {
-//             try {
-//                     KERBEROS_OID = new Oid("1.3.6.1.5.5.2");
-//             } catch (GSSException e) {
-//                     throw new IllegalStateException("Cannot create Kerberos OID", e);
-//             }
-//     }
-
-       private final static String DEFAULT_KERBEROS_SERVICE = "HTTP";
-
-       private boolean complete = false;
-       private String realm;
-
-       @Override
-       public void processChallenge(String challenge) throws MalformedChallengeException {
-               // if(tokenStr!=null){
-               // log.error("Received challenge while there is a token. Failing.");
-               // complete = false;
-               // }
-
-       }
-
-       @Override
-       public String getSchemeName() {
-               return NAME;
-       }
-
-       @Override
-       public String getParameter(String name) {
-               return null;
-       }
-
-       @Override
-       public String getRealm() {
-               return realm;
-       }
-
-       @Override
-       public String getID() {
-               return NAME;
-       }
-
-       @Override
-       public boolean isConnectionBased() {
-               return true;
-       }
-
-       @Override
-       public boolean isComplete() {
-               return complete;
-       }
-
-       @Override
-       public String authenticate(Credentials credentials, String method, String uri) throws AuthenticationException {
-               // log.debug("authenticate " + method + " " + uri);
-               // return null;
-               throw new UnsupportedOperationException();
-       }
-
-       @Override
-       public String authenticate(Credentials credentials, HttpMethod method) throws AuthenticationException {
-//             GSSContext context = null;
-               String hostname;
-               try {
-                       hostname = method.getURI().getHost();
-                       String tokenStr = RemoteAuthUtils.createGssToken(null, DEFAULT_KERBEROS_SERVICE, hostname);
-                       return "Negotiate " + tokenStr;
-               } catch (Exception e1) {
-                       complete = true;
-                       throw new AuthenticationException("Cannot authenticate " + method, e1);
-               }
-//             String serverPrinc = DEFAULT_KERBEROS_SERVICE + "@" + hostname;
-//
-//             try {
-//                     // Get service's principal name
-//                     GSSManager manager = GSSManager.getInstance();
-//                     GSSName serverName = manager.createName(serverPrinc, GSSName.NT_HOSTBASED_SERVICE, KERBEROS_OID);
-//
-//                     // Get the context for authentication
-//                     context = manager.createContext(serverName, KERBEROS_OID, null, GSSContext.DEFAULT_LIFETIME);
-//                     // context.requestMutualAuth(true); // Request mutual authentication
-//                     // context.requestConf(true); // Request confidentiality
-//                     context.requestCredDeleg(true);
-//
-//                     byte[] token = new byte[0];
-//
-//                     // token is ignored on the first call
-//                     token = context.initSecContext(token, 0, token.length);
-//
-//                     // Send a token to the server if one was generated by
-//                     // initSecContext
-//                     if (token != null) {
-//                             tokenStr = Base64.getEncoder().encodeToString(token);
-//                             // complete=true;
-//                     }
-//             } catch (GSSException e) {
-//                     complete = true;
-//                     throw new AuthenticationException("Cannot authenticate to " + serverPrinc, e);
-//             }
-       }
-
-       public static void main(String[] args) {
-               String principal = System.getProperty("javax.security.auth.login.name");
-               if (args.length == 0 || principal == null) {
-                       System.err.println("usage: java -Djavax.security.auth.login.name=<principal@REALM> "
-                                       + SpnegoAuthScheme.class.getName() + " <url>");
-                       System.exit(1);
-                       return;
-               }
-               String url = args[0];
-
-               URL jaasUrl = SpnegoAuthScheme.class.getResource("jaas.cfg");
-               System.setProperty("java.security.auth.login.config", jaasUrl.toExternalForm());
-               try {
-                       LoginContext lc = new LoginContext("SINGLE_USER");
-                       lc.login();
-
-                       AuthPolicy.registerAuthScheme(SpnegoAuthScheme.NAME, SpnegoAuthScheme.class);
-                       HttpParams params = DefaultHttpParams.getDefaultParams();
-                       ArrayList<String> schemes = new ArrayList<>();
-                       schemes.add(SpnegoAuthScheme.NAME);
-                       params.setParameter(AuthPolicy.AUTH_SCHEME_PRIORITY, schemes);
-                       params.setParameter(CredentialsProvider.PROVIDER, new HttpCredentialProvider());
-
-                       int responseCode = Subject.doAs(lc.getSubject(), new PrivilegedExceptionAction<Integer>() {
-                               public Integer run() throws Exception {
-                                       HttpClient httpClient = new HttpClient();
-                                       return httpClient.executeMethod(new GetMethod(url));
-                               }
-                       });
-                       System.out.println("Reponse code: " + responseCode);
-               } catch (Exception e) {
-                       e.printStackTrace();
-               }
-       }
-
-}
diff --git a/cms/org.argeo.slc.cms/src/org/argeo/slc/cms/httpclient3/SpnegoCredentials.java b/cms/org.argeo.slc.cms/src/org/argeo/slc/cms/httpclient3/SpnegoCredentials.java
deleted file mode 100644 (file)
index 06f6d53..0000000
+++ /dev/null
@@ -1,7 +0,0 @@
-package org.argeo.slc.cms.httpclient3;
-
-import org.apache.commons.httpclient.Credentials;
-
-public class SpnegoCredentials implements Credentials {
-
-}
diff --git a/cms/org.argeo.slc.cms/src/org/argeo/slc/cms/httpclient3/jaas.cfg b/cms/org.argeo.slc.cms/src/org/argeo/slc/cms/httpclient3/jaas.cfg
deleted file mode 100644 (file)
index dc540dd..0000000
+++ /dev/null
@@ -1,10 +0,0 @@
-SINGLE_USER {
-    com.sun.security.auth.module.Krb5LoginModule required
-     useTicketCache=true
-     debug=true;
-};
-
-com.sun.security.jgss.krb5.initiate {
-    com.sun.security.auth.module.Krb5LoginModule
-     required useTicketCache=true;
-};
\ No newline at end of file
diff --git a/cms/org.argeo.slc.cms/src/org/argeo/slc/cms/test/CmsSmokeTest.java b/cms/org.argeo.slc.cms/src/org/argeo/slc/cms/test/CmsSmokeTest.java
deleted file mode 100644 (file)
index 10b088c..0000000
+++ /dev/null
@@ -1,20 +0,0 @@
-package org.argeo.slc.cms.test;
-
-import java.io.IOException;
-import java.nio.file.Files;
-import java.nio.file.Path;
-import java.nio.file.Paths;
-
-public class CmsSmokeTest {
-
-       public static void main(String[] args) throws IOException {
-               Path instanceData;
-               if (args.length > 0) {
-                       instanceData = Paths.get(args[0]);
-               } else {
-                       instanceData = Files.createTempDirectory("cms-test");
-               }
-
-       }
-
-}
diff --git a/cnf/build.bnd b/cnf/build.bnd
deleted file mode 100644 (file)
index f6e8be2..0000000
+++ /dev/null
@@ -1,3 +0,0 @@
--include: \
-${workspace}/cnf/unstable.bnd, \
-${workspace}/sdk/argeo-build/argeo.bnd, \
diff --git a/cnf/unstable.bnd b/cnf/unstable.bnd
deleted file mode 100644 (file)
index 136d42a..0000000
+++ /dev/null
@@ -1,10 +0,0 @@
-MAJOR=2
-MINOR=3
-MICRO=4
-qualifier=.next
-
-category=org.argeo.slc
-Bundle-RequiredExecutionEnvironment=JavaSE-11
-
-argeo.rpm.stagingRepository=/srv/rpmfactory/unstable/argeo-osgi-2/argeo
-argeo.rpm.suffix=-unstable
index 9b3e9804b04280910d6df08fd74ba0fe4cf4079c..47f7d96251de657313915790cff5aaf0d8ba8878 100755 (executable)
--- a/configure
+++ b/configure
@@ -1,55 +1,7 @@
 #!/bin/sh
 
-# We build where we are
-SDK_BUILD_BASE=$(pwd -P)/output
-
 # Source are located where this script is
 SDK_SRC_BASE="$(cd "$(dirname "$0")"; pwd -P)"
 
-SDK_MK=$SDK_SRC_BASE/sdk.mk
-
-#echo SDK_BUILD_BASE=$SDK_BUILD_BASE
-#echo SDK_SRC_BASE=$SDK_SRC_BASE
-#echo SDK_MK=$SDK_MK
-
-if [ -f "$SDK_MK" ]; 
-then
-
-echo "File $SDK_MK already exists. Remove it in order to configure a new build location:"
-echo "rm $SDK_MK"
-exit 1
-
-else
-
-if [ -z "$JAVA_HOME" ]
-then
-echo "Environment variable JAVA_HOME must be set"
-exit 1
-fi
-
-# Create build directory, so that it can be used right away
-# and we check whether we have the rights
-mkdir -p $SDK_BUILD_BASE
-if [ -f "$SDK_MK" ];
-then
-echo "Cannot create $SDK_BUILD_BASE, SDK configuration has failed."
-exit 2
-fi
-
-# Generate sdk.mk
-cat > "$SDK_MK" <<EOF
-SDK_SRC_BASE := $SDK_SRC_BASE
-SDK_BUILD_BASE := $SDK_BUILD_BASE
-JAVA_HOME := $JAVA_HOME
-
-include \$(SDK_SRC_BASE)/branch.mk
-EOF
-
-
-echo SDK was configured.
-echo "JAVA_HOME        : $JAVA_HOME"
-echo "Base for sources : $SDK_SRC_BASE"
-echo "Base for builds  : $SDK_BUILD_BASE"
-exit 0
-fi
-
+# Source the configure script
+. $SDK_SRC_BASE/sdk/argeo-build/configure
diff --git a/org.argeo.slc.cms/.classpath b/org.argeo.slc.cms/.classpath
new file mode 100644 (file)
index 0000000..81fe078
--- /dev/null
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+       <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-17"/>
+       <classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
+       <classpathentry kind="src" path="src"/>
+       <classpathentry kind="output" path="bin"/>
+</classpath>
diff --git a/org.argeo.slc.cms/.project b/org.argeo.slc.cms/.project
new file mode 100644 (file)
index 0000000..95c8de1
--- /dev/null
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+       <name>org.argeo.slc.cms</name>
+       <comment></comment>
+       <projects>
+       </projects>
+       <buildSpec>
+               <buildCommand>
+                       <name>org.eclipse.jdt.core.javabuilder</name>
+                       <arguments>
+                       </arguments>
+               </buildCommand>
+               <buildCommand>
+                       <name>org.eclipse.pde.ManifestBuilder</name>
+                       <arguments>
+                       </arguments>
+               </buildCommand>
+               <buildCommand>
+                       <name>org.eclipse.pde.SchemaBuilder</name>
+                       <arguments>
+                       </arguments>
+               </buildCommand>
+       </buildSpec>
+       <natures>
+               <nature>org.eclipse.pde.PluginNature</nature>
+               <nature>org.eclipse.jdt.core.javanature</nature>
+       </natures>
+</projectDescription>
diff --git a/org.argeo.slc.cms/bnd.bnd b/org.argeo.slc.cms/bnd.bnd
new file mode 100644 (file)
index 0000000..144bd1a
--- /dev/null
@@ -0,0 +1,4 @@
+Import-Package: \
+org.apache.commons.logging,\
+org.osgi.*;version="0.0.0",\
+*
\ No newline at end of file
diff --git a/org.argeo.slc.cms/build.properties b/org.argeo.slc.cms/build.properties
new file mode 100644 (file)
index 0000000..5d082ea
--- /dev/null
@@ -0,0 +1,5 @@
+source.. = src/
+output.. = bin/
+bin.includes = META-INF/,\
+               .
+additional.bundles = org.argeo.init
diff --git a/org.argeo.slc.cms/src/org/argeo/slc/backup/vfs/AbstractAtomicBackup.java b/org.argeo.slc.cms/src/org/argeo/slc/backup/vfs/AbstractAtomicBackup.java
new file mode 100644 (file)
index 0000000..6d55374
--- /dev/null
@@ -0,0 +1,82 @@
+package org.argeo.slc.backup.vfs;
+
+import org.apache.commons.vfs2.FileObject;
+import org.apache.commons.vfs2.FileSystemManager;
+import org.apache.commons.vfs2.FileSystemOptions;
+import org.apache.commons.vfs2.provider.sftp.SftpFileSystemConfigBuilder;
+
+/**
+ * Simplify atomic backups implementation, especially by managing VFS.
+ */
+public abstract class AbstractAtomicBackup implements AtomicBackup {
+       private String name;
+       private String compression = "bz2";
+
+       protected abstract void writeBackup(FileObject targetFo);
+
+       public AbstractAtomicBackup() {
+       }
+
+       public AbstractAtomicBackup(String name) {
+               this.name = name;
+       }
+
+       public void init() {
+               if (name == null)
+                       throw new MaintenanceException("Atomic backup name must be set");
+       }
+
+       public void destroy() {
+
+       }
+
+       @Override
+       public String backup(FileSystemManager fileSystemManager,
+                       String backupsBase, BackupContext backupContext,
+                       FileSystemOptions opts) {
+               if (name == null)
+                       throw new MaintenanceException("Atomic backup name must be set");
+
+               FileObject targetFo = null;
+               try {
+                       if (backupsBase.startsWith("sftp:"))
+                               SftpFileSystemConfigBuilder.getInstance()
+                                               .setStrictHostKeyChecking(opts, "no");
+                       if (compression == null || compression.equals("none"))
+                               targetFo = fileSystemManager.resolveFile(backupsBase + '/'
+                                               + backupContext.getRelativeFolder() + '/' + name, opts);
+                       else if (compression.equals("bz2"))
+                               targetFo = fileSystemManager.resolveFile("bz2:" + backupsBase
+                                               + '/' + backupContext.getRelativeFolder() + '/' + name
+                                               + ".bz2" + "!" + name, opts);
+                       else if (compression.equals("gz"))
+                               targetFo = fileSystemManager.resolveFile("gz:" + backupsBase
+                                               + '/' + backupContext.getRelativeFolder() + '/' + name
+                                               + ".gz" + "!" + name, opts);
+                       else
+                               throw new MaintenanceException("Unsupported compression "
+                                               + compression);
+
+                       writeBackup(targetFo);
+
+                       return targetFo.toString();
+               } catch (Exception e) {
+                       throw new MaintenanceException("Cannot backup " + name + " to "
+                                       + targetFo, e);
+               } finally {
+                       BackupUtils.closeFOQuietly(targetFo);
+               }
+       }
+
+       public void setName(String name) {
+               this.name = name;
+       }
+
+       public String getName() {
+               return name;
+       }
+
+       public void setCompression(String compression) {
+               this.compression = compression;
+       }
+}
diff --git a/org.argeo.slc.cms/src/org/argeo/slc/backup/vfs/AtomicBackup.java b/org.argeo.slc.cms/src/org/argeo/slc/backup/vfs/AtomicBackup.java
new file mode 100644 (file)
index 0000000..0cfcfab
--- /dev/null
@@ -0,0 +1,22 @@
+package org.argeo.slc.backup.vfs;
+
+import org.apache.commons.vfs2.FileSystemManager;
+import org.apache.commons.vfs2.FileSystemOptions;
+
+/** Performs the backup of a single component, typically a database dump */
+public interface AtomicBackup {
+       /** Name identifiying this backup */
+       public String getName();
+
+       /**
+        * Retrieves the data of the component in a format that allows to restore
+        * the component
+        * 
+        * @param backupContext
+        *            the context of this backup
+        * @return the VFS URI of the generated file or directory
+        */
+       public String backup(FileSystemManager fileSystemManager,
+                       String backupsBase, BackupContext backupContext,
+                       FileSystemOptions opts);
+}
diff --git a/org.argeo.slc.cms/src/org/argeo/slc/backup/vfs/BackupContext.java b/org.argeo.slc.cms/src/org/argeo/slc/backup/vfs/BackupContext.java
new file mode 100644 (file)
index 0000000..9c1140b
--- /dev/null
@@ -0,0 +1,25 @@
+package org.argeo.slc.backup.vfs;
+
+import java.text.DateFormat;
+import java.util.Date;
+
+/**
+ * Transient information of a given backup, centralizing common information such
+ * as timestamp and location.
+ */
+public interface BackupContext {
+       /** Backup date */
+       public Date getTimestamp();
+
+       /** Formatted backup date */
+       public String getTimestampAsString();
+
+       /** System name */
+       public String getSystemName();
+
+       /** Local base */
+       public String getRelativeFolder();
+
+       /** Date format */
+       public DateFormat getDateFormat();
+}
diff --git a/org.argeo.slc.cms/src/org/argeo/slc/backup/vfs/BackupFileSystemManager.java b/org.argeo.slc.cms/src/org/argeo/slc/backup/vfs/BackupFileSystemManager.java
new file mode 100644 (file)
index 0000000..ad42dd3
--- /dev/null
@@ -0,0 +1,36 @@
+package org.argeo.slc.backup.vfs;
+
+import org.apache.commons.vfs2.FileSystemException;
+import org.apache.commons.vfs2.impl.DefaultFileSystemManager;
+import org.apache.commons.vfs2.provider.bzip2.Bzip2FileProvider;
+import org.apache.commons.vfs2.provider.ftp.FtpFileProvider;
+import org.apache.commons.vfs2.provider.gzip.GzipFileProvider;
+import org.apache.commons.vfs2.provider.local.DefaultLocalFileProvider;
+import org.apache.commons.vfs2.provider.ram.RamFileProvider;
+import org.apache.commons.vfs2.provider.sftp.SftpFileProvider;
+import org.apache.commons.vfs2.provider.url.UrlFileProvider;
+
+/**
+ * Programatically configured VFS file system manager which can be declared as a
+ * bean and associated with a life cycle (methods
+ * {@link DefaultFileSystemManager#init()} and
+ * {@link DefaultFileSystemManager#close()}). Supports bz2, file, ram, gzip,
+ * ftp, sftp
+ */
+public class BackupFileSystemManager extends DefaultFileSystemManager {
+
+       public BackupFileSystemManager() {
+               super();
+               try {
+                       addProvider("file", new DefaultLocalFileProvider());
+                       addProvider("bz2", new Bzip2FileProvider());
+                       addProvider("ftp", new FtpFileProvider());
+                       addProvider("sftp", new SftpFileProvider());
+                       addProvider("gzip", new GzipFileProvider());
+                       addProvider("ram", new RamFileProvider());
+                       setDefaultProvider(new UrlFileProvider());
+               } catch (FileSystemException e) {
+                       throw new MaintenanceException("Cannot configure backup file provider", e);
+               }
+       }
+}
diff --git a/org.argeo.slc.cms/src/org/argeo/slc/backup/vfs/BackupPurge.java b/org.argeo.slc.cms/src/org/argeo/slc/backup/vfs/BackupPurge.java
new file mode 100644 (file)
index 0000000..1d07bbf
--- /dev/null
@@ -0,0 +1,18 @@
+package org.argeo.slc.backup.vfs;
+
+import java.text.DateFormat;
+
+import org.apache.commons.vfs2.FileSystemManager;
+import org.apache.commons.vfs2.FileSystemOptions;
+
+/** Purges previous backups */
+public interface BackupPurge {
+       /**
+        * Purge the backups identified by these arguments. Although these are the
+        * same fields as a {@link BackupContext} we don't pass it as argument since
+        * we want to use this interface to purge remote backups as well (that is,
+        * with a different base), or outside the scope of a running backup.
+        */
+       public void purge(FileSystemManager fileSystemManager, String base,
+                       String name, DateFormat dateFormat, FileSystemOptions opts);
+}
diff --git a/org.argeo.slc.cms/src/org/argeo/slc/backup/vfs/BackupUtils.java b/org.argeo.slc.cms/src/org/argeo/slc/backup/vfs/BackupUtils.java
new file mode 100644 (file)
index 0000000..bc4d0c8
--- /dev/null
@@ -0,0 +1,21 @@
+package org.argeo.slc.backup.vfs;
+
+import org.apache.commons.vfs2.FileObject;
+
+/** Backup utilities */
+public class BackupUtils {
+       /** Close a file object quietly even if it is null or throws an exception. */
+       public static void closeFOQuietly(FileObject fo) {
+               if (fo != null) {
+                       try {
+                               fo.close();
+                       } catch (Exception e) {
+                               // silent
+                       }
+               }
+       }
+       
+       /** Prevents instantiation */
+       private BackupUtils() {
+       }
+}
diff --git a/org.argeo.slc.cms/src/org/argeo/slc/backup/vfs/MaintenanceException.java b/org.argeo.slc.cms/src/org/argeo/slc/backup/vfs/MaintenanceException.java
new file mode 100644 (file)
index 0000000..1532503
--- /dev/null
@@ -0,0 +1,15 @@
+package org.argeo.slc.backup.vfs;
+
+@Deprecated
+class MaintenanceException extends RuntimeException {
+       private static final long serialVersionUID = -5770049663929537270L;
+
+       public MaintenanceException(String message, Throwable cause) {
+               super(message, cause);
+       }
+
+       public MaintenanceException(String message) {
+               super(message);
+       }
+
+}
diff --git a/org.argeo.slc.cms/src/org/argeo/slc/backup/vfs/MySqlBackup.java b/org.argeo.slc.cms/src/org/argeo/slc/backup/vfs/MySqlBackup.java
new file mode 100644 (file)
index 0000000..3f0e670
--- /dev/null
@@ -0,0 +1,59 @@
+package org.argeo.slc.backup.vfs;
+
+import org.apache.commons.vfs2.FileObject;
+
+/** Backups a MySQL database using mysqldump. */
+public class MySqlBackup extends OsCallBackup {
+       private String mysqldumpLocation = "/usr/bin/mysqldump";
+
+       private String dbUser;
+       private String dbPassword;
+       private String dbName;
+
+       public MySqlBackup() {
+       }
+
+       public MySqlBackup(String dbUser, String dbPassword, String dbName) {
+               this.dbUser = dbUser;
+               this.dbPassword = dbPassword;
+               this.dbName = dbName;
+               init();
+       }
+
+       @Override
+       public void init() {
+               if (getName() == null)
+                       setName(dbName + ".mysql");
+               super.init();
+       }
+
+       @Override
+       public void writeBackup(FileObject targetFo) {
+               if (getCommand() == null)
+                       setCommand(mysqldumpLocation
+                                       + " --lock-tables --add-locks --add-drop-table"
+                                       + " -u ${dbUser} --password=${dbPassword} --databases ${dbName}");
+               getVariables().put("dbUser", dbUser);
+               getVariables().put("dbPassword", dbPassword);
+               getVariables().put("dbName", dbName);
+
+               super.writeBackup(targetFo);
+       }
+
+       public void setDbUser(String dbUser) {
+               this.dbUser = dbUser;
+       }
+
+       public void setDbPassword(String dbPassword) {
+               this.dbPassword = dbPassword;
+       }
+
+       public void setDbName(String dbName) {
+               this.dbName = dbName;
+       }
+
+       public void setMysqldumpLocation(String mysqldumpLocation) {
+               this.mysqldumpLocation = mysqldumpLocation;
+       }
+
+}
diff --git a/org.argeo.slc.cms/src/org/argeo/slc/backup/vfs/OpenLdapBackup.java b/org.argeo.slc.cms/src/org/argeo/slc/backup/vfs/OpenLdapBackup.java
new file mode 100644 (file)
index 0000000..31914bd
--- /dev/null
@@ -0,0 +1,46 @@
+package org.argeo.slc.backup.vfs;
+
+import org.apache.commons.vfs2.FileObject;
+
+/** Backups an OpenLDAP server using slapcat */
+public class OpenLdapBackup extends OsCallBackup {
+       private String slapcatLocation = "/usr/sbin/slapcat";
+       private String slapdConfLocation = "/etc/openldap/slapd.conf";
+       private String baseDn;
+
+       public OpenLdapBackup() {
+               super();
+       }
+
+       public OpenLdapBackup(String baseDn) {
+               super();
+               this.baseDn = baseDn;
+       }
+
+       @Override
+       public void writeBackup(FileObject targetFo) {
+               if (baseDn == null)
+                       throw new MaintenanceException("Base DN must be set");
+
+               if (getCommand() == null)
+                       setCommand(slapcatLocation
+                                       + " -f ${slapdConfLocation} -b '${baseDn}'");
+               getVariables().put("slapdConfLocation", slapdConfLocation);
+               getVariables().put("baseDn", baseDn);
+
+               super.writeBackup(targetFo);
+       }
+
+       public void setSlapcatLocation(String slapcatLocation) {
+               this.slapcatLocation = slapcatLocation;
+       }
+
+       public void setSlapdConfLocation(String slapdConfLocation) {
+               this.slapdConfLocation = slapdConfLocation;
+       }
+
+       public void setBaseDn(String baseDn) {
+               this.baseDn = baseDn;
+       }
+
+}
diff --git a/org.argeo.slc.cms/src/org/argeo/slc/backup/vfs/OsCallBackup.java b/org.argeo.slc.cms/src/org/argeo/slc/backup/vfs/OsCallBackup.java
new file mode 100644 (file)
index 0000000..380dffe
--- /dev/null
@@ -0,0 +1,115 @@
+package org.argeo.slc.backup.vfs;
+
+import java.io.ByteArrayOutputStream;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.commons.exec.CommandLine;
+import org.apache.commons.exec.DefaultExecutor;
+import org.apache.commons.exec.ExecuteException;
+import org.apache.commons.exec.ExecuteStreamHandler;
+import org.apache.commons.exec.Executor;
+import org.apache.commons.exec.PumpStreamHandler;
+import org.apache.commons.io.IOUtils;
+import org.apache.commons.vfs2.FileContent;
+import org.apache.commons.vfs2.FileObject;
+import org.argeo.api.cms.CmsLog;
+
+/**
+ * Runs an OS command and save its standard output as a file. Typically used for
+ * MySQL or OpenLDAP dumps.
+ */
+public class OsCallBackup extends AbstractAtomicBackup {
+       private final static CmsLog log = CmsLog.getLog(OsCallBackup.class);
+
+       private String command;
+       private Map<String, String> variables = new HashMap<String, String>();
+       private Executor executor = new DefaultExecutor();
+
+       private Map<String, String> environment = new HashMap<String, String>();
+
+       /** Name of the sudo user, root if "", not sudo if null */
+       private String sudo = null;
+
+       public OsCallBackup() {
+       }
+
+       public OsCallBackup(String name) {
+               super(name);
+       }
+
+       public OsCallBackup(String name, String command) {
+               super(name);
+               this.command = command;
+       }
+
+       @Override
+       public void writeBackup(FileObject targetFo) {
+               String commandToUse = command;
+
+               // sudo
+               if (sudo != null) {
+                       if (sudo.equals(""))
+                               commandToUse = "sudo " + commandToUse;
+                       else
+                               commandToUse = "sudo -u " + sudo + " " + commandToUse;
+               }
+
+               CommandLine commandLine = CommandLine.parse(commandToUse, variables);
+               ByteArrayOutputStream errBos = new ByteArrayOutputStream();
+               if (log.isTraceEnabled())
+                       log.trace(commandLine.toString());
+
+               try {
+                       // stdout
+                       FileContent targetContent = targetFo.getContent();
+                       // stderr
+                       ExecuteStreamHandler streamHandler = new PumpStreamHandler(targetContent.getOutputStream(), errBos);
+                       executor.setStreamHandler(streamHandler);
+                       executor.execute(commandLine, environment);
+               } catch (ExecuteException e) {
+                       byte[] err = errBos.toByteArray();
+                       String errStr = new String(err);
+                       throw new MaintenanceException("Process " + commandLine + " failed (" + e.getExitValue() + "): " + errStr, e);
+               } catch (Exception e) {
+                       byte[] err = errBos.toByteArray();
+                       String errStr = new String(err);
+                       throw new MaintenanceException("Process " + commandLine + " failed: " + errStr, e);
+               } finally {
+                       IOUtils.closeQuietly(errBos);
+               }
+       }
+
+       public void setCommand(String command) {
+               this.command = command;
+       }
+
+       protected String getCommand() {
+               return command;
+       }
+
+       /**
+        * A reference to the environment variables that will be passed to the
+        * process. Empty by default.
+        */
+       protected Map<String, String> getEnvironment() {
+               return environment;
+       }
+
+       protected Map<String, String> getVariables() {
+               return variables;
+       }
+
+       public void setVariables(Map<String, String> variables) {
+               this.variables = variables;
+       }
+
+       public void setExecutor(Executor executor) {
+               this.executor = executor;
+       }
+
+       public void setSudo(String sudo) {
+               this.sudo = sudo;
+       }
+
+}
diff --git a/org.argeo.slc.cms/src/org/argeo/slc/backup/vfs/PostgreSqlBackup.java b/org.argeo.slc.cms/src/org/argeo/slc/backup/vfs/PostgreSqlBackup.java
new file mode 100644 (file)
index 0000000..613fd5a
--- /dev/null
@@ -0,0 +1,70 @@
+package org.argeo.slc.backup.vfs;
+
+import org.apache.commons.vfs2.FileObject;
+
+/** Backups a PostgreSQL database using pg_dump. */
+public class PostgreSqlBackup extends OsCallBackup {
+       /**
+        * PostgreSQL password environment variable (see
+        * http://stackoverflow.com/questions
+        * /2893954/how-to-pass-in-password-to-pg-dump)
+        */
+       protected final static String PGPASSWORD = "PGPASSWORD";
+
+       private String pgDumpLocation = "/usr/bin/pg_dump";
+
+       private String dbUser;
+       private String dbPassword;
+       private String dbName;
+
+       public PostgreSqlBackup() {
+               super();
+       }
+
+       public PostgreSqlBackup(String dbUser, String dbPassword, String dbName) {
+               this.dbUser = dbUser;
+               this.dbPassword = dbPassword;
+               this.dbName = dbName;
+               init();
+       }
+
+       @Override
+       public void init() {
+               // disable compression since pg_dump is used with -Fc option
+               setCompression(null);
+
+               if (getName() == null)
+                       setName(dbName + ".pgdump");
+               super.init();
+       }
+
+       @Override
+       public void writeBackup(FileObject targetFo) {
+               if (getCommand() == null) {
+                       getEnvironment().put(PGPASSWORD, dbPassword);
+                       setCommand(pgDumpLocation + " -Fc" + " -U ${dbUser} ${dbName}");
+               }
+               getVariables().put("dbUser", dbUser);
+               getVariables().put("dbPassword", dbPassword);
+               getVariables().put("dbName", dbName);
+
+               super.writeBackup(targetFo);
+       }
+
+       public void setDbUser(String dbUser) {
+               this.dbUser = dbUser;
+       }
+
+       public void setDbPassword(String dbPassword) {
+               this.dbPassword = dbPassword;
+       }
+
+       public void setDbName(String dbName) {
+               this.dbName = dbName;
+       }
+
+       public void setPgDumpLocation(String mysqldumpLocation) {
+               this.pgDumpLocation = mysqldumpLocation;
+       }
+
+}
diff --git a/org.argeo.slc.cms/src/org/argeo/slc/backup/vfs/SimpleBackupContext.java b/org.argeo.slc.cms/src/org/argeo/slc/backup/vfs/SimpleBackupContext.java
new file mode 100644 (file)
index 0000000..9ee6871
--- /dev/null
@@ -0,0 +1,48 @@
+package org.argeo.slc.backup.vfs;
+
+import java.text.DateFormat;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+
+import org.apache.commons.vfs2.FileSystemManager;
+
+/** Simple implementation of a backup context */
+public class SimpleBackupContext implements BackupContext {
+       private DateFormat dateFormat = new SimpleDateFormat("yyyyMMdd_HHmm");
+       private final Date timestamp;
+       private final String name;
+
+       private final FileSystemManager fileSystemManager;
+
+       public SimpleBackupContext(FileSystemManager fileSystemManager,
+                       String backupsBase, String name) {
+               this.name = name;
+               this.timestamp = new Date();
+               this.fileSystemManager = fileSystemManager;
+       }
+
+       public Date getTimestamp() {
+               return timestamp;
+       }
+
+       public String getTimestampAsString() {
+               return dateFormat.format(timestamp);
+       }
+
+       public String getSystemName() {
+               return name;
+       }
+
+       public String getRelativeFolder() {
+               return name + '/' + getTimestampAsString();
+       }
+
+       public DateFormat getDateFormat() {
+               return dateFormat;
+       }
+
+       public FileSystemManager getFileSystemManager() {
+               return fileSystemManager;
+       }
+
+}
diff --git a/org.argeo.slc.cms/src/org/argeo/slc/backup/vfs/SimpleBackupPurge.java b/org.argeo.slc.cms/src/org/argeo/slc/backup/vfs/SimpleBackupPurge.java
new file mode 100644 (file)
index 0000000..0871109
--- /dev/null
@@ -0,0 +1,71 @@
+package org.argeo.slc.backup.vfs;
+
+import java.text.DateFormat;
+import java.time.Period;
+import java.time.ZoneId;
+import java.time.ZonedDateTime;
+import java.util.Date;
+import java.util.SortedMap;
+import java.util.TreeMap;
+
+import org.apache.commons.vfs2.FileObject;
+import org.apache.commons.vfs2.FileSystemManager;
+import org.apache.commons.vfs2.FileSystemOptions;
+import org.apache.commons.vfs2.Selectors;
+import org.argeo.api.cms.CmsLog;
+
+/** Simple backup purge which keeps backups only for a given number of days */
+public class SimpleBackupPurge implements BackupPurge {
+       private final static CmsLog log = CmsLog.getLog(SimpleBackupPurge.class);
+
+       private Integer daysKept = 30;
+
+       @Override
+       public void purge(FileSystemManager fileSystemManager, String base, String name, DateFormat dateFormat,
+                       FileSystemOptions opts) {
+               try {
+                       ZonedDateTime nowDt = ZonedDateTime.now();
+                       FileObject baseFo = fileSystemManager.resolveFile(base + '/' + name, opts);
+
+                       SortedMap<ZonedDateTime, FileObject> toDelete = new TreeMap<ZonedDateTime, FileObject>();
+                       int backupCount = 0;
+
+                       // make sure base dir exists
+                       baseFo.createFolder();
+
+                       // scan backups and list those which should be deleted
+                       for (FileObject backupFo : baseFo.getChildren()) {
+                               String backupName = backupFo.getName().getBaseName();
+                               Date backupDate = dateFormat.parse(backupName);
+                               backupCount++;
+                               ZonedDateTime backupDt = ZonedDateTime.ofInstant(backupDate.toInstant(), ZoneId.systemDefault());
+                               Period sinceThen = Period.between(backupDt.toLocalDate(), nowDt.toLocalDate());
+                               // new Period(backupDt, nowDt);
+                               int days = sinceThen.getDays();
+                               // int days = sinceThen.getMinutes();
+                               if (days > daysKept) {
+                                       toDelete.put(backupDt, backupFo);
+                               }
+                       }
+
+                       if (toDelete.size() != 0 && toDelete.size() == backupCount) {
+                               // all backups would be deleted
+                               // but we want to keep at least one
+                               ZonedDateTime lastBackupDt = toDelete.firstKey();
+                               FileObject keptFo = toDelete.remove(lastBackupDt);
+                               log.warn("Backup " + keptFo + " kept although it is older than " + daysKept + " days.");
+                       }
+
+                       // delete old backups
+                       for (FileObject backupFo : toDelete.values()) {
+                               backupFo.delete(Selectors.SELECT_ALL);
+                               if (log.isDebugEnabled())
+                                       log.debug("Deleted backup " + backupFo);
+                       }
+               } catch (Exception e) {
+                       throw new MaintenanceException("Could not purge previous backups", e);
+               }
+
+       }
+
+}
diff --git a/org.argeo.slc.cms/src/org/argeo/slc/backup/vfs/SvnBackup.java b/org.argeo.slc.cms/src/org/argeo/slc/backup/vfs/SvnBackup.java
new file mode 100644 (file)
index 0000000..ea9f844
--- /dev/null
@@ -0,0 +1,55 @@
+package org.argeo.slc.backup.vfs;
+
+import java.io.File;
+
+import org.apache.commons.vfs2.FileObject;
+
+/** Backups a Subversion repository using svnadmin. */
+public class SvnBackup extends OsCallBackup {
+       private String svnadminLocation = "/usr/bin/svnadmin";
+
+       private String repoLocation;
+       private String repoName;
+
+       public SvnBackup() {
+       }
+
+       public SvnBackup(String repoLocation) {
+               this.repoLocation = repoLocation;
+               init();
+       }
+
+       @Override
+       public void init() {
+               // use directory as repo name
+               if (repoName == null)
+                       repoName = new File(repoLocation).getName();
+
+               if (getName() == null)
+                       setName(repoName + ".svndump");
+               super.init();
+       }
+
+       @Override
+       public void writeBackup(FileObject targetFo) {
+               if (getCommand() == null) {
+                       setCommand(svnadminLocation + " dump " + " ${repoLocation}");
+               }
+               getVariables().put("repoLocation", repoLocation);
+
+               super.writeBackup(targetFo);
+       }
+
+       public void setRepoLocation(String repoLocation) {
+               this.repoLocation = repoLocation;
+       }
+
+       public void setRepoName(String repoName) {
+               this.repoName = repoName;
+       }
+
+       public void setSvnadminLocation(String mysqldumpLocation) {
+               this.svnadminLocation = mysqldumpLocation;
+       }
+
+}
diff --git a/org.argeo.slc.cms/src/org/argeo/slc/backup/vfs/SystemBackup.java b/org.argeo.slc.cms/src/org/argeo/slc/backup/vfs/SystemBackup.java
new file mode 100644 (file)
index 0000000..7f23d72
--- /dev/null
@@ -0,0 +1,199 @@
+package org.argeo.slc.backup.vfs;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.commons.vfs2.FileObject;
+import org.apache.commons.vfs2.FileSystemException;
+import org.apache.commons.vfs2.FileSystemManager;
+import org.apache.commons.vfs2.FileSystemOptions;
+import org.apache.commons.vfs2.Selectors;
+import org.apache.commons.vfs2.UserAuthenticator;
+import org.apache.commons.vfs2.impl.DefaultFileSystemConfigBuilder;
+import org.argeo.api.cms.CmsLog;
+import org.argeo.util.LangUtils;
+
+/**
+ * Combines multiple backups and transfer them to a remote location. Purges
+ * remote and local data based on certain criteria.
+ */
+public class SystemBackup implements Runnable {
+       private final static CmsLog log = CmsLog.getLog(SystemBackup.class);
+
+       private FileSystemManager fileSystemManager;
+       private UserAuthenticator userAuthenticator = null;
+
+       private String backupsBase;
+       private String systemName;
+
+       private List<AtomicBackup> atomicBackups = new ArrayList<AtomicBackup>();
+       private BackupPurge backupPurge = new SimpleBackupPurge();
+
+       private Map<String, UserAuthenticator> remoteBases = new HashMap<String, UserAuthenticator>();
+
+       @Override
+       public void run() {
+               if (atomicBackups.size() == 0)
+                       throw new MaintenanceException("No atomic backup listed");
+               List<String> failures = new ArrayList<String>();
+
+               SimpleBackupContext backupContext = new SimpleBackupContext(fileSystemManager, backupsBase, systemName);
+
+               // purge older backups
+               FileSystemOptions opts = new FileSystemOptions();
+               try {
+                       DefaultFileSystemConfigBuilder.getInstance().setUserAuthenticator(opts, userAuthenticator);
+               } catch (Exception e) {
+                       throw new MaintenanceException("Cannot create authentication", e);
+               }
+
+               try {
+
+                       backupPurge.purge(fileSystemManager, backupsBase, systemName, backupContext.getDateFormat(), opts);
+               } catch (Exception e) {
+                       failures.add("Purge " + backupsBase + " failed: " + e.getMessage());
+                       log.error("Purge of " + backupsBase + " failed", e);
+               }
+
+               // perform backup
+               for (AtomicBackup atomickBackup : atomicBackups) {
+                       try {
+                               String target = atomickBackup.backup(fileSystemManager, backupsBase, backupContext, opts);
+                               if (log.isDebugEnabled())
+                                       log.debug("Performed backup " + target);
+                       } catch (Exception e) {
+                               String msg = "Atomic backup " + atomickBackup.getName() + " failed: "
+                                               + LangUtils.chainCausesMessages(e);
+                               failures.add(msg);
+                               log.error(msg);
+                               if (log.isTraceEnabled())
+                                       log.trace("Stacktrace of atomic backup " + atomickBackup.getName() + " failure.", e);
+                       }
+               }
+
+               // dispatch to remote
+               for (String remoteBase : remoteBases.keySet()) {
+                       FileObject localBaseFo = null;
+                       FileObject remoteBaseFo = null;
+                       UserAuthenticator auth = remoteBases.get(remoteBase);
+
+                       // authentication
+                       FileSystemOptions remoteOpts = new FileSystemOptions();
+                       try {
+                               DefaultFileSystemConfigBuilder.getInstance().setUserAuthenticator(remoteOpts, auth);
+                               backupPurge.purge(fileSystemManager, remoteBase, systemName, backupContext.getDateFormat(), remoteOpts);
+                       } catch (Exception e) {
+                               failures.add("Purge " + remoteBase + " failed: " + e.getMessage());
+                               log.error("Cannot purge " + remoteBase, e);
+                       }
+
+                       try {
+                               localBaseFo = fileSystemManager.resolveFile(backupsBase + '/' + backupContext.getRelativeFolder(),
+                                               opts);
+                               remoteBaseFo = fileSystemManager.resolveFile(remoteBase + '/' + backupContext.getRelativeFolder(),
+                                               remoteOpts);
+                               remoteBaseFo.copyFrom(localBaseFo, Selectors.SELECT_ALL);
+                               if (log.isDebugEnabled())
+                                       log.debug("Copied backup to " + remoteBaseFo + " from " + localBaseFo);
+                               // }
+                       } catch (Exception e) {
+                               failures.add("Dispatch to " + remoteBase + " failed: " + e.getMessage());
+                               log.error("Cannot dispatch backups from " + backupContext.getRelativeFolder() + " to " + remoteBase, e);
+                       }
+                       BackupUtils.closeFOQuietly(localBaseFo);
+                       BackupUtils.closeFOQuietly(remoteBaseFo);
+               }
+
+               int failureCount = 0;
+               if (failures.size() > 0) {
+                       StringBuffer buf = new StringBuffer();
+                       for (String failure : failures) {
+                               buf.append('\n').append(failureCount).append(" - ").append(failure);
+                               failureCount++;
+                       }
+                       throw new MaintenanceException(failureCount + " error(s) when running the backup,"
+                                       + " check the logs and the backups as soon as possible." + buf);
+               }
+       }
+
+       public void setFileSystemManager(FileSystemManager fileSystemManager) {
+               this.fileSystemManager = fileSystemManager;
+       }
+
+       public void setBackupsBase(String backupsBase) {
+               this.backupsBase = backupsBase;
+       }
+
+       public void setSystemName(String name) {
+               this.systemName = name;
+       }
+
+       public void setAtomicBackups(List<AtomicBackup> atomicBackups) {
+               this.atomicBackups = atomicBackups;
+       }
+
+       public void setBackupPurge(BackupPurge backupPurge) {
+               this.backupPurge = backupPurge;
+       }
+
+       public void setUserAuthenticator(UserAuthenticator userAuthenticator) {
+               this.userAuthenticator = userAuthenticator;
+       }
+
+       public void setRemoteBases(Map<String, UserAuthenticator> remoteBases) {
+               this.remoteBases = remoteBases;
+       }
+
+       // public static void main(String args[]) {
+       // while (true) {
+       // try {
+       // StandardFileSystemManager fsm = new StandardFileSystemManager();
+       // fsm.init();
+       //
+       // SystemBackup systemBackup = new SystemBackup();
+       // systemBackup.setSystemName("mySystem");
+       // systemBackup
+       // .setBackupsBase("/home/mbaudier/dev/src/commons/server/runtime/org.argeo.server.core/target");
+       // systemBackup.setFileSystemManager(fsm);
+       //
+       // List<AtomicBackup> atomicBackups = new ArrayList<AtomicBackup>();
+       //
+       // MySqlBackup mySqlBackup = new MySqlBackup("root", "", "test");
+       // atomicBackups.add(mySqlBackup);
+       // PostgreSqlBackup postgreSqlBackup = new PostgreSqlBackup(
+       // "argeo", "argeo", "gis_template");
+       // atomicBackups.add(postgreSqlBackup);
+       // SvnBackup svnBackup = new SvnBackup(
+       // "/home/mbaudier/tmp/testsvnrepo");
+       // atomicBackups.add(svnBackup);
+       //
+       // systemBackup.setAtomicBackups(atomicBackups);
+       //
+       // Map<String, UserAuthenticator> remoteBases = new HashMap<String,
+       // UserAuthenticator>();
+       // StaticUserAuthenticator userAuthenticator = new StaticUserAuthenticator(
+       // null, "demo", "demo");
+       // remoteBases.put("sftp://localhost/home/mbaudier/test",
+       // userAuthenticator);
+       // systemBackup.setRemoteBases(remoteBases);
+       //
+       // systemBackup.run();
+       //
+       // fsm.close();
+       // } catch (FileSystemException e) {
+       // // TODO Auto-generated catch block
+       // e.printStackTrace();
+       // System.exit(1);
+       // }
+       //
+       // // wait
+       // try {
+       // Thread.sleep(120 * 1000);
+       // } catch (InterruptedException e) {
+       // e.printStackTrace();
+       // }
+       // }
+       // }
+}
diff --git a/org.argeo.slc.cms/src/org/argeo/slc/backup/vfs/package-info.java b/org.argeo.slc.cms/src/org/argeo/slc/backup/vfs/package-info.java
new file mode 100644 (file)
index 0000000..f70499d
--- /dev/null
@@ -0,0 +1,2 @@
+/** Argeo Node backup utilities based on Apache Commons VFS. */
+package org.argeo.slc.backup.vfs;
\ No newline at end of file
diff --git a/org.argeo.slc.cms/src/org/argeo/slc/cms/deploy/CmsDeployedSystem.java b/org.argeo.slc.cms/src/org/argeo/slc/cms/deploy/CmsDeployedSystem.java
new file mode 100644 (file)
index 0000000..feec64f
--- /dev/null
@@ -0,0 +1,7 @@
+package org.argeo.slc.cms.deploy;
+
+import org.argeo.slc.deploy.DeployedSystem;
+
+public interface CmsDeployedSystem extends DeployedSystem {
+
+}
diff --git a/org.argeo.slc.cms/src/org/argeo/slc/cms/deploy/CmsDeploymentData.java b/org.argeo.slc.cms/src/org/argeo/slc/cms/deploy/CmsDeploymentData.java
new file mode 100644 (file)
index 0000000..17cecd8
--- /dev/null
@@ -0,0 +1,9 @@
+package org.argeo.slc.cms.deploy;
+
+import java.util.List;
+
+import org.argeo.slc.deploy.DeploymentData;
+
+public interface CmsDeploymentData extends DeploymentData {
+       List<String> getModulesToActivate(int startLevel);
+}
diff --git a/org.argeo.slc.cms/src/org/argeo/slc/cms/deploy/CmsTargetData.java b/org.argeo.slc.cms/src/org/argeo/slc/cms/deploy/CmsTargetData.java
new file mode 100644 (file)
index 0000000..4616b20
--- /dev/null
@@ -0,0 +1,12 @@
+package org.argeo.slc.cms.deploy;
+
+import java.nio.file.Path;
+
+import org.argeo.slc.deploy.TargetData;
+
+public interface CmsTargetData extends TargetData {
+       Path getInstanceData();
+
+       Integer getHttpPort();
+
+}
diff --git a/org.argeo.slc.cms/src/org/argeo/slc/cms/deploy/SimpleCmsDeploymentData.java b/org.argeo.slc.cms/src/org/argeo/slc/cms/deploy/SimpleCmsDeploymentData.java
new file mode 100644 (file)
index 0000000..c95f441
--- /dev/null
@@ -0,0 +1,17 @@
+package org.argeo.slc.cms.deploy;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.TreeMap;
+
+public class SimpleCmsDeploymentData implements CmsDeploymentData {
+       private Map<Integer, List<String>> startLevels = new TreeMap<>();
+
+       @Override
+       public List<String> getModulesToActivate(int startLevel) {
+               startLevels.putIfAbsent(startLevel, new ArrayList<>());
+               return startLevels.get(startLevel);
+       }
+
+}
diff --git a/org.argeo.slc.cms/src/org/argeo/slc/cms/deploy/SimpleCmsTargetData.java b/org.argeo.slc.cms/src/org/argeo/slc/cms/deploy/SimpleCmsTargetData.java
new file mode 100644 (file)
index 0000000..ecf17d6
--- /dev/null
@@ -0,0 +1,30 @@
+package org.argeo.slc.cms.deploy;
+
+import java.nio.file.Path;
+
+public class SimpleCmsTargetData implements CmsTargetData {
+       private Path instanceData;
+       private Integer httpPort;
+
+       public SimpleCmsTargetData(Path instanceData, Integer httpPort) {
+               this.instanceData = instanceData;
+               this.httpPort = httpPort;
+       }
+
+       public Integer getHttpPort() {
+               return httpPort;
+       }
+
+       public void setHttpPort(Integer httpPort) {
+               this.httpPort = httpPort;
+       }
+
+       public Path getInstanceData() {
+               return instanceData;
+       }
+
+       public void setInstanceData(Path instanceData) {
+               this.instanceData = instanceData;
+       }
+
+}
diff --git a/org.argeo.slc.cms/src/org/argeo/slc/cms/deploy/osgi/CmsOsgiDeployedSystem.java b/org.argeo.slc.cms/src/org/argeo/slc/cms/deploy/osgi/CmsOsgiDeployedSystem.java
new file mode 100644 (file)
index 0000000..8de4354
--- /dev/null
@@ -0,0 +1,49 @@
+package org.argeo.slc.cms.deploy.osgi;
+
+import org.argeo.slc.build.Distribution;
+import org.argeo.slc.build.ModularDistribution;
+import org.argeo.slc.cms.deploy.CmsDeployedSystem;
+import org.argeo.slc.cms.deploy.CmsDeploymentData;
+import org.argeo.slc.cms.deploy.CmsTargetData;
+import org.argeo.slc.deploy.DeploymentData;
+import org.argeo.slc.deploy.TargetData;
+import org.osgi.framework.BundleContext;
+
+public class CmsOsgiDeployedSystem implements CmsDeployedSystem {
+       private ModularDistribution distribution;
+       private CmsTargetData targetData;
+       private CmsDeploymentData deploymentData;
+
+       private BundleContext systemBundleContext;
+
+       public CmsOsgiDeployedSystem(BundleContext systemBundleContext, ModularDistribution distribution,
+                       CmsTargetData targetData, CmsDeploymentData deploymentData) {
+               this.systemBundleContext = systemBundleContext;
+
+               this.distribution = distribution;
+               this.targetData = targetData;
+               this.deploymentData = deploymentData;
+       }
+
+       @Override
+       public String getDeployedSystemId() {
+               // TODO Auto-generated method stub
+               return null;
+       }
+
+       @Override
+       public Distribution getDistribution() {
+               return distribution;
+       }
+
+       @Override
+       public DeploymentData getDeploymentData() {
+               return deploymentData;
+       }
+
+       @Override
+       public TargetData getTargetData() {
+               return targetData;
+       }
+
+}
diff --git a/org.argeo.slc.cms/src/org/argeo/slc/cms/deploy/osgi/CmsOsgiDeployment.java b/org.argeo.slc.cms/src/org/argeo/slc/cms/deploy/osgi/CmsOsgiDeployment.java
new file mode 100644 (file)
index 0000000..3c0cf7c
--- /dev/null
@@ -0,0 +1,182 @@
+package org.argeo.slc.cms.deploy.osgi;
+
+import java.io.IOException;
+import java.lang.System.Logger;
+import java.lang.System.Logger.Level;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.List;
+import java.util.Map;
+import java.util.StringJoiner;
+import java.util.TreeMap;
+
+import org.argeo.init.a2.A2Source;
+import org.argeo.init.a2.FsA2Source;
+import org.argeo.init.osgi.OsgiBoot;
+import org.argeo.init.osgi.OsgiRuntimeContext;
+import org.argeo.slc.WellKnownConstants;
+import org.argeo.slc.build.Distribution;
+import org.argeo.slc.cms.deploy.CmsDeployedSystem;
+import org.argeo.slc.cms.deploy.CmsDeploymentData;
+import org.argeo.slc.cms.deploy.CmsTargetData;
+import org.argeo.slc.cms.deploy.SimpleCmsDeploymentData;
+import org.argeo.slc.cms.deploy.SimpleCmsTargetData;
+import org.argeo.slc.cms.distribution.A2Distribution;
+import org.argeo.slc.deploy.DeployedSystem;
+import org.argeo.slc.deploy.Deployment;
+import org.argeo.slc.deploy.DeploymentData;
+import org.argeo.slc.deploy.TargetData;
+
+public class CmsOsgiDeployment implements Deployment {
+       private final static Logger logger = System.getLogger(CmsOsgiDeployment.class.getName());
+
+       private A2Distribution distribution;
+       private CmsTargetData targetData;
+       private CmsDeploymentData deploymentData;
+
+       private CmsDeployedSystem deployedSystem;
+
+       private OsgiRuntimeContext runtimeContext;
+
+       @Override
+       public void run() {
+               try {
+                       Map<String, String> config = new TreeMap<>();
+
+                       // sources
+                       StringJoiner sourcesProperty = new StringJoiner(",");
+                       for (A2Source a2Source : distribution.getA2Sources()) {
+                               sourcesProperty.add(a2Source.getUri().toString());
+                       }
+                       config.put(OsgiBoot.PROP_ARGEO_OSGI_SOURCES, sourcesProperty.toString());
+
+                       // target
+                       config.put(WellKnownConstants.OSGI_INSTANCE_AREA,
+                                       targetData.getInstanceData().toRealPath().toUri().toString());
+                       if (targetData.getHttpPort() != null) {
+                               config.put(WellKnownConstants.OSGI_HTTP_PORT, targetData.getHttpPort().toString());
+                       }
+
+                       Path configurationArea = Files.createTempDirectory("slc-cms-test");
+                       config.put(WellKnownConstants.OSGI_CONFIGURATION_AREA, configurationArea.toUri().toString());
+
+                       // modules activation
+                       for (int startLevel = 0; startLevel <= 6; startLevel++) {
+                               List<String> modules = deploymentData.getModulesToActivate(startLevel);
+                               if (modules.size() != 0) {
+                                       String startProperty = String.join(",", modules);
+                                       config.put(OsgiBoot.PROP_ARGEO_OSGI_START + "." + startLevel + ".node", startProperty);
+                               }
+                       }
+
+                       config.put("org.eclipse.equinox.http.jetty.autostart", "false");
+                       config.put("org.osgi.framework.bootdelegation",
+                                       "com.sun.jndi.ldap,com.sun.jndi.ldap.sasl,com.sun.security.jgss,com.sun.jndi.dns,com.sun.nio.file,com.sun.nio.sctp");
+                       config.put("eclipse.ignoreApp", "true");
+                       config.put("osgi.noShutdown", "true");
+
+//                     config.put("osgi.console", "true");
+
+                       // initialise
+                       for (String key : config.keySet()) {
+//                             System.out.println(key + "=" + config.get(key));
+                               logger.log(Level.INFO, () -> key + "=" + config.get(key));
+                       }
+
+                       runtimeContext = new OsgiRuntimeContext(config);
+                       runtimeContext.run();
+
+                       deployedSystem = new CmsOsgiDeployedSystem(runtimeContext.getFramework().getBundleContext(), distribution,
+                                       targetData, deploymentData);
+
+               } catch (Exception e) {
+                       throw new IllegalStateException("Cannot run OSGi deployment", e);
+               }
+
+       }
+
+       @Override
+       public DeployedSystem getDeployedSystem() {
+               return deployedSystem;
+       }
+
+       @Override
+       public void setTargetData(TargetData targetData) {
+               this.targetData = (CmsTargetData) targetData;
+       }
+
+       @Override
+       public void setDeploymentData(DeploymentData deploymentData) {
+               this.deploymentData = (CmsDeploymentData) deploymentData;
+       }
+
+       @Override
+       public void setDistribution(Distribution distribution) {
+               this.distribution = (A2Distribution) distribution;
+       }
+
+       public OsgiRuntimeContext getRuntimeContext() {
+               return runtimeContext;
+       }
+
+       public static void main(String[] args) {
+               try {
+                       Path userHome = Paths.get(System.getProperty("user.home"));
+
+                       // distribution
+                       Path a2Base = userHome.resolve("dev/git/unstable/output/a2");
+                       A2Distribution distribution = new A2Distribution();
+                       distribution.getA2Sources().add(new FsA2Source(a2Base));
+
+                       // target data
+                       Path instanceData = userHome.resolve("dev/git/unstable/argeo-slc/sdk/exec/cms-deployment/data");
+                       Files.createDirectories(instanceData);
+                       Integer httpPort = 7070;
+                       SimpleCmsTargetData targetData = new SimpleCmsTargetData(instanceData, httpPort);
+
+                       // deployment data
+                       SimpleCmsDeploymentData deploymentData = new SimpleCmsDeploymentData();
+                       deploymentData.getModulesToActivate(2).add("org.eclipse.equinox.http.servlet");
+                       deploymentData.getModulesToActivate(2).add("org.eclipse.equinox.cm");
+                       deploymentData.getModulesToActivate(2).add("org.apache.felix.scr");
+                       deploymentData.getModulesToActivate(2).add("org.eclipse.rap.rwt.osgi");
+
+                       deploymentData.getModulesToActivate(3).add("org.argeo.cms");
+
+                       deploymentData.getModulesToActivate(4).add("org.argeo.cms.servlet");
+                       deploymentData.getModulesToActivate(4).add("org.argeo.cms.ui.rap");
+                       deploymentData.getModulesToActivate(4).add("org.argeo.cms.jcr");
+
+                       deploymentData.getModulesToActivate(5).add("org.argeo.cms.e4.rap");
+
+                       CmsOsgiDeployment deployment = new CmsOsgiDeployment();
+                       deployment.setDistribution(distribution);
+                       deployment.setTargetData(targetData);
+                       deployment.setDeploymentData(deploymentData);
+                       deployment.run();
+
+                       boolean multiple = false;
+                       if (multiple) {
+
+                               Path instanceData2 = userHome.resolve("dev/git/unstable/argeo-slc/sdk/exec/cms-deployment2/data");
+                               Files.createDirectories(instanceData2);
+                               Integer httpPort2 = 7071;
+                               SimpleCmsTargetData targetData2 = new SimpleCmsTargetData(instanceData2, httpPort2);
+
+                               CmsOsgiDeployment deployment2 = new CmsOsgiDeployment();
+                               deployment2.setDistribution(distribution);
+                               deployment2.setTargetData(targetData2);
+                               deployment2.setDeploymentData(deploymentData);
+                               deployment2.run();
+                       }
+
+                       deployment.getRuntimeContext().waitForStop(0);
+
+               } catch (IOException | InterruptedException e) {
+                       e.printStackTrace();
+                       System.exit(1);
+               }
+       }
+
+}
diff --git a/org.argeo.slc.cms/src/org/argeo/slc/cms/distribution/A2Distribution.java b/org.argeo.slc.cms/src/org/argeo/slc/cms/distribution/A2Distribution.java
new file mode 100644 (file)
index 0000000..6c8bbe7
--- /dev/null
@@ -0,0 +1,75 @@
+package org.argeo.slc.cms.distribution;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+import org.argeo.init.a2.A2Branch;
+import org.argeo.init.a2.A2Component;
+import org.argeo.init.a2.A2Contribution;
+import org.argeo.init.a2.A2Module;
+import org.argeo.init.a2.A2Source;
+import org.argeo.slc.CategoryNameVersion;
+import org.argeo.slc.DefaultCategoryNameVersion;
+import org.argeo.slc.NameVersion;
+import org.argeo.slc.build.Distribution;
+import org.argeo.slc.build.ModularDistribution;
+
+public class A2Distribution implements ModularDistribution {
+       private List<A2Source> a2Sources = new ArrayList<>();
+
+       @Override
+       public String getDistributionId() {
+               // TODO Auto-generated method stub
+               return null;
+       }
+
+       @Override
+       public String getName() {
+               // TODO Auto-generated method stub
+               return null;
+       }
+
+       @Override
+       public String getVersion() {
+               // TODO Auto-generated method stub
+               return null;
+       }
+
+       @Override
+       public Iterator<? extends NameVersion> nameVersions() {
+               List<CategoryNameVersion> nameVersions = new ArrayList<>();
+               for (A2Source a2Source : a2Sources) {
+                       for (A2Contribution a2Contribution : a2Source.listContributions(null)) {
+                               for (A2Component a2Component : a2Contribution.listComponents(null)) {
+                                       for (A2Branch a2Branch : a2Component.listBranches(null)) {
+                                               for (A2Module a2Module : a2Branch.listModules(null)) {
+                                                       CategoryNameVersion nameVersion = new DefaultCategoryNameVersion(a2Contribution.getId(),
+                                                                       a2Component.getId(), a2Module.getVersion().toString());
+                                                       nameVersions.add(nameVersion);
+                                               }
+                                       }
+                               }
+                       }
+               }
+               return nameVersions.iterator();
+       }
+
+       @Override
+       public Distribution getModuleDistribution(String moduleName, String moduleVersion) {
+               // TODO Auto-generated method stub
+               return null;
+       }
+
+       @Override
+       public Object getModulesDescriptor(String descriptorType) {
+               // TODO Auto-generated method stub
+               return null;
+       }
+
+       public List<A2Source> getA2Sources() {
+               return a2Sources;
+       }
+
+       
+}
diff --git a/org.argeo.slc.cms/src/org/argeo/slc/cms/distribution/A2ModuleDistribution.java b/org.argeo.slc.cms/src/org/argeo/slc/cms/distribution/A2ModuleDistribution.java
new file mode 100644 (file)
index 0000000..cc7e681
--- /dev/null
@@ -0,0 +1,14 @@
+package org.argeo.slc.cms.distribution;
+
+import org.argeo.init.a2.A2Module;
+import org.argeo.slc.build.Distribution;
+
+public class A2ModuleDistribution implements Distribution {
+       private A2Module a2Module;
+
+       @Override
+       public String getDistributionId() {
+               return a2Module.getCoordinates();
+       }
+
+}
diff --git a/org.argeo.slc.cms/src/org/argeo/slc/cms/httpclient3/HttpCredentialProvider.java b/org.argeo.slc.cms/src/org/argeo/slc/cms/httpclient3/HttpCredentialProvider.java
new file mode 100644 (file)
index 0000000..59cfc4f
--- /dev/null
@@ -0,0 +1,20 @@
+package org.argeo.slc.cms.httpclient3;
+
+import org.apache.commons.httpclient.Credentials;
+import org.apache.commons.httpclient.auth.AuthScheme;
+import org.apache.commons.httpclient.auth.CredentialsNotAvailableException;
+import org.apache.commons.httpclient.auth.CredentialsProvider;
+
+/** SPNEGO credential provider */
+public class HttpCredentialProvider implements CredentialsProvider {
+
+       @Override
+       public Credentials getCredentials(AuthScheme scheme, String host, int port, boolean proxy)
+                       throws CredentialsNotAvailableException {
+               if (scheme instanceof SpnegoAuthScheme)
+                       return new SpnegoCredentials();
+               else
+                       throw new UnsupportedOperationException("Auth scheme " + scheme.getSchemeName() + " not supported");
+       }
+
+}
diff --git a/org.argeo.slc.cms/src/org/argeo/slc/cms/httpclient3/SpnegoAuthScheme.java b/org.argeo.slc.cms/src/org/argeo/slc/cms/httpclient3/SpnegoAuthScheme.java
new file mode 100644 (file)
index 0000000..a28559a
--- /dev/null
@@ -0,0 +1,179 @@
+package org.argeo.slc.cms.httpclient3;
+
+import java.net.URL;
+import java.security.PrivilegedExceptionAction;
+import java.util.ArrayList;
+
+import javax.security.auth.Subject;
+import javax.security.auth.login.LoginContext;
+
+import org.apache.commons.httpclient.Credentials;
+import org.apache.commons.httpclient.HttpClient;
+import org.apache.commons.httpclient.HttpMethod;
+import org.apache.commons.httpclient.auth.AuthPolicy;
+import org.apache.commons.httpclient.auth.AuthScheme;
+import org.apache.commons.httpclient.auth.AuthenticationException;
+import org.apache.commons.httpclient.auth.CredentialsProvider;
+import org.apache.commons.httpclient.auth.MalformedChallengeException;
+import org.apache.commons.httpclient.methods.GetMethod;
+import org.apache.commons.httpclient.params.DefaultHttpParams;
+import org.apache.commons.httpclient.params.HttpMethodParams;
+import org.apache.commons.httpclient.params.HttpParams;
+import org.argeo.cms.auth.RemoteAuthUtils;
+
+//// Register client-side SPNEGO auth scheme
+//AuthPolicy.registerAuthScheme(SpnegoAuthScheme.NAME, SpnegoAuthScheme.class);
+//HttpParams params = DefaultHttpParams.getDefaultParams();
+//ArrayList<String> schemes = new ArrayList<>();
+//schemes.add(SpnegoAuthScheme.NAME);// SPNEGO preferred
+//// schemes.add(AuthPolicy.BASIC);// incompatible with Basic
+//params.setParameter(AuthPolicy.AUTH_SCHEME_PRIORITY, schemes);
+//params.setParameter(CredentialsProvider.PROVIDER, new HttpCredentialProvider());
+//params.setParameter(HttpMethodParams.COOKIE_POLICY, KernelConstants.COOKIE_POLICY_BROWSER_COMPATIBILITY);
+//// params.setCookiePolicy(CookiePolicy.BROWSER_COMPATIBILITY);
+
+
+
+/** Implementation of the SPNEGO auth scheme. */
+public class SpnegoAuthScheme implements AuthScheme {
+//     private final static Log log = LogFactory.getLog(SpnegoAuthScheme.class);
+
+       public static final String NAME = "Negotiate";
+//     private final static Oid KERBEROS_OID;
+//     static {
+//             try {
+//                     KERBEROS_OID = new Oid("1.3.6.1.5.5.2");
+//             } catch (GSSException e) {
+//                     throw new IllegalStateException("Cannot create Kerberos OID", e);
+//             }
+//     }
+
+       private final static String DEFAULT_KERBEROS_SERVICE = "HTTP";
+
+       private boolean complete = false;
+       private String realm;
+
+       @Override
+       public void processChallenge(String challenge) throws MalformedChallengeException {
+               // if(tokenStr!=null){
+               // log.error("Received challenge while there is a token. Failing.");
+               // complete = false;
+               // }
+
+       }
+
+       @Override
+       public String getSchemeName() {
+               return NAME;
+       }
+
+       @Override
+       public String getParameter(String name) {
+               return null;
+       }
+
+       @Override
+       public String getRealm() {
+               return realm;
+       }
+
+       @Override
+       public String getID() {
+               return NAME;
+       }
+
+       @Override
+       public boolean isConnectionBased() {
+               return true;
+       }
+
+       @Override
+       public boolean isComplete() {
+               return complete;
+       }
+
+       @Override
+       public String authenticate(Credentials credentials, String method, String uri) throws AuthenticationException {
+               // log.debug("authenticate " + method + " " + uri);
+               // return null;
+               throw new UnsupportedOperationException();
+       }
+
+       @Override
+       public String authenticate(Credentials credentials, HttpMethod method) throws AuthenticationException {
+//             GSSContext context = null;
+               String hostname;
+               try {
+                       hostname = method.getURI().getHost();
+                       String tokenStr = RemoteAuthUtils.createGssToken(null, DEFAULT_KERBEROS_SERVICE, hostname);
+                       return "Negotiate " + tokenStr;
+               } catch (Exception e1) {
+                       complete = true;
+                       throw new AuthenticationException("Cannot authenticate " + method, e1);
+               }
+//             String serverPrinc = DEFAULT_KERBEROS_SERVICE + "@" + hostname;
+//
+//             try {
+//                     // Get service's principal name
+//                     GSSManager manager = GSSManager.getInstance();
+//                     GSSName serverName = manager.createName(serverPrinc, GSSName.NT_HOSTBASED_SERVICE, KERBEROS_OID);
+//
+//                     // Get the context for authentication
+//                     context = manager.createContext(serverName, KERBEROS_OID, null, GSSContext.DEFAULT_LIFETIME);
+//                     // context.requestMutualAuth(true); // Request mutual authentication
+//                     // context.requestConf(true); // Request confidentiality
+//                     context.requestCredDeleg(true);
+//
+//                     byte[] token = new byte[0];
+//
+//                     // token is ignored on the first call
+//                     token = context.initSecContext(token, 0, token.length);
+//
+//                     // Send a token to the server if one was generated by
+//                     // initSecContext
+//                     if (token != null) {
+//                             tokenStr = Base64.getEncoder().encodeToString(token);
+//                             // complete=true;
+//                     }
+//             } catch (GSSException e) {
+//                     complete = true;
+//                     throw new AuthenticationException("Cannot authenticate to " + serverPrinc, e);
+//             }
+       }
+
+       public static void main(String[] args) {
+               String principal = System.getProperty("javax.security.auth.login.name");
+               if (args.length == 0 || principal == null) {
+                       System.err.println("usage: java -Djavax.security.auth.login.name=<principal@REALM> "
+                                       + SpnegoAuthScheme.class.getName() + " <url>");
+                       System.exit(1);
+                       return;
+               }
+               String url = args[0];
+
+               URL jaasUrl = SpnegoAuthScheme.class.getResource("jaas.cfg");
+               System.setProperty("java.security.auth.login.config", jaasUrl.toExternalForm());
+               try {
+                       LoginContext lc = new LoginContext("SINGLE_USER");
+                       lc.login();
+
+                       AuthPolicy.registerAuthScheme(SpnegoAuthScheme.NAME, SpnegoAuthScheme.class);
+                       HttpParams params = DefaultHttpParams.getDefaultParams();
+                       ArrayList<String> schemes = new ArrayList<>();
+                       schemes.add(SpnegoAuthScheme.NAME);
+                       params.setParameter(AuthPolicy.AUTH_SCHEME_PRIORITY, schemes);
+                       params.setParameter(CredentialsProvider.PROVIDER, new HttpCredentialProvider());
+
+                       int responseCode = Subject.doAs(lc.getSubject(), new PrivilegedExceptionAction<Integer>() {
+                               public Integer run() throws Exception {
+                                       HttpClient httpClient = new HttpClient();
+                                       return httpClient.executeMethod(new GetMethod(url));
+                               }
+                       });
+                       System.out.println("Reponse code: " + responseCode);
+               } catch (Exception e) {
+                       e.printStackTrace();
+               }
+       }
+
+}
diff --git a/org.argeo.slc.cms/src/org/argeo/slc/cms/httpclient3/SpnegoCredentials.java b/org.argeo.slc.cms/src/org/argeo/slc/cms/httpclient3/SpnegoCredentials.java
new file mode 100644 (file)
index 0000000..06f6d53
--- /dev/null
@@ -0,0 +1,7 @@
+package org.argeo.slc.cms.httpclient3;
+
+import org.apache.commons.httpclient.Credentials;
+
+public class SpnegoCredentials implements Credentials {
+
+}
diff --git a/org.argeo.slc.cms/src/org/argeo/slc/cms/httpclient3/jaas.cfg b/org.argeo.slc.cms/src/org/argeo/slc/cms/httpclient3/jaas.cfg
new file mode 100644 (file)
index 0000000..dc540dd
--- /dev/null
@@ -0,0 +1,10 @@
+SINGLE_USER {
+    com.sun.security.auth.module.Krb5LoginModule required
+     useTicketCache=true
+     debug=true;
+};
+
+com.sun.security.jgss.krb5.initiate {
+    com.sun.security.auth.module.Krb5LoginModule
+     required useTicketCache=true;
+};
\ No newline at end of file
diff --git a/org.argeo.slc.cms/src/org/argeo/slc/cms/test/CmsSmokeTest.java b/org.argeo.slc.cms/src/org/argeo/slc/cms/test/CmsSmokeTest.java
new file mode 100644 (file)
index 0000000..10b088c
--- /dev/null
@@ -0,0 +1,20 @@
+package org.argeo.slc.cms.test;
+
+import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+
+public class CmsSmokeTest {
+
+       public static void main(String[] args) throws IOException {
+               Path instanceData;
+               if (args.length > 0) {
+                       instanceData = Paths.get(args[0]);
+               } else {
+                       instanceData = Files.createTempDirectory("cms-test");
+               }
+
+       }
+
+}
index 3dc9a223f1177b4eb34ccac1e96a354d4dd8ee25..a261043de5f9d90373bb1e7f395e3371ba9e67ef 160000 (submodule)
@@ -1 +1 @@
-Subproject commit 3dc9a223f1177b4eb34ccac1e96a354d4dd8ee25
+Subproject commit a261043de5f9d90373bb1e7f395e3371ba9e67ef
diff --git a/sdk/branches/unstable.bnd b/sdk/branches/unstable.bnd
new file mode 100644 (file)
index 0000000..9eb7ef5
--- /dev/null
@@ -0,0 +1,4 @@
+major=2
+minor=3
+micro=4
+qualifier=.next
\ No newline at end of file