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

spack setup: Fix Bugs + Multi-setup #2664

Closed
wants to merge 17 commits into from

Conversation

citibeth
Copy link
Member

This PR addresses a serious case of "bitrot" in spack setup: changes accumulated in cmd/install.py and ended up breaking cmd/setup.py. spack setup was simply unusable. The main thrust of this PR is to make spack setup work again.

Benefits

  1. So far, this PR seems to fix Spack Melts Down into a puddle... #2657 and spack setup is just plain broken #2662, and possibly other related issues of unstable hashes in the past.
  2. More consistent UI
  3. Addresses spack install should print spec! #2661 (duplicate of Copy MacPorts UI: List dependencies to be installed before installing them! #2149).
  4. Should not change behavior outside of spack setup.
  5. Faster: avoid concretizing twice.

Changes

  1. Previously, spack setup called spack install twice, by passing it command line arguments. spack install in turn calls Package.do_install(). Now, spack setup and spack install both call Package.do_install() directly.

  2. Previously, a call to spack setup would concretize three times. By not calling spack install, spack setup now ony concretizes once. This is not just for efficiency, but also correctness. I suspect that concretizing is not idempotent; and that concretizing three times was a root cause of the bugs. This could have something to do with the way concretization results are memoized.

  3. Relevant parts of spack install were factored out into subroutines so that spack setup can make use of them.

  4. spack setup and spack install now take the same command line arguments. All arguments were determined to make sense for spack setup.

  5. A new '-I' option was added that prints out the fully concretized spec before installing. If users want a more customized printout, they should use spack spec.

  6. A context manager is now used to set up / tear down logging. This ensures that the logging tear-down will always be done, even in the face of a sys.exit(1) or tty.die().

To Do

  • Like spack setup, spack diy also derives from spack install. It should also be refactored to match spack setup and spack install.
  • @alalazo You re-did this code most recently; can you please verify that this PR does not change the behavior of spack install?

@citibeth
Copy link
Member Author

I'm looking for review on this PR... before Travis issues have been cleared.

@citibeth citibeth added bug Something isn't working concretization hashes labels Dec 22, 2016
@scheibelp
Copy link
Member

This will also address #2597 (where an error was popping up for some concretization after the first)

Copy link
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.

This PR should add regression tests for Spack setup's behavior.

@citibeth
Copy link
Member Author

citibeth commented Dec 22, 2016 via email

@citibeth
Copy link
Member Author

Does Spack currently have any regression tests that form a pattern I can follow?

@tgamblin
Copy link
Member

The whole lib/spack/spack/test subdirectory has tests. The install test (install.py) and the command tests (under cmd) are probably most appropriate.

Copy link
Member

@alalazo alalazo left a comment

Choose a reason for hiding this comment

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

There are two things I don't get in this PR:

  • why do we want to add a --install-status flag to spack install that competes with spack spec?

  • why do we want to drive externally the order of installation for dependencies in install?

format = '$_' + '$@$%@+$+$=',
hashes = True,
hashlen = 7,
install_status = True)
Copy link
Member

Choose a reason for hiding this comment

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

Why has this been added to install?


if len(specs) != 1:
tty.die('only one spec can be installed at a time.')
spec = specs.pop()
Copy link
Member

Choose a reason for hiding this comment

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

I don't get the change in arguments: why allow-multi? parse specs is supposed to be able to parse multiple specs. The fact that currently it is not is a bug (see #1248 and #1976).

Also, an error message that says that only one item can be installed doesn't seem appropriate in a function that parses.

Copy link
Member Author

Choose a reason for hiding this comment

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

The docstring for parse_specs() indicates that it is a "convenience function." That means (to me) that it's not really necessary, but its entire purpose is to factor stuff out of places that use it, making other code neater and easier to deal with. Adding the allow_multi functionality to parse_specs() does exactly that, allowing the following lines to be factored out of at least 2 places:

    if len(specs) != 1:
        tty.die('only one spec can be installed at a time.')
    spec = specs.pop()
    return spec

Point taken on the error message.

The fact that currently it is not is a bug (see #1248 and #1976).

Bug or no bug, I took existing code and refactored it into a convenience function.

Copy link
Member

Choose a reason for hiding this comment

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

allow_multi should be irrelevant now, the parser accepts multiple specs as of #2769

def setup_parser(subparser):
subparser.add_argument(
'--only',
default='package,dependencies',
dest='things_to_install',
dest='only_str',
Copy link
Member

Choose a reason for hiding this comment

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

It might be me, but I don't get what the name only_str means in this context. Why did you change the name of this variable?

Copy link
Member Author

Choose a reason for hiding this comment

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

only_str is consistent with the argument named only. Maybe this should be called only (except that only is really a set, but it's being encoded as a string)

@@ -73,6 +77,11 @@ def setup_parser(subparser):
'--fake', action='store_true', dest='fake',
help="Fake install. Just remove prefix and create a fake file.")

subparser.add_argument(
'--install-status', '-I', action='store_true', dest='install_status',
help="Show spec before installing.")
Copy link
Member

Choose a reason for hiding this comment

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

Why not:

spack spec -Il <spec>
spack install <spec>

?

Copy link
Member

Choose a reason for hiding this comment

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

I agree, having two command which do the same thing is not good. I understand that spack spec may take some time for big packages, but IMO it's not a good enough reason to add this functionality to spack install.

Copy link
Member Author

Choose a reason for hiding this comment

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

Because it takes 68 seconds instead of 34; and because I really want to use it routinely on every spack install or spack setup command. That way, I can see what Spack is doing while it's doing it, and I don't have to type twice as much and wait twice as long before I can check whether things are going OK. Why all the pushback on this one? It doesn't affect anybody who doesn't want to use it.

package = spack.repo.get(s)
package.do_install(install_dependencies=True, explicit=False, **kwargs)

if install_package:
Copy link
Member

Choose a reason for hiding this comment

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

Not a big deal, but why we changed the semantics here? We are driving dependencies installation explicitly when it shouldn't be necessary: do_install knows how to recurse internally and here we are mixing two competing recursions on dependencies.

Copy link
Member Author

Choose a reason for hiding this comment

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

This will get changed back.

@@ -300,25 +310,25 @@ def install(parser, args, **kwargs):
if args.no_checksum:
spack.do_checksum = False # TODO: remove this global.

only = set([x.strip() for x in args.only_str.split(',')])
Copy link
Member

Choose a reason for hiding this comment

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

Minor thing: there's no need to turn the argument into a list. Invoking __contains__ will succeed also with the plain string.

@citibeth
Copy link
Member Author

citibeth commented Dec 22, 2016

why do we want to add a --install-status flag to spack install that competes with spack spec?

Because for specs that take a long time to concretize, it is a real lifesaver. time spack spec icebin takes 34 seconds for me. The recent switch to JSON has certainly helped, as has avoiding multiple concretizations in spack setup; it used to be worse. But still... 34 seconds is a long time when trying to debug. Printing out the spec before you install makes using Spack less frustrating for large builds.

why do we want to drive externally the order of installation for dependencies in install?

I have no preferences. Sounds like install.py/top_install() should be reverted to do something more like the code it replaced:

    # Do the actual installation
    if args.things_to_install == 'dependencies':
        # Install dependencies as-if they were installed
        # for root (explicit=False in the DB)
        kwargs['explicit'] = False
        for s in spec.dependencies():
            p = spack.repo.get(s)
            p.do_install(**kwargs)
    else:
        package = spack.repo.get(spec)
        kwargs['explicit'] = True
        package.do_install(**kwargs)

(The to_install() method has been factored out from install.py/install() for purposes of kwargs jujitsu. It is really a private method, and maybe should be called _to_install())

@citibeth
Copy link
Member Author

@alalazo I restored the original logic for spack install. How does it look to you?
8d03f1b

@citibeth
Copy link
Member Author

citibeth commented Dec 27, 2016 via email

@tgamblin
Copy link
Member

@citibeth: Sounds good to me.

w.r.t. tests, look at test/install.py, which looks way cleaner in #2502 than it did before. That test uses some fixtures to fetch a fake tarball, install, and uninstall. The fixtures you need for that are in test/conftest.py -- you can probably either use or modify mock_archive.

@citibeth
Copy link
Member Author

citibeth commented Jan 4, 2017

I just pushed some significant changes that improve the spack setup experience when working with more than one package. Suppose you have A->B->...; and you want to work on A and B together. You could do:

cd B
spack setup B
cd ../A
spack setup A

The problem is... there is no guarantee that the version of A obtained with spack setup A will be the same as the version of A used by B when running spack setup B. There are many possible reasons for these "inconsistent hashes"; some of them bugs, and others not. Many bugs have been found and fixed by comparing hashes this way.

BUT... there are also "legitimate" reasons for these hash problems. For example, if B depends_on('A+extravariant'), then A could easily have a different hash when it's being built as a dependency of B than when it's built alone. This problem can be fixed by writing spack setup A+extravariant (or putting the variant in a packages.yaml file before calling spack setup A).

Another similar setup is that (say) A->boost and B->boost+mpi. In this case, you will have to add +mpi to boost in your packages.yaml.

For a complex build with more than two packages you wish to spack setup (say, $n=4$) and a number of dependencies, tracking down reasons for inconsistent hashes quickly becomes unwieldy; and packages.yaml grows with settings that have no purpose other than to trick Spack into yielding stable hashes. These settings are brittle: they are essentially a copy of default variants out of the packages one intends to build.

At the end of the day, it's a way to waste hours digging through a mess. Which is what Spack is supposed to get us out of.

This PR now offers a better way: generate all the spconfig.py files you need during the course of one concretization. The idea is you tell Spack (on the command line) which packages you want to be setup rather than installed; and then Spack will either setup or install every package in your DAG. This is a generalization of spack setup, which can setup only the top package. spack setup has been re-implemented now to call this generalized spack install.

Note that if you setup package A and B->A, then you must also setup package B; doing spack setup "breaks" the automated installation process. However, Spack does not check for that, yielding possibilities to run spack setup B after A has been setup and installed with make install. Remember that spack setup is a developer tool.

The recent commits also make some other changes:

  1. spack setup was crashing before, but nobody cared. That has been fixed up.

  2. spack setup used to run a fake install that produced a file called bin/fake. That was probably not going to cause problems; but it has been cleaned up. Now spack setup just creates an empty directory.

  3. When printing the error message Warning: Module file already exists : skipping creation, Spack now only prints the full spec as part of the message if it's being run in debug mode.

Below is an example of the "new" spack setup on my software configuration. I'm so glad I don't have to manage this configuration by hand.

$ dspack install --setup modele --setup ibmisc --setup pism --setup icebin modele
[+]  haxxwlf  modele@landice%gcc@4.9.3~aux+debug~diags+everytrace~fexception~ic+icebin+model+mods+mpi+pnetcdf~tests arch=linux-centos7-x86_64
[+]  f44ykg7      ^cmake@3.7.1%gcc@4.9.3~doc+ncurses+openssl+ownlibs~qt arch=linux-centos7-x86_64
[+]  h66uwdb          ^ncurses@6.0%gcc@4.9.3 arch=linux-centos7-x86_64
[-]  kuxs2xu          ^openssl@1.0.1e%gcc@4.9.3 arch=linux-centos7-x86_64
[+]  gyeos66      ^everytrace@develop%gcc@4.9.3+fortran+mpi arch=linux-centos7-x86_64
[+]  2ew2gg7          ^openmpi@1.10.1%gcc@4.9.3~java~mxm~pmi~psm~psm2~slurm~sqlite3~thread_multiple~tm~verbs+vt arch=linux-centos7-x86_64
[+]  nygoq6c              ^hwloc@1.11.4%gcc@4.9.3 arch=linux-centos7-x86_64
[+]  a6hzhtg                  ^libpciaccess@0.13.4%gcc@4.9.3 arch=linux-centos7-x86_64
[+]  q5ztpkl                      ^libtool@2.4.6%gcc@4.9.3 arch=linux-centos7-x86_64
[+]  kmufpwm                          ^m4@1.4.17%gcc@4.9.3+sigsegv arch=linux-centos7-x86_64
[+]  ytewamh                              ^libsigsegv@2.10%gcc@4.9.3 arch=linux-centos7-x86_64
[+]  zmirozy                      ^pkg-config@0.29.1%gcc@4.9.3+internal_glib arch=linux-centos7-x86_64
[+]  36ec63z                      ^util-macros@1.19.0%gcc@4.9.3 arch=linux-centos7-x86_64
[+]  5ad3eli      ^icebin@develop%gcc@4.9.3+coupler~doc+everytrace+gridgen+pism+python arch=linux-centos7-x86_64
[+]  f5m2jss          ^blitz@1.0.0%gcc@4.9.3 arch=linux-centos7-x86_64
[+]  y4h7xx3          ^boost@1.62.0%gcc@4.9.3+atomic+chrono+date_time~debug+filesystem~graph~icu+iostreams+locale+log+math+mpi+multithreaded+program_options~python+random+regex+serialization+shared+signals~singlethreaded+system~taggedlayout+test+thread+timer+wave arch=linux-centos7-x86_64
[+]  nawaab2              ^bzip2@1.0.6%gcc@4.9.3 arch=linux-centos7-x86_64
[+]  xsie4hd              ^zlib@1.2.8%gcc@4.9.3+pic arch=linux-centos7-x86_64
[+]  24jxqwo          ^cgal@4.9%gcc@4.9.3~core~debug~demos~imageio+shared arch=linux-centos7-x86_64
[+]  tl5w2mh              ^gmp@6.1.2%gcc@4.9.3 arch=linux-centos7-x86_64
[+]  2igx7t2              ^mpfr@3.1.4%gcc@4.9.3 arch=linux-centos7-x86_64
[+]  2cbaqas          ^eigen@3.2.10%gcc@4.9.3~debug+fftw+metis+mpfr+scotch~suitesparse arch=linux-centos7-x86_64
[+]  ikgs5nv              ^fftw@3.3.5%gcc@4.9.3+float+long_double+mpi~openmp~pfft_patches~quad arch=linux-centos7-x86_64
[+]  3zcn2vz              ^metis@5.1.0%gcc@4.9.3~debug~gdb~idx64~real64+shared arch=linux-centos7-x86_64
[+]  clop2l7              ^scotch@6.0.4%gcc@4.9.3+compression~esmumps+metis+mpi+shared arch=linux-centos7-x86_64
[+]  qkwzrwh                  ^bison@3.0.4%gcc@4.9.3 arch=linux-centos7-x86_64
[+]  ufadjk4                  ^flex@2.6.1%gcc@4.9.3 arch=linux-centos7-x86_64
[+]  hpq5i6r                      ^gettext@0.19.8.1%gcc@4.9.3+bzip2+curses+git~libunistring+libxml2+tar+xz arch=linux-centos7-x86_64
[+]  lhr4cim                          ^libxml2@2.9.4%gcc@4.9.3~python arch=linux-centos7-x86_64
[+]  zooqtth                              ^xz@5.2.2%gcc@4.9.3 arch=linux-centos7-x86_64
[+]  hq2pmmu                          ^tar@1.29%gcc@4.9.3 arch=linux-centos7-x86_64
[+]  xv4z622                      ^help2man@1.47.4%gcc@4.9.3 arch=linux-centos7-x86_64
[+]  eqnywrt          ^ibmisc@develop%gcc@4.9.3+blitz+boost~doc+everytrace+googletest+netcdf+proj+python+udunits2 arch=linux-centos7-x86_64
[+]  mdbsavk              ^googletest@1.7.0%gcc@4.9.3 arch=linux-centos7-x86_64
[+]  zeouisc              ^netcdf-cxx4@4.3.0%gcc@4.9.3 arch=linux-centos7-x86_64
[+]  tbehzc4                  ^autoconf@2.69%gcc@4.9.3 arch=linux-centos7-x86_64
[+]  as7nvfd                  ^netcdf@4.4.1%gcc@4.9.3~cdmremote~dap~hdf4 maxdims=1024 maxvars=8192+mpi~parallel-netcdf+shared arch=linux-centos7-x86_64
[+]  vjo6kk3                      ^hdf5@1.10.0-patch1%gcc@4.9.3+cxx~debug+fortran+mpi+pic+shared~szip~threadsafe arch=linux-centos7-x86_64
[+]  54uiqru              ^proj@4.9.2%gcc@4.9.3 arch=linux-centos7-x86_64
[+]  j6fjvjh              ^py-cython@0.23.5%gcc@4.9.3 arch=linux-centos7-x86_64
[+]  zlh4sb6                  ^binutils@2.27%gcc@4.9.3+gold~krellpatch~libiberty arch=linux-centos7-x86_64
[+]  twdmmvi                  ^python@3.5.2%gcc@4.9.3~tk~ucs4 arch=linux-centos7-x86_64
[+]  bbjtafh                      ^readline@6.3%gcc@4.9.3 arch=linux-centos7-x86_64
[+]  7h5xpac                      ^sqlite@3.8.5%gcc@4.9.3 arch=linux-centos7-x86_64
[+]  ingtf52              ^py-numpy@1.11.2%gcc@4.9.3+blas+lapack arch=linux-centos7-x86_64
[+]  qnfdxmf                  ^openblas@0.2.19%gcc@4.9.3~openmp+pic+shared arch=linux-centos7-x86_64
[+]  cyssdfv                  ^py-nose@1.3.7%gcc@4.9.3 arch=linux-centos7-x86_64
[+]  jqf3eg2                      ^py-setuptools@25.2.0%gcc@4.9.3 arch=linux-centos7-x86_64
[+]  tjpaxgr              ^udunits2@2.2.20%gcc@4.9.3 arch=linux-centos7-x86_64
[+]  gsmcyiz                  ^expat@2.2.0%gcc@4.9.3 arch=linux-centos7-x86_64
[+]  k3syjvi          ^petsc@3.7.4%gcc@4.9.3+boost~complex~debug+double+hdf5+hypre+metis+mpi+mumps+shared+superlu-dist arch=linux-centos7-x86_64
[+]  ehjwhs7              ^hypre@2.11.1%gcc@4.9.3~internal-superlu+shared arch=linux-centos7-x86_64
[+]  nt3b5ju              ^mumps@5.0.2%gcc@4.9.3+complex+double+float~idx64~metis+mpi~parmetis~ptscotch~scotch+shared arch=linux-centos7-x86_64
[+]  55r2m7h                  ^netlib-scalapack@2.0.2%gcc@4.9.3~fpic+shared arch=linux-centos7-x86_64
[+]  t6ftobm              ^parmetis@4.0.3%gcc@4.9.3~debug~gdb+shared arch=linux-centos7-x86_64
[+]  lezx2yp              ^superlu-dist@5.1.1%gcc@4.9.3 arch=linux-centos7-x86_64
[+]  kkl2u4y          ^pism@dev%gcc@4.9.3~doc~extra+icebin~parallel-hdf5~parallel-netcdf3~parallel-netcdf4+proj~python+shared arch=linux-centos7-x86_64
[+]  5qnos74              ^gsl@2.3%gcc@4.9.3 arch=linux-centos7-x86_64
[+]  xhwyxt3      ^netcdf-fortran@4.4.4%gcc@4.9.3 arch=linux-centos7-x86_64
[+]  a3b7wj6      ^parallel-netcdf@1.7.0%gcc@4.9.3~cxx+fortran+fpic arch=linux-centos7-x86_64

==> Installing modele
==> cmake is already installed in /home2/rpfische/spack5/opt/spack/linux-centos7-x86_64/gcc-4.9.3/cmake-3.7.1-f44ykg74y4woethb2gw5utad3rpkdn7e
==> m4 is already installed in /home2/rpfische/spack5/opt/spack/linux-centos7-x86_64/gcc-4.9.3/m4-1.4.17-kmufpwmhwys35ygpe5zcnxrzdy6dvm3e
==> everytrace is already installed in /home2/rpfische/spack5/opt/spack/linux-centos7-x86_64/gcc-4.9.3/everytrace-develop-gyeos66xokjpztn4ez7cgmkzgftvtqfh
==> openmpi is already installed in /home2/rpfische/spack5/opt/spack/linux-centos7-x86_64/gcc-4.9.3/openmpi-1.10.1-2ew2gg7hvoc7vj7fc4s6c3mdfeoblp76
==> netcdf-fortran is already installed in /home2/rpfische/spack5/opt/spack/linux-centos7-x86_64/gcc-4.9.3/netcdf-fortran-4.4.4-xhwyxt3xnhofmktp7lrby5jchgurwjso
==> parallel-netcdf is already installed in /home2/rpfische/spack5/opt/spack/linux-centos7-x86_64/gcc-4.9.3/parallel-netcdf-1.7.0-a3b7wj6rkjrukhqfak2ucjnitx3gbp7p
==> Installing icebin
==> Installing pism
==> cmake is already installed in /home2/rpfische/spack5/opt/spack/linux-centos7-x86_64/gcc-4.9.3/cmake-3.7.1-f44ykg74y4woethb2gw5utad3rpkdn7e
==> fftw is already installed in /home2/rpfische/spack5/opt/spack/linux-centos7-x86_64/gcc-4.9.3/fftw-3.3.5-ikgs5nv3q7wxnsixm7slhgoj4j7pfcey
==> petsc is already installed in /home2/rpfische/spack5/opt/spack/linux-centos7-x86_64/gcc-4.9.3/petsc-3.7.4-k3syjviy2nud4jq2e7eo4fr7ie4kwu4p
==> udunits2 is already installed in /home2/rpfische/spack5/opt/spack/linux-centos7-x86_64/gcc-4.9.3/udunits2-2.2.20-tjpaxgrlyqexjfqv5b4pijwdaila5euu
==> openmpi is already installed in /home2/rpfische/spack5/opt/spack/linux-centos7-x86_64/gcc-4.9.3/openmpi-1.10.1-2ew2gg7hvoc7vj7fc4s6c3mdfeoblp76
==> netcdf is already installed in /home2/rpfische/spack5/opt/spack/linux-centos7-x86_64/gcc-4.9.3/netcdf-4.4.1-as7nvfdulzo3lw5rdd4kwn33zpcpy2ki
==> proj is already installed in /home2/rpfische/spack5/opt/spack/linux-centos7-x86_64/gcc-4.9.3/proj-4.9.2-54uiqru7o2ndyewznekplt3a4naxid5v
==> gsl is already installed in /home2/rpfische/spack5/opt/spack/linux-centos7-x86_64/gcc-4.9.3/gsl-2.3-5qnos74efitt5lzzmn64mfv66v4mc4qz
==> Generating spconfig.py [pism@dev%gcc@4.9.3~doc~extra+icebin~parallel-hdf5~parallel-netcdf3~parallel-netcdf4+proj~python+shared arch=linux-centos7-x86_64-kkl2u4y]
==> Building pism [CMakePackage]
==> Warning: Module file already exists : skipping creation
file : /home2/rpfische/spack5/share/spack/modules/linux-centos7-x86_64/pism-dev-gcc-4.9.3-kkl2u4y

==> Warning: Module file already exists : skipping creation
file : /home2/rpfische/spack5/share/spack/dotkit/linux-centos7-x86_64/pism-dev-gcc-4.9.3-kkl2u4y.dk

==> Successfully setup pism
  Config file is pism_config.py
[+] /home2/rpfische/spack5/opt/spack/linux-centos7-x86_64/gcc-4.9.3/pism-dev-kkl2u4yp2rjcfu7cyozlbldntkarer5l
==> Installing ibmisc
==> cmake is already installed in /home2/rpfische/spack5/opt/spack/linux-centos7-x86_64/gcc-4.9.3/cmake-3.7.1-f44ykg74y4woethb2gw5utad3rpkdn7e
==> eigen is already installed in /home2/rpfische/spack5/opt/spack/linux-centos7-x86_64/gcc-4.9.3/eigen-3.2.10-2cbaqas5aj3c2ty4wavwopmb5i6bjxzo
==> python is already installed in /home2/rpfische/spack5/opt/spack/linux-centos7-x86_64/gcc-4.9.3/python-3.5.2-twdmmviznl4lwbqmx3eifpl56z7no65n
==> netcdf-cxx4 is already installed in /home2/rpfische/spack5/opt/spack/linux-centos7-x86_64/gcc-4.9.3/netcdf-cxx4-4.3.0-zeouiscr2ll5g7xcy6zf56w5ujkedr5x
==> blitz is already installed in /home2/rpfische/spack5/opt/spack/linux-centos7-x86_64/gcc-4.9.3/blitz-1.0.0-f5m2jsss6vvt6azbgvwqmb6xgemlgi7x
==> udunits2 is already installed in /home2/rpfische/spack5/opt/spack/linux-centos7-x86_64/gcc-4.9.3/udunits2-2.2.20-tjpaxgrlyqexjfqv5b4pijwdaila5euu
==> py-numpy is already installed in /home2/rpfische/spack5/opt/spack/linux-centos7-x86_64/gcc-4.9.3/py-numpy-1.11.2-ingtf52klf75lja4tafbkfd5f3svtphf
==> py-cython is already installed in /home2/rpfische/spack5/opt/spack/linux-centos7-x86_64/gcc-4.9.3/py-cython-0.23.5-j6fjvjhngoaymffempjt6vnsonxzfz5h
==> everytrace is already installed in /home2/rpfische/spack5/opt/spack/linux-centos7-x86_64/gcc-4.9.3/everytrace-develop-gyeos66xokjpztn4ez7cgmkzgftvtqfh
==> googletest is already installed in /home2/rpfische/spack5/opt/spack/linux-centos7-x86_64/gcc-4.9.3/googletest-1.7.0-mdbsavkkz6fpc2xhh3q2qtiia3eeuxfm
==> proj is already installed in /home2/rpfische/spack5/opt/spack/linux-centos7-x86_64/gcc-4.9.3/proj-4.9.2-54uiqru7o2ndyewznekplt3a4naxid5v
==> boost is already installed in /home2/rpfische/spack5/opt/spack/linux-centos7-x86_64/gcc-4.9.3/boost-1.62.0-y4h7xx32yv4rqf3ncbop76phrxw4dfhb
==> Generating spconfig.py [ibmisc@develop%gcc@4.9.3+blitz+boost~doc+everytrace+googletest+netcdf+proj+python+udunits2 arch=linux-centos7-x86_64-eqnywrt]
==> Building ibmisc [CMakePackage]
==> Warning: Module file already exists : skipping creation
file : /home2/rpfische/spack5/share/spack/modules/linux-centos7-x86_64/ibmisc-develop-gcc-4.9.3-eqnywrt

==> Warning: Module file already exists : skipping creation
file : /home2/rpfische/spack5/share/spack/dotkit/linux-centos7-x86_64/ibmisc-develop-gcc-4.9.3-eqnywrt.dk

==> Successfully setup ibmisc
  Config file is ibmisc_config.py
[+] /home2/rpfische/spack5/opt/spack/linux-centos7-x86_64/gcc-4.9.3/ibmisc-develop-eqnywrtzozzyw7uvfjzb437lbajen4c3
==> cmake is already installed in /home2/rpfische/spack5/opt/spack/linux-centos7-x86_64/gcc-4.9.3/cmake-3.7.1-f44ykg74y4woethb2gw5utad3rpkdn7e
==> eigen is already installed in /home2/rpfische/spack5/opt/spack/linux-centos7-x86_64/gcc-4.9.3/eigen-3.2.10-2cbaqas5aj3c2ty4wavwopmb5i6bjxzo
==> py-cython is already installed in /home2/rpfische/spack5/opt/spack/linux-centos7-x86_64/gcc-4.9.3/py-cython-0.23.5-j6fjvjhngoaymffempjt6vnsonxzfz5h
==> python is already installed in /home2/rpfische/spack5/opt/spack/linux-centos7-x86_64/gcc-4.9.3/python-3.5.2-twdmmviznl4lwbqmx3eifpl56z7no65n
==> cgal is already installed in /home2/rpfische/spack5/opt/spack/linux-centos7-x86_64/gcc-4.9.3/cgal-4.9-24jxqwo2r6wopens6fzj5m444fjysffv
==> blitz is already installed in /home2/rpfische/spack5/opt/spack/linux-centos7-x86_64/gcc-4.9.3/blitz-1.0.0-f5m2jsss6vvt6azbgvwqmb6xgemlgi7x
==> py-numpy is already installed in /home2/rpfische/spack5/opt/spack/linux-centos7-x86_64/gcc-4.9.3/py-numpy-1.11.2-ingtf52klf75lja4tafbkfd5f3svtphf
==> petsc is already installed in /home2/rpfische/spack5/opt/spack/linux-centos7-x86_64/gcc-4.9.3/petsc-3.7.4-k3syjviy2nud4jq2e7eo4fr7ie4kwu4p
==> everytrace is already installed in /home2/rpfische/spack5/opt/spack/linux-centos7-x86_64/gcc-4.9.3/everytrace-develop-gyeos66xokjpztn4ez7cgmkzgftvtqfh
==> openmpi is already installed in /home2/rpfische/spack5/opt/spack/linux-centos7-x86_64/gcc-4.9.3/openmpi-1.10.1-2ew2gg7hvoc7vj7fc4s6c3mdfeoblp76
==> proj is already installed in /home2/rpfische/spack5/opt/spack/linux-centos7-x86_64/gcc-4.9.3/proj-4.9.2-54uiqru7o2ndyewznekplt3a4naxid5v
==> netcdf-cxx4 is already installed in /home2/rpfische/spack5/opt/spack/linux-centos7-x86_64/gcc-4.9.3/netcdf-cxx4-4.3.0-zeouiscr2ll5g7xcy6zf56w5ujkedr5x
==> gmp is already installed in /home2/rpfische/spack5/opt/spack/linux-centos7-x86_64/gcc-4.9.3/gmp-6.1.2-tl5w2mhmaszqxjlmdbsbywrfr2jmhm54
==> boost is already installed in /home2/rpfische/spack5/opt/spack/linux-centos7-x86_64/gcc-4.9.3/boost-1.62.0-y4h7xx32yv4rqf3ncbop76phrxw4dfhb
==> mpfr is already installed in /home2/rpfische/spack5/opt/spack/linux-centos7-x86_64/gcc-4.9.3/mpfr-3.1.4-2igx7t2p5wxlg6iignrzio55hz5exsu7
==> Generating spconfig.py [icebin@develop%gcc@4.9.3+coupler~doc+everytrace+gridgen+pism+python arch=linux-centos7-x86_64-5ad3eli]
==> Building icebin [CMakePackage]
==> Warning: Module file already exists : skipping creation
file : /home2/rpfische/spack5/share/spack/modules/linux-centos7-x86_64/icebin-develop-gcc-4.9.3-5ad3eli

==> Warning: Module file already exists : skipping creation
file : /home2/rpfische/spack5/share/spack/dotkit/linux-centos7-x86_64/icebin-develop-gcc-4.9.3-5ad3eli.dk

==> Successfully setup icebin
  Config file is icebin_config.py
[+] /home2/rpfische/spack5/opt/spack/linux-centos7-x86_64/gcc-4.9.3/icebin-develop-5ad3elimosln3ene6vuapyxjqgueiiij
==> Generating spconfig.py [modele@landice%gcc@4.9.3~aux+debug~diags+everytrace~fexception~ic+icebin+model+mods+mpi+pnetcdf~tests arch=linux-centos7-x86_64-haxxwlf]
==> Building modele [CMakePackage]
==> Warning: Module file already exists : skipping creation
file : /home2/rpfische/spack5/share/spack/modules/linux-centos7-x86_64/modele-landice-gcc-4.9.3-haxxwlf

==> Warning: Module file already exists : skipping creation
file : /home2/rpfische/spack5/share/spack/dotkit/linux-centos7-x86_64/modele-landice-gcc-4.9.3-haxxwlf.dk

==> Successfully setup modele
  Config file is modele_config.py
[+] /home2/rpfische/spack5/opt/spack/linux-centos7-x86_64/gcc-4.9.3/modele-landice-haxxwlfc33ynauwd7lmbqe3xin7i64u7

An ls -ltrah shows that this created for files that will be used to configure CMake for the four projects I wanted to build manually:

12K Jan  3 16:19 pism_config.py
18K Jan  3 16:19 ibmisc_config.py
23K Jan  3 16:19 icebin_config.py
25K Jan  3 16:19 modele_config.py

@citibeth
Copy link
Member Author

citibeth commented Jan 4, 2017

Another change... CMake-specific stuff has now been factored into cmake.py. This sets the stage for spack setup functionality for other Package superclasses.

@citibeth citibeth changed the title spack setup: Squash Bugs through Refactoring spack setup: Fix Bugs + Multi-setup Jan 4, 2017
@@ -49,6 +60,8 @@ class CMakePackage(PackageBase):
# build-system class we are using
build_system_class = 'CMakePackage'

depends_on('cmake', type='build')
Copy link
Member

Choose a reason for hiding this comment

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

Can you rebase? This line is now present in develop.

@citibeth citibeth mentioned this pull request Jan 7, 2017
@citibeth
Copy link
Member Author

citibeth commented Jan 9, 2017

@tgamblin It is my humble opinion that the structure set up for tests is needlessly complicated for this purpose, because the tests happen from WITHIN Spack. I would like a test like the following:

git clone everytrace
cd everytrace
spack setup everytrace
mkdir build
cd build
../spconfig.py
make install

I shouldn't have to get deeply involved with mock archives, mock packages, etc. just to do that. I do see the value in avoiding network access in tests. Can I write a test, external to Spack, that does the above? Do you have any suggestions?

@citibeth
Copy link
Member Author

citibeth commented Jan 18, 2017 via email

@tgamblin
Copy link
Member

Unless/until all calls to this function have allow_multi=True, it should remain, IMHO.

Seems reasonable to do in a separate PR.

@becker33
Copy link
Member

@citibeth Are there any commands left that don't accept multiple specs? I know install did not even accepting the broken parser, but that changed as of #2769 as well. I don't believe there are any left.

@citibeth
Copy link
Member Author

@tgamblin See latest for where I'm heading with the tests. I'm working on Suggestion no. 1 from above. Unfortunately, after merging with the latest develop I've broken the existing unit tests, and should probably get that fixed first. Do you know what is going wrong in the unit test log output below? 2 out of 516 tests are failing.

=========================================== FAILURES ============================================
_____________________ InstallTestJunitLog.test_dependency_already_installed _____________________

self = <spack.test.cmd.install.InstallTestJunitLog testMethod=test_dependency_already_installed>

    def test_dependency_already_installed(self):
        pkgX.installed = True
        pkgY.installed = True
        parser = argparse.ArgumentParser()
        install.setup_parser(parser)
        args = parser.parse_args(['--log-format=junit', 'X'])
        install.install(parser, args)
>       self.assertEqual(len(FILE_REGISTRY), 1)
E       AssertionError: 0 != 1

../../../lib/spack/spack/test/cmd/install.py:215: AssertionError
___________________________ InstallTestJunitLog.test_installing_both ____________________________

self = <spack.test.cmd.install.InstallTestJunitLog testMethod=test_installing_both>

    def test_installing_both(self):
        parser = argparse.ArgumentParser()
        install.setup_parser(parser)
        args = parser.parse_args(['--log-format=junit', 'X'])
        install.install(parser, args)
>       self.assertEqual(len(FILE_REGISTRY), 1)
E       AssertionError: 0 != 1

../../../lib/spack/spack/test/cmd/install.py:202: AssertionError
======================= 2 failed, 514 passed, 1 xfailed in 129.06 seconds =======================

@citibeth
Copy link
Member Author

It looks like these tests failed before my merge with develop as well. So it's something I did, not something getting messed up in the merge.

@citibeth
Copy link
Member Author

OK I found the problem.

Elizabeth Fischer added 3 commits February 12, 2017 18:49
Add everytrace to Mock repo; will be used for spack setup tests.
Added unit test: setup
Elizabeth Fischer added 2 commits February 12, 2017 20:49
@citibeth
Copy link
Member Author

@tgamblin OK unit tests pass. And I added a unit test that scrutinizes the generated spconfig.py file. You're right, install and setup are now part of the same code path anyway, reducing the chance that one works when the other does not. I'd be happy to see this merged as-is.

If you want further tests, I'd be happy to build them on top of the example you suggest:

It actually isn't that bad to mock up a simple test that can fetch a mock archive. The tests I pointed you to might be a bit complicated, though. What if I make you a simple example that does a fetch, then push it, and you can write the actual tests?

Please tell me what you think; this PR should be merged sooner rather than later.

@pramodk
Copy link
Contributor

pramodk commented Feb 21, 2017

waiting for this PR, it would be great to have spack setup working.

@citibeth
Copy link
Member Author

@tgamblin Does this PR need anything more before being merged?

@davydden
Copy link
Member

@tgamblin @alalazo @adamjstewart ping. Would be good to have spack setup working...

@adamjstewart
Copy link
Member

Ping ping @tgamblin. This addresses multiple issues.

Copy link
Member

@scheibelp scheibelp left a comment

Choose a reason for hiding this comment

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

I'm taking over reviewing this from @tgamblin.

Some of these comments are actually just questions about how this works. This also needs to be brought up to date with the current develop branch, so I understand that some of my comments may be irrelevant when you do so.

Where I make a request, I'm curious whether you agree and - if you do - whether you have the time to address it. I imagine the most onerous request is for more tests.

skip_patch=False,
verbose=False,
make_jobs=None,
run_tests=False,
fake=False,
explicit=False,
dirty=None,
setup=set(),
Copy link
Member

Choose a reason for hiding this comment

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

Elsewhere I state a preference that this be encoded as a member variable of package. But if you disagree with that:

Could you do one of the following:

  • set the default to None and replace with an empty set in the body?
  • set the default to frozenset()

Otherwise IMO this is confusing since the defaults are evaluated once at definition time. To be clear I don't think this is an issue in your case since you don't modify the set, but making it a frozenset would make that explicit.

# Abort install if install directory exists.
# But do NOT remove it (you'd be overwriting someone else's stuff)
tty.warn("Keeping existing install prefix in place.")
if self.name in setup:
Copy link
Member

Choose a reason for hiding this comment

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

I think this should just set keep_prefix=True no matter what. That seems to be what you want in your case and also what should happen anyway based on the comment.

if self.name in setup:
this_fake = True
explicit = True
self.stage = DIYStage(os.getcwd()) # Force build in cwd
Copy link
Member

Choose a reason for hiding this comment

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

If setup was a property of Package, _make_stage could generate this stage instead of overwriting it which IMO would be clearer.

Also, a question: I'm not clear how we came to be in the build directory of the package. I presume that we aren't assuming that spack install is launched from the build directory of the package to be set up, since I'm not sure how that would work if two different packages were being set up.

skip_patch=False,
verbose=False,
make_jobs=None,
run_tests=False,
fake=False,
explicit=False,
dirty=None,
setup=set(),
spconfig_fname_fn=None, # Must be set
Copy link
Member

Choose a reason for hiding this comment

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

I don't see spconfig_fname_fn being customized anywhere - from what I can tell this is always cmd.install.get_spconfig_fname. I'd prefer this was a property of Package, or possibly even a static function (since the method signature of do_install is getting a bit unwieldy).

if fake:
if self.name in setup:
pass # Don't write any files in the install...
elif this_fake:
Copy link
Member

Choose a reason for hiding this comment

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

I can see how this works out but if if this_fake is used in this manner, I'd prefer it didn't also include the value of self.name in setup. i.e. above where you decide whether to skip patching/staging, check if fake or self.name in setup


defs = dict()
defre = re.compile('-D(.*?)(:(.*?))?=(.*)')
print(spconfig.cmd)
Copy link
Member

Choose a reason for hiding this comment

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

Remove print statement

os.environ = self.orig_environ
shutil.rmtree(self.dir)

def test_setup_cmake(self):
Copy link
Member

Choose a reason for hiding this comment

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

I think some additional tests would be worthwhile:

  • Make sure the stage is not deleted if a setup package fails to install
  • Make sure Package.install is called for packages which should be set up

I could be wrong about those in particular but at the moment this only tests the integrity of the spconfig.py file, and it doesn't test any of the modifications to Package.do_install

def spack_transitive_include_path():
return ';'.join(
os.path.join(dep, 'include')
for dep in os.environ['SPACK_DEPENDENCIES'].split(os.pathsep)
Copy link
Member

Choose a reason for hiding this comment

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

Could you add a TODO comment to expose this in build_environment with a function so you don't have to grab it from the environment? I think that ought to be done but I don't think it needs to be done in this PR.


def write_spconfig(self, spconfig_fname):
"""Writes the spconfig.py (CMake setup file) to a file."""
print('BEGIN write_spconfig')
Copy link
Member

Choose a reason for hiding this comment

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

Remove print statement (use tty.debug if you wan to see this somewhere)

@scheibelp scheibelp dismissed tgamblin’s stale review May 25, 2017 00:31

Out of date/incomplete

@pramodskumbhar
Copy link
Contributor

@citibeth : would it be possible to rebase this on latest develop? I was trying to do it myself but don't have knowledge of all changes involved. spack setup would be really useful !

@citibeth
Copy link
Member Author

citibeth commented Aug 9, 2017

@pramodskumbhar see #5043 for rebased version. I unfortunately do not currently have the time to push this PR over the finish line. I have put the new PR on the main LLNL Spak repo, in the hopes that someone else can test it, etc. and get it merged. I'm happy to answer questions, try it out on samples, etc.

@pramodskumbhar
Copy link
Contributor

thank you very much @citibeth! No problem, I will test it and will let you know if I see any issues.

@alalazo
Copy link
Member

alalazo commented Aug 15, 2017

Superseded by #5043

@alalazo alalazo closed this Aug 15, 2017
@tgamblin tgamblin added this to the v0.11.0 milestone Nov 12, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Spack Melts Down into a puddle...
10 participants