Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
A
athena
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Wiki
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Snippets
Build
Pipelines
Jobs
Pipeline schedules
Artifacts
Deploy
Releases
Package Registry
Container Registry
Model registry
Operate
Environments
Terraform modules
Monitor
Incidents
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
EIC
detectors
athena
Commits
01e51f9f
Commit
01e51f9f
authored
3 years ago
by
Wouter Deconinck
Browse files
Options
Downloads
Patches
Plain Diff
FileLoader.cpp: create hash and link
parent
a43183ed
No related branches found
No related tags found
2 merge requests
!329
Master into deathvalley
,
!317
FileLoader.cpp: create hash and link
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
src/FileLoader.cpp
+112
-11
112 additions, 11 deletions
src/FileLoader.cpp
with
112 additions
and
11 deletions
src/FileLoader.cpp
+
112
−
11
View file @
01e51f9f
#include
<DD4hep/DetFactoryHelper.h>
#include
<DD4hep/DetFactoryHelper.h>
#include
<DD4hep/Primitives.h>
#include
<DD4hep/Factories.h>
#include
<DD4hep/Factories.h>
#include
<DD4hep/Printout.h>
#include
<DD4hep/Printout.h>
#include
<XML/Utilities.h>
#include
<XML/Utilities.h>
#include
<fmt/core.h>
#include
<filesystem>
#include
<filesystem>
#include
<iostream>
#include
<iostream>
#include
<string>
#include
<string>
...
@@ -11,12 +14,14 @@ namespace fs = std::filesystem;
...
@@ -11,12 +14,14 @@ namespace fs = std::filesystem;
using
namespace
dd4hep
;
using
namespace
dd4hep
;
void
usage
(
int
argc
,
char
**
argv
)
{
void
usage
(
int
argc
,
char
**
argv
)
{
std
::
cout
<<
std
::
cout
<<
"Usage: -plugin <name> -arg [-arg]
\n
"
"Usage: -plugin <name> -arg [-arg]
\n
"
" name: factory name FileLoader
\n
"
" name: factory name FileLoader
\n
"
" cache:<string> cache location (may be read-only)
\n
"
" file:<string> file location
\n
"
" file:<string> file location
\n
"
" url:<string> url location
\n
"
" url:<string> url location
\n
"
" cmd:<string> download command with {0} for url, {1} for output
\n
"
"
\t
Arguments given: "
<<
arguments
(
argc
,
argv
)
<<
std
::
endl
;
"
\t
Arguments given: "
<<
arguments
(
argc
,
argv
)
<<
std
::
endl
;
std
::
exit
(
EINVAL
);
std
::
exit
(
EINVAL
);
}
}
...
@@ -27,24 +32,120 @@ long load_file(
...
@@ -27,24 +32,120 @@ long load_file(
int
argc
,
int
argc
,
char
**
argv
char
**
argv
)
{
)
{
std
::
string
file
,
url
;
// argument parsing
std
::
string
cache
,
file
,
url
;
std
::
string
cmd
(
"curl --retry 5 -f {0} -o {1}"
);
for
(
int
i
=
0
;
i
<
argc
&&
argv
[
i
];
++
i
)
{
for
(
int
i
=
0
;
i
<
argc
&&
argv
[
i
];
++
i
)
{
if
(
0
==
std
::
strncmp
(
"file:"
,
argv
[
i
],
5
))
file
=
(
argv
[
i
]
+
5
);
if
(
0
==
std
::
strncmp
(
"cache:"
,
argv
[
i
],
6
))
cache
=
(
argv
[
i
]
+
6
);
else
if
(
0
==
std
::
strncmp
(
"url:"
,
argv
[
i
],
4
))
url
=
(
argv
[
i
]
+
4
);
else
if
(
0
==
std
::
strncmp
(
"file:"
,
argv
[
i
],
5
))
file
=
(
argv
[
i
]
+
5
);
else
if
(
0
==
std
::
strncmp
(
"url:"
,
argv
[
i
],
4
))
url
=
(
argv
[
i
]
+
4
);
else
if
(
0
==
std
::
strncmp
(
"cmd:"
,
argv
[
i
],
4
))
cmd
=
(
argv
[
i
]
+
4
);
else
usage
(
argc
,
argv
);
else
usage
(
argc
,
argv
);
}
}
std
::
cout
<<
"Loading "
<<
file
<<
" from "
<<
url
<<
std
::
endl
;
printout
(
DEBUG
,
"FileLoader"
,
"arg cache: "
+
cache
);
printout
(
DEBUG
,
"FileLoader"
,
"arg file: "
+
file
);
printout
(
DEBUG
,
"FileLoader"
,
"arg url: "
+
url
);
printout
(
DEBUG
,
"FileLoader"
,
"arg cmd: "
+
cmd
);
// if file or url is empty, do nothing
if
(
file
.
empty
())
{
printout
(
WARNING
,
"FileLoader"
,
"no file specified"
);
return
0
;
}
if
(
url
.
empty
())
{
printout
(
WARNING
,
"FileLoader"
,
"no url specified"
);
return
0
;
}
// create file path
fs
::
path
file_path
(
file
);
if
(
!
fs
::
exists
(
fs
::
path
(
file
)))
{
// create hash from url, hex of unsigned long long
std
::
string
parent_path
=
fs
::
path
(
file
).
parent_path
();
std
::
string
hash
=
fmt
::
format
(
"{:016x}"
,
dd4hep
::
detail
::
hash64
(
url
));
// TODO: Use c++20 std::fmt
auto
ret
=
std
::
system
((
"mkdir -p "
+
parent_path
+
" && "
"curl --retry 5 -f "
+
url
+
" -o "
+
file
).
c_str
());
// create file parent path, if not exists
if
(
!
fs
::
exists
(
fs
::
path
(
file
)))
{
fs
::
path
parent_path
=
file_path
.
parent_path
();
std
::
cerr
<<
"ERROR: file, "
<<
file
<<
", does not exist
\n
"
;
if
(
!
fs
::
exists
(
parent_path
))
{
if
(
fs
::
create_directories
(
parent_path
)
==
false
)
{
printout
(
ERROR
,
"FileLoader"
,
"parent path "
+
parent_path
.
string
()
+
" cannot be created"
);
printout
(
ERROR
,
"FileLoader"
,
"check permissions and retry"
);
std
::
quick_exit
(
1
);
std
::
quick_exit
(
1
);
}
}
}
}
// if file exists and is symlink to correct hash
fs
::
path
hash_path
(
parent_path
/
hash
);
if
(
fs
::
exists
(
file_path
)
&&
fs
::
equivalent
(
file_path
,
hash_path
))
{
printout
(
INFO
,
"FileLoader"
,
"Link "
+
file
+
" -> hash "
+
hash
+
" already exists"
);
return
0
;
}
// if hash does not exist, we must retrieve file from cache or url
if
(
!
fs
::
exists
(
hash_path
))
{
fs
::
path
cache_path
(
cache
);
fs
::
path
cache_hash_path
(
cache_path
/
hash
);
if
(
fs
::
exists
(
cache_hash_path
))
{
// if cache/hash exists
// symlink hash to cache/hash
printout
(
INFO
,
"FileLoader"
,
"File "
+
file
+
" with hash "
+
hash
+
" found in "
+
cache
);
try
{
fs
::
create_symlink
(
cache_hash_path
,
hash_path
);
}
catch
(
const
fs
::
filesystem_error
&
)
{
printout
(
ERROR
,
"FileLoader"
,
"unable to link from "
+
hash_path
.
string
()
+
" to "
+
cache_hash_path
.
string
());
printout
(
ERROR
,
"FileLoader"
,
"check permissions and retry"
);
std
::
quick_exit
(
1
);
}
}
else
{
// if cache/hash doesn't exists
cmd
=
fmt
::
format
(
cmd
,
url
,
hash_path
.
c_str
());
// TODO: Use c++20 std::fmt
printout
(
INFO
,
"FileLoader"
,
"Downloading "
+
file
+
" as hash "
+
hash
+
" with "
+
cmd
);
// run cmd
auto
ret
=
std
::
system
(
cmd
.
c_str
());
if
(
!
fs
::
exists
(
hash_path
))
{
printout
(
ERROR
,
"FileLoader"
,
"unable to run cmd "
+
cmd
);
printout
(
ERROR
,
"FileLoader"
,
"check command and retry"
);
std
::
quick_exit
(
1
);
}
}
}
// hash_path now exists
// check if file already exists
if
(
fs
::
exists
(
file_path
))
{
// file already exists
if
(
fs
::
is_symlink
(
file_path
))
{
// file is symlink
if
(
fs
::
equivalent
(
hash_path
,
fs
::
read_symlink
(
file_path
)))
{
// link points to correct path
return
0
;
}
else
{
// link points to incorrect path
if
(
fs
::
remove
(
file_path
)
==
false
)
{
printout
(
ERROR
,
"FileLoader"
,
"unable to remove symlink "
+
file_path
.
string
());
printout
(
ERROR
,
"FileLoader"
,
"check permissions or remove manually"
);
std
::
quick_exit
(
1
);
}
}
}
else
{
// file exists but not symlink
printout
(
ERROR
,
"FileLoader"
,
"will not remove actual file "
+
file_path
.
string
());
printout
(
ERROR
,
"FileLoader"
,
"check content, remove manually, and retry"
);
std
::
quick_exit
(
1
);
}
}
// file_path now does not exist
// symlink file_path to hash_path
try
{
// use new path from hash so file link is local
fs
::
create_symlink
(
fs
::
path
(
hash
),
file_path
);
}
catch
(
const
fs
::
filesystem_error
&
)
{
printout
(
ERROR
,
"FileLoader"
,
"unable to link from "
+
file_path
.
string
()
+
" to "
+
hash_path
.
string
());
printout
(
ERROR
,
"FileLoader"
,
"check permissions and retry"
);
std
::
quick_exit
(
1
);
}
return
0
;
return
0
;
}
}
...
...
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment