Skip to content

feature : register external packages in the DB#1167

Merged
tgamblin merged 9 commits intospack:developfrom
epfl-scitas:features/external_packages_are_first_class_citizens
Apr 23, 2017
Merged

feature : register external packages in the DB#1167
tgamblin merged 9 commits intospack:developfrom
epfl-scitas:features/external_packages_are_first_class_citizens

Conversation

@alalazo
Copy link
Copy Markdown
Member

@alalazo alalazo commented Jul 5, 2016

Modifications
  • external packages are registered in the db and generate module files
  • added an attribute external to each spec in the DB entry
  • added unit tests to stress the new feature

fixes #1066

@alalazo alalazo changed the title feature : register external packages in the DB [WIP] feature : register external packages in the DB Jul 5, 2016
@alalazo alalazo changed the title [WIP] feature : register external packages in the DB feature : register external packages in the DB Jul 5, 2016
@alalazo
Copy link
Copy Markdown
Member Author

alalazo commented Jul 5, 2016

@tgamblin @becker33 @mathstuf @mplegendre I think this is ready to be reviewed

d = dictionary
return InstallRecord(spec, d['path'], d['installed'], d['ref_count'],
d.get('explicit', False))
d['explicit'], d['external'])
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm. Seems this would be best as **dictionary. Does that work?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@mathstuf Apparently not... spec may be in dictionary, so I had to resort to popping it out before doing a **d. Would this be good enough ?

@davydden davydden added feature A feature is missing in Spack ready labels Sep 21, 2016
@tgamblin
Copy link
Copy Markdown
Member

@alalazo: this looks good to me except for one thing. I think the spec should be where things are stored as external or not. If I build a package with one version of an external package, and then I change the external location, that should be considered a different build and a different package, and it should change the hash. Would you agree with that?

Places where this would help:

  1. This would let you regenerate almost the complete state of the DB. In the current implementation, reindex would not do this b/c the external info is not stored in spec.yaml.
  2. We would need this information if we're going to use spec.yaml descriptors to identify binary packages. There should be a difference between a package installed with a spack-built version of a spec and one installed with a non-spack-built version.
  3. If we don't do this, you could get a hash conflict in the DB if you first build a package with a Spack MPI, then build it with an external MPI.

Right now the Spec has an external field, but it is only maintained from concretization time to install time. It's not actually read in from the DB. I was thinking it would be worth adding, to external specs, a field like this:

external:
    path: /path/to/package
    module: name-of-module

Either path or module could be specified in the spec.

What do you think?

def installed(self):
return os.path.isdir(self.prefix)
try:
rec = spack.installed_db.get_record(self.spec)
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@tgamblin If I remember well this line was slowing things down. Maybe the situation won't be that bad after JSON indexing though...

@alalazo
Copy link
Copy Markdown
Member Author

alalazo commented Nov 1, 2016

@tgamblin Do you want this for v0.10 ?

@alalazo
Copy link
Copy Markdown
Member Author

alalazo commented Nov 1, 2016

What do you think?

It seems a good plan to me

@tgamblin
Copy link
Copy Markdown
Member

tgamblin commented Nov 1, 2016

Depends on how long it would take. If you can do it this week I think it is reasonable to put in. Imho it's how this should work... what do you think?

@alalazo
Copy link
Copy Markdown
Member Author

alalazo commented Nov 1, 2016

Depends on how long it would take. If you can do it this week I think it is reasonable to put in. Imho it's how this should work... what do you think?

Fine with me. I'll try to do this asap.

@alalazo alalazo added WIP and removed ready labels Nov 30, 2016
@alalazo alalazo force-pushed the features/external_packages_are_first_class_citizens branch from b272410 to fddb921 Compare January 13, 2017 17:54
@alalazo alalazo self-assigned this Jan 13, 2017
@alalazo
Copy link
Copy Markdown
Member Author

alalazo commented Jan 13, 2017

@tgamblin Just to let you know: I restarted working on this. The current version should work as you asked, but I didn't have the possibility to check it on Cray (for the external_module part). I still need to do polish a bit the code and add tests. Will ping you when done.

@alalazo alalazo force-pushed the features/external_packages_are_first_class_citizens branch from 8dcc62c to 15c6ecd Compare January 14, 2017 11:10
@alalazo alalazo added ready and removed WIP labels Jan 15, 2017
@alalazo
Copy link
Copy Markdown
Member Author

alalazo commented Jan 15, 2017

@mplegendre @tgamblin PR ready for review, unit tests have been added.

@adamjstewart
Copy link
Copy Markdown
Member

@tgamblin A thought I had on changing hashes. Since Spack is no longer compatible with installations done under a previous hashing mechanism, users are forced to either uninstall everything or create a new Spack installation. Could we increment the version number of Spack every time this happens? Instead of incrementing the version during each release, the version of develop should be incremented to reflect changes in the hashing mechanism.

@alalazo
Copy link
Copy Markdown
Member Author

alalazo commented Jan 15, 2017

@adamjstewart Just my 2 cents: I don't like very much this idea. I think that as the core of Spack becomes more stable we should try to go for time-based releases (e.g. every n months), increment the version number on releases and feature-freeze some time before a new release to focus only on bug-fixes and documentation.

develop shouldn't be treated as a moving stable release because doing so will either prevent experimenting with new design (as we need to be conservative to maintain stability) or it will compromise stability (giving users the impression that the tool is not ready for production). Besides we will be already at Spack 5.0 which would be weird 😄

@adamjstewart
Copy link
Copy Markdown
Member

I agree, and this makes perfect sense for a regular project. But I currently have a spack-0.9.1 installation, and a spack-0.10 installation from the last time the hash changed. Once this is merged, I'll have a spack-0.10.1 installation, but the real core Spack will still be on 0.9.1. We either need to fix Spack so that a change in the hashing algorithm doesn't require you to reinstall it, or we need some way to make it clear that "Spack after this PR is merged" is incompatible with "Spack before this PR is merged". Incrementing the version number is at least one way of indicating this.

alalazo and others added 5 commits April 22, 2017 09:52
…f a spec/yaml round-trip for things that involve an external
* Improve implementation of external packages

* Don't find external module path at each step of concretization

it's not necessary.. The paths are retrieved at the end of concretizaion

* Don't find replacements for external packages.

* Test root of the DAG if external

No reason not to test if the root of the DAG is external when external
packages are now first class citizens!

* Clean up statements in package for external modules

* Correct serious flaw with external package code I made earlier

* Create external property for Spec.

* Remove some stray externals

* Allow users to specify external package paths relative to spack

Canonicalize external package paths so that users may specify their
locations relative to spack's directory.

* Remove leftover external= statement

* Update tests to use new external_path and external properly.
@alalazo alalazo force-pushed the features/external_packages_are_first_class_citizens branch from 3f0760e to 5af97a7 Compare April 22, 2017 09:18
@alalazo
Copy link
Copy Markdown
Member Author

alalazo commented Apr 22, 2017

Tested manually with this packages.yaml:

packages:
  zlib:
    buildable:	False
    paths:
      [email protected]%[email protected]: /usr/lib/x86_64-linux-gnu
  openssl:
    buildable:	False
    paths:
      openssl@system%[email protected]: /usr/lib/x86_64-linux-gnu

The result is the following:

$ spack install openssl
==> openssl@system : externally installed in /usr/lib/x86_64-linux-gnu
==> openssl@system : generating module file
==> openssl@system : registering into DB

$ spack install hdf5~mpi+szip
==> [email protected] : externally installed in /usr/lib/x86_64-linux-gnu
==> [email protected] : generating module file
==> [email protected] : registering into DB
==> Installing szip
==> Using cached archive: /home/mculpo/PycharmProjects/spack/var/spack/cache/szip/szip-2.1.tar.gz
==> Staging archive: /home/mculpo/PycharmProjects/spack/var/spack/stage/szip-2.1-uxcvrxb4jpm3rkqjwmburqcaobtac6mw/szip-2.1.tar.gz
==> Created stage in /home/mculpo/PycharmProjects/spack/var/spack/stage/szip-2.1-uxcvrxb4jpm3rkqjwmburqcaobtac6mw
==> Ran patch() for szip
==> Building szip [AutotoolsPackage]
==> Executing phase : 'autoreconf'
==> Executing phase : 'configure'
==> Executing phase : 'build'
==> Executing phase : 'install'
==> Successfully installed szip
  Fetch: 0.00s.  Build: 8.60s.  Total: 8.60s.
[+] /home/mculpo/PycharmProjects/spack/opt/spack/linux-ubuntu14-x86_64/gcc-4.8/szip-2.1-uxcvrxb4jpm3rkqjwmburqcaobtac6mw
==> Installing hdf5
==> Using cached archive: /home/mculpo/PycharmProjects/spack/var/spack/cache/hdf5/hdf5-1.10.0-patch1.tar.gz
==> Staging archive: /home/mculpo/PycharmProjects/spack/var/spack/stage/hdf5-1.10.0-patch1-slyc4764jhitnou4jpaf4lo5l3qvovdp/hdf5-1.10.0-patch1.tar.gz
==> Created stage in /home/mculpo/PycharmProjects/spack/var/spack/stage/hdf5-1.10.0-patch1-slyc4764jhitnou4jpaf4lo5l3qvovdp
==> Ran patch() for hdf5
==> Building hdf5 [AutotoolsPackage]
==> Executing phase : 'autoreconf'
==> Executing phase : 'configure'
==> Executing phase : 'build'
==> Executing phase : 'install'
==> Successfully installed hdf5
  Fetch: 0.04s.  Build: 6m 24.44s.  Total: 6m 24.48s.
[+] /home/mculpo/PycharmProjects/spack/opt/spack/linux-ubuntu14-x86_64/gcc-4.8/hdf5-1.10.0-patch1-slyc4764jhitnou4jpaf4lo5l3qvovdp

$ cp -r opt/spack/.spack-db/ ~/tmp/

$ spack -d reindex
==> WRITE LOCK: /home/mculpo/PycharmProjects/spack/opt/spack/.spack-db/lock[0:0] [Acquiring]
==> RECONSTRUCTING FROM SPEC.YAML: [email protected]%[email protected] arch=linux-ubuntu14-x86_64
==> RECONSTRUCTING FROM SPEC.YAML: [email protected]%[email protected]+cxx~debug+fortran~mpi+pic+shared+szip~threadsafe arch=linux-ubuntu14-x86_64 ^[email protected]%[email protected] arch=linux-ubuntu14-x86_64 ^[email protected]%[email protected]+pic+shared arch=linux-ubuntu14-x86_64
==> RECONSTRUCTING FROM OLD DB: [email protected]%[email protected]+pic+shared arch=linux-ubuntu14-x86_64
==> SKIPPING RECONSTRUCTION FROM OLD DB: [email protected]%[email protected] arch=linux-ubuntu14-x86_64 [already reconstructed from spec.yaml]
==> RECONSTRUCTING FROM OLD DB: openssl@system%[email protected] arch=linux-ubuntu14-x86_64
==> SKIPPING RECONSTRUCTION FROM OLD DB: [email protected]%[email protected]+cxx~debug+fortran~mpi+pic+shared+szip~threadsafe arch=linux-ubuntu14-x86_64 ^[email protected]%[email protected] arch=linux-ubuntu14-x86_64 ^[email protected]%[email protected]+pic+shared arch=linux-ubuntu14-x86_64 [already reconstructed from spec.yaml]
==> WRITE LOCK: /home/mculpo/PycharmProjects/spack/opt/spack/.spack-db/lock[0:0] [Released]

$ diff opt/spack/.spack-db/index.json ~/tmp/.spack-db/index.json

@alalazo
Copy link
Copy Markdown
Member Author

alalazo commented Apr 22, 2017

Is this an artifact of the way this PR started -- with external stored only in the DB and not in the spec? Could we just keep the old logic?

I added the logic to take care of the fact that you may have registered external packages that are not dependencies of anything else (think of an externally installed Intel compiler, or an external licensed application), so that they could be reconstructed as well. I agree that the logic should be reversed, and this is fixed now.

I also added comments in the code to not lose memory of what we said here. Let me kow if I need to rephrase anything to make it clearer.

@alalazo
Copy link
Copy Markdown
Member Author

alalazo commented Apr 22, 2017

Ok, this should be ready for another review round.

Copy link
Copy Markdown
Member

@tgamblin tgamblin left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM! Minor comments but finally done. Thanks for all the updates!

# considered authoritative with respect to DB reindexing, as
# entries in the DB may be corrupted in a way that still makes
# them readable. If we considered DB entries authoritative
# instead, we would perpetuate errors over a reindex.
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎉

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We probably should add an option to propagate only specs from spec.yaml files, but that can wait for a separate PR. I don't think there is an immediate need for it.

except Exception as e:
# Something went wrong, so the spec was not restored
# from old data
tty.debug(e.message)
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also for separate PR: it would be good to add something like:

if spack.debug:
    print(traceback.format_exc())

So we don't lose the trace.

tty.msg(message.format(s=self, module=self.spec.external_module))
message = '{s.name}@{s.version} : is actually installed in {path}'
tty.msg(message.format(s=self, path=self.spec.external_path))
else:
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

generally good style to either assert self.spec.external or to say eilf self.spec.external_path: ... else: raise ValueError("spec was not external")

@tgamblin tgamblin merged commit 3b52d0a into spack:develop Apr 23, 2017
@alalazo alalazo deleted the features/external_packages_are_first_class_citizens branch April 23, 2017 07:40
scheibelp added a commit to scheibelp/spack that referenced this pull request Apr 27, 2017
Fixes spack#4026

spack#1167 updated Database.reindex to keep old installation records to
support external packages. However, when a user manually removes a
prefix and reindexes this kept the records so the packages were
still installed according to "spack find" etc. This adds a check
for non-external packages to ensure they are properly installed
according to the directory layout.
tgamblin pushed a commit that referenced this pull request Apr 27, 2017
Fixes #4026

#1167 updated Database.reindex to keep old installation records to
support external packages. However, when a user manually removes a
prefix and reindexes this kept the records so the packages were
still installed according to "spack find" etc. This adds a check
for non-external packages to ensure they are properly installed
according to the directory layout.
diaena pushed a commit to diaena/spack that referenced this pull request May 26, 2017
* treats correctly a change from `explicit=False` to `explicit=True` in an external package DB entry.
* added unit tests
* fixed issues raised by @tgamblin . In particular the PR is no more hash-changing for packages that are not external.
* added a test to check correctness of a spec/yaml round-trip for things that involve an external
* Don't find external module path at each step of concretization
    * it's not necessary.. The paths are retrieved at the end of concretizaion
* Don't find replacements for external packages.
* Test root of the DAG if external
    * No reason not to test if the root of the DAG is external when external
packages are now first class citizens!
* Create `external` property for Spec (for external_path and external_module)
* Allow users to specify external package paths relative to spack
    * Canonicalize external package paths so that users may specify their
locations relative to spack's directory.
* Update tests to use new external_path and external properly.
* skip license hooks on external
diaena pushed a commit to diaena/spack that referenced this pull request May 26, 2017
Fixes spack#4026

spack#1167 updated Database.reindex to keep old installation records to
support external packages. However, when a user manually removes a
prefix and reindexes this kept the records so the packages were
still installed according to "spack find" etc. This adds a check
for non-external packages to ensure they are properly installed
according to the directory layout.
xavierandrade pushed a commit to xavierandrade/spack that referenced this pull request Jun 16, 2017
* treats correctly a change from `explicit=False` to `explicit=True` in an external package DB entry.
* added unit tests
* fixed issues raised by @tgamblin . In particular the PR is no more hash-changing for packages that are not external.
* added a test to check correctness of a spec/yaml round-trip for things that involve an external
* Don't find external module path at each step of concretization
    * it's not necessary.. The paths are retrieved at the end of concretizaion
* Don't find replacements for external packages.
* Test root of the DAG if external
    * No reason not to test if the root of the DAG is external when external
packages are now first class citizens!
* Create `external` property for Spec (for external_path and external_module)
* Allow users to specify external package paths relative to spack
    * Canonicalize external package paths so that users may specify their
locations relative to spack's directory.
* Update tests to use new external_path and external properly.
* skip license hooks on external
xavierandrade pushed a commit to xavierandrade/spack that referenced this pull request Jun 16, 2017
Fixes spack#4026

spack#1167 updated Database.reindex to keep old installation records to
support external packages. However, when a user manually removes a
prefix and reindexes this kept the records so the packages were
still installed according to "spack find" etc. This adds a check
for non-external packages to ensure they are properly installed
according to the directory layout.
EmreAtes pushed a commit to EmreAtes/spack that referenced this pull request Jul 10, 2017
* treats correctly a change from `explicit=False` to `explicit=True` in an external package DB entry.
* added unit tests
* fixed issues raised by @tgamblin . In particular the PR is no more hash-changing for packages that are not external.
* added a test to check correctness of a spec/yaml round-trip for things that involve an external
* Don't find external module path at each step of concretization
    * it's not necessary.. The paths are retrieved at the end of concretizaion
* Don't find replacements for external packages.
* Test root of the DAG if external
    * No reason not to test if the root of the DAG is external when external
packages are now first class citizens!
* Create `external` property for Spec (for external_path and external_module)
* Allow users to specify external package paths relative to spack
    * Canonicalize external package paths so that users may specify their
locations relative to spack's directory.
* Update tests to use new external_path and external properly.
* skip license hooks on external
EmreAtes pushed a commit to EmreAtes/spack that referenced this pull request Jul 10, 2017
Fixes spack#4026

spack#1167 updated Database.reindex to keep old installation records to
support external packages. However, when a user manually removes a
prefix and reindexes this kept the records so the packages were
still installed according to "spack find" etc. This adds a check
for non-external packages to ensure they are properly installed
according to the directory layout.
amklinv pushed a commit that referenced this pull request Jul 17, 2017
* treats correctly a change from `explicit=False` to `explicit=True` in an external package DB entry.
* added unit tests
* fixed issues raised by @tgamblin . In particular the PR is no more hash-changing for packages that are not external.
* added a test to check correctness of a spec/yaml round-trip for things that involve an external
* Don't find external module path at each step of concretization
    * it's not necessary.. The paths are retrieved at the end of concretizaion
* Don't find replacements for external packages.
* Test root of the DAG if external
    * No reason not to test if the root of the DAG is external when external
packages are now first class citizens!
* Create `external` property for Spec (for external_path and external_module)
* Allow users to specify external package paths relative to spack
    * Canonicalize external package paths so that users may specify their
locations relative to spack's directory.
* Update tests to use new external_path and external properly.
* skip license hooks on external
@tgamblin tgamblin added this to the v0.11.0 milestone Nov 12, 2017
olupton pushed a commit to olupton/spack that referenced this pull request Feb 7, 2022
* Updates the CoreNEURON package to be consistent with the CI
* Clean references and configurations to old versions
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

feature A feature is missing in Spack

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Question] : external packages and post-install hooks

6 participants