Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: support geesefs by allowing to skip utimes #14103

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions docs/docs/install/environment-variables.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ These environment variables are used by the `docker-compose.yml` file and do **N
| `IMMICH_PROCESS_INVALID_IMAGES` | When `true`, generate thumbnails for invalid images | | server | microservices |
| `IMMICH_TRUSTED_PROXIES` | List of comma separated IPs set as trusted proxies | | server | api |
| `IMMICH_IGNORE_MOUNT_CHECK_ERRORS` | See [System Integrity](/docs/administration/system-integrity) | | server | api, microservices |
| `IMMICH_SKIP_UTIMES` | Does not call [`utimes`](https://linux.die.net/man/2/utimes) on files after processing. This can be useful for certain filesystems such as [geesefs](https://github.com/yandex-cloud/geesefs) that do not support it | `false` | server | |

\*1: `TZ` should be set to a `TZ identifier` from [this list][tz-list]. For example, `TZ="Etc/UTC"`.
`TZ` is used by `exiftool` as a fallback in case the timezone cannot be determined from the image metadata. It is also used for logfile timestamps and cron job execution.
Expand Down
3 changes: 3 additions & 0 deletions server/src/dtos/env.dto.ts
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,9 @@ export class EnvDto {
@Optional()
IMMICH_REPOSITORY_URL?: string;

@ValidateBoolean({ optional: true })
IMMICH_SKIP_UTIMES?: boolean;

@IsString()
@Optional()
IMMICH_SOURCE_REF?: string;
Expand Down
1 change: 1 addition & 0 deletions server/src/interfaces/config.interface.ts
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@ export interface EnvData {

storage: {
ignoreMountCheckErrors: boolean;
skipUtimes: boolean;
};

workers: ImmichWorker[];
Expand Down
1 change: 1 addition & 0 deletions server/src/repositories/config.repository.ts
Original file line number Diff line number Diff line change
Expand Up @@ -209,6 +209,7 @@ const getEnv = (): EnvData => {

storage: {
ignoreMountCheckErrors: !!dto.IMMICH_IGNORE_MOUNT_CHECK_ERRORS,
skipUtimes: !!dto.IMMICH_SKIP_UTIMES,
},

telemetry: {
Expand Down
9 changes: 8 additions & 1 deletion server/src/repositories/storage.repository.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import path from 'node:path';
import { Writable } from 'node:stream';
import { CrawlOptionsDto, WalkOptionsDto } from 'src/dtos/library.dto';
import { ILoggerRepository } from 'src/interfaces/logger.interface';
import { IConfigRepository } from "src/interfaces/config.interface";
import {
DiskUsage,
IStorageRepository,
Expand All @@ -19,7 +20,10 @@ import { mimeTypes } from 'src/utils/mime-types';

@Injectable()
export class StorageRepository implements IStorageRepository {
constructor(@Inject(ILoggerRepository) private logger: ILoggerRepository) {
constructor(
@Inject(ILoggerRepository) private logger: ILoggerRepository,
@Inject(IConfigRepository) private configRepository: IConfigRepository,
) {
this.logger.setContext(StorageRepository.name);
}

Expand Down Expand Up @@ -60,6 +64,9 @@ export class StorageRepository implements IStorageRepository {
}

utimes(filepath: string, atime: Date, mtime: Date) {
if (this.configRepository.getEnv().storage.skipUtimes){
return Promise.resolve();
}
return fs.utimes(filepath, atime, mtime);
}

Expand Down
Loading