From 19732b785f222871a76f931213587b2c04cc1e10 Mon Sep 17 00:00:00 2001
From: Kai Reinhard <K.Reinhard@micromata.de>
Date: Fri, 14 Dec 2018 21:56:53 +0000
Subject: [PATCH] ...
---
borgbutler-core/src/main/java/de/micromata/borgbutler/config/Configuration.java | 6
borgbutler-core/src/main/java/de/micromata/borgbutler/BorgCommands.java | 41 +++++++---
borgbutler-core/src/main/java/de/micromata/borgbutler/config/BorgRepoConfig.java | 4
README.adoc | 21 ++--
borgbutler-webapp/src/components/views/repos/RepoArchiveListView.jsx | 12 --
borgbutler-core/src/main/java/de/micromata/borgbutler/json/borg/BorgRepoList.java | 6 -
borgbutler-server/src/main/java/de/micromata/borgbutler/server/rest/ReposRest.java | 20 ++++
borgbutler-core/src/main/java/de/micromata/borgbutler/json/borg/BorgRepository.java | 28 -------
borgbutler-webapp/src/components/views/repos/RepoCard.jsx | 2
borgbutler-core/src/main/java/de/micromata/borgbutler/json/borg/BorgArchive.java | 6 -
borgbutler-webapp/src/containers/WebApp.jsx | 2
borgbutler-core/src/main/java/de/micromata/borgbutler/json/borg/BorgArchiveInfo.java | 6 -
borgbutler-core/src/main/java/de/micromata/borgbutler/data/Repository.java | 14 ++
borgbutler-core/src/main/java/de/micromata/borgbutler/cache/ButlerCache.java | 58 +++++++++-----
borgbutler-core/src/main/java/de/micromata/borgbutler/json/borg/BorgRepoInfo.java | 6 -
15 files changed, 118 insertions(+), 114 deletions(-)
diff --git a/README.adoc b/README.adoc
index abd14df..d1dbfd0 100644
--- a/README.adoc
+++ b/README.adoc
@@ -16,14 +16,14 @@
{
"cache_archive_content_max_disc_size_mb" : 1000,
"repo-configs" : [ {
- "name" : "My-Laptop-Local-Backup",
- "repo" : "/Volumes/backup/my-laptop-backup",
+ "display_name" : "My-Laptop-Local-Backup",
+ "repo" : "/Volumes/backup/my-laptop-backup",
},
{
- "name" : "My-Laptop-Remote-Backup",
- "repo" : "ssh://backup.acme.com/./backups/my-laptop",
+ "display_name" : "My-Laptop-Remote-Backup",
+ "repo" : "ssh://backup.acme.com/./backups/my-laptop",
"passwordCommand" : "security find-generic-password -a $USER -s borg-passphrase -w",
- "rsh" : "ssh -i /Users/horst/.ssh/acme_rsa"
+ "rsh" : "ssh -i /Users/horst/.ssh/acme_rsa"
} ]
}
----
@@ -47,13 +47,14 @@
=== Work with borgbutler-server
==== npm
-1. `gradle npmBuild`
-2. `cd borgbutler-webapp`
-3. `npm install`
-4. `npm start`
-5. Start borgbutler-server's Main.
+1. `cd borgbutler-webapp`
+2. `npm install`
+3. `npm start`
+4. Start borgbutler-server's Main.
=== Ideas
==== 2 factor authentication
https://github.com/j256/two-factor-auth
+=== Install server
+==== Debian
diff --git a/borgbutler-core/src/main/java/de/micromata/borgbutler/BorgCommands.java b/borgbutler-core/src/main/java/de/micromata/borgbutler/BorgCommands.java
index cca1438..2b14b34 100644
--- a/borgbutler-core/src/main/java/de/micromata/borgbutler/BorgCommands.java
+++ b/borgbutler-core/src/main/java/de/micromata/borgbutler/BorgCommands.java
@@ -8,9 +8,12 @@
import de.micromata.borgbutler.json.JsonUtils;
import de.micromata.borgbutler.json.borg.*;
import de.micromata.borgbutler.utils.DateUtils;
-import org.apache.commons.exec.*;
+import org.apache.commons.exec.CommandLine;
+import org.apache.commons.exec.DefaultExecutor;
+import org.apache.commons.exec.PumpStreamHandler;
import org.apache.commons.exec.environment.EnvironmentUtils;
import org.apache.commons.io.output.ByteArrayOutputStream;
+import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -26,10 +29,10 @@
private static Logger log = LoggerFactory.getLogger(BorgCommands.class);
/**
- * Executes borg info repository
+ * Executes borg info repository.
*
* @param repoConfig
- * @return Parsed repo config returned by Borg command.
+ * @return Parsed repo config returned by Borg command (without archives).
*/
public static Repository info(BorgRepoConfig repoConfig) {
String json = execute(repoConfig, "info", repoConfig.getRepo(), "--json");
@@ -37,27 +40,42 @@
return null;
}
BorgRepoInfo repoInfo = JsonUtils.fromJson(BorgRepoInfo.class, json);
- repoInfo.setOriginalJson(json);
- Repository repository = new Repository();
BorgRepository borgRepository = repoInfo.getRepository();
- repository.setId(borgRepository.getId())
+ Repository repository = new Repository()
+ .setId(borgRepository.getId())
+ .setName(repoConfig.getRepo())
+ .setDisplayName(repoConfig.getDisplayName())
.setLastModified(DateUtils.get(borgRepository.getLastModified()))
.setLocation(borgRepository.getLocation())
- .setName(borgRepository.getName())
.setCache(repoInfo.getCache())
.setEncryption(repoInfo.getEncryption())
.setSecurityDir(repoInfo.getSecurityDir());
return repository;
}
- public static BorgRepoList list(BorgRepoConfig repoConfig) {
- String json = execute(repoConfig, "list", repoConfig.getRepo(), "--json");
+ /**
+ * Executes borg list repository.
+ * The given repository will be cloned and archives will be added.
+ * The field {@link Repository#getLastModified()} of masterRepository will be updated.
+ *
+ * @param masterRepository Repository without archives.
+ * @return Parsed repo config returned by Borg command including archives.
+ */
+ public static Repository list(BorgRepoConfig repoConfig, Repository masterRepository) {
+ String json = execute(repoConfig, "list", masterRepository.getName(), "--json");
if (json == null) {
+ log.error("Can't load archives from repo '" + masterRepository.getName() + "'.");
return null;
}
BorgRepoList repoList = JsonUtils.fromJson(BorgRepoList.class, json);
- repoList.setOriginalJson(json);
- return repoList;
+ if (repoList == null) {
+ log.error("Can't load archives from repo '" + masterRepository.getName() + "'.");
+ return null;
+ }
+ masterRepository.setLastModified(repoList.getRepository().getLastModified());
+ Repository repository = ObjectUtils.clone(masterRepository)
+ .setArchives(repoList.getArchives());
+ return repository;
}
/**
@@ -73,7 +91,6 @@
return null;
}
BorgArchiveInfo archiveInfo = JsonUtils.fromJson(BorgArchiveInfo.class, json);
- archiveInfo.setOriginalJson(json);
return archiveInfo;
}
diff --git a/borgbutler-core/src/main/java/de/micromata/borgbutler/cache/ButlerCache.java b/borgbutler-core/src/main/java/de/micromata/borgbutler/cache/ButlerCache.java
index 2598f7c..23cd648 100644
--- a/borgbutler-core/src/main/java/de/micromata/borgbutler/cache/ButlerCache.java
+++ b/borgbutler-core/src/main/java/de/micromata/borgbutler/cache/ButlerCache.java
@@ -7,11 +7,9 @@
import de.micromata.borgbutler.data.Repository;
import de.micromata.borgbutler.json.borg.BorgArchive;
import de.micromata.borgbutler.json.borg.BorgFilesystemItem;
-import de.micromata.borgbutler.json.borg.BorgRepoList;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.jcs.JCS;
import org.apache.commons.jcs.access.CacheAccess;
-import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -40,24 +38,53 @@
*/
public Repository getRepository(String idOrName) {
BorgRepoConfig repoConfig = ConfigurationHandler.getConfiguration().getRepoConfig(idOrName);
+ if (repoConfig != null) {
+ return getRepository(repoConfig);
+ }
+ List<Repository> repositories = getAllRepositories();
+ if (CollectionUtils.isNotEmpty(repositories)) {
+ for (Repository repository : repositories) {
+ if (StringUtils.equals(idOrName, repository.getName()) || StringUtils.equals(idOrName, repository.getId())) {
+ return repository;
+ }
+ }
+ }
+ log.warn("Repo with id or name '" + idOrName + "' not found.");
+ return null;
+ }
+
+ /**
+ * @param repoConfig
+ * @return Repository without list of archives.
+ */
+ private Repository getRepository(BorgRepoConfig repoConfig) {
Repository repository = repoCacheAccess.get(repoConfig.getRepo());
if (repository == null || repository.getLocation() == null) {
repository = BorgCommands.info(repoConfig);
repoCacheAccess.put(repoConfig.getRepo(), repository);
}
if (repository == null) {
- log.warn("Repo with name '" + idOrName + "' not found.");
+ log.warn("Repo with name '" + repoConfig.getRepo() + "' not found.");
}
return repository;
}
+ private BorgRepoConfig getBorgRepoConfig(String name) {
+ for (BorgRepoConfig repoConfig : ConfigurationHandler.getConfiguration().getRepoConfigs()) {
+ if (StringUtils.equals(repoConfig.getRepo(), name))
+ return repoConfig;
+ }
+ log.error("Repo config with name '" + name + "' not found.");
+ return null;
+ }
+
/**
* @return the list of all repositories without the list of archives.
*/
public List<Repository> getAllRepositories() {
List<Repository> repositories = new ArrayList<>();
for (BorgRepoConfig repoConfig : ConfigurationHandler.getConfiguration().getRepoConfigs()) {
- Repository repository = getRepository(repoConfig.getName());
+ Repository repository = getRepository(repoConfig);
if (repository == null) {
continue;
}
@@ -84,25 +111,16 @@
* @return The repository including all archives.
*/
public Repository getRepositoryArchives(String idOrName) {
- BorgRepoConfig repoConfig = ConfigurationHandler.getConfiguration().getRepoConfig(idOrName);
- //ArchiveInfo archiveInfo = BorgCommands.info(repoConfig, repoConfig.getRepo());
- Repository plainRepository = repoArchivesCacheAccess.get(repoConfig.getRepo());
- if (plainRepository != null) {
- return plainRepository;
- }
- plainRepository = repoCacheAccess.get(repoConfig.getRepo());
- if (plainRepository == null) {
- log.warn("Repo with name '" + idOrName + "' not found.");
+ Repository masterRepository = getRepository(idOrName);
+ if (masterRepository == null) {
return null;
}
- BorgRepoList repoList = BorgCommands.list(repoConfig);
- if (repoList == null) {
- log.warn("Repo with name '" + idOrName + "' not found.");
- return null;
+ Repository repository = repoArchivesCacheAccess.get(masterRepository.getName());
+ if (repository != null) {
+ return repository;
}
- Repository repository = ObjectUtils.clone(plainRepository);
- repository.setArchives(repoList.getArchives());
- repoArchivesCacheAccess.put(repoConfig.getRepo(), repository);
+ repository = BorgCommands.list(getBorgRepoConfig(masterRepository.getName()), masterRepository);
+ repoArchivesCacheAccess.put(repository.getName(), repository);
return repository;
}
diff --git a/borgbutler-core/src/main/java/de/micromata/borgbutler/config/BorgRepoConfig.java b/borgbutler-core/src/main/java/de/micromata/borgbutler/config/BorgRepoConfig.java
index fda822e..3212946 100644
--- a/borgbutler-core/src/main/java/de/micromata/borgbutler/config/BorgRepoConfig.java
+++ b/borgbutler-core/src/main/java/de/micromata/borgbutler/config/BorgRepoConfig.java
@@ -1,5 +1,6 @@
package de.micromata.borgbutler.config;
+import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Getter;
import lombok.Setter;
@@ -8,7 +9,8 @@
* A name describing this config. Only used for displaying purposes.
*/
@Getter @Setter
- private String name;
+ @JsonProperty("display_name")
+ private String displayName;
@Getter @Setter
private String repo;
@Getter @Setter
diff --git a/borgbutler-core/src/main/java/de/micromata/borgbutler/config/Configuration.java b/borgbutler-core/src/main/java/de/micromata/borgbutler/config/Configuration.java
index f1c9f04..d22c314 100644
--- a/borgbutler-core/src/main/java/de/micromata/borgbutler/config/Configuration.java
+++ b/borgbutler-core/src/main/java/de/micromata/borgbutler/config/Configuration.java
@@ -24,12 +24,12 @@
repoConfigs.add(repoConfig);
}
- public BorgRepoConfig getRepoConfig(String idOrName) {
- if (idOrName == null) {
+ public BorgRepoConfig getRepoConfig(String name) {
+ if (name == null) {
return null;
}
for (BorgRepoConfig repoConfig : repoConfigs) {
- if (idOrName.equals(repoConfig.getRepo()) ||idOrName.equals(repoConfig.getName())) {
+ if (name.equals(repoConfig.getRepo())) {
return repoConfig;
}
}
diff --git a/borgbutler-core/src/main/java/de/micromata/borgbutler/data/Repository.java b/borgbutler-core/src/main/java/de/micromata/borgbutler/data/Repository.java
index e6780fe..6246326 100644
--- a/borgbutler-core/src/main/java/de/micromata/borgbutler/data/Repository.java
+++ b/borgbutler-core/src/main/java/de/micromata/borgbutler/data/Repository.java
@@ -16,14 +16,22 @@
public class Repository implements Serializable, Cloneable {
private static final long serialVersionUID = 1278802519434516280L;
/**
- * A name describing this config. Only used for displaying purposes. This is automatically set with the name
- * of the repository configuration.
+ * The repo configured for borg.
*
- * @see BorgRepoConfig#getName()
+ * @see BorgRepoConfig#getRepo()
*/
@Getter
@Setter
String name;
+ /**
+ * A name describing this config. Only used for displaying purposes. This is automatically set with the name
+ * of the repository configuration.
+ *
+ * @see BorgRepoConfig#getDisplayName()
+ */
+ @Getter
+ @Setter
+ String displayName;
@Getter
@Setter
private String id;
diff --git a/borgbutler-core/src/main/java/de/micromata/borgbutler/json/borg/BorgArchive.java b/borgbutler-core/src/main/java/de/micromata/borgbutler/json/borg/BorgArchive.java
index 9bc6cce..5d28333 100644
--- a/borgbutler-core/src/main/java/de/micromata/borgbutler/json/borg/BorgArchive.java
+++ b/borgbutler-core/src/main/java/de/micromata/borgbutler/json/borg/BorgArchive.java
@@ -1,9 +1,7 @@
package de.micromata.borgbutler.json.borg;
-import com.fasterxml.jackson.annotation.JsonIgnore;
import de.micromata.borgbutler.json.JsonUtils;
import lombok.Getter;
-import lombok.Setter;
import java.io.Serializable;
@@ -24,10 +22,6 @@
private String start;
@Getter
private String time;
- @Getter
- @Setter
- @JsonIgnore
- private String originalJson;
public String toString() {
return JsonUtils.toJson(this, true);
diff --git a/borgbutler-core/src/main/java/de/micromata/borgbutler/json/borg/BorgArchiveInfo.java b/borgbutler-core/src/main/java/de/micromata/borgbutler/json/borg/BorgArchiveInfo.java
index b719bfe..472c94f 100644
--- a/borgbutler-core/src/main/java/de/micromata/borgbutler/json/borg/BorgArchiveInfo.java
+++ b/borgbutler-core/src/main/java/de/micromata/borgbutler/json/borg/BorgArchiveInfo.java
@@ -1,8 +1,6 @@
package de.micromata.borgbutler.json.borg;
-import com.fasterxml.jackson.annotation.JsonIgnore;
import lombok.Getter;
-import lombok.Setter;
import java.io.Serializable;
import java.util.List;
@@ -20,8 +18,4 @@
private BorgEncryption encryption;
@Getter
private BorgRepository repository;
- @Getter
- @Setter
- @JsonIgnore
- private String originalJson;
}
diff --git a/borgbutler-core/src/main/java/de/micromata/borgbutler/json/borg/BorgRepoInfo.java b/borgbutler-core/src/main/java/de/micromata/borgbutler/json/borg/BorgRepoInfo.java
index 507769b..c5a4209 100644
--- a/borgbutler-core/src/main/java/de/micromata/borgbutler/json/borg/BorgRepoInfo.java
+++ b/borgbutler-core/src/main/java/de/micromata/borgbutler/json/borg/BorgRepoInfo.java
@@ -1,9 +1,7 @@
package de.micromata.borgbutler.json.borg;
-import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Getter;
-import lombok.Setter;
import java.io.Serializable;
@@ -21,8 +19,4 @@
private BorgEncryption encryption;
@Getter
private BorgRepository repository;
- @Getter
- @Setter
- @JsonIgnore
- protected String originalJson;
}
diff --git a/borgbutler-core/src/main/java/de/micromata/borgbutler/json/borg/BorgRepoList.java b/borgbutler-core/src/main/java/de/micromata/borgbutler/json/borg/BorgRepoList.java
index a5dd6e8..f8ee03f 100644
--- a/borgbutler-core/src/main/java/de/micromata/borgbutler/json/borg/BorgRepoList.java
+++ b/borgbutler-core/src/main/java/de/micromata/borgbutler/json/borg/BorgRepoList.java
@@ -1,8 +1,6 @@
package de.micromata.borgbutler.json.borg;
-import com.fasterxml.jackson.annotation.JsonIgnore;
import lombok.Getter;
-import lombok.Setter;
import java.io.Serializable;
import java.util.List;
@@ -18,8 +16,4 @@
private BorgEncryption encryption;
@Getter
private BorgRepository repository;
- @Getter
- @Setter
- @JsonIgnore
- protected String originalJson;
}
diff --git a/borgbutler-core/src/main/java/de/micromata/borgbutler/json/borg/BorgRepository.java b/borgbutler-core/src/main/java/de/micromata/borgbutler/json/borg/BorgRepository.java
index 94e5062..4c22b8a 100644
--- a/borgbutler-core/src/main/java/de/micromata/borgbutler/json/borg/BorgRepository.java
+++ b/borgbutler-core/src/main/java/de/micromata/borgbutler/json/borg/BorgRepository.java
@@ -1,10 +1,7 @@
package de.micromata.borgbutler.json.borg;
import com.fasterxml.jackson.annotation.JsonProperty;
-import de.micromata.borgbutler.config.BorgRepoConfig;
-import de.micromata.borgbutler.config.ConfigurationHandler;
import lombok.Getter;
-import lombok.Setter;
import java.io.Serializable;
@@ -13,15 +10,6 @@
*/
public class BorgRepository implements Serializable {
private static final long serialVersionUID = 1278802519434516280L;
- /**
- * A name describing this config. Only used for displaying purposes. This is automatically set with the name
- * of the repository configuration.
- *
- * @see BorgRepoConfig#getName()
- */
- @Getter
- @Setter
- String name;
@Getter
private String id;
@Getter
@@ -29,20 +17,4 @@
private String lastModified;
@Getter
private String location;
-
- /**
- * Sets also the name for this repository if available in the configuration.
- *
- * @param location
- * @return
- */
- public BorgRepository setLocation(String location) {
- this.location = location;
- // It's ugly but efficiently ;-)
- BorgRepoConfig repoConfig = ConfigurationHandler.getConfiguration().getRepoConfig(location);
- if (repoConfig != null) {
- this.name = repoConfig.getName();
- }
- return this;
- }
}
diff --git a/borgbutler-server/src/main/java/de/micromata/borgbutler/server/rest/ReposRest.java b/borgbutler-server/src/main/java/de/micromata/borgbutler/server/rest/ReposRest.java
index 8812d65..e45f177 100644
--- a/borgbutler-server/src/main/java/de/micromata/borgbutler/server/rest/ReposRest.java
+++ b/borgbutler-server/src/main/java/de/micromata/borgbutler/server/rest/ReposRest.java
@@ -24,16 +24,32 @@
@Produces(MediaType.APPLICATION_JSON)
/**
*
- * @param id
+ * @param id id or name of repo.
* @param prettyPrinter If true then the json output will be in pretty format.
+ * @return Repository (without list of archives) as json string.
* @see JsonUtils#toJson(Object, boolean)
*/
- public String getTemplate(@QueryParam("id") String id, @QueryParam("prettyPrinter") boolean prettyPrinter) {
+ public String getRepo(@QueryParam("id") String id, @QueryParam("prettyPrinter") boolean prettyPrinter) {
Repository repository = ButlerCache.getInstance().getRepository(id);
return JsonUtils.toJson(repository, prettyPrinter);
}
@GET
+ @Path("repoArchiveList")
+ @Produces(MediaType.APPLICATION_JSON)
+ /**
+ *
+ * @param id id or name of repo.
+ * @param prettyPrinter If true then the json output will be in pretty format.
+ * @return Repository (including list of archives) as json string.
+ * @see JsonUtils#toJson(Object, boolean)
+ */
+ public String getRepoArchiveList(@QueryParam("id") String id, @QueryParam("prettyPrinter") boolean prettyPrinter) {
+ Repository repository = ButlerCache.getInstance().getRepositoryArchives(id);
+ return JsonUtils.toJson(repository, prettyPrinter);
+ }
+
+ @GET
@Path("list")
@Produces(MediaType.APPLICATION_JSON)
/**
diff --git a/borgbutler-webapp/src/components/views/repos/RepoArchiveList.jsx b/borgbutler-webapp/src/components/views/repos/RepoArchiveListView.jsx
similarity index 87%
rename from borgbutler-webapp/src/components/views/repos/RepoArchiveList.jsx
rename to borgbutler-webapp/src/components/views/repos/RepoArchiveListView.jsx
index 57ff200..52608e8 100644
--- a/borgbutler-webapp/src/components/views/repos/RepoArchiveList.jsx
+++ b/borgbutler-webapp/src/components/views/repos/RepoArchiveListView.jsx
@@ -4,7 +4,7 @@
import ErrorAlert from '../../general/ErrorAlert';
import {IconRefresh} from "../../general/IconComponents";
-class RepoListView extends React.Component {
+class RepoArchiveListView extends React.Component {
path = getRestServiceUrl('repos');
@@ -74,14 +74,6 @@
>
<IconRefresh/>
</div>
- <CardDeck>
- {this.state.repos.map(repo => {
- return <RepoCard
- key={repo.id}
- repo={repo}
- />;
- })}
- </CardDeck>
</React.Fragment>;
}
@@ -101,4 +93,4 @@
}
}
-export default RepoListView;
+export default RepoArchiveListView;
diff --git a/borgbutler-webapp/src/components/views/repos/RepoCard.jsx b/borgbutler-webapp/src/components/views/repos/RepoCard.jsx
index 81df17c..552e7e2 100644
--- a/borgbutler-webapp/src/components/views/repos/RepoCard.jsx
+++ b/borgbutler-webapp/src/components/views/repos/RepoCard.jsx
@@ -19,7 +19,7 @@
let repoText = this.buildItem(null, content);
return <React.Fragment>
- <Card tag={Link} to={`/repos/${repo.id}`} outline color="success" className={'repo'}
+ <Card tag={Link} to={`/repoArchives/${repo.id}`} outline color="success" className={'repo'}
style={{backgroundColor: '#fff'}}>
<CardHeader>{repo.name}</CardHeader>
<CardBody>
diff --git a/borgbutler-webapp/src/containers/WebApp.jsx b/borgbutler-webapp/src/containers/WebApp.jsx
index f947221..eb84e03 100644
--- a/borgbutler-webapp/src/containers/WebApp.jsx
+++ b/borgbutler-webapp/src/containers/WebApp.jsx
@@ -6,6 +6,7 @@
import Menu from '../components/general/Menu';
import Start from '../components/views/Start';
import RepoListView from '../components/views/repos/RepoListView';
+import RepoArchiveListView from '../components/views/repos/RepoArchiveListView';
import ConfigurationPage from '../components/views/config/ConfigurationPage';
import RestServices from '../components/views/develop/RestServices';
import {isDevelopmentMode} from '../utilities/global';
@@ -50,6 +51,7 @@
/>
))
}
+ <Route path={'/repoArchives/:repoId'} component={RepoArchiveListView}/>
</Switch>
</div>
<Footer versionInfo={this.props.version}/>
--
Gitblit v1.10.0