Giter VIP home page Giter VIP logo

redisio's Issues

Service Provider needs to load_current_resource

The redis_service provider needs to both implement load_current_resource, and also call updated_by_last_action when some action is taken. This will allow it to send notifications and receive subscriptions.

Split install resource into install / configure in next major revision?

In the next major revision change I think it makes sense to split the install Resource into two resources. Install and Configure.

Install will ONLY be responsible for laying down the binaries... be this via Source or package.

Configure will be responsible for laying down all the appropriate init and configuration files.

Redis Sentinel support

Im currently writing a simple cookbook to provide redis sentinel support, and am contemplating merging it into here, as this is the best redis cookbook! Before i start, Any suggestions on how this could be best implemented?
Give me some ideas and i will hack some support in.

Add updated_by_last_action

Currently the providers don't implement updated_by_last action, which would allow the use of notifies. This is poor implementation and needs to be fixed.

Default settings "save" as empty string breaks install

The README says "if you want to disable saving use an empty string" for the default settings "save" option.

However, the code checks only for nil, leaving an empty string to break on the .empty method, as in:

Template Context:
-----------------
on line #104
102:     save 60 10000
103:   <% else %>
104:     <% @save.each do |save_option| %>
105:       <%= "save #{save_option}" %>
106:     <% end %>

[2013-07-29T20:57:35+00:00] FATAL: Chef::Mixin::Template::TemplateError: undefined method `each' for "":String

Add support for server configuration via data bag

The recipe should support taking redis server configurations from a data bag. This allows for better re-use of configurations without having to muck around in role files. This also allows the role files to become more slim.

Find how to call updated_by_last_action on nested resources

See if it is possible to pass on the updated_by_last_action from resources called within a provider. WIthout doing that it will be pretty difficult to properly called updated_by_last_action for the configure step of the redisio install provider. This is a shame because it would be nice to provide the option to allow for the LWRP to use notifications for restarts.

Upstart script fails to create missing pid directory

setuid and setgid cause the ENTIRE upstart job to run as that user. Since the default user is "redis" this means that user cannot create the appropriate pid directory. The upstart script will have to be modified to call out to sudo to run the redis process itself, this is an issue however as I don't believe you can use sudo to set the ulimit as limit is a shell builtin.

This is a known limitation of upstart and a real pain in the butt :)

Does not work with 2.6.0-rc6

Out of the box, the cookbook fails with this:

[2012-08-09T17:28:59+02:00] INFO: Processing user[redis] action create (/home/vagrant/chef/cookbooks/redisio/providers/install.rb line 84)
[2012-08-09T17:28:59+02:00] INFO: Processing directory[/etc/redis] action create (/home/vagrant/chef/cookbooks/redisio/providers/install.rb line 91)
[2012-08-09T17:28:59+02:00] INFO: Processing directory[/var/lib/redis] action create (/home/vagrant/chef/cookbooks/redisio/providers/install.rb line 98)
[2012-08-09T17:28:59+02:00] INFO: Processing template[/etc/redis/6379.conf] action create (/home/vagrant/chef/cookbooks/redisio/providers/install.rb line 104)
[2012-08-09T17:28:59+02:00] INFO: Processing template[/etc/init.d/redis6379] action create (/home/vagrant/chef/cookbooks/redisio/providers/install.rb line 136)
[2012-08-09T17:28:59+02:00] INFO: Processing redisio_service[6379] action start (redisio::enable line 25)
[2012-08-09T17:28:59+02:00] INFO: Processing redisio_service[6379] action enable (redisio::enable line 25)
[2012-08-09T17:28:59+02:00] INFO: Processing execute[/etc/init.d/redis6379 start] action run (/home/vagrant/chef/cookbooks/redisio/providers/service.rb line 24)
[2012-08-09T17:28:59+02:00] ERROR: execute[/etc/init.d/redis6379 start] (/home/vagrant/chef/cookbooks/redisio/providers/service.rb line 24) has had an error
[2012-08-09T17:28:59+02:00] ERROR: execute[/etc/init.d/redis6379 start] (/home/vagrant/chef/cookbooks/redisio/providers/service.rb:24:in `block in class_from_file') had an error:
execute[/etc/init.d/redis6379 start] (/home/vagrant/chef/cookbooks/redisio/providers/service.rb line 24) had an error: Mixlib::ShellOut::ShellCommandFailed: Expected process to exit with [0], but received '1'
---- Begin output of /etc/init.d/redis6379 start ----
STDOUT: Starting Redis server...
STDERR: *** FATAL CONFIG FILE ERROR ***
Reading the configuration file, at line 199
>>> 'maxclients 0'
Invalid max clients limit
---- End output of /etc/init.d/redis6379 start ----
Ran /etc/init.d/redis6379 start returned 1
/var/lib/gems/1.9.1/gems/mixlib-shellout-1.1.0/lib/mixlib/shellout.rb:248:in `invalid!'
/var/lib/gems/1.9.1/gems/mixlib-shellout-1.1.0/lib/mixlib/shellout.rb:234:in `error!'
/var/lib/gems/1.9.1/gems/chef-10.12.0/lib/chef/mixin/shell_out.rb:36:in `shell_out!'
/var/lib/gems/1.9.1/gems/chef-10.12.0/lib/chef/provider/execute.rb:58:in `action_run'
/var/lib/gems/1.9.1/gems/chef-10.12.0/lib/chef/resource.rb:454:in `run_action'
/var/lib/gems/1.9.1/gems/chef-10.12.0/lib/chef/runner.rb:49:in `run_action'
/var/lib/gems/1.9.1/gems/chef-10.12.0/lib/chef/runner.rb:85:in `block (2 levels) in converge'
/var/lib/gems/1.9.1/gems/chef-10.12.0/lib/chef/runner.rb:85:in `each'
/var/lib/gems/1.9.1/gems/chef-10.12.0/lib/chef/runner.rb:85:in `block in converge'
/var/lib/gems/1.9.1/gems/chef-10.12.0/lib/chef/resource_collection.rb:94:in `block in execute_each_resource'
/var/lib/gems/1.9.1/gems/chef-10.12.0/lib/chef/resource_collection/stepable_iterator.rb:116:in `call'
/var/lib/gems/1.9.1/gems/chef-10.12.0/lib/chef/resource_collection/stepable_iterator.rb:116:in `call_iterator_block'
/var/lib/gems/1.9.1/gems/chef-10.12.0/lib/chef/resource_collection/stepable_iterator.rb:85:in `step'
/var/lib/gems/1.9.1/gems/chef-10.12.0/lib/chef/resource_collection/stepable_iterator.rb:104:in `iterate'
/var/lib/gems/1.9.1/gems/chef-10.12.0/lib/chef/resource_collection/stepable_iterator.rb:55:in `each_with_index'
/var/lib/gems/1.9.1/gems/chef-10.12.0/lib/chef/resource_collection.rb:92:in `execute_each_resource'
/var/lib/gems/1.9.1/gems/chef-10.12.0/lib/chef/runner.rb:80:in `converge'
/var/lib/gems/1.9.1/gems/chef-10.12.0/lib/chef/client.rb:330:in `converge'
/var/lib/gems/1.9.1/gems/chef-10.12.0/lib/chef/client.rb:163:in `run'
/var/lib/gems/1.9.1/gems/chef-10.12.0/lib/chef/application/solo.rb:207:in `block in run_application'
/var/lib/gems/1.9.1/gems/chef-10.12.0/lib/chef/application/solo.rb:195:in `loop'
/var/lib/gems/1.9.1/gems/chef-10.12.0/lib/chef/application/solo.rb:195:in `run_application'
/var/lib/gems/1.9.1/gems/chef-10.12.0/lib/chef/application.rb:70:in `run'
/var/lib/gems/1.9.1/gems/chef-10.12.0/bin/chef-solo:25:in `<top (required)>'
/usr/local/bin/chef-solo:19:in `load'
/usr/local/bin/chef-solo:19:in `<main>'
[2012-08-09T17:28:59+02:00] ERROR: Running exception handlers
[2012-08-09T17:28:59+02:00] ERROR: Exception handlers complete
[2012-08-09T17:28:59+02:00] FATAL: Stacktrace dumped to /home/vagrant/chef/chef-stacktrace.out
[2012-08-09T17:28:59+02:00] FATAL: Mixlib::ShellOut::ShellCommandFailed: execute[/etc/init.d/redis6379 start] (/home/vagrant/chef/cookbooks/redisio/providers/service.rb line 24) had an error: Mixlib::ShellOut::ShellCommandFailed: Expected process to exit with [0], but received '1'
---- Begin output of /etc/init.d/redis6379 start ----
STDOUT: Starting Redis server...
STDERR: *** FATAL CONFIG FILE ERROR ***
Reading the configuration file, at line 199
>>> 'maxclients 0'
Invalid max clients limit
---- End output of /etc/init.d/redis6379 start ----
Ran /etc/init.d/redis6379 start returned 1

Specifying maxmemory as percentage fails

If you specify maxmemory as a percentage, installation fails because redis.conf.erb calls @maxmemory.empty?, which doesn't work because @maxmemory is a Fixnum, not a String.

Patch will be submitted shortly.

uninitialized constant Chef::Provider::RedisioInstall::RedisioHelper

Hi,
Just updated our redisio cookbook for chef, and i encounter the following error when executing chef-client:

2013-03-12T10:56:46+00:00] ERROR: Running exception handlers
[2013-03-12T10:56:46+00:00] FATAL: Saving node information to /var/chef/cache/failed-run-data.json
[2013-03-12T10:56:46+00:00] ERROR: Exception handlers complete
Chef Client failed. 0 resources updated
[2013-03-12T10:56:46+00:00] FATAL: Stacktrace dumped to /var/chef/cache/chef-stacktrace.out
[2013-03-12T10:56:46+00:00] FATAL: NameError: redisio_install[redis-servers](redisio::install line 30) had an error: NameError: uninitialized constant Chef::Provider::RedisioInstall::RedisioHelper

any idea what's the cause?

Support configuring multiple sentinel commands

Firstly, thanks for this cookbook!

We usually overload sentinels to watch multiple master servers. I've hacked this together by overriding the existing attributes, template, and provider, but before I clean it up and submit a pull request, I wanted to see if you had plans for this and if so, how you intended it.

I ask mainly because there is a monitor default attribute that isn't used anywhere, and I haven't found any configuration in redis that corresponds to that keyword aside from sentinel monitor.

I've basically rolled up the sentinel config options into an array for the monitor attribute.

Sample config (testing on a single, vagrant instance):

sentinels: [
    # Primary Sentinel
    {
      'sentinel_port' => 26379,
      'name' => '26379',
      'monitor' => [
          {'master_name'  => 'redis1',
            'master_ip'   => '127.0.0.1',
            'master_port' => 6379,
          },
          {'master_name'  => 'redis2',
            'master_ip'   => '127.0.0.1',
            'master_port' => 6380,
          },
      ],
    },
    # Secondary Sentinel
    {
      'sentinel_port' => 26380,
      'name' => '26380',
      'monitor' => [
          {'master_name'  => 'redis1',
            'master_ip'   => '127.0.0.1',
            'master_port' => 6379,
          },
          {'master_name'  => 'redis2',
            'master_ip'   => '127.0.0.1',
            'master_port' => 6380,
          },
      ],
    },
  ]

Sample config output:

sentinel monitor redis1 127.0.0.1 6379 2
sentinel down-after-milliseconds redis1 30000
sentinel can-failover redis1 yes
sentinel parallel-syncs redis1 1
sentinel failover-timeout redis1 900000

sentinel monitor redis2 127.0.0.1 6380 2
sentinel down-after-milliseconds redis2 30000
sentinel can-failover redis2 yes
sentinel parallel-syncs redis2 1
sentinel failover-timeout redis2 900000

Thoughts?

Kevin

2.8.0-rc6

Does this cookbook works with 2.8.0-rc6? I changed google files download link to redis.io

[2013-11-15T15:42:43+00:00] WARN: Overridden Run List: [recipe[redisio::enable]]
Compiling Cookbooks...

Recipe Compile Error in /opt/cookbooks/redisio/recipes/enable.rb

NoMethodError

undefined method `each' for nil:NilClass

redis is being run as root

The docs say that the attribute "user" is the user to run redis as and to own the directories. Although the directories are owned by the redis user, the init script starts redis as root defeating the purpose of this attribute. The debian package has an init script that drops root which could probably be used.

Commented out run level + enable causes the Upstart conf to be regenerated at each run

I'm not sure that it's really a problem, but it's added churn.

Chef-client 0.11.4

Output:

 * template[/etc/init/redis6379.conf] action create[2013-03-31T20:52:01+00:00] INFO: Processing template[/etc/init/redis6379.conf] action create (/var/chef/cache/cookbooks/redisio/providers/install.rb line 228)
[2013-03-31T20:52:01+00:00] INFO: template[/etc/init/redis6379.conf] backed up to /var/chef/backup/etc/init/redis6379.conf.chef-20130331205201
[2013-03-31T20:52:01+00:00] INFO: template[/etc/init/redis6379.conf] removed backup at /var/chef/backup/./etc/init/redis6379.conf.chef-20130331192234
[2013-03-31T20:52:01+00:00] INFO: template[/etc/init/redis6379.conf] updated content
[2013-03-31T20:52:01+00:00] INFO: template[/etc/init/redis6379.conf] owner changed to 107
[2013-03-31T20:52:01+00:00] INFO: template[/etc/init/redis6379.conf] group changed to 113
[2013-03-31T20:52:01+00:00] INFO: template[/etc/init/redis6379.conf] mode changed to 644

    - update template[/etc/init/redis6379.conf] from 34258b to 0c9af1
        --- /etc/init/redis6379.conf    2013-03-31 20:23:30.472773025 +0000
        +++ /tmp/chef-rendered-template20130331-8886-1bz6idw    2013-03-31 20:52:01.696321990 +0000
        @@ -1,7 +1,7 @@
         description "Start the redis instance on port 6379"
         author "Installed by chef redisio cookbook"

        -start on runlevel [2345]
        +#start on runlevel [2345]
         stop on runlevel [06]

         script


    - would evaluate block and run any associated actions

Recipe: redisio::install

redisio_service notifies every time on Ubuntu

Since you don't check whether the service is already enabled and/or running, the execute resource will run every time.
For those of us who get notifications on every action that has been run, that's extra noise.

Is there any particular reason why you can't use the builtin service resource, at least on Debian and Ubuntu?
They support specifying the priority; and as for run levels, (2..5) is the default IIUC.

No status option in redis6379 service.

Surprised to find that there was only a start & stop in the redis6579 service. I'm guessing this hasn't been gotten to yet? I can add support for this and submit a PR if you'd like.

#!/bin/sh
#
# Simple Redis init.d script conceived to work on Linux systems
# as it does use of the /proc filesystem.
#
# description: Redis is an in memory key-value store database
#
### BEGIN INIT INFO
# Provides: redis6379
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Description: redis6379 init script
### END INIT INFO

REDISNAME=6379
REDISPORT=6379
EXEC="sudo -u redis /usr/local/bin/redis-server /etc/redis/${REDISNAME}.conf"
CLIEXEC=/usr/local/bin/redis-cli


PIDFILE=/var/run/redis/6379/redis_${REDISNAME}.pid

if [ ! -d /var/run/redis/6379 ]; then
    mkdir -p /var/run/redis/6379
    chown redis  /var/run/redis/6379
fi

case "$1" in
    start)
        if [ -f $PIDFILE ]
        then
                echo "$PIDFILE exists, process is already running or crashed"
        else
                echo "Starting Redis server..."
                eval $EXEC
        fi
        ;;
    stop)
        if [ ! -f $PIDFILE ]
        then
                echo "$PIDFILE does not exist, process is not running"
        else
                PID=$(cat $PIDFILE)
                echo "Stopping ..."


                $CLIEXEC  -p 6379 shutdown

                while [ -x /proc/${PID} ]
                do
                    echo "Waiting for Redis to shutdown ..."
                    sleep 1
                done
                echo "Redis stopped"
        fi
        ;;
    *)
        echo "Please use start or stop as first argument"
        ;;
esac

Test 1.1.0 on all platforms

1.1.0 needs to be tested on all platforms before release

Ubuntu - Tested
Debian - Needs Testing
Fedora - Needs Testing
Scientific - Needs Testing
Centos - Needs Testing

Initd script - why check pidfile exists?

Hi,

Why is it pertinent to have this if statement?:
https://github.com/brianbianco/redisio/blob/master/templates/default/redis.init.erb#L45

I use monit to monitor redis, and I can't restart it, since it keeps saying that a pid file already exists. I removed the if so eval $EXEC is always called no matter if there's a pidfile or not, and it worked wonderfully.

Also, is there any way to have a pid file when using upstart script? I like to use upstart and defer to Monit the cpu/memory alerting + restarting the app via upstart, but it looks like it don't create any pid file:
https://github.com/brianbianco/redisio/blob/master/templates/default/redis.conf.erb#L17

Thanks for the h elp

New service method not functioning properly

This issue appears to be new with version 1.2 of the cookbook. When the Chef run completes, the service is not running. If I check the debug output, there seems to be an attempt to check if it's running, which always succeeds. I know it's not running, but I'm not sure why Chef thinks it is:

ake[1]: Leaving directory `/var/chef/cache/redis-2.6.4/src'
[2012-11-26T20:51:57+00:00] INFO: execute[cd /var/chef/cache/redis-2.6.4 && make install] ran successfully
[2012-11-26T20:51:57+00:00] INFO: Processing service[redis6379] action nothing (redisio::install line 34)
[2012-11-26T20:51:57+00:00] DEBUG: service[redis6379] you have specified a status command, running..
14086 sh -c pgrep -lf 'redis.*6379'
[2012-11-26T20:51:57+00:00] DEBUG: service[redis6379] is running
[2012-11-26T20:51:57+00:00] DEBUG: Doing nothing for service[redis6379]
[2012-11-26T20:51:57+00:00] INFO: Processing service[redis6379] action start (redisio::install line 34)
[2012-11-26T20:51:57+00:00] DEBUG: service[redis6379] you have specified a status command, running..
14093 sh -c pgrep -lf 'redis.*6379'
[2012-11-26T20:51:57+00:00] DEBUG: service[redis6379] is running
[2012-11-26T20:51:57+00:00] DEBUG: service[redis6379] already running - nothing to do
[2012-11-26T20:51:57+00:00] INFO: Processing service[redis6379] action enable (redisio::install line 34)
[2012-11-26T20:51:57+00:00] DEBUG: service[redis6379] you have specified a status command, running..
14100 sh -c pgrep -lf 'redis.*6379'
[2012-11-26T20:51:58+00:00] DEBUG: service[redis6379] is running

Ubuntu 12.04.1
Chef 10.16.2

slaveof cannot be set from search

I have a redis-master and redis-slave roles. In the slave wrapper cookbook I'm using search to pull the IP for "slaveof" but I'm getting an unknown method error

redis_server = search(:node, 'role:redis-master').first
node.override[:redisio][:default_settings][:slaveof] =  redis_server[:rackspace][:private_ip]

returns

Recipe compiler error
NoMethodError
2:>> node.override[:redisio][:default_settings][:slaveof] =  redis_server[:rackspace][:private_ip]

Review Readme.md

Review the Readme.md and make sure there are no errors in it, especially with the latest updates.

More sensible attribute names

I wish that all of the attributes were names identically to the related redis configuration option. For a lot of these this is true, but for some it isn't. This would make it easier to just progamatically generate the configuration file instead of having to modify the template file each time.

Originally I liked the idea of keeping the configuration file identical to the one that came with the distribution for some reason. While this would be easy to write the code for, I have to add in a way to gracefully handle backwards compatability with my original poorly designed way of doing things.

Create "safe install" attribute

There should be an attribute called safe_install that will refuse to install redis over an existing version. It might even make sense to have this set to true by default, so that in order to "upgrade" you have to make sure you have safe_install set to false.

redisio using upstart does not start?

Why I try to use upstart and I do sudo start redismaster, I see that upstart successfully started it, but no process is started (ps aux | grep redis).
also there's a redismaster.conf and redismaster.conf.old, no idea why.

Using init.d works number one.

Migrate to using build-essential.

What would you think about changing the package resources to use:
https://github.com/opscode-cookbooks/build-essential
https://github.com/cramerdev/tar-cookbook

The motivation would be to prevent the warnings on compilation:
[2013-07-25T14:14:08-04:00] WARN: Cloning resource attributes for package[make] from prior resource (CHEF-3694)
[2013-07-25T14:14:08-04:00] WARN: Previous package[make]: /tmp/chef-local20130725-29889-g6igcs/build-essential/recipes/fedora.rb:31:in `block in from_file'

Not able to restart redis on Ubuntu 10.04

I am using this cookbook with vagrant and a Ubuntu 10.04 installation. When booting the virtual machine and running chef, I cannot stop or restart redis using the init.d script because no pid file exists. redis is running, so starting it again also doesn't work. If I kill the process, starting redis with sudo and then stopping/restarting it works perfectly. It also works when I boot the machine without running chef (`--no-provision')

I don't know if the problem is with the cookbook or with vagrant and would really appreciate any help. If I can provide more information, please tell me what you need.

Upstart

I see you have a fork of someone's upstart addition. Do you plan to merge this in to master? I have been using his fork for a while now and it works perfectly fine on my end. Would like to use your master fork but cannot unless you merge in upstart.

Cheers,
Michael

Stopping the service fails if requirepass is set

/etc/init.d/redis calls redis-cli, which gets an error; it goes on and gets stuck in the infinite while loop.

Fixes:

  • pass the appropriate password, something like:

    $CLIEXEC -p $REDISPORT <%= @requirepass ? "-a #{@requirepass}" : "" %> shutdown

  • for bonus points, call set -e at the beginning of the script so that errors in redis-cli become fatal.

Logs

Hi Brian!

I had a corrupt AOF file today. But, prior to figuring that out, I was wondering where the logs were stored. Looking at the redis.conf file that's being generated all log entries are being sent to STDOUT but are never persisted to any physical file on the file system. I also don't see any options in the cookbook where I could specify a path for the log file. Also, the init script doesn't seem to redirect any STDOUT that comes from the process to any location.

Is this intentional? If not, any plans for adding a :log => "/path/to/redis/logs" option?

Cheers,
Michael

Redis won't start if .rdb is empty

Now that I touch the RDB and AOF files to make sure they are owned properly... if they are totally empty (got touched because this is the first run), Redis will actually refuse to start. This is annoying and a serious bug. Looking into fixing it now.

Add ability to determine master/slave IPs based on roles

I am considering adding the ability to set the master and slave addresses based on a node search for roles. I would add a node attribute named something like the following

redis_master
redis_slave

Then I would perform a search

search(:node, "chef_environment:#{node.chef_environment} AND roles:#{node['redisio']['redis_master}")

What I am considering the most is that there must be a way to enable and disable this. A straightforward way could be to set the "slaveof" field to the results of that search if the slaveof field is nil and the results from the search are not nil.

Redis on ubuntu 12.04 hangs on shutdown

I'm using this cookbook and everything works great, a part when I stop the redis server (manually through init or rebooting the system), it shows that it's "Waiting for Redis to shutdown..."

I'm using Ubuntu 12.04, this is the call in the init script:

$CLIEXEC -p 6379 -a 'aabbccdd' shutdown

I only set the requirepass attribute, all others are the cookbook's defaults

Add load_current_resource method

The current implementation to find out what version of redis is installed works but doesn't follow the convention of using load_current_resource and @current_resource.... and it should! Add that.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.