Skip to content

Instantly share code, notes, and snippets.

@jstanley0
Last active February 17, 2022 17:07
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jstanley0/e6cbbb7fb243e794bca7cba9597172f9 to your computer and use it in GitHub Desktop.
Save jstanley0/e6cbbb7fb243e794bca7cba9597172f9 to your computer and use it in GitHub Desktop.
Canvas Time Travel HOWTO

Canvas time travel HOWTO

How to get a historic version of Canvas up and running. Other than a few specific points, these tips may be useful for other Rails apps.

0. preparation

  • provision a linux VM (see MACOS_NOTE at the end of this document)
    • if you are using Multipass, be sure to set up adequate disk space (e.g. multipass launch --disk 30G), since the 5GB default will not be sufficient and there is no way to increase it after the fact. don't ask me how I know this. also use --mem 8G or thereabouts because the 1GB default is also not enough (you can change this after the fact, but it involves editing a json file buried in a directory you need sudo to get into)
  • pull down the repo
  • set up rvm and chruby

1. identify the desired tag or commit hash

  • you can browse with e.g. git log --before 2012-02-23
  • then get it with git checkout
  • the older you get, the lesser the chance that the code is actually runnable at some arbitrary timestamp. you may have better luck checking out specific tags.

2. identify the required versions of ruby and bundler

  • look at Gemfile.d/_before.rb (or just Gemfile in very old versions)
  • note that IME bundler older than 1.8.x will not talk to rubygems anymore but I had success with that version
  • if you are using Rails older than 3, use Ruby 1.8.7. you will not need a ruby version older than this

3. install ruby

  • if you're lucky, something like ruby-install 2.4.10 will work even if the version is past EOL
  • you will not be that lucky
  • openssl incompatibility is the primary reason why; old ruby versions need 1.0, and your linux distro probably uses a newer version, with a different API
  • you will likely need to download openssl 1.0 and compile it from source
  • make install puts it in /usr/local/ssl which, on ubuntu at least, does not clash with the built-in library
  • when compiling ruby, point at the SSL 1.0 library, e.g.
    CFLAGS="-I/usr/local/ssl/include" LDFLAGS="-L/usr/local/ssl/lib" ruby-install 2.4.10
    
  • with really old ruby versions, I had better luck with ruby-build than ruby-install. this is part of the rbenv project, but the installation will work with chruby if you provide the location chruby looks for rubies. build with e.g.
    CFLAGS="-I/usr/local/ssl/include" LDFLAGS="-L/usr/local/ssl/lib" ruby-build 1.8.7-p374 ~/.rubies/ruby-1.8.7-p374
    
  • if the compile fails, it may be because of signature mismatches with openssl or zlib. I saw both in my time travels. for example, ruby's zlib extension tried to put the return value from get_crc_table into an unsigned long *, which is the wrong type (and probably changed from 32 bits to 64 bits at some point). changing it to the correct type, z_crc_t *, fixed this issue.
  • if you're using ruby-build, the ruby repo is in /tmp; if you're using ruby-install, it's in ~/src. after fixing the build issues, you can run make and make install to complete the process

4. install bundler

  • select the proper ruby version with chruby
  • install bundler with e.g. gem install bundler -v 1.8.9

5. bundle install

  • if it hangs when trying to talk to rubygems, try a newer version than the contemporary canvas actually used (IME anything older than 1.8 will not work)
  • try --without sqlite to make life a little simpler
  • you will see two kinds of errors:
    1. gems where a version wasn't specified, and bundler tried to get the newest one, which is incompatible with your version of ruby
      • go to rubygems.org and find a contemporary version, then update the Gemfile to use that version (or add it if it's not in there already; it's likely another gem botched the dependency)
    2. gems where the native extension fails to build
      • you may need to find a newer version of the gem that's compatible with whatever OS change broke the old one... but hopefully not new enough that it's incompatible with your version of ruby or canvas
      • if all else fails, verify the gem is actually needed. if it's a test dependency you can just comment it out (unless you really want to run ancient specs)

6. install node

  • if your version of canvas has a .nvmrc, great, use that version
  • if it doesn't, you can look for a contemporary version of node; however, IME anything older than 0.10 won't talk to modern services due to old-SSL deprecation

7. npm install

  • if a too-new package is selected implicity, you can install a contemporary one with e.g. npm install aws-sdk@2.98.0 and try again (adding it to the package.json may not help because npm is happy to install multiple versions of the same package and may (fail to) get the newer dependency before finding your version)

8. compile assets

  • bundle exec rake canvas:compile_assets
  • you may need to install libsass
  • if production assets fail to build, meh, you don't need 'em

9. config

  • you can probably get away with using the .yml.example files for the most part
  • note that very old canvas versions can use sqlite; look for database.yml.sqlite-example

10. initialize the database

  • bundle exec rake db:initial_setup
  • I successfully got 2015 canvas talking to postgres 14.2 but this did require a few simple tweaks to fix errors that cropped up during rails boot/db migration. still probably easier than installing legacy postgres
    • remove the -i from pg_dump
    • change pg_current_xlog_location to pg_current_wal_lsn
    • change pg_last_xlog_replay_location to pg_last_wal_replay_lsn

11. start the server

  • bundle exec rails server works if rails is 3 or newer
  • for really old canvas, use script/server

MACOS_NOTE

  • changes in clang break the build for some old C code (either ruby itself or gem/npm native extensions). mostly it seems like clang deciding to promote the "no implicit function declaration" warning to an error by default causes a lot of problems. to build ruby:
    CFLAGS="-Wno-implicit-function-declaration -I$(brew --prefix openssl@1.0)/include" LDFLAGS="-L$(brew --prefix openssl@1.0)/lib" ruby-build 1.8.7-p375 ~/.rubies/ruby-1.8.7
    
    to build gems:
    gem install ffi -v '1.9.14' -- --with-cflags=-Wno-implicit-function-declaration
    
  • older versions of node can't find the Xcode command-line development tools. newer versions may be incompatible with your modules. this is why I ended up switching to Linux. there may be workarounds at https://github.com/nodejs/node-gyp/blob/master/macOS_Catalina.md but I couldn't get anything short of reinstalling Xcode to work, and I was unwilling to go that far.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment