def expand_into(self, rg): loc_ref = self.id_attrs['location'] loc_path = loc_ref.id_attrs['path'] run_file_path = loc_path + '/run' contents = self.wanted_attrs['contents'] present = self.wanted_attrs['present'] status = self.wanted_attrs['status'] if not present and status != 'down': raise ValueError(present, status) down_file_present = present and status == 'down' down_file = rg.add_resource(resource('PlainFile', path=loc_path+'/down', mode='0644', present=down_file_present, ), depends=(loc_ref, )) run_file = rg.add_resource(resource('PlainFile', path=run_file_path, mode='0755', present=present, contents=contents, ), depends=(down_file, )) if present: # We have no guarantee there is a runsv for us, # be lax with exit codes. cmd = {'up': 'start', 'down': 'force-shutdown', }[status] set_state = rg.add_transition(transition('Command', cmdline=['/usr/bin/sv', cmd, loc_path], expected_retcodes=(0, 1, ), ), depends=(run_file, ))
def expand_into(self, rg): name = self.id_attrs['name'] present = self.wanted_attrs['present'] enabled = self.wanted_attrs['enabled'] hostname = self.wanted_attrs['hostname'] port = self.wanted_attrs['port'] rails_dir = self.wanted_attrs['rails_dir'] rails_pub_path = rails_dir.id_attrs['path'] + '/public' contents = build_and_render(''' DocumentRoot {{ rails_pub_path }} RailsBaseUri / ''', rails_pub_path=rails_pub_path, ).encode('utf8') fastthread = rg.add_resource(resource('RubyGem', name='fastthread', version='1.0.1')) worker_mpm = rg.add_resource(resource('AptitudePackage', name='apache2-mpm-worker')) rg.add_resource(resource('A2Site', name=name, present=present, enabled=enabled, hostname=hostname, port=port, contents=contents, ), depends=[fastthread, worker_mpm], )
def test_gitosis(pub_file, user_name='git', user_home='/var/git'): with open(pub_file) as f: pub_file_s = f.read() pkg = rg.add_resource(resource('AptitudePackage', name='gitosis')) usr = rg.add_resource(resource('User', name=user_name, home=user_home, shell='/bin/sh')) rg.add_transition(transition('Command', username=user_name, extra_env={'HOME': user_home, }, cmdline=['/usr/bin/gitosis-init', ], cmdline_input=pub_file_s, unless=[ '/usr/bin/test', '-f', user_home+'/.gitosis.conf'], ), depends=(pkg, usr), )
def expand_into(self, rg): # XXX key mngmt source_path = self.id_attrs['source'].id_attrs['path'] dest_url = self.id_attrs['dest'] pkg = rg.add_resource(resource('AptitudePackage', name='duplicity', )) cmd = rg.add_transition(transition('Command', cmdline=['/usr/bin/duplicity', source_path, dest_url ] ), depends=[pkg])
def expand_into(self, rg): name = self.id_attrs['name'] enabled = self.wanted_attrs['enabled'] apache2 = rg.add_to_top(resource('AptitudePackage', name='apache2.2-common', )) cmd = '/usr/sbin/a2%smod' % { True: 'en', False: 'dis', }[enabled] endis = rg.add_transition(transition('Command', cmdline=[cmd, name, ] ), depends=[apache2])
def expand_into(self, rg): owner = self.wanted_attrs['owner'] cluster = self.id_attrs['cluster'] if owner.id_attrs['cluster'].unref != cluster.unref: raise ValueError p0, p1 = self.read_attrs()['present'], self.wanted_attrs['present'] if (p0, p1) == (False, True): tr = rg.add_transition(self.create_db_trans(), (owner, cluster)) elif (p0, p1) == (True, True): tr = rg.add_transition(self.update_owner_trans(), (owner, cluster)) elif (p0, p1) == (True, False): tr = rg.add_transition(self.drop_db_trans(), (owner, cluster)) enable_backups = p1 and self.wanted_attrs['enable_backups'] # XXX This backup strategy can fill up disks. # Need to somehow ensure crontab can send mail. backupdir = rg.add_to_top(resource('Directory', path='/var/backups/postgresql', )) dbname = self.id_attrs['name'] template = u'''#!/bin/sh set -e [ -e /usr/bin/pg_dump ] || exit 0 exec /usr/bin/pg_dump -Fc \\ -f /var/backups/postgresql/{{ dbname }}-$(/bin/date --rfc-3339=date) \\ -- {{ dbname }} ''' code = build_and_render(template, dbname=dbname) # Name and mode are important for run-parts to consider the script. fname = '/etc/cron.daily/db-backup-' + dbname rg.add_resource(resource('PlainFile', present=enable_backups, path=fname, mode='0755', contents=code.encode('utf8'), ), depends=[backupdir], )
def expand_into(self, rg): svn_branch = self.wanted_attrs['svn_branch'] cluster = self.wanted_attrs['cluster'] hostname = self.wanted_attrs['hostname'] rails_name = 'redmine-%s' % self.id_attrs['name'] # Privileged (create tables, update checkout) maint_user_name = 'redmine-maint-%s' % self.id_attrs['name'] # Less privileged (run server, write temporary files) run_user_name = 'redmine-run-%s' % self.id_attrs['name'] run_user = rg.add_resource(resource('User', name=run_user_name)) maint_user = rg.add_resource(resource('User', name=maint_user_name)) loc = rg.add_resource(resource('Directory', path=self.id_attrs['path'], owner=maint_user_name, group='root', mode='0755', ), depends=(maint_user, )) co = rg.add_resource(resource('SvnWorkingCopy', location=loc, url=svn_branch, )) rewrite_mod = rg.add_resource(resource('A2Mod', name='rewrite')) loc_alias = rg.make_alias_ref(loc, depends=(co, )) rails = rg.add_resource(resource('Rails', name=rails_name, location=loc_alias, maint_user=maint_user, run_user=run_user, hostname=hostname, cluster=cluster, ))
def expand_into(self, rg): name = self.id_attrs['name'] present = self.wanted_attrs['present'] enabled = self.wanted_attrs['enabled'] hostname = self.wanted_attrs['hostname'] port = self.wanted_attrs['port'] contents = self.wanted_attrs['contents'] if not present and enabled: raise ValueError(present, enabled) fcontents = build_and_render(''' NameVirtualHost {{ hostname }}:{{ port }} <VirtualHost {{ hostname }}:{{ port }}> {{ contents }} </VirtualHost> ''', contents=contents, hostname=hostname, port=port).encode('utf8') apache2 = rg.add_to_top(resource('AptitudePackage', name='apache2.2-common', )) site_file = rg.add_resource(resource('PlainFile', path='/etc/apache2/sites-available/' + name, contents=fcontents, present=present, mode='0644', ), depends=[apache2]) cmd = '/usr/sbin/a2%ssite' % { True: 'en', False: 'dis', }[enabled] endis = rg.add_transition(transition('Command', cmdline=[cmd, name, ] ), depends=[site_file]) # We don't really need to reload everytime. reload = rg.add_transition(transition('Command', cmdline=['/usr/sbin/invoke-rc.d', 'apache2', 'reload', ], ), depends=[endis], )
def expand_into(self, rg): loc_ref = self.id_attrs['location'] present = self.wanted_attrs['present'] status = self.wanted_attrs['status'] target_dir_ref = self.wanted_attrs['target_dir'] target_path = target_dir_ref.id_attrs['path'] contents = build_and_render('''#!/bin/sh exec 2>&1 exec runsvdir {{ target_path }} ''', target_path=target_path).encode('utf8') rg.add_resource(resource('Service', location=loc_ref, present=present, status=status, contents=contents, ), depends=(target_dir_ref, ))
def expand_into(self, rg): name = self.id_attrs['name'] enabled = self.wanted_attrs['enabled'] apache2 = rg.add_to_top(resource('AptitudePackage', name='apache2.2-common', )) cmd = '/usr/sbin/a2%smod' % { True: 'en', False: 'dis', }[enabled] endis = rg.add_transition(transition('Command', cmdline=[cmd, name, ] ), depends=[apache2]) # We don't need to restart everytime, which takes some time. reload = rg.add_transition(transition('Command', cmdline=['/usr/sbin/invoke-rc.d', 'apache2', 'restart', ], ), depends=[endis], )
def expand_into(self, rg): loc_ref = self.id_attrs['location'] # An alternative to valid_condition if not loc_ref.wanted_attrs['present']: raise ValueError pkg_ref = rg.add_to_top(resource('AptitudePackage', name='subversion')) repo_url = self.wanted_attrs['url'] path = loc_ref.id_attrs['path'] owner = loc_ref.wanted_attrs['owner'] co = rg.add_transition(transition('Command', username=owner, cmdline=['/usr/bin/svn', 'checkout', '--non-interactive', '--force', '--', repo_url, path, ]), depends=(pkg_ref, loc_ref, )) up = rg.add_transition(transition('Command', username=owner, cmdline=['/usr/bin/svn', 'update', '--non-interactive', '--force', '--', path, ]), depends=(co, ))
def expand_into(self, rg): # Also: pg_createcluster, pg_deletecluster if not self.wanted_attrs['present']: return rg.add_resource(resource('AptitudePackage', name='postgresql'))
def expand_into(self, rg): loc = self.id_attrs['location'] loc_path = loc.id_attrs['path'] if not loc.wanted_attrs['present']: raise ValueError rails_gem = rg.add_resource(resource('RubyGem', name='rails', version='2.1.2')) rake_pkg = rg.add_resource(resource('AptitudePackage', name='rake')) ruby_pgsql_pkg = rg.add_resource(resource('AptitudePackage', name='libpgsql-ruby')) ssl_pkg = rg.add_resource(resource('AptitudePackage', name='libopenssl-ruby1.8')) pkgs = rg.add_checkpoint( depends=(rails_gem, rake_pkg, ruby_pgsql_pkg, ssl_pkg)) name = self.id_attrs['name'] hostname = self.wanted_attrs['hostname'] cluster = self.wanted_attrs['cluster'] run_user = self.wanted_attrs['run_user'] run_user_name = run_user.id_attrs['name'] # XXX Need to give an ACL from db_maint_user to db_run_user. maint_user = self.wanted_attrs['maint_user'] maint_user_name = maint_user.id_attrs['name'] # Same name means 'local ident sameuser' auth will work. db_run_user = rg.add_resource(resource('PgUser', name=run_user_name, cluster=cluster, )) db_maint_user = rg.add_resource(resource('PgUser', name=maint_user_name, cluster=cluster, )) sv_dir_loc = rg.add_resource(resource('Directory', path=loc_path+'/service', mode='0755', ), depends=(loc, )) sv_dir_serv_loc = rg.add_resource(resource('Directory', path='/etc/service/' + name, mode='0755', )) sv_dir_service = rg.add_resource(resource('DirService', location=sv_dir_serv_loc, target_dir=sv_dir_loc, )) db_conf_tree = {} migs = [] # XXX Leads to conflicts env_ports = {'production': 4334, 'test': 5434, 'development': 6534, } for env in ('production', 'test', 'development', ): db_name = 'rails-%s-%s' % (name, env, ) db_conf_tree[env] = { 'adapter': 'postgresql', 'database': db_name, 'username': maint_user_name, } db = rg.add_resource(resource('PgDatabase', name=db_name, owner=db_maint_user, cluster=cluster, )) # Testing for db:version retcode doesn't work anymore. mig = rg.add_transition(transition('Command', cmdline=['/usr/bin/rake', 'db:migrate'], username=maint_user_name, extra_env={ 'RAILS_ENV': env, }, cwd=loc_path, ), depends=(maint_user, loc, pkgs, db, )) migs.append(mig) sv_loc_path = loc_path + '/service/' + env sv_loc = rg.add_resource(resource('Directory', path=sv_loc_path, mode='0755', ), depends=(sv_dir_loc, )) sv_contents = build_and_render('''#!/bin/sh cd ../.. # Rails messages and backtraces are normally on stderr. exec 2>&1 exec chpst -u {{ maint_user_name }} ./script/server webrick --environment {{ env }} --binding {{ binding_ip }} --port {{ port }} ''', maint_user_name=maint_user_name, env=env, binding_ip='127.0.0.1', port=env_ports[env], ).encode('utf8') sv = rg.add_resource(resource('Service', location=sv_loc, contents=sv_contents, status='down', )) tmp_dirs = rg.add_transition(transition('Command', cmdline=['/usr/bin/rake', 'tmp:create'], username=maint_user_name, cwd=loc_path, ), depends=(maint_user, loc, pkgs, )) db_conf_str = yaml.safe_dump(db_conf_tree, default_flow_style=False) db_conf_file = rg.add_resource(resource('PlainFile', path=loc_path + '/config/database.yml', contents=db_conf_str, mode='0644', ), depends=(loc, )) for mig in migs: rg.add_dependency(db_conf_file, mig) passenger_site = rg.add_resource(resource('PassengerSite', name=name, hostname=hostname, rails_dir=loc, ))
def expand(rg): cluster = rg.add_resource(resource('PgCluster')) rails_sites = rg.add_resource(resource('Directory', path='/var/lib/rails-sites', mode='0755')) redmine = rg.add_resource(resource('Redmine', name='main', path='/var/lib/rails-sites/redmine', hostname='volutes.localdomain', cluster=cluster, ), depends=[rails_sites], ) # Lambdas won't do well in YAML if False: rg.add_transition(transition('PythonCode', function=lambda: sys.stderr.write('Fariboles!\n'))) cmd_tr = rg.add_transition(transition('Command', cmdline=['/bin/echo', 'Chatty command is chatty'])) LOGGER.debug(yaml.dump(cmd_tr)) LOGGER.debug(yaml.dump(yaml.load(yaml.dump(cluster)))) text = build_and_render('Hello {{ name }}!\n', name='Jane Doe') rg.add_resource(resource('PlainFile', path='/tmp/testfile', mode='0644', contents=text.encode('utf8'))) rg.add_resource(resource('AptitudePackage', name='python-networkx')) rg.add_resource(resource('User', name='zorglub', present=False, shell='/bin/true')) u = rg.add_resource(resource('PgUser', name='user-pfuuit', cluster=cluster)) d = rg.add_resource(resource('PgDatabase', owner=u, name='db-pfuuit', cluster=cluster)) dj_dir = rg.add_resource(resource('Directory', path='/tmp/django-queue-service', mode='0755', owner='nobody', group='nogroup')) svn_wc = rg.add_resource(resource('SvnWorkingCopy', location=dj_dir, url='http://django-queue-service.googlecode.com/svn/trunk/')) LOGGER.debug(yaml.dump(svn_wc)) def test_gitosis(pub_file, user_name='git', user_home='/var/git'): with open(pub_file) as f: pub_file_s = f.read() pkg = rg.add_resource(resource('AptitudePackage', name='gitosis')) usr = rg.add_resource(resource('User', name=user_name, home=user_home, shell='/bin/sh')) rg.add_transition(transition('Command', username=user_name, extra_env={'HOME': user_home, }, cmdline=['/usr/bin/gitosis-init', ], cmdline_input=pub_file_s, unless=[ '/usr/bin/test', '-f', user_home+'/.gitosis.conf'], ), depends=(pkg, usr), ) test_gitosis('g2p-moulinex.pub')
def expand_predepends_into(self, rg): # XXX Make context use this. gems = rg.add_resource(resource('AptitudePackage', 'rubygems'))