mirror of
https://github.com/linuxserver/fleet.git
synced 2026-02-20 05:11:08 +08:00
Refactored model classes to use a key rather than direct ID.
This commit is contained in:
parent
00ffb31c9c
commit
423ee87b18
@ -18,20 +18,19 @@
|
||||
package io.linuxserver.fleet.cache;
|
||||
|
||||
import io.linuxserver.fleet.model.internal.Image;
|
||||
import io.linuxserver.fleet.model.key.ImageKey;
|
||||
import io.linuxserver.fleet.model.key.RepositoryKey;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class ImageCache {
|
||||
|
||||
private static final Logger LOGGER = LoggerFactory.getLogger(ImageCache.class);
|
||||
|
||||
private final Map<Integer, List<Image>> cachedImages;
|
||||
private final Map<RepositoryKey, List<Image>> cachedImages;
|
||||
|
||||
public ImageCache() {
|
||||
this.cachedImages = new HashMap<>();
|
||||
@ -41,19 +40,19 @@ public class ImageCache {
|
||||
|
||||
Image updatedImage = Image.copyOf(image);
|
||||
|
||||
if (cachedImages.containsKey(updatedImage.getRepositoryId())) {
|
||||
if (cachedImages.containsKey(updatedImage.getKey().getRepositoryKey())) {
|
||||
|
||||
List<Image> images = cachedImages.get(updatedImage.getRepositoryId());
|
||||
List<Image> images = cachedImages.get(updatedImage.getKey().getRepositoryKey());
|
||||
int cachedImageLocation = images.indexOf(updatedImage);
|
||||
|
||||
if (cachedImageLocation > -1) {
|
||||
|
||||
LOGGER.info("updateCache({}) Updating existing cached image.", updatedImage.getName());
|
||||
LOGGER.info("updateCache({}) Updating existing cached image.", updatedImage);
|
||||
images.set(cachedImageLocation, updatedImage);
|
||||
|
||||
} else {
|
||||
|
||||
LOGGER.info("updateCache({}) Adding image to cache", updatedImage.getName());
|
||||
LOGGER.info("updateCache({}) Adding image to cache", updatedImage);
|
||||
images.add(updatedImage);
|
||||
}
|
||||
|
||||
@ -62,33 +61,37 @@ public class ImageCache {
|
||||
List<Image> images = new ArrayList<>();
|
||||
images.add(updatedImage);
|
||||
|
||||
LOGGER.info("updateCache({}:{}) Creating new cache for repository {}", updatedImage.getName(), updatedImage.getRepositoryId());
|
||||
cachedImages.put(updatedImage.getRepositoryId(), images);
|
||||
LOGGER.info("updateCache({}) Creating new cache for repository {}", updatedImage, updatedImage.getRepositoryId());
|
||||
cachedImages.put(updatedImage.getKey().getRepositoryKey(), images);
|
||||
}
|
||||
}
|
||||
|
||||
public List<Image> getAll(int repositoryId) {
|
||||
public List<Image> getAll(RepositoryKey repositoryKey) {
|
||||
|
||||
if (cachedImages.containsKey(repositoryId)) {
|
||||
return cachedImages.get(repositoryId).stream().map(Image::copyOf).collect(Collectors.toList());
|
||||
if (cachedImages.containsKey(repositoryKey)) {
|
||||
return cachedImages.get(repositoryKey).stream().map(Image::copyOf).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
return new ArrayList<>();
|
||||
}
|
||||
|
||||
public Image get(int repositoryId, String imageName) {
|
||||
public Image get(ImageKey imageKey) {
|
||||
|
||||
if (cachedImages.containsKey(repositoryId)) {
|
||||
return cachedImages.get(repositoryId).stream().filter(i -> i.getName().equals(imageName)).findFirst().orElse(null);
|
||||
final RepositoryKey repositoryKey = imageKey.getRepositoryKey();
|
||||
|
||||
if (cachedImages.containsKey(repositoryKey)) {
|
||||
return cachedImages.get(repositoryKey).stream().filter(i -> i.getName().equals(imageKey.getName())).findFirst().orElse(null);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public void remove(Image image) {
|
||||
public void remove(ImageKey imageKey) {
|
||||
|
||||
if (cachedImages.containsKey(image.getRepositoryId())) {
|
||||
cachedImages.get(image.getRepositoryId()).remove(image);
|
||||
final RepositoryKey repositoryKey = imageKey.getRepositoryKey();
|
||||
|
||||
if (cachedImages.containsKey(repositoryKey)) {
|
||||
cachedImages.get(repositoryKey).removeIf(image -> image.getKey().equals(imageKey));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -23,8 +23,9 @@ import io.linuxserver.fleet.db.query.InsertUpdateStatus;
|
||||
import io.linuxserver.fleet.db.query.LimitedResult;
|
||||
import io.linuxserver.fleet.model.internal.Image;
|
||||
import io.linuxserver.fleet.model.internal.ImagePullStat;
|
||||
import io.linuxserver.fleet.model.internal.Repository;
|
||||
import io.linuxserver.fleet.model.internal.Tag;
|
||||
import io.linuxserver.fleet.model.key.ImageKey;
|
||||
import io.linuxserver.fleet.model.key.RepositoryKey;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
@ -46,15 +47,15 @@ public class DefaultImageDAO implements ImageDAO {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Image findImageByRepositoryAndImageName(int repositoryId, String imageName) {
|
||||
public Image findImageByRepositoryAndImageName(ImageKey imageKey) {
|
||||
|
||||
CallableStatement call = null;
|
||||
|
||||
try (Connection connection = databaseConnection.getConnection()) {
|
||||
|
||||
call = connection.prepareCall("{CALL Image_GetByName(?,?)}");
|
||||
call.setInt(1, repositoryId);
|
||||
call.setString(2, imageName);
|
||||
call.setInt(1, imageKey.getRepositoryKey().getId());
|
||||
call.setString(2, imageKey.getName());
|
||||
|
||||
ResultSet results = call.executeQuery();
|
||||
if (results.next())
|
||||
@ -70,16 +71,16 @@ public class DefaultImageDAO implements ImageDAO {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Image fetchImage(Integer id) {
|
||||
public Image fetchImage(ImageKey imageKey) {
|
||||
|
||||
LOGGER.debug("Fetching image by ID: " + id);
|
||||
LOGGER.debug("Fetching image by ID: " + imageKey);
|
||||
|
||||
CallableStatement call = null;
|
||||
|
||||
try (Connection connection = databaseConnection.getConnection()) {
|
||||
|
||||
call = connection.prepareCall("{CALL Image_Get(?)}");
|
||||
call.setInt(1, id);
|
||||
call.setInt(1, imageKey.getId());
|
||||
|
||||
ResultSet results = call.executeQuery();
|
||||
if (results.next())
|
||||
@ -95,7 +96,7 @@ public class DefaultImageDAO implements ImageDAO {
|
||||
}
|
||||
|
||||
@Override
|
||||
public LimitedResult<Image> fetchImagesByRepository(int repositoryId) {
|
||||
public LimitedResult<Image> fetchImagesByRepository(final RepositoryKey repositoryKey) {
|
||||
|
||||
List<Image> images = new ArrayList<>();
|
||||
|
||||
@ -104,7 +105,7 @@ public class DefaultImageDAO implements ImageDAO {
|
||||
try (Connection connection = databaseConnection.getConnection()) {
|
||||
|
||||
call = connection.prepareCall("{CALL Image_GetAll(?,?)}");
|
||||
call.setInt(1, repositoryId);
|
||||
call.setInt(1, repositoryKey.getId());
|
||||
call.registerOutParameter(2, Types.INTEGER);
|
||||
|
||||
ResultSet results = call.executeQuery();
|
||||
@ -131,7 +132,7 @@ public class DefaultImageDAO implements ImageDAO {
|
||||
try (Connection connection = databaseConnection.getConnection()) {
|
||||
|
||||
call = connection.prepareCall("{CALL Image_Save(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)");
|
||||
setNullableInt(call, 1, image.getId());
|
||||
setNullableInt(call, 1, image.getKey().getId());
|
||||
call.setInt(2, image.getRepositoryId());
|
||||
call.setString(3, image.getName());
|
||||
setNullableLong(call, 4, image.getPullCount());
|
||||
@ -155,7 +156,7 @@ public class DefaultImageDAO implements ImageDAO {
|
||||
String statusMessage = call.getString(15);
|
||||
|
||||
if (InsertUpdateStatus.OK == status)
|
||||
return new InsertUpdateResult<>(fetchImage(imageId), status, statusMessage);
|
||||
return new InsertUpdateResult<>(fetchImage(image.getKey().cloneWithId(imageId)), status, statusMessage);
|
||||
|
||||
return new InsertUpdateResult<>(status, statusMessage);
|
||||
|
||||
@ -170,14 +171,14 @@ public class DefaultImageDAO implements ImageDAO {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeImage(Integer id) {
|
||||
public void removeImage(final ImageKey imageKey) {
|
||||
|
||||
CallableStatement call = null;
|
||||
|
||||
try (Connection connection = databaseConnection.getConnection()) {
|
||||
|
||||
call = connection.prepareCall("{CALL Image_Delete(?)}");
|
||||
call.setInt(1, id);
|
||||
call.setInt(1, imageKey.getId());
|
||||
|
||||
call.executeUpdate();
|
||||
call.close();
|
||||
@ -190,7 +191,7 @@ public class DefaultImageDAO implements ImageDAO {
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<ImagePullStat> fetchImagePullHistory(Integer imageId, ImagePullStat.GroupMode groupMode) {
|
||||
public List<ImagePullStat> fetchImagePullHistory(final ImageKey imageKey, ImagePullStat.GroupMode groupMode) {
|
||||
|
||||
List<ImagePullStat> pullHistory = new ArrayList<>();
|
||||
|
||||
@ -199,7 +200,7 @@ public class DefaultImageDAO implements ImageDAO {
|
||||
try (Connection connection = databaseConnection.getConnection()) {
|
||||
|
||||
call = connection.prepareCall("CALL Image_GetPullHistory(?, ?)");
|
||||
call.setInt(1, imageId);
|
||||
call.setInt(1, imageKey.getId());
|
||||
call.setString(2, groupMode.toString());
|
||||
|
||||
ResultSet results = call.executeQuery();
|
||||
@ -230,12 +231,14 @@ public class DefaultImageDAO implements ImageDAO {
|
||||
private Image parseImageFromResultSet(ResultSet results) throws SQLException {
|
||||
|
||||
Image image = new Image(
|
||||
results.getInt("ImageId"),
|
||||
new Repository(
|
||||
results.getInt("RepositoryId"),
|
||||
results.getString("RepositoryName")
|
||||
new ImageKey(
|
||||
results.getInt("ImageId"),
|
||||
results.getString("ImageName"),
|
||||
new RepositoryKey(
|
||||
results.getInt("RepositoryId"),
|
||||
results.getString("RepositoryName")
|
||||
)
|
||||
),
|
||||
results.getString("ImageName"),
|
||||
new Tag(
|
||||
results.getString("LatestTagVersion"),
|
||||
results.getString("LatestMaskedTagVersion"),
|
||||
|
||||
@ -21,6 +21,7 @@ import io.linuxserver.fleet.db.PoolingDatabaseConnection;
|
||||
import io.linuxserver.fleet.db.query.InsertUpdateResult;
|
||||
import io.linuxserver.fleet.db.query.InsertUpdateStatus;
|
||||
import io.linuxserver.fleet.model.internal.Repository;
|
||||
import io.linuxserver.fleet.model.key.RepositoryKey;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
@ -28,9 +29,7 @@ import java.sql.*;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import static io.linuxserver.fleet.db.dao.Utils.safeClose;
|
||||
import static io.linuxserver.fleet.db.dao.Utils.setNullableInt;
|
||||
import static io.linuxserver.fleet.db.dao.Utils.setNullableString;
|
||||
import static io.linuxserver.fleet.db.dao.Utils.*;
|
||||
|
||||
public class DefaultRepositoryDAO implements RepositoryDAO {
|
||||
|
||||
@ -43,14 +42,14 @@ public class DefaultRepositoryDAO implements RepositoryDAO {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Repository fetchRepository(int id) {
|
||||
public Repository fetchRepository(RepositoryKey repositoryKey) {
|
||||
|
||||
CallableStatement call = null;
|
||||
|
||||
try (Connection connection = databaseConnection.getConnection()) {
|
||||
|
||||
call = connection.prepareCall("{CALL Repository_Get(?)}");
|
||||
call.setInt(1, id);
|
||||
call.setInt(1, repositoryKey.getId());
|
||||
|
||||
ResultSet results = call.executeQuery();
|
||||
if (results.next())
|
||||
@ -73,7 +72,7 @@ public class DefaultRepositoryDAO implements RepositoryDAO {
|
||||
try (Connection connection = databaseConnection.getConnection()) {
|
||||
|
||||
call = connection.prepareCall("{CALL Repository_Save(?,?,?,?,?,?,?)}");
|
||||
setNullableInt(call, 1, repository.getId());
|
||||
setNullableInt(call, 1, repository.getKey().getId());
|
||||
call.setString(2, repository.getName());
|
||||
setNullableString(call, 3, repository.getVersionMask());
|
||||
call.setBoolean(4, repository.isSyncEnabled());
|
||||
@ -89,7 +88,7 @@ public class DefaultRepositoryDAO implements RepositoryDAO {
|
||||
String statusMessage = call.getString(7);
|
||||
|
||||
if (InsertUpdateStatus.OK == status)
|
||||
return new InsertUpdateResult<>(fetchRepository(repositoryId), status, statusMessage);
|
||||
return new InsertUpdateResult<>(fetchRepository(repository.getKey().cloneWithId(repositoryId)), status, statusMessage);
|
||||
|
||||
return new InsertUpdateResult<>(status, statusMessage);
|
||||
|
||||
@ -171,7 +170,7 @@ public class DefaultRepositoryDAO implements RepositoryDAO {
|
||||
|
||||
private Repository parseRepositoryFromResultSet(ResultSet results) throws SQLException {
|
||||
|
||||
Repository repository = new Repository(results.getInt("RepositoryId"), results.getString("RepositoryName"))
|
||||
Repository repository = new Repository(new RepositoryKey(results.getInt("RepositoryId"), results.getString("RepositoryName")))
|
||||
.withSyncEnabled(results.getBoolean("SyncEnabled"))
|
||||
.withVersionMask(results.getString("RepositoryVersionMask"))
|
||||
.withModifiedTime(results.getTimestamp("ModifiedTime").toLocalDateTime());
|
||||
|
||||
@ -85,7 +85,7 @@ public class DefaultUserDAO implements UserDAO {
|
||||
try (Connection connection = databaseConnection.getConnection()) {
|
||||
|
||||
CallableStatement call = connection.prepareCall("{CALL User_Save(?,?,?,?,?,?)}");
|
||||
setNullableInt(call, 1, user.getId());
|
||||
setNullableInt(call, 1, user.getKey().getId());
|
||||
call.setString(2, user.getUsername());
|
||||
setNullableString(call, 3, user.getPassword());
|
||||
|
||||
@ -137,7 +137,7 @@ public class DefaultUserDAO implements UserDAO {
|
||||
try (Connection connection = databaseConnection.getConnection()) {
|
||||
|
||||
CallableStatement call = connection.prepareCall("{CALL User_Delete(?)}");
|
||||
call.setInt(1, user.getId());
|
||||
call.setInt(1, user.getKey().getId());
|
||||
|
||||
call.executeUpdate();
|
||||
|
||||
|
||||
@ -4,20 +4,22 @@ import io.linuxserver.fleet.db.query.InsertUpdateResult;
|
||||
import io.linuxserver.fleet.db.query.LimitedResult;
|
||||
import io.linuxserver.fleet.model.internal.Image;
|
||||
import io.linuxserver.fleet.model.internal.ImagePullStat;
|
||||
import io.linuxserver.fleet.model.key.ImageKey;
|
||||
import io.linuxserver.fleet.model.key.RepositoryKey;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public interface ImageDAO {
|
||||
|
||||
Image findImageByRepositoryAndImageName(int repositoryId, String imageName);
|
||||
Image findImageByRepositoryAndImageName(ImageKey imageKey);
|
||||
|
||||
Image fetchImage(Integer id);
|
||||
Image fetchImage(ImageKey imageKey);
|
||||
|
||||
LimitedResult<Image> fetchImagesByRepository(int repositoryId);
|
||||
LimitedResult<Image> fetchImagesByRepository(RepositoryKey repositoryKey);
|
||||
|
||||
InsertUpdateResult<Image> saveImage(Image image);
|
||||
|
||||
void removeImage(Integer id);
|
||||
void removeImage(ImageKey imageKey);
|
||||
|
||||
List<ImagePullStat> fetchImagePullHistory(Integer imageId, ImagePullStat.GroupMode groupMode);
|
||||
List<ImagePullStat> fetchImagePullHistory(ImageKey imageKey, ImagePullStat.GroupMode groupMode);
|
||||
}
|
||||
|
||||
@ -2,12 +2,13 @@ package io.linuxserver.fleet.db.dao;
|
||||
|
||||
import io.linuxserver.fleet.db.query.InsertUpdateResult;
|
||||
import io.linuxserver.fleet.model.internal.Repository;
|
||||
import io.linuxserver.fleet.model.key.RepositoryKey;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public interface RepositoryDAO {
|
||||
|
||||
Repository fetchRepository(int id);
|
||||
Repository fetchRepository(RepositoryKey repositoryKey);
|
||||
|
||||
InsertUpdateResult<Repository> saveRepository(Repository repository);
|
||||
|
||||
|
||||
@ -24,6 +24,8 @@ import io.linuxserver.fleet.db.query.InsertUpdateStatus;
|
||||
import io.linuxserver.fleet.exception.SaveException;
|
||||
import io.linuxserver.fleet.model.internal.Image;
|
||||
import io.linuxserver.fleet.model.internal.ImagePullStat;
|
||||
import io.linuxserver.fleet.model.key.ImageKey;
|
||||
import io.linuxserver.fleet.model.key.RepositoryKey;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@ -45,13 +47,13 @@ public class ImageDelegate {
|
||||
* already has the image stored against the repository.
|
||||
* </p>
|
||||
*/
|
||||
public Image findImageByRepositoryAndImageName(int repositoryId, String imageName) {
|
||||
public Image findImageByRepositoryAndImageName(final ImageKey imageKey) {
|
||||
|
||||
Image cachedImage = imageCache.get(repositoryId, imageName);
|
||||
Image cachedImage = imageCache.get(imageKey);
|
||||
|
||||
if (null == cachedImage) {
|
||||
|
||||
Image image = imageDAO.findImageByRepositoryAndImageName(repositoryId, imageName);
|
||||
Image image = imageDAO.findImageByRepositoryAndImageName(imageKey);
|
||||
|
||||
if (null != image) {
|
||||
imageCache.updateCache(image);
|
||||
@ -63,16 +65,16 @@ public class ImageDelegate {
|
||||
return cachedImage;
|
||||
}
|
||||
|
||||
public Image fetchImage(int id) {
|
||||
return imageDAO.fetchImage(id);
|
||||
public Image fetchImage(ImageKey imageKey) {
|
||||
return imageDAO.fetchImage(imageKey);
|
||||
}
|
||||
|
||||
public List<Image> fetchImagesByRepository(int repositoryId) {
|
||||
public List<Image> fetchImagesByRepository(final RepositoryKey repositoryKey) {
|
||||
|
||||
List<Image> cachedImages = imageCache.getAll(repositoryId);
|
||||
List<Image> cachedImages = imageCache.getAll(repositoryKey);
|
||||
if (cachedImages.isEmpty()) {
|
||||
|
||||
List<Image> images = imageDAO.fetchImagesByRepository(repositoryId).getResults();
|
||||
List<Image> images = imageDAO.fetchImagesByRepository(repositoryKey).getResults();
|
||||
images.forEach(imageCache::updateCache);
|
||||
|
||||
return images;
|
||||
@ -81,13 +83,13 @@ public class ImageDelegate {
|
||||
return cachedImages;
|
||||
}
|
||||
|
||||
public void removeImage(Integer id) {
|
||||
public void removeImage(ImageKey imageKey) {
|
||||
|
||||
Image existingImage = imageDAO.fetchImage(id);
|
||||
Image existingImage = imageDAO.fetchImage(imageKey);
|
||||
if (null != existingImage) {
|
||||
|
||||
imageDAO.removeImage(id);
|
||||
imageCache.remove(existingImage);
|
||||
imageDAO.removeImage(imageKey);
|
||||
imageCache.remove(imageKey);
|
||||
}
|
||||
}
|
||||
|
||||
@ -106,7 +108,7 @@ public class ImageDelegate {
|
||||
throw new SaveException(result.getStatusMessage());
|
||||
}
|
||||
|
||||
public List<ImagePullStat> fetchImagePullHistory(int id, ImagePullStat.GroupMode groupMode) {
|
||||
return imageDAO.fetchImagePullHistory(id, groupMode);
|
||||
public List<ImagePullStat> fetchImagePullHistory(ImageKey imageKey, ImagePullStat.GroupMode groupMode) {
|
||||
return imageDAO.fetchImagePullHistory(imageKey, groupMode);
|
||||
}
|
||||
}
|
||||
|
||||
@ -22,6 +22,7 @@ import io.linuxserver.fleet.db.query.InsertUpdateResult;
|
||||
import io.linuxserver.fleet.db.query.InsertUpdateStatus;
|
||||
import io.linuxserver.fleet.exception.SaveException;
|
||||
import io.linuxserver.fleet.model.internal.Repository;
|
||||
import io.linuxserver.fleet.model.key.RepositoryKey;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@ -33,8 +34,8 @@ public class RepositoryDelegate {
|
||||
this.repositoryDAO = repositoryDAO;
|
||||
}
|
||||
|
||||
public Repository fetchRepository(int id) {
|
||||
return repositoryDAO.fetchRepository(id);
|
||||
public Repository fetchRepository(RepositoryKey repositoryKey) {
|
||||
return repositoryDAO.fetchRepository(repositoryKey);
|
||||
}
|
||||
|
||||
public Repository saveRepository(Repository repository) throws SaveException {
|
||||
|
||||
@ -20,8 +20,8 @@ package io.linuxserver.fleet.dockerhub.queue;
|
||||
import io.linuxserver.fleet.delegate.DockerHubDelegate;
|
||||
import io.linuxserver.fleet.model.internal.Image;
|
||||
import io.linuxserver.fleet.queue.FleetRequest;
|
||||
|
||||
import java.util.Objects;
|
||||
import org.apache.commons.lang3.builder.EqualsBuilder;
|
||||
import org.apache.commons.lang3.builder.HashCodeBuilder;
|
||||
|
||||
public class DockerHubSyncRequest implements FleetRequest<DockerHubSyncResponse> {
|
||||
|
||||
@ -41,14 +41,15 @@ public class DockerHubSyncRequest implements FleetRequest<DockerHubSyncResponse>
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
DockerHubSyncRequest that = (DockerHubSyncRequest) o;
|
||||
return Objects.equals(image, that.image);
|
||||
|
||||
if (!(o instanceof DockerHubSyncRequest))
|
||||
return false;
|
||||
|
||||
return EqualsBuilder.reflectionEquals(this, "dockerHubDelegate");
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(image);
|
||||
return HashCodeBuilder.reflectionHashCode(this, "dockerHubDelegate");
|
||||
}
|
||||
}
|
||||
|
||||
@ -41,8 +41,9 @@ public class DockerHubSyncResponse implements FleetResponse {
|
||||
@Override
|
||||
public void handle() {
|
||||
|
||||
DockerImage dockerImage = dockerHubDelegate.fetchImageFromRepository(image.getRepository().getName(), image.getName());
|
||||
String versionMask = getVersionMask(image.getRepository().getVersionMask(), image.getVersionMask());
|
||||
DockerImage dockerImage = dockerHubDelegate.fetchImageFromRepository(image.getKey().getRepositoryKey().getName(), image.getName());
|
||||
|
||||
String versionMask = getVersionMask(null, image.getVersionMask());
|
||||
Tag maskedVersion = getLatestTagAndCreateMaskedVersion(versionMask);
|
||||
|
||||
image.withPullCount(dockerImage.getPullCount());
|
||||
@ -59,7 +60,7 @@ public class DockerHubSyncResponse implements FleetResponse {
|
||||
|
||||
private Tag getLatestTagAndCreateMaskedVersion(String versionMask) {
|
||||
|
||||
DockerTag tag = dockerHubDelegate.fetchLatestImageTag(image.getRepository().getName(), image.getName());
|
||||
DockerTag tag = dockerHubDelegate.fetchLatestImageTag(image.getKey().getRepositoryKey().getName(), image.getName());
|
||||
|
||||
if (null == tag)
|
||||
return Tag.NONE;
|
||||
|
||||
@ -49,7 +49,7 @@ public class ApiImagePullHistory {
|
||||
public static ApiImagePullHistory fromPullStats(Image image, List<ImagePullStat> stats) {
|
||||
|
||||
ApiImagePullHistory history = new ApiImagePullHistory();
|
||||
history.imageId = image.getId();
|
||||
history.imageId = image.getKey().getId();
|
||||
history.imageName = image.getName();
|
||||
history.groupMode = stats.get(0).getGroupMode().toString();
|
||||
|
||||
|
||||
@ -17,9 +17,11 @@
|
||||
|
||||
package io.linuxserver.fleet.model.internal;
|
||||
|
||||
import io.linuxserver.fleet.model.key.AbstractHasKey;
|
||||
import io.linuxserver.fleet.model.key.ImageKey;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
@ -27,36 +29,35 @@ import java.util.Objects;
|
||||
* specific information regarding its build status and pull count.
|
||||
* </p>
|
||||
*/
|
||||
public class Image extends PersistableItem<Image> {
|
||||
public class Image extends AbstractHasKey<ImageKey> {
|
||||
|
||||
private final Repository repository;
|
||||
private final String name;
|
||||
private static final DateTimeFormatter DATE_PATTERN = DateTimeFormatter.ofPattern("dd MMM yyyy HH:mm:ss");
|
||||
|
||||
private Tag tag;
|
||||
private long pullCount;
|
||||
private String versionMask;
|
||||
private boolean unstable;
|
||||
private boolean hidden;
|
||||
|
||||
private LocalDateTime modifiedTime;
|
||||
private boolean deprecated;
|
||||
private String deprecationReason;
|
||||
|
||||
public Image(Integer id, Repository repository, String name, Tag latestVersion) {
|
||||
|
||||
super(id);
|
||||
|
||||
this.name = name;
|
||||
this.repository = repository;
|
||||
this.tag = new Tag(latestVersion.getVersion(), latestVersion.getMaskedVersion(), latestVersion.getBuildDate());
|
||||
public Image(final ImageKey imageKey, final Tag latestVersion) {
|
||||
super(imageKey);
|
||||
this.tag = new Tag(latestVersion.getVersion(), latestVersion.getMaskedVersion(), latestVersion.getBuildDate());
|
||||
}
|
||||
|
||||
public Image(Repository repository, String name) {
|
||||
this(null, repository, name, Tag.NONE);
|
||||
public Image(final ImageKey imageKey) {
|
||||
this(imageKey, Tag.NONE);
|
||||
}
|
||||
|
||||
public static Image makeFromKey(ImageKey imageKey) {
|
||||
return new Image(imageKey);
|
||||
}
|
||||
|
||||
public static Image copyOf(Image image) {
|
||||
|
||||
Image cloned = new Image(image.getId(), Repository.copyOf(image.repository), image.name, image.tag);
|
||||
Image cloned = new Image(image.getKey(), image.tag);
|
||||
cloned.pullCount = image.pullCount;
|
||||
cloned.versionMask = image.versionMask;
|
||||
cloned.unstable = image.unstable;
|
||||
@ -103,20 +104,22 @@ public class Image extends PersistableItem<Image> {
|
||||
return this;
|
||||
}
|
||||
|
||||
public Image withModifiedTime(final LocalDateTime modifiedTime) {
|
||||
|
||||
this.modifiedTime = modifiedTime;
|
||||
return this;
|
||||
}
|
||||
|
||||
public void updateTag(Tag maskedVersion) {
|
||||
this.tag = new Tag(maskedVersion.getVersion(), maskedVersion.getMaskedVersion(), maskedVersion.getBuildDate());
|
||||
}
|
||||
|
||||
public int getRepositoryId() {
|
||||
return repository.getId();
|
||||
}
|
||||
|
||||
public Repository getRepository() {
|
||||
return repository;
|
||||
return getKey().getRepositoryKey().getId();
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
return getKey().getName();
|
||||
}
|
||||
|
||||
public long getPullCount() {
|
||||
@ -138,7 +141,7 @@ public class Image extends PersistableItem<Image> {
|
||||
public String getBuildDateAsString() {
|
||||
|
||||
if (getBuildDate() != null) {
|
||||
return getBuildDate().format(DateTimeFormatter.ofPattern("dd MMM yyyy HH:mm:ss"));
|
||||
return getBuildDate().format(DATE_PATTERN);
|
||||
}
|
||||
|
||||
return null;
|
||||
@ -164,17 +167,20 @@ public class Image extends PersistableItem<Image> {
|
||||
return deprecationReason;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
public LocalDateTime getModifiedTime() {
|
||||
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
Image image = (Image) o;
|
||||
return Objects.equals(repository, image.repository) && Objects.equals(name, image.name);
|
||||
}
|
||||
if (null != modifiedTime) {
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(repository, name);
|
||||
return LocalDateTime.of(
|
||||
modifiedTime.getYear(),
|
||||
modifiedTime.getMonth(),
|
||||
modifiedTime.getDayOfMonth(),
|
||||
modifiedTime.getHour(),
|
||||
modifiedTime.getMinute(),
|
||||
modifiedTime.getSecond()
|
||||
);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@ -17,29 +17,23 @@
|
||||
|
||||
package io.linuxserver.fleet.model.internal;
|
||||
|
||||
import java.util.Objects;
|
||||
import io.linuxserver.fleet.model.key.AbstractHasKey;
|
||||
import io.linuxserver.fleet.model.key.RepositoryKey;
|
||||
|
||||
public class Repository extends PersistableItem<Repository> {
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
private final String name;
|
||||
public class Repository extends AbstractHasKey<RepositoryKey> {
|
||||
|
||||
private String versionMask;
|
||||
private boolean syncEnabled;
|
||||
private String versionMask;
|
||||
private boolean syncEnabled;
|
||||
private LocalDateTime modifiedTime;
|
||||
|
||||
public Repository(Integer id, String name) {
|
||||
super(id);
|
||||
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public Repository(String name) {
|
||||
super();
|
||||
|
||||
this.name = name;
|
||||
public Repository(final RepositoryKey repositoryKey) {
|
||||
super(repositoryKey);
|
||||
}
|
||||
|
||||
public static Repository copyOf(Repository repository) {
|
||||
return new Repository(repository.getId(), repository.name).withVersionMask(repository.versionMask).withSyncEnabled(repository.syncEnabled);
|
||||
return new Repository(repository.getKey()).withVersionMask(repository.versionMask).withSyncEnabled(repository.syncEnabled);
|
||||
}
|
||||
|
||||
public Repository withVersionMask(String versionMask) {
|
||||
@ -54,8 +48,14 @@ public class Repository extends PersistableItem<Repository> {
|
||||
return this;
|
||||
}
|
||||
|
||||
public Repository withModifiedTime(LocalDateTime modifiedTime) {
|
||||
|
||||
this.modifiedTime = modifiedTime;
|
||||
return this;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
return getKey().getName();
|
||||
}
|
||||
|
||||
public String getVersionMask() {
|
||||
@ -66,16 +66,20 @@ public class Repository extends PersistableItem<Repository> {
|
||||
return syncEnabled;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
Repository that = (Repository) o;
|
||||
return Objects.equals(name, that.name);
|
||||
}
|
||||
public LocalDateTime getModifiedTime() {
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(name);
|
||||
if (null != modifiedTime) {
|
||||
|
||||
return LocalDateTime.of(
|
||||
modifiedTime.getYear(),
|
||||
modifiedTime.getMonth(),
|
||||
modifiedTime.getDayOfMonth(),
|
||||
modifiedTime.getHour(),
|
||||
modifiedTime.getMinute(),
|
||||
modifiedTime.getSecond()
|
||||
);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@ -17,20 +17,27 @@
|
||||
|
||||
package io.linuxserver.fleet.model.internal;
|
||||
|
||||
public class User extends PersistableItem<User> {
|
||||
import io.linuxserver.fleet.model.key.AbstractHasKey;
|
||||
import io.linuxserver.fleet.model.key.UserKey;
|
||||
|
||||
private final String username;
|
||||
private final String password;
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
public class User extends AbstractHasKey<UserKey> {
|
||||
|
||||
private final String username;
|
||||
private final String password;
|
||||
|
||||
private LocalDateTime modifiedTime;
|
||||
|
||||
public User(String username, String password) {
|
||||
super();
|
||||
super(new UserKey());
|
||||
|
||||
this.username = username;
|
||||
this.password = password;
|
||||
}
|
||||
|
||||
public User(Integer id, String username, String password) {
|
||||
super(id);
|
||||
super(new UserKey(id));
|
||||
|
||||
this.username = username;
|
||||
this.password = password;
|
||||
@ -43,4 +50,27 @@ public class User extends PersistableItem<User> {
|
||||
public String getPassword() {
|
||||
return password;
|
||||
}
|
||||
|
||||
public User withModifiedTime(LocalDateTime modifiedTime) {
|
||||
|
||||
this.modifiedTime = modifiedTime;
|
||||
return this;
|
||||
}
|
||||
|
||||
public LocalDateTime getModifiedTime() {
|
||||
|
||||
if (null != modifiedTime) {
|
||||
|
||||
return LocalDateTime.of(
|
||||
modifiedTime.getYear(),
|
||||
modifiedTime.getMonth(),
|
||||
modifiedTime.getDayOfMonth(),
|
||||
modifiedTime.getHour(),
|
||||
modifiedTime.getMinute(),
|
||||
modifiedTime.getSecond()
|
||||
);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@ -0,0 +1,52 @@
|
||||
/*
|
||||
* Copyright (c) 2019 LinuxServer.io
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package io.linuxserver.fleet.model.key;
|
||||
|
||||
public abstract class AbstractHasKey<KEY extends Key> implements HasKey<KEY> {
|
||||
|
||||
private final KEY key;
|
||||
|
||||
public AbstractHasKey(final KEY key) {
|
||||
this.key = key;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final KEY getKey() {
|
||||
return key;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return key.hashCode();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
|
||||
if (!(o instanceof HasKey<?>)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return key.equals(((HasKey<?>) o).getKey());
|
||||
}
|
||||
|
||||
@Override
|
||||
public final String toString() {
|
||||
return key.toString();
|
||||
}
|
||||
}
|
||||
@ -15,41 +15,47 @@
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package io.linuxserver.fleet.model.internal;
|
||||
package io.linuxserver.fleet.model.key;
|
||||
|
||||
import org.apache.commons.lang3.builder.ToStringBuilder;
|
||||
import org.apache.commons.lang3.builder.ToStringStyle;
|
||||
public abstract class AbstractKey implements Key {
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
private final Integer id;
|
||||
|
||||
public abstract class PersistableItem<T extends PersistableItem> {
|
||||
|
||||
private Integer id;
|
||||
private LocalDateTime modifiedTime;
|
||||
|
||||
PersistableItem() { }
|
||||
|
||||
PersistableItem(Integer id) {
|
||||
public AbstractKey(final Integer id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public T withModifiedTime(LocalDateTime modifiedTime) {
|
||||
|
||||
this.modifiedTime = modifiedTime;
|
||||
return (T) this;
|
||||
}
|
||||
|
||||
public Integer getId() {
|
||||
@Override
|
||||
public final Integer getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public LocalDateTime getModifiedTime() {
|
||||
return modifiedTime;
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
|
||||
if (!(o instanceof Key)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (null == id) {
|
||||
return ((Key) o).getId() == null;
|
||||
}
|
||||
|
||||
return ((Key) o).getId().equals(id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
|
||||
if (null == id) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return id.hashCode();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return ToStringBuilder.reflectionToString(this, ToStringStyle.SHORT_PREFIX_STYLE);
|
||||
return null == id ? "<NO_ID>" : String.valueOf(id);
|
||||
}
|
||||
}
|
||||
23
src/main/java/io/linuxserver/fleet/model/key/HasKey.java
Normal file
23
src/main/java/io/linuxserver/fleet/model/key/HasKey.java
Normal file
@ -0,0 +1,23 @@
|
||||
/*
|
||||
* Copyright (c) 2019 LinuxServer.io
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package io.linuxserver.fleet.model.key;
|
||||
|
||||
public interface HasKey<KEY extends Key> {
|
||||
|
||||
KEY getKey();
|
||||
}
|
||||
56
src/main/java/io/linuxserver/fleet/model/key/ImageKey.java
Normal file
56
src/main/java/io/linuxserver/fleet/model/key/ImageKey.java
Normal file
@ -0,0 +1,56 @@
|
||||
/*
|
||||
* Copyright (c) 2019 LinuxServer.io
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package io.linuxserver.fleet.model.key;
|
||||
|
||||
public class ImageKey extends AbstractKey {
|
||||
|
||||
private final RepositoryKey repositoryKey;
|
||||
private final String name;
|
||||
|
||||
public ImageKey(final String name, final RepositoryKey repositoryKey) {
|
||||
this(null, name, repositoryKey);
|
||||
}
|
||||
|
||||
public ImageKey(final Integer id, final String name, final RepositoryKey repositoryKey) {
|
||||
super(id);
|
||||
|
||||
this.repositoryKey = repositoryKey;
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public static ImageKey makeForLookup(final int imageId) {
|
||||
return new ImageKey(imageId, "<LookupKey>", null);
|
||||
}
|
||||
|
||||
public ImageKey cloneWithId(int id) {
|
||||
return new ImageKey(id, name, repositoryKey);
|
||||
}
|
||||
|
||||
public final RepositoryKey getRepositoryKey() {
|
||||
return repositoryKey;
|
||||
}
|
||||
|
||||
public final String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return super.toString() + ":" + (repositoryKey == null ? "<LookupKey>" : repositoryKey.getName()) + "/" + name;
|
||||
}
|
||||
}
|
||||
23
src/main/java/io/linuxserver/fleet/model/key/Key.java
Normal file
23
src/main/java/io/linuxserver/fleet/model/key/Key.java
Normal file
@ -0,0 +1,23 @@
|
||||
/*
|
||||
* Copyright (c) 2019 LinuxServer.io
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package io.linuxserver.fleet.model.key;
|
||||
|
||||
public interface Key {
|
||||
|
||||
Integer getId();
|
||||
}
|
||||
@ -0,0 +1,49 @@
|
||||
/*
|
||||
* Copyright (c) 2019 LinuxServer.io
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package io.linuxserver.fleet.model.key;
|
||||
|
||||
public class RepositoryKey extends AbstractKey {
|
||||
|
||||
private final String name;
|
||||
|
||||
public RepositoryKey(final int id) {
|
||||
this(id, "<LookupKey>");
|
||||
}
|
||||
|
||||
public RepositoryKey(final String name) {
|
||||
this(null, name);
|
||||
}
|
||||
|
||||
public RepositoryKey(final Integer id, final String name) {
|
||||
super(id);
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public RepositoryKey cloneWithId(int id) {
|
||||
return new RepositoryKey(id, name);
|
||||
}
|
||||
|
||||
public final String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return super.toString() + ":" + name;
|
||||
}
|
||||
}
|
||||
29
src/main/java/io/linuxserver/fleet/model/key/UserKey.java
Normal file
29
src/main/java/io/linuxserver/fleet/model/key/UserKey.java
Normal file
@ -0,0 +1,29 @@
|
||||
/*
|
||||
* Copyright (c) 2019 LinuxServer.io
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package io.linuxserver.fleet.model.key;
|
||||
|
||||
public class UserKey extends AbstractKey {
|
||||
|
||||
public UserKey() {
|
||||
this(null);
|
||||
}
|
||||
|
||||
public UserKey(Integer id) {
|
||||
super(id);
|
||||
}
|
||||
}
|
||||
@ -24,6 +24,8 @@ import io.linuxserver.fleet.model.docker.DockerTag;
|
||||
import io.linuxserver.fleet.model.internal.Image;
|
||||
import io.linuxserver.fleet.model.internal.Repository;
|
||||
import io.linuxserver.fleet.model.internal.Tag;
|
||||
import io.linuxserver.fleet.model.key.ImageKey;
|
||||
import io.linuxserver.fleet.model.key.RepositoryKey;
|
||||
import io.linuxserver.fleet.sync.event.ImageUpdateEvent;
|
||||
import io.linuxserver.fleet.sync.event.RepositoriesScannedEvent;
|
||||
import org.slf4j.Logger;
|
||||
@ -167,7 +169,7 @@ public class DefaultSynchronisationState implements SynchronisationState {
|
||||
if (!repositories.contains(storedRepository.getName())) {
|
||||
|
||||
LOGGER.info("Found repository which no longer exists in Docker Hub. Removing {}", storedRepository.getName());
|
||||
context.getRepositoryDelegate().removeRepository(storedRepository.getId());
|
||||
context.getRepositoryDelegate().removeRepository(storedRepository.getKey().getId());
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -177,12 +179,12 @@ public class DefaultSynchronisationState implements SynchronisationState {
|
||||
List<String> dockerHubImageNames = images.stream().map(DockerImage::getName).collect(Collectors.toList());
|
||||
|
||||
LOGGER.info("Checking for any removed images under {}", repository.getName());
|
||||
for (Image storedImage : context.getImageDelegate().fetchImagesByRepository(repository.getId())) {
|
||||
for (Image storedImage : context.getImageDelegate().fetchImagesByRepository(repository.getKey())) {
|
||||
|
||||
if (!dockerHubImageNames.contains(storedImage.getName())) {
|
||||
|
||||
LOGGER.info("Found image which no longer exists in Docker Hub. Removing {}", storedImage.getName());
|
||||
context.getImageDelegate().removeImage(storedImage.getId());
|
||||
context.getImageDelegate().removeImage(storedImage.getKey());
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -216,7 +218,7 @@ public class DefaultSynchronisationState implements SynchronisationState {
|
||||
|
||||
try {
|
||||
|
||||
return context.getRepositoryDelegate().saveRepository(new Repository(repositoryName));
|
||||
return context.getRepositoryDelegate().saveRepository(new Repository(new RepositoryKey(repositoryName)));
|
||||
|
||||
} catch (SaveException e) {
|
||||
LOGGER.error("Tried to save new repository during sync but failed", e);
|
||||
@ -232,13 +234,14 @@ public class DefaultSynchronisationState implements SynchronisationState {
|
||||
*/
|
||||
private Image configureImage(Repository repository, DockerImage dockerHubImage, SynchronisationContext context) {
|
||||
|
||||
Image image = context.getImageDelegate().findImageByRepositoryAndImageName(repository.getId(), dockerHubImage.getName());
|
||||
final ImageKey baseImageKey = new ImageKey(dockerHubImage.getName(), repository.getKey());
|
||||
final Image image = context.getImageDelegate().findImageByRepositoryAndImageName(baseImageKey);
|
||||
|
||||
if (isImageNew(image)) {
|
||||
|
||||
try {
|
||||
|
||||
return context.getImageDelegate().saveImage(new Image(repository, dockerHubImage.getName()));
|
||||
return context.getImageDelegate().saveImage(Image.makeFromKey(baseImageKey));
|
||||
|
||||
} catch (SaveException e) {
|
||||
LOGGER.error("Tried to save new image during sync but failed", e);
|
||||
|
||||
@ -51,7 +51,7 @@ public class HomePage extends WebPage {
|
||||
for (Repository repository : repositories) {
|
||||
|
||||
if (repository.isSyncEnabled())
|
||||
populatedRepositories.add(new RepositoryWithImages(repository, imageDelegate.fetchImagesByRepository(repository.getId())));
|
||||
populatedRepositories.add(new RepositoryWithImages(repository, imageDelegate.fetchImagesByRepository(repository.getKey())));
|
||||
}
|
||||
|
||||
model.put("populatedRepositories", populatedRepositories);
|
||||
|
||||
@ -55,7 +55,7 @@ public class AllImagesApi implements Route {
|
||||
|
||||
if (repository.isSyncEnabled()) {
|
||||
|
||||
List<Image> savedImages = imageDelegate.fetchImagesByRepository(repository.getId());
|
||||
List<Image> savedImages = imageDelegate.fetchImagesByRepository(repository.getKey());
|
||||
List<ApiImage> apiImages = new ArrayList<>();
|
||||
|
||||
for (Image savedImage : savedImages) {
|
||||
|
||||
@ -21,6 +21,7 @@ import io.linuxserver.fleet.delegate.ImageDelegate;
|
||||
import io.linuxserver.fleet.model.internal.Image;
|
||||
import io.linuxserver.fleet.model.api.ApiResponse;
|
||||
import io.linuxserver.fleet.model.api.FleetApiException;
|
||||
import io.linuxserver.fleet.model.key.ImageKey;
|
||||
import spark.Request;
|
||||
import spark.Response;
|
||||
import spark.Route;
|
||||
@ -41,7 +42,7 @@ public class GetImageApi implements Route {
|
||||
throw new FleetApiException(400, "Missing imageId param");
|
||||
}
|
||||
|
||||
Image image = imageDelegate.fetchImage(Integer.parseInt(imageIdParam));
|
||||
Image image = imageDelegate.fetchImage(ImageKey.makeForLookup(Integer.parseInt(imageIdParam)));
|
||||
if (null == image) {
|
||||
throw new FleetApiException(404, "Image not found");
|
||||
}
|
||||
|
||||
@ -23,6 +23,7 @@ import io.linuxserver.fleet.model.internal.ImagePullStat;
|
||||
import io.linuxserver.fleet.model.api.ApiImagePullHistory;
|
||||
import io.linuxserver.fleet.model.api.ApiResponse;
|
||||
import io.linuxserver.fleet.model.api.FleetApiException;
|
||||
import io.linuxserver.fleet.model.key.ImageKey;
|
||||
import spark.Request;
|
||||
import spark.Response;
|
||||
import spark.Route;
|
||||
@ -45,10 +46,10 @@ public class GetImagePullHistoryApi implements Route {
|
||||
throw new FleetApiException(400, "Missing imageId param");
|
||||
}
|
||||
|
||||
int imageId = Integer.parseInt(imageIdParam);
|
||||
List<ImagePullStat> imagePullStats = imageDelegate.fetchImagePullHistory(imageId, getGroupMode(request));
|
||||
final ImageKey lookupKey = ImageKey.makeForLookup(Integer.parseInt(imageIdParam));
|
||||
List<ImagePullStat> imagePullStats = imageDelegate.fetchImagePullHistory(lookupKey, getGroupMode(request));
|
||||
|
||||
Image image = imageDelegate.fetchImage(imageId);
|
||||
Image image = imageDelegate.fetchImage(lookupKey);
|
||||
return new ApiResponse<>("OK", ApiImagePullHistory.fromPullStats(image, imagePullStats));
|
||||
}
|
||||
|
||||
|
||||
@ -21,6 +21,7 @@ import io.linuxserver.fleet.delegate.ImageDelegate;
|
||||
import io.linuxserver.fleet.model.internal.Image;
|
||||
import io.linuxserver.fleet.model.api.ApiResponse;
|
||||
import io.linuxserver.fleet.model.api.FleetApiException;
|
||||
import io.linuxserver.fleet.model.key.ImageKey;
|
||||
import spark.Request;
|
||||
import spark.Response;
|
||||
import spark.Route;
|
||||
@ -40,7 +41,7 @@ public class ManageImageApi implements Route {
|
||||
|
||||
int imageId = Integer.parseInt(request.queryParams("imageId"));
|
||||
|
||||
Image image = imageDelegate.fetchImage(imageId);
|
||||
Image image = imageDelegate.fetchImage(ImageKey.makeForLookup(imageId));
|
||||
if (null == image) {
|
||||
|
||||
response.status(404);
|
||||
|
||||
@ -21,6 +21,7 @@ import io.linuxserver.fleet.delegate.RepositoryDelegate;
|
||||
import io.linuxserver.fleet.model.internal.Repository;
|
||||
import io.linuxserver.fleet.model.api.ApiResponse;
|
||||
import io.linuxserver.fleet.model.api.FleetApiException;
|
||||
import io.linuxserver.fleet.model.key.RepositoryKey;
|
||||
import spark.Request;
|
||||
import spark.Response;
|
||||
import spark.Route;
|
||||
@ -40,7 +41,7 @@ public class ManageRepositoryApi implements Route {
|
||||
|
||||
int repositoryId = Integer.parseInt(request.queryParams("repositoryId"));
|
||||
|
||||
Repository repository = repositoryDelegate.fetchRepository(repositoryId);
|
||||
Repository repository = repositoryDelegate.fetchRepository(new RepositoryKey(repositoryId));
|
||||
if (null == repository) {
|
||||
|
||||
response.status(404);
|
||||
|
||||
@ -34,7 +34,7 @@
|
||||
<tbody>
|
||||
|
||||
<#list repositories as repository>
|
||||
<tr data-repository-id="#{repository.id}">
|
||||
<tr data-repository-id="#{repository.key.id}">
|
||||
<td>
|
||||
${repository.name}
|
||||
</td>
|
||||
|
||||
@ -10,7 +10,7 @@
|
||||
<ul class="nav nav--repositories" id="all-repositories-tablist" role="tablist">
|
||||
<#list populatedRepositories as populatedRepository>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link <#if populatedRepository?index == 0>active</#if>" data-toggle="tab" role="tab" aria-controls="repository_#{populatedRepository.repository.id}" id="repository-tab_#{populatedRepository.repository.id}" href="#repository_#{populatedRepository.repository.id}">${populatedRepository.repository.name}</a>
|
||||
<a class="nav-link <#if populatedRepository?index == 0>active</#if>" data-toggle="tab" role="tab" aria-controls="repository_#{populatedRepository.repository.key.id}" id="repository-tab_#{populatedRepository.repository.key.id}" href="#repository_#{populatedRepository.repository.key.id}">${populatedRepository.repository.name}</a>
|
||||
</li>
|
||||
</#list>
|
||||
</ul>
|
||||
@ -21,7 +21,7 @@
|
||||
<div class="tab-content" id="repository-tab-content">
|
||||
<#list populatedRepositories as populatedRepository>
|
||||
|
||||
<div class="tab-pane<#if populatedRepository?index == 0> show active</#if>" id="repository_#{populatedRepository.repository.id}" role="tabpanel" aria-labelledby="repository-tab_#{populatedRepository.repository.id}">
|
||||
<div class="tab-pane<#if populatedRepository?index == 0> show active</#if>" id="repository_#{populatedRepository.repository.key.id}" role="tabpanel" aria-labelledby="repository-tab_#{populatedRepository.repository.key.id}">
|
||||
<div class="container">
|
||||
|
||||
<#if populatedRepository.everyImageStable>
|
||||
@ -48,15 +48,15 @@
|
||||
<div class="col-md-8">
|
||||
<div class="input-group input-group-sm mb-3 mt-3">
|
||||
<div class="input-group-prepend">
|
||||
<span class="input-group-text" id="searchLabel_#{populatedRepository.repository.id}"><i class="fas fa-search"></i> Search ${populatedRepository.repository.name}</span>
|
||||
<span class="input-group-text" id="searchLabel_#{populatedRepository.repository.key.id}"><i class="fas fa-search"></i> Search ${populatedRepository.repository.name}</span>
|
||||
</div>
|
||||
<input type="text" class="form-control image-search" id="search_#{populatedRepository.repository.id}" data-repository-id="#{populatedRepository.repository.id}" aria-describedby="searchLabel_#{populatedRepository.repository.id}">
|
||||
<input type="text" class="form-control image-search" id="search_#{populatedRepository.repository.key.id}" data-repository-id="#{populatedRepository.repository.key.id}" aria-describedby="searchLabel_#{populatedRepository.repository.key.id}">
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-2"></div>
|
||||
<div class="col-12">
|
||||
|
||||
<div class="table-responsive" id="#{populatedRepository.repository.id}_images">
|
||||
<div class="table-responsive" id="#{populatedRepository.repository.key.id}_images">
|
||||
<table class="table table--sortable">
|
||||
<thead>
|
||||
<tr>
|
||||
@ -73,7 +73,7 @@
|
||||
<tbody>
|
||||
<#list populatedRepository.images as image>
|
||||
<#if !image.hidden || __AUTHENTICATED_USER?has_content>
|
||||
<tr class="<#if image.hidden>hidden-image</#if><#if image.deprecated>deprecated-image</#if>" data-image-id="#{image.id}" data-image-name="${image.name}">
|
||||
<tr class="<#if image.hidden>hidden-image</#if><#if image.deprecated>deprecated-image</#if>" data-image-id="#{image.key.id}" data-image-name="${image.name}">
|
||||
<td class="image-name">
|
||||
<span class="image-name--repository">${populatedRepository.repository.name} /</span> <a target="_blank" href="https://hub.docker.com/r/${populatedRepository.repository.name}/${image.name}"><span class="image-name__image">${image.name}</span></a>
|
||||
<#if image.deprecated>
|
||||
@ -105,10 +105,10 @@
|
||||
<#if __AUTHENTICATED_USER?has_content>
|
||||
<td class="admin-actions">
|
||||
<div class="dropdown">
|
||||
<button class="btn btn-info btn-xsm dropdown-toggle" type="button" id="admin-actions_#{populatedRepository.repository.id}" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
|
||||
<button class="btn btn-info btn-xsm dropdown-toggle" type="button" id="admin-actions_#{populatedRepository.repository.key.id}" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
|
||||
Actions
|
||||
</button>
|
||||
<div class="dropdown-menu" aria-labelledby="admin-actions_#{populatedRepository.repository.id}">
|
||||
<div class="dropdown-menu" aria-labelledby="admin-actions_#{populatedRepository.repository.key.id}">
|
||||
|
||||
<#if image.hidden>
|
||||
<button type="button" class="image--show dropdown-item btn-clickable"><i class="fas fa-eye"></i> Show in list</button>
|
||||
@ -124,7 +124,7 @@
|
||||
<#if image.deprecated>
|
||||
<button type="button" class="image--remove-deprecation-notice dropdown-item btn-clickable"><i class="fas fa-thumbs-up"></i> Remove deprecation notice</button>
|
||||
<#else>
|
||||
<button id="deprecate-image_#{image.id}" type="button" class="dropdown-item btn-clickable" data-toggle="modal" data-target="#update-image-deprecation"><i class="fas fa-exclamation-circle"></i> Mark as deprecated</button>
|
||||
<button id="deprecate-image_#{image.key.id}" type="button" class="dropdown-item btn-clickable" data-toggle="modal" data-target="#update-image-deprecation"><i class="fas fa-exclamation-circle"></i> Mark as deprecated</button>
|
||||
</#if>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user