mirror of
https://github.com/linuxserver/fleet.git
synced 2026-02-20 05:11:08 +08:00
Started implementing design for docker api requests.
Display page for image details.
This commit is contained in:
parent
0fb61d05ef
commit
e0c9317225
@ -17,8 +17,8 @@
|
||||
|
||||
package io.linuxserver.fleet.dockerhub;
|
||||
|
||||
import io.linuxserver.fleet.rest.RestClient;
|
||||
import io.linuxserver.fleet.rest.RestResponse;
|
||||
import io.linuxserver.fleet.v2.client.rest.RestClient;
|
||||
import io.linuxserver.fleet.v2.client.rest.RestResponse;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
|
||||
@ -18,9 +18,9 @@
|
||||
package io.linuxserver.fleet.dockerhub;
|
||||
|
||||
import io.linuxserver.fleet.dockerhub.model.*;
|
||||
import io.linuxserver.fleet.rest.HttpException;
|
||||
import io.linuxserver.fleet.rest.RestClient;
|
||||
import io.linuxserver.fleet.rest.RestResponse;
|
||||
import io.linuxserver.fleet.v2.client.rest.HttpException;
|
||||
import io.linuxserver.fleet.v2.client.rest.RestClient;
|
||||
import io.linuxserver.fleet.v2.client.rest.RestResponse;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
|
||||
@ -18,12 +18,26 @@
|
||||
package io.linuxserver.fleet.v2.cache;
|
||||
|
||||
import io.linuxserver.fleet.v2.key.ImageKey;
|
||||
import io.linuxserver.fleet.v2.key.ImageLookupKey;
|
||||
import io.linuxserver.fleet.v2.key.RepositoryKey;
|
||||
import io.linuxserver.fleet.v2.types.Image;
|
||||
import io.linuxserver.fleet.v2.types.Repository;
|
||||
|
||||
public class RepositoryCache extends AbstractItemCache<RepositoryKey, Repository> {
|
||||
|
||||
public final Image lookupImage(final ImageLookupKey lookupKey) {
|
||||
|
||||
for (Repository repository : getAllItems()) {
|
||||
for (Image image : repository.getImages()) {
|
||||
if (lookupKey.isLookupKeyFor(image)) {
|
||||
return image;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public final Image findImage(final ImageKey imageKey) {
|
||||
|
||||
if (isItemCached(imageKey.getRepositoryKey())) {
|
||||
|
||||
@ -15,7 +15,7 @@
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package io.linuxserver.fleet.rest;
|
||||
package io.linuxserver.fleet.v2.client.rest;
|
||||
|
||||
public class HttpException extends RuntimeException {
|
||||
|
||||
@ -15,11 +15,11 @@
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package io.linuxserver.fleet.rest;
|
||||
package io.linuxserver.fleet.v2.client.rest;
|
||||
|
||||
import io.linuxserver.fleet.rest.marshalling.JacksonMarshallingStrategy;
|
||||
import io.linuxserver.fleet.rest.marshalling.MarshallingStrategy;
|
||||
import io.linuxserver.fleet.rest.proxy.LazyLoadPayloadProxy;
|
||||
import io.linuxserver.fleet.v2.client.rest.marshalling.JacksonMarshallingStrategy;
|
||||
import io.linuxserver.fleet.v2.client.rest.marshalling.MarshallingStrategy;
|
||||
import io.linuxserver.fleet.v2.client.rest.proxy.LazyLoadPayloadProxy;
|
||||
import org.apache.http.HttpEntity;
|
||||
import org.apache.http.StatusLine;
|
||||
import org.apache.http.client.methods.CloseableHttpResponse;
|
||||
@ -36,7 +36,7 @@ import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.charset.Charset;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
@ -85,7 +85,7 @@ public class RestClient {
|
||||
try {
|
||||
|
||||
HttpPost post = new HttpPost(url + parseQueryParameters(queryParameters));
|
||||
post.setEntity(new StringEntity(marshallingStrategy.marshall(payload), Charset.forName("UTF-8")));
|
||||
post.setEntity(new StringEntity(marshallingStrategy.marshall(payload), StandardCharsets.UTF_8));
|
||||
post.setHeader("Content-Type", marshallingStrategy.getContentType());
|
||||
|
||||
return executeBaseRequest(responseType, headers, post);
|
||||
@ -15,9 +15,9 @@
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package io.linuxserver.fleet.rest;
|
||||
package io.linuxserver.fleet.v2.client.rest;
|
||||
|
||||
import io.linuxserver.fleet.rest.proxy.PayloadProxy;
|
||||
import io.linuxserver.fleet.v2.client.rest.proxy.PayloadProxy;
|
||||
|
||||
public class RestResponse<T> {
|
||||
|
||||
@ -15,7 +15,7 @@
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package io.linuxserver.fleet.rest.marshalling;
|
||||
package io.linuxserver.fleet.v2.client.rest.marshalling;
|
||||
|
||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||
import com.fasterxml.jackson.databind.DeserializationFeature;
|
||||
@ -1,4 +1,4 @@
|
||||
package io.linuxserver.fleet.rest.marshalling;
|
||||
package io.linuxserver.fleet.v2.client.rest.marshalling;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
@ -15,10 +15,10 @@
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package io.linuxserver.fleet.rest.proxy;
|
||||
package io.linuxserver.fleet.v2.client.rest.proxy;
|
||||
|
||||
import io.linuxserver.fleet.rest.HttpException;
|
||||
import io.linuxserver.fleet.rest.marshalling.MarshallingStrategy;
|
||||
import io.linuxserver.fleet.v2.client.rest.HttpException;
|
||||
import io.linuxserver.fleet.v2.client.rest.marshalling.MarshallingStrategy;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
@ -15,7 +15,7 @@
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package io.linuxserver.fleet.rest.proxy;
|
||||
package io.linuxserver.fleet.v2.client.rest.proxy;
|
||||
|
||||
public interface PayloadProxy<T> {
|
||||
|
||||
@ -44,7 +44,7 @@ public class DefaultImageDAO extends AbstractDAO implements ImageDAO {
|
||||
private static final String CreateTagBranchOutline = "{CALL Image_CreateTagBranchOutline(?,?)}";
|
||||
private static final String StoreTagDigest = "{CALL Image_StoreTagDigest(?,?,?,?,?)}";
|
||||
private static final String GetTagBranches = "{CALL Image_GetTagBranches(?)}";
|
||||
public static final String GetTagDigests = "{CALL Image_GetTagDigests(?)}";
|
||||
private static final String GetTagDigests = "{CALL Image_GetTagDigests(?)}";
|
||||
private static final String CreateImageOutline = "{CALL Image_CreateOutline(?,?,?,?)}";
|
||||
private static final String GetImage = "{CALL Image_Get(?)}";
|
||||
private static final String DeleteImage = "{CALL Image_Delete(?)}";
|
||||
|
||||
@ -17,7 +17,7 @@
|
||||
|
||||
package io.linuxserver.fleet.v2.key;
|
||||
|
||||
public class AbstractLookupKey implements Key {
|
||||
public abstract class AbstractLookupKey<TYPE extends HasKey<?>> implements Key {
|
||||
|
||||
private final String query;
|
||||
|
||||
@ -33,4 +33,11 @@ public class AbstractLookupKey implements Key {
|
||||
public final Integer getId() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return query;
|
||||
}
|
||||
|
||||
public abstract boolean isLookupKeyFor(final TYPE type);
|
||||
}
|
||||
|
||||
@ -74,4 +74,9 @@ public class ImageKey extends AbstractDatabaseKey {
|
||||
public String toString() {
|
||||
return repositoryKey.getId() + ":" + super.toString() + ":" + repositoryKey.getName() + "/" + name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
return super.equals(o) && ((ImageKey) o).name.equals(name);
|
||||
}
|
||||
}
|
||||
|
||||
@ -17,9 +17,36 @@
|
||||
|
||||
package io.linuxserver.fleet.v2.key;
|
||||
|
||||
public class ImageLookupKey extends AbstractLookupKey {
|
||||
import io.linuxserver.fleet.v2.types.Image;
|
||||
|
||||
public class ImageLookupKey extends AbstractLookupKey<Image> {
|
||||
|
||||
private static final String KeyPattern = "^[^/]+/[^/]+$";
|
||||
|
||||
private final String lookupRepositoryName;
|
||||
private final String lookupImageName;
|
||||
|
||||
public ImageLookupKey(final String query) {
|
||||
super(query);
|
||||
|
||||
if (query.matches(KeyPattern)) {
|
||||
|
||||
final String[] names = query.split("/");
|
||||
lookupRepositoryName = names[0];
|
||||
lookupImageName = names[1];
|
||||
|
||||
} else {
|
||||
throw new IllegalArgumentException("Malformed lookup query for ImageLookupKey");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public final boolean isLookupKeyFor(final Image image) {
|
||||
|
||||
if (null == image) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return image.getRepositoryName().equals(lookupRepositoryName) && image.getName().equals(lookupImageName);
|
||||
}
|
||||
}
|
||||
|
||||
@ -21,6 +21,7 @@ import io.linuxserver.fleet.db.query.InsertUpdateResult;
|
||||
import io.linuxserver.fleet.v2.cache.RepositoryCache;
|
||||
import io.linuxserver.fleet.v2.db.ImageDAO;
|
||||
import io.linuxserver.fleet.v2.key.ImageKey;
|
||||
import io.linuxserver.fleet.v2.key.ImageLookupKey;
|
||||
import io.linuxserver.fleet.v2.key.RepositoryKey;
|
||||
import io.linuxserver.fleet.v2.types.Image;
|
||||
import io.linuxserver.fleet.v2.types.Repository;
|
||||
@ -86,6 +87,10 @@ public class RepositoryManager {
|
||||
return repositoryCache.findImage(imageKey);
|
||||
}
|
||||
|
||||
public final Image lookupImage(final ImageLookupKey imageLookupKey) {
|
||||
return repositoryCache.lookupImage(imageLookupKey);
|
||||
}
|
||||
|
||||
public final Repository getRepository(final RepositoryKey repositoryKey) {
|
||||
return repositoryCache.findItem(repositoryKey);
|
||||
}
|
||||
|
||||
@ -23,6 +23,7 @@ import io.linuxserver.fleet.v2.key.RepositoryKey;
|
||||
import io.linuxserver.fleet.v2.types.meta.ItemSyncSpec;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
@ -74,6 +75,10 @@ public class Image extends AbstractSyncItem<ImageKey, Image> {
|
||||
return cloned;
|
||||
}
|
||||
|
||||
public final String getFullName() {
|
||||
return getRepositoryName() + "/" + getName();
|
||||
}
|
||||
|
||||
public final RepositoryKey getRepositoryKey() {
|
||||
return getKey().getRepositoryKey();
|
||||
}
|
||||
@ -94,6 +99,12 @@ public class Image extends AbstractSyncItem<ImageKey, Image> {
|
||||
return parseDateTime(lastUpdated);
|
||||
}
|
||||
|
||||
public final String getLastUpdatedAsString() {
|
||||
|
||||
final LocalDateTime lastUpdated = parseDateTime(this.lastUpdated);
|
||||
return null == lastUpdated ? null : DateTimeFormatter.ISO_DATE_TIME.format(lastUpdated);
|
||||
}
|
||||
|
||||
public final List<TagBranch> getTagBranches() {
|
||||
return new ArrayList<>(tagBranches);
|
||||
}
|
||||
|
||||
@ -44,27 +44,27 @@ public class DockerImage {
|
||||
this.buildDate = buildDate;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
public final String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public String getRepository() {
|
||||
public final String getRepository() {
|
||||
return repository;
|
||||
}
|
||||
|
||||
public String getDescription() {
|
||||
public final String getDescription() {
|
||||
return description;
|
||||
}
|
||||
|
||||
public int getStarCount() {
|
||||
public final int getStarCount() {
|
||||
return starCount;
|
||||
}
|
||||
|
||||
public long getPullCount() {
|
||||
public final long getPullCount() {
|
||||
return pullCount;
|
||||
}
|
||||
|
||||
public LocalDateTime getBuildDate() {
|
||||
public final LocalDateTime getBuildDate() {
|
||||
return buildDate;
|
||||
}
|
||||
}
|
||||
|
||||
@ -34,7 +34,7 @@ public interface Locations {
|
||||
// All pages
|
||||
String Home = "/";
|
||||
String Login = "/login";
|
||||
String Image = "/image/:imageKey";
|
||||
String Image = "/image";
|
||||
|
||||
// Api endpoints
|
||||
String ApiImages = "/api/v1/images";
|
||||
|
||||
@ -22,6 +22,7 @@ import io.linuxserver.fleet.core.FleetAppController;
|
||||
import io.linuxserver.fleet.core.config.WebConfiguration;
|
||||
import io.linuxserver.fleet.v2.web.routes.DefaultAccessManager;
|
||||
import io.linuxserver.fleet.v2.web.routes.HomeController;
|
||||
import io.linuxserver.fleet.v2.web.routes.ImageController;
|
||||
import io.linuxserver.fleet.v2.web.routes.LoginController;
|
||||
|
||||
public class WebRouteController {
|
||||
@ -46,6 +47,7 @@ public class WebRouteController {
|
||||
|
||||
webInstance.get(Locations.Login, new LoginController());
|
||||
webInstance.get(Locations.Home, new HomeController(app.getRepositoryManager()));
|
||||
webInstance.get(Locations.Image, new ImageController(app.getRepositoryManager()));
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
body.has-context-home {
|
||||
background-color: #eaeaea;
|
||||
body {
|
||||
font-size: 0.8rem;
|
||||
}
|
||||
|
||||
.card {
|
||||
@ -154,4 +154,8 @@ input:checked + .slider:before {
|
||||
|
||||
.slider.round:before {
|
||||
border-radius: 50%;
|
||||
}
|
||||
|
||||
table tbody th.is-half {
|
||||
width: 50%;
|
||||
}
|
||||
@ -30,8 +30,10 @@
|
||||
<div class="media-content">
|
||||
<div class="content">
|
||||
|
||||
<h4 class="title is-5">
|
||||
<span class="has-text-weight-light">${image.repositoryKey.name}/</span><span class="has-text-weight-500">${image.name}</span>
|
||||
<h4 class="title is-6">
|
||||
<a class="has-text-grey-dark" href="/image?name=${image.fullName}">
|
||||
<span class="has-text-weight-light">${image.repositoryKey.name}/</span><span class="has-text-weight-500">${image.name}</span>
|
||||
</a>
|
||||
</h4>
|
||||
|
||||
${image.description!""}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user