Skip to content

Commit f6e18d0

Browse files
committed
Merge remote-tracking branch 'upstream/master' into release/7.5
2 parents b18e321 + db41565 commit f6e18d0

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

41 files changed

+864
-502
lines changed

.github/workflows/integration.yml

+1-1
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ jobs:
2828
CCTOOLS_DOCKER_GITHUB: ${{ matrix.os-name }}
2929
strategy:
3030
matrix:
31-
os-name: ['centos7', 'centos8', 'ubuntu20.04']
31+
os-name: ['centos7', 'almalinux8', 'ubuntu20.04']
3232
steps:
3333
- name: checkout CCTools from branch head
3434
if: github.event_name != 'workflow_dispatch'

doc/manuals/install/index.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,7 @@ a new `cctools-dev` environment via Conda:
9191

9292
```sh
9393
unset PYTHONPATH
94-
conda create -y -n cctools-dev -c conda-forge --strict-channel-priority python=3 gcc_linux-64 gxx_linux-64 gdb m4 perl swig make zlib libopenssl-static openssl conda-pack
94+
conda create -y -n cctools-dev -c conda-forge --strict-channel-priority python=3 gcc_linux-64 gxx_linux-64 gdb m4 perl swig make zlib libopenssl-static openssl conda-pack packaging cloudpickle
9595
conda activate cctools-dev
9696
```
9797

doc/manuals/taskvine/index.md

+32-2
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,13 @@ the cluster.
2424

2525
<img src=images/architecture.svg>
2626

27+
The TaskVine system is naturally robust. While an application is running,
28+
workers may be added or removed as computing resources become available.
29+
Newly added workers will gradually accumulate data within the cluster.
30+
Removed (or failed) workers are handled gracefully, and tasks will be
31+
retried elsewhere as needed. If a worker failure results in the loss
32+
of files, tasks will be re-executed as necessary to re-create them.
33+
2734
TaskVine manager applications can be written in Python or C
2835
on Linux or OSX platforms. Individual tasks can be simple
2936
Python functions, complex Unix applications, or serverless function
@@ -47,8 +54,7 @@ Tasks share a common set of options. Each task can be labelled with the resourc
4754
(CPU cores, GPU devices, memory, disk space) that it needs to execute. This allows each worker to pack the appropriate
4855
number of tasks. For example, a worker running on a 64-core machine could run 32 dual-core tasks, 16 four-core tasks,
4956
or any other combination that adds up to 64 cores. If you don't know the resources needed, you can enable
50-
Automatic
51-
a resource monitor to track and report what each task uses.
57+
an automatic resource monitor to track and report what each task uses.
5258

5359
TaskVine is easy to deploy on existing HPC and cloud facilities.
5460
The worker processes are self-contained executables, and TaskVine
@@ -219,6 +225,8 @@ visible within the manager application.
219225
used to capture the output of a task, and then serve as the input
220226
of a later task. Temporary files exist only within the cluster
221227
for the duration of a workflow, and are deleted when no longer needed.
228+
If a temporary file is unexpectedly lost due to the crash or failure
229+
of a worker, then the task that created it will be re-executed.
222230

223231
If it is necessary to unpack a file before it is used,
224232
use the `declare_untar` transformation to wrap the file definition.
@@ -724,6 +732,28 @@ that peer transfers are not permitted:
724732
```
725733
vine_declare_file(m,"myfile.txt",VINE_CACHE|VINE_PEER_NOSHARE)
726734
```
735+
Automatic sharing of files between workers, or peer transfers, are enabled by default
736+
in TaskVine. If communication between workers is not possible or not desired, peer transfers
737+
may be globally disabled:
738+
739+
=== "Python"
740+
```python
741+
m.disable_peer_transfers()
742+
```
743+
=== "C"
744+
```
745+
vine_disable_peer_transfers(m);
746+
```
747+
If peer transfers have been disabled, they may be re-enabled accordingly:
748+
749+
=== "Python"
750+
```python
751+
m.enable_peer_transfers()
752+
```
753+
=== "C"
754+
```
755+
vine_enable_peer_transfers(m);
756+
```
727757

728758
### MiniTasks
729759

dttools/src/histogram.c

+3-11
Original file line numberDiff line numberDiff line change
@@ -47,22 +47,14 @@ struct histogram *histogram_create(double bucket_size) {
4747
return h;
4848
}
4949

50-
void histogram_clear(struct histogram *h) {
51-
52-
uint64_t key;
53-
struct box_count *box;
54-
55-
itable_firstkey(h->buckets);
56-
while(itable_nextkey(h->buckets, &key, (void **) &box)) {
57-
free(box);
58-
}
50+
void histogram_clear(struct histogram *h)
51+
{
52+
itable_clear(h->buckets,free);
5953

6054
h->total_count = 0;
6155
h->max_value = 0;
6256
h->min_value = 0;
6357
h->mode = 0;
64-
65-
itable_clear(h->buckets);
6658
}
6759

6860
void histogram_delete(struct histogram *h) {

dttools/src/itable.c

+3-2
Original file line numberDiff line numberDiff line change
@@ -50,14 +50,15 @@ struct itable *itable_create(int bucket_count)
5050
return h;
5151
}
5252

53-
void itable_clear(struct itable *h)
53+
void itable_clear( struct itable *h, void (*delete_func)( void *) )
5454
{
5555
struct entry *e, *f;
5656
int i;
5757

5858
for(i = 0; i < h->bucket_count; i++) {
5959
e = h->buckets[i];
6060
while(e) {
61+
if(delete_func) delete_func(e->value);
6162
f = e->next;
6263
free(e);
6364
e = f;
@@ -71,7 +72,7 @@ void itable_clear(struct itable *h)
7172

7273
void itable_delete(struct itable *h)
7374
{
74-
itable_clear(h);
75+
itable_clear(h,0);
7576
free(h->buckets);
7677
free(h);
7778
}

dttools/src/itable.h

+2-2
Original file line numberDiff line numberDiff line change
@@ -56,11 +56,11 @@ ITABLE_ITERATE(h,key,value) {
5656
struct itable *itable_create(int buckets);
5757

5858
/** Remove all entries from an integer table.
59-
Note that this function will not delete all of the objects contained within the integer table.
6059
@param h The integer table to delete.
60+
@param delete_func If non-null, will be invoked on each object to delete it.
6161
*/
6262

63-
void itable_clear(struct itable *h);
63+
void itable_clear( struct itable *h, void (*delete_func)(void*) );
6464

6565
/** Delete an integer table.
6666
Note that this function will not delete all of the objects contained within the integer table.

dttools/src/sort_dir.c

+3
Original file line numberDiff line numberDiff line change
@@ -29,8 +29,11 @@ int sort_dir(const char *dirname, char ***list, int (*sort) (const char *a, cons
2929
n += 1;
3030
}
3131
closedir(dir);
32+
} else {
33+
return 0;
3234
}
3335

36+
3437
if(sort) {
3538
qsort(*list, n, sizeof(char *), (int (*)(const void *, const void *)) sort);
3639
}

dttools/test/test_runner_common.sh

+1-1
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,7 @@ run_wq_worker()
116116
return 0
117117
}
118118

119-
run_ds_worker()
119+
run_taskvine_worker()
120120
{
121121
local port_file=$1
122122
shift

packaging/scripts/generate-images

+39-21
Original file line numberDiff line numberDiff line change
@@ -136,9 +136,12 @@ my %preinstall_for;
136136
# list of shell commands to execute post installation.
137137
my %postinstall_for;
138138

139-
$versions_of{centos} = [ qw{ 8 7 } ];
139+
$versions_of{centos} = [ qw{ 7 } ];
140140
$command_for{centos} = 'yum install -y';
141141

142+
$versions_of{almalinux} = [ qw{ 8 9 } ];
143+
$command_for{almalinux} = 'dnf install -y';
144+
142145
$versions_of{fedora} = [ qw{ 30 } ];
143146
$command_for{fedora} = 'dnf install -y';
144147

@@ -171,7 +174,7 @@ gtar => 'tar',
171174
image_magick => 'ImageMagick',
172175
libattr => 'libattr-devel',
173176
libffi => 'libffi',
174-
lsb_release => 'redhat-lsb-core',
177+
lsb_release => [],
175178
m4 => 'm4',
176179
musl => [], # from builder
177180
mysql => [], # from builder
@@ -199,9 +202,11 @@ zlib => 'zlib-devel',
199202
#$package_for{centos}{6}{python3} = ['python34-devel', 'python34-setuptools']; centos6 end-of-life
200203
$package_for{centos}{7}{python} = ['python', 'python-devel', 'python-setuptools', 'python-tools'];
201204
$package_for{centos}{7}{python3} = ['python36-devel', 'python36-setuptools', 'python36-pip'];
205+
$package_for{centos}{7}{lsb_release} = ['redhat-lsb-core'];
202206

203207
$package_for{centos}{8}{python3} = ['python39-devel', 'python39-setuptools', 'python39-pip'];
204208
$package_for{centos}{8}{swig} = ['swig'];
209+
$package_for{centos}{8}{lsb_release} = ['redhat-lsb-core'];
205210

206211
$extras_for{centos}{6} = ['libc-devel'];
207212
$extras_for{centos}{7} = ['libc-devel'];
@@ -218,15 +223,6 @@ $preinstall_for{centos}{7} = [
218223
'yum -y install https://ecsft.cern.ch/dist/cvmfs/cvmfs-release/cvmfs-release-latest.noarch.rpm'
219224
];
220225

221-
$preinstall_for{centos}{8} = [
222-
"sed -i 's/mirrorlist/#mirrorlist/g' /etc/yum.repos.d/CentOS-*",
223-
"sed -i 's|#baseurl=http://mirror.centos.org|baseurl=http://vault.centos.org|g' /etc/yum.repos.d/CentOS-*",
224-
'dnf install -y "dnf-command(config-manager)"',
225-
'dnf config-manager -y --set-enabled powertools', # for doxygen, and groff
226-
'dnf install -y epel-release',
227-
'dnf install -y https://ecsft.cern.ch/dist/cvmfs/cvmfs-release/cvmfs-release-latest.noarch.rpm'
228-
];
229-
230226
$postinstall_for{centos}{7} = [
231227
@{$builder},
232228
@{$fuse},
@@ -240,23 +236,45 @@ $postinstall_for{centos}{7} = [
240236
'yum -y clean all',
241237
];
242238

243-
$postinstall_for{centos}{8} = [
239+
# end-of-life
240+
#$postinstall_for{centos}{6} = [
241+
# 'ln -sf /usr/bin/python3.4 /usr/bin/python3',
242+
# 'ln -sf /usr/bin/python3.4-config /usr/bin/python3-config'
243+
#];
244+
245+
########## almalinux ##########
246+
$package_for{almalinux}{default} = { %{$package_for{centos}{default}} };
247+
248+
$preinstall_for{almalinux}{default} = [
249+
'dnf install -y "dnf-command(config-manager)"',
250+
'dnf install -y epel-release',
251+
'dnf install -y https://ecsft.cern.ch/dist/cvmfs/cvmfs-release/cvmfs-release-latest.noarch.rpm'
252+
];
253+
254+
$preinstall_for{almalinux}{8} = [
255+
'dnf config-manager -y --set-enabled powertools', # for doxygen, and groff
256+
];
257+
258+
$preinstall_for{almalinux}{9} = [
259+
'dnf config-manager -y --set-enabled crb', # for doxygen, and groff
260+
];
261+
262+
$postinstall_for{almalinux}{default} = [
244263
'ln -s /usr/bin/python3 /usr/bin/python',
245264
@{$builder},
246265
@{$fuse},
247266
@{$e2fsprogs},
248-
@{$mysql},
249-
@{$uuid},
250-
'yum -y install cvmfs-devel',
251-
'yum -y clean all',
267+
@{$mysql}, # does not compile in alma9
268+
'dnf -y install cvmfs-devel',
269+
'dnf -y clean all',
252270
];
253271

254-
# end-of-life
255-
#$postinstall_for{centos}{6} = [
256-
# 'ln -sf /usr/bin/python3.4 /usr/bin/python3',
257-
# 'ln -sf /usr/bin/python3.4-config /usr/bin/python3-config'
258-
#];
272+
$package_for{almalinux}{default}{python3} = ['python3-devel', 'python3-setuptools', 'python3-pip'];
273+
$package_for{almalinux}{default}{swig} = ['swig'];
274+
$extras_for{almalinux}{default} = ['glibc-devel', 'libuuid-devel', 'diffutils'];
259275

276+
$package_for{almalinux}{9}{lsb_release} = []; # there is no redhat-lsb package for redhat9
277+
$package_for{almalinux}{9}{curl} = []; # curl already in base image and there is a conflict if we try to update it
260278

261279
########## FEDORA ##########
262280
$package_for{fedora}{default} = { %{$package_for{centos}{default}} };

poncho/src/poncho/package_create.py

+27-3
Original file line numberDiff line numberDiff line change
@@ -97,8 +97,24 @@ def _copy_run_in_env(env_dir):
9797
f.write('exec "${env_dir}"/bin/poncho_package_run -e ${env_dir} "$@"\n')
9898
os.chmod(f'{env_dir}/env/bin/run_in_env', 0o755)
9999

100+
def pack_env_with_conda_dir(spec, output, ignore_editable_packages=False):
101+
# remove trailing slash if present
102+
spec = spec[:-1] if spec[-1] == '/' else spec
103+
try:
104+
logger.info('packaging the environment...')
105+
os.makedirs(f'{spec}/bin/', exist_ok=True)
106+
os.makedirs(f'{spec}/env/bin/', exist_ok=True)
107+
_copy_run_in_env(spec)
108+
os.rename(f'{spec}/env/bin/poncho_package_run', f'{spec}/bin/poncho_package_run')
109+
os.rename(f'{spec}/env/bin/run_in_env', f'{spec}/bin/run_in_env')
110+
111+
conda_pack.pack(prefix=f'{spec}', output=str(output), force=True, ignore_missing_files=True, ignore_editable_packages=ignore_editable_packages)
112+
logger.info('to activate environment run poncho_package_run -e {} <command>'.format(output))
113+
return output
114+
except Exception as e:
115+
raise Exception(f"Error when packing a conda directory.\n{e}")
100116

101-
def pack_env(spec, output, conda_executable=None, download_micromamba=None):
117+
def pack_env_with_spec(spec, output, conda_executable=None, download_micromamba=False, ignore_editable_packages=False):
102118
# record packages installed as editable from pip
103119
local_pip_pkgs = _find_local_pip()
104120

@@ -138,13 +154,22 @@ def pack_env(spec, output, conda_executable=None, download_micromamba=None):
138154
# Bug breaks bundling common packages (e.g. python).
139155
# ignore_missing_files may be safe to remove in the future.
140156
# https://github.com/conda/conda-pack/issues/145
141-
conda_pack.pack(prefix=f'{env_dir}/env', output=str(output), force=True, ignore_missing_files=True)
157+
if ignore_editable_packages is not True:
158+
ignore_editable_packages = False
159+
conda_pack.pack(prefix=f'{env_dir}/env', output=str(output), force=True, ignore_missing_files=True, ignore_editable_packages=ignore_editable_packages)
142160

143161
logger.info('to activate environment run poncho_package_run -e {} <command>'.format(output))
144162

145163
return output
146164

165+
def pack_env(spec, output, conda_executable=None, download_micromamba=False, ignore_editable_packages=False):
166+
# pack a conda directory directly
167+
if not os.path.isfile(spec) and spec != "-":
168+
pack_env_with_conda_dir(spec, output, ignore_editable_packages)
147169

170+
# else if spec is a file or from stdin
171+
else:
172+
pack_env_with_spec(spec, output, conda_executable, download_micromamba, ignore_editable_packages)
148173

149174
def _run_conda_command(environment, needs_confirmation, command, *args):
150175
all_args = [conda_exec] + command.split()
@@ -160,7 +185,6 @@ def _run_conda_command(environment, needs_confirmation, command, *args):
160185
print(e.output.decode())
161186
sys.exit(1)
162187

163-
164188
def _find_local_pip():
165189
edit_raw = subprocess.check_output([sys.executable, '-m' 'pip', 'list', '--editable']).decode()
166190

poncho/src/poncho_package_create

+4-3
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,13 @@
22
from poncho import package_create as create
33
import argparse
44
if __name__ == '__main__':
5-
parser = argparse.ArgumentParser(description='Create a packed environment from a spec.')
6-
parser.add_argument('spec', help='Read in a spec file, or - for stdin.')
5+
parser = argparse.ArgumentParser(description='Create a packed environment from a spec or a conda directory.')
6+
parser.add_argument('spec', help='Read in a spec file, a conda directory, or - for stdin.')
77
parser.add_argument('output', help='Write output from conda-pack to the given file.')
88
parser.add_argument('--conda-executable', action='store_true', help='Path to conda executable to use. Default are, in this order: mamba, $CONDA_EXE, conda')
99

1010
parser.add_argument('--no-micromamba', action='store_true', help='Do not try no download micromamba if a conda executable is not found.')
11+
parser.add_argument('--ignore-editable-packages', action='store_true', help='Skip checks for editable packages.')
1112

1213
args = parser.parse_args()
13-
create.pack_env(args.spec, args.output, args.conda_executable, not args.no_micromamba)
14+
create.pack_env(args.spec, args.output, args.conda_executable, not args.no_micromamba, args.ignore_editable_packages)

0 commit comments

Comments
 (0)