summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDominic Cleal <dcleal@redhat.com>2010-11-27 13:36:04 +0000
committerDominic Cleal <dcleal@redhat.com>2010-11-27 13:36:04 +0000
commitafe2d014feb2210a8666c93465d11e9c9d555f8b (patch)
tree208f5ac82b2c29610d2021821c8fca9b079e638b
parent143fc744a839affd328234fca26246d49d15d3d8 (diff)
parent4b35402ba85d8842d757becec5c8a7bf4d6f6654 (diff)
downloadpuppet-afe2d014feb2210a8666c93465d11e9c9d555f8b.tar.gz
puppet-afe2d014feb2210a8666c93465d11e9c9d555f8b.tar.xz
puppet-afe2d014feb2210a8666c93465d11e9c9d555f8b.zip
Merge branch 'master' of github.com:domcleal/puppet into master-old
-rw-r--r--CHANGELOG430
-rw-r--r--LICENSE4
-rw-r--r--Rakefile2
-rw-r--r--conf/redhat/puppet.spec10
-rwxr-xr-xconf/solaris/smf/svc-puppetd2
-rwxr-xr-xconf/solaris/smf/svc-puppetmasterd2
-rw-r--r--conf/suse/client.init8
-rw-r--r--conf/suse/fileserver.conf12
-rw-r--r--conf/suse/logrotate10
-rw-r--r--conf/suse/puppet.conf25
-rw-r--r--conf/suse/puppet.spec174
-rw-r--r--conf/suse/puppet.suse.patch16
-rw-r--r--conf/suse/server.init8
-rwxr-xr-xext/cert_inspector140
-rwxr-xr-xext/envpuppet80
-rw-r--r--ext/extlookup.rb181
-rw-r--r--ext/logcheck/puppet46
-rw-r--r--ext/puppet-load.rb393
-rwxr-xr-xext/puppetlast16
-rw-r--r--ext/puppetstoredconfigclean.rb8
-rw-r--r--ext/rack/files/config.ru8
-rw-r--r--ext/vim/syntax/puppet.vim11
-rwxr-xr-xinstall.rb43
-rw-r--r--lib/puppet.rb2
-rw-r--r--lib/puppet/agent.rb4
-rw-r--r--lib/puppet/application.rb41
-rw-r--r--lib/puppet/application/agent.rb6
-rw-r--r--lib/puppet/application/apply.rb23
-rw-r--r--lib/puppet/application/describe.rb2
-rw-r--r--lib/puppet/application/doc.rb38
-rw-r--r--lib/puppet/application/master.rb3
-rw-r--r--lib/puppet/application/queue.rb1
-rw-r--r--lib/puppet/configurer.rb27
-rwxr-xr-xlib/puppet/daemon.rb6
-rw-r--r--lib/puppet/defaults.rb130
-rw-r--r--lib/puppet/dsl.rb4
-rw-r--r--lib/puppet/dsl/resource_type_api.rb48
-rw-r--r--lib/puppet/external/event-loop/event-loop.rb26
-rw-r--r--lib/puppet/external/pson/pure/generator.rb30
-rw-r--r--lib/puppet/feature/base.rb3
-rw-r--r--lib/puppet/feature/rails.rb4
-rw-r--r--lib/puppet/file_serving/indirection_hooks.rb4
-rw-r--r--lib/puppet/indirector/catalog/compiler.rb13
-rw-r--r--lib/puppet/indirector/facts/memory.rb2
-rw-r--r--lib/puppet/indirector/facts/rest.rb2
-rw-r--r--lib/puppet/indirector/indirection.rb1
-rw-r--r--lib/puppet/indirector/inventory/yaml.rb81
-rw-r--r--lib/puppet/indirector/node/exec.rb2
-rw-r--r--lib/puppet/indirector/node/ldap.rb62
-rw-r--r--lib/puppet/indirector/node/memory.rb2
-rw-r--r--lib/puppet/indirector/report/yaml.rb11
-rw-r--r--lib/puppet/indirector/yaml.rb15
-rw-r--r--lib/puppet/network/format_handler.rb6
-rw-r--r--lib/puppet/network/formats.rb8
-rwxr-xr-xlib/puppet/network/handler/fileserver.rb4
-rw-r--r--lib/puppet/network/http/api/v1.rb5
-rw-r--r--lib/puppet/network/http/handler.rb46
-rw-r--r--lib/puppet/network/http/rack.rb3
-rw-r--r--lib/puppet/network/http/rack/rest.rb2
-rw-r--r--lib/puppet/network/http/webrick/rest.rb1
-rw-r--r--lib/puppet/network/http_pool.rb12
-rw-r--r--lib/puppet/network/rest_authconfig.rb31
-rw-r--r--lib/puppet/network/rest_authorization.rb4
-rw-r--r--lib/puppet/network/server.rb4
-rw-r--r--lib/puppet/node.rb1
-rw-r--r--lib/puppet/node/environment.rb50
-rwxr-xr-xlib/puppet/node/facts.rb37
-rw-r--r--lib/puppet/node/inventory.rb7
-rw-r--r--lib/puppet/parameter/value_collection.rb6
-rw-r--r--lib/puppet/parser/ast.rb8
-rw-r--r--lib/puppet/parser/ast/astarray.rb35
-rw-r--r--lib/puppet/parser/ast/caseopt.rb36
-rw-r--r--lib/puppet/parser/ast/collection.rb85
-rw-r--r--lib/puppet/parser/ast/definition.rb17
-rw-r--r--lib/puppet/parser/ast/function.rb3
-rw-r--r--lib/puppet/parser/ast/hostclass.rb29
-rw-r--r--lib/puppet/parser/ast/leaf.rb14
-rw-r--r--lib/puppet/parser/ast/node.rb20
-rw-r--r--lib/puppet/parser/ast/resource.rb92
-rw-r--r--lib/puppet/parser/ast/resource_instance.rb9
-rw-r--r--lib/puppet/parser/ast/resource_override.rb5
-rw-r--r--lib/puppet/parser/ast/resource_reference.rb11
-rw-r--r--lib/puppet/parser/ast/top_level_construct.rb4
-rw-r--r--lib/puppet/parser/compiler.rb30
-rw-r--r--lib/puppet/parser/files.rb2
-rw-r--r--lib/puppet/parser/functions.rb10
-rw-r--r--lib/puppet/parser/functions/defined.rb2
-rw-r--r--lib/puppet/parser/functions/extlookup.rb157
-rw-r--r--lib/puppet/parser/functions/file.rb2
-rw-r--r--lib/puppet/parser/functions/inline_template.rb11
-rw-r--r--lib/puppet/parser/functions/md5.rb5
-rw-r--r--lib/puppet/parser/functions/realize.rb2
-rw-r--r--lib/puppet/parser/functions/regsubst.rb38
-rw-r--r--lib/puppet/parser/functions/require.rb5
-rw-r--r--lib/puppet/parser/functions/split.rb2
-rw-r--r--lib/puppet/parser/functions/sprintf.rb2
-rw-r--r--lib/puppet/parser/functions/template.rb6
-rw-r--r--lib/puppet/parser/functions/versioncmp.rb24
-rw-r--r--lib/puppet/parser/grammar.ra205
-rw-r--r--lib/puppet/parser/lexer.rb32
-rw-r--r--lib/puppet/parser/parser.rb2775
-rw-r--r--lib/puppet/parser/parser_support.rb131
-rw-r--r--lib/puppet/parser/resource.rb17
-rw-r--r--lib/puppet/parser/resource/param.rb2
-rw-r--r--lib/puppet/parser/scope.rb35
-rw-r--r--lib/puppet/parser/templatewrapper.rb1
-rw-r--r--lib/puppet/parser/type_loader.rb159
-rw-r--r--lib/puppet/property.rb10
-rw-r--r--lib/puppet/provider.rb10
-rw-r--r--lib/puppet/provider/confine/exists.rb5
-rw-r--r--lib/puppet/provider/group/groupadd.rb2
-rw-r--r--lib/puppet/provider/group/ldap.rb6
-rw-r--r--lib/puppet/provider/group/pw.rb2
-rw-r--r--lib/puppet/provider/host/parsed.rb76
-rwxr-xr-xlib/puppet/provider/maillist/mailman.rb11
-rw-r--r--lib/puppet/provider/mcx/mcxcontent.rb134
-rw-r--r--lib/puppet/provider/mount.rb2
-rw-r--r--lib/puppet/provider/nameservice.rb3
-rw-r--r--lib/puppet/provider/nameservice/directoryservice.rb34
-rw-r--r--lib/puppet/provider/nameservice/objectadd.rb3
-rwxr-xr-xlib/puppet/provider/package/apple.rb2
-rwxr-xr-xlib/puppet/provider/package/apt.rb6
-rwxr-xr-xlib/puppet/provider/package/aptitude.rb2
-rw-r--r--lib/puppet/provider/package/aptrpm.rb2
-rwxr-xr-xlib/puppet/provider/package/blastwave.rb2
-rwxr-xr-xlib/puppet/provider/package/dpkg.rb4
-rwxr-xr-xlib/puppet/provider/package/fink.rb2
-rwxr-xr-xlib/puppet/provider/package/gem.rb2
-rwxr-xr-xlib/puppet/provider/package/openbsd.rb18
-rwxr-xr-xlib/puppet/provider/package/rpm.rb2
-rw-r--r--lib/puppet/provider/package/rug.rb2
-rwxr-xr-xlib/puppet/provider/package/sunfreeware.rb4
-rw-r--r--lib/puppet/provider/package/up2date.rb2
-rw-r--r--lib/puppet/provider/package/urpmi.rb2
-rwxr-xr-xlib/puppet/provider/package/yum.rb11
-rw-r--r--lib/puppet/provider/package/zypper.rb2
-rwxr-xr-xlib/puppet/provider/service/base.rb2
-rw-r--r--lib/puppet/provider/service/bsd.rb4
-rwxr-xr-xlib/puppet/provider/service/debian.rb4
-rw-r--r--lib/puppet/provider/service/freebsd.rb7
-rw-r--r--lib/puppet/provider/service/gentoo.rb4
-rwxr-xr-xlib/puppet/provider/service/init.rb4
-rw-r--r--lib/puppet/provider/service/launchd.rb25
-rwxr-xr-xlib/puppet/provider/service/redhat.rb4
-rwxr-xr-xlib/puppet/provider/service/upstart.rb73
-rw-r--r--lib/puppet/provider/ssh_authorized_key/parsed.rb7
-rw-r--r--lib/puppet/provider/user/hpux.rb1
-rw-r--r--lib/puppet/provider/user/ldap.rb6
-rw-r--r--lib/puppet/provider/user/pw.rb2
-rw-r--r--lib/puppet/provider/user/user_role_add.rb34
-rw-r--r--lib/puppet/provider/user/useradd.rb48
-rw-r--r--lib/puppet/rails.rb14
-rw-r--r--lib/puppet/rails/host.rb72
-rw-r--r--lib/puppet/reference/configuration.rb90
-rw-r--r--lib/puppet/reference/indirection.rb9
-rw-r--r--lib/puppet/reference/metaparameter.rb27
-rw-r--r--lib/puppet/reference/network.rb8
-rw-r--r--lib/puppet/reference/providers.rb8
-rw-r--r--lib/puppet/reference/report.rb11
-rw-r--r--lib/puppet/reference/type.rb28
-rw-r--r--lib/puppet/reports/http.rb2
-rw-r--r--lib/puppet/reports/rrdgraph.rb19
-rw-r--r--lib/puppet/reports/store.rb4
-rw-r--r--lib/puppet/reports/tagmail.rb27
-rw-r--r--lib/puppet/resource.rb152
-rw-r--r--lib/puppet/resource/catalog.rb2
-rw-r--r--lib/puppet/resource/type.rb66
-rw-r--r--lib/puppet/resource/type_collection.rb115
-rw-r--r--lib/puppet/simple_graph.rb426
-rw-r--r--lib/puppet/ssl/certificate_request.rb2
-rw-r--r--lib/puppet/sslcertificates/ca.rb14
-rw-r--r--lib/puppet/transaction/report.rb39
-rw-r--r--lib/puppet/transaction/resource_harness.rb2
-rw-r--r--lib/puppet/type.rb198
-rw-r--r--lib/puppet/type/augeas.rb89
-rw-r--r--lib/puppet/type/computer.rb4
-rwxr-xr-xlib/puppet/type/cron.rb60
-rwxr-xr-xlib/puppet/type/exec.rb141
-rw-r--r--lib/puppet/type/file.rb50
-rwxr-xr-xlib/puppet/type/file/content.rb8
-rwxr-xr-xlib/puppet/type/file/ensure.rb26
-rwxr-xr-xlib/puppet/type/file/mode.rb12
-rw-r--r--lib/puppet/type/file/selcontext.rb10
-rwxr-xr-xlib/puppet/type/file/source.rb62
-rwxr-xr-xlib/puppet/type/filebucket.rb11
-rwxr-xr-xlib/puppet/type/group.rb3
-rwxr-xr-xlib/puppet/type/host.rb37
-rw-r--r--lib/puppet/type/k5login.rb6
-rw-r--r--lib/puppet/type/macauthorization.rb3
-rwxr-xr-xlib/puppet/type/mailalias.rb1
-rwxr-xr-xlib/puppet/type/maillist.rb1
-rw-r--r--lib/puppet/type/mcx.rb18
-rwxr-xr-xlib/puppet/type/mount.rb21
-rw-r--r--lib/puppet/type/notify.rb1
-rw-r--r--lib/puppet/type/package.rb70
-rw-r--r--lib/puppet/type/resources.rb6
-rwxr-xr-xlib/puppet/type/schedule.rb31
-rw-r--r--lib/puppet/type/selboolean.rb9
-rw-r--r--lib/puppet/type/selmodule.rb7
-rw-r--r--lib/puppet/type/service.rb20
-rw-r--r--lib/puppet/type/ssh_authorized_key.rb5
-rwxr-xr-xlib/puppet/type/sshkey.rb11
-rw-r--r--lib/puppet/type/stage.rb9
-rwxr-xr-xlib/puppet/type/tidy.rb17
-rwxr-xr-xlib/puppet/type/user.rb58
-rw-r--r--lib/puppet/type/whit.rb11
-rw-r--r--lib/puppet/type/yumrepo.rb19
-rwxr-xr-xlib/puppet/type/zfs.rb3
-rw-r--r--lib/puppet/type/zone.rb56
-rwxr-xr-xlib/puppet/type/zpool.rb15
-rw-r--r--lib/puppet/util.rb46
-rw-r--r--lib/puppet/util/autoload.rb22
-rw-r--r--lib/puppet/util/cacher.rb25
-rw-r--r--lib/puppet/util/command_line.rb2
-rwxr-xr-xlib/puppet/util/command_line/puppetdoc10
-rwxr-xr-xlib/puppet/util/command_line/puppetrun2
-rwxr-xr-xlib/puppet/util/command_line/ralsh26
-rw-r--r--lib/puppet/util/docs.rb17
-rw-r--r--lib/puppet/util/file_locking.rb9
-rw-r--r--lib/puppet/util/log.rb1
-rw-r--r--lib/puppet/util/log/destinations.rb14
-rw-r--r--lib/puppet/util/metric.rb57
-rw-r--r--lib/puppet/util/monkey_patches.rb30
-rw-r--r--lib/puppet/util/nagios_maker.rb9
-rw-r--r--lib/puppet/util/provider_features.rb4
-rw-r--r--lib/puppet/util/rdoc.rb11
-rw-r--r--lib/puppet/util/rdoc/generators/puppet_generator.rb6
-rw-r--r--lib/puppet/util/rdoc/parser.rb56
-rw-r--r--lib/puppet/util/reference.rb66
-rw-r--r--lib/puppet/util/suidmanager.rb2
-rw-r--r--lib/puppet/util/zaml.rb29
-rw-r--r--man/man5/puppet.conf.53582
-rw-r--r--man/man8/filebucket.8210
-rw-r--r--man/man8/pi.861
-rw-r--r--man/man8/puppet.817
-rw-r--r--man/man8/puppetca.8297
-rw-r--r--man/man8/puppetd.8508
-rw-r--r--man/man8/puppetdoc.8206
-rw-r--r--man/man8/puppetmasterd.8122
-rw-r--r--man/man8/puppetqd.871
-rw-r--r--man/man8/puppetrun.8306
-rw-r--r--man/man8/ralsh.8191
-rw-r--r--spec/fixtures/yaml/report0.25.x.yaml64
-rw-r--r--spec/fixtures/yaml/report2.6.x.yaml190
-rw-r--r--spec/integration/application/doc_spec.rb55
-rwxr-xr-xspec/integration/configurer_spec.rb43
-rwxr-xr-xspec/integration/defaults_spec.rb3
-rw-r--r--spec/integration/indirector/bucket_file/rest_spec.rb68
-rwxr-xr-xspec/integration/indirector/certificate/rest_spec.rb68
-rwxr-xr-xspec/integration/indirector/certificate_request/rest_spec.rb88
-rwxr-xr-xspec/integration/indirector/certificate_revocation_list/rest_spec.rb76
-rw-r--r--spec/integration/indirector/report/rest_spec.rb96
-rwxr-xr-xspec/integration/indirector/rest_spec.rb524
-rwxr-xr-xspec/integration/network/server/webrick_spec.rb1
-rwxr-xr-xspec/integration/parser/collector_spec.rb2
-rwxr-xr-xspec/integration/parser/compiler_spec.rb105
-rw-r--r--spec/integration/parser/functions_spec.rb21
-rwxr-xr-xspec/integration/parser/parser_spec.rb8
-rw-r--r--spec/integration/parser/ruby_manifest_spec.rb128
-rwxr-xr-xspec/integration/provider/mailalias/aliases_spec.rb10
-rwxr-xr-xspec/integration/ssl/certificate_authority_spec.rb5
-rwxr-xr-xspec/integration/ssl/certificate_request_spec.rb1
-rwxr-xr-xspec/integration/ssl/certificate_revocation_list_spec.rb1
-rwxr-xr-xspec/integration/ssl/host_spec.rb1
-rwxr-xr-xspec/integration/util/file_locking_spec.rb42
-rw-r--r--spec/lib/puppet_spec/files.rb1
-rw-r--r--spec/monkey_patches/add_confine_and_runnable_to_rspec_dsl.rb1
-rw-r--r--spec/monkey_patches/publicize_methods.rb11
-rw-r--r--spec/shared_behaviours/file_serving.rb13
-rw-r--r--spec/spec_helper.rb34
-rwxr-xr-xspec/unit/application/agent_spec.rb48
-rwxr-xr-xspec/unit/application/apply_spec.rb66
-rwxr-xr-xspec/unit/application/cert_spec.rb2
-rwxr-xr-xspec/unit/application/doc_spec.rb19
-rw-r--r--spec/unit/application/filebucket_spec.rb1
-rw-r--r--spec/unit/application/master_spec.rb11
-rwxr-xr-xspec/unit/application/queue_spec.rb1
-rwxr-xr-xspec/unit/application_spec.rb53
-rwxr-xr-xspec/unit/configurer_spec.rb79
-rwxr-xr-xspec/unit/daemon_spec.rb12
-rwxr-xr-xspec/unit/dsl/resource_type_api_spec.rb48
-rwxr-xr-xspec/unit/indirector/active_record_spec.rb1
-rwxr-xr-xspec/unit/indirector/catalog/compiler_spec.rb28
-rwxr-xr-xspec/unit/indirector/facts/active_record_spec.rb1
-rwxr-xr-xspec/unit/indirector/facts/yaml_spec.rb4
-rw-r--r--spec/unit/indirector/inventory/yaml_spec.rb221
-rwxr-xr-xspec/unit/indirector/node/active_record_spec.rb1
-rwxr-xr-xspec/unit/indirector/node/ldap_spec.rb40
-rw-r--r--spec/unit/indirector/report/yaml_spec.rb38
-rwxr-xr-xspec/unit/indirector/yaml_spec.rb24
-rw-r--r--spec/unit/network/handler/fileserver_spec.rb6
-rw-r--r--spec/unit/network/http/api/v1_spec.rb33
-rwxr-xr-xspec/unit/network/http/handler_spec.rb127
-rwxr-xr-xspec/unit/network/http/rack/rest_spec.rb6
-rwxr-xr-xspec/unit/network/http/rack/xmlrpc_spec.rb1
-rwxr-xr-xspec/unit/network/http/rack_spec.rb1
-rwxr-xr-xspec/unit/network/http/webrick/rest_spec.rb1
-rwxr-xr-xspec/unit/network/http/webrick_spec.rb1
-rwxr-xr-xspec/unit/network/rest_authconfig_spec.rb11
-rwxr-xr-xspec/unit/network/rest_authorization_spec.rb43
-rwxr-xr-xspec/unit/network/server_spec.rb13
-rwxr-xr-xspec/unit/network/xmlrpc/client_spec.rb1
-rwxr-xr-xspec/unit/node/environment_spec.rb92
-rwxr-xr-xspec/unit/node/facts_spec.rb39
-rwxr-xr-xspec/unit/parameter/value_collection_spec.rb4
-rwxr-xr-xspec/unit/parser/ast/astarray_spec.rb49
-rwxr-xr-xspec/unit/parser/ast/collection_spec.rb4
-rw-r--r--spec/unit/parser/ast/definition_spec.rb22
-rw-r--r--spec/unit/parser/ast/function_spec.rb18
-rw-r--r--spec/unit/parser/ast/hostclass_spec.rb73
-rwxr-xr-xspec/unit/parser/ast/leaf_spec.rb46
-rw-r--r--spec/unit/parser/ast/node_spec.rb31
-rwxr-xr-xspec/unit/parser/ast/resource_reference_spec.rb5
-rwxr-xr-xspec/unit/parser/ast/resource_spec.rb226
-rwxr-xr-xspec/unit/parser/collector_spec.rb1
-rwxr-xr-xspec/unit/parser/compiler_spec.rb29
-rw-r--r--spec/unit/parser/files_spec.rb6
-rwxr-xr-xspec/unit/parser/functions/extlookup_spec.rb95
-rw-r--r--spec/unit/parser/functions/include_spec.rb33
-rwxr-xr-xspec/unit/parser/functions/require_spec.rb2
-rwxr-xr-xspec/unit/parser/functions/tag_spec.rb1
-rwxr-xr-xspec/unit/parser/lexer_spec.rb20
-rwxr-xr-xspec/unit/parser/parser_spec.rb145
-rwxr-xr-xspec/unit/parser/resource_spec.rb12
-rwxr-xr-xspec/unit/parser/scope_spec.rb3
-rwxr-xr-xspec/unit/parser/templatewrapper_spec.rb1
-rw-r--r--spec/unit/parser/type_loader_spec.rb113
-rwxr-xr-xspec/unit/provider/confine/exists_spec.rb19
-rw-r--r--spec/unit/provider/host/parsed_spec.rb196
-rwxr-xr-xspec/unit/provider/mount_spec.rb9
-rw-r--r--spec/unit/provider/package/yum_spec.rb67
-rw-r--r--spec/unit/provider/service/freebsd_spec.rb50
-rwxr-xr-xspec/unit/provider/service/launchd_spec.rb13
-rw-r--r--spec/unit/provider/service/upstart.rb49
-rwxr-xr-xspec/unit/provider/ssh_authorized_key/parsed_spec.rb7
-rw-r--r--spec/unit/provider/user/user_role_add_spec.rb19
-rwxr-xr-xspec/unit/provider/user/useradd_spec.rb61
-rwxr-xr-xspec/unit/rails/param_value_spec.rb1
-rwxr-xr-xspec/unit/rails/resource_spec.rb3
-rwxr-xr-xspec/unit/rails_spec.rb118
-rw-r--r--spec/unit/reports/rrdgraph_spec.rb31
-rwxr-xr-xspec/unit/reports/tagmail_spec.rb5
-rwxr-xr-xspec/unit/resource/catalog_spec.rb8
-rw-r--r--spec/unit/resource/type_collection_spec.rb157
-rwxr-xr-xspec/unit/resource/type_spec.rb51
-rwxr-xr-xspec/unit/resource_spec.rb36
-rwxr-xr-xspec/unit/simple_graph_spec.rb262
-rw-r--r--spec/unit/sslcertificates/ca_spec.rb110
-rwxr-xr-xspec/unit/transaction/report_spec.rb15
-rwxr-xr-xspec/unit/transaction/resource_harness_spec.rb2
-rwxr-xr-xspec/unit/type/file/content_spec.rb3
-rwxr-xr-xspec/unit/type/host_spec.rb83
-rwxr-xr-xspec/unit/type/mount_spec.rb32
-rwxr-xr-xspec/unit/type/schedule_spec.rb72
-rwxr-xr-xspec/unit/type/service_spec.rb12
-rwxr-xr-xspec/unit/type/tidy_spec.rb3
-rwxr-xr-xspec/unit/type/user_spec.rb25
-rw-r--r--spec/unit/type/whit_spec.rb11
-rwxr-xr-xspec/unit/type_spec.rb7
-rwxr-xr-xspec/unit/util/backups_spec.rb1
-rw-r--r--spec/unit/util/command_line_spec.rb4
-rwxr-xr-xspec/unit/util/file_locking_spec.rb52
-rwxr-xr-xspec/unit/util/json_spec.rb21
-rwxr-xr-xspec/unit/util/log_spec.rb4
-rw-r--r--spec/unit/util/monkey_patches_spec.rb26
-rwxr-xr-xspec/unit/util/pson_spec.rb53
-rwxr-xr-xspec/unit/util/rdoc/parser_spec.rb54
-rwxr-xr-xspec/unit/util/rdoc_spec.rb23
-rwxr-xr-xspec/unit/util/storage_spec.rb5
-rwxr-xr-x[-rw-r--r--]spec/unit/util/zaml_spec.rb29
-rw-r--r--tasks/rake/git_workflow.rake13
-rw-r--r--tasks/rake/tracdocs.rake8
-rwxr-xr-xtest/certmgr/ca.rb87
-rwxr-xr-xtest/certmgr/support.rb3
-rw-r--r--test/data/providers/host/parsed/valid_hosts19
-rwxr-xr-xtest/language/functions.rb2
-rwxr-xr-xtest/language/parser.rb93
-rwxr-xr-xtest/language/scope.rb6
-rw-r--r--test/lib/mocha_standalone.rb2
-rwxr-xr-xtest/lib/puppettest.rb30
-rw-r--r--test/lib/puppettest/fakes.rb2
-rw-r--r--test/lib/puppettest/parsertesting.rb13
-rw-r--r--test/lib/puppettest/support/assertions.rb2
-rw-r--r--test/lib/puppettest/support/utils.rb45
-rwxr-xr-xtest/other/provider.rb13
-rwxr-xr-xtest/other/report.rb7
-rwxr-xr-xtest/puppet/tc_suidmanager.rb19
-rwxr-xr-xtest/rails/railsparameter.rb2
-rwxr-xr-xtest/ral/manager/attributes.rb5
-rwxr-xr-xtest/ral/manager/type.rb2
-rwxr-xr-xtest/ral/providers/cron/crontab.rb5
-rwxr-xr-xtest/ral/providers/host/parsed.rb9
-rwxr-xr-xtest/ral/providers/provider.rb6
-rwxr-xr-xtest/util/metrics.rb4
394 files changed, 11982 insertions, 9217 deletions
diff --git a/CHANGELOG b/CHANGELOG
index 53124a13b..78483351c 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -1,5 +1,240 @@
+2.6.3
+=====
+184733c [#5322] (#5322) Remove spec file that adds little value and causes failures
+178c2a6 Fix test failures that fixing #4726 exposed.
+74b6c09 (#4726) Fix RRD legacy support
+8662056 Fix for #4279 -- mount detection on HP-UX
+fbb096a Fix for #5055 -- adding to_sym to Puppet::Node::Environment
+b2ff6a5 Fix for #5298 -- Collections need to do type lookup
+1ce00dc Step towards [5298] -- cleanup indentation, etc. in AST::Collection
+722608b Fixed #5287 - Schedule documentation is incorrect
+c8b6fb5 Fixed #5296 - test warnings messages
+d221c05 (#5297) Fix schedule tests that were missing stubs for Time.now
+f2fd0d1 Fix for #5273 -- user resource constantly resetting password age
+544dcf8 Fix #5289 -- Bad copy/paste changes message on test failure
+
+2.6.3rc3
+========
+126681f Updated CHANGELOG for 2.6.3rc3
+b15231d Fix for #4299 -- Don't require which
+ea435a4 Fix #5020 - Prefer finding node name from REST uri over certname
+a097b93 Fix for #4894 -- retry tests if port is in use
+ee61b4e Fix for #4955 -- Race condition & memory leak in Puppet::Util
+f57425d Fix #4921 - race condition in Parser Functions creation
+9604f1c Fix #5252 - line number mis-attribution during parsing
+cc5224c Maint. fix for test broken by 00eedac5
+5f7d0fb Fix for #2568 -- Add a dbconnections option to set AR pool size
+ba4d22b Maint. Removing code for which no CLA has been signed
+4a3d5d7 Reimplementation of functionality removed by prior commit
+235d641 Refactor for CLA
+9ba0c8a Fix #4923 - close process race when truncating existing file
+cb16d3d Puppet-load: better and safer error reporting
+1d26742 Fix #5023 - puppet-load multiple nodes support
+00eedac capture stderr from exec resources
+4cbceab (#4573) FreeBSD service provider now supports versions <7 and >8
+06c8748 Fix #3808 - puppetdoc should use --force-update only if RDoc supports it
+6e6712b [#4813] Remove dead code from puppet/rails/host.rb
+956296a Fix #4911 - Do not generate doc for standard RDoc parser generated object
+4fa24bb Fix #5127 - error when accessing array elements
+abb8c66 (#5242) Fix schedule specs that fail near daylight savings
+ec667fd Kludge for #5206 -- port of fix for #3536 to yaml
+9a3b584 (#5062) Add envpuppet helper script to ext/
+aad7008 [#5225] Fix spec failure that depended on time change
+21db472 (#5233) Randomize tmp dir paths
+
+2.6.3rc2
+========
+244213c Updated CHANGELOG for 2.6.3rc2
+76ac1f8 Fixed #5112 - Launchd Service broke in 2.6.2 with OS X 10.4 Clients.
+776ea2a Fixed #5137 - Removed no longer required TOC references
+31118fe Kludge for #5048 -- serialization compatibility with 0.25.x
+65ef24e (#4534/#4778) -- Normalize parameterized classes
+3b53bfc Fix for #5022 -- Escaped newlines should be elided
+
+2.6.3rc1
+========
+e3fc5b9 Updated CHANGELOG and version for 2.6.3rc1
+3c56705 Fix for #4832 -- Making PSON handle arbitrary binary data
+e232770 Minimal fix for #4975 -- only call chage when managing password age rules
+a090e86 Fix for #4963 -- Use correct commands for password expiry on solaris
+
+2.6.2
+=====
+295c3be Updated CHANGELOG for 2.6.2
+1d719be Fix for #4945 -- explicitly check os to supress man page installation
+55417bc Reversion of 021d534482dd8edb863cb77d668ac3525362a0a6
+a6e2bea Fixed #4919 - added parenths to fix error message:
+
+2.6.2rc1
+========
+917c520 Incremented version to 2.6.2
+900eae4 Updated CHANGELOG for 2.6.2rc1
+1b6094d Fixed documentation typo
+bdf12fe Fix for #4896 -- stray newline left over from removed diagnostic
+e7424c6 (#4772) Update SuSE .spec file
+0aaa742 Fixes #4792 (Duplicate definition since 2.6.1 upgrade)
+ea49d13 Improvement to #4025: made spec tests work on all platforms
+0b4ce08 Adds #3046 - support for password min/max age
+e9f9d26 [#4783] (#4783) Fix RRDGraph report generation
+34f87cf Add user account expiry to the useradd type and provider
+a7fb9b1 Fixed #4025 (failure in launchd if certain plists are binary).
+2573872 Fix for #4649 -- avoid unsupported features on non-posix systems
+eb9279c Fix for 4273 -- revert b7e2580ab49ecdb67fc9b522829c005fc3750fbe
+53a2bea Fix for #4804 -- escaped backslashes in interpolated strings
+d12e477 Fixes #4863 (Missing "require 'webrick'" causes nondeterministic spec failures)
+574812e (#4860) Add regression tests that would have caught bad params method
+68947e7 (#4860) Fix wrong method name.. params seems to be renamed to parameters
+021359b Fix for #4644: install.rb works properly on Windows
+d057b90 Fix #4726 Update puppet rrdtool metric code to support modern rrd ruby bindings
+66cf3a9 Fix #4226 - Prepend 'Puppet CA: ' to fqdn for default root ca_name
+d54352a Port Puppet::SSLCertificates::CA test to rspec
+effc6b8 Fixes #4852 - error messages involving Whits now mention Classes instead
+3f99bd7 Fix #4267 - Create a backup before dropping permissions
+6468f4e (#4763) Don't call a method that was removed in Rails 3 activerecord
+79d5fde Fixed #4763 - Hardcoded ActiveRecord version
+4798df3 Fixes #4822 -- Puppet doc -o option broken
+99c1019 [#4798] Puppet doc manifests documentation mode broken
+8cd1540 [#4692] undefined variables cause :undef to be passed to functions
+06bf566 [#4787] Missing require causing failure
+bba04e0 Fix for #4746 -- Newline goes at the _end_ of the line
+9e17c25 Fix #4743: Allow the audit meta-parameter to accept both 'all', and :all
+f950061 [#4716] ResourceTypeAPI exposes implementation details that are likely to change
+8ff4b9a Fixed #4819 - corrected cron documentation
+2b50f30 [#4771] Import of manifests with the same name only happens once
+7b8cb74 Fix for #4708 - tagmail should allow . in tagname
+6f229ee Minimal fix for #4631 -- set implicit classes as in 0.25.x
+021d534 Fixed #3707 - rpm, like dpkg-query exits 1 if the package is not installed. Returning nil in this provider had the effect that on every run, puppet would end up calling yum erase . Returning the correct data structure resolves this.
+216f663 Fixed Puppet Doc TOC generation
+c3cb57c Fixed versioncmp function typo
+898a170 Fixed Reductive references in LICENSE file
+996f14e Documentation updates for Markdown conversion
+
+2.6.1
+=====
+cad1e0f Updated CHANGELOG for 2.6.1
+14f871d [#4756] addendum for #4756
+9bdfe69 Fix for Bug #4756 - Providers no longer respect missing features Restored deleted lines from type.rb and reinstated unit tests
+14b3340 Fix for #4736 -- preserve case of defined resources
+bd973a2 Fix for #4637 --use of namevar missed in refactor
+
+2.6.1rc4
+========
+efa834a Updated CHANGELOG for 2.6.1rc4
+763e7cb Minimal fix for #4691 -- class name uppercased in $name
+4a9c857 Fix for #4693 -- implicit stages should never be serialized
+fa4d32c Fix for #4646 -- Missing stub
+4d55c6e Fix for tests broken by fix for #4489 -- stub standalone
+b397b69 Fix for #4489 -- apply was using the rest terminus
+e91a8cc [#4462] uncaught Timeout::Error
+4d36a51 Fixed alias metaparam docs error
+b063635 Skip apt-listbugs and apt-listchanges when installing from puppet
+e860907 [#4660] Avoid passing rake and autotest args to puppet tests
+419e007 Fixed #4706 - logcheck patterns
+f6c0265 Fixed queue require for #4555
+07d0be4 [#4308] Remove puppettest from specs
+9e69616 Fixed RSpec warning messages
+8d24861 Fixed #4100 - Added http_caching to yumrepo type
+8cd266e Added cost parameter to the yumrepo type
+0056d41 Fixed extlookup documentation and spacing
+e783a16 Fix for #4506 -- too much data being serialized
+f59cfc8 Fixed terminus example documentation
+690465e Fix #4615 - vim highlighting fails on slashes and colons.
+078e4fd Updated man pages
+7548c65 Updated Man page generation since move to Markdown
+
+2.6.1rc3
+========
+8be1929 Updated CHANGELOG for 2.6.1rc3
+81a2725 Fix for #4456 -- need to accept some mime-type aliases
+c318558 Fix for #4489 -- apply was using the rest terminus
+491c31d Fix for #4542 -- included classes weren't assigned proper stages
+302d657 Fix for #4501 -- reports not generated in standalone
+1ea4ccf Start server before agent
+4c28079 [#4555] puppet queue tries to call code it hasn't required
+d1150e0 fix #4528 - treat * as absent
+20f4b90 Fix for #4518 -- classes not getting added to compiler.classes
+57bb06b [#4545] Remove obsolete 'trac' specs
+82b4f04 Maint. -- Fix test failures broken by previous commit
+0c30754 Maint. Removing code at the request of the original author
+3df0490 [#4298] Puppet apply prints an error if the file to apply doesn't exist
+5d4f222 Fixed #4527 correctly for 2.6.1
+1b3d782 Updated config.ru example for 2.6.1
+
+2.6.1rc2
+========
+0aa27b5 Updated for 2.6.1rc2
+252c9b8 Further RST to Markdown fixes for types, values, tests
+1157e8d Updated all types to Markdown output
+fef8800 Updated reference output to generate valid Markdown
+79e0a2e Reformatting documentation from RST to MarkDown (#4509) Signed-off-by: Jes Fraser <jes@gadget.geek.nz>
+62435e5 Rewrote functions documentation to Markdown
+e4b2aa6 Removed legacy Trac code
+8ddea2a Maint. Passenger fix broke a test
+f43e87b Fix for #4476 -- rails calling yaml internals
+a23d80a Fixes #4485 -- single quoted strings should not treat \n as new line
+8e31b52 Passenger needs HTTP headers values to be string
+037bb32 [#4404] Remove requirement for source on Parser::Resource::Param
+0e4bc62 [#4364] Fix failing spec due to incorrect loglevel
+3a6ca54 Fix #4458 - Do not dump the whole environment when instances can't be found
+d909827 Fix for #4465 -- earlier "feature" patch broke ldap
+47005aa Maint -- tests need to respect RFC-952
+6aac8f0 [#4467] Make Puppet Master respect facts_terminus settings
+1cba9a7 added md5 support as requested in http://serverfault.com/questions/166199/puppet-md5-sum-of-string
+1dfd2b6 [#4381] extlookup shouldn't trigger reparses of .pp files
+be2b1f3 [#4370] Fixes extlookup precedence getting overwritten between runs
+03808fd Fixed #4364 - Reduced audit msg from info to debug
+539b57c [#4347] run_mode was colliding with --mode for "puppet doc"
+1faebdd [#4423] repair parameterized class instantiation
+37568bd [#4423] class { shouldn't get stored on the namespace stack
+449315a [#4397]+[#4344] Move type-name resolution out of Puppet::Resource into the AST resources.
+daa801b [#4344] Temporary fix to stop agent from importing modules
+00ebf01 [#4344] Fix for failing templates when module name matches file in local dir.
+e32320e [#4336] "reportdir" was in the wrong section
+0f9672a Fixed #4311 - Typo in defaults.rb
+f54d843 Fix #4461 - attempt to fix another performance issue
+2c21fae Fix for #4300 Solaris svc files need new pid filenames
+83c2419 [#4284] Fix failing specs run as root due to missing puppet group
+8237f68 [#4242] Fixed (removed) a broken unit test
+d5ad0fb Removed eventual documentation line ... eventually came
+871e6fd Fixed #4368 - Updated clean stored configs ext script for new config sections
+cb64477 Updated version to 2.6.1
+
+2.6.1rc1
+========
+ecf44e4 Updated CHANGELOG for 2.6.1rc1
+bdfcac5 Update Red Hat spec file for 2.6.0
+9f08e7c Feature: puppet-load - a tool to stress-test master compilation
+ef9a4a6 Fix #4245 - default insertion of ACL is not thread safe
+4065e81 Fix race condition in rack autoloading of request/response
+3163932 Fix #4244 - Cached Attributes is not thread safe
+7d42f77 JRuby doesn't implement Process.maxgroups
+760e418 Fix #4349 - Parsing with ignoreimport=true was always loading site.pp
+67bdf89 Fix #4348 - Puppet doc single manifest broken
+13c71b9 extlookup() is a builtin
+d38e522 [#4333] old optparse doesn't support default_argv=
+86b0882 Fixed #4326 - Updated SUSE packaging
+03313b8 Fix #4319 - source file url sent to the master is invalid
+ac3a0d2 vim: highlight default parameters in definition/classes
+be2141a vim: match collected resources.
+c047c8d vim: added elsif
+9569136 Fix for 4314 -- Need to allow '-' in class name for refs
+636079f Fixed #4304 - Changed logging level for auto import message
+000fd1e Fix for #4303 -- reverting to old escaping in '-strings
+1d494a3 Tweak to fix for #4302--dangling ref to known_resource_types
+2383050 Fix #4302 - Compilation speed regression compared to 2.6
+63ec207 Minimal fix for #4297, with notes for follow-up
+7ad7eb1 Fix #4286 - rename puppetdoc global module <site> to __site__
+28bb195 Fixed yumrepo type deprecation wanring `
+067a46d Temporary tweak to tests for #4242
+9778f2a [#4242] Fixed recursion due to parents including their children
+59a23d6 Fix for #3382 -- Empty classes as graph placeholders
+865282a Fixed example config.ru
+a0a63c3 Fixed network and indirection reference
+64386cf Fixed Indirection reference
+
2.6.0
=====
+db0b30d Updated CHANGELOG for 2.6.0
42a475e Fixing #4268 - manifests always imported
06fc40c [#4269] Undef variables interpolate to empty string
1288f8c [#4270] Force inherited classes to load into the correct environment
@@ -3427,10 +3662,6 @@ ada960b Constants in provider/interface/redhat.rb are getting redifined as they
5e8d71d Fix the ral:providers:host:parsed tests so they run successfully
9530df1 Updated to version 0.23.2
0d312a1 Updated to version 0.23.2
-
-0.23.2
-======
-49c9a62 Adding release tag REL_0_23_2
b84015a The last set of bug-fixes before the next release. This commit just fixes a couple of problems that resulted when I changed the Provider#initialize method to not duplicate its argument, which was necessary for ParsedFile.
aaf5959 Adding test support for the other mongrel configuration header
db0ffc7 Copying the "commands" and "confine" statements to the actual dscl providers, since they need to be there to determine where the providers are suitable. Otherwise base classes could unnecessarily affect how subclasses work.
@@ -3460,10 +3691,6 @@ a8bf96a Adding a file that should have been in a commit from yesterda
530d290 Applying a modification of the patch from Marcin Owsiany, allowing Mongrel to be a CA
64fba48 Updated to version 0.23.1
d3988cc Updated to version 0.23.1
-
-0.23.1
-======
-0f7f752 Adding release tag REL_0_23_1
2229dc1 Fixing #726 -- mounts can now correctly handle mounted but absent filesystems.
47b7058 Adding some code in an attempt to fix #728, but it is all commented out since I could not get it fixed in time for beaker
2e14ea4 Attempting to clean up the mount documentation as in #727.
@@ -3554,10 +3781,6 @@ dc2a0bf Use single config file
ada4355 Updated to version 0.23.0
d8f4c53 Updated to version 0.23.0
049faf8 Updated to version 0.23.0
-
-0.23.0
-======
-f588d47 Adding release tag REL_0_23_0
8844fca Changing the paths to match laeg, instead of culain.
d79a788 Modified the fileserver to cache file information, so that each file isn't being read on every connection. Also, added londo's patch from #678 to avoid reading entire files into memory.
944e1f4 More updates to puppet-test
@@ -3731,10 +3954,6 @@ fb4f04d updating changelog with version number
0f02a54 Updated to version 0.22.4
e049999 Updated to version 0.22.4
4f2b903 Updated to version 0.22.4
-
-0.22.4
-======
-22ce899 Adding release tag REL_0_22_4
3e895b5 Changing the remount stuff back to not repeating the mount options.
6438270 Adding a "supports_parameter?" method to test whether a given provider supports the features required by a given parameter. This is used during attribute instance creation, but its creation was necessicated by test code.
c9de332 Fixing the fileserver naming tests after the change to allow "-" in fileserver module names.
@@ -3798,10 +4017,6 @@ ca5d068 Updating the docs for the sourceselect parameter
a999752 Updated to version 0.22.3
24ad5ab Updated to version 0.22.3
9ce7c79 Updated to version 0.22.3
-
-0.22.3
-======
-a3a7ea7 Adding release tag REL_0_22_3
e154589 Fixing puppetdoc with the recent changes to the networking code
801d0f7 Fixing a bug I apparently introduced in the testing that would have made user management not work with netinfo. In the process, I am enabling validation on the nameservice subclasses.
2544f75 Fixing the documentation to match reality, as reported in #548.
@@ -3825,10 +4040,6 @@ c5e1a44 Fixing the "readcert" method after getting the signed cert; the method
36feb29 Fixing a small bug in testing whether instance methods are already defined.
45904ca Updated to version 0.22.2
0452878 Updated to version 0.22.2
-
-0.22.2
-======
-a917a3e Adding release tag REL_0_22_2
474b86c Hopefully the last batch of commits before I release 0.22.2. Mostly just get tests to pass.
90d8b2d Remove no-lockdir patch. Clean changelog
a68a7c2 Change puppet's homedir to /var/lib/puppet
@@ -3983,10 +4194,6 @@ f80bd5e Fixing exec so it actually works when path is specified as an array
d117aa8 Updated to version 0.22.1
1e90209 Updated to version 0.22.1
463d3a8 Updated to version 0.22.1
-
-0.22.1
-======
-530c255 Adding release tag REL_0_22_1
1d059b0 Fixing #470, I think. I basically just threw away the validation and let suidmanager do it all when running commands.
69a07b1 The resolve functionality in "test" is almost working...
42d15fe Adding note about removing mounts netinfo provider
@@ -4078,10 +4285,6 @@ f7d8350 Updating docs for 0.22.0
4ee6c97 Updated to version 0.22.0
98ed0ae Updated to version 0.22.0
38cfa67 Updated to version 0.22.0
-
-0.22.0
-======
-728d745 Adding release tag REL_0_22_0
3446dd6 Last round of fixes before the next release
954a285 Fixing puppet test task for older ruby versions
7afa69c Fixing rake test so it works with the new puppet loader
@@ -4260,10 +4463,6 @@ c3c5851 Fixing configuration storage -- there was a check being done that cause
60af8e2 Updated to version 0.20.1
e313a26 Updated to version 0.20.1
68d9e78 Updated to version 0.20.1
-
-0.20.1
-======
-2feb9e8 Adding release tag REL_0_20_1
7d46167 Updating changelog for 0.20.1
7fa96cb Another small fix, just for solaris
db5d9d4 Another testing fix
@@ -4315,10 +4514,6 @@ e741b7b Fixing some Class.to_s handling
71924ad Updated to version 0.20.0
a488dd9 Updated to version 0.20.0
4688d93 Updated to version 0.20.0
-
-0.20.0
-======
-7694bd9 Adding release tag
f9f939e Updating changelog for 0.20
e3b4f23 Another round of bugfixing, including finding out that the tagmail report was leaving zombie processes lying around
07f616b A round of bug-fixing on OS X
@@ -4440,16 +4635,6 @@ f2ac4dc Updating changelog for 0.19.3, and merging the version changes over.
8f9dcb5 Updated to version 0.19.2
595d5ba Updated to version 0.19.2
6902f2d Updated to version 0.19.2
-
-0.19.3
-======
-bec795d Adding release tag REL_0_19_3
-0513ffa Fixing problem with the hostname being removed when running locally. The node_name setting was not checking that the client was set, and it is never set when running locally.
-7726afc Adding branch to fix the problem with hostnames getting nilled
-
-0.19.2
-======
-ddb4c47 Adding release tag REL_0_19_2
164c18f As requested by Christian Warden, triggering an object now results in an event, which can result in further triggers.
98004b2 Adding some error handling for when a non-existent report is asked for, and adding a bit more testing.
a1e27bc Adding trace information to autoload.rb
@@ -4494,10 +4679,6 @@ fd4ef3c Better documentation around certificate revocation and mgmt
c8a6df0 Updated to version 0.19.1
ee8b8c7 Updated to version 0.19.1
6f85511 Updated to version 0.19.1
-
-0.19.1
-======
-7e229a8 Adding release tag REL_0_19_2
0e58f65 Updating changelog for 0.19.1
4a3c8d1 Adding testing for the default? method, and fixing it to support arrays and returning false when no defaults are specified
48992d7 Using the "trace" configuration parameter to determine whether a stack trace should be printed, rather than just using "debug". I added the param a little while ago and was using it internally in Puppet::DevError, but I just now went through the whole configuration and switched to using it.
@@ -4539,10 +4720,6 @@ c651b19 Disable the sample fileserver module by default, otherwise users get sp
65bb635 Updated to version 0.19.0
61e42e7 Updated to version 0.19.0
12b219e Updated to version 0.19.0
-
-0.19.0
-======
-fbebcc5 Adding release tag REL_0_19_0
e309b76 Modifying the provider base class so that it defines a method for every used command (e.g., you call "commands :rpm => 'rpm'", and it defines an "rpm" method. I then pushed this throughout the package providers, which are the heaviest users of commands.
c5ce953 Adding aptitude support, including a new util::package module that provides a method for package version sorting, and a couple of smaller bug fixes. This fixes #237.
2113eed Adding hasrestart parameter to services
@@ -4660,10 +4837,6 @@ b2f1aa0 doc updates
b8bf113 Updated to version 0.18.4
94cc68b Updated to version 0.18.4
ce95ee3 Updated to version 0.18.4
-
-0.18.4
-======
-74a3b4d Adding release tag REL_0_18_4
f13c451 updating changelog for 0.18.4
cdeccab Another batch of bug fixes, this time focused on OS X patches. Looks like I did not test on os x last time.
b42eaee First round of bugfixes in preparation for 0.18.4
@@ -4694,10 +4867,6 @@ e74b8af fixing html markup
b23b797 Updated to version 0.18.3
fe8ce26 Updated to version 0.18.3
a984a90 Updated to version 0.18.3
-
-0.18.3
-======
-04a99e7 Adding release tag REL_0_18_3
8063ab1 Fixing filebucket server so that paths are not added multiple times
1ab4594 Adding tests for previous config bugfixes, and updating changelog
a6cc3e4 Fixing reports so that multiple host report directories can be created. There was a config conflict before.
@@ -4727,10 +4896,6 @@ eff8d6e Accepting the patch from #190.
bd9fd8d Updated to version 0.18.2
71036e7 Updated to version 0.18.2
aa87963 Updated to version 0.18.2
-
-0.18.2
-======
-3e5907d Adding release tag REL_0_18_2
afe84ec small fixes towards 0.18.2
e17f4ed adding host information to reports and tagmail report
1503b42 renaming tagmail config file
@@ -4761,10 +4926,6 @@ ea91896 changing the #!ruby lines to #!env ruby
d275489 Updated to version 0.18.1
35ef37b Updated to version 0.18.1
427831c Updated to version 0.18.1
-
-0.18.1
-======
-1cc2712 Adding release tag REL_0_18_1
7adafc6 For each type, adding a "new<type>" method to Puppet::Type, so instead of typing Puppet::Type.type(:file).create(...) you can now type Puppet::Type.newfile(...).
e8c57ae Cleaning up plugin handling a bit -- they can now be colon-separated paths, and I added a separate "plugindest" setting for determining where plugins are synchronized to. The major feature I added, though, is that Puppet::Type now knows how to load plugins, and treats :pluginpath as a search path for plugins.
d98ab11 Fixing zone tests
@@ -4814,11 +4975,6 @@ e841d8f Adding test and fix for empty execs being ignored
0ab461b Updated to version 0.18.0
daac8cf Updated to version 0.18.0
8779dbe Updated to version 0.18.0
-
-0.18.0
-======
-4a5df83 Adding release tag REL_0_18_0
-a6f9bf4 Adding release tag REL_0_18_0
ae3dba9 updating changelog for 0.18.0
ead6b17 updating documentation for sshkey
20b0a6d fixing transaction tests to just warn when the user is not in more than one group, rather than failing.
@@ -4880,10 +5036,6 @@ b08816b Fixing #162. Node names must now be comma-separated.
3ab4a89 Small fix to include puppetrun in /usr/bin
62a0ff0 adding puppetrun to the red hat spec file
fda013a Updated to version 0.17.2
-
-0.17.2
-======
-b742236 Adding release tag REL_0_17_2
3c15a28 updating changelog for 0.17.2
a08ca93 Fixing #138, all of it, I think. Environment settings are now allowed, although all bets are off in terms of parsing existing environment settings in crontabs.
69cf2fe Adding a small fix to cron tabs; they will at least parse tabs that have env settings in them, although you still cannot, at this point, set them.
@@ -4893,10 +5045,6 @@ d55adda First version of puppetrun. It seems to mostly work, but I need to tes
b3ea53c Adding a lot of structure to puppet.rb to make it easier to manage multiple objects in a single process, including making it easy to add threads. Added some testing for all of that.
93771b7 fixing user[:groups] management when the user is absent
738698c Updated to version 0.17.1
-
-0.17.1
-======
-f028420 Adding release tag REL_0_17_1
ed9adf5 updating changelog for 0.17.1 and 0.17.0
9b5de11 Allowing empty files
5382118 Fixing #146. I think I mostly just fixed the error message; I do not think there was another bug there.
@@ -4904,10 +5052,6 @@ ed9adf5 updating changelog for 0.17.1 and 0.17.0
dc3a6d5 Making sure file recursion works for all valid inputs
373afa3 updating version on spec file
4296b02 Updated to version 0.17.0
-
-0.17.0
-======
-559f4b0 Adding release tag REL_0_17_0
3be0f95 Wrapping the host storage into a transaction. It might have a slight performance improvement, but, ah, unlikely.
9d6166e adding a test to make sure that defaults get taken up by components
a0bcf5a Adding code to try for the rails gem if the library cannot be found normally, and adding some protections in case there are problems
@@ -4939,27 +5083,15 @@ e06c661 Small bug fixes
18de804 fixing log messages
a7fadbe fixing log messages
43fdd89 Updated to version 0.16.5
-
-0.16.5
-======
-054cc77 Adding release tag REL_0_16_5
64a58e4 updating changelog for 0.16.5
44f1579 Fixing a stupid bug i managed to introduce in 0.16.2 (probably) involving importing files with classes in them. This is a better solution than what I had before the bug, anyway. Also, some documentation fixes.
a9df49d Fixing some naming problems with crons, and adding appropriate tests
e8c912d Allowing dashes in class names, although grammar rules restrict it from working anywhere except node names or in tag(). They are valid in host names, and many companies have them in the host names; in fact, this fix is for a company with this exact problem -- they cannot use puppet with their nodes because all their hosts have dashes in the host names.
37d2850 Switching to just using "preserve" for file copying in file#handlebackups
8b0481c Updated to version 0.16.4
-
-0.16.4
-======
-66b8bfd Adding release tag REL_0_16_4
4b84ca9 updating changelog for 0.16.4
b67a19b Fixing #132, which involved creating a separate CA client and using it to retrieve the certificates. There was more work to do because of the weird client/daemon/server heirarchy.
a435d07 Updated to version 0.16.3
-
-0.16.3
-======
-ab17248 Adding release tag REL_0_16_3
3f08155 updating changelog
2faa447 Bug fixes from OS X for 0.16.3
5e246ab Hopefully final bug fixes in preparation for 0.16.3
@@ -4975,17 +5107,9 @@ a1574a5 Fixing TransObject#to_type so that it does not modify the object being
bcfc469 Adding in all of the patches necessary to make a prototype rails interface to puppet nodes work. The biggest change is that there is now a separate NetworkClient class for every Client subclass, because otherwise you get namespace collisions. Most everything other change is a relatively minor patch.
9539dbb Adding in all of the patches necessary to make a prototype rails interface to puppet nodes work. The biggest change is that there is now a separate NetworkClient class for every Client subclass, because otherwise you get namespace collisions. Most everything other change is a relatively minor patch.
9b627cd Trying to track down the bugs reported this morning, so I added some more test cases. I did find a bug in the filebuckets, fixed it, and added a test case.
-
-0.16.2
-======
-13c91ea Adding release tag REL_0_16_2
003e897 updating changelog for 0.16.1 and 0.16.2
a78bf1e adding "clean" mode to puppetca
bda8e52 This should have been in 0.16.1. Moving the "setclass" statements around so that classes are set before a given class's code is evaluated, so it can be tested within the code, within node defs, components, or classes.
-
-0.16.1
-======
-77bf69c Adding release tag REL_0_16_1
bff9463 Adding sum type to the retrieved sum if it is not already there. This provides backwards compatibility for existing cache files.
feff317 removing unnecessary debugging
baa412c Adding "defined" functino to puppet, so you can now test whether a given class or definition is defined.
@@ -4993,10 +5117,6 @@ baa412c Adding "defined" functino to puppet, so you can now test whether a give
ccc4d95 Modifying non-existent-package test to make sure syncing fails, and modified ports package type to check the error output instead of the return code, because the portinstall command returns 0 even on failure.
e64bd22 Fix ownership on server files (trac #122) Change ownership on /var/puppet
9fe0b37 removing patch from red hat spec file
-
-0.16.0
-======
-2492328 Adding release tag REL_0_16_0
a0b4553 Final commit before 0.16.0
63cdc6c making corrections to pass tests on freebsd
d9fd002 Go some work started on developing authorization, but I have made little progress. I might wait on this for the next point release.
@@ -5034,10 +5154,6 @@ ae4b12e Revamp the yumrepo type to deal with repositories defined anywhere in y
8df6e84 another small mount fix; this time, for stupid os x
88dd992 committing version changes
d10a638 Committing an important fix to mounts; since i am sure no one has downloaded 0.15.3, i am just going to rerelease 0.15.3 with this fix in it
-
-0.15.3
-======
-abf09dc Adding release tag REL_0_15_3
83d5236 updating changelog for 0.15.3; I need these exec fixes for my client
e5be7d3 Adding autoloading for types and service types, also.
fcce820 Okay, last one, hopefully. Modifying checks to support arrays.
@@ -5047,10 +5163,6 @@ fcce820 Okay, last one, hopefully. Modifying checks to support arrays.
1e4abae moving cwd existence check into "sync" instead of "validate"
7dae24f Fixing a small bug in type.rb that ignored false values (instead of nil values), another small bug in value setting that resulted in the file and line appearing twice in errors, and added validation to all of the checks in :exec (along with testing for all of it).
b0edb35 removing patch from spec file
-
-0.15.2
-======
-feab8d9 Adding release tag REL_0_15_2
122cf58 updating changelog in preparation for 0.15.2
013cfd2 Adding darwinport type.
9697354 differentiating openbsd from freebsd, adding freebsd, and autoloading package types instead of manually loading them
@@ -5094,10 +5206,6 @@ a9fdf9d Disbale running puppetmaster as puppet until we've sorted out which fil
791e4da Committing support for group membership management. Currently only works on Linuxes and other OSes that use "useradd" that support -G.
932fd03 commiting package test fix that i thought i committed ages ago
28602a6 Simplified as yum install can be used for both install and update
-
-0.15.1
-======
-437ee64 Adding release tag REL_0_15_1
95b762b updating changelog for 0.15.1
fc98ab0 Fixing #100. I just added a bit of a hack to configuration parsing -- if a group is specified in a section that matches the name of the process, then it is assumed to be the group that the process should run as. The problem is that we are reusing the term "group" here for both the run-group and the file-group. Oh well.
5dcf303 Using differents commands with yum depending on whether the package is currently installed or not.
@@ -5113,10 +5221,6 @@ fc68910 removing dos EOL chars
c74fd81 Committing the EPM support. I am in the process of moving this to a common library that all of my projects can use.
271a8d2 Adding EPM package building.
805b32b Updated to version 0.15.0
-
-0.15.0
-======
-1409cd6 Adding release tag REL_0_15_0
92e3c1e Updating changelog for 0.15.0.
ec7d46e fixing small bug in the test code when there are no packages to test
f851be7 Adding upgrade ability to sun packages. Currently it removes the old package and installs the new one.
@@ -5146,19 +5250,11 @@ b6d829b Fixing #95. I had to redesign how events were triggered; the transacti
7756f9a Fixing #97. I was wrong about the object type I had, so I was calling "type" with no arguments, which was causing the bug.
2faff5d lowering the log output for nonexistent files
eb68633 Updated to version 0.14.1
-
-0.14.1
-======
-ad0fa4b Adding release tag REL_0_14_1
cee0882 updating changelog for 0.14.1
2351cd7 making case statements not create a new scope
54fcdbd fixing some more logging issues
0549d03 Making some logging changes, and fixing a small bug in group management on missing files
72d747b Updated to version 0.14.0
-
-0.14.0
-======
-783735c Adding release tag REL_0_14_0
b76004a Fixing yum listing bug, and caching the "latest" value so it is not asked for so many times; this fixes #90.
3c07deb Committing the last changes, for now, to handling links. You still cannot copy remote links, but you can either ignore or follow them. I do not think we will be able to copy remote links until I have merged symlinks and files to be the same object type again.
e9e88b0 Adding "links" parameter to files, and adding support for following or ignoring links to all of the states it can matter to. I still need to modify "source" so that it behaves correctly when managing links.
@@ -5175,10 +5271,6 @@ f2ea9b7 Supporting variables as the test value in both case statements and sele
aae9b2a Definitions now always create their own context, which means that they cannot override elements in the containing scopes.
451ba6d upgrading to warning the message about using a cached copy
faffd69 Updated to version 0.13.6
-
-0.13.6
-======
-25614df Adding release tag REL_0_13_6
caa7f48 updating changelog for 0.13.6
343dd08 Fixing tests so they do not chmod /dev/null to 640 (stupid tests).
1a93c82 Fixing #68. After tons and tons and tons of work, everything successfully configures itself, and the --genmanifest argument should actually work. User and group creation will not necessarily work everywhere (in particular, Puppet uses dependencies to create the group first, but Fedora complains on user creation if the group already exists), but file and directory creation should. The only downside is that there is a decent amount of extra information printed on daemon startup, as the daemon checks its config; this could maybe be seen as a bonus, though, I guess.
@@ -5207,20 +5299,12 @@ b119a72 Fixing output when user/group are not found
043fc33 adding commas to each line
d06cd3f removing the initial syslog dest setting
f6ca82b Updated to version 0.13.5
-
-0.13.5
-======
-7ec2f82 Adding release tag REL_0_13_5
85e4d31 adding changelog for 0.13.5
2dffbee Adding redhat service type, to support enabling and disabling a service
7e5cc76 Fixing package types so you can specify the package type manually in a manifest
7806618 removing extra error statement
6e26a73 adding passwd converter
3aff15e Updated to version 0.13.4
-
-0.13.4
-======
-d0b3f6c Adding release tag REL_0_13_4
1f05ad0 updating changelog for 0.13.4
cfb0e36 updates
89856ec Adding a bit more logging
@@ -5237,10 +5321,6 @@ beef01c Properly figure out when updates are available. Previously, packages wo
5f4335f Adding logoutput parameter to :exec
89702d8 Fixing symbolic naming bug where symbolic names were being ignored in some cases
7d15fe1 Updated to version 0.13.2
-
-0.13.2
-======
-d0bbab5 Adding release tag REL_0_13_2
037b7ac Changed the parsedtype definition of exists(), and fixed a few smaller bugs. Last code commit before 0.13.2
6fe01ce Tracked down a few other bugs; everything now passes on debian in preparation for 0.13.2
8602932 Changing "answerfile" to "adminfile", adding "responsefile", and autorequiring both.
@@ -5255,10 +5335,6 @@ f098485 Correcting some path problems with symlink, and changing "target" state
3f15cb8 Fixing :target reference in pfile.rb
9508bd0 Correcting some path problems with symlink, and changing "target" state to "ensure"
64eafa8 Updated to version 0.13.1
-
-0.13.1
-======
-ac8f3ae Adding release tag REL_0_13_1
a456c4d updating alias docs to pass ReST checks
1a05ed2 updating changelog and docs for :alias
89d37f6 Fixing some problems with cron tab management, and creating Puppet::Util.{u,g}id methods.
@@ -5269,10 +5345,6 @@ b13b5ed Set the Release tag in the spec file to 1 when the version is changed
8c02ffd Adapt specfile to the fact that puppetmaster now automatically runs as user puppet. Add default config files that send logs to /var/log/puppet.
d629a80 Fix version in last changelog entry (makes rpmlint happy)
44071d0 Updated to version 0.13.0
-
-0.13.0
-======
-4751fce Adding release tag REL_0_13_0
2cb5cb3 Updating changelog for 0.13.0
387db24 Adding answerfile support to sun pkgs.
2ce061a adding some documentation
@@ -5309,10 +5381,6 @@ d5af359 Rewrote client init script since puppetd is now a proper demon.
96b761b Fixing waitforcert so that the client can actually add the certs once it receives them
c7f9942 Adding release tag REL_0_12_0
cf82cfa Updated to version 0.12.0
-
-0.12.0
-======
-2c35151 Adding 0.12.0 release tag
282cfcf Updated to version 0.12.0
1186069 Small mods to the packaging stuff
87904d3 RPM release is almost entirely there, it just needs to be integrated into release management
@@ -5322,26 +5390,14 @@ ae2575b Adding the event-loop stuff to the repository and switching to using it
258114d Modifying docs, and adding scheduling hooks
0cb51f3 Fixing a small checksumming bug, reorganizing the client stuff a bit, and adding freshness checking for the configuration, so the config is recompiled every time nor is it downloaded unless it has been recompiled
f49b103 Updated to version 0.11.2
-
-0.11.2
-======
-36f6e05 Adding release tag REL_0_11_2
c372a7d modding changelog for 0.11.2
6bab167 Made lots of small changes, mostly to help usability but also fixed a couple of key bugs
ed39be9 Fixing most types to allow no statements
3d458ef Updated to version 0.11.1
-
-0.11.1
-======
-4bbb952 Adding release tag REL_0_11_1
c3df525 modifying changelog for 0.11.1
060b8bd Adding openbsd packaging support
ada3aee Fixing problems where objects were passing @parameters[:param] objects, instead of specifically retrieving the value
f36c7d1 Updated to version 0.11.0
-
-0.11.0
-======
-1d2095b Adding release tag REL_0_11_0
3700b37 Adding an "ensure" state where appropriate, and significantly reworking the builtin docs.
92a780a Added "ensure" state to some classes, and added infrastructure for it to work elsewhere.
83906a2 Adding sshkey class plus tests, and adding "aggregatable" methods to type.rb
@@ -5362,10 +5418,6 @@ f420135 Converting transport format to YAML instead of Marshal, and caching the
c5782df Adding "content" state to files, and string interpolation handles escaped whitespace characters.
b0ea70d Adding 0.10.2 stuff
6b6c49b Updated to version 0.10.2
-
-0.10.2
-======
-f7211e3 Adding release tag REL_0_10_2
1cf05ff Services now work at least somewhat on solaris 10, and service testing is pretty different.
4c4f530 Fixing dependencies to not depend on file order. Added Puppet::Type.{finalize,mkdepends,builddepends}
21410a2 Fixing documentation generation, and fixing aliasing so that objects can safely be aliased to themselves
@@ -5374,10 +5426,6 @@ f7211e3 Adding release tag REL_0_10_2
97fb6c9 Adding generic autorequire mechanism, and thus removing it from exec
11b5463 Adding a requires? method to types, fixed the bug where exec fail when Puppet is downloading the script to execute, and modified "exec" to autorequire any managed scripts
932b783 Updated to version 0.10.1
-
-0.10.1
-======
-dc012b1 adding 0.10.1 release tag
854f16b modifying changelog for 0.10.1
89d0050 Adding Sun support and fixing the last remaining bugs related to the daemon changes i just made
45ac512 Supporting puppetmasterd running as a non-root user, and doing some basic message cleanup
@@ -5386,10 +5434,6 @@ dc012b1 adding 0.10.1 release tag
e5ac196 Adding some consistencies to the executable tests. All exe tests now pass on OpenBSD, although the only real problem was that ruby was in /usr/local/bin.
dccafc7 Updating Puppet to work with the new Facter
b7974b5 Updated to version 0.10.0
-
-0.10.0
-======
-8458a0d Adding 0.10.0 release tag
48031dd Describing 0.10.0 changes
48ba030 Modifying hosttest
f00a7db All tests pass now, although the lack of service support on os x means that i have now disabled services on it
@@ -5409,10 +5453,6 @@ e611f2c adding some better readme stuff
b532a30 adding things to the change log, and modifying the order of the steps
584652c Disabling most documentation generation except for the API docs, and wrapping the StatusServer in the xmlrpc check
0e0fdac Updated to version 0.9.3
-
-0.9.3
-=====
-d4a9f3e Adding release tag
e2e2fb3 some updates to the typegen stuff, even though i may still not use it
5302921 Fixing two reported bugs in cron jobs. Cron jobs correctly change when fields other than the command are updated, and they do not continually refresh when the command has trailing spaces
592c24d adding some comments
diff --git a/LICENSE b/LICENSE
index 57d96f83e..a43a24352 100644
--- a/LICENSE
+++ b/LICENSE
@@ -1,6 +1,6 @@
-Puppet - Automating Configuration Management. Copyright (C) 2005 Reductive Labs LLC
+Puppet - Automating Configuration Management. Copyright (C) 2005 Puppet Labs LLC
-Reductive Labs can be contacted at: info@reductivelabs.com
+Puppet Labs can be contacted at: info@puppetlabs.com
This program and entire repository is free software; you can
redistribute it and/or modify it under the terms of the GNU
diff --git a/Rakefile b/Rakefile
index 8e21cebd9..22d4a9aeb 100644
--- a/Rakefile
+++ b/Rakefile
@@ -43,7 +43,7 @@ desc "Create the tarball and the gem - use when releasing"
task :puppetpackages => [:create_gem, :package]
Spec::Rake::SpecTask.new do |t|
- t.spec_opts = ['--format','s', '--loadby','mtime','--color']
+ t.spec_opts = ['--format','s', '--loadby','mtime','--color', '--backtrace']
t.pattern ='spec/{unit,integration}/**/*.rb'
t.fail_on_error = false
end
diff --git a/conf/redhat/puppet.spec b/conf/redhat/puppet.spec
index 6791cea77..e51af0a6b 100644
--- a/conf/redhat/puppet.spec
+++ b/conf/redhat/puppet.spec
@@ -5,14 +5,14 @@
%global confdir conf/redhat
Name: puppet
-Version: 0.25.5
+Version: 2.6.0
Release: 1%{?dist}
Summary: A network tool for managing many disparate systems
License: GPLv2+
URL: http://puppetlabs.com
Source0: http://puppetlabs.com/downloads/%{name}/%{name}-%{version}.tar.gz
Source1: http://puppetlabs.com/downloads/%{name}/%{name}-%{version}.tar.gz.sign
-Patch0: rundir-perms.patch
+
Group: System Environment/Base
BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n)
@@ -68,6 +68,7 @@ The server can also function as a certificate authority and file server.
%setup -q
patch -p1 < conf/redhat/rundir-perms.patch
+
%build
# Fix some rpmlint complaints
for f in mac_dscl.pp mac_dscl_revert.pp \
@@ -91,6 +92,7 @@ rm -rf %{buildroot}
ruby install.rb --destdir=%{buildroot} --quick --no-rdoc
install -d -m0755 %{buildroot}%{_sysconfdir}/puppet/manifests
+install -d -m0755 %{buildroot}%{_datadir}/%{name}/modules
install -d -m0755 %{buildroot}%{_localstatedir}/lib/puppet
install -d -m0755 %{buildroot}%{_localstatedir}/run/puppet
install -d -m0750 %{buildroot}%{_localstatedir}/log/puppet
@@ -221,6 +223,10 @@ fi
rm -rf %{buildroot}
%changelog
+* Tue Jul 20 2010 Todd Zullinger <tmz@pobox.com> - 2.6.0-1
+- Update to 2.6.0
+- Create and own /usr/share/puppet/modules (#615432)
+
* Mon May 03 2010 Todd Zullinger <tmz@pobox.com> - 0.25.5-1
- Update to 0.25.5
- Adjust selinux conditional for EL-6
diff --git a/conf/solaris/smf/svc-puppetd b/conf/solaris/smf/svc-puppetd
index 9036b505c..b6cf05736 100755
--- a/conf/solaris/smf/svc-puppetd
+++ b/conf/solaris/smf/svc-puppetd
@@ -12,7 +12,7 @@ exec_prefix=/opt/csw
sysconfdir=/opt/csw/etc
sbindir=/opt/csw/sbin
-pidfile=/var/lib/puppet/run/puppetd.pid
+pidfile=/var/lib/puppet/run/agent.pid
case "$1" in
start)
diff --git a/conf/solaris/smf/svc-puppetmasterd b/conf/solaris/smf/svc-puppetmasterd
index 34f5a62e6..80e3d464a 100755
--- a/conf/solaris/smf/svc-puppetmasterd
+++ b/conf/solaris/smf/svc-puppetmasterd
@@ -8,7 +8,7 @@ exec_prefix=/opt/csw
sysconfdir=/opt/csw/etc
sbindir=/opt/csw/sbin
-pidfile=/var/lib/puppet/run/puppetmasterd.pid
+pidfile=/var/lib/puppet/run/master.pid
case "$1" in
start)
diff --git a/conf/suse/client.init b/conf/suse/client.init
index d72b09b2c..71585cd7b 100644
--- a/conf/suse/client.init
+++ b/conf/suse/client.init
@@ -13,10 +13,10 @@
### BEGIN INIT INFO
# Provides: puppet
-# Required-Start: $local_fs $network $syslog
-# Should-Start: $null
-# Required-Stop: $null
-# Should-Stop: $null
+# Required-Start: $local_fs $remote_fs $network $syslog
+# Should-Start: puppet
+# Required-Stop: $local_fs $remote_fs $network $syslog
+# Should-Stop: puppet
# Default-Start: 3 4 5
# Default-Stop: 0 1 2 6
# Short-Description: puppet
diff --git a/conf/suse/fileserver.conf b/conf/suse/fileserver.conf
new file mode 100644
index 000000000..67e387ca0
--- /dev/null
+++ b/conf/suse/fileserver.conf
@@ -0,0 +1,12 @@
+# This file consists of arbitrarily named sections/modules
+# defining where files are served from and to whom
+
+# Define a section 'files'
+# Adapt the allow/deny settings to your needs. Order
+# for allow/deny does not matter, allow always takes precedence
+# over deny
+# [files]
+# path /var/lib/puppet/files
+# allow *.example.com
+# deny *.evil.example.com
+# allow 192.168.0.0/24
diff --git a/conf/suse/logrotate b/conf/suse/logrotate
new file mode 100644
index 000000000..c3a4d437a
--- /dev/null
+++ b/conf/suse/logrotate
@@ -0,0 +1,10 @@
+/var/log/puppet/*log {
+ missingok
+ notifempty
+ create 0644 puppet puppet
+ sharedscripts
+ postrotate
+ [ -e /etc/init.d/puppetmaster ] && /etc/init.d/puppetmaster condrestart >/dev/null 2>&1 || true
+ [ -e /etc/init.d/puppet ] && /etc/init.d/puppet reload > /dev/null 2>&1 || true
+ endscript
+}
diff --git a/conf/suse/puppet.conf b/conf/suse/puppet.conf
new file mode 100644
index 000000000..47501a388
--- /dev/null
+++ b/conf/suse/puppet.conf
@@ -0,0 +1,25 @@
+[main]
+ # The Puppet log directory.
+ # The default value is '$vardir/log'.
+ logdir = /var/log/puppet
+
+ # Where Puppet PID files are kept.
+ # The default value is '$vardir/run'.
+ rundir = /var/run/puppet
+
+ # Where SSL certificates are kept.
+ # The default value is '$confdir/ssl'.
+ ssldir = $vardir/ssl
+
+[agent]
+ # The file in which puppetd stores a list of the classes
+ # associated with the retrieved configuratiion. Can be loaded in
+ # the separate ``puppet`` executable using the ``--loadclasses``
+ # option.
+ # The default value is '$confdir/classes.txt'.
+ classfile = $vardir/classes.txt
+
+ # Where puppetd caches the local configuration. An
+ # extension indicating the cache format is added automatically.
+ # The default value is '$confdir/localconfig'.
+ localconfig = $vardir/localconfig
diff --git a/conf/suse/puppet.spec b/conf/suse/puppet.spec
index 2a0e6e359..777f6a4b6 100644
--- a/conf/suse/puppet.spec
+++ b/conf/suse/puppet.spec
@@ -1,31 +1,32 @@
%{!?ruby_sitelibdir: %define ruby_sitelibdir %(ruby -rrbconfig -e 'puts Config::CONFIG["sitelibdir"]')}
%define pbuild %{_builddir}/%{name}-%{version}
-%define suseconfdir conf/suse
-%define confdir conf/redhat
+%define confdir conf/suse
Summary: A network tool for managing many disparate systems
Name: puppet
-Version: 0.25.4
+Version: 2.6.1
Release: 1%{?dist}
License: GPL
-Group: System Environment/Base
+Group: Productivity/Networking/System
-URL: http://reductivelabs.com/projects/puppet/
-Source: http://reductivelabs.com/downloads/puppet/%{name}-%{version}.tar.gz
-Patch0: puppet.suse.patch
+URL: http://puppetlabs.com/projects/puppet/
+Source0: http://puppetlabs.com/downloads/puppet/%{name}-%{version}.tar.gz
+
+PreReq: %{insserv_prereq} %{fillup_prereq}
Requires: ruby >= 1.8.2
-Requires: facter >= 1.3.7
+Requires: facter >= 1.5
+Requires: cron
BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n)
BuildRequires: ruby >= 1.8.2
%description
-Puppet lets you centrally manage every important aspect of your system using a
-cross-platform specification language that manages all the separate elements
-normally aggregated in different files, like users, cron jobs, and hosts,
+Puppet lets you centrally manage every important aspect of your system using a
+cross-platform specification language that manages all the separate elements
+normally aggregated in different files, like users, cron jobs, and hosts,
along with obviously discrete elements like packages, services, and files.
%package server
-Group: System Environment/Base
+Group: Productivity/Networking/System
Summary: Server for the puppet system management tool
Requires: puppet = %{version}-%{release}
@@ -35,55 +36,56 @@ The server can also function as a certificate authority and file server.
%prep
%setup -q
-%patch0 -p0
%build
-for f in bin/* ; do
- sed -i -e '1c#!/usr/bin/ruby' $f
+for f in bin/* sbin/*; do
+ sed -i -e '1s,^#!.*ruby$,#!/usr/bin/ruby,' $f
done
%install
%{__install} -d -m0755 %{buildroot}%{_sbindir}
%{__install} -d -m0755 %{buildroot}%{_bindir}
+%{__install} -d -m0755 %{buildroot}%{_confdir}
%{__install} -d -m0755 %{buildroot}%{ruby_sitelibdir}
%{__install} -d -m0755 %{buildroot}%{_sysconfdir}/puppet/manifests
%{__install} -d -m0755 %{buildroot}%{_docdir}/%{name}-%{version}
%{__install} -d -m0755 %{buildroot}%{_localstatedir}/lib/puppet
%{__install} -d -m0755 %{buildroot}%{_localstatedir}/run/puppet
%{__install} -d -m0755 %{buildroot}%{_localstatedir}/log/puppet
-%{__install} -Dp -m0755 %{pbuild}/bin/* %{buildroot}%{_sbindir}
+%{__install} -Dp -m0755 %{pbuild}/bin/* %{buildroot}%{_bindir}
%{__install} -Dp -m0755 %{pbuild}/sbin/* %{buildroot}%{_sbindir}
-%{__mv} %{buildroot}%{_sbindir}/puppet %{buildroot}%{_bindir}/puppet
-%{__mv} %{buildroot}%{_sbindir}/puppetrun %{buildroot}%{_bindir}/puppetrun
%{__install} -Dp -m0644 %{pbuild}/lib/puppet.rb %{buildroot}%{ruby_sitelibdir}/puppet.rb
%{__cp} -a %{pbuild}/lib/puppet %{buildroot}%{ruby_sitelibdir}
find %{buildroot}%{ruby_sitelibdir} -type f -perm +ugo+x -exec chmod a-x '{}' \;
-%{__install} -Dp -m0644 %{confdir}/client.sysconfig %{buildroot}/var/adm/fillup-templates/sysconfig.puppet
-%{__install} -Dp -m0755 %SOURCE1 %{buildroot}%{_initrddir}/puppet
-%{__install} -Dp -m0644 %{confdir}/server.sysconfig %{buildroot}/var/adm/fillup-templates/sysconfig.puppetmaster
-%{__install} -Dp -m0755 %SOURCE2 %{buildroot}%{_initrddir}/puppetmaster
-%{__install} -Dp -m0644 %{confdir}/fileserver.conf %{buildroot}%{_sysconfdir}/puppet/fileserver.conf
-%{__install} -Dp -m0644 %{confdir}/puppet.conf %{buildroot}%{_sysconfdir}/puppet/puppet.conf
-#%{__ln_s} puppet.conf %{buildroot}%{_sysconfdir}/puppet/puppetmasterd.conf
-#%{__ln_s} puppet.conf %{buildroot}%{_sysconfdir}/puppet/puppetca.conf
-%{__install} -Dp -m0644 %{confdir}/logrotate %{buildroot}%{_sysconfdir}/logrotate.d/puppet
+%{__cp} -a %{pbuild}/conf/redhat/client.sysconfig %{buildroot}%{_confdir}/client.sysconfig
+%{__install} -Dp -m0644 %{buildroot}%{_confdir}/client.sysconfig %{buildroot}/var/adm/fillup-templates/sysconfig.puppet
+%{__cp} -a %{pbuild}/conf/redhat/server.sysconfig %{buildroot}%{_confdir}/server.sysconfig
+%{__install} -Dp -m0644 %{buildroot}%{_confdir}/server.sysconfig %{buildroot}/var/adm/fillup-templates/sysconfig.puppetmaster
+%{__cp} -a %{pbuild}/conf/redhat/fileserver.conf %{buildroot}%{_confdir}/fileserver.conf
+%{__install} -Dp -m0644 %{buildroot}%{_confdir}/fileserver.conf %{buildroot}%{_sysconfdir}/puppet/fileserver.conf
+%{__cp} -a %{pbuild}/conf/redhat/puppet.conf %{buildroot}%{_confdir}/puppet.conf
+%{__install} -Dp -m0644 %{buildroot}%{_confdir}/puppet.conf %{buildroot}%{_sysconfdir}/puppet/puppet.conf
+%{__cp} -a %{pbuild}/conf/redhat/logrotate %{buildroot}%{_confdir}/logrotate
+%{__install} -Dp -m0644 %{buildroot}%{_confdir}/logrotate %{buildroot}%{_sysconfdir}/logrotate.d/puppet
+%{__install} -Dp -m0755 %{confdir}/client.init %{buildroot}%{_initrddir}/puppet
+%{__install} -Dp -m0755 %{confdir}/server.init %{buildroot}%{_initrddir}/puppetmaster
%{__ln_s} %{_initrddir}/puppet %{buildroot}%{_sbindir}/rcpuppet
%{__ln_s} %{_initrddir}/puppetmaster %{buildroot}%{_sbindir}/rcpuppetmaster
%files
%defattr(-, root, root, 0755)
%{_bindir}/puppet
-%{_sbindir}/filebucket
-%{_sbindir}/ralsh
+%{_bindir}/puppetdoc
+%{_bindir}/filebucket
+%{_bindir}/ralsh
+%{_bindir}/pi
%{_sbindir}/puppetd
%{_sbindir}/rcpuppet
-%{_sbindir}/pi
%{ruby_sitelibdir}/*
%{_initrddir}/puppet
/var/adm/fillup-templates/sysconfig.puppet
%config(noreplace) %{_sysconfdir}/puppet/puppet.conf
%doc CHANGELOG COPYING LICENSE README examples
-%exclude %{_sbindir}/puppetdoc
%config(noreplace) %{_sysconfdir}/logrotate.d/puppet
%dir %{_sysconfdir}/puppet
# These need to be owned by puppet so the server can
@@ -95,56 +97,122 @@ find %{buildroot}%{ruby_sitelibdir} -type f -perm +ugo+x -exec chmod a-x '{}' \;
%files server
%defattr(-, root, root, 0755)
%{_sbindir}/puppetmasterd
+%{_sbindir}/rcpuppetmaster
%{_sbindir}/puppetqd
-%{_bindir}/puppetrun
+%{_sbindir}/puppetrun
+%{_sbindir}/puppetca
%{_initrddir}/puppetmaster
%config(noreplace) %{_sysconfdir}/puppet/*
-%config(noreplace) %{_sysconfdir}/sysconfig/puppetmaster
-%{_sbindir}/puppetca
+%exclude %{_sysconfdir}/puppet/puppet.conf
+/var/adm/fillup-templates/sysconfig.puppetmaster
+%dir %{_sysconfdir}/puppet
%pre
/usr/sbin/groupadd -r puppet 2>/dev/null || :
/usr/sbin/useradd -g puppet -c "Puppet" \
- -s /sbin/nologin -r -d /var/lib/puppet puppet 2> /dev/null || :
+ -s /sbin/nologin -r -d /var/puppet puppet 2> /dev/null || :
%post
-/sbin/chkconfig --add puppet
-exit 0
+%{fillup_and_insserv -y puppet}
%post server
-/sbin/chkconfig --add puppetmaster
+%{fillup_and_insserv -n -y puppetmaster}
%preun
-if [ "$1" = 0 ] ; then
- /sbin/service puppet stop > /dev/null 2>&1
- /sbin/chkconfig --del puppet
-fi
+%stop_on_removal puppet
%preun server
-if [ "$1" = 0 ] ; then
- /sbin/service puppetmaster stop > /dev/null 2>&1
- /sbin/chkconfig --del puppetmaster
-fi
+%stop_on_removal puppetmaster
+
+%postun
+%restart_on_update puppet
+%{insserv_cleanup}
%postun server
-if [ "$1" -ge 1 ]; then
- /sbin/service puppetmaster try-restart > /dev/null 2>&1
-fi
+%restart_on_update puppetmaster
+%{insserv_cleanup}
%clean
%{__rm} -rf %{buildroot}
%changelog
-* Sat Feb 16 2008 James Turnbull <james@lovedthanlost.net> - 0.24.1-1
-- Fixed puppet configuation file references to match single puppet.conf file
-- Update versions for 0.24.1 release
+* Tue Sep 14 2010 Ben Kevan <ben.kevan@gmail.com> - 2.6.1
+- New version to 2.6.1
+- Add client.init and server.init from source since it's now included in the packages
+- Change BuildRequires Ruby version to match Requires Ruby version
+- Removed ruby-env patch, replaced with sed in prep
+- Update urls to puppetlabs.com
+
+* Wed Jul 21 2010 Ben Kevan <ben.kevan@gmail.com> - 2.6.0
+- New version and ruby version bump
+- Add puppetdoc to %_bindir (unknown why original suse package, excluded or forgot to add)
+- Corrected patch for ruby environment
+- Move binaries back to the correct directories
+
+* Wed Jul 14 2010 Ben Kevan <ben.kevan@gmail.com> - 0.25.5
+- New version.
+- Use original client, server.init names
+- Revert to puppetmaster
+- Fixed client.init and server.init and included $null and Should-Stop for both
+
+* Tue Mar 2 2010 Martin Vuk <martin.vuk@fri.uni-lj.si> - 0.25.4
+- New version.
+
+* Sun Aug 9 2009 Noah Fontes <nfontes@transtruct.org>
+- Fix build on SLES 9.
+- Enable puppet and puppet-server services by default.
+
+* Sat Aug 8 2009 Noah Fontes <nfontes@transtruct.org>
+- Fix a lot of relevant warnings from rpmlint.
+- Build on OpenSUSE 11.1 correctly.
+- Rename puppetmaster init scripts to puppet-server to correspond to the package name.
+
+* Wed Apr 22 2009 Leo Eraly <leo@unstable.be> - 0.24.8
+- New version.
+
+* Tue Dec 9 2008 Leo Eraly <leo@unstable.be> - 0.24.6
+- New version.
+
+* Fri Sep 5 2008 Leo Eraly <leo@unstable.be> - 0.24.5
+- New version.
+
+* Fri Jun 20 2008 Martin Vuk <martin.vuk@fri.uni-lj.si> - 0.24.4
+- Removed symlinks to old configuration files
+
+* Fri Dec 14 2007 Martin Vuk <martin.vuk@fri.uni-lj.si> - 0.24.0
+- New version.
+
+* Fri Jun 29 2007 Martin Vuk <martin.vuk@fri.uni-lj.si> - 0.23.0
+- New version.
+
+* Wed May 2 2007 Martin Vuk <martin.vuk@fri.uni-lj.si> - 0.22.4
+- New version. Includes provider for rug package manager.
+
+* Wed Apr 25 2007 Martin Vuk <martin.vuk@fri.uni-lj.si> - 0.22.3
+- New version. Added links /sbin/rcpuppet and /sbin/rcpuppetmaster
+
+* Sun Jan 7 2007 Martin Vuk <martin.vuk@fri.uni-lj.si> - 0.22.0
+- version bump
+
+* Tue Oct 3 2006 Martin Vuk <martin.vuk@fri.uni-lj.si> - 0.19.3-3
+- Made package arch dependant.
+
+* Sat Sep 23 2006 Martin Vuk <martin.vuk@fri.uni-lj.si> - 0.19.3-1
+- New version
+
+* Sun Sep 17 2006 Martin Vuk <martin.vuk@fri.uni-lj.si> - 0.19.1-1
+- New version
+
+* Tue Aug 30 2006 Martin Vuk <martin.vuk@fri.uni-lj.si> - 0.19.0-1
+- New version
+- No need to patch anymore :-), since my changes went into official release.
* Tue Aug 3 2006 Martin Vuk <martin.vuk@fri.uni-lj.si> - 0.18.4-3
- Replaced puppet-bin.patch with %build section from David's spec
* Tue Aug 1 2006 Martin Vuk <martin.vuk@fri.uni-lj.si> - 0.18.4-2
- Added supprot for enabling services in SuSE
-
+
* Tue Aug 1 2006 Martin Vuk <martin.vuk@fri.uni-lj.si> - 0.18.4-1
- New version and support for SuSE
diff --git a/conf/suse/puppet.suse.patch b/conf/suse/puppet.suse.patch
deleted file mode 100644
index 41974679f..000000000
--- a/conf/suse/puppet.suse.patch
+++ /dev/null
@@ -1,16 +0,0 @@
---- sbin/puppetmasterd.orig 2009-11-23 10:38:16.632264990 -0500
-+++ sbin/puppetmasterd 2009-11-23 10:38:28.884265155 -0500
-@@ -1,4 +1,4 @@
--#!/usr/bin/env ruby
-+#!/usr/bin/ruby
-
- #
- # = Synopsis
---- sbin/puppetd.orig 2009-11-23 10:38:23.240265893 -0500
-+++ sbin/puppetd 2009-11-23 10:38:35.044265271 -0500
-@@ -1,4 +1,4 @@
--#!/usr/bin/env ruby
-+#!/usr/bin/ruby
- # == Synopsis
- #
- # Retrieve the client configuration from the central puppet server and apply
diff --git a/conf/suse/server.init b/conf/suse/server.init
index e3a1d902a..50b9fef81 100644
--- a/conf/suse/server.init
+++ b/conf/suse/server.init
@@ -11,10 +11,10 @@
### BEGIN INIT INFO
# Provides: puppetmaster
-# Required-Start: $local_fs $network $syslog
-# Should-Start: $null
-# Required-Stop: $null
-# Should-Stop: $null
+# Required-Start: $local_fs $remote_fs $network $syslog
+# Should-Start: puppetmaster
+# Required-Stop: $local_fs $remote_fs $network $syslog
+# Should-Stop: puppetmaster
# Default-Start: 3 4 5
# Default-Stop: 0 1 2 6
# Short-Description: puppetmaster
diff --git a/ext/cert_inspector b/ext/cert_inspector
new file mode 100755
index 000000000..1effcaa04
--- /dev/null
+++ b/ext/cert_inspector
@@ -0,0 +1,140 @@
+#!/usr/bin/env ruby
+require 'openssl'
+
+class X509Collector
+ include Enumerable
+
+ def initialize
+ @collected_data = {}
+ end
+
+ def interpret_contents(contents)
+ cls = case contents.split("\n")[0]
+ when /BEGIN X509 CRL/ then OpenSSL::X509::CRL
+ when /BEGIN CERTIFICATE REQUEST/ then OpenSSL::X509::Request
+ when /BEGIN CERTIFICATE/ then OpenSSL::X509::Certificate
+ when /BEGIN RSA (PRIVATE|PUBLIC) KEY/ then OpenSSL::PKey::RSA
+ else return nil
+ end
+ cls.new(contents)
+ rescue
+ nil
+ end
+
+ def expected_non_x509_files
+ ['inventory.txt', 'ca.pass', 'serial']
+ end
+
+ def investigate_path(path)
+ if File.directory?(path)
+ Dir.foreach(path) do |x|
+ next if ['.', '..'].include? x
+ investigate_path File.join(path, x)
+ end
+ else
+ contents = File.read path
+ meaning = interpret_contents contents
+ unless meaning || expected_non_x509_files.include?(File.basename(path))
+ puts "WARNING: file #{path.inspect} could not be interpreted"
+ end
+ @collected_data[path] = meaning if meaning
+ end
+ end
+
+ def each(&block)
+ @collected_data.each(&block)
+ end
+
+ def extract_public_key_info(path, meaning)
+ case meaning
+ when OpenSSL::PKey::RSA
+ if meaning.private?
+ [meaning.public_key, 2, path]
+ else
+ [meaning, 3, path]
+ end
+ when OpenSSL::X509::Certificate
+ [meaning.public_key, 0, meaning.subject.to_s]
+ when OpenSSL::X509::Request
+ [meaning.public_key, 1, meaning.subject.to_s]
+ end
+ end
+
+ def who_signed(meaning, key_names, keys)
+ signing_key = keys.find { |key| meaning.verify(key) }
+ if signing_key then "#{key_names[signing_key.to_s]}" else "???" end
+ end
+
+ def explain(meaning, key_names, keys)
+ case meaning
+ when OpenSSL::PKey::RSA
+ if meaning.private?
+ "Private key for #{key_names[meaning.public_key.to_s]}"
+ else
+ "Public key for #{key_names[meaning.public_key.to_s]}"
+ end
+ when OpenSSL::X509::Certificate
+ signature_desc = who_signed(meaning, key_names, keys)
+ "Certificate assigning name #{meaning.subject.to_s} to #{key_names[meaning.public_key.to_s]}\n serial number #{meaning.serial}\n issued by #{meaning.issuer.to_s}\n signed by #{signature_desc}"
+ when OpenSSL::X509::Request
+ signature_desc = who_signed(meaning, key_names, keys)
+ "Certificate request for #{meaning.subject.to_s} having key #{key_names[meaning.public_key.to_s]}\n signed by #{signature_desc}"
+ when OpenSSL::X509::CRL
+ signature_desc = who_signed(meaning, key_names, keys)
+ revoked_serial_numbers = meaning.revoked.map { |r| r.serial }
+ revoked_desc = if revoked_serial_numbers.count > 0 then "serial numbers #{revoked_serial_numbers.inspect}" else "nothing" end
+ "Certificate revocation list revoking #{revoked_desc}\n issued by #{meaning.issuer.to_s}\n signed by #{signature_desc}"
+ else
+ "Unknown"
+ end
+ end
+
+ # Yield unique public keys, with a canonical name for each.
+ def collect_public_keys
+ key_data = {} # pem => (priority, name, public_key)
+ @collected_data.collect do |path, meaning|
+ begin
+ next unless public_key_info = extract_public_key_info(path, meaning)
+ public_key, priority, name = public_key_info
+ pem = public_key.to_s
+ existing_priority, existing_name, existing_public_key = key_data[pem]
+ next if existing_priority and existing_priority < priority
+ key_data[pem] = priority, name, public_key
+ rescue
+ puts "exception!"
+ end
+ end
+ name_to_key_hash = {}
+ key_data.each do |pem, data|
+ priority, name, public_key = data
+ if name_to_key_hash[name]
+ suffix_num = 2
+ while name_to_key_hash[name + " (#{suffix_num})"]
+ suffix_num += 1
+ end
+ name = name + " (#{suffix_num})"
+ end
+ name_to_key_hash[name] = public_key
+ end
+ key_names = {}
+ keys = []
+ name_to_key_hash.each do |name, public_key|
+ key_names[public_key.to_s] = "key<#{name}>"
+ keys << public_key
+ end
+ [key_names, keys]
+ end
+end
+
+collector = X509Collector.new
+ARGV.each do |path|
+ collector.investigate_path(path)
+end
+key_names, keys = collector.collect_public_keys
+collector.map do |path, meaning|
+ [collector.explain(meaning, key_names, keys), path]
+end.sort.each do |description, path|
+ puts "#{path}:"
+ puts " #{description}"
+ puts
+end
diff --git a/ext/envpuppet b/ext/envpuppet
new file mode 100755
index 000000000..d921a19b8
--- /dev/null
+++ b/ext/envpuppet
@@ -0,0 +1,80 @@
+#! /bin/bash
+#
+# Jeff McCune <jeff@puppetlabs.com>
+# 2010-10-20
+#
+# Copyright (c) 2010, Puppet Labs
+# License: BSD 3-clause license
+#
+# This script provides a simple way to execute puppet and related tools
+# directly from a git clone of the upstream repositories. This allows you to
+# quickly switch branches and test different versions of code without much
+# friction.
+#
+# NOTE: There may be issues if puppet, facter, etc... are already installed
+# into RUBY's site_ruby directory. If you run into strange problems, make sure
+# the correct ruby libraries are being loaded...
+#
+# Sample Usage:
+# =============
+# cd ~/src
+# git clone git://github.com/puppetlabs/puppet.git
+# git clone git://github.com/puppetlabs/facter.git
+# pushd puppet
+# git checkout tags/2.6.1
+# popd
+# pushd facter
+# git checkout tags/1.5.8
+# export ENVPUPPET_BASEDIR=/home/jeff/src
+# envpuppet puppet --version
+# 2.6.1
+# envpuppet facter --version
+# 1.5.8
+
+set -e
+set -u
+
+if test -d puppet -o -d facter; then
+ echo " WARNING!"
+ echo " Strange things happen if puppet or facter are in the"
+ echo " current working directory"
+ echo " (import errors from ruby are a prime example)"
+ echo " WARNING!"
+ echo ""
+ echo "I suggest changing to ~ or /tmp or something..."
+ echo ""
+ echo "Sleeping 2 seconds."
+ echo ""
+ sleep 2
+fi
+
+# Set this to where you check out puppet and facter
+: ${ENVPUPPET_BASEDIR:="${HOME}/src"}
+
+# git://github.com/reductivelabs/puppet.git
+mypath="${ENVPUPPET_BASEDIR}/puppet/sbin:${ENVPUPPET_BASEDIR}/puppet/bin"
+myrubylib="${ENVPUPPET_BASEDIR}/puppet/lib"
+
+# git://github.com/reductivelabs/facter.git
+mypath="${mypath}:${ENVPUPPET_BASEDIR}/facter/bin"
+myrubylib="${myrubylib}:${ENVPUPPET_BASEDIR}/facter/lib"
+
+# http://github.com/jamtur01/puppet-scaffold.git
+mypath="${mypath}:${ENVPUPPET_BASEDIR}/puppet-scaffold/bin"
+myrubylib="${myrubylib}:${ENVPUPPET_BASEDIR}/puppet-scaffold/lib"
+
+# http://github.com/puppetlabs/puppet-module-tool.git
+# Also known as "pmt" Will become "puppet module"
+mypath="${mypath}:${ENVPUPPET_BASEDIR}/puppet-module-tool/bin"
+myrubylib="${myrubylib}:${ENVPUPPET_BASEDIR}/puppet-module-tool/lib"
+
+# Use the existing environment, if present.
+# Default to no value to prevent unbound variable issues
+mypath="${mypath}:${PATH:-}"
+myrubylib="${myrubylib}:${RUBYLIB:-}"
+
+# Trim any trailing colons from the path list.
+export PATH="${mypath%%:}"
+export RUBYLIB="${myrubylib%%:}"
+
+exec "$@"
diff --git a/ext/extlookup.rb b/ext/extlookup.rb
deleted file mode 100644
index d87583ba7..000000000
--- a/ext/extlookup.rb
+++ /dev/null
@@ -1,181 +0,0 @@
-# Puppet External Data Sources
-#
-# This is a parser function to read data from external files, this version
-# uses CSV files but the concept can easily be adjust for databases, yaml
-# or any other queryable data source.
-#
-# The object of this is to make it obvious when it's being used, rather than
-# magically loading data in when an module is loaded I prefer to look at the code
-# and see statements like:
-#
-# $snmp_contact = extlookup("snmp_contact")
-#
-# The above snippet will load the snmp_contact value from CSV files, this in its
-# own is useful but a common construct in puppet manifests is something like this:
-#
-# case $domain {
-# "myclient.com": { $snmp_contact = "John Doe <john@myclient.com>" }
-# default: { $snmp_contact = "My Support <support@my.com>" }
-# }
-#
-# Over time there will be a lot of this kind of thing spread all over your manifests
-# and adding an additional client involves grepping through manifests to find all the
-# places where you have constructs like this.
-#
-# This is a data problem and shouldn't be handled in code, a using this function you
-# can do just that.
-#
-# First you configure it in site.pp:
-# $extlookup_datadir = "/etc/puppet/manifests/extdata"
-# $extlookup_precedence = ["%{fqdn}", "domain_%{domain}", "common"]
-#
-# The array tells the code how to resolve values, first it will try to find it in
-# web1.myclient.com.csv then in domain_myclient.com.csv and finally in common.csv
-#
-# Now create the following data files in /etc/puppet/manifests/extdata
-#
-# domain_myclient.com.csv:
-# snmp_contact,John Doe <john@myclient.com>
-# root_contact,support@%{domain}
-# client_trusted_ips,192.168.1.130,192.168.10.0/24
-#
-# common.csv:
-# snmp_contact,My Support <support@my.com>
-# root_contact,support@my.com
-#
-# Now you can replace the case statement with the simple single line to achieve
-# the exact same outcome:
-#
-# $snmp_contact = extlookup("snmp_contact")
-#
-# The obove code shows some other features, you can use any fact or variable that
-# is in scope by simply using %{varname} in your data files, you can return arrays
-# by just having multiple values in the csv after the initial variable name.
-#
-# In the event that a variable is nowhere to be found a critical error will be raised
-# that will prevent your manifest from compiling, this is to avoid accidentally putting
-# in empty values etc. You can however specify a default value:
-#
-# $ntp_servers = extlookup("ntp_servers", "1.${country}.pool.ntp.org")
-#
-# In this case it will default to "1.${country}.pool.ntp.org" if nothing is defined in
-# any data file.
-#
-# You can also specify an additional data file to search first before any others at use
-# time, for example:
-#
-# $version = extlookup("rsyslog_version", "present", "packages")
-#
-# package{"rsyslog": ensure => $version }
-#
-# This will look for a version configured in packages.csv and then in the rest as configured
-# by $extlookup_precedence if it's not found anywhere it will default to "present", this kind
-# of use case makes puppet a lot nicer for managing large amounts of packages since you do not
-# need to edit a load of manifests to do simple things like adjust a desired version number.
-#
-# For more information on installing and writing your own custom functions see:
-# http://docs.puppetlabs.com/guides/custom_functions.html
-#
-# For further help contact Volcane on #puppet
-require 'csv'
-
-module Puppet::Parser::Functions
- newfunction(:extlookup, :type => :rvalue) do |args|
- key = args[0]
- default = "_ExtUNSET_"
- datafile = "_ExtUNSET_"
-
- default = args[1] if args[1]
- datafile = args[2] if args[2]
-
- extlookup_datadir = lookupvar('extlookup_datadir')
- extlookup_precedence = Array.new
-
- # precedence values can have variables embedded in them
- # in the form %{fqdn}, you could for example do
- #
- # $extlookup_precedence = ["hosts/%{fqdn}", "common"]
- #
- # this will result in /path/to/extdata/hosts/your.box.com.csv
- # being searched.
- #
- # we parse the precedence here because the best place to specify
- # it would be in site.pp but site.pp is only evaluated at startup
- # so $fqdn etc would have no meaning there, this way it gets evaluated
- # each run and has access to the right variables for that run
- lookupvar('extlookup_precedence').each do |prec|
- while prec =~ /%\{(.+?)\}/
- prec.gsub!(/%\{#{$1}\}/, lookupvar($1))
- end
-
- extlookup_precedence << prec
- end
-
-
- datafiles = Array.new
-
- # if we got a custom data file, put it first in the array of search files
- if datafile != ""
- datafiles << extlookup_datadir + "/#{datafile}.csv" if File.exists?(extlookup_datadir + "/#{datafile}.csv")
- end
-
- extlookup_precedence.each do |d|
- datafiles << extlookup_datadir + "/#{d}.csv"
- end
-
- desired = "_ExtUNSET_"
-
- datafiles.each do |file|
- parser.watch_file(file) if File.exists?(file)
-
- if desired == "_ExtUNSET_"
- if File.exists?(file)
- result = CSV.read(file).find_all do |r|
- r[0] == key
- end
-
-
- # return just the single result if theres just one,
- # else take all the fields in the csv and build an array
- if result.length > 0
- if result[0].length == 2
- val = result[0][1].to_s
-
- # parse %{}'s in the CSV into local variables using lookupvar()
- while val =~ /%\{(.+?)\}/
- val.gsub!(/%\{#{$1}\}/, lookupvar($1))
- end
-
- desired = val
- elsif result[0].length > 1
- length = result[0].length
- cells = result[0][1,length]
-
- # Individual cells in a CSV result are a weird data type and throws
- # puppets yaml parsing, so just map it all to plain old strings
- desired = cells.map do |c|
- # parse %{}'s in the CSV into local variables using lookupvar()
- while c =~ /%\{(.+?)\}/
- c.gsub!(/%\{#{$1}\}/, lookupvar($1))
- end
-
- c.to_s
- end
- end
- end
- end
- end
- end
-
- # don't accidently return nil's and such rather throw a parse error
- if desired == "_ExtUNSET_" && default == "_ExtUNSET_"
- raise Puppet::ParseError, "No match found for '#{key}' in any data file during extlookup()"
- else
- desired = default if desired == "_ExtUNSET_"
- end
-
- desired
- end
-end
-
-# vi:tabstop=4:expandtab:ai
diff --git a/ext/logcheck/puppet b/ext/logcheck/puppet
index f3280c7b7..7de06aa0f 100644
--- a/ext/logcheck/puppet
+++ b/ext/logcheck/puppet
@@ -1,23 +1,23 @@
-^\w{3} [ :0-9]{11} [._[:alnum:]-]+ puppetmasterd\[[0-9]+\]: (Handled resources in|Resource comparison took|Searched for (host|resources|resource params and tags) in) [0-9.]+ seconds
-^\w{3} [ :0-9]{11} [._[:alnum:]-]+ puppetmasterd\[[0-9]+\]: Starting Puppet server version [.0-9]+$
-^\w{3} [ :0-9]{11} [._[:alnum:]-]+ puppetmasterd\[[0-9]+\]: Compiled catalog for [._[:alnum:]-]+ in [.0-9]+ seconds$
-^\w{3} [ :0-9]{11} [._[:alnum:]-]+ puppetmasterd\[[0-9]+\]: Caught TERM; shutting down$
-^\w{3} [ :0-9]{11} [._[:alnum:]-]+ puppetmasterd\[[0-9]+\]: Shutting down$
-^\w{3} [ :0-9]{11} [._[:alnum:]-]+ puppetd\[[0-9]+\]: Starting Puppet client version [.0-9]+$
-^\w{3} [ :0-9]{11} [._[:alnum:]-]+ puppetd\[[0-9]+\]: getting config$
-^\w{3} [ :0-9]{11} [._[:alnum:]-]+ puppetd\[[0-9]+\]: Caching configuration at [\/._[:alnum:]-]+$
-^\w{3} [ :0-9]{11} [._[:alnum:]-]+ puppetd\[[0-9]+\]: Loaded state in [.0-9]+ seconds$
-^\w{3} [ :0-9]{11} [._[:alnum:]-]+ puppetd\[[0-9]+\]: Calling puppetmaster.getconfig$
-^\w{3} [ :0-9]{11} [._[:alnum:]-]+ puppetd\[[0-9]+\]: Retrieved configuration in [.0-9]+ seconds$
-^\w{3} [ :0-9]{11} [._[:alnum:]-]+ puppetd\[[0-9]+\]: Starting configuration run$
-^\w{3} [ :0-9]{11} [._[:alnum:]-]+ puppetd\[[0-9]+\]: Finished configuration run in [.0-9]+ seconds$
-^\w{3} [ :0-9]{11} [._[:alnum:]-]+ puppetd\[[0-9]+\]: Caught (TERM|INT); shutting down$
-^\w{3} [ :0-9]{11} [._[:alnum:]-]+ puppetd\[[0-9]+\]: Shutting down$
-^\w{3} [ :0-9]{11} [._[:alnum:]-]+ puppetd\[[0-9]+\]: Restarting with .*$
-^\w{3} [ :0-9]{11} [._[:alnum:]-]+ puppetd\[[0-9]+\]: Starting catalog run$
-^\w{3} [ :0-9]{11} [._[:alnum:]-]+ puppetd\[[0-9]+\]: Finished catalog run in [.0-9]+ seconds$
-^\w{3} [ :0-9]{11} [._[:alnum:]-]+ puppetd\[[0-9]+\]: Loading fact .*$
-^\w{3} [ :0-9]{11} [._[:alnum:]-]+ puppetd\[[0-9]+\]: Ignoring cache$
-^\w{3} [ :0-9]{11} [._[:alnum:]-]+ puppetd\[[0-9]+\]: Ignoring --listen on onetime run$
-^\w{3} [ :0-9]{11} [._[:alnum:]-]+ puppetd\[[0-9]+\]: Retrieving plugins$
-^\w{3} [ :0-9]{11} [._[:alnum:]-]+ puppetmasterd\[[0-9]+\]: Reopening log files$
+^\w{3} [ :0-9]{11} [._[:alnum:]-]+ puppet-master\[[0-9]+\]: (Handled resources in|Resource comparison took|Searched for (host|resources|resource params and tags) in) [0-9.]+ seconds
+^\w{3} [ :0-9]{11} [._[:alnum:]-]+ puppet-master\[[0-9]+\]: Starting Puppet server version [.0-9]+$
+^\w{3} [ :0-9]{11} [._[:alnum:]-]+ puppet-master\[[0-9]+\]: Compiled catalog for [._[:alnum:]-]+ in [.0-9]+ seconds$
+^\w{3} [ :0-9]{11} [._[:alnum:]-]+ puppet-master\[[0-9]+\]: Caught TERM; shutting down$
+^\w{3} [ :0-9]{11} [._[:alnum:]-]+ puppet-master\[[0-9]+\]: Shutting down$
+^\w{3} [ :0-9]{11} [._[:alnum:]-]+ puppet-agent\[[0-9]+\]: Starting Puppet client version [.0-9]+$
+^\w{3} [ :0-9]{11} [._[:alnum:]-]+ puppet-agent\[[0-9]+\]: getting config$
+^\w{3} [ :0-9]{11} [._[:alnum:]-]+ puppet-agent\[[0-9]+\]: Caching configuration at [\/._[:alnum:]-]+$
+^\w{3} [ :0-9]{11} [._[:alnum:]-]+ puppet-agent\[[0-9]+\]: Loaded state in [.0-9]+ seconds$
+^\w{3} [ :0-9]{11} [._[:alnum:]-]+ puppet-agent\[[0-9]+\]: Calling puppetmaster.getconfig$
+^\w{3} [ :0-9]{11} [._[:alnum:]-]+ puppet-agent\[[0-9]+\]: Retrieved configuration in [.0-9]+ seconds$
+^\w{3} [ :0-9]{11} [._[:alnum:]-]+ puppet-agent\[[0-9]+\]: Starting configuration run$
+^\w{3} [ :0-9]{11} [._[:alnum:]-]+ puppet-agent\[[0-9]+\]: Finished configuration run in [.0-9]+ seconds$
+^\w{3} [ :0-9]{11} [._[:alnum:]-]+ puppet-agent\[[0-9]+\]: Caught (TERM|INT); shutting down$
+^\w{3} [ :0-9]{11} [._[:alnum:]-]+ puppet-agent\[[0-9]+\]: Shutting down$
+^\w{3} [ :0-9]{11} [._[:alnum:]-]+ puppet-agent\[[0-9]+\]: Restarting with .*$
+^\w{3} [ :0-9]{11} [._[:alnum:]-]+ puppet-agent\[[0-9]+\]: Starting catalog run$
+^\w{3} [ :0-9]{11} [._[:alnum:]-]+ puppet-agent\[[0-9]+\]: Finished catalog run in [.0-9]+ seconds$
+^\w{3} [ :0-9]{11} [._[:alnum:]-]+ puppet-agent\[[0-9]+\]: Loading fact .*$
+^\w{3} [ :0-9]{11} [._[:alnum:]-]+ puppet-agent\[[0-9]+\]: Ignoring cache$
+^\w{3} [ :0-9]{11} [._[:alnum:]-]+ puppet-agent\[[0-9]+\]: Ignoring --listen on onetime run$
+^\w{3} [ :0-9]{11} [._[:alnum:]-]+ puppet-agent\[[0-9]+\]: Retrieving plugins$
+^\w{3} [ :0-9]{11} [._[:alnum:]-]+ puppet-master\[[0-9]+\]: Reopening log files$
diff --git a/ext/puppet-load.rb b/ext/puppet-load.rb
new file mode 100644
index 000000000..35bee6ef8
--- /dev/null
+++ b/ext/puppet-load.rb
@@ -0,0 +1,393 @@
+#!/usr/bin/env ruby
+# == Synopsis
+#
+# This tool can exercize a puppetmaster by simulating an arbitraty number of concurrent clients
+# in a lightweight way.
+#
+# = Prerequisites
+#
+# This tool requires Event Machine and em-http-request, and an installation of Puppet.
+# Event Machine can be installed from gem.
+# em-http-request can be installed from gem.
+#
+# = Usage
+#
+# puppet-load [-d|--debug] [--concurrency <num>] [--repeat <num>] [-V|--version] [-v|--verbose]
+# [--node <host.domain.com>] [--facts <factfile>] [--cert <certfile>] [--key <keyfile>]
+# [--factsdir <factsdir>] [--server <server.domain.com>]
+#
+# = Description
+#
+# This is a simple script meant for doing performance tests of puppet masters. It does this
+# by simulating concurrent connections to a puppet master and asking for catalog compilation.
+#
+# = Options
+#
+# Unlike other puppet executables, puppet-load doesn't parse puppet.conf nor use puppet options
+#
+# debug::
+# Enable full debugging.
+#
+# concurreny::
+# Number of simulated concurrent clients.
+#
+# server::
+# Set the puppet master hostname or IP address..
+#
+# node::
+# Set the fully-qualified domain name of the client. This option can be given multiple
+# times. In this case puppet-load will ask for catalog compilation of all the given nodes
+# on a round robin way.
+#
+# help::
+# Print this help message
+#
+# facts::
+# This can be used to provide facts for the compilation, directly from a YAML
+# file as found in the clientyaml directory. If none are provided, puppet-load
+# will look by itself using Puppet facts indirector.
+#
+# factsdir::
+# Specify a directory where the yaml facts files can be found. If provided puppet-load
+# will look up facts in this directory. If not found it will resort to using Puppet Facts
+# indirector.
+#
+# cert::
+# This option is mandatory. It should be set to the cert PEM file that will be used
+# to quthenticate the client connections.
+#
+# key::
+# This option is mandatory. It should be set to the private key PEM file that will be used
+# to quthenticate the client connections.
+#
+# timeout::
+# The number of seconds after which a simulated client is declared in error if it didn't get
+# a catalog. The default is 180s.
+#
+# repeat::
+# How many times to perform the test. This means puppet-load will ask for
+# concurrency * repeat catalogs.
+#
+# verbose::
+# Turn on verbose reporting.
+#
+# version::
+# Print the puppet version number and exit.
+#
+# = Example usage
+#
+# SINGLE NODE:
+# 1) On the master host, generate a new certificate and private key for our test host:
+# puppet ca --generate puppet-load.domain.com
+#
+# 2) Copy the cert and key to the puppet-load host (which can be the same as the master one)
+#
+# 3) On the master host edit or create the auth.conf so that the catalog ACL match:
+# path ~ ^/catalog/([^/]+)$
+# method find
+# allow $1
+# allow puppet-load.domain.com
+#
+# 4) launch the master(s)
+#
+# 5) Prepare or get a fact file. One way to get one is to look on the master in $vardir/yaml/ for the host
+# you want to simulate.
+#
+# 5) launch puppet-load
+# puppet-load -debug --node server.domain.com --server master.domain.com --facts server.domain.com.yaml --concurrency 2 --repeat 20
+#
+# MULTIPLE NODES:
+# 1) On the master host, generate a new certificate and private key for our test host:
+# puppet ca --generate puppet-load.domain.com
+#
+# 2) Copy the cert and key to the puppet-load host (which can be the same as the master one)
+#
+# 3) On the master host edit or create the auth.conf so that the catalog ACL match:
+# path ~ ^/catalog/([^/]+)$
+# method find
+# allow $1
+# allow puppet-load.domain.com
+#
+# 4) launch the master(s)
+#
+# 5) Prepare or get a fact file. One way to get one is to look on the master in $vardir/yaml/ for the host
+# you want to simulate.
+#
+# 5) launch puppet-load
+# puppet-load -debug --node server1.domain.com --node server2.domain.com --node server3.domain.com \
+# --server master.domain.com --factsdir /var/lib/puppet/yaml/facts --concurrency 2 --repeat 20
+#
+# puppet-load will load facts file in the --factsdir directory based on the node name.
+#
+# = TODO
+# * More output stats for error connections (ie report errors, HTTP code...)
+#
+#
+
+# Do an initial trap, so that cancels don't get a stack trace.
+trap(:INT) do
+ $stderr.puts "Cancelling startup"
+ exit(1)
+end
+
+require 'rubygems'
+require 'eventmachine'
+require 'em-http'
+require 'getoptlong'
+require 'puppet'
+
+$cmdargs = [
+ [ "--concurrency", "-c", GetoptLong::REQUIRED_ARGUMENT ],
+ [ "--node", "-n", GetoptLong::REQUIRED_ARGUMENT ],
+ [ "--facts", GetoptLong::REQUIRED_ARGUMENT ],
+ [ "--factsdir", GetoptLong::REQUIRED_ARGUMENT ],
+ [ "--repeat", "-r", GetoptLong::REQUIRED_ARGUMENT ],
+ [ "--cert", "-C", GetoptLong::REQUIRED_ARGUMENT ],
+ [ "--key", "-k", GetoptLong::REQUIRED_ARGUMENT ],
+ [ "--timeout", "-t", GetoptLong::REQUIRED_ARGUMENT ],
+ [ "--server", "-s", GetoptLong::REQUIRED_ARGUMENT ],
+ [ "--debug", "-d", GetoptLong::NO_ARGUMENT ],
+ [ "--help", "-h", GetoptLong::NO_ARGUMENT ],
+ [ "--verbose", "-v", GetoptLong::NO_ARGUMENT ],
+ [ "--version", "-V", GetoptLong::NO_ARGUMENT ],
+]
+
+Puppet::Util::Log.newdestination(:console)
+
+times = {}
+
+def read_facts(file)
+ Puppet.debug("reading facts from: #{file}")
+ fact = YAML.load(File.read(file))
+end
+
+
+result = GetoptLong.new(*$cmdargs)
+
+$args = {}
+$options = {:repeat => 1, :concurrency => 1, :pause => false, :cert => nil, :key => nil, :timeout => 180, :masterport => 8140, :node => [], :factsdir => nil}
+
+begin
+ result.each { |opt,arg|
+ case opt
+ when "--concurrency"
+ begin
+ $options[:concurrency] = Integer(arg)
+ rescue => detail
+ $stderr.puts "The argument to 'fork' must be an integer"
+ exit(14)
+ end
+ when "--node"
+ $options[:node] << arg
+ when "--factsdir"
+ $options[:factsdir] = arg
+ when "--server"
+ $options[:server] = arg
+ when "--masterport"
+ $options[:masterport] = arg
+ when "--facts"
+ $options[:facts] = arg
+ when "--repeat"
+ $options[:repeat] = Integer(arg)
+ when "--help"
+ if Puppet.features.usage?
+ RDoc::usage && exit
+ else
+ puts "No help available unless you have RDoc::usage installed"
+ exit
+ end
+ when "--version"
+ puts "%s" % Puppet.version
+ exit
+ when "--verbose"
+ Puppet::Util::Log.level = :info
+ Puppet::Util::Log.newdestination(:console)
+ when "--debug"
+ Puppet::Util::Log.level = :debug
+ Puppet::Util::Log.newdestination(:console)
+ when "--cert"
+ $options[:cert] = arg
+ when "--key"
+ $options[:key] = arg
+ end
+ }
+rescue GetoptLong::InvalidOption => detail
+ $stderr.puts detail
+ $stderr.puts "Try '#{$0} --help'"
+ exit(1)
+end
+
+unless $options[:cert] and $options[:key]
+ raise "--cert and --key are mandatory to authenticate the client"
+end
+
+parameters = []
+
+unless $options[:node].size > 0
+ raise "--node is a mandatory argument. It tells to the master what node to compile"
+end
+
+$options[:node].each do |node|
+ factfile = $options[:factsdir] ? File.join($options[:factsdir], node + ".yaml") : $options[:facts]
+ unless fact = read_facts(factfile) or fact = Puppet::Node::Facts.find(node)
+ raise "Could not find facts for %s" % node
+ end
+ fact.values["fqdn"] = node
+ fact.values["hostname"] = node.sub(/\..+/, '')
+ fact.values["domain"] = node.sub(/^[^.]+\./, '')
+
+ parameters << {:facts_format => "b64_zlib_yaml", :facts => CGI.escape(fact.render(:b64_zlib_yaml))}
+end
+
+
+class RequestPool
+ include EventMachine::Deferrable
+
+ attr_reader :requests, :responses, :times, :sizes
+ attr_reader :repeat, :concurrency, :max_request
+
+ def initialize(concurrency, repeat, parameters)
+ @parameters = parameters
+ @current_request = 0
+ @max_request = repeat * concurrency
+ @repeat = repeat
+ @concurrency = concurrency
+ @requests = []
+ @responses = {:succeeded => [], :failed => []}
+ @times = {}
+ @sizes = {}
+
+ # initial spawn
+ (1..concurrency).each do |i|
+ spawn
+ end
+
+ end
+
+ def spawn_request(index)
+ @times[index] = Time.now
+ @sizes[index] = 0
+ nodeidx = index % $options[:node].size
+ node = $options[:node][nodeidx]
+ EventMachine::HttpRequest.new("https://#{$options[:server]}:#{$options[:masterport]}/production/catalog/#{node}").get(
+ :port => $options[:masterport],
+ :query => @parameters[nodeidx],
+ :timeout => $options[:timeout],
+ :head => { "Accept" => "pson, yaml, b64_zlib_yaml, marshal, dot, raw", "Accept-Encoding" => "gzip, deflate" },
+ :ssl => { :private_key_file => $options[:key],
+ :cert_chain_file => $options[:cert],
+ :verify_peer => false } ) do
+ @times[index] = Time.now
+ @sizes[index] = 0
+ Puppet.debug("starting client #{index} for #{node}")
+ end
+ end
+
+ def add(index, conn)
+ @requests.push(conn)
+
+ conn.stream { |data|
+ @sizes[index] += data.length
+ }
+
+ conn.callback {
+ @times[index] = Time.now - @times[index]
+ code = conn.response_header.status
+ if code >= 200 && code < 300
+ Puppet.debug("Client #{index} finished successfully")
+ @responses[:succeeded].push(conn)
+ else
+ Puppet.debug("Client #{index} finished with HTTP code #{code}")
+ @responses[:failed].push(conn)
+ end
+ check_progress
+ }
+
+ conn.errback {
+ Puppet.debug("Client #{index} finished with an error: #{conn.error}")
+ @times[index] = Time.now - @times[index]
+ @responses[:failed].push(conn)
+ check_progress
+ }
+ end
+
+ def all_responses
+ @responses[:succeeded] + @responses[:failed]
+ end
+
+ protected
+
+ def check_progress
+ spawn unless all_spawned?
+ succeed if all_finished?
+ end
+
+ def all_spawned?
+ @requests.size >= max_request
+ end
+
+ def all_finished?
+ @responses[:failed].size + @responses[:succeeded].size >= max_request
+ end
+
+ def spawn
+ add(@current_request, spawn_request(@current_request))
+ @current_request += 1
+ end
+end
+
+
+def mean(array)
+ array.inject(0) { |sum, x| sum += x } / array.size.to_f
+end
+
+def median(array)
+ array = array.sort
+ m_pos = array.size / 2
+ return array.size % 2 == 1 ? array[m_pos] : mean(array[m_pos-1..m_pos])
+end
+
+def format_bytes(bytes)
+ if bytes < 1024
+ "%.2f B" % bytes
+ elsif bytes < 1024 * 1024
+ "%.2f KiB" % (bytes/1024.0)
+ else
+ "%.2f MiB" % (bytes/(1024.0*1024.0))
+ end
+end
+
+EM::run {
+
+ start = Time.now
+ multi = RequestPool.new($options[:concurrency], $options[:repeat], parameters)
+
+ multi.callback do
+ duration = Time.now - start
+ puts "#{multi.max_request} requests finished in #{duration} s"
+ puts "#{multi.responses[:failed].size} requests failed"
+ puts "Availability: %3.2f %%" % (100.0*multi.responses[:succeeded].size/(multi.responses[:succeeded].size+multi.responses[:failed].size))
+
+ minmax = multi.times.values.minmax
+ all_time = multi.times.values.reduce(:+)
+
+ puts "\nTime (s):"
+ puts "\tmin: #{minmax[0]} s"
+ puts "\tmax: #{minmax[1]} s"
+ puts "\taverage: #{mean(multi.times.values)} s"
+ puts "\tmedian: #{median(multi.times.values)} s"
+
+ puts "\nConcurrency: %.2f" % (all_time/duration)
+ puts "Transaction Rate (tps): %.2f t/s" % (multi.max_request / duration)
+
+ transferred = multi.sizes.values.reduce(:+)
+
+ puts "\nReceived bytes: #{format_bytes(transferred)}"
+ puts "Throughput: %.5f MiB/s" % (transferred/duration/(1024.0*1024.0))
+
+ # this is the end
+ EventMachine.stop
+ end
+}
+
+
diff --git a/ext/puppetlast b/ext/puppetlast
deleted file mode 100755
index 7434368a3..000000000
--- a/ext/puppetlast
+++ /dev/null
@@ -1,16 +0,0 @@
-#!/usr/bin/env ruby
-# Puppetlast, a script to output the last check-in time of nodes. Also outputs the cached configuration state, if expired or not.
-#
-# AJ "Fujin" Christensen <aj@junglist.gen.nz>
-#
-require 'puppet'
-require 'time'
-
-Puppet[:config] = "/etc/puppet/puppet.conf"
-Puppet.parse_config
-Puppet[:name] = "puppetmasterd"
-Puppet::Node::Facts.terminus_class = :yaml
-
-Puppet::Node::Facts.search("*").sort { |a,b| a.name <=> b.name }.each do |node|
- puts "#{node.name} checked in #{((Time.now - Time.parse(node.values[:_timestamp].to_s)) / 60).floor} minutes ago. Version #{node.values['puppetversion']}#{node.expired? ? ' Cache expired.' : ''}"
-end
diff --git a/ext/puppetstoredconfigclean.rb b/ext/puppetstoredconfigclean.rb
index 34dd72f5d..16f39efa1 100644
--- a/ext/puppetstoredconfigclean.rb
+++ b/ext/puppetstoredconfigclean.rb
@@ -19,11 +19,11 @@ end
opts = GetoptLong.new(
-
+
[ "--config", "-c", GetoptLong::REQUIRED_ARGUMENT ],
[ "--help", "-h", GetoptLong::NO_ARGUMENT ],
[ "--usage", "-u", GetoptLong::NO_ARGUMENT ],
-
+
[ "--version", "-v", GetoptLong::NO_ARGUMENT ]
)
@@ -54,7 +54,7 @@ printusage(1) unless ARGV.size > 0
require 'puppet/rails'
Puppet[:config] = config
Puppet.parse_config
-pm_conf = Puppet.settings.instance_variable_get(:@values)[:puppetmasterd]
+pm_conf = Puppet.settings.instance_variable_get(:@values)[:master]
adapter = pm_conf[:dbadapter]
args = {:adapter => adapter, :log_level => pm_conf[:rails_loglevel]}
@@ -70,8 +70,6 @@ case adapter
args[:port] = pm_conf[:dbport] unless pm_conf[:dbport].to_s.empty?
socket = pm_conf[:dbsocket]
args[:socket] = socket unless socket.to_s.empty?
- connections = pm_conf[:dbconnections].to_i
- args[:pool] = connections if connections > 0
else
raise ArgumentError, "Invalid db adapter #{adapter}"
end
diff --git a/ext/rack/files/config.ru b/ext/rack/files/config.ru
index 5f0834a7d..f9c492dd7 100644
--- a/ext/rack/files/config.ru
+++ b/ext/rack/files/config.ru
@@ -4,15 +4,13 @@
# if puppet is not in your RUBYLIB:
# $:.unshift('/opt/puppet/lib')
-$0 = "puppetmasterd"
-require 'puppet'
+$0 = "master"
# if you want debugging:
# ARGV << "--debug"
ARGV << "--rack"
-require 'puppet/application/puppetmasterd'
+require 'puppet/application/master'
# we're usually running inside a Rack::Builder.new {} block,
# therefore we need to call run *here*.
-run Puppet::Application[:puppetmasterd].run
-
+run Puppet::Application[:master].run
diff --git a/ext/vim/syntax/puppet.vim b/ext/vim/syntax/puppet.vim
index 80cd91c6c..96052104d 100644
--- a/ext/vim/syntax/puppet.vim
+++ b/ext/vim/syntax/puppet.vim
@@ -19,7 +19,7 @@ endif
" match class/definition/node declarations
syn region puppetDefine start="^\s*\(class\|define\|node\)\s" end="{" contains=puppetDefType,puppetDefName,puppetDefArguments,puppetNodeRe
syn keyword puppetDefType class define node inherits contained
-syn region puppetDefArguments start="(" end=")" contained contains=puppetArgument
+syn region puppetDefArguments start="(" end=")" contained contains=puppetArgument,puppetString
syn match puppetArgument "\w\+" contained
syn match puppetArgument "\$\w\+" contained
syn match puppetArgument "'[^']+'" contained
@@ -33,6 +33,7 @@ syn match puppetNodeRe "/.*/" contained
"FIXME: "Foo-bar" doesn't get highlighted as expected, although "foo-bar" does.
syn match puppetInstance "[A-Za-z0-9_-]\+\(::[A-Za-z0-9_-]\+\)*\s*{" contains=puppetTypeName,puppetTypeDefault
syn match puppetInstance "[A-Z][a-z_-]\+\(::[A-Z][a-z_-]\+\)*\s*[[{]" contains=puppetTypeName,puppetTypeDefault
+syn match puppetInstance "[A-Z][a-z_-]\+\(::[A-Z][a-z_-]\+\)*\s*<\?<|" contains=puppetTypeName,puppetTypeDefault
syn match puppetTypeName "[a-z]\w*" contained
syn match puppetTypeDefault "[A-Z]\w*" contained
@@ -56,19 +57,19 @@ syn region puppetFunction start="^\s*\(alert\|crit\|debug\|emerg\|err\|fai
" rvalues
syn region puppetFunction start="^\s*\(defined\|file\|fqdn_rand\|generate\|inline_template\|regsubst\|sha1\|shellquote\|split\|sprintf\|tagged\|template\|versioncmp\)\s*(" end=")" contained contains=puppetString
-syn match puppetVariable "$\w\+"
-syn match puppetVariable "${\w\+}"
+syn match puppetVariable "$[a-zA-Z0-9_:]\+"
+syn match puppetVariable "${[a-zA-Z0-9_:]\+}"
" match anything between simple/double quotes.
" don't match variables if preceded by a backslash.
syn region puppetString start=+'+ skip=+\\\\\|\\'+ end=+'+
syn region puppetString start=+"+ skip=+\\\\\|\\"+ end=+"+ contains=puppetVariable,puppetNotVariable
-syn match puppetString "/.*/"
+syn match puppetString "/[^/]*/"
syn match puppetNotVariable "\\$\w\+" contained
syn match puppetNotVariable "\\${\w\+}" contained
syn keyword puppetKeyword import inherits include
-syn keyword puppetControl case default if else
+syn keyword puppetControl case default if else elsif
syn keyword puppetSpecial true false undef
" comments last overriding everything else
diff --git a/install.rb b/install.rb
index b06ec09fd..f7541c854 100755
--- a/install.rb
+++ b/install.rb
@@ -55,13 +55,13 @@ end
begin
if $haverdoc
- rst2man = %x{which rst2man.py}
+ ronn = %x{which ronn}
$haveman = true
else
$haveman = false
end
rescue
- puts "Missing rst2man; skipping man page creation"
+ puts "Missing ronn; skipping man page creation"
$haveman = false
end
@@ -88,6 +88,7 @@ libs = glob(%w{lib/**/*.rb lib/**/*.py lib/puppet/util/command_line/*})
tests = glob(%w{test/**/*.rb})
def do_bins(bins, target, strip = 's?bin/')
+ Dir.mkdir(target) unless File.directory? target
bins.each do |bf|
obf = bf.gsub(/#{strip}/, '')
install_binfile(bf, obf, target)
@@ -154,10 +155,12 @@ end
# Prepare the file installation.
#
def prepare_installation
+ $operatingsystem = Facter["operatingsystem"].value
+
# Only try to do docs if we're sure they have rdoc
if $haverdoc
InstallOptions.rdoc = true
- InstallOptions.ri = RUBY_PLATFORM != "i386-mswin32"
+ InstallOptions.ri = $operatingsystem != "windows"
else
InstallOptions.rdoc = false
InstallOptions.ri = false
@@ -166,7 +169,7 @@ def prepare_installation
if $haveman
InstallOptions.man = true
- if RUBY_PLATFORM == "i386-mswin32"
+ if $operatingsystem == "windows"
InstallOptions.man = false
end
else
@@ -175,15 +178,6 @@ def prepare_installation
InstallOptions.tests = true
- if $haveman
- InstallOptions.man = true
- if RUBY_PLATFORM == "i386-mswin32"
- InstallOptions.man = false
- end
- else
- InstallOptions.man = false
- end
-
ARGV.options do |opts|
opts.banner = "Usage: #{File.basename($0)} [options]"
opts.separator ""
@@ -347,21 +341,22 @@ end
def build_man(bins, sbins)
return unless $haveman
begin
- # Locate rst2man
- rst2man = %x{which rst2man.py}
- rst2man.chomp!
+ # Locate ronn
+ ronn = %x{which ronn}
+ ronn.chomp!
# Create puppet.conf.5 man page
- %x{bin/puppetdoc --reference configuration > ./puppet.conf.rst}
- %x{#{rst2man} ./puppet.conf.rst ./man/man5/puppet.conf.5}
- File.unlink("./puppet.conf.rst")
+ %x{bin/puppetdoc --reference configuration > ./man/man5/puppetconf.5.ronn}
+ %x{#{ronn} -r ./man/man5/puppetconf.5.ronn}
+ File.move("./man/man5/puppetconf.5", "./man/man5/puppet.conf.5")
+ File.unlink("./man/man5/puppetconf.5.ronn")
# Create binary man pages
binary = bins + sbins
binary.each do |bin|
b = bin.gsub( /(bin|sbin)\//, "")
- %x{#{bin} --help > ./#{b}.rst}
- %x{#{rst2man} ./#{b}.rst ./man/man8/#{b}.8}
- File.unlink("./#{b}.rst")
+ %x{#{bin} --help > ./man/man8/#{b}.8.ronn}
+ %x{#{ronn} -r ./man/man8/#{b}.8.ronn}
+ File.unlink("./man/man8/#{b}.8.ronn")
end
rescue SystemCallError
@@ -417,7 +412,7 @@ def install_binfile(from, op_file, target)
end
end
- if Config::CONFIG["target_os"] =~ /win/io and Config::CONFIG["target_os"] !~ /darwin/io
+ if $operatingsystem == "windows"
installed_wrapper = false
if File.exists?("#{from}.bat")
@@ -467,4 +462,4 @@ prepare_installation
do_bins(sbins, InstallOptions.sbin_dir)
do_bins(bins, InstallOptions.bin_dir)
do_libs(libs)
-do_man(man)
+do_man(man) unless $operatingsystem == "windows"
diff --git a/lib/puppet.rb b/lib/puppet.rb
index 902f5bf5c..78fb5138b 100644
--- a/lib/puppet.rb
+++ b/lib/puppet.rb
@@ -24,7 +24,7 @@ require 'puppet/util/run_mode'
# it's also a place to find top-level commands like 'debug'
module Puppet
- PUPPETVERSION = '2.6.0'
+ PUPPETVERSION = '2.6.3'
def Puppet.version
PUPPETVERSION
diff --git a/lib/puppet/agent.rb b/lib/puppet/agent.rb
index 52acc64aa..47dd44a0e 100644
--- a/lib/puppet/agent.rb
+++ b/lib/puppet/agent.rb
@@ -37,7 +37,9 @@ class Puppet::Agent
with_client do |client|
begin
sync.synchronize { lock { result = client.run(*args) } }
- rescue => detail
+ rescue SystemExit,NoMemoryError
+ raise
+ rescue Exception => detail
puts detail.backtrace if Puppet[:trace]
Puppet.err "Could not run #{client_class}: #{detail}"
end
diff --git a/lib/puppet/application.rb b/lib/puppet/application.rb
index 05b7d466f..f0159a65d 100644
--- a/lib/puppet/application.rb
+++ b/lib/puppet/application.rb
@@ -254,20 +254,6 @@ class Application
def preinit
end
- def option_parser
- return @option_parser if defined?(@option_parser)
-
- @option_parser = OptionParser.new(self.class.banner)
-
- self.class.option_parser_commands.each do |options, fname|
- @option_parser.on(*options) do |value|
- self.send(fname, value)
- end
- end
- @option_parser.default_argv = self.command_line.args
- @option_parser
- end
-
def initialize(command_line = nil)
require 'puppet/util/command_line'
@command_line = command_line || Puppet::Util::CommandLine.new
@@ -286,7 +272,7 @@ class Application
Puppet.settings.set_value(:name, Puppet.application_name.to_s, :mutable_defaults)
Puppet.settings.set_value(:logdir, Puppet.run_mode.logopts, :mutable_defaults)
Puppet.settings.set_value(:rundir, Puppet.run_mode.run_dir, :mutable_defaults)
- Puppet.settings.set_value(:mode, Puppet.run_mode.name.to_s, :mutable_defaults)
+ Puppet.settings.set_value(:run_mode, Puppet.run_mode.name.to_s, :mutable_defaults)
end
require 'puppet'
@@ -324,20 +310,29 @@ class Application
end
def parse_options
- # get all puppet options
- optparse_opt = []
- optparse_opt = Puppet.settings.optparse_addargs(optparse_opt)
+ # Create an option parser
+ option_parser = OptionParser.new(self.class.banner)
- # convert them to OptionParser format
- optparse_opt.each do |option|
- self.option_parser.on(*option) do |arg|
+ # Add all global options to it.
+ Puppet.settings.optparse_addargs([]).each do |option|
+ option_parser.on(*option) do |arg|
handlearg(option[0], arg)
end
end
- # scan command line argument
+ # Add options that are local to this application, which were
+ # created using the "option()" metaprogramming method. If there
+ # are any conflicts, this application's options will be favored.
+ self.class.option_parser_commands.each do |options, fname|
+ option_parser.on(*options) do |value|
+ # Call the method that "option()" created.
+ self.send(fname, value)
+ end
+ end
+
+ # scan command line.
begin
- self.option_parser.parse!
+ option_parser.parse!(self.command_line.args)
rescue OptionParser::ParseError => detail
$stderr.puts detail
$stderr.puts "Try 'puppet #{command_line.subcommand_name} --help'"
diff --git a/lib/puppet/application/agent.rb b/lib/puppet/application/agent.rb
index f0e7f4d8f..c5ad72068 100644
--- a/lib/puppet/application/agent.rb
+++ b/lib/puppet/application/agent.rb
@@ -219,12 +219,18 @@ class Puppet::Application::Agent < Puppet::Application
Puppet.settings.use :main, :agent, :ssl
+ # Always ignoreimport for agent. It really shouldn't even try to import,
+ # but this is just a temporary band-aid.
+ Puppet[:ignoreimport] = true
+
# We need to specify a ca location for all of the SSL-related i
# indirected classes to work; in fingerprint mode we just need
# access to the local files and we don't need a ca.
Puppet::SSL::Host.ca_location = options[:fingerprint] ? :none : :remote
Puppet::Transaction::Report.terminus_class = :rest
+ # we want the last report to be persisted locally
+ Puppet::Transaction::Report.cache_class = :yaml
# Override the default; puppetd needs this, usually.
# You can still override this on the command-line with, e.g., :compiler.
diff --git a/lib/puppet/application/apply.rb b/lib/puppet/application/apply.rb
index bb4186dbd..8ec3fab6b 100644
--- a/lib/puppet/application/apply.rb
+++ b/lib/puppet/application/apply.rb
@@ -78,7 +78,10 @@ class Puppet::Application::Apply < Puppet::Application
if options[:code] or command_line.args.length == 0
Puppet[:code] = options[:code] || STDIN.read
else
- Puppet[:manifest] = command_line.args.shift
+ manifest = command_line.args.shift
+ raise "Could not find file #{manifest}" unless File.exist?(manifest)
+ Puppet.warning("Only one file can be applied per run. Skipping #{command_line.args.join(', ')}") if command_line.args.size > 0
+ Puppet[:manifest] = manifest
end
# Collect our facts.
@@ -120,20 +123,9 @@ class Puppet::Application::Apply < Puppet::Application
require 'puppet/configurer'
configurer = Puppet::Configurer.new
- configurer.execute_prerun_command
-
- # And apply it
- transaction = catalog.apply
-
- configurer.execute_postrun_command
+ report = configurer.run(:skip_plugin_download => true, :catalog => catalog)
- status = 0
- if not Puppet[:noop] and options[:detailed_exitcodes]
- transaction.generate_report
- exit(transaction.report.exit_status)
- else
- exit(0)
- end
+ exit( Puppet[:noop] ? 0 : options[:detailed_exitcodes] ? report.exit_status : 0 )
rescue => detail
puts detail.backtrace if Puppet[:trace]
$stderr.puts detail.message
@@ -156,6 +148,9 @@ class Puppet::Application::Apply < Puppet::Application
exit(1)
end
+ # we want the last report to be persisted locally
+ Puppet::Transaction::Report.cache_class = :yaml
+
if options[:debug]
Puppet::Util::Log.level = :debug
elsif options[:verbose]
diff --git a/lib/puppet/application/describe.rb b/lib/puppet/application/describe.rb
index 5abe3ea14..e76b347f6 100644
--- a/lib/puppet/application/describe.rb
+++ b/lib/puppet/application/describe.rb
@@ -130,7 +130,7 @@ class TypeDoc
a[0].to_s <=> b[0].to_s
}.each { |name, doc|
print "\n- **#{name}**"
- if type.namevar == name and name != :name
+ if type.key_attributes.include?(name) and name != :name
puts " (*namevar*)"
else
puts ""
diff --git a/lib/puppet/application/doc.rb b/lib/puppet/application/doc.rb
index 66aa6c8a1..1f6c63286 100644
--- a/lib/puppet/application/doc.rb
+++ b/lib/puppet/application/doc.rb
@@ -56,7 +56,7 @@ class Puppet::Application::Doc < Puppet::Application
end
def run_command
- return[:rdoc, :trac, :markdown].include?(options[:mode]) ? send(options[:mode]) : other
+ return[:rdoc].include?(options[:mode]) ? send(options[:mode]) : other
end
def rdoc
@@ -72,7 +72,7 @@ class Puppet::Application::Doc < Puppet::Application
Puppet.settings.setdefaults(
"puppetdoc",
-
+
"document_all" => [false, "Document all resources"]
)
Puppet.settings[:document_all] = options[:all] || false
@@ -92,40 +92,6 @@ class Puppet::Application::Doc < Puppet::Application
exit exit_code
end
- def trac
- require 'puppet/util/reference'
- options[:references].each do |name|
- section = Puppet::Util::Reference.reference(name) or raise "Could not find section #{name}"
- section.trac unless options[:mode] == :pdf
- end
- end
-
- def markdown
- text = ""
- with_contents = false
- exit_code = 0
- require 'puppet/util/reference'
- options[:references].sort { |a,b| a.to_s <=> b.to_s }.each do |name|
- raise "Could not find reference #{name}" unless section = Puppet::Util::Reference.reference(name)
-
- begin
- # Add the per-section text, but with no ToC
- text += section.send(options[:format], with_contents)
- text += Puppet::Util::Reference.footer
- text.gsub!(/`\w+\s+([^`]+)`:trac:/) { |m| $1 }
- Puppet::Util::Reference.markdown(name, text)
- text = ""
- rescue => detail
- puts detail.backtrace
- $stderr.puts "Could not generate reference #{name}: #{detail}"
- exit_code = 1
- next
- end
- end
-
- exit exit_code
- end
-
def other
text = ""
with_contents = options[:references].length <= 1
diff --git a/lib/puppet/application/master.rb b/lib/puppet/application/master.rb
index 777a50eaa..fde474907 100644
--- a/lib/puppet/application/master.rb
+++ b/lib/puppet/application/master.rb
@@ -138,9 +138,6 @@ class Puppet::Application::Master < Puppet::Application
Puppet.settings.use :main, :master, :ssl
- # A temporary solution, to at least make the master work for now.
- Puppet::Node::Facts.terminus_class = :yaml
-
# Cache our nodes in yaml. Currently not configurable.
Puppet::Node.cache_class = :yaml
diff --git a/lib/puppet/application/queue.rb b/lib/puppet/application/queue.rb
index 6df825dd1..239f6b2ad 100644
--- a/lib/puppet/application/queue.rb
+++ b/lib/puppet/application/queue.rb
@@ -38,6 +38,7 @@ class Puppet::Application::Queue < Puppet::Application
option("--verbose","-v")
def main
+ require 'puppet/indirector/catalog/queue' # provides Puppet::Indirector::Queue.subscribe
Puppet.notice "Starting puppetqd #{Puppet.version}"
Puppet::Resource::Catalog::Queue.subscribe do |catalog|
# Once you have a Puppet::Resource::Catalog instance, calling save on it should suffice
diff --git a/lib/puppet/configurer.rb b/lib/puppet/configurer.rb
index 327955b03..1c0639029 100644
--- a/lib/puppet/configurer.rb
+++ b/lib/puppet/configurer.rb
@@ -77,12 +77,12 @@ class Puppet::Configurer
end
# Prepare for catalog retrieval. Downloads everything necessary, etc.
- def prepare
+ def prepare(options)
dostorage
- download_plugins
+ download_plugins unless options[:skip_plugin_download]
- download_fact_plugins
+ download_fact_plugins unless options[:skip_plugin_download]
execute_prerun_command
end
@@ -126,7 +126,7 @@ class Puppet::Configurer
# which accepts :tags and :ignoreschedules.
def run(options = {})
begin
- prepare
+ prepare(options)
rescue SystemExit,NoMemoryError
raise
rescue Exception => detail
@@ -158,25 +158,40 @@ class Puppet::Configurer
return
end
ensure
+ # Make sure we forget the retained module_directories of any autoload
+ # we might have used.
+ Thread.current[:env_module_directories] = nil
+
# Now close all of our existing http connections, since there's no
# reason to leave them lying open.
Puppet::Network::HttpPool.clear_http_instances
execute_postrun_command
Puppet::Util::Log.close(report)
-
send_report(report, transaction)
end
def send_report(report, trans = nil)
trans.generate_report if trans
puts report.summary if Puppet[:summarize]
- report.save if Puppet[:report]
+ save_last_run_summary(report)
+ if Puppet[:report]
+ report.save
+ end
rescue => detail
puts detail.backtrace if Puppet[:trace]
Puppet.err "Could not send report: #{detail}"
end
+ def save_last_run_summary(report)
+ Puppet::Util::FileLocking.writelock(Puppet[:lastrunfile], 0660) do |file|
+ file.print YAML.dump(report.raw_summary)
+ end
+ rescue => detail
+ puts detail.backtrace if Puppet[:trace]
+ Puppet.err "Could not save last run local report: #{detail}"
+ end
+
private
def self.timeout
diff --git a/lib/puppet/daemon.rb b/lib/puppet/daemon.rb
index aa4a12bfa..c76d63a54 100755
--- a/lib/puppet/daemon.rb
+++ b/lib/puppet/daemon.rb
@@ -43,7 +43,7 @@ class Puppet::Daemon
# Create a pidfile for our daemon, so we can be stopped and others
# don't try to start.
def create_pidfile
- Puppet::Util.sync(Puppet[:name]).synchronize(Sync::EX) do
+ Puppet::Util.synchronize_on(Puppet[:name],Sync::EX) do
raise "Could not create PID file: #{pidfile}" unless Puppet::Util::Pidlock.new(pidfile).lock
end
end
@@ -73,7 +73,7 @@ class Puppet::Daemon
# Remove the pid file for our daemon.
def remove_pidfile
- Puppet::Util.sync(Puppet[:name]).synchronize(Sync::EX) do
+ Puppet::Util.synchronize_on(Puppet[:name],Sync::EX) do
locker = Puppet::Util::Pidlock.new(pidfile)
locker.unlock or Puppet.err "Could not remove PID file #{pidfile}" if locker.locked?
end
@@ -121,8 +121,8 @@ class Puppet::Daemon
create_pidfile
raise Puppet::DevError, "Daemons must have an agent, server, or both" unless agent or server
- agent.start if agent
server.start if server
+ agent.start if agent
EventLoop.current.run
end
diff --git a/lib/puppet/defaults.rb b/lib/puppet/defaults.rb
index 84e2d93fc..8bf1cd84d 100644
--- a/lib/puppet/defaults.rb
+++ b/lib/puppet/defaults.rb
@@ -2,12 +2,12 @@
module Puppet
setdefaults(:main,
:confdir => [Puppet.run_mode.conf_dir, "The main Puppet configuration directory. The default for this parameter is calculated based on the user. If the process
- is running as root or the user that ``puppet master`` is supposed to run as, it defaults to a system directory, but if it's running as any other user,
- it defaults to being in ``~``."],
+ is running as root or the user that `puppet master` is supposed to run as, it defaults to a system directory, but if it's running as any other user,
+ it defaults to being in `~`."],
:vardir => [Puppet.run_mode.var_dir, "Where Puppet stores dynamic and growing data. The default for this parameter is calculated specially, like `confdir`_."],
:name => [Puppet.application_name.to_s, "The name of the application, if we are running as one. The
- default is essentially $0 without the path or ``.rb``."],
- :mode => [Puppet.run_mode.name.to_s, "The effective 'run mode' of the application: master, agent, or user."]
+ default is essentially $0 without the path or `.rb`."],
+ :run_mode => [Puppet.run_mode.name.to_s, "The effective 'run mode' of the application: master, agent, or user."]
)
setdefaults(:main, :logdir => Puppet.run_mode.logopts)
@@ -44,8 +44,8 @@ module Puppet
specify 'all'. This feature is only available in Puppet versions
higher than 0.18.4."],
:color => ["ansi", "Whether to use colors when logging to the console.
- Valid values are ``ansi`` (equivalent to ``true``), ``html`` (mostly
- used during testing with TextMate), and ``false``, which produces
+ Valid values are `ansi` (equivalent to `true`), `html` (mostly
+ used during testing with TextMate), and `false`, which produces
no color."],
:mkusers => [false,
"Whether to create the necessary user and group that puppet agent will
@@ -92,18 +92,18 @@ module Puppet
:authconfig => [ "$confdir/namespaceauth.conf",
"The configuration file that defines the rights to the different
namespaces and methods. This can be used as a coarse-grained
- authorization system for both ``puppet agent`` and ``puppet master``."
+ authorization system for both `puppet agent` and `puppet master`."
],
:environment => {:default => "production", :desc => "The environment Puppet is running in. For clients
- (e.g., ``puppet agent``) this determines the environment itself, which
- is used to find modules and much more. For servers (i.e., ``puppet master``) this provides the default environment for nodes
+ (e.g., `puppet agent`) this determines the environment itself, which
+ is used to find modules and much more. For servers (i.e., `puppet master`) this provides the default environment for nodes
we know nothing about."
},
:diff_args => ["-u", "Which arguments to pass to the diff command when printing differences between files."],
:diff => ["diff", "Which diff command to use when printing differences between files."],
:show_diff => [false, "Whether to print a contextual diff when files are being replaced. The diff
is printed on stdout, so this option is meaningless unless you are running Puppet interactively.
- This feature currently requires the ``diff/lcs`` Ruby library."],
+ This feature currently requires the `diff/lcs` Ruby library."],
:daemonize => { :default => true,
:desc => "Send the process into the background. This is the default.",
:short => "D"
@@ -115,7 +115,17 @@ module Puppet
:node_terminus => ["plain", "Where to find information about nodes."],
:catalog_terminus => ["compiler", "Where to get node catalogs. This is useful to change if, for instance,
you'd like to pre-compile catalogs and store them in memcached or some other easily-accessed store."],
- :facts_terminus => ["facter", "Where to get node facts."],
+ :facts_terminus => {
+ :default => Puppet.application_name.to_s == "master" ? 'yaml' : 'facter',
+ :desc => "The node facts terminus.",
+ :hook => proc do |value|
+ require 'puppet/node/facts'
+ if value.to_s == "rest"
+ Puppet::Node::Facts.cache_class = :yaml
+ end
+ end
+ },
+ :inventory_terminus => [ "$facts_terminus", "Should usually be the same as the facts terminus" ],
:httplog => { :default => "$logdir/http.log",
:owner => "root",
:mode => 0640,
@@ -135,7 +145,7 @@ module Puppet
:queue_source => ["stomp://localhost:61613/", "Which type of queue to use for asynchronous processing. If your stomp server requires
authentication, you can include it in the URI as long as your stomp client library is at least 1.1.1"],
:async_storeconfigs => {:default => false, :desc => "Whether to use a queueing system to provide asynchronous database integration.
- Requires that ``puppetqd`` be running and that 'PSON' support for ruby be installed.",
+ Requires that `puppetqd` be running and that 'PSON' support for ruby be installed.",
:hook => proc do |value|
if value
# This reconfigures the terminii for Node, Facts, and Catalog
@@ -266,10 +276,9 @@ module Puppet
to all clients. If enabled, CA chaining will almost definitely not work."]
)
-
setdefaults(
:ca,
- :ca_name => ["$certname", "The name to use the Certificate Authority certificate."],
+ :ca_name => ["Puppet CA: $certname", "The name to use the Certificate Authority certificate."],
:cadir => { :default => "$ssldir/ca",
:owner => "service",
:group => "service",
@@ -385,7 +394,7 @@ module Puppet
:manifestdir => ["$confdir/manifests", "Where puppet master looks for its manifests."],
:manifest => ["$manifestdir/site.pp", "The entry-point manifest for puppet master."],
:code => ["", "Code to parse directly. This is essentially only used
- by ``puppet``, and should only be set if you're writing your own Puppet
+ by `puppet`, and should only be set if you're writing your own Puppet
executable"],
:masterlog => { :default => "$logdir/puppetmaster.log",
:owner => "service",
@@ -419,7 +428,7 @@ module Puppet
:rest_authconfig => [ "$confdir/auth.conf",
"The configuration file that defines the rights to the different
rest indirections. This can be used as a fine-grained
- authorization system for ``puppet master``."
+ authorization system for `puppet master`."
],
:ca => [true, "Wether the master should function as a certificate authority."],
:modulepath => {:default => "$confdir/modules:/usr/share/puppet/modules",
@@ -427,7 +436,7 @@ module Puppet
directories.", :type => :setting }, # We don't want this to be considered a file, since it's multiple files.
:ssl_client_header => ["HTTP_X_CLIENT_DN", "The header containing an authenticated
client's SSL DN. Only used with Mongrel. This header must be set by the proxy
- to the authenticated client's SSL DN (e.g., ``/CN=puppet.puppetlabs.com``).
+ to the authenticated client's SSL DN (e.g., `/CN=puppet.puppetlabs.com`).
See http://projects.puppetlabs.com/projects/puppet/wiki/Using_Mongrel for more information."],
:ssl_client_verify_header => ["HTTP_X_CLIENT_VERIFY", "The header containing the status
message of the client verification. Only used with Mongrel. This header must be set by the proxy
@@ -441,10 +450,25 @@ module Puppet
:desc => "The directory in which serialized data is stored, usually in a subdirectory."},
:reports => ["store",
"The list of reports to generate. All reports are looked for
- in puppet/reports/name.rb, and multiple report names should be
+ in `puppet/reports/name.rb`, and multiple report names should be
comma-separated (whitespace is okay)."
],
+ :reportdir => {:default => "$vardir/reports",
+ :mode => 0750,
+ :owner => "service",
+ :group => "service",
+ :desc => "The directory in which to store reports
+ received from the client. Each client gets a separate
+ subdirectory."},
+ :reporturl => ["http://localhost:3000/reports",
+ "The URL used by the http reports processor to send reports"],
:fileserverconfig => ["$confdir/fileserver.conf", "Where the fileserver configuration is stored."],
+ :strict_hostname_checking => [false, "Whether to only search for the complete
+ hostname as it is in the certificate when searching for node information
+ in the catalogs."]
+ )
+
+ setdefaults(:metrics,
:rrddir => {:default => "$vardir/rrd",
:owner => "service",
:group => "service",
@@ -453,10 +477,7 @@ module Puppet
this directory."
},
:rrdinterval => ["$runinterval", "How often RRD should expect data.
- This should match how often the hosts report back to the server."],
- :strict_hostname_checking => [false, "Whether to only search for the complete
- hostname as it is in the certificate when searching for node information
- in the catalogs."]
+ This should match how often the hosts report back to the server."]
)
setdefaults(:agent,
@@ -479,7 +500,7 @@ module Puppet
:mode => 0644,
:desc => "The file in which puppet agent stores a list of the classes
associated with the retrieved configuration. Can be loaded in
- the separate ``puppet`` executable using the ``--loadclasses``
+ the separate `puppet` executable using the `--loadclasses`
option."},
:puppetdlog => { :default => "$logdir/puppetd.log",
:owner => "root",
@@ -496,8 +517,8 @@ module Puppet
"How often puppet agent applies the client configuration; in seconds."],
:listen => [false, "Whether puppet agent should listen for
connections. If this is true, then by default only the
- ``runner`` server is started, which allows remote authorized
- and authenticated nodes to connect and trigger ``puppet agent``
+ `runner` server is started, which allows remote authorized
+ and authenticated nodes to connect and trigger `puppet agent`
runs."],
:ca_server => ["$server", "The server to use for certificate
authority requests. It's a separate server because it cannot
@@ -567,14 +588,28 @@ module Puppet
end
},
:report_server => ["$server",
- "The server to which to send transaction reports."
+ "The server to send transaction reports to."
],
:report_port => ["$masterport",
"The port to communicate with the report_server."
],
- :report => [false,
+ :inventory_server => ["$server",
+ "The server to send facts to."
+ ],
+ :inventory_port => ["$masterport",
+ "The port to communicate with the inventory_server."
+ ],
+ :report => [true,
"Whether to send reports after every transaction."
],
+ :lastrunfile => { :default => "$statedir/last_run_summary.yaml",
+ :mode => 0660,
+ :desc => "Where puppet agent stores the last run report summary in yaml format."
+ },
+ :lastrunreport => { :default => "$statedir/last_run_report.yaml",
+ :mode => 0660,
+ :desc => "Where puppet agent stores the last run report in yaml format."
+ },
:graph => [false, "Whether to create dot graph files for the different
configuration graphs. These dot files can be interpreted by tools
like OmniGraffle or dot (which is part of ImageMagick)."],
@@ -595,7 +630,7 @@ module Puppet
"Where Puppet should store plugins that it pulls down from the central
server."],
:pluginsource => ["puppet://$server/plugins",
- "From where to retrieve plugins. The standard Puppet ``file`` type
+ "From where to retrieve plugins. The standard Puppet `file` type
is used for retrieval, so anything that is a valid file source can
be used here."],
:pluginsync => [false, "Whether plugins should be synced with the central server."],
@@ -607,7 +642,7 @@ module Puppet
setdefaults(
:main,
- :factpath => {:default => "$vardir/lib/facter/${File::PATH_SEPARATOR}$vardir/facts",
+ :factpath => {:default => "$vardir/lib/facter:$vardir/facts",
:desc => "Where Puppet should look for facts. Multiple directories should
be colon-separated, like normal PATH variables.",
@@ -618,33 +653,23 @@ module Puppet
"Where Puppet should store facts that it pulls down from the central
server."],
:factsource => ["puppet://$server/facts/",
- "From where to retrieve facts. The standard Puppet ``file`` type
+ "From where to retrieve facts. The standard Puppet `file` type
is used for retrieval, so anything that is a valid file source can
be used here."],
:factsync => [false, "Whether facts should be synced with the central server."],
- :factsignore => [".svn CVS", "What files to ignore when pulling down facts."],
- :reportdir => {:default => "$vardir/reports",
- :mode => 0750,
- :owner => "service",
- :group => "service",
- :desc => "The directory in which to store reports
- received from the client. Each client gets a separate
- subdirectory."},
- :reporturl => ["http://localhost:3000/reports",
- "The URL used by the http reports processor to send reports"]
+ :factsignore => [".svn CVS", "What files to ignore when pulling down facts."]
)
setdefaults(
:tagmail,
:tagmap => ["$confdir/tagmail.conf", "The mapping between reporting tags and email addresses."],
- :sendmail => [%x{which sendmail 2>/dev/null}.chomp, "Where to find the sendmail binary with which to send email."],
+ :sendmail => [which('sendmail') || '', "Where to find the sendmail binary with which to send email."],
:reportfrom => ["report@" + [Facter["hostname"].value, Facter["domain"].value].join("."), "The 'from' email address for the reports."],
:smtpserver => ["none", "The server through which to send email reports."]
)
-
setdefaults(
:rails,
:dblocation => { :default => "$statedir/clientconfigs.sqlite3",
@@ -665,11 +690,10 @@ module Puppet
used when networked databases are used."],
:dbpassword => [ "puppet", "The database password for caching. Only
used when networked databases are used."],
+ :dbconnections => [ '', "The number of database connections for networked
+ databases. Will be ignored unless the value is a positive integer."],
:dbsocket => [ "", "The database socket location. Only used when networked
databases are used. Will be ignored if the value is an empty string."],
- :dbconnections => [ 0, "The number of database connections. Only used when
- networked databases are used. Will be ignored if the value is an empty
- string or is less than 1."],
:railslog => {:default => "$logdir/rails.log",
:mode => 0600,
:owner => "service",
@@ -678,18 +702,16 @@ module Puppet
},
:rails_loglevel => ["info", "The log level for Rails connections. The value must be
- a valid log level within Rails. Production environments normally use ``info``
- and other environments normally use ``debug``."]
+ a valid log level within Rails. Production environments normally use `info`
+ and other environments normally use `debug`."]
)
-
setdefaults(
:couchdb,
:couchdb_url => ["http://127.0.0.1:5984/puppet", "The url where the puppet couchdb database will be created"]
)
-
setdefaults(
:transaction,
:tags => ["", "Tags to use to find resources. If this is set, then
@@ -704,21 +726,19 @@ module Puppet
]
)
-
setdefaults(
:main,
:external_nodes => ["none",
"An external command that can produce node information. The output
must be a YAML dump of a hash, and that hash must have one or both of
- ``classes`` and ``parameters``, where ``classes`` is an array and
- ``parameters`` is a hash. For unknown nodes, the commands should
+ `classes` and `parameters`, where `classes` is an array and
+ `parameters` is a hash. For unknown nodes, the commands should
exit with a non-zero exit code.
This command makes it straightforward to store your node mapping
information in other data sources like databases."])
-
setdefaults(
:ldap,
:ldapnodes => [false,
@@ -733,9 +753,9 @@ module Puppet
Defaults to false because TLS usually requires certificates
to be set up on the client side."],
:ldapserver => ["ldap",
- "The LDAP server. Only used if ``ldapnodes`` is enabled."],
+ "The LDAP server. Only used if `ldapnodes` is enabled."],
:ldapport => [389,
- "The LDAP port. Only used if ``ldapnodes`` is enabled."],
+ "The LDAP port. Only used if `ldapnodes` is enabled."],
:ldapstring => ["(&(objectclass=puppetClient)(cn=%s))",
"The search string used to find an LDAP node."],
diff --git a/lib/puppet/dsl.rb b/lib/puppet/dsl.rb
index abdb78f67..97a310436 100644
--- a/lib/puppet/dsl.rb
+++ b/lib/puppet/dsl.rb
@@ -5,7 +5,3 @@ end
require 'puppet/dsl/resource_type_api'
require 'puppet/dsl/resource_api'
-
-class Object
- include Puppet::DSL::ResourceTypeAPI
-end
diff --git a/lib/puppet/dsl/resource_type_api.rb b/lib/puppet/dsl/resource_type_api.rb
index 487aab99d..8810d5368 100644
--- a/lib/puppet/dsl/resource_type_api.rb
+++ b/lib/puppet/dsl/resource_type_api.rb
@@ -1,34 +1,15 @@
require 'puppet/resource/type'
-module Puppet::DSL::ResourceTypeAPI
- def define(name, *args, &block)
- result = mk_resource_type(:definition, name, Hash.new, block)
- result.set_arguments(munge_type_arguments(args))
- result
- end
-
- def hostclass(name, options = {}, &block)
- mk_resource_type(:hostclass, name, options, block)
- end
-
- def node(name, options = {}, &block)
- mk_resource_type(:node, name, options, block)
- end
-
- private
-
- def mk_resource_type(type, name, options, code)
- klass = Puppet::Resource::Type.new(type, name, options)
-
- klass.ruby_code = code if code
-
- Puppet::Node::Environment.new.known_resource_types.add klass
-
- klass
+# Type of the objects inside of which pure ruby manifest files are
+# executed. Provides methods for creating defines, hostclasses, and
+# nodes.
+class Puppet::DSL::ResourceTypeAPI
+ def initialize
+ @__created_ast_objects__ = []
end
- def munge_type_arguments(args)
- args.inject([]) do |result, item|
+ def define(name, *args, &block)
+ args = args.inject([]) do |result, item|
if item.is_a?(Hash)
item.each { |p, v| result << [p, v] }
else
@@ -36,5 +17,18 @@ module Puppet::DSL::ResourceTypeAPI
end
result
end
+ @__created_ast_objects__.push Puppet::Parser::AST::Definition.new(name, {:arguments => args}, &block)
+ nil
+ end
+
+ def hostclass(name, options = {}, &block)
+ @__created_ast_objects__.push Puppet::Parser::AST::Hostclass.new(name, options, &block)
+ nil
+ end
+
+ def node(name, options = {}, &block)
+ name = [name] unless name.is_a?(Array)
+ @__created_ast_objects__.push Puppet::Parser::AST::Node.new(name, options, &block)
+ nil
end
end
diff --git a/lib/puppet/external/event-loop/event-loop.rb b/lib/puppet/external/event-loop/event-loop.rb
index dc51a55ae..3b40f6e71 100644
--- a/lib/puppet/external/event-loop/event-loop.rb
+++ b/lib/puppet/external/event-loop/event-loop.rb
@@ -75,8 +75,10 @@ class EventLoop
@notify_src, @notify_snk = IO.pipe
# prevent file descriptor leaks
- @notify_src.fcntl(Fcntl::F_SETFD, Fcntl::FD_CLOEXEC)
- @notify_snk.fcntl(Fcntl::F_SETFD, Fcntl::FD_CLOEXEC)
+ if @notify_src.respond_to?(:fcntl) and defined?(Fcntl) and defined?(Fcntl::F_SETFD) and defined?(Fcntl::FD_CLOEXEC)
+ @notify_src.fcntl(Fcntl::F_SETFD, Fcntl::FD_CLOEXEC)
+ @notify_snk.fcntl(Fcntl::F_SETFD, Fcntl::FD_CLOEXEC)
+ end
@notify_src.will_block = false
@notify_snk.will_block = false
@@ -234,19 +236,21 @@ class IO
end
def will_block?
- require "fcntl"
- fcntl(Fcntl::F_GETFL, 0) & Fcntl::O_NONBLOCK == 0
+ if respond_to?(:fcntl) and defined?(Fcntl) and defined?(Fcntl::F_GETFL) and defined?(Fcntl::O_NONBLOCK)
+ fcntl(Fcntl::F_GETFL, 0) & Fcntl::O_NONBLOCK == 0
+ end
end
def will_block= (wants_blocking)
- require "fcntl"
- flags = fcntl(Fcntl::F_GETFL, 0)
- if wants_blocking
- flags &= ~Fcntl::O_NONBLOCK
- else
- flags |= Fcntl::O_NONBLOCK
+ if respond_to?(:fcntl) and defined?(Fcntl) and defined?(Fcntl::F_GETFL) and defined?(Fcntl::O_NONBLOCK)
+ flags = fcntl(Fcntl::F_GETFL, 0)
+ if wants_blocking
+ flags &= ~Fcntl::O_NONBLOCK
+ else
+ flags |= Fcntl::O_NONBLOCK
+ end
+ fcntl(Fcntl::F_SETFL, flags)
end
- fcntl(Fcntl::F_SETFL, flags)
end
end
diff --git a/lib/puppet/external/pson/pure/generator.rb b/lib/puppet/external/pson/pure/generator.rb
index ef8b36d31..89a0c62e0 100644
--- a/lib/puppet/external/pson/pure/generator.rb
+++ b/lib/puppet/external/pson/pure/generator.rb
@@ -44,41 +44,13 @@ module PSON
string << '' # XXX workaround: avoid buffer sharing
string.force_encoding(Encoding::ASCII_8BIT)
string.gsub!(/["\\\x0-\x1f]/) { MAP[$MATCH] }
- string.gsub!(/(
- (?:
- [\xc2-\xdf][\x80-\xbf] |
- [\xe0-\xef][\x80-\xbf]{2} |
- [\xf0-\xf4][\x80-\xbf]{3}
- )+ |
- [\x80-\xc1\xf5-\xff] # invalid
- )/nx) { |c|
- c.size == 1 and raise GeneratorError, "invalid utf8 byte: '#{c}'"
- s = PSON::UTF8toUTF16.iconv(c).unpack('H*')[0]
- s.gsub!(/.{4}/n, '\\\\u\&')
- }
- string.force_encoding(Encoding::UTF_8)
string
rescue Iconv::Failure => e
raise GeneratorError, "Caught #{e.class}: #{e}"
end
else
def utf8_to_pson(string) # :nodoc:
- string = string.gsub(/["\\\x0-\x1f]/) { MAP[$MATCH] }
- string.gsub!(/(
- (?:
- [\xc2-\xdf][\x80-\xbf] |
- [\xe0-\xef][\x80-\xbf]{2} |
- [\xf0-\xf4][\x80-\xbf]{3}
- )+ |
- [\x80-\xc1\xf5-\xff] # invalid
- )/nx) { |c|
- c.size == 1 and raise GeneratorError, "invalid utf8 byte: '#{c}'"
- s = PSON::UTF8toUTF16.iconv(c).unpack('H*')[0]
- s.gsub!(/.{4}/n, '\\\\u\&')
- }
- string
- rescue Iconv::Failure => e
- raise GeneratorError, "Caught #{e.class}: #{e}"
+ string.gsub(/["\\\x0-\x1f]/n) { MAP[$MATCH] }
end
end
module_function :utf8_to_pson
diff --git a/lib/puppet/feature/base.rb b/lib/puppet/feature/base.rb
index c153fba98..c983f5c12 100644
--- a/lib/puppet/feature/base.rb
+++ b/lib/puppet/feature/base.rb
@@ -27,7 +27,8 @@ Puppet.features.add :diff, :libs => %w{diff/lcs diff/lcs/hunk}
Puppet.features.add(:augeas, :libs => ["augeas"])
# We have RRD available
-Puppet.features.add(:rrd, :libs => ["RRDtool"])
+Puppet.features.add(:rrd_legacy, :libs => ["RRDtool"])
+Puppet.features.add(:rrd, :libs => ["RRD"])
# We have OpenSSL
Puppet.features.add(:openssl, :libs => ["openssl"])
diff --git a/lib/puppet/feature/rails.rb b/lib/puppet/feature/rails.rb
index e0e14ebeb..74ed09aa6 100644
--- a/lib/puppet/feature/rails.rb
+++ b/lib/puppet/feature/rails.rb
@@ -24,9 +24,7 @@ Puppet.features.add(:rails) do
end
end
- if ! (defined?(::ActiveRecord) and defined?(::ActiveRecord::VERSION) and defined?(::ActiveRecord::VERSION::MAJOR) and defined?(::ActiveRecord::VERSION::MINOR))
- false
- elsif ! (::ActiveRecord::VERSION::MAJOR == 2 and ::ActiveRecord::VERSION::MINOR >= 1)
+ unless (Puppet::Util.activerecord_version >= 2.1)
Puppet.info "ActiveRecord 2.1 or later required for StoreConfigs"
false
else
diff --git a/lib/puppet/file_serving/indirection_hooks.rb b/lib/puppet/file_serving/indirection_hooks.rb
index 7e0c17916..a85e90ef1 100644
--- a/lib/puppet/file_serving/indirection_hooks.rb
+++ b/lib/puppet/file_serving/indirection_hooks.rb
@@ -19,8 +19,8 @@ module Puppet::FileServing::IndirectionHooks
return PROTOCOL_MAP["file"] if request.key =~ /^#{::File::SEPARATOR}/
return PROTOCOL_MAP["file"] if request.protocol == "file"
- # We're heading over the wire the protocol is 'puppet' and we've got a server name or we're not named 'puppet'
- if request.protocol == "puppet" and (request.server or Puppet.settings[:name] != "puppet")
+ # We're heading over the wire the protocol is 'puppet' and we've got a server name or we're not named 'apply' or 'puppet'
+ if request.protocol == "puppet" and (request.server or !["puppet","apply"].include?(Puppet.settings[:name]))
return PROTOCOL_MAP["puppet"]
end
diff --git a/lib/puppet/indirector/catalog/compiler.rb b/lib/puppet/indirector/catalog/compiler.rb
index c50022fff..78be4caf7 100644
--- a/lib/puppet/indirector/catalog/compiler.rb
+++ b/lib/puppet/indirector/catalog/compiler.rb
@@ -22,6 +22,7 @@ class Puppet::Resource::Catalog::Compiler < Puppet::Indirector::Code
else
facts = Puppet::Node::Facts.convert_from(format, text_facts)
end
+ facts.add_timestamp
facts.save
end
@@ -107,10 +108,14 @@ class Puppet::Resource::Catalog::Compiler < Puppet::Indirector::Code
return node
end
- # If the request is authenticated, then the 'node' info will
- # be available; if not, then we use the passed-in key. We rely
- # on our authorization system to determine whether this is allowed.
- name = request.node || request.key
+ # We rely on our authorization system to determine whether the connected
+ # node is allowed to compile the catalog's node referenced by key.
+ # By default the REST authorization system makes sure only the connected node
+ # can compile his catalog.
+ # This allows for instance monitoring systems or puppet-load to check several
+ # node's catalog with only one certificate and a modification to auth.conf
+ # If no key is provided we can only compile the currently connected node.
+ name = request.key || request.node
if node = find_node(name)
return node
end
diff --git a/lib/puppet/indirector/facts/memory.rb b/lib/puppet/indirector/facts/memory.rb
index c4ca19da5..93682f456 100644
--- a/lib/puppet/indirector/facts/memory.rb
+++ b/lib/puppet/indirector/facts/memory.rb
@@ -3,7 +3,7 @@ require 'puppet/indirector/memory'
class Puppet::Node::Facts::Memory < Puppet::Indirector::Memory
desc "Keep track of facts in memory but nowhere else. This is used for
- one-time compiles, such as what the stand-alone ``puppet`` does.
+ one-time compiles, such as what the stand-alone `puppet` does.
To use this terminus, you must load it with the data you want it
to contain."
end
diff --git a/lib/puppet/indirector/facts/rest.rb b/lib/puppet/indirector/facts/rest.rb
index 07491fc77..e2afa14b2 100644
--- a/lib/puppet/indirector/facts/rest.rb
+++ b/lib/puppet/indirector/facts/rest.rb
@@ -3,4 +3,6 @@ require 'puppet/indirector/rest'
class Puppet::Node::Facts::Rest < Puppet::Indirector::REST
desc "Find and save facts about nodes over HTTP via REST."
+ use_server_setting(:inventory_server)
+ use_port_setting(:inventory_port)
end
diff --git a/lib/puppet/indirector/indirection.rb b/lib/puppet/indirector/indirection.rb
index 309eed7b6..9095e48f8 100644
--- a/lib/puppet/indirector/indirection.rb
+++ b/lib/puppet/indirector/indirection.rb
@@ -238,6 +238,7 @@ class Puppet::Indirector::Indirection
if result = terminus.search(request)
raise Puppet::DevError, "Search results from terminus #{terminus.name} are not an array" unless result.is_a?(Array)
result.each do |instance|
+ next unless instance.respond_to? :expiration
instance.expiration ||= self.expiration
end
return result
diff --git a/lib/puppet/indirector/inventory/yaml.rb b/lib/puppet/indirector/inventory/yaml.rb
new file mode 100644
index 000000000..fe3489a95
--- /dev/null
+++ b/lib/puppet/indirector/inventory/yaml.rb
@@ -0,0 +1,81 @@
+require 'puppet/node/inventory'
+require 'puppet/indirector/yaml'
+
+class Puppet::Node::Inventory::Yaml < Puppet::Indirector::Yaml
+ desc "Return node names matching the fact query"
+
+ # Return the path to a given node's file.
+ def yaml_dir_path
+ base = Puppet.run_mode.master? ? Puppet[:yamldir] : Puppet[:clientyamldir]
+ File.join(base, 'facts', '*.yaml')
+ end
+
+ def node_matches?(facts, options)
+ options.each do |key, value|
+ type, name, operator = key.to_s.split(".")
+ operator ||= 'eq'
+
+ return false unless node_matches_option?(type, name, operator, value, facts)
+ end
+ return true
+ end
+
+ def search(request)
+ node_names = []
+ Dir.glob(yaml_dir_path).each do |file|
+ facts = YAML.load_file(file)
+ node_names << facts.name if node_matches?(facts, request.options)
+ end
+ node_names
+ end
+
+ private
+
+ def node_matches_option?(type, name, operator, value, facts)
+ case type
+ when "meta"
+ case name
+ when "timestamp"
+ compare_timestamp(operator, facts.timestamp, Time.parse(value))
+ end
+ when "facts"
+ compare_facts(operator, facts.values[name], value)
+ end
+ end
+
+ def compare_facts(operator, value1, value2)
+ return false unless value1
+
+ case operator
+ when "eq"
+ value1.to_s == value2.to_s
+ when "le"
+ value1.to_f <= value2.to_f
+ when "ge"
+ value1.to_f >= value2.to_f
+ when "lt"
+ value1.to_f < value2.to_f
+ when "gt"
+ value1.to_f > value2.to_f
+ when "ne"
+ value1.to_s != value2.to_s
+ end
+ end
+
+ def compare_timestamp(operator, value1, value2)
+ case operator
+ when "eq"
+ value1 == value2
+ when "le"
+ value1 <= value2
+ when "ge"
+ value1 >= value2
+ when "lt"
+ value1 < value2
+ when "gt"
+ value1 > value2
+ when "ne"
+ value1 != value2
+ end
+ end
+end
diff --git a/lib/puppet/indirector/node/exec.rb b/lib/puppet/indirector/node/exec.rb
index c3e690943..6e065c6f3 100644
--- a/lib/puppet/indirector/node/exec.rb
+++ b/lib/puppet/indirector/node/exec.rb
@@ -3,7 +3,7 @@ require 'puppet/indirector/exec'
class Puppet::Node::Exec < Puppet::Indirector::Exec
desc "Call an external program to get node information. See
- the `ExternalNodes`:trac: page for more information."
+ the [External Nodes](http://docs.puppetlabs.com/guides/external_nodes.html) page for more information."
include Puppet::Util
def command
diff --git a/lib/puppet/indirector/node/ldap.rb b/lib/puppet/indirector/node/ldap.rb
index b9fe35575..5fd738511 100644
--- a/lib/puppet/indirector/node/ldap.rb
+++ b/lib/puppet/indirector/node/ldap.rb
@@ -3,9 +3,9 @@ require 'puppet/indirector/ldap'
class Puppet::Node::Ldap < Puppet::Indirector::Ldap
desc "Search in LDAP for node configuration information. See
- the `LdapNodes`:trac: page for more information. This will first
+ the [LDAP Nodes](http://projects.puppetlabs.com/projects/puppet/wiki/Ldap_Nodes) page for more information. This will first
search for whatever the certificate name is, then (if that name
- contains a '.') for the short name, then 'default'."
+ contains a `.`) for the short name, then `default`."
# The attributes that Puppet class information is stored in.
def class_attributes
@@ -19,30 +19,10 @@ class Puppet::Node::Ldap < Puppet::Indirector::Ldap
# LAK:NOTE Unfortunately, the ldap support is too stupid to throw anything
# but LDAP::ResultError, even on bad connections, so we are rough handed
# with our error handling.
- def name2hash(name,name_env,node_type)
+ def name2hash(name)
info = nil
- ldapsearch(search_filter(name)) {
- |entry| info = entry2hash(entry)
- if info[:environment]
- if name_env == info[:environment]
- return info
- else
- info = nil
- end
- else
- info_env = "production"
- if name_env == info[:environment]
- return info
- else
- info = nil
- end
- end
- }
- if node_type == 'parent'
- raise Puppet::Error.new("Could not find node '#{name}' with environment '#{name_env}'")
- end
-
- info = name2hash('default',name_env,'parent')
+ ldapsearch(search_filter(name)) { |entry| info = entry2hash(entry) }
+ info
end
# Look for our node in ldap.
@@ -53,18 +33,9 @@ class Puppet::Node::Ldap < Puppet::Indirector::Ldap
node = nil
names.each do |name|
- facts = Puppet::Node::Facts.find(name)
- if facts.values["environment"]
- name_env = facts.values["environment"]
- else
- name_env = "production"
- end
- info = name2hash(name,name_env,'child')
- next if info == nil
+ next unless info = name2hash(name)
- if info
- break if node = info2node(request.key, info)
- end
+ break if node = info2node(request.key, info)
end
node
@@ -200,29 +171,14 @@ class Puppet::Node::Ldap < Puppet::Indirector::Ldap
# Find information for our parent and merge it into the current info.
def find_and_merge_parent(parent, information)
-
- if information[:environment]
- name_env = information[:environment]
- else
- name_env = 'production'
- end
-
- parent_info = name2hash(parent,name_env,'parent')
- if parent_info
+ parent_info = name2hash(parent) || raise(Puppet::Error.new("Could not find parent node '#{parent}'"))
information[:classes] += parent_info[:classes]
parent_info[:parameters].each do |param, value|
- # Specifically test for whether it's set, so false values are handled
- # correctly.
+ # Specifically test for whether it's set, so false values are handled correctly.
information[:parameters][param] = value unless information[:parameters].include?(param)
end
-
information[:environment] ||= parent_info[:environment]
parent_info[:parent]
- else
- raise Puppet::Error.new("Could not find parent node '#{parent}'")
- nil
- end
-
end
# Take a name and a hash, and return a node instance.
diff --git a/lib/puppet/indirector/node/memory.rb b/lib/puppet/indirector/node/memory.rb
index ce4a52a8f..029926af8 100644
--- a/lib/puppet/indirector/node/memory.rb
+++ b/lib/puppet/indirector/node/memory.rb
@@ -3,7 +3,7 @@ require 'puppet/indirector/memory'
class Puppet::Node::Memory < Puppet::Indirector::Memory
desc "Keep track of nodes in memory but nowhere else. This is used for
- one-time compiles, such as what the stand-alone ``puppet`` does.
+ one-time compiles, such as what the stand-alone `puppet` does.
To use this terminus, you must load it with the data you want it
to contain; it is only useful for developers and should generally not
be chosen by a normal user."
diff --git a/lib/puppet/indirector/report/yaml.rb b/lib/puppet/indirector/report/yaml.rb
new file mode 100644
index 000000000..bf7bf4fe5
--- /dev/null
+++ b/lib/puppet/indirector/report/yaml.rb
@@ -0,0 +1,11 @@
+require 'puppet/transaction/report'
+require 'puppet/indirector/yaml'
+
+class Puppet::Transaction::Report::Yaml < Puppet::Indirector::Yaml
+ desc "Store last report as a flat file, serialized using YAML."
+
+ # Force report to be saved there
+ def path(name,ext='.yaml')
+ Puppet[:lastrunreport]
+ end
+end
diff --git a/lib/puppet/indirector/yaml.rb b/lib/puppet/indirector/yaml.rb
index c7c053f4b..23997e97a 100644
--- a/lib/puppet/indirector/yaml.rb
+++ b/lib/puppet/indirector/yaml.rb
@@ -41,19 +41,16 @@ class Puppet::Indirector::Yaml < Puppet::Indirector::Terminus
end
end
- # Get the yaml directory
- def base
- Puppet.run_mode.master? ? Puppet[:yamldir] : Puppet[:clientyamldir]
- end
-
# Return the path to a given node's file.
- def path(name)
- File.join(base, self.class.indirection_name.to_s, name.to_s + ".yaml")
+ def path(name,ext='.yaml')
+ base = Puppet.run_mode.master? ? Puppet[:yamldir] : Puppet[:clientyamldir]
+ File.join(base, self.class.indirection_name.to_s, name.to_s + ext)
end
- # Do a glob on the yaml directory, loading each file found
def search(request)
- Dir.glob(File.join(base, self.class.indirection_name.to_s, request.key)).collect { |f| YAML.load_file(f) }
+ Dir.glob(path(request.key,'')).collect do |file|
+ YAML.load_file(file)
+ end
end
private
diff --git a/lib/puppet/network/format_handler.rb b/lib/puppet/network/format_handler.rb
index d378ad6a1..b94a4f902 100644
--- a/lib/puppet/network/format_handler.rb
+++ b/lib/puppet/network/format_handler.rb
@@ -37,6 +37,12 @@ module Puppet::Network::FormatHandler
instance
end
+ def self.create_serialized_formats(name,options = {},&block)
+ ["application/x-#{name}", "application/#{name}", "text/x-#{name}", "text/#{name}"].each { |mime_type|
+ create name, {:mime => mime_type}.update(options), &block
+ }
+ end
+
def self.extended(klass)
klass.extend(ClassMethods)
diff --git a/lib/puppet/network/formats.rb b/lib/puppet/network/formats.rb
index 8a61ee62a..4ca3240d4 100644
--- a/lib/puppet/network/formats.rb
+++ b/lib/puppet/network/formats.rb
@@ -1,6 +1,6 @@
require 'puppet/network/format_handler'
-Puppet::Network::FormatHandler.create(:yaml, :mime => "text/yaml") do
+Puppet::Network::FormatHandler.create_serialized_formats(:yaml) do
# Yaml doesn't need the class name; it's serialized.
def intern(klass, text)
YAML.load(text)
@@ -29,7 +29,7 @@ end
# This is a "special" format which is used for the moment only when sending facts
# as REST GET parameters (see Puppet::Configurer::FactHandler).
# This format combines a yaml serialization, then zlib compression and base64 encoding.
-Puppet::Network::FormatHandler.create(:b64_zlib_yaml, :mime => "text/b64_zlib_yaml") do
+Puppet::Network::FormatHandler.create_serialized_formats(:b64_zlib_yaml) do
require 'base64'
def use_zlib?
@@ -127,7 +127,7 @@ Puppet::Network::FormatHandler.create(:raw, :mime => "application/x-raw", :weigh
end
end
-Puppet::Network::FormatHandler.create(:pson, :mime => "text/pson", :weight => 10, :required_methods => [:render_method, :intern_method]) do
+Puppet::Network::FormatHandler.create_serialized_formats(:pson, :weight => 10, :required_methods => [:render_method, :intern_method]) do
confine :true => Puppet.features.pson?
def intern(klass, text)
@@ -159,4 +159,4 @@ Puppet::Network::FormatHandler.create(:pson, :mime => "text/pson", :weight => 10
end
# This is really only ever going to be used for Catalogs.
-Puppet::Network::FormatHandler.create(:dot, :mime => "text/dot", :required_methods => [:render_method])
+Puppet::Network::FormatHandler.create_serialized_formats(:dot, :required_methods => [:render_method])
diff --git a/lib/puppet/network/handler/fileserver.rb b/lib/puppet/network/handler/fileserver.rb
index 27b913ab9..9abc7ee1a 100755
--- a/lib/puppet/network/handler/fileserver.rb
+++ b/lib/puppet/network/handler/fileserver.rb
@@ -4,9 +4,13 @@ require 'webrick/httpstatus'
require 'cgi'
require 'delegate'
require 'sync'
+require 'xmlrpc/server'
+require 'puppet/network/handler'
+require 'puppet/network/xmlrpc/server'
require 'puppet/file_serving'
require 'puppet/file_serving/metadata'
+require 'puppet/network/handler'
class Puppet::Network::Handler
AuthStoreError = Puppet::AuthStoreError
diff --git a/lib/puppet/network/http/api/v1.rb b/lib/puppet/network/http/api/v1.rb
index dd4612a14..abbb2dfa9 100644
--- a/lib/puppet/network/http/api/v1.rb
+++ b/lib/puppet/network/http/api/v1.rb
@@ -30,7 +30,7 @@ module Puppet::Network::HTTP::API::V1
key = URI.unescape(key)
- Puppet::Indirector::Request.new(indirection, method, key, params)
+ [indirection, method, key, params]
end
def indirection2uri(request)
@@ -57,9 +57,8 @@ module Puppet::Network::HTTP::API::V1
# fix to not need this, and our goal is to move away from the complication
# that leads to the fix being too long.
return :singular if indirection == "facts"
-
- # "status" really is singular
return :singular if indirection == "status"
+ return :plural if indirection == "inventory"
result = (indirection =~ /s$/) ? :plural : :singular
diff --git a/lib/puppet/network/http/handler.rb b/lib/puppet/network/http/handler.rb
index 03d24b3fe..82238aa0a 100644
--- a/lib/puppet/network/http/handler.rb
+++ b/lib/puppet/network/http/handler.rb
@@ -61,11 +61,11 @@ module Puppet::Network::HTTP::Handler
# handle an HTTP request
def process(request, response)
- indirection_request = uri2indirection(http_method(request), path(request), params(request))
+ indirection, method, key, params = uri2indirection(http_method(request), path(request), params(request))
- check_authorization(indirection_request)
+ check_authorization(indirection, method, key, params)
- send("do_#{indirection_request.method}", indirection_request, request, response)
+ send("do_#{method}", indirection, key, params, request, response)
rescue SystemExit,NoMemoryError
raise
rescue Exception => e
@@ -96,11 +96,16 @@ module Puppet::Network::HTTP::Handler
set_response(response, exception.to_s, status)
end
+ def model(indirection_name)
+ raise ArgumentError, "Could not find indirection '#{indirection_name}'" unless indirection = Puppet::Indirector::Indirection.instance(indirection_name.to_sym)
+ indirection.model
+ end
+
# Execute our find.
- def do_find(indirection_request, request, response)
- unless result = indirection_request.model.find(indirection_request.key, indirection_request.to_hash)
- Puppet.info("Could not find #{indirection_request.indirection_name} for '#{indirection_request.key}'")
- return do_exception(response, "Could not find #{indirection_request.indirection_name} #{indirection_request.key}", 404)
+ def do_find(indirection_name, key, params, request, response)
+ unless result = model(indirection_name).find(key, params)
+ Puppet.info("Could not find #{indirection_name} for '#{key}'")
+ return do_exception(response, "Could not find #{indirection_name} #{key}", 404)
end
# The encoding of the result must include the format to use,
@@ -113,34 +118,35 @@ module Puppet::Network::HTTP::Handler
end
# Execute our search.
- def do_search(indirection_request, request, response)
- result = indirection_request.model.search(indirection_request.key, indirection_request.to_hash)
+ def do_search(indirection_name, key, params, request, response)
+ model = self.model(indirection_name)
+ result = model.search(key, params)
- if result.nil? or (result.is_a?(Array) and result.empty?)
- return do_exception(response, "Could not find instances in #{indirection_request.indirection_name} with '#{indirection_request.to_hash.inspect}'", 404)
+ if result.nil?
+ return do_exception(response, "Could not find instances in #{indirection_name} with '#{key}'", 404)
end
format = format_to_use(request)
set_content_type(response, format)
- set_response(response, indirection_request.model.render_multiple(format, result))
+ set_response(response, model.render_multiple(format, result))
end
# Execute our destroy.
- def do_destroy(indirection_request, request, response)
- result = indirection_request.model.destroy(indirection_request.key, indirection_request.to_hash)
+ def do_destroy(indirection_name, key, params, request, response)
+ result = model(indirection_name).destroy(key, params)
return_yaml_response(response, result)
end
# Execute our save.
- def do_save(indirection_request, request, response)
+ def do_save(indirection_name, key, params, request, response)
data = body(request).to_s
raise ArgumentError, "No data to save" if !data or data.empty?
format = request_format(request)
- obj = indirection_request.model.convert_from(format, data)
- result = save_object(indirection_request, obj)
+ obj = model(indirection_name).convert_from(format, data)
+ result = obj.save(key)
return_yaml_response(response, result)
end
@@ -162,12 +168,6 @@ module Puppet::Network::HTTP::Handler
set_response(response, body.to_yaml)
end
- # LAK:NOTE This has to be here for testing; it's a stub-point so
- # we keep infinite recursion from happening.
- def save_object(ind_request, object)
- object.save(ind_request.key)
- end
-
def get?(request)
http_method(request) == 'GET'
end
diff --git a/lib/puppet/network/http/rack.rb b/lib/puppet/network/http/rack.rb
index c18a07559..5b4ef7e1c 100644
--- a/lib/puppet/network/http/rack.rb
+++ b/lib/puppet/network/http/rack.rb
@@ -1,3 +1,6 @@
+require 'rack'
+require 'rack/request'
+require 'rack/response'
require 'puppet/network/http'
require 'puppet/network/http/rack/rest'
diff --git a/lib/puppet/network/http/rack/rest.rb b/lib/puppet/network/http/rack/rest.rb
index e5f50c465..b7e1d9709 100644
--- a/lib/puppet/network/http/rack/rest.rb
+++ b/lib/puppet/network/http/rack/rest.rb
@@ -41,7 +41,7 @@ class Puppet::Network::HTTP::RackREST < Puppet::Network::HTTP::RackHttpHandler
unless result.is_a?(File)
response.write result
else
- response["Content-Length"] = result.stat.size
+ response["Content-Length"] = result.stat.size.to_s
response.body = RackFile.new(result)
end
end
diff --git a/lib/puppet/network/http/webrick/rest.rb b/lib/puppet/network/http/webrick/rest.rb
index 91008aa1a..d5c146d88 100644
--- a/lib/puppet/network/http/webrick/rest.rb
+++ b/lib/puppet/network/http/webrick/rest.rb
@@ -1,5 +1,6 @@
require 'puppet/network/http/handler'
require 'resolv'
+require 'webrick'
class Puppet::Network::HTTP::WEBrickREST < WEBrick::HTTPServlet::AbstractServlet
diff --git a/lib/puppet/network/http_pool.rb b/lib/puppet/network/http_pool.rb
index a3b055572..7d227b4d4 100644
--- a/lib/puppet/network/http_pool.rb
+++ b/lib/puppet/network/http_pool.rb
@@ -58,18 +58,6 @@ module Puppet::Network::HttpPool
http.cert = ssl_host.certificate.content
http.verify_mode = OpenSSL::SSL::VERIFY_PEER
http.key = ssl_host.key.content
- http.verify_callback = self.method(:ssl_verify_callback).to_proc if Puppet[:debug]
- end
-
- def self.ssl_verify_callback(peer_ok, x509_store_ctx)
- if not peer_ok
- Puppet.debug "OpenSSL: Error(#{x509_store_ctx.error}): #{x509_store_ctx.error_string}"
- Puppet.debug "OpenSSL: Cert: #{x509_store_ctx.current_cert.issuer}"
- Puppet.debug "OpenSSL: Current CRL: #{x509_store_ctx.current_crl}"
- Puppet.debug "OpenSSL: Chain:"
- x509_store_ctx.chain.each_index { |i| Puppet.debug "OpenSSL: \t#{i} #{x509_store_ctx.chain[i].issuer}" }
- end
- peer_ok
end
# Retrieve a cached http instance if caching is enabled, else return
diff --git a/lib/puppet/network/rest_authconfig.rb b/lib/puppet/network/rest_authconfig.rb
index 38a8f9a09..b6a163316 100644
--- a/lib/puppet/network/rest_authconfig.rb
+++ b/lib/puppet/network/rest_authconfig.rb
@@ -3,6 +3,7 @@ require 'puppet/network/authconfig'
module Puppet
class Network::RestAuthConfig < Network::AuthConfig
+ extend MonitorMixin
attr_accessor :rights
DEFAULT_ACL = [
@@ -20,30 +21,32 @@ module Puppet
]
def self.main
- add_acl = @main.nil?
- super
- @main.insert_default_acl if add_acl and !@main.exists?
+ synchronize do
+ add_acl = @main.nil?
+ super
+ @main.insert_default_acl if add_acl and !@main.exists?
+ end
@main
end
# check wether this request is allowed in our ACL
# raise an Puppet::Network::AuthorizedError if the request
# is denied.
- def allowed?(request)
+ def allowed?(indirection, method, key, params)
read
# we're splitting the request in part because
# fail_on_deny could as well be called in the XMLRPC context
# with a ClientRequest.
- @rights.fail_on_deny(
- build_uri(request),
-
- :node => request.node,
- :ip => request.ip,
- :method => request.method,
- :environment => request.environment,
- :authenticated => request.authenticated)
+ @rights.fail_on_deny(
+ build_uri(indirection, key),
+ :node => params[:node],
+ :ip => params[:ip],
+ :method => method,
+ :environment => params[:environment],
+ :authenticated => params[:authenticated]
+ )
end
def initialize(file = nil, parsenow = true)
@@ -87,8 +90,8 @@ module Puppet
@rights.restrict_authenticated(acl[:acl], acl[:authenticated]) unless acl[:authenticated].nil?
end
- def build_uri(request)
- "/#{request.indirection_name}/#{request.key}"
+ def build_uri(indirection_name, key)
+ "/#{indirection_name}/#{key}"
end
end
end
diff --git a/lib/puppet/network/rest_authorization.rb b/lib/puppet/network/rest_authorization.rb
index e052245eb..50f094e3e 100644
--- a/lib/puppet/network/rest_authorization.rb
+++ b/lib/puppet/network/rest_authorization.rb
@@ -15,8 +15,8 @@ module Puppet::Network
end
# Verify that our client has access.
- def check_authorization(request)
- authconfig.allowed?(request)
+ def check_authorization(indirection, method, key, params)
+ authconfig.allowed?(indirection, method, key, params)
end
end
end
diff --git a/lib/puppet/network/server.rb b/lib/puppet/network/server.rb
index d424b9c4a..e4de07dea 100644
--- a/lib/puppet/network/server.rb
+++ b/lib/puppet/network/server.rb
@@ -32,14 +32,14 @@ class Puppet::Network::Server
# Create a pidfile for our daemon, so we can be stopped and others
# don't try to start.
def create_pidfile
- Puppet::Util.sync(Puppet[:name]).synchronize(Sync::EX) do
+ Puppet::Util.synchronize_on(Puppet[:name],Sync::EX) do
raise "Could not create PID file: #{pidfile}" unless Puppet::Util::Pidlock.new(pidfile).lock
end
end
# Remove the pid file for our daemon.
def remove_pidfile
- Puppet::Util.sync(Puppet[:name]).synchronize(Sync::EX) do
+ Puppet::Util.synchronize_on(Puppet[:name],Sync::EX) do
locker = Puppet::Util::Pidlock.new(pidfile)
locker.unlock or Puppet.err "Could not remove PID file #{pidfile}" if locker.locked?
end
diff --git a/lib/puppet/node.rb b/lib/puppet/node.rb
index 2453cd1d5..e8d58e6be 100644
--- a/lib/puppet/node.rb
+++ b/lib/puppet/node.rb
@@ -3,6 +3,7 @@ require 'puppet/indirector'
# A class for managing nodes, including their facts and environment.
class Puppet::Node
require 'puppet/node/facts'
+ require 'puppet/node/inventory'
require 'puppet/node/environment'
# Set up indirection, so that nodes can be looked for in
diff --git a/lib/puppet/node/environment.rb b/lib/puppet/node/environment.rb
index 762599cff..7877b7f73 100644
--- a/lib/puppet/node/environment.rb
+++ b/lib/puppet/node/environment.rb
@@ -1,4 +1,5 @@
require 'puppet/util/cacher'
+require 'monitor'
# Just define it, so this class has fewer load dependencies.
class Puppet::Node
@@ -67,14 +68,23 @@ class Puppet::Node::Environment
def initialize(name)
@name = name
+ extend MonitorMixin
end
def known_resource_types
- if @known_resource_types.nil? or @known_resource_types.stale?
- @known_resource_types = Puppet::Resource::TypeCollection.new(self)
- @known_resource_types.perform_initial_import
- end
- @known_resource_types
+ # This makes use of short circuit evaluation to get the right thread-safe
+ # per environment semantics with an efficient most common cases; we almost
+ # always just return our thread's known-resource types. Only at the start
+ # of a compilation (after our thread var has been set to nil) or when the
+ # environment has changed do we delve deeper.
+ Thread.current[:known_resource_types] = nil if (krt = Thread.current[:known_resource_types]) && krt.environment != self
+ Thread.current[:known_resource_types] ||= synchronize {
+ if @known_resource_types.nil? or @known_resource_types.stale?
+ @known_resource_types = Puppet::Resource::TypeCollection.new(self)
+ @known_resource_types.import_ast(perform_initial_import, '')
+ end
+ @known_resource_types
+ }
end
def module(name)
@@ -114,6 +124,10 @@ class Puppet::Node::Environment
name.to_s
end
+ def to_sym
+ to_s.to_sym
+ end
+
# The only thing we care about when serializing an environment is its
# identity; everything else is ephemeral and should not be stored or
# transmitted.
@@ -133,5 +147,31 @@ class Puppet::Node::Environment
end
end
+ private
+
+ def perform_initial_import
+ return empty_parse_result if Puppet.settings[:ignoreimport]
+ parser = Puppet::Parser::Parser.new(self)
+ if code = Puppet.settings.uninterpolated_value(:code, name.to_s) and code != ""
+ parser.string = code
+ else
+ file = Puppet.settings.value(:manifest, name.to_s)
+ return empty_parse_result unless File.exist?(file)
+ parser.file = file
+ end
+ parser.parse
+ rescue => detail
+ msg = "Could not parse for environment #{self}: #{detail}"
+ error = Puppet::Error.new(msg)
+ error.set_backtrace(detail.backtrace)
+ raise error
+ end
+
+ def empty_parse_result
+ # Return an empty toplevel hostclass to use as the result of
+ # perform_initial_import when no file was actually loaded.
+ return Puppet::Parser::AST::Hostclass.new('')
+ end
+
@root = new(:'*root*')
end
diff --git a/lib/puppet/node/facts.rb b/lib/puppet/node/facts.rb
index b77ad22d5..d84d54113 100755
--- a/lib/puppet/node/facts.rb
+++ b/lib/puppet/node/facts.rb
@@ -1,12 +1,17 @@
+require 'time'
+
require 'puppet/node'
require 'puppet/indirector'
+require 'puppet/util/pson'
+
# Manage a given node's facts. This either accepts facts and stores them, or
# returns facts for a given node.
class Puppet::Node::Facts
# Set up indirection, so that nodes can be looked for in
# the node sources.
extend Puppet::Indirector
+ extend Puppet::Util::Pson
# We want to expire any cached nodes if the facts are saved.
module NodeExpirer
@@ -30,7 +35,7 @@ class Puppet::Node::Facts
@name = name
@values = values
- add_internal
+ add_timestamp
end
def downcase_if_necessary
@@ -54,13 +59,37 @@ class Puppet::Node::Facts
strip_internal == other.send(:strip_internal)
end
- private
+ def self.from_pson(data)
+ result = new(data['name'], data['values'])
+ result.values[:_timestamp] = Time.parse(data['timestamp'])
+ result.expiration = Time.parse(data['expiration'])
+ result
+ end
+
+ def to_pson(*args)
+ {
+ 'expiration' => expiration,
+ 'name' => name,
+ 'timestamp' => values[:_timestamp],
+ 'values' => values.reject {|k,v| k == :_timestamp},
+ }.to_pson(*args)
+ end
# Add internal data to the facts for storage.
- def add_internal
- self.values[:_timestamp] = Time.now
+ def add_timestamp
+ self.timestamp = Time.now
end
+ def timestamp=(time)
+ self.values[:_timestamp] = time
+ end
+
+ def timestamp
+ self.values[:_timestamp]
+ end
+
+ private
+
# Strip out that internal data.
def strip_internal
newvals = values.dup
diff --git a/lib/puppet/node/inventory.rb b/lib/puppet/node/inventory.rb
new file mode 100644
index 000000000..fd99163b0
--- /dev/null
+++ b/lib/puppet/node/inventory.rb
@@ -0,0 +1,7 @@
+require 'puppet/node'
+require 'puppet/indirector'
+
+class Puppet::Node::Inventory
+ extend Puppet::Indirector
+ indirects :inventory, :terminus_setting => :inventory_terminus
+end
diff --git a/lib/puppet/parameter/value_collection.rb b/lib/puppet/parameter/value_collection.rb
index a9fd20233..619e0731d 100644
--- a/lib/puppet/parameter/value_collection.rb
+++ b/lib/puppet/parameter/value_collection.rb
@@ -21,14 +21,14 @@ class Puppet::Parameter::ValueCollection
@doc += " Valid values are "
@doc += @strings.collect do |value|
if aliases = value.aliases and ! aliases.empty?
- "``#{value.name}`` (also called ``#{aliases.join(", ")}``)"
+ "`#{value.name}` (also called `#{aliases.join(", ")}`)"
else
- "``#{value.name}``"
+ "`#{value.name}`"
end
end.join(", ") + "."
end
- @doc += " Values can match ``" + regexes.join("``, ``") + "``." unless regexes.empty?
+ @doc += " Values can match `" + regexes.join("`, `") + "`." unless regexes.empty?
end
@doc
diff --git a/lib/puppet/parser/ast.rb b/lib/puppet/parser/ast.rb
index 54e034acb..03891160b 100644
--- a/lib/puppet/parser/ast.rb
+++ b/lib/puppet/parser/ast.rb
@@ -107,28 +107,32 @@ end
require 'puppet/parser/ast/arithmetic_operator'
require 'puppet/parser/ast/astarray'
require 'puppet/parser/ast/asthash'
-require 'puppet/parser/ast/branch'
require 'puppet/parser/ast/boolean_operator'
+require 'puppet/parser/ast/branch'
require 'puppet/parser/ast/caseopt'
require 'puppet/parser/ast/casestatement'
require 'puppet/parser/ast/collection'
require 'puppet/parser/ast/collexpr'
require 'puppet/parser/ast/comparison_operator'
+require 'puppet/parser/ast/definition'
require 'puppet/parser/ast/else'
require 'puppet/parser/ast/function'
+require 'puppet/parser/ast/hostclass'
require 'puppet/parser/ast/ifstatement'
require 'puppet/parser/ast/in_operator'
require 'puppet/parser/ast/leaf'
require 'puppet/parser/ast/match_operator'
require 'puppet/parser/ast/minus'
+require 'puppet/parser/ast/node'
require 'puppet/parser/ast/nop'
require 'puppet/parser/ast/not'
+require 'puppet/parser/ast/relationship'
require 'puppet/parser/ast/resource'
require 'puppet/parser/ast/resource_defaults'
+require 'puppet/parser/ast/resource_instance'
require 'puppet/parser/ast/resource_override'
require 'puppet/parser/ast/resource_reference'
require 'puppet/parser/ast/resourceparam'
require 'puppet/parser/ast/selector'
require 'puppet/parser/ast/tag'
require 'puppet/parser/ast/vardef'
-require 'puppet/parser/ast/relationship'
diff --git a/lib/puppet/parser/ast/astarray.rb b/lib/puppet/parser/ast/astarray.rb
index 529998e3c..7283a1f6c 100644
--- a/lib/puppet/parser/ast/astarray.rb
+++ b/lib/puppet/parser/ast/astarray.rb
@@ -16,25 +16,20 @@ class Puppet::Parser::AST
# Evaluate our children.
def evaluate(scope)
- # Make a new array, so we don't have to deal with the details of
- # flattening and such
- items = []
-
- # First clean out any AST::ASTArrays
- @children.each { |child|
- if child.instance_of?(AST::ASTArray)
- child.each do |ac|
- items << ac
+ result = []
+ @children.each do |child|
+ # Skip things that respond to :instantiate (classes, nodes,
+ # and definitions), because they have already been
+ # instantiated.
+ if !child.respond_to?(:instantiate)
+ item = child.safeevaluate(scope)
+ if !item.nil?
+ # nil values are implicitly removed.
+ result.push(item)
end
- else
- items << child
end
- }
-
- rets = items.flatten.collect { |child|
- child.safeevaluate(scope)
- }
- rets.reject { |o| o.nil? }
+ end
+ result
end
def push(*ary)
@@ -52,10 +47,4 @@ class Puppet::Parser::AST
"[" + @children.collect { |c| c.to_s }.join(', ') + "]"
end
end
-
- # A simple container class, containing the parameters for an object.
- # Used for abstracting the grammar declarations. Basically unnecessary
- # except that I kept finding bugs because I had too many arrays that
- # meant completely different things.
- class ResourceInstance < ASTArray; end
end
diff --git a/lib/puppet/parser/ast/caseopt.rb b/lib/puppet/parser/ast/caseopt.rb
index 4e296e82f..db4c2b024 100644
--- a/lib/puppet/parser/ast/caseopt.rb
+++ b/lib/puppet/parser/ast/caseopt.rb
@@ -18,16 +18,12 @@ class Puppet::Parser::AST
# Cache the @default value.
return @default if defined?(@default)
- if @value.is_a?(AST::ASTArray)
- @value.each { |subval|
- if subval.is_a?(AST::Default)
- @default = true
- break
- end
- }
- else
- @default = true if @value.is_a?(AST::Default)
- end
+ @value.each { |subval|
+ if subval.is_a?(AST::Default)
+ @default = true
+ break
+ end
+ }
@default ||= false
@@ -36,23 +32,15 @@ class Puppet::Parser::AST
# You can specify a list of values; return each in turn.
def eachvalue(scope)
- if @value.is_a?(AST::ASTArray)
- @value.each { |subval|
- yield subval.safeevaluate(scope)
- }
- else
- yield @value.safeevaluate(scope)
- end
+ @value.each { |subval|
+ yield subval.safeevaluate(scope)
+ }
end
def eachopt
- if @value.is_a?(AST::ASTArray)
- @value.each { |subval|
- yield subval
- }
- else
- yield @value
- end
+ @value.each { |subval|
+ yield subval
+ }
end
# Evaluate the actual statements; this only gets called if
diff --git a/lib/puppet/parser/ast/collection.rb b/lib/puppet/parser/ast/collection.rb
index 09d5b4eb3..ef36b7143 100644
--- a/lib/puppet/parser/ast/collection.rb
+++ b/lib/puppet/parser/ast/collection.rb
@@ -5,61 +5,44 @@ require 'puppet/parser/collector'
# An object that collects stored objects from the central cache and returns
# them to the current host, yo.
class Puppet::Parser::AST
-class Collection < AST::Branch
- attr_accessor :type, :query, :form
- attr_reader :override
-
- associates_doc
-
- # We return an object that does a late-binding evaluation.
- def evaluate(scope)
- if self.query
- str, code = self.query.safeevaluate scope
- else
- str = code = nil
- end
-
- newcoll = Puppet::Parser::Collector.new(scope, @type, str, code, self.form)
-
- scope.compiler.add_collection(newcoll)
-
- # overrides if any
- # Evaluate all of the specified params.
- if @override
- params = @override.collect do |param|
- param.safeevaluate(scope)
+ class Collection < AST::Branch
+ attr_accessor :type, :query, :form
+ attr_reader :override
+
+ associates_doc
+
+ # We return an object that does a late-binding evaluation.
+ def evaluate(scope)
+ str, code = query && query.safeevaluate(scope)
+
+ resource_type = scope.find_resource_type(@type)
+ newcoll = Puppet::Parser::Collector.new(scope, resource_type.name, str, code, self.form)
+
+ scope.compiler.add_collection(newcoll)
+
+ # overrides if any
+ # Evaluate all of the specified params.
+ if @override
+ params = @override.collect { |param| param.safeevaluate(scope) }
+ newcoll.add_override(
+ :parameters => params,
+ :file => @file,
+ :line => @line,
+ :source => scope.source,
+ :scope => scope
+ )
end
-
- newcoll.add_override(
-
- :parameters => params,
- :file => @file,
- :line => @line,
- :source => scope.source,
-
- :scope => scope
- )
+ newcoll
end
- newcoll
- end
-
- # Handle our parameter ourselves
- def override=(override)
- if override.is_a?(AST::ASTArray)
- @override = override
- else
-
- @override = AST::ASTArray.new(
-
- :line => override.line,
- :file => override.file,
-
- :children => [override]
- )
+ # Handle our parameter ourselves
+ def override=(override)
+ @override = if override.is_a?(AST::ASTArray)
+ override
+ else
+ AST::ASTArray.new(:line => override.line,:file => override.file,:children => [override])
+ end
end
end
-
-end
end
diff --git a/lib/puppet/parser/ast/definition.rb b/lib/puppet/parser/ast/definition.rb
new file mode 100644
index 000000000..c43422f82
--- /dev/null
+++ b/lib/puppet/parser/ast/definition.rb
@@ -0,0 +1,17 @@
+require 'puppet/parser/ast/top_level_construct'
+
+class Puppet::Parser::AST::Definition < Puppet::Parser::AST::TopLevelConstruct
+ attr_accessor :context
+
+ def initialize(name, context = {}, &ruby_code)
+ @name = name
+ @context = context
+ @ruby_code = ruby_code
+ end
+
+ def instantiate(modname)
+ new_definition = Puppet::Resource::Type.new(:definition, @name, @context.merge(:module_name => modname))
+ new_definition.ruby_code = @ruby_code if @ruby_code
+ [new_definition]
+ end
+end
diff --git a/lib/puppet/parser/ast/function.rb b/lib/puppet/parser/ast/function.rb
index 602016c75..80e6e6512 100644
--- a/lib/puppet/parser/ast/function.rb
+++ b/lib/puppet/parser/ast/function.rb
@@ -11,7 +11,6 @@ class Puppet::Parser::AST
@settor = true
def evaluate(scope)
-
# Make sure it's a defined function
raise Puppet::ParseError, "Unknown function #{@name}" unless Puppet::Parser::Functions.function(@name)
@@ -29,7 +28,7 @@ class Puppet::Parser::AST
end
# We don't need to evaluate the name, because it's plaintext
- args = @arguments.safeevaluate(scope)
+ args = @arguments.safeevaluate(scope).map { |x| x == :undef ? '' : x }
scope.send("function_#{@name}", args)
end
diff --git a/lib/puppet/parser/ast/hostclass.rb b/lib/puppet/parser/ast/hostclass.rb
new file mode 100644
index 000000000..cab5e4a24
--- /dev/null
+++ b/lib/puppet/parser/ast/hostclass.rb
@@ -0,0 +1,29 @@
+require 'puppet/parser/ast/top_level_construct'
+
+class Puppet::Parser::AST::Hostclass < Puppet::Parser::AST::TopLevelConstruct
+ attr_accessor :name, :context
+
+ def initialize(name, context = {}, &ruby_code)
+ @context = context
+ @name = name
+ @ruby_code = ruby_code
+ end
+
+ def instantiate(modname)
+ new_class = Puppet::Resource::Type.new(:hostclass, @name, @context.merge(:module_name => modname))
+ new_class.ruby_code = @ruby_code if @ruby_code
+ all_types = [new_class]
+ if code
+ code.each do |nested_ast_node|
+ if nested_ast_node.respond_to? :instantiate
+ all_types += nested_ast_node.instantiate(modname)
+ end
+ end
+ end
+ return all_types
+ end
+
+ def code()
+ @context[:code]
+ end
+end
diff --git a/lib/puppet/parser/ast/leaf.rb b/lib/puppet/parser/ast/leaf.rb
index 49cde63ca..fcdd219d7 100644
--- a/lib/puppet/parser/ast/leaf.rb
+++ b/lib/puppet/parser/ast/leaf.rb
@@ -42,7 +42,7 @@ class Puppet::Parser::AST
# The base string class.
class String < AST::Leaf
def evaluate(scope)
- @value
+ @value.dup
end
def to_s
@@ -148,12 +148,20 @@ class Puppet::Parser::AST
key.respond_to?(:evaluate) ? key.safeevaluate(scope) : key
end
+ def array_index_or_key(object, key)
+ if object.is_a?(Array)
+ raise Puppet::ParserError, "#{key} is not an integer, but is used as an index of an array" unless key = Puppet::Parser::Scope.number?(key)
+ end
+ key
+ end
+
def evaluate(scope)
object = evaluate_container(scope)
+ accesskey = evaluate_key(scope)
raise Puppet::ParseError, "#{variable} is not an hash or array when accessing it with #{accesskey}" unless object.is_a?(Hash) or object.is_a?(Array)
- object[evaluate_key(scope)]
+ object[array_index_or_key(object, accesskey)]
end
# Assign value to this hashkey or array index
@@ -166,7 +174,7 @@ class Puppet::Parser::AST
end
# assign to hash or array
- object[accesskey] = value
+ object[array_index_or_key(object, accesskey)] = value
end
def to_s
diff --git a/lib/puppet/parser/ast/node.rb b/lib/puppet/parser/ast/node.rb
new file mode 100644
index 000000000..b69a5c4e0
--- /dev/null
+++ b/lib/puppet/parser/ast/node.rb
@@ -0,0 +1,20 @@
+require 'puppet/parser/ast/top_level_construct'
+
+class Puppet::Parser::AST::Node < Puppet::Parser::AST::TopLevelConstruct
+ attr_accessor :names, :context
+
+ def initialize(names, context = {}, &ruby_code)
+ raise ArgumentError, "names should be an array" unless names.is_a? Array
+ @names = names
+ @context = context
+ @ruby_code = ruby_code
+ end
+
+ def instantiate(modname)
+ @names.collect do |name|
+ new_node = Puppet::Resource::Type.new(:node, name, @context.merge(:module_name => modname))
+ new_node.ruby_code = @ruby_code if @ruby_code
+ new_node
+ end
+ end
+end
diff --git a/lib/puppet/parser/ast/resource.rb b/lib/puppet/parser/ast/resource.rb
index 1b063c984..ce3c499c5 100644
--- a/lib/puppet/parser/ast/resource.rb
+++ b/lib/puppet/parser/ast/resource.rb
@@ -3,26 +3,15 @@ require 'puppet/parser/ast/resource_reference'
# Any normal puppet resource declaration. Can point to a definition or a
# builtin type.
class Puppet::Parser::AST
-class Resource < AST::ResourceReference
+class Resource < AST::Branch
associates_doc
- attr_accessor :title, :type, :exported, :virtual
- attr_reader :parameters
+ attr_accessor :type, :instances, :exported, :virtual
# Does not actually return an object; instead sets an object
# in the current scope.
def evaluate(scope)
- # Evaluate all of the specified params.
- paramobjects = parameters.collect { |param|
- param.safeevaluate(scope)
- }
-
- resource_titles = @title.safeevaluate(scope)
-
- # it's easier to always use an array, even for only one name
- resource_titles = [resource_titles] unless resource_titles.is_a?(Array)
-
# We want virtual to be true if exported is true. We can't
# just set :virtual => self.virtual in the initialization,
# because sometimes the :virtual attribute is set *after*
@@ -30,48 +19,49 @@ class Resource < AST::ResourceReference
# is true. Argh, this was a very tough one to track down.
virt = self.virtual || self.exported
- # This is where our implicit iteration takes place; if someone
- # passed an array as the name, then we act just like the called us
- # many times.
- resource_titles.flatten.collect { |resource_title|
- exceptwrap :type => Puppet::ParseError do
+ # First level of implicit iteration: build a resource for each
+ # instance. This handles things like:
+ # file { '/foo': owner => blah; '/bar': owner => blah }
+ @instances.collect { |instance|
- resource = Puppet::Parser::Resource.new(
- type, resource_title,
- :parameters => paramobjects,
- :file => self.file,
- :line => self.line,
- :exported => self.exported,
- :virtual => virt,
- :source => scope.source,
- :scope => scope,
-
- :strict => true
- )
+ # Evaluate all of the specified params.
+ paramobjects = instance.parameters.collect { |param|
+ param.safeevaluate(scope)
+ }
- # And then store the resource in the compiler.
- # At some point, we need to switch all of this to return
- # resources instead of storing them like this.
- scope.compiler.add_resource(scope, resource)
- resource
- end
- }.reject { |resource| resource.nil? }
- end
+ resource_titles = instance.title.safeevaluate(scope)
+
+ # it's easier to always use an array, even for only one name
+ resource_titles = [resource_titles] unless resource_titles.is_a?(Array)
+
+ fully_qualified_type, resource_titles = scope.resolve_type_and_titles(type, resource_titles)
- # Set the parameters for our object.
- def parameters=(params)
- if params.is_a?(AST::ASTArray)
- @parameters = params
- else
+ # Second level of implicit iteration; build a resource for each
+ # title. This handles things like:
+ # file { ['/foo', '/bar']: owner => blah }
+ resource_titles.flatten.collect { |resource_title|
+ exceptwrap :type => Puppet::ParseError do
+ resource = Puppet::Parser::Resource.new(
+ fully_qualified_type, resource_title,
+ :parameters => paramobjects,
+ :file => self.file,
+ :line => self.line,
+ :exported => self.exported,
+ :virtual => virt,
+ :source => scope.source,
+ :scope => scope,
+ :strict => true
+ )
- @parameters = AST::ASTArray.new(
-
- :line => params.line,
- :file => params.file,
-
- :children => [params]
- )
- end
+ if resource.resource_type.is_a? Puppet::Resource::Type
+ resource.resource_type.instantiate_resource(scope, resource)
+ end
+ scope.compiler.add_resource(scope, resource)
+ scope.compiler.evaluate_classes([resource_title],scope,false) if fully_qualified_type == 'class'
+ resource
+ end
+ }
+ }.flatten.reject { |resource| resource.nil? }
end
end
end
diff --git a/lib/puppet/parser/ast/resource_instance.rb b/lib/puppet/parser/ast/resource_instance.rb
new file mode 100644
index 000000000..ebfb17bf1
--- /dev/null
+++ b/lib/puppet/parser/ast/resource_instance.rb
@@ -0,0 +1,9 @@
+require 'puppet/parser/ast/branch'
+
+class Puppet::Parser::AST
+ class ResourceInstance < Branch
+ # A simple container for a parameter for an object. Consists of a
+ # title and a set of parameters.
+ attr_accessor :title, :parameters
+ end
+end
diff --git a/lib/puppet/parser/ast/resource_override.rb b/lib/puppet/parser/ast/resource_override.rb
index e0be889ff..d638202ab 100644
--- a/lib/puppet/parser/ast/resource_override.rb
+++ b/lib/puppet/parser/ast/resource_override.rb
@@ -3,12 +3,11 @@ require 'puppet/parser/ast/resource'
class Puppet::Parser::AST
# Set a parameter on a resource specification created somewhere else in the
# configuration. The object is responsible for verifying that this is allowed.
- class ResourceOverride < Resource
+ class ResourceOverride < AST::Branch
associates_doc
- attr_accessor :object
- attr_reader :parameters
+ attr_accessor :object, :parameters
# Iterate across all of our children.
def each
diff --git a/lib/puppet/parser/ast/resource_reference.rb b/lib/puppet/parser/ast/resource_reference.rb
index 5d8334335..0f8e655bf 100644
--- a/lib/puppet/parser/ast/resource_reference.rb
+++ b/lib/puppet/parser/ast/resource_reference.rb
@@ -7,8 +7,15 @@ class Puppet::Parser::AST::ResourceReference < Puppet::Parser::AST::Branch
# Evaluate our object, but just return a simple array of the type
# and name.
def evaluate(scope)
- titles = Array(title.safeevaluate(scope)).collect { |t| Puppet::Resource.new(type, t, :namespaces => scope.namespaces) }
- return(titles.length == 1 ? titles.pop : titles)
+ titles = Array(title.safeevaluate(scope))
+
+ a_type, titles = scope.resolve_type_and_titles(type, titles)
+
+ resources = titles.collect{ |a_title|
+ Puppet::Resource.new(a_type, a_title)
+ }
+
+ return(resources.length == 1 ? resources.pop : resources)
end
def to_s
diff --git a/lib/puppet/parser/ast/top_level_construct.rb b/lib/puppet/parser/ast/top_level_construct.rb
new file mode 100644
index 000000000..901a939c2
--- /dev/null
+++ b/lib/puppet/parser/ast/top_level_construct.rb
@@ -0,0 +1,4 @@
+# The base class for AST nodes representing top level things:
+# hostclasses, definitions, and nodes.
+class Puppet::Parser::AST::TopLevelConstruct < Puppet::Parser::AST
+end
diff --git a/lib/puppet/parser/compiler.rb b/lib/puppet/parser/compiler.rb
index a901c0dd6..c60e1d4fb 100644
--- a/lib/puppet/parser/compiler.rb
+++ b/lib/puppet/parser/compiler.rb
@@ -19,7 +19,12 @@ class Puppet::Parser::Compiler
rescue => detail
puts detail.backtrace if Puppet[:trace]
raise Puppet::Error, "#{detail} on node #{node.name}"
- end
+ ensure
+ # We get these from the environment and only cache them in a thread
+ # variable for the duration of the compilation.
+ Thread.current[:known_resource_types] = nil
+ Thread.current[:env_module_directories] = nil
+ end
attr_reader :node, :facts, :collections, :catalog, :node_scope, :resources, :relationships
@@ -51,13 +56,10 @@ class Puppet::Parser::Compiler
# Note that this will fail if the resource is not unique.
@catalog.add_resource(resource)
- set_container_resource(scope, resource)
- end
- # Add our container edge. If we're a class, then we get treated specially - we can
- # control the stage that the class is applied in. Otherwise, we just
- # get added to our parent container.
- def set_container_resource(scope, resource)
+ # Add our container edge. If we're a class, then we get treated specially - we can
+ # control the stage that the class is applied in. Otherwise, we just
+ # get added to our parent container.
return if resource.type.to_s.downcase == "stage"
if resource.type.to_s.downcase != "class"
@@ -65,15 +67,14 @@ class Puppet::Parser::Compiler
return @catalog.add_edge(scope.resource, resource)
end
- unless stage = @catalog.resource(:stage, resource[:stage] || :main)
+ unless stage = @catalog.resource(:stage, resource[:stage] || (scope && scope.resource && scope.resource[:stage]) || :main)
raise ArgumentError, "Could not find stage #{resource[:stage] || :main} specified by #{resource}"
end
+ resource[:stage] ||= stage.title unless stage.title == :main
@catalog.add_edge(stage, resource)
end
- private :set_container_resource
-
# Do we use nodes found in the code, vs. the external node sources?
def ast_nodes?
known_resource_types.nodes?
@@ -143,7 +144,7 @@ class Puppet::Parser::Compiler
if klass = scope.find_hostclass(name)
found << name and next if scope.class_scope(klass)
- resource = klass.mk_plain_resource(scope)
+ resource = klass.ensure_in_catalog(scope)
# If they've disabled lazy evaluation (which the :include function does),
# then evaluate our resource immediately.
@@ -219,7 +220,7 @@ class Puppet::Parser::Compiler
# Create a resource to model this node, and then add it to the list
# of resources.
- resource = astnode.mk_plain_resource(topscope)
+ resource = astnode.ensure_in_catalog(topscope)
resource.evaluate
@@ -284,10 +285,7 @@ class Puppet::Parser::Compiler
@main_resource = Puppet::Parser::Resource.new("class", :main, :scope => @topscope, :source => @main)
@topscope.resource = @main_resource
- @resources << @main_resource
- @catalog.add_resource(@main_resource)
-
- set_container_resource(@topscope, @main_resource)
+ add_resource(@topscope, @main_resource)
@main_resource.evaluate
end
diff --git a/lib/puppet/parser/files.rb b/lib/puppet/parser/files.rb
index 9ef05e102..f34683153 100644
--- a/lib/puppet/parser/files.rb
+++ b/lib/puppet/parser/files.rb
@@ -24,7 +24,7 @@ module Puppet::Parser::Files
# Than that would be a "no."
end
abspat = File::expand_path(start, cwd)
- [nil, Dir.glob(abspat + (File.extname(abspat).empty? ? '{,.pp,.rb}' : '' )).uniq.reject { |f| FileTest.directory?(f) }]
+ [nil, Dir.glob(abspat + (File.extname(abspat).empty? ? '{.pp,.rb}' : '' )).uniq.reject { |f| FileTest.directory?(f) }]
end
# Find the concrete file denoted by +file+. If +file+ is absolute,
diff --git a/lib/puppet/parser/functions.rb b/lib/puppet/parser/functions.rb
index c238da5d4..5807c0bbe 100644
--- a/lib/puppet/parser/functions.rb
+++ b/lib/puppet/parser/functions.rb
@@ -20,7 +20,7 @@ module Puppet::Parser::Functions
@autoloader = Puppet::Util::Autoload.new(
self,
"puppet/parser/functions",
-
+
:wrap => false
)
end
@@ -73,8 +73,10 @@ module Puppet::Parser::Functions
def self.function(name)
name = symbolize(name)
- unless functions.include?(name) or functions(Puppet::Node::Environment.root).include?(name)
- autoloader.load(name,Environment.current || Environment.root)
+ @functions.synchronize do
+ unless functions.include?(name) or functions(Puppet::Node::Environment.root).include?(name)
+ autoloader.load(name,Environment.current || Environment.root)
+ end
end
( functions(Environment.root)[name] || functions[name] || {:name => false} )[:name]
@@ -94,7 +96,7 @@ module Puppet::Parser::Functions
ret += "Undocumented.\n"
end
- ret += "\n\n- **Type**: #{hash[:type]}\n\n"
+ ret += "\n\n- *Type*: #{hash[:type]}\n\n"
end
ret
diff --git a/lib/puppet/parser/functions/defined.rb b/lib/puppet/parser/functions/defined.rb
index 2930a65cc..90632af2f 100644
--- a/lib/puppet/parser/functions/defined.rb
+++ b/lib/puppet/parser/functions/defined.rb
@@ -3,7 +3,7 @@ Puppet::Parser::Functions::newfunction(:defined, :type => :rvalue, :doc => "Dete
type is defined, either as a native type or a defined type, or whether a class is defined.
This is useful for checking whether a class is defined and only including it if it is.
This function can also test whether a resource has been defined, using resource references
- (e.g., ``if defined(File['/tmp/myfile']) { ... }``). This function is unfortunately
+ (e.g., `if defined(File['/tmp/myfile']) { ... }`). This function is unfortunately
dependent on the parse order of the configuration when testing whether a resource is defined.") do |vals|
result = false
vals = [vals] unless vals.is_a?(Array)
diff --git a/lib/puppet/parser/functions/extlookup.rb b/lib/puppet/parser/functions/extlookup.rb
new file mode 100644
index 000000000..bc55410b9
--- /dev/null
+++ b/lib/puppet/parser/functions/extlookup.rb
@@ -0,0 +1,157 @@
+require 'csv'
+
+module Puppet::Parser::Functions
+ newfunction(:extlookup,
+ :type => :rvalue,
+ :doc => "This is a parser function to read data from external files, this version
+uses CSV files but the concept can easily be adjust for databases, yaml
+or any other queryable data source.
+
+The object of this is to make it obvious when it's being used, rather than
+magically loading data in when an module is loaded I prefer to look at the code
+and see statements like:
+
+ $snmp_contact = extlookup(\"snmp_contact\")
+
+The above snippet will load the snmp_contact value from CSV files, this in its
+own is useful but a common construct in puppet manifests is something like this:
+
+ case $domain {
+ \"myclient.com\": { $snmp_contact = \"John Doe <john@myclient.com>\" }
+ default: { $snmp_contact = \"My Support <support@my.com>\" }
+ }
+
+Over time there will be a lot of this kind of thing spread all over your manifests
+and adding an additional client involves grepping through manifests to find all the
+places where you have constructs like this.
+
+This is a data problem and shouldn't be handled in code, a using this function you
+can do just that.
+
+First you configure it in site.pp:
+
+ $extlookup_datadir = \"/etc/puppet/manifests/extdata\"
+ $extlookup_precedence = [\"%{fqdn}\", \"domain_%{domain}\", \"common\"]
+
+The array tells the code how to resolve values, first it will try to find it in
+web1.myclient.com.csv then in domain_myclient.com.csv and finally in common.csv
+
+Now create the following data files in /etc/puppet/manifests/extdata:
+
+ domain_myclient.com.csv:
+ snmp_contact,John Doe <john@myclient.com>
+ root_contact,support@%{domain}
+ client_trusted_ips,192.168.1.130,192.168.10.0/24
+
+ common.csv:
+ snmp_contact,My Support <support@my.com>
+ root_contact,support@my.com
+
+Now you can replace the case statement with the simple single line to achieve
+the exact same outcome:
+
+ $snmp_contact = extlookup(\"snmp_contact\")
+
+The above code shows some other features, you can use any fact or variable that
+is in scope by simply using %{varname} in your data files, you can return arrays
+by just having multiple values in the csv after the initial variable name.
+
+In the event that a variable is nowhere to be found a critical error will be raised
+that will prevent your manifest from compiling, this is to avoid accidentally putting
+in empty values etc. You can however specify a default value:
+
+ $ntp_servers = extlookup(\"ntp_servers\", \"1.${country}.pool.ntp.org\")
+
+In this case it will default to \"1.${country}.pool.ntp.org\" if nothing is defined in
+any data file.
+
+You can also specify an additional data file to search first before any others at use
+time, for example:
+
+ $version = extlookup(\"rsyslog_version\", \"present\", \"packages\")
+ package{\"rsyslog\": ensure => $version }
+
+This will look for a version configured in packages.csv and then in the rest as configured
+by $extlookup_precedence if it's not found anywhere it will default to `present`, this kind
+of use case makes puppet a lot nicer for managing large amounts of packages since you do not
+need to edit a load of manifests to do simple things like adjust a desired version number.
+
+Precedence values can have variables embedded in them in the form %{fqdn}, you could for example do:
+
+ $extlookup_precedence = [\"hosts/%{fqdn}\", \"common\"]
+
+This will result in /path/to/extdata/hosts/your.box.com.csv being searched.
+
+This is for back compatibility to interpolate variables with %. % interpolation is a workaround for a problem that has been fixed: Puppet variable interpolation at top scope used to only happen on each run.") do |args|
+
+ key = args[0]
+
+ default = args[1]
+ datafile = args[2]
+
+ raise Puppet::ParseError, ("extlookup(): wrong number of arguments (#{args.length}; must be <= 3)") if args.length > 3
+
+ extlookup_datadir = lookupvar('extlookup_datadir')
+ extlookup_precedence = Array.new
+
+ extlookup_precedence = lookupvar('extlookup_precedence').collect do |var|
+ var.gsub(/%\{(.+?)\}/) do |capture|
+ lookupvar($1)
+ end
+ end
+
+ datafiles = Array.new
+
+ # if we got a custom data file, put it first in the array of search files
+ if datafile != ""
+ datafiles << extlookup_datadir + "/#{datafile}.csv" if File.exists?(extlookup_datadir + "/#{datafile}.csv")
+ end
+
+ extlookup_precedence.each do |d|
+ datafiles << extlookup_datadir + "/#{d}.csv"
+ end
+
+ desired = nil
+
+ datafiles.each do |file|
+ if desired.nil?
+ if File.exists?(file)
+ result = CSV.read(file).find_all do |r|
+ r[0] == key
+ end
+
+ # return just the single result if theres just one,
+ # else take all the fields in the csv and build an array
+ if result.length > 0
+ if result[0].length == 2
+ val = result[0][1].to_s
+
+ # parse %{}'s in the CSV into local variables using lookupvar()
+ while val =~ /%\{(.+?)\}/
+ val.gsub!(/%\{#{$1}\}/, lookupvar($1))
+ end
+
+ desired = val
+ elsif result[0].length > 1
+ length = result[0].length
+ cells = result[0][1,length]
+
+ # Individual cells in a CSV result are a weird data type and throws
+ # puppets yaml parsing, so just map it all to plain old strings
+ desired = cells.map do |c|
+ # parse %{}'s in the CSV into local variables using lookupvar()
+ while c =~ /%\{(.+?)\}/
+ c.gsub!(/%\{#{$1}\}/, lookupvar($1))
+ end
+
+ c.to_s
+ end
+ end
+ end
+ end
+ end
+ end
+
+ desired || default or raise Puppet::ParseError, "No match found for '#{key}' in any data file during extlookup()"
+ end
+end
diff --git a/lib/puppet/parser/functions/file.rb b/lib/puppet/parser/functions/file.rb
index 963111260..19ab9ba2e 100644
--- a/lib/puppet/parser/functions/file.rb
+++ b/lib/puppet/parser/functions/file.rb
@@ -2,7 +2,7 @@
Puppet::Parser::Functions::newfunction(
:file, :type => :rvalue,
-
+
:doc => "Return the contents of a file. Multiple files
can be passed, and the first file that exists will be read in.") do |vals|
ret = nil
diff --git a/lib/puppet/parser/functions/inline_template.rb b/lib/puppet/parser/functions/inline_template.rb
index 46e000383..9759ff6e1 100644
--- a/lib/puppet/parser/functions/inline_template.rb
+++ b/lib/puppet/parser/functions/inline_template.rb
@@ -1,9 +1,10 @@
Puppet::Parser::Functions::newfunction(:inline_template, :type => :rvalue, :doc =>
- "Evaluate a template string and return its value. See `the templating docs
- <http://docs.puppetlabs.com/guides/templating.html>`_ for more information. Note that
- if multiple template strings are specified, their output is all concatenated
- and returned as the output of the function.") do |vals|
- require 'erb'
+ "Evaluate a template string and return its value. See
+ [the templating docs](http://docs.puppetlabs.com/guides/templating.html) for
+ more information. Note that if multiple template strings are specified, their
+ output is all concatenated and returned as the output of the function.") do |vals|
+
+ require 'erb'
vals.collect do |string|
# Use a wrapper, so the template can't get access to the full
diff --git a/lib/puppet/parser/functions/md5.rb b/lib/puppet/parser/functions/md5.rb
new file mode 100644
index 000000000..f7a4f7222
--- /dev/null
+++ b/lib/puppet/parser/functions/md5.rb
@@ -0,0 +1,5 @@
+Puppet::Parser::Functions::newfunction(:md5, :type => :rvalue, :doc => "Returns a MD5 hash value from a provided string.") do |args|
+ require 'md5'
+
+ Digest::MD5.hexdigest(args[0])
+end
diff --git a/lib/puppet/parser/functions/realize.rb b/lib/puppet/parser/functions/realize.rb
index 4247b8af8..c21ccd14a 100644
--- a/lib/puppet/parser/functions/realize.rb
+++ b/lib/puppet/parser/functions/realize.rb
@@ -5,7 +5,7 @@ Puppet::Parser::Functions::newfunction(:realize, :doc => "Make a virtual object
when you want to know the name of the virtual object and don't want to
bother with a full collection. It is slightly faster than a collection,
and, of course, is a bit shorter. You must pass the object using a
- reference; e.g.: ``realize User[luke]``." ) do |vals|
+ reference; e.g.: `realize User[luke]`." ) do |vals|
coll = Puppet::Parser::Collector.new(self, :nomatter, nil, nil, :virtual)
vals = [vals] unless vals.is_a?(Array)
coll.resources = vals.flatten
diff --git a/lib/puppet/parser/functions/regsubst.rb b/lib/puppet/parser/functions/regsubst.rb
index c0aeef222..f655db7b3 100644
--- a/lib/puppet/parser/functions/regsubst.rb
+++ b/lib/puppet/parser/functions/regsubst.rb
@@ -6,37 +6,37 @@ module Puppet::Parser::Functions
:doc => "
Perform regexp replacement on a string or array of strings.
-- **Parameters** (in order):
+* *Parameters* (in order):
-:target: The string or array of strings to operate on. If an array, the replacement will be performed on each of the elements in the array, and the return value will be an array.
+ _target_ The string or array of strings to operate on. If an array, the replacement will be performed on each of the elements in the array, and the return value will be an array.
-:regexp: The regular expression matching the target string. If you want it anchored at the start and or end of the string, you must do that with ^ and $ yourself.
+ _regexp_ The regular expression matching the target string. If you want it anchored at the start and or end of the string, you must do that with ^ and $ yourself.
-:replacement: Replacement string. Can contain back references to what was matched using \\0, \\1, and so on.
+ _replacement_ Replacement string. Can contain back references to what was matched using \\0, \\1, and so on.
-:flags: Optional. String of single letter flags for how the regexp is interpreted:
+ _flags_ Optional. String of single letter flags for how the regexp is interpreted:
- - **E** Extended regexps
- - **I** Ignore case in regexps
- - **M** Multiline regexps
- - **G** Global replacement; all occurrences of the regexp in each target string will be replaced. Without this, only the first occurrence will be replaced.
+ - *E* Extended regexps
+ - *I* Ignore case in regexps
+ - *M* Multiline regexps
+ - *G* Global replacement; all occurrences of the regexp in each target string will be replaced. Without this, only the first occurrence will be replaced.
-:lang: Optional. How to handle multibyte characters. A single-character string with the following values:
+ _lang_ Optional. How to handle multibyte characters. A single-character string with the following values:
- - **N** None
- - **E** EUC
- - **S** SJIS
- - **U** UTF-8
+ - *N* None
+ - *E* EUC
+ - *S* SJIS
+ - *U* UTF-8
-- **Examples**
+* *Examples*
-Get the third octet from the node's IP address::
+Get the third octet from the node's IP address:
- $i3 = regsubst($ipaddress,'^([0-9]+)[.]([0-9]+)[.]([0-9]+)[.]([0-9]+)$','\\3')
+ $i3 = regsubst($ipaddress,'^([0-9]+)[.]([0-9]+)[.]([0-9]+)[.]([0-9]+)$','\\3')
-Put angle brackets around each octet in the node's IP address::
+Put angle brackets around each octet in the node's IP address:
- $x = regsubst($ipaddress, '([0-9]+)', '<\\1>', 'G')
+ $x = regsubst($ipaddress, '([0-9]+)', '<\\1>', 'G')
") \
do |args|
unless args.length.between?(3, 5)
diff --git a/lib/puppet/parser/functions/require.rb b/lib/puppet/parser/functions/require.rb
index 3f98c9523..64285307e 100644
--- a/lib/puppet/parser/functions/require.rb
+++ b/lib/puppet/parser/functions/require.rb
@@ -12,9 +12,8 @@ relationships between classes. This function is a superset of the
class depends on the required class.
Warning: using require in place of include can lead to unwanted dependency cycles.
- For instance the following manifest, with 'require' instead of 'include'
- would produce a nasty dependence cycle, because notify imposes a before
- between File[/foo] and Service[foo]::
+
+For instance the following manifest, with 'require' instead of 'include' would produce a nasty dependence cycle, because notify imposes a before between File[/foo] and Service[foo]:
class myservice {
service { foo: ensure => running }
diff --git a/lib/puppet/parser/functions/split.rb b/lib/puppet/parser/functions/split.rb
index 5d0a9dabc..52394095a 100644
--- a/lib/puppet/parser/functions/split.rb
+++ b/lib/puppet/parser/functions/split.rb
@@ -6,7 +6,7 @@ module Puppet::Parser::Functions
:doc => "\
Split a string variable into an array using the specified split regexp.
- Usage::
+ Usage:
$string = 'v1.v2:v3.v4'
$array_var1 = split($string, ':')
diff --git a/lib/puppet/parser/functions/sprintf.rb b/lib/puppet/parser/functions/sprintf.rb
index 5ada0fed7..5eb4a4f9d 100644
--- a/lib/puppet/parser/functions/sprintf.rb
+++ b/lib/puppet/parser/functions/sprintf.rb
@@ -5,7 +5,7 @@ module Puppet::Parser::Functions
:doc => "Perform printf-style formatting of text.
- The first parameter is format string describing how the rest of the parameters should be formatted. See the documentation for the ``Kernel::sprintf`` function in Ruby for all the details.") do |args|
+ The first parameter is format string describing how the rest of the parameters should be formatted. See the documentation for the `Kernel::sprintf` function in Ruby for all the details.") do |args|
raise Puppet::ParseError, 'sprintf() needs at least one argument' if args.length < 1
fmt = args.shift
return sprintf(fmt, *args)
diff --git a/lib/puppet/parser/functions/template.rb b/lib/puppet/parser/functions/template.rb
index f51bcc1e2..6fa110332 100644
--- a/lib/puppet/parser/functions/template.rb
+++ b/lib/puppet/parser/functions/template.rb
@@ -1,6 +1,8 @@
Puppet::Parser::Functions::newfunction(:template, :type => :rvalue, :doc =>
- "Evaluate a template and return its value. See `the templating docs
- <http://docs.puppetlabs.com/guides/templating.html>`_ for more information.
+ "Evaluate a template and return its value. See
+ [the templating docs](http://docs.puppetlabs.com/guides/templating.html) for
+ more information.
+
Note that if multiple templates are specified, their output is all
concatenated and returned as the output of the function.") do |vals|
require 'erb'
diff --git a/lib/puppet/parser/functions/versioncmp.rb b/lib/puppet/parser/functions/versioncmp.rb
index b38406532..6091e0923 100644
--- a/lib/puppet/parser/functions/versioncmp.rb
+++ b/lib/puppet/parser/functions/versioncmp.rb
@@ -3,26 +3,26 @@ require 'puppet/util/package'
Puppet::Parser::Functions::newfunction(
:versioncmp, :type => :rvalue,
-
+
:doc => "Compares two versions
-Prototype::
+Prototype:
- \$result = versioncmp(a, b)
+ \$result = versioncmp(a, b)
- where a and b are arbitrary version strings
+Where a and b are arbitrary version strings
-This functions returns a number::
+This functions returns a number:
- * > 0 if version a is greater than version b
- * == 0 if both version are equals
- * < 0 if version a is less than version b
+* Greater than 0 if version a is greater than version b
+* Equal to 0 if both version are equals
+* Less than 0 if version a is less than version b
-Example::
+Example:
- if versioncmp('2.6-1', '2.4.5') > 0 {
- notice('2.6-1 is > than 2.4.5')
- }
+ if versioncmp('2.6-1', '2.4.5') > 0 {
+ notice('2.6-1 is > than 2.4.5')
+ }
") do |args|
diff --git a/lib/puppet/parser/grammar.ra b/lib/puppet/parser/grammar.ra
index 7a316d4d7..ecb27f363 100644
--- a/lib/puppet/parser/grammar.ra
+++ b/lib/puppet/parser/grammar.ra
@@ -28,41 +28,33 @@ prechigh
preclow
rule
-program: statements {
- if val[0]
- # Make sure we always return an array.
- if val[0].is_a?(AST::ASTArray)
- if val[0].children.empty?
- result = nil
- else
- result = val[0]
- end
- else
- result = aryfy(val[0])
- end
- else
- result = nil
- end
-}
+program: statements_and_declarations
| nil
-statements: statement
- | statements statement {
- if val[0] and val[1]
- if val[0].instance_of?(AST::ASTArray)
+ statements_and_declarations: statement_or_declaration {
+ result = ast AST::ASTArray, :children => (val[0] ? [val[0]] : [])
+ }
+ | statements_and_declarations statement_or_declaration {
+ if val[1]
val[0].push(val[1])
- result = val[0]
- else
- result = ast AST::ASTArray, :children => [val[0],val[1]]
end
- elsif obj = (val[0] || val[1])
- result = obj
- else result = nil
+ result = val[0]
+ }
+
+# statements is like statements_and_declarations, but it doesn't allow
+# nested definitions, classes, or nodes.
+statements: statements_and_declarations {
+ val[0].each do |stmt|
+ if stmt.is_a?(AST::TopLevelConstruct)
+ error "Classes, definitions, and nodes may only appear at toplevel or inside other classes", \
+ :line => stmt.context[:line], :file => stmt.context[:file]
+ end
end
+ result = val[0]
}
# The main list of valid statements
-statement: resource
+statement_or_declaration: resource
| virtualresource
| collection
| assignment
@@ -89,19 +81,17 @@ relationship_side: resource | resourceref | collection
edge: IN_EDGE | OUT_EDGE | IN_EDGE_SUB | OUT_EDGE_SUB
fstatement: NAME LPAREN funcvalues RPAREN {
- args = aryfy(val[2])
result = ast AST::Function,
:name => val[0][:value],
:line => val[0][:line],
- :arguments => args,
+ :arguments => val[2],
:ftype => :statement
}
| NAME LPAREN funcvalues COMMA RPAREN {
- args = aryfy(val[2])
result = ast AST::Function,
:name => val[0][:value],
:line => val[0][:line],
- :arguments => args,
+ :arguments => val[2],
:ftype => :statement
} | NAME LPAREN RPAREN {
result = ast AST::Function,
@@ -111,29 +101,22 @@ fstatement: NAME LPAREN funcvalues RPAREN {
:ftype => :statement
}
| NAME funcvalues {
- args = aryfy(val[1])
result = ast AST::Function,
:name => val[0][:value],
:line => val[0][:line],
- :arguments => args,
+ :arguments => val[1],
:ftype => :statement
}
-funcvalues: namestring
- | resourceref
+funcvalues: namestring { result = aryfy(val[0]) }
+ | resourceref { result = aryfy(val[0]) }
| funcvalues COMMA namestring {
- result = aryfy(val[0], val[2])
- result.line = @lexer.line
- result.file = @lexer.file
+ val[0].push(val[2])
+ result = val[0]
}
| funcvalues COMMA resourceref {
- unless val[0].is_a?(AST::ASTArray)
- val[0] = aryfy(val[0])
- end
-
- val[0].push(val[2])
-
- result = val[0]
+ val[0].push(val[2])
+ result = val[0]
}
# This is *almost* an rvalue, but I couldn't get a full
@@ -152,23 +135,7 @@ namestring: name
resource: classname LBRACE resourceinstances endsemi RBRACE {
@lexer.commentpop
- array = val[2]
- array = [array] if array.instance_of?(AST::ResourceInstance)
- result = ast AST::ASTArray
-
- # this iterates across each specified resourceinstance
- array.each { |instance|
- raise Puppet::Dev, "Got something that isn't an instance" unless instance.instance_of?(AST::ResourceInstance)
- # now, i need to somehow differentiate between those things with
- # arrays in their names, and normal things
-
- result.push ast(
- AST::Resource,
- :type => val[0],
- :title => instance[0],
-
- :parameters => instance[1])
- }
+ result = ast(AST::Resource, :type => val[0], :instances => val[2])
} | classname LBRACE params endcomma RBRACE {
# This is a deprecated syntax.
error "All resource specifications require names"
@@ -197,14 +164,8 @@ virtualresource: at resource {
method = type.to_s + "="
- # Just mark our resources as exported and pass them through.
- if val[1].instance_of?(AST::ASTArray)
- val[1].each do |obj|
- obj.send(method, true)
- end
- else
- val[1].send(method, true)
- end
+ # Just mark our resource as exported and pass it through.
+ val[1].send(method, true)
result = val[1]
}
@@ -303,17 +264,13 @@ colllval: variable
| name
resourceinst: resourcename COLON params endcomma {
- result = ast AST::ResourceInstance, :children => [val[0],val[2]]
+ result = ast AST::ResourceInstance, :title => val[0], :parameters => val[2]
}
-resourceinstances: resourceinst
+resourceinstances: resourceinst { result = aryfy(val[0]) }
| resourceinstances SEMIC resourceinst {
- if val[0].instance_of?(AST::ResourceInstance)
- result = ast AST::ASTArray, :children => [val[0],val[2]]
- else
val[0].push val[2]
result = val[0]
- end
}
endsemi: # nothing
@@ -358,14 +315,10 @@ params: # nothing
{
result = ast AST::ASTArray
}
- | param { result = val[0] }
+ | param { result = aryfy(val[0]) }
| params COMMA param {
- if val[0].instance_of?(AST::ASTArray)
val[0].push(val[2])
result = val[0]
- else
- result = ast AST::ASTArray, :children => [val[0],val[2]]
- end
}
param: NAME FARROW rvalue {
@@ -384,24 +337,14 @@ anyparams: # nothing
{
result = ast AST::ASTArray
}
- | anyparam { result = val[0] }
+ | anyparam { result = aryfy(val[0]) }
| anyparams COMMA anyparam {
- if val[0].instance_of?(AST::ASTArray)
val[0].push(val[2])
result = val[0]
- else
- result = ast AST::ASTArray, :children => [val[0],val[2]]
- end
}
-rvalues: rvalue
- | rvalues comma rvalue {
- if val[0].instance_of?(AST::ASTArray)
- result = val[0].push(val[2])
- else
- result = ast AST::ASTArray, :children => [val[0],val[2]]
- end
-}
+rvalues: rvalue { result = aryfy(val[0]) }
+ | rvalues comma rvalue { result = val[0].push(val[2]) }
simplervalue: quotedtext
| name
@@ -425,10 +368,9 @@ rvalue: quotedtext
# We currently require arguments in these functions.
funcrvalue: NAME LPAREN funcvalues RPAREN {
- args = aryfy(val[2])
result = ast AST::Function,
:name => val[0][:value], :line => val[0][:line],
- :arguments => args,
+ :arguments => val[2],
:ftype => :rvalue
} | NAME LPAREN RPAREN {
result = ast AST::Function,
@@ -572,19 +514,13 @@ expression: rvalue
casestatement: CASE rvalue LBRACE caseopts RBRACE {
@lexer.commentpop
- options = val[3]
- options = ast AST::ASTArray, :children => [val[3]] unless options.instance_of?(AST::ASTArray)
- result = ast AST::CaseStatement, :test => val[1], :options => options
+ result = ast AST::CaseStatement, :test => val[1], :options => val[3]
}
-caseopts: caseopt
+caseopts: caseopt { result = aryfy(val[0]) }
| caseopts caseopt {
- if val[0].instance_of?(AST::ASTArray)
val[0].push val[1]
result = val[0]
- else
- result = ast AST::ASTArray, :children => [val[0], val[1]]
- end
}
caseopt: casevalues COLON LBRACE statements RBRACE {
@@ -601,14 +537,10 @@ caseopt: casevalues COLON LBRACE statements RBRACE {
)
}
-casevalues: selectlhand
+casevalues: selectlhand { result = aryfy(val[0]) }
| casevalues COMMA selectlhand {
- if val[0].instance_of?(AST::ASTArray)
val[0].push(val[2])
result = val[0]
- else
- result = ast AST::ASTArray, :children => [val[0],val[2]]
- end
}
selector: selectlhand QMARK svalues {
@@ -657,48 +589,51 @@ import: IMPORT strings {
import(file)
end
- result = AST::ASTArray.new(:children => [])
+ result = nil
}
# Disable definition inheritance for now. 8/27/06, luke
#definition: DEFINE NAME argumentlist parent LBRACE statements RBRACE {
definition: DEFINE classname argumentlist LBRACE statements RBRACE {
@lexer.commentpop
- newdefine classname(val[1]), :arguments => val[2], :code => val[4], :line => val[0][:line]
+ result = Puppet::Parser::AST::Definition.new(classname(val[1]),
+ ast_context(true).merge(:arguments => val[2], :code => val[4],
+ :line => val[0][:line]))
@lexer.indefine = false
- result = nil
#} | DEFINE NAME argumentlist parent LBRACE RBRACE {
} | DEFINE classname argumentlist LBRACE RBRACE {
@lexer.commentpop
- newdefine classname(val[1]), :arguments => val[2], :line => val[0][:line]
+ result = Puppet::Parser::AST::Definition.new(classname(val[1]),
+ ast_context(true).merge(:arguments => val[2], :line => val[0][:line]))
@lexer.indefine = false
- result = nil
}
#hostclass: CLASS NAME argumentlist parent LBRACE statements RBRACE {
-hostclass: CLASS classname argumentlist classparent LBRACE statements RBRACE {
+hostclass: CLASS classname argumentlist classparent LBRACE statements_and_declarations RBRACE {
@lexer.commentpop
# Our class gets defined in the parent namespace, not our own.
@lexer.namepop
- newclass classname(val[1]), :arguments => val[2], :parent => val[3], :code => val[5], :line => val[0][:line]
- result = nil
+ result = Puppet::Parser::AST::Hostclass.new(classname(val[1]),
+ ast_context(true).merge(:arguments => val[2], :parent => val[3],
+ :code => val[5], :line => val[0][:line]))
} | CLASS classname argumentlist classparent LBRACE RBRACE {
@lexer.commentpop
# Our class gets defined in the parent namespace, not our own.
@lexer.namepop
- newclass classname(val[1]), :arguments => val[2], :parent => val[3], :line => val[0][:line]
- result = nil
+ result = Puppet::Parser::AST::Hostclass.new(classname(val[1]),
+ ast_context(true).merge(:arguments => val[2], :parent => val[3],
+ :line => val[0][:line]))
}
nodedef: NODE hostnames nodeparent LBRACE statements RBRACE {
@lexer.commentpop
- newnode val[1], :parent => val[2], :code => val[4], :line => val[0][:line]
- result = nil
+ result = Puppet::Parser::AST::Node.new(val[1],
+ ast_context(true).merge(:parent => val[2], :code => val[4],
+ :line => val[0][:line]))
} | NODE hostnames nodeparent LBRACE RBRACE {
@lexer.commentpop
- newnode val[1], :parent => val[2], :line => val[0][:line]
- result = nil
+ result = Puppet::Parser::AST::Node.new(val[1], ast_context(true).merge(:parent => val[2], :line => val[0][:line]))
}
classref: CLASSREF { result = val[0][:value] }
@@ -709,10 +644,11 @@ classname: NAME { result = val[0][:value] }
# Multiple hostnames, as used for node names. These are all literal
# strings, not AST objects.
-hostnames: nodename
+hostnames: nodename {
+ result = [result]
+}
| hostnames COMMA nodename {
result = val[0]
- result = [result] unless result.is_a?(Array)
result << val[2]
}
@@ -778,22 +714,9 @@ variable: VARIABLE {
result = ast AST::Variable, :value => val[0][:value], :line => val[0][:line]
}
-array: LBRACK rvalues RBRACK {
- if val[1].instance_of?(AST::ASTArray)
- result = val[1]
- else
- result = ast AST::ASTArray, :children => [val[1]]
- end
-}
- | LBRACK rvalues COMMA RBRACK {
- if val[1].instance_of?(AST::ASTArray)
- result = val[1]
- else
- result = ast AST::ASTArray, :children => [val[1]]
- end
-} | LBRACK RBRACK {
- result = ast AST::ASTArray
-}
+array: LBRACK rvalues RBRACK { result = val[1] }
+ | LBRACK rvalues COMMA RBRACK { result = val[1] }
+ | LBRACK RBRACK { result = ast AST::ASTArray }
comma: FARROW
| COMMA
diff --git a/lib/puppet/parser/lexer.rb b/lib/puppet/parser/lexer.rb
index 1e10ff96c..31d39ae2f 100644
--- a/lib/puppet/parser/lexer.rb
+++ b/lib/puppet/parser/lexer.rb
@@ -221,7 +221,7 @@ class Puppet::Parser::Lexer
TOKENS.add_token :RETURN, "\n", :skip => true, :incr_line => true, :skip_text => true
TOKENS.add_token :SQUOTE, "'" do |lexer, value|
- [TOKENS[:STRING], lexer.slurpstring(value).first ]
+ [TOKENS[:STRING], lexer.slurpstring(value,["'"],:ignore_invalid_escapes).first ]
end
DQ_initial_token_types = {'$' => :DQPRE,'"' => :STRING}
@@ -483,7 +483,7 @@ class Puppet::Parser::Lexer
yield [final_token.name, token_value]
if @previous_token
- namestack(value) if @previous_token.name == :CLASS
+ namestack(value) if @previous_token.name == :CLASS and value != '{'
if @previous_token.name == :DEFINE
if indefine?
@@ -517,24 +517,24 @@ class Puppet::Parser::Lexer
# we've encountered the start of a string...
# slurp in the rest of the string and return it
- Valid_escapes_in_strings = %w{ \\ $ ' " n t s }+["\n"]
- def slurpstring(terminators)
+ def slurpstring(terminators,escapes=%w{ \\ $ ' " n t s }+["\n"],ignore_invalid_escapes=false)
# we search for the next quote that isn't preceded by a
# backslash; the caret is there to match empty strings
- str = @scanner.scan_until(/([^\\]|^)[#{terminators}]/) or lex_error "Unclosed quote after '#{last}' in '#{rest}'"
+ str = @scanner.scan_until(/([^\\]|^|[^\\])([\\]{2})*[#{terminators}]/) or lex_error "Unclosed quote after '#{last}' in '#{rest}'"
@line += str.count("\n") # literal carriage returns add to the line count.
- str.gsub!(/\\(.)/) {
- case ch=$1
- when 'n'; "\n"
- when 't'; "\t"
- when 's'; " "
- else
- if Valid_escapes_in_strings.include? ch and not (ch == '"' and terminators == "'")
- ch
- else
- Puppet.warning "Unrecognised escape sequence '\\#{ch}'#{file && " in file #{file}"}#{line && " at line #{line}"}"
- "\\#{ch}"
+ str.gsub!(/\\(.)/m) {
+ ch = $1
+ if escapes.include? ch
+ case ch
+ when 'n'; "\n"
+ when 't'; "\t"
+ when 's'; " "
+ when "\n": ''
+ else ch
end
+ else
+ Puppet.warning "Unrecognised escape sequence '\\#{ch}'#{file && " in file #{file}"}#{line && " at line #{line}"}" unless ignore_invalid_escapes
+ "\\#{ch}"
end
}
[ str[0..-2],str[-1,1] ]
diff --git a/lib/puppet/parser/parser.rb b/lib/puppet/parser/parser.rb
index 5be9e5a3f..60b272e76 100644
--- a/lib/puppet/parser/parser.rb
+++ b/lib/puppet/parser/parser.rb
@@ -13,9 +13,9 @@ require 'puppet/parser/lexer'
require 'puppet/parser/ast'
module Puppet
- class ParseError < Puppet::Error; end
- class ImportError < Racc::ParseError; end
- class AlreadyImportedError < ImportError; end
+ class ParseError < Puppet::Error; end
+ class ImportError < Racc::ParseError; end
+ class AlreadyImportedError < ImportError; end
end
@@ -25,7 +25,7 @@ module Puppet
class Parser < Racc::Parser
-module_eval <<'..end grammar.ra modeval..id7145220b1b', 'grammar.ra', 876
+module_eval <<'..end grammar.ra modeval..id6362f948d9', 'grammar.ra', 788
# It got too annoying having code in a file that needs to be compiled.
require 'puppet/parser/parser_support'
@@ -37,16 +37,17 @@ require 'puppet/parser/parser_support'
# $Id$
-..end grammar.ra modeval..id7145220b1b
+..end grammar.ra modeval..id6362f948d9
##### racc 1.4.5 generates ###
racc_reduce_table = [
0, 0, :racc_error,
- 1, 70, :_reduce_1,
1, 70, :_reduce_none,
- 1, 71, :_reduce_none,
+ 1, 70, :_reduce_none,
+ 1, 71, :_reduce_3,
2, 71, :_reduce_4,
+ 1, 74, :_reduce_5,
1, 73, :_reduce_none,
1, 73, :_reduce_none,
1, 73, :_reduce_none,
@@ -61,864 +62,820 @@ racc_reduce_table = [
1, 73, :_reduce_none,
1, 73, :_reduce_none,
1, 73, :_reduce_none,
- 3, 87, :_reduce_19,
- 3, 87, :_reduce_20,
- 1, 88, :_reduce_none,
- 1, 88, :_reduce_none,
- 1, 88, :_reduce_none,
- 1, 89, :_reduce_none,
+ 3, 88, :_reduce_20,
+ 3, 88, :_reduce_21,
1, 89, :_reduce_none,
1, 89, :_reduce_none,
1, 89, :_reduce_none,
- 4, 81, :_reduce_28,
- 5, 81, :_reduce_29,
- 3, 81, :_reduce_30,
- 2, 81, :_reduce_31,
- 1, 91, :_reduce_none,
- 1, 91, :_reduce_none,
- 3, 91, :_reduce_34,
- 3, 91, :_reduce_35,
- 1, 92, :_reduce_none,
- 1, 92, :_reduce_none,
- 1, 92, :_reduce_none,
- 1, 92, :_reduce_none,
- 1, 92, :_reduce_none,
- 1, 92, :_reduce_none,
- 1, 92, :_reduce_none,
- 1, 92, :_reduce_none,
- 1, 92, :_reduce_44,
- 5, 74, :_reduce_45,
- 5, 74, :_reduce_46,
- 5, 74, :_reduce_47,
- 5, 85, :_reduce_48,
- 2, 75, :_reduce_49,
- 1, 108, :_reduce_50,
- 2, 108, :_reduce_51,
- 6, 76, :_reduce_52,
- 2, 76, :_reduce_53,
- 3, 109, :_reduce_54,
- 3, 109, :_reduce_55,
- 1, 110, :_reduce_none,
- 1, 110, :_reduce_none,
- 3, 110, :_reduce_58,
+ 1, 90, :_reduce_none,
+ 1, 90, :_reduce_none,
+ 1, 90, :_reduce_none,
+ 1, 90, :_reduce_none,
+ 4, 82, :_reduce_29,
+ 5, 82, :_reduce_30,
+ 3, 82, :_reduce_31,
+ 2, 82, :_reduce_32,
+ 1, 92, :_reduce_33,
+ 1, 92, :_reduce_34,
+ 3, 92, :_reduce_35,
+ 3, 92, :_reduce_36,
+ 1, 93, :_reduce_none,
+ 1, 93, :_reduce_none,
+ 1, 93, :_reduce_none,
+ 1, 93, :_reduce_none,
+ 1, 93, :_reduce_none,
+ 1, 93, :_reduce_none,
+ 1, 93, :_reduce_none,
+ 1, 93, :_reduce_none,
+ 1, 93, :_reduce_45,
+ 5, 75, :_reduce_46,
+ 5, 75, :_reduce_47,
+ 5, 75, :_reduce_48,
+ 5, 86, :_reduce_49,
+ 2, 76, :_reduce_50,
+ 1, 109, :_reduce_51,
+ 2, 109, :_reduce_52,
+ 6, 77, :_reduce_53,
+ 2, 77, :_reduce_54,
+ 3, 110, :_reduce_55,
+ 3, 110, :_reduce_56,
1, 111, :_reduce_none,
- 3, 111, :_reduce_60,
- 1, 112, :_reduce_61,
- 1, 112, :_reduce_62,
- 3, 113, :_reduce_63,
- 3, 113, :_reduce_64,
- 1, 114, :_reduce_none,
- 1, 114, :_reduce_none,
- 4, 116, :_reduce_67,
- 1, 102, :_reduce_none,
- 3, 102, :_reduce_69,
- 0, 103, :_reduce_none,
- 1, 103, :_reduce_none,
- 1, 118, :_reduce_72,
- 1, 93, :_reduce_73,
- 1, 95, :_reduce_74,
- 1, 117, :_reduce_none,
- 1, 117, :_reduce_none,
- 1, 117, :_reduce_none,
- 1, 117, :_reduce_none,
- 1, 117, :_reduce_none,
- 1, 117, :_reduce_none,
- 1, 117, :_reduce_none,
- 3, 77, :_reduce_82,
- 3, 77, :_reduce_83,
- 3, 86, :_reduce_84,
- 0, 104, :_reduce_85,
- 1, 104, :_reduce_86,
- 3, 104, :_reduce_87,
- 3, 122, :_reduce_88,
- 3, 124, :_reduce_89,
- 1, 125, :_reduce_none,
- 1, 125, :_reduce_none,
- 0, 107, :_reduce_92,
- 1, 107, :_reduce_93,
- 3, 107, :_reduce_94,
- 1, 126, :_reduce_none,
- 3, 126, :_reduce_96,
- 1, 115, :_reduce_none,
- 1, 115, :_reduce_none,
- 1, 115, :_reduce_none,
- 1, 115, :_reduce_none,
+ 1, 111, :_reduce_none,
+ 3, 111, :_reduce_59,
+ 1, 112, :_reduce_none,
+ 3, 112, :_reduce_61,
+ 1, 113, :_reduce_62,
+ 1, 113, :_reduce_63,
+ 3, 114, :_reduce_64,
+ 3, 114, :_reduce_65,
1, 115, :_reduce_none,
1, 115, :_reduce_none,
- 1, 123, :_reduce_none,
- 1, 123, :_reduce_none,
- 1, 123, :_reduce_none,
- 1, 123, :_reduce_none,
- 1, 123, :_reduce_none,
- 1, 123, :_reduce_none,
- 1, 123, :_reduce_none,
- 1, 123, :_reduce_none,
- 1, 123, :_reduce_none,
- 1, 123, :_reduce_none,
- 1, 123, :_reduce_none,
- 1, 123, :_reduce_none,
- 4, 97, :_reduce_115,
- 3, 97, :_reduce_116,
- 1, 99, :_reduce_117,
- 2, 99, :_reduce_118,
- 2, 129, :_reduce_119,
- 1, 130, :_reduce_120,
- 2, 130, :_reduce_121,
- 1, 96, :_reduce_122,
- 4, 90, :_reduce_123,
- 4, 90, :_reduce_124,
- 2, 79, :_reduce_125,
- 5, 131, :_reduce_126,
- 4, 131, :_reduce_127,
- 0, 132, :_reduce_none,
- 2, 132, :_reduce_129,
- 4, 132, :_reduce_130,
- 3, 132, :_reduce_131,
- 1, 120, :_reduce_none,
- 3, 120, :_reduce_133,
- 3, 120, :_reduce_134,
- 3, 120, :_reduce_135,
- 3, 120, :_reduce_136,
- 3, 120, :_reduce_137,
- 3, 120, :_reduce_138,
- 3, 120, :_reduce_139,
- 3, 120, :_reduce_140,
- 3, 120, :_reduce_141,
- 2, 120, :_reduce_142,
- 3, 120, :_reduce_143,
- 3, 120, :_reduce_144,
- 3, 120, :_reduce_145,
- 3, 120, :_reduce_146,
- 3, 120, :_reduce_147,
- 3, 120, :_reduce_148,
- 2, 120, :_reduce_149,
- 3, 120, :_reduce_150,
- 3, 120, :_reduce_151,
- 3, 120, :_reduce_152,
- 5, 78, :_reduce_153,
- 1, 134, :_reduce_none,
- 2, 134, :_reduce_155,
- 5, 135, :_reduce_156,
- 4, 135, :_reduce_157,
- 1, 136, :_reduce_none,
- 3, 136, :_reduce_159,
- 3, 98, :_reduce_160,
+ 4, 117, :_reduce_68,
+ 1, 103, :_reduce_69,
+ 3, 103, :_reduce_70,
+ 0, 104, :_reduce_none,
+ 1, 104, :_reduce_none,
+ 1, 119, :_reduce_73,
+ 1, 94, :_reduce_74,
+ 1, 96, :_reduce_75,
+ 1, 118, :_reduce_none,
+ 1, 118, :_reduce_none,
+ 1, 118, :_reduce_none,
+ 1, 118, :_reduce_none,
+ 1, 118, :_reduce_none,
+ 1, 118, :_reduce_none,
+ 1, 118, :_reduce_none,
+ 3, 78, :_reduce_83,
+ 3, 78, :_reduce_84,
+ 3, 87, :_reduce_85,
+ 0, 105, :_reduce_86,
+ 1, 105, :_reduce_87,
+ 3, 105, :_reduce_88,
+ 3, 123, :_reduce_89,
+ 3, 125, :_reduce_90,
+ 1, 126, :_reduce_none,
+ 1, 126, :_reduce_none,
+ 0, 108, :_reduce_93,
+ 1, 108, :_reduce_94,
+ 3, 108, :_reduce_95,
+ 1, 127, :_reduce_96,
+ 3, 127, :_reduce_97,
+ 1, 116, :_reduce_none,
+ 1, 116, :_reduce_none,
+ 1, 116, :_reduce_none,
+ 1, 116, :_reduce_none,
+ 1, 116, :_reduce_none,
+ 1, 116, :_reduce_none,
+ 1, 124, :_reduce_none,
+ 1, 124, :_reduce_none,
+ 1, 124, :_reduce_none,
+ 1, 124, :_reduce_none,
+ 1, 124, :_reduce_none,
+ 1, 124, :_reduce_none,
+ 1, 124, :_reduce_none,
+ 1, 124, :_reduce_none,
+ 1, 124, :_reduce_none,
+ 1, 124, :_reduce_none,
+ 1, 124, :_reduce_none,
+ 1, 124, :_reduce_none,
+ 4, 98, :_reduce_116,
+ 3, 98, :_reduce_117,
+ 1, 100, :_reduce_118,
+ 2, 100, :_reduce_119,
+ 2, 130, :_reduce_120,
+ 1, 131, :_reduce_121,
+ 2, 131, :_reduce_122,
+ 1, 97, :_reduce_123,
+ 4, 91, :_reduce_124,
+ 4, 91, :_reduce_125,
+ 2, 80, :_reduce_126,
+ 5, 132, :_reduce_127,
+ 4, 132, :_reduce_128,
+ 0, 133, :_reduce_none,
+ 2, 133, :_reduce_130,
+ 4, 133, :_reduce_131,
+ 3, 133, :_reduce_132,
+ 1, 121, :_reduce_none,
+ 3, 121, :_reduce_134,
+ 3, 121, :_reduce_135,
+ 3, 121, :_reduce_136,
+ 3, 121, :_reduce_137,
+ 3, 121, :_reduce_138,
+ 3, 121, :_reduce_139,
+ 3, 121, :_reduce_140,
+ 3, 121, :_reduce_141,
+ 3, 121, :_reduce_142,
+ 2, 121, :_reduce_143,
+ 3, 121, :_reduce_144,
+ 3, 121, :_reduce_145,
+ 3, 121, :_reduce_146,
+ 3, 121, :_reduce_147,
+ 3, 121, :_reduce_148,
+ 3, 121, :_reduce_149,
+ 2, 121, :_reduce_150,
+ 3, 121, :_reduce_151,
+ 3, 121, :_reduce_152,
+ 3, 121, :_reduce_153,
+ 5, 79, :_reduce_154,
+ 1, 135, :_reduce_155,
+ 2, 135, :_reduce_156,
+ 5, 136, :_reduce_157,
+ 4, 136, :_reduce_158,
+ 1, 137, :_reduce_159,
+ 3, 137, :_reduce_160,
+ 3, 99, :_reduce_161,
+ 1, 139, :_reduce_none,
+ 4, 139, :_reduce_163,
+ 1, 141, :_reduce_none,
+ 3, 141, :_reduce_165,
+ 3, 140, :_reduce_166,
+ 1, 138, :_reduce_none,
+ 1, 138, :_reduce_none,
+ 1, 138, :_reduce_none,
1, 138, :_reduce_none,
- 4, 138, :_reduce_162,
- 1, 140, :_reduce_none,
- 3, 140, :_reduce_164,
- 3, 139, :_reduce_165,
- 1, 137, :_reduce_none,
- 1, 137, :_reduce_none,
- 1, 137, :_reduce_none,
- 1, 137, :_reduce_none,
- 1, 137, :_reduce_none,
- 1, 137, :_reduce_none,
- 1, 137, :_reduce_none,
- 1, 137, :_reduce_173,
- 1, 137, :_reduce_none,
- 1, 141, :_reduce_175,
- 1, 142, :_reduce_none,
- 3, 142, :_reduce_177,
- 2, 80, :_reduce_178,
- 6, 82, :_reduce_179,
- 5, 82, :_reduce_180,
- 7, 83, :_reduce_181,
- 6, 83, :_reduce_182,
+ 1, 138, :_reduce_none,
+ 1, 138, :_reduce_none,
+ 1, 138, :_reduce_none,
+ 1, 138, :_reduce_174,
+ 1, 138, :_reduce_none,
+ 1, 142, :_reduce_176,
+ 1, 143, :_reduce_none,
+ 3, 143, :_reduce_178,
+ 2, 81, :_reduce_179,
+ 6, 83, :_reduce_180,
+ 5, 83, :_reduce_181,
+ 7, 84, :_reduce_182,
6, 84, :_reduce_183,
- 5, 84, :_reduce_184,
- 1, 106, :_reduce_185,
- 1, 101, :_reduce_186,
- 1, 101, :_reduce_187,
- 1, 101, :_reduce_188,
- 1, 145, :_reduce_none,
- 3, 145, :_reduce_190,
- 1, 147, :_reduce_191,
+ 6, 85, :_reduce_184,
+ 5, 85, :_reduce_185,
+ 1, 107, :_reduce_186,
+ 1, 102, :_reduce_187,
+ 1, 102, :_reduce_188,
+ 1, 102, :_reduce_189,
+ 1, 146, :_reduce_190,
+ 3, 146, :_reduce_191,
1, 148, :_reduce_192,
- 1, 148, :_reduce_193,
- 1, 148, :_reduce_194,
- 1, 148, :_reduce_none,
- 0, 72, :_reduce_196,
- 0, 149, :_reduce_197,
- 1, 143, :_reduce_none,
- 3, 143, :_reduce_199,
- 3, 143, :_reduce_200,
- 1, 150, :_reduce_none,
- 3, 150, :_reduce_202,
- 3, 151, :_reduce_203,
- 1, 151, :_reduce_204,
- 3, 151, :_reduce_205,
- 1, 151, :_reduce_206,
- 1, 146, :_reduce_none,
- 2, 146, :_reduce_208,
+ 1, 149, :_reduce_193,
+ 1, 149, :_reduce_194,
+ 1, 149, :_reduce_195,
+ 1, 149, :_reduce_none,
+ 0, 72, :_reduce_197,
+ 0, 150, :_reduce_198,
1, 144, :_reduce_none,
- 2, 144, :_reduce_210,
- 1, 152, :_reduce_none,
- 1, 152, :_reduce_none,
- 1, 94, :_reduce_213,
- 3, 119, :_reduce_214,
- 4, 119, :_reduce_215,
- 2, 119, :_reduce_216,
- 1, 127, :_reduce_none,
- 1, 127, :_reduce_none,
- 0, 105, :_reduce_none,
- 1, 105, :_reduce_220,
- 1, 133, :_reduce_221,
- 3, 128, :_reduce_222,
- 4, 128, :_reduce_223,
- 2, 128, :_reduce_224,
+ 3, 144, :_reduce_200,
+ 3, 144, :_reduce_201,
+ 1, 151, :_reduce_none,
+ 3, 151, :_reduce_203,
+ 3, 152, :_reduce_204,
+ 1, 152, :_reduce_205,
+ 3, 152, :_reduce_206,
+ 1, 152, :_reduce_207,
+ 1, 147, :_reduce_none,
+ 2, 147, :_reduce_209,
+ 1, 145, :_reduce_none,
+ 2, 145, :_reduce_211,
1, 153, :_reduce_none,
- 3, 153, :_reduce_226,
+ 1, 153, :_reduce_none,
+ 1, 95, :_reduce_214,
+ 3, 120, :_reduce_215,
+ 4, 120, :_reduce_216,
+ 2, 120, :_reduce_217,
+ 1, 128, :_reduce_none,
+ 1, 128, :_reduce_none,
+ 0, 106, :_reduce_none,
+ 1, 106, :_reduce_221,
+ 1, 134, :_reduce_222,
+ 3, 129, :_reduce_223,
+ 4, 129, :_reduce_224,
+ 2, 129, :_reduce_225,
+ 1, 154, :_reduce_none,
3, 154, :_reduce_227,
- 1, 155, :_reduce_228,
- 1, 155, :_reduce_229,
- 4, 121, :_reduce_230,
- 1, 100, :_reduce_none,
- 4, 100, :_reduce_232 ]
+ 3, 155, :_reduce_228,
+ 1, 156, :_reduce_229,
+ 1, 156, :_reduce_230,
+ 4, 122, :_reduce_231,
+ 1, 101, :_reduce_none,
+ 4, 101, :_reduce_233 ]
-racc_reduce_n = 233
+racc_reduce_n = 234
-racc_shift_n = 384
+racc_shift_n = 385
racc_action_table = [
- 256, 257, 228, 82, 54, 72, 75, 181, 251, 48,
- 72, 75, 194, 205, 210, 163, 156, 348, 46, 47,
- 344, 184, 201, 203, 206, 209, 162, 352, 54, 182,
- 351, 169, 54, -168, 72, 75, 241, 242, 102, 305,
- 106, 158, 58, 193, 230, 60, 204, 208, 193, 306,
- 213, 196, 197, 198, 200, 202, 97, 207, 211, 72,
- 75, 72, 75, 163, 199, 59, 58, 71, 245, 60,
- 58, 83, 86, 60, 162, 92, 244, 72, 75, 169,
- 78, 100, 352, 269, 89, 351, 63, 94, 64, 59,
- 228, 326, 71, 59, 162, 59, 83, 86, 83, 268,
- 92, 65, 92, 184, 76, 78, 307, 137, 163, 89,
- 162, 89, 72, 75, 83, 268, 241, 242, 92, 162,
- 59, 163, 59, 137, 169, 62, 254, 89, 207, 211,
- 72, 75, 162, 308, 102, 199, 106, 169, 59, 255,
- 213, 196, 197, 198, -166, 162, 309, 207, 211, 83,
- 268, 310, 97, 92, 199, 72, 75, 355, 137, 102,
- -170, 106, 89, 71, 218, 356, 173, 83, 86, 220,
- 313, 92, -171, 59, 72, 75, 78, 100, 37, 218,
- 89, 249, 38, 94, 220, 246, 247, 173, 71, 11,
- 210, 59, 83, 86, 246, 367, 92, 271, 201, 37,
- -167, 78, 37, 38, 270, 89, 38, 71, 246, 247,
- 11, 83, 86, 11, 14, 92, 59, 72, 75, 76,
- 78, 102, 278, 106, 89, 277, 213, 196, 197, 198,
- 200, 202, 275, 207, 211, 59, 246, 274, 152, 97,
- 199, 37, 318, 72, 75, 127, 319, 102, -169, 106,
- 71, 63, 11, 14, 83, 86, -167, 37, 92, 207,
- 211, 127, -169, 78, 100, 97, 199, 89, 11, 14,
- 94, -166, 117, 72, 75, -185, 71, 82, 59, 336,
- 83, 86, 197, 198, 92, 231, 338, 207, 211, 78,
- 100, 181, 48, 89, 199, 74, 94, 240, -168, 72,
- 75, 241, 242, 102, 59, 106, 71, 184, 176, 37,
- 83, 86, 59, 38, 92, 345, 322, 175, 76, 78,
- 11, 97, -172, 89, -171, 72, 75, -170, 59, 102,
- 214, 106, 71, 64, 59, 215, 83, 86, 173, 217,
- 92, -23, -23, -23, -23, 78, 100, 97, 155, 89,
- 72, 75, 94, 122, 102, 152, 106, 82, 71, 223,
- 59, 122, 83, 86, 72, 75, 92, -168, 102, 225,
- 106, 78, 100, -166, 276, 89, 226, 117, 94, 44,
- 45, 41, 42, 71, -169, -167, 59, 83, 86, 72,
- 75, 92, 226, 102, 229, 106, 78, 71, 52, -168,
- 89, 83, 86, 72, 75, 92, -166, 102, -169, 106,
- 78, 59, 197, 198, 89, -167, -171, 207, 211, 365,
- 231, 152, 71, 234, 199, 59, 83, 86, 50, 210,
- 92, -21, -21, -21, -21, 78, 71, 201, 372, 89,
- 83, 86, 49, 374, 92, 72, 75, 228, -220, 78,
- 59, 226, 354, 89, 377, 72, 75, 40, 39, 102,
- 237, 106, 341, nil, 59, 213, 196, 197, 198, 200,
- 202, nil, 207, 211, nil, nil, nil, 97, 162, 199,
- nil, nil, 83, 268, nil, nil, 92, nil, 71, nil,
- nil, 137, 83, 86, nil, 89, 92, 44, 45, 41,
- 42, 78, 100, 72, 75, 89, 59, 102, 94, 106,
- 213, 196, 197, 198, 200, 202, 59, 207, 211, nil,
- 213, 196, 197, 198, 199, 97, nil, 207, 211, 72,
- 75, nil, nil, 102, 199, 106, 71, nil, nil, nil,
- 83, 86, nil, nil, 92, nil, nil, nil, nil, 78,
- 100, 97, nil, 89, nil, nil, 94, nil, nil, 72,
- 75, nil, 71, 102, 59, 106, 83, 86, nil, nil,
- 92, nil, nil, nil, nil, 78, 100, nil, nil, 89,
- nil, 97, 94, nil, nil, 72, 75, nil, nil, 102,
- 59, 106, 71, nil, nil, nil, 83, 86, nil, nil,
- 92, nil, nil, nil, nil, 78, 100, 97, nil, 89,
- 72, 75, 94, nil, 102, nil, 106, nil, 71, nil,
- 59, nil, 83, 86, 72, 75, 92, nil, 102, nil,
- nil, 78, 100, nil, nil, 89, nil, nil, 94, nil,
- nil, nil, nil, 71, nil, nil, 59, 83, 86, 72,
- 75, 92, nil, 102, nil, 106, 78, 71, nil, nil,
- 89, 83, 143, nil, nil, 92, nil, nil, nil, nil,
- 137, 59, nil, nil, 89, 72, 75, nil, nil, 102,
- nil, 106, 71, nil, nil, 59, 83, 86, nil, nil,
- 92, nil, nil, nil, nil, 78, nil, 97, nil, 89,
- nil, 72, 75, nil, nil, 102, nil, 106, 71, nil,
- 59, nil, 83, 86, nil, nil, 92, nil, nil, nil,
- nil, 78, 100, 97, nil, 89, nil, nil, 94, nil,
- nil, 72, 75, nil, 71, 102, 59, 106, 83, 86,
- nil, nil, 92, nil, nil, nil, nil, 78, 100, nil,
- nil, 89, nil, 97, 94, nil, nil, 72, 75, nil,
- nil, 102, 59, 106, 71, nil, nil, nil, 83, 86,
- nil, nil, 92, nil, nil, nil, nil, 78, 100, 97,
- nil, 89, 72, 75, 94, nil, 102, nil, 106, nil,
- 71, nil, 59, nil, 83, 86, nil, nil, 92, nil,
- nil, nil, nil, 78, 100, nil, nil, 89, 72, 75,
- 94, nil, 102, nil, 106, 71, nil, nil, 59, 83,
- 86, nil, nil, 92, nil, nil, nil, nil, 78, nil,
- 97, nil, 89, nil, 72, 75, nil, nil, 102, nil,
- 106, 71, nil, 59, nil, 83, 86, nil, nil, 92,
- nil, nil, 72, 75, 78, 100, 97, nil, 89, 72,
- 75, 94, nil, 102, nil, 106, nil, 71, nil, 59,
- nil, 83, 86, nil, nil, 92, nil, nil, nil, nil,
- 78, 100, nil, nil, 89, 162, nil, 94, nil, 83,
- 268, nil, 71, 92, nil, 59, 83, 86, 137, nil,
- 92, nil, 89, nil, nil, 78, 72, 75, nil, 89,
- 102, nil, 106, 59, nil, nil, nil, nil, nil, nil,
- 59, nil, nil, nil, nil, 72, 75, nil, 97, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, 71,
- nil, nil, nil, 83, 86, nil, nil, 92, 177, nil,
- 72, 75, 78, 100, nil, nil, 89, nil, 71, 94,
- nil, nil, 83, 86, nil, nil, 92, 59, 72, 75,
- 76, 78, 102, 339, 106, 89, nil, nil, nil, nil,
- nil, nil, nil, 71, nil, nil, 59, 83, 86, nil,
- 97, 92, nil, 72, 75, 76, 78, 102, nil, 106,
- 89, 71, nil, 72, 75, 83, 86, nil, nil, 92,
- nil, 59, nil, nil, 78, 100, nil, nil, 89, 72,
- 75, 94, nil, nil, nil, nil, 71, nil, nil, 59,
- 83, 86, nil, nil, 92, nil, 162, nil, nil, 78,
- 83, 268, nil, 89, 92, nil, 72, 75, nil, 137,
- 102, nil, 162, 89, 59, nil, 83, 268, nil, nil,
- 92, nil, 72, 75, 59, 137, 102, nil, 106, 89,
- nil, nil, 72, 75, nil, nil, 102, nil, 106, 71,
- 59, nil, nil, 83, 268, nil, nil, 92, nil, nil,
- nil, nil, 137, nil, 97, 71, 89, nil, nil, 83,
- 86, nil, nil, 92, nil, 71, nil, 59, 78, 83,
- 86, nil, 89, 92, nil, nil, nil, nil, 78, 100,
- 72, 75, 89, 59, 102, 94, 106, 213, 196, 197,
- 198, 200, 202, 59, 207, 211, nil, nil, nil, 72,
- 75, 199, 97, 102, 189, 106, 72, 75, nil, nil,
- 102, nil, 106, 71, nil, nil, nil, 83, 86, nil,
- nil, 92, nil, nil, nil, nil, 78, 100, 72, 75,
- 89, nil, 71, 94, nil, nil, 83, 86, nil, 71,
- 92, 59, nil, 83, 86, 78, nil, 92, nil, 89,
- nil, nil, 78, 72, 75, nil, 89, 102, nil, 106,
- 59, 162, nil, nil, nil, 83, 268, 59, nil, 92,
- nil, 72, 75, nil, 137, 102, nil, 106, 89, nil,
- nil, nil, nil, nil, nil, nil, 71, nil, nil, 59,
- 83, 86, nil, 97, 92, nil, nil, nil, nil, 78,
- nil, 72, 75, 89, 71, 102, nil, 106, 83, 86,
- nil, nil, 92, nil, 59, nil, nil, 78, 100, nil,
- nil, 89, nil, 97, 94, nil, nil, 72, 75, nil,
- nil, 102, 59, 106, 71, nil, nil, nil, 83, 86,
- nil, nil, 92, nil, nil, nil, nil, 78, 100, 97,
- nil, 89, nil, nil, 94, nil, nil, nil, nil, nil,
- 71, nil, 59, nil, 83, 86, 212, nil, 92, nil,
- nil, nil, nil, 78, 100, 205, 210, 89, nil, nil,
- 94, nil, nil, nil, 201, 203, 206, 209, 59, nil,
- 205, 210, nil, nil, nil, nil, nil, nil, nil, 201,
- 203, 206, 209, nil, nil, nil, nil, nil, 204, 208,
- nil, nil, 213, 196, 197, 198, 200, 202, nil, 207,
- 211, nil, nil, 204, 208, nil, 199, 213, 196, 197,
- 198, 200, 202, nil, 207, 211, 205, 210, nil, nil,
- nil, 199, nil, nil, nil, 201, 203, 206, 209, nil,
- nil, 205, 210, nil, nil, nil, nil, nil, nil, nil,
- 201, 203, 206, 209, nil, nil, nil, nil, nil, 204,
- 208, nil, nil, 213, 196, 197, 198, 200, 202, nil,
- 207, 211, nil, nil, 204, 208, nil, 199, 213, 196,
- 197, 198, 200, 202, nil, 207, 211, 205, 210, nil,
- nil, nil, 199, nil, nil, nil, 201, 203, 206, 209,
- nil, nil, 205, 210, nil, nil, nil, nil, nil, nil,
- 273, 201, 203, 206, 209, nil, nil, nil, nil, nil,
- nil, 208, nil, nil, 213, 196, 197, 198, 200, 202,
- nil, 207, 211, nil, nil, 204, 208, nil, 199, 213,
- 196, 197, 198, 200, 202, nil, 207, 211, 205, 210,
- nil, nil, nil, 199, nil, nil, nil, 201, 203, 206,
- 209, nil, nil, 26, 210, 33, 1, nil, 7, 12,
- nil, 17, 201, 23, nil, 29, nil, 3, nil, nil,
- 11, 14, nil, 210, nil, 213, 196, 197, 198, 200,
- 202, 201, 207, 211, nil, nil, nil, nil, nil, 199,
- 213, 196, 197, 198, 200, 202, nil, 207, 211, nil,
- nil, 324, nil, nil, 199, nil, nil, nil, nil, 213,
- 196, 197, 198, 200, 202, nil, 207, 211, nil, nil,
- 379, nil, 26, 199, 33, 1, nil, 7, 12, nil,
- 17, nil, 23, nil, 29, nil, 3, nil, nil, 11,
- 14, 26, 382, 33, 1, nil, 7, 12, nil, 17,
- nil, 23, nil, 29, nil, 3, nil, nil, 11, 14,
- nil, 296, nil, 26, nil, 33, 1, nil, 7, 12,
- nil, 17, nil, 23, nil, 29, nil, 3, nil, nil,
- 11, 14, 26, 364, 33, 1, nil, 7, 12, nil,
- 17, nil, 23, nil, 29, nil, 3, nil, nil, 11,
- 14, nil, 381, nil, 26, nil, 33, 1, nil, 7,
- 12, nil, 17, nil, 23, nil, 29, nil, 3, nil,
- nil, 11, 14, 26, 383, 33, 1, nil, 7, 12,
- nil, 17, nil, 23, nil, 29, nil, 3, nil, nil,
- 11, 14, nil, 357, nil, 26, nil, 33, 1, nil,
- 7, 12, nil, 17, nil, 23, nil, 29, nil, 3,
- nil, nil, 11, 14, 26, 363, 33, 1, nil, 7,
- 12, nil, 17, nil, 23, nil, 29, nil, 3, nil,
- nil, 11, 14, nil, 375, nil, 26, nil, 33, 1,
- nil, 7, 12, nil, 17, nil, 23, nil, 29, nil,
- 3, nil, nil, 11, 14, 26, 304, 33, 1, nil,
- 7, 12, nil, 17, nil, 23, nil, 29, nil, 3,
- nil, nil, 11, 14, nil, 349, nil, 26, nil, 33,
- 1, nil, 7, 12, nil, 17, nil, 23, nil, 29,
- nil, 3, nil, nil, 11, 14, 26, nil, 33, 1,
- nil, 7, 12, nil, 17, nil, 23, nil, 29, nil,
- 3, nil, nil, 11, 14, 26, nil, 33, 1, nil,
- 7, 12, nil, 17, nil, 23, nil, 29, nil, 3,
- nil, nil, 11, 14 ]
+ 242, 243, 55, 231, 356, 112, 157, 113, 78, 298,
+ 68, 71, 357, 181, 186, 326, 344, 340, 55, 295,
+ 114, 231, 177, 179, 182, 185, 170, 294, 68, 71,
+ 286, 158, 100, 285, 103, 68, 71, 291, 292, 55,
+ 59, 291, 292, 61, 111, 233, 180, 184, 198, 231,
+ 189, 172, 173, 174, 176, 178, 59, 183, 187, 61,
+ -168, 66, 170, 60, 175, 79, 81, 186, 202, 88,
+ 112, 166, 79, 252, 74, 177, 88, 59, 84, 60,
+ 61, 139, 68, 71, 333, 84, 100, 117, 103, 60,
+ 36, -170, 68, 71, 38, 306, 60, 307, 203, 240,
+ 60, 10, 203, 189, 172, 173, 174, 176, 178, 202,
+ 183, 187, 241, 202, 209, 66, 218, 175, 209, 79,
+ 81, 219, 284, 88, 309, 202, 256, 283, 74, 79,
+ 252, 308, 84, 88, 203, 68, 71, 310, 139, 100,
+ 203, 103, 84, 60, 218, 202, 256, 367, 36, 219,
+ 209, 202, 38, 60, 68, 71, 209, 95, 100, 10,
+ 103, 68, 71, 68, 71, 100, 337, 103, 66, 335,
+ 199, 154, 79, 81, 173, 174, 88, 183, 187, 183,
+ 187, 74, 99, 95, 175, 84, 175, 66, 90, 311,
+ 337, 79, 81, 335, 66, 88, 60, 287, 79, 81,
+ 74, 198, 88, 315, 84, 68, 71, 74, 99, -172,
+ 213, 84, 68, 71, 90, 60, 100, 36, 103, 68,
+ 71, 38, 60, 100, 318, 103, 68, 71, 10, 15,
+ 36, -167, 213, 355, 38, 167, 36, 313, 202, 154,
+ 127, 10, 79, 252, 323, 66, 88, 10, 15, 79,
+ 81, 139, 66, 88, 166, 84, 79, 81, 74, 202,
+ 88, 229, 84, 79, 252, 74, 60, 88, 49, 84,
+ 68, 71, 139, 60, 78, -186, 84, 47, 48, 49,
+ 60, 329, 36, 170, 183, 187, 127, 60, -169, 68,
+ 71, 175, 70, 10, 15, 68, 71, 161, -171, 100,
+ 289, 103, -169, 66, 291, 292, 60, 79, 81, 258,
+ -167, 88, -170, 256, 257, 72, 74, 95, -168, 60,
+ 84, 156, 66, 154, 68, 71, 79, 81, 66, 122,
+ 88, 60, 79, 81, 72, 74, 88, -170, -173, 84,
+ -172, 74, 99, 68, 71, 84, -171, 100, 90, 103,
+ 60, 200, 334, 68, 71, 213, 60, 202, 215, 254,
+ 338, 79, 252, 173, 174, 88, 122, 296, 183, 187,
+ 139, 256, 257, 216, 84, 175, 66, 234, 68, 71,
+ 79, 81, 113, 117, 88, 60, 202, 217, 78, 74,
+ 79, 252, 353, 84, 88, 53, 68, 71, 223, 139,
+ 100, 260, 103, 84, 60, 43, 44, 40, 41, 358,
+ 52, 66, 51, 225, 60, 79, 81, -169, 229, 88,
+ 365, 68, 71, 72, 74, 100, 238, 103, 84, 66,
+ 228, -167, 234, 79, 81, 372, 373, 88, -169, 60,
+ -167, -170, 74, 95, -168, -172, 84, 68, 71, 45,
+ 375, 100, 229, 103, 66, -221, 232, 60, 79, 81,
+ 378, 39, 88, -24, -24, -24, -24, 74, 99, 95,
+ -168, 84, 383, 384, 90, nil, nil, 68, 71, nil,
+ 66, 100, 60, 103, 79, 81, nil, nil, 88, -22,
+ -22, -22, -22, 74, 99, nil, nil, 84, nil, 95,
+ 90, nil, nil, 68, 71, nil, nil, 100, 60, 103,
+ 66, nil, nil, nil, 79, 81, nil, nil, 88, 43,
+ 44, 40, 41, 74, 99, 95, nil, 84, nil, nil,
+ 90, nil, nil, 68, 71, nil, 66, 100, 60, 103,
+ 79, 81, nil, nil, 88, nil, nil, nil, nil, 74,
+ 99, nil, nil, 84, nil, 95, 90, nil, nil, 68,
+ 71, nil, nil, 100, 60, 103, 66, nil, nil, nil,
+ 79, 81, nil, nil, 88, nil, nil, 68, 71, 74,
+ 99, 100, nil, 84, 68, 71, 90, nil, 100, nil,
+ 103, nil, 66, nil, 60, nil, 79, 81, nil, nil,
+ 88, nil, nil, nil, nil, 74, 95, nil, nil, 84,
+ 66, nil, nil, nil, 79, 144, nil, 66, 88, nil,
+ 60, 79, 81, 139, nil, 88, nil, 84, nil, nil,
+ 74, 99, nil, nil, 84, 68, 71, 90, 60, 100,
+ nil, 103, nil, nil, nil, 60, nil, nil, nil, nil,
+ nil, nil, nil, nil, 68, 71, nil, 95, 100, nil,
+ 103, 68, 71, nil, nil, 100, nil, 103, 66, nil,
+ nil, nil, 79, 81, nil, nil, 88, nil, nil, 68,
+ 71, 74, 99, nil, nil, 84, nil, 66, 90, nil,
+ nil, 79, 81, nil, 66, 88, 60, nil, 79, 81,
+ 74, nil, 88, nil, 84, 68, 71, 74, nil, nil,
+ nil, 84, 202, nil, nil, 60, 79, 252, nil, nil,
+ 88, nil, 60, nil, nil, 139, 68, 71, 162, 84,
+ 100, nil, 103, nil, nil, nil, nil, nil, 66, nil,
+ 60, nil, 79, 81, nil, nil, 88, nil, 95, nil,
+ 72, 74, 68, 71, nil, 84, 100, nil, 103, 66,
+ nil, nil, nil, 79, 81, nil, 60, 88, nil, nil,
+ nil, nil, 74, 99, 95, nil, 84, 68, 71, 90,
+ nil, nil, nil, nil, nil, 66, nil, 60, nil, 79,
+ 81, nil, nil, 88, nil, nil, nil, nil, 74, 99,
+ 327, nil, 84, 68, 71, 90, nil, 100, nil, 103,
+ 66, nil, nil, 60, 79, 81, nil, nil, 88, nil,
+ nil, nil, 72, 74, nil, 95, nil, 84, 68, 71,
+ nil, nil, 100, nil, 103, nil, 66, nil, 60, nil,
+ 79, 81, 68, 71, 88, nil, 100, nil, 103, 74,
+ 99, nil, nil, 84, nil, nil, 90, nil, nil, nil,
+ nil, 66, nil, nil, 60, 79, 81, 68, 71, 88,
+ nil, 100, nil, 103, 74, 66, nil, nil, 84, 79,
+ 81, 68, 71, 88, nil, 100, nil, nil, 74, 60,
+ nil, nil, 84, nil, nil, nil, nil, nil, nil, nil,
+ 66, nil, nil, 60, 79, 81, nil, nil, 88, nil,
+ nil, 68, 71, 74, 66, nil, nil, 84, 79, 252,
+ nil, nil, 88, nil, nil, nil, nil, 139, 60, 68,
+ 71, 84, nil, 100, nil, 103, nil, nil, nil, nil,
+ nil, nil, 60, nil, 202, nil, nil, nil, 79, 252,
+ nil, 95, 88, nil, nil, nil, nil, 139, nil, 68,
+ 71, 84, 66, 100, nil, 103, 79, 81, nil, nil,
+ 88, nil, 60, nil, nil, 74, 99, nil, nil, 84,
+ nil, 95, 90, nil, nil, 68, 71, nil, nil, 100,
+ 60, 103, 66, nil, nil, nil, 79, 81, nil, nil,
+ 88, nil, nil, nil, nil, 74, 99, 95, nil, 84,
+ nil, nil, 90, nil, nil, 68, 71, nil, 66, 100,
+ 60, 103, 79, 81, nil, nil, 88, nil, nil, nil,
+ nil, 74, 99, nil, nil, 84, nil, 95, 90, nil,
+ nil, 68, 71, nil, nil, 100, 60, 103, 66, nil,
+ nil, nil, 79, 81, nil, nil, 88, nil, nil, nil,
+ nil, 74, 99, 95, nil, 84, nil, nil, 90, nil,
+ nil, 68, 71, nil, 66, 100, 60, 103, 79, 81,
+ nil, nil, 88, nil, nil, nil, nil, 74, 99, nil,
+ nil, 84, nil, 95, 90, nil, nil, 68, 71, nil,
+ nil, 100, 60, 103, 66, nil, nil, nil, 79, 81,
+ nil, nil, 88, nil, nil, nil, nil, 74, 99, 95,
+ nil, 84, nil, nil, 90, nil, nil, 68, 71, nil,
+ 66, 100, 60, 103, 79, 81, nil, nil, 88, nil,
+ nil, nil, nil, 74, 99, nil, nil, 84, nil, 95,
+ 90, nil, nil, 68, 71, nil, nil, 100, 60, 103,
+ 66, nil, nil, nil, 79, 81, nil, nil, 88, nil,
+ nil, nil, nil, 74, 99, 95, nil, 84, 68, 71,
+ 90, nil, 100, 193, 103, nil, 66, nil, 60, nil,
+ 79, 81, nil, nil, 88, nil, nil, nil, nil, 74,
+ 99, nil, nil, 84, 68, 71, 90, nil, 100, nil,
+ 103, 66, nil, nil, 60, 79, 81, nil, nil, 88,
+ nil, nil, nil, nil, 74, nil, 95, nil, 84, nil,
+ 68, 71, nil, nil, 100, nil, 103, 66, nil, 60,
+ nil, 79, 81, nil, nil, 88, nil, nil, nil, nil,
+ 74, 99, 95, nil, 84, nil, nil, 90, nil, nil,
+ nil, nil, nil, 66, nil, 60, nil, 79, 81, 188,
+ nil, 88, nil, nil, nil, nil, 74, 99, 181, 186,
+ 84, nil, nil, 90, nil, nil, nil, 177, 179, 182,
+ 185, 60, nil, 181, 186, nil, nil, nil, nil, nil,
+ nil, 282, 177, 179, 182, 185, nil, nil, nil, nil,
+ nil, 180, 184, nil, nil, 189, 172, 173, 174, 176,
+ 178, nil, 183, 187, nil, nil, 180, 184, nil, 175,
+ 189, 172, 173, 174, 176, 178, nil, 183, 187, 181,
+ 186, nil, nil, nil, 175, nil, nil, nil, 177, 179,
+ 182, 185, nil, nil, 181, 186, nil, nil, nil, nil,
+ nil, nil, nil, 177, 179, 182, 185, nil, nil, nil,
+ nil, nil, nil, nil, nil, nil, 189, 172, 173, 174,
+ 176, 178, nil, 183, 187, nil, nil, 180, 184, nil,
+ 175, 189, 172, 173, 174, 176, 178, nil, 183, 187,
+ 181, 186, nil, nil, nil, 175, nil, nil, nil, 177,
+ 179, 182, 185, nil, nil, 181, 186, nil, nil, nil,
+ nil, nil, nil, nil, 177, 179, 182, 185, nil, nil,
+ nil, nil, nil, 180, 184, nil, nil, 189, 172, 173,
+ 174, 176, 178, nil, 183, 187, nil, nil, nil, 184,
+ nil, 175, 189, 172, 173, 174, 176, 178, nil, 183,
+ 187, 181, 186, nil, nil, nil, 175, nil, nil, nil,
+ 177, 179, 182, 185, nil, nil, nil, 186, nil, 189,
+ 172, 173, 174, 176, 178, 177, 183, 187, nil, nil,
+ nil, nil, nil, 175, 180, 184, 186, nil, 189, 172,
+ 173, 174, 176, 178, 177, 183, 187, nil, nil, nil,
+ nil, 186, 175, 189, 172, 173, 174, 176, 178, 177,
+ 183, 187, nil, nil, nil, nil, nil, 175, nil, nil,
+ nil, nil, 189, 172, 173, 174, 176, 178, nil, 183,
+ 187, 280, nil, nil, nil, nil, 175, 189, 172, 173,
+ 174, 176, 178, nil, 183, 187, nil, nil, nil, nil,
+ 325, 175, 26, nil, 32, 1, nil, 8, 11, nil,
+ 18, nil, 23, nil, 29, nil, 2, nil, nil, 10,
+ 15, 26, 363, 32, 1, nil, 8, 11, nil, 18,
+ nil, 23, nil, 29, nil, 2, nil, nil, 10, 15,
+ nil, 382, nil, 26, nil, 32, 1, nil, 8, 11,
+ nil, 18, nil, 23, nil, 29, nil, 2, nil, nil,
+ 10, 15, 26, 380, 32, 1, nil, 8, 11, nil,
+ 18, nil, 23, nil, 29, nil, 2, nil, nil, 10,
+ 15, nil, 376, nil, 26, nil, 32, 1, nil, 8,
+ 11, nil, 18, nil, 23, nil, 29, nil, 2, nil,
+ nil, 10, 15, 26, 305, 32, 1, nil, 8, 11,
+ nil, 18, nil, 23, nil, 29, nil, 2, nil, nil,
+ 10, 15, nil, nil, nil, 26, nil, 32, 1, nil,
+ 8, 11, nil, 18, nil, 23, nil, 29, nil, 2,
+ nil, nil, 10, 15, 26, nil, 32, 1, nil, 8,
+ 11, nil, 18, nil, 23, nil, 29, nil, 2, nil,
+ nil, 10, 15, 26, nil, 32, 1, nil, 8, 11,
+ nil, 18, nil, 23, nil, 29, nil, 2, nil, nil,
+ 10, 15, 26, nil, 32, 1, nil, 8, 11, nil,
+ 18, nil, 23, nil, 29, nil, 2, nil, nil, 10,
+ 15, 189, 172, 173, 174, 176, 178, nil, 183, 187,
+ 189, 172, 173, 174, nil, 175, nil, 183, 187, 189,
+ 172, 173, 174, nil, 175, nil, 183, 187, nil, nil,
+ nil, nil, nil, 175 ]
racc_action_check = [
- 180, 180, 152, 86, 156, 106, 106, 272, 174, 7,
- 277, 277, 106, 180, 180, 65, 55, 277, 7, 7,
- 272, 86, 180, 180, 180, 180, 65, 296, 17, 80,
- 296, 65, 158, 95, 202, 202, 174, 174, 202, 218,
- 202, 55, 156, 106, 152, 156, 180, 180, 277, 219,
- 180, 180, 180, 180, 180, 180, 202, 180, 180, 181,
- 181, 368, 368, 239, 180, 156, 17, 202, 165, 17,
- 158, 202, 202, 158, 239, 202, 165, 182, 182, 239,
- 202, 202, 349, 182, 202, 349, 22, 202, 22, 17,
- 143, 243, 181, 158, 368, 202, 181, 181, 368, 368,
- 181, 22, 368, 143, 181, 181, 220, 368, 163, 181,
- 182, 368, 355, 355, 182, 182, 243, 243, 182, 163,
- 181, 62, 368, 182, 163, 22, 178, 182, 281, 281,
- 351, 351, 62, 221, 351, 281, 351, 62, 182, 178,
- 285, 285, 285, 285, 101, 355, 221, 285, 285, 355,
- 355, 224, 351, 355, 285, 341, 341, 300, 355, 341,
- 91, 341, 355, 351, 308, 300, 226, 351, 351, 308,
- 227, 351, 90, 355, 184, 184, 351, 351, 12, 122,
- 351, 171, 12, 351, 122, 171, 171, 229, 341, 12,
- 286, 351, 341, 341, 343, 343, 341, 184, 286, 1,
- 87, 341, 30, 1, 183, 341, 30, 184, 183, 183,
- 1, 184, 184, 30, 30, 184, 341, 196, 196, 184,
- 184, 196, 195, 196, 184, 195, 286, 286, 286, 286,
- 286, 286, 188, 286, 286, 184, 188, 188, 231, 196,
- 286, 120, 232, 197, 197, 120, 233, 197, 103, 197,
- 196, 85, 120, 120, 196, 196, 105, 43, 196, 280,
- 280, 43, 84, 196, 196, 197, 280, 196, 43, 43,
- 196, 81, 215, 23, 23, 78, 197, 23, 196, 250,
- 197, 197, 279, 279, 197, 252, 253, 279, 279, 197,
- 197, 77, 71, 197, 279, 23, 197, 160, 68, 26,
- 26, 160, 160, 26, 197, 26, 23, 268, 67, 234,
- 23, 23, 211, 234, 23, 274, 234, 66, 23, 23,
- 234, 26, 107, 23, 108, 198, 198, 109, 207, 198,
- 114, 198, 26, 115, 23, 119, 26, 26, 64, 121,
- 26, 35, 35, 35, 35, 26, 26, 198, 52, 26,
- 29, 29, 26, 51, 29, 50, 29, 127, 198, 132,
- 26, 36, 198, 198, 307, 307, 198, 133, 307, 136,
- 307, 198, 198, 138, 192, 198, 139, 33, 198, 34,
- 34, 34, 34, 29, 140, 142, 198, 29, 29, 305,
- 305, 29, 315, 305, 144, 305, 29, 307, 16, 327,
- 29, 307, 307, 199, 199, 307, 328, 199, 330, 199,
- 307, 29, 297, 297, 307, 331, 332, 297, 297, 337,
- 153, 175, 305, 154, 297, 307, 305, 305, 9, 288,
- 305, 28, 28, 28, 28, 305, 199, 288, 352, 305,
- 199, 199, 8, 356, 199, 298, 298, 173, 367, 199,
- 305, 172, 298, 199, 369, 200, 200, 3, 2, 200,
- 157, 200, 263, nil, 199, 288, 288, 288, 288, 288,
- 288, nil, 288, 288, nil, nil, nil, 200, 298, 288,
- nil, nil, 298, 298, nil, nil, 298, nil, 200, nil,
- nil, 298, 200, 200, nil, 298, 200, 4, 4, 4,
- 4, 200, 200, 39, 39, 200, 298, 39, 200, 39,
- 293, 293, 293, 293, 293, 293, 200, 293, 293, nil,
- 283, 283, 283, 283, 293, 39, nil, 283, 283, 201,
- 201, nil, nil, 201, 283, 201, 39, nil, nil, nil,
- 39, 39, nil, nil, 39, nil, nil, nil, nil, 39,
- 39, 201, nil, 39, nil, nil, 39, nil, nil, 46,
- 46, nil, 201, 46, 39, 46, 201, 201, nil, nil,
- 201, nil, nil, nil, nil, 201, 201, nil, nil, 201,
- nil, 46, 201, nil, nil, 47, 47, nil, nil, 47,
- 201, 47, 46, nil, nil, nil, 46, 46, nil, nil,
- 46, nil, nil, nil, nil, 46, 46, 47, nil, 46,
- 48, 48, 46, nil, 48, nil, 48, nil, 47, nil,
- 46, nil, 47, 47, 49, 49, 47, nil, 49, nil,
- nil, 47, 47, nil, nil, 47, nil, nil, 47, nil,
- nil, nil, nil, 48, nil, nil, 47, 48, 48, 176,
- 176, 48, nil, 176, nil, 176, 48, 49, nil, nil,
- 48, 49, 49, nil, nil, 49, nil, nil, nil, nil,
- 49, 48, nil, nil, 49, 203, 203, nil, nil, 203,
- nil, 203, 176, nil, nil, 49, 176, 176, nil, nil,
- 176, nil, nil, nil, nil, 176, nil, 203, nil, 176,
- nil, 204, 204, nil, nil, 204, nil, 204, 203, nil,
- 176, nil, 203, 203, nil, nil, 203, nil, nil, nil,
- nil, 203, 203, 204, nil, 203, nil, nil, 203, nil,
- nil, 205, 205, nil, 204, 205, 203, 205, 204, 204,
- nil, nil, 204, nil, nil, nil, nil, 204, 204, nil,
- nil, 204, nil, 205, 204, nil, nil, 100, 100, nil,
- nil, 100, 204, 100, 205, nil, nil, nil, 205, 205,
- nil, nil, 205, nil, nil, nil, nil, 205, 205, 100,
- nil, 205, 63, 63, 205, nil, 63, nil, 63, nil,
- 100, nil, 205, nil, 100, 100, nil, nil, 100, nil,
- nil, nil, nil, 100, 100, nil, nil, 100, 208, 208,
- 100, nil, 208, nil, 208, 63, nil, nil, 100, 63,
- 63, nil, nil, 63, nil, nil, nil, nil, 63, nil,
- 208, nil, 63, nil, 209, 209, nil, nil, 209, nil,
- 209, 208, nil, 63, nil, 208, 208, nil, nil, 208,
- nil, nil, 269, 269, 208, 208, 209, nil, 208, 276,
- 276, 208, nil, 276, nil, 276, nil, 209, nil, 208,
- nil, 209, 209, nil, nil, 209, nil, nil, nil, nil,
- 209, 209, nil, nil, 209, 269, nil, 209, nil, 269,
- 269, nil, 276, 269, nil, 209, 276, 276, 269, nil,
- 276, nil, 269, nil, nil, 276, 256, 256, nil, 276,
- 256, nil, 256, 269, nil, nil, nil, nil, nil, nil,
- 276, nil, nil, nil, nil, 74, 74, nil, 256, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, 256,
- nil, nil, nil, 256, 256, nil, nil, 256, 74, nil,
- 254, 254, 256, 256, nil, nil, 256, nil, 74, 256,
- nil, nil, 74, 74, nil, nil, 74, 256, 75, 75,
- 74, 74, 75, 254, 75, 74, nil, nil, nil, nil,
- nil, nil, nil, 254, nil, nil, 74, 254, 254, nil,
- 75, 254, nil, 248, 248, 254, 254, 248, nil, 248,
- 254, 75, nil, 245, 245, 75, 75, nil, nil, 75,
- nil, 254, nil, nil, 75, 75, nil, nil, 75, 244,
- 244, 75, nil, nil, nil, nil, 248, nil, nil, 75,
- 248, 248, nil, nil, 248, nil, 245, nil, nil, 248,
- 245, 245, nil, 248, 245, nil, 225, 225, nil, 245,
- 225, nil, 244, 245, 248, nil, 244, 244, nil, nil,
- 244, nil, 82, 82, 245, 244, 82, nil, 82, 244,
- nil, nil, 210, 210, nil, nil, 210, nil, 210, 225,
- 244, nil, nil, 225, 225, nil, nil, 225, nil, nil,
- nil, nil, 225, nil, 210, 82, 225, nil, nil, 82,
- 82, nil, nil, 82, nil, 210, nil, 225, 82, 210,
- 210, nil, 82, 210, nil, nil, nil, nil, 210, 210,
- 213, 213, 210, 82, 213, 210, 213, 284, 284, 284,
- 284, 284, 284, 210, 284, 284, nil, nil, nil, 102,
- 102, 284, 213, 102, 102, 102, 230, 230, nil, nil,
- 230, nil, 230, 213, nil, nil, nil, 213, 213, nil,
- nil, 213, nil, nil, nil, nil, 213, 213, 214, 214,
- 213, nil, 102, 213, nil, nil, 102, 102, nil, 230,
- 102, 213, nil, 230, 230, 102, nil, 230, nil, 102,
- nil, nil, 230, 228, 228, nil, 230, 228, nil, 228,
- 102, 214, nil, nil, nil, 214, 214, 230, nil, 214,
- nil, 94, 94, nil, 214, 94, nil, 94, 214, nil,
- nil, nil, nil, nil, nil, nil, 228, nil, nil, 214,
- 228, 228, nil, 94, 228, nil, nil, nil, nil, 228,
- nil, 97, 97, 228, 94, 97, nil, 97, 94, 94,
- nil, nil, 94, nil, 228, nil, nil, 94, 94, nil,
- nil, 94, nil, 97, 94, nil, nil, 206, 206, nil,
- nil, 206, 94, 206, 97, nil, nil, nil, 97, 97,
- nil, nil, 97, nil, nil, nil, nil, 97, 97, 206,
- nil, 97, nil, nil, 97, nil, nil, nil, nil, nil,
- 206, nil, 97, nil, 206, 206, 111, nil, 206, nil,
- nil, nil, nil, 206, 206, 111, 111, 206, nil, nil,
- 206, nil, nil, nil, 111, 111, 111, 111, 206, nil,
- 124, 124, nil, nil, nil, nil, nil, nil, nil, 124,
- 124, 124, 124, nil, nil, nil, nil, nil, 111, 111,
- nil, nil, 111, 111, 111, 111, 111, 111, nil, 111,
- 111, nil, nil, 124, 124, nil, 111, 124, 124, 124,
- 124, 124, 124, nil, 124, 124, 130, 130, nil, nil,
- nil, 124, nil, nil, nil, 130, 130, 130, 130, nil,
- nil, 131, 131, nil, nil, nil, nil, nil, nil, nil,
- 131, 131, 131, 131, nil, nil, nil, nil, nil, 130,
- 130, nil, nil, 130, 130, 130, 130, 130, 130, nil,
- 130, 130, nil, nil, 131, 131, nil, 130, 131, 131,
- 131, 131, 131, 131, nil, 131, 131, 287, 287, nil,
- nil, nil, 131, nil, nil, nil, 287, 287, 287, 287,
- nil, nil, 186, 186, nil, nil, nil, nil, nil, nil,
- 186, 186, 186, 186, 186, nil, nil, nil, nil, nil,
- nil, 287, nil, nil, 287, 287, 287, 287, 287, 287,
- nil, 287, 287, nil, nil, 186, 186, nil, 287, 186,
- 186, 186, 186, 186, 186, nil, 186, 186, 291, 291,
- nil, nil, nil, 186, nil, nil, nil, 291, 291, 291,
- 291, nil, nil, 19, 292, 19, 19, nil, 19, 19,
- nil, 19, 292, 19, nil, 19, nil, 19, nil, nil,
- 19, 19, nil, 289, nil, 291, 291, 291, 291, 291,
- 291, 289, 291, 291, nil, nil, nil, nil, nil, 291,
- 292, 292, 292, 292, 292, 292, nil, 292, 292, nil,
- nil, 237, nil, nil, 292, nil, nil, nil, nil, 289,
- 289, 289, 289, 289, 289, nil, 289, 289, nil, nil,
- 372, nil, 237, 289, 237, 237, nil, 237, 237, nil,
- 237, nil, 237, nil, 237, nil, 237, nil, nil, 237,
- 237, 372, 378, 372, 372, nil, 372, 372, nil, 372,
- nil, 372, nil, 372, nil, 372, nil, nil, 372, 372,
- nil, 212, nil, 378, nil, 378, 378, nil, 378, 378,
- nil, 378, nil, 378, nil, 378, nil, 378, nil, nil,
- 378, 378, 212, 323, 212, 212, nil, 212, 212, nil,
- 212, nil, 212, nil, 212, nil, 212, nil, nil, 212,
- 212, nil, 374, nil, 323, nil, 323, 323, nil, 323,
- 323, nil, 323, nil, 323, nil, 323, nil, 323, nil,
- nil, 323, 323, 374, 380, 374, 374, nil, 374, 374,
- nil, 374, nil, 374, nil, 374, nil, 374, nil, nil,
- 374, 374, nil, 303, nil, 380, nil, 380, 380, nil,
- 380, 380, nil, 380, nil, 380, nil, 380, nil, 380,
- nil, nil, 380, 380, 303, 319, 303, 303, nil, 303,
- 303, nil, 303, nil, 303, nil, 303, nil, 303, nil,
- nil, 303, 303, nil, 362, nil, 319, nil, 319, 319,
- nil, 319, 319, nil, 319, nil, 319, nil, 319, nil,
- 319, nil, nil, 319, 319, 362, 217, 362, 362, nil,
- 362, 362, nil, 362, nil, 362, nil, 362, nil, 362,
- nil, nil, 362, 362, nil, 295, nil, 217, nil, 217,
- 217, nil, 217, 217, nil, 217, nil, 217, nil, 217,
- nil, 217, nil, nil, 217, 217, 295, nil, 295, 295,
- nil, 295, 295, nil, 295, nil, 295, nil, 295, nil,
- 295, nil, nil, 295, 295, 0, nil, 0, 0, nil,
- 0, 0, nil, 0, nil, 0, nil, 0, nil, 0,
- nil, nil, 0, 0 ]
+ 164, 164, 158, 154, 301, 27, 56, 27, 81, 214,
+ 285, 285, 301, 164, 164, 239, 293, 285, 18, 206,
+ 27, 213, 164, 164, 164, 164, 81, 206, 175, 175,
+ 194, 56, 175, 194, 175, 368, 368, 214, 214, 157,
+ 158, 293, 293, 158, 27, 154, 164, 164, 285, 144,
+ 164, 164, 164, 164, 164, 164, 18, 164, 164, 18,
+ 85, 175, 144, 158, 164, 175, 175, 272, 368, 175,
+ 83, 261, 368, 368, 175, 272, 368, 157, 175, 18,
+ 157, 368, 161, 161, 261, 368, 161, 216, 161, 175,
+ 1, 82, 356, 356, 1, 218, 368, 219, 203, 163,
+ 157, 1, 114, 272, 272, 272, 272, 272, 272, 203,
+ 272, 272, 163, 114, 203, 161, 122, 272, 114, 161,
+ 161, 122, 192, 161, 221, 356, 192, 192, 161, 356,
+ 356, 220, 161, 356, 290, 335, 335, 221, 356, 335,
+ 111, 335, 356, 161, 309, 290, 331, 331, 11, 309,
+ 290, 111, 11, 356, 329, 329, 111, 335, 329, 11,
+ 329, 48, 48, 103, 103, 48, 334, 48, 335, 334,
+ 103, 200, 335, 335, 262, 262, 335, 263, 263, 262,
+ 262, 335, 335, 48, 263, 335, 262, 329, 335, 224,
+ 280, 329, 329, 280, 48, 329, 335, 197, 48, 48,
+ 329, 103, 48, 227, 329, 295, 295, 48, 48, 87,
+ 229, 48, 307, 307, 48, 329, 307, 33, 307, 306,
+ 306, 33, 48, 306, 230, 306, 299, 299, 33, 33,
+ 225, 80, 232, 299, 225, 77, 46, 225, 295, 234,
+ 46, 225, 295, 295, 235, 307, 295, 46, 46, 307,
+ 307, 295, 306, 307, 75, 295, 306, 306, 307, 299,
+ 306, 212, 307, 299, 299, 306, 295, 299, 8, 306,
+ 23, 23, 299, 307, 23, 74, 299, 8, 8, 66,
+ 306, 249, 42, 252, 264, 264, 42, 299, 65, 166,
+ 166, 264, 23, 42, 42, 26, 26, 64, 89, 26,
+ 201, 26, 94, 23, 201, 201, 187, 23, 23, 169,
+ 101, 23, 102, 169, 169, 23, 23, 26, 105, 183,
+ 23, 53, 166, 52, 294, 294, 166, 166, 26, 50,
+ 166, 23, 26, 26, 166, 166, 26, 143, 106, 166,
+ 107, 26, 26, 29, 29, 26, 108, 29, 26, 29,
+ 166, 110, 279, 167, 167, 113, 26, 294, 115, 167,
+ 283, 294, 294, 281, 281, 294, 37, 211, 281, 281,
+ 294, 211, 211, 116, 294, 281, 29, 288, 170, 170,
+ 29, 29, 119, 32, 29, 294, 167, 121, 127, 29,
+ 167, 167, 297, 29, 167, 17, 287, 287, 133, 167,
+ 287, 170, 287, 167, 29, 3, 3, 3, 3, 304,
+ 13, 170, 12, 134, 167, 170, 170, 136, 320, 170,
+ 324, 172, 172, 170, 170, 172, 159, 172, 170, 287,
+ 140, 141, 155, 287, 287, 337, 342, 287, 346, 170,
+ 347, 349, 287, 172, 350, 351, 287, 45, 45, 5,
+ 357, 45, 142, 45, 172, 367, 147, 287, 172, 172,
+ 369, 2, 172, 4, 4, 4, 4, 172, 172, 45,
+ 146, 172, 379, 381, 172, nil, nil, 173, 173, nil,
+ 45, 173, 172, 173, 45, 45, nil, nil, 45, 31,
+ 31, 31, 31, 45, 45, nil, nil, 45, nil, 173,
+ 45, nil, nil, 47, 47, nil, nil, 47, 45, 47,
+ 173, nil, nil, nil, 173, 173, nil, nil, 173, 6,
+ 6, 6, 6, 173, 173, 47, nil, 173, nil, nil,
+ 173, nil, nil, 174, 174, nil, 47, 174, 173, 174,
+ 47, 47, nil, nil, 47, nil, nil, nil, nil, 47,
+ 47, nil, nil, 47, nil, 174, 47, nil, nil, 49,
+ 49, nil, nil, 49, 47, 49, 174, nil, nil, nil,
+ 174, 174, nil, nil, 174, nil, nil, 51, 51, 174,
+ 174, 51, nil, 174, 176, 176, 174, nil, 176, nil,
+ 176, nil, 49, nil, 174, nil, 49, 49, nil, nil,
+ 49, nil, nil, nil, nil, 49, 176, nil, nil, 49,
+ 51, nil, nil, nil, 51, 51, nil, 176, 51, nil,
+ 49, 176, 176, 51, nil, 176, nil, 51, nil, nil,
+ 176, 176, nil, nil, 176, 177, 177, 176, 51, 177,
+ nil, 177, nil, nil, nil, 176, nil, nil, nil, nil,
+ nil, nil, nil, nil, 112, 112, nil, 177, 112, nil,
+ 112, 259, 259, nil, nil, 259, nil, 259, 177, nil,
+ nil, nil, 177, 177, nil, nil, 177, nil, nil, 254,
+ 254, 177, 177, nil, nil, 177, nil, 112, 177, nil,
+ nil, 112, 112, nil, 259, 112, 177, nil, 259, 259,
+ 112, nil, 259, nil, 112, 70, 70, 259, nil, nil,
+ nil, 259, 254, nil, nil, 112, 254, 254, nil, nil,
+ 254, nil, 259, nil, nil, 254, 242, 242, 70, 254,
+ 242, nil, 242, nil, nil, nil, nil, nil, 70, nil,
+ 254, nil, 70, 70, nil, nil, 70, nil, 242, nil,
+ 70, 70, 71, 71, nil, 70, 71, nil, 71, 242,
+ nil, nil, nil, 242, 242, nil, 70, 242, nil, nil,
+ nil, nil, 242, 242, 71, nil, 242, 240, 240, 242,
+ nil, nil, nil, nil, nil, 71, nil, 242, nil, 71,
+ 71, nil, nil, 71, nil, nil, nil, nil, 71, 71,
+ 240, nil, 71, 178, 178, 71, nil, 178, nil, 178,
+ 240, nil, nil, 71, 240, 240, nil, nil, 240, nil,
+ nil, nil, 240, 240, nil, 178, nil, 240, 233, 233,
+ nil, nil, 233, nil, 233, nil, 178, nil, 240, nil,
+ 178, 178, 78, 78, 178, nil, 78, nil, 78, 178,
+ 178, nil, nil, 178, nil, nil, 178, nil, nil, nil,
+ nil, 233, nil, nil, 178, 233, 233, 231, 231, 233,
+ nil, 231, nil, 231, 233, 78, nil, nil, 233, 78,
+ 78, 228, 228, 78, nil, 228, nil, nil, 78, 233,
+ nil, nil, 78, nil, nil, nil, nil, nil, nil, nil,
+ 231, nil, nil, 78, 231, 231, nil, nil, 231, nil,
+ nil, 215, 215, 231, 228, nil, nil, 231, 228, 228,
+ nil, nil, 228, nil, nil, nil, nil, 228, 231, 179,
+ 179, 228, nil, 179, nil, 179, nil, nil, nil, nil,
+ nil, nil, 228, nil, 215, nil, nil, nil, 215, 215,
+ nil, 179, 215, nil, nil, nil, nil, 215, nil, 185,
+ 185, 215, 179, 185, nil, 185, 179, 179, nil, nil,
+ 179, nil, 215, nil, nil, 179, 179, nil, nil, 179,
+ nil, 185, 179, nil, nil, 181, 181, nil, nil, 181,
+ 179, 181, 185, nil, nil, nil, 185, 185, nil, nil,
+ 185, nil, nil, nil, nil, 185, 185, 181, nil, 185,
+ nil, nil, 185, nil, nil, 189, 189, nil, 181, 189,
+ 185, 189, 181, 181, nil, nil, 181, nil, nil, nil,
+ nil, 181, 181, nil, nil, 181, nil, 189, 181, nil,
+ nil, 90, 90, nil, nil, 90, 181, 90, 189, nil,
+ nil, nil, 189, 189, nil, nil, 189, nil, nil, nil,
+ nil, 189, 189, 90, nil, 189, nil, nil, 189, nil,
+ nil, 182, 182, nil, 90, 182, 189, 182, 90, 90,
+ nil, nil, 90, nil, nil, nil, nil, 90, 90, nil,
+ nil, 90, nil, 182, 90, nil, nil, 184, 184, nil,
+ nil, 184, 90, 184, 182, nil, nil, nil, 182, 182,
+ nil, nil, 182, nil, nil, nil, nil, 182, 182, 184,
+ nil, 182, nil, nil, 182, nil, nil, 95, 95, nil,
+ 184, 95, 182, 95, 184, 184, nil, nil, 184, nil,
+ nil, nil, nil, 184, 184, nil, nil, 184, nil, 95,
+ 184, nil, nil, 99, 99, nil, nil, 99, 184, 99,
+ 95, nil, nil, nil, 95, 95, nil, nil, 95, nil,
+ nil, nil, nil, 95, 95, 99, nil, 95, 100, 100,
+ 95, nil, 100, 100, 100, nil, 99, nil, 95, nil,
+ 99, 99, nil, nil, 99, nil, nil, nil, nil, 99,
+ 99, nil, nil, 99, 186, 186, 99, nil, 186, nil,
+ 186, 100, nil, nil, 99, 100, 100, nil, nil, 100,
+ nil, nil, nil, nil, 100, nil, 186, nil, 100, nil,
+ 180, 180, nil, nil, 180, nil, 180, 186, nil, 100,
+ nil, 186, 186, nil, nil, 186, nil, nil, nil, nil,
+ 186, 186, 180, nil, 186, nil, nil, 186, nil, nil,
+ nil, nil, nil, 180, nil, 186, nil, 180, 180, 91,
+ nil, 180, nil, nil, nil, nil, 180, 180, 91, 91,
+ 180, nil, nil, 180, nil, nil, nil, 91, 91, 91,
+ 91, 180, nil, 190, 190, nil, nil, nil, nil, nil,
+ nil, 190, 190, 190, 190, 190, nil, nil, nil, nil,
+ nil, 91, 91, nil, nil, 91, 91, 91, 91, 91,
+ 91, nil, 91, 91, nil, nil, 190, 190, nil, 91,
+ 190, 190, 190, 190, 190, 190, nil, 190, 190, 274,
+ 274, nil, nil, nil, 190, nil, nil, nil, 274, 274,
+ 274, 274, nil, nil, 132, 132, nil, nil, nil, nil,
+ nil, nil, nil, 132, 132, 132, 132, nil, nil, nil,
+ nil, nil, nil, nil, nil, nil, 274, 274, 274, 274,
+ 274, 274, nil, 274, 274, nil, nil, 132, 132, nil,
+ 274, 132, 132, 132, 132, 132, 132, nil, 132, 132,
+ 131, 131, nil, nil, nil, 132, nil, nil, nil, 131,
+ 131, 131, 131, nil, nil, 270, 270, nil, nil, nil,
+ nil, nil, nil, nil, 270, 270, 270, 270, nil, nil,
+ nil, nil, nil, 131, 131, nil, nil, 131, 131, 131,
+ 131, 131, 131, nil, 131, 131, nil, nil, nil, 270,
+ nil, 131, 270, 270, 270, 270, 270, 270, nil, 270,
+ 270, 129, 129, nil, nil, nil, 270, nil, nil, nil,
+ 129, 129, 129, 129, nil, nil, nil, 269, nil, 276,
+ 276, 276, 276, 276, 276, 269, 276, 276, nil, nil,
+ nil, nil, nil, 276, 129, 129, 275, nil, 129, 129,
+ 129, 129, 129, 129, 275, 129, 129, nil, nil, nil,
+ nil, 271, 129, 269, 269, 269, 269, 269, 269, 271,
+ 269, 269, nil, nil, nil, nil, nil, 269, nil, nil,
+ nil, nil, 275, 275, 275, 275, 275, 275, nil, 275,
+ 275, 188, nil, nil, nil, nil, 275, 271, 271, 271,
+ 271, 271, 271, nil, 271, 271, nil, nil, nil, nil,
+ 238, 271, 188, nil, 188, 188, nil, 188, 188, nil,
+ 188, nil, 188, nil, 188, nil, 188, nil, nil, 188,
+ 188, 238, 311, 238, 238, nil, 238, 238, nil, 238,
+ nil, 238, nil, 238, nil, 238, nil, nil, 238, 238,
+ nil, 375, nil, 311, nil, 311, 311, nil, 311, 311,
+ nil, 311, nil, 311, nil, 311, nil, 311, nil, nil,
+ 311, 311, 375, 372, 375, 375, nil, 375, 375, nil,
+ 375, nil, 375, nil, 375, nil, 375, nil, nil, 375,
+ 375, nil, 362, nil, 372, nil, 372, 372, nil, 372,
+ 372, nil, 372, nil, 372, nil, 372, nil, 372, nil,
+ nil, 372, 372, 362, 217, 362, 362, nil, 362, 362,
+ nil, 362, nil, 362, nil, 362, nil, 362, nil, nil,
+ 362, 362, nil, nil, nil, 217, nil, 217, 217, nil,
+ 217, 217, nil, 217, nil, 217, nil, 217, nil, 217,
+ nil, nil, 217, 217, 0, nil, 0, 0, nil, 0,
+ 0, nil, 0, nil, 0, nil, 0, nil, 0, nil,
+ nil, 0, 0, 20, nil, 20, 20, nil, 20, 20,
+ nil, 20, nil, 20, nil, 20, nil, 20, nil, nil,
+ 20, 20, 278, nil, 278, 278, nil, 278, 278, nil,
+ 278, nil, 278, nil, 278, nil, 278, nil, nil, 278,
+ 278, 267, 267, 267, 267, 267, 267, nil, 267, 267,
+ 266, 266, 266, 266, nil, 267, nil, 266, 266, 268,
+ 268, 268, 268, nil, 266, nil, 268, 268, nil, nil,
+ nil, nil, nil, 268 ]
racc_action_pointer = [
- 1795, 163, 443, 413, 433, nil, nil, 3, 434, 420,
- nil, nil, 142, nil, nil, nil, 398, 26, nil, 1483,
- nil, nil, 80, 271, nil, nil, 297, nil, 367, 348,
- 166, nil, nil, 375, 315, 277, 337, nil, nil, 501,
- nil, nil, nil, 221, nil, nil, 557, 583, 608, 622,
- 315, 329, 348, nil, nil, 4, nil, nil, nil, nil,
- nil, nil, 97, 780, 298, -9, 309, 302, 275, nil,
- nil, 286, nil, nil, 923, 966, nil, 279, 269, nil,
- 6, 248, 1060, nil, 239, 245, -3, 177, nil, nil,
- 149, 137, nil, nil, 1209, 10, nil, 1239, nil, nil,
- 755, 121, 1137, 225, nil, 233, 3, 299, 301, 304,
- nil, 1298, nil, nil, 322, 325, nil, nil, nil, 323,
- 205, 331, 144, nil, 1313, nil, nil, 351, nil, nil,
- 1359, 1374, 352, 344, nil, nil, 328, nil, 350, 364,
- 361, nil, 362, 79, 374, nil, nil, nil, nil, nil,
- nil, nil, -9, 408, 386, nil, 2, 452, 30, nil,
- 251, nil, nil, 84, nil, 50, nil, nil, nil, nil,
- nil, 174, 439, 436, -14, 381, 647, nil, 114, nil,
- -4, 57, 75, 197, 172, nil, 1435, nil, 225, nil,
- nil, nil, 363, nil, nil, 213, 215, 241, 323, 401,
- 453, 527, 32, 673, 699, 729, 1265, 265, 806, 832,
- 1070, 249, 1612, 1118, 1166, 270, nil, 1757, 24, 24,
- 91, 121, nil, nil, 142, 1044, 126, 161, 1191, 147,
- 1144, 198, 233, 238, 273, nil, nil, 1552, nil, 39,
- nil, nil, nil, 66, 1017, 1001, nil, nil, 991, nil,
- 270, nil, 273, 279, 948, nil, 904, nil, nil, nil,
- nil, nil, nil, 451, nil, nil, nil, nil, 283, 850,
- nil, nil, -5, nil, 308, nil, 857, 8, nil, 226,
- 198, 67, nil, 466, 1073, 86, 172, 1420, 411, 1515,
- nil, 1481, 1496, 456, nil, 1776, -4, 356, 443, nil,
- 145, nil, nil, 1694, nil, 387, nil, 362, 129, nil,
- nil, nil, nil, nil, nil, 380, nil, nil, nil, 1716,
- nil, nil, nil, 1634, nil, nil, nil, 376, 383, nil,
- 385, 392, 393, nil, nil, nil, nil, 410, nil, nil,
- nil, 153, nil, 183, nil, nil, nil, nil, nil, 51,
- nil, 128, 430, nil, nil, 110, 435, nil, nil, nil,
- nil, nil, 1735, nil, nil, nil, nil, 439, 59, 445,
- nil, nil, 1571, nil, 1653, nil, nil, nil, 1593, nil,
- 1675, nil, nil, nil ]
+ 1674, 54, 417, 341, 399, 434, 455, nil, 262, nil,
+ nil, 112, 404, 402, nil, nil, nil, 395, 16, nil,
+ 1693, nil, nil, 268, nil, nil, 293, -1, nil, 341,
+ nil, 425, 381, 181, nil, nil, nil, 342, nil, nil,
+ nil, nil, 246, nil, nil, 445, 200, 501, 159, 557,
+ 305, 575, 283, 321, nil, nil, -6, nil, nil, nil,
+ nil, nil, nil, nil, 291, 265, 273, nil, nil, nil,
+ 703, 750, nil, nil, 269, 242, nil, 212, 840, nil,
+ 208, 2, 68, 64, nil, 37, nil, 186, nil, 275,
+ 1039, 1261, nil, nil, 279, 1125, nil, nil, nil, 1151,
+ 1176, 287, 289, 161, nil, 295, 315, 317, 323, nil,
+ 343, 116, 652, 315, 78, 350, 361, nil, nil, 374,
+ nil, 379, 81, nil, nil, nil, nil, 382, nil, 1444,
+ nil, 1383, 1337, 391, 376, nil, 394, nil, nil, nil,
+ 389, 408, 440, 314, 38, nil, 447, 436, nil, nil,
+ nil, nil, nil, nil, -8, 420, nil, 37, 0, 418,
+ nil, 80, nil, 87, -4, nil, 287, 351, nil, 302,
+ 376, nil, 419, 475, 531, 26, 582, 633, 801, 927,
+ 1228, 983, 1069, 256, 1095, 957, 1202, 243, 1532, 1013,
+ 1276, nil, 115, nil, 21, nil, nil, 186, nil, nil,
+ 131, 254, nil, 74, nil, nil, 1, nil, nil, nil,
+ nil, 360, 249, 10, -13, 909, 85, 1655, 80, 82,
+ 106, 112, nil, nil, 181, 194, nil, 194, 879, 170,
+ 215, 865, 192, 826, 199, 235, nil, nil, 1551, 8,
+ 775, nil, 724, nil, nil, nil, nil, nil, nil, 270,
+ nil, nil, 259, nil, 677, nil, nil, nil, nil, 659,
+ nil, 59, 118, 116, 223, nil, 1716, 1707, 1725, 1459,
+ 1398, 1493, 49, nil, 1322, 1478, 1425, nil, 1712, 343,
+ 159, 307, nil, 353, nil, 8, nil, 394, 365, nil,
+ 110, nil, nil, -9, 322, 203, nil, 383, nil, 224,
+ nil, -8, nil, nil, 400, nil, 217, 210, nil, 109,
+ nil, 1573, nil, nil, nil, nil, nil, nil, nil, nil,
+ 406, nil, nil, nil, 411, nil, nil, nil, nil, 152,
+ nil, 135, nil, nil, 135, 133, nil, 427, nil, nil,
+ nil, nil, 427, nil, nil, nil, 415, 417, nil, 418,
+ 421, 422, nil, nil, nil, nil, 90, 442, nil, nil,
+ nil, nil, 1633, nil, nil, nil, nil, 446, 33, 451,
+ nil, nil, 1614, nil, nil, 1592, nil, nil, nil, 463,
+ nil, 464, nil, nil, nil ]
racc_action_default = [
- -196, -233, -233, -50, -233, -8, -9, -233, -233, -22,
- -10, -187, -188, -11, -185, -12, -233, -233, -13, -1,
- -14, -2, -233, -186, -15, -3, -233, -16, -5, -233,
- -233, -17, -6, -233, -18, -7, -196, -188, -186, -233,
- -51, -26, -27, -233, -24, -25, -233, -233, -233, -85,
- -92, -196, -233, -195, -193, -196, -189, -191, -192, -221,
- -194, -4, -196, -233, -85, -196, -53, -231, -42, -174,
- -43, -213, -117, -33, -233, -233, -44, -31, -74, -32,
- -233, -36, -233, -122, -37, -233, -73, -38, -172, -72,
- -39, -40, -173, -41, -233, -103, -111, -233, -132, -112,
- -233, -104, -233, -108, -110, -105, -233, -114, -106, -113,
- -109, -233, -125, -107, -233, -233, -49, -175, -176, -178,
- -233, -233, -197, -198, -83, -19, -22, -186, -21, -23,
- -82, -84, -233, -75, -86, -81, -70, -74, -76, -219,
- -79, -68, -77, -73, -233, -171, -170, -80, -78, -90,
- -91, -93, -233, -219, -196, 384, -233, -233, -233, -207,
- -233, -57, -213, -196, -59, -233, -66, -65, -56, -73,
- -95, -233, -219, -233, -233, -92, -233, -30, -233, -118,
- -233, -233, -233, -233, -233, -142, -233, -149, -233, -216,
- -229, -225, -233, -228, -224, -233, -233, -233, -233, -233,
- -233, -233, -233, -233, -233, -233, -233, -233, -233, -233,
- -233, -233, -233, -233, -233, -233, -20, -233, -206, -233,
- -204, -233, -201, -230, -233, -71, -220, -233, -233, -85,
- -233, -220, -233, -233, -233, -209, -190, -233, -208, -233,
- -54, -62, -61, -233, -233, -233, -217, -218, -233, -124,
- -233, -55, -219, -233, -233, -28, -233, -120, -119, -35,
- -34, -168, -166, -233, -169, -160, -167, -161, -73, -233,
- -123, -116, -233, -152, -218, -214, -233, -233, -222, -137,
- -139, -138, -133, -140, -144, -141, -146, -151, -148, -145,
- -134, -150, -147, -143, -135, -233, -128, -136, -233, -154,
- -233, -158, -177, -233, -180, -233, -199, -233, -233, -200,
- -45, -69, -87, -46, -88, -219, -89, -94, -48, -233,
- -211, -210, -212, -233, -184, -58, -60, -97, -98, -63,
- -102, -99, -100, -101, -64, -96, -47, -233, -232, -29,
- -121, -233, -163, -219, -115, -215, -227, -226, -223, -128,
- -127, -233, -233, -155, -153, -233, -233, -179, -205, -203,
- -202, -67, -233, -182, -183, -52, -165, -218, -233, -233,
- -126, -129, -233, -159, -233, -181, -164, -162, -233, -131,
- -233, -157, -130, -156 ]
+ -197, -234, -51, -19, -8, -234, -234, -9, -234, -10,
+ -188, -189, -234, -23, -11, -186, -12, -234, -234, -13,
+ -1, -14, -2, -187, -15, -3, -234, -234, -16, -234,
+ -17, -6, -234, -234, -18, -7, -189, -197, -187, -52,
+ -27, -28, -234, -25, -26, -234, -234, -234, -234, -234,
+ -197, -86, -93, -234, -196, -194, -197, -190, -192, -193,
+ -222, -195, -4, -42, -232, -43, -214, -175, -118, -44,
+ -234, -234, -45, -34, -75, -32, -33, -234, -234, -123,
+ -37, -74, -38, -234, -73, -39, -173, -40, -174, -41,
+ -234, -234, -126, -108, -104, -234, -112, -133, -113, -234,
+ -234, -105, -109, -234, -111, -106, -115, -107, -114, -110,
+ -54, -197, -234, -86, -197, -234, -179, -176, -177, -234,
+ -50, -234, -198, -199, -24, -21, -23, -187, -22, -84,
+ -20, -83, -85, -234, -197, -79, -76, -87, -82, -75,
+ -71, -77, -220, -80, -74, -69, -78, -234, -172, -171,
+ -81, -91, -92, -94, -234, -220, 385, -234, -234, -234,
+ -208, -234, -31, -234, -234, -119, -234, -234, -96, -234,
+ -234, -143, -234, -234, -234, -234, -234, -234, -234, -234,
+ -234, -234, -234, -234, -234, -234, -234, -234, -234, -234,
+ -234, -150, -234, -217, -234, -230, -226, -234, -229, -225,
+ -93, -234, -214, -197, -58, -60, -234, -67, -57, -74,
+ -66, -234, -220, -234, -234, -234, -234, -234, -207, -205,
+ -234, -234, -202, -231, -234, -234, -210, -234, -72, -221,
+ -234, -234, -86, -234, -221, -234, -191, -209, -234, -234,
+ -234, -29, -234, -121, -120, -36, -35, -169, -167, -234,
+ -170, -161, -74, -168, -234, -162, -218, -219, -124, -234,
+ -117, -234, -138, -140, -139, -134, -141, -145, -142, -147,
+ -152, -149, -146, -135, -151, -148, -144, -136, -5, -234,
+ -129, -137, -153, -219, -215, -234, -223, -234, -220, -55,
+ -234, -63, -62, -234, -234, -234, -125, -234, -56, -234,
+ -155, -234, -159, -178, -234, -181, -234, -234, -200, -234,
+ -201, -234, -212, -213, -211, -46, -70, -88, -47, -89,
+ -220, -90, -95, -49, -234, -185, -233, -30, -122, -234,
+ -164, -220, -97, -116, -129, -234, -128, -234, -216, -227,
+ -224, -228, -234, -59, -61, -102, -98, -99, -64, -103,
+ -100, -101, -65, -48, -156, -154, -234, -234, -180, -206,
+ -204, -203, -234, -183, -68, -184, -166, -219, -234, -234,
+ -127, -130, -234, -53, -160, -234, -182, -165, -163, -234,
+ -132, -234, -158, -131, -157 ]
racc_goto_table = [
- 22, 9, 68, 112, 53, 118, 61, 36, 91, 222,
- 19, 267, 70, 93, 2, 227, 139, 191, 51, 22,
- 9, 179, 77, 56, 73, 149, 21, 141, 133, 232,
- 115, 172, 153, 2, 146, 263, 125, 116, 135, 148,
- 147, 299, 129, 22, 126, 260, 160, 350, 250, 174,
- 128, 171, 43, 68, 121, 329, 334, 298, 368, 91,
- 258, 265, 123, 70, 93, 317, 343, 301, 136, 154,
- 183, 119, 224, 178, 233, 73, 55, 123, 157, 66,
- 238, 159, 120, 219, 221, 190, 325, 321, 195, 16,
- 188, nil, nil, nil, nil, nil, nil, nil, 342, nil,
- 370, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, 216, nil, nil, nil, nil, 260, 129,
- 22, 126, 263, nil, nil, 353, nil, 128, 337, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, 81,
- nil, nil, nil, 53, nil, 53, nil, 243, nil, nil,
- 149, 301, nil, nil, nil, nil, nil, 252, nil, nil,
- 68, 261, 236, 68, nil, 138, 91, 146, nil, 91,
- 70, 93, nil, 70, 93, nil, nil, nil, 166, nil,
- 235, 166, 259, 272, nil, 73, nil, 302, 347, nil,
- 81, 361, nil, 261, 290, 360, 315, 376, 294, 146,
- nil, 312, 340, 311, 133, nil, 149, nil, 373, nil,
- 146, nil, 22, 9, 135, 148, 147, 22, 9, 369,
- nil, 263, 295, 327, 327, nil, 2, 303, nil, 146,
- 146, 2, nil, 68, 333, 333, nil, 22, 9, 91,
- 320, 88, nil, 70, 93, nil, nil, 323, 261, nil,
- nil, 2, nil, nil, 146, 259, 190, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, 88, nil, nil,
- nil, nil, nil, nil, nil, 87, nil, 261, nil, 166,
- nil, nil, 61, 146, nil, nil, nil, nil, nil, nil,
- 61, nil, 88, nil, nil, 22, 9, 81, 262, nil,
- 81, 142, nil, 22, 9, nil, nil, nil, nil, 2,
- 61, nil, nil, nil, nil, nil, nil, 2, nil, 22,
- 9, nil, nil, 22, 9, nil, 87, nil, 371, 362,
- 262, nil, nil, 2, 261, nil, nil, 2, nil, nil,
- 146, 138, nil, nil, nil, nil, nil, 261, nil, 61,
- nil, nil, nil, 146, nil, 166, nil, nil, nil, nil,
- 328, 328, 22, 9, 114, 61, nil, 61, nil, 84,
- 81, nil, 22, 9, 22, 9, 2, 90, 22, 9,
- 22, 9, 378, 132, 380, 262, 2, nil, 2, nil,
- nil, nil, 2, nil, 2, 140, nil, nil, 170, 88,
- 88, nil, 88, 145, nil, nil, nil, nil, 167, nil,
- nil, 167, nil, nil, 262, nil, nil, 170, nil, nil,
- 84, nil, nil, nil, nil, nil, nil, nil, 90, nil,
- nil, nil, 88, 87, 266, nil, 87, 170, nil, nil,
- nil, nil, nil, 88, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, 88, 88, nil, nil, 266, nil, nil, nil,
- nil, 262, 88, nil, nil, nil, nil, 142, nil, nil,
- nil, nil, nil, nil, 262, nil, nil, 88, nil, nil,
- nil, nil, nil, nil, nil, nil, 331, 331, nil, nil,
- nil, nil, nil, nil, nil, nil, 87, nil, nil, 167,
- nil, 253, nil, nil, nil, nil, 88, nil, nil, nil,
- nil, 266, nil, nil, nil, nil, nil, 84, 264, nil,
- 84, nil, nil, nil, 282, 90, 145, nil, 90, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- 266, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- 264, nil, nil, 314, nil, 316, nil, 124, 145, nil,
- nil, 140, nil, 88, 130, 131, nil, nil, nil, 145,
- nil, nil, nil, 335, nil, 167, 88, nil, nil, nil,
- 330, 330, nil, nil, nil, nil, nil, nil, 332, 332,
- 84, nil, nil, 180, nil, nil, nil, 266, 90, nil,
- nil, 346, nil, nil, nil, 264, nil, nil, nil, nil,
- 266, nil, 185, 145, nil, 186, nil, nil, 187, nil,
+ 27, 13, 5, 37, 62, 255, 249, 20, 118, 196,
+ 92, 89, 142, 50, 155, 300, 69, 63, 222, 336,
+ 27, 13, 5, 165, 73, 75, 57, 279, 348, 352,
+ 246, 151, 145, 119, 343, 150, 121, 230, 65, 149,
+ 299, 22, 27, 126, 138, 135, 27, 126, 201, 134,
+ 235, 214, 120, 87, 302, 86, 304, 244, 89, 42,
+ 169, 128, 46, 69, 63, 128, 136, 251, 368, 331,
+ 322, 73, 163, 370, 212, 125, 124, 324, 123, 130,
+ 124, 148, 192, 86, 116, 65, 140, 224, 56, 159,
+ 227, 123, 330, 249, 211, 237, 220, 160, 221, 354,
+ 87, 110, 86, 115, 246, 314, 194, 297, 17, nil,
+ nil, nil, nil, nil, nil, nil, nil, nil, 195, nil,
+ nil, nil, nil, 133, nil, nil, nil, nil, nil, nil,
+ nil, nil, nil, nil, 54, nil, nil, nil, 302, nil,
+ 293, nil, nil, nil, nil, nil, nil, nil, nil, nil,
+ nil, nil, 168, nil, 89, 149, nil, nil, 89, 69,
+ 63, nil, 288, 69, 63, 236, nil, 245, nil, nil,
+ nil, 73, 261, 82, 168, 226, nil, nil, nil, 151,
+ nil, 65, 247, 342, nil, 65, 168, nil, 27, 13,
+ 5, 339, 303, 320, 328, 374, 87, 148, 86, 86,
+ 87, 143, 86, 149, 80, 361, 377, 249, 317, 316,
+ nil, 379, 150, 151, 381, 364, 149, 27, 13, 5,
+ 82, 138, 135, nil, nil, nil, 369, 312, 89, nil,
+ 247, nil, 141, 69, 63, 239, nil, nil, 27, 13,
+ 5, 245, 149, 136, nil, 148, nil, 86, nil, 265,
+ nil, 80, nil, nil, nil, 65, nil, nil, 148, nil,
+ 86, 210, 62, nil, 210, nil, nil, nil, 85, 247,
+ 87, nil, 86, 54, 54, nil, nil, nil, 27, 13,
+ 5, nil, 149, 149, 148, nil, 86, 149, 345, 345,
+ nil, nil, 207, nil, nil, 207, 146, nil, nil, 273,
+ 195, nil, nil, 277, nil, 319, nil, 321, nil, 346,
+ 346, 27, 13, 5, 247, 85, 82, 250, 362, 371,
+ 82, nil, nil, nil, 351, 351, 86, 86, nil, 148,
+ nil, 86, nil, 332, nil, nil, nil, nil, nil, nil,
+ nil, nil, nil, nil, 149, nil, 62, 80, 248, nil,
+ nil, 80, nil, 210, nil, nil, 149, nil, nil, nil,
+ nil, 341, 27, 13, 5, 250, nil, nil, nil, nil,
+ nil, 247, 27, 13, 5, 27, 13, 5, 143, nil,
+ 359, 360, nil, 247, 207, nil, 148, nil, 86, nil,
+ 82, nil, 129, nil, 131, 132, 248, nil, 148, nil,
+ 86, nil, nil, 366, 250, nil, nil, nil, nil, 141,
+ nil, 85, 253, nil, nil, 85, nil, nil, 164, nil,
+ nil, 80, nil, nil, nil, nil, nil, nil, nil, nil,
+ nil, nil, nil, nil, nil, 248, nil, 171, nil, nil,
+ 210, nil, 190, nil, 349, 349, 191, nil, nil, 250,
nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- 358, nil, 359, nil, 264, nil, nil, nil, nil, nil,
- nil, nil, 145, nil, nil, nil, nil, nil, nil, nil,
+ 253, nil, nil, nil, nil, nil, nil, nil, nil, nil,
+ nil, 207, nil, 146, nil, 347, 347, nil, nil, nil,
+ 248, nil, nil, nil, nil, 85, nil, nil, nil, nil,
+ nil, nil, nil, nil, nil, nil, nil, nil, nil, 253,
+ nil, nil, nil, nil, nil, nil, 250, nil, nil, nil,
+ nil, nil, nil, nil, nil, nil, nil, nil, 250, 262,
+ 263, 264, nil, 266, 267, 268, 269, 270, 271, 272,
+ nil, 274, 275, 276, nil, nil, 281, 248, nil, 350,
+ 350, nil, nil, nil, 253, nil, nil, nil, nil, 248,
nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, 366, nil, nil, nil,
nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, 264, nil, nil, nil, nil, nil, nil, nil, 145,
- nil, nil, nil, nil, 264, nil, nil, nil, nil, nil,
- nil, nil, 145, nil, 279, 280, 281, nil, 283, 284,
- 285, 286, 287, 288, 289, nil, 291, 292, 293, nil,
- nil, 297, nil, nil, nil, nil, nil, nil, nil, nil,
+ nil, nil, nil, nil, nil, nil, nil, nil, nil, 164,
nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, 180 ]
+ nil, 253, nil, nil, nil, nil, nil, nil, nil, nil,
+ nil, nil, nil, 253 ]
racc_goto_check = [
- 37, 21, 30, 62, 64, 72, 4, 32, 28, 82,
- 2, 70, 31, 29, 52, 36, 35, 85, 32, 37,
- 21, 60, 22, 78, 21, 53, 3, 47, 30, 36,
- 37, 35, 38, 52, 28, 68, 19, 5, 31, 29,
- 50, 66, 7, 37, 21, 23, 41, 63, 36, 41,
- 5, 57, 20, 30, 74, 46, 46, 65, 58, 28,
- 61, 69, 3, 31, 29, 56, 71, 68, 33, 74,
- 57, 73, 34, 22, 75, 21, 76, 3, 77, 40,
- 79, 3, 20, 80, 81, 30, 42, 83, 84, 1,
- 57, nil, nil, nil, nil, nil, nil, nil, 70, nil,
- 63, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, 19, nil, nil, nil, nil, 23, 7,
- 37, 21, 68, nil, nil, 66, nil, 5, 36, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, 24,
- nil, nil, nil, 64, nil, 64, nil, 41, nil, nil,
- 53, 68, nil, nil, nil, nil, nil, 38, nil, nil,
- 30, 30, 78, 30, nil, 24, 28, 28, nil, 28,
- 31, 29, nil, 31, 29, nil, nil, nil, 24, nil,
- 3, 24, 21, 22, nil, 21, nil, 72, 85, nil,
- 24, 36, nil, 30, 64, 82, 35, 70, 64, 28,
- nil, 53, 60, 47, 30, nil, 53, nil, 68, nil,
- 28, nil, 37, 21, 31, 29, 50, 37, 21, 36,
- nil, 68, 2, 30, 30, nil, 52, 2, nil, 28,
- 28, 52, nil, 30, 29, 29, nil, 37, 21, 28,
- 32, 49, nil, 31, 29, nil, nil, 2, 30, nil,
- nil, 52, nil, nil, 28, 21, 30, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, 49, nil, nil,
- nil, nil, nil, nil, nil, 26, nil, 30, nil, 24,
- nil, nil, 4, 28, nil, nil, nil, nil, nil, nil,
- 4, nil, 49, nil, nil, 37, 21, 24, 24, nil,
- 24, 26, nil, 37, 21, nil, nil, nil, nil, 52,
- 4, nil, nil, nil, nil, nil, nil, 52, nil, 37,
- 21, nil, nil, 37, 21, nil, 26, nil, 62, 2,
- 24, nil, nil, 52, 30, nil, nil, 52, nil, nil,
- 28, 24, nil, nil, nil, nil, nil, 30, nil, 4,
- nil, nil, nil, 28, nil, 24, nil, nil, nil, nil,
- 24, 24, 37, 21, 54, 4, nil, 4, nil, 25,
- 24, nil, 37, 21, 37, 21, 52, 27, 37, 21,
- 37, 21, 2, 54, 2, 24, 52, nil, 52, nil,
- nil, nil, 52, nil, 52, 25, nil, nil, 54, 49,
- 49, nil, 49, 27, nil, nil, nil, nil, 25, nil,
- nil, 25, nil, nil, 24, nil, nil, 54, nil, nil,
- 25, nil, nil, nil, nil, nil, nil, nil, 27, nil,
- nil, nil, 49, 26, 26, nil, 26, 54, nil, nil,
- nil, nil, nil, 49, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, 49, 49, nil, nil, 26, nil, nil, nil,
- nil, 24, 49, nil, nil, nil, nil, 26, nil, nil,
- nil, nil, nil, nil, 24, nil, nil, 49, nil, nil,
- nil, nil, nil, nil, nil, nil, 26, 26, nil, nil,
- nil, nil, nil, nil, nil, nil, 26, nil, nil, 25,
- nil, 54, nil, nil, nil, nil, 49, nil, nil, nil,
- nil, 26, nil, nil, nil, nil, nil, 25, 25, nil,
- 25, nil, nil, nil, 54, 27, 27, nil, 27, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- 26, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- 25, nil, nil, 54, nil, 54, nil, 51, 27, nil,
- nil, 25, nil, 49, 51, 51, nil, nil, nil, 27,
- nil, nil, nil, 54, nil, 25, 49, nil, nil, nil,
- 25, 25, nil, nil, nil, nil, nil, nil, 27, 27,
- 25, nil, nil, 51, nil, nil, nil, 26, 27, nil,
- nil, 54, nil, nil, nil, 25, nil, nil, nil, nil,
- 26, nil, 51, 27, nil, 51, nil, nil, 51, nil,
+ 38, 22, 53, 33, 4, 71, 69, 2, 73, 86,
+ 63, 29, 36, 33, 39, 67, 32, 30, 83, 64,
+ 38, 22, 53, 61, 22, 23, 79, 5, 47, 47,
+ 24, 54, 48, 38, 43, 51, 75, 37, 31, 29,
+ 66, 3, 38, 22, 32, 30, 38, 22, 42, 75,
+ 37, 42, 6, 28, 69, 50, 5, 62, 29, 21,
+ 58, 6, 21, 32, 30, 6, 31, 70, 59, 72,
+ 57, 22, 23, 64, 36, 20, 8, 5, 3, 20,
+ 8, 28, 58, 50, 74, 31, 34, 76, 77, 78,
+ 35, 3, 71, 69, 58, 80, 81, 3, 82, 67,
+ 28, 41, 50, 55, 24, 84, 85, 37, 1, nil,
+ nil, nil, nil, nil, nil, nil, nil, nil, 31, nil,
+ nil, nil, nil, 55, nil, nil, nil, nil, nil, nil,
+ nil, nil, nil, nil, 65, nil, nil, nil, 69, nil,
+ 42, nil, nil, nil, nil, nil, nil, nil, nil, nil,
+ nil, nil, 55, nil, 29, 29, nil, nil, 29, 32,
+ 30, nil, 39, 32, 30, 79, nil, 22, nil, nil,
+ nil, 22, 23, 26, 55, 3, nil, nil, nil, 54,
+ nil, 31, 31, 37, nil, 31, 55, nil, 38, 22,
+ 53, 86, 73, 36, 61, 69, 28, 28, 50, 50,
+ 28, 26, 50, 29, 25, 83, 71, 69, 54, 48,
+ nil, 5, 51, 54, 5, 37, 29, 38, 22, 53,
+ 26, 32, 30, nil, nil, nil, 37, 33, 29, nil,
+ 31, nil, 25, 32, 30, 55, nil, nil, 38, 22,
+ 53, 22, 29, 31, nil, 28, nil, 50, nil, 55,
+ nil, 25, nil, nil, nil, 31, nil, nil, 28, nil,
+ 50, 26, 4, nil, 26, nil, nil, nil, 27, 31,
+ 28, nil, 50, 65, 65, nil, nil, nil, 38, 22,
+ 53, nil, 29, 29, 28, nil, 50, 29, 30, 30,
+ nil, nil, 25, nil, nil, 25, 27, nil, nil, 65,
+ 31, nil, nil, 65, nil, 55, nil, 55, nil, 31,
+ 31, 38, 22, 53, 31, 27, 26, 26, 2, 63,
+ 26, nil, nil, nil, 28, 28, 50, 50, nil, 28,
+ nil, 50, nil, 55, nil, nil, nil, nil, nil, nil,
+ nil, nil, nil, nil, 29, nil, 4, 25, 25, nil,
+ nil, 25, nil, 26, nil, nil, 29, nil, nil, nil,
+ nil, 55, 38, 22, 53, 26, nil, nil, nil, nil,
+ nil, 31, 38, 22, 53, 38, 22, 53, 26, nil,
+ 55, 55, nil, 31, 25, nil, 28, nil, 50, nil,
+ 26, nil, 52, nil, 52, 52, 25, nil, 28, nil,
+ 50, nil, nil, 55, 26, nil, nil, nil, nil, 25,
+ nil, 27, 27, nil, nil, 27, nil, nil, 52, nil,
+ nil, 25, nil, nil, nil, nil, nil, nil, nil, nil,
+ nil, nil, nil, nil, nil, 25, nil, 52, nil, nil,
+ 26, nil, 52, nil, 26, 26, 52, nil, nil, 26,
nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- 54, nil, 54, nil, 25, nil, nil, nil, nil, nil,
- nil, nil, 27, nil, nil, nil, nil, nil, nil, nil,
+ 27, nil, nil, nil, nil, nil, nil, nil, nil, nil,
+ nil, 25, nil, 27, nil, 25, 25, nil, nil, nil,
+ 25, nil, nil, nil, nil, 27, nil, nil, nil, nil,
+ nil, nil, nil, nil, nil, nil, nil, nil, nil, 27,
+ nil, nil, nil, nil, nil, nil, 26, nil, nil, nil,
+ nil, nil, nil, nil, nil, nil, nil, nil, 26, 52,
+ 52, 52, nil, 52, 52, 52, 52, 52, 52, 52,
+ nil, 52, 52, 52, nil, nil, 52, 25, nil, 27,
+ 27, nil, nil, nil, 27, nil, nil, nil, nil, 25,
nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, 54, nil, nil, nil,
nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, 25, nil, nil, nil, nil, nil, nil, nil, 27,
- nil, nil, nil, nil, 25, nil, nil, nil, nil, nil,
- nil, nil, 27, nil, 51, 51, 51, nil, 51, 51,
- 51, 51, 51, 51, 51, nil, 51, 51, 51, nil,
- nil, 51, nil, nil, nil, nil, nil, nil, nil, nil,
+ nil, nil, nil, nil, nil, nil, nil, nil, nil, 52,
nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, 51 ]
+ nil, 27, nil, nil, nil, nil, nil, nil, nil, nil,
+ nil, nil, nil, 27 ]
racc_goto_pointer = [
- nil, 89, 10, 26, -13, 7, nil, -1, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, -7,
- 48, 1, -1, -136, 116, 346, 252, 354, -15, -10,
- -21, -11, 6, 19, -64, -33, -124, 0, -18, nil,
- 57, -16, -153, nil, nil, nil, -189, -22, nil, 218,
- -9, 528, 14, -25, 335, nil, -166, -12, -285, nil,
- -54, -120, -23, -249, -13, -157, -173, nil, -147, -121,
- -171, -203, -28, 38, 18, -80, 59, 23, 6, -78,
- -39, -38, -113, -147, -18, -89, nil ]
+ nil, 108, 7, 41, -16, -161, 19, nil, 34, nil,
+ nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
+ 33, 56, 1, 2, -136, 181, 150, 245, 30, -12,
+ -6, 15, -7, 2, 35, -50, -39, -105, 0, -38,
+ nil, 74, -63, -256, nil, nil, nil, -266, -19, nil,
+ 32, -16, 347, 2, -21, 74, nil, -164, -18, -263,
+ nil, -48, -107, -16, -261, 116, -175, -200, nil, -161,
+ -100, -162, -185, -24, 52, -1, -47, 70, 33, 8,
+ -63, -26, -24, -104, -120, 3, -94, nil ]
racc_goto_default = [
- nil, nil, nil, 168, 25, 28, 32, 35, 5, 6,
- 10, 13, 15, 18, 20, 24, 27, 31, 34, 4,
- nil, 99, nil, 79, 101, 103, 105, 108, 109, 113,
- 95, 96, 8, nil, nil, nil, nil, 85, nil, 30,
- nil, nil, 161, 239, 164, 165, nil, nil, 144, 107,
- 110, 111, 67, 134, 98, 150, 151, nil, 248, 104,
- nil, nil, nil, nil, 69, nil, nil, 300, 80, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, 57,
- nil, nil, nil, nil, nil, nil, 192 ]
+ nil, nil, 278, 208, 25, nil, 31, 35, 4, 7,
+ 9, 14, 16, 19, 21, 24, 28, 30, 34, 3,
+ 6, nil, 98, nil, 76, 101, 102, 105, 107, 108,
+ 93, 94, 96, 12, nil, nil, nil, nil, 83, nil,
+ 33, nil, nil, 204, 290, 205, 206, nil, nil, 147,
+ 106, 109, 91, 64, 137, 97, 152, 153, nil, 259,
+ 104, nil, nil, nil, nil, 67, nil, nil, 301, 77,
+ nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
+ 58, nil, nil, nil, nil, nil, nil, 197 ]
racc_token_table = {
false => 0,
@@ -1083,9 +1040,10 @@ Racc_token_to_s_table = [
'IN',
'$start',
'program',
-'statements',
+'statements_and_declarations',
'nil',
-'statement',
+'statement_or_declaration',
+'statements',
'resource',
'virtualresource',
'collection',
@@ -1175,48 +1133,39 @@ Racc_debug_parser = false
# reduce 0 omitted
-module_eval <<'.,.,', 'grammar.ra', 46
- def _reduce_1( val, _values, result )
- if val[0]
- # Make sure we always return an array.
- if val[0].is_a?(AST::ASTArray)
- if val[0].children.empty?
- result = nil
- else
- result = val[0]
- end
- else
- result = aryfy(val[0])
- end
- else
- result = nil
- end
- result
- end
-.,.,
+ # reduce 1 omitted
# reduce 2 omitted
- # reduce 3 omitted
+module_eval <<'.,.,', 'grammar.ra', 36
+ def _reduce_3( val, _values, result )
+ result = ast AST::ASTArray, :children => (val[0] ? [val[0]] : [])
+ result
+ end
+.,.,
-module_eval <<'.,.,', 'grammar.ra', 62
+module_eval <<'.,.,', 'grammar.ra', 42
def _reduce_4( val, _values, result )
- if val[0] and val[1]
- if val[0].instance_of?(AST::ASTArray)
- val[0].push(val[1])
- result = val[0]
- else
- result = ast AST::ASTArray, :children => [val[0],val[1]]
- end
- elsif obj = (val[0] || val[1])
- result = obj
- else result = nil
+ if val[1]
+ val[0].push(val[1])
end
+ result = val[0]
result
end
.,.,
- # reduce 5 omitted
+module_eval <<'.,.,', 'grammar.ra', 54
+ def _reduce_5( val, _values, result )
+ val[0].each do |stmt|
+ if stmt.is_a?(AST::TopLevelConstruct)
+ error "Classes, definitions, and nodes may only appear at toplevel or inside other classes", \
+ :line => stmt.context[:line], :file => stmt.context[:file]
+ end
+ end
+ result = val[0]
+ result
+ end
+.,.,
# reduce 6 omitted
@@ -1244,22 +1193,22 @@ module_eval <<'.,.,', 'grammar.ra', 62
# reduce 18 omitted
-module_eval <<'.,.,', 'grammar.ra', 82
- def _reduce_19( val, _values, result )
- result = AST::Relationship.new(val[0], val[2], val[1][:value], ast_context)
+ # reduce 19 omitted
+
+module_eval <<'.,.,', 'grammar.ra', 74
+ def _reduce_20( val, _values, result )
+ result = AST::Relationship.new(val[0], val[2], val[1][:value], ast_context)
result
end
.,.,
-module_eval <<'.,.,', 'grammar.ra', 85
- def _reduce_20( val, _values, result )
+module_eval <<'.,.,', 'grammar.ra', 77
+ def _reduce_21( val, _values, result )
result = AST::Relationship.new(val[0], val[2], val[1][:value], ast_context)
result
end
.,.,
- # reduce 21 omitted
-
# reduce 22 omitted
# reduce 23 omitted
@@ -1272,80 +1221,81 @@ module_eval <<'.,.,', 'grammar.ra', 85
# reduce 27 omitted
-module_eval <<'.,.,', 'grammar.ra', 98
- def _reduce_28( val, _values, result )
- args = aryfy(val[2])
- result = ast AST::Function,
- :name => val[0][:value],
- :line => val[0][:line],
- :arguments => args,
- :ftype => :statement
- result
- end
-.,.,
+ # reduce 28 omitted
-module_eval <<'.,.,', 'grammar.ra', 106
+module_eval <<'.,.,', 'grammar.ra', 89
def _reduce_29( val, _values, result )
- args = aryfy(val[2])
- result = ast AST::Function,
- :name => val[0][:value],
- :line => val[0][:line],
- :arguments => args,
- :ftype => :statement
+ result = ast AST::Function,
+ :name => val[0][:value],
+ :line => val[0][:line],
+ :arguments => val[2],
+ :ftype => :statement
result
end
.,.,
-module_eval <<'.,.,', 'grammar.ra', 112
+module_eval <<'.,.,', 'grammar.ra', 96
def _reduce_30( val, _values, result )
- result = ast AST::Function,
- :name => val[0][:value],
- :line => val[0][:line],
- :arguments => AST::ASTArray.new({}),
- :ftype => :statement
+ result = ast AST::Function,
+ :name => val[0][:value],
+ :line => val[0][:line],
+ :arguments => val[2],
+ :ftype => :statement
result
end
.,.,
-module_eval <<'.,.,', 'grammar.ra', 120
+module_eval <<'.,.,', 'grammar.ra', 102
def _reduce_31( val, _values, result )
- args = aryfy(val[1])
- result = ast AST::Function,
- :name => val[0][:value],
- :line => val[0][:line],
- :arguments => args,
- :ftype => :statement
+ result = ast AST::Function,
+ :name => val[0][:value],
+ :line => val[0][:line],
+ :arguments => AST::ASTArray.new({}),
+ :ftype => :statement
result
end
.,.,
- # reduce 32 omitted
+module_eval <<'.,.,', 'grammar.ra', 109
+ def _reduce_32( val, _values, result )
+ result = ast AST::Function,
+ :name => val[0][:value],
+ :line => val[0][:line],
+ :arguments => val[1],
+ :ftype => :statement
+ result
+ end
+.,.,
- # reduce 33 omitted
+module_eval <<'.,.,', 'grammar.ra', 110
+ def _reduce_33( val, _values, result )
+ result = aryfy(val[0])
+ result
+ end
+.,.,
-module_eval <<'.,.,', 'grammar.ra', 128
+module_eval <<'.,.,', 'grammar.ra', 111
def _reduce_34( val, _values, result )
- result = aryfy(val[0], val[2])
- result.line = @lexer.line
- result.file = @lexer.file
+ result = aryfy(val[0])
result
end
.,.,
-module_eval <<'.,.,', 'grammar.ra', 137
+module_eval <<'.,.,', 'grammar.ra', 116
def _reduce_35( val, _values, result )
- unless val[0].is_a?(AST::ASTArray)
- val[0] = aryfy(val[0])
- end
-
val[0].push(val[2])
-
result = val[0]
result
end
.,.,
- # reduce 36 omitted
+module_eval <<'.,.,', 'grammar.ra', 120
+ def _reduce_36( val, _values, result )
+ val[0].push(val[2])
+ result = val[0]
+ result
+ end
+.,.,
# reduce 37 omitted
@@ -1361,223 +1311,198 @@ module_eval <<'.,.,', 'grammar.ra', 137
# reduce 43 omitted
-module_eval <<'.,.,', 'grammar.ra', 151
- def _reduce_44( val, _values, result )
- result = ast AST::Name, :value => val[0][:value]
- result
- end
-.,.,
+ # reduce 44 omitted
-module_eval <<'.,.,', 'grammar.ra', 173
+module_eval <<'.,.,', 'grammar.ra', 134
def _reduce_45( val, _values, result )
- @lexer.commentpop
- array = val[2]
- if array.instance_of?(AST::ResourceInstance)
- array = [array]
- end
- result = ast AST::ASTArray
-
- # this iterates across each specified resourceinstance
- array.each { |instance|
- unless instance.instance_of?(AST::ResourceInstance)
- raise Puppet::Dev, "Got something that isn't an instance"
- end
- # now, i need to somehow differentiate between those things with
- # arrays in their names, and normal things
- result.push ast(AST::Resource,
- :type => val[0],
- :title => instance[0],
- :parameters => instance[1])
- }
+ result = ast AST::Name, :value => val[0][:value]
result
end
.,.,
-module_eval <<'.,.,', 'grammar.ra', 176
+module_eval <<'.,.,', 'grammar.ra', 139
def _reduce_46( val, _values, result )
- # This is a deprecated syntax.
- error "All resource specifications require names"
+ @lexer.commentpop
+ result = ast(AST::Resource, :type => val[0], :instances => val[2])
result
end
.,.,
-module_eval <<'.,.,', 'grammar.ra', 180
+module_eval <<'.,.,', 'grammar.ra', 142
def _reduce_47( val, _values, result )
- # a defaults setting for a type
- @lexer.commentpop
- result = ast(AST::ResourceDefaults, :type => val[0], :parameters => val[2])
+ # This is a deprecated syntax.
+ error "All resource specifications require names"
result
end
.,.,
-module_eval <<'.,.,', 'grammar.ra', 186
+module_eval <<'.,.,', 'grammar.ra', 146
def _reduce_48( val, _values, result )
- @lexer.commentpop
- result = ast AST::ResourceOverride, :object => val[0], :parameters => val[2]
+ # a defaults setting for a type
+ @lexer.commentpop
+ result = ast(AST::ResourceDefaults, :type => val[0], :parameters => val[2])
result
end
.,.,
-module_eval <<'.,.,', 'grammar.ra', 213
+module_eval <<'.,.,', 'grammar.ra', 152
def _reduce_49( val, _values, result )
- type = val[0]
+ @lexer.commentpop
+ result = ast AST::ResourceOverride, :object => val[0], :parameters => val[2]
+ result
+ end
+.,.,
- if (type == :exported and ! Puppet[:storeconfigs]) and ! Puppet[:parseonly]
- Puppet.warning addcontext("You cannot collect without storeconfigs being set")
- end
+module_eval <<'.,.,', 'grammar.ra', 171
+ def _reduce_50( val, _values, result )
+ type = val[0]
- if val[1].is_a? AST::ResourceDefaults
- error "Defaults are not virtualizable"
- end
+ if (type == :exported and ! Puppet[:storeconfigs]) and ! Puppet[:parseonly]
+ Puppet.warning addcontext("You cannot collect without storeconfigs being set")
+ end
- method = type.to_s + "="
+ error "Defaults are not virtualizable" if val[1].is_a? AST::ResourceDefaults
- # Just mark our resources as exported and pass them through.
- if val[1].instance_of?(AST::ASTArray)
- val[1].each do |obj|
- obj.send(method, true)
- end
- else
- val[1].send(method, true)
- end
+ method = type.to_s + "="
- result = val[1]
+ # Just mark our resource as exported and pass it through.
+ val[1].send(method, true)
+
+ result = val[1]
result
end
.,.,
-module_eval <<'.,.,', 'grammar.ra', 214
- def _reduce_50( val, _values, result )
+module_eval <<'.,.,', 'grammar.ra', 172
+ def _reduce_51( val, _values, result )
result = :virtual
result
end
.,.,
-module_eval <<'.,.,', 'grammar.ra', 215
- def _reduce_51( val, _values, result )
+module_eval <<'.,.,', 'grammar.ra', 173
+ def _reduce_52( val, _values, result )
result = :exported
result
end
.,.,
-module_eval <<'.,.,', 'grammar.ra', 240
- def _reduce_52( val, _values, result )
- @lexer.commentpop
- if val[0] =~ /^[a-z]/
- Puppet.warning addcontext("Collection names must now be capitalized")
- end
- type = val[0].downcase
- args = {:type => type}
-
- if val[1].is_a?(AST::CollExpr)
- args[:query] = val[1]
- args[:query].type = type
- args[:form] = args[:query].form
- else
- args[:form] = val[1]
- end
- if args[:form] == :exported and ! Puppet[:storeconfigs] and ! Puppet[:parseonly]
- Puppet.warning addcontext("You cannot collect exported resources without storeconfigs being set; the collection will be ignored")
- end
- args[:override] = val[3]
- result = ast AST::Collection, args
+module_eval <<'.,.,', 'grammar.ra', 196
+ def _reduce_53( val, _values, result )
+ @lexer.commentpop
+ Puppet.warning addcontext("Collection names must now be capitalized") if val[0] =~ /^[a-z]/
+ type = val[0].downcase
+ args = {:type => type}
+
+ if val[1].is_a?(AST::CollExpr)
+ args[:query] = val[1]
+ args[:query].type = type
+ args[:form] = args[:query].form
+ else
+ args[:form] = val[1]
+ end
+ if args[:form] == :exported and ! Puppet[:storeconfigs] and ! Puppet[:parseonly]
+ Puppet.warning addcontext("You cannot collect exported resources without storeconfigs being set; the collection will be ignored")
+ end
+ args[:override] = val[3]
+ result = ast AST::Collection, args
result
end
.,.,
-module_eval <<'.,.,', 'grammar.ra', 259
- def _reduce_53( val, _values, result )
+module_eval <<'.,.,', 'grammar.ra', 215
+ def _reduce_54( val, _values, result )
if val[0] =~ /^[a-z]/
- Puppet.warning addcontext("Collection names must now be capitalized")
- end
- type = val[0].downcase
- args = {:type => type }
-
- if val[1].is_a?(AST::CollExpr)
- args[:query] = val[1]
- args[:query].type = type
- args[:form] = args[:query].form
- else
- args[:form] = val[1]
- end
- if args[:form] == :exported and ! Puppet[:storeconfigs] and ! Puppet[:parseonly]
- Puppet.warning addcontext("You cannot collect exported resources without storeconfigs being set; the collection will be ignored")
- end
- result = ast AST::Collection, args
+ Puppet.warning addcontext("Collection names must now be capitalized")
+ end
+ type = val[0].downcase
+ args = {:type => type }
+
+ if val[1].is_a?(AST::CollExpr)
+ args[:query] = val[1]
+ args[:query].type = type
+ args[:form] = args[:query].form
+ else
+ args[:form] = val[1]
+ end
+ if args[:form] == :exported and ! Puppet[:storeconfigs] and ! Puppet[:parseonly]
+ Puppet.warning addcontext("You cannot collect exported resources without storeconfigs being set; the collection will be ignored")
+ end
+ result = ast AST::Collection, args
result
end
.,.,
-module_eval <<'.,.,', 'grammar.ra', 269
- def _reduce_54( val, _values, result )
- if val[1]
- result = val[1]
- result.form = :virtual
- else
- result = :virtual
- end
+module_eval <<'.,.,', 'grammar.ra', 225
+ def _reduce_55( val, _values, result )
+ if val[1]
+ result = val[1]
+ result.form = :virtual
+ else
+ result = :virtual
+ end
result
end
.,.,
-module_eval <<'.,.,', 'grammar.ra', 277
- def _reduce_55( val, _values, result )
+module_eval <<'.,.,', 'grammar.ra', 233
+ def _reduce_56( val, _values, result )
if val[1]
- result = val[1]
- result.form = :exported
- else
- result = :exported
- end
+ result = val[1]
+ result.form = :exported
+ else
+ result = :exported
+ end
result
end
.,.,
- # reduce 56 omitted
-
# reduce 57 omitted
-module_eval <<'.,.,', 'grammar.ra', 285
- def _reduce_58( val, _values, result )
+ # reduce 58 omitted
+
+module_eval <<'.,.,', 'grammar.ra', 241
+ def _reduce_59( val, _values, result )
result = ast AST::CollExpr, :test1 => val[0], :oper => val[1], :test2 => val[2]
result
end
.,.,
- # reduce 59 omitted
+ # reduce 60 omitted
-module_eval <<'.,.,', 'grammar.ra', 291
- def _reduce_60( val, _values, result )
+module_eval <<'.,.,', 'grammar.ra', 247
+ def _reduce_61( val, _values, result )
result = val[1]
result.parens = true
result
end
.,.,
-module_eval <<'.,.,', 'grammar.ra', 292
- def _reduce_61( val, _values, result )
+module_eval <<'.,.,', 'grammar.ra', 248
+ def _reduce_62( val, _values, result )
result=val[0][:value]
result
end
.,.,
-module_eval <<'.,.,', 'grammar.ra', 293
- def _reduce_62( val, _values, result )
+module_eval <<'.,.,', 'grammar.ra', 249
+ def _reduce_63( val, _values, result )
result=val[0][:value]
result
end
.,.,
-module_eval <<'.,.,', 'grammar.ra', 300
- def _reduce_63( val, _values, result )
- result = ast AST::CollExpr, :test1 => val[0], :oper => val[1][:value], :test2 => val[2]
- #result = ast AST::CollExpr
- #result.push *val
+module_eval <<'.,.,', 'grammar.ra', 256
+ def _reduce_64( val, _values, result )
+ result = ast AST::CollExpr, :test1 => val[0], :oper => val[1][:value], :test2 => val[2]
+ #result = ast AST::CollExpr
+ #result.push *val
result
end
.,.,
-module_eval <<'.,.,', 'grammar.ra', 305
- def _reduce_64( val, _values, result )
+module_eval <<'.,.,', 'grammar.ra', 261
+ def _reduce_65( val, _values, result )
result = ast AST::CollExpr, :test1 => val[0], :oper => val[1][:value], :test2 => val[2]
#result = ast AST::CollExpr
#result.push *val
@@ -1585,57 +1510,56 @@ module_eval <<'.,.,', 'grammar.ra', 305
end
.,.,
- # reduce 65 omitted
-
# reduce 66 omitted
-module_eval <<'.,.,', 'grammar.ra', 312
- def _reduce_67( val, _values, result )
- result = ast AST::ResourceInstance, :children => [val[0],val[2]]
+ # reduce 67 omitted
+
+module_eval <<'.,.,', 'grammar.ra', 268
+ def _reduce_68( val, _values, result )
+ result = ast AST::ResourceInstance, :title => val[0], :parameters => val[2]
result
end
.,.,
- # reduce 68 omitted
-
-module_eval <<'.,.,', 'grammar.ra', 322
+module_eval <<'.,.,', 'grammar.ra', 269
def _reduce_69( val, _values, result )
- if val[0].instance_of?(AST::ResourceInstance)
- result = ast AST::ASTArray, :children => [val[0],val[2]]
- else
- val[0].push val[2]
- result = val[0]
- end
+ result = aryfy(val[0])
result
end
.,.,
- # reduce 70 omitted
-
- # reduce 71 omitted
-
-module_eval <<'.,.,', 'grammar.ra', 329
- def _reduce_72( val, _values, result )
- result = ast AST::Undef, :value => :undef
+module_eval <<'.,.,', 'grammar.ra', 274
+ def _reduce_70( val, _values, result )
+ val[0].push val[2]
+ result = val[0]
result
end
.,.,
-module_eval <<'.,.,', 'grammar.ra', 333
+ # reduce 71 omitted
+
+ # reduce 72 omitted
+
+module_eval <<'.,.,', 'grammar.ra', 281
def _reduce_73( val, _values, result )
- result = ast AST::Name, :value => val[0][:value], :line => val[0][:line]
+ result = ast AST::Undef, :value => :undef
result
end
.,.,
-module_eval <<'.,.,', 'grammar.ra', 337
+module_eval <<'.,.,', 'grammar.ra', 285
def _reduce_74( val, _values, result )
- result = ast AST::Type, :value => val[0][:value], :line => val[0][:line]
+ result = ast AST::Name, :value => val[0][:value], :line => val[0][:line]
result
end
.,.,
- # reduce 75 omitted
+module_eval <<'.,.,', 'grammar.ra', 289
+ def _reduce_75( val, _values, result )
+ result = ast AST::Type, :value => val[0][:value], :line => val[0][:line]
+ result
+ end
+.,.,
# reduce 76 omitted
@@ -1649,118 +1573,109 @@ module_eval <<'.,.,', 'grammar.ra', 337
# reduce 81 omitted
-module_eval <<'.,.,', 'grammar.ra', 354
- def _reduce_82( val, _values, result )
- if val[0][:value] =~ /::/
- raise Puppet::ParseError, "Cannot assign to variables in other namespaces"
- end
- # this is distinct from referencing a variable
- variable = ast AST::Name, :value => val[0][:value], :line => val[0][:line]
- result = ast AST::VarDef, :name => variable, :value => val[2], :line => val[0][:line]
- result
- end
-.,.,
+ # reduce 82 omitted
-module_eval <<'.,.,', 'grammar.ra', 357
+module_eval <<'.,.,', 'grammar.ra', 304
def _reduce_83( val, _values, result )
- result = ast AST::VarDef, :name => val[0], :value => val[2]
+ raise Puppet::ParseError, "Cannot assign to variables in other namespaces" if val[0][:value] =~ /::/
+ # this is distinct from referencing a variable
+ variable = ast AST::Name, :value => val[0][:value], :line => val[0][:line]
+ result = ast AST::VarDef, :name => variable, :value => val[2], :line => val[0][:line]
result
end
.,.,
-module_eval <<'.,.,', 'grammar.ra', 362
+module_eval <<'.,.,', 'grammar.ra', 307
def _reduce_84( val, _values, result )
- variable = ast AST::Name, :value => val[0][:value], :line => val[0][:line]
- result = ast AST::VarDef, :name => variable, :value => val[2], :append => true, :line => val[0][:line]
+ result = ast AST::VarDef, :name => val[0], :value => val[2]
result
end
.,.,
-module_eval <<'.,.,', 'grammar.ra', 367
+module_eval <<'.,.,', 'grammar.ra', 312
def _reduce_85( val, _values, result )
- result = ast AST::ASTArray
+ variable = ast AST::Name, :value => val[0][:value], :line => val[0][:line]
+ result = ast AST::VarDef, :name => variable, :value => val[2], :append => true, :line => val[0][:line]
result
end
.,.,
-module_eval <<'.,.,', 'grammar.ra', 367
+module_eval <<'.,.,', 'grammar.ra', 317
def _reduce_86( val, _values, result )
- result = val[0]
+ result = ast AST::ASTArray
result
end
.,.,
-module_eval <<'.,.,', 'grammar.ra', 376
+module_eval <<'.,.,', 'grammar.ra', 317
def _reduce_87( val, _values, result )
- if val[0].instance_of?(AST::ASTArray)
- val[0].push(val[2])
- result = val[0]
- else
- result = ast AST::ASTArray, :children => [val[0],val[2]]
- end
+ result = aryfy(val[0])
result
end
.,.,
-module_eval <<'.,.,', 'grammar.ra', 380
+module_eval <<'.,.,', 'grammar.ra', 322
def _reduce_88( val, _values, result )
- result = ast AST::ResourceParam, :param => val[0][:value], :line => val[0][:line], :value => val[2]
+ val[0].push(val[2])
+ result = val[0]
result
end
.,.,
-module_eval <<'.,.,', 'grammar.ra', 385
+module_eval <<'.,.,', 'grammar.ra', 326
def _reduce_89( val, _values, result )
- result = ast AST::ResourceParam, :param => val[0][:value], :line => val[0][:line], :value => val[2],
- :add => true
+ result = ast AST::ResourceParam, :param => val[0][:value], :line => val[0][:line], :value => val[2]
result
end
.,.,
- # reduce 90 omitted
-
- # reduce 91 omitted
-
-module_eval <<'.,.,', 'grammar.ra', 393
- def _reduce_92( val, _values, result )
- result = ast AST::ASTArray
+module_eval <<'.,.,', 'grammar.ra', 331
+ def _reduce_90( val, _values, result )
+ result = ast AST::ResourceParam, :param => val[0][:value], :line => val[0][:line], :value => val[2],
+ :add => true
result
end
.,.,
-module_eval <<'.,.,', 'grammar.ra', 393
+ # reduce 91 omitted
+
+ # reduce 92 omitted
+
+module_eval <<'.,.,', 'grammar.ra', 339
def _reduce_93( val, _values, result )
- result = val[0]
+ result = ast AST::ASTArray
result
end
.,.,
-module_eval <<'.,.,', 'grammar.ra', 402
+module_eval <<'.,.,', 'grammar.ra', 339
def _reduce_94( val, _values, result )
- if val[0].instance_of?(AST::ASTArray)
- val[0].push(val[2])
- result = val[0]
- else
- result = ast AST::ASTArray, :children => [val[0],val[2]]
- end
+ result = aryfy(val[0])
result
end
.,.,
- # reduce 95 omitted
+module_eval <<'.,.,', 'grammar.ra', 344
+ def _reduce_95( val, _values, result )
+ val[0].push(val[2])
+ result = val[0]
+ result
+ end
+.,.,
-module_eval <<'.,.,', 'grammar.ra', 411
+module_eval <<'.,.,', 'grammar.ra', 345
def _reduce_96( val, _values, result )
- if val[0].instance_of?(AST::ASTArray)
- result = val[0].push(val[2])
- else
- result = ast AST::ASTArray, :children => [val[0],val[2]]
- end
+ result = aryfy(val[0])
result
end
.,.,
- # reduce 97 omitted
+module_eval <<'.,.,', 'grammar.ra', 346
+ def _reduce_97( val, _values, result )
+ result = val[0].push(val[2])
+ result
+ end
+.,.,
# reduce 98 omitted
@@ -1796,392 +1711,387 @@ module_eval <<'.,.,', 'grammar.ra', 411
# reduce 114 omitted
-module_eval <<'.,.,', 'grammar.ra', 440
- def _reduce_115( val, _values, result )
- args = aryfy(val[2])
- result = ast AST::Function,
- :name => val[0][:value], :line => val[0][:line],
- :arguments => args,
- :ftype => :rvalue
- result
- end
-.,.,
+ # reduce 115 omitted
-module_eval <<'.,.,', 'grammar.ra', 445
+module_eval <<'.,.,', 'grammar.ra', 375
def _reduce_116( val, _values, result )
- result = ast AST::Function,
- :name => val[0][:value], :line => val[0][:line],
- :arguments => AST::ASTArray.new({}),
- :ftype => :rvalue
+ result = ast AST::Function,
+ :name => val[0][:value], :line => val[0][:line],
+ :arguments => val[2],
+ :ftype => :rvalue
result
end
.,.,
-module_eval <<'.,.,', 'grammar.ra', 446
+module_eval <<'.,.,', 'grammar.ra', 380
def _reduce_117( val, _values, result )
- result = ast AST::String, :value => val[0][:value], :line => val[0][:line]
+ result = ast AST::Function,
+ :name => val[0][:value], :line => val[0][:line],
+ :arguments => AST::ASTArray.new({}),
+ :ftype => :rvalue
result
end
.,.,
-module_eval <<'.,.,', 'grammar.ra', 447
+module_eval <<'.,.,', 'grammar.ra', 381
def _reduce_118( val, _values, result )
- result = ast AST::Concat, :value => [ast(AST::String,val[0])]+val[1], :line => val[0][:line]
+ result = ast AST::String, :value => val[0][:value], :line => val[0][:line]
result
end
.,.,
-module_eval <<'.,.,', 'grammar.ra', 449
+module_eval <<'.,.,', 'grammar.ra', 382
def _reduce_119( val, _values, result )
- result = [val[0]] + val[1]
+ result = ast AST::Concat, :value => [ast(AST::String,val[0])]+val[1], :line => val[0][:line]
result
end
.,.,
-module_eval <<'.,.,', 'grammar.ra', 451
+module_eval <<'.,.,', 'grammar.ra', 384
def _reduce_120( val, _values, result )
- result = [ast(AST::String,val[0])]
+ result = [val[0]] + val[1]
result
end
.,.,
-module_eval <<'.,.,', 'grammar.ra', 452
+module_eval <<'.,.,', 'grammar.ra', 386
def _reduce_121( val, _values, result )
- result = [ast(AST::String,val[0])] + val[1]
+ result = [ast(AST::String,val[0])]
result
end
.,.,
-module_eval <<'.,.,', 'grammar.ra', 457
+module_eval <<'.,.,', 'grammar.ra', 387
def _reduce_122( val, _values, result )
- result = ast AST::Boolean, :value => val[0][:value], :line => val[0][:line]
+ result = [ast(AST::String,val[0])] + val[1]
result
end
.,.,
-module_eval <<'.,.,', 'grammar.ra', 462
+module_eval <<'.,.,', 'grammar.ra', 392
def _reduce_123( val, _values, result )
- Puppet.warning addcontext("Deprecation notice: Resource references should now be capitalized")
- result = ast AST::ResourceReference, :type => val[0][:value], :line => val[0][:line], :title => val[2]
+ result = ast AST::Boolean, :value => val[0][:value], :line => val[0][:line]
result
end
.,.,
-module_eval <<'.,.,', 'grammar.ra', 464
+module_eval <<'.,.,', 'grammar.ra', 397
def _reduce_124( val, _values, result )
- result = ast AST::ResourceReference, :type => val[0], :title => val[2]
+ Puppet.warning addcontext("Deprecation notice: Resource references should now be capitalized")
+ result = ast AST::ResourceReference, :type => val[0][:value], :line => val[0][:line], :title => val[2]
result
end
.,.,
-module_eval <<'.,.,', 'grammar.ra', 468
+module_eval <<'.,.,', 'grammar.ra', 399
def _reduce_125( val, _values, result )
- result = val[1]
+ result = ast AST::ResourceReference, :type => val[0], :title => val[2]
result
end
.,.,
-module_eval <<'.,.,', 'grammar.ra', 482
+module_eval <<'.,.,', 'grammar.ra', 403
def _reduce_126( val, _values, result )
- @lexer.commentpop
- args = {
- :test => val[0],
- :statements => val[2]
- }
+ result = val[1]
+ result
+ end
+.,.,
- if val[4]
- args[:else] = val[4]
- end
+module_eval <<'.,.,', 'grammar.ra', 415
+ def _reduce_127( val, _values, result )
+ @lexer.commentpop
+ args = {
+ :test => val[0],
+ :statements => val[2]
+ }
+
+ args[:else] = val[4] if val[4]
- result = ast AST::IfStatement, args
+ result = ast AST::IfStatement, args
result
end
.,.,
-module_eval <<'.,.,', 'grammar.ra', 495
- def _reduce_127( val, _values, result )
+module_eval <<'.,.,', 'grammar.ra', 426
+ def _reduce_128( val, _values, result )
@lexer.commentpop
args = {
- :test => val[0],
- :statements => ast(AST::Nop)
- }
+ :test => val[0],
+ :statements => ast(AST::Nop)
+ }
- if val[3]
- args[:else] = val[3]
- end
+ args[:else] = val[3] if val[3]
- result = ast AST::IfStatement, args
+ result = ast AST::IfStatement, args
result
end
.,.,
- # reduce 128 omitted
+ # reduce 129 omitted
-module_eval <<'.,.,', 'grammar.ra', 501
- def _reduce_129( val, _values, result )
- #@lexer.commentpop
+module_eval <<'.,.,', 'grammar.ra', 431
+ def _reduce_130( val, _values, result )
result = ast AST::Else, :statements => val[1]
result
end
.,.,
-module_eval <<'.,.,', 'grammar.ra', 505
- def _reduce_130( val, _values, result )
+module_eval <<'.,.,', 'grammar.ra', 435
+ def _reduce_131( val, _values, result )
@lexer.commentpop
result = ast AST::Else, :statements => val[2]
result
end
.,.,
-module_eval <<'.,.,', 'grammar.ra', 509
- def _reduce_131( val, _values, result )
+module_eval <<'.,.,', 'grammar.ra', 439
+ def _reduce_132( val, _values, result )
@lexer.commentpop
result = ast AST::Else, :statements => ast(AST::Nop)
result
end
.,.,
- # reduce 132 omitted
+ # reduce 133 omitted
-module_eval <<'.,.,', 'grammar.ra', 526
- def _reduce_133( val, _values, result )
- result = ast AST::InOperator, :lval => val[0], :rval => val[2]
- result
- end
-.,.,
-
-module_eval <<'.,.,', 'grammar.ra', 529
+module_eval <<'.,.,', 'grammar.ra', 456
def _reduce_134( val, _values, result )
- result = ast AST::MatchOperator, :operator => val[1][:value], :lval => val[0], :rval => val[2]
+ result = ast AST::InOperator, :lval => val[0], :rval => val[2]
result
end
.,.,
-module_eval <<'.,.,', 'grammar.ra', 532
+module_eval <<'.,.,', 'grammar.ra', 459
def _reduce_135( val, _values, result )
result = ast AST::MatchOperator, :operator => val[1][:value], :lval => val[0], :rval => val[2]
result
end
.,.,
-module_eval <<'.,.,', 'grammar.ra', 535
+module_eval <<'.,.,', 'grammar.ra', 462
def _reduce_136( val, _values, result )
- result = ast AST::ArithmeticOperator, :operator => val[1][:value], :lval => val[0], :rval => val[2]
+ result = ast AST::MatchOperator, :operator => val[1][:value], :lval => val[0], :rval => val[2]
result
end
.,.,
-module_eval <<'.,.,', 'grammar.ra', 538
+module_eval <<'.,.,', 'grammar.ra', 465
def _reduce_137( val, _values, result )
result = ast AST::ArithmeticOperator, :operator => val[1][:value], :lval => val[0], :rval => val[2]
result
end
.,.,
-module_eval <<'.,.,', 'grammar.ra', 541
+module_eval <<'.,.,', 'grammar.ra', 468
def _reduce_138( val, _values, result )
result = ast AST::ArithmeticOperator, :operator => val[1][:value], :lval => val[0], :rval => val[2]
result
end
.,.,
-module_eval <<'.,.,', 'grammar.ra', 544
+module_eval <<'.,.,', 'grammar.ra', 471
def _reduce_139( val, _values, result )
result = ast AST::ArithmeticOperator, :operator => val[1][:value], :lval => val[0], :rval => val[2]
result
end
.,.,
-module_eval <<'.,.,', 'grammar.ra', 547
+module_eval <<'.,.,', 'grammar.ra', 474
def _reduce_140( val, _values, result )
result = ast AST::ArithmeticOperator, :operator => val[1][:value], :lval => val[0], :rval => val[2]
result
end
.,.,
-module_eval <<'.,.,', 'grammar.ra', 550
+module_eval <<'.,.,', 'grammar.ra', 477
def _reduce_141( val, _values, result )
result = ast AST::ArithmeticOperator, :operator => val[1][:value], :lval => val[0], :rval => val[2]
result
end
.,.,
-module_eval <<'.,.,', 'grammar.ra', 553
+module_eval <<'.,.,', 'grammar.ra', 480
def _reduce_142( val, _values, result )
- result = ast AST::Minus, :value => val[1]
+ result = ast AST::ArithmeticOperator, :operator => val[1][:value], :lval => val[0], :rval => val[2]
result
end
.,.,
-module_eval <<'.,.,', 'grammar.ra', 556
+module_eval <<'.,.,', 'grammar.ra', 483
def _reduce_143( val, _values, result )
- result = ast AST::ComparisonOperator, :operator => val[1][:value], :lval => val[0], :rval => val[2]
+ result = ast AST::Minus, :value => val[1]
result
end
.,.,
-module_eval <<'.,.,', 'grammar.ra', 559
+module_eval <<'.,.,', 'grammar.ra', 486
def _reduce_144( val, _values, result )
result = ast AST::ComparisonOperator, :operator => val[1][:value], :lval => val[0], :rval => val[2]
result
end
.,.,
-module_eval <<'.,.,', 'grammar.ra', 562
+module_eval <<'.,.,', 'grammar.ra', 489
def _reduce_145( val, _values, result )
result = ast AST::ComparisonOperator, :operator => val[1][:value], :lval => val[0], :rval => val[2]
result
end
.,.,
-module_eval <<'.,.,', 'grammar.ra', 565
+module_eval <<'.,.,', 'grammar.ra', 492
def _reduce_146( val, _values, result )
result = ast AST::ComparisonOperator, :operator => val[1][:value], :lval => val[0], :rval => val[2]
result
end
.,.,
-module_eval <<'.,.,', 'grammar.ra', 568
+module_eval <<'.,.,', 'grammar.ra', 495
def _reduce_147( val, _values, result )
result = ast AST::ComparisonOperator, :operator => val[1][:value], :lval => val[0], :rval => val[2]
result
end
.,.,
-module_eval <<'.,.,', 'grammar.ra', 571
+module_eval <<'.,.,', 'grammar.ra', 498
def _reduce_148( val, _values, result )
result = ast AST::ComparisonOperator, :operator => val[1][:value], :lval => val[0], :rval => val[2]
result
end
.,.,
-module_eval <<'.,.,', 'grammar.ra', 574
+module_eval <<'.,.,', 'grammar.ra', 501
def _reduce_149( val, _values, result )
- result = ast AST::Not, :value => val[1]
+ result = ast AST::ComparisonOperator, :operator => val[1][:value], :lval => val[0], :rval => val[2]
result
end
.,.,
-module_eval <<'.,.,', 'grammar.ra', 577
+module_eval <<'.,.,', 'grammar.ra', 504
def _reduce_150( val, _values, result )
- result = ast AST::BooleanOperator, :operator => val[1][:value], :lval => val[0], :rval => val[2]
+ result = ast AST::Not, :value => val[1]
result
end
.,.,
-module_eval <<'.,.,', 'grammar.ra', 580
+module_eval <<'.,.,', 'grammar.ra', 507
def _reduce_151( val, _values, result )
result = ast AST::BooleanOperator, :operator => val[1][:value], :lval => val[0], :rval => val[2]
result
end
.,.,
-module_eval <<'.,.,', 'grammar.ra', 583
+module_eval <<'.,.,', 'grammar.ra', 510
def _reduce_152( val, _values, result )
- result = val[1]
+ result = ast AST::BooleanOperator, :operator => val[1][:value], :lval => val[0], :rval => val[2]
result
end
.,.,
-module_eval <<'.,.,', 'grammar.ra', 592
+module_eval <<'.,.,', 'grammar.ra', 513
def _reduce_153( val, _values, result )
- @lexer.commentpop
- options = val[3]
- unless options.instance_of?(AST::ASTArray)
- options = ast AST::ASTArray, :children => [val[3]]
- end
- result = ast AST::CaseStatement, :test => val[1], :options => options
+ result = val[1]
result
end
.,.,
- # reduce 154 omitted
+module_eval <<'.,.,', 'grammar.ra', 518
+ def _reduce_154( val, _values, result )
+ @lexer.commentpop
+ result = ast AST::CaseStatement, :test => val[1], :options => val[3]
+ result
+ end
+.,.,
-module_eval <<'.,.,', 'grammar.ra', 602
+module_eval <<'.,.,', 'grammar.ra', 519
def _reduce_155( val, _values, result )
- if val[0].instance_of?(AST::ASTArray)
- val[0].push val[1]
- result = val[0]
- else
- result = ast AST::ASTArray, :children => [val[0], val[1]]
- end
+ result = aryfy(val[0])
result
end
.,.,
-module_eval <<'.,.,', 'grammar.ra', 607
+module_eval <<'.,.,', 'grammar.ra', 524
def _reduce_156( val, _values, result )
- @lexer.commentpop
- result = ast AST::CaseOpt, :value => val[0], :statements => val[3]
+ val[0].push val[1]
+ result = val[0]
result
end
.,.,
-module_eval <<'.,.,', 'grammar.ra', 613
+module_eval <<'.,.,', 'grammar.ra', 529
def _reduce_157( val, _values, result )
- @lexer.commentpop
- result = ast(AST::CaseOpt,
- :value => val[0],
- :statements => ast(AST::ASTArray)
- )
+ @lexer.commentpop
+ result = ast AST::CaseOpt, :value => val[0], :statements => val[3]
result
end
.,.,
- # reduce 158 omitted
+module_eval <<'.,.,', 'grammar.ra', 538
+ def _reduce_158( val, _values, result )
+ @lexer.commentpop
-module_eval <<'.,.,', 'grammar.ra', 623
+ result = ast(
+ AST::CaseOpt,
+ :value => val[0],
+
+ :statements => ast(AST::ASTArray)
+ )
+ result
+ end
+.,.,
+
+module_eval <<'.,.,', 'grammar.ra', 539
def _reduce_159( val, _values, result )
- if val[0].instance_of?(AST::ASTArray)
- val[0].push(val[2])
- result = val[0]
- else
- result = ast AST::ASTArray, :children => [val[0],val[2]]
- end
+ result = aryfy(val[0])
result
end
.,.,
-module_eval <<'.,.,', 'grammar.ra', 627
+module_eval <<'.,.,', 'grammar.ra', 544
def _reduce_160( val, _values, result )
- result = ast AST::Selector, :param => val[0], :values => val[2]
+ val[0].push(val[2])
+ result = val[0]
result
end
.,.,
- # reduce 161 omitted
+module_eval <<'.,.,', 'grammar.ra', 548
+ def _reduce_161( val, _values, result )
+ result = ast AST::Selector, :param => val[0], :values => val[2]
+ result
+ end
+.,.,
+
+ # reduce 162 omitted
-module_eval <<'.,.,', 'grammar.ra', 633
- def _reduce_162( val, _values, result )
+module_eval <<'.,.,', 'grammar.ra', 554
+ def _reduce_163( val, _values, result )
@lexer.commentpop
result = val[1]
result
end
.,.,
- # reduce 163 omitted
+ # reduce 164 omitted
-module_eval <<'.,.,', 'grammar.ra', 643
- def _reduce_164( val, _values, result )
+module_eval <<'.,.,', 'grammar.ra', 564
+ def _reduce_165( val, _values, result )
if val[0].instance_of?(AST::ASTArray)
- val[0].push(val[2])
- result = val[0]
- else
- result = ast AST::ASTArray, :children => [val[0],val[2]]
- end
+ val[0].push(val[2])
+ result = val[0]
+ else
+ result = ast AST::ASTArray, :children => [val[0],val[2]]
+ end
result
end
.,.,
-module_eval <<'.,.,', 'grammar.ra', 647
- def _reduce_165( val, _values, result )
- result = ast AST::ResourceParam, :param => val[0], :value => val[2]
+module_eval <<'.,.,', 'grammar.ra', 568
+ def _reduce_166( val, _values, result )
+ result = ast AST::ResourceParam, :param => val[0], :value => val[2]
result
end
.,.,
- # reduce 166 omitted
-
# reduce 167 omitted
# reduce 168 omitted
@@ -2194,208 +2104,217 @@ module_eval <<'.,.,', 'grammar.ra', 647
# reduce 172 omitted
-module_eval <<'.,.,', 'grammar.ra', 658
- def _reduce_173( val, _values, result )
+ # reduce 173 omitted
+
+module_eval <<'.,.,', 'grammar.ra', 579
+ def _reduce_174( val, _values, result )
result = ast AST::Default, :value => val[0][:value], :line => val[0][:line]
result
end
.,.,
- # reduce 174 omitted
+ # reduce 175 omitted
-module_eval <<'.,.,', 'grammar.ra', 661
- def _reduce_175( val, _values, result )
+module_eval <<'.,.,', 'grammar.ra', 582
+ def _reduce_176( val, _values, result )
result = [val[0][:value]]
result
end
.,.,
- # reduce 176 omitted
+ # reduce 177 omitted
-module_eval <<'.,.,', 'grammar.ra', 663
- def _reduce_177( val, _values, result )
- result = val[0] += val[2]
- result
- end
-.,.,
-
-module_eval <<'.,.,', 'grammar.ra', 672
+module_eval <<'.,.,', 'grammar.ra', 584
def _reduce_178( val, _values, result )
- val[1].each do |file|
- import(file)
- end
-
- result = AST::ASTArray.new(:children => [])
+ result = val[0] += val[2]
result
end
.,.,
-module_eval <<'.,.,', 'grammar.ra', 683
+module_eval <<'.,.,', 'grammar.ra', 593
def _reduce_179( val, _values, result )
- @lexer.commentpop
- newdefine classname(val[1]), :arguments => val[2], :code => val[4], :line => val[0][:line]
- @lexer.indefine = false
- result = nil
+ val[1].each do |file|
+ import(file)
+ end
-#} | DEFINE NAME argumentlist parent LBRACE RBRACE {
+ result = nil
result
end
.,.,
-module_eval <<'.,.,', 'grammar.ra', 688
+module_eval <<'.,.,', 'grammar.ra', 605
def _reduce_180( val, _values, result )
- @lexer.commentpop
- newdefine classname(val[1]), :arguments => val[2], :line => val[0][:line]
- @lexer.indefine = false
- result = nil
+ @lexer.commentpop
+ result = Puppet::Parser::AST::Definition.new(classname(val[1]),
+ ast_context(true).merge(:arguments => val[2], :code => val[4],
+ :line => val[0][:line]))
+ @lexer.indefine = false
+
+#} | DEFINE NAME argumentlist parent LBRACE RBRACE {
result
end
.,.,
-module_eval <<'.,.,', 'grammar.ra', 697
+module_eval <<'.,.,', 'grammar.ra', 610
def _reduce_181( val, _values, result )
- @lexer.commentpop
- # Our class gets defined in the parent namespace, not our own.
- @lexer.namepop
- newclass classname(val[1]), :arguments => val[2], :parent => val[3], :code => val[5], :line => val[0][:line]
- result = nil
+ @lexer.commentpop
+ result = Puppet::Parser::AST::Definition.new(classname(val[1]),
+ ast_context(true).merge(:arguments => val[2], :line => val[0][:line]))
+ @lexer.indefine = false
result
end
.,.,
-module_eval <<'.,.,', 'grammar.ra', 703
+module_eval <<'.,.,', 'grammar.ra', 620
def _reduce_182( val, _values, result )
- @lexer.commentpop
- # Our class gets defined in the parent namespace, not our own.
- @lexer.namepop
- newclass classname(val[1]), :arguments => val[2], :parent => val[3], :line => val[0][:line]
- result = nil
+ @lexer.commentpop
+ # Our class gets defined in the parent namespace, not our own.
+ @lexer.namepop
+ result = Puppet::Parser::AST::Hostclass.new(classname(val[1]),
+ ast_context(true).merge(:arguments => val[2], :parent => val[3],
+ :code => val[5], :line => val[0][:line]))
result
end
.,.,
-module_eval <<'.,.,', 'grammar.ra', 709
+module_eval <<'.,.,', 'grammar.ra', 627
def _reduce_183( val, _values, result )
- @lexer.commentpop
- newnode val[1], :parent => val[2], :code => val[4], :line => val[0][:line]
- result = nil
+ @lexer.commentpop
+ # Our class gets defined in the parent namespace, not our own.
+ @lexer.namepop
+ result = Puppet::Parser::AST::Hostclass.new(classname(val[1]),
+ ast_context(true).merge(:arguments => val[2], :parent => val[3],
+ :line => val[0][:line]))
result
end
.,.,
-module_eval <<'.,.,', 'grammar.ra', 713
+module_eval <<'.,.,', 'grammar.ra', 634
def _reduce_184( val, _values, result )
- @lexer.commentpop
- newnode val[1], :parent => val[2], :line => val[0][:line]
- result = nil
+ @lexer.commentpop
+ result = Puppet::Parser::AST::Node.new(val[1],
+ ast_context(true).merge(:parent => val[2], :code => val[4],
+ :line => val[0][:line]))
result
end
.,.,
-module_eval <<'.,.,', 'grammar.ra', 714
+module_eval <<'.,.,', 'grammar.ra', 637
def _reduce_185( val, _values, result )
- result = val[0][:value]
+ @lexer.commentpop
+ result = Puppet::Parser::AST::Node.new(val[1], ast_context(true).merge(:parent => val[2], :line => val[0][:line]))
result
end
.,.,
-module_eval <<'.,.,', 'grammar.ra', 716
+module_eval <<'.,.,', 'grammar.ra', 638
def _reduce_186( val, _values, result )
result = val[0][:value]
result
end
.,.,
-module_eval <<'.,.,', 'grammar.ra', 717
+module_eval <<'.,.,', 'grammar.ra', 640
def _reduce_187( val, _values, result )
result = val[0][:value]
result
end
.,.,
-module_eval <<'.,.,', 'grammar.ra', 718
+module_eval <<'.,.,', 'grammar.ra', 641
def _reduce_188( val, _values, result )
- result = "class"
+ result = val[0][:value]
result
end
.,.,
- # reduce 189 omitted
+module_eval <<'.,.,', 'grammar.ra', 642
+ def _reduce_189( val, _values, result )
+ result = "class"
+ result
+ end
+.,.,
-module_eval <<'.,.,', 'grammar.ra', 728
+module_eval <<'.,.,', 'grammar.ra', 649
def _reduce_190( val, _values, result )
- result = val[0]
- result = [result] unless result.is_a?(Array)
- result << val[2]
+ result = [result]
result
end
.,.,
-module_eval <<'.,.,', 'grammar.ra', 732
+module_eval <<'.,.,', 'grammar.ra', 653
def _reduce_191( val, _values, result )
- result = ast AST::HostName, :value => val[0]
+ result = val[0]
+ result << val[2]
result
end
.,.,
-module_eval <<'.,.,', 'grammar.ra', 733
+module_eval <<'.,.,', 'grammar.ra', 657
def _reduce_192( val, _values, result )
- result = val[0][:value]
+ result = ast AST::HostName, :value => val[0]
result
end
.,.,
-module_eval <<'.,.,', 'grammar.ra', 734
+module_eval <<'.,.,', 'grammar.ra', 658
def _reduce_193( val, _values, result )
result = val[0][:value]
result
end
.,.,
-module_eval <<'.,.,', 'grammar.ra', 735
+module_eval <<'.,.,', 'grammar.ra', 659
def _reduce_194( val, _values, result )
result = val[0][:value]
result
end
.,.,
- # reduce 195 omitted
-
-module_eval <<'.,.,', 'grammar.ra', 741
- def _reduce_196( val, _values, result )
- result = nil
+module_eval <<'.,.,', 'grammar.ra', 660
+ def _reduce_195( val, _values, result )
+ result = val[0][:value]
result
end
.,.,
-module_eval <<'.,.,', 'grammar.ra', 745
+ # reduce 196 omitted
+
+module_eval <<'.,.,', 'grammar.ra', 666
def _reduce_197( val, _values, result )
- result = ast AST::ASTArray, :children => []
+ result = nil
+ result
+ end
+.,.,
+
+module_eval <<'.,.,', 'grammar.ra', 670
+ def _reduce_198( val, _values, result )
+ result = ast AST::ASTArray, :children => []
result
end
.,.,
- # reduce 198 omitted
+ # reduce 199 omitted
-module_eval <<'.,.,', 'grammar.ra', 750
- def _reduce_199( val, _values, result )
+module_eval <<'.,.,', 'grammar.ra', 675
+ def _reduce_200( val, _values, result )
result = nil
result
end
.,.,
-module_eval <<'.,.,', 'grammar.ra', 754
- def _reduce_200( val, _values, result )
+module_eval <<'.,.,', 'grammar.ra', 679
+ def _reduce_201( val, _values, result )
result = val[1]
result = [result] unless result[0].is_a?(Array)
result
end
.,.,
- # reduce 201 omitted
+ # reduce 202 omitted
-module_eval <<'.,.,', 'grammar.ra', 761
- def _reduce_202( val, _values, result )
+module_eval <<'.,.,', 'grammar.ra', 686
+ def _reduce_203( val, _values, result )
result = val[0]
result = [result] unless result[0].is_a?(Array)
result << val[2]
@@ -2403,189 +2322,181 @@ module_eval <<'.,.,', 'grammar.ra', 761
end
.,.,
-module_eval <<'.,.,', 'grammar.ra', 766
- def _reduce_203( val, _values, result )
- Puppet.warning addcontext("Deprecation notice: must now include '$' in prototype")
- result = [val[0][:value], val[2]]
+module_eval <<'.,.,', 'grammar.ra', 691
+ def _reduce_204( val, _values, result )
+ Puppet.warning addcontext("Deprecation notice: must now include '$' in prototype")
+ result = [val[0][:value], val[2]]
result
end
.,.,
-module_eval <<'.,.,', 'grammar.ra', 770
- def _reduce_204( val, _values, result )
+module_eval <<'.,.,', 'grammar.ra', 695
+ def _reduce_205( val, _values, result )
Puppet.warning addcontext("Deprecation notice: must now include '$' in prototype")
result = [val[0][:value]]
result
end
.,.,
-module_eval <<'.,.,', 'grammar.ra', 772
- def _reduce_205( val, _values, result )
- result = [val[0][:value], val[2]]
+module_eval <<'.,.,', 'grammar.ra', 697
+ def _reduce_206( val, _values, result )
+ result = [val[0][:value], val[2]]
result
end
.,.,
-module_eval <<'.,.,', 'grammar.ra', 774
- def _reduce_206( val, _values, result )
- result = [val[0][:value]]
+module_eval <<'.,.,', 'grammar.ra', 699
+ def _reduce_207( val, _values, result )
+ result = [val[0][:value]]
result
end
.,.,
- # reduce 207 omitted
+ # reduce 208 omitted
-module_eval <<'.,.,', 'grammar.ra', 779
- def _reduce_208( val, _values, result )
+module_eval <<'.,.,', 'grammar.ra', 704
+ def _reduce_209( val, _values, result )
result = val[1]
result
end
.,.,
- # reduce 209 omitted
+ # reduce 210 omitted
-module_eval <<'.,.,', 'grammar.ra', 784
- def _reduce_210( val, _values, result )
+module_eval <<'.,.,', 'grammar.ra', 709
+ def _reduce_211( val, _values, result )
result = val[1]
result
end
.,.,
- # reduce 211 omitted
-
# reduce 212 omitted
-module_eval <<'.,.,', 'grammar.ra', 790
- def _reduce_213( val, _values, result )
- result = ast AST::Variable, :value => val[0][:value], :line => val[0][:line]
- result
- end
-.,.,
+ # reduce 213 omitted
-module_eval <<'.,.,', 'grammar.ra', 798
+module_eval <<'.,.,', 'grammar.ra', 715
def _reduce_214( val, _values, result )
- if val[1].instance_of?(AST::ASTArray)
- result = val[1]
- else
- result = ast AST::ASTArray, :children => [val[1]]
- end
+ result = ast AST::Variable, :value => val[0][:value], :line => val[0][:line]
result
end
.,.,
-module_eval <<'.,.,', 'grammar.ra', 805
+module_eval <<'.,.,', 'grammar.ra', 716
def _reduce_215( val, _values, result )
- if val[1].instance_of?(AST::ASTArray)
- result = val[1]
- else
- result = ast AST::ASTArray, :children => [val[1]]
- end
+ result = val[1]
result
end
.,.,
-module_eval <<'.,.,', 'grammar.ra', 807
+module_eval <<'.,.,', 'grammar.ra', 717
def _reduce_216( val, _values, result )
- result = ast AST::ASTArray
+ result = val[1]
result
end
.,.,
- # reduce 217 omitted
+module_eval <<'.,.,', 'grammar.ra', 718
+ def _reduce_217( val, _values, result )
+ result = ast AST::ASTArray
+ result
+ end
+.,.,
# reduce 218 omitted
# reduce 219 omitted
-module_eval <<'.,.,', 'grammar.ra', 812
- def _reduce_220( val, _values, result )
+ # reduce 220 omitted
+
+module_eval <<'.,.,', 'grammar.ra', 724
+ def _reduce_221( val, _values, result )
result = nil
result
end
.,.,
-module_eval <<'.,.,', 'grammar.ra', 817
- def _reduce_221( val, _values, result )
- result = ast AST::Regex, :value => val[0][:value]
+module_eval <<'.,.,', 'grammar.ra', 729
+ def _reduce_222( val, _values, result )
+ result = ast AST::Regex, :value => val[0][:value]
result
end
.,.,
-module_eval <<'.,.,', 'grammar.ra', 825
- def _reduce_222( val, _values, result )
- if val[1].instance_of?(AST::ASTHash)
- result = val[1]
- else
- result = ast AST::ASTHash, { :value => val[1] }
- end
+module_eval <<'.,.,', 'grammar.ra', 737
+ def _reduce_223( val, _values, result )
+ if val[1].instance_of?(AST::ASTHash)
+ result = val[1]
+ else
+ result = ast AST::ASTHash, { :value => val[1] }
+ end
result
end
.,.,
-module_eval <<'.,.,', 'grammar.ra', 832
- def _reduce_223( val, _values, result )
+module_eval <<'.,.,', 'grammar.ra', 744
+ def _reduce_224( val, _values, result )
if val[1].instance_of?(AST::ASTHash)
- result = val[1]
- else
- result = ast AST::ASTHash, { :value => val[1] }
- end
+ result = val[1]
+ else
+ result = ast AST::ASTHash, { :value => val[1] }
+ end
result
end
.,.,
-module_eval <<'.,.,', 'grammar.ra', 834
- def _reduce_224( val, _values, result )
- result = ast AST::ASTHash
+module_eval <<'.,.,', 'grammar.ra', 746
+ def _reduce_225( val, _values, result )
+ result = ast AST::ASTHash
result
end
.,.,
- # reduce 225 omitted
+ # reduce 226 omitted
-module_eval <<'.,.,', 'grammar.ra', 844
- def _reduce_226( val, _values, result )
+module_eval <<'.,.,', 'grammar.ra', 756
+ def _reduce_227( val, _values, result )
if val[0].instance_of?(AST::ASTHash)
- result = val[0].merge(val[2])
- else
- result = ast AST::ASTHash, :value => val[0]
- result.merge(val[2])
- end
+ result = val[0].merge(val[2])
+ else
+ result = ast AST::ASTHash, :value => val[0]
+ result.merge(val[2])
+ end
result
end
.,.,
-module_eval <<'.,.,', 'grammar.ra', 848
- def _reduce_227( val, _values, result )
- result = ast AST::ASTHash, { :value => { val[0] => val[2] } }
+module_eval <<'.,.,', 'grammar.ra', 760
+ def _reduce_228( val, _values, result )
+ result = ast AST::ASTHash, { :value => { val[0] => val[2] } }
result
end
.,.,
-module_eval <<'.,.,', 'grammar.ra', 849
- def _reduce_228( val, _values, result )
+module_eval <<'.,.,', 'grammar.ra', 761
+ def _reduce_229( val, _values, result )
result = val[0][:value]
result
end
.,.,
-module_eval <<'.,.,', 'grammar.ra', 850
- def _reduce_229( val, _values, result )
+module_eval <<'.,.,', 'grammar.ra', 762
+ def _reduce_230( val, _values, result )
result = val[0]
result
end
.,.,
-module_eval <<'.,.,', 'grammar.ra', 855
- def _reduce_230( val, _values, result )
- result = ast AST::HashOrArrayAccess, :variable => val[0][:value], :key => val[2]
+module_eval <<'.,.,', 'grammar.ra', 767
+ def _reduce_231( val, _values, result )
+ result = ast AST::HashOrArrayAccess, :variable => val[0][:value], :key => val[2]
result
end
.,.,
- # reduce 231 omitted
+ # reduce 232 omitted
-module_eval <<'.,.,', 'grammar.ra', 860
- def _reduce_232( val, _values, result )
+module_eval <<'.,.,', 'grammar.ra', 772
+ def _reduce_233( val, _values, result )
result = ast AST::HashOrArrayAccess, :variable => val[0], :key => val[2]
result
end
diff --git a/lib/puppet/parser/parser_support.rb b/lib/puppet/parser/parser_support.rb
index c0fd37178..746aa0f90 100644
--- a/lib/puppet/parser/parser_support.rb
+++ b/lib/puppet/parser/parser_support.rb
@@ -29,29 +29,20 @@ class Puppet::Parser::Parser
message
end
- # Create an AST array out of all of the args
- def aryfy(*args)
- if args[0].instance_of?(AST::ASTArray)
- result = args.shift
- args.each { |arg|
- result.push arg
- }
- else
- result = ast AST::ASTArray, :children => args
- end
-
- result
+ # Create an AST array containing a single element
+ def aryfy(arg)
+ ast AST::ASTArray, :children => [arg]
end
# Create an AST object, and automatically add the file and line information if
# available.
def ast(klass, hash = {})
- klass.new ast_context(klass.use_docs).merge(hash)
+ klass.new ast_context(klass.use_docs, hash[:line]).merge(hash)
end
- def ast_context(include_docs = false)
+ def ast_context(include_docs = false, ast_line = nil)
result = {
- :line => lexer.line,
+ :line => ast_line || lexer.line,
:file => lexer.file
}
result[:doc] = lexer.getcomment(result[:line]) if include_docs
@@ -68,13 +59,13 @@ class Puppet::Parser::Parser
end
# Raise a Parse error.
- def error(message)
+ def error(message, options = {})
if brace = @lexer.expected
message += "; expected '%s'"
end
except = Puppet::ParseError.new(message)
- except.line = @lexer.line
- except.file = @lexer.file if @lexer.file
+ except.line = options[:line] || @lexer.line
+ except.file = options[:file] || @lexer.file
raise except
end
@@ -103,15 +94,15 @@ class Puppet::Parser::Parser
end
def find_hostclass(namespace, name)
- known_resource_types.find_or_load(namespace, name, :hostclass)
+ known_resource_types.find_hostclass(namespace, name)
end
def find_definition(namespace, name)
- known_resource_types.find_or_load(namespace, name, :definition)
+ known_resource_types.find_definition(namespace, name)
end
def import(file)
- known_resource_types.loader.import_if_possible(file, @lexer.file)
+ known_resource_types.loader.import(file, @lexer.file)
end
def initialize(env)
@@ -133,26 +124,6 @@ class Puppet::Parser::Parser
return ns, n
end
- # Create a new class, or merge with an existing class.
- def newclass(name, options = {})
- known_resource_types.add Puppet::Resource::Type.new(:hostclass, name, ast_context(true).merge(options))
- end
-
- # Create a new definition.
- def newdefine(name, options = {})
- known_resource_types.add Puppet::Resource::Type.new(:definition, name, ast_context(true).merge(options))
- end
-
- # Create a new node. Nodes are special, because they're stored in a global
- # table, not according to namespaces.
- def newnode(names, options = {})
- names = [names] unless names.instance_of?(Array)
- context = ast_context(true)
- names.collect do |name|
- known_resource_types.add(Puppet::Resource::Type.new(:node, name, context.merge(options)))
- end
- end
-
def on_error(token,value,stack)
if token == 0 # denotes end of file
value = 'end of file'
@@ -174,48 +145,54 @@ class Puppet::Parser::Parser
# how should I do error handling here?
def parse(string = nil)
- return parse_ruby_file if self.file =~ /\.rb$/
- self.string = string if string
- begin
- @yydebug = false
- main = yyparse(@lexer,:scan)
- rescue Racc::ParseError => except
- error = Puppet::ParseError.new(except)
- error.line = @lexer.line
- error.file = @lexer.file
- error.set_backtrace except.backtrace
- raise error
- rescue Puppet::ParseError => except
- except.line ||= @lexer.line
- except.file ||= @lexer.file
- raise except
- rescue Puppet::Error => except
- # and this is a framework error
- except.line ||= @lexer.line
- except.file ||= @lexer.file
- raise except
- rescue Puppet::DevError => except
- except.line ||= @lexer.line
- except.file ||= @lexer.file
- raise except
- rescue => except
- error = Puppet::DevError.new(except.message)
- error.line = @lexer.line
- error.file = @lexer.file
- error.set_backtrace except.backtrace
- raise error
- end
- if main
- # Store the results as the top-level class.
- newclass("", :code => main)
+ if self.file =~ /\.rb$/
+ main = parse_ruby_file
+ else
+ self.string = string if string
+ begin
+ @yydebug = false
+ main = yyparse(@lexer,:scan)
+ rescue Racc::ParseError => except
+ error = Puppet::ParseError.new(except)
+ error.line = @lexer.line
+ error.file = @lexer.file
+ error.set_backtrace except.backtrace
+ raise error
+ rescue Puppet::ParseError => except
+ except.line ||= @lexer.line
+ except.file ||= @lexer.file
+ raise except
+ rescue Puppet::Error => except
+ # and this is a framework error
+ except.line ||= @lexer.line
+ except.file ||= @lexer.file
+ raise except
+ rescue Puppet::DevError => except
+ except.line ||= @lexer.line
+ except.file ||= @lexer.file
+ raise except
+ rescue => except
+ error = Puppet::DevError.new(except.message)
+ error.line = @lexer.line
+ error.file = @lexer.file
+ error.set_backtrace except.backtrace
+ raise error
+ end
end
- return known_resource_types
+ # Store the results as the top-level class.
+ return Puppet::Parser::AST::Hostclass.new('', :code => main)
ensure
@lexer.clear
end
def parse_ruby_file
- require self.file
+ # Execute the contents of the file inside its own "main" object so
+ # that it can call methods in the resource type API.
+ main_object = Puppet::DSL::ResourceTypeAPI.new
+ main_object.instance_eval(File.read(self.file))
+
+ # Then extract any types that were created.
+ Puppet::Parser::AST::ASTArray.new :children => main_object.instance_eval { @__created_ast_objects__ }
end
def string=(string)
diff --git a/lib/puppet/parser/resource.rb b/lib/puppet/parser/resource.rb
index c956a1106..c007d4dbe 100644
--- a/lib/puppet/parser/resource.rb
+++ b/lib/puppet/parser/resource.rb
@@ -64,6 +64,8 @@ class Puppet::Parser::Resource < Puppet::Resource
# Retrieve the associated definition and evaluate it.
def evaluate
+ return if evaluated?
+ @evaluated = true
if klass = resource_type and ! builtin_type?
finish
return klass.evaluate_code(self)
@@ -72,8 +74,6 @@ class Puppet::Parser::Resource < Puppet::Resource
else
self.fail "Cannot find definition #{type}"
end
- ensure
- @evaluated = true
end
# Mark this resource as both exported and virtual,
@@ -94,6 +94,7 @@ class Puppet::Parser::Resource < Puppet::Resource
@finished = true
add_defaults
add_metaparams
+ add_scope_tags
validate
end
@@ -103,9 +104,9 @@ class Puppet::Parser::Resource < Puppet::Resource
end
def initialize(*args)
+ raise ArgumentError, "Resources require a scope" unless args.last[:scope]
super
- raise ArgumentError, "Resources require a scope" unless scope
@source ||= scope.source
end
@@ -141,10 +142,6 @@ class Puppet::Parser::Resource < Puppet::Resource
self[:name] || self.title
end
- def namespaces
- scope.namespaces
- end
-
# A temporary occasion, until I get paths in the scopes figured out.
def path
to_s
@@ -264,6 +261,12 @@ class Puppet::Parser::Resource < Puppet::Resource
end
end
+ def add_scope_tags
+ if scope_resource = scope.resource
+ tag(*scope_resource.tags)
+ end
+ end
+
# Accept a parameter from an override.
def override_parameter(param)
# This can happen if the override is defining a new parameter, rather
diff --git a/lib/puppet/parser/resource/param.rb b/lib/puppet/parser/resource/param.rb
index af2d98fe8..c28322337 100644
--- a/lib/puppet/parser/resource/param.rb
+++ b/lib/puppet/parser/resource/param.rb
@@ -13,7 +13,7 @@ class Puppet::Parser::Resource::Param
def initialize(hash)
set_options(hash)
- requiredopts(:name, :value, :source)
+ requiredopts(:name, :value)
@name = symbolize(@name)
end
diff --git a/lib/puppet/parser/scope.rb b/lib/puppet/parser/scope.rb
index ae0f9ea4a..24f1d01f7 100644
--- a/lib/puppet/parser/scope.rb
+++ b/lib/puppet/parser/scope.rb
@@ -474,6 +474,41 @@ class Puppet::Parser::Scope
end
end
+ def find_resource_type(type)
+ # It still works fine without the type == 'class' short-cut, but it is a lot slower.
+ return nil if ["class", "node"].include? type.to_s.downcase
+ find_builtin_resource_type(type) || find_defined_resource_type(type)
+ end
+
+ def find_builtin_resource_type(type)
+ Puppet::Type.type(type.to_s.downcase.to_sym)
+ end
+
+ def find_defined_resource_type(type)
+ environment.known_resource_types.find_definition(namespaces, type.to_s.downcase)
+ end
+
+ def resolve_type_and_titles(type, titles)
+ raise ArgumentError, "titles must be an array" unless titles.is_a?(Array)
+
+ case type.downcase
+ when "class"
+ # resolve the titles
+ titles = titles.collect do |a_title|
+ hostclass = find_hostclass(a_title)
+ hostclass ? hostclass.name : a_title
+ end
+ when "node"
+ # no-op
+ else
+ # resolve the type
+ resource_type = find_resource_type(type)
+ type = resource_type.name if resource_type
+ end
+
+ return [type, titles]
+ end
+
private
def extend_with_functions_module
diff --git a/lib/puppet/parser/templatewrapper.rb b/lib/puppet/parser/templatewrapper.rb
index 73a4ad8aa..6864aa1a9 100644
--- a/lib/puppet/parser/templatewrapper.rb
+++ b/lib/puppet/parser/templatewrapper.rb
@@ -1,6 +1,7 @@
# A simple wrapper for templates, so they don't have full access to
# the scope objects.
require 'puppet/parser/files'
+require 'erb'
class Puppet::Parser::TemplateWrapper
attr_writer :scope
diff --git a/lib/puppet/parser/type_loader.rb b/lib/puppet/parser/type_loader.rb
index 35ad49593..140c9f2ca 100644
--- a/lib/puppet/parser/type_loader.rb
+++ b/lib/puppet/parser/type_loader.rb
@@ -3,25 +3,56 @@ require 'puppet/node/environment'
class Puppet::Parser::TypeLoader
include Puppet::Node::Environment::Helper
- class Helper < Hash
+ # Helper class that makes sure we don't try to import the same file
+ # more than once from either the same thread or different threads.
+ class Helper
include MonitorMixin
- def done_with(item)
- synchronize do
- delete(item)[:busy].signal if self.has_key?(item) and self[item][:loader] == Thread.current
- end
+ def initialize
+ super
+ # These hashes are indexed by filename
+ @state = {} # :doing or :done
+ @thread = {} # if :doing, thread that's doing the parsing
+ @cond_var = {} # if :doing, condition var that will be signaled when done.
end
- def owner_of(item)
- synchronize do
- if !self.has_key? item
- self[item] = { :loader => Thread.current, :busy => self.new_cond}
- :nobody
- elsif self[item][:loader] == Thread.current
- :this_thread
+
+ # Execute the supplied block exactly once per file, no matter how
+ # many threads have asked for it to run. If another thread is
+ # already executing it, wait for it to finish. If this thread is
+ # already executing it, return immediately without executing the
+ # block.
+ #
+ # Note: the reason for returning immediately if this thread is
+ # already executing the block is to handle the case of a circular
+ # import--when this happens, we attempt to recursively re-parse a
+ # file that we are already in the process of parsing. To prevent
+ # an infinite regress we need to simply do nothing when the
+ # recursive import is attempted.
+ def do_once(file)
+ need_to_execute = synchronize do
+ case @state[file]
+ when :doing
+ if @thread[file] != Thread.current
+ @cond_var[file].wait
+ end
+ false
+ when :done
+ false
else
- flag = self[item][:busy]
- flag.wait
- flag.signal
- :another_thread
+ @state[file] = :doing
+ @thread[file] = Thread.current
+ @cond_var[file] = new_cond
+ true
+ end
+ end
+ if need_to_execute
+ begin
+ yield
+ ensure
+ synchronize do
+ @state[file] = :done
+ @thread.delete(file)
+ @cond_var.delete(file).broadcast
+ end
end
end
end
@@ -47,21 +78,18 @@ class Puppet::Parser::TypeLoader
raise Puppet::ImportError.new("No file(s) found for import of '#{pat}'")
end
+ loaded_asts = []
files.each do |file|
unless file =~ /^#{File::SEPARATOR}/
file = File.join(dir, file)
end
- unless imported? file
- @imported[file] = true
- parse_file(file)
+ @loading_helper.do_once(file) do
+ loaded_asts << parse_file(file)
end
end
-
- modname
- end
-
- def imported?(file)
- @imported.has_key?(file)
+ loaded_asts.inject([]) do |loaded_types, ast|
+ loaded_types + known_resource_types.import_ast(ast, modname)
+ end
end
def known_resource_types
@@ -70,77 +98,48 @@ class Puppet::Parser::TypeLoader
def initialize(env)
self.environment = env
- @loaded = {}
- @loading = Helper.new
-
- @imported = {}
+ @loading_helper = Helper.new
end
- def load_until(namespaces, name)
- return nil if name == "" # special-case main.
- name2files(namespaces, name).each do |filename|
- modname = begin
- import_if_possible(filename)
+ # Try to load the object with the given fully qualified name.
+ def try_load_fqname(type, fqname)
+ return nil if fqname == "" # special-case main.
+ name2files(fqname).each do |filename|
+ begin
+ imported_types = import(filename)
+ if result = imported_types.find { |t| t.type == type and t.name == fqname }
+ Puppet.debug "Automatically imported #{fqname} from #{filename} into #{environment}"
+ return result
+ end
rescue Puppet::ImportError => detail
# We couldn't load the item
# I'm not convienced we should just drop these errors, but this
# preserves existing behaviours.
- nil
- end
- if result = yield(filename)
- Puppet.info "Automatically imported #{name} from #{filename} into #{environment}"
- result.module_name = modname if modname and result.respond_to?(:module_name=)
- return result
end
end
- nil
- end
-
- def loaded?(name)
- @loaded.include?(name)
- end
-
- def name2files(namespaces, name)
- return [name.sub(/^::/, '').gsub("::", File::SEPARATOR)] if name =~ /^::/
-
- result = namespaces.inject([]) do |names_to_try, namespace|
- fullname = (namespace + "::#{name}").sub(/^::/, '')
-
- # Try to load the module init file if we're a qualified name
- names_to_try << fullname.split("::")[0] if fullname.include?("::")
-
- # Then the fully qualified name
- names_to_try << fullname
- end
-
- # Otherwise try to load the bare name on its own. This
- # is appropriate if the class we're looking for is in a
- # module that's different from our namespace.
- result << name
- result.uniq.collect { |f| f.gsub("::", File::SEPARATOR) }
+ # Nothing found.
+ return nil
end
def parse_file(file)
Puppet.debug("importing '#{file}' in environment #{environment}")
parser = Puppet::Parser::Parser.new(environment)
parser.file = file
- parser.parse
+ return parser.parse
end
- # Utility method factored out of load for handling thread-safety.
- # This isn't tested in the specs, because that's basically impossible.
- def import_if_possible(file, current_file = nil)
- @loaded[file] || begin
- case @loading.owner_of(file)
- when :this_thread
- nil
- when :another_thread
- import_if_possible(file,current_file)
- when :nobody
- @loaded[file] = import(file,current_file)
- end
- ensure
- @loading.done_with(file)
+ private
+
+ # Return a list of all file basenames that should be tried in order
+ # to load the object with the given fully qualified name.
+ def name2files(fqname)
+ result = []
+ ary = fqname.split("::")
+ while ary.length > 0
+ result << ary.join(File::SEPARATOR)
+ ary.pop
end
+ return result
end
+
end
diff --git a/lib/puppet/property.rb b/lib/puppet/property.rb
index 282a52cf4..84e1a0360 100644
--- a/lib/puppet/property.rb
+++ b/lib/puppet/property.rb
@@ -55,10 +55,10 @@ class Puppet::Property < Puppet::Parameter
# * <tt>:required_features</tt>: A list of features this value requires.
# * <tt>:event</tt>: The event that should be returned when this value is set.
# * <tt>:call</tt>: When to call any associated block. The default value
- # is ``instead``, which means to call the value instead of calling the
- # provider. You can also specify ``before`` or ``after``, which will
+ # is `instead`, which means to call the value instead of calling the
+ # provider. You can also specify `before` or `after`, which will
# call both the block and the provider, according to the order you specify
- # (the ``first`` refers to when the block is called, not the provider).
+ # (the `first` refers to when the block is called, not the provider).
def self.newvalue(name, options = {}, &block)
value = value_collection.newvalue(name, options, &block)
@@ -181,10 +181,10 @@ class Puppet::Property < Puppet::Parameter
def log(msg)
Puppet::Util::Log.create(
-
+
:level => resource[:loglevel],
:message => msg,
-
+
:source => self
)
end
diff --git a/lib/puppet/provider.rb b/lib/puppet/provider.rb
index 8f993dbc1..4456feb4e 100644
--- a/lib/puppet/provider.rb
+++ b/lib/puppet/provider.rb
@@ -12,7 +12,7 @@ class Puppet::Provider
Puppet::Util.logmethods(self, true)
class << self
- # Include the util module so we have access to things like 'binary'
+ # Include the util module so we have access to things like 'which'
include Puppet::Util, Puppet::Util::Docs
include Puppet::Util::Logging
attr_accessor :name
@@ -43,7 +43,7 @@ class Puppet::Provider
raise Puppet::DevError, "No command #{name} defined for provider #{self.name}"
end
- binary(command)
+ which(command)
end
# Define commands that are not optional.
@@ -205,7 +205,7 @@ class Puppet::Provider
dochook(:defaults) do
if @defaults.length > 0
return " Default for " + @defaults.collect do |f, v|
- "``#{f}`` == ``#{v}``"
+ "`#{f}` == `#{v}`"
end.join(" and ") + "."
end
end
@@ -213,7 +213,7 @@ class Puppet::Provider
dochook(:commands) do
if @commands.length > 0
return " Required binaries: " + @commands.collect do |n, c|
- "``#{c}``"
+ "`#{c}`"
end.join(", ") + "."
end
end
@@ -221,7 +221,7 @@ class Puppet::Provider
dochook(:features) do
if features.length > 0
return " Supported features: " + features.collect do |f|
- "``#{f}``"
+ "`#{f}`"
end.join(", ") + "."
end
end
diff --git a/lib/puppet/provider/confine/exists.rb b/lib/puppet/provider/confine/exists.rb
index 085118b2a..09f94dfd9 100644
--- a/lib/puppet/provider/confine/exists.rb
+++ b/lib/puppet/provider/confine/exists.rb
@@ -6,10 +6,7 @@ class Puppet::Provider::Confine::Exists < Puppet::Provider::Confine
end
def pass?(value)
- if for_binary?
- return false unless value = binary(value)
- end
- value and FileTest.exist?(value)
+ value && (for_binary? ? which(value) : FileTest.exist?(value))
end
def message(value)
diff --git a/lib/puppet/provider/group/groupadd.rb b/lib/puppet/provider/group/groupadd.rb
index e661ddd7f..82ed4c0c7 100644
--- a/lib/puppet/provider/group/groupadd.rb
+++ b/lib/puppet/provider/group/groupadd.rb
@@ -1,7 +1,7 @@
require 'puppet/provider/nameservice/objectadd'
Puppet::Type.type(:group).provide :groupadd, :parent => Puppet::Provider::NameService::ObjectAdd do
- desc "Group management via ``groupadd`` and its ilk.
+ desc "Group management via `groupadd` and its ilk.
The default for most platforms
diff --git a/lib/puppet/provider/group/ldap.rb b/lib/puppet/provider/group/ldap.rb
index 2737feea6..86c72a5d3 100644
--- a/lib/puppet/provider/group/ldap.rb
+++ b/lib/puppet/provider/group/ldap.rb
@@ -1,11 +1,11 @@
require 'puppet/provider/ldap'
Puppet::Type.type(:group).provide :ldap, :parent => Puppet::Provider::Ldap do
- desc "Group management via ``ldap``.
+ desc "Group management via `ldap`.
This provider requires that you have valid values for all of the
- ldap-related settings, including ``ldapbase``. You will also almost
- definitely need settings for ``ldapuser`` and ``ldappassword``, so that
+ ldap-related settings, including `ldapbase`. You will also almost
+ definitely need settings for `ldapuser` and `ldappassword`, so that
your clients can write to ldap.
Note that this provider will automatically generate a GID for you if you do
diff --git a/lib/puppet/provider/group/pw.rb b/lib/puppet/provider/group/pw.rb
index e3dd714ee..a054d1ff1 100644
--- a/lib/puppet/provider/group/pw.rb
+++ b/lib/puppet/provider/group/pw.rb
@@ -1,7 +1,7 @@
require 'puppet/provider/nameservice/pw'
Puppet::Type.type(:group).provide :pw, :parent => Puppet::Provider::NameService::PW do
- desc "Group management via ``pw``.
+ desc "Group management via `pw`.
Only works on FreeBSD.
diff --git a/lib/puppet/provider/host/parsed.rb b/lib/puppet/provider/host/parsed.rb
index 4f15eff3f..a303c4bcf 100644
--- a/lib/puppet/provider/host/parsed.rb
+++ b/lib/puppet/provider/host/parsed.rb
@@ -8,66 +8,36 @@ else
end
- Puppet::Type.type(:host).provide(
- :parsed,
- :parent => Puppet::Provider::ParsedFile,
- :default_target => hosts,
-
- :filetype => :flat
-) do
+Puppet::Type.type(:host).provide(:parsed,:parent => Puppet::Provider::ParsedFile,
+ :default_target => hosts,:filetype => :flat) do
confine :exists => hosts
text_line :comment, :match => /^#/
text_line :blank, :match => /^\s*$/
- record_line :parsed, :fields => %w{ip name host_aliases},
- :optional => %w{host_aliases},
- :rts => true do |line|
- hash = {}
- if line.sub!(/^(\S+)\s+(\S+)\s*/, '')
- hash[:ip] = $1
- hash[:name] = $2
-
- if line.empty?
- hash[:host_aliases] = []
+ record_line :parsed, :fields => %w{ip name host_aliases comment},
+ :optional => %w{host_aliases comment},
+ :match => /^(\S+)\s+(\S+)\s*(.*?)?(?:\s*#\s*(.*))?$/,
+ :post_parse => proc { |hash|
+ # An absent comment should match "comment => ''"
+ hash[:comment] = '' if hash[:comment].nil? or hash[:comment] == :absent
+ unless hash[:host_aliases].nil? or hash[:host_aliases] == :absent
+ hash[:host_aliases] = hash[:host_aliases].split(/\s+/)
else
- line.sub!(/\s*/, '')
- line.sub!(/^([^#]+)\s*/) do |value|
- aliases = $1
- unless aliases =~ /^\s*$/
- hash[:host_aliases] = aliases.split(/\s+/)
- end
-
- ""
- end
+ hash[:host_aliases] = []
end
- else
- raise Puppet::Error, "Could not match '#{line}'"
- end
-
- hash[:host_aliases] = [] if hash[:host_aliases] == ""
-
- return hash
- end
-
- # Convert the current object into a host-style string.
- def self.to_line(hash)
- return super unless hash[:record_type] == :parsed
- [:ip, :name].each do |n|
- raise ArgumentError, "#{n} is a required attribute for hosts" unless hash[n] and hash[n] != :absent
- end
-
- str = "#{hash[:ip]}\t#{hash[:name]}"
-
- if hash.include? :host_aliases and !hash[:host_aliases].empty?
- if hash[:host_aliases].is_a? Array
+ },
+ :to_line => proc { |hash|
+ [:ip, :name].each do |n|
+ raise ArgumentError, "#{n} is a required attribute for hosts" unless hash[n] and hash[n] != :absent
+ end
+ str = "#{hash[:ip]}\t#{hash[:name]}"
+ if hash.include? :host_aliases and !hash[:host_aliases].empty?
str += "\t#{hash[:host_aliases].join("\t")}"
- else
- raise ArgumentError, "Host aliases must be specified as an array"
end
- end
-
- str
- end
+ if hash.include? :comment and !hash[:comment].empty?
+ str += "\t# #{hash[:comment]}"
+ end
+ str
+ }
end
-
diff --git a/lib/puppet/provider/maillist/mailman.rb b/lib/puppet/provider/maillist/mailman.rb
index 4fdc20a69..633642af7 100755
--- a/lib/puppet/provider/maillist/mailman.rb
+++ b/lib/puppet/provider/maillist/mailman.rb
@@ -2,11 +2,11 @@ require 'puppet/provider/parsedfile'
Puppet::Type.type(:maillist).provide(:mailman) do
if [ "CentOS", "RedHat", "Fedora" ].any? { |os| Facter.value(:operatingsystem) == os }
- commands :list_lists => "/usr/lib/mailman/bin/list_lists", :rmlist => "/usr/lib/mailman/bin/rmlist", :newlist => "/usr/lib/mailman/bin/newlist"
+ commands :list_lists => "/usr/lib/mailman/bin/list_lists --bare", :rmlist => "/usr/lib/mailman/bin/rmlist", :newlist => "/usr/lib/mailman/bin/newlist"
commands :mailman => "/usr/lib/mailman/mail/mailman"
else
# This probably won't work for non-Debian installs, but this path is sure not to be in the PATH.
- commands :list_lists => "list_lists", :rmlist => "rmlist", :newlist => "newlist"
+ commands :list_lists => "list_lists --bare", :rmlist => "rmlist", :newlist => "newlist"
commands :mailman => "/var/lib/mailman/mail/mailman"
end
@@ -14,10 +14,9 @@ Puppet::Type.type(:maillist).provide(:mailman) do
# Return a list of existing mailman instances.
def self.instances
- list_lists.split("\n").reject { |line| line.include?("matching mailing lists") }.collect do |line|
- name, description = line.sub(/^\s+/, '').sub(/\s+$/, '').split(/\s+-\s+/)
- description = :absent if description.include?("no description available")
- new(:ensure => :present, :name => name, :description => description)
+ list_lists.split("\n").collect do |line|
+ name = line.strip
+ new(:ensure => :present, :name => name)
end
end
diff --git a/lib/puppet/provider/mcx/mcxcontent.rb b/lib/puppet/provider/mcx/mcxcontent.rb
index cb5adc698..3ad437b53 100644
--- a/lib/puppet/provider/mcx/mcxcontent.rb
+++ b/lib/puppet/provider/mcx/mcxcontent.rb
@@ -53,39 +53,31 @@ Puppet::Type.type(:mcx).provide :mcxcontent, :parent => Puppet::Provider do
confine :operatingsystem => :darwin
defaultfor :operatingsystem => :darwin
- # self.instances is all important.
- # This is the only class method, it returns
- # an array of instances of this class.
def self.instances
mcx_list = []
- for ds_type in TypeMap.keys
+ TypeMap.keys.each do |ds_type|
ds_path = "/Local/Default/#{TypeMap[ds_type]}"
output = dscl 'localhost', '-list', ds_path
member_list = output.split
- for ds_name in member_list
+ member_list.each do |ds_name|
content = mcxexport(ds_type, ds_name)
if content.empty?
Puppet.debug "/#{TypeMap[ds_type]}/#{ds_name} has no MCX data."
else
# This node has MCX data.
- rsrc = self.new(
- :name => "/#{TypeMap[ds_type]}/#{ds_name}",
- :ds_type => ds_type,
- :ds_name => ds_name,
-
- :content => content)
- mcx_list << rsrc
+ mcx_list << self.new(
+ :name => "/#{TypeMap[ds_type]}/#{ds_name}",
+ :ds_type => ds_type,
+ :ds_name => ds_name,
+ :content => content
+ )
end
end
end
mcx_list
end
- private
-
- # mcxexport is used by instances, and therefore
- # a class method.
def self.mcxexport(ds_type, ds_name)
ds_t = TypeMap[ds_type]
ds_n = ds_name.to_s
@@ -93,9 +85,49 @@ Puppet::Type.type(:mcx).provide :mcxcontent, :parent => Puppet::Provider do
dscl 'localhost', '-mcxexport', ds_path
end
+
+ def create
+ self.content=(resource[:content])
+ end
+
+ def destroy
+ ds_parms = get_dsparams
+ ds_t = TypeMap[ds_parms[:ds_type]]
+ ds_n = ds_parms[:ds_name].to_s
+ ds_path = "/Local/Default/#{ds_t}/#{ds_n}"
+
+ dscl 'localhost', '-mcxdelete', ds_path
+ end
+
+ def exists?
+ begin
+ has_mcx?
+ rescue Puppet::ExecutionFailure => e
+ return false
+ end
+ end
+
+ def content
+ ds_parms = get_dsparams
+
+ self.class.mcxexport(ds_parms[:ds_type], ds_parms[:ds_name])
+ end
+
+ def content=(value)
+ # dscl localhost -mcximport
+ ds_parms = get_dsparams
+
+ mcximport(ds_parms[:ds_type], ds_parms[:ds_name], resource[:content])
+ end
+
+ private
+
+ def has_mcx?
+ !content.empty?
+ end
+
def mcximport(ds_type, ds_name, val)
ds_t = TypeMap[ds_type]
- ds_n = ds_name.to_s
ds_path = "/Local/Default/#{ds_t}/#{ds_name}"
tmp = Tempfile.new('puppet_mcx')
@@ -111,33 +143,31 @@ Puppet::Type.type(:mcx).provide :mcxcontent, :parent => Puppet::Provider do
# Given the resource name string, parse ds_type out.
def parse_type(name)
- tmp = name.split('/')[1]
- if ! tmp.is_a? String
+ ds_type = name.split('/')[1]
+ unless ds_type
raise MCXContentProviderException,
"Coult not parse ds_type from resource name '#{name}'. Specify with ds_type parameter."
end
# De-pluralize and downcase.
- tmp = tmp.chop.downcase.to_sym
- if not TypeMap.keys.member? tmp
+ ds_type = ds_type.chop.downcase.to_sym
+ unless TypeMap.key? ds_type
raise MCXContentProviderException,
"Coult not parse ds_type from resource name '#{name}'. Specify with ds_type parameter."
end
- tmp
+ ds_type
end
# Given the resource name string, parse ds_name out.
def parse_name(name)
ds_name = name.split('/')[2]
- if ! ds_name.is_a? String
+ unless ds_name
raise MCXContentProviderException,
"Could not parse ds_name from resource name '#{name}'. Specify with ds_name parameter."
end
ds_name
end
- # Gather ds_type and ds_name from resource or
- # parse it out of the name.
- # This is a private instance method, not a class method.
+ # Gather ds_type and ds_name from resource or parse it out of the name.
def get_dsparams
ds_type = resource[:ds_type]
ds_type ||= parse_type(resource[:name])
@@ -146,60 +176,10 @@ Puppet::Type.type(:mcx).provide :mcxcontent, :parent => Puppet::Provider do
ds_name = resource[:ds_name]
ds_name ||= parse_name(resource[:name])
- rval = {
+ {
:ds_type => ds_type.to_sym,
:ds_name => ds_name,
}
-
- return rval
-
- end
-
- public
-
- def create
- self.content=(resource[:content])
- end
-
- def destroy
- ds_parms = get_dsparams
- ds_t = TypeMap[ds_parms[:ds_type]]
- ds_n = ds_parms[:ds_name].to_s
- ds_path = "/Local/Default/#{ds_t}/#{ds_n}"
-
- dscl 'localhost', '-mcxdelete', ds_path
- end
-
- def exists?
- # JJM Just re-use the content method and see if it's empty.
- begin
- mcx = content
- rescue Puppet::ExecutionFailure => e
- return false
- end
- has_mcx = ! mcx.empty?
- end
-
- def content
- ds_parms = get_dsparams
-
- mcx = self.class.mcxexport(
- ds_parms[:ds_type],
-
- ds_parms[:ds_name])
- mcx
- end
-
- def content=(value)
- # dscl localhost -mcximport
- ds_parms = get_dsparams
-
- mcx = mcximport(
- ds_parms[:ds_type],
- ds_parms[:ds_name],
-
- resource[:content])
- mcx
end
end
diff --git a/lib/puppet/provider/mount.rb b/lib/puppet/provider/mount.rb
index 393ae56c9..8c7b24bd4 100644
--- a/lib/puppet/provider/mount.rb
+++ b/lib/puppet/provider/mount.rb
@@ -41,7 +41,7 @@ module Puppet::Provider::Mount
case platform
when "Darwin"
line =~ / on #{name} / or line =~ %r{ on /private/var/automount#{name}}
- when "Solaris"
+ when "Solaris", "HP-UX"
line =~ /^#{name} on /
else
line =~ / on #{name} /
diff --git a/lib/puppet/provider/nameservice.rb b/lib/puppet/provider/nameservice.rb
index 7339b646e..d57052bd9 100644
--- a/lib/puppet/provider/nameservice.rb
+++ b/lib/puppet/provider/nameservice.rb
@@ -165,6 +165,9 @@ class Puppet::Provider::NameService < Puppet::Provider
begin
execute(self.addcmd)
+ if feature?(:manages_password_age) && (cmd = passcmd)
+ execute(cmd)
+ end
rescue Puppet::ExecutionFailure => detail
raise Puppet::Error, "Could not create #{@resource.class.name} #{@resource.name}: #{detail}"
end
diff --git a/lib/puppet/provider/nameservice/directoryservice.rb b/lib/puppet/provider/nameservice/directoryservice.rb
index 965a2aa60..106d99eb3 100644
--- a/lib/puppet/provider/nameservice/directoryservice.rb
+++ b/lib/puppet/provider/nameservice/directoryservice.rb
@@ -321,6 +321,31 @@ class DirectoryService < Puppet::Provider::NameService
password_hash
end
+ # Unlike most other *nixes, OS X doesn't provide built in functionality
+ # for automatically assigning uids and gids to accounts, so we set up these
+ # methods for consumption by functionality like --mkusers
+ # By default we restrict to a reasonably sane range for system accounts
+ def self.next_system_id(id_type, min_id=20)
+ dscl_args = ['.', '-list']
+ if id_type == 'uid'
+ dscl_args << '/Users' << 'uid'
+ elsif id_type == 'gid'
+ dscl_args << '/Groups' << 'gid'
+ else
+ fail("Invalid id_type #{id_type}. Only 'uid' and 'gid' supported")
+ end
+ dscl_out = dscl(dscl_args)
+ # We're ok with throwing away negative uids here.
+ ids = dscl_out.split.compact.collect { |l| l.to_i if l.match(/^\d+$/) }
+ ids.compact!.sort! { |a,b| a.to_f <=> b.to_f }
+ # We're just looking for an unused id in our sorted array.
+ ids.each_index do |i|
+ next_id = ids[i] + 1
+ return next_id if ids[i+1] != next_id and next_id >= min_id
+ end
+ end
+
+
def ensure=(ensure_value)
super
# We need to loop over all valid properties for the type we're
@@ -422,7 +447,14 @@ class DirectoryService < Puppet::Provider::NameService
# Now we create all the standard properties
Puppet::Type.type(@resource.class.name).validproperties.each do |property|
next if property == :ensure
- if value = @resource.should(property) and value != ""
+ value = @resource.should(property)
+ if property == :gid and value.nil?
+ value = self.class.next_system_id(id_type='gid')
+ end
+ if property == :uid and value.nil?
+ value = self.class.next_system_id(id_type='uid')
+ end
+ if value != "" and not value.nil?
if property == :members
add_members(nil, value)
else
diff --git a/lib/puppet/provider/nameservice/objectadd.rb b/lib/puppet/provider/nameservice/objectadd.rb
index 80c142982..dbb9f306f 100644
--- a/lib/puppet/provider/nameservice/objectadd.rb
+++ b/lib/puppet/provider/nameservice/objectadd.rb
@@ -13,7 +13,8 @@ class ObjectAdd < Puppet::Provider::NameService
end
def modifycmd(param, value)
- cmd = [command(:modify), flag(param), value]
+ cmd = [command(param.to_s =~ /password_.+_age/ ? :password : :modify)]
+ cmd << flag(param) << value
if @resource.allowdupe? && ((param == :uid) || (param == :gid and self.class.name == :groupadd))
cmd << "-o"
end
diff --git a/lib/puppet/provider/package/apple.rb b/lib/puppet/provider/package/apple.rb
index 0946de47f..b5bb9102f 100755
--- a/lib/puppet/provider/package/apple.rb
+++ b/lib/puppet/provider/package/apple.rb
@@ -5,7 +5,7 @@ Puppet::Type.type(:package).provide :apple, :parent => Puppet::Provider::Package
desc "Package management based on OS X's builtin packaging system. This is
essentially the simplest and least functional package system in existence --
it only supports installation; no deletion or upgrades. The provider will
- automatically add the ``.pkg`` extension, so leave that off when specifying
+ automatically add the `.pkg` extension, so leave that off when specifying
the package name."
confine :operatingsystem => :darwin
diff --git a/lib/puppet/provider/package/apt.rb b/lib/puppet/provider/package/apt.rb
index d055e7552..2fc787419 100755
--- a/lib/puppet/provider/package/apt.rb
+++ b/lib/puppet/provider/package/apt.rb
@@ -2,7 +2,7 @@ Puppet::Type.type(:package).provide :apt, :parent => :dpkg, :source => :dpkg do
# Provide sorting functionality
include Puppet::Util::Package
- desc "Package management via ``apt-get``."
+ desc "Package management via `apt-get`."
has_feature :versionable
@@ -14,6 +14,10 @@ Puppet::Type.type(:package).provide :apt, :parent => :dpkg, :source => :dpkg do
ENV['DEBIAN_FRONTEND'] = "noninteractive"
+ # disable common apt helpers to allow non-interactive package installs
+ ENV['APT_LISTBUGS_FRONTEND'] = "none"
+ ENV['APT_LISTCHANGES_FRONTEND'] = "none"
+
# A derivative of DPKG; this is how most people actually manage
# Debian boxes, and the only thing that differs is that it can
# install packages from remote sites.
diff --git a/lib/puppet/provider/package/aptitude.rb b/lib/puppet/provider/package/aptitude.rb
index 557e657a4..8bdf984e6 100755
--- a/lib/puppet/provider/package/aptitude.rb
+++ b/lib/puppet/provider/package/aptitude.rb
@@ -1,5 +1,5 @@
Puppet::Type.type(:package).provide :aptitude, :parent => :apt, :source => :dpkg do
- desc "Package management via ``aptitude``."
+ desc "Package management via `aptitude`."
has_feature :versionable
diff --git a/lib/puppet/provider/package/aptrpm.rb b/lib/puppet/provider/package/aptrpm.rb
index d7842089f..2eb33c72b 100644
--- a/lib/puppet/provider/package/aptrpm.rb
+++ b/lib/puppet/provider/package/aptrpm.rb
@@ -2,7 +2,7 @@ Puppet::Type.type(:package).provide :aptrpm, :parent => :rpm, :source => :rpm do
# Provide sorting functionality
include Puppet::Util::Package
- desc "Package management via ``apt-get`` ported to ``rpm``."
+ desc "Package management via `apt-get` ported to `rpm`."
has_feature :versionable
diff --git a/lib/puppet/provider/package/blastwave.rb b/lib/puppet/provider/package/blastwave.rb
index 9f1f1ec19..e9c84845f 100755
--- a/lib/puppet/provider/package/blastwave.rb
+++ b/lib/puppet/provider/package/blastwave.rb
@@ -1,6 +1,6 @@
# Packaging using Blastwave's pkg-get program.
Puppet::Type.type(:package).provide :blastwave, :parent => :sun, :source => :sun do
- desc "Package management using Blastwave.org's ``pkg-get`` command on Solaris."
+ desc "Package management using Blastwave.org's `pkg-get` command on Solaris."
pkgget = "pkg-get"
pkgget = "/opt/csw/bin/pkg-get" if FileTest.executable?("/opt/csw/bin/pkg-get")
diff --git a/lib/puppet/provider/package/dpkg.rb b/lib/puppet/provider/package/dpkg.rb
index bee63bfba..7b34b09af 100755
--- a/lib/puppet/provider/package/dpkg.rb
+++ b/lib/puppet/provider/package/dpkg.rb
@@ -1,8 +1,8 @@
require 'puppet/provider/package'
Puppet::Type.type(:package).provide :dpkg, :parent => Puppet::Provider::Package do
- desc "Package management via ``dpkg``. Because this only uses ``dpkg``
- and not ``apt``, you must specify the source of any packages you want
+ desc "Package management via `dpkg`. Because this only uses `dpkg`
+ and not `apt`, you must specify the source of any packages you want
to manage."
has_feature :holdable
diff --git a/lib/puppet/provider/package/fink.rb b/lib/puppet/provider/package/fink.rb
index 5cf47860e..db991397a 100755
--- a/lib/puppet/provider/package/fink.rb
+++ b/lib/puppet/provider/package/fink.rb
@@ -2,7 +2,7 @@ Puppet::Type.type(:package).provide :fink, :parent => :dpkg, :source => :dpkg do
# Provide sorting functionality
include Puppet::Util::Package
- desc "Package management via ``fink``."
+ desc "Package management via `fink`."
commands :fink => "/sw/bin/fink"
commands :aptget => "/sw/bin/apt-get"
diff --git a/lib/puppet/provider/package/gem.rb b/lib/puppet/provider/package/gem.rb
index 8d70b756f..19414cec4 100755
--- a/lib/puppet/provider/package/gem.rb
+++ b/lib/puppet/provider/package/gem.rb
@@ -3,7 +3,7 @@ require 'uri'
# Ruby gems support.
Puppet::Type.type(:package).provide :gem, :parent => Puppet::Provider::Package do
- desc "Ruby Gem support. If a URL is passed via ``source``, then that URL is used as the
+ desc "Ruby Gem support. If a URL is passed via `source`, then that URL is used as the
remote gem repository; if a source is present but is not a valid URL, it will be
interpreted as the path to a local gem file. If source is not present at all,
the gem will be installed from the default gem repositories."
diff --git a/lib/puppet/provider/package/openbsd.rb b/lib/puppet/provider/package/openbsd.rb
index ca477e56a..bb07d894a 100755
--- a/lib/puppet/provider/package/openbsd.rb
+++ b/lib/puppet/provider/package/openbsd.rb
@@ -2,8 +2,7 @@ require 'puppet/provider/package'
# Packaging on OpenBSD. Doesn't work anywhere else that I know of.
Puppet::Type.type(:package).provide :openbsd, :parent => Puppet::Provider::Package do
- include Puppet::Util::Execution
- desc "OpenBSD's form of ``pkg_add`` support."
+ desc "OpenBSD's form of `pkg_add` support."
commands :pkginfo => "pkg_info", :pkgadd => "pkg_add", :pkgdelete => "pkg_delete"
@@ -61,18 +60,15 @@ Puppet::Type.type(:package).provide :openbsd, :parent => Puppet::Provider::Packa
"You must specify a package source for BSD packages"
end
- old_ensure = @resource[:ensure]
-
- if @resource[:source] =~ /\/$/
- withenv :PKG_PATH => @resource[:source] do
- @resource[:ensure] = old_ensure if (@resource[:ensure] = get_version) == nil
- full_name = [ @resource[:name], @resource[:ensure], @resource[:flavor] ]
- pkgadd full_name.join('-').chomp('-')
- end
+ if @resource[:source][-1,1] == ::File::PATH_SEPARATOR
+ e_vars = { :PKG_PATH => @resource[:source] }
+ full_name = [ @resource[:name], get_version || @resource[:ensure], @resource[:flavor] ].join('-').chomp('-')
else
- pkgadd @resource[:source]
+ e_vars = {}
+ full_name = @resource[:source]
end
+ Puppet::Util::Execution::withenv(e_vars) { pkgadd full_name }
end
def get_version
diff --git a/lib/puppet/provider/package/rpm.rb b/lib/puppet/provider/package/rpm.rb
index d33a4f2f3..72dc260a4 100755
--- a/lib/puppet/provider/package/rpm.rb
+++ b/lib/puppet/provider/package/rpm.rb
@@ -1,7 +1,7 @@
require 'puppet/provider/package'
# RPM packaging. Should work anywhere that has rpm installed.
Puppet::Type.type(:package).provide :rpm, :source => :rpm, :parent => Puppet::Provider::Package do
- desc "RPM packaging support; should work anywhere with a working ``rpm``
+ desc "RPM packaging support; should work anywhere with a working `rpm`
binary."
has_feature :versionable
diff --git a/lib/puppet/provider/package/rug.rb b/lib/puppet/provider/package/rug.rb
index 7028cc9e5..28729952d 100644
--- a/lib/puppet/provider/package/rug.rb
+++ b/lib/puppet/provider/package/rug.rb
@@ -1,5 +1,5 @@
Puppet::Type.type(:package).provide :rug, :parent => :rpm do
- desc "Support for suse ``rug`` package manager."
+ desc "Support for suse `rug` package manager."
has_feature :versionable
diff --git a/lib/puppet/provider/package/sunfreeware.rb b/lib/puppet/provider/package/sunfreeware.rb
index 53f03ed6e..4745ea1eb 100755
--- a/lib/puppet/provider/package/sunfreeware.rb
+++ b/lib/puppet/provider/package/sunfreeware.rb
@@ -1,7 +1,7 @@
# At this point, it's an exact copy of the Blastwave stuff.
Puppet::Type.type(:package).provide :sunfreeware, :parent => :blastwave, :source => :sun do
- desc "Package management using sunfreeware.com's ``pkg-get`` command on Solaris.
- At this point, support is exactly the same as ``blastwave`` support and
+ desc "Package management using sunfreeware.com's `pkg-get` command on Solaris.
+ At this point, support is exactly the same as `blastwave` support and
has not actually been tested."
commands :pkgget => "pkg-get"
diff --git a/lib/puppet/provider/package/up2date.rb b/lib/puppet/provider/package/up2date.rb
index 5ff32bedc..243bc6c6b 100644
--- a/lib/puppet/provider/package/up2date.rb
+++ b/lib/puppet/provider/package/up2date.rb
@@ -1,5 +1,5 @@
Puppet::Type.type(:package).provide :up2date, :parent => :rpm, :source => :rpm do
- desc "Support for Red Hat's proprietary ``up2date`` package update
+ desc "Support for Red Hat's proprietary `up2date` package update
mechanism."
commands :up2date => "/usr/sbin/up2date-nox"
diff --git a/lib/puppet/provider/package/urpmi.rb b/lib/puppet/provider/package/urpmi.rb
index 88a17ccb4..425d77849 100644
--- a/lib/puppet/provider/package/urpmi.rb
+++ b/lib/puppet/provider/package/urpmi.rb
@@ -1,5 +1,5 @@
Puppet::Type.type(:package).provide :urpmi, :parent => :rpm, :source => :rpm do
- desc "Support via ``urpmi``."
+ desc "Support via `urpmi`."
commands :urpmi => "urpmi", :urpmq => "urpmq", :rpm => "rpm"
if command('rpm')
diff --git a/lib/puppet/provider/package/yum.rb b/lib/puppet/provider/package/yum.rb
index 07f68ddb1..6ed966fbd 100755
--- a/lib/puppet/provider/package/yum.rb
+++ b/lib/puppet/provider/package/yum.rb
@@ -1,5 +1,6 @@
+require 'puppet/util/package'
Puppet::Type.type(:package).provide :yum, :parent => :rpm, :source => :rpm do
- desc "Support via ``yum``."
+ desc "Support via `yum`."
has_feature :versionable
@@ -52,6 +53,7 @@ Puppet::Type.type(:package).provide :yum, :parent => :rpm, :source => :rpm do
should = @resource.should(:ensure)
self.debug "Ensuring => #{should}"
wanted = @resource[:name]
+ operation = :install
# XXX: We don't actually deal with epochs here.
case should
@@ -61,9 +63,14 @@ Puppet::Type.type(:package).provide :yum, :parent => :rpm, :source => :rpm do
else
# Add the package version
wanted += "-#{should}"
+ is = self.query
+ if is && Puppet::Util::Package.versioncmp(should, is[:ensure]) < 0
+ self.debug "Downgrading package #{@resource[:name]} from version #{is[:ensure]} to #{should}"
+ operation = :downgrade
+ end
end
- output = yum "-d", "0", "-e", "0", "-y", :install, wanted
+ output = yum "-d", "0", "-e", "0", "-y", operation, wanted
is = self.query
raise Puppet::Error, "Could not find package #{self.name}" unless is
diff --git a/lib/puppet/provider/package/zypper.rb b/lib/puppet/provider/package/zypper.rb
index d56c72549..f129ef6e6 100644
--- a/lib/puppet/provider/package/zypper.rb
+++ b/lib/puppet/provider/package/zypper.rb
@@ -1,5 +1,5 @@
Puppet::Type.type(:package).provide :zypper, :parent => :rpm do
- desc "Support for SuSE ``zypper`` package manager. Found in SLES10sp2+ and SLES11"
+ desc "Support for SuSE `zypper` package manager. Found in SLES10sp2+ and SLES11"
has_feature :versionable
diff --git a/lib/puppet/provider/service/base.rb b/lib/puppet/provider/service/base.rb
index 70d764187..211e7f964 100755
--- a/lib/puppet/provider/service/base.rb
+++ b/lib/puppet/provider/service/base.rb
@@ -5,7 +5,7 @@ Puppet::Type.type(:service).provide :base do
minimum you can specify is a binary for starting the process, and this
same binary will be searched for in the process table to stop the
service. It is preferable to specify start, stop, and status commands,
- akin to how you would do so using ``init``.
+ akin to how you would do so using `init`.
"
diff --git a/lib/puppet/provider/service/bsd.rb b/lib/puppet/provider/service/bsd.rb
index 2e00c33f1..e2a0e35f7 100644
--- a/lib/puppet/provider/service/bsd.rb
+++ b/lib/puppet/provider/service/bsd.rb
@@ -1,8 +1,8 @@
# Manage FreeBSD services.
Puppet::Type.type(:service).provide :bsd, :parent => :init do
- desc "FreeBSD's (and probably NetBSD?) form of ``init``-style service management.
+ desc "FreeBSD's (and probably NetBSD?) form of `init`-style service management.
- Uses ``rc.conf.d`` for service enabling and disabling.
+ Uses `rc.conf.d` for service enabling and disabling.
"
diff --git a/lib/puppet/provider/service/debian.rb b/lib/puppet/provider/service/debian.rb
index 4379f1b59..3d09e2849 100755
--- a/lib/puppet/provider/service/debian.rb
+++ b/lib/puppet/provider/service/debian.rb
@@ -1,10 +1,10 @@
# Manage debian services. Start/stop is the same as InitSvc, but enable/disable
# is special.
Puppet::Type.type(:service).provide :debian, :parent => :init do
- desc "Debian's form of ``init``-style management.
+ desc "Debian's form of `init`-style management.
The only difference is that this supports service enabling and disabling
- via ``update-rc.d`` and determines enabled status via ``invoke-rc.d``.
+ via `update-rc.d` and determines enabled status via `invoke-rc.d`.
"
diff --git a/lib/puppet/provider/service/freebsd.rb b/lib/puppet/provider/service/freebsd.rb
index 10970e4da..f8c7134f0 100644
--- a/lib/puppet/provider/service/freebsd.rb
+++ b/lib/puppet/provider/service/freebsd.rb
@@ -18,6 +18,9 @@ Puppet::Type.type(:service).provide :freebsd, :parent => :init do
def rcvar
rcvar = execute([self.initscript, :rcvar], :failonfail => true, :squelch => false)
rcvar = rcvar.split("\n")
+ rcvar.delete_if {|str| str =~ /^#\s*$/}
+ rcvar[1] = rcvar[1].gsub(/^\$/, '')
+ rcvar
end
# Extract service name
@@ -44,7 +47,7 @@ Puppet::Type.type(:service).provide :freebsd, :parent => :init do
def rcvar_value
value = self.rcvar[1]
self.error("No rcvar value found in rcvar") if value.nil?
- value = value.gsub!(/(.*)_enable=\"?(.*)\"?/, '\2')
+ value = value.gsub!(/(.*)_enable="?(\w+)"?/, '\2')
self.error("rcvar value is empty") if value.nil?
self.debug("rcvar value is #{value}")
value
@@ -78,7 +81,7 @@ Puppet::Type.type(:service).provide :freebsd, :parent => :init do
# Add a new setting to the rc files
def rc_add(service, rcvar, yesno)
- append = "\n\# Added by Puppet\n#{rcvar}_enable=\"#{yesno}\""
+ append = "\# Added by Puppet\n#{rcvar}_enable=\"#{yesno}\"\n"
# First, try the one-file-per-service style
if File.exists?(@@rcconf_dir)
File.open(@@rcconf_dir + "/#{service}", File::WRONLY | File::APPEND | File::CREAT, 0644) {
diff --git a/lib/puppet/provider/service/gentoo.rb b/lib/puppet/provider/service/gentoo.rb
index 08250a06a..382c74267 100644
--- a/lib/puppet/provider/service/gentoo.rb
+++ b/lib/puppet/provider/service/gentoo.rb
@@ -1,9 +1,9 @@
# Manage gentoo services. Start/stop is the same as InitSvc, but enable/disable
# is special.
Puppet::Type.type(:service).provide :gentoo, :parent => :init do
- desc "Gentoo's form of ``init``-style service management.
+ desc "Gentoo's form of `init`-style service management.
- Uses ``rc-update`` for service enabling and disabling.
+ Uses `rc-update` for service enabling and disabling.
"
diff --git a/lib/puppet/provider/service/init.rb b/lib/puppet/provider/service/init.rb
index 6abff12db..447c01aa5 100755
--- a/lib/puppet/provider/service/init.rb
+++ b/lib/puppet/provider/service/init.rb
@@ -3,9 +3,9 @@
Puppet::Type.type(:service).provide :init, :parent => :base do
desc "Standard init service management.
- This provider assumes that the init script has no ``status`` command,
+ This provider assumes that the init script has no `status` command,
because so few scripts do, so you need to either provide a status
- command or specify via ``hasstatus`` that one already exists in the
+ command or specify via `hasstatus` that one already exists in the
init script.
"
diff --git a/lib/puppet/provider/service/launchd.rb b/lib/puppet/provider/service/launchd.rb
index 970359539..1632edabf 100644
--- a/lib/puppet/provider/service/launchd.rb
+++ b/lib/puppet/provider/service/launchd.rb
@@ -38,6 +38,7 @@ Puppet::Type.type(:service).provide :launchd, :parent => :base do
commands :launchctl => "/bin/launchctl"
commands :sw_vers => "/usr/bin/sw_vers"
+ commands :plutil => "/usr/bin/plutil"
defaultfor :operatingsystem => :darwin
confine :operatingsystem => :darwin
@@ -52,6 +53,12 @@ Puppet::Type.type(:service).provide :launchd, :parent => :base do
Launchd_Overrides = "/var/db/launchd.db/com.apple.launchd/overrides.plist"
+ # Read a plist, whether its format is XML or in Apple's "binary1"
+ # format.
+ def self.read_plist(path)
+ Plist::parse_xml(plutil('-convert', 'xml1', '-o', '/dev/stdout', path))
+ end
+
# returns a label => path map for either all jobs, or just a single
# job if the label is specified
def self.jobsearch(label=nil)
@@ -62,8 +69,7 @@ Puppet::Type.type(:service).provide :launchd, :parent => :base do
next if f =~ /^\..*$/
next if FileTest.directory?(f)
fullpath = File.join(path, f)
- job = Plist::parse_xml(fullpath)
- if job and job.has_key?("Label")
+ if FileTest.file?(fullpath) and job = read_plist(fullpath) and job.has_key?("Label")
if job["Label"] == label
return { label => fullpath }
else
@@ -118,8 +124,11 @@ Puppet::Type.type(:service).provide :launchd, :parent => :base do
def plist_from_label(label)
job = self.class.jobsearch(label)
job_path = job[label]
- job_plist = Plist::parse_xml(job_path)
- raise Puppet::Error.new("Unable to parse launchd plist at path: #{job_path}") if not job_plist
+ if FileTest.file?(job_path)
+ job_plist = self.class.read_plist(job_path)
+ else
+ raise Puppet::Error.new("Unable to parse launchd plist at path: #{job_path}")
+ end
[job_path, job_plist]
end
@@ -200,9 +209,7 @@ Puppet::Type.type(:service).provide :launchd, :parent => :base do
job_plist_disabled = job_plist["Disabled"] if job_plist.has_key?("Disabled")
if self.class.get_macosx_version_major == "10.6":
- overrides = Plist::parse_xml(Launchd_Overrides)
-
- unless overrides.nil?
+ if FileTest.file?(Launchd_Overrides) and overrides = self.class.read_plist(Launchd_Overrides)
if overrides.has_key?(resource[:name])
overrides_disabled = overrides[resource[:name]]["Disabled"] if overrides[resource[:name]].has_key?("Disabled")
end
@@ -227,7 +234,7 @@ Puppet::Type.type(:service).provide :launchd, :parent => :base do
# versions this is stored in the job plist itself.
def enable
if self.class.get_macosx_version_major == "10.6"
- overrides = Plist::parse_xml(Launchd_Overrides)
+ overrides = self.class.read_plist(Launchd_Overrides)
overrides[resource[:name]] = { "Disabled" => false }
Plist::Emit.save_plist(overrides, Launchd_Overrides)
else
@@ -242,7 +249,7 @@ Puppet::Type.type(:service).provide :launchd, :parent => :base do
def disable
if self.class.get_macosx_version_major == "10.6"
- overrides = Plist::parse_xml(Launchd_Overrides)
+ overrides = self.class.read_plist(Launchd_Overrides)
overrides[resource[:name]] = { "Disabled" => true }
Plist::Emit.save_plist(overrides, Launchd_Overrides)
else
diff --git a/lib/puppet/provider/service/redhat.rb b/lib/puppet/provider/service/redhat.rb
index 3ca67d66f..e851a488d 100755
--- a/lib/puppet/provider/service/redhat.rb
+++ b/lib/puppet/provider/service/redhat.rb
@@ -1,9 +1,9 @@
# Manage Red Hat services. Start/stop uses /sbin/service and enable/disable uses chkconfig
Puppet::Type.type(:service).provide :redhat, :parent => :init, :source => :init do
- desc "Red Hat's (and probably many others) form of ``init``-style service management:
+ desc "Red Hat's (and probably many others) form of `init`-style service management:
- Uses ``chkconfig`` for service enabling and disabling.
+ Uses `chkconfig` for service enabling and disabling.
"
diff --git a/lib/puppet/provider/service/upstart.rb b/lib/puppet/provider/service/upstart.rb
new file mode 100755
index 000000000..54971eeac
--- /dev/null
+++ b/lib/puppet/provider/service/upstart.rb
@@ -0,0 +1,73 @@
+Puppet::Type.type(:service).provide :upstart, :parent => :init do
+ desc "Ubuntu service manager upstart.
+
+ This provider manages upstart jobs which have replaced initd.
+
+ See:
+ * http://upstart.ubuntu.com/
+ "
+ # confine to :ubuntu for now because I haven't tested on other platforms
+ confine :operatingsystem => :ubuntu #[:ubuntu, :fedora, :debian]
+
+ commands :start => "/sbin/start",
+ :stop => "/sbin/stop",
+ :restart => "/sbin/restart",
+ :status_exec => "/sbin/status",
+ :initctl => "/sbin/initctl"
+
+ # upstart developer haven't implemented initctl enable/disable yet:
+ # http://www.linuxplanet.com/linuxplanet/tutorials/7033/2/
+ # has_feature :enableable
+
+ def self.instances
+ instances = []
+ execpipe("#{command(:initctl)} list") { |process|
+ process.each { |line|
+ # needs special handling of services such as network-interface:
+ # initctl list:
+ # network-interface (lo) start/running
+ # network-interface (eth0) start/running
+ # network-interface-security start/running
+ name = \
+ if matcher = line.match(/^(network-interface)\s\(([^\)]+)\)/)
+ "#{matcher[1]} INTERFACE=#{matcher[2]}"
+ else
+ line.split.first
+ end
+ instances << new(:name => name)
+ }
+ }
+ instances
+ end
+
+ def startcmd
+ [command(:start), @resource[:name]]
+ end
+
+ def stopcmd
+ [command(:stop), @resource[:name]]
+ end
+
+ def restartcmd
+ (@resource[:hasrestart] == :true) && [command(:restart), @resource[:name]]
+ end
+
+ def status
+ # allows user override of status command
+ if @resource[:status]
+ ucommand(:status, false)
+ if $?.exitstatus == 0
+ return :running
+ else
+ return :stopped
+ end
+ else
+ output = status_exec(@resource[:name].split)
+ if (! $?.nil?) && (output =~ /start\//)
+ return :running
+ else
+ return :stopped
+ end
+ end
+ end
+end
diff --git a/lib/puppet/provider/ssh_authorized_key/parsed.rb b/lib/puppet/provider/ssh_authorized_key/parsed.rb
index 82f6b8881..6a3855c0e 100644
--- a/lib/puppet/provider/ssh_authorized_key/parsed.rb
+++ b/lib/puppet/provider/ssh_authorized_key/parsed.rb
@@ -61,6 +61,13 @@ require 'puppet/provider/parsedfile'
Dir.mkdir(dir, dir_perm)
File.chown(uid, nil, dir)
end
+
+ # ParsedFile usually calls backup_target much later in the flush process,
+ # but our SUID makes that fail to open filebucket files for writing.
+ # Fortunately, there's already logic to make sure it only ever happens once,
+ # so calling it here supresses the later attempt by our superclass's flush method.
+ self.class.backup_target(target)
+
Puppet::Util::SUIDManager.asuser(@resource.should(:user)) { super }
File.chown(uid, nil, target)
File.chmod(file_perm, target)
diff --git a/lib/puppet/provider/user/hpux.rb b/lib/puppet/provider/user/hpux.rb
index 50506c4cd..983970935 100644
--- a/lib/puppet/provider/user/hpux.rb
+++ b/lib/puppet/provider/user/hpux.rb
@@ -26,5 +26,4 @@ Puppet::Type.type(:user).provide :hpuxuseradd, :parent => :useradd do
def modifycmd(param,value)
super.insert(1,"-F")
end
-
end
diff --git a/lib/puppet/provider/user/ldap.rb b/lib/puppet/provider/user/ldap.rb
index df082c569..75a9667b3 100644
--- a/lib/puppet/provider/user/ldap.rb
+++ b/lib/puppet/provider/user/ldap.rb
@@ -1,10 +1,10 @@
require 'puppet/provider/ldap'
Puppet::Type.type(:user).provide :ldap, :parent => Puppet::Provider::Ldap do
- desc "User management via ``ldap``. This provider requires that you
+ desc "User management via `ldap`. This provider requires that you
have valid values for all of the ldap-related settings,
- including ``ldapbase``. You will also almost definitely need settings
- for ``ldapuser`` and ``ldappassword``, so that your clients can write
+ including `ldapbase`. You will also almost definitely need settings
+ for `ldapuser` and `ldappassword`, so that your clients can write
to ldap.
Note that this provider will automatically generate a UID for you if
diff --git a/lib/puppet/provider/user/pw.rb b/lib/puppet/provider/user/pw.rb
index 345d924bf..a5988cad1 100644
--- a/lib/puppet/provider/user/pw.rb
+++ b/lib/puppet/provider/user/pw.rb
@@ -1,7 +1,7 @@
require 'puppet/provider/nameservice/pw'
Puppet::Type.type(:user).provide :pw, :parent => Puppet::Provider::NameService::PW do
- desc "User management via ``pw`` on FreeBSD."
+ desc "User management via `pw` on FreeBSD."
commands :pw => "pw"
has_features :manages_homedir, :allows_duplicates
diff --git a/lib/puppet/provider/user/user_role_add.rb b/lib/puppet/provider/user/user_role_add.rb
index ea1b01b3b..2377f9e65 100644
--- a/lib/puppet/provider/user/user_role_add.rb
+++ b/lib/puppet/provider/user/user_role_add.rb
@@ -2,17 +2,19 @@ require 'puppet/util/user_attr'
Puppet::Type.type(:user).provide :user_role_add, :parent => :useradd, :source => :useradd do
- desc "User management inherits ``useradd`` and adds logic to manage roles on Solaris using roleadd."
+ desc "User management inherits `useradd` and adds logic to manage roles on Solaris using roleadd."
defaultfor :operatingsystem => :solaris
- commands :add => "useradd", :delete => "userdel", :modify => "usermod", :role_add => "roleadd", :role_delete => "roledel", :role_modify => "rolemod"
+ commands :add => "useradd", :delete => "userdel", :modify => "usermod", :password => "passwd", :role_add => "roleadd", :role_delete => "roledel", :role_modify => "rolemod"
options :home, :flag => "-d", :method => :dir
options :comment, :method => :gecos
options :groups, :flag => "-G"
options :roles, :flag => "-R"
options :auths, :flag => "-A"
options :profiles, :flag => "-P"
+ options :password_min_age, :flag => "-n"
+ options :password_max_age, :flag => "-x"
verify :gid, "GID must be an integer" do |value|
value.is_a? Integer
@@ -22,14 +24,14 @@ Puppet::Type.type(:user).provide :user_role_add, :parent => :useradd, :source =>
value !~ /\s/
end
- has_features :manages_homedir, :allows_duplicates, :manages_solaris_rbac, :manages_passwords
+ has_features :manages_homedir, :allows_duplicates, :manages_solaris_rbac, :manages_passwords, :manages_password_age
#must override this to hand the keyvalue pairs
def add_properties
cmd = []
Puppet::Type.type(:user).validproperties.each do |property|
#skip the password because we can't create it with the solaris useradd
- next if [:ensure, :password].include?(property)
+ next if [:ensure, :password, :password_min_age, :password_max_age].include?(property)
# 1680 Now you can set the hashed passwords on solaris:lib/puppet/provider/user/user_role_add.rb
# the value needs to be quoted, mostly because -c might
# have spaces in it
@@ -79,6 +81,9 @@ Puppet::Type.type(:user).provide :user_role_add, :parent => :useradd, :source =>
run(transition("normal"), "transition role to")
else
run(addcmd, "create")
+ if cmd = passcmd
+ run(cmd, "change password policy for")
+ end
end
# added to handle case when password is specified
self.password = @resource[:password] if @resource[:password]
@@ -140,14 +145,23 @@ Puppet::Type.type(:user).provide :user_role_add, :parent => :useradd, :source =>
run([command(:modify)] + build_keys_cmd(keys_hash) << @resource[:name], "modify attribute key pairs")
end
- #Read in /etc/shadow, find the line for this user (skipping comments, because who knows) and return the hashed pw (the second entry)
+ #Read in /etc/shadow, find the line for this user (skipping comments, because who knows) and return it
#No abstraction, all esoteric knowledge of file formats, yay
+ def shadow_entry
+ return @shadow_entry if defined? @shadow_entry
+ @shadow_entry = File.readlines("/etc/shadow").reject { |r| r =~ /^[^\w]/ }.collect { |l| l.chomp.split(':') }.find { |user, _| user == @resource[:name] }
+ end
+
def password
- #got perl?
- if ary = File.readlines("/etc/shadow").reject { |r| r =~ /^[^\w]/}.collect { |l| l.split(':')[0..1] }.find { |user, passwd| user == @resource[:name] }
- pass = ary[1]
- end
- pass
+ shadow_entry[1] if shadow_entry
+ end
+
+ def password_min_age
+ shadow_entry ? shadow_entry[3] : :absent
+ end
+
+ def password_max_age
+ shadow_entry ? shadow_entry[4] : :absent
end
#Read in /etc/shadow, find the line for our used and rewrite it with the new pw
diff --git a/lib/puppet/provider/user/useradd.rb b/lib/puppet/provider/user/useradd.rb
index ec87694d7..ba406cc63 100644
--- a/lib/puppet/provider/user/useradd.rb
+++ b/lib/puppet/provider/user/useradd.rb
@@ -1,13 +1,15 @@
require 'puppet/provider/nameservice/objectadd'
Puppet::Type.type(:user).provide :useradd, :parent => Puppet::Provider::NameService::ObjectAdd do
- desc "User management via ``useradd`` and its ilk. Note that you will need to install the ``Shadow Password`` Ruby library often known as ruby-libshadow to manage user passwords."
+ desc "User management via `useradd` and its ilk. Note that you will need to install the `Shadow Password` Ruby library often known as ruby-libshadow to manage user passwords."
- commands :add => "useradd", :delete => "userdel", :modify => "usermod"
+ commands :add => "useradd", :delete => "userdel", :modify => "usermod", :password => "chage"
options :home, :flag => "-d", :method => :dir
options :comment, :method => :gecos
options :groups, :flag => "-G"
+ options :password_min_age, :flag => "-m"
+ options :password_max_age, :flag => "-M"
verify :gid, "GID must be an integer" do |value|
value.is_a? Integer
@@ -17,9 +19,9 @@ Puppet::Type.type(:user).provide :useradd, :parent => Puppet::Provider::NameServ
value !~ /\s/
end
- has_features :manages_homedir, :allows_duplicates
+ has_features :manages_homedir, :allows_duplicates, :manages_expiry
- has_feature :manages_passwords if Puppet.features.libshadow?
+ has_features :manages_passwords, :manages_password_age if Puppet.features.libshadow?
def check_allow_dup
@resource.allowdupe? ? ["-o"] : []
@@ -35,10 +37,20 @@ Puppet::Type.type(:user).provide :useradd, :parent => Puppet::Provider::NameServ
cmd
end
+ def check_manage_expiry
+ cmd = []
+ if @resource[:expiry]
+ cmd << "-e #{@resource[:expiry]}"
+ end
+
+ cmd
+ end
+
def add_properties
cmd = []
Puppet::Type.type(:user).validproperties.each do |property|
next if property == :ensure
+ next if property.to_s =~ /password_.+_age/
# the value needs to be quoted, mostly because -c might
# have spaces in it
if value = @resource.should(property) and value != ""
@@ -53,9 +65,37 @@ Puppet::Type.type(:user).provide :useradd, :parent => Puppet::Provider::NameServ
cmd += add_properties
cmd += check_allow_dup
cmd += check_manage_home
+ cmd += check_manage_expiry
cmd << @resource[:name]
end
+ def passcmd
+ age_limits = [:password_min_age, :password_max_age].select { |property| @resource.should(property) }
+ if age_limits.empty?
+ nil
+ else
+ [command(:password),age_limits.collect { |property| [flag(property), @resource.should(property)]}, @resource[:name]].flatten
+ end
+ end
+
+ def password_min_age
+ if Puppet.features.libshadow?
+ if ent = Shadow::Passwd.getspnam(@resource.name)
+ return ent.sp_min
+ end
+ end
+ :absent
+ end
+
+ def password_max_age
+ if Puppet.features.libshadow?
+ if ent = Shadow::Passwd.getspnam(@resource.name)
+ return ent.sp_max
+ end
+ end
+ :absent
+ end
+
# Retrieve the password using the Shadow Password library
def password
if Puppet.features.libshadow?
diff --git a/lib/puppet/rails.rb b/lib/puppet/rails.rb
index 414b1bc18..74805bb6f 100644
--- a/lib/puppet/rails.rb
+++ b/lib/puppet/rails.rb
@@ -2,6 +2,7 @@
require 'facter'
require 'puppet'
+require 'logger'
module Puppet::Rails
TIME_DEBUG = true
@@ -22,9 +23,8 @@ module Puppet::Rails
ActiveRecord::Base.logger.level = Logger::DEBUG
end
- if (::ActiveRecord::VERSION::MAJOR == 2 and ::ActiveRecord::VERSION::MINOR <= 1)
- ActiveRecord::Base.allow_concurrency = true
- end
+ # As of ActiveRecord 2.2 allow_concurrency has been deprecated and no longer has any effect.
+ ActiveRecord::Base.allow_concurrency = true if Puppet::Util.activerecord_version < 2.2
ActiveRecord::Base.verify_active_connections!
@@ -52,21 +52,17 @@ module Puppet::Rails
args[:port] = Puppet[:dbport] unless Puppet[:dbport].to_s.empty?
args[:username] = Puppet[:dbuser] unless Puppet[:dbuser].to_s.empty?
args[:password] = Puppet[:dbpassword] unless Puppet[:dbpassword].to_s.empty?
+ args[:pool] = Puppet[:dbconnections].to_i unless Puppet[:dbconnections].to_i <= 0
args[:database] = Puppet[:dbname]
args[:reconnect]= true
socket = Puppet[:dbsocket]
args[:socket] = socket unless socket.to_s.empty?
-
- connections = Puppet[:dbconnections].to_i
- args[:pool] = connections if connections > 0
when "oracle_enhanced":
args[:database] = Puppet[:dbname] unless Puppet[:dbname].to_s.empty?
args[:username] = Puppet[:dbuser] unless Puppet[:dbuser].to_s.empty?
args[:password] = Puppet[:dbpassword] unless Puppet[:dbpassword].to_s.empty?
-
- connections = Puppet[:dbconnections].to_i
- args[:pool] = connections if connections > 0
+ args[:pool] = Puppet[:dbconnections].to_i unless Puppet[:dbconnections].to_i <= 0
else
raise ArgumentError, "Invalid db adapter #{adapter}"
end
diff --git a/lib/puppet/rails/host.rb b/lib/puppet/rails/host.rb
index 986cebd0a..b9dea2a3d 100644
--- a/lib/puppet/rails/host.rb
+++ b/lib/puppet/rails/host.rb
@@ -16,16 +16,6 @@ class Puppet::Rails::Host < ActiveRecord::Base
belongs_to :source_file
has_many :resources, :dependent => :destroy, :class_name => "Puppet::Rails::Resource"
- # If the host already exists, get rid of its objects
- def self.clean(host)
- if obj = self.find_by_name(host)
- obj.rails_objects.clear
- return obj
- else
- return nil
- end
- end
-
def self.from_puppet(node)
host = find_by_name(node.name) || new(:name => node.name)
@@ -38,63 +28,6 @@ class Puppet::Rails::Host < ActiveRecord::Base
host
end
- # Store our host in the database.
- def self.store(node, resources)
- args = {}
-
- host = nil
- railsmark "Stored node" do
- transaction do
- #unless host = find_by_name(name)
-
- debug_benchmark("Searched for host")do
- unless host = find_by_name(node.name)
- host = new(:name => node.name)
- end
- end
- if ip = node.parameters["ipaddress"]
- host.ip = ip
- end
-
- if env = node.environment
- host.environment = env
- end
-
- # Store the facts into the database.
- host.merge_facts(node.parameters)
-
- debug_benchmark("Handled resources") {
- host.merge_resources(resources)
- }
-
- host.last_compile = Time.now
-
- debug_benchmark("Saved host") {
- host.save
- }
- end
-
- end
-
- # This only runs if time debugging is enabled.
- write_benchmarks
-
- host
- end
-
- # Return the value of a fact.
- def fact(name)
-
- if fv = self.fact_values.find(
- :all, :include => :fact_name,
-
- :conditions => "fact_names.name = '#{name}'")
- return fv
- else
- return nil
- end
- end
-
# returns a hash of fact_names.name => [ fact_values ] for this host.
# Note that 'fact_values' is actually a list of the value instances, not
# just actual values.
@@ -305,11 +238,6 @@ class Puppet::Rails::Host < ActiveRecord::Base
end
end
- def update_connect_time
- self.last_connect = Time.now
- save
- end
-
def to_puppet
node = Puppet::Node.new(self.name)
{"ip" => "ipaddress", "environment" => "environment"}.each do |myparam, itsparam|
diff --git a/lib/puppet/reference/configuration.rb b/lib/puppet/reference/configuration.rb
index bfa2cb802..e6a8dc20f 100644
--- a/lib/puppet/reference/configuration.rb
+++ b/lib/puppet/reference/configuration.rb
@@ -33,7 +33,7 @@ config = Puppet::Util::Reference.newreference(:configuration, :depth => 1, :doc
# Leave out the section information; it was apparently confusing people.
#str += "- **Section**: #{object.section}\n"
unless val == ""
- str += "- **Default**: #{val}\n"
+ str += "- *Default*: #{val}\n"
end
str += "\n"
end
@@ -42,12 +42,11 @@ config = Puppet::Util::Reference.newreference(:configuration, :depth => 1, :doc
end
config.header = "
-Specifying Configuration Parameters
------------------------------------
+## Specifying Configuration Parameters
-On The Command-Line
-+++++++++++++++++++
-Every Puppet executable (with the exception of ``puppetdoc``) accepts all of
+### On The Command-Line
+
+Every Puppet executable (with the exception of `puppetdoc`) accepts all of
the parameters below, but not all of the arguments make sense for every executable.
I have tried to be as thorough as possible in the descriptions of the
@@ -55,60 +54,59 @@ arguments, so it should be obvious whether an argument is appropriate or not.
These parameters can be supplied to the executables either as command-line
options or in the configuration file. For instance, the command-line
-invocation below would set the configuration directory to ``/private/puppet``::
+invocation below would set the configuration directory to `/private/puppet`:
- $ puppet agent --confdir=/private/puppet
+ $ puppet agent --confdir=/private/puppet
Note that boolean options are turned on and off with a slightly different
-syntax on the command line::
+syntax on the command line:
- $ puppet agent --storeconfigs
+ $ puppet agent --storeconfigs
- $ puppet agent --no-storeconfigs
+ $ puppet agent --no-storeconfigs
The invocations above will enable and disable, respectively, the storage of
the client configuration.
-Configuration Files
-+++++++++++++++++++
+### Configuration Files
+
As mentioned above, the configuration parameters can also be stored in a
configuration file, located in the configuration directory. As root, the
-default configuration directory is ``/etc/puppet``, and as a regular user, the
-default configuration directory is ``~user/.puppet``. As of 0.23.0, all
-executables look for ``puppet.conf`` in their configuration directory
+default configuration directory is `/etc/puppet`, and as a regular user, the
+default configuration directory is `~user/.puppet`. As of 0.23.0, all
+executables look for `puppet.conf` in their configuration directory
(although they previously looked for separate files). For example,
-``puppet.conf`` is located at ``/etc/puppet/puppet.conf`` as root and
-``~user/.puppet/puppet.conf`` as a regular user by default.
+`puppet.conf` is located at `/etc/puppet/puppet.conf` as `root` and
+`~user/.puppet/puppet.conf` as a regular user by default.
+
+All executables will set any parameters set within the `[main]` section,
+and each executable will also use one of the `[master]`, `[agent]`.
-All executables will set any parameters set within the ``main`` section,
-and each executable will also use one of the ``master``, ``agent``, or
-``user`` sections.
+#### File Format
-File Format
-'''''''''''
The file follows INI-style formatting. Here is an example of a very simple
-``puppet.conf`` file::
+`puppet.conf` file:
- [main]
- confdir = /private/puppet
- storeconfigs = true
+ [main]
+ confdir = /private/puppet
+ storeconfigs = true
Note that boolean parameters must be explicitly specified as `true` or
`false` as seen above.
If you need to change file parameters (e.g., reset the mode or owner), do
-so within curly braces on the same line::
+so within curly braces on the same line:
- [main]
- myfile = /tmp/whatever {owner = root, mode = 644}
+ [main]
+ myfile = /tmp/whatever {owner = root, mode = 644}
If you're starting out with a fresh configuration, you may wish to let
the executable generate a template configuration file for you by invoking
the executable in question with the `--genconfig` command. The executable
will print a template configuration to standard output, which can be
-redirected to a file like so::
+redirected to a file like so:
- $ puppet agent --genconfig > /etc/puppet/puppet.conf
+ $ puppet agent --genconfig > /etc/puppet/puppet.conf
Note that this invocation will replace the contents of any pre-existing
`puppet.conf` file, so make a backup of your present config if it contains
@@ -117,28 +115,28 @@ valuable information.
Like the `--genconfig` argument, the executables also accept a `--genmanifest`
argument, which will generate a manifest that can be used to manage all of
Puppet's directories and files and prints it to standard output. This can
-likewise be redirected to a file::
+likewise be redirected to a file:
- $ puppet agent --genmanifest > /etc/puppet/manifests/site.pp
+ $ puppet agent --genmanifest > /etc/puppet/manifests/site.pp
Puppet can also create user and group accounts for itself (one `puppet` group
-and one `puppet` user) if it is invoked as `root` with the `--mkusers` argument::
+and one `puppet` user) if it is invoked as `root` with the `--mkusers` argument:
- $ puppet agent --mkusers
+ $ puppet agent --mkusers
-Signals
--------
-The ``puppet agent`` and ``puppet master`` executables catch some signals for special
-handling. Both daemons catch (``SIGHUP``), which forces the server to restart
-tself. Predictably, interrupt and terminate (``SIGINT`` and ``SIGTERM``) will shut
-down the server, whether it be an instance of ``puppet agent`` or ``puppet master``.
+## Signals
-Sending the ``SIGUSR1`` signal to an instance of ``puppet agent`` will cause it to
+The `puppet agent` and `puppet master` executables catch some signals for special
+handling. Both daemons catch (`SIGHUP`), which forces the server to restart
+tself. Predictably, interrupt and terminate (`SIGINT` and `SIGTERM`) will shut
+down the server, whether it be an instance of `puppet agent` or `puppet master`.
+
+Sending the `SIGUSR1` signal to an instance of `puppet agent` will cause it to
immediately begin a new configuration transaction with the server. This
-signal has no effect on ``puppet master``.
+signal has no effect on `puppet master`.
+
+## Configuration Parameter Reference
-Configuration Parameter Reference
----------------------------------
Below is a list of all documented parameters. Not all of them are valid with all
Puppet executables, but the executables will ignore any inappropriate values.
diff --git a/lib/puppet/reference/indirection.rb b/lib/puppet/reference/indirection.rb
index d14510c16..e5b076508 100644
--- a/lib/puppet/reference/indirection.rb
+++ b/lib/puppet/reference/indirection.rb
@@ -8,12 +8,12 @@ reference = Puppet::Util::Reference.newreference :indirection, :doc => "Indirect
Puppet::Indirector::Indirection.instances.sort { |a,b| a.to_s <=> b.to_s }.each do |indirection|
ind = Puppet::Indirector::Indirection.instance(indirection)
name = indirection.to_s.capitalize
- text += indirection.to_s + "\n" + ("-" * name.length) + "\n\n"
+ text += "## " + indirection.to_s + "\n\n"
text += ind.doc + "\n\n"
Puppet::Indirector::Terminus.terminus_classes(ind.name).sort { |a,b| a.to_s <=> b.to_s }.each do |terminus|
- text += terminus.to_s + "\n" + ("+" * terminus.to_s.length) + "\n\n"
+ text += "### " + terminus.to_s + "\n\n"
term_class = Puppet::Indirector::Terminus.terminus_class(ind.name, terminus)
@@ -26,9 +26,8 @@ end
reference.header = "This is the list of all indirections, their associated terminus classes, and how you select between them.
-In general, the appropriate terminus class is selected by the application for you (e.g., ``puppet agent`` would always use the ``rest``
-terminus for most of its indirected classes), but some classes are tunable via normal settings. These will have ``terminus setting``
-documentation listed with them.
+In general, the appropriate terminus class is selected by the application for you (e.g., `puppet agent` would always use the `rest`
+terminus for most of its indirected classes), but some classes are tunable via normal settings. These will have `terminus setting` documentation listed with them.
"
diff --git a/lib/puppet/reference/metaparameter.rb b/lib/puppet/reference/metaparameter.rb
index 6a319f1c2..c16a1d33a 100644
--- a/lib/puppet/reference/metaparameter.rb
+++ b/lib/puppet/reference/metaparameter.rb
@@ -9,16 +9,17 @@ metaparameter = Puppet::Util::Reference.newreference :metaparameter, :doc => "Al
}
str = %{
- Metaparameters
- --------------
- Metaparameters are parameters that work with any resource type; they are part of the
- Puppet framework itself rather than being part of the implementation of any
- given instance. Thus, any defined metaparameter can be used with any instance
- in your manifest, including defined components.
- Available Metaparameters
- ++++++++++++++++++++++++
- }
+# Metaparameters
+
+Metaparameters are parameters that work with any resource type; they are part of the
+Puppet framework itself rather than being part of the implementation of any
+given instance. Thus, any defined metaparameter can be used with any instance
+in your manifest, including defined components.
+
+## Available Metaparameters
+
+}
begin
params = []
Puppet::Type.eachmetaparam { |param|
@@ -29,14 +30,6 @@ metaparameter = Puppet::Util::Reference.newreference :metaparameter, :doc => "Al
a.to_s <=> b.to_s
}.each { |param|
str += paramwrap(param.to_s, scrub(Puppet::Type.metaparamdoc(param)), :level => 4)
- #puts "<dt>#{param}</dt>"
- #puts tab(1) + Puppet::Type.metaparamdoc(param).scrub.indent($tab)gsub(/\n\s*/,' ')
- #puts "<dd>"
- #puts indent(scrub(Puppet::Type.metaparamdoc(param)), $tab)
- #puts scrub(Puppet::Type.metaparamdoc(param))
- #puts "</dd>"
-
- #puts ""
}
rescue => detail
puts detail.backtrace
diff --git a/lib/puppet/reference/network.rb b/lib/puppet/reference/network.rb
index 15e4f6769..fda7931fb 100644
--- a/lib/puppet/reference/network.rb
+++ b/lib/puppet/reference/network.rb
@@ -29,11 +29,11 @@ on the server, and the client knows how to call the handler's methods
appropriately.
Most handlers are meant to be started on the server, usually within
-``puppet master``, and the clients are mostly started on the client,
-usually within ``puppet agent``.
+`puppet master`, and the clients are mostly started on the client,
+usually within `puppet agent`.
You can find the server-side handler for each interface at
-``puppet/network/handler/<name>.rb`` and the client class at
-``puppet/network/client/<name>.rb``.
+`puppet/network/handler/<name>.rb` and the client class at
+`puppet/network/client/<name>.rb`.
"
diff --git a/lib/puppet/reference/providers.rb b/lib/puppet/reference/providers.rb
index ef33a559b..c85ad23ab 100644
--- a/lib/puppet/reference/providers.rb
+++ b/lib/puppet/reference/providers.rb
@@ -47,7 +47,7 @@ providers = Puppet::Util::Reference.newreference :providers, :title => "Provider
# Add the suitability note
if missing = provider.suitable?(false) and missing.empty?
- data << "**X**"
+ data << "*X*"
suit = true
functional = true
else
@@ -86,7 +86,7 @@ providers = Puppet::Util::Reference.newreference :providers, :title => "Provider
# Add a note for every feature
features.each do |feature|
if provider.features.include?(feature)
- data << "**X**"
+ data << "*X*"
else
data << ""
end
@@ -95,7 +95,7 @@ providers = Puppet::Util::Reference.newreference :providers, :title => "Provider
ret += h(type.name.to_s + "_", 2)
- ret += ".. _#{type.name}: #{"http://docs.puppetlabs.com/references/stable/type.html##{type.name}"}\n\n"
+ ret += "[#{type.name}](#{"http://docs.puppetlabs.com/references/stable/type.html##{type.name}"})\n\n"
ret += option("Default provider", default)
ret += doctable(headers, table_data)
@@ -111,7 +111,7 @@ providers = Puppet::Util::Reference.newreference :providers, :title => "Provider
ret
end
providers.header = "
-Puppet resource types are usually backed by multiple implementations called ``providers``,
+Puppet resource types are usually backed by multiple implementations called `providers`,
which handle variance between platforms and tools.
Different providers are suitable or unsuitable on different platforms based on things
diff --git a/lib/puppet/reference/report.rb b/lib/puppet/reference/report.rb
index 481ca2dc1..47fc779ab 100644
--- a/lib/puppet/reference/report.rb
+++ b/lib/puppet/reference/report.rb
@@ -7,16 +7,15 @@ end
report.header = "
Puppet clients can report back to the server after each transaction. This
transaction report is sent as a YAML dump of the
-``Puppet::Transaction::Report`` class and includes every log message that was
+`Puppet::Transaction::Report` class and includes every log message that was
generated during the transaction along with as many metrics as Puppet knows how
-to collect. See `ReportsAndReporting Reports and Reporting`:trac:
-for more information on how to use reports.
+to collect. See [Reports and Reporting](http://projects.puppetlabs.com/projects/puppet/wiki/Reports_And_Reporting) for more information on how to use reports.
Currently, clients default to not sending in reports; you can enable reporting
-by setting the ``report`` parameter to true.
+by setting the `report` parameter to true.
-To use a report, set the ``reports`` parameter on the server; multiple
-reports must be comma-separated. You can also specify ``none`` to disable
+To use a report, set the `reports` parameter on the server; multiple
+reports must be comma-separated. You can also specify `none` to disable
reports entirely.
Puppet provides multiple report handlers that will process client reports:
diff --git a/lib/puppet/reference/type.rb b/lib/puppet/reference/type.rb
index be8742edc..b423387e9 100644
--- a/lib/puppet/reference/type.rb
+++ b/lib/puppet/reference/type.rb
@@ -5,34 +5,34 @@ type = Puppet::Util::Reference.newreference :type, :doc => "All Puppet resource
Puppet::Type.eachtype { |type|
next if type.name == :puppet
next if type.name == :component
+ next if type.name == :whit
types[type.name] = type
}
str = %{
- Resource Types
- --------------
+## Resource Types
- - The *namevar* is the parameter used to uniquely identify a type instance.
+- The *namevar* is the parameter used to uniquely identify a type instance.
This is the parameter that gets assigned when a string is provided before
the colon in a type declaration. In general, only developers will need to
- worry about which parameter is the ``namevar``.
+ worry about which parameter is the `namevar`.
- In the following code::
+ In the following code:
- file { "/etc/passwd":
- owner => root,
- group => root,
- mode => 644
- }
+ file { "/etc/passwd":
+ owner => root,
+ group => root,
+ mode => 644
+ }
- ``/etc/passwd`` is considered the title of the file object (used for things like
- dependency handling), and because ``path`` is the namevar for ``file``, that
- string is assigned to the ``path`` parameter.
+ `/etc/passwd` is considered the title of the file object (used for things like
+ dependency handling), and because `path` is the namevar for `file`, that
+ string is assigned to the `path` parameter.
- *Parameters* determine the specific configuration of the instance. They either
directly modify the system (internally, these are called properties) or they affect
- how the instance behaves (e.g., adding a search path for ``exec`` instances or determining recursion on ``file`` instances).
+ how the instance behaves (e.g., adding a search path for `exec` instances or determining recursion on `file` instances).
- *Providers* provide low-level functionality for a given resource type. This is
usually in the form of calling out to external commands.
diff --git a/lib/puppet/reports/http.rb b/lib/puppet/reports/http.rb
index f1a74195d..7ac54dfbd 100644
--- a/lib/puppet/reports/http.rb
+++ b/lib/puppet/reports/http.rb
@@ -5,7 +5,7 @@ require 'uri'
Puppet::Reports.register_report(:http) do
desc <<-DESC
- Send report information via HTTP to the ``reporturl``. Each host sends
+ Send report information via HTTP to the `reporturl`. Each host sends
its report as a YAML dump and this sends this YAML to a client via HTTP POST.
The YAML is the `report` parameter of the request."
DESC
diff --git a/lib/puppet/reports/rrdgraph.rb b/lib/puppet/reports/rrdgraph.rb
index 9fbeb60e8..517fa8f03 100644
--- a/lib/puppet/reports/rrdgraph.rb
+++ b/lib/puppet/reports/rrdgraph.rb
@@ -1,12 +1,11 @@
Puppet::Reports.register_report(:rrdgraph) do
desc "Graph all available data about hosts using the RRD library. You
must have the Ruby RRDtool library installed to use this report, which
- you can get from `the RubyRRDTool RubyForge page`_. This package may also
- be available as ``ruby-rrd`` or ``rrdtool-ruby`` in your distribution's package
- management system. The library and/or package will both require the binary
- ``rrdtool`` package from your distribution to be installed.
-
- .. _the RubyRRDTool RubyForge page: http://rubyforge.org/projects/rubyrrdtool/
+ you can get from
+ [the RubyRRDTool RubyForge page](http://rubyforge.org/projects/rubyrrdtool/).
+ This package may also be available as `ruby-rrd` or `rrdtool-ruby` in your
+ distribution's package management system. The library and/or package will both
+ require the binary `rrdtool` package from your distribution to be installed.
This report will create, manage, and graph RRD database files for each
of the metrics generated during transactions, and it will create a
@@ -14,12 +13,12 @@ Puppet::Reports.register_report(:rrdgraph) do
point, it will not create a common index file to display links to
all hosts.
- All RRD files and graphs get created in the ``rrddir`` directory. If
+ All RRD files and graphs get created in the `rrddir` directory. If
you want to serve these publicly, you should be able to just alias that
directory in a web server.
- If you really know what you're doing, you can tune the ``rrdinterval``,
- which defaults to the ``runinterval``."
+ If you really know what you're doing, you can tune the `rrdinterval`,
+ which defaults to the `runinterval`."
def hostdir
@hostdir ||= File.join(Puppet[:rrddir], self.host)
@@ -123,7 +122,7 @@ Puppet::Reports.register_report(:rrdgraph) do
# that means we record the total time, the config time, and that's about
# it. We should probably send each type's time as a separate metric.
def timeclean(metric)
- metric.values = metric.values.find_all { |name, label, value| [:total, :config_retrieval].include?(name) }
+ metric.values = metric.values.find_all { |name, label, value| ['total', 'config_retrieval'].include?(name.to_s) }
end
end
diff --git a/lib/puppet/reports/store.rb b/lib/puppet/reports/store.rb
index 65159fc07..30f24591c 100644
--- a/lib/puppet/reports/store.rb
+++ b/lib/puppet/reports/store.rb
@@ -2,7 +2,7 @@ require 'puppet'
Puppet::Reports.register_report(:store) do
desc "Store the yaml report on disk. Each host sends its report as a YAML dump
- and this just stores the file on disk, in the ``reportdir`` directory.
+ and this just stores the file on disk, in the `reportdir` directory.
These files collect quickly -- one every half hour -- so it is a good idea
to perform some maintenance on them if you use this report (it's the only
@@ -19,7 +19,7 @@ Puppet::Reports.register_report(:store) do
:owner => 'service',
:group => 'service'
},
-
+
:noop => [false, "Used by settings internally."]
)
diff --git a/lib/puppet/reports/tagmail.rb b/lib/puppet/reports/tagmail.rb
index 652104096..e17143e2f 100644
--- a/lib/puppet/reports/tagmail.rb
+++ b/lib/puppet/reports/tagmail.rb
@@ -6,12 +6,12 @@ require 'time'
Puppet::Reports.register_report(:tagmail) do
desc "This report sends specific log messages to specific email addresses
- based on the tags in the log messages. See the
- `UsingTags tag documentation`:trac: for more information
- on tags.
+ based on the tags in the log messages.
- To use this report, you must create a ``tagmail.conf`` (in the location
- specified by ``tagmap``). This is a simple file that maps tags to
+ See the [UsingTags tag documentation](http://projects.puppetlabs.com/projects/puppet/wiki/Using_Tags) for more information on tags.
+
+ To use this report, you must create a `tagmail.conf` (in the location
+ specified by `tagmap`). This is a simple file that maps tags to
email addresses: Any log messages in the report that match the specified
tags will be sent to the specified email addresses.
@@ -20,21 +20,20 @@ Puppet::Reports.register_report(:tagmail) do
the email addresses by a colon, and the email addresses should also
be comma-separated.
- Lastly, there is an ``all`` tag that will always match all log messages.
+ Lastly, there is an `all` tag that will always match all log messages.
- Here is an example tagmail.conf::
+ Here is an example `tagmail.conf`:
- all: me@domain.com
- webserver, !mailserver: httpadmins@domain.com
+ all: me@domain.com
+ webserver, !mailserver: httpadmins@domain.com
- This will send all messages to ``me@domain.com``, and all messages from
- webservers that are not also from mailservers to ``httpadmins@domain.com``.
+ This will send all messages to `me@domain.com`, and all messages from
+ webservers that are not also from mailservers to `httpadmins@domain.com`.
If you are using anti-spam controls, such as grey-listing, on your mail
- server you should whitelist the sending email (controlled by ``reportform`` configuration option) to ensure your email is not discarded as spam.
+ server you should whitelist the sending email (controlled by `reportform` configuration option) to ensure your email is not discarded as spam.
"
-
# Find all matching messages.
def match(taglists)
matching_logs = []
@@ -85,7 +84,7 @@ Puppet::Reports.register_report(:tagmail) do
pos = []
neg = []
taglist.sub(/\s+$/,'').split(/\s*,\s*/).each do |tag|
- unless tag =~ /^!?[-\w]+$/
+ unless tag =~ /^!?[-\w\.]+$/
raise ArgumentError, "Invalid tag #{tag.inspect}"
end
case tag
diff --git a/lib/puppet/resource.rb b/lib/puppet/resource.rb
index 96d22e414..4f0d50750 100644
--- a/lib/puppet/resource.rb
+++ b/lib/puppet/resource.rb
@@ -13,7 +13,7 @@ class Puppet::Resource
extend Puppet::Util::Pson
include Enumerable
attr_accessor :file, :line, :catalog, :exported, :virtual, :validate_parameters, :strict
- attr_reader :namespaces
+ attr_reader :type, :title
require 'puppet/indirector'
extend Puppet::Indirector
@@ -80,6 +80,18 @@ class Puppet::Resource
end
end
+ def yaml_property_munge(x)
+ case x
+ when Hash
+ x.inject({}) { |h,kv|
+ k,v = kv
+ h[k] = self.class.value_to_pson_data(v)
+ h
+ }
+ else self.class.value_to_pson_data(x)
+ end
+ end
+
def to_pson(*args)
to_pson_data_hash.to_pson(*args)
end
@@ -154,33 +166,42 @@ class Puppet::Resource
end
end
+ # This stub class is only needed for serialization compatibility with 0.25.x
+ class Reference
+ attr_accessor :type,:title
+ def initialize(type,title)
+ @type,@title = type,title
+ end
+ end
+
# Create our resource.
def initialize(type, title = nil, attributes = {})
@parameters = {}
- @namespaces = [""]
- # Set things like namespaces and strictness first.
+ # Set things like strictness first.
attributes.each do |attr, value|
next if attr == :parameters
send(attr.to_s + "=", value)
end
- # We do namespaces first, and use tmp variables, so our title
- # canonicalization works (i.e., namespaces are set and resource
- # types can be looked up)
- tmp_type, tmp_title = extract_type_and_title(type, title)
- self.type = tmp_type
- self.title = tmp_title
+ @type, @title = extract_type_and_title(type, title)
+
+ @type = munge_type_name(@type)
+
+ if @type == "Class"
+ @title = :main if @title == ""
+ @title = munge_type_name(@title)
+ end
if params = attributes[:parameters]
extract_parameters(params)
end
- resolve_type_and_title
-
tag(self.type)
tag(self.title) if valid_tag?(self.title)
+ @reference = Reference.new(@type,@title) # for serialization compatibility with 0.25.x
+
raise ArgumentError, "Invalid resource type #{type}" if strict? and ! resource_type
end
@@ -193,17 +214,12 @@ class Puppet::Resource
return(catalog ? catalog.resource(to_s) : nil)
end
- def title=(value)
- @unresolved_title = value
- @title = nil
- end
-
def resource_type
- @resource_type ||= case type
- when "Class"; find_hostclass(title)
- when "Node"; find_node(title)
+ case type
+ when "Class"; known_resource_types.hostclass(title == :main ? "" : title)
+ when "Node"; known_resource_types.node(title)
else
- find_resource_type(type)
+ Puppet::Type.type(type.to_s.downcase.to_sym) || known_resource_types.definition(type)
end
end
@@ -314,28 +330,6 @@ class Puppet::Resource
self
end
- # We have to lazy-evaluate this.
- def title=(value)
- @title = nil
- @unresolved_title = value
- end
-
- # We have to lazy-evaluate this.
- def type=(value)
- @type = nil
- @unresolved_type = value || "Class"
- end
-
- def title
- resolve_type_and_title unless @title
- @title
- end
-
- def type
- resolve_type_and_title unless @type
- @type
- end
-
def valid_parameter?(name)
resource_type.valid_parameter?(name)
end
@@ -346,29 +340,6 @@ class Puppet::Resource
private
- def find_node(name)
- known_resource_types.node(name)
- end
-
- def find_hostclass(title)
- name = title == :main ? "" : title
- known_resource_types.find_hostclass(namespaces, name)
- end
-
- def find_resource_type(type)
- # It still works fine without the type == 'class' short-cut, but it is a lot slower.
- return nil if ["class", "node"].include? type.to_s.downcase
- find_builtin_resource_type(type) || find_defined_resource_type(type)
- end
-
- def find_builtin_resource_type(type)
- Puppet::Type.type(type.to_s.downcase.to_sym)
- end
-
- def find_defined_resource_type(type)
- known_resource_types.find_definition(namespaces, type.to_s.downcase)
- end
-
# Produce a canonical method name.
def parameter_name(param)
param = param.to_s.downcase.to_sym
@@ -378,10 +349,6 @@ class Puppet::Resource
param
end
- def namespaces=(ns)
- @namespaces = Array(ns)
- end
-
# The namevar for our resource type. If the type doesn't exist,
# always use :name.
def namevar
@@ -428,54 +395,9 @@ class Puppet::Resource
value.to_s.split("::").collect { |s| s.capitalize }.join("::")
end
- # This is an annoyingly complicated method for resolving qualified
- # types as necessary, and putting them in type or title attributes.
- def resolve_type_and_title
- if @unresolved_type
- @type = resolve_type
- @unresolved_type = nil
- end
- if @unresolved_title
- @title = resolve_title
- @unresolved_title = nil
- end
- end
-
- def resolve_type
- case type = munge_type_name(@unresolved_type)
- when "Class", "Node";
- type
- else
- # Otherwise, some kind of builtin or defined resource type
- munge_type_name( (r = find_resource_type(type)) ? r.name : type)
- end
- end
-
- # This method only works if resolve_type was called first
- def resolve_title
- case @type
- when "Node"; return @unresolved_title
- when "Class";
- resolve_title_for_class(@unresolved_title)
- else
- @unresolved_title
- end
- end
-
- def resolve_title_for_class(title)
- if title == "" or title == :main
- return :main
- end
-
- if klass = find_hostclass(title)
- result = klass.name
- end
- munge_type_name(result || title)
- end
-
def parse_title
h = {}
- type = find_resource_type(@type)
+ type = resource_type
if type.respond_to? :title_patterns
type.title_patterns.each { |regexp, symbols_and_lambdas|
if captures = regexp.match(title.to_s)
diff --git a/lib/puppet/resource/catalog.rb b/lib/puppet/resource/catalog.rb
index 4b4342d11..a8668d844 100644
--- a/lib/puppet/resource/catalog.rb
+++ b/lib/puppet/resource/catalog.rb
@@ -57,7 +57,7 @@ class Puppet::Resource::Catalog < Puppet::SimpleGraph
end
def title_key_for_ref( ref )
- ref =~ /^([\w:]+)\[(.*)\]$/m
+ ref =~ /^([-\w:]+)\[(.*)\]$/m
[$1, $2]
end
diff --git a/lib/puppet/resource/type.rb b/lib/puppet/resource/type.rb
index 85c0979c1..77824845d 100644
--- a/lib/puppet/resource/type.rb
+++ b/lib/puppet/resource/type.rb
@@ -13,8 +13,8 @@ class Puppet::Resource::Type
RESOURCE_SUPERTYPES = [:hostclass, :node, :definition]
- attr_accessor :file, :line, :doc, :code, :ruby_code, :parent, :resource_type_collection, :module_name
- attr_reader :type, :namespace, :arguments, :behaves_like
+ attr_accessor :file, :line, :doc, :code, :ruby_code, :parent, :resource_type_collection
+ attr_reader :type, :namespace, :arguments, :behaves_like, :module_name
RESOURCE_SUPERTYPES.each do |t|
define_method("#{t}?") { self.type == t }
@@ -69,6 +69,7 @@ class Puppet::Resource::Type
end
scope = subscope(scope, resource) unless resource.title == :main
+ scope.compiler.add_class(name) unless definition?
set_resource_parameters(resource, scope)
@@ -91,6 +92,8 @@ class Puppet::Resource::Type
end
set_arguments(options[:arguments])
+
+ @module_name = options[:module_name]
end
# This is only used for node names, and really only when the node name
@@ -137,21 +140,15 @@ class Puppet::Resource::Type
end
end
- # Make an instance of our resource type. This is only possible
- # for those classes and nodes that don't have any arguments, and is
- # only useful for things like the 'include' function.
- def mk_plain_resource(scope)
+ # Make an instance of the resource type, and place it in the catalog
+ # if it isn't in the catalog already. This is only possible for
+ # classes and nodes. No parameters are be supplied--if this is a
+ # parameterized class, then all parameters take on their default
+ # values.
+ def ensure_in_catalog(scope)
type == :definition and raise ArgumentError, "Cannot create resources for defined resource types"
resource_type = type == :hostclass ? :class : :node
- # Make sure our parent class has been evaluated, if we have one.
- if parent
- parent_resource = scope.catalog.resource(resource_type, parent)
- unless parent_resource
- parent_type(scope).mk_plain_resource(scope)
- end
- end
-
# Do nothing if the resource already exists; this makes sure we don't
# get multiple copies of the class resource, which helps provide the
# singleton nature of classes.
@@ -160,11 +157,22 @@ class Puppet::Resource::Type
end
resource = Puppet::Parser::Resource.new(resource_type, name, :scope => scope, :source => self)
+ instantiate_resource(scope, resource)
scope.compiler.add_resource(scope, resource)
- scope.catalog.tag(*resource.tags)
resource
end
+ def instantiate_resource(scope, resource)
+ # Make sure our parent class has been evaluated, if we have one.
+ if parent && !scope.catalog.resource(resource.type, parent)
+ parent_type(scope).ensure_in_catalog(scope)
+ end
+
+ if ['Class', 'Node'].include? resource.type
+ scope.catalog.tag(*resource.tags)
+ end
+ end
+
def name
return @name unless @name.is_a?(Regexp)
@name.source.downcase.gsub(/[^-\w:.]/,'').sub(/^\.+/,'')
@@ -174,12 +182,29 @@ class Puppet::Resource::Type
@name.is_a?(Regexp)
end
+ # MQR TODO:
+ #
+ # The change(s) introduced by the fix for #4270 are mostly silly & should be
+ # removed, though we didn't realize it at the time. If it can be established/
+ # ensured that nodes never call parent_type and that resource_types are always
+ # (as they should be) members of exactly one resource_type_collection the
+ # following method could / should be replaced with:
+ #
+ # def parent_type
+ # @parent_type ||= parent && (
+ # resource_type_collection.find_or_load([name],parent,type.to_sym) ||
+ # fail Puppet::ParseError, "Could not find parent resource type '#{parent}' of type #{type} in #{resource_type_collection.environment}"
+ # )
+ # end
+ #
+ # ...and then the rest of the changes around passing in scope reverted.
+ #
def parent_type(scope = nil)
return nil unless parent
unless @parent_type
raise "Must pass scope to parent_type when called first time" unless scope
- unless @parent_type = scope.environment.known_resource_types.send("find_#{type}", scope.namespaces, parent)
+ unless @parent_type = scope.environment.known_resource_types.send("find_#{type}", [name], parent)
fail Puppet::ParseError, "Could not find parent resource type '#{parent}' of type #{type} in #{scope.environment}"
end
end
@@ -215,8 +240,13 @@ class Puppet::Resource::Type
resource[param] = value
end
- scope.setvar("title", resource.title) unless set.include? :title
- scope.setvar("name", resource.name) unless set.include? :name
+ if @type == :hostclass
+ scope.setvar("title", resource.title.to_s.downcase) unless set.include? :title
+ scope.setvar("name", resource.name.to_s.downcase ) unless set.include? :name
+ else
+ scope.setvar("title", resource.title ) unless set.include? :title
+ scope.setvar("name", resource.name ) unless set.include? :name
+ end
scope.setvar("module_name", module_name) if module_name and ! set.include? :module_name
if caller_name = scope.parent_module_name and ! set.include?(:caller_module_name)
diff --git a/lib/puppet/resource/type_collection.rb b/lib/puppet/resource/type_collection.rb
index 6a933362f..a96927613 100644
--- a/lib/puppet/resource/type_collection.rb
+++ b/lib/puppet/resource/type_collection.rb
@@ -19,6 +19,12 @@ class Puppet::Resource::TypeCollection
@watched_files = {}
end
+ def import_ast(ast, modname)
+ ast.instantiate(modname).each do |instance|
+ add(instance)
+ end
+ end
+
def <<(thing)
add(thing)
self
@@ -92,50 +98,8 @@ class Puppet::Resource::TypeCollection
@definitions[munge_name(name)]
end
- def find(namespaces, name, type)
- #Array("") == [] for some reason
- namespaces = [namespaces] unless namespaces.is_a?(Array)
-
- if r = find_fully_qualified(name, type)
- return r
- end
-
- namespaces.each do |namespace|
- ary = namespace.split("::")
-
- while ary.length > 0
- tmp_namespace = ary.join("::")
- if r = find_partially_qualified(tmp_namespace, name, type)
- return r
- end
-
- # Delete the second to last object, which reduces our namespace by one.
- ary.pop
- end
-
- if result = send(type, name)
- return result
- end
- end
- nil
- end
-
- def find_or_load(namespaces, name, type)
- name = name.downcase
- namespaces = [namespaces] unless namespaces.is_a?(Array)
- namespaces = namespaces.collect { |ns| ns.downcase }
-
- # This could be done in the load_until, but the knowledge seems to
- # belong here.
- if r = find(namespaces, name, type)
- return r
- end
-
- loader.load_until(namespaces, name) { find(namespaces, name, type) }
- end
-
def find_node(namespaces, name)
- find("", name, :node)
+ @nodes[munge_name(name)]
end
def find_hostclass(namespaces, name)
@@ -152,23 +116,6 @@ class Puppet::Resource::TypeCollection
end
end
- def perform_initial_import
- parser = Puppet::Parser::Parser.new(environment)
- if code = Puppet.settings.uninterpolated_value(:code, environment.to_s) and code != ""
- parser.string = code
- else
- file = Puppet.settings.value(:manifest, environment.to_s)
- return unless File.exist?(file)
- parser.file = file
- end
- parser.parse
- rescue => detail
- msg = "Could not parse for environment #{environment}: #{detail}"
- error = Puppet::Error.new(msg)
- error.set_backtrace(detail.backtrace)
- raise error
- end
-
def stale?
@watched_files.values.detect { |file| file.changed? }
end
@@ -197,12 +144,52 @@ class Puppet::Resource::TypeCollection
private
- def find_fully_qualified(name, type)
- send(type, name.sub(/^::/, ''))
+ # Return a list of all possible fully-qualified names that might be
+ # meant by the given name, in the context of namespaces.
+ def resolve_namespaces(namespaces, name)
+ name = name.downcase
+ if name =~ /^::/
+ # name is explicitly fully qualified, so just return it, sans
+ # initial "::".
+ return [name.sub(/^::/, '')]
+ end
+ if name == ""
+ # The name "" has special meaning--it always refers to a "main"
+ # hostclass which contains all toplevel resources.
+ return [""]
+ end
+
+ namespaces = [namespaces] unless namespaces.is_a?(Array)
+ namespaces = namespaces.collect { |ns| ns.downcase }
+
+ result = []
+ namespaces.each do |namespace|
+ ary = namespace.split("::")
+
+ # Search each namespace nesting in innermost-to-outermost order.
+ while ary.length > 0
+ result << "#{ary.join("::")}::#{name}"
+ ary.pop
+ end
+
+ # Finally, search the toplevel namespace.
+ result << name
+ end
+
+ return result.uniq
end
- def find_partially_qualified(namespace, name, type)
- send(type, [namespace, name].join("::"))
+ # Resolve namespaces and find the given object. Autoload it if
+ # necessary.
+ def find_or_load(namespaces, name, type)
+ resolve_namespaces(namespaces, name).each do |fqname|
+ if result = send(type, fqname) || loader.try_load_fqname(type, fqname)
+ return result
+ end
+ end
+
+ # Nothing found.
+ return nil
end
def munge_name(name)
diff --git a/lib/puppet/simple_graph.rb b/lib/puppet/simple_graph.rb
index 945b1beb3..6d153b46d 100644
--- a/lib/puppet/simple_graph.rb
+++ b/lib/puppet/simple_graph.rb
@@ -7,123 +7,45 @@ require 'set'
# A hopefully-faster graph class to replace the use of GRATR.
class Puppet::SimpleGraph
- # An internal class for handling a vertex's edges.
- class VertexWrapper
- attr_accessor :in, :out, :vertex
-
- # Remove all references to everything.
- def clear
- @adjacencies[:in].clear
- @adjacencies[:out].clear
- @vertex = nil
- end
-
- def initialize(vertex)
- @vertex = vertex
- @adjacencies = {:in => {}, :out => {}}
- end
-
- # Find adjacent vertices or edges.
- def adjacent(options)
- direction = options[:direction] || :out
- options[:type] ||= :vertices
-
- return send(direction.to_s + "_edges") if options[:type] == :edges
-
- @adjacencies[direction].keys.reject { |vertex| @adjacencies[direction][vertex].empty? }
- end
-
- # Add an edge to our list.
- def add_edge(direction, edge)
- opposite_adjacencies(direction, edge) << edge
- end
-
- # Return all known edges.
- def edges
- in_edges + out_edges
- end
-
- # Test whether we share an edge with a given vertex.
- def has_edge?(direction, vertex)
- return(vertex_adjacencies(direction, vertex).length > 0 ? true : false)
- end
-
- # Create methods for returning the degree and edges.
- [:in, :out].each do |direction|
- # LAK:NOTE If you decide to create methods for directly
- # testing the degree, you'll have to get the values and flatten
- # the results -- you might have duplicate edges, which can give
- # a false impression of what the degree is. That's just
- # as expensive as just getting the edge list, so I've decided
- # to only add this method.
- define_method("#{direction}_edges") do
- @adjacencies[direction].values.inject([]) { |total, adjacent| total += adjacent.to_a; total }
- end
- end
-
- # The other vertex in the edge.
- def other_vertex(direction, edge)
- case direction
- when :in; edge.source
- else
- edge.target
- end
- end
-
- # Remove an edge from our list. Assumes that we've already checked
- # that the edge is valid.
- def remove_edge(direction, edge)
- opposite_adjacencies(direction, edge).delete(edge)
- end
-
- def to_s
- vertex.to_s
- end
-
- private
-
- # These methods exist so we don't need a Hash with a default proc.
-
- # Look up the adjacencies for a vertex at the other end of an
- # edge.
- def opposite_adjacencies(direction, edge)
- opposite_vertex = other_vertex(direction, edge)
- vertex_adjacencies(direction, opposite_vertex)
- end
-
- # Look up the adjacencies for a given vertex.
- def vertex_adjacencies(direction, vertex)
- @adjacencies[direction][vertex] ||= Set.new
- @adjacencies[direction][vertex]
- end
- end
-
+ #
+ # All public methods of this class must maintain (assume ^ ensure) the following invariants, where "=~=" means
+ # equiv. up to order:
+ #
+ # @in_to.keys =~= @out_to.keys =~= all vertices
+ # @in_to.values.collect { |x| x.values }.flatten =~= @out_from.values.collect { |x| x.values }.flatten =~= all edges
+ # @in_to[v1][v2] =~= @out_from[v2][v1] =~= all edges from v1 to v2
+ # @in_to [v].keys =~= vertices with edges leading to v
+ # @out_from[v].keys =~= vertices with edges leading from v
+ # no operation may shed reference loops (for gc)
+ # recursive operation must scale with the depth of the spanning trees, or better (e.g. no recursion over the set
+ # of all vertices, etc.)
+ #
+ # This class is intended to be used with DAGs. However, if the
+ # graph has a cycle, it will not cause non-termination of any of the
+ # algorithms. The topsort method detects and reports cycles.
+ #
def initialize
- @vertices = {}
- @edges = []
+ @in_to = {}
+ @out_from = {}
+ @upstream_from = {}
+ @downstream_from = {}
end
# Clear our graph.
def clear
- @vertices.each { |vertex, wrapper| wrapper.clear }
- @vertices.clear
- @edges.clear
- end
-
- # Which resources a given resource depends upon.
- def dependents(resource)
- tree_from_vertex(resource).keys
+ @in_to.clear
+ @out_from.clear
+ @upstream_from.clear
+ @downstream_from.clear
end
# Which resources depend upon the given resource.
def dependencies(resource)
- # Cache the reversal graph, because it's somewhat expensive
- # to create.
- @reversal ||= reversal
- # Strangely, it's significantly faster to search a reversed
- # tree in the :out direction than to search a normal tree
- # in the :in direction.
- @reversal.tree_from_vertex(resource, :out).keys
+ vertex?(resource) ? upstream_from_vertex(resource).keys : []
+ end
+
+ def dependents(resource)
+ vertex?(resource) ? downstream_from_vertex(resource).keys : []
end
# Whether our graph is directed. Always true. Used to produce dot files.
@@ -133,8 +55,7 @@ class Puppet::SimpleGraph
# Determine all of the leaf nodes below a given vertex.
def leaves(vertex, direction = :out)
- tree = tree_from_vertex(vertex, direction)
- l = tree.keys.find_all { |c| adjacent(c, :direction => direction).empty? }
+ tree_from_vertex(vertex, direction).keys.find_all { |c| adjacent(c, :direction => direction).empty? }
end
# Collect all of the edges that the passed events match. Returns
@@ -149,9 +70,7 @@ class Puppet::SimpleGraph
# Get all of the edges that this vertex should forward events
# to, which is the same thing as saying all edges directly below
# This vertex in the graph.
- adjacent(source, :direction => :out, :type => :edges).find_all do |edge|
- edge.match?(event.name)
- end
+ @out_from[source].values.flatten.find_all { |edge| edge.match?(event.name) }
end
# Return a reversed version of this graph.
@@ -159,20 +78,50 @@ class Puppet::SimpleGraph
result = self.class.new
vertices.each { |vertex| result.add_vertex(vertex) }
edges.each do |edge|
- newedge = edge.class.new(edge.target, edge.source, edge.label)
- result.add_edge(newedge)
+ result.add_edge edge.class.new(edge.target, edge.source, edge.label)
end
result
end
# Return the size of the graph.
def size
- @vertices.length
+ vertices.size
end
- # Return the graph as an array.
def to_a
- @vertices.keys
+ vertices
+ end
+
+ # Provide a topological sort with cycle reporting
+ def topsort_with_cycles
+ degree = {}
+ zeros = []
+ result = []
+
+ # Collect each of our vertices, with the number of in-edges each has.
+ vertices.each do |v|
+ edges = @in_to[v].dup
+ zeros << v if edges.empty?
+ degree[v] = edges
+ end
+
+ # Iterate over each 0-degree vertex, decrementing the degree of
+ # each of its out-edges.
+ while v = zeros.pop
+ result << v
+ @out_from[v].each { |v2,es|
+ degree[v2].delete(v)
+ zeros << v2 if degree[v2].empty?
+ }
+ end
+
+ # If we have any vertices left with non-zero in-degrees, then we've found a cycle.
+ if cycles = degree.values.reject { |ns| ns.empty? } and cycles.length > 0
+ message = cycles.collect { |edges| '('+edges.collect { |e| e.to_s }.join(", ")+')' }.join(", ")
+ raise Puppet::Error, "Found dependency cycles in the following relationships: #{message}; try using the '--graph' option and open the '.dot' files in OmniGraffle or GraphViz"
+ end
+
+ result
end
# Provide a topological sort.
@@ -182,26 +131,24 @@ class Puppet::SimpleGraph
result = []
# Collect each of our vertices, with the number of in-edges each has.
- @vertices.each do |name, wrapper|
- edges = wrapper.in_edges
- zeros << wrapper if edges.length == 0
- degree[wrapper.vertex] = edges
+ vertices.each do |v|
+ edges = @in_to[v]
+ zeros << v if edges.empty?
+ degree[v] = edges.length
end
# Iterate over each 0-degree vertex, decrementing the degree of
# each of its out-edges.
- while wrapper = zeros.pop
- result << wrapper.vertex
- wrapper.out_edges.each do |edge|
- degree[edge.target].delete(edge)
- zeros << @vertices[edge.target] if degree[edge.target].length == 0
- end
+ while v = zeros.pop
+ result << v
+ @out_from[v].each { |v2,es|
+ zeros << v2 if (degree[v2] -= 1) == 0
+ }
end
# If we have any vertices left with non-zero in-degrees, then we've found a cycle.
- if cycles = degree.find_all { |vertex, edges| edges.length > 0 } and cycles.length > 0
- message = cycles.collect { |vertex, edges| edges.collect { |e| e.to_s }.join(", ") }.join(", ")
- raise Puppet::Error, "Found dependency cycles in the following relationships: #{message}; try using the '--graph' option and open the '.dot' files in OmniGraffle or GraphViz"
+ if cycles = degree.values.reject { |ns| ns == 0 } and cycles.length > 0
+ topsort_with_cycles
end
result
@@ -209,103 +156,80 @@ class Puppet::SimpleGraph
# Add a new vertex to the graph.
def add_vertex(vertex)
- @reversal = nil
- return false if vertex?(vertex)
- setup_vertex(vertex)
- true # don't return the VertexWrapper instance.
+ @in_to[vertex] ||= {}
+ @out_from[vertex] ||= {}
end
# Remove a vertex from the graph.
- def remove_vertex!(vertex)
- return nil unless vertex?(vertex)
- @vertices[vertex].edges.each { |edge| remove_edge!(edge) }
- @edges -= @vertices[vertex].edges
- @vertices[vertex].clear
- @vertices.delete(vertex)
+ def remove_vertex!(v)
+ return unless vertex?(v)
+ @upstream_from.clear
+ @downstream_from.clear
+ (@in_to[v].values+@out_from[v].values).flatten.each { |e| remove_edge!(e) }
+ @in_to.delete(v)
+ @out_from.delete(v)
end
# Test whether a given vertex is in the graph.
- def vertex?(vertex)
- @vertices.include?(vertex)
+ def vertex?(v)
+ @in_to.include?(v)
end
# Return a list of all vertices.
def vertices
- @vertices.keys
+ @in_to.keys
end
# Add a new edge. The graph user has to create the edge instance,
# since they have to specify what kind of edge it is.
- def add_edge(source, target = nil, label = nil)
- @reversal = nil
- if target
- edge = Puppet::Relationship.new(source, target, label)
- else
- edge = source
- end
- [edge.source, edge.target].each { |vertex| setup_vertex(vertex) unless vertex?(vertex) }
- @vertices[edge.source].add_edge :out, edge
- @vertices[edge.target].add_edge :in, edge
- @edges << edge
- true
+ def add_edge(e,*a)
+ return add_relationship(e,*a) unless a.empty?
+ @upstream_from.clear
+ @downstream_from.clear
+ add_vertex(e.source)
+ add_vertex(e.target)
+ @in_to[ e.target][e.source] ||= []; @in_to[ e.target][e.source] |= [e]
+ @out_from[e.source][e.target] ||= []; @out_from[e.source][e.target] |= [e]
end
- # Find a matching edge. Note that this only finds the first edge,
- # not all of them or whatever.
- def edge(source, target)
- @edges.each_with_index { |test_edge, index| return test_edge if test_edge.source == source and test_edge.target == target }
+ def add_relationship(source, target, label = nil)
+ add_edge Puppet::Relationship.new(source, target, label)
end
- def edge_label(source, target)
- return nil unless edge = edge(source, target)
- edge.label
+ # Find all matching edges.
+ def edges_between(source, target)
+ (@out_from[source] || {})[target] || []
end
# Is there an edge between the two vertices?
def edge?(source, target)
- return false unless vertex?(source) and vertex?(target)
-
- @vertices[source].has_edge?(:out, target)
+ vertex?(source) and vertex?(target) and @out_from[source][target]
end
def edges
- @edges.dup
+ @in_to.values.collect { |x| x.values }.flatten
end
- # Remove an edge from our graph.
- def remove_edge!(edge)
- @vertices[edge.source].remove_edge(:out, edge)
- @vertices[edge.target].remove_edge(:in, edge)
-
- @edges.delete(edge)
- nil
+ def each_edge
+ @in_to.each { |t,ns| ns.each { |s,es| es.each { |e| yield e }}}
end
- # Find adjacent edges.
- def adjacent(vertex, options = {})
- return [] unless wrapper = @vertices[vertex]
- wrapper.adjacent(options)
+ # Remove an edge from our graph.
+ def remove_edge!(e)
+ if edge?(e.source,e.target)
+ @upstream_from.clear
+ @downstream_from.clear
+ @in_to [e.target].delete e.source if (@in_to [e.target][e.source] -= [e]).empty?
+ @out_from[e.source].delete e.target if (@out_from[e.source][e.target] -= [e]).empty?
+ end
end
- private
-
- # An internal method that skips the validation, so we don't have
- # duplicate validation calls.
- def setup_vertex(vertex)
- @vertices[vertex] = VertexWrapper.new(vertex)
+ # Find adjacent edges.
+ def adjacent(v, options = {})
+ return [] unless ns = (options[:direction] == :in) ? @in_to[v] : @out_from[v]
+ (options[:type] == :edges) ? ns.values.flatten : ns.keys
end
-
- public
-
-# # For some reason, unconnected vertices do not show up in
-# # this graph.
-# def to_jpg(path, name)
-# gv = vertices
-# Dir.chdir(path) do
-# induced_subgraph(gv).write_to_graphic_file('jpg', name)
-# end
-# end
-
+
# Take container information from another graph and use it
# to replace any container vertices with their respective leaves.
# This creates direct relationships where there were previously
@@ -318,16 +242,15 @@ class Puppet::SimpleGraph
# to container leaves, but that would result in many more
# relationships.
stage_class = Puppet::Type.type(:stage)
+ whit_class = Puppet::Type.type(:whit)
containers = other.topsort.find_all { |v| (v.is_a?(type) or v.is_a?(stage_class)) and vertex?(v) }
containers.each do |container|
# Get the list of children from the other graph.
children = other.adjacent(container, :direction => :out)
- # Just remove the container if it's empty.
- if children.empty?
- remove_vertex!(container)
- next
- end
+ # MQR TODO: Luke suggests that it should be possible to refactor the system so that
+ # container nodes are retained, thus obviating the need for the whit.
+ children = [whit_class.new(:name => container.name, :catalog => other)] if children.empty?
# First create new edges for each of the :in edges
[:in, :out].each do |dir|
@@ -382,6 +305,26 @@ class Puppet::SimpleGraph
predecessor
end
+ def downstream_from_vertex(v)
+ return @downstream_from[v] if @downstream_from[v]
+ result = @downstream_from[v] = {}
+ @out_from[v].keys.each do |node|
+ result[node] = 1
+ result.update(downstream_from_vertex(node))
+ end
+ result
+ end
+
+ def upstream_from_vertex(v)
+ return @upstream_from[v] if @upstream_from[v]
+ result = @upstream_from[v] = {}
+ @in_to[v].keys.each do |node|
+ result[node] = 1
+ result.update(upstream_from_vertex(node))
+ end
+ result
+ end
+
# LAK:FIXME This is just a paste of the GRATR code with slight modifications.
# Return a DOT::DOTDigraph for directed graphs or a DOT::DOTSubgraph for an
@@ -423,18 +366,6 @@ class Puppet::SimpleGraph
system('dotty', dotfile)
end
- # Use +dot+ to create a graphical representation of the graph. Returns the
- # filename of the graphics file.
- def write_to_graphic_file (fmt='png', dotfile='graph')
- src = dotfile + '.dot'
- dot = dotfile + '.' + fmt
-
- File.open(src, 'w') {|f| f << self.to_dot << "\n"}
-
- system( "dot -T#{fmt} #{src} -o #{dot}" )
- dot
- end
-
# Produce the graph files if requested.
def write_graph(name)
return unless Puppet[:graph]
@@ -446,4 +377,73 @@ class Puppet::SimpleGraph
f.puts to_dot("name" => name.to_s.capitalize)
}
end
+
+ # This flag may be set to true to use the new YAML serialzation
+ # format (where @vertices is a simple list of vertices rather than a
+ # list of VertexWrapper objects). Deserialization supports both
+ # formats regardless of the setting of this flag.
+ class << self
+ attr_accessor :use_new_yaml_format
+ end
+ self.use_new_yaml_format = false
+
+ # Stub class to allow graphs to be represented in YAML using the old
+ # (version 2.6) format.
+ class VertexWrapper
+ attr_reader :vertex, :adjacencies
+ def initialize(vertex, adjacencies)
+ @vertex = vertex
+ @adjacencies = adjacencies
+ end
+ end
+
+ # instance_variable_get is used by Object.to_zaml to get instance
+ # variables. Override it so that we can simulate the presence of
+ # instance variables @edges and @vertices for serialization.
+ def instance_variable_get(v)
+ case v.to_s
+ when '@edges' then
+ edges
+ when '@vertices' then
+ if self.class.use_new_yaml_format
+ vertices
+ else
+ result = {}
+ vertices.each do |vertex|
+ adjacencies = {}
+ [:in, :out].each do |direction|
+ adjacencies[direction] = {}
+ adjacent(vertex, :direction => direction, :type => :edges).each do |edge|
+ other_vertex = direction == :in ? edge.source : edge.target
+ (adjacencies[direction][other_vertex] ||= Set.new).add(edge)
+ end
+ end
+ result[vertex] = Puppet::SimpleGraph::VertexWrapper.new(vertex, adjacencies)
+ end
+ result
+ end
+ else
+ super(v)
+ end
+ end
+
+ def to_yaml_properties
+ other_vars = instance_variables.reject { |v| %w{@in_to @out_from @upstream_from @downstream_from}.include?(v) }
+ (other_vars + %w{@vertices @edges}).sort.uniq
+ end
+
+ def yaml_initialize(tag, var)
+ initialize()
+ vertices = var.delete('vertices')
+ edges = var.delete('edges')
+ if vertices.is_a?(Hash)
+ # Support old (2.6) format
+ vertices = vertices.keys
+ end
+ vertices.each { |v| add_vertex(v) }
+ edges.each { |e| add_edge(e) }
+ var.each do |varname, value|
+ instance_variable_set("@#{varname}", value)
+ end
+ end
end
diff --git a/lib/puppet/ssl/certificate_request.rb b/lib/puppet/ssl/certificate_request.rb
index e4d06a039..2f6cae3f5 100644
--- a/lib/puppet/ssl/certificate_request.rb
+++ b/lib/puppet/ssl/certificate_request.rb
@@ -29,7 +29,7 @@ class Puppet::SSL::CertificateRequest < Puppet::SSL::Base
# Support either an actual SSL key, or a Puppet key.
key = key.content if key.is_a?(Puppet::SSL::Key)
- # If we're a CSR for the CA, then use the real certname, rather than the
+ # If we're a CSR for the CA, then use the real ca_name, rather than the
# fake 'ca' name. This is mostly for backward compatibility with 0.24.x,
# but it's also just a good idea.
common_name = name == Puppet::SSL::CA_NAME ? Puppet.settings[:ca_name] : name
diff --git a/lib/puppet/sslcertificates/ca.rb b/lib/puppet/sslcertificates/ca.rb
index 63e6b922a..f3321bd29 100644
--- a/lib/puppet/sslcertificates/ca.rb
+++ b/lib/puppet/sslcertificates/ca.rb
@@ -147,21 +147,19 @@ class Puppet::SSLCertificates::CA
# Create the root certificate.
def mkrootcert
- # Make the root cert's name the FQDN of the host running the CA.
- name = Facter["hostname"].value
+ # Make the root cert's name "Puppet CA: " plus the FQDN of the host running the CA.
+ name = "Puppet CA: #{Facter["hostname"].value}"
if domain = Facter["domain"].value
name += ".#{domain}"
end
- cert = Certificate.new(
-
+ cert = Certificate.new(
:name => name,
:cert => @config[:cacert],
:encrypt => @config[:capass],
:key => @config[:cakey],
:selfsign => true,
:ttl => ttl,
-
:type => :ca
)
@@ -241,19 +239,15 @@ class Puppet::SSLCertificates::CA
f << "%04X" % (serial + 1)
}
-
- newcert = Puppet::SSLCertificates.mkcert(
-
+ newcert = Puppet::SSLCertificates.mkcert(
:type => :server,
:name => csr.subject,
:ttl => ttl,
:issuer => @cert,
:serial => serial,
-
:publickey => csr.public_key
)
-
sign_with_key(newcert)
self.storeclientcert(newcert)
diff --git a/lib/puppet/transaction/report.rb b/lib/puppet/transaction/report.rb
index e6d1e0528..1d3091428 100644
--- a/lib/puppet/transaction/report.rb
+++ b/lib/puppet/transaction/report.rb
@@ -62,30 +62,49 @@ class Puppet::Transaction::Report
host
end
- # Provide a summary of this report.
+ # Provide a human readable textual summary of this report.
def summary
+ report = raw_summary
+
ret = ""
+ report.keys.sort { |a,b| a.to_s <=> b.to_s }.each do |key|
+ ret += "#{Puppet::Util::Metric.labelize(key)}:\n"
- @metrics.sort { |a,b| a[1].label <=> b[1].label }.each do |name, metric|
- ret += "#{metric.label}:\n"
- metric.values.sort { |a,b|
+ report[key].keys.sort { |a,b|
# sort by label
- if a[0] == :total
+ if a == :total
1
- elsif b[0] == :total
+ elsif b == :total
-1
else
- a[1] <=> b[1]
+ report[key][a].to_s <=> report[key][b].to_s
end
- }.each do |name, label, value|
+ }.each do |label|
+ value = report[key][label]
next if value == 0
value = "%0.2f" % value if value.is_a?(Float)
- ret += " %15s %s\n" % [label + ":", value]
+ ret += " %15s %s\n" % [Puppet::Util::Metric.labelize(label) + ":", value]
end
end
ret
end
+ # Provide a raw hash summary of this report.
+ def raw_summary
+ report = {}
+
+ @metrics.each do |name, metric|
+ key = metric.name.to_s
+ report[key] = {}
+ metric.values.each do |name, label, value|
+ report[key][name.to_s] = value
+ end
+ report[key]["total"] = 0 unless key == "time" or report[key].include?("total")
+ end
+ (report["time"] ||= {})["last_run"] = Time.now.tv_sec
+ report
+ end
+
# Based on the contents of this report's metrics, compute a single number
# that represents the report. The resulting number is a bitmask where
# individual bits represent the presence of different metrics.
@@ -103,7 +122,6 @@ class Puppet::Transaction::Report
resource_statuses.each do |name, status|
metrics[:total] += status.change_count if status.change_count
end
-
add_metric(:changes, metrics)
end
@@ -124,7 +142,6 @@ class Puppet::Transaction::Report
metrics[:total] = resource_statuses.length
resource_statuses.each do |name, status|
-
Puppet::Resource::Status::STATES.each do |state|
metrics[state] += 1 if status.send(state)
end
diff --git a/lib/puppet/transaction/resource_harness.rb b/lib/puppet/transaction/resource_harness.rb
index aace6a38a..29ec9a539 100644
--- a/lib/puppet/transaction/resource_harness.rb
+++ b/lib/puppet/transaction/resource_harness.rb
@@ -72,7 +72,7 @@ class Puppet::Transaction::ResourceHarness
resource[param] = value
audited << param
else
- resource.info "Storing newly-audited value #{current[param]} for #{param}"
+ resource.debug "Storing newly-audited value #{current[param]} for #{param}"
cache(resource, param, current[param])
end
end
diff --git a/lib/puppet/type.rb b/lib/puppet/type.rb
index c3855a400..1b6e7dcd7 100644
--- a/lib/puppet/type.rb
+++ b/lib/puppet/type.rb
@@ -410,13 +410,15 @@ class Type
property = self.newattr(name)
- begin
- # make sure the parameter doesn't have any errors
- property.value = value
- rescue => detail
- error = Puppet::Error.new("Parameter #{name} failed: #{detail}")
- error.set_backtrace(detail.backtrace)
- raise error
+ if property
+ begin
+ # make sure the parameter doesn't have any errors
+ property.value = value
+ rescue => detail
+ error = Puppet::Error.new("Parameter #{name} failed: #{detail}")
+ error.set_backtrace(detail.backtrace)
+ raise error
+ end
end
nil
@@ -472,6 +474,12 @@ class Type
raise Puppet::Error, "Resource type #{self.class.name} does not support parameter #{name}"
end
+ if provider and ! provider.class.supports_parameter?(klass)
+ missing = klass.required_features.find_all { |f| ! provider.class.feature?(f) }
+ info "Provider %s does not support features %s; not managing attribute %s" % [provider.class.name, missing.join(", "), name]
+ return nil
+ end
+
return @parameters[name] if @parameters.include?(name)
@parameters[name] = klass.new(:resource => self)
@@ -933,16 +941,16 @@ class Type
newmetaparam(:schedule) do
desc "On what schedule the object should be managed. You must create a
schedule object, and then reference the name of that object to use
- that for your schedule::
+ that for your schedule:
- schedule { daily:
- period => daily,
- range => \"2-4\"
- }
+ schedule { daily:
+ period => daily,
+ range => \"2-4\"
+ }
- exec { \"/usr/bin/apt-get update\":
- schedule => daily
- }
+ exec { \"/usr/bin/apt-get update\":
+ schedule => daily
+ }
The creation of the schedule object does not need to appear in the
configuration before objects that use it."
@@ -957,7 +965,7 @@ class Type
the value, and any changes already get logged."
validate do |list|
- list = Array(list)
+ list = Array(list).collect {|p| p.to_sym}
unless list == [:all]
list.each do |param|
next if @resource.class.validattr?(param)
@@ -982,8 +990,8 @@ class Type
end
def properties_to_audit(list)
- if list == :all
- list = all_properties if list == :all
+ if !list.kind_of?(Array) && list.to_sym == :all
+ list = all_properties
else
list = Array(list).collect { |p| p.to_sym }
end
@@ -1020,40 +1028,40 @@ class Type
newmetaparam(:alias) do
desc "Creates an alias for the object. Puppet uses this internally when you
- provide a symbolic name::
-
- file { sshdconfig:
- path => $operatingsystem ? {
- solaris => \"/usr/local/etc/ssh/sshd_config\",
- default => \"/etc/ssh/sshd_config\"
- },
- source => \"...\"
- }
+ provide a symbolic name:
+
+ file { sshdconfig:
+ path => $operatingsystem ? {
+ solaris => \"/usr/local/etc/ssh/sshd_config\",
+ default => \"/etc/ssh/sshd_config\"
+ },
+ source => \"...\"
+ }
- service { sshd:
- subscribe => file[sshdconfig]
- }
+ service { sshd:
+ subscribe => File[sshdconfig]
+ }
- When you use this feature, the parser sets ``sshdconfig`` as the name,
+ When you use this feature, the parser sets `sshdconfig` as the name,
and the library sets that as an alias for the file so the dependency
- lookup for ``sshd`` works. You can use this parameter yourself,
+ lookup for `sshd` works. You can use this parameter yourself,
but note that only the library can use these aliases; for instance,
- the following code will not work::
+ the following code will not work:
- file { \"/etc/ssh/sshd_config\":
- owner => root,
- group => root,
- alias => sshdconfig
- }
+ file { \"/etc/ssh/sshd_config\":
+ owner => root,
+ group => root,
+ alias => sshdconfig
+ }
- file { sshdconfig:
- mode => 644
- }
+ file { sshdconfig:
+ mode => 644
+ }
There's no way here for the Puppet parser to know that these two stanzas
should be affecting the same file.
- See the `LanguageTutorial language tutorial`:trac: for more information.
+ See the [Language Tutorial](http://docs.puppetlabs.com/guides/language_tutorial.html) for more information.
"
@@ -1083,9 +1091,9 @@ class Type
be useful to add your own tags to a given resource.
Tags are currently useful for things like applying a subset of a
- host's configuration::
+ host's configuration:
- puppet agent --test --tags mytag
+ puppet agent --test --tags mytag
This way, when you're testing a configuration you can run just the
portion you're testing."
@@ -1189,23 +1197,23 @@ class Type
newmetaparam(:require, :parent => RelationshipMetaparam, :attributes => {:direction => :in, :events => :NONE}) do
desc "One or more objects that this object depends on.
This is used purely for guaranteeing that changes to required objects
- happen before the dependent object. For instance::
+ happen before the dependent object. For instance:
- # Create the destination directory before you copy things down
- file { \"/usr/local/scripts\":
- ensure => directory
- }
+ # Create the destination directory before you copy things down
+ file { \"/usr/local/scripts\":
+ ensure => directory
+ }
- file { \"/usr/local/scripts/myscript\":
- source => \"puppet://server/module/myscript\",
- mode => 755,
- require => File[\"/usr/local/scripts\"]
- }
+ file { \"/usr/local/scripts/myscript\":
+ source => \"puppet://server/module/myscript\",
+ mode => 755,
+ require => File[\"/usr/local/scripts\"]
+ }
Multiple dependencies can be specified by providing a comma-seperated list
- of resources, enclosed in square brackets::
+ of resources, enclosed in square brackets:
- require => [ File[\"/usr/local\"], File[\"/usr/local/scripts\"] ]
+ require => [ File[\"/usr/local\"], File[\"/usr/local/scripts\"] ]
Note that Puppet will autorequire everything that it can, and
there are hooks in place so that it's easy for resources to add new
@@ -1219,10 +1227,10 @@ class Type
Currently, exec resources will autorequire their CWD (if it is
specified) plus any fully qualified paths that appear in the
- command. For instance, if you had an ``exec`` command that ran
- the ``myscript`` mentioned above, the above code that pulls the
+ command. For instance, if you had an `exec` command that ran
+ the `myscript` mentioned above, the above code that pulls the
file down would be automatically listed as a requirement to the
- ``exec`` code, so that you would always be running againts the
+ `exec` code, so that you would always be running againts the
most recent version.
"
end
@@ -1230,20 +1238,20 @@ class Type
newmetaparam(:subscribe, :parent => RelationshipMetaparam, :attributes => {:direction => :in, :events => :ALL_EVENTS, :callback => :refresh}) do
desc "One or more objects that this object depends on. Changes in the
subscribed to objects result in the dependent objects being
- refreshed (e.g., a service will get restarted). For instance::
-
- class nagios {
- file { \"/etc/nagios/nagios.conf\":
- source => \"puppet://server/module/nagios.conf\",
- alias => nagconf # just to make things easier for me
- }
- service { nagios:
- ensure => running,
- subscribe => File[nagconf]
+ refreshed (e.g., a service will get restarted). For instance:
+
+ class nagios {
+ file { \"/etc/nagios/nagios.conf\":
+ source => \"puppet://server/module/nagios.conf\",
+ alias => nagconf # just to make things easier for me
+ }
+ service { nagios:
+ ensure => running,
+ subscribe => File[nagconf]
+ }
}
- }
- Currently the ``exec``, ``mount`` and ``service`` type support
+ Currently the `exec`, `mount` and `service` type support
refreshing.
"
end
@@ -1251,18 +1259,18 @@ class Type
newmetaparam(:before, :parent => RelationshipMetaparam, :attributes => {:direction => :out, :events => :NONE}) do
desc %{This parameter is the opposite of **require** -- it guarantees
that the specified object is applied later than the specifying
- object::
+ object:
- file { "/var/nagios/configuration":
- source => "...",
- recurse => true,
- before => Exec["nagios-rebuid"]
- }
+ file { "/var/nagios/configuration":
+ source => "...",
+ recurse => true,
+ before => Exec["nagios-rebuid"]
+ }
- exec { "nagios-rebuild":
- command => "/usr/bin/make",
- cwd => "/var/nagios/configuration"
- }
+ exec { "nagios-rebuild":
+ command => "/usr/bin/make",
+ cwd => "/var/nagios/configuration"
+ }
This will make sure all of the files are up to date before the
make command is run.}
@@ -1270,16 +1278,16 @@ class Type
newmetaparam(:notify, :parent => RelationshipMetaparam, :attributes => {:direction => :out, :events => :ALL_EVENTS, :callback => :refresh}) do
desc %{This parameter is the opposite of **subscribe** -- it sends events
- to the specified object::
+ to the specified object:
- file { "/etc/sshd_config":
- source => "....",
- notify => Service[sshd]
- }
+ file { "/etc/sshd_config":
+ source => "....",
+ notify => Service[sshd]
+ }
- service { sshd:
- ensure => running
- }
+ service { sshd:
+ ensure => running
+ }
This will restart the sshd service if the sshd config file changes.}
end
@@ -1293,24 +1301,24 @@ class Type
By default, all classes get directly added to the
'main' stage. You can create new stages as resources:
- stage { [pre, post]: }
+ stage { [pre, post]: }
To order stages, use standard relationships:
- stage { pre: before => Stage[main] }
+ stage { pre: before => Stage[main] }
Or use the new relationship syntax:
- Stage[pre] -> Stage[main] -> Stage[post]
+ Stage[pre] -> Stage[main] -> Stage[post]
Then use the new class parameters to specify a stage:
- class { foo: stage => pre }
+ class { foo: stage => pre }
Stages can only be set on classes, not individual resources. This will
- fail::
+ fail:
- file { '/foo': stage => pre, ensure => file }
+ file { '/foo': stage => pre, ensure => file }
}
end
diff --git a/lib/puppet/type/augeas.rb b/lib/puppet/type/augeas.rb
index 7fcfdd7a3..d29bda648 100644
--- a/lib/puppet/type/augeas.rb
+++ b/lib/puppet/type/augeas.rb
@@ -28,27 +28,28 @@ Puppet::Type.newtype(:augeas) do
via the augeas tool.
Requires:
- - augeas to be installed (http://www.augeas.net)
- - ruby-augeas bindings
- Sample usage with a string::
+ - augeas to be installed (http://www.augeas.net)
+ - ruby-augeas bindings
- augeas{\"test1\" :
- context => \"/files/etc/sysconfig/firstboot\",
- changes => \"set RUN_FIRSTBOOT YES\",
- onlyif => \"match other_value size > 0\",
- }
+ Sample usage with a string:
- Sample usage with an array and custom lenses::
+ augeas{\"test1\" :
+ context => \"/files/etc/sysconfig/firstboot\",
+ changes => \"set RUN_FIRSTBOOT YES\",
+ onlyif => \"match other_value size > 0\",
+ }
- augeas{\"jboss_conf\":
- context => \"/files\",
- changes => [
- \"set /etc/jbossas/jbossas.conf/JBOSS_IP $ipaddress\",
- \"set /etc/jbossas/jbossas.conf/JAVA_HOME /usr\"
- ],
- load_path => \"$/usr/share/jbossas/lenses\",
- }
+ Sample usage with an array and custom lenses:
+
+ augeas{\"jboss_conf\":
+ context => \"/files\",
+ changes => [
+ \"set /etc/jbossas/jbossas.conf/JBOSS_IP $ipaddress\",
+ \"set /etc/jbossas/jbossas.conf/JAVA_HOME /usr\"
+ ],
+ load_path => \"$/usr/share/jbossas/lenses\",
+ }
"
@@ -71,23 +72,23 @@ Puppet::Type.newtype(:augeas) do
newparam (:onlyif) do
desc "Optional augeas command and comparisons to control the execution of this type.
- Supported onlyif syntax::
-
- get [AUGEAS_PATH] [COMPARATOR] [STRING]
- match [MATCH_PATH] size [COMPARATOR] [INT]
- match [MATCH_PATH] include [STRING]
- match [MATCH_PATH] not_include [STRING]
- match [MATCH_PATH] == [AN_ARRAY]
- match [MATCH_PATH] != [AN_ARRAY]
-
- where::
-
- AUGEAS_PATH is a valid path scoped by the context
- MATCH_PATH is a valid match synatx scoped by the context
- COMPARATOR is in the set [> >= != == <= <]
- STRING is a string
- INT is a number
- AN_ARRAY is in the form ['a string', 'another']"
+ Supported onlyif syntax:
+
+ get [AUGEAS_PATH] [COMPARATOR] [STRING]
+ match [MATCH_PATH] size [COMPARATOR] [INT]
+ match [MATCH_PATH] include [STRING]
+ match [MATCH_PATH] not_include [STRING]
+ match [MATCH_PATH] == [AN_ARRAY]
+ match [MATCH_PATH] != [AN_ARRAY]
+
+ where:
+
+ AUGEAS_PATH is a valid path scoped by the context
+ MATCH_PATH is a valid match synatx scoped by the context
+ COMPARATOR is in the set [> >= != == <= <]
+ STRING is a string
+ INT is a number
+ AN_ARRAY is in the form ['a string', 'another']"
defaultto ""
end
@@ -95,16 +96,14 @@ Puppet::Type.newtype(:augeas) do
newparam(:changes) do
desc "The changes which should be applied to the filesystem. This
can be either a string which contains a command or an array of commands.
- Commands supported are::
+ Commands supported are:
- set [PATH] [VALUE] Sets the value VALUE at loction PATH
- rm [PATH] Removes the node at location PATH
- remove [PATH] Synonym for rm
- clear [PATH] Keeps the node at PATH, but removes the value.
- ins [LABEL] [WHERE] [PATH]
- Inserts an empty node LABEL either [WHERE={before|after}] PATH.
- insert [LABEL] [WHERE] [PATH]
- Synonym for ins
+ set [PATH] [VALUE] Sets the value VALUE at loction PATH
+ rm [PATH] Removes the node at location PATH
+ remove [PATH] Synonym for rm
+ clear [PATH] Keeps the node at PATH, but removes the value.
+ ins [LABEL] [WHERE] [PATH] Inserts an empty node LABEL either [WHERE={before|after}] PATH.
+ insert [LABEL] [WHERE] [PATH] Synonym for ins
If the parameter 'context' is set that value is prepended to PATH"
end
@@ -136,11 +135,11 @@ Puppet::Type.newtype(:augeas) do
end
newparam(:lens) do
- desc "Use a specific lens, e.g. 'Hosts.lns'. When this parameter is set, you must also set the incl parameter to indicate which file to load. Only that file will be loaded, which greatly speeds up execution of the type"
+ desc "Use a specific lens, e.g. `Hosts.lns`. When this parameter is set, you must also set the incl parameter to indicate which file to load. Only that file will be loaded, which greatly speeds up execution of the type"
end
newparam(:incl) do
- desc "Load only a specific file, e.g. '/etc/hosts'. When this parameter is set, you must also set the lens parameter to indicate which lens to use."
+ desc "Load only a specific file, e.g. `/etc/hosts`. When this parameter is set, you must also set the lens parameter to indicate which lens to use."
end
validate do
diff --git a/lib/puppet/type/computer.rb b/lib/puppet/type/computer.rb
index 86a30be27..89a0692bf 100644
--- a/lib/puppet/type/computer.rb
+++ b/lib/puppet/type/computer.rb
@@ -10,7 +10,7 @@ Puppet::Type.newtype(:computer) do
This provider only manages Computer objects in the local directory service
domain, not in remote directories.
- If you wish to manage /etc/hosts on Mac OS X, then simply use the host
+ If you wish to manage `/etc/hosts` file on Mac OS X, then simply use the host
type as per other platforms.
This type primarily exists to create localhost Computer objects that MCX
@@ -31,7 +31,7 @@ Puppet::Type.newtype(:computer) do
newproperty(:ensure, :parent => Puppet::Property::Ensure) do
desc "Control the existences of this computer record. Set this attribute to
- ``present`` to ensure the computer record exists. Set it to ``absent``
+ `present` to ensure the computer record exists. Set it to `absent`
to delete any computer records with this name"
newvalue(:present) do
provider.create
diff --git a/lib/puppet/type/cron.rb b/lib/puppet/type/cron.rb
index b3f5e608d..76399d693 100755
--- a/lib/puppet/type/cron.rb
+++ b/lib/puppet/type/cron.rb
@@ -15,32 +15,32 @@ Puppet::Type.newtype(:cron) do
association is made and synced to disk, you can then manage the job
normally (e.g., change the schedule of the job).
- Example::
-
- cron { logrotate:
- command => \"/usr/sbin/logrotate\",
- user => root,
- hour => 2,
- minute => 0
- }
-
- Note that all cron values can be specified as an array of values::
-
- cron { logrotate:
- command => \"/usr/sbin/logrotate\",
- user => root,
- hour => [2, 4]
- }
-
- Or using ranges, or the step syntax ``*/2`` (although there's no guarantee that
- your ``cron`` daemon supports it)::
-
- cron { logrotate:
- command => \"/usr/sbin/logrotate\",
- user => root,
- hour => ['2-4'],
- minute => '*/10'
- }
+ Example:
+
+ cron { logrotate:
+ command => \"/usr/sbin/logrotate\",
+ user => root,
+ hour => 2,
+ minute => 0
+ }
+
+ Note that all cron values can be specified as an array of values:
+
+ cron { logrotate:
+ command => \"/usr/sbin/logrotate\",
+ user => root,
+ hour => [2, 4]
+ }
+
+ Or using ranges, or the step syntax `*/2` (although there's no guarantee that
+ your `cron` daemon supports it):
+
+ cron { logrotate:
+ command => \"/usr/sbin/logrotate\",
+ user => root,
+ hour => ['2-4'],
+ minute => '*/10'
+ }
"
ensurable
@@ -169,7 +169,7 @@ Puppet::Type.newtype(:cron) do
end
if value == "*"
- return value
+ return :absent
end
return value unless self.class.boundaries
@@ -206,7 +206,7 @@ Puppet::Type.newtype(:cron) do
profile is not sourced when the command is run, so if the
user's environment is desired it should be sourced manually.
- All cron parameters support ``absent`` as a value; this will
+ All cron parameters support `absent` as a value; this will
remove any existing values for that field."
def retrieve
@@ -230,7 +230,7 @@ Puppet::Type.newtype(:cron) do
end
newproperty(:special) do
- desc "Special schedules only supported on FreeBSD."
+ desc "Special schedules"
def specials
%w{reboot yearly annually monthly weekly daily midnight hourly}
@@ -293,7 +293,7 @@ Puppet::Type.newtype(:cron) do
but will not associate them with a specific job.
Settings should be specified exactly as they should appear in
- the crontab, e.g., ``PATH=/bin:/usr/bin:/usr/sbin``."
+ the crontab, e.g., `PATH=/bin:/usr/bin:/usr/sbin`."
validate do |value|
unless value =~ /^\s*(\w+)\s*=\s*(.*)\s*$/ or value == :absent or value == "absent"
diff --git a/lib/puppet/type/exec.rb b/lib/puppet/type/exec.rb
index bfeaaad34..606888c75 100755
--- a/lib/puppet/type/exec.rb
+++ b/lib/puppet/type/exec.rb
@@ -6,51 +6,51 @@ module Puppet
@doc = "Executes external commands. It is critical that all commands
executed using this mechanism can be run multiple times without
harm, i.e., they are *idempotent*. One useful way to create idempotent
- commands is to use the checks like ``creates`` to avoid running the
+ commands is to use the checks like `creates` to avoid running the
command unless some condition is met.
- Note also that you can restrict an ``exec`` to only run when it receives
- events by using the ``refreshonly`` parameter; this is a useful way to
+ Note also that you can restrict an `exec` to only run when it receives
+ events by using the `refreshonly` parameter; this is a useful way to
have your configuration respond to events with arbitrary commands.
- It is worth noting that ``exec`` is special, in that it is not
- currently considered an error to have multiple ``exec`` instances
+ It is worth noting that `exec` is special, in that it is not
+ currently considered an error to have multiple `exec` instances
with the same name. This was done purely because it had to be this
way in order to get certain functionality, but it complicates things.
- In particular, you will not be able to use ``exec`` instances that
+ In particular, you will not be able to use `exec` instances that
share their commands with other instances as a dependency, since
Puppet has no way of knowing which instance you mean.
- For example::
+ For example:
- # defined in the production class
- exec { \"make\":
- cwd => \"/prod/build/dir\",
- path => \"/usr/bin:/usr/sbin:/bin\"
- }
+ # defined in the production class
+ exec { \"make\":
+ cwd => \"/prod/build/dir\",
+ path => \"/usr/bin:/usr/sbin:/bin\"
+ }
- . etc. .
+ . etc. .
- # defined in the test class
- exec { \"make\":
- cwd => \"/test/build/dir\",
- path => \"/usr/bin:/usr/sbin:/bin\"
- }
+ # defined in the test class
+ exec { \"make\":
+ cwd => \"/test/build/dir\",
+ path => \"/usr/bin:/usr/sbin:/bin\"
+ }
Any other type would throw an error, complaining that you had
the same instance being managed in multiple places, but these are
- obviously different images, so ``exec`` had to be treated specially.
+ obviously different images, so `exec` had to be treated specially.
It is recommended to avoid duplicate names whenever possible.
- Note that if an ``exec`` receives an event from another resource,
- it will get executed again (or execute the command specified in ``refresh``, if there is one).
+ Note that if an `exec` receives an event from another resource,
+ it will get executed again (or execute the command specified in `refresh`, if there is one).
- There is a strong tendency to use ``exec`` to do whatever work Puppet
+ There is a strong tendency to use `exec` to do whatever work Puppet
can't already do; while this is obviously acceptable (and unavoidable)
- in the short term, it is highly recommended to migrate work from ``exec``
+ in the short term, it is highly recommended to migrate work from `exec`
to native Puppet types as quickly as possible. If you find that
- you are doing a lot of work with ``exec``, please at least notify
+ you are doing a lot of work with `exec`, please at least notify
us at Puppet Labs what you are doing, and hopefully we can work with
you to get a native resource type for the work you are doing."
@@ -159,9 +159,9 @@ module Puppet
desc "The actual command to execute. Must either be fully qualified
or a search path for the command must be provided. If the command
succeeds, any output produced will be logged at the instance's
- normal log level (usually ``notice``), but if the command fails
+ normal log level (usually `notice`), but if the command fails
(meaning its return code does not match the specified code) then
- any output is logged at the ``err`` log level."
+ any output is logged at the `err` log level."
end
newparam(:path) do
@@ -223,7 +223,7 @@ module Puppet
newparam(:logoutput) do
desc "Whether to log output. Defaults to logging output at the
- loglevel for the ``exec`` resource. Use *on_failure* to only
+ loglevel for the `exec` resource. Use *on_failure* to only
log the output when the command reports an error. Values are
**true**, *false*, *on_failure*, and any legal log level."
@@ -253,7 +253,7 @@ module Puppet
newparam(:environment) do
desc "Any additional environment variables you want to set for a
command. Note that if you use this to set PATH, it will override
- the ``path`` attribute. Multiple environment variables should be
+ the `path` attribute. Multiple environment variables should be
specified as an array."
validate do |values|
@@ -330,22 +330,22 @@ module Puppet
desc "The command should only be run as a
refresh mechanism for when a dependent object is changed. It only
makes sense to use this option when this command depends on some
- other object; it is useful for triggering an action::
-
- # Pull down the main aliases file
- file { \"/etc/aliases\":
- source => \"puppet://server/module/aliases\"
- }
-
- # Rebuild the database, but only when the file changes
- exec { newaliases:
- path => [\"/usr/bin\", \"/usr/sbin\"],
- subscribe => File[\"/etc/aliases\"],
- refreshonly => true
- }
+ other object; it is useful for triggering an action:
+
+ # Pull down the main aliases file
+ file { \"/etc/aliases\":
+ source => \"puppet://server/module/aliases\"
+ }
+
+ # Rebuild the database, but only when the file changes
+ exec { newaliases:
+ path => [\"/usr/bin\", \"/usr/sbin\"],
+ subscribe => File[\"/etc/aliases\"],
+ refreshonly => true
+ }
- Note that only ``subscribe`` and ``notify`` can trigger actions, not ``require``,
- so it only makes sense to use ``refreshonly`` with ``subscribe`` or ``notify``."
+ Note that only `subscribe` and `notify` can trigger actions, not `require`,
+ so it only makes sense to use `refreshonly` with `subscribe` or `notify`."
newvalues(:true, :false)
@@ -364,13 +364,13 @@ module Puppet
newcheck(:creates) do
desc "A file that this command creates. If this
parameter is provided, then the command will only be run
- if the specified file does not exist::
+ if the specified file does not exist:
- exec { \"tar xf /my/tar/file.tar\":
- cwd => \"/var/tmp\",
- creates => \"/var/tmp/myfile\",
- path => [\"/usr/bin\", \"/usr/sbin\"]
- }
+ exec { \"tar xf /my/tar/file.tar\":
+ cwd => \"/var/tmp\",
+ creates => \"/var/tmp/myfile\",
+ path => [\"/usr/bin\", \"/usr/sbin\"]
+ }
"
@@ -396,16 +396,16 @@ module Puppet
end
newcheck(:unless) do
- desc "If this parameter is set, then this ``exec`` will run unless
- the command returns 0. For example::
+ desc "If this parameter is set, then this `exec` will run unless
+ the command returns 0. For example:
- exec { \"/bin/echo root >> /usr/lib/cron/cron.allow\":
- path => \"/usr/bin:/usr/sbin:/bin\",
- unless => \"grep root /usr/lib/cron/cron.allow 2>/dev/null\"
- }
+ exec { \"/bin/echo root >> /usr/lib/cron/cron.allow\":
+ path => \"/usr/bin:/usr/sbin:/bin\",
+ unless => \"grep root /usr/lib/cron/cron.allow 2>/dev/null\"
+ }
- This would add ``root`` to the cron.allow file (on Solaris) unless
- ``grep`` determines it's already there.
+ This would add `root` to the cron.allow file (on Solaris) unless
+ `grep` determines it's already there.
Note that this command follows the same rules as the main command,
which is to say that it must be fully qualified if the path is not set.
@@ -433,22 +433,22 @@ module Puppet
end
newcheck(:onlyif) do
- desc "If this parameter is set, then this ``exec`` will only run if
- the command returns 0. For example::
+ desc "If this parameter is set, then this `exec` will only run if
+ the command returns 0. For example:
- exec { \"logrotate\":
- path => \"/usr/bin:/usr/sbin:/bin\",
- onlyif => \"test `du /var/log/messages | cut -f1` -gt 100000\"
- }
+ exec { \"logrotate\":
+ path => \"/usr/bin:/usr/sbin:/bin\",
+ onlyif => \"test `du /var/log/messages | cut -f1` -gt 100000\"
+ }
- This would run ``logrotate`` only if that test returned true.
+ This would run `logrotate` only if that test returned true.
Note that this command follows the same rules as the main command,
which is to say that it must be fully qualified if the path is not set.
- Also note that onlyif can take an array as its value, eg::
+ Also note that onlyif can take an array as its value, e.g.:
- onlyif => [\"test -f /tmp/file1\", \"test -f /tmp/file2\"]
+ onlyif => [\"test -f /tmp/file1\", \"test -f /tmp/file2\"]
This will only run the exec if /all/ conditions in the array return true.
"
@@ -553,13 +553,7 @@ module Puppet
if self[:path]
if Puppet.features.posix? and !File.exists?(exe)
withenv :PATH => self[:path].join(File::PATH_SEPARATOR) do
- path = %x{which #{exe}}.chomp
- if path == ""
- raise ArgumentError,
- "Could not find command '#{exe}'"
- else
- exe = path
- end
+ exe = which(exe) || raise(ArgumentError,"Could not find command '#{exe}'")
end
elsif Puppet.features.microsoft_windows? and !File.exists?(exe)
self[:path].each do |path|
@@ -683,4 +677,3 @@ module Puppet
end
end
end
-
diff --git a/lib/puppet/type/file.rb b/lib/puppet/type/file.rb
index 71f2756bc..f35a26408 100644
--- a/lib/puppet/type/file.rb
+++ b/lib/puppet/type/file.rb
@@ -16,7 +16,7 @@ Puppet::Type.newtype(:file) do
@doc = "Manages local files, including setting ownership and
permissions, creation of both files and directories, and
retrieving entire files from remote servers. As Puppet matures, it
- expected that the ``file`` resource will be used less and less to
+ expected that the `file` resource will be used less and less to
manage content, and instead native resources will be used to do so.
If you find that you are often copying files in from a central
@@ -61,33 +61,33 @@ Puppet::Type.newtype(:file) do
newparam(:backup) do
desc "Whether files should be backed up before
being replaced. The preferred method of backing files up is via
- a ``filebucket``, which stores files by their MD5 sums and allows
+ a `filebucket`, which stores files by their MD5 sums and allows
easy retrieval without littering directories with backups. You
can specify a local filebucket or a network-accessible
- server-based filebucket by setting ``backup => bucket-name``.
- Alternatively, if you specify any value that begins with a ``.``
- (e.g., ``.puppet-bak``), then Puppet will use copy the file in
+ server-based filebucket by setting `backup => bucket-name`.
+ Alternatively, if you specify any value that begins with a `.`
+ (e.g., `.puppet-bak`), then Puppet will use copy the file in
the same directory with that value as the extension of the
- backup. Setting ``backup => false`` disables all backups of the
+ backup. Setting `backup => false` disables all backups of the
file in question.
- Puppet automatically creates a local filebucket named ``puppet`` and
+ Puppet automatically creates a local filebucket named `puppet` and
defaults to backing up there. To use a server-based filebucket,
- you must specify one in your configuration::
+ you must specify one in your configuration
- filebucket { main:
- server => puppet
- }
+ filebucket { main:
+ server => puppet
+ }
- The ``puppet master`` daemon creates a filebucket by default,
+ The `puppet master` daemon creates a filebucket by default,
so you can usually back up to your main server with this
configuration. Once you've described the bucket in your
- configuration, you can use it in any file::
+ configuration, you can use it in any file
- file { \"/my/file\":
- source => \"/path/in/nfs/or/something\",
- backup => main
- }
+ file { \"/my/file\":
+ source => \"/path/in/nfs/or/something\",
+ backup => main
+ }
This will back the file up to the central server.
@@ -192,9 +192,9 @@ Puppet::Type.newtype(:file) do
newparam(:ignore) do
desc "A parameter which omits action on files matching
specified patterns during recursion. Uses Ruby's builtin globbing
- engine, so shell metacharacters are fully supported, e.g. ``[a-z]*``.
+ engine, so shell metacharacters are fully supported, e.g. `[a-z]*`.
Matches that would descend into the directory structure are ignored,
- e.g., ``*/*``."
+ e.g., `*/*`."
validate do |value|
unless value.is_a?(Array) or value.is_a?(String) or value == false
@@ -205,10 +205,10 @@ Puppet::Type.newtype(:file) do
newparam(:links) do
desc "How to handle links during file actions. During file copying,
- ``follow`` will copy the target file instead of the link, ``manage``
- will copy the link itself, and ``ignore`` will just pass it by.
- When not copying, ``manage`` and ``ignore`` behave equivalently
- (because you cannot really ignore links entirely during local recursion), and ``follow`` will manage the file to which the
+ `follow` will copy the target file instead of the link, `manage`
+ will copy the link itself, and `ignore` will just pass it by.
+ When not copying, `manage` and `ignore` behave equivalently
+ (because you cannot really ignore links entirely during local recursion), and `follow` will manage the file to which the
link points."
newvalues(:follow, :manage)
@@ -223,7 +223,7 @@ Puppet::Type.newtype(:file) do
files unless you really know what you are doing. This option only
makes sense when recursively managing directories.
- Note that when using ``purge`` with ``source``, Puppet will purge any files
+ Note that when using `purge` with `source`, Puppet will purge any files
that are not on the remote system."
defaultto :false
@@ -234,7 +234,7 @@ Puppet::Type.newtype(:file) do
newparam(:sourceselect) do
desc "Whether to copy all valid sources, or just the first one. This parameter
is only used in recursive copies; by default, the first valid source is the
- only one used as a recursive source, but if this parameter is set to ``all``,
+ only one used as a recursive source, but if this parameter is set to `all`,
then all valid sources will have all of their contents copied to the local host,
and for sources that have the same file, the source earlier in the list will
be used."
diff --git a/lib/puppet/type/file/content.rb b/lib/puppet/type/file/content.rb
index 74b380f55..b8f30a9c7 100755
--- a/lib/puppet/type/file/content.rb
+++ b/lib/puppet/type/file/content.rb
@@ -161,11 +161,17 @@ module Puppet
}
end
+ def self.standalone?
+ Puppet.settings[:name] == "apply"
+ end
+
def each_chunk_from(source_or_content)
if source_or_content.is_a?(String)
yield source_or_content
elsif source_or_content.nil?
yield read_file_from_filebucket
+ elsif self.class.standalone?
+ yield source_or_content.content
elsif source_or_content.local?
chunk_file_from_disk(source_or_content) { |chunk| yield chunk }
else
@@ -184,7 +190,7 @@ module Puppet
end
def chunk_file_from_source(source_or_content)
- request = Puppet::Indirector::Request.new(:file_content, :find, source_or_content.full_path)
+ request = Puppet::Indirector::Request.new(:file_content, :find, source_or_content.full_path.sub(/^\//,''))
connection = Puppet::Network::HttpPool.http_instance(source_or_content.server, source_or_content.port)
connection.request_get(indirection2uri(request), add_accept_encoding({"Accept" => "raw"})) do |response|
case response.code
diff --git a/lib/puppet/type/file/ensure.rb b/lib/puppet/type/file/ensure.rb
index c74a1d47a..967e06aee 100755
--- a/lib/puppet/type/file/ensure.rb
+++ b/lib/puppet/type/file/ensure.rb
@@ -3,27 +3,27 @@ module Puppet
require 'etc'
desc "Whether to create files that don't currently exist.
Possible values are *absent*, *present*, *file*, and *directory*.
- Specifying ``present`` will match any form of file existence, and
+ Specifying `present` will match any form of file existence, and
if the file is missing will create an empty file. Specifying
- ``absent`` will delete the file (and directory if recurse => true).
+ `absent` will delete the file (and directory if recurse => true).
Anything other than those values will be considered to be a symlink.
- For instance, the following text creates a link::
+ For instance, the following text creates a link:
- # Useful on solaris
- file { \"/etc/inetd.conf\":
- ensure => \"/etc/inet/inetd.conf\"
- }
+ # Useful on solaris
+ file { \"/etc/inetd.conf\":
+ ensure => \"/etc/inet/inetd.conf\"
+ }
- You can make relative links::
+ You can make relative links:
- # Useful on solaris
- file { \"/etc/inetd.conf\":
- ensure => \"inet/inetd.conf\"
- }
+ # Useful on solaris
+ file { \"/etc/inetd.conf\":
+ ensure => \"inet/inetd.conf\"
+ }
If you need to make a relative link to a file named the same
- as one of the valid values, you must prefix it with ``./`` or
+ as one of the valid values, you must prefix it with `./` or
something similar.
You can also make recursive symlinks, which will create a
diff --git a/lib/puppet/type/file/mode.rb b/lib/puppet/type/file/mode.rb
index 9abf56d26..1ce56c843 100755
--- a/lib/puppet/type/file/mode.rb
+++ b/lib/puppet/type/file/mode.rb
@@ -13,14 +13,14 @@ module Puppet
entries in a directory, and search/traverse allows you to access
(read/write/execute) those entries.) Because of this feature, you
can recursively make a directory and all of the files in it
- world-readable by setting e.g.::
+ world-readable by setting e.g.:
- file { '/some/dir':
- mode => 644,
- recurse => true,
- }
+ file { '/some/dir':
+ mode => 644,
+ recurse => true,
+ }
- In this case all of the files underneath ``/some/dir`` will have
+ In this case all of the files underneath `/some/dir` will have
mode 644, and all of the directories will have mode 755."
@event = :file_changed
diff --git a/lib/puppet/type/file/selcontext.rb b/lib/puppet/type/file/selcontext.rb
index edcfb83b2..a33c6a000 100644
--- a/lib/puppet/type/file/selcontext.rb
+++ b/lib/puppet/type/file/selcontext.rb
@@ -56,7 +56,7 @@ module Puppet
Puppet::Type.type(:file).newproperty(:seluser, :parent => Puppet::SELFileContext) do
desc "What the SELinux user component of the context of the file should be.
- Any valid SELinux user component is accepted. For example ``user_u``.
+ Any valid SELinux user component is accepted. For example `user_u`.
If not specified it defaults to the value returned by matchpathcon for
the file, if any exists. Only valid on systems with SELinux support
enabled."
@@ -67,7 +67,7 @@ module Puppet
Puppet::Type.type(:file).newproperty(:selrole, :parent => Puppet::SELFileContext) do
desc "What the SELinux role component of the context of the file should be.
- Any valid SELinux role component is accepted. For example ``role_r``.
+ Any valid SELinux role component is accepted. For example `role_r`.
If not specified it defaults to the value returned by matchpathcon for
the file, if any exists. Only valid on systems with SELinux support
enabled."
@@ -78,7 +78,7 @@ module Puppet
Puppet::Type.type(:file).newproperty(:seltype, :parent => Puppet::SELFileContext) do
desc "What the SELinux type component of the context of the file should be.
- Any valid SELinux type component is accepted. For example ``tmp_t``.
+ Any valid SELinux type component is accepted. For example `tmp_t`.
If not specified it defaults to the value returned by matchpathcon for
the file, if any exists. Only valid on systems with SELinux support
enabled."
@@ -89,8 +89,8 @@ module Puppet
Puppet::Type.type(:file).newproperty(:selrange, :parent => Puppet::SELFileContext) do
desc "What the SELinux range component of the context of the file should be.
- Any valid SELinux range component is accepted. For example ``s0`` or
- ``SystemHigh``. If not specified it defaults to the value returned by
+ Any valid SELinux range component is accepted. For example `s0` or
+ `SystemHigh`. If not specified it defaults to the value returned by
matchpathcon for the file, if any exists. Only valid on systems with
SELinux support enabled and that have support for MCS (Multi-Category
Security)."
diff --git a/lib/puppet/type/file/source.rb b/lib/puppet/type/file/source.rb
index 2eaf4a33f..7d03de2b0 100755
--- a/lib/puppet/type/file/source.rb
+++ b/lib/puppet/type/file/source.rb
@@ -12,7 +12,7 @@ module Puppet
include Puppet::Util::Diff
attr_accessor :source, :local
- desc "Copy a file over the current file. Uses ``checksum`` to
+ desc "Copy a file over the current file. Uses `checksum` to
determine when a file should be copied. Valid values are either
fully qualified paths to files, or URIs. Currently supported URI
types are *puppet* and *file*.
@@ -20,47 +20,47 @@ module Puppet
This is one of the primary mechanisms for getting content into
applications that Puppet does not directly support and is very
useful for those configuration files that don't change much across
- sytems. For instance::
+ sytems. For instance:
- class sendmail {
- file { \"/etc/mail/sendmail.cf\":
- source => \"puppet://server/modules/module_name/sendmail.cf\"
+ class sendmail {
+ file { \"/etc/mail/sendmail.cf\":
+ source => \"puppet://server/modules/module_name/sendmail.cf\"
+ }
}
- }
- You can also leave out the server name, in which case ``puppet agent``
- will fill in the name of its configuration server and ``puppet apply``
+ You can also leave out the server name, in which case `puppet agent`
+ will fill in the name of its configuration server and `puppet apply`
will use the local filesystem. This makes it easy to use the same
configuration in both local and centralized forms.
- Currently, only the ``puppet`` scheme is supported for source
+ Currently, only the `puppet` scheme is supported for source
URL's. Puppet will connect to the file server running on
- ``server`` to retrieve the contents of the file. If the
- ``server`` part is empty, the behavior of the command-line
- interpreter (``puppet apply``) and the client demon (``puppet agent``) differs
- slightly: ``apply`` will look such a file up on the module path
- on the local host, whereas ``agent`` will connect to the
+ `server` to retrieve the contents of the file. If the
+ `server` part is empty, the behavior of the command-line
+ interpreter (`puppet apply`) and the client demon (`puppet agent`) differs
+ slightly: `apply` will look such a file up on the module path
+ on the local host, whereas `agent` will connect to the
puppet server that it received the manifest from.
- See the `FileServingConfiguration fileserver configuration documentation`:trac: for information on how to configure
+ See the [fileserver configuration documentation](http://projects.puppetlabs.com/projects/puppet/wiki/File_Serving_Configuration) for information on how to configure
and use file services within Puppet.
If you specify multiple file sources for a file, then the first
source that exists will be used. This allows you to specify
- what amount to search paths for files::
-
- file { \"/path/to/my/file\":
- source => [
- \"/modules/nfs/files/file.$host\",
- \"/modules/nfs/files/file.$operatingsystem\",
- \"/modules/nfs/files/file\"
- ]
- }
+ what amount to search paths for files:
+
+ file { \"/path/to/my/file\":
+ source => [
+ \"/modules/nfs/files/file.$host\",
+ \"/modules/nfs/files/file.$operatingsystem\",
+ \"/modules/nfs/files/file\"
+ ]
+ }
This will use the first found file as the source.
- You cannot currently copy links using this mechanism; set ``links``
- to ``follow`` if any remote sources are links.
+ You cannot currently copy links using this mechanism; set `links`
+ to `follow` if any remote sources are links.
"
validate do |sources|
@@ -94,6 +94,16 @@ module Puppet
metadata && metadata.checksum
end
+ # Look up (if necessary) and return remote content.
+ cached_attr(:content) do
+ raise Puppet::DevError, "No source for content was stored with the metadata" unless metadata.source
+
+ unless tmp = Puppet::FileServing::Content.find(metadata.source)
+ fail "Could not find any content at %s" % metadata.source
+ end
+ tmp.content
+ end
+
# Copy the values from the source to the resource. Yay.
def copy_source_values
devfail "Somehow got asked to copy source values without any metadata" unless metadata
diff --git a/lib/puppet/type/filebucket.rb b/lib/puppet/type/filebucket.rb
index 65ff88411..7fd2ef46b 100755
--- a/lib/puppet/type/filebucket.rb
+++ b/lib/puppet/type/filebucket.rb
@@ -16,13 +16,13 @@ module Puppet
undo transactions.
You will normally want to define a single filebucket for your
- whole network and then use that as the default backup location::
+ whole network and then use that as the default backup location:
- # Define the bucket
- filebucket { main: server => puppet }
+ # Define the bucket
+ filebucket { main: server => puppet }
- # Specify it as the default target
- File { backup => main }
+ # Specify it as the default target
+ File { backup => main }
Puppetmaster servers create a filebucket by default, so this will
work in a default configuration."
@@ -92,4 +92,3 @@ module Puppet
end
end
end
-
diff --git a/lib/puppet/type/group.rb b/lib/puppet/type/group.rb
index 9f26d2243..cde1cfd65 100755
--- a/lib/puppet/type/group.rb
+++ b/lib/puppet/type/group.rb
@@ -89,7 +89,7 @@ module Puppet
newparam(:allowdupe, :boolean => true) do
desc "Whether to allow duplicate GIDs. This option does not work on
- FreeBSD (contract to the ``pw`` man page)."
+ FreeBSD (contract to the `pw` man page)."
newvalues(:true, :false)
@@ -97,4 +97,3 @@ module Puppet
end
end
end
-
diff --git a/lib/puppet/type/host.rb b/lib/puppet/type/host.rb
index 929542d7c..1af74d886 100755
--- a/lib/puppet/type/host.rb
+++ b/lib/puppet/type/host.rb
@@ -5,19 +5,17 @@ module Puppet
newproperty(:ip) do
desc "The host's IP address, IPv4 or IPv6."
- validate do |value|
- unless value =~ /((([0-9a-fA-F]+:){7}[0-9a-fA-F]+)|(([0-9a-fA-F]+:)*[0-9a-fA-F]+)?::(([0-9a-fA-F]+:)*[0-9a-fA-F]+)?)|((25[0-5]|2[0-4][\d]|[0-1]?\d?\d)(\.(25[0-5]|2[0-4]\d|[0-1]?\d?\d)){3})/
- raise Puppet::Error, "Invalid IP address"
+ validate do |value|
+ unless value =~ /^((([0-9a-fA-F]+:){7}[0-9a-fA-F]+)|(([0-9a-fA-F]+:)*[0-9a-fA-F]+)?::(([0-9a-fA-F]+:)*[0-9a-fA-F]+)?)|((25[0-5]|2[0-4][\d]|[0-1]?\d?\d)(\.(25[0-5]|2[0-4]\d|[0-1]?\d?\d)){3})$/
+ raise Puppet::Error, "Invalid IP address"
+ end
end
- end
end
newproperty(:host_aliases) do
- desc 'Any aliases the host might have. Multiple values must be
- specified as an array. Note that this property is not the same as
- the "alias" metaparam; use this property to add aliases to a host
- on disk, and "alias" to aliases for use in your Puppet scripts.'
+ desc "Any aliases the host might have. Multiple values must be
+ specified as an array."
def insync?(is)
is == @should
@@ -28,21 +26,6 @@ module Puppet
currentvalue.join(" ")
end
- def retrieve
- is = super
- case is
- when String
- is = is.split(/\s*,\s*/)
- when Symbol
- is = [is]
- when Array
- # nothing
- else
- raise Puppet::DevError, "Invalid @is type #{is.class}"
- end
- is
- end
-
# We actually want to return the whole array here, not just the first
# value.
def should
@@ -63,9 +46,14 @@ module Puppet
validate do |value|
raise Puppet::Error, "Host aliases cannot include whitespace" if value =~ /\s/
+ raise Puppet::Error, "Host alias cannot be an empty string. Use an empty array to delete all host_aliases " if value =~ /^\s*$/
end
end
+ newproperty(:comment) do
+ desc "A comment that will be attached to the line with a # character"
+ end
+
newproperty(:target) do
desc "The file in which to store service information. Only used by
those providers that write to disk."
@@ -94,8 +82,7 @@ module Puppet
end
@doc = "Installs and manages host entries. For most systems, these
- entries will just be in ``/etc/hosts``, but some systems (notably OS X)
+ entries will just be in `/etc/hosts`, but some systems (notably OS X)
will have different solutions."
end
end
-
diff --git a/lib/puppet/type/k5login.rb b/lib/puppet/type/k5login.rb
index 850e37733..a343e9e5c 100644
--- a/lib/puppet/type/k5login.rb
+++ b/lib/puppet/type/k5login.rb
@@ -3,15 +3,15 @@
# Plug-in type for handling k5login files
Puppet::Type.newtype(:k5login) do
- @doc = "Manage the .k5login file for a user. Specify the full path to
- the .k5login file as the name and an array of principals as the
+ @doc = "Manage the `.k5login` file for a user. Specify the full path to
+ the `.k5login` file as the name and an array of principals as the
property principals."
ensurable
# Principals that should exist in the file
newproperty(:principals, :array_matching => :all) do
- desc "The principals present in the .k5login file."
+ desc "The principals present in the `.k5login` file."
end
# The path/name of the k5login file
diff --git a/lib/puppet/type/macauthorization.rb b/lib/puppet/type/macauthorization.rb
index 9b17c279d..ef6fbb6c1 100644
--- a/lib/puppet/type/macauthorization.rb
+++ b/lib/puppet/type/macauthorization.rb
@@ -1,8 +1,7 @@
Puppet::Type.newtype(:macauthorization) do
@doc = "Manage the Mac OS X authorization database.
- See:
- http://developer.apple.com/documentation/Security/Conceptual/Security_Overview/Security_Services/chapter_4_section_5.html for more information."
+ See the [Apple developer site](http://developer.apple.com/documentation/Security/Conceptual/Security_Overview/Security_Services/chapter_4_section_5.html) for more information."
ensurable
diff --git a/lib/puppet/type/mailalias.rb b/lib/puppet/type/mailalias.rb
index 5534fdf25..ce7ca790b 100755
--- a/lib/puppet/type/mailalias.rb
+++ b/lib/puppet/type/mailalias.rb
@@ -46,4 +46,3 @@ module Puppet
end
end
end
-
diff --git a/lib/puppet/type/maillist.rb b/lib/puppet/type/maillist.rb
index 7ac0e4e4f..732fbf09f 100755
--- a/lib/puppet/type/maillist.rb
+++ b/lib/puppet/type/maillist.rb
@@ -60,4 +60,3 @@ module Puppet
end
end
end
-
diff --git a/lib/puppet/type/mcx.rb b/lib/puppet/type/mcx.rb
index e56b11938..4f0a6c3c5 100644
--- a/lib/puppet/type/mcx.rb
+++ b/lib/puppet/type/mcx.rb
@@ -21,8 +21,6 @@ Puppet::Type.newtype(:mcx) do
@doc = "MCX object management using DirectoryService on OS X.
-Original Author: Jeff McCune <mccune.jeff@gmail.com>
-
The default provider of this type merely manages the XML plist as
reported by the dscl -mcxexport command. This is similar to the
content property of the file type in Puppet.
@@ -51,13 +49,13 @@ to other machines.
newparam(:name) do
desc "The name of the resource being managed.
- The default naming convention follows Directory Service paths::
+ The default naming convention follows Directory Service paths:
- /Computers/localhost
- /Groups/admin
- /Users/localadmin
+ /Computers/localhost
+ /Groups/admin
+ /Users/localadmin
- The ds_type and ds_name type parameters are not necessary if the
+ The `ds_type` and `ds_name` type parameters are not necessary if the
default naming convention is followed."
isnamevar
end
@@ -80,8 +78,10 @@ to other machines.
newproperty(:content, :required_features => :manages_content) do
desc "The XML Plist. The value of MCXSettings in DirectoryService.
This is the standard output from the system command:
- dscl localhost -mcxexport /Local/Default/<ds_type>/ds_name
- Note that ds_type is capitalized and plural in the dscl command."
+
+ dscl localhost -mcxexport /Local/Default/<ds_type>/ds_name
+
+ Note that `ds_type` is capitalized and plural in the dscl command."
end
# JJM Yes, this is not DRY at all. Because of the code blocks
diff --git a/lib/puppet/type/mount.rb b/lib/puppet/type/mount.rb
index 6ee5dd174..e8c6b3290 100755
--- a/lib/puppet/type/mount.rb
+++ b/lib/puppet/type/mount.rb
@@ -5,8 +5,8 @@ module Puppet
information into the mount table. The actual behavior depends
on the value of the 'ensure' parameter.
- Note that if a ``mount`` receives an event from another resource,
- it will try to remount the filesystems if ``ensure`` is set to ``mounted``."
+ Note that if a `mount` receives an event from another resource,
+ it will try to remount the filesystems if `ensure` is set to `mounted`."
feature :refreshable, "The provider can remount the filesystem.",
:methods => [:remount]
@@ -15,10 +15,10 @@ module Puppet
# call code when sync is called.
newproperty(:ensure) do
desc "Control what to do with this mount. Set this attribute to
- ``umounted`` to make sure the filesystem is in the filesystem table
- but not mounted (if the filesystem is currently mounted, it will be unmounted). Set it to ``absent`` to unmount (if necessary) and remove
- the filesystem from the fstab. Set to ``mounted`` to add it to the
- fstab and mount it. Set to ``present`` to add to fstab but not change
+ `umounted` to make sure the filesystem is in the filesystem table
+ but not mounted (if the filesystem is currently mounted, it will be unmounted). Set it to `absent` to unmount (if necessary) and remove
+ the filesystem from the fstab. Set to `mounted` to add it to the
+ fstab and mount it. Set to `present` to add to fstab but not change
mount/unmount status"
newvalue(:defined) do
@@ -149,7 +149,7 @@ module Puppet
newproperty(:dump) do
desc "Whether to dump the mount. Not all platform support this.
- Valid values are ``1`` or ``0``. or ``2`` on FreeBSD, Default is ``0``."
+ Valid values are `1` or `0`. or `2` on FreeBSD, Default is `0`."
if Facter["operatingsystem"].value == "FreeBSD"
newvalue(%r{(0|1|2)})
@@ -183,7 +183,7 @@ module Puppet
end
newparam(:path) do
- desc "The deprecated name for the mount point. Please use ``name`` now."
+ desc "The deprecated name for the mount point. Please use `name` now."
def value=(value)
warning "'path' is deprecated for mounts. Please use 'name'."
@@ -193,7 +193,7 @@ module Puppet
end
newparam(:remounts) do
- desc "Whether the mount can be remounted ``mount -o remount``. If
+ desc "Whether the mount can be remounted `mount -o remount`. If
this is false, then the filesystem will be unmounted and remounted
manually, which is prone to failure."
@@ -210,7 +210,7 @@ module Puppet
def refresh
# Only remount if we're supposed to be mounted.
- provider.remount if self.should(:fstype) != "swap" and provider.mounted?
+ provider.remount if self.should(:fstype) != "swap" and self.should(:ensure) == :mounted
end
def value(name)
@@ -222,4 +222,3 @@ module Puppet
end
end
end
-
diff --git a/lib/puppet/type/notify.rb b/lib/puppet/type/notify.rb
index 97935e270..a6ec1dc8b 100644
--- a/lib/puppet/type/notify.rb
+++ b/lib/puppet/type/notify.rb
@@ -42,4 +42,3 @@ module Puppet
end
end
end
-
diff --git a/lib/puppet/type/package.rb b/lib/puppet/type/package.rb
index f25464db5..51a866332 100644
--- a/lib/puppet/type/package.rb
+++ b/lib/puppet/type/package.rb
@@ -8,12 +8,12 @@ module Puppet
@doc = "Manage packages. There is a basic dichotomy in package
support right now: Some package types (e.g., yum and apt) can
retrieve their own package files, while others (e.g., rpm and sun) cannot. For those package formats that cannot retrieve
- their own files, you can use the ``source`` parameter to point to
+ their own files, you can use the `source` parameter to point to
the correct file.
Puppet will automatically guess the packaging format that you are
using based on the platform you are on, but you can override it
- using the ``provider`` parameter; each provider defines what it
+ using the `provider` parameter; each provider defines what it
requires in order to function, and you must meet those requirements
to use a given provider."
@@ -22,7 +22,7 @@ module Puppet
feature :uninstallable, "The provider can uninstall packages.",
:methods => [:uninstall]
feature :upgradeable, "The provider can upgrade to the latest version of a
- package. This feature is used by specifying ``latest`` as the
+ package. This feature is used by specifying `latest` as the
desired value for the package.",
:methods => [:update, :latest]
feature :purgeable, "The provider can purge packages. This generally means
@@ -104,7 +104,6 @@ module Puppet
end
end
-
defaultto :installed
# Override the parent method, because we've got all kinds of
@@ -181,35 +180,35 @@ module Puppet
system uses internally, which is sometimes (especially on Solaris)
a name that is basically useless to humans. If you want to
abstract package installation, then you can use aliases to provide
- a common name to packages::
-
- # In the 'openssl' class
- $ssl = $operatingsystem ? {
- solaris => SMCossl,
- default => openssl
- }
-
- # It is not an error to set an alias to the same value as the
- # object name.
- package { $ssl:
- ensure => installed,
- alias => openssl
- }
-
- . etc. .
-
- $ssh = $operatingsystem ? {
- solaris => SMCossh,
- default => openssh
- }
-
- # Use the alias to specify a dependency, rather than
- # having another selector to figure it out again.
- package { $ssh:
- ensure => installed,
- alias => openssh,
- require => Package[openssl]
- }
+ a common name to packages:
+
+ # In the 'openssl' class
+ $ssl = $operatingsystem ? {
+ solaris => SMCossl,
+ default => openssl
+ }
+
+ # It is not an error to set an alias to the same value as the
+ # object name.
+ package { $ssl:
+ ensure => installed,
+ alias => openssl
+ }
+
+ . etc. .
+
+ $ssh = $operatingsystem ? {
+ solaris => SMCossh,
+ default => openssh
+ }
+
+ # Use the alias to specify a dependency, rather than
+ # having another selector to figure it out again.
+ package { $ssh:
+ ensure => installed,
+ alias => openssh,
+ require => Package[openssl]
+ }
"
isnamevar
@@ -228,7 +227,7 @@ module Puppet
end
newparam(:type) do
- desc "Deprecated form of ``provider``."
+ desc "Deprecated form of `provider`."
munge do |value|
warning "'type' is deprecated; use 'provider' instead"
@@ -243,7 +242,7 @@ module Puppet
This is currently only used on Solaris. The value will be
validated according to system rules, which in the case of
Solaris means that it should either be a fully qualified path
- or it should be in /var/sadm/install/admin."
+ or it should be in `/var/sadm/install/admin`."
end
newparam(:responsefile) do
@@ -320,4 +319,3 @@ module Puppet
end
end
end
-
diff --git a/lib/puppet/type/resources.rb b/lib/puppet/type/resources.rb
index 34382e067..ae41b883b 100644
--- a/lib/puppet/type/resources.rb
+++ b/lib/puppet/type/resources.rb
@@ -1,12 +1,9 @@
-# Created by Luke Kanies on 2006-12-12.
-# Copyright (c) 2006. All rights reserved.
-
require 'puppet'
Puppet::Type.newtype(:resources) do
@doc = "This is a metatype that can manage other resource types. Any
metaparams specified here will be passed on to any generated resources,
- so you can purge umanaged resources but set ``noop`` to true so the
+ so you can purge umanaged resources but set `noop` to true so the
purging is only logged and does not actually happen."
@@ -132,4 +129,3 @@ Puppet::Type.newtype(:resources) do
%w{root nobody bin noaccess daemon sys}
end
end
-
diff --git a/lib/puppet/type/schedule.rb b/lib/puppet/type/schedule.rb
index bedf1e536..82f17e533 100755
--- a/lib/puppet/type/schedule.rb
+++ b/lib/puppet/type/schedule.rb
@@ -16,7 +16,7 @@ module Puppet
Thus, it behooves you to use wider scheduling (e.g., over a couple of
hours) combined with periods and repetitions. For instance, if you
wanted to restrict certain resources to only running once, between
- the hours of two and 4 AM, then you would use this schedule::
+ the hours of two and 4 AM, then you would use this schedule:
schedule { maint:
range => \"2 - 4\",
@@ -33,7 +33,7 @@ module Puppet
Puppet automatically creates a schedule for each valid period with the
same name as that period (e.g., hourly and daily). Additionally,
a schedule named *puppet* is created and used as the default,
- with the following attributes::
+ with the following attributes:
schedule { puppet:
period => hourly,
@@ -45,11 +45,11 @@ module Puppet
newparam(:name) do
desc "The name of the schedule. This name is used to retrieve the
- schedule when assigning it to an object::
+ schedule when assigning it to an object:
schedule { daily:
period => daily,
- range => [2, 4]
+ range => \"2 - 4\",
}
exec { \"/usr/bin/apt-get update\":
@@ -65,7 +65,7 @@ module Puppet
is always a range within a 24 hour period, and hours must be
specified in numbers between 0 and 23, inclusive. Minutes and
seconds can be provided, using the normal colon as a separator.
- For instance::
+ For instance:
schedule { maintenance:
range => \"1:30 - 4:30\"
@@ -196,17 +196,17 @@ module Puppet
Note that the period defines how often a given resource will get
applied but not when; if you would like to restrict the hours
that a given resource can be applied (e.g., only at night during
- a maintenance window) then use the ``range`` attribute.
+ a maintenance window) then use the `range` attribute.
If the provided periods are not sufficient, you can provide a
value to the *repeat* attribute, which will cause Puppet to
schedule the affected resources evenly in the period the
- specified number of times. Take this schedule::
+ specified number of times. Take this schedule:
- schedule { veryoften:
- period => hourly,
- repeat => 6
- }
+ schedule { veryoften:
+ period => hourly,
+ repeat => 6
+ }
This can cause Puppet to apply that resource up to every 10 minutes.
@@ -215,7 +215,7 @@ module Puppet
internal factors might prevent it from actually running that
often (e.g., long-running Puppet runs will squash conflictingly scheduled runs).
- See the ``periodmatch`` attribute for tuning whether to match
+ See the `periodmatch` attribute for tuning whether to match
times by their distance apart or by their specific value."
newvalues(:hourly, :daily, :weekly, :monthly, :never)
@@ -307,10 +307,10 @@ module Puppet
Puppet.debug "Creating default schedules"
result << self.new(
-
+
:name => "puppet",
:period => :hourly,
-
+
:repeat => "2"
)
@@ -318,9 +318,7 @@ module Puppet
@parameters.find { |p| p.name == :period }.value_collection.values.each { |value|
result << self.new(
-
:name => value.to_s,
-
:period => value
)
}
@@ -349,4 +347,3 @@ module Puppet
end
end
end
-
diff --git a/lib/puppet/type/selboolean.rb b/lib/puppet/type/selboolean.rb
index cf873e987..204b89056 100644
--- a/lib/puppet/type/selboolean.rb
+++ b/lib/puppet/type/selboolean.rb
@@ -1,11 +1,7 @@
-#
-# Simple module for manageing SELinux booleans
-#
-
module Puppet
newtype(:selboolean) do
@doc = "Manages SELinux booleans on systems with SELinux support. The supported booleans
- are any of the ones found in /selinux/booleans/."
+ are any of the ones found in `/selinux/booleans/`."
newparam(:name) do
desc "The name of the SELinux boolean to be managed."
@@ -20,7 +16,7 @@ module Puppet
newparam(:persistent) do
desc "If set true, SELinux booleans will be written to disk and persist accross reboots.
- The default is ``false``."
+ The default is `false`."
defaultto :false
newvalues(:true, :false)
@@ -28,4 +24,3 @@ module Puppet
end
end
-
diff --git a/lib/puppet/type/selmodule.rb b/lib/puppet/type/selmodule.rb
index 240d6e6d1..60be8a855 100644
--- a/lib/puppet/type/selmodule.rb
+++ b/lib/puppet/type/selmodule.rb
@@ -18,7 +18,7 @@ Puppet::Type.newtype(:selmodule) do
newparam(:selmoduledir) do
desc "The directory to look for the compiled pp module file in.
- Currently defaults to /usr/share/selinux/targeted. If selmodulepath
+ Currently defaults to `/usr/share/selinux/targeted`. If selmodulepath
is not specified the module will be looked for in this directory in a
in a file called NAME.pp, where NAME is the value of the name parameter."
@@ -34,9 +34,9 @@ Puppet::Type.newtype(:selmodule) do
newproperty(:syncversion) do
- desc "If set to ``true``, the policy will be reloaded if the
+ desc "If set to `true`, the policy will be reloaded if the
version found in the on-disk file differs from the loaded
- version. If set to ``false`` (the default) the the only check
+ version. If set to `false` (the default) the the only check
that will be made is if the policy is loaded at all or not."
newvalue(:true)
@@ -51,4 +51,3 @@ Puppet::Type.newtype(:selmodule) do
end
end
end
-
diff --git a/lib/puppet/type/service.rb b/lib/puppet/type/service.rb
index 8f5c6ee37..786a50448 100644
--- a/lib/puppet/type/service.rb
+++ b/lib/puppet/type/service.rb
@@ -17,10 +17,10 @@ module Puppet
can provide the better behaviour you will get. Or, you can just
use a platform that has very good service support.
- Note that if a ``service`` receives an event from another resource,
+ Note that if a `service` receives an event from another resource,
the service will get restarted. The actual command to restart the
service depends on the platform. You can provide a special command
- for restarting with the ``restart`` attribute."
+ for restarting with the `restart` attribute."
feature :refreshable, "The provider can restart the service.",
:methods => [:restart]
@@ -83,7 +83,7 @@ module Puppet
newparam(:binary) do
desc "The path to the daemon. This is only used for
systems that do not support init scripts. This binary will be
- used to start the service if no ``start`` parameter is
+ used to start the service if no `start` parameter is
provided."
end
@@ -94,12 +94,14 @@ module Puppet
not support any kind of status command; thus, you must specify
manually whether the service you are running has such a
command (or you can specify a specific command using the
- ``status`` parameter).
+ `status` parameter).
If you do not specify anything, then the service name will be
looked for in the process table."
newvalues(:true, :false)
+
+ defaultto :true
end
newparam(:name) do
desc "The name of the service to run. This name is used to find
@@ -140,7 +142,7 @@ module Puppet
end
newparam(:start) do
desc "Specify a *start* command manually. Most service subsystems
- support a ``start`` command, so this will not need to be
+ support a `start` command, so this will not need to be
specified."
end
newparam(:status) do
@@ -156,14 +158,14 @@ module Puppet
newparam(:control) do
desc "The control variable used to manage services (originally for HP-UX).
- Defaults to the upcased service name plus ``START`` replacing dots with
- underscores, for those providers that support the ``controllable`` feature."
+ Defaults to the upcased service name plus `START` replacing dots with
+ underscores, for those providers that support the `controllable` feature."
defaultto { resource.name.gsub(".","_").upcase + "_START" if resource.provider.controllable? }
end
newparam :hasrestart do
- desc "Specify that an init script has a ``restart`` option. Otherwise,
- the init script's ``stop`` and ``start`` methods are used."
+ desc "Specify that an init script has a `restart` option. Otherwise,
+ the init script's `stop` and `start` methods are used."
newvalues(:true, :false)
end
diff --git a/lib/puppet/type/ssh_authorized_key.rb b/lib/puppet/type/ssh_authorized_key.rb
index 2bfa87b0f..e3320140e 100644
--- a/lib/puppet/type/ssh_authorized_key.rb
+++ b/lib/puppet/type/ssh_authorized_key.rb
@@ -34,8 +34,8 @@ module Puppet
newproperty(:target) do
desc "The absolute filename in which to store the SSH key. This
property is optional and should only be used in cases where keys
- are stored in a non-standard location (ie not in
- ~user/.ssh/authorized_keys)."
+ are stored in a non-standard location (i.e.` not in
+ `~user/.ssh/authorized_keys`)."
defaultto :absent
@@ -96,4 +96,3 @@ module Puppet
end
end
end
-
diff --git a/lib/puppet/type/sshkey.rb b/lib/puppet/type/sshkey.rb
index e1adc7173..b7a1b8a8d 100755
--- a/lib/puppet/type/sshkey.rb
+++ b/lib/puppet/type/sshkey.rb
@@ -1,8 +1,8 @@
module Puppet
newtype(:sshkey) do
@doc = "Installs and manages ssh host keys. At this point, this type
- only knows how to install keys into /etc/ssh/ssh_known_hosts, and
- it cannot manage user authorized keys yet."
+ only knows how to install keys into `/etc/ssh/ssh_known_hosts`. See
+ the `ssh_authorized_key` type to manage authorized keys."
ensurable
@@ -23,9 +23,7 @@ module Puppet
# to see if we can automatically glean any aliases.
newproperty(:host_aliases) do
desc 'Any aliases the host might have. Multiple values must be
- specified as an array. Note that this property is not the same as
- the "alias" metaparam; use this property to add aliases to a host
- on disk, and "alias" to aliases for use in your Puppet scripts.'
+ specified as an array.'
attr_accessor :meta
@@ -56,7 +54,7 @@ module Puppet
newproperty(:target) do
desc "The file in which to store the ssh key. Only used by
- the ``parsed`` provider."
+ the `parsed` provider."
defaultto { if @resource.class.defaultprovider.ancestors.include?(Puppet::Provider::ParsedFile)
@resource.class.defaultprovider.default_target
@@ -67,4 +65,3 @@ module Puppet
end
end
end
-
diff --git a/lib/puppet/type/stage.rb b/lib/puppet/type/stage.rb
index d22cd7b70..0736dc4b9 100644
--- a/lib/puppet/type/stage.rb
+++ b/lib/puppet/type/stage.rb
@@ -1,11 +1,12 @@
Puppet::Type.newtype(:stage) do
desc "A resource type for specifying run stages. The actual stage should
- be specified on resources::
- class { foo: stage => pre }
+ be specified on resources:
+
+ class { foo: stage => pre }
- And you must manually control stage order::
+ And you must manually control stage order:
- stage { pre: before => Stage[main] }
+ stage { pre: before => Stage[main] }
You automatically get a 'main' stage created, and by default all resources
get inserted into that stage.
diff --git a/lib/puppet/type/tidy.rb b/lib/puppet/type/tidy.rb
index a6605211e..93a7e96cf 100755
--- a/lib/puppet/type/tidy.rb
+++ b/lib/puppet/type/tidy.rb
@@ -1,11 +1,12 @@
Puppet::Type.newtype(:tidy) do
require 'puppet/file_serving/fileset'
+ require 'puppet/file_bucket/dipper'
@doc = "Remove unwanted files based on specific criteria. Multiple
criteria are OR'd together, so a file that is too large but is not
old enough will still get tidied.
- If you don't specify either 'age' or 'size', then all files will
+ If you don't specify either `age` or `size`, then all files will
be removed.
This resource type works by generating a file resource for every file
@@ -47,7 +48,7 @@ Puppet::Type.newtype(:tidy) do
at least one of the patterns specified. Multiple patterns can
be specified using an array.
- Example::
+ Example:
tidy { \"/tmp\":
age => \"1w\",
@@ -55,7 +56,7 @@ Puppet::Type.newtype(:tidy) do
matches => [ \"[0-9]pub*.tmp\", \"*.temp\", \"tmpfile?\" ]
}
- This removes files from \/tmp if they are one week old or older,
+ This removes files from `/tmp` if they are one week old or older,
are not in a subdirectory and match one of the shell globs given.
Note that the patterns are matched against the basename of each
@@ -140,15 +141,17 @@ Puppet::Type.newtype(:tidy) do
newparam(:size) do
desc "Tidy files whose size is equal to or greater than
the specified size. Unqualified values are in kilobytes, but
- *b*, *k*, and *m* can be appended to specify *bytes*, *kilobytes*,
- and *megabytes*, respectively. Only the first character is
- significant, so the full word can also be used."
+ *b*, *k*, *m*, *g*, and *t* can be appended to specify *bytes*,
+ *kilobytes*, *megabytes*, *gigabytes*, and *terabytes*, respectively.
+ Only the first character is significant, so the full word can also
+ be used."
@@sizeconvertors = {
:b => 0,
:k => 1,
:m => 2,
- :g => 3
+ :g => 3,
+ :t => 4
}
def convert(unit, multi)
diff --git a/lib/puppet/type/user.rb b/lib/puppet/type/user.rb
index c7ac796a3..c8110bb69 100755
--- a/lib/puppet/type/user.rb
+++ b/lib/puppet/type/user.rb
@@ -12,7 +12,7 @@ module Puppet
This resource type uses the prescribed native tools for creating
groups and generally uses POSIX APIs for retrieving information
- about them. It does not directly modify /etc/passwd or anything."
+ about them. It does not directly modify `/etc/passwd` or anything."
feature :allows_duplicates,
"The provider supports duplicate users with the same UID."
@@ -24,9 +24,16 @@ module Puppet
"The provider can modify user passwords, by accepting a password
hash."
+ feature :manages_password_age,
+ "The provider can set age requirements and restrictions for
+ passwords."
+
feature :manages_solaris_rbac,
"The provider can manage roles and normal users"
+ feature :manages_expiry,
+ "The provider can manage the expiry date for a user."
+
newproperty(:ensure, :parent => Puppet::Property::Ensure) do
newvalue(:present, :event => :user_created) do
provider.create
@@ -157,6 +164,43 @@ module Puppet
end
end
+ newproperty(:password_min_age, :required_features => :manages_password_age) do
+ desc "The minimum amount of time in days a password must be used before it may be changed"
+
+ munge do |value|
+ case value
+ when String
+ Integer(value)
+ else
+ value
+ end
+ end
+
+ validate do |value|
+ if value.to_s !~ /^\d+$/
+ raise ArgumentError, "Password minimum age must be provided as a number"
+ end
+ end
+ end
+
+ newproperty(:password_max_age, :required_features => :manages_password_age) do
+ desc "The maximum amount of time in days a password may be used before it must be changed"
+
+ munge do |value|
+ case value
+ when String
+ Integer(value)
+ else
+ value
+ end
+ end
+
+ validate do |value|
+ if value.to_s !~ /^\d+$/
+ raise ArgumentError, "Password maximum age must be provided as a number"
+ end
+ end
+ end
newproperty(:groups, :parent => Puppet::Property::List) do
desc "The groups of which the user is a member. The primary
@@ -210,6 +254,17 @@ module Puppet
end
end
+ newproperty(:expiry, :required_features => :manages_expiry) do
+ desc "The expiry date for this user. Must be provided in
+ a zero padded YYYY-MM-DD format - e.g 2010-02-19."
+
+ validate do |value|
+ if value !~ /^\d{4}-\d{2}-\d{2}$/
+ raise ArgumentError, "Expiry dates must be YYYY-MM-DD"
+ end
+ end
+ end
+
# Autorequire the group, if it's around
autorequire(:group) do
autos = []
@@ -381,4 +436,3 @@ module Puppet
end
end
end
-
diff --git a/lib/puppet/type/whit.rb b/lib/puppet/type/whit.rb
new file mode 100644
index 000000000..55bfcfb46
--- /dev/null
+++ b/lib/puppet/type/whit.rb
@@ -0,0 +1,11 @@
+Puppet::Type.newtype(:whit) do
+ desc "The smallest possible resource type, for when you need a resource and naught else."
+
+ newparam :name do
+ desc "The name of the whit, because it must have one."
+ end
+
+ def to_s
+ "Class[#{name}]"
+ end
+end
diff --git a/lib/puppet/type/yumrepo.rb b/lib/puppet/type/yumrepo.rb
index e0ed3ad37..160b2164d 100644
--- a/lib/puppet/type/yumrepo.rb
+++ b/lib/puppet/type/yumrepo.rb
@@ -52,8 +52,9 @@ module Puppet
newtype(:yumrepo) do
@doc = "The client-side description of a yum repository. Repository
- configurations are found by parsing /etc/yum.conf and
- the files indicated by reposdir in that file (see yum.conf(5) for details)
+ configurations are found by parsing `/etc/yum.conf` and
+ the files indicated by the `reposdir` option in that file
+ (see yum.conf(5) for details)
Most parameters are identical to the ones documented
in yum.conf(5)
@@ -85,7 +86,7 @@ module Puppet
clear
inifile.each_section do |s|
next if s.name == "main"
- obj = create(:name => s.name, :audit => check)
+ obj = new(:name => s.name, :audit => check)
current_values = obj.retrieve
obj.eachproperty do |property|
if current_values[property].nil?
@@ -294,6 +295,12 @@ module Puppet
newvalue(%r{(0|1)}) { }
end
+ newproperty(:http_caching, :parent => Puppet::IniProperty) do
+ desc "Either 'packages' or 'all' or 'none'.\n#{ABSENT_DOC}"
+ newvalue(:absent) { self.should = :absent }
+ newvalue(%r(packages|all|none)) { }
+ end
+
newproperty(:timeout, :parent => Puppet::IniProperty) do
desc "Number of seconds to wait for a connection before timing
out.\n#{ABSENT_DOC}"
@@ -324,6 +331,12 @@ module Puppet
newvalue(%r{[1-9][0-9]?}) { }
end
+ newproperty(:cost, :parent => Puppet::IniProperty) do
+ desc "Cost of this repository.\n#{ABSENT_DOC}"
+ newvalue(:absent) { self.should = :absent }
+ newvalue(%r{\d+}) { }
+ end
+
newproperty(:proxy, :parent => Puppet::IniProperty) do
desc "URL to the proxy server for this repository.\n#{ABSENT_DOC}"
newvalue(:absent) { self.should = :absent }
diff --git a/lib/puppet/type/zfs.rb b/lib/puppet/type/zfs.rb
index e1a972ddf..1757931f8 100755
--- a/lib/puppet/type/zfs.rb
+++ b/lib/puppet/type/zfs.rb
@@ -33,7 +33,7 @@ module Puppet
end
newproperty(:snapdir) do
- desc "The sharenfs property."
+ desc "The snapdir property."
end
autorequire(:zpool) do
@@ -48,4 +48,3 @@ module Puppet
end
end
end
-
diff --git a/lib/puppet/type/zone.rb b/lib/puppet/type/zone.rb
index d523c469a..408d6f5dd 100644
--- a/lib/puppet/type/zone.rb
+++ b/lib/puppet/type/zone.rb
@@ -69,9 +69,9 @@ Puppet::Type.newtype(:zone) do
ensurable do
desc "The running state of the zone. The valid states directly reflect
- the states that ``zoneadm`` provides. The states are linear,
- in that a zone must be ``configured`` then ``installed``, and
- only then can be ``running``. Note also that ``halt`` is currently
+ the states that `zoneadm` provides. The states are linear,
+ in that a zone must be `configured` then `installed`, and
+ only then can be `running`. Note also that `halt` is currently
used to stop zones."
@states = {}
@@ -313,31 +313,31 @@ Puppet::Type.newtype(:zone) do
# only used to boot the zone the very first time.
newparam(:sysidcfg) do
desc %{The text to go into the sysidcfg file when the zone is first
- booted. The best way is to use a template::
-
- # $templatedir/sysidcfg
- system_locale=en_US
- timezone=GMT
- terminal=xterms
- security_policy=NONE
- root_password=&lt;%= password %>
- timeserver=localhost
- name_service=DNS {domain_name=&lt;%= domain %> name_server=&lt;%= nameserver %>}
- network_interface=primary {hostname=&lt;%= realhostname %>
- ip_address=&lt;%= ip %>
- netmask=&lt;%= netmask %>
- protocol_ipv6=no
- default_route=&lt;%= defaultroute %>}
- nfs4_domain=dynamic
-
- And then call that::
-
- zone { myzone:
- ip => "bge0:192.168.0.23",
- sysidcfg => template(sysidcfg),
- path => "/opt/zones/myzone",
- realhostname => "fully.qualified.domain.name"
- }
+ booted. The best way is to use a template:
+
+ # $templatedir/sysidcfg
+ system_locale=en_US
+ timezone=GMT
+ terminal=xterms
+ security_policy=NONE
+ root_password=<%= password %>
+ timeserver=localhost
+ name_service=DNS {domain_name=<%= domain %> name_server=<%= nameserver %>}
+ network_interface=primary {hostname=<%= realhostname %>
+ ip_address=<%= ip %>
+ netmask=<%= netmask %>
+ protocol_ipv6=no
+ default_route=<%= defaultroute %>}
+ nfs4_domain=dynamic
+
+ And then call that:
+
+ zone { myzone:
+ ip => "bge0:192.168.0.23",
+ sysidcfg => template(sysidcfg),
+ path => "/opt/zones/myzone",
+ realhostname => "fully.qualified.domain.name"
+ }
The sysidcfg only matters on the first booting of the zone,
so Puppet only checks for it at that time.}
diff --git a/lib/puppet/type/zpool.rb b/lib/puppet/type/zpool.rb
index 80e635504..49cce552a 100755
--- a/lib/puppet/type/zpool.rb
+++ b/lib/puppet/type/zpool.rb
@@ -44,8 +44,11 @@ module Puppet
end
newproperty(:mirror, :array_matching => :all, :parent => Puppet::Property::MultiVDev) do
- desc "List of all the devices to mirror for this pool. Each mirror should be a space separated string.
- mirror => [\"disk1 disk2\", \"disk3 disk4\"]"
+ desc "List of all the devices to mirror for this pool. Each mirror should be a space separated string:
+
+ mirror => [\"disk1 disk2\", \"disk3 disk4\"]
+
+ "
validate do |value|
raise ArgumentError, "mirror names must be provided as string separated, not a comma-separated list" if value.include?(",")
@@ -53,8 +56,11 @@ module Puppet
end
newproperty(:raidz, :array_matching => :all, :parent => Puppet::Property::MultiVDev) do
- desc "List of all the devices to raid for this pool. Should be an array of space separated strings.
- raidz => [\"disk1 disk2\", \"disk3 disk4\"]"
+ desc "List of all the devices to raid for this pool. Should be an array of space separated strings:
+
+ raidz => [\"disk1 disk2\", \"disk3 disk4\"]
+
+ "
validate do |value|
raise ArgumentError, "raid names must be provided as string separated, not a comma-separated list" if value.include?(",")
@@ -84,4 +90,3 @@ module Puppet
end
end
end
-
diff --git a/lib/puppet/util.rb b/lib/puppet/util.rb
index bb4127089..850d147e2 100644
--- a/lib/puppet/util.rb
+++ b/lib/puppet/util.rb
@@ -3,6 +3,7 @@
require 'puppet/util/monkey_patches'
require 'sync'
require 'puppet/external/lock'
+require 'monitor'
module Puppet
# A command failed to execute.
@@ -17,13 +18,29 @@ module Util
require 'puppet/util/posix'
extend Puppet::Util::POSIX
- # Create a hash to store the different sync objects.
- @@syncresources = {}
+ @@sync_objects = {}.extend MonitorMixin
- # Return the sync object associated with a given resource.
- def self.sync(resource)
- @@syncresources[resource] ||= Sync.new
- @@syncresources[resource]
+ def self.activerecord_version
+ if (defined?(::ActiveRecord) and defined?(::ActiveRecord::VERSION) and defined?(::ActiveRecord::VERSION::MAJOR) and defined?(::ActiveRecord::VERSION::MINOR))
+ ([::ActiveRecord::VERSION::MAJOR, ::ActiveRecord::VERSION::MINOR].join('.').to_f)
+ else
+ 0
+ end
+ end
+
+
+ def self.synchronize_on(x,type)
+ sync_object,users = 0,1
+ begin
+ @@sync_objects.synchronize {
+ (@@sync_objects[x] ||= [Sync.new,0])[users] += 1
+ }
+ @@sync_objects[x][sync_object].synchronize(type) { yield }
+ ensure
+ @@sync_objects.synchronize {
+ @@sync_objects.delete(x) unless (@@sync_objects[x][users] -= 1) > 0
+ }
+ end
end
# Change the process to a different user
@@ -181,7 +198,7 @@ module Util
end
end
- def binary(bin)
+ def which(bin)
if bin =~ /^\//
return bin if FileTest.file? bin and FileTest.executable? bin
else
@@ -192,7 +209,7 @@ module Util
end
nil
end
- module_function :binary
+ module_function :which
# Execute the provided command in a pipe, yielding the pipe object.
def execpipe(command, failonfail = true)
@@ -351,9 +368,7 @@ module Util
# Create an exclusive lock.
def threadlock(resource, type = Sync::EX)
- Puppet::Util.sync(resource).synchronize(type) do
- yield
- end
+ Puppet::Util.synchronize_on(resource,type) { yield }
end
# Because some modules provide their own version of this method.
@@ -363,15 +378,10 @@ module Util
def memory
unless defined?(@pmap)
- pmap = %x{which pmap 2>/dev/null}.chomp
- if $CHILD_STATUS != 0 or pmap =~ /^no/
- @pmap = nil
- else
- @pmap = pmap
- end
+ @pmap = which('pmap')
end
if @pmap
- return %x{pmap #{Process.pid}| grep total}.chomp.sub(/^\s*total\s+/, '').sub(/K$/, '').to_i
+ %x{#{@pmap} #{Process.pid}| grep total}.chomp.sub(/^\s*total\s+/, '').sub(/K$/, '').to_i
else
0
end
diff --git a/lib/puppet/util/autoload.rb b/lib/puppet/util/autoload.rb
index c293ac14a..f0dd0a5c5 100644
--- a/lib/puppet/util/autoload.rb
+++ b/lib/puppet/util/autoload.rb
@@ -131,11 +131,23 @@ class Puppet::Util::Autoload
# We have to require this late in the process because otherwise we might have
# load order issues.
require 'puppet/node/environment'
- Puppet::Node::Environment.new(env).modulepath.collect do |dir|
- Dir.entries(dir).reject { |f| f =~ /^\./ }.collect { |f| File.join(dir, f) }
- end.flatten.collect { |d| [File.join(d, "plugins"), File.join(d, "lib")] }.flatten.find_all do |d|
- FileTest.directory?(d)
- end
+
+ real_env = Puppet::Node::Environment.new(env)
+
+ # We're using a per-thread cache of said module directories, so that
+ # we don't scan the filesystem each time we try to load something with
+ # this autoload instance. But since we don't want to cache for the eternity
+ # this env_module_directories gets reset after the compilation on the master.
+ # This is also reset after an agent ran.
+ # One of the side effect of this change is that this module directories list will be
+ # shared among all autoload that we have running at a time. But that won't be an issue
+ # as by definition those directories are shared by all autoload.
+ Thread.current[:env_module_directories] ||= {}
+ Thread.current[:env_module_directories][real_env] ||= real_env.modulepath.collect do |dir|
+ Dir.entries(dir).reject { |f| f =~ /^\./ }.collect { |f| File.join(dir, f) }
+ end.flatten.collect { |d| [File.join(d, "plugins"), File.join(d, "lib")] }.flatten.find_all do |d|
+ FileTest.directory?(d)
+ end
end
def search_directories(env=nil)
diff --git a/lib/puppet/util/cacher.rb b/lib/puppet/util/cacher.rb
index 8785c694f..3dddec0d4 100644
--- a/lib/puppet/util/cacher.rb
+++ b/lib/puppet/util/cacher.rb
@@ -1,3 +1,5 @@
+require 'monitor'
+
module Puppet::Util::Cacher
module Expirer
attr_reader :timestamp
@@ -49,7 +51,7 @@ module Puppet::Util::Cacher
define_method(name.to_s + "=") do |value|
# Make sure the cache timestamp is set
cache_timestamp
- value_cache[name] = value
+ value_cache.synchronize { value_cache[name] = value }
end
if ttl = options[:ttl]
@@ -70,6 +72,7 @@ module Puppet::Util::Cacher
# Methods that get added to instances.
module InstanceMethods
+
def expire
# Only expire if we have an expirer. This is
# mostly so that we can comfortably handle cases
@@ -92,15 +95,17 @@ module Puppet::Util::Cacher
end
def cached_value(name)
- # Allow a nil expirer, in which case we regenerate the value every time.
- if expired_by_expirer?(name)
- value_cache.clear
- @cache_timestamp = Time.now
- elsif expired_by_ttl?(name)
- value_cache.delete(name)
+ value_cache.synchronize do
+ # Allow a nil expirer, in which case we regenerate the value every time.
+ if expired_by_expirer?(name)
+ value_cache.clear
+ @cache_timestamp = Time.now
+ elsif expired_by_ttl?(name)
+ value_cache.delete(name)
+ end
+ value_cache[name] = send("init_#{name}") unless value_cache.include?(name)
+ value_cache[name]
end
- value_cache[name] = send("init_#{name}") unless value_cache.include?(name)
- value_cache[name]
end
def expired_by_expirer?(name)
@@ -121,7 +126,7 @@ module Puppet::Util::Cacher
end
def value_cache
- @value_cache ||= {}
+ @value_cache ||= {}.extend(MonitorMixin)
end
end
end
diff --git a/lib/puppet/util/command_line.rb b/lib/puppet/util/command_line.rb
index 2a97ee069..3562a3dc0 100644
--- a/lib/puppet/util/command_line.rb
+++ b/lib/puppet/util/command_line.rb
@@ -62,7 +62,7 @@ module Puppet
external_command = "puppet-#{subcommand_name}"
require 'puppet/util'
- path_to_subcommand = Puppet::Util.binary( external_command )
+ path_to_subcommand = Puppet::Util.which( external_command )
return false unless path_to_subcommand
system( path_to_subcommand, *args )
diff --git a/lib/puppet/util/command_line/puppetdoc b/lib/puppet/util/command_line/puppetdoc
index d9bbbec33..0fa1830d6 100755
--- a/lib/puppet/util/command_line/puppetdoc
+++ b/lib/puppet/util/command_line/puppetdoc
@@ -8,15 +8,15 @@
#
# = Usage
#
-# puppet doc [-a|--all] [-h|--help] [-o|--outputdir <rdoc outputdir>] [-m|--mode <text|pdf|markdown|trac|rdoc>]
+# puppet doc [-a|--all] [-h|--help] [-o|--outputdir <rdoc outputdir>] [-m|--mode <text|pdf|rdoc>]
# [-r|--reference <[type]|configuration|..>] [--charset CHARSET] [manifest-file]
#
# = Description
#
-# If mode is not 'rdoc', then this command generates a restructured-text document describing all installed
+# If mode is not 'rdoc', then this command generates a Markdown document describing all installed
# Puppet types or all allowable arguments to puppet executables. It is largely
# meant for internal use and is used to generate the reference document
-# available on the Reductive Labs web site.
+# available on the Puppet Labs web site.
#
# In 'rdoc' mode, this command generates an html RDoc hierarchy describing the manifests that
# are in 'manifestdir' and 'modulepath' configuration directives.
@@ -37,7 +37,7 @@
# Specifies the directory where to output the rdoc documentation in 'rdoc' mode.
#
# mode::
-# Determine the output mode. Valid modes are 'text', 'trac', 'pdf', 'markdown' and 'rdoc'. The 'pdf' and 'markdown' modes create PDF or Markdown formatted files in the /tmp directory. Note that 'trac' mode only works on Reductive Labs servers. The default mode is 'text'. In 'rdoc' mode you must provide 'manifests-path'
+# Determine the output mode. Valid modes are 'text', 'trac', 'pdf' and 'rdoc'. The 'pdf' mode creates PDF formatted files in the /tmp directory. The default mode is 'text'. In 'rdoc' mode you must provide 'manifests-path'
#
# reference::
# Build a particular reference. Get a list of references by running +puppet doc --list+.
@@ -53,7 +53,7 @@
# or
# $ puppet doc /etc/puppet/manifests/site.pp
# or
-# $ puppet doc -m markdown -r configuration
+# $ puppet doc -m pdf -r configuration
#
# = Author
#
diff --git a/lib/puppet/util/command_line/puppetrun b/lib/puppet/util/command_line/puppetrun
index ee95c47eb..27cd775b9 100755
--- a/lib/puppet/util/command_line/puppetrun
+++ b/lib/puppet/util/command_line/puppetrun
@@ -54,8 +54,6 @@
# This is what you would install on your Puppet master; non-master hosts could
# leave off the 'fileserver' and 'puppetmaster' namespaces.
#
-# Expect more documentation on this eventually.
-#
# = Options
#
# Note that any configuration parameter that's valid in the configuration file
diff --git a/lib/puppet/util/command_line/ralsh b/lib/puppet/util/command_line/ralsh
index 68ad92d84..83338fcbc 100755
--- a/lib/puppet/util/command_line/ralsh
+++ b/lib/puppet/util/command_line/ralsh
@@ -59,23 +59,23 @@
# types:
# List all available types.
#
-# verbose::
+# verbose:
# Print extra information.
#
# = Example
#
-# This example uses ``puppet resource`` to return Puppet configuration for the user ``luke``::
-#
-# $ puppet resource user luke
-# user { 'luke':
-# home => '/home/luke',
-# uid => '100',
-# ensure => 'present',
-# comment => 'Luke Kanies,,,',
-# gid => '1000',
-# shell => '/bin/bash',
-# groups => ['sysadmin','audio','video','puppet']
-# }
+# This example uses `puppet resource` to return Puppet configuration for the user `luke`:
+#
+# $ puppet resource user luke
+# user { 'luke':
+# home => '/home/luke',
+# uid => '100',
+# ensure => 'present',
+# comment => 'Luke Kanies,,,',
+# gid => '1000',
+# shell => '/bin/bash',
+# groups => ['sysadmin','audio','video','puppet']
+# }
#
# = Author
#
diff --git a/lib/puppet/util/docs.rb b/lib/puppet/util/docs.rb
index efd054d85..4344d67ab 100644
--- a/lib/puppet/util/docs.rb
+++ b/lib/puppet/util/docs.rb
@@ -47,25 +47,19 @@ module Puppet::Util::Docs
lengths[i] = value.to_s.length if value.to_s.length > lengths[i]
end
- # Add the top header row
- str += lengths.collect { |num| "=" * num }.join(" ") + "\n"
+ # Add the header names
+ str += headers.zip(lengths).collect { |value, num| pad(value, num) }.join(" | ") + " |" + "\n"
- # And the header names
- str += headers.zip(lengths).collect { |value, num| pad(value, num) }.join(" ") + "\n"
-
- # And the second header row
- str += lengths.collect { |num| "=" * num }.join(" ") + "\n"
+ # And the header row
+ str += lengths.collect { |num| "-" * num }.join(" | ") + " |" + "\n"
# Now each data row
data.sort { |a, b| a[0].to_s <=> b[0].to_s }.each do |name, rows|
str += [name, rows].flatten.zip(lengths).collect do |value, length|
pad(value, length)
- end.join(" ") + "\n"
+ end.join(" | ") + " |" + "\n"
end
- # And the bottom line row
- str += lengths.collect { |num| "=" * num }.join(" ") + "\n"
-
str + "\n"
end
@@ -111,4 +105,3 @@ module Puppet::Util::Docs
module_function :scrub
end
-
diff --git a/lib/puppet/util/file_locking.rb b/lib/puppet/util/file_locking.rb
index 8b194ed83..18744cab7 100644
--- a/lib/puppet/util/file_locking.rb
+++ b/lib/puppet/util/file_locking.rb
@@ -6,7 +6,7 @@ module Puppet::Util::FileLocking
# Create a shared lock for reading
def readlock(file)
raise ArgumentError, "#{file} is not a file" unless !File.exists?(file) or File.file?(file)
- Puppet::Util.sync(file).synchronize(Sync::SH) do
+ Puppet::Util.synchronize_on(file,Sync::SH) do
File.open(file) { |f|
f.lock_shared { |lf| yield lf }
}
@@ -33,9 +33,12 @@ module Puppet::Util::FileLocking
end
end
- Puppet::Util.sync(file).synchronize(Sync::EX) do
- File.open(file, "w", mode) do |rf|
+ Puppet::Util.synchronize_on(file,Sync::EX) do
+ File.open(file, File::Constants::CREAT | File::Constants::WRONLY, mode) do |rf|
rf.lock_exclusive do |lrf|
+ # poor's man open(2) O_EXLOCK|O_TRUNC
+ lrf.seek(0, IO::SEEK_SET)
+ lrf.truncate(0)
yield lrf
end
end
diff --git a/lib/puppet/util/log.rb b/lib/puppet/util/log.rb
index 36a765c61..a5aacc265 100644
--- a/lib/puppet/util/log.rb
+++ b/lib/puppet/util/log.rb
@@ -57,6 +57,7 @@ class Puppet::Util::Log
destinations.keys.each { |dest|
close(dest)
}
+ raise Puppet::DevError.new("Log.close_all failed to close #{@destinations.keys.inspect}") if !@destinations.empty?
end
# Flush any log destinations that support such operations.
diff --git a/lib/puppet/util/log/destinations.rb b/lib/puppet/util/log/destinations.rb
index 22b3dedb2..2e2f9a5b7 100644
--- a/lib/puppet/util/log/destinations.rb
+++ b/lib/puppet/util/log/destinations.rb
@@ -203,8 +203,20 @@ Puppet::Util::Log.newdesttype :report do
end
# Log to an array, just for testing.
+module Puppet::Test
+ class LogCollector
+ def initialize(logs)
+ @logs = logs
+ end
+
+ def <<(value)
+ @logs << value
+ end
+ end
+end
+
Puppet::Util::Log.newdesttype :array do
- match "Array"
+ match "Puppet::Test::LogCollector"
def initialize(messages)
@messages = messages
diff --git a/lib/puppet/util/metric.rb b/lib/puppet/util/metric.rb
index 7e14a5fec..7fdc6951f 100644
--- a/lib/puppet/util/metric.rb
+++ b/lib/puppet/util/metric.rb
@@ -31,9 +31,12 @@ class Puppet::Util::Metric
start ||= Time.now.to_i - 5
- @rrd = RRDtool.new(self.path)
args = []
+ if Puppet.features.rrd_legacy? && ! Puppet.features.rrd?
+ @rrd = RRDtool.new(self.path)
+ end
+
values.each { |value|
# the 7200 is the heartbeat -- this means that any data that isn't
# more frequently than every two hours gets thrown away
@@ -42,18 +45,26 @@ class Puppet::Util::Metric
args.push "RRA:AVERAGE:0.5:1:300"
begin
- @rrd.create( Puppet[:rrdinterval].to_i, start, args)
+ if Puppet.features.rrd_legacy? && ! Puppet.features.rrd?
+ @rrd.create( Puppet[:rrdinterval].to_i, start, args)
+ else
+ RRD.create( self.path, '-s', Puppet[:rrdinterval].to_i.to_s, '-b', start.to_i.to_s, *args)
+ end
rescue => detail
raise "Could not create RRD file #{path}: #{detail}"
end
end
def dump
- puts @rrd.info
+ if Puppet.features.rrd_legacy? && ! Puppet.features.rrd?
+ puts @rrd.info
+ else
+ puts RRD.info(self.path)
+ end
end
def graph(range = nil)
- unless Puppet.features.rrd?
+ unless Puppet.features.rrd? || Puppet.features.rrd_legacy?
Puppet.warning "RRD library is missing; cannot graph metrics"
return
end
@@ -82,14 +93,26 @@ class Puppet::Util::Metric
args << lines
args.flatten!
if range
- args.push("--start",range[0],"--end",range[1])
+ if Puppet.features.rrd_legacy? && ! Puppet.features.rrd?
+ args.push("--start",range[0],"--end",range[1])
+ else
+ args.push("--start",range[0].to_i.to_s,"--end",range[1].to_i.to_s)
+ end
else
- args.push("--start", Time.now.to_i - time, "--end", Time.now.to_i)
+ if Puppet.features.rrd_legacy? && ! Puppet.features.rrd?
+ args.push("--start", Time.now.to_i - time, "--end", Time.now.to_i)
+ else
+ args.push("--start", (Time.now.to_i - time).to_s, "--end", Time.now.to_i.to_s)
+ end
end
begin
#Puppet.warning "args = #{args}"
- RRDtool.graph( args )
+ if Puppet.features.rrd_legacy? && ! Puppet.features.rrd?
+ RRDtool.graph( args )
+ else
+ RRD.graph( *args )
+ end
rescue => detail
Puppet.err "Failed to graph #{self.name}: #{detail}"
end
@@ -99,7 +122,7 @@ class Puppet::Util::Metric
def initialize(name,label = nil)
@name = name.to_s
- @label = label || labelize(name)
+ @label = label || self.class.labelize(name)
@values = []
end
@@ -109,18 +132,20 @@ class Puppet::Util::Metric
end
def newvalue(name,value,label = nil)
- label ||= labelize(name)
+ label ||= self.class.labelize(name)
@values.push [name,label,value]
end
def store(time)
- unless Puppet.features.rrd?
+ unless Puppet.features.rrd? || Puppet.features.rrd_legacy?
Puppet.warning "RRD library is missing; cannot store metrics"
return
end
self.create(time - 5) unless FileTest.exists?(self.path)
- @rrd ||= RRDtool.new(self.path)
+ if Puppet.features.rrd_legacy? && ! Puppet.features.rrd?
+ @rrd ||= RRDtool.new(self.path)
+ end
# XXX this is not terribly error-resistant
args = [time]
@@ -133,7 +158,11 @@ class Puppet::Util::Metric
arg = args.join(":")
template = temps.join(":")
begin
- @rrd.update( template, [ arg ] )
+ if Puppet.features.rrd_legacy? && ! Puppet.features.rrd?
+ @rrd.update( template, [ arg ] )
+ else
+ RRD.update( self.path, '-t', template, arg )
+ end
#system("rrdtool updatev #{self.path} '#{arg}'")
rescue => detail
raise Puppet::Error, "Failed to update #{self.name}: #{detail}"
@@ -144,10 +173,8 @@ class Puppet::Util::Metric
@values.sort { |a, b| a[1] <=> b[1] }
end
- private
-
# Convert a name into a label.
- def labelize(name)
+ def self.labelize(name)
name.to_s.capitalize.gsub("_", " ")
end
end
diff --git a/lib/puppet/util/monkey_patches.rb b/lib/puppet/util/monkey_patches.rb
index e035afd9f..1c35ae523 100644
--- a/lib/puppet/util/monkey_patches.rb
+++ b/lib/puppet/util/monkey_patches.rb
@@ -1,4 +1,7 @@
-Process.maxgroups = 1024
+
+unless defined? JRUBY_VERSION
+ Process.maxgroups = 1024
+end
module RDoc
def self.caller(skip=nil)
@@ -22,7 +25,7 @@ end
[Object, Exception, Integer, Struct, Date, Time, Range, Regexp, Hash, Array, Float, String, FalseClass, TrueClass, Symbol, NilClass, Class].each { |cls|
cls.class_eval do
- def to_yaml
+ def to_yaml(ignored=nil)
ZAML.dump(self)
end
end
@@ -45,3 +48,26 @@ if RUBY_VERSION == '1.8.7'
end
end
+
+class Object
+ # ActiveSupport 2.3.x mixes in a dangerous method
+ # that can cause rspec to fork bomb
+ # and other strange things like that.
+ def daemonize
+ raise NotImplementedError, "Kernel.daemonize is too dangerous, please don't try to use it."
+ end
+end
+
+# Workaround for yaml_initialize, which isn't supported before Ruby
+# 1.8.3.
+if RUBY_VERSION == '1.8.1' || RUBY_VERSION == '1.8.2'
+ YAML.add_ruby_type( /^object/ ) { |tag, val|
+ type, obj_class = YAML.read_type_class( tag, Object )
+ r = YAML.object_maker( obj_class, val )
+ if r.respond_to? :yaml_initialize
+ r.instance_eval { instance_variables.each { |name| remove_instance_variable name } }
+ r.yaml_initialize(tag, val)
+ end
+ r
+ }
+end
diff --git a/lib/puppet/util/nagios_maker.rb b/lib/puppet/util/nagios_maker.rb
index 59ed820f9..863fe24fa 100644
--- a/lib/puppet/util/nagios_maker.rb
+++ b/lib/puppet/util/nagios_maker.rb
@@ -45,17 +45,16 @@ module Puppet::Util::NagiosMaker
provider.nagios_type
type.desc "The Nagios type #{name.to_s}. This resource type is autogenerated using the
- model developed in Naginator_, and all of the Nagios types are generated using the
+ model developed in Naginator, and all of the Nagios types are generated using the
same code and the same library.
This type generates Nagios configuration statements in Nagios-parseable configuration
- files. By default, the statements will be added to ``#{target}``, but
- you can send them to a different file by setting their ``target`` attribute.
+ files. By default, the statements will be added to `#{target}`, but
+ you can send them to a different file by setting their `target` attribute.
- You can purge Nagios resources using the ``resources`` type, but *only*
+ You can purge Nagios resources using the `resources` type, but *only*
in the default file locations. This is an architectural limitation.
- .. _naginator: http://projects.reductivelabs.com/projects/naginator
"
end
end
diff --git a/lib/puppet/util/provider_features.rb b/lib/puppet/util/provider_features.rb
index ac294d20d..30e8dcb39 100644
--- a/lib/puppet/util/provider_features.rb
+++ b/lib/puppet/util/provider_features.rb
@@ -72,7 +72,7 @@ module Puppet::Util::ProviderFeatures
names = @features.keys.sort { |a,b| a.to_s <=> b.to_s }
names.each do |name|
doc = @features[name].docs.gsub(/\n\s+/, " ")
- str += "- **#{name}**: #{doc}\n"
+ str += "- *#{name}*: #{doc}\n"
end
if providers.length > 0
@@ -83,7 +83,7 @@ module Puppet::Util::ProviderFeatures
prov = provider(provname)
names.each do |name|
if prov.feature?(name)
- data[provname] << "**X**"
+ data[provname] << "*X*"
else
data[provname] << ""
end
diff --git a/lib/puppet/util/rdoc.rb b/lib/puppet/util/rdoc.rb
index 4a80b069b..bdac579d6 100644
--- a/lib/puppet/util/rdoc.rb
+++ b/lib/puppet/util/rdoc.rb
@@ -10,24 +10,25 @@ module Puppet::Util::RDoc
# then rdoc
require 'rdoc/rdoc'
+ require 'rdoc/options'
# load our parser
require 'puppet/util/rdoc/parser'
r = RDoc::RDoc.new
- RDoc::RDoc::GENERATORS["puppet"] = RDoc::RDoc::Generator.new(
+ RDoc::RDoc::GENERATORS["puppet"] = RDoc::RDoc::Generator.new(
"puppet/util/rdoc/generators/puppet_generator.rb",
- "PuppetGenerator".intern,
+ "PuppetGenerator".intern,
+ "puppet")
- "puppet")
# specify our own format & where to output
options = [ "--fmt", "puppet",
"--quiet",
- "--force-update",
"--exclude", "/modules/[^/]*/files/.*\.pp$",
"--op", outputdir ]
+ options << "--force-update" if Options::OptionList.options.any? { |o| o[0] == "--force-update" }
options += [ "--charset", charset] if charset
options += files
@@ -41,7 +42,7 @@ module Puppet::Util::RDoc
def manifestdoc(files)
Puppet[:ignoreimport] = true
files.select { |f| FileTest.file?(f) }.each do |f|
- parser = Puppet::Parser::Parser.new(:environment => Puppet[:environment])
+ parser = Puppet::Parser::Parser.new(Puppet::Node::Environment.new(Puppet[:environment]))
parser.file = f
ast = parser.parse
output(f, ast)
diff --git a/lib/puppet/util/rdoc/generators/puppet_generator.rb b/lib/puppet/util/rdoc/generators/puppet_generator.rb
index 9caeacd5e..e6bbb2e1e 100644
--- a/lib/puppet/util/rdoc/generators/puppet_generator.rb
+++ b/lib/puppet/util/rdoc/generators/puppet_generator.rb
@@ -88,6 +88,12 @@ module Generators
@modules = {}
@allclasses = {}
+ # remove unknown toplevels
+ # it can happen that RDoc triggers a different parser for some files (ie .c, .cc or .h)
+ # in this case RDoc generates a RDoc::TopLevel which we do not support in this generator
+ # So let's make sure we don't generate html for those.
+ @toplevels = @toplevels.select { |tl| tl.is_a? RDoc::PuppetTopLevel }
+
# build the modules, classes and per modules classes and define list
@toplevels.each do |toplevel|
next unless toplevel.document_self
diff --git a/lib/puppet/util/rdoc/parser.rb b/lib/puppet/util/rdoc/parser.rb
index 573d1766f..ce34442ab 100644
--- a/lib/puppet/util/rdoc/parser.rb
+++ b/lib/puppet/util/rdoc/parser.rb
@@ -15,7 +15,9 @@ module RDoc
class Parser
extend ParserFactory
- attr_accessor :ast, :input_file_name, :top_level
+ SITE = "__site__"
+
+ attr_accessor :input_file_name, :top_level
# parser registration into RDoc
parse_files_matching(/\.(rb|pp)$/)
@@ -31,13 +33,19 @@ class Parser
# main entry point
def scan
- Puppet.info "rdoc: scanning #{@input_file_name}"
- if @input_file_name =~ /\.pp$/
- @parser = Puppet::Parser::Parser.new(Puppet[:environment])
- @parser.file = @input_file_name
- @ast = @parser.parse
+ environment = Puppet::Node::Environment.new
+ unless environment.known_resource_types.watching_file?(@input_file_name)
+ Puppet.info "rdoc: scanning #{@input_file_name}"
+ if @input_file_name =~ /\.pp$/
+ @parser = Puppet::Parser::Parser.new(environment)
+ @parser.file = @input_file_name
+ @known_resource_types = environment.known_resource_types
+ @parser.parse.instantiate('').each do |type|
+ @known_resource_types.add type
+ end
+ scan_top_level(@top_level)
+ end
end
- scan_top_level(@top_level)
@top_level
end
@@ -74,7 +82,7 @@ class Parser
# split_module tries to find if +path+ belongs to the module path
# if it does, it returns the module name, otherwise if we are sure
- # it is part of the global manifest path, "<site>" is returned.
+ # it is part of the global manifest path, "__site__" is returned.
# And finally if this path couldn't be mapped anywhere, nil is returned.
def split_module(path)
# find a module
@@ -105,7 +113,7 @@ class Parser
end
# we are under a global manifests
Puppet.debug "rdoc: global manifests"
- "<site>"
+ SITE
end
# create documentation for the top level +container+
@@ -128,7 +136,7 @@ class Parser
Puppet.debug "rdoc: scanning for #{name}"
container.module_name = name
- container.global=true if name == "<site>"
+ container.global=true if name == SITE
@stats.num_modules += 1
container, name = get_class_or_module(container,name)
@@ -199,19 +207,21 @@ class Parser
if stmt.is_a?(Puppet::Parser::AST::Resource) and !stmt.type.nil?
begin
type = stmt.type.split("::").collect { |s| s.capitalize }.join("::")
- title = stmt.title.is_a?(Puppet::Parser::AST::ASTArray) ? stmt.title.to_s.gsub(/\[(.*)\]/,'\1') : stmt.title.to_s
- Puppet.debug "rdoc: found resource: #{type}[#{title}]"
+ stmt.instances.each do |inst|
+ title = inst.title.is_a?(Puppet::Parser::AST::ASTArray) ? inst.title.to_s.gsub(/\[(.*)\]/,'\1') : inst.title.to_s
+ Puppet.debug "rdoc: found resource: #{type}[#{title}]"
- param = []
- stmt.params.children.each do |p|
- res = {}
- res["name"] = p.param
- res["value"] = "#{p.value.to_s}" unless p.value.nil?
+ param = []
+ inst.parameters.children.each do |p|
+ res = {}
+ res["name"] = p.param
+ res["value"] = "#{p.value.to_s}" unless p.value.nil?
- param << res
- end
+ param << res
+ end
- container.add_resource(PuppetResource.new(type, title, stmt.doc, param))
+ container.add_resource(PuppetResource.new(type, title, stmt.doc, param))
+ end
rescue => detail
raise Puppet::ParseError, "impossible to parse resource in #{stmt.file} at line #{stmt.line}: #{detail}"
end
@@ -332,7 +342,7 @@ class Parser
# that contains the documentation
def parse_elements(container)
Puppet.debug "rdoc: scanning manifest"
- @ast.hostclasses.values.sort { |a,b| a.name <=> b.name }.each do |klass|
+ @known_resource_types.hostclasses.values.sort { |a,b| a.name <=> b.name }.each do |klass|
name = klass.name
if klass.file == @input_file_name
unless name.empty?
@@ -345,13 +355,13 @@ class Parser
end
end
- @ast.definitions.each do |name, define|
+ @known_resource_types.definitions.each do |name, define|
if define.file == @input_file_name
document_define(name,define,container)
end
end
- @ast.nodes.each do |name, node|
+ @known_resource_types.nodes.each do |name, node|
if node.file == @input_file_name
document_node(name.to_s,node,container)
end
diff --git a/lib/puppet/util/reference.rb b/lib/puppet/util/reference.rb
index 62bab643e..95efeb1c1 100644
--- a/lib/puppet/util/reference.rb
+++ b/lib/puppet/util/reference.rb
@@ -15,7 +15,7 @@ class Puppet::Util::Reference
end
def self.modes
- %w{pdf trac text markdown}
+ %w{pdf text}
end
def self.newreference(name, options = {}, &block)
@@ -32,7 +32,6 @@ class Puppet::Util::Reference
section = reference(name) or raise "Could not find section #{name}"
depth = section.depth if section.depth < depth
end
- text = ".. contents:: :depth: 2\n\n"
end
def self.pdf(text)
@@ -40,14 +39,7 @@ class Puppet::Util::Reference
Puppet::Util.secure_open("/tmp/puppetdoc.txt", "w") do |f|
f.puts text
end
- rst2latex = %x{which rst2latex}
- if $CHILD_STATUS != 0 or rst2latex =~ /no /
- rst2latex = %x{which rst2latex.py}
- end
- if $CHILD_STATUS != 0 or rst2latex =~ /no /
- raise "Could not find rst2latex"
- end
- rst2latex.chomp!
+ rst2latex = which('rst2latex') || which('rst2latex.py') || raise("Could not find rst2latex")
cmd = %{#{rst2latex} /tmp/puppetdoc.txt > /tmp/puppetdoc.tex}
Puppet::Util.secure_open("/tmp/puppetdoc.tex","w") do |f|
# If we get here without an error, /tmp/puppetdoc.tex isn't a tricky cracker's symlink
@@ -67,38 +59,12 @@ class Puppet::Util::Reference
end
- def self.markdown(name, text)
- puts "Creating markdown for #{name} reference."
- dir = "/tmp/#{Puppet::PUPPETVERSION}"
- FileUtils.mkdir(dir) unless File.directory?(dir)
- Puppet::Util.secure_open(dir + "/#{name}.rst", "w") do |f|
- f.puts text
- end
- pandoc = %x{which pandoc}
- if $CHILD_STATUS != 0 or pandoc =~ /no /
- pandoc = %x{which pandoc}
- end
- if $CHILD_STATUS != 0 or pandoc =~ /no /
- raise "Could not find pandoc"
- end
- pandoc.chomp!
- cmd = %{#{pandoc} -s -r rst -w markdown #{dir}/#{name}.rst -o #{dir}/#{name}.mdwn}
- output = %x{#{cmd}}
- unless $CHILD_STATUS == 0
- $stderr.puts "Pandoc failed to create #{name} reference."
- $stderr.puts output
- exit(1)
- end
-
- File.unlink(dir + "/#{name}.rst")
- end
-
def self.references
instance_loader(:reference).loadall
loaded_instances(:reference).sort { |a,b| a.to_s <=> b.to_s }
end
- HEADER_LEVELS = [nil, "=", "-", "+", "'", "~"]
+ HEADER_LEVELS = [nil, "#", "##", "###", "####", "#####"]
attr_accessor :page, :depth, :header, :title, :dynamic
attr_writer :doc
@@ -116,7 +82,7 @@ class Puppet::Util::Reference
end
def h(name, level)
- "#{name}\n#{HEADER_LEVELS[level] * name.to_s.length}\n\n"
+ "#{HEADER_LEVELS[level]} #{name}\n\n"
end
def initialize(name, options = {}, &block)
@@ -167,7 +133,6 @@ class Puppet::Util::Reference
# First the header
text = h(@title, 1)
text += "\n\n**This page is autogenerated; any changes will get overwritten** *(last generated on #{Time.now.to_s})*\n\n"
- text += ".. contents:: :depth: #{@depth}\n\n" if withcontents
text += @header
@@ -181,27 +146,4 @@ class Puppet::Util::Reference
def to_text(withcontents = true)
strip_trac(to_rest(withcontents))
end
-
- def to_trac(with_contents = true)
- "{{{\n#!rst\n#{self.to_rest(with_contents)}\n}}}"
- end
-
- def trac
- Puppet::Util.secure_open("/tmp/puppetdoc.txt", "w") do |f|
- f.puts self.to_trac
- end
-
- puts "Writing #{@name} reference to trac as #{@page}"
- cmd = %{sudo trac-admin /opt/rl/trac/puppet wiki import %s /tmp/puppetdoc.txt} % self.page
- output = %x{#{cmd}}
- unless $CHILD_STATUS == 0
- $stderr.puts "trac-admin failed"
- $stderr.puts output
- exit(1)
- end
- unless output =~ /^\s+/
- $stderr.puts output
- end
- end
end
-
diff --git a/lib/puppet/util/suidmanager.rb b/lib/puppet/util/suidmanager.rb
index 4d2c32217..6633de002 100644
--- a/lib/puppet/util/suidmanager.rb
+++ b/lib/puppet/util/suidmanager.rb
@@ -88,7 +88,7 @@ module Puppet::Util::SUIDManager
module_function :initgroups
def run_and_capture(command, new_uid=nil, new_gid=nil)
- output = Puppet::Util.execute(command, :failonfail => false, :uid => new_uid, :gid => new_gid)
+ output = Puppet::Util.execute(command, :failonfail => false, :combine => true, :uid => new_uid, :gid => new_gid)
[output, $CHILD_STATUS.dup]
end
module_function :run_and_capture
diff --git a/lib/puppet/util/zaml.rb b/lib/puppet/util/zaml.rb
index 8ecc2c8bd..2155e989c 100644
--- a/lib/puppet/util/zaml.rb
+++ b/lib/puppet/util/zaml.rb
@@ -29,7 +29,8 @@ class ZAML
@result = []
@indent = nil
@structured_key_prefix = nil
- Label.counter_reset
+ @previously_emitted_object = {}
+ @next_free_label_number = 0
emit('--- ')
end
def nested(tail=' ')
@@ -55,31 +56,29 @@ class ZAML
# which we will encounter a reference to the object as we serialize
# it can be handled).
#
- def self.counter_reset
- @@previously_emitted_object = {}
- @@next_free_label_number = 0
- end
+ attr_accessor :this_label_number
def initialize(obj,indent)
@indent = indent
@this_label_number = nil
- @@previously_emitted_object[obj.object_id] = self
end
def to_s
@this_label_number ? ('&id%03d%s' % [@this_label_number, @indent]) : ''
end
def reference
- @this_label_number ||= (@@next_free_label_number += 1)
@reference ||= '*id%03d' % @this_label_number
end
- def self.for(obj)
- @@previously_emitted_object[obj.object_id]
- end
+ end
+ def label_for(obj)
+ @previously_emitted_object[obj.object_id]
end
def new_label_for(obj)
- Label.new(obj,(Hash === obj || Array === obj) ? "#{@indent || "\n"} " : ' ')
+ label = Label.new(obj,(Hash === obj || Array === obj) ? "#{@indent || "\n"} " : ' ')
+ @previously_emitted_object[obj.object_id] = label
+ label
end
def first_time_only(obj)
- if label = Label.for(obj)
+ if label = label_for(obj)
+ label.this_label_number ||= (@next_free_label_number += 1)
emit(label.reference)
else
if @structured_key_prefix and not obj.is_a? String
@@ -120,6 +119,9 @@ class Object
def to_yaml_properties
instance_variables.sort # Default YAML behavior
end
+ def yaml_property_munge(x)
+ x
+ end
def zamlized_class_name(root)
cls = self.class
"!ruby/#{root.name.downcase}#{cls == root ? '' : ":#{cls.respond_to?(:name) ? cls.name : cls}"}"
@@ -136,7 +138,7 @@ class Object
z.nl
v[1..-1].to_zaml(z) # Remove leading '@'
z.emit(': ')
- instance_variable_get(v).to_zaml(z)
+ yaml_property_munge(instance_variable_get(v)).to_zaml(z)
}
end
}
@@ -243,7 +245,6 @@ class String
when self =~ /\n/
if self[-1..-1] == "\n" then z.emit('|+') else z.emit('|-') end
z.nested { split("\n",-1).each { |line| z.nl; z.emit(line.chomp("\n")) } }
- z.nl
else
z.emit(self)
end
diff --git a/man/man5/puppet.conf.5 b/man/man5/puppet.conf.5
index 1e4e70457..210f36786 100644
--- a/man/man5/puppet.conf.5
+++ b/man/man5/puppet.conf.5
@@ -1,1557 +1,2103 @@
-.TH CONFIGURATION REFERENCE "" "" ""
-.SH NAME
-Configuration Reference \-
-.\" Man page generated from reStructeredText.
-.
-.sp
-\fBThis page is autogenerated; any changes will get overwritten\fP \fI(last generated on Wed Jul 14 14:33:09 \-0700 2010)\fP
-.SS Contents
-.INDENT 0.0
-.IP \(bu 2
-.
-\fI\%Specifying Configuration Parameters\fP
-.IP \(bu 2
-.
-\fI\%Signals\fP
-.IP \(bu 2
-.
-\fI\%Configuration Parameter Reference\fP
-.UNINDENT
-.SH SPECIFYING CONFIGURATION PARAMETERS
-.SS On The Command\-Line
-.sp
-Every Puppet executable (with the exception of \fBpuppetdoc\fP) accepts all of
-the parameters below, but not all of the arguments make sense for every executable.
-.sp
-I have tried to be as thorough as possible in the descriptions of the
-arguments, so it should be obvious whether an argument is appropriate or not.
-.sp
-These parameters can be supplied to the executables either as command\-line
-options or in the configuration file. For instance, the command\-line
-invocation below would set the configuration directory to \fB/private/puppet\fP:
-.sp
+.\" generated with Ronn/v0.7.3
+.\" http://github.com/rtomayko/ronn/tree/0.7.3
+.
+.TH "PUPPETCONF" "5" "August 2010" "" ""
+\fBThis page is autogenerated; any changes will get overwritten\fR \fI(last generated on Sat Aug 28 14:00:20 \-0700 2010)\fR
+.
+.P
+{:toc}
+.
+.SH "Specifying Configuration Parameters"
+On The Command\-Line +++++++++++++++++++ Every Puppet executable (with the exception of \fBpuppetdoc\fR) accepts all of the parameters below, but not all of the arguments make sense for every executable\.
+.
+.P
+I have tried to be as thorough as possible in the descriptions of the arguments, so it should be obvious whether an argument is appropriate or not\.
+.
+.P
+These parameters can be supplied to the executables either as command\-line options or in the configuration file\. For instance, the command\-line invocation below would set the configuration directory to \fB/private/puppet\fR:
+.
+.IP "" 4
+.
.nf
-.ft C
+
$ puppet agent \-\-confdir=/private/puppet
-.ft P
+.
.fi
-.sp
-Note that boolean options are turned on and off with a slightly different
-syntax on the command line:
-.sp
+.
+.IP "" 0
+.
+.P
+Note that boolean options are turned on and off with a slightly different syntax on the command line:
+.
+.IP "" 4
+.
.nf
-.ft C
+
$ puppet agent \-\-storeconfigs
$ puppet agent \-\-no\-storeconfigs
-.ft P
+.
.fi
-.sp
-The invocations above will enable and disable, respectively, the storage of
-the client configuration.
-.SS Configuration Files
-.sp
-As mentioned above, the configuration parameters can also be stored in a
-configuration file, located in the configuration directory. As root, the
-default configuration directory is \fB/etc/puppet\fP, and as a regular user, the
-default configuration directory is \fB~user/.puppet\fP. As of 0.23.0, all
-executables look for \fBpuppet.conf\fP in their configuration directory
-(although they previously looked for separate files). For example,
-\fBpuppet.conf\fP is located at \fB/etc/puppet/puppet.conf\fP as root and
-\fB~user/.puppet/puppet.conf\fP as a regular user by default.
-.sp
-All executables will set any parameters set within the \fBmain\fP section,
-and each executable will also use one of the \fBmaster\fP, \fBagent\fP, or
-\fBuser\fP sections.
-.SS File Format
-.sp
-The file follows INI\-style formatting. Here is an example of a very simple
-\fBpuppet.conf\fP file:
-.sp
+.
+.IP "" 0
+.
+.P
+The invocations above will enable and disable, respectively, the storage of the client configuration\.
+.
+.P
+Configuration Files +++++++++++++++++++
+.
+.P
+As mentioned above, the configuration parameters can also be stored in a configuration file, located in the configuration directory\. As root, the default configuration directory is \fB/etc/puppet\fR, and as a regular user, the default configuration directory is \fB~user/\.puppet\fR\. As of 0\.23\.0, all executables look for \fBpuppet\.conf\fR in their configuration directory (although they previously looked for separate files)\. For example, \fBpuppet\.conf\fR is located at \fB/etc/puppet/puppet\.conf\fR as \fBroot\fR and \fB~user/\.puppet/puppet\.conf\fR as a regular user by default\.
+.
+.P
+All executables will set any parameters set within the \fB[main]\fR section, and each executable will also use one of the \fB[master]\fR, \fB[agent]\fR\.
+.
+.P
+File Format \'\'\'\'\'\'\'\'\'\'\'
+.
+.P
+The file follows INI\-style formatting\. Here is an example of a very simple \fBpuppet\.conf\fR file:
+.
+.IP "" 4
+.
.nf
-.ft C
+
[main]
confdir = /private/puppet
storeconfigs = true
-.ft P
+.
.fi
-.sp
-Note that boolean parameters must be explicitly specified as \fItrue\fP or
-\fIfalse\fP as seen above.
-.sp
-If you need to change file parameters (e.g., reset the mode or owner), do
-so within curly braces on the same line:
-.sp
+.
+.IP "" 0
+.
+.P
+Note that boolean parameters must be explicitly specified as \fBtrue\fR or \fBfalse\fR as seen above\.
+.
+.P
+If you need to change file parameters (e\.g\., reset the mode or owner), do so within curly braces on the same line:
+.
+.IP "" 4
+.
.nf
-.ft C
+
[main]
myfile = /tmp/whatever {owner = root, mode = 644}
-.ft P
+.
.fi
-.sp
-If you\(aqre starting out with a fresh configuration, you may wish to let
-the executable generate a template configuration file for you by invoking
-the executable in question with the \fI\-\-genconfig\fP command. The executable
-will print a template configuration to standard output, which can be
-redirected to a file like so:
-.sp
+.
+.IP "" 0
+.
+.P
+If you\'re starting out with a fresh configuration, you may wish to let the executable generate a template configuration file for you by invoking the executable in question with the \fB\-\-genconfig\fR command\. The executable will print a template configuration to standard output, which can be redirected to a file like so:
+.
+.IP "" 4
+.
.nf
-.ft C
-$ puppet agent \-\-genconfig > /etc/puppet/puppet.conf
-.ft P
+
+$ puppet agent \-\-genconfig > /etc/puppet/puppet\.conf
+.
.fi
-.sp
-Note that this invocation will replace the contents of any pre\-existing
-\fIpuppet.conf\fP file, so make a backup of your present config if it contains
-valuable information.
-.sp
-Like the \fI\-\-genconfig\fP argument, the executables also accept a \fI\-\-genmanifest\fP
-argument, which will generate a manifest that can be used to manage all of
-Puppet\(aqs directories and files and prints it to standard output. This can
-likewise be redirected to a file:
-.sp
+.
+.IP "" 0
+.
+.P
+Note that this invocation will replace the contents of any pre\-existing \fBpuppet\.conf\fR file, so make a backup of your present config if it contains valuable information\.
+.
+.P
+Like the \fB\-\-genconfig\fR argument, the executables also accept a \fB\-\-genmanifest\fR argument, which will generate a manifest that can be used to manage all of Puppet\'s directories and files and prints it to standard output\. This can likewise be redirected to a file:
+.
+.IP "" 4
+.
.nf
-.ft C
-$ puppet agent \-\-genmanifest > /etc/puppet/manifests/site.pp
-.ft P
+
+$ puppet agent \-\-genmanifest > /etc/puppet/manifests/site\.pp
+.
.fi
-.sp
-Puppet can also create user and group accounts for itself (one \fIpuppet\fP group
-and one \fIpuppet\fP user) if it is invoked as \fIroot\fP with the \fI\-\-mkusers\fP argument:
-.sp
+.
+.IP "" 0
+.
+.P
+Puppet can also create user and group accounts for itself (one \fBpuppet\fR group and one \fBpuppet\fR user) if it is invoked as \fBroot\fR with the \fB\-\-mkusers\fR argument:
+.
+.IP "" 4
+.
.nf
-.ft C
+
$ puppet agent \-\-mkusers
-.ft P
+.
.fi
-.SH SIGNALS
-.sp
-The \fBpuppet agent\fP and \fBpuppet master\fP executables catch some signals for special
-handling. Both daemons catch (\fBSIGHUP\fP), which forces the server to restart
-tself. Predictably, interrupt and terminate (\fBSIGINT\fP and \fBSIGTERM\fP) will shut
-down the server, whether it be an instance of \fBpuppet agent\fP or \fBpuppet master\fP.
-.sp
-Sending the \fBSIGUSR1\fP signal to an instance of \fBpuppet agent\fP will cause it to
-immediately begin a new configuration transaction with the server. This
-signal has no effect on \fBpuppet master\fP.
-.SH CONFIGURATION PARAMETER REFERENCE
-.sp
-Below is a list of all documented parameters. Not all of them are valid with all
-Puppet executables, but the executables will ignore any inappropriate values.
-.SS async_storeconfigs
-.sp
-Whether to use a queueing system to provide asynchronous database integration. Requires that \fBpuppetqd\fP be running and that \(aqPSON\(aq support for ruby be installed.
-.INDENT 0.0
-.IP \(bu 2
-.
-\fBDefault\fP: false
-.UNINDENT
-.SS authconfig
-.sp
-The configuration file that defines the rights to the different namespaces and methods. This can be used as a coarse\-grained authorization system for both \fBpuppet agent\fP and \fBpuppet master\fP.
-.INDENT 0.0
-.IP \(bu 2
-.
-\fBDefault\fP: $confdir/namespaceauth.conf
-.UNINDENT
-.SS autoflush
-.sp
-Whether log files should always flush to disk.
-.INDENT 0.0
-.IP \(bu 2
-.
-\fBDefault\fP: false
-.UNINDENT
-.SS autosign
-.sp
-Whether to enable autosign. Valid values are true (which autosigns any key request, and is a very bad idea), false (which never autosigns any key request), and the path to a file, which uses that configuration file to determine which keys to sign.
-.INDENT 0.0
-.IP \(bu 2
-.
-\fBDefault\fP: $confdir/autosign.conf
-.UNINDENT
-.SS bindaddress
-.sp
-The address a listening server should bind to. Mongrel servers default to 127.0.0.1 and WEBrick defaults to 0.0.0.0.
-.SS bucketdir
-.sp
-Where FileBucket files are stored.
-.INDENT 0.0
-.IP \(bu 2
-.
-\fBDefault\fP: $vardir/bucket
-.UNINDENT
-.SS ca
-.sp
-Wether the master should function as a certificate authority.
-.INDENT 0.0
-.IP \(bu 2
-.
-\fBDefault\fP: true
-.UNINDENT
-.SS ca_days
-.sp
-How long a certificate should be valid. This parameter is deprecated, use ca_ttl instead
-.SS ca_md
-.sp
-The type of hash used in certificates.
-.INDENT 0.0
-.IP \(bu 2
-.
-\fBDefault\fP: md5
-.UNINDENT
-.SS ca_name
-.sp
-The name to use the Certificate Authority certificate.
-.INDENT 0.0
-.IP \(bu 2
-.
-\fBDefault\fP: $certname
-.UNINDENT
-.SS ca_port
-.sp
-The port to use for the certificate authority.
-.INDENT 0.0
-.IP \(bu 2
-.
-\fBDefault\fP: $masterport
-.UNINDENT
-.SS ca_server
-.sp
-The server to use for certificate authority requests. It\(aqs a separate server because it cannot and does not need to horizontally scale.
-.INDENT 0.0
-.IP \(bu 2
-.
-\fBDefault\fP: $server
-.UNINDENT
-.SS ca_ttl
-.sp
-The default TTL for new certificates; valid values must be an integer, optionally followed by one of the units \(aqy\(aq (years of 365 days), \(aqd\(aq (days), \(aqh\(aq (hours), or \(aqs\(aq (seconds). The unit defaults to seconds. If this parameter is set, ca_days is ignored. Examples are \(aq3600\(aq (one hour) and \(aq1825d\(aq, which is the same as \(aq5y\(aq (5 years)
-.INDENT 0.0
-.IP \(bu 2
-.
-\fBDefault\fP: 5y
-.UNINDENT
-.SS cacert
-.sp
-The CA certificate.
-.INDENT 0.0
-.IP \(bu 2
-.
-\fBDefault\fP: $cadir/ca_crt.pem
-.UNINDENT
-.SS cacrl
-.sp
-The certificate revocation list (CRL) for the CA. Will be used if present but otherwise ignored.
-.INDENT 0.0
-.IP \(bu 2
-.
-\fBDefault\fP: $cadir/ca_crl.pem
-.UNINDENT
-.SS cadir
-.sp
-The root directory for the certificate authority.
-.INDENT 0.0
-.IP \(bu 2
-.
-\fBDefault\fP: $ssldir/ca
-.UNINDENT
-.SS cakey
-.sp
-The CA private key.
-.INDENT 0.0
-.IP \(bu 2
-.
-\fBDefault\fP: $cadir/ca_key.pem
-.UNINDENT
-.SS capass
-.sp
+.
+.IP "" 0
+.
+.SH "Signals"
+The \fBpuppet agent\fR and \fBpuppet master\fR executables catch some signals for special handling\. Both daemons catch (\fBSIGHUP\fR), which forces the server to restart tself\. Predictably, interrupt and terminate (\fBSIGINT\fR and \fBSIGTERM\fR) will shut down the server, whether it be an instance of \fBpuppet agent\fR or \fBpuppet master\fR\.
+.
+.P
+Sending the \fBSIGUSR1\fR signal to an instance of \fBpuppet agent\fR will cause it to immediately begin a new configuration transaction with the server\. This signal has no effect on \fBpuppet master\fR\.
+.
+.SH "Configuration Parameter Reference"
+Below is a list of all documented parameters\. Not all of them are valid with all Puppet executables, but the executables will ignore any inappropriate values\.
+.
+.P
+async_storeconfigs ++++++++++++++++++
+.
+.P
+Whether to use a queueing system to provide asynchronous database integration\. Requires that \fBpuppetqd\fR be running and that \'PSON\' support for ruby be installed\.
+.
+.IP "\(bu" 4
+\fIDefault\fR: false
+.
+.IP "" 0
+.
+.P
+authconfig ++++++++++
+.
+.P
+The configuration file that defines the rights to the different namespaces and methods\. This can be used as a coarse\-grained authorization system for both \fBpuppet agent\fR and \fBpuppet master\fR\.
+.
+.IP "\(bu" 4
+\fIDefault\fR: $confdir/namespaceauth\.conf
+.
+.IP "" 0
+.
+.P
+autoflush +++++++++
+.
+.P
+Whether log files should always flush to disk\.
+.
+.IP "\(bu" 4
+\fIDefault\fR: false
+.
+.IP "" 0
+.
+.P
+autosign ++++++++
+.
+.P
+Whether to enable autosign\. Valid values are true (which autosigns any key request, and is a very bad idea), false (which never autosigns any key request), and the path to a file, which uses that configuration file to determine which keys to sign\.
+.
+.IP "\(bu" 4
+\fIDefault\fR: $confdir/autosign\.conf
+.
+.IP "" 0
+.
+.P
+bindaddress +++++++++++
+.
+.P
+The address a listening server should bind to\. Mongrel servers default to 127\.0\.0\.1 and WEBrick defaults to 0\.0\.0\.0\.
+.
+.P
+bucketdir +++++++++
+.
+.P
+Where FileBucket files are stored\.
+.
+.IP "\(bu" 4
+\fIDefault\fR: $vardir/bucket
+.
+.IP "" 0
+.
+.P
+ca ++
+.
+.P
+Wether the master should function as a certificate authority\.
+.
+.IP "\(bu" 4
+\fIDefault\fR: true
+.
+.IP "" 0
+.
+.P
+ca_days +++++++
+.
+.P
+How long a certificate should be valid\. This parameter is deprecated, use ca_ttl instead
+.
+.P
+ca_md +++++
+.
+.P
+The type of hash used in certificates\.
+.
+.IP "\(bu" 4
+\fIDefault\fR: md5
+.
+.IP "" 0
+.
+.P
+ca_name +++++++
+.
+.P
+The name to use the Certificate Authority certificate\.
+.
+.IP "\(bu" 4
+\fIDefault\fR: $certname
+.
+.IP "" 0
+.
+.P
+ca_port +++++++
+.
+.P
+The port to use for the certificate authority\.
+.
+.IP "\(bu" 4
+\fIDefault\fR: $masterport
+.
+.IP "" 0
+.
+.P
+ca_server +++++++++
+.
+.P
+The server to use for certificate authority requests\. It\'s a separate server because it cannot and does not need to horizontally scale\.
+.
+.IP "\(bu" 4
+\fIDefault\fR: $server
+.
+.IP "" 0
+.
+.P
+ca_ttl ++++++
+.
+.P
+The default TTL for new certificates; valid values must be an integer, optionally followed by one of the units \'y\' (years of 365 days), \'d\' (days), \'h\' (hours), or \'s\' (seconds)\. The unit defaults to seconds\. If this parameter is set, ca_days is ignored\. Examples are \'3600\' (one hour) and \'1825d\', which is the same as \'5y\' (5 years)
+.
+.IP "\(bu" 4
+\fIDefault\fR: 5y
+.
+.IP "" 0
+.
+.P
+cacert ++++++
+.
+.P
+The CA certificate\.
+.
+.IP "\(bu" 4
+\fIDefault\fR: $cadir/ca_crt\.pem
+.
+.IP "" 0
+.
+.P
+cacrl +++++
+.
+.P
+The certificate revocation list (CRL) for the CA\. Will be used if present but otherwise ignored\.
+.
+.IP "\(bu" 4
+\fIDefault\fR: $cadir/ca_crl\.pem
+.
+.IP "" 0
+.
+.P
+cadir +++++
+.
+.P
+The root directory for the certificate authority\.
+.
+.IP "\(bu" 4
+\fIDefault\fR: $ssldir/ca
+.
+.IP "" 0
+.
+.P
+cakey +++++
+.
+.P
+The CA private key\.
+.
+.IP "\(bu" 4
+\fIDefault\fR: $cadir/ca_key\.pem
+.
+.IP "" 0
+.
+.P
+capass ++++++
+.
+.P
Where the CA stores the password for the private key
-.INDENT 0.0
-.IP \(bu 2
-.
-\fBDefault\fP: $caprivatedir/ca.pass
-.UNINDENT
-.SS caprivatedir
-.sp
-Where the CA stores private certificate information.
-.INDENT 0.0
-.IP \(bu 2
-.
-\fBDefault\fP: $cadir/private
-.UNINDENT
-.SS capub
-.sp
-The CA public key.
-.INDENT 0.0
-.IP \(bu 2
-.
-\fBDefault\fP: $cadir/ca_pub.pem
-.UNINDENT
-.SS catalog_format
-.sp
-(Deprecated for \(aqpreferred_serialization_format\(aq) What format to use to dump the catalog. Only supports \(aqmarshal\(aq and \(aqyaml\(aq. Only matters on the client, since it asks the server for a specific format.
-.SS catalog_terminus
-.sp
-Where to get node catalogs. This is useful to change if, for instance, you\(aqd like to pre\-compile catalogs and store them in memcached or some other easily\-accessed store.
-.INDENT 0.0
-.IP \(bu 2
-.
-\fBDefault\fP: compiler
-.UNINDENT
-.SS cert_inventory
-.sp
+.
+.IP "\(bu" 4
+\fIDefault\fR: $caprivatedir/ca\.pass
+.
+.IP "" 0
+.
+.P
+caprivatedir ++++++++++++
+.
+.P
+Where the CA stores private certificate information\.
+.
+.IP "\(bu" 4
+\fIDefault\fR: $cadir/private
+.
+.IP "" 0
+.
+.P
+capub +++++
+.
+.P
+The CA public key\.
+.
+.IP "\(bu" 4
+\fIDefault\fR: $cadir/ca_pub\.pem
+.
+.IP "" 0
+.
+.P
+catalog_format ++++++++++++++
+.
+.P
+(Deprecated for \'preferred_serialization_format\') What format to use to dump the catalog\. Only supports \'marshal\' and \'yaml\'\. Only matters on the client, since it asks the server for a specific format\.
+.
+.P
+catalog_terminus ++++++++++++++++
+.
+.P
+Where to get node catalogs\. This is useful to change if, for instance, you\'d like to pre\-compile catalogs and store them in memcached or some other easily\-accessed store\.
+.
+.IP "\(bu" 4
+\fIDefault\fR: compiler
+.
+.IP "" 0
+.
+.P
+cert_inventory ++++++++++++++
+.
+.P
A Complete listing of all certificates
-.INDENT 0.0
-.IP \(bu 2
-.
-\fBDefault\fP: $cadir/inventory.txt
-.UNINDENT
-.SS certdir
-.sp
-The certificate directory.
-.INDENT 0.0
-.IP \(bu 2
-.
-\fBDefault\fP: $ssldir/certs
-.UNINDENT
-.SS certdnsnames
-.sp
-The DNS names on the Server certificate as a colon\-separated list. If it\(aqs anything other than an empty string, it will be used as an alias in the created certificate. By default, only the server gets an alias set up, and only for \(aqpuppet\(aq.
-.SS certificate_revocation
-.sp
-Whether certificate revocation should be supported by downloading a Certificate Revocation List (CRL) to all clients. If enabled, CA chaining will almost definitely not work.
-.INDENT 0.0
-.IP \(bu 2
-.
-\fBDefault\fP: true
-.UNINDENT
-.SS certname
-.sp
-The name to use when handling certificates. Defaults to the fully qualified domain name.
-.INDENT 0.0
-.IP \(bu 2
-.
-\fBDefault\fP: pelin.lovedthanlost.net
-.UNINDENT
-.SS classfile
-.sp
-The file in which puppet agent stores a list of the classes associated with the retrieved configuration. Can be loaded in the separate \fBpuppet\fP executable using the \fB\-\-loadclasses\fP option.
-.INDENT 0.0
-.IP \(bu 2
-.
-\fBDefault\fP: $statedir/classes.txt
-.UNINDENT
-.SS client_datadir
-.sp
-The directory in which serialized data is stored on the client.
-.INDENT 0.0
-.IP \(bu 2
-.
-\fBDefault\fP: $vardir/client_data
-.UNINDENT
-.SS clientbucketdir
-.sp
-Where FileBucket files are stored locally.
-.INDENT 0.0
-.IP \(bu 2
-.
-\fBDefault\fP: $vardir/clientbucket
-.UNINDENT
-.SS clientyamldir
-.sp
-The directory in which client\-side YAML data is stored.
-.INDENT 0.0
-.IP \(bu 2
-.
-\fBDefault\fP: $vardir/client_yaml
-.UNINDENT
-.SS code
-.sp
-Code to parse directly. This is essentially only used by \fBpuppet\fP, and should only be set if you\(aqre writing your own Puppet executable
-.SS color
-.sp
-Whether to use colors when logging to the console. Valid values are \fBansi\fP (equivalent to \fBtrue\fP), \fBhtml\fP (mostly used during testing with TextMate), and \fBfalse\fP, which produces no color.
-.INDENT 0.0
-.IP \(bu 2
-.
-\fBDefault\fP: ansi
-.UNINDENT
-.SS confdir
-.sp
-The main Puppet configuration directory. The default for this parameter is calculated based on the user. If the process is running as root or the user that \fBpuppet master\fP is supposed to run as, it defaults to a system directory, but if it\(aqs running as any other user, it defaults to being in \fB~\fP.
-.INDENT 0.0
-.IP \(bu 2
-.
-\fBDefault\fP: /etc/puppet
-.UNINDENT
-.SS config
-.sp
-The configuration file for doc.
-.INDENT 0.0
-.IP \(bu 2
-.
-\fBDefault\fP: $confdir/puppet.conf
-.UNINDENT
-.SS config_version
-.sp
-How to determine the configuration version. By default, it will be the time that the configuration is parsed, but you can provide a shell script to override how the version is determined. The output of this script will be added to every log message in the reports, allowing you to correlate changes on your hosts to the source version on the server.
-.SS configprint
-.sp
-Print the value of a specific configuration parameter. If a parameter is provided for this, then the value is printed and puppet exits. Comma\-separate multiple values. For a list of all values, specify \(aqall\(aq. This feature is only available in Puppet versions higher than 0.18.4.
-.SS configtimeout
-.sp
-How long the client should wait for the configuration to be retrieved before considering it a failure. This can help reduce flapping if too many clients contact the server at one time.
-.INDENT 0.0
-.IP \(bu 2
-.
-\fBDefault\fP: 120
-.UNINDENT
-.SS couchdb_url
-.sp
+.
+.IP "\(bu" 4
+\fIDefault\fR: $cadir/inventory\.txt
+.
+.IP "" 0
+.
+.P
+certdir +++++++
+.
+.P
+The certificate directory\.
+.
+.IP "\(bu" 4
+\fIDefault\fR: $ssldir/certs
+.
+.IP "" 0
+.
+.P
+certdnsnames ++++++++++++
+.
+.P
+The DNS names on the Server certificate as a colon\-separated list\. If it\'s anything other than an empty string, it will be used as an alias in the created certificate\. By default, only the server gets an alias set up, and only for \'puppet\'\.
+.
+.P
+certificate_revocation ++++++++++++++++++++++
+.
+.P
+Whether certificate revocation should be supported by downloading a Certificate Revocation List (CRL) to all clients\. If enabled, CA chaining will almost definitely not work\.
+.
+.IP "\(bu" 4
+\fIDefault\fR: true
+.
+.IP "" 0
+.
+.P
+certname ++++++++
+.
+.P
+The name to use when handling certificates\. Defaults to the fully qualified domain name\.
+.
+.IP "\(bu" 4
+\fIDefault\fR: pelin\.members\.linode\.com
+.
+.IP "" 0
+.
+.P
+classfile +++++++++
+.
+.P
+The file in which puppet agent stores a list of the classes associated with the retrieved configuration\. Can be loaded in the separate \fBpuppet\fR executable using the \fB\-\-loadclasses\fR option\.
+.
+.IP "\(bu" 4
+\fIDefault\fR: $statedir/classes\.txt
+.
+.IP "" 0
+.
+.P
+client_datadir ++++++++++++++
+.
+.P
+The directory in which serialized data is stored on the client\.
+.
+.IP "\(bu" 4
+\fIDefault\fR: $vardir/client_data
+.
+.IP "" 0
+.
+.P
+clientbucketdir +++++++++++++++
+.
+.P
+Where FileBucket files are stored locally\.
+.
+.IP "\(bu" 4
+\fIDefault\fR: $vardir/clientbucket
+.
+.IP "" 0
+.
+.P
+clientyamldir +++++++++++++
+.
+.P
+The directory in which client\-side YAML data is stored\.
+.
+.IP "\(bu" 4
+\fIDefault\fR: $vardir/client_yaml
+.
+.IP "" 0
+.
+.P
+code ++++
+.
+.P
+Code to parse directly\. This is essentially only used by \fBpuppet\fR, and should only be set if you\'re writing your own Puppet executable
+.
+.P
+color +++++
+.
+.P
+Whether to use colors when logging to the console\. Valid values are \fBansi\fR (equivalent to \fBtrue\fR), \fBhtml\fR (mostly used during testing with TextMate), and \fBfalse\fR, which produces no color\.
+.
+.IP "\(bu" 4
+\fIDefault\fR: ansi
+.
+.IP "" 0
+.
+.P
+confdir +++++++
+.
+.P
+The main Puppet configuration directory\. The default for this parameter is calculated based on the user\. If the process is running as root or the user that \fBpuppet master\fR is supposed to run as, it defaults to a system directory, but if it\'s running as any other user, it defaults to being in \fB~\fR\.
+.
+.IP "\(bu" 4
+\fIDefault\fR: /etc/puppet
+.
+.IP "" 0
+.
+.P
+config ++++++
+.
+.P
+The configuration file for doc\.
+.
+.IP "\(bu" 4
+\fIDefault\fR: $confdir/puppet\.conf
+.
+.IP "" 0
+.
+.P
+config_version ++++++++++++++
+.
+.P
+How to determine the configuration version\. By default, it will be the time that the configuration is parsed, but you can provide a shell script to override how the version is determined\. The output of this script will be added to every log message in the reports, allowing you to correlate changes on your hosts to the source version on the server\.
+.
+.P
+configprint +++++++++++
+.
+.P
+Print the value of a specific configuration parameter\. If a parameter is provided for this, then the value is printed and puppet exits\. Comma\-separate multiple values\. For a list of all values, specify \'all\'\. This feature is only available in Puppet versions higher than 0\.18\.4\.
+.
+.P
+configtimeout +++++++++++++
+.
+.P
+How long the client should wait for the configuration to be retrieved before considering it a failure\. This can help reduce flapping if too many clients contact the server at one time\.
+.
+.IP "\(bu" 4
+\fIDefault\fR: 120
+.
+.IP "" 0
+.
+.P
+couchdb_url +++++++++++
+.
+.P
The url where the puppet couchdb database will be created
-.INDENT 0.0
-.IP \(bu 2
.
-\fBDefault\fP: \fI\%http://127.0.0.1:5984/puppet\fP
-.UNINDENT
-.SS csrdir
-.sp
+.IP "\(bu" 4
+\fIDefault\fR: http://127\.0\.0\.1:5984/puppet
+.
+.IP "" 0
+.
+.P
+csrdir ++++++
+.
+.P
Where the CA stores certificate requests
-.INDENT 0.0
-.IP \(bu 2
-.
-\fBDefault\fP: $cadir/requests
-.UNINDENT
-.SS daemonize
-.sp
-Send the process into the background. This is the default.
-.INDENT 0.0
-.IP \(bu 2
-.
-\fBDefault\fP: true
-.UNINDENT
-.SS dbadapter
-.sp
-The type of database to use.
-.INDENT 0.0
-.IP \(bu 2
-.
-\fBDefault\fP: sqlite3
-.UNINDENT
-.SS dbconnections
-.sp
-The number of database connections. Only used when networked databases are used. Will be ignored if the value is an empty string or is less than 1.
-.INDENT 0.0
-.IP \(bu 2
-.
-\fBDefault\fP: 0
-.UNINDENT
-.SS dblocation
-.sp
-The database cache for client configurations. Used for querying within the language.
-.INDENT 0.0
-.IP \(bu 2
-.
-\fBDefault\fP: $statedir/clientconfigs.sqlite3
-.UNINDENT
-.SS dbmigrate
-.sp
-Whether to automatically migrate the database.
-.INDENT 0.0
-.IP \(bu 2
-.
-\fBDefault\fP: false
-.UNINDENT
-.SS dbname
-.sp
-The name of the database to use.
-.INDENT 0.0
-.IP \(bu 2
-.
-\fBDefault\fP: puppet
-.UNINDENT
-.SS dbpassword
-.sp
-The database password for caching. Only used when networked databases are used.
-.INDENT 0.0
-.IP \(bu 2
-.
-\fBDefault\fP: puppet
-.UNINDENT
-.SS dbport
-.sp
-The database password for caching. Only used when networked databases are used.
-.SS dbserver
-.sp
-The database server for caching. Only used when networked databases are used.
-.INDENT 0.0
-.IP \(bu 2
-.
-\fBDefault\fP: localhost
-.UNINDENT
-.SS dbsocket
-.sp
-The database socket location. Only used when networked databases are used. Will be ignored if the value is an empty string.
-.SS dbuser
-.sp
-The database user for caching. Only used when networked databases are used.
-.INDENT 0.0
-.IP \(bu 2
-.
-\fBDefault\fP: puppet
-.UNINDENT
-.SS diff
-.sp
-Which diff command to use when printing differences between files.
-.INDENT 0.0
-.IP \(bu 2
-.
-\fBDefault\fP: diff
-.UNINDENT
-.SS diff_args
-.sp
-Which arguments to pass to the diff command when printing differences between files.
-.INDENT 0.0
-.IP \(bu 2
-.
-\fBDefault\fP: \-u
-.UNINDENT
-.SS downcasefacts
-.sp
-Whether facts should be made all lowercase when sent to the server.
-.INDENT 0.0
-.IP \(bu 2
-.
-\fBDefault\fP: false
-.UNINDENT
-.SS dynamicfacts
-.sp
-Facts that are dynamic; these facts will be ignored when deciding whether changed facts should result in a recompile. Multiple facts should be comma\-separated.
-.INDENT 0.0
-.IP \(bu 2
-.
-\fBDefault\fP: memorysize,memoryfree,swapsize,swapfree
-.UNINDENT
-.SS environment
-.sp
-The environment Puppet is running in. For clients (e.g., \fBpuppet agent\fP) this determines the environment itself, which is used to find modules and much more. For servers (i.e., \fBpuppet master\fP) this provides the default environment for nodes we know nothing about.
-.INDENT 0.0
-.IP \(bu 2
-.
-\fBDefault\fP: production
-.UNINDENT
-.SS evaltrace
-.sp
-Whether each resource should log when it is being evaluated. This allows you to interactively see exactly what is being done.
-.INDENT 0.0
-.IP \(bu 2
-.
-\fBDefault\fP: false
-.UNINDENT
-.SS external_nodes
-.sp
-An external command that can produce node information. The output must be a YAML dump of a hash, and that hash must have one or both of \fBclasses\fP and \fBparameters\fP, where \fBclasses\fP is an array and \fBparameters\fP is a hash. For unknown nodes, the commands should exit with a non\-zero exit code. This command makes it straightforward to store your node mapping information in other data sources like databases.
-.INDENT 0.0
-.IP \(bu 2
-.
-\fBDefault\fP: none
-.UNINDENT
-.SS factdest
-.sp
-Where Puppet should store facts that it pulls down from the central server.
-.INDENT 0.0
-.IP \(bu 2
-.
-\fBDefault\fP: $vardir/facts/
-.UNINDENT
-.SS factpath
-.sp
-Where Puppet should look for facts. Multiple directories should be colon\-separated, like normal PATH variables.
-.INDENT 0.0
-.IP \(bu 2
-.
-\fBDefault\fP: $vardir/lib/facter/${\fI\%File::PATH_SEPARATOR\fP}$vardir/facts
-.UNINDENT
-.SS facts_terminus
-.sp
-Where to get node facts.
-.INDENT 0.0
-.IP \(bu 2
-.
-\fBDefault\fP: facter
-.UNINDENT
-.SS factsignore
-.sp
-What files to ignore when pulling down facts.
-.INDENT 0.0
-.IP \(bu 2
-.
-\fBDefault\fP: .svn CVS
-.UNINDENT
-.SS factsource
-.sp
-From where to retrieve facts. The standard Puppet \fBfile\fP type is used for retrieval, so anything that is a valid file source can be used here.
-.INDENT 0.0
-.IP \(bu 2
-.
-\fBDefault\fP: puppet://$server/facts/
-.UNINDENT
-.SS factsync
-.sp
-Whether facts should be synced with the central server.
-.INDENT 0.0
-.IP \(bu 2
-.
-\fBDefault\fP: false
-.UNINDENT
-.SS fileserverconfig
-.sp
-Where the fileserver configuration is stored.
-.INDENT 0.0
-.IP \(bu 2
-.
-\fBDefault\fP: $confdir/fileserver.conf
-.UNINDENT
-.SS filetimeout
-.sp
-The minimum time to wait (in seconds) between checking for updates in configuration files. This timeout determines how quickly Puppet checks whether a file (such as manifests or templates) has changed on disk.
-.INDENT 0.0
-.IP \(bu 2
-.
-\fBDefault\fP: 15
-.UNINDENT
-.SS freeze_main
-.sp
-Freezes the \(aqmain\(aq class, disallowing any code to be added to it. This essentially means that you can\(aqt have any code outside of a node, class, or definition other than in the site manifest.
-.INDENT 0.0
-.IP \(bu 2
-.
-\fBDefault\fP: false
-.UNINDENT
-.SS genconfig
-.sp
-Whether to just print a configuration to stdout and exit. Only makes sense when used interactively. Takes into account arguments specified on the CLI.
-.INDENT 0.0
-.IP \(bu 2
-.
-\fBDefault\fP: false
-.UNINDENT
-.SS genmanifest
-.sp
-Whether to just print a manifest to stdout and exit. Only makes sense when used interactively. Takes into account arguments specified on the CLI.
-.INDENT 0.0
-.IP \(bu 2
-.
-\fBDefault\fP: false
-.UNINDENT
-.SS graph
-.sp
-Whether to create dot graph files for the different configuration graphs. These dot files can be interpreted by tools like OmniGraffle or dot (which is part of ImageMagick).
-.INDENT 0.0
-.IP \(bu 2
-.
-\fBDefault\fP: false
-.UNINDENT
-.SS graphdir
-.sp
-Where to store dot\-outputted graphs.
-.INDENT 0.0
-.IP \(bu 2
-.
-\fBDefault\fP: $statedir/graphs
-.UNINDENT
-.SS group
-.sp
-The group puppet master should run as.
-.INDENT 0.0
-.IP \(bu 2
-.
-\fBDefault\fP: puppet
-.UNINDENT
-.SS hostcert
-.sp
-Where individual hosts store and look for their certificates.
-.INDENT 0.0
-.IP \(bu 2
-.
-\fBDefault\fP: $certdir/$certname.pem
-.UNINDENT
-.SS hostcrl
-.sp
-Where the host\(aqs certificate revocation list can be found. This is distinct from the certificate authority\(aqs CRL.
-.INDENT 0.0
-.IP \(bu 2
-.
-\fBDefault\fP: $ssldir/crl.pem
-.UNINDENT
-.SS hostcsr
-.sp
-Where individual hosts store and look for their certificate requests.
-.INDENT 0.0
-.IP \(bu 2
-.
-\fBDefault\fP: $ssldir/csr_$certname.pem
-.UNINDENT
-.SS hostprivkey
-.sp
-Where individual hosts store and look for their private key.
-.INDENT 0.0
-.IP \(bu 2
-.
-\fBDefault\fP: $privatekeydir/$certname.pem
-.UNINDENT
-.SS hostpubkey
-.sp
-Where individual hosts store and look for their public key.
-.INDENT 0.0
-.IP \(bu 2
-.
-\fBDefault\fP: $publickeydir/$certname.pem
-.UNINDENT
-.SS http_compression
-.sp
-Allow http compression in REST communication with the master. This setting might improve performance for agent \-> master communications over slow WANs. Your puppetmaster needs to support compression (usually by activating some settings in a reverse\-proxy in front of the puppetmaster, which rules out webrick). It is harmless to activate this settings if your master doesn\(aqt support compression, but if it supports it, this setting might reduce performance on high\-speed LANs.
-.INDENT 0.0
-.IP \(bu 2
-.
-\fBDefault\fP: false
-.UNINDENT
-.SS http_proxy_host
-.sp
-The HTTP proxy host to use for outgoing connections. Note: You may need to use a FQDN for the server hostname when using a proxy.
-.INDENT 0.0
-.IP \(bu 2
-.
-\fBDefault\fP: none
-.UNINDENT
-.SS http_proxy_port
-.sp
+.
+.IP "\(bu" 4
+\fIDefault\fR: $cadir/requests
+.
+.IP "" 0
+.
+.P
+daemonize +++++++++
+.
+.P
+Send the process into the background\. This is the default\.
+.
+.IP "\(bu" 4
+\fIDefault\fR: true
+.
+.IP "" 0
+.
+.P
+dbadapter +++++++++
+.
+.P
+The type of database to use\.
+.
+.IP "\(bu" 4
+\fIDefault\fR: sqlite3
+.
+.IP "" 0
+.
+.P
+dbconnections +++++++++++++
+.
+.P
+The number of database connections\. Only used when networked databases are used\. Will be ignored if the value is an empty string or is less than 1\.
+.
+.IP "\(bu" 4
+\fIDefault\fR: 0
+.
+.IP "" 0
+.
+.P
+dblocation ++++++++++
+.
+.P
+The database cache for client configurations\. Used for querying within the language\.
+.
+.IP "\(bu" 4
+\fIDefault\fR: $statedir/clientconfigs\.sqlite3
+.
+.IP "" 0
+.
+.P
+dbmigrate +++++++++
+.
+.P
+Whether to automatically migrate the database\.
+.
+.IP "\(bu" 4
+\fIDefault\fR: false
+.
+.IP "" 0
+.
+.P
+dbname ++++++
+.
+.P
+The name of the database to use\.
+.
+.IP "\(bu" 4
+\fIDefault\fR: puppet
+.
+.IP "" 0
+.
+.P
+dbpassword ++++++++++
+.
+.P
+The database password for caching\. Only used when networked databases are used\.
+.
+.IP "\(bu" 4
+\fIDefault\fR: puppet
+.
+.IP "" 0
+.
+.P
+dbport ++++++
+.
+.P
+The database password for caching\. Only used when networked databases are used\.
+.
+.P
+dbserver ++++++++
+.
+.P
+The database server for caching\. Only used when networked databases are used\.
+.
+.IP "\(bu" 4
+\fIDefault\fR: localhost
+.
+.IP "" 0
+.
+.P
+dbsocket ++++++++
+.
+.P
+The database socket location\. Only used when networked databases are used\. Will be ignored if the value is an empty string\.
+.
+.P
+dbuser ++++++
+.
+.P
+The database user for caching\. Only used when networked databases are used\.
+.
+.IP "\(bu" 4
+\fIDefault\fR: puppet
+.
+.IP "" 0
+.
+.P
+diff ++++
+.
+.P
+Which diff command to use when printing differences between files\.
+.
+.IP "\(bu" 4
+\fIDefault\fR: diff
+.
+.IP "" 0
+.
+.P
+diff_args +++++++++
+.
+.P
+Which arguments to pass to the diff command when printing differences between files\.
+.
+.IP "\(bu" 4
+\fIDefault\fR: \-u
+.
+.IP "" 0
+.
+.P
+downcasefacts +++++++++++++
+.
+.P
+Whether facts should be made all lowercase when sent to the server\.
+.
+.IP "\(bu" 4
+\fIDefault\fR: false
+.
+.IP "" 0
+.
+.P
+dynamicfacts ++++++++++++
+.
+.P
+Facts that are dynamic; these facts will be ignored when deciding whether changed facts should result in a recompile\. Multiple facts should be comma\-separated\.
+.
+.IP "\(bu" 4
+\fIDefault\fR: memorysize,memoryfree,swapsize,swapfree
+.
+.IP "" 0
+.
+.P
+environment +++++++++++
+.
+.P
+The environment Puppet is running in\. For clients (e\.g\., \fBpuppet agent\fR) this determines the environment itself, which is used to find modules and much more\. For servers (i\.e\., \fBpuppet master\fR) this provides the default environment for nodes we know nothing about\.
+.
+.IP "\(bu" 4
+\fIDefault\fR: production
+.
+.IP "" 0
+.
+.P
+evaltrace +++++++++
+.
+.P
+Whether each resource should log when it is being evaluated\. This allows you to interactively see exactly what is being done\.
+.
+.IP "\(bu" 4
+\fIDefault\fR: false
+.
+.IP "" 0
+.
+.P
+external_nodes ++++++++++++++
+.
+.P
+An external command that can produce node information\. The output must be a YAML dump of a hash, and that hash must have one or both of \fBclasses\fR and \fBparameters\fR, where \fBclasses\fR is an array and \fBparameters\fR is a hash\. For unknown nodes, the commands should exit with a non\-zero exit code\. This command makes it straightforward to store your node mapping information in other data sources like databases\.
+.
+.IP "\(bu" 4
+\fIDefault\fR: none
+.
+.IP "" 0
+.
+.P
+factdest ++++++++
+.
+.P
+Where Puppet should store facts that it pulls down from the central server\.
+.
+.IP "\(bu" 4
+\fIDefault\fR: $vardir/facts/
+.
+.IP "" 0
+.
+.P
+factpath ++++++++
+.
+.P
+Where Puppet should look for facts\. Multiple directories should be colon\-separated, like normal PATH variables\.
+.
+.IP "\(bu" 4
+\fIDefault\fR: $vardir/lib/facter:$vardir/facts
+.
+.IP "" 0
+.
+.P
+facts_terminus ++++++++++++++
+.
+.P
+The node facts terminus\.
+.
+.IP "\(bu" 4
+\fIDefault\fR: facter
+.
+.IP "" 0
+.
+.P
+factsignore +++++++++++
+.
+.P
+What files to ignore when pulling down facts\.
+.
+.IP "\(bu" 4
+\fIDefault\fR: \.svn CVS
+.
+.IP "" 0
+.
+.P
+factsource ++++++++++
+.
+.P
+From where to retrieve facts\. The standard Puppet \fBfile\fR type is used for retrieval, so anything that is a valid file source can be used here\.
+.
+.IP "\(bu" 4
+\fIDefault\fR: puppet://$server/facts/
+.
+.IP "" 0
+.
+.P
+factsync ++++++++
+.
+.P
+Whether facts should be synced with the central server\.
+.
+.IP "\(bu" 4
+\fIDefault\fR: false
+.
+.IP "" 0
+.
+.P
+fileserverconfig ++++++++++++++++
+.
+.P
+Where the fileserver configuration is stored\.
+.
+.IP "\(bu" 4
+\fIDefault\fR: $confdir/fileserver\.conf
+.
+.IP "" 0
+.
+.P
+filetimeout +++++++++++
+.
+.P
+The minimum time to wait (in seconds) between checking for updates in configuration files\. This timeout determines how quickly Puppet checks whether a file (such as manifests or templates) has changed on disk\.
+.
+.IP "\(bu" 4
+\fIDefault\fR: 15
+.
+.IP "" 0
+.
+.P
+freeze_main +++++++++++
+.
+.P
+Freezes the \'main\' class, disallowing any code to be added to it\. This essentially means that you can\'t have any code outside of a node, class, or definition other than in the site manifest\.
+.
+.IP "\(bu" 4
+\fIDefault\fR: false
+.
+.IP "" 0
+.
+.P
+genconfig +++++++++
+.
+.P
+Whether to just print a configuration to stdout and exit\. Only makes sense when used interactively\. Takes into account arguments specified on the CLI\.
+.
+.IP "\(bu" 4
+\fIDefault\fR: false
+.
+.IP "" 0
+.
+.P
+genmanifest +++++++++++
+.
+.P
+Whether to just print a manifest to stdout and exit\. Only makes sense when used interactively\. Takes into account arguments specified on the CLI\.
+.
+.IP "\(bu" 4
+\fIDefault\fR: false
+.
+.IP "" 0
+.
+.P
+graph +++++
+.
+.P
+Whether to create dot graph files for the different configuration graphs\. These dot files can be interpreted by tools like OmniGraffle or dot (which is part of ImageMagick)\.
+.
+.IP "\(bu" 4
+\fIDefault\fR: false
+.
+.IP "" 0
+.
+.P
+graphdir ++++++++
+.
+.P
+Where to store dot\-outputted graphs\.
+.
+.IP "\(bu" 4
+\fIDefault\fR: $statedir/graphs
+.
+.IP "" 0
+.
+.P
+group +++++
+.
+.P
+The group puppet master should run as\.
+.
+.IP "\(bu" 4
+\fIDefault\fR: puppet
+.
+.IP "" 0
+.
+.P
+hostcert ++++++++
+.
+.P
+Where individual hosts store and look for their certificates\.
+.
+.IP "\(bu" 4
+\fIDefault\fR: $certdir/$certname\.pem
+.
+.IP "" 0
+.
+.P
+hostcrl +++++++
+.
+.P
+Where the host\'s certificate revocation list can be found\. This is distinct from the certificate authority\'s CRL\.
+.
+.IP "\(bu" 4
+\fIDefault\fR: $ssldir/crl\.pem
+.
+.IP "" 0
+.
+.P
+hostcsr +++++++
+.
+.P
+Where individual hosts store and look for their certificate requests\.
+.
+.IP "\(bu" 4
+\fIDefault\fR: $ssldir/csr_$certname\.pem
+.
+.IP "" 0
+.
+.P
+hostprivkey +++++++++++
+.
+.P
+Where individual hosts store and look for their private key\.
+.
+.IP "\(bu" 4
+\fIDefault\fR: $privatekeydir/$certname\.pem
+.
+.IP "" 0
+.
+.P
+hostpubkey ++++++++++
+.
+.P
+Where individual hosts store and look for their public key\.
+.
+.IP "\(bu" 4
+\fIDefault\fR: $publickeydir/$certname\.pem
+.
+.IP "" 0
+.
+.P
+http_compression ++++++++++++++++
+.
+.P
+Allow http compression in REST communication with the master\. This setting might improve performance for agent \-> master communications over slow WANs\. Your puppetmaster needs to support compression (usually by activating some settings in a reverse\-proxy in front of the puppetmaster, which rules out webrick)\. It is harmless to activate this settings if your master doesn\'t support compression, but if it supports it, this setting might reduce performance on high\-speed LANs\.
+.
+.IP "\(bu" 4
+\fIDefault\fR: false
+.
+.IP "" 0
+.
+.P
+http_proxy_host +++++++++++++++
+.
+.P
+The HTTP proxy host to use for outgoing connections\. Note: You may need to use a FQDN for the server hostname when using a proxy\.
+.
+.IP "\(bu" 4
+\fIDefault\fR: none
+.
+.IP "" 0
+.
+.P
+http_proxy_port +++++++++++++++
+.
+.P
The HTTP proxy port to use for outgoing connections
-.INDENT 0.0
-.IP \(bu 2
-.
-\fBDefault\fP: 3128
-.UNINDENT
-.SS httplog
-.sp
-Where the puppet agent web server logs.
-.INDENT 0.0
-.IP \(bu 2
-.
-\fBDefault\fP: $logdir/http.log
-.UNINDENT
-.SS ignorecache
-.sp
-Ignore cache and always recompile the configuration. This is useful for testing new configurations, where the local cache may in fact be stale even if the timestamps are up to date \- if the facts change or if the server changes.
-.INDENT 0.0
-.IP \(bu 2
-.
-\fBDefault\fP: false
-.UNINDENT
-.SS ignoreimport
-.sp
-A parameter that can be used in commit hooks, since it enables you to parse\-check a single file rather than requiring that all files exist.
-.INDENT 0.0
-.IP \(bu 2
-.
-\fBDefault\fP: false
-.UNINDENT
-.SS ignoreschedules
-.sp
-Boolean; whether puppet agent should ignore schedules. This is useful for initial puppet agent runs.
-.INDENT 0.0
-.IP \(bu 2
-.
-\fBDefault\fP: false
-.UNINDENT
-.SS keylength
-.sp
-The bit length of keys.
-.INDENT 0.0
-.IP \(bu 2
-.
-\fBDefault\fP: 1024
-.UNINDENT
-.SS ldapattrs
-.sp
-The LDAP attributes to include when querying LDAP for nodes. All returned attributes are set as variables in the top\-level scope. Multiple values should be comma\-separated. The value \(aqall\(aq returns all attributes.
-.INDENT 0.0
-.IP \(bu 2
-.
-\fBDefault\fP: all
-.UNINDENT
-.SS ldapbase
-.sp
-The search base for LDAP searches. It\(aqs impossible to provide a meaningful default here, although the LDAP libraries might have one already set. Generally, it should be the \(aqou=Hosts\(aq branch under your main directory.
-.SS ldapclassattrs
-.sp
-The LDAP attributes to use to define Puppet classes. Values should be comma\-separated.
-.INDENT 0.0
-.IP \(bu 2
-.
-\fBDefault\fP: puppetclass
-.UNINDENT
-.SS ldapnodes
-.sp
-Whether to search for node configurations in LDAP. See \fI\%http://projects.puppetlabs.com/projects/puppet/wiki/LDAP_Nodes\fP for more information.
-.INDENT 0.0
-.IP \(bu 2
-.
-\fBDefault\fP: false
-.UNINDENT
-.SS ldapparentattr
-.sp
-The attribute to use to define the parent node.
-.INDENT 0.0
-.IP \(bu 2
-.
-\fBDefault\fP: parentnode
-.UNINDENT
-.SS ldappassword
-.sp
-The password to use to connect to LDAP.
-.SS ldapport
-.sp
-The LDAP port. Only used if \fBldapnodes\fP is enabled.
-.INDENT 0.0
-.IP \(bu 2
-.
-\fBDefault\fP: 389
-.UNINDENT
-.SS ldapserver
-.sp
-The LDAP server. Only used if \fBldapnodes\fP is enabled.
-.INDENT 0.0
-.IP \(bu 2
-.
-\fBDefault\fP: ldap
-.UNINDENT
-.SS ldapssl
-.sp
-Whether SSL should be used when searching for nodes. Defaults to false because SSL usually requires certificates to be set up on the client side.
-.INDENT 0.0
-.IP \(bu 2
-.
-\fBDefault\fP: false
-.UNINDENT
-.SS ldapstackedattrs
-.sp
-The LDAP attributes that should be stacked to arrays by adding the values in all hierarchy elements of the tree. Values should be comma\-separated.
-.INDENT 0.0
-.IP \(bu 2
-.
-\fBDefault\fP: puppetvar
-.UNINDENT
-.SS ldapstring
-.sp
-The search string used to find an LDAP node.
-.INDENT 0.0
-.IP \(bu 2
-.
-\fBDefault\fP: (&(objectclass=puppetClient)(cn=%s))
-.UNINDENT
-.SS ldaptls
-.sp
-Whether TLS should be used when searching for nodes. Defaults to false because TLS usually requires certificates to be set up on the client side.
-.INDENT 0.0
-.IP \(bu 2
-.
-\fBDefault\fP: false
-.UNINDENT
-.SS ldapuser
-.sp
-The user to use to connect to LDAP. Must be specified as a full DN.
-.SS lexical
-.sp
-Whether to use lexical scoping (vs. dynamic).
-.INDENT 0.0
-.IP \(bu 2
-.
-\fBDefault\fP: false
-.UNINDENT
-.SS libdir
-.sp
-An extra search path for Puppet. This is only useful for those files that Puppet will load on demand, and is only guaranteed to work for those cases. In fact, the autoload mechanism is responsible for making sure this directory is in Ruby\(aqs search path
-.INDENT 0.0
-.IP \(bu 2
-.
-\fBDefault\fP: $vardir/lib
-.UNINDENT
-.SS listen
-.sp
-Whether puppet agent should listen for connections. If this is true, then by default only the \fBrunner\fP server is started, which allows remote authorized and authenticated nodes to connect and trigger \fBpuppet agent\fP runs.
-.INDENT 0.0
-.IP \(bu 2
-.
-\fBDefault\fP: false
-.UNINDENT
-.SS localcacert
-.sp
-Where each client stores the CA certificate.
-.INDENT 0.0
-.IP \(bu 2
-.
-\fBDefault\fP: $certdir/ca.pem
-.UNINDENT
-.SS localconfig
-.sp
-Where puppet agent caches the local configuration. An extension indicating the cache format is added automatically.
-.INDENT 0.0
-.IP \(bu 2
-.
-\fBDefault\fP: $statedir/localconfig
-.UNINDENT
-.SS logdir
-.sp
-The Puppet log directory.
-.INDENT 0.0
-.IP \(bu 2
-.
-\fBDefault\fP: $vardir/log
-.UNINDENT
-.SS manage_internal_file_permissions
-.sp
+.
+.IP "\(bu" 4
+\fIDefault\fR: 3128
+.
+.IP "" 0
+.
+.P
+httplog +++++++
+.
+.P
+Where the puppet agent web server logs\.
+.
+.IP "\(bu" 4
+\fIDefault\fR: $logdir/http\.log
+.
+.IP "" 0
+.
+.P
+ignorecache +++++++++++
+.
+.P
+Ignore cache and always recompile the configuration\. This is useful for testing new configurations, where the local cache may in fact be stale even if the timestamps are up to date \- if the facts change or if the server changes\.
+.
+.IP "\(bu" 4
+\fIDefault\fR: false
+.
+.IP "" 0
+.
+.P
+ignoreimport ++++++++++++
+.
+.P
+A parameter that can be used in commit hooks, since it enables you to parse\-check a single file rather than requiring that all files exist\.
+.
+.IP "\(bu" 4
+\fIDefault\fR: false
+.
+.IP "" 0
+.
+.P
+ignoreschedules +++++++++++++++
+.
+.P
+Boolean; whether puppet agent should ignore schedules\. This is useful for initial puppet agent runs\.
+.
+.IP "\(bu" 4
+\fIDefault\fR: false
+.
+.IP "" 0
+.
+.P
+keylength +++++++++
+.
+.P
+The bit length of keys\.
+.
+.IP "\(bu" 4
+\fIDefault\fR: 1024
+.
+.IP "" 0
+.
+.P
+ldapattrs +++++++++
+.
+.P
+The LDAP attributes to include when querying LDAP for nodes\. All returned attributes are set as variables in the top\-level scope\. Multiple values should be comma\-separated\. The value \'all\' returns all attributes\.
+.
+.IP "\(bu" 4
+\fIDefault\fR: all
+.
+.IP "" 0
+.
+.P
+ldapbase ++++++++
+.
+.P
+The search base for LDAP searches\. It\'s impossible to provide a meaningful default here, although the LDAP libraries might have one already set\. Generally, it should be the \'ou=Hosts\' branch under your main directory\.
+.
+.P
+ldapclassattrs ++++++++++++++
+.
+.P
+The LDAP attributes to use to define Puppet classes\. Values should be comma\-separated\.
+.
+.IP "\(bu" 4
+\fIDefault\fR: puppetclass
+.
+.IP "" 0
+.
+.P
+ldapnodes +++++++++
+.
+.P
+Whether to search for node configurations in LDAP\. See http://projects\.puppetlabs\.com/projects/puppet/wiki/LDAP_Nodes for more information\.
+.
+.IP "\(bu" 4
+\fIDefault\fR: false
+.
+.IP "" 0
+.
+.P
+ldapparentattr ++++++++++++++
+.
+.P
+The attribute to use to define the parent node\.
+.
+.IP "\(bu" 4
+\fIDefault\fR: parentnode
+.
+.IP "" 0
+.
+.P
+ldappassword ++++++++++++
+.
+.P
+The password to use to connect to LDAP\.
+.
+.P
+ldapport ++++++++
+.
+.P
+The LDAP port\. Only used if \fBldapnodes\fR is enabled\.
+.
+.IP "\(bu" 4
+\fIDefault\fR: 389
+.
+.IP "" 0
+.
+.P
+ldapserver ++++++++++
+.
+.P
+The LDAP server\. Only used if \fBldapnodes\fR is enabled\.
+.
+.IP "\(bu" 4
+\fIDefault\fR: ldap
+.
+.IP "" 0
+.
+.P
+ldapssl +++++++
+.
+.P
+Whether SSL should be used when searching for nodes\. Defaults to false because SSL usually requires certificates to be set up on the client side\.
+.
+.IP "\(bu" 4
+\fIDefault\fR: false
+.
+.IP "" 0
+.
+.P
+ldapstackedattrs ++++++++++++++++
+.
+.P
+The LDAP attributes that should be stacked to arrays by adding the values in all hierarchy elements of the tree\. Values should be comma\-separated\.
+.
+.IP "\(bu" 4
+\fIDefault\fR: puppetvar
+.
+.IP "" 0
+.
+.P
+ldapstring ++++++++++
+.
+.P
+The search string used to find an LDAP node\.
+.
+.IP "\(bu" 4
+\fIDefault\fR: (&(objectclass=puppetClient)(cn=%s))
+.
+.IP "" 0
+.
+.P
+ldaptls +++++++
+.
+.P
+Whether TLS should be used when searching for nodes\. Defaults to false because TLS usually requires certificates to be set up on the client side\.
+.
+.IP "\(bu" 4
+\fIDefault\fR: false
+.
+.IP "" 0
+.
+.P
+ldapuser ++++++++
+.
+.P
+The user to use to connect to LDAP\. Must be specified as a full DN\.
+.
+.P
+lexical +++++++
+.
+.P
+Whether to use lexical scoping (vs\. dynamic)\.
+.
+.IP "\(bu" 4
+\fIDefault\fR: false
+.
+.IP "" 0
+.
+.P
+libdir ++++++
+.
+.P
+An extra search path for Puppet\. This is only useful for those files that Puppet will load on demand, and is only guaranteed to work for those cases\. In fact, the autoload mechanism is responsible for making sure this directory is in Ruby\'s search path
+.
+.IP "\(bu" 4
+\fIDefault\fR: $vardir/lib
+.
+.IP "" 0
+.
+.P
+listen ++++++
+.
+.P
+Whether puppet agent should listen for connections\. If this is true, then by default only the \fBrunner\fR server is started, which allows remote authorized and authenticated nodes to connect and trigger \fBpuppet agent\fR runs\.
+.
+.IP "\(bu" 4
+\fIDefault\fR: false
+.
+.IP "" 0
+.
+.P
+localcacert +++++++++++
+.
+.P
+Where each client stores the CA certificate\.
+.
+.IP "\(bu" 4
+\fIDefault\fR: $certdir/ca\.pem
+.
+.IP "" 0
+.
+.P
+localconfig +++++++++++
+.
+.P
+Where puppet agent caches the local configuration\. An extension indicating the cache format is added automatically\.
+.
+.IP "\(bu" 4
+\fIDefault\fR: $statedir/localconfig
+.
+.IP "" 0
+.
+.P
+logdir ++++++
+.
+.P
+The Puppet log directory\.
+.
+.IP "\(bu" 4
+\fIDefault\fR: $vardir/log
+.
+.IP "" 0
+.
+.P
+manage_internal_file_permissions ++++++++++++++++++++++++++++++++
+.
+.P
Whether Puppet should manage the owner, group, and mode of files it uses internally
-.INDENT 0.0
-.IP \(bu 2
-.
-\fBDefault\fP: true
-.UNINDENT
-.SS manifest
-.sp
-The entry\-point manifest for puppet master.
-.INDENT 0.0
-.IP \(bu 2
-.
-\fBDefault\fP: $manifestdir/site.pp
-.UNINDENT
-.SS manifestdir
-.sp
-Where puppet master looks for its manifests.
-.INDENT 0.0
-.IP \(bu 2
-.
-\fBDefault\fP: $confdir/manifests
-.UNINDENT
-.SS masterhttplog
-.sp
-Where the puppet master web server logs.
-.INDENT 0.0
-.IP \(bu 2
-.
-\fBDefault\fP: $logdir/masterhttp.log
-.UNINDENT
-.SS masterlog
-.sp
-Where puppet master logs. This is generally not used, since syslog is the default log destination.
-.INDENT 0.0
-.IP \(bu 2
-.
-\fBDefault\fP: $logdir/puppetmaster.log
-.UNINDENT
-.SS masterport
-.sp
-Which port puppet master listens on.
-.INDENT 0.0
-.IP \(bu 2
-.
-\fBDefault\fP: 8140
-.UNINDENT
-.SS maximum_uid
-.sp
-The maximum allowed UID. Some platforms use negative UIDs but then ship with tools that do not know how to handle signed ints, so the UIDs show up as huge numbers that can then not be fed back into the system. This is a hackish way to fail in a slightly more useful way when that happens.
-.INDENT 0.0
-.IP \(bu 2
-.
-\fBDefault\fP: 4294967290
-.UNINDENT
-.SS mkusers
-.sp
-Whether to create the necessary user and group that puppet agent will run as.
-.INDENT 0.0
-.IP \(bu 2
-.
-\fBDefault\fP: false
-.UNINDENT
-.SS mode
-.sp
-The effective \(aqrun mode\(aq of the application: master, agent, or user.
-.INDENT 0.0
-.IP \(bu 2
-.
-\fBDefault\fP: master
-.UNINDENT
-.SS modulepath
-.sp
-The search path for modules as a colon\-separated list of directories.
-.INDENT 0.0
-.IP \(bu 2
-.
-\fBDefault\fP: $confdir/modules:/usr/share/puppet/modules
-.UNINDENT
-.SS name
-.sp
-The name of the application, if we are running as one. The default is essentially $0 without the path or \fB.rb\fP.
-.INDENT 0.0
-.IP \(bu 2
-.
-\fBDefault\fP: doc
-.UNINDENT
-.SS node_name
-.sp
-How the puppetmaster determines the client\(aqs identity and sets the \(aqhostname\(aq, \(aqfqdn\(aq and \(aqdomain\(aq facts for use in the manifest, in particular for determining which \(aqnode\(aq statement applies to the client. Possible values are \(aqcert\(aq (use the subject\(aqs CN in the client\(aqs certificate) and \(aqfacter\(aq (use the hostname that the client reported in its facts)
-.INDENT 0.0
-.IP \(bu 2
-.
-\fBDefault\fP: cert
-.UNINDENT
-.SS node_terminus
-.sp
-Where to find information about nodes.
-.INDENT 0.0
-.IP \(bu 2
-.
-\fBDefault\fP: plain
-.UNINDENT
-.SS noop
-.sp
-Whether puppet agent should be run in noop mode.
-.INDENT 0.0
-.IP \(bu 2
-.
-\fBDefault\fP: false
-.UNINDENT
-.SS onetime
-.sp
-Run the configuration once, rather than as a long\-running daemon. This is useful for interactively running puppetd.
-.INDENT 0.0
-.IP \(bu 2
-.
-\fBDefault\fP: false
-.UNINDENT
-.SS parseonly
-.sp
-Just check the syntax of the manifests.
-.INDENT 0.0
-.IP \(bu 2
-.
-\fBDefault\fP: false
-.UNINDENT
-.SS passfile
-.sp
-Where puppet agent stores the password for its private key. Generally unused.
-.INDENT 0.0
-.IP \(bu 2
-.
-\fBDefault\fP: $privatedir/password
-.UNINDENT
-.SS path
-.sp
-The shell search path. Defaults to whatever is inherited from the parent process.
-.INDENT 0.0
-.IP \(bu 2
-.
-\fBDefault\fP: none
-.UNINDENT
-.SS pidfile
-.sp
+.
+.IP "\(bu" 4
+\fIDefault\fR: true
+.
+.IP "" 0
+.
+.P
+manifest ++++++++
+.
+.P
+The entry\-point manifest for puppet master\.
+.
+.IP "\(bu" 4
+\fIDefault\fR: $manifestdir/site\.pp
+.
+.IP "" 0
+.
+.P
+manifestdir +++++++++++
+.
+.P
+Where puppet master looks for its manifests\.
+.
+.IP "\(bu" 4
+\fIDefault\fR: $confdir/manifests
+.
+.IP "" 0
+.
+.P
+masterhttplog +++++++++++++
+.
+.P
+Where the puppet master web server logs\.
+.
+.IP "\(bu" 4
+\fIDefault\fR: $logdir/masterhttp\.log
+.
+.IP "" 0
+.
+.P
+masterlog +++++++++
+.
+.P
+Where puppet master logs\. This is generally not used, since syslog is the default log destination\.
+.
+.IP "\(bu" 4
+\fIDefault\fR: $logdir/puppetmaster\.log
+.
+.IP "" 0
+.
+.P
+masterport ++++++++++
+.
+.P
+Which port puppet master listens on\.
+.
+.IP "\(bu" 4
+\fIDefault\fR: 8140
+.
+.IP "" 0
+.
+.P
+maximum_uid +++++++++++
+.
+.P
+The maximum allowed UID\. Some platforms use negative UIDs but then ship with tools that do not know how to handle signed ints, so the UIDs show up as huge numbers that can then not be fed back into the system\. This is a hackish way to fail in a slightly more useful way when that happens\.
+.
+.IP "\(bu" 4
+\fIDefault\fR: 4294967290
+.
+.IP "" 0
+.
+.P
+mkusers +++++++
+.
+.P
+Whether to create the necessary user and group that puppet agent will run as\.
+.
+.IP "\(bu" 4
+\fIDefault\fR: false
+.
+.IP "" 0
+.
+.P
+modulepath ++++++++++
+.
+.P
+The search path for modules as a colon\-separated list of directories\.
+.
+.IP "\(bu" 4
+\fIDefault\fR: $confdir/modules:/usr/share/puppet/modules
+.
+.IP "" 0
+.
+.P
+name ++++
+.
+.P
+The name of the application, if we are running as one\. The default is essentially $0 without the path or \fB\.rb\fR\.
+.
+.IP "\(bu" 4
+\fIDefault\fR: doc
+.
+.IP "" 0
+.
+.P
+node_name +++++++++
+.
+.P
+How the puppetmaster determines the client\'s identity and sets the \'hostname\', \'fqdn\' and \'domain\' facts for use in the manifest, in particular for determining which \'node\' statement applies to the client\. Possible values are \'cert\' (use the subject\'s CN in the client\'s certificate) and \'facter\' (use the hostname that the client reported in its facts)
+.
+.IP "\(bu" 4
+\fIDefault\fR: cert
+.
+.IP "" 0
+.
+.P
+node_terminus +++++++++++++
+.
+.P
+Where to find information about nodes\.
+.
+.IP "\(bu" 4
+\fIDefault\fR: plain
+.
+.IP "" 0
+.
+.P
+noop ++++
+.
+.P
+Whether puppet agent should be run in noop mode\.
+.
+.IP "\(bu" 4
+\fIDefault\fR: false
+.
+.IP "" 0
+.
+.P
+onetime +++++++
+.
+.P
+Run the configuration once, rather than as a long\-running daemon\. This is useful for interactively running puppetd\.
+.
+.IP "\(bu" 4
+\fIDefault\fR: false
+.
+.IP "" 0
+.
+.P
+parseonly +++++++++
+.
+.P
+Just check the syntax of the manifests\.
+.
+.IP "\(bu" 4
+\fIDefault\fR: false
+.
+.IP "" 0
+.
+.P
+passfile ++++++++
+.
+.P
+Where puppet agent stores the password for its private key\. Generally unused\.
+.
+.IP "\(bu" 4
+\fIDefault\fR: $privatedir/password
+.
+.IP "" 0
+.
+.P
+path ++++
+.
+.P
+The shell search path\. Defaults to whatever is inherited from the parent process\.
+.
+.IP "\(bu" 4
+\fIDefault\fR: none
+.
+.IP "" 0
+.
+.P
+pidfile +++++++
+.
+.P
The pid file
-.INDENT 0.0
-.IP \(bu 2
-.
-\fBDefault\fP: $rundir/$name.pid
-.UNINDENT
-.SS plugindest
-.sp
-Where Puppet should store plugins that it pulls down from the central server.
-.INDENT 0.0
-.IP \(bu 2
-.
-\fBDefault\fP: $libdir
-.UNINDENT
-.SS pluginsignore
-.sp
-What files to ignore when pulling down plugins.
-.INDENT 0.0
-.IP \(bu 2
-.
-\fBDefault\fP: .svn CVS .git
-.UNINDENT
-.SS pluginsource
-.sp
-From where to retrieve plugins. The standard Puppet \fBfile\fP type is used for retrieval, so anything that is a valid file source can be used here.
-.INDENT 0.0
-.IP \(bu 2
-.
-\fBDefault\fP: puppet://$server/plugins
-.UNINDENT
-.SS pluginsync
-.sp
-Whether plugins should be synced with the central server.
-.INDENT 0.0
-.IP \(bu 2
-.
-\fBDefault\fP: false
-.UNINDENT
-.SS postrun_command
-.sp
-A command to run after every agent run. If this command returns a non\-zero return code, the entire Puppet run will be considered to have failed, even though it might have performed work during the normal run.
-.SS preferred_serialization_format
-.sp
-The preferred means of serializing ruby instances for passing over the wire. This won\(aqt guarantee that all instances will be serialized using this method, since not all classes can be guaranteed to support this format, but it will be used for all classes that support it.
-.INDENT 0.0
-.IP \(bu 2
-.
-\fBDefault\fP: pson
-.UNINDENT
-.SS prerun_command
-.sp
-A command to run before every agent run. If this command returns a non\-zero return code, the entire Puppet run will fail.
-.SS privatedir
-.sp
-Where the client stores private certificate information.
-.INDENT 0.0
-.IP \(bu 2
-.
-\fBDefault\fP: $ssldir/private
-.UNINDENT
-.SS privatekeydir
-.sp
-The private key directory.
-.INDENT 0.0
-.IP \(bu 2
-.
-\fBDefault\fP: $ssldir/private_keys
-.UNINDENT
-.SS publickeydir
-.sp
-The public key directory.
-.INDENT 0.0
-.IP \(bu 2
-.
-\fBDefault\fP: $ssldir/public_keys
-.UNINDENT
-.SS puppetdlockfile
-.sp
-A lock file to temporarily stop puppet agent from doing anything.
-.INDENT 0.0
-.IP \(bu 2
-.
-\fBDefault\fP: $statedir/puppetdlock
-.UNINDENT
-.SS puppetdlog
-.sp
-The log file for puppet agent. This is generally not used.
-.INDENT 0.0
-.IP \(bu 2
-.
-\fBDefault\fP: $logdir/puppetd.log
-.UNINDENT
-.SS puppetport
-.sp
-Which port puppet agent listens on.
-.INDENT 0.0
-.IP \(bu 2
-.
-\fBDefault\fP: 8139
-.UNINDENT
-.SS queue_source
-.sp
-Which type of queue to use for asynchronous processing. If your stomp server requires authentication, you can include it in the URI as long as your stomp client library is at least 1.1.1
-.INDENT 0.0
-.IP \(bu 2
-.
-\fBDefault\fP: stomp://localhost:61613/
-.UNINDENT
-.SS queue_type
-.sp
-Which type of queue to use for asynchronous processing.
-.INDENT 0.0
-.IP \(bu 2
-.
-\fBDefault\fP: stomp
-.UNINDENT
-.SS rails_loglevel
-.sp
-The log level for Rails connections. The value must be a valid log level within Rails. Production environments normally use \fBinfo\fP and other environments normally use \fBdebug\fP.
-.INDENT 0.0
-.IP \(bu 2
-.
-\fBDefault\fP: info
-.UNINDENT
-.SS railslog
-.sp
+.
+.IP "\(bu" 4
+\fIDefault\fR: $rundir/$name\.pid
+.
+.IP "" 0
+.
+.P
+plugindest ++++++++++
+.
+.P
+Where Puppet should store plugins that it pulls down from the central server\.
+.
+.IP "\(bu" 4
+\fIDefault\fR: $libdir
+.
+.IP "" 0
+.
+.P
+pluginsignore +++++++++++++
+.
+.P
+What files to ignore when pulling down plugins\.
+.
+.IP "\(bu" 4
+\fIDefault\fR: \.svn CVS \.git
+.
+.IP "" 0
+.
+.P
+pluginsource ++++++++++++
+.
+.P
+From where to retrieve plugins\. The standard Puppet \fBfile\fR type is used for retrieval, so anything that is a valid file source can be used here\.
+.
+.IP "\(bu" 4
+\fIDefault\fR: puppet://$server/plugins
+.
+.IP "" 0
+.
+.P
+pluginsync ++++++++++
+.
+.P
+Whether plugins should be synced with the central server\.
+.
+.IP "\(bu" 4
+\fIDefault\fR: false
+.
+.IP "" 0
+.
+.P
+postrun_command +++++++++++++++
+.
+.P
+A command to run after every agent run\. If this command returns a non\-zero return code, the entire Puppet run will be considered to have failed, even though it might have performed work during the normal run\.
+.
+.P
+preferred_serialization_format ++++++++++++++++++++++++++++++
+.
+.P
+The preferred means of serializing ruby instances for passing over the wire\. This won\'t guarantee that all instances will be serialized using this method, since not all classes can be guaranteed to support this format, but it will be used for all classes that support it\.
+.
+.IP "\(bu" 4
+\fIDefault\fR: pson
+.
+.IP "" 0
+.
+.P
+prerun_command ++++++++++++++
+.
+.P
+A command to run before every agent run\. If this command returns a non\-zero return code, the entire Puppet run will fail\.
+.
+.P
+privatedir ++++++++++
+.
+.P
+Where the client stores private certificate information\.
+.
+.IP "\(bu" 4
+\fIDefault\fR: $ssldir/private
+.
+.IP "" 0
+.
+.P
+privatekeydir +++++++++++++
+.
+.P
+The private key directory\.
+.
+.IP "\(bu" 4
+\fIDefault\fR: $ssldir/private_keys
+.
+.IP "" 0
+.
+.P
+publickeydir ++++++++++++
+.
+.P
+The public key directory\.
+.
+.IP "\(bu" 4
+\fIDefault\fR: $ssldir/public_keys
+.
+.IP "" 0
+.
+.P
+puppetdlockfile +++++++++++++++
+.
+.P
+A lock file to temporarily stop puppet agent from doing anything\.
+.
+.IP "\(bu" 4
+\fIDefault\fR: $statedir/puppetdlock
+.
+.IP "" 0
+.
+.P
+puppetdlog ++++++++++
+.
+.P
+The log file for puppet agent\. This is generally not used\.
+.
+.IP "\(bu" 4
+\fIDefault\fR: $logdir/puppetd\.log
+.
+.IP "" 0
+.
+.P
+puppetport ++++++++++
+.
+.P
+Which port puppet agent listens on\.
+.
+.IP "\(bu" 4
+\fIDefault\fR: 8139
+.
+.IP "" 0
+.
+.P
+queue_source ++++++++++++
+.
+.P
+Which type of queue to use for asynchronous processing\. If your stomp server requires authentication, you can include it in the URI as long as your stomp client library is at least 1\.1\.1
+.
+.IP "\(bu" 4
+\fIDefault\fR: stomp://localhost:61613/
+.
+.IP "" 0
+.
+.P
+queue_type ++++++++++
+.
+.P
+Which type of queue to use for asynchronous processing\.
+.
+.IP "\(bu" 4
+\fIDefault\fR: stomp
+.
+.IP "" 0
+.
+.P
+rails_loglevel ++++++++++++++
+.
+.P
+The log level for Rails connections\. The value must be a valid log level within Rails\. Production environments normally use \fBinfo\fR and other environments normally use \fBdebug\fR\.
+.
+.IP "\(bu" 4
+\fIDefault\fR: info
+.
+.IP "" 0
+.
+.P
+railslog ++++++++
+.
+.P
Where Rails\-specific logs are sent
-.INDENT 0.0
-.IP \(bu 2
-.
-\fBDefault\fP: $logdir/rails.log
-.UNINDENT
-.SS report
-.sp
-Whether to send reports after every transaction.
-.INDENT 0.0
-.IP \(bu 2
-.
-\fBDefault\fP: false
-.UNINDENT
-.SS report_port
-.sp
-The port to communicate with the report_server.
-.INDENT 0.0
-.IP \(bu 2
-.
-\fBDefault\fP: $masterport
-.UNINDENT
-.SS report_server
-.sp
-The server to which to send transaction reports.
-.INDENT 0.0
-.IP \(bu 2
-.
-\fBDefault\fP: $server
-.UNINDENT
-.SS reportdir
-.sp
-The directory in which to store reports received from the client. Each client gets a separate subdirectory.
-.INDENT 0.0
-.IP \(bu 2
-.
-\fBDefault\fP: $vardir/reports
-.UNINDENT
-.SS reportfrom
-.sp
-The \(aqfrom\(aq email address for the reports.
-.INDENT 0.0
-.IP \(bu 2
-.
-\fBDefault\fP: \fI\%report@pelin.lovedthanlost.net\fP
-.UNINDENT
-.SS reports
-.sp
-The list of reports to generate. All reports are looked for in puppet/reports/name.rb, and multiple report names should be comma\-separated (whitespace is okay).
-.INDENT 0.0
-.IP \(bu 2
-.
-\fBDefault\fP: store
-.UNINDENT
-.SS reportserver
-.sp
-(Deprecated for \(aqreport_server\(aq) The server to which to send transaction reports.
-.INDENT 0.0
-.IP \(bu 2
-.
-\fBDefault\fP: $server
-.UNINDENT
-.SS reporturl
-.sp
+.
+.IP "\(bu" 4
+\fIDefault\fR: $logdir/rails\.log
+.
+.IP "" 0
+.
+.P
+report ++++++
+.
+.P
+Whether to send reports after every transaction\.
+.
+.IP "\(bu" 4
+\fIDefault\fR: false
+.
+.IP "" 0
+.
+.P
+report_port +++++++++++
+.
+.P
+The port to communicate with the report_server\.
+.
+.IP "\(bu" 4
+\fIDefault\fR: $masterport
+.
+.IP "" 0
+.
+.P
+report_server +++++++++++++
+.
+.P
+The server to which to send transaction reports\.
+.
+.IP "\(bu" 4
+\fIDefault\fR: $server
+.
+.IP "" 0
+.
+.P
+reportdir +++++++++
+.
+.P
+The directory in which to store reports received from the client\. Each client gets a separate subdirectory\.
+.
+.IP "\(bu" 4
+\fIDefault\fR: $vardir/reports
+.
+.IP "" 0
+.
+.P
+reportfrom ++++++++++
+.
+.P
+The \'from\' email address for the reports\.
+.
+.IP "\(bu" 4
+\fIDefault\fR: report@pelin\.members\.linode\.com
+.
+.IP "" 0
+.
+.P
+reports +++++++
+.
+.P
+The list of reports to generate\. All reports are looked for in \fBpuppet/reports/name\.rb\fR, and multiple report names should be comma\-separated (whitespace is okay)\.
+.
+.IP "\(bu" 4
+\fIDefault\fR: store
+.
+.IP "" 0
+.
+.P
+reportserver ++++++++++++
+.
+.P
+(Deprecated for \'report_server\') The server to which to send transaction reports\.
+.
+.IP "\(bu" 4
+\fIDefault\fR: $server
+.
+.IP "" 0
+.
+.P
+reporturl +++++++++
+.
+.P
The URL used by the http reports processor to send reports
-.INDENT 0.0
-.IP \(bu 2
-.
-\fBDefault\fP: \fI\%http://localhost:3000/reports\fP
-.UNINDENT
-.SS req_bits
-.sp
-The bit length of the certificates.
-.INDENT 0.0
-.IP \(bu 2
-.
-\fBDefault\fP: 2048
-.UNINDENT
-.SS requestdir
-.sp
-Where host certificate requests are stored.
-.INDENT 0.0
-.IP \(bu 2
-.
-\fBDefault\fP: $ssldir/certificate_requests
-.UNINDENT
-.SS rest_authconfig
-.sp
-The configuration file that defines the rights to the different rest indirections. This can be used as a fine\-grained authorization system for \fBpuppet master\fP.
-.INDENT 0.0
-.IP \(bu 2
-.
-\fBDefault\fP: $confdir/auth.conf
-.UNINDENT
-.SS rrddir
-.sp
-The directory where RRD database files are stored. Directories for each reporting host will be created under this directory.
-.INDENT 0.0
-.IP \(bu 2
-.
-\fBDefault\fP: $vardir/rrd
-.UNINDENT
-.SS rrdinterval
-.sp
-How often RRD should expect data. This should match how often the hosts report back to the server.
-.INDENT 0.0
-.IP \(bu 2
-.
-\fBDefault\fP: $runinterval
-.UNINDENT
-.SS rundir
-.sp
-Where Puppet PID files are kept.
-.INDENT 0.0
-.IP \(bu 2
-.
-\fBDefault\fP: $vardir/run
-.UNINDENT
-.SS runinterval
-.sp
-How often puppet agent applies the client configuration; in seconds.
-.INDENT 0.0
-.IP \(bu 2
-.
-\fBDefault\fP: 1800
-.UNINDENT
-.SS sendmail
-.sp
-Where to find the sendmail binary with which to send email.
-.INDENT 0.0
-.IP \(bu 2
-.
-\fBDefault\fP: /usr/sbin/sendmail
-.UNINDENT
-.SS serial
-.sp
-Where the serial number for certificates is stored.
-.INDENT 0.0
-.IP \(bu 2
-.
-\fBDefault\fP: $cadir/serial
-.UNINDENT
-.SS server
-.sp
+.
+.IP "\(bu" 4
+\fIDefault\fR: http://localhost:3000/reports
+.
+.IP "" 0
+.
+.P
+req_bits ++++++++
+.
+.P
+The bit length of the certificates\.
+.
+.IP "\(bu" 4
+\fIDefault\fR: 2048
+.
+.IP "" 0
+.
+.P
+requestdir ++++++++++
+.
+.P
+Where host certificate requests are stored\.
+.
+.IP "\(bu" 4
+\fIDefault\fR: $ssldir/certificate_requests
+.
+.IP "" 0
+.
+.P
+rest_authconfig +++++++++++++++
+.
+.P
+The configuration file that defines the rights to the different rest indirections\. This can be used as a fine\-grained authorization system for \fBpuppet master\fR\.
+.
+.IP "\(bu" 4
+\fIDefault\fR: $confdir/auth\.conf
+.
+.IP "" 0
+.
+.P
+rrddir ++++++
+.
+.P
+The directory where RRD database files are stored\. Directories for each reporting host will be created under this directory\.
+.
+.IP "\(bu" 4
+\fIDefault\fR: $vardir/rrd
+.
+.IP "" 0
+.
+.P
+rrdinterval +++++++++++
+.
+.P
+How often RRD should expect data\. This should match how often the hosts report back to the server\.
+.
+.IP "\(bu" 4
+\fIDefault\fR: $runinterval
+.
+.IP "" 0
+.
+.P
+run_mode ++++++++
+.
+.P
+The effective \'run mode\' of the application: master, agent, or user\.
+.
+.IP "\(bu" 4
+\fIDefault\fR: master
+.
+.IP "" 0
+.
+.P
+rundir ++++++
+.
+.P
+Where Puppet PID files are kept\.
+.
+.IP "\(bu" 4
+\fIDefault\fR: $vardir/run
+.
+.IP "" 0
+.
+.P
+runinterval +++++++++++
+.
+.P
+How often puppet agent applies the client configuration; in seconds\.
+.
+.IP "\(bu" 4
+\fIDefault\fR: 1800
+.
+.IP "" 0
+.
+.P
+sendmail ++++++++
+.
+.P
+Where to find the sendmail binary with which to send email\.
+.
+.IP "\(bu" 4
+\fIDefault\fR: /usr/sbin/sendmail
+.
+.IP "" 0
+.
+.P
+serial ++++++
+.
+.P
+Where the serial number for certificates is stored\.
+.
+.IP "\(bu" 4
+\fIDefault\fR: $cadir/serial
+.
+.IP "" 0
+.
+.P
+server ++++++
+.
+.P
The server to which server puppet agent should connect
-.INDENT 0.0
-.IP \(bu 2
-.
-\fBDefault\fP: puppet
-.UNINDENT
-.SS server_datadir
-.sp
-The directory in which serialized data is stored, usually in a subdirectory.
-.INDENT 0.0
-.IP \(bu 2
-.
-\fBDefault\fP: $vardir/server_data
-.UNINDENT
-.SS servertype
-.sp
-The type of server to use. Currently supported options are webrick and mongrel. If you use mongrel, you will need a proxy in front of the process or processes, since Mongrel cannot speak SSL.
-.INDENT 0.0
-.IP \(bu 2
-.
-\fBDefault\fP: webrick
-.UNINDENT
-.SS show_diff
-.sp
-Whether to print a contextual diff when files are being replaced. The diff is printed on stdout, so this option is meaningless unless you are running Puppet interactively. This feature currently requires the \fBdiff/lcs\fP Ruby library.
-.INDENT 0.0
-.IP \(bu 2
-.
-\fBDefault\fP: false
-.UNINDENT
-.SS signeddir
-.sp
-Where the CA stores signed certificates.
-.INDENT 0.0
-.IP \(bu 2
-.
-\fBDefault\fP: $cadir/signed
-.UNINDENT
-.SS smtpserver
-.sp
-The server through which to send email reports.
-.INDENT 0.0
-.IP \(bu 2
-.
-\fBDefault\fP: none
-.UNINDENT
-.SS splay
-.sp
-Whether to sleep for a pseudo\-random (but consistent) amount of time before a run.
-.INDENT 0.0
-.IP \(bu 2
-.
-\fBDefault\fP: false
-.UNINDENT
-.SS splaylimit
-.sp
-The maximum time to delay before runs. Defaults to being the same as the run interval.
-.INDENT 0.0
-.IP \(bu 2
-.
-\fBDefault\fP: $runinterval
-.UNINDENT
-.SS ssl_client_header
-.sp
-The header containing an authenticated client\(aqs SSL DN. Only used with Mongrel. This header must be set by the proxy to the authenticated client\(aqs SSL DN (e.g., \fB/CN=puppet.puppetlabs.com\fP). See \fI\%http://projects.puppetlabs.com/projects/puppet/wiki/Using_Mongrel\fP for more information.
-.INDENT 0.0
-.IP \(bu 2
-.
-\fBDefault\fP: HTTP_X_CLIENT_DN
-.UNINDENT
-.SS ssl_client_verify_header
-.sp
-The header containing the status message of the client verification. Only used with Mongrel. This header must be set by the proxy to \(aqSUCCESS\(aq if the client successfully authenticated, and anything else otherwise. See \fI\%http://projects.puppetlabs.com/projects/puppet/wiki/Using_Mongrel\fP for more information.
-.INDENT 0.0
-.IP \(bu 2
-.
-\fBDefault\fP: HTTP_X_CLIENT_VERIFY
-.UNINDENT
-.SS ssldir
-.sp
-Where SSL certificates are kept.
-.INDENT 0.0
-.IP \(bu 2
-.
-\fBDefault\fP: $confdir/ssl
-.UNINDENT
-.SS statedir
-.sp
-The directory where Puppet state is stored. Generally, this directory can be removed without causing harm (although it might result in spurious service restarts).
-.INDENT 0.0
-.IP \(bu 2
-.
-\fBDefault\fP: $vardir/state
-.UNINDENT
-.SS statefile
-.sp
-Where puppet agent and puppet master store state associated with the running configuration. In the case of puppet master, this file reflects the state discovered through interacting with clients.
-.INDENT 0.0
-.IP \(bu 2
-.
-\fBDefault\fP: $statedir/state.yaml
-.UNINDENT
-.SS storeconfigs
-.sp
-Whether to store each client\(aqs configuration. This requires ActiveRecord from Ruby on Rails.
-.INDENT 0.0
-.IP \(bu 2
-.
-\fBDefault\fP: false
-.UNINDENT
-.SS strict_hostname_checking
-.sp
-Whether to only search for the complete hostname as it is in the certificate when searching for node information in the catalogs.
-.INDENT 0.0
-.IP \(bu 2
-.
-\fBDefault\fP: false
-.UNINDENT
-.SS summarize
-.sp
-Whether to print a transaction summary.
-.INDENT 0.0
-.IP \(bu 2
-.
-\fBDefault\fP: false
-.UNINDENT
-.SS syslogfacility
-.sp
-What syslog facility to use when logging to syslog. Syslog has a fixed list of valid facilities, and you must choose one of those; you cannot just make one up.
-.INDENT 0.0
-.IP \(bu 2
-.
-\fBDefault\fP: daemon
-.UNINDENT
-.SS tagmap
-.sp
-The mapping between reporting tags and email addresses.
-.INDENT 0.0
-.IP \(bu 2
-.
-\fBDefault\fP: $confdir/tagmail.conf
-.UNINDENT
-.SS tags
-.sp
-Tags to use to find resources. If this is set, then only resources tagged with the specified tags will be applied. Values must be comma\-separated.
-.SS templatedir
-.sp
-Where Puppet looks for template files. Can be a list of colon\-seperated directories.
-.INDENT 0.0
-.IP \(bu 2
-.
-\fBDefault\fP: $vardir/templates
-.UNINDENT
-.SS thin_storeconfigs
-.sp
-Boolean; wether storeconfigs store in the database only the facts and exported resources. If true, then storeconfigs performance will be higher and still allow exported/collected resources, but other usage external to Puppet might not work
-.INDENT 0.0
-.IP \(bu 2
-.
-\fBDefault\fP: false
-.UNINDENT
-.SS trace
-.sp
+.
+.IP "\(bu" 4
+\fIDefault\fR: puppet
+.
+.IP "" 0
+.
+.P
+server_datadir ++++++++++++++
+.
+.P
+The directory in which serialized data is stored, usually in a subdirectory\.
+.
+.IP "\(bu" 4
+\fIDefault\fR: $vardir/server_data
+.
+.IP "" 0
+.
+.P
+servertype ++++++++++
+.
+.P
+The type of server to use\. Currently supported options are webrick and mongrel\. If you use mongrel, you will need a proxy in front of the process or processes, since Mongrel cannot speak SSL\.
+.
+.IP "\(bu" 4
+\fIDefault\fR: webrick
+.
+.IP "" 0
+.
+.P
+show_diff +++++++++
+.
+.P
+Whether to print a contextual diff when files are being replaced\. The diff is printed on stdout, so this option is meaningless unless you are running Puppet interactively\. This feature currently requires the \fBdiff/lcs\fR Ruby library\.
+.
+.IP "\(bu" 4
+\fIDefault\fR: false
+.
+.IP "" 0
+.
+.P
+signeddir +++++++++
+.
+.P
+Where the CA stores signed certificates\.
+.
+.IP "\(bu" 4
+\fIDefault\fR: $cadir/signed
+.
+.IP "" 0
+.
+.P
+smtpserver ++++++++++
+.
+.P
+The server through which to send email reports\.
+.
+.IP "\(bu" 4
+\fIDefault\fR: none
+.
+.IP "" 0
+.
+.P
+splay +++++
+.
+.P
+Whether to sleep for a pseudo\-random (but consistent) amount of time before a run\.
+.
+.IP "\(bu" 4
+\fIDefault\fR: false
+.
+.IP "" 0
+.
+.P
+splaylimit ++++++++++
+.
+.P
+The maximum time to delay before runs\. Defaults to being the same as the run interval\.
+.
+.IP "\(bu" 4
+\fIDefault\fR: $runinterval
+.
+.IP "" 0
+.
+.P
+ssl_client_header +++++++++++++++++
+.
+.P
+The header containing an authenticated client\'s SSL DN\. Only used with Mongrel\. This header must be set by the proxy to the authenticated client\'s SSL DN (e\.g\., \fB/CN=puppet\.puppetlabs\.com\fR)\. See http://projects\.puppetlabs\.com/projects/puppet/wiki/Using_Mongrel for more information\.
+.
+.IP "\(bu" 4
+\fIDefault\fR: HTTP_X_CLIENT_DN
+.
+.IP "" 0
+.
+.P
+ssl_client_verify_header ++++++++++++++++++++++++
+.
+.P
+The header containing the status message of the client verification\. Only used with Mongrel\. This header must be set by the proxy to \'SUCCESS\' if the client successfully authenticated, and anything else otherwise\. See http://projects\.puppetlabs\.com/projects/puppet/wiki/Using_Mongrel for more information\.
+.
+.IP "\(bu" 4
+\fIDefault\fR: HTTP_X_CLIENT_VERIFY
+.
+.IP "" 0
+.
+.P
+ssldir ++++++
+.
+.P
+Where SSL certificates are kept\.
+.
+.IP "\(bu" 4
+\fIDefault\fR: $confdir/ssl
+.
+.IP "" 0
+.
+.P
+statedir ++++++++
+.
+.P
+The directory where Puppet state is stored\. Generally, this directory can be removed without causing harm (although it might result in spurious service restarts)\.
+.
+.IP "\(bu" 4
+\fIDefault\fR: $vardir/state
+.
+.IP "" 0
+.
+.P
+statefile +++++++++
+.
+.P
+Where puppet agent and puppet master store state associated with the running configuration\. In the case of puppet master, this file reflects the state discovered through interacting with clients\.
+.
+.IP "\(bu" 4
+\fIDefault\fR: $statedir/state\.yaml
+.
+.IP "" 0
+.
+.P
+storeconfigs ++++++++++++
+.
+.P
+Whether to store each client\'s configuration\. This requires ActiveRecord from Ruby on Rails\.
+.
+.IP "\(bu" 4
+\fIDefault\fR: false
+.
+.IP "" 0
+.
+.P
+strict_hostname_checking ++++++++++++++++++++++++
+.
+.P
+Whether to only search for the complete hostname as it is in the certificate when searching for node information in the catalogs\.
+.
+.IP "\(bu" 4
+\fIDefault\fR: false
+.
+.IP "" 0
+.
+.P
+summarize +++++++++
+.
+.P
+Whether to print a transaction summary\.
+.
+.IP "\(bu" 4
+\fIDefault\fR: false
+.
+.IP "" 0
+.
+.P
+syslogfacility ++++++++++++++
+.
+.P
+What syslog facility to use when logging to syslog\. Syslog has a fixed list of valid facilities, and you must choose one of those; you cannot just make one up\.
+.
+.IP "\(bu" 4
+\fIDefault\fR: daemon
+.
+.IP "" 0
+.
+.P
+tagmap ++++++
+.
+.P
+The mapping between reporting tags and email addresses\.
+.
+.IP "\(bu" 4
+\fIDefault\fR: $confdir/tagmail\.conf
+.
+.IP "" 0
+.
+.P
+tags ++++
+.
+.P
+Tags to use to find resources\. If this is set, then only resources tagged with the specified tags will be applied\. Values must be comma\-separated\.
+.
+.P
+templatedir +++++++++++
+.
+.P
+Where Puppet looks for template files\. Can be a list of colon\-seperated directories\.
+.
+.IP "\(bu" 4
+\fIDefault\fR: $vardir/templates
+.
+.IP "" 0
+.
+.P
+thin_storeconfigs +++++++++++++++++
+.
+.P
+Boolean; wether storeconfigs store in the database only the facts and exported resources\. If true, then storeconfigs performance will be higher and still allow exported/collected resources, but other usage external to Puppet might not work
+.
+.IP "\(bu" 4
+\fIDefault\fR: false
+.
+.IP "" 0
+.
+.P
+trace +++++
+.
+.P
Whether to print stack traces on some errors
-.INDENT 0.0
-.IP \(bu 2
-.
-\fBDefault\fP: false
-.UNINDENT
-.SS use_cached_catalog
-.sp
-Whether to only use the cached catalog rather than compiling a new catalog on every run. Puppet can be run with this enabled by default and then selectively disabled when a recompile is desired.
-.INDENT 0.0
-.IP \(bu 2
-.
-\fBDefault\fP: false
-.UNINDENT
-.SS usecacheonfailure
-.sp
-Whether to use the cached configuration when the remote configuration will not compile. This option is useful for testing new configurations, where you want to fix the broken configuration rather than reverting to a known\-good one.
-.INDENT 0.0
-.IP \(bu 2
-.
-\fBDefault\fP: true
-.UNINDENT
-.SS user
-.sp
-The user puppet master should run as.
-.INDENT 0.0
-.IP \(bu 2
-.
-\fBDefault\fP: puppet
-.UNINDENT
-.SS vardir
-.sp
-Where Puppet stores dynamic and growing data. The default for this parameter is calculated specially, like \fI\%confdir\fP.
-.INDENT 0.0
-.IP \(bu 2
-.
-\fBDefault\fP: /var/lib/puppet
-.UNINDENT
-.SS yamldir
-.sp
-The directory in which YAML data is stored, usually in a subdirectory.
-.INDENT 0.0
-.IP \(bu 2
-.
-\fBDefault\fP: $vardir/yaml
-.UNINDENT
-.SS zlib
-.sp
+.
+.IP "\(bu" 4
+\fIDefault\fR: false
+.
+.IP "" 0
+.
+.P
+use_cached_catalog ++++++++++++++++++
+.
+.P
+Whether to only use the cached catalog rather than compiling a new catalog on every run\. Puppet can be run with this enabled by default and then selectively disabled when a recompile is desired\.
+.
+.IP "\(bu" 4
+\fIDefault\fR: false
+.
+.IP "" 0
+.
+.P
+usecacheonfailure +++++++++++++++++
+.
+.P
+Whether to use the cached configuration when the remote configuration will not compile\. This option is useful for testing new configurations, where you want to fix the broken configuration rather than reverting to a known\-good one\.
+.
+.IP "\(bu" 4
+\fIDefault\fR: true
+.
+.IP "" 0
+.
+.P
+user ++++
+.
+.P
+The user puppet master should run as\.
+.
+.IP "\(bu" 4
+\fIDefault\fR: puppet
+.
+.IP "" 0
+.
+.P
+vardir ++++++
+.
+.P
+Where Puppet stores dynamic and growing data\. The default for this parameter is calculated specially, like \fBconfdir\fR_\.
+.
+.IP "\(bu" 4
+\fIDefault\fR: /var/lib/puppet
+.
+.IP "" 0
+.
+.P
+yamldir +++++++
+.
+.P
+The directory in which YAML data is stored, usually in a subdirectory\.
+.
+.IP "\(bu" 4
+\fIDefault\fR: $vardir/yaml
+.
+.IP "" 0
+.
+.P
+zlib ++++
+.
+.P
Boolean; whether to use the zlib library
-.INDENT 0.0
-.IP \(bu 2
.
-\fBDefault\fP: true
-.UNINDENT
-
-.sp
-.ce
-----
-
-.ce 0
-.sp
-.sp
-\fIThis page autogenerated on Wed Jul 14 14:33:09 \-0700 2010\fP
-.\" Generated by docutils manpage writer.
-.\"
+.IP "\(bu" 4
+\fIDefault\fR: true
+.
+.IP "" 0
.
+.P
+\fIThis page autogenerated on Sat Aug 28 14:00:20 \-0700 2010\fR
diff --git a/man/man8/filebucket.8 b/man/man8/filebucket.8
index dc2d60e63..60a6eb28e 100644
--- a/man/man8/filebucket.8
+++ b/man/man8/filebucket.8
@@ -1,107 +1,105 @@
-.TH "" "" ""
-.SH NAME
- \-
-.\" Man page generated from reStructeredText.
-.
-.SH SYNOPSIS
-.sp
-A stand\-alone Puppet filebucket client.
-.SH USAGE
-.INDENT 0.0
-.INDENT 3.5
-.INDENT 0.0
-.TP
-.B puppet filebucket [\-h|\-\-help] [\-V|\-\-version] [\-d|\-\-debug] [\-v|\-\-verbose]
-.
-[\-l|\-\-local] [\-r|\-\-remote]
-[\-s|\-\-server <server>] [\-b|\-\-bucket <directory>] <file> <file> ...
-.UNINDENT
-.UNINDENT
-.UNINDENT
-.SH DESCRIPTION
-.sp
-This is a stand\-alone filebucket client for sending files to a local or
-central filebucket.
-.SH USAGE
-.sp
-This client can operate in three modes, with only one mode per call:
-.INDENT 0.0
-.TP
-.B backup: Send one or more files to the specified file bucket. Each sent
-.
-file is printed with its resulting md5 sum.
-.TP
-.B get: Return the text associated with an md5 sum. The text is printed
-.
-to stdout, and only one file can be retrieved at a time.
-.TP
-.B restore: Given a file path and an md5 sum, store the content associated
-.
-with the sum into the specified file path. You can specify an
-entirely new path to this argument; you are not restricted to
-restoring the content to its original location.
-.UNINDENT
-.sp
-Note that +filebucket+ defaults to using a network\-based filebucket
-available on the server named +puppet+. To use this, you\(aqll have to be
-running as a user with valid Puppet certificates. Alternatively, you can
-use your local file bucket by specifying +\-\-local+.
-.SH EXAMPLE
-.INDENT 0.0
-.INDENT 3.5
-.sp
-$ puppet filebucket backup /etc/passwd
-/etc/passwd: 429b225650b912a2ee067b0a4cf1e949
-$ puppet filebucket restore /tmp/passwd 429b225650b912a2ee067b0a4cf1e949
-$
-.UNINDENT
-.UNINDENT
-.SH OPTIONS
-.sp
-Note that any configuration parameter that\(aqs valid in the configuration
-file is also a valid long argument. For example, \(aqssldir\(aq is a valid
-configuration parameter, so you can specify \(aq\-\-ssldir <directory>\(aq as an
-argument.
-.sp
-See the configuration file documentation at
-\fI\%http://docs.puppetlabs.com/references/stable/configuration.html\fP for the
-full list of acceptable parameters. A commented list of all
-configuration options can also be generated by running puppet with
-\(aq\-\-genconfig\(aq.
-.sp
-debug: Enable full debugging.
-.sp
-help: Print this help message
-.INDENT 0.0
-.TP
-.B local: Use the local filebucket. This will use the default
-.
-configuration information.
-.TP
-.B remote: Use a remote filebucket. This will use the default
-.
-configuration information.
-.UNINDENT
-.sp
-server: The server to send the file to, instead of locally.
-.sp
-verbose: Print extra information.
-.sp
-version: Print version information.
-.SH EXAMPLE
-.INDENT 0.0
-.INDENT 3.5
-.sp
-puppet filebucket \-b /tmp/filebucket /my/file
-.UNINDENT
-.UNINDENT
-.SH AUTHOR
-.sp
-Luke Kanies
-.SH COPYRIGHT
-.sp
-Copyright (c) 2005 Reductive Labs, LLC Licensed under the GNU Public
-License
-.\" Generated by docutils manpage writer.
-.\"
+.\" generated with Ronn/v0.7.3
+.\" http://github.com/rtomayko/ronn/tree/0.7.3
.
+.TH "FILEBUCKET" "8" "August 2010" "" ""
+A stand\-alone Puppet filebucket client\.puppet filebucket [\-h|\-\-help] [\-V|\-\-version] [\-d|\-\-debug] [\-v|\-\-verbose]
+.
+.IP "" 4
+.
+.nf
+
+ [\-l|\-\-local] [\-r|\-\-remote]
+ [\-s|\-\-server <server>] [\-b|\-\-bucket <directory>] <file> <file> \.\.\.
+.
+.fi
+.
+.IP "" 0
+This is a stand\-alone filebucket client for sending files to a local or central filebucket\.This client can operate in three modes, with only one mode per call:
+.
+.P
+backup: Send one or more files to the specified file bucket\. Each sent
+.
+.IP "" 4
+.
+.nf
+
+ file is printed with its resulting md5 sum\.
+.
+.fi
+.
+.IP "" 0
+.
+.P
+get: Return the text associated with an md5 sum\. The text is printed
+.
+.IP "" 4
+.
+.nf
+
+ to stdout, and only one file can be retrieved at a time\.
+.
+.fi
+.
+.IP "" 0
+.
+.P
+restore: Given a file path and an md5 sum, store the content associated
+.
+.IP "" 4
+.
+.nf
+
+ with the sum into the specified file path\. You can specify an
+ entirely new path to this argument; you are not restricted to
+ restoring the content to its original location\.
+.
+.fi
+.
+.IP "" 0
+.
+.P
+Note that +filebucket+ defaults to using a network\-based filebucket available on the server named +puppet+\. To use this, you\'ll have to be running as a user with valid Puppet certificates\. Alternatively, you can use your local file bucket by specifying +\-\-local+\.$ puppet filebucket backup /etc/passwd /etc/passwd: 429b225650b912a2ee067b0a4cf1e949 $ puppet filebucket restore /tmp/passwd 429b225650b912a2ee067b0a4cf1e949 $Note that any configuration parameter that\'s valid in the configuration file is also a valid long argument\. For example, \'ssldir\' is a valid configuration parameter, so you can specify \'\-\-ssldir \fIdirectory\fR\' as an argument\.
+.
+.P
+See the configuration file documentation at http://docs\.puppetlabs\.com/references/stable/configuration\.html for the full list of acceptable parameters\. A commented list of all configuration options can also be generated by running puppet with \'\-\-genconfig\'\.
+.
+.P
+debug: Enable full debugging\.
+.
+.P
+help: Print this help message
+.
+.P
+local: Use the local filebucket\. This will use the default
+.
+.IP "" 4
+.
+.nf
+
+ configuration information\.
+.
+.fi
+.
+.IP "" 0
+.
+.P
+remote: Use a remote filebucket\. This will use the default
+.
+.IP "" 4
+.
+.nf
+
+ configuration information\.
+.
+.fi
+.
+.IP "" 0
+.
+.P
+server: The server to send the file to, instead of locally\.
+.
+.P
+verbose: Print extra information\.
+.
+.P
+version: Print version information\.puppet filebucket \-b /tmp/filebucket /my/fileLuke KaniesCopyright (c) 2005 Reductive Labs, LLC Licensed under the GNU Public License
diff --git a/man/man8/pi.8 b/man/man8/pi.8
index 3e25485fc..e8f5ab531 100644
--- a/man/man8/pi.8
+++ b/man/man8/pi.8
@@ -1,50 +1,17 @@
-.TH "" "" ""
-.SH NAME
- \-
-.\" Man page generated from reStructeredText.
+.\" generated with Ronn/v0.7.3
+.\" http://github.com/rtomayko/ronn/tree/0.7.3
.
-.SH SYNOPSIS
-.sp
-Print help about puppet types on the console. Run with \(aq\-h\(aq to get
-detailed help.
-.SH USAGE
-.INDENT 0.0
-.INDENT 3.5
-.sp
-puppet describe [\-h|\-\-help] [\-s|\-\-short] [\-p|\-\-providers] [\-l|\-\-list] [\-m|\-\-meta]
-.UNINDENT
-.UNINDENT
-.SH DESCRIPTION
-.sp
-Prints details of Puppet types, providers and metaparameters on the
-console.
-.SH OPTIONS
-.sp
-help: Print this help text
-.sp
+.TH "PI" "8" "August 2010" "" ""
+Print help about puppet types on the console\. Run with \'\-h\' to get detailed help\.puppet describe [\-h|\-\-help] [\-s|\-\-short] [\-p|\-\-providers] [\-l|\-\-list] [\-m|\-\-meta]Prints details of Puppet types, providers and metaparameters on the console\.help: Print this help text
+.
+.P
providers: Describe providers in detail for each type
-.sp
-list: List all types
-.sp
-meta: List all metaparameters
-.sp
-short: List only parameters without detail
-.SH EXAMPLE
-.INDENT 0.0
-.INDENT 3.5
-.sp
-puppet describe \-\-list
-puppet describe file \-\-providers
-puppet describe user \-s \-m
-.UNINDENT
-.UNINDENT
-.SH AUTHOR
-.sp
-David Lutterkort
-.SH COPYRIGHT
-.sp
-Copyright (c) 2005 Reductive Labs, LLC Licensed under the GNU Public
-License
-.\" Generated by docutils manpage writer.
-.\"
.
+.P
+list: List all types
+.
+.P
+meta: List all metaparameters
+.
+.P
+short: List only parameters without detailpuppet describe \-\-list puppet describe file \-\-providers puppet describe user \-s \-mDavid LutterkortCopyright (c) 2005 Reductive Labs, LLC Licensed under the GNU Public License
diff --git a/man/man8/puppet.8 b/man/man8/puppet.8
index 7fa2a05c2..513d45338 100644
--- a/man/man8/puppet.8
+++ b/man/man8/puppet.8
@@ -1,11 +1,10 @@
-.TH "" "" ""
-.SH NAME
- \-
-.\" Man page generated from reStructeredText.
+.\" generated with Ronn/v0.7.3
+.\" http://github.com/rtomayko/ronn/tree/0.7.3
.
-.sp
-Usage: puppet command <space separated arguments>
-Available commands are: agent, apply, cert, describe, doc, filebucket, kick, master, pi, puppet, puppetca, puppetd, puppetdoc, puppetmasterd, puppetqd, puppetrun, queue, ralsh, resource
-.\" Generated by docutils manpage writer.
-.\"
+.TH "PUPPET" "8" "August 2010" "" ""
.
+.SH "NAME"
+\fBpuppet\fR
+.
+.P
+Usage: puppet command \fIspace separated arguments\fR Available commands are: agent, apply, cert, describe, doc, filebucket, kick, master, queue, resource
diff --git a/man/man8/puppetca.8 b/man/man8/puppetca.8
index ec1f5045c..17369aa20 100644
--- a/man/man8/puppetca.8
+++ b/man/man8/puppetca.8
@@ -1,130 +1,169 @@
-.TH "" "" ""
-.SH NAME
- \-
-.\" Man page generated from reStructeredText.
-.
-.SH SYNOPSIS
-.sp
-Stand\-alone certificate authority. Capable of generating certificates
-but mostly meant for signing certificate requests from puppet clients.
-.SH USAGE
-.INDENT 0.0
-.INDENT 3.5
-.INDENT 0.0
-.TP
-.B puppet cert [\-h|\-\-help] [\-V|\-\-version] [\-d|\-\-debug] [\-v|\-\-verbose]
-.
-[\-g|\-\-generate] [\-l|\-\-list] [\-s|\-\-sign] [\-r|\-\-revoke]
-[\-p|\-\-print] [\-c|\-\-clean] [\-\-verify] [\-\-digest DIGEST]
-[\-\-fingerprint] [host]
-.UNINDENT
-.UNINDENT
-.UNINDENT
-.SH DESCRIPTION
-.sp
-Because the puppetmasterd daemon defaults to not signing client
-certificate requests, this script is available for signing outstanding
-requests. It can be used to list outstanding requests and then either
-sign them individually or sign all of them.
-.SH OPTIONS
-.sp
-Note that any configuration parameter that\(aqs valid in the configuration
-file is also a valid long argument. For example, \(aqssldir\(aq is a valid
-configuration parameter, so you can specify \(aq\-\-ssldir <directory>\(aq as an
-argument.
-.sp
-See the configuration file documentation at
-\fI\%http://reductivelabs.com/projects/puppet/reference/configref.html\fP for
-the full list of acceptable parameters. A commented list of all
-configuration options can also be generated by running puppet cert with
-\(aq\-\-genconfig\(aq.
-.INDENT 0.0
-.TP
-.B all: Operate on all items. Currently only makes sense with
-.
-\(aq\-\-sign\(aq, \(aq\-\-clean\(aq, or \(aq\-\-list\(aq.
-.TP
-.B digest: Set the digest for fingerprinting (defaults to md5). Valid
-.
-values depends on your openssl and openssl ruby extension
-version, but should contain at least md5, sha1, md2,
-sha256.
-.TP
-.B clean: Remove all files related to a host from puppet cert\(aqs
-.
-storage. This is useful when rebuilding hosts, since new
-certificate signing requests will only be honored if puppet
-cert does not have a copy of a signed certificate for that
-host. The certificate of the host remains valid. If \(aq\-\-all\(aq
-is specified then all host certificates, both signed and
-unsigned, will be removed.
-.UNINDENT
-.sp
-debug: Enable full debugging.
-.INDENT 0.0
-.TP
-.B generate: Generate a certificate for a named client. A
-.
-certificate/keypair will be generated for each client named
-on the command line.
-.UNINDENT
-.sp
-help: Print this help message
-.INDENT 0.0
-.TP
-.B list: List outstanding certificate requests. If \(aq\-\-all\(aq is
-.
-specified, signed certificates are also listed, prefixed by
-\(aq+\(aq, and revoked or invalid certificates are prefixed by
-\(aq\-\(aq (the verification outcome is printed in parenthesis).
-.UNINDENT
-.sp
-print: Print the full\-text version of a host\(aqs certificate.
-.INDENT 0.0
-.TP
-.B fingerprint: Print the DIGEST (defaults to md5) fingerprint of a host\(aqs
-.
-certificate.
-.TP
-.B revoke: Revoke the certificate of a client. The certificate can be
-.
-specified either by its serial number, given as a decimal
-number or a hexadecimal number prefixed by \(aq0x\(aq, or by its
-hostname. The certificate is revoked by adding it to the
-Certificate Revocation List given by the \(aqcacrl\(aq config
-parameter. Note that the puppetmasterd needs to be
-restarted after revoking certificates.
-.TP
-.B sign: Sign an outstanding certificate request. Unless \(aq\-\-all\(aq is
-.
-specified, hosts must be listed after all flags.
-.UNINDENT
-.sp
-verbose: Enable verbosity.
-.sp
-version: Print the puppet version number and exit.
-.INDENT 0.0
-.TP
-.B verify: Verify the named certificate against the local CA
-.
-certificate.
-.UNINDENT
-.SH EXAMPLE
-.INDENT 0.0
-.INDENT 3.5
-.sp
-$ puppet cert \-l
-culain.madstop.com
-$ puppet cert \-s culain.madstop.com
-.UNINDENT
-.UNINDENT
-.SH AUTHOR
-.sp
-Luke Kanies
-.SH COPYRIGHT
-.sp
-Copyright (c) 2005 Reductive Labs, LLC Licensed under the GNU Public
-License
-.\" Generated by docutils manpage writer.
-.\"
+.\" generated with Ronn/v0.7.3
+.\" http://github.com/rtomayko/ronn/tree/0.7.3
.
+.TH "PUPPETCA" "8" "August 2010" "" ""
+Stand\-alone certificate authority\. Capable of generating certificates but mostly meant for signing certificate requests from puppet clients\.puppet cert [\-h|\-\-help] [\-V|\-\-version] [\-d|\-\-debug] [\-v|\-\-verbose]
+.
+.IP "" 4
+.
+.nf
+
+ [\-g|\-\-generate] [\-l|\-\-list] [\-s|\-\-sign] [\-r|\-\-revoke]
+ [\-p|\-\-print] [\-c|\-\-clean] [\-\-verify] [\-\-digest DIGEST]
+ [\-\-fingerprint] [host]
+.
+.fi
+.
+.IP "" 0
+Because the puppetmasterd daemon defaults to not signing client certificate requests, this script is available for signing outstanding requests\. It can be used to list outstanding requests and then either sign them individually or sign all of them\.Note that any configuration parameter that\'s valid in the configuration file is also a valid long argument\. For example, \'ssldir\' is a valid configuration parameter, so you can specify \'\-\-ssldir \fIdirectory\fR\' as an argument\.
+.
+.P
+See the configuration file documentation at http://reductivelabs\.com/projects/puppet/reference/configref\.html for the full list of acceptable parameters\. A commented list of all configuration options can also be generated by running puppet cert with \'\-\-genconfig\'\.
+.
+.P
+all: Operate on all items\. Currently only makes sense with
+.
+.IP "" 4
+.
+.nf
+
+ \'\-\-sign\', \'\-\-clean\', or \'\-\-list\'\.
+.
+.fi
+.
+.IP "" 0
+.
+.P
+digest: Set the digest for fingerprinting (defaults to md5)\. Valid
+.
+.IP "" 4
+.
+.nf
+
+ values depends on your openssl and openssl ruby extension
+ version, but should contain at least md5, sha1, md2,
+ sha256\.
+.
+.fi
+.
+.IP "" 0
+.
+.P
+clean: Remove all files related to a host from puppet cert\'s
+.
+.IP "" 4
+.
+.nf
+
+ storage\. This is useful when rebuilding hosts, since new
+ certificate signing requests will only be honored if puppet
+ cert does not have a copy of a signed certificate for that
+ host\. The certificate of the host remains valid\. If \'\-\-all\'
+ is specified then all host certificates, both signed and
+ unsigned, will be removed\.
+.
+.fi
+.
+.IP "" 0
+.
+.P
+debug: Enable full debugging\.
+.
+.P
+generate: Generate a certificate for a named client\. A
+.
+.IP "" 4
+.
+.nf
+
+ certificate/keypair will be generated for each client named
+ on the command line\.
+.
+.fi
+.
+.IP "" 0
+.
+.P
+help: Print this help message
+.
+.P
+list: List outstanding certificate requests\. If \'\-\-all\' is
+.
+.IP "" 4
+.
+.nf
+
+ specified, signed certificates are also listed, prefixed by
+ \'+\', and revoked or invalid certificates are prefixed by
+ \'\-\' (the verification outcome is printed in parenthesis)\.
+.
+.fi
+.
+.IP "" 0
+.
+.P
+print: Print the full\-text version of a host\'s certificate\.
+.
+.P
+fingerprint: Print the DIGEST (defaults to md5) fingerprint of a host\'s
+.
+.IP "" 4
+.
+.nf
+
+ certificate\.
+.
+.fi
+.
+.IP "" 0
+.
+.P
+revoke: Revoke the certificate of a client\. The certificate can be
+.
+.IP "" 4
+.
+.nf
+
+ specified either by its serial number, given as a decimal
+ number or a hexadecimal number prefixed by \'0x\', or by its
+ hostname\. The certificate is revoked by adding it to the
+ Certificate Revocation List given by the \'cacrl\' config
+ parameter\. Note that the puppetmasterd needs to be
+ restarted after revoking certificates\.
+.
+.fi
+.
+.IP "" 0
+.
+.P
+sign: Sign an outstanding certificate request\. Unless \'\-\-all\' is
+.
+.IP "" 4
+.
+.nf
+
+ specified, hosts must be listed after all flags\.
+.
+.fi
+.
+.IP "" 0
+.
+.P
+verbose: Enable verbosity\.
+.
+.P
+version: Print the puppet version number and exit\.
+.
+.P
+verify: Verify the named certificate against the local CA
+.
+.IP "" 4
+.
+.nf
+
+ certificate\.
+.
+.fi
+.
+.IP "" 0
+$ puppet cert \-l culain\.madstop\.com $ puppet cert \-s culain\.madstop\.comLuke KaniesCopyright (c) 2005 Reductive Labs, LLC Licensed under the GNU Public License
diff --git a/man/man8/puppetd.8 b/man/man8/puppetd.8
index 090c3342d..32aede791 100644
--- a/man/man8/puppetd.8
+++ b/man/man8/puppetd.8
@@ -1,227 +1,283 @@
-.TH SYNOPSIS "" "" ""
-.SH NAME
-Synopsis \-
-.\" Man page generated from reStructeredText.
-.
-.sp
-Retrieve the client configuration from the puppet master and apply it to
-the local host.
-.sp
-Currently must be run out periodically, using cron or something similar.
-.SH USAGE
-.INDENT 0.0
-.INDENT 3.5
-.INDENT 0.0
-.TP
-.B puppet agent [\-D|\-\-daemonize|\-\-no\-daemonize] [\-d|\-\-debug]
-.
-[\-\-detailed\-exitcodes] [\-\-disable] [\-\-enable]
-[\-h|\-\-help] [\-\-fqdn <host name>] [\-l|\-\-logdest syslog|<file>|console]
-[\-o|\-\-onetime] [\-\-serve <handler>] [\-t|\-\-test] [\-\-noop]
-[\-\-digest <digest>] [\-\-fingerprint] [\-V|\-\-version]
-[\-v|\-\-verbose] [\-w|\-\-waitforcert <seconds>]
-.UNINDENT
-.UNINDENT
-.UNINDENT
-.SH DESCRIPTION
-.sp
-This is the main puppet client. Its job is to retrieve the local
-machine\(aqs configuration from a remote server and apply it. In order to
-successfully communicate with the remote server, the client must have a
-certificate signed by a certificate authority that the server trusts;
-the recommended method for this, at the moment, is to run a certificate
-authority as part of the puppet server (which is the default). The
-client will connect and request a signed certificate, and will continue
-connecting until it receives one.
-.sp
-Once the client has a signed certificate, it will retrieve its
-configuration and apply it.
-.SH USAGE NOTES
-.sp
-+puppet agent+ does its best to find a compromise between interactive
-use and daemon use. Run with no arguments and no configuration, it will
-go into the backgroun, attempt to get a signed certificate, and retrieve
-and apply its configuration every 30 minutes.
-.sp
-Some flags are meant specifically for interactive use \-\- in particular,
-+test+, +tags+ or +fingerprint+ are useful. +test+ enables verbose
-logging, causes the daemon to stay in the foreground, exits if the
-server\(aqs configuration is invalid (this happens if, for instance, you\(aqve
-left a syntax error on the server), and exits after running the
-configuration once (rather than hanging around as a long\-running
-process).
-.sp
-+tags+ allows you to specify what portions of a configuration you want
-to apply. Puppet elements are tagged with all of the class or definition
-names that contain them, and you can use the +tags+ flag to specify one
-of these names, causing only configuration elements contained within
-that class or definition to be applied. This is very useful when you are
-testing new configurations \-\- for instance, if you are just starting to
-manage +ntpd+, you would put all of the new elements into an +ntpd+
-class, and call puppet with +\-\-tags ntpd+, which would only apply that
-small portion of the configuration during your testing, rather than
-applying the whole thing.
-.sp
-+fingerprint+ is a one\-time flag. In this mode +puppet agent+ will run
-once and display on the console (and in the log) the current certificate
-(or certificate request) fingerprint. Providing the +\-\-digest+ option
-allows to use a different digest algorithm to generate the fingerprint.
-The main use is to verify that before signing a certificate request on
-the master, the certificate request the master received is the same as
-the one the client sent (to prevent against man\-in\-the\-middle attacks
-when signing certificates).
-.SH OPTIONS
-.sp
-Note that any configuration parameter that\(aqs valid in the configuration
-file is also a valid long argument. For example, \(aqserver\(aq is a valid
-configuration parameter, so you can specify \(aq\-\-server <servername>\(aq as
-an argument.
-.sp
-See the configuration file documentation at
-\fI\%http://docs.puppetlabs.com/references/stable/configuration.html\fP for the
-full list of acceptable parameters. A commented list of all
-configuration options can also be generated by running puppet agent with
-\(aq\-\-genconfig\(aq.
-.INDENT 0.0
-.TP
-.B daemonize: Send the process into the background. This is the
-.
-default.
-.UNINDENT
-.sp
-no\-daemonize: Do not send the process into the background.
-.sp
-debug: Enable full debugging.
-.INDENT 0.0
-.TP
-.B digest: Change the certificate fingerprinting digest
-.
-algorithm. The default is MD5. Valid values depends
-on the version of OpenSSL installed, but should
-always at least contain MD5, MD2, SHA1 and SHA256.
-.TP
-.B detailed\-exitcodes: Provide transaction information via exit codes. If
-.
-this is enabled, an exit code of \(aq2\(aq means there
-were changes, and an exit code of \(aq4\(aq means that
-there were failures during the transaction. This
-option only makes sense in conjunction with
-\-\-onetime.
-.TP
-.B disable: Disable working on the local system. This puts a
-.
-lock file in place, causing +puppet agent+ not to
-work on the system until the lock file is removed.
-This is useful if you are testing a configuration
-and do not want the central configuration to
-override the local state until everything is tested
-and committed.
-.UNINDENT
-.sp
-+puppet agent+ uses the same lock file while it is running, so no more
-than one +puppet agent+ process is working at a time.
-.sp
-+puppet agent+ exits after executing this.
-.INDENT 0.0
-.TP
-.B enable: Enable working on the local system. This removes any
-.
-lock file, causing +puppet agent+ to start managing
-the local system again (although it will continue to
-use its normal scheduling, so it might not start for
-another half hour).
-.UNINDENT
-.sp
-+puppet agent+ exits after executing this.
-.INDENT 0.0
-.TP
-.B fqdn: Set the fully\-qualified domain name of the client.
-.
-This is only used for certificate purposes, but can
-be used to override the discovered hostname. If you
-need to use this flag, it is generally an indication
-of a setup problem.
-.UNINDENT
-.sp
-help: Print this help message
-.INDENT 0.0
-.TP
-.B logdest: Where to send messages. Choose between syslog, the
-.
-console, and a log file. Defaults to sending
-messages to syslog, or the console if debugging or
-verbosity is enabled.
-.TP
-.B no\-client: Do not create a config client. This will cause the
-.
-daemon to run without ever checking for its
-configuration automatically, and only makes sense
-when used in conjunction with \-\-listen.
-.TP
-.B onetime: Run the configuration once. Runs a single (normally
-.
-daemonized) Puppet run. Useful for interactively
-running puppet agent when used in conjunction with
-the \-\-no\-daemonize option.
-.TP
-.B fingerprint: Display the current certificate or certificate
-.
-signing request fingerprint and then exit. Use the
-+\-\-digest+ option to change the digest algorithm
-used.
-.TP
-.B serve: Start another type of server. By default, +puppet
-.
-agent+ will start a service handler that allows
-authenticated and authorized remote nodes to trigger
-the configuration to be pulled down and applied. You
-can specify any handler here that does not require
-configuration, e.g., filebucket, ca, or resource.
-The handlers are in +lib/puppet/network/handler+,
-and the names must match exactly, both in the call
-to +serve+ and in +namespaceauth.conf+.
-.TP
-.B test: Enable the most common options used for testing.
-.
-These are +onetime+, +verbose+, +ignorecache,
-+no\-daemonize+, and +no\-usecacheonfailure+.
-.TP
-.B noop: Use +noop+ mode where the daemon runs in a no\-op or
-.
-dry\-run mode. This is useful for seeing what changes
-Puppet will make without actually executing the
-changes.
-.UNINDENT
-.sp
-verbose: Turn on verbose reporting.
-.sp
-version: Print the puppet version number and exit.
-.INDENT 0.0
-.TP
-.B waitforcert: This option only matters for daemons that do not yet
-.
-have certificates and it is enabled by default, with
-a value of 120 (seconds). This causes +puppet agent+
-to connect to the server every 2 minutes and ask it
-to sign a certificate request. This is useful for
-the initial setup of a puppet client. You can turn
-off waiting for certificates by specifying a time of
-0.
-.UNINDENT
-.SH EXAMPLE
-.INDENT 0.0
-.INDENT 3.5
-.sp
-puppet agent \-\-server puppet.domain.com
-.UNINDENT
-.UNINDENT
-.SH AUTHOR
-.sp
-Luke Kanies
-.SH COPYRIGHT
-.sp
-Copyright (c) 2005, 2006 Reductive Labs, LLC Licensed under the GNU
-Public License
-.\" Generated by docutils manpage writer.
-.\"
+.\" generated with Ronn/v0.7.3
+.\" http://github.com/rtomayko/ronn/tree/0.7.3
.
+.TH "PUPPETD" "8" "August 2010" "" ""
+puppet agent [\-D|\-\-daemonize|\-\-no\-daemonize] [\-d|\-\-debug]
+.
+.IP "" 4
+.
+.nf
+
+ [\-\-detailed\-exitcodes] [\-\-disable] [\-\-enable]
+ [\-h|\-\-help] [\-\-fqdn <host name>] [\-l|\-\-logdest syslog|<file>|console]
+ [\-o|\-\-onetime] [\-\-serve <handler>] [\-t|\-\-test] [\-\-noop]
+ [\-\-digest <digest>] [\-\-fingerprint] [\-V|\-\-version]
+ [\-v|\-\-verbose] [\-w|\-\-waitforcert <seconds>]
+.
+.fi
+.
+.IP "" 0
+This is the main puppet client\. Its job is to retrieve the local machine\'s configuration from a remote server and apply it\. In order to successfully communicate with the remote server, the client must have a certificate signed by a certificate authority that the server trusts; the recommended method for this, at the moment, is to run a certificate authority as part of the puppet server (which is the default)\. The client will connect and request a signed certificate, and will continue connecting until it receives one\.
+.
+.P
+Once the client has a signed certificate, it will retrieve its configuration and apply it\.+puppet agent+ does its best to find a compromise between interactive use and daemon use\. Run with no arguments and no configuration, it will go into the backgroun, attempt to get a signed certificate, and retrieve and apply its configuration every 30 minutes\.
+.
+.P
+Some flags are meant specifically for interactive use \-\- in particular, +test+, +tags+ or +fingerprint+ are useful\. +test+ enables verbose logging, causes the daemon to stay in the foreground, exits if the server\'s configuration is invalid (this happens if, for instance, you\'ve left a syntax error on the server), and exits after running the configuration once (rather than hanging around as a long\-running process)\.
+.
+.P
++tags+ allows you to specify what portions of a configuration you want to apply\. Puppet elements are tagged with all of the class or definition names that contain them, and you can use the +tags+ flag to specify one of these names, causing only configuration elements contained within that class or definition to be applied\. This is very useful when you are testing new configurations \-\- for instance, if you are just starting to manage +ntpd+, you would put all of the new elements into an +ntpd+ class, and call puppet with +\-\-tags ntpd+, which would only apply that small portion of the configuration during your testing, rather than applying the whole thing\.
+.
+.P
++fingerprint+ is a one\-time flag\. In this mode +puppet agent+ will run once and display on the console (and in the log) the current certificate (or certificate request) fingerprint\. Providing the +\-\-digest+ option allows to use a different digest algorithm to generate the fingerprint\. The main use is to verify that before signing a certificate request on the master, the certificate request the master received is the same as the one the client sent (to prevent against man\-in\-the\-middle attacks when signing certificates)\.Note that any configuration parameter that\'s valid in the configuration file is also a valid long argument\. For example, \'server\' is a valid configuration parameter, so you can specify \'\-\-server \fIservername\fR\' as an argument\.
+.
+.P
+See the configuration file documentation at http://docs\.puppetlabs\.com/references/stable/configuration\.html for the full list of acceptable parameters\. A commented list of all configuration options can also be generated by running puppet agent with \'\-\-genconfig\'\.
+.
+.P
+daemonize: Send the process into the background\. This is the
+.
+.IP "" 4
+.
+.nf
+
+ default\.
+.
+.fi
+.
+.IP "" 0
+.
+.P
+no\-daemonize: Do not send the process into the background\.
+.
+.P
+debug: Enable full debugging\.
+.
+.P
+digest: Change the certificate fingerprinting digest
+.
+.IP "" 4
+.
+.nf
+
+ algorithm\. The default is MD5\. Valid values depends
+ on the version of OpenSSL installed, but should
+ always at least contain MD5, MD2, SHA1 and SHA256\.
+.
+.fi
+.
+.IP "" 0
+.
+.P
+detailed\-exitcodes: Provide transaction information via exit codes\. If
+.
+.IP "" 4
+.
+.nf
+
+ this is enabled, an exit code of \'2\' means there
+ were changes, and an exit code of \'4\' means that
+ there were failures during the transaction\. This
+ option only makes sense in conjunction with
+ \-\-onetime\.
+.
+.fi
+.
+.IP "" 0
+.
+.P
+disable: Disable working on the local system\. This puts a
+.
+.IP "" 4
+.
+.nf
+
+ lock file in place, causing +puppet agent+ not to
+ work on the system until the lock file is removed\.
+ This is useful if you are testing a configuration
+ and do not want the central configuration to
+ override the local state until everything is tested
+ and committed\.
+.
+.fi
+.
+.IP "" 0
+.
+.P
++puppet agent+ uses the same lock file while it is running, so no more than one +puppet agent+ process is working at a time\.
+.
+.P
++puppet agent+ exits after executing this\.
+.
+.P
+enable: Enable working on the local system\. This removes any
+.
+.IP "" 4
+.
+.nf
+
+ lock file, causing +puppet agent+ to start managing
+ the local system again (although it will continue to
+ use its normal scheduling, so it might not start for
+ another half hour)\.
+.
+.fi
+.
+.IP "" 0
+.
+.P
++puppet agent+ exits after executing this\.
+.
+.P
+fqdn: Set the fully\-qualified domain name of the client\.
+.
+.IP "" 4
+.
+.nf
+
+ This is only used for certificate purposes, but can
+ be used to override the discovered hostname\. If you
+ need to use this flag, it is generally an indication
+ of a setup problem\.
+.
+.fi
+.
+.IP "" 0
+.
+.P
+help: Print this help message
+.
+.P
+logdest: Where to send messages\. Choose between syslog, the
+.
+.IP "" 4
+.
+.nf
+
+ console, and a log file\. Defaults to sending
+ messages to syslog, or the console if debugging or
+ verbosity is enabled\.
+.
+.fi
+.
+.IP "" 0
+.
+.P
+no\-client: Do not create a config client\. This will cause the
+.
+.IP "" 4
+.
+.nf
+
+ daemon to run without ever checking for its
+ configuration automatically, and only makes sense
+ when used in conjunction with \-\-listen\.
+.
+.fi
+.
+.IP "" 0
+.
+.P
+onetime: Run the configuration once\. Runs a single (normally
+.
+.IP "" 4
+.
+.nf
+
+ daemonized) Puppet run\. Useful for interactively
+ running puppet agent when used in conjunction with
+ the \-\-no\-daemonize option\.
+.
+.fi
+.
+.IP "" 0
+.
+.P
+fingerprint: Display the current certificate or certificate
+.
+.IP "" 4
+.
+.nf
+
+ signing request fingerprint and then exit\. Use the
+ +\-\-digest+ option to change the digest algorithm
+ used\.
+.
+.fi
+.
+.IP "" 0
+.
+.P
+serve: Start another type of server\. By default, +puppet
+.
+.IP "" 4
+.
+.nf
+
+ agent+ will start a service handler that allows
+ authenticated and authorized remote nodes to trigger
+ the configuration to be pulled down and applied\. You
+ can specify any handler here that does not require
+ configuration, e\.g\., filebucket, ca, or resource\.
+ The handlers are in +lib/puppet/network/handler+,
+ and the names must match exactly, both in the call
+ to +serve+ and in +namespaceauth\.conf+\.
+.
+.fi
+.
+.IP "" 0
+.
+.P
+test: Enable the most common options used for testing\.
+.
+.IP "" 4
+.
+.nf
+
+ These are +onetime+, +verbose+, +ignorecache,
+ +no\-daemonize+, and +no\-usecacheonfailure+\.
+.
+.fi
+.
+.IP "" 0
+.
+.P
+noop: Use +noop+ mode where the daemon runs in a no\-op or
+.
+.IP "" 4
+.
+.nf
+
+ dry\-run mode\. This is useful for seeing what changes
+ Puppet will make without actually executing the
+ changes\.
+.
+.fi
+.
+.IP "" 0
+.
+.P
+verbose: Turn on verbose reporting\.
+.
+.P
+version: Print the puppet version number and exit\.
+.
+.P
+waitforcert: This option only matters for daemons that do not yet
+.
+.IP "" 4
+.
+.nf
+
+ have certificates and it is enabled by default, with
+ a value of 120 (seconds)\. This causes +puppet agent+
+ to connect to the server every 2 minutes and ask it
+ to sign a certificate request\. This is useful for
+ the initial setup of a puppet client\. You can turn
+ off waiting for certificates by specifying a time of
+ 0\.
+.
+.fi
+.
+.IP "" 0
+puppet agent \-\-server puppet\.domain\.comLuke KaniesCopyright (c) 2005, 2006 Reductive Labs, LLC Licensed under the GNU Public License
diff --git a/man/man8/puppetdoc.8 b/man/man8/puppetdoc.8
index 281b7385e..5fc01c2ba 100644
--- a/man/man8/puppetdoc.8
+++ b/man/man8/puppetdoc.8
@@ -1,108 +1,108 @@
-.TH "" "" ""
-.SH NAME
- \-
-.\" Man page generated from reStructeredText.
-.
-.SH SYNOPSIS
-.sp
-Generate a reference for all Puppet types. Largely meant for internal
-Reductive Labs use.
-.SH USAGE
-.INDENT 0.0
-.INDENT 3.5
-.INDENT 0.0
-.TP
-.B puppet doc [\-a|\-\-all] [\-h|\-\-help] [\-o|\-\-outputdir <rdoc outputdir>] [\-m|\-\-mode <text|pdf|markdown|trac|rdoc>]
-.
-[\-r|\-\-reference <[type]|configuration|..>] [\-\-charset CHARSET] [manifest\-file]
-.UNINDENT
-.UNINDENT
-.UNINDENT
-.SH DESCRIPTION
-.sp
-If mode is not \(aqrdoc\(aq, then this command generates a restructured\-text
-document describing all installed Puppet types or all allowable
-arguments to puppet executables. It is largely meant for internal use
-and is used to generate the reference document available on the
-Reductive Labs web site.
-.sp
-In \(aqrdoc\(aq mode, this command generates an html RDoc hierarchy describing
-the manifests that are in \(aqmanifestdir\(aq and \(aqmodulepath\(aq configuration
-directives. The generated documentation directory is doc by default but
-can be changed with the \(aqoutputdir\(aq option.
-.sp
-If the command is started with \(aqmanifest\-file\(aq command\-line arguments,
-puppet doc generate a single manifest documentation that is output on
-stdout.
-.SH OPTIONS
-.INDENT 0.0
-.TP
-.B all: Output the docs for all of the reference types. In \(aqrdoc\(aq
-.
-modes, this also outputs documentation for all resources
-.UNINDENT
-.sp
-help: Print this help message
-.INDENT 0.0
-.TP
-.B outputdir: Specifies the directory where to output the rdoc
-.
-documentation in \(aqrdoc\(aq mode.
-.TP
-.B mode: Determine the output mode. Valid modes are \(aqtext\(aq, \(aqtrac\(aq,
-.
-\(aqpdf\(aq, \(aqmarkdown\(aq and \(aqrdoc\(aq. The \(aqpdf\(aq and \(aqmarkdown\(aq modes
-create PDF or Markdown formatted files in the /tmp directory.
-Note that \(aqtrac\(aq mode only works on Reductive Labs servers.
-The default mode is \(aqtext\(aq. In \(aqrdoc\(aq mode you must provide
-\(aqmanifests\-path\(aq
-.TP
-.B reference: Build a particular reference. Get a list of references by
-.
-running +puppet doc \-\-list+.
-.TP
-.B charset: Used only in \(aqrdoc\(aq mode. It sets the charset used in the
-.
-html files produced.
-.UNINDENT
-.SH EXAMPLE
-.INDENT 0.0
-.INDENT 3.5
-.sp
-$ puppet doc \-r type > /tmp/type_reference.rst
-.UNINDENT
-.UNINDENT
-.sp
+.\" generated with Ronn/v0.7.3
+.\" http://github.com/rtomayko/ronn/tree/0.7.3
+.
+.TH "PUPPETDOC" "8" "August 2010" "" ""
+Generate a reference for all Puppet types\. Largely meant for internal Reductive Labs use\.puppet doc [\-a|\-\-all] [\-h|\-\-help] [\-o|\-\-outputdir \fIrdoc outputdir\fR] [\-m|\-\-mode \fItext|pdf|rdoc\fR]
+.
+.IP "" 4
+.
+.nf
+
+ [\-r|\-\-reference <[type]|configuration|\.\.>] [\-\-charset CHARSET] [manifest\-file]
+.
+.fi
+.
+.IP "" 0
+If mode is not \'rdoc\', then this command generates a Markdown document describing all installed Puppet types or all allowable arguments to puppet executables\. It is largely meant for internal use and is used to generate the reference document available on the Puppet Labs web site\.
+.
+.P
+In \'rdoc\' mode, this command generates an html RDoc hierarchy describing the manifests that are in \'manifestdir\' and \'modulepath\' configuration directives\. The generated documentation directory is doc by default but can be changed with the \'outputdir\' option\.
+.
+.P
+If the command is started with \'manifest\-file\' command\-line arguments, puppet doc generate a single manifest documentation that is output on stdout\.all: Output the docs for all of the reference types\. In \'rdoc\'
+.
+.IP "" 4
+.
+.nf
+
+ modes, this also outputs documentation for all resources
+.
+.fi
+.
+.IP "" 0
+.
+.P
+help: Print this help message
+.
+.P
+outputdir: Specifies the directory where to output the rdoc
+.
+.IP "" 4
+.
+.nf
+
+ documentation in \'rdoc\' mode\.
+.
+.fi
+.
+.IP "" 0
+.
+.P
+mode: Determine the output mode\. Valid modes are \'text\', \'trac\',
+.
+.IP "" 4
+.
+.nf
+
+ \'pdf\' and \'rdoc\'\. The \'pdf\' mode creates PDF formatted files
+ in the /tmp directory\. The default mode is \'text\'\. In \'rdoc\'
+ mode you must provide \'manifests\-path\'
+.
+.fi
+.
+.IP "" 0
+.
+.P
+reference: Build a particular reference\. Get a list of references by
+.
+.IP "" 4
+.
+.nf
+
+ running +puppet doc \-\-list+\.
+.
+.fi
+.
+.IP "" 0
+.
+.P
+charset: Used only in \'rdoc\' mode\. It sets the charset used in the
+.
+.IP "" 4
+.
+.nf
+
+ html files produced\.
+.
+.fi
+.
+.IP "" 0
+$ puppet doc \-r type > /tmp/type_reference\.rst
+.
+.P
or
-.INDENT 0.0
-.INDENT 3.5
-.sp
+.
+.P
$ puppet doc \-\-outputdir /tmp/rdoc \-\-mode rdoc /path/to/manifests
-.UNINDENT
-.UNINDENT
-.sp
+.
+.P
or
-.INDENT 0.0
-.INDENT 3.5
-.sp
-$ puppet doc /etc/puppet/manifests/site.pp
-.UNINDENT
-.UNINDENT
-.sp
+.
+.P
+$ puppet doc /etc/puppet/manifests/site\.pp
+.
+.P
or
-.INDENT 0.0
-.INDENT 3.5
-.sp
-$ puppet doc \-m markdown \-r configuration
-.UNINDENT
-.UNINDENT
-.SH AUTHOR
-.sp
-Luke Kanies
-.SH COPYRIGHT
-.sp
-Copyright (c) 2005\-2007 Reductive Labs, LLC Licensed under the GNU
-Public License
-.\" Generated by docutils manpage writer.
-.\"
.
+.P
+$ puppet doc \-m pdf \-r configurationLuke KaniesCopyright (c) 2005\-2007 Reductive Labs, LLC Licensed under the GNU Public License
diff --git a/man/man8/puppetmasterd.8 b/man/man8/puppetmasterd.8
index f6fb1e095..3ae567a69 100644
--- a/man/man8/puppetmasterd.8
+++ b/man/man8/puppetmasterd.8
@@ -1,72 +1,52 @@
-.TH "" "" ""
-.SH NAME
- \-
-.\" Man page generated from reStructeredText.
-.
-.SH SYNOPSIS
-.sp
-The central puppet server. Functions as a certificate authority by
-default.
-.SH USAGE
-.INDENT 0.0
-.INDENT 3.5
-.INDENT 0.0
-.TP
-.B puppet master [\-D|\-\-daemonize|\-\-no\-daemonize] [\-d|\-\-debug] [\-h|\-\-help]
-.
-[\-l|\-\-logdest <file>|console|syslog] [\-v|\-\-verbose] [\-V|\-\-version]
-.UNINDENT
-.UNINDENT
-.UNINDENT
-.SH DESCRIPTION
-.sp
-This is the puppet central daemon.
-.SH OPTIONS
-.sp
-Note that any configuration parameter that\(aqs valid in the configuration
-file is also a valid long argument. For example, \(aqssldir\(aq is a valid
-configuration parameter, so you can specify \(aq\-\-ssldir <directory>\(aq as an
-argument.
-.sp
-See the configuration file documentation at
-\fI\%http://docs.puppetlabs.com/references/stable/configuration.html\fP for the
-full list of acceptable parameters. A commented list of all
-configuration options can also be generated by running puppetmasterdd
-with \(aq\-\-genconfig\(aq.
-.sp
-daemonize: Send the process into the background. This is the default.
-.sp
-no\-daemonize: Do not send the process into the background.
-.sp
-debug: Enable full debugging.
-.sp
-help: Print this help message.
-.INDENT 0.0
-.TP
-.B logdest: Where to send messages. Choose between syslog, the
-.
-console, and a log file. Defaults to sending messages to
-syslog, or the console if debugging or verbosity is
-enabled.
-.UNINDENT
-.sp
-verbose: Enable verbosity.
-.sp
-version: Print the puppet version number and exit.
-.SH EXAMPLE
-.INDENT 0.0
-.INDENT 3.5
-.sp
-puppet master
-.UNINDENT
-.UNINDENT
-.SH AUTHOR
-.sp
-Luke Kanies
-.SH COPYRIGHT
-.sp
-Copyright (c) 2005 Reductive Labs, LLC Licensed under the GNU Public
-License
-.\" Generated by docutils manpage writer.
-.\"
+.\" generated with Ronn/v0.7.3
+.\" http://github.com/rtomayko/ronn/tree/0.7.3
.
+.TH "PUPPETMASTERD" "8" "August 2010" "" ""
+The central puppet server\. Functions as a certificate authority by default\.puppet master [\-D|\-\-daemonize|\-\-no\-daemonize] [\-d|\-\-debug] [\-h|\-\-help]
+.
+.IP "" 4
+.
+.nf
+
+ [\-l|\-\-logdest <file>|console|syslog] [\-v|\-\-verbose] [\-V|\-\-version]
+.
+.fi
+.
+.IP "" 0
+This is the puppet central daemon\.Note that any configuration parameter that\'s valid in the configuration file is also a valid long argument\. For example, \'ssldir\' is a valid configuration parameter, so you can specify \'\-\-ssldir \fIdirectory\fR\' as an argument\.
+.
+.P
+See the configuration file documentation at http://docs\.puppetlabs\.com/references/stable/configuration\.html for the full list of acceptable parameters\. A commented list of all configuration options can also be generated by running puppetmasterdd with \'\-\-genconfig\'\.
+.
+.P
+daemonize: Send the process into the background\. This is the default\.
+.
+.P
+no\-daemonize: Do not send the process into the background\.
+.
+.P
+debug: Enable full debugging\.
+.
+.P
+help: Print this help message\.
+.
+.P
+logdest: Where to send messages\. Choose between syslog, the
+.
+.IP "" 4
+.
+.nf
+
+ console, and a log file\. Defaults to sending messages to
+ syslog, or the console if debugging or verbosity is
+ enabled\.
+.
+.fi
+.
+.IP "" 0
+.
+.P
+verbose: Enable verbosity\.
+.
+.P
+version: Print the puppet version number and exit\.puppet masterLuke KaniesCopyright (c) 2005 Reductive Labs, LLC Licensed under the GNU Public License
diff --git a/man/man8/puppetqd.8 b/man/man8/puppetqd.8
index db27c664e..137a13af3 100644
--- a/man/man8/puppetqd.8
+++ b/man/man8/puppetqd.8
@@ -1,55 +1,20 @@
-.TH SYNOPSIS "" "" ""
-.SH NAME
-Synopsis \-
-.\" Man page generated from reStructeredText.
+.\" generated with Ronn/v0.7.3
+.\" http://github.com/rtomayko/ronn/tree/0.7.3
.
-.sp
-Retrieve serialized records from a queue and process them in order.
-.SH USAGE
-.INDENT 0.0
-.INDENT 3.5
-.sp
-puppet queue [\-d|\-\-debug] [\-v|\-\-verbose]
-.UNINDENT
-.UNINDENT
-.SH DESCRIPTION
-.sp
-This is a simple application that just processes entities in a queue as
-they are recieved.
-.SH OPTIONS
-.sp
-Note that any configuration parameter that\(aqs valid in the configuration
-file is also a valid long argument. For example, \(aqserver\(aq is a valid
-configuration parameter, so you can specify \(aq\-\-server <servername>\(aq as
-an argument.
-.sp
-See the configuration file documentation at
-\fI\%http://docs.puppetlabs.com/references/stable/configuration.html\fP for the
-full list of acceptable parameters. A commented list of all
-configuration options can also be generated by running puppetd with
-\(aq\-\-genconfig\(aq.
-.sp
-debug: Enable full debugging.
-.sp
-help: Print this help message
-.sp
-verbose: Turn on verbose reporting.
-.sp
-version: Print the puppet version number and exit.
-.SH EXAMPLE
-.INDENT 0.0
-.INDENT 3.5
-.sp
-puppet queue
-.UNINDENT
-.UNINDENT
-.SH AUTHOR
-.sp
-Luke Kanies
-.SH COPYRIGHT
-.sp
-Copyright (c) 2009 Reductive Labs, LLC Licensed under the GNU Public
-License
-.\" Generated by docutils manpage writer.
-.\"
+.TH "PUPPETQD" "8" "August 2010" "" ""
+puppet queue [\-d|\-\-debug] [\-v|\-\-verbose]This is a simple application that just processes entities in a queue as they are recieved\.Note that any configuration parameter that\'s valid in the configuration file is also a valid long argument\. For example, \'server\' is a valid configuration parameter, so you can specify \'\-\-server \fIservername\fR\' as an argument\.
.
+.P
+See the configuration file documentation at http://docs\.puppetlabs\.com/references/stable/configuration\.html for the full list of acceptable parameters\. A commented list of all configuration options can also be generated by running puppetd with \'\-\-genconfig\'\.
+.
+.P
+debug: Enable full debugging\.
+.
+.P
+help: Print this help message
+.
+.P
+verbose: Turn on verbose reporting\.
+.
+.P
+version: Print the puppet version number and exit\.puppet queueLuke KaniesCopyright (c) 2009 Reductive Labs, LLC Licensed under the GNU Public License
diff --git a/man/man8/puppetrun.8 b/man/man8/puppetrun.8
index 9cbc2bd9b..b3c27c3a7 100644
--- a/man/man8/puppetrun.8
+++ b/man/man8/puppetrun.8
@@ -1,153 +1,173 @@
-.TH "" "" ""
-.SH NAME
- \-
-.\" Man page generated from reStructeredText.
-.
-.SH SYNOPSIS
-.sp
-Trigger a puppet agent run on a set of hosts.
-.SH USAGE
-.INDENT 0.0
-.INDENT 3.5
-.INDENT 0.0
-.TP
-.B puppet kick [\-a|\-\-all] [\-c|\-\-class <class>] [\-d|\-\-debug] [\-f|\-\-foreground]
-.
-[\-h|\-\-help] [\-\-host <host>] [\-\-no\-fqdn] [\-\-ignoreschedules]
-[\-t|\-\-tag <tag>] [\-\-test] [\-p|\-\-ping] <host> [<host> [...]]
-.UNINDENT
-.UNINDENT
-.UNINDENT
-.SH DESCRIPTION
-.sp
-This script can be used to connect to a set of machines running +puppet
-agent+ and trigger them to run their configurations. The most common
-usage would be to specify a class of hosts and a set of tags, and
-+puppet kick+ would look up in LDAP all of the hosts matching that
-class, then connect to each host and trigger a run of all of the objects
-with the specified tags.
-.sp
-If you are not storing your host configurations in LDAP, you can specify
-hosts manually.
-.sp
-You will most likely have to run +puppet kick+ as root to get access to
-the SSL certificates.
-.sp
-+puppet kick+ reads +puppet master+\(aqs configuration file, so that it can
-copy things like LDAP settings.
-.SH USAGE NOTES
-.sp
-+puppet kick+ is useless unless +puppet agent+ is listening. See its
-documentation for more information, but the gist is that you must enable
-+listen+ on the +puppet agent+ daemon, either using +\-\-listen+ on the
-command line or adding \(aqlisten: true\(aq in its config file. In addition,
-you need to set the daemons up to specifically allow connections by
-creating the +namespaceauth+ file, normally at
-\(aq/etc/puppet/namespaceauth.conf\(aq. This file specifies who has access to
-each namespace; if you create the file you must add every namespace you
-want any Puppet daemon to allow \-\- it is currently global to all Puppet
-daemons.
-.sp
-An example file looks like this:
-.sp
+.\" generated with Ronn/v0.7.3
+.\" http://github.com/rtomayko/ronn/tree/0.7.3
+.
+.TH "PUPPETRUN" "8" "August 2010" "" ""
+Trigger a puppet agent run on a set of hosts\.puppet kick [\-a|\-\-all] [\-c|\-\-class \fIclass\fR] [\-d|\-\-debug] [\-f|\-\-foreground]
+.
+.IP "" 4
+.
.nf
-.ft C
+
+ [\-h|\-\-help] [\-\-host <host>] [\-\-no\-fqdn] [\-\-ignoreschedules]
+ [\-t|\-\-tag <tag>] [\-\-test] [\-p|\-\-ping] <host> [<host> [\.\.\.]]
+.
+.fi
+.
+.IP "" 0
+This script can be used to connect to a set of machines running +puppet agent+ and trigger them to run their configurations\. The most common usage would be to specify a class of hosts and a set of tags, and +puppet kick+ would look up in LDAP all of the hosts matching that class, then connect to each host and trigger a run of all of the objects with the specified tags\.
+.
+.P
+If you are not storing your host configurations in LDAP, you can specify hosts manually\.
+.
+.P
+You will most likely have to run +puppet kick+ as root to get access to the SSL certificates\.
+.
+.P
++puppet kick+ reads +puppet master+\'s configuration file, so that it can copy things like LDAP settings\.+puppet kick+ is useless unless +puppet agent+ is listening\. See its documentation for more information, but the gist is that you must enable +listen+ on the +puppet agent+ daemon, either using +\-\-listen+ on the command line or adding \'listen: true\' in its config file\. In addition, you need to set the daemons up to specifically allow connections by creating the +namespaceauth+ file, normally at \'/etc/puppet/namespaceauth\.conf\'\. This file specifies who has access to each namespace; if you create the file you must add every namespace you want any Puppet daemon to allow \-\- it is currently global to all Puppet daemons\.
+.
+.P
+An example file looks like this::
+.
+.IP "" 4
+.
+.nf
+
[fileserver]
- allow *.madstop.com
+ allow *\.madstop\.com
[puppetmaster]
- allow *.madstop.com
+ allow *\.madstop\.com
[puppetrunner]
- allow culain.madstop.com
-.ft P
+ allow culain\.madstop\.com
+.
+.fi
+.
+.IP "" 0
+.
+.P
+This is what you would install on your Puppet master; non\-master hosts could leave off the \'fileserver\' and \'puppetmaster\' namespaces\.Note that any configuration parameter that\'s valid in the configuration file is also a valid long argument\. For example, \'ssldir\' is a valid configuration parameter, so you can specify \'\-\-ssldir \fIdirectory\fR\' as an argument\.
+.
+.P
+See the configuration file documentation at http://reductivelabs\.com/projects/puppet/reference/configref\.html for the full list of acceptable parameters\. A commented list of all configuration options can also be generated by running puppet master with \'\-\-genconfig\'\.
+.
+.P
+all: Connect to all available hosts\. Requires LDAP support
+.
+.IP "" 4
+.
+.nf
+
+ at this point\.
+.
+.fi
+.
+.IP "" 0
+.
+.P
+class: Specify a class of machines to which to connect\. This
+.
+.IP "" 4
+.
+.nf
+
+ only works if you have LDAP configured, at the moment\.
+.
+.fi
+.
+.IP "" 0
+.
+.P
+debug: Enable full debugging\.
+.
+.P
+foreground: Run each configuration in the foreground; that is, when
+.
+.IP "" 4
+.
+.nf
+
+ connecting to a host, do not return until the host has
+ finished its run\. The default is false\.
+.
+.fi
+.
+.IP "" 0
+.
+.P
+help: Print this help message
+.
+.P
+host: A specific host to which to connect\. This flag can be
+.
+.IP "" 4
+.
+.nf
+
+ specified more than once\.
+.
+.fi
+.
+.IP "" 0
+.
+.P
+ignoreschedules: Whether the client should ignore schedules when running
+.
+.IP "" 4
+.
+.nf
+
+ its configuration\. This can be used to force the client
+ to perform work it would not normally perform so soon\.
+ The default is false\.
+.
+.fi
+.
+.IP "" 0
+.
+.P
+parallel: How parallel to make the connections\. Parallelization
+.
+.IP "" 4
+.
+.nf
+
+ is provided by forking for each client to which to
+ connect\. The default is 1, meaning serial execution\.
+.
.fi
-.sp
-This is what you would install on your Puppet master; non\-master hosts
-could leave off the \(aqfileserver\(aq and \(aqpuppetmaster\(aq namespaces.
-.sp
-Expect more documentation on this eventually.
-.SH OPTIONS
-.sp
-Note that any configuration parameter that\(aqs valid in the configuration
-file is also a valid long argument. For example, \(aqssldir\(aq is a valid
-configuration parameter, so you can specify \(aq\-\-ssldir <directory>\(aq as an
-argument.
-.sp
-See the configuration file documentation at
-\fI\%http://reductivelabs.com/projects/puppet/reference/configref.html\fP for
-the full list of acceptable parameters. A commented list of all
-configuration options can also be generated by running puppet master
-with \(aq\-\-genconfig\(aq.
-.INDENT 0.0
-.TP
-.B all: Connect to all available hosts. Requires LDAP support
-.
-at this point.
-.TP
-.B class: Specify a class of machines to which to connect. This
-.
-only works if you have LDAP configured, at the moment.
-.UNINDENT
-.sp
-debug: Enable full debugging.
-.INDENT 0.0
-.TP
-.B foreground: Run each configuration in the foreground; that is, when
-.
-connecting to a host, do not return until the host has
-finished its run. The default is false.
-.UNINDENT
-.sp
-help: Print this help message
-.INDENT 0.0
-.TP
-.B host: A specific host to which to connect. This flag can be
-.
-specified more than once.
-.TP
-.B ignoreschedules: Whether the client should ignore schedules when running
-.
-its configuration. This can be used to force the client
-to perform work it would not normally perform so soon.
-The default is false.
-.TP
-.B parallel: How parallel to make the connections. Parallelization
-.
-is provided by forking for each client to which to
-connect. The default is 1, meaning serial execution.
-.TP
-.B tag: Specify a tag for selecting the objects to apply. Does
-.
-not work with the \-\-test option.
-.TP
-.B test: Print the hosts you would connect to but do not
-.
-actually connect. This option requires LDAP support at
-this point.
-.UNINDENT
-.sp
-ping:
-.sp
+.
+.IP "" 0
+.
+.P
+tag: Specify a tag for selecting the objects to apply\. Does
+.
+.IP "" 4
+.
.nf
-.ft C
-Do a ICMP echo against the target host. Skip hosts that don\(aqt respond to ping.
-.ft P
+
+ not work with the \-\-test option\.
+.
.fi
-.SH EXAMPLE
-.INDENT 0.0
-.INDENT 3.5
-.sp
-sudo puppet kick \-p 10 \-t remotefile \-t webserver host1 host2
-.UNINDENT
-.UNINDENT
-.SH AUTHOR
-.sp
-Luke Kanies
-.SH COPYRIGHT
-.sp
-Copyright (c) 2005 Reductive Labs, LLC Licensed under the GNU Public
-License
-.\" Generated by docutils manpage writer.
-.\"
.
+.IP "" 0
+.
+.P
+test: Print the hosts you would connect to but do not
+.
+.IP "" 4
+.
+.nf
+
+ actually connect\. This option requires LDAP support at
+ this point\.
+.
+.fi
+.
+.IP "" 0
+.
+.P
+ping::
+.
+.P
+Do a ICMP echo against the target host\. Skip hosts that don\'t respond to ping\.sudo puppet kick \-p 10 \-t remotefile \-t webserver host1 host2Luke KaniesCopyright (c) 2005 Reductive Labs, LLC Licensed under the GNU Public License
diff --git a/man/man8/ralsh.8 b/man/man8/ralsh.8
index 83494bba5..e387e2324 100644
--- a/man/man8/ralsh.8
+++ b/man/man8/ralsh.8
@@ -1,122 +1,85 @@
-.TH "" "" ""
-.SH NAME
- \-
-.\" Man page generated from reStructeredText.
-.
-.SH SYNOPSIS
-.sp
-Use the Puppet RAL to directly interact with the system.
-.SH USAGE
-.INDENT 0.0
-.INDENT 3.5
-.INDENT 0.0
-.TP
-.B puppet resource [\-h|\-\-help] [\-d|\-\-debug] [\-v|\-\-verbose] [\-e|\-\-edit]
-.
-[\-H|\-\-host <host>] [\-p|\-\-param <param>] [\-t|\-\-types]
-type <name>
-.UNINDENT
-.UNINDENT
-.UNINDENT
-.SH DESCRIPTION
-.sp
-This command provides simple facilities for converting current system
-state into Puppet code, along with some ability to use Puppet to affect
-the current state.
-.sp
-By default, you must at least provide a type to list, which case puppet
-resource will tell you everything it knows about all instances of that
-type. You can optionally specify an instance name, and puppet resource
-will only describe that single instance.
-.sp
-You can also add +\-\-edit+ as an argument, and puppet resource will write
-its output to a file, open that file in an editor, and then apply the
-file as a Puppet transaction. You can easily use this to use Puppet to
-make simple changes to a system.
-.SH OPTIONS
-.sp
-Note that any configuration parameter that\(aqs valid in the configuration
-file is also a valid long argument. For example, \(aqssldir\(aq is a valid
-configuration parameter, so you can specify \(aq\-\-ssldir <directory>\(aq as an
-argument.
-.sp
-See the configuration file documentation at
-\fI\%http://docs.puppetlabs.com/references/stable/configuration.html\fP for the
-full list of acceptable parameters. A commented list of all
-configuration options can also be generated by running puppet with
-\(aq\-\-genconfig\(aq.
-.sp
-debug: Enable full debugging.
-.sp
+.\" generated with Ronn/v0.7.3
+.\" http://github.com/rtomayko/ronn/tree/0.7.3
+.
+.TH "RALSH" "8" "August 2010" "" ""
+Use the Puppet RAL to directly interact with the system\.puppet resource [\-h|\-\-help] [\-d|\-\-debug] [\-v|\-\-verbose] [\-e|\-\-edit]
+.
+.IP "" 4
+.
+.nf
+
+ [\-H|\-\-host <host>] [\-p|\-\-param <param>] [\-t|\-\-types]
+ type <name>
+.
+.fi
+.
+.IP "" 0
+This command provides simple facilities for converting current system state into Puppet code, along with some ability to use Puppet to affect the current state\.
+.
+.P
+By default, you must at least provide a type to list, which case puppet resource will tell you everything it knows about all instances of that type\. You can optionally specify an instance name, and puppet resource will only describe that single instance\.
+.
+.P
+You can also add +\-\-edit+ as an argument, and puppet resource will write its output to a file, open that file in an editor, and then apply the file as a Puppet transaction\. You can easily use this to use Puppet to make simple changes to a system\.Note that any configuration parameter that\'s valid in the configuration file is also a valid long argument\. For example, \'ssldir\' is a valid configuration parameter, so you can specify \'\-\-ssldir \fIdirectory\fR\' as an argument\.
+.
+.P
+See the configuration file documentation at http://docs\.puppetlabs\.com/references/stable/configuration\.html for the full list of acceptable parameters\. A commented list of all configuration options can also be generated by running puppet with \'\-\-genconfig\'\.
+.
+.P
+debug: Enable full debugging\.
+.
+.P
edit:
-.INDENT 0.0
-.INDENT 3.5
-.sp
-Write the results of the query to a file, open the file in an editor,
-and read the file back in as an executable Puppet manifest.
-.UNINDENT
-.UNINDENT
-.sp
+.
+.P
+Write the results of the query to a file, open the file in an editor, and read the file back in as an executable Puppet manifest\.
+.
+.P
host:
-.INDENT 0.0
-.INDENT 3.5
-.sp
-When specified, connect to the resource server on the named host
-and retrieve the list of resouces of the type specified.
-.UNINDENT
-.UNINDENT
-.sp
+.
+.P
+When specified, connect to the resource server on the named host and retrieve the list of resouces of the type specified\.
+.
+.P
help:
-.INDENT 0.0
-.INDENT 3.5
-.sp
-Print this help message.
-.UNINDENT
-.UNINDENT
-.sp
+.
+.P
+Print this help message\.
+.
+.P
param:
-.INDENT 0.0
-.INDENT 3.5
-.sp
-Add more parameters to be outputted from queries.
-.UNINDENT
-.UNINDENT
-.sp
+.
+.P
+Add more parameters to be outputted from queries\.
+.
+.P
types:
-.INDENT 0.0
-.INDENT 3.5
-.sp
-List all available types.
-.UNINDENT
-.UNINDENT
-.sp
-verbose: Print extra information.
-.SH EXAMPLE
-.sp
-This example uses \fBpuppet resource\fP to return Puppet configuration for
-the user \fBluke\fP:
-.sp
+.
+.P
+List all available types\.
+.
+.P
+verbose:
+.
+.P
+Print extra information\.This example uses \fBpuppet resource\fR to return Puppet configuration for the user \fBluke\fR:
+.
+.IP "" 4
+.
.nf
-.ft C
-$ puppet resource user luke
-user { \(aqluke\(aq:
- home => \(aq/home/luke\(aq,
- uid => \(aq100\(aq,
- ensure => \(aqpresent\(aq,
- comment => \(aqLuke Kanies,,,\(aq,
- gid => \(aq1000\(aq,
- shell => \(aq/bin/bash\(aq,
- groups => [\(aqsysadmin\(aq,\(aqaudio\(aq,\(aqvideo\(aq,\(aqpuppet\(aq]
-}
-.ft P
+
+ $ puppet resource user luke
+ user { \'luke\':
+ home => \'/home/luke\',
+ uid => \'100\',
+ ensure => \'present\',
+ comment => \'Luke Kanies,,,\',
+ gid => \'1000\',
+ shell => \'/bin/bash\',
+ groups => [\'sysadmin\',\'audio\',\'video\',\'puppet\']
+ }
+.
.fi
-.SH AUTHOR
-.sp
-Luke Kanies
-.SH COPYRIGHT
-.sp
-Copyright (c) 2005\-2007 Reductive Labs, LLC Licensed under the GNU
-Public License
-.\" Generated by docutils manpage writer.
-.\"
.
+.IP "" 0
+Luke KaniesCopyright (c) 2005\-2007 Reductive Labs, LLC Licensed under the GNU Public License
diff --git a/spec/fixtures/yaml/report0.25.x.yaml b/spec/fixtures/yaml/report0.25.x.yaml
new file mode 100644
index 000000000..ce6a64286
--- /dev/null
+++ b/spec/fixtures/yaml/report0.25.x.yaml
@@ -0,0 +1,64 @@
+--- !ruby/object:Puppet::Transaction::Report
+ host: mattmac.local
+ logs:
+ - !ruby/object:Puppet::Util::Log
+ level: !ruby/sym info
+ message: Applying configuration version '1285283846'
+ source: Puppet
+ tags:
+ - info
+ time: 2010-09-23 16:17:26.977750 -07:00
+ metrics:
+ time: !ruby/object:Puppet::Util::Metric
+ label: Time
+ name: time
+ values:
+ - - !ruby/sym config_retrieval
+ - Config retrieval
+ - 0.955046892166138
+ - - !ruby/sym schedule
+ - Schedule
+ - 0.00123691558837891
+ - - !ruby/sym total
+ - Total
+ - 0.956486701965332
+ - - !ruby/sym filebucket
+ - Filebucket
+ - 0.00020289421081543
+ resources: !ruby/object:Puppet::Util::Metric
+ label: Resources
+ name: resources
+ values:
+ - - !ruby/sym skipped
+ - Skipped
+ - 0
+ - - !ruby/sym scheduled
+ - Scheduled
+ - 7
+ - - !ruby/sym applied
+ - Applied
+ - 0
+ - - !ruby/sym restarted
+ - Restarted
+ - 0
+ - - !ruby/sym total
+ - Total
+ - 10
+ - - !ruby/sym failed_restarts
+ - Failed restarts
+ - 0
+ - - !ruby/sym out_of_sync
+ - Out of sync
+ - 0
+ - - !ruby/sym failed
+ - Failed
+ - 0
+ changes: !ruby/object:Puppet::Util::Metric
+ label: Changes
+ name: changes
+ values:
+ - - !ruby/sym total
+ - Total
+ - 0
+ records: {}
+ time: 2010-09-23 16:17:26.987789 -07:00 \ No newline at end of file
diff --git a/spec/fixtures/yaml/report2.6.x.yaml b/spec/fixtures/yaml/report2.6.x.yaml
new file mode 100644
index 000000000..dd4c3814e
--- /dev/null
+++ b/spec/fixtures/yaml/report2.6.x.yaml
@@ -0,0 +1,190 @@
+--- !ruby/object:Puppet::Transaction::Report
+ external_times:
+ !ruby/sym config_retrieval: 0.170313835144043
+ host: ubuntu1004desktop.localdomain
+ logs:
+ - !ruby/object:Puppet::Util::Log
+ level: !ruby/sym debug
+ message: Using cached certificate for ca
+ source: Puppet
+ tags:
+ - debug
+ time: 2010-09-23 15:44:06.244173 -07:00
+ version: &id001 2.6.1
+ - !ruby/object:Puppet::Util::Log
+ level: !ruby/sym debug
+ message: Using cached certificate for ubuntu1004desktop.localdomain
+ source: Puppet
+ tags:
+ - debug
+ time: 2010-09-23 15:44:06.244764 -07:00
+ version: *id001
+ - !ruby/object:Puppet::Util::Log
+ level: !ruby/sym debug
+ message: Using cached certificate_revocation_list for ca
+ source: Puppet
+ tags:
+ - debug
+ time: 2010-09-23 15:44:06.245677 -07:00
+ version: *id001
+ - !ruby/object:Puppet::Util::Log
+ level: !ruby/sym debug
+ message: "catalog supports formats: b64_zlib_yaml dot marshal pson raw yaml; using pson"
+ source: Puppet
+ tags:
+ - debug
+ time: 2010-09-23 15:44:06.247069 -07:00
+ version: *id001
+ - !ruby/object:Puppet::Util::Log
+ level: !ruby/sym info
+ message: Caching catalog for ubuntu1004desktop.localdomain
+ source: Puppet
+ tags:
+ - info
+ time: 2010-09-23 15:44:06.409109 -07:00
+ version: *id001
+ - !ruby/object:Puppet::Util::Log
+ level: !ruby/sym debug
+ message: Creating default schedules
+ source: Puppet
+ tags:
+ - debug
+ time: 2010-09-23 15:44:06.418755 -07:00
+ version: *id001
+ - !ruby/object:Puppet::Util::Log
+ level: !ruby/sym debug
+ message: Loaded state in 0.00 seconds
+ source: Puppet
+ tags:
+ - debug
+ time: 2010-09-23 15:44:06.427441 -07:00
+ version: *id001
+ - !ruby/object:Puppet::Util::Log
+ level: !ruby/sym info
+ message: Applying configuration version '1285281846'
+ source: Puppet
+ tags:
+ - info
+ time: 2010-09-23 15:44:06.429532 -07:00
+ version: *id001
+ metrics:
+ time: !ruby/object:Puppet::Util::Metric
+ label: Time
+ name: time
+ values:
+ - - config_retrieval
+ - Config retrieval
+ - 0.170313835144043
+ - - schedule
+ - Schedule
+ - 0.00077
+ - - filebucket
+ - Filebucket
+ - 0.000166
+ resources: !ruby/object:Puppet::Util::Metric
+ label: Resources
+ name: resources
+ values:
+ - - !ruby/sym total
+ - Total
+ - 7
+ events: !ruby/object:Puppet::Util::Metric
+ label: Events
+ name: events
+ values:
+ - - !ruby/sym total
+ - Total
+ - 0
+ changes: !ruby/object:Puppet::Util::Metric
+ label: Changes
+ name: changes
+ values:
+ - - !ruby/sym total
+ - Total
+ - 0
+ resource_statuses:
+ "Schedule[monthly]": !ruby/object:Puppet::Resource::Status
+ evaluation_time: 0.000121
+ events: []
+ file:
+ line:
+ resource: "Schedule[monthly]"
+ source_description: "/Schedule[monthly]"
+ tags:
+ - schedule
+ - monthly
+ time: 2010-09-23 15:44:06.430577 -07:00
+ version: 1285281846
+ "Filebucket[puppet]": !ruby/object:Puppet::Resource::Status
+ evaluation_time: 0.000166
+ events: []
+ file:
+ line:
+ resource: "Filebucket[puppet]"
+ source_description: "/Filebucket[puppet]"
+ tags:
+ - filebucket
+ - puppet
+ time: 2010-09-23 15:44:06.430998 -07:00
+ version: 1285281846
+ "Schedule[never]": !ruby/object:Puppet::Resource::Status
+ evaluation_time: 0.000119
+ events: []
+ file:
+ line:
+ resource: "Schedule[never]"
+ source_description: "/Schedule[never]"
+ tags:
+ - schedule
+ - never
+ time: 2010-09-23 15:44:06.433034 -07:00
+ version: 1285281846
+ "Schedule[weekly]": !ruby/object:Puppet::Resource::Status
+ evaluation_time: 0.000118
+ events: []
+ file:
+ line:
+ resource: "Schedule[weekly]"
+ source_description: "/Schedule[weekly]"
+ tags:
+ - schedule
+ - weekly
+ time: 2010-09-23 15:44:06.431443 -07:00
+ version: 1285281846
+ "Schedule[puppet]": !ruby/object:Puppet::Resource::Status
+ evaluation_time: 0.000129
+ events: []
+ file:
+ line:
+ resource: "Schedule[puppet]"
+ source_description: "/Schedule[puppet]"
+ tags:
+ - schedule
+ - puppet
+ time: 2010-09-23 15:44:06.432626 -07:00
+ version: 1285281846
+ "Schedule[daily]": !ruby/object:Puppet::Resource::Status
+ evaluation_time: 0.000154
+ events: []
+ file:
+ line:
+ resource: "Schedule[daily]"
+ source_description: "/Schedule[daily]"
+ tags:
+ - schedule
+ - daily
+ time: 2010-09-23 15:44:06.430130 -07:00
+ version: 1285281846
+ "Schedule[hourly]": !ruby/object:Puppet::Resource::Status
+ evaluation_time: 0.000129
+ events: []
+ file:
+ line:
+ resource: "Schedule[hourly]"
+ source_description: "/Schedule[hourly]"
+ tags:
+ - schedule
+ - hourly
+ time: 2010-09-23 15:44:06.432185 -07:00
+ version: 1285281846
+ time: 2010-09-23 15:44:05.894401 -07:00 \ No newline at end of file
diff --git a/spec/integration/application/doc_spec.rb b/spec/integration/application/doc_spec.rb
new file mode 100644
index 000000000..eaf5442a0
--- /dev/null
+++ b/spec/integration/application/doc_spec.rb
@@ -0,0 +1,55 @@
+#!/usr/bin/env ruby
+
+require File.dirname(__FILE__) + '/../../spec_helper'
+require 'puppet_spec/files'
+
+describe Puppet::Application::Doc do
+ include PuppetSpec::Files
+
+ it "should not generate an error when module dir overlaps parent of site.pp (#4798)" do
+ begin
+ # Note: the directory structure below is more complex than it
+ # needs to be, but it's representative of the directory structure
+ # used in bug #4798.
+ old_dir = Dir.getwd # Note: can't use chdir with a block because it will generate bogus warnings
+ tmpdir = tmpfile('doc_spec')
+ Dir.mkdir(tmpdir)
+ Dir.chdir(tmpdir)
+ site_file = 'site.pp'
+ File.open(site_file, 'w') do |f|
+ f.puts '# A comment'
+ end
+ modules_dir = 'modules'
+ Dir.mkdir(modules_dir)
+ rt_dir = File.join(modules_dir, 'rt')
+ Dir.mkdir(rt_dir)
+ manifests_dir = File.join(rt_dir, 'manifests')
+ Dir.mkdir(manifests_dir)
+ rt_file = File.join(manifests_dir, 'rt.pp')
+ File.open(rt_file, 'w') do |f|
+ f.puts '# A class'
+ f.puts 'class foo { }'
+ f.puts '# A definition'
+ f.puts 'define bar { }'
+ end
+
+ puppet = Puppet::Application[:doc]
+ Puppet[:modulepath] = modules_dir
+ Puppet[:manifest] = site_file
+ puppet.options[:mode] = :rdoc
+ puppet.expects(:exit).with(0)
+ puppet.run_command
+
+ File.should be_exist('doc')
+ ensure
+ Dir.chdir(old_dir)
+ end
+ end
+
+ it "should respect the -o option" do
+ puppetdoc = Puppet::Application[:doc]
+ puppetdoc.command_line.stubs(:args).returns(['foo', '-o', 'bar'])
+ puppetdoc.parse_options
+ puppetdoc.options[:outputdir].should == 'bar'
+ end
+end
diff --git a/spec/integration/configurer_spec.rb b/spec/integration/configurer_spec.rb
index 9a8b66fe4..cb7d3d779 100755
--- a/spec/integration/configurer_spec.rb
+++ b/spec/integration/configurer_spec.rb
@@ -5,6 +5,8 @@ require File.dirname(__FILE__) + '/../spec_helper'
require 'puppet/configurer'
describe Puppet::Configurer do
+ include PuppetSpec::Files
+
describe "when downloading plugins" do
it "should use the :pluginsignore setting, split on whitespace, for ignoring remote files" do
resource = Puppet::Type.type(:notify).new :name => "yay"
@@ -17,19 +19,50 @@ describe Puppet::Configurer do
end
describe "when running" do
- it "should send a transaction report with valid data" do
- catalog = Puppet::Resource::Catalog.new
- catalog.add_resource(Puppet::Type.type(:notify).new(:title => "testing"))
+ before(:each) do
+ @catalog = Puppet::Resource::Catalog.new
+ @catalog.add_resource(Puppet::Type.type(:notify).new(:title => "testing"))
- configurer = Puppet::Configurer.new
+ # Make sure we don't try to persist the local state after the transaction ran,
+ # because it will fail during test (the state file is in an not existing directory)
+ # and we need the transaction to be successful to be able to produce a summary report
+ @catalog.host_config = false
+
+ @configurer = Puppet::Configurer.new
+ end
+
+ it "should send a transaction report with valid data" do
+ @configurer.stubs(:save_last_run_summary)
Puppet::Transaction::Report.indirection.expects(:save).with do |x, report|
report.time.class == Time and report.logs.length > 0
end
Puppet[:report] = true
- configurer.run :catalog => catalog
+ @configurer.run :catalog => @catalog
+ end
+
+ it "should save a correct last run summary" do
+ report = Puppet::Transaction::Report.new
+ report.stubs(:save)
+
+ Puppet[:lastrunfile] = tmpfile("lastrunfile")
+ Puppet[:report] = true
+
+ @configurer.run :catalog => @catalog, :report => report
+
+ summary = nil
+ File.open(Puppet[:lastrunfile], "r") do |fd|
+ summary = YAML.load(fd.read)
+ end
+
+ summary.should be_a(Hash)
+ %w{time changes events resources}.each do |key|
+ summary.should be_key(key)
+ end
+ summary["time"].should be_key("notify")
+ summary["time"]["last_run"].should >= Time.now.tv_sec
end
end
end
diff --git a/spec/integration/defaults_spec.rb b/spec/integration/defaults_spec.rb
index 4ae2983f4..2f30014e8 100755
--- a/spec/integration/defaults_spec.rb
+++ b/spec/integration/defaults_spec.rb
@@ -3,6 +3,7 @@
require File.dirname(__FILE__) + '/../spec_helper'
require 'puppet/defaults'
+require 'puppet/rails'
describe "Puppet defaults" do
include Puppet::Util::Execution
@@ -227,7 +228,7 @@ describe "Puppet defaults" do
it "should have a :caname setting that defaults to the cert name" do
Puppet.settings[:certname] = "foo"
- Puppet.settings[:ca_name].should == "foo"
+ Puppet.settings[:ca_name].should == "Puppet CA: foo"
end
it "should have a 'prerun_command' that defaults to the empty string" do
diff --git a/spec/integration/indirector/bucket_file/rest_spec.rb b/spec/integration/indirector/bucket_file/rest_spec.rb
deleted file mode 100644
index 4d90a8c59..000000000
--- a/spec/integration/indirector/bucket_file/rest_spec.rb
+++ /dev/null
@@ -1,68 +0,0 @@
-#!/usr/bin/env ruby
-
-Dir.chdir(File.dirname(__FILE__)) { (s = lambda { |f| File.exist?(f) ? require(f) : Dir.chdir("..") { s.call(f) } }).call("spec/spec_helper.rb") }
-
-require 'puppet/file_bucket/file'
-require 'puppet/network/server'
-require 'puppet/network/http/webrick/rest'
-
-describe "Filebucket REST Terminus" do
- before do
- Puppet[:masterport] = 34343
- Puppet[:server] = "localhost"
-
- # Get a safe temporary file
- @tmpfile = Tempfile.new("webrick_integration_testing")
- @dir = @tmpfile.path + "_dir"
-
- Puppet.settings[:confdir] = @dir
- Puppet.settings[:vardir] = @dir
- Puppet.settings[:server] = "127.0.0.1"
- Puppet.settings[:masterport] = "34343"
-
- Puppet::Util::Cacher.expire
-
- Puppet[:servertype] = 'webrick'
- Puppet[:server] = '127.0.0.1'
- Puppet[:certname] = '127.0.0.1'
-
- # Generate the certificate with a local CA
- Puppet::SSL::Host.ca_location = :local
- ca = Puppet::SSL::CertificateAuthority.new
- ca.generate(Puppet[:certname]) unless Puppet::SSL::Certificate.find(Puppet[:certname])
- ca.generate("foo.madstop.com") unless Puppet::SSL::Certificate.find(Puppet[:certname])
-
- @host = Puppet::SSL::Host.new(Puppet[:certname])
-
- @params = { :port => 34343, :handlers => [ :file_bucket_file ] }
- @server = Puppet::Network::Server.new(@params)
- @server.listen
-
- @old_terminus = Puppet::FileBucket::File.indirection.terminus_class
- Puppet::FileBucket::File.terminus_class = :rest
-
- # LAK:NOTE We need to have a fake model here so that our indirected methods get
- # passed through REST; otherwise we'd be stubbing 'find', which would cause an immediate
- # return.
- @file_bucket_file = stub_everything 'file_bucket_file'
- @mock_model = stub('faked model', :name => "file_bucket_file", :convert_from => @file_bucket_file)
- Puppet::Indirector::Request.any_instance.stubs(:model).returns(@mock_model)
-
- Puppet::Network::HTTP::WEBrickREST.any_instance.stubs(:check_authorization)
- end
-
- after do
- Puppet::Network::HttpPool.expire
- Puppet::SSL::Host.ca_location = :none
- Puppet.settings.clear
- @server.unlisten
- Puppet::FileBucket::File.terminus_class = @old_terminus
- end
-
- it "should be able save a file to the remote filebucket" do
- @file_bucket_file.expects(:save)
-
- file_bucket_file = Puppet::FileBucket::File.new("pouet")
- file_bucket_file.save
- end
-end
diff --git a/spec/integration/indirector/certificate/rest_spec.rb b/spec/integration/indirector/certificate/rest_spec.rb
deleted file mode 100755
index 356a7d316..000000000
--- a/spec/integration/indirector/certificate/rest_spec.rb
+++ /dev/null
@@ -1,68 +0,0 @@
-#!/usr/bin/env ruby
-
-Dir.chdir(File.dirname(__FILE__)) { (s = lambda { |f| File.exist?(f) ? require(f) : Dir.chdir("..") { s.call(f) } }).call("spec/spec_helper.rb") }
-
-require 'puppet/ssl/certificate'
-require 'puppet/network/server'
-require 'puppet/network/http/webrick/rest'
-
-describe "Certificate REST Terminus" do
- before do
- Puppet[:masterport] = 34343
- Puppet[:server] = "localhost"
-
- # Get a safe temporary file
- @tmpfile = Tempfile.new("webrick_integration_testing")
- @dir = @tmpfile.path + "_dir"
-
- Puppet.settings[:confdir] = @dir
- Puppet.settings[:vardir] = @dir
- Puppet.settings[:server] = "127.0.0.1"
- Puppet.settings[:masterport] = "34343"
-
- Puppet::Util::Cacher.expire
-
- Puppet[:servertype] = 'webrick'
- Puppet[:server] = '127.0.0.1'
- Puppet[:certname] = '127.0.0.1'
-
- # Generate the certificate with a local CA
- Puppet::SSL::Host.ca_location = :local
- ca = Puppet::SSL::CertificateAuthority.new
- ca.generate(Puppet[:certname]) unless Puppet::SSL::Certificate.find(Puppet[:certname])
- ca.generate("foo.madstop.com") unless Puppet::SSL::Certificate.find(Puppet[:certname])
-
- @host = Puppet::SSL::Host.new(Puppet[:certname])
-
- @params = { :port => 34343, :handlers => [ :certificate ] }
- @server = Puppet::Network::Server.new(@params)
- @server.listen
-
- # Then switch to a remote CA, so that we go through REST.
- Puppet::SSL::Host.ca_location = :remote
-
- # LAK:NOTE We need to have a fake model here so that our indirected methods get
- # passed through REST; otherwise we'd be stubbing 'find', which would cause an immediate
- # return.
- @mock_model = stub('faked model', :name => "certificate")
- Puppet::Indirector::Request.any_instance.stubs(:model).returns(@mock_model)
-
- Puppet::Network::HTTP::WEBrickREST.any_instance.stubs(:check_authorization).returns(true)
- end
-
- after do
- Puppet::Network::HttpPool.expire
- Puppet::SSL::Host.ca_location = :none
- Puppet.settings.clear
- @server.unlisten
- end
-
- it "should be able to retrieve a remote certificate" do
- @mock_model.expects(:find).returns @host.certificate
- result = Puppet::SSL::Certificate.find('bar')
-
- # There's no good '==' method on certs.
- result.content.to_s.should == @host.certificate.content.to_s
- result.name.should == "bar"
- end
-end
diff --git a/spec/integration/indirector/certificate_request/rest_spec.rb b/spec/integration/indirector/certificate_request/rest_spec.rb
deleted file mode 100755
index 2c98ef66c..000000000
--- a/spec/integration/indirector/certificate_request/rest_spec.rb
+++ /dev/null
@@ -1,88 +0,0 @@
-#!/usr/bin/env ruby
-
-Dir.chdir(File.dirname(__FILE__)) { (s = lambda { |f| File.exist?(f) ? require(f) : Dir.chdir("..") { s.call(f) } }).call("spec/spec_helper.rb") }
-
-require 'puppet/ssl/certificate_request'
-require 'puppet/network/server'
-require 'puppet/network/http/webrick/rest'
-
-describe "Certificate Request REST Terminus" do
- before do
- Puppet::Util::Cacher.expire
-
- Puppet[:masterport] = 34343
- Puppet[:server] = "localhost"
-
- # Get a safe temporary file
- @tmpfile = Tempfile.new("webrick_integration_testing")
- @dir = @tmpfile.path + "_dir"
-
- Puppet.settings[:confdir] = @dir
- Puppet.settings[:vardir] = @dir
- Puppet.settings[:server] = "127.0.0.1"
- Puppet.settings[:masterport] = "34343"
-
- Puppet[:servertype] = 'webrick'
- Puppet[:server] = '127.0.0.1'
- Puppet[:certname] = '127.0.0.1'
-
- # Generate the certificate with a local CA
- Puppet::SSL::Host.ca_location = :local
- ca = Puppet::SSL::CertificateAuthority.new
- ca.generate(Puppet[:certname]) unless Puppet::SSL::Certificate.find(Puppet[:certname])
-
- # Create the CSR and write it to disk
- @host = Puppet::SSL::Host.new("foo.madstop.com")
- @host.generate_certificate_request
-
- # Now remove the cached csr
- Puppet::SSL::Host.ca_location = :none
- Puppet::SSL::Host.destroy("foo.madstop.com")
-
- @params = { :port => 34343, :handlers => [ :certificate_request ] }
- @server = Puppet::Network::Server.new(@params)
- @server.listen
-
- # Then switch to a remote CA, so that we go through REST.
- Puppet::SSL::Host.ca_location = :remote
-
- # LAK:NOTE We need to have a fake model here so that our indirected methods get
- # passed through REST; otherwise we'd be stubbing 'find', which would cause an immediate
- # return.
- @mock_model = stub('faked model', :name => "certificate request")
- Puppet::Indirector::Request.any_instance.stubs(:model).returns(@mock_model)
-
- Puppet::Network::HTTP::WEBrickREST.any_instance.stubs(:check_authorization).returns(true)
- end
-
- after do
- Puppet::Network::HttpPool.expire
- Puppet::SSL::Host.ca_location = :none
- Puppet.settings.clear
- @server.unlisten
- end
-
- it "should be able to save a certificate request to the CA" do
- key = Puppet::SSL::Key.new("bar.madstop.com")
- key.generate
-
- csr = Puppet::SSL::CertificateRequest.new("bar.madstop.com")
- csr.generate(key.content)
-
- server_csr = mock 'csr'
- server_csr.expects(:save)
- @mock_model.expects(:convert_from).with("s", csr.content.to_s).returns server_csr
-
- csr.save
- end
-
- it "should be able to retrieve a remote certificate request" do
- # We're finding the cached value :/
- @mock_model.expects(:find).returns @host.certificate_request
- result = Puppet::SSL::CertificateRequest.find('foo.madstop.com')
-
- # There's no good '==' method on certs.
- result.content.to_s.should == @host.certificate_request.content.to_s
- result.name.should == @host.certificate_request.name
- end
-end
diff --git a/spec/integration/indirector/certificate_revocation_list/rest_spec.rb b/spec/integration/indirector/certificate_revocation_list/rest_spec.rb
deleted file mode 100755
index 62a2f808e..000000000
--- a/spec/integration/indirector/certificate_revocation_list/rest_spec.rb
+++ /dev/null
@@ -1,76 +0,0 @@
-#!/usr/bin/env ruby
-
-Dir.chdir(File.dirname(__FILE__)) { (s = lambda { |f| File.exist?(f) ? require(f) : Dir.chdir("..") { s.call(f) } }).call("spec/spec_helper.rb") }
-
-require 'puppet/ssl/certificate'
-require 'puppet/network/server'
-require 'puppet/network/http/webrick/rest'
-
-describe "Certificate REST Terminus" do
- before do
- Puppet[:masterport] = 34343
- Puppet[:server] = "localhost"
-
- # Get a safe temporary file
- @tmpfile = Tempfile.new("webrick_integration_testing")
- @dir = @tmpfile.path + "_dir"
-
- Puppet.settings[:confdir] = @dir
- Puppet.settings[:vardir] = @dir
- Puppet.settings[:server] = "127.0.0.1"
- Puppet.settings[:masterport] = "34343"
-
- Puppet::Util::Cacher.expire
-
- Puppet[:servertype] = 'webrick'
- Puppet[:server] = '127.0.0.1'
- Puppet[:certname] = '127.0.0.1'
-
- # Generate the certificate with a local CA
- Puppet::SSL::Host.ca_location = :local
- ca = Puppet::SSL::CertificateAuthority.new
- ca.generate(Puppet[:certname]) unless Puppet::SSL::Certificate.find(Puppet[:certname])
-
- @params = { :port => 34343, :handlers => [ :certificate_revocation_list ] }
- @server = Puppet::Network::Server.new(@params)
- @server.listen
-
- # And make sure we've generated the CRL
- @crl = ca.crl
-
- # Now remove the cached crl
- Puppet::SSL::Host.ca_location = :none
- Puppet::SSL::CertificateRevocationList.destroy(Puppet::SSL::CA_NAME)
-
- # This is necessary so that we create the SSL store before we start
- # using REST. This is necessary to prevent an infinite loop,
- # which only occurs during testing.
- Puppet::Network::HttpPool.ssl_host.ssl_store
-
- # Then switch to a remote CA, so that we go through REST.
- Puppet::SSL::Host.ca_location = :remote
-
- # LAK:NOTE We need to have a fake model here so that our indirected methods get
- # passed through REST; otherwise we'd be stubbing 'find', which would cause an immediate
- # return.
- @mock_model = stub('faked model', :name => "certificate")
- Puppet::Indirector::Request.any_instance.stubs(:model).returns(@mock_model)
-
- Puppet::Network::HTTP::WEBrickREST.any_instance.stubs(:check_authorization).returns(true)
- end
-
- after do
- Puppet::Network::HttpPool.expire
- Puppet::SSL::Host.ca_location = :none
- Puppet.settings.clear
- @server.unlisten
- end
-
- it "should be able to retrieve a remote CRL" do
- @mock_model.expects(:find).returns @crl
- result = Puppet::SSL::CertificateRevocationList.find('bar')
-
- # There's no good '==' method on certs.
- result.content.to_s.should == @crl.content.to_s
- end
-end
diff --git a/spec/integration/indirector/report/rest_spec.rb b/spec/integration/indirector/report/rest_spec.rb
deleted file mode 100644
index 089f8fd3f..000000000
--- a/spec/integration/indirector/report/rest_spec.rb
+++ /dev/null
@@ -1,96 +0,0 @@
-#!/usr/bin/env ruby
-
-Dir.chdir(File.dirname(__FILE__)) { (s = lambda { |f| File.exist?(f) ? require(f) : Dir.chdir("..") { s.call(f) } }).call("spec/spec_helper.rb") }
-
-require 'puppet/transaction/report'
-require 'puppet/network/server'
-require 'puppet/network/http/webrick/rest'
-
-describe "Report REST Terminus" do
- before do
- Puppet[:masterport] = 34343
- Puppet[:server] = "localhost"
-
- # Get a safe temporary file
- @tmpfile = Tempfile.new("webrick_integration_testing")
- @dir = @tmpfile.path + "_dir"
-
- Puppet.settings[:confdir] = @dir
- Puppet.settings[:vardir] = @dir
- Puppet.settings[:server] = "127.0.0.1"
- Puppet.settings[:masterport] = "34343"
-
- Puppet::Util::Cacher.expire
-
- Puppet[:servertype] = 'webrick'
- Puppet[:server] = '127.0.0.1'
- Puppet[:certname] = '127.0.0.1'
-
- # Generate the certificate with a local CA
- Puppet::SSL::Host.ca_location = :local
- ca = Puppet::SSL::CertificateAuthority.new
- ca.generate(Puppet[:certname]) unless Puppet::SSL::Certificate.find(Puppet[:certname])
- ca.generate("foo.madstop.com") unless Puppet::SSL::Certificate.find(Puppet[:certname])
-
- @host = Puppet::SSL::Host.new(Puppet[:certname])
-
- @params = { :port => 34343, :handlers => [ :report ] }
- @server = Puppet::Network::Server.new(@params)
- @server.listen
-
- # Let's use REST for our reports :-)
- @old_terminus = Puppet::Transaction::Report.indirection.terminus_class
- Puppet::Transaction::Report.terminus_class = :rest
-
- # LAK:NOTE We need to have a fake model here so that our indirected methods get
- # passed through REST; otherwise we'd be stubbing 'save', which would cause an immediate
- # return.
- @report = stub_everything 'report'
- @mock_model = stub_everything 'faked model', :name => "report", :convert_from => @report
- Puppet::Indirector::Request.any_instance.stubs(:model).returns(@mock_model)
-
- Puppet::Network::HTTP::WEBrickREST.any_instance.stubs(:check_authorization)
- end
-
- after do
- Puppet::Network::HttpPool.expire
- Puppet::SSL::Host.ca_location = :none
- Puppet.settings.clear
- @server.unlisten
- Puppet::Transaction::Report.terminus_class = @old_terminus
- end
-
- it "should be able to send a report to the server" do
- @report.expects(:save)
-
- report = Puppet::Transaction::Report.new
-
- resourcemetrics = {
- :total => 12,
- :out_of_sync => 20,
- :applied => 45,
- :skipped => 1,
- :restarted => 23,
- :failed_restarts => 1,
- :scheduled => 10
- }
- report.add_metric(:resources, resourcemetrics)
-
- timemetrics = {
- :resource1 => 10,
- :resource2 => 50,
- :resource3 => 40,
- :resource4 => 20,
- }
- report.add_metric(:times, timemetrics)
-
-
- report.add_metric(
- :changes,
-
- :total => 20
- )
-
- report.save
- end
-end
diff --git a/spec/integration/indirector/rest_spec.rb b/spec/integration/indirector/rest_spec.rb
deleted file mode 100755
index e9048392a..000000000
--- a/spec/integration/indirector/rest_spec.rb
+++ /dev/null
@@ -1,524 +0,0 @@
-#!/usr/bin/env ruby
-
-require File.dirname(__FILE__) + '/../../spec_helper'
-require 'puppet/network/server'
-require 'puppet/indirector'
-require 'puppet/indirector/rest'
-
-# a fake class that will be indirected via REST
-class Puppet::TestIndirectedFoo
- extend Puppet::Indirector
- indirects :test_indirected_foo, :terminus_setting => :test_indirected_foo_terminus
-
- attr_reader :value
- attr_accessor :name
-
- def initialize(value = 0)
- @value = value
- end
-
- def self.from_yaml(yaml)
- YAML.load(yaml)
- end
-
- def name
- "bob"
- end
-end
-
-# empty Terminus class -- this would normally have to be in a directory findable by the autoloader, but we short-circuit that below
-class Puppet::TestIndirectedFoo::Rest < Puppet::Indirector::REST
-end
-
-
-describe Puppet::Indirector::REST do
- before do
- # Get a safe temporary file
- @tmpfile = Tempfile.new("webrick_integration_testing")
- @dir = @tmpfile.path + "_dir"
-
- Puppet.settings[:confdir] = @dir
- Puppet.settings[:vardir] = @dir
- Puppet.settings[:server] = "127.0.0.1"
- Puppet.settings[:masterport] = "34343"
-
- Puppet::SSL::Host.ca_location = :local
-
- Puppet::TestIndirectedFoo.terminus_class = :rest
- end
-
- after do
- Puppet::Network::HttpPool.expire
- Puppet::SSL::Host.ca_location = :none
- Puppet.settings.clear
- end
-
- describe "when using webrick" do
- before :each do
- Puppet::Util::Cacher.expire
-
- Puppet[:servertype] = 'webrick'
- Puppet[:server] = '127.0.0.1'
- Puppet[:certname] = '127.0.0.1'
-
- ca = Puppet::SSL::CertificateAuthority.new
- ca.generate(Puppet[:certname]) unless Puppet::SSL::Certificate.find(Puppet[:certname])
-
- @params = { :port => 34343, :handlers => [ :test_indirected_foo ], :xmlrpc_handlers => [ :status ] }
- @server = Puppet::Network::Server.new(@params)
- @server.listen
-
- # LAK:NOTE We need to have a fake model here so that our indirected methods get
- # passed through REST; otherwise we'd be stubbing 'find', which would cause an immediate
- # return.
- @mock_model = stub('faked model', :name => "foo")
- Puppet::Indirector::Request.any_instance.stubs(:model).returns(@mock_model)
-
- # do not trigger the authorization layer
- Puppet::Network::HTTP::WEBrickREST.any_instance.stubs(:check_authorization).returns(true)
- end
-
- describe "when finding a model instance over REST" do
- describe "when a matching model instance can be found" do
- before :each do
- @model_instance = Puppet::TestIndirectedFoo.new(23)
- @mock_model.stubs(:find).returns @model_instance
- end
-
- it "should not fail" do
- lambda { Puppet::TestIndirectedFoo.find('bar') }.should_not raise_error
- end
-
- it 'should return an instance of the model class' do
- Puppet::TestIndirectedFoo.find('bar').class.should == Puppet::TestIndirectedFoo
- end
-
- it "should pass options all the way through" do
- @mock_model.expects(:find).with { |key, args| args[:one] == "two" and args[:three] == "four" }.returns @model_instance
- Puppet::TestIndirectedFoo.find('bar', :one => "two", :three => "four")
- end
-
- it 'should return the instance of the model class associated with the provided lookup key' do
- Puppet::TestIndirectedFoo.find('bar').value.should == @model_instance.value
- end
-
- it 'should set an expiration on model instance' do
- Puppet::TestIndirectedFoo.find('bar').expiration.should_not be_nil
- end
-
- it "should use a supported format" do
- Puppet::TestIndirectedFoo.expects(:supported_formats).returns ["marshal"]
- text = Marshal.dump(@model_instance)
- @model_instance.expects(:render).with(Puppet::Network::FormatHandler.format("marshal")).returns text
- Puppet::TestIndirectedFoo.find('bar')
- end
- end
-
- describe "when no matching model instance can be found" do
- before :each do
- @mock_model = stub('faked model', :name => "foo", :find => nil)
- Puppet::Indirector::Request.any_instance.stubs(:model).returns(@mock_model)
- end
-
- it "should return nil" do
- Puppet::TestIndirectedFoo.find('bar').should be_nil
- end
- end
-
- describe "when an exception is encountered in looking up a model instance" do
- before :each do
- @mock_model = stub('faked model', :name => "foo")
- @mock_model.stubs(:find).raises(RuntimeError)
- Puppet::Indirector::Request.any_instance.stubs(:model).returns(@mock_model)
- end
-
- it "should raise an exception" do
- lambda { Puppet::TestIndirectedFoo.find('bar') }.should raise_error(Net::HTTPError)
- end
- end
- end
-
- describe "when searching for model instances over REST" do
- describe "when matching model instances can be found" do
- before :each do
- @model_instances = [ Puppet::TestIndirectedFoo.new(23), Puppet::TestIndirectedFoo.new(24) ]
- @mock_model.stubs(:search).returns @model_instances
-
- # Force yaml, because otherwise our mocks can't work correctly
- Puppet::TestIndirectedFoo.stubs(:supported_formats).returns %w{yaml}
-
- @mock_model.stubs(:render_multiple).returns @model_instances.to_yaml
- end
-
- it "should not fail" do
- lambda { Puppet::TestIndirectedFoo.search('bar') }.should_not raise_error
- end
-
- it 'should return all matching results' do
- Puppet::TestIndirectedFoo.search('bar').length.should == @model_instances.length
- end
-
- it "should pass options all the way through" do
- @mock_model.expects(:search).with { |key, args| args[:one] == "two" and args[:three] == "four" }.returns @model_instances
- Puppet::TestIndirectedFoo.search("foo", :one => "two", :three => "four")
- end
-
- it 'should return model instances' do
- Puppet::TestIndirectedFoo.search('bar').each do |result|
- result.class.should == Puppet::TestIndirectedFoo
- end
- end
-
- it 'should return the instance of the model class associated with the provided lookup key' do
- Puppet::TestIndirectedFoo.search('bar').collect { |i| i.value }.should == @model_instances.collect { |i| i.value }
- end
- end
-
- describe "when no matching model instance can be found" do
- before :each do
- @mock_model = stub('faked model', :name => "foo", :find => nil)
- Puppet::Indirector::Request.any_instance.stubs(:model).returns(@mock_model)
- end
-
- it "should return nil" do
- Puppet::TestIndirectedFoo.find('bar').should be_nil
- end
- end
-
- describe "when an exception is encountered in looking up a model instance" do
- before :each do
- @mock_model = stub('faked model')
- @mock_model.stubs(:find).raises(RuntimeError)
- Puppet::Indirector::Request.any_instance.stubs(:model).returns(@mock_model)
- end
-
- it "should raise an exception" do
- lambda { Puppet::TestIndirectedFoo.find('bar') }.should raise_error(Net::HTTPError)
- end
- end
- end
-
- describe "when destroying a model instance over REST" do
- describe "when a matching model instance can be found" do
- before :each do
- @mock_model.stubs(:destroy).returns true
- end
-
- it "should not fail" do
- lambda { Puppet::TestIndirectedFoo.destroy('bar') }.should_not raise_error
- end
-
- it 'should return success' do
- Puppet::TestIndirectedFoo.destroy('bar').should == true
- end
- end
-
- describe "when no matching model instance can be found" do
- before :each do
- @mock_model.stubs(:destroy).returns false
- end
-
- it "should return failure" do
- Puppet::TestIndirectedFoo.destroy('bar').should == false
- end
- end
-
- describe "when an exception is encountered in destroying a model instance" do
- before :each do
- @mock_model.stubs(:destroy).raises(RuntimeError)
- end
-
- it "should raise an exception" do
- lambda { Puppet::TestIndirectedFoo.destroy('bar') }.should raise_error(Net::HTTPError)
- end
- end
- end
-
- describe "when saving a model instance over REST" do
- before :each do
- @instance = Puppet::TestIndirectedFoo.new(42)
- @mock_model.stubs(:save_object).returns @instance
- @mock_model.stubs(:convert_from).returns @instance
- Puppet::Network::HTTP::WEBrickREST.any_instance.stubs(:save_object).returns(@instance)
- end
-
- describe "when a successful save can be performed" do
- before :each do
- end
-
- it "should not fail" do
- lambda { @instance.save }.should_not raise_error
- end
-
- it 'should return an instance of the model class' do
- @instance.save.class.should == Puppet::TestIndirectedFoo
- end
-
- it 'should return a matching instance of the model class' do
- @instance.save.value.should == @instance.value
- end
- end
-
- describe "when a save cannot be completed" do
- before :each do
- Puppet::Network::HTTP::WEBrickREST.any_instance.stubs(:save_object).returns(false)
- end
-
- it "should return failure" do
- @instance.save.should == false
- end
- end
-
- describe "when an exception is encountered in performing a save" do
- before :each do
- Puppet::Network::HTTP::WEBrickREST.any_instance.stubs(:save_object).raises(RuntimeError)
- end
-
- it "should raise an exception" do
- lambda { @instance.save }.should raise_error(Net::HTTPError)
- end
- end
- end
-
- after :each do
- @server.unlisten
- end
- end
-
- describe "when using mongrel" do
- confine "Mongrel is not available" => Puppet.features.mongrel?
-
- before :each do
- Puppet[:servertype] = 'mongrel'
- @params = { :port => 34343, :handlers => [ :test_indirected_foo ] }
-
- # Make sure we never get a cert, since mongrel can't speak ssl
- Puppet::SSL::Certificate.stubs(:find).returns nil
-
- # We stub ssl to be off, since mongrel can't speak ssl
- Net::HTTP.any_instance.stubs(:use_ssl?).returns false
-
- @server = Puppet::Network::Server.new(@params)
- @server.listen
-
- # LAK:NOTE We need to have a fake model here so that our indirected methods get
- # passed through REST; otherwise we'd be stubbing 'find', which would cause an immediate
- # return.
- @mock_model = stub('faked model', :name => "foo")
- Puppet::Indirector::Request.any_instance.stubs(:model).returns(@mock_model)
-
- # do not trigger the authorization layer
- Puppet::Network::HTTP::MongrelREST.any_instance.stubs(:check_authorization).returns(true)
- end
-
- after do
- @server.unlisten
- end
-
- describe "when finding a model instance over REST" do
- describe "when a matching model instance can be found" do
- before :each do
- @model_instance = Puppet::TestIndirectedFoo.new(23)
- @mock_model.stubs(:find).returns @model_instance
- end
-
- it "should not fail" do
- lambda { Puppet::TestIndirectedFoo.find('bar') }.should_not raise_error
- end
-
- it 'should return an instance of the model class' do
- Puppet::TestIndirectedFoo.find('bar').class.should == Puppet::TestIndirectedFoo
- end
-
- it "should pass options all the way through" do
- @mock_model.expects(:find).with { |key, args| args[:one] == "two" and args[:three] == "four" }.returns @model_instance
- Puppet::TestIndirectedFoo.find('bar', :one => "two", :three => "four")
- end
-
- it 'should return the instance of the model class associated with the provided lookup key' do
- Puppet::TestIndirectedFoo.find('bar').value.should == @model_instance.value
- end
-
- it 'should set an expiration on model instance' do
- Puppet::TestIndirectedFoo.find('bar').expiration.should_not be_nil
- end
-
- it "should use a supported format" do
- Puppet::TestIndirectedFoo.expects(:supported_formats).returns ["marshal"]
- format = stub 'format'
- text = Marshal.dump(@model_instance)
- @model_instance.expects(:render).with(Puppet::Network::FormatHandler.format("marshal")).returns text
- Puppet::TestIndirectedFoo.find('bar')
- end
- end
-
- describe "when no matching model instance can be found" do
- before :each do
- @mock_model.stubs(:find).returns nil
- end
-
- it "should return nil" do
- Puppet::TestIndirectedFoo.find('bar').should be_nil
- end
- end
-
- describe "when an exception is encountered in looking up a model instance" do
- before :each do
- @mock_model.stubs(:find).raises(RuntimeError)
- end
-
- it "should raise an exception" do
- lambda { Puppet::TestIndirectedFoo.find('bar') }.should raise_error(Net::HTTPError)
- end
- end
- end
-
- describe "when searching for model instances over REST" do
- describe "when matching model instances can be found" do
- before :each do
- @model_instances = [ Puppet::TestIndirectedFoo.new(23), Puppet::TestIndirectedFoo.new(24) ]
-
- # Force yaml, because otherwise our mocks can't work correctly
- Puppet::TestIndirectedFoo.stubs(:supported_formats).returns %w{yaml}
-
- @mock_model.stubs(:search).returns @model_instances
- @mock_model.stubs(:render_multiple).returns @model_instances.to_yaml
- end
-
- it "should not fail" do
- lambda { Puppet::TestIndirectedFoo.search('bar') }.should_not raise_error
- end
-
- it 'should return all matching results' do
- Puppet::TestIndirectedFoo.search('bar').length.should == @model_instances.length
- end
-
- it "should pass options all the way through" do
- @mock_model.expects(:search).with { |key, args| args[:one] == "two" and args[:three] == "four" }.returns @model_instances
- Puppet::TestIndirectedFoo.search('bar', :one => "two", :three => "four")
- end
-
- it 'should return model instances' do
- Puppet::TestIndirectedFoo.search('bar').each do |result|
- result.class.should == Puppet::TestIndirectedFoo
- end
- end
-
- it 'should return the instance of the model class associated with the provided lookup key' do
- Puppet::TestIndirectedFoo.search('bar').collect { |i| i.value }.should == @model_instances.collect { |i| i.value }
- end
-
- it 'should set an expiration on model instances' do
- Puppet::TestIndirectedFoo.search('bar').each do |result|
- result.expiration.should_not be_nil
- end
- end
- end
-
- describe "when no matching model instance can be found" do
- before :each do
- @mock_model.stubs(:search).returns nil
- @mock_model.stubs(:render_multiple).returns nil.to_yaml
- end
-
- it "should return nil" do
- Puppet::TestIndirectedFoo.search('bar').should == []
- end
- end
-
- describe "when an exception is encountered in looking up a model instance" do
- before :each do
- @mock_model.stubs(:find).raises(RuntimeError)
- end
-
- it "should raise an exception" do
- lambda { Puppet::TestIndirectedFoo.find('bar') }.should raise_error(Net::HTTPError)
- end
- end
- end
-
- describe "when destroying a model instance over REST" do
- describe "when a matching model instance can be found" do
- before :each do
- @mock_model.stubs(:destroy).returns true
- end
-
- it "should not fail" do
- lambda { Puppet::TestIndirectedFoo.destroy('bar') }.should_not raise_error
- end
-
- it 'should return success' do
- Puppet::TestIndirectedFoo.destroy('bar').should == true
- end
- end
-
- describe "when no matching model instance can be found" do
- before :each do
- @mock_model.stubs(:destroy).returns false
- end
-
- it "should return failure" do
- Puppet::TestIndirectedFoo.destroy('bar').should == false
- end
- end
-
- describe "when an exception is encountered in destroying a model instance" do
- before :each do
- @mock_model.stubs(:destroy).raises(RuntimeError)
- end
-
- it "should raise an exception" do
- lambda { Puppet::TestIndirectedFoo.destroy('bar') }.should raise_error(Net::HTTPError)
- end
- end
- end
-
- describe "when saving a model instance over REST" do
- before :each do
- @instance = Puppet::TestIndirectedFoo.new(42)
- @mock_model.stubs(:convert_from).returns @instance
-
- # LAK:NOTE This stub is necessary to prevent the REST call from calling
- # REST.save again, thus producing painful infinite recursion.
- Puppet::Network::HTTP::MongrelREST.any_instance.stubs(:save_object).returns(@instance)
- end
-
- describe "when a successful save can be performed" do
- before :each do
- end
-
- it "should not fail" do
- lambda { @instance.save }.should_not raise_error
- end
-
- it 'should return an instance of the model class' do
- @instance.save.class.should == Puppet::TestIndirectedFoo
- end
-
- it 'should return a matching instance of the model class' do
- @instance.save.value.should == @instance.value
- end
- end
-
- describe "when a save cannot be completed" do
- before :each do
- Puppet::Network::HTTP::MongrelREST.any_instance.stubs(:save_object).returns(false)
- end
-
- it "should return failure" do
- @instance.save.should == false
- end
- end
-
- describe "when an exception is encountered in performing a save" do
- before :each do
- Puppet::Network::HTTP::MongrelREST.any_instance.stubs(:save_object).raises(RuntimeError)
- end
-
- it "should raise an exception" do
- lambda { @instance.save }.should raise_error(Net::HTTPError)
- end
- end
- end
- end
-end
diff --git a/spec/integration/network/server/webrick_spec.rb b/spec/integration/network/server/webrick_spec.rb
index 2809df780..2b14dfb37 100755
--- a/spec/integration/network/server/webrick_spec.rb
+++ b/spec/integration/network/server/webrick_spec.rb
@@ -18,6 +18,7 @@ describe Puppet::Network::Server do
Puppet.settings[:confdir] = @dir
Puppet.settings[:vardir] = @dir
+ Puppet.settings[:group] = Process.gid
Puppet::SSL::Host.ca_location = :local
diff --git a/spec/integration/parser/collector_spec.rb b/spec/integration/parser/collector_spec.rb
index 73273c909..b1cfc51c7 100755
--- a/spec/integration/parser/collector_spec.rb
+++ b/spec/integration/parser/collector_spec.rb
@@ -17,7 +17,7 @@ describe Puppet::Parser::Collector do
def query(text)
code = "File <| #{text} |>"
parser = Puppet::Parser::Parser.new(@scope.compiler)
- parser.parse(code).hostclass("").code[0].query
+ return parser.parse(code).code[0].query
end
{true => [%{title == "/tmp/testing"}, %{(title == "/tmp/testing")}, %{group == bin},
diff --git a/spec/integration/parser/compiler_spec.rb b/spec/integration/parser/compiler_spec.rb
index 83bbf9500..f731692b3 100755
--- a/spec/integration/parser/compiler_spec.rb
+++ b/spec/integration/parser/compiler_spec.rb
@@ -26,4 +26,109 @@ describe Puppet::Parser::Compiler do
@compiler.catalog.version.should == version
end
+
+ it "should not create duplicate resources when a class is referenced both directly and indirectly by the node classifier (4792)" do
+ Puppet[:code] = <<-PP
+ class foo
+ {
+ notify { foo_notify: }
+ include bar
+ }
+ class bar
+ {
+ notify { bar_notify: }
+ }
+ PP
+
+ @node.stubs(:classes).returns(['foo', 'bar'])
+
+ catalog = Puppet::Parser::Compiler.compile(@node)
+
+ catalog.resource("Notify[foo_notify]").should_not be_nil
+ catalog.resource("Notify[bar_notify]").should_not be_nil
+ end
+
+ describe "when resolving class references" do
+ it "should favor local scope, even if there's an included class in topscope" do
+ Puppet[:code] = <<-PP
+ class experiment {
+ class baz {
+ }
+ notify {"x" : require => Class[Baz] }
+ }
+ class baz {
+ }
+ include baz
+ include experiment
+ include experiment::baz
+ PP
+
+ catalog = Puppet::Parser::Compiler.compile(Puppet::Node.new("mynode"))
+
+ notify_resource = catalog.resource( "Notify[x]" )
+
+ notify_resource[:require].title.should == "Experiment::Baz"
+ end
+
+ it "should favor local scope, even if there's an unincluded class in topscope" do
+ Puppet[:code] = <<-PP
+ class experiment {
+ class baz {
+ }
+ notify {"x" : require => Class[Baz] }
+ }
+ class baz {
+ }
+ include experiment
+ include experiment::baz
+ PP
+
+ catalog = Puppet::Parser::Compiler.compile(Puppet::Node.new("mynode"))
+
+ notify_resource = catalog.resource( "Notify[x]" )
+
+ notify_resource[:require].title.should == "Experiment::Baz"
+ end
+ end
+
+ it "should recompute the version after input files are re-parsed" do
+ Puppet[:code] = 'class foo { }'
+ Time.stubs(:now).returns(1)
+ node = Puppet::Node.new('mynode')
+ Puppet::Parser::Compiler.compile(node).version.should == 1
+ Time.stubs(:now).returns(2)
+ Puppet::Parser::Compiler.compile(node).version.should == 1 # no change because files didn't change
+ Puppet::Resource::TypeCollection.any_instance.stubs(:stale?).returns(true).then.returns(false) # pretend change
+ Puppet::Parser::Compiler.compile(node).version.should == 2
+ end
+
+ ['class', 'define', 'node'].each do |thing|
+ it "should not allow #{thing} inside evaluated conditional constructs" do
+ Puppet[:code] = <<-PP
+ if true {
+ #{thing} foo {
+ }
+ notify { decoy: }
+ }
+ PP
+
+ begin
+ Puppet::Parser::Compiler.compile(Puppet::Node.new("mynode"))
+ raise "compilation should have raised Puppet::Error"
+ rescue Puppet::Error => e
+ e.message.should =~ /at line 2/
+ end
+ end
+ end
+
+ it "should not allow classes inside unevaluated conditional constructs" do
+ Puppet[:code] = <<-PP
+ if false {
+ class foo {
+ }
+ }
+ PP
+
+ lambda { Puppet::Parser::Compiler.compile(Puppet::Node.new("mynode")) }.should raise_error(Puppet::Error)
+ end
end
diff --git a/spec/integration/parser/functions_spec.rb b/spec/integration/parser/functions_spec.rb
new file mode 100644
index 000000000..cbfb4ac88
--- /dev/null
+++ b/spec/integration/parser/functions_spec.rb
@@ -0,0 +1,21 @@
+#!/usr/bin/env ruby
+
+require File.dirname(__FILE__) + '/../../spec_helper'
+
+describe Puppet::Parser::Functions do
+ before :each do
+ Puppet::Parser::Functions.rmfunction("template") if Puppet::Parser::Functions.function("template")
+ end
+
+ it "should support multiple threads autoloading the same function" do
+ threads = []
+ lambda {
+ 10.times { |a|
+ threads << Thread.new {
+ Puppet::Parser::Functions.function("template")
+ }
+ }
+ }.should_not raise_error
+ threads.each { |t| t.join }
+ end
+end \ No newline at end of file
diff --git a/spec/integration/parser/parser_spec.rb b/spec/integration/parser/parser_spec.rb
index 7b85bcacb..0d9aa51e1 100755
--- a/spec/integration/parser/parser_spec.rb
+++ b/spec/integration/parser/parser_spec.rb
@@ -11,7 +11,7 @@ describe Puppet::Parser::Parser do
end
def result_instance
- @result.hostclass("").code[0]
+ @result.code[0]
end
def matches?(string)
@@ -44,7 +44,7 @@ describe Puppet::Parser::Parser do
end
def result_instance
- @result.hostclass("").code[0]
+ @result.code[0]
end
def matches?(string)
@@ -85,7 +85,9 @@ describe Puppet::Parser::Parser do
class test {}
""")
- ast.hostclass("test").doc.should == "comment\n"
+ ast.code[0].should be_a(Puppet::Parser::AST::Hostclass)
+ ast.code[0].name.should == 'test'
+ ast.code[0].instantiate('')[0].doc.should == "comment\n"
end
end
diff --git a/spec/integration/parser/ruby_manifest_spec.rb b/spec/integration/parser/ruby_manifest_spec.rb
new file mode 100644
index 000000000..de6f4628c
--- /dev/null
+++ b/spec/integration/parser/ruby_manifest_spec.rb
@@ -0,0 +1,128 @@
+#!/usr/bin/env ruby
+
+require File.dirname(__FILE__) + '/../../spec_helper'
+
+require 'tempfile'
+require 'puppet_spec/files'
+
+describe "Pure ruby manifests" do
+ include PuppetSpec::Files
+
+ before do
+ @node = Puppet::Node.new "testnode"
+
+ @scope_resource = stub 'scope_resource', :builtin? => true, :finish => nil, :ref => 'Class[main]'
+ @scope = stub 'scope', :resource => @scope_resource, :source => mock("source")
+ @test_dir = tmpdir('ruby_manifest_test')
+ end
+
+ after do
+ Puppet.settings.clear
+ end
+
+ def write_file(name, contents)
+ path = File.join(@test_dir, name)
+ File.open(path, "w") { |f| f.write(contents) }
+ path
+ end
+
+ def compile(contents)
+ Puppet[:code] = contents
+ Dir.chdir(@test_dir) do
+ Puppet::Parser::Compiler.compile(Puppet::Node.new("mynode"))
+ end
+ end
+
+ it "should allow classes" do
+ write_file('foo.rb', ["hostclass 'one' do notify('one_notify') end",
+ "hostclass 'two' do notify('two_notify') end"].join("\n"))
+ catalog = compile("import 'foo'\ninclude one")
+ catalog.resource("Notify[one_notify]").should_not be_nil
+ catalog.resource("Notify[two_notify]").should be_nil
+ end
+
+ it "should allow defines" do
+ write_file('foo.rb', 'define "bar", :arg do notify("bar_#{@name}_#{@arg}") end')
+ catalog = compile("import 'foo'\nbar { instance: arg => 'xyz' }")
+ catalog.resource("Notify[bar_instance_xyz]").should_not be_nil
+ catalog.resource("Bar[instance]").should_not be_nil
+ end
+
+ it "should allow node declarations" do
+ write_file('foo.rb', "node 'mynode' do notify('mynode') end")
+ catalog = compile("import 'foo'")
+ node_declaration = catalog.resource("Notify[mynode]")
+ node_declaration.should_not be_nil
+ node_declaration.title.should == 'mynode'
+ end
+
+ it "should allow access to the environment" do
+ write_file('foo.rb', ["hostclass 'bar' do",
+ " if environment.is_a? Puppet::Node::Environment",
+ " notify('success')",
+ " end",
+ "end"].join("\n"))
+ compile("import 'foo'\ninclude bar").resource("Notify[success]").should_not be_nil
+ end
+
+ it "should allow creation of resources of built-in types" do
+ write_file('foo.rb', "hostclass 'bar' do file 'test_file', :owner => 'root', :mode => '644' end")
+ catalog = compile("import 'foo'\ninclude bar")
+ file = catalog.resource("File[test_file]")
+ file.should be_a(Puppet::Resource)
+ file.type.should == 'File'
+ file.title.should == 'test_file'
+ file.exported.should_not be
+ file.virtual.should_not be
+ file[:owner].should == 'root'
+ file[:mode].should == '644'
+ file[:stage].should be_nil # TODO: is this correct behavior?
+ end
+
+ it "should allow calling user-defined functions" do
+ write_file('foo.rb', "hostclass 'bar' do user_func 'name', :arg => 'xyz' end")
+ catalog = compile(['define user_func($arg) { notify {"n_$arg": } }',
+ 'import "foo"',
+ 'include bar'].join("\n"))
+ catalog.resource("Notify[n_xyz]").should_not be_nil
+ catalog.resource("User_func[name]").should_not be_nil
+ end
+
+ it "should be properly cached for multiple compiles" do
+ # Note: we can't test this by calling compile() twice, because
+ # that sets Puppet[:code], which clears out all cached
+ # environments.
+ Puppet[:filetimeout] = 1000
+ write_file('foo.rb', "hostclass 'bar' do notify('success') end")
+ Puppet[:code] = "import 'foo'\ninclude bar"
+
+ # Compile the catalog and check it
+ catalog = Dir.chdir(@test_dir) do
+ Puppet::Parser::Compiler.compile(Puppet::Node.new("mynode"))
+ end
+ catalog.resource("Notify[success]").should_not be_nil
+
+ # Secretly change the file to make it invalid. This change
+ # shouldn't be noticed because the we've set a high
+ # Puppet[:filetimeout].
+ write_file('foo.rb', "raise 'should not be executed'")
+
+ # Compile the catalog a second time and make sure it's still ok.
+ catalog = Dir.chdir(@test_dir) do
+ Puppet::Parser::Compiler.compile(Puppet::Node.new("mynode"))
+ end
+ catalog.resource("Notify[success]").should_not be_nil
+ end
+
+ it "should be properly reloaded when stale" do
+ Puppet[:filetimeout] = -1 # force stale check to happen all the time
+ write_file('foo.rb', "hostclass 'bar' do notify('version1') end")
+ catalog = compile("import 'foo'\ninclude bar")
+ catalog.resource("Notify[version1]").should_not be_nil
+ sleep 1 # so that timestamp will change forcing file reload
+ write_file('foo.rb', "hostclass 'bar' do notify('version2') end")
+ catalog = compile("import 'foo'\ninclude bar")
+ catalog.resource("Notify[version1]").should be_nil
+ catalog.resource("Notify[version2]").should_not be_nil
+ end
+end
diff --git a/spec/integration/provider/mailalias/aliases_spec.rb b/spec/integration/provider/mailalias/aliases_spec.rb
index 8106c2cb5..0511205f2 100755
--- a/spec/integration/provider/mailalias/aliases_spec.rb
+++ b/spec/integration/provider/mailalias/aliases_spec.rb
@@ -2,7 +2,6 @@
require File.dirname(__FILE__) + '/../../../spec_helper'
-require 'puppettest'
require 'puppettest/support/utils'
require 'puppettest/fileparsing'
@@ -11,15 +10,16 @@ provider_class = Puppet::Type.type(:mailalias).provider(:aliases)
describe provider_class do
include PuppetTest
include PuppetTest::FileParsing
+ include PuppetTest::Support::Utils
before :each do
@provider = provider_class
end
# #1560
- PuppetTest.fakedata("data/providers/mailalias/aliases").each { |file|
- it "should be able to parse the examples in #{file}" do
+ it "should be able to parse the mailalias examples" do
+ fakedata("data/providers/mailalias/aliases").each { |file|
fakedataparse(file)
- end
- }
+ }
+ end
end
diff --git a/spec/integration/ssl/certificate_authority_spec.rb b/spec/integration/ssl/certificate_authority_spec.rb
index be82b5fb7..67ff6f215 100755
--- a/spec/integration/ssl/certificate_authority_spec.rb
+++ b/spec/integration/ssl/certificate_authority_spec.rb
@@ -17,6 +17,7 @@ describe Puppet::SSL::CertificateAuthority do
Puppet.settings[:confdir] = @dir
Puppet.settings[:vardir] = @dir
+ Puppet.settings[:group] = Process.gid
Puppet::SSL::Host.ca_location = :local
@ca = Puppet::SSL::CertificateAuthority.new
@@ -120,9 +121,7 @@ describe Puppet::SSL::CertificateAuthority do
it "should save valid certificates" do
@ca.sign("luke.madstop.com")
- ssl = %x{which openssl}
-
- unless ssl
+ unless ssl = Puppet::Util::which('openssl')
pending "No ssl available"
else
ca_cert = Puppet[:cacert]
diff --git a/spec/integration/ssl/certificate_request_spec.rb b/spec/integration/ssl/certificate_request_spec.rb
index 365ecce38..8426b9dc5 100755
--- a/spec/integration/ssl/certificate_request_spec.rb
+++ b/spec/integration/ssl/certificate_request_spec.rb
@@ -21,6 +21,7 @@ describe Puppet::SSL::CertificateRequest do
Puppet.settings[:confdir] = @dir
Puppet.settings[:vardir] = @dir
+ Puppet.settings[:group] = Process.gid
Puppet::SSL::Host.ca_location = :none
diff --git a/spec/integration/ssl/certificate_revocation_list_spec.rb b/spec/integration/ssl/certificate_revocation_list_spec.rb
index 127654ce3..44eee363d 100755
--- a/spec/integration/ssl/certificate_revocation_list_spec.rb
+++ b/spec/integration/ssl/certificate_revocation_list_spec.rb
@@ -17,6 +17,7 @@ describe Puppet::SSL::CertificateRevocationList do
Puppet.settings[:confdir] = @dir
Puppet.settings[:vardir] = @dir
+ Puppet.settings[:group] = Process.gid
Puppet::SSL::Host.ca_location = :local
end
diff --git a/spec/integration/ssl/host_spec.rb b/spec/integration/ssl/host_spec.rb
index 9b4152e83..05862dfc4 100755
--- a/spec/integration/ssl/host_spec.rb
+++ b/spec/integration/ssl/host_spec.rb
@@ -17,6 +17,7 @@ describe Puppet::SSL::Host do
Puppet.settings[:confdir] = @dir
Puppet.settings[:vardir] = @dir
+ Puppet.settings[:group] = Process.gid
Puppet::SSL::Host.ca_location = :local
diff --git a/spec/integration/util/file_locking_spec.rb b/spec/integration/util/file_locking_spec.rb
index 20c61d3d5..50613448b 100755
--- a/spec/integration/util/file_locking_spec.rb
+++ b/spec/integration/util/file_locking_spec.rb
@@ -5,28 +5,30 @@ Dir.chdir(File.dirname(__FILE__)) { (s = lambda { |f| File.exist?(f) ? require(f
require 'puppet/util/file_locking'
describe Puppet::Util::FileLocking do
- it "should be able to keep file corruption from happening when there are multiple writers" do
- file = Tempfile.new("puppetspec")
- filepath = file.path
- file.close!()
- file = filepath
- data = {:a => :b, :c => "A string", :d => "another string", :e => %w{an array of strings}}
- File.open(file, "w") { |f| f.puts YAML.dump(data) }
+ before :each do
+ @file = Tempfile.new("puppetspec")
+ filepath = @file.path
+ @file.close!()
+ @file = filepath
+ @data = {:a => :b, :c => "A string", :d => "another string", :e => %w{an array of strings}}
+ File.open(@file, "w") { |f| f.puts YAML.dump(@data) }
+ end
+ it "should be able to keep file corruption from happening when there are multiple writers threads" do
threads = []
sync = Sync.new
9.times { |a|
threads << Thread.new {
9.times { |b|
sync.synchronize(Sync::SH) {
- Puppet::Util::FileLocking.readlock(file) { |f|
- YAML.load(f.read).should == data
+ Puppet::Util::FileLocking.readlock(@file) { |f|
+ YAML.load(f.read).should == @data
}
}
sleep 0.01
sync.synchronize(Sync::EX) {
- Puppet::Util::FileLocking.writelock(file) { |f|
- f.puts YAML.dump(data)
+ Puppet::Util::FileLocking.writelock(@file) { |f|
+ f.puts YAML.dump(@data)
}
}
}
@@ -34,4 +36,22 @@ describe Puppet::Util::FileLocking do
}
threads.each { |th| th.join }
end
+
+ it "should be able to keep file corruption from happening when there are multiple writers processes" do
+ unless Process.fork
+ 50.times { |b|
+ Puppet::Util::FileLocking.writelock(@file) { |f|
+ f.puts YAML.dump(@data)
+ }
+ sleep 0.01
+ }
+ Kernel.exit!
+ end
+
+ 50.times { |c|
+ Puppet::Util::FileLocking.readlock(@file) { |f|
+ YAML.load(f.read).should == @data
+ }
+ }
+ end
end
diff --git a/spec/lib/puppet_spec/files.rb b/spec/lib/puppet_spec/files.rb
index cab4a1e47..52ed903ec 100644
--- a/spec/lib/puppet_spec/files.rb
+++ b/spec/lib/puppet_spec/files.rb
@@ -1,4 +1,5 @@
require 'fileutils'
+require 'tempfile'
# A support module for testing files.
module PuppetSpec::Files
diff --git a/spec/monkey_patches/add_confine_and_runnable_to_rspec_dsl.rb b/spec/monkey_patches/add_confine_and_runnable_to_rspec_dsl.rb
index 15a7cd0ac..3762b7033 100644
--- a/spec/monkey_patches/add_confine_and_runnable_to_rspec_dsl.rb
+++ b/spec/monkey_patches/add_confine_and_runnable_to_rspec_dsl.rb
@@ -5,7 +5,6 @@ dir = File.expand_path(File.dirname(__FILE__))
end
require 'spec'
-require 'puppettest'
require 'puppettest/runnable_test'
module Spec
diff --git a/spec/monkey_patches/publicize_methods.rb b/spec/monkey_patches/publicize_methods.rb
new file mode 100644
index 000000000..b39e9c002
--- /dev/null
+++ b/spec/monkey_patches/publicize_methods.rb
@@ -0,0 +1,11 @@
+# Some monkey-patching to allow us to test private methods.
+class Class
+ def publicize_methods(*methods)
+ saved_private_instance_methods = methods.empty? ? self.private_instance_methods : methods
+
+ self.class_eval { public(*saved_private_instance_methods) }
+ yield
+ self.class_eval { private(*saved_private_instance_methods) }
+ end
+end
+
diff --git a/spec/shared_behaviours/file_serving.rb b/spec/shared_behaviours/file_serving.rb
index c86453a03..5f5b2b0af 100644
--- a/spec/shared_behaviours/file_serving.rb
+++ b/spec/shared_behaviours/file_serving.rb
@@ -15,7 +15,7 @@ describe "Puppet::FileServing::Files", :shared => true do
@test_class.find(uri)
end
- it "should use the rest terminus when the 'puppet' URI scheme is used, no host name is present, and the process name is not 'puppet'" do
+ it "should use the rest terminus when the 'puppet' URI scheme is used, no host name is present, and the process name is not 'puppet' or 'apply'" do
uri = "puppet:///fakemod/my/file"
Puppet.settings.stubs(:value).returns "foo"
Puppet.settings.stubs(:value).with(:name).returns("puppetd")
@@ -35,6 +35,17 @@ describe "Puppet::FileServing::Files", :shared => true do
@test_class.find(uri)
end
+ it "should use the file_server terminus when the 'puppet' URI scheme is used, no host name is present, and the process name is 'apply'" do
+ uri = "puppet:///fakemod/my/file"
+ Puppet::Node::Environment.stubs(:new).returns(stub("env", :name => "testing", :module => nil, :modulepath => []))
+ Puppet.settings.stubs(:value).returns ""
+ Puppet.settings.stubs(:value).with(:name).returns("apply")
+ Puppet.settings.stubs(:value).with(:fileserverconfig).returns("/whatever")
+ @indirection.terminus(:file_server).expects(:find)
+ @indirection.terminus(:file_server).stubs(:authorized?).returns(true)
+ @test_class.find(uri)
+ end
+
it "should use the file terminus when the 'file' URI scheme is used" do
uri = "file:///fakemod/my/file"
@indirection.terminus(:file).expects(:find)
diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb
index 539ae2040..0c4b076f4 100644
--- a/spec/spec_helper.rb
+++ b/spec/spec_helper.rb
@@ -6,20 +6,11 @@ dir = File.expand_path(File.dirname(__FILE__))
$LOAD_PATH.unshift("#{dir}/")
$LOAD_PATH.unshift("#{dir}/lib") # a spec-specific test lib dir
$LOAD_PATH.unshift("#{dir}/../lib")
-$LOAD_PATH.unshift("#{dir}/../test/lib") # Add the old test dir, so that we can still find our local mocha and spec
-# include any gems in vendor/gems
-Dir["#{dir}/../vendor/gems/**"].each do |path|
- libpath = File.join(path, "lib")
- if File.directory?(libpath)
- $LOAD_PATH.unshift(libpath)
- else
- $LOAD_PATH.unshift(path)
- end
-end
+# Don't want puppet getting the command line arguments for rake or autotest
+ARGV.clear
-require 'puppettest'
-require 'puppettest/runnable_test'
+require 'puppet'
require 'mocha'
gem 'rspec', '>=1.2.9'
require 'spec/autorun'
@@ -29,17 +20,14 @@ module PuppetSpec
FIXTURE_DIR = File.join(dir = File.expand_path(File.dirname(__FILE__)), "fixtures") unless defined?(FIXTURE_DIR)
end
-# load any monkey-patches
-Dir["#{dir}/monkey_patches/*.rb"].map { |file| require file }
+require 'lib/puppet_spec/files'
+require 'monkey_patches/alias_should_to_must'
+require 'monkey_patches/add_confine_and_runnable_to_rspec_dsl'
+require 'monkey_patches/publicize_methods'
Spec::Runner.configure do |config|
config.mock_with :mocha
-# config.prepend_before :all do
-# setup_mocks_for_rspec
-# setup if respond_to? :setup
-# end
-#
config.prepend_after :each do
Puppet.settings.clear
Puppet::Node::Environment.clear
@@ -84,14 +72,8 @@ Spec::Runner.configure do |config|
Puppet.settings[:bindaddress] = "127.0.0.1"
@logs = []
- Puppet::Util::Log.newdestination(@logs)
+ Puppet::Util::Log.newdestination(Puppet::Test::LogCollector.new(@logs))
end
end
-# We need this because the RAL uses 'should' as a method. This
-# allows us the same behaviour but with a different method name.
-class Object
- alias :must :should
-end
-
end
diff --git a/spec/unit/application/agent_spec.rb b/spec/unit/application/agent_spec.rb
index 54726c185..50ef00c57 100755
--- a/spec/unit/application/agent_spec.rb
+++ b/spec/unit/application/agent_spec.rb
@@ -6,6 +6,7 @@ require 'puppet/agent'
require 'puppet/application/agent'
require 'puppet/network/server'
require 'puppet/daemon'
+require 'puppet/network/handler'
describe Puppet::Application::Agent do
before :each do
@@ -13,6 +14,7 @@ describe Puppet::Application::Agent do
@puppetd.stubs(:puts)
@daemon = stub_everything 'daemon'
Puppet::Daemon.stubs(:new).returns(@daemon)
+ Puppet[:daemonize] = false
@agent = stub_everything 'agent'
Puppet::Agent.stubs(:new).returns(@agent)
@puppetd.preinit
@@ -175,13 +177,10 @@ describe Puppet::Application::Agent do
@puppetd.options.stubs(:[])
Puppet.stubs(:info)
FileTest.stubs(:exists?).returns(true)
- Puppet.stubs(:[])
- Puppet.stubs(:[]=)
- Puppet.stubs(:[]).with(:libdir).returns("/dev/null/lib")
- Puppet.settings.stubs(:print_config?)
- Puppet.settings.stubs(:print_config)
+ Puppet[:libdir] = "/dev/null/lib"
Puppet::SSL::Host.stubs(:ca_location=)
Puppet::Transaction::Report.stubs(:terminus_class=)
+ Puppet::Transaction::Report.stubs(:cache_class=)
Puppet::Resource::Catalog.stubs(:terminus_class=)
Puppet::Resource::Catalog.stubs(:cache_class=)
Puppet::Node::Facts.stubs(:terminus_class=)
@@ -192,7 +191,7 @@ describe Puppet::Application::Agent do
describe "with --test" do
before :each do
- Puppet.settings.stubs(:handlearg)
+ #Puppet.settings.stubs(:handlearg)
@puppetd.options.stubs(:[]=)
end
@@ -207,8 +206,9 @@ describe Puppet::Application::Agent do
@puppetd.setup_test
end
it "should set options[:onetime] to true" do
- Puppet.expects(:[]=).with(:onetime,true)
+ Puppet[:onetime] = false
@puppetd.setup_test
+ Puppet[:onetime].should == true
end
it "should set options[:detailed_exitcodes] to true" do
@puppetd.options.expects(:[]=).with(:detailed_exitcodes,true)
@@ -264,7 +264,7 @@ describe Puppet::Application::Agent do
it "should print puppet config if asked to in Puppet config" do
@puppetd.stubs(:exit)
- Puppet.settings.stubs(:print_configs?).returns(true)
+ Puppet[:configprint] = "pluginsync"
Puppet.settings.expects(:print_configs)
@@ -272,14 +272,14 @@ describe Puppet::Application::Agent do
end
it "should exit after printing puppet config if asked to in Puppet config" do
- Puppet.settings.stubs(:print_configs?).returns(true)
+ Puppet[:configprint] = "pluginsync"
lambda { @puppetd.setup }.should raise_error(SystemExit)
end
it "should set a central log destination with --centrallogs" do
@puppetd.options.stubs(:[]).with(:centrallogs).returns(true)
- Puppet.stubs(:[]).with(:server).returns("puppet.reductivelabs.com")
+ Puppet[:server] = "puppet.reductivelabs.com"
Puppet::Util::Log.stubs(:newdestination).with(:syslog)
Puppet::Util::Log.expects(:newdestination).with("puppet.reductivelabs.com")
@@ -312,9 +312,16 @@ describe Puppet::Application::Agent do
@puppetd.setup
end
+ it "should tell the report handler to cache locally as yaml" do
+ Puppet::Transaction::Report.expects(:cache_class=).with(:yaml)
+
+ @puppetd.setup
+ end
+
it "should change the catalog_terminus setting to 'rest'" do
- Puppet.expects(:[]=).with(:catalog_terminus, :rest)
+ Puppet[:catalog_terminus] = :foo
@puppetd.setup
+ Puppet[:catalog_terminus].should == :rest
end
it "should tell the catalog handler to use cache" do
@@ -324,9 +331,10 @@ describe Puppet::Application::Agent do
end
it "should change the facts_terminus setting to 'facter'" do
- Puppet.expects(:[]=).with(:facts_terminus, :facter)
+ Puppet[:facts_terminus] = :foo
@puppetd.setup
+ Puppet[:facts_terminus].should == :facter
end
it "should create an agent" do
@@ -374,7 +382,7 @@ describe Puppet::Application::Agent do
end
it "should daemonize if needed" do
- Puppet.stubs(:[]).with(:daemonize).returns(true)
+ Puppet[:daemonize] = true
@daemon.expects(:daemonize)
@@ -397,7 +405,7 @@ describe Puppet::Application::Agent do
end
it "should setup listen if told to and not onetime" do
- Puppet.stubs(:[]).with(:listen).returns(true)
+ Puppet[:listen] = true
@puppetd.options.stubs(:[]).with(:onetime).returns(false)
@puppetd.expects(:setup_listen)
@@ -407,7 +415,7 @@ describe Puppet::Application::Agent do
describe "when setting up listen" do
before :each do
- Puppet.stubs(:[]).with(:authconfig).returns('auth')
+ Puppet[:authconfig] = 'auth'
FileTest.stubs(:exists?).with('auth').returns(true)
File.stubs(:exist?).returns(true)
@puppetd.options.stubs(:[]).with(:serve).returns([])
@@ -419,7 +427,7 @@ describe Puppet::Application::Agent do
it "should exit if no authorization file" do
Puppet.stubs(:err)
- FileTest.stubs(:exists?).with('auth').returns(false)
+ FileTest.stubs(:exists?).with(Puppet[:authconfig]).returns(false)
@puppetd.expects(:exit)
@@ -440,9 +448,9 @@ describe Puppet::Application::Agent do
end
it "should use puppet default port" do
- Puppet.stubs(:[]).with(:puppetport).returns(:port)
+ Puppet[:puppetport] = 32768
- Puppet::Network::Server.expects(:new).with { |args| args[:port] == :port }
+ Puppet::Network::Server.expects(:new).with { |args| args[:port] == 32768 }
@puppetd.setup_listen
end
@@ -521,7 +529,7 @@ describe Puppet::Application::Agent do
end
it "should exit with report's computed exit status" do
- Puppet.stubs(:[]).with(:noop).returns(false)
+ Puppet[:noop] = false
report = stub 'report', :exit_status => 666
@agent.stubs(:run).returns(report)
@puppetd.expects(:exit).with(666)
@@ -530,7 +538,7 @@ describe Puppet::Application::Agent do
end
it "should always exit with 0 if --noop" do
- Puppet.stubs(:[]).with(:noop).returns(true)
+ Puppet[:noop] = true
report = stub 'report', :exit_status => 666
@agent.stubs(:run).returns(report)
@puppetd.expects(:exit).with(0)
diff --git a/spec/unit/application/apply_spec.rb b/spec/unit/application/apply_spec.rb
index 0b00d1a2e..f07416378 100755
--- a/spec/unit/application/apply_spec.rb
+++ b/spec/unit/application/apply_spec.rb
@@ -3,6 +3,8 @@
require File.dirname(__FILE__) + '/../../spec_helper'
require 'puppet/application/apply'
+require 'puppet/file_bucket/dipper'
+require 'puppet/configurer'
describe Puppet::Application::Apply do
before :each do
@@ -53,9 +55,9 @@ describe Puppet::Application::Apply do
Puppet.stubs(:trap)
Puppet::Log.stubs(:level=)
Puppet.stubs(:parse_config)
- require 'lib/puppet/file_bucket/dipper'
Puppet::FileBucket::Dipper.stubs(:new)
STDIN.stubs(:read)
+ Puppet::Transaction::Report.stubs(:cache_class=)
@apply.options.stubs(:[]).with(any_parameters)
end
@@ -113,6 +115,11 @@ describe Puppet::Application::Apply do
lambda { @apply.setup }.should raise_error(SystemExit)
end
+ it "should tell the report handler to cache locally as yaml" do
+ Puppet::Transaction::Report.expects(:cache_class=).with(:yaml)
+
+ @apply.setup
+ end
end
describe "when executing" do
@@ -142,17 +149,16 @@ describe Puppet::Application::Apply do
describe "the parseonly command" do
before :each do
- Puppet.stubs(:[]).with(:environment)
+ @environment = Puppet::Node::Environment.new("env")
+ Puppet.stubs(:[]).with(:environment).returns(@environment)
Puppet.stubs(:[]).with(:manifest).returns("site.pp")
Puppet.stubs(:err)
@apply.stubs(:exit)
@apply.options.stubs(:[]).with(:code).returns "some code"
- @collection = stub_everything
- Puppet::Resource::TypeCollection.stubs(:new).returns(@collection)
end
- it "should use a Puppet Resource Type Collection to parse the file" do
- @collection.expects(:perform_initial_import)
+ it "should use the environment to parse the file" do
+ @environment.stubs(:perform_initial_import)
@apply.parseonly
end
@@ -162,7 +168,7 @@ describe Puppet::Application::Apply do
end
it "should exit with exit code 1 if error" do
- @collection.stubs(:perform_initial_import).raises(Puppet::ParseError)
+ @environment.stubs(:perform_initial_import).raises(Puppet::ParseError)
@apply.expects(:exit).with(1)
@apply.parseonly
end
@@ -194,6 +200,9 @@ describe Puppet::Application::Apply do
@catalog.stubs(:apply).returns(@transaction)
@apply.stubs(:exit)
+
+ Puppet::Util::Storage.stubs(:load)
+ Puppet::Configurer.any_instance.stubs(:save_last_run_summary) # to prevent it from trying to write files
end
it "should set the code to run from --code" do
@@ -212,7 +221,8 @@ describe Puppet::Application::Apply do
@apply.main
end
- it "should set the manifest if some files are passed on command line" do
+ it "should set the manifest if a file is passed on command line and the file exists" do
+ File.stubs(:exist?).with('site.pp').returns true
@apply.command_line.stubs(:args).returns(['site.pp'])
Puppet.expects(:[]=).with(:manifest,"site.pp")
@@ -220,6 +230,23 @@ describe Puppet::Application::Apply do
@apply.main
end
+ it "should raise an error if a file is passed on command line and the file does not exist" do
+ File.stubs(:exist?).with('noexist.pp').returns false
+ @apply.command_line.stubs(:args).returns(['noexist.pp'])
+ lambda { @apply.main }.should raise_error(RuntimeError, 'Could not find file noexist.pp')
+ end
+
+ it "should set the manifest to the first file and warn other files will be skipped" do
+ File.stubs(:exist?).with('starwarsIV').returns true
+ File.expects(:exist?).with('starwarsI').never
+ @apply.command_line.stubs(:args).returns(['starwarsIV', 'starwarsI', 'starwarsII'])
+
+ Puppet.expects(:[]=).with(:manifest,"starwarsIV")
+ Puppet.expects(:warning).with('Only one file can be applied per run. Skipping starwarsI, starwarsII')
+
+ @apply.main
+ end
+
it "should collect the node facts" do
Puppet::Node::Facts.expects(:find).returns(@facts)
@@ -232,7 +259,7 @@ describe Puppet::Application::Apply do
lambda { @apply.main }.should raise_error
end
- it "should find the node" do
+ it "should look for the node" do
Puppet::Node.expects(:find).returns(@node)
@apply.main
@@ -284,18 +311,24 @@ describe Puppet::Application::Apply do
end
it "should call the prerun and postrun commands on a Configurer instance" do
- configurer = stub 'configurer'
-
- Puppet::Configurer.expects(:new).returns configurer
- configurer.expects(:execute_prerun_command)
- configurer.expects(:execute_postrun_command)
+ Puppet::Configurer.any_instance.expects(:execute_prerun_command)
+ Puppet::Configurer.any_instance.expects(:execute_postrun_command)
@apply.main
end
it "should apply the catalog" do
- @catalog.expects(:apply)
+ @catalog.expects(:apply).returns(stub_everything('transaction'))
+
+ @apply.main
+ end
+
+ it "should save the last run summary" do
+ Puppet.stubs(:[]).with(:noop).returns(false)
+ report = stub 'report'
+ Puppet::Configurer.any_instance.stubs(:initialize_report).returns(report)
+ Puppet::Configurer.any_instance.expects(:save_last_run_summary).with(report)
@apply.main
end
@@ -303,8 +336,7 @@ describe Puppet::Application::Apply do
it "should exit with report's computed exit status" do
Puppet.stubs(:[]).with(:noop).returns(false)
@apply.options.stubs(:[]).with(:detailed_exitcodes).returns(true)
- report = stub 'report', :exit_status => 666
- @transaction.stubs(:report).returns(report)
+ Puppet::Transaction::Report.any_instance.stubs(:exit_status).returns(666)
@apply.expects(:exit).with(666)
@apply.main
diff --git a/spec/unit/application/cert_spec.rb b/spec/unit/application/cert_spec.rb
index b82a2fe89..4663fc938 100755
--- a/spec/unit/application/cert_spec.rb
+++ b/spec/unit/application/cert_spec.rb
@@ -12,7 +12,7 @@ describe Puppet::Application::Cert do
end
it "should operate in master run_mode" do
- @cert_app.class.run_mode.name.should equal :master
+ @cert_app.class.run_mode.name.should equal(:master)
end
it "should ask Puppet::Application to parse Puppet configuration file" do
diff --git a/spec/unit/application/doc_spec.rb b/spec/unit/application/doc_spec.rb
index 7a22f5b2e..55da5e39a 100755
--- a/spec/unit/application/doc_spec.rb
+++ b/spec/unit/application/doc_spec.rb
@@ -27,10 +27,6 @@ describe Puppet::Application::Doc do
@doc.should respond_to(:rdoc)
end
- it "should declare a trac command" do
- @doc.should respond_to(:trac)
- end
-
it "should declare a fallback for unknown options" do
@doc.should respond_to(:handle_unknown)
end
@@ -270,21 +266,6 @@ describe Puppet::Application::Doc do
end
describe "when running" do
- before :each do
- end
-
- describe "in trac mode" do
- it "should call trac for each reference" do
- ref = stub 'ref'
- Puppet::Util::Reference.stubs(:reference).with(:ref).returns(ref)
- @doc.options.stubs(:[]).with(:references).returns([:ref])
- @doc.options.stubs(:[]).with(:mode).returns(:trac)
-
- ref.expects(:trac)
-
- @doc.trac
- end
- end
describe "in rdoc mode" do
before :each do
diff --git a/spec/unit/application/filebucket_spec.rb b/spec/unit/application/filebucket_spec.rb
index 6e7a7b819..e6272f179 100644
--- a/spec/unit/application/filebucket_spec.rb
+++ b/spec/unit/application/filebucket_spec.rb
@@ -3,6 +3,7 @@
require File.dirname(__FILE__) + '/../../spec_helper'
require 'puppet/application/filebucket'
+require 'puppet/file_bucket/dipper'
describe Puppet::Application::Filebucket do
before :each do
diff --git a/spec/unit/application/master_spec.rb b/spec/unit/application/master_spec.rb
index 0baa8229b..e657445a4 100644
--- a/spec/unit/application/master_spec.rb
+++ b/spec/unit/application/master_spec.rb
@@ -23,7 +23,7 @@ describe Puppet::Application::Master do
end
it "should operate in master run_mode" do
- @master.class.run_mode.name.should equal :master
+ @master.class.run_mode.name.should equal(:master)
end
it "should ask Puppet::Application to parse Puppet configuration file" do
@@ -257,16 +257,15 @@ describe Puppet::Application::Master do
describe "the parseonly command" do
before :each do
- Puppet.stubs(:[]).with(:environment)
+ @environment = Puppet::Node::Environment.new("env")
+ Puppet.stubs(:[]).with(:environment).returns(@environment)
Puppet.stubs(:[]).with(:manifest).returns("site.pp")
Puppet.stubs(:err)
@master.stubs(:exit)
- @collection = stub_everything
- Puppet::Resource::TypeCollection.stubs(:new).returns(@collection)
end
it "should use a Puppet Resource Type Collection to parse the file" do
- @collection.expects(:perform_initial_import)
+ @environment.expects(:perform_initial_import)
@master.parseonly
end
@@ -276,7 +275,7 @@ describe Puppet::Application::Master do
end
it "should exit with exit code 1 if error" do
- @collection.stubs(:perform_initial_import).raises(Puppet::ParseError)
+ @environment.stubs(:perform_initial_import).raises(Puppet::ParseError)
@master.expects(:exit).with(1)
@master.parseonly
end
diff --git a/spec/unit/application/queue_spec.rb b/spec/unit/application/queue_spec.rb
index 87c96dfff..bd0d53ab1 100755
--- a/spec/unit/application/queue_spec.rb
+++ b/spec/unit/application/queue_spec.rb
@@ -3,6 +3,7 @@
require File.dirname(__FILE__) + '/../../spec_helper'
require 'puppet/application/queue'
+require 'puppet/indirector/catalog/queue'
describe Puppet::Application::Queue do
before :each do
diff --git a/spec/unit/application_spec.rb b/spec/unit/application_spec.rb
index 3c354cce9..be7cda340 100755
--- a/spec/unit/application_spec.rb
+++ b/spec/unit/application_spec.rb
@@ -191,35 +191,17 @@ describe Puppet::Application do
Puppet.settings.stubs(:optparse_addargs).returns([])
end
- it "should create a new option parser when needed" do
- option_parser = stub "option parser"
- option_parser.stubs(:on)
- option_parser.stubs(:default_argv=)
- OptionParser.expects(:new).returns(option_parser).once
- @app.option_parser.should == option_parser
- @app.option_parser.should == option_parser
- end
-
it "should pass the banner to the option parser" do
option_parser = stub "option parser"
option_parser.stubs(:on)
- option_parser.stubs(:default_argv=)
+ option_parser.stubs(:parse!)
@app.class.instance_eval do
banner "banner"
end
OptionParser.expects(:new).with("banner").returns(option_parser)
- @app.option_parser
- end
-
- it "should set the optionparser's args to the command line args" do
- option_parser = stub "option parser"
- option_parser.stubs(:on)
- option_parser.expects(:default_argv=).with(%w{ fake args })
- @app.command_line.stubs(:args).returns(%w{ fake args })
- OptionParser.expects(:new).returns(option_parser)
- @app.option_parser
+ @app.parse_options
end
it "should get options from Puppet.settings.optparse_addargs" do
@@ -230,14 +212,14 @@ describe Puppet::Application do
it "should add Puppet.settings options to OptionParser" do
Puppet.settings.stubs(:optparse_addargs).returns( [["--option","-o", "Funny Option"]])
-
- @app.option_parser.expects(:on).with { |*arg| arg == ["--option","-o", "Funny Option"] }
-
+ Puppet.settings.expects(:handlearg).with("--option", 'true')
+ @app.command_line.stubs(:args).returns(["--option"])
@app.parse_options
end
it "should ask OptionParser to parse the command-line argument" do
- @app.option_parser.expects(:parse!)
+ @app.command_line.stubs(:args).returns(%w{ fake args })
+ OptionParser.any_instance.expects(:parse!).with(%w{ fake args })
@app.parse_options
end
@@ -268,31 +250,30 @@ describe Puppet::Application do
describe "when dealing with an argument not declared directly by the application" do
it "should pass it to handle_unknown if this method exists" do
- Puppet.settings.stubs(:optparse_addargs).returns([["--not-handled"]])
- @app.option_parser.stubs(:on).yields("value")
+ Puppet.settings.stubs(:optparse_addargs).returns([["--not-handled", :REQUIRED]])
@app.expects(:handle_unknown).with("--not-handled", "value").returns(true)
-
+ @app.command_line.stubs(:args).returns(["--not-handled", "value"])
@app.parse_options
end
it "should pass it to Puppet.settings if handle_unknown says so" do
- Puppet.settings.stubs(:optparse_addargs).returns([["--topuppet"]])
- @app.option_parser.stubs(:on).yields("value")
+ Puppet.settings.stubs(:optparse_addargs).returns([["--topuppet", :REQUIRED]])
@app.stubs(:handle_unknown).with("--topuppet", "value").returns(false)
Puppet.settings.expects(:handlearg).with("--topuppet", "value")
+ @app.command_line.stubs(:args).returns(["--topuppet", "value"])
@app.parse_options
end
it "should pass it to Puppet.settings if there is no handle_unknown method" do
- Puppet.settings.stubs(:optparse_addargs).returns([["--topuppet"]])
- @app.option_parser.stubs(:on).yields("value")
+ Puppet.settings.stubs(:optparse_addargs).returns([["--topuppet", :REQUIRED]])
@app.stubs(:respond_to?).returns(false)
Puppet.settings.expects(:handlearg).with("--topuppet", "value")
+ @app.command_line.stubs(:args).returns(["--topuppet", "value"])
@app.parse_options
end
@@ -320,7 +301,7 @@ describe Puppet::Application do
it "should exit if OptionParser raises an error" do
$stderr.stubs(:puts)
- @app.option_parser.stubs(:parse!).raises(OptionParser::ParseError.new("blah blah"))
+ OptionParser.any_instance.stubs(:parse!).raises(OptionParser::ParseError.new("blah blah"))
@app.expects(:exit)
@@ -488,7 +469,7 @@ describe Puppet::Application do
@app.class.option("--[no-]test3","-t") do
end
- @app.option_parser
+ @app.parse_options
end
it "should pass a block that calls our defined method" do
@@ -500,7 +481,7 @@ describe Puppet::Application do
@app.class.option("--test4","-t") do
end
- @app.option_parser
+ @app.parse_options
end
end
@@ -511,7 +492,7 @@ describe Puppet::Application do
@app.class.option("--test4","-t")
- @app.option_parser
+ @app.parse_options
end
it "should give to OptionParser a block that adds the the value to the options array" do
@@ -522,7 +503,7 @@ describe Puppet::Application do
@app.class.option("--test4","-t")
- @app.option_parser
+ @app.parse_options
end
end
end
diff --git a/spec/unit/configurer_spec.rb b/spec/unit/configurer_spec.rb
index 0c9d06362..e34e6fffb 100755
--- a/spec/unit/configurer_spec.rb
+++ b/spec/unit/configurer_spec.rb
@@ -89,9 +89,7 @@ describe Puppet::Configurer, "when executing a catalog run" do
@catalog = Puppet::Resource::Catalog.new
@catalog.stubs(:apply)
@agent.stubs(:retrieve_catalog).returns @catalog
-
- Puppet::Util::Log.stubs(:newdestination)
- Puppet::Util::Log.stubs(:close)
+ @agent.stubs(:save_last_run_summary)
end
it "should prepare for the run" do
@@ -101,14 +99,14 @@ describe Puppet::Configurer, "when executing a catalog run" do
end
it "should initialize a transaction report if one is not provided" do
- report = stub 'report'
+ report = Puppet::Transaction::Report.new
@agent.expects(:initialize_report).returns report
@agent.run
end
it "should pass the new report to the catalog" do
- report = stub 'report'
+ report = Puppet::Transaction::Report.new
@agent.stubs(:initialize_report).returns report
@catalog.expects(:apply).with{|options| options[:report] == report}
@@ -116,7 +114,7 @@ describe Puppet::Configurer, "when executing a catalog run" do
end
it "should use the provided report if it was passed one" do
- report = stub 'report'
+ report = Puppet::Transaction::Report.new
@agent.expects(:initialize_report).never
@catalog.expects(:apply).with{|options| options[:report] == report}
@@ -176,7 +174,7 @@ describe Puppet::Configurer, "when executing a catalog run" do
end
it "should send the report" do
- report = stub 'report'
+ report = Puppet::Transaction::Report.new
@agent.expects(:initialize_report).returns report
@agent.expects(:send_report).with { |r, trans| r == report }
@@ -184,7 +182,7 @@ describe Puppet::Configurer, "when executing a catalog run" do
end
it "should send the transaction report with a reference to the transaction if a run was actually made" do
- report = stub 'report'
+ report = Puppet::Transaction::Report.new
@agent.expects(:initialize_report).returns report
trans = stub 'transaction'
@@ -198,7 +196,7 @@ describe Puppet::Configurer, "when executing a catalog run" do
it "should send the transaction report even if the catalog could not be retrieved" do
@agent.expects(:retrieve_catalog).returns nil
- report = stub 'report'
+ report = Puppet::Transaction::Report.new
@agent.expects(:initialize_report).returns report
@agent.expects(:send_report)
@@ -208,7 +206,7 @@ describe Puppet::Configurer, "when executing a catalog run" do
it "should send the transaction report even if there is a failure" do
@agent.expects(:retrieve_catalog).raises "whatever"
- report = stub 'report'
+ report = Puppet::Transaction::Report.new
@agent.expects(:initialize_report).returns report
@agent.expects(:send_report)
@@ -216,16 +214,16 @@ describe Puppet::Configurer, "when executing a catalog run" do
end
it "should remove the report as a log destination when the run is finished" do
- report = stub 'report'
+ report = Puppet::Transaction::Report.new
@agent.expects(:initialize_report).returns report
-
- Puppet::Util::Log.expects(:close).with(report)
+ report.expects(:<<).at_least_once
@agent.run
+ Puppet::Util::Log.destinations.should_not include(report)
end
it "should return the report as the result of the run" do
- report = stub 'report'
+ report = Puppet::Transaction::Report.new
@agent.expects(:initialize_report).returns report
@agent.run.should equal(report)
@@ -236,6 +234,7 @@ describe Puppet::Configurer, "when sending a report" do
before do
Puppet.settings.stubs(:use).returns(true)
@configurer = Puppet::Configurer.new
+ @configurer.stubs(:save_last_run_summary)
@report = stub 'report'
@trans = stub 'transaction'
@@ -284,6 +283,20 @@ describe Puppet::Configurer, "when sending a report" do
@configurer.send_report(@report)
end
+ it "should save the last run summary if reporting is enabled" do
+ Puppet.settings[:report] = true
+
+ @configurer.expects(:save_last_run_summary).with(@report)
+ @configurer.send_report(@report)
+ end
+
+ it "should not save the last run summary if reporting is disabled" do
+ Puppet.settings[:report] = false
+
+ @configurer.expects(:save_last_run_summary).never
+ @configurer.send_report(@report)
+ end
+
it "should log but not fail if saving the report fails" do
Puppet.settings[:report] = true
@@ -294,6 +307,36 @@ describe Puppet::Configurer, "when sending a report" do
end
end
+describe Puppet::Configurer, "when saving the summary report file" do
+ before do
+ Puppet.settings.stubs(:use).returns(true)
+ @configurer = Puppet::Configurer.new
+
+ @report = stub 'report'
+ @trans = stub 'transaction'
+ @lastrunfd = stub 'lastrunfd'
+ Puppet::Util::FileLocking.stubs(:writelock).yields(@lastrunfd)
+ end
+
+ it "should write the raw summary to the lastrunfile setting value" do
+ Puppet::Util::FileLocking.expects(:writelock).with(Puppet[:lastrunfile], 0660)
+ @configurer.save_last_run_summary(@report)
+ end
+
+ it "should write the raw summary as yaml" do
+ @report.expects(:raw_summary).returns("summary")
+ @lastrunfd.expects(:print).with(YAML.dump("summary"))
+ @configurer.save_last_run_summary(@report)
+ end
+
+ it "should log but not fail if saving the last run summary fails" do
+ Puppet::Util::FileLocking.expects(:writelock).raises "exception"
+ Puppet.expects(:err)
+ lambda { @configurer.save_last_run_summary(@report) }.should_not raise_error
+ end
+
+end
+
describe Puppet::Configurer, "when retrieving a catalog" do
before do
Puppet.settings.stubs(:use).returns(true)
@@ -472,23 +515,23 @@ describe Puppet::Configurer, "when preparing for a run" do
it "should initialize the metadata store" do
@agent.class.stubs(:facts).returns(@facts)
@agent.expects(:dostorage)
- @agent.prepare
+ @agent.prepare({})
end
it "should download fact plugins" do
@agent.expects(:download_fact_plugins)
- @agent.prepare
+ @agent.prepare({})
end
it "should download plugins" do
@agent.expects(:download_plugins)
- @agent.prepare
+ @agent.prepare({})
end
it "should perform the pre-run commands" do
@agent.expects(:execute_prerun_command)
- @agent.prepare
+ @agent.prepare({})
end
end
diff --git a/spec/unit/daemon_spec.rb b/spec/unit/daemon_spec.rb
index 15320736c..e24db7881 100755
--- a/spec/unit/daemon_spec.rb
+++ b/spec/unit/daemon_spec.rb
@@ -1,4 +1,4 @@
-#!/usr/bin/env ruby"
+#!/usr/bin/env ruby
require File.dirname(__FILE__) + '/../spec_helper'
require 'puppet/daemon'
@@ -142,11 +142,7 @@ describe Puppet::Daemon do
describe "when creating its pidfile" do
it "should use an exclusive mutex" do
Puppet.settings.expects(:value).with(:name).returns "me"
-
- sync = mock 'sync'
- Puppet::Util.expects(:sync).with("me").returns sync
-
- sync.expects(:synchronize).with(Sync::EX)
+ Puppet::Util.expects(:synchronize_on).with("me",Sync::EX)
@daemon.create_pidfile
end
@@ -180,10 +176,8 @@ describe Puppet::Daemon do
it "should use an exclusive mutex" do
Puppet.settings.expects(:value).with(:name).returns "me"
- sync = mock 'sync'
- Puppet::Util.expects(:sync).with("me").returns sync
+ Puppet::Util.expects(:synchronize_on).with("me",Sync::EX)
- sync.expects(:synchronize).with(Sync::EX)
@daemon.remove_pidfile
end
diff --git a/spec/unit/dsl/resource_type_api_spec.rb b/spec/unit/dsl/resource_type_api_spec.rb
index 5abe79ea7..c9a5d272f 100755
--- a/spec/unit/dsl/resource_type_api_spec.rb
+++ b/spec/unit/dsl/resource_type_api_spec.rb
@@ -4,43 +4,51 @@ require File.dirname(__FILE__) + '/../../spec_helper'
require 'puppet/dsl/resource_type_api'
-class DSLAPITester
- include Puppet::DSL::ResourceTypeAPI
-end
-
describe Puppet::DSL::ResourceTypeAPI do
- before do
- @api = DSLAPITester.new
+ # Verify that the block creates a single AST node through the API,
+ # instantiate that AST node into a types, and return that type.
+ def test_api_call(&block)
+ main_object = Puppet::DSL::ResourceTypeAPI.new
+ main_object.instance_eval(&block)
+ created_ast_objects = main_object.instance_eval { @__created_ast_objects__ }
+ created_ast_objects.length.should == 1
+ new_types = created_ast_objects[0].instantiate('')
+ new_types.length.should == 1
+ new_types[0]
+ ensure
+ Thread.current[:ruby_file_parse_result] = nil
end
[:definition, :node, :hostclass].each do |type|
method = type == :definition ? "define" : type
it "should be able to create a #{type}" do
- newtype = Puppet::Resource::Type.new(:hostclass, "foo")
- Puppet::Resource::Type.expects(:new).with { |t, n, args| t == type }.returns newtype
- @api.send(method, "myname")
+ newtype = test_api_call { send(method, "myname").should == nil }
+ newtype.should be_a(Puppet::Resource::Type)
+ newtype.type.should == type
end
it "should use the provided name when creating a #{type}" do
- type = Puppet::Resource::Type.new(:hostclass, "foo")
- Puppet::Resource::Type.expects(:new).with { |t, n, args| n == "myname" }.returns type
- @api.send(method, "myname")
+ newtype = test_api_call { send(method, "myname") }
+ newtype.name.should == "myname"
end
unless type == :definition
- it "should pass in any provided options" do
- type = Puppet::Resource::Type.new(:hostclass, "foo")
- Puppet::Resource::Type.expects(:new).with { |t, n, args| args == {:myarg => :myvalue} }.returns type
- @api.send(method, "myname", :myarg => :myvalue)
+ it "should pass in any provided options when creating a #{type}" do
+ newtype = test_api_call { send(method, "myname", :line => 200) }
+ newtype.line.should == 200
end
end
- it "should set any provided block as the type's ruby code"
-
- it "should add the type to the current environment's known resource types"
+ it "should set any provided block as the type's ruby code" do
+ newtype = test_api_call { send(method, "myname") { 'method_result' } }
+ newtype.ruby_code.call.should == 'method_result'
+ end
end
describe "when creating a definition" do
- it "should use the provided options to define valid arguments for the resource type"
+ it "should use the provided options to define valid arguments for the resource type" do
+ newtype = test_api_call { define("myname", :arg1, :arg2) }
+ newtype.arguments.should == { 'arg1' => nil, 'arg2' => nil }
+ end
end
end
diff --git a/spec/unit/indirector/active_record_spec.rb b/spec/unit/indirector/active_record_spec.rb
index 258c4e793..40af146c8 100755
--- a/spec/unit/indirector/active_record_spec.rb
+++ b/spec/unit/indirector/active_record_spec.rb
@@ -2,6 +2,7 @@
require File.dirname(__FILE__) + '/../../spec_helper'
+require 'puppet/rails'
require 'puppet/indirector/active_record'
describe Puppet::Indirector::ActiveRecord do
diff --git a/spec/unit/indirector/catalog/compiler_spec.rb b/spec/unit/indirector/catalog/compiler_spec.rb
index 2ae5f6ff3..49b8986eb 100755
--- a/spec/unit/indirector/catalog/compiler_spec.rb
+++ b/spec/unit/indirector/catalog/compiler_spec.rb
@@ -6,9 +6,11 @@
require File.dirname(__FILE__) + '/../../../spec_helper'
require 'puppet/indirector/catalog/compiler'
+require 'puppet/rails'
describe Puppet::Resource::Catalog::Compiler do
before do
+ require 'puppet/rails'
Puppet::Rails.stubs(:init)
Facter.stubs(:to_hash).returns({})
Facter.stubs(:value).returns(Facter::Util::Fact.new("something"))
@@ -33,8 +35,8 @@ describe Puppet::Resource::Catalog::Compiler do
Puppet::Node.stubs(:find).with('node1').returns(node1)
Puppet::Node.stubs(:find).with('node2').returns(node2)
- compiler.find(stub('request', :node => 'node1', :options => {}))
- compiler.find(stub('node2request', :node => 'node2', :options => {}))
+ compiler.find(stub('request', :key => 'node1', :node => 'node1', :options => {}))
+ compiler.find(stub('node2request', :key => 'node2', :node => 'node2', :options => {}))
end
it "should provide a method for determining if the catalog is networked" do
@@ -70,7 +72,7 @@ describe Puppet::Resource::Catalog::Compiler do
@node = Puppet::Node.new @name
@node.stubs(:merge)
Puppet::Node.stubs(:find).returns @node
- @request = stub 'request', :key => "does not matter", :node => @name, :options => {}
+ @request = stub 'request', :key => @name, :node => @name, :options => {}
end
it "should directly use provided nodes" do
@@ -80,14 +82,14 @@ describe Puppet::Resource::Catalog::Compiler do
@compiler.find(@request)
end
- it "should use the request's node name if no explicit node is provided" do
+ it "should use the authenticated node name if no request key is provided" do
+ @request.stubs(:key).returns(nil)
Puppet::Node.expects(:find).with(@name).returns(@node)
@compiler.expects(:compile).with(@node)
@compiler.find(@request)
end
- it "should use the provided node name if no explicit node is provided and no authenticated node information is available" do
- @request.expects(:node).returns nil
+ it "should use the provided node name by default" do
@request.expects(:key).returns "my_node"
Puppet::Node.expects(:find).with("my_node").returns @node
@@ -155,7 +157,8 @@ describe Puppet::Resource::Catalog::Compiler do
@compiler = Puppet::Resource::Catalog::Compiler.new
@request = stub 'request', :options => {}
- @facts = stub 'facts', :save => nil
+ @facts = Puppet::Node::Facts.new('hostname', "fact" => "value", "architecture" => "i386")
+ @facts.stubs(:save).returns(nil)
end
it "should do nothing if no facts are provided" do
@@ -165,12 +168,17 @@ describe Puppet::Resource::Catalog::Compiler do
@compiler.extract_facts_from_request(@request)
end
- it "should use the Facts class to deserialize the provided facts" do
+ it "should use the Facts class to deserialize the provided facts and update the timestamp" do
@request.options[:facts_format] = "foo"
@request.options[:facts] = "bar"
Puppet::Node::Facts.expects(:convert_from).returns @facts
+ @facts.timestamp = Time.parse('2010-11-01')
+ @now = Time.parse('2010-11-02')
+ Time.expects(:now).returns(@now)
+
@compiler.extract_facts_from_request(@request)
+ @facts.timestamp.should == @now
end
it "should use the provided fact format" do
@@ -198,7 +206,7 @@ describe Puppet::Resource::Catalog::Compiler do
@compiler = Puppet::Resource::Catalog::Compiler.new
@name = "me"
@node = mock 'node'
- @request = stub 'request', :node => @name, :options => {}
+ @request = stub 'request', :key => @name, :options => {}
@compiler.stubs(:compile)
end
@@ -217,7 +225,7 @@ describe Puppet::Resource::Catalog::Compiler do
@compiler = Puppet::Resource::Catalog::Compiler.new
@name = "me"
@node = mock 'node'
- @request = stub 'request', :node => @name, :options => {}
+ @request = stub 'request', :key => @name, :options => {}
@compiler.stubs(:compile)
Puppet::Node.stubs(:find).with(@name).returns(@node)
end
diff --git a/spec/unit/indirector/facts/active_record_spec.rb b/spec/unit/indirector/facts/active_record_spec.rb
index 0cdb70e01..0bdcfcb77 100755
--- a/spec/unit/indirector/facts/active_record_spec.rb
+++ b/spec/unit/indirector/facts/active_record_spec.rb
@@ -2,6 +2,7 @@
require File.dirname(__FILE__) + '/../../../spec_helper'
+require 'puppet/rails'
require 'puppet/node/facts'
describe "Puppet::Node::Facts::ActiveRecord" do
diff --git a/spec/unit/indirector/facts/yaml_spec.rb b/spec/unit/indirector/facts/yaml_spec.rb
index e7bac3471..37a1bcae0 100755
--- a/spec/unit/indirector/facts/yaml_spec.rb
+++ b/spec/unit/indirector/facts/yaml_spec.rb
@@ -10,9 +10,9 @@ describe Puppet::Node::Facts::Yaml do
Puppet::Node::Facts::Yaml.superclass.should equal(Puppet::Indirector::Yaml)
end
-
it "should have documentation" do
Puppet::Node::Facts::Yaml.doc.should_not be_nil
+ Puppet::Node::Facts::Yaml.doc.should_not be_empty
end
it "should be registered with the facts indirection" do
@@ -20,7 +20,7 @@ describe Puppet::Node::Facts::Yaml do
Puppet::Node::Facts::Yaml.indirection.should equal(indirection)
end
- it "should have its name set to :facts" do
+ it "should have its name set to :yaml" do
Puppet::Node::Facts::Yaml.name.should == :yaml
end
end
diff --git a/spec/unit/indirector/inventory/yaml_spec.rb b/spec/unit/indirector/inventory/yaml_spec.rb
new file mode 100644
index 000000000..9f0c54353
--- /dev/null
+++ b/spec/unit/indirector/inventory/yaml_spec.rb
@@ -0,0 +1,221 @@
+#!/usr/bin/env ruby
+
+require File.dirname(__FILE__) + '/../../../spec_helper'
+
+require 'puppet/node/inventory'
+require 'puppet/indirector/inventory/yaml'
+require 'puppet/indirector/request'
+
+describe Puppet::Node::Inventory::Yaml do
+ def assert_search_matches(matching, nonmatching, query)
+ request = Puppet::Indirector::Request.new(:inventory, :search, nil, query)
+
+ Dir.stubs(:glob).returns(matching.keys + nonmatching.keys)
+ [matching, nonmatching].each do |examples|
+ examples.each do |key, value|
+ YAML.stubs(:load_file).with(key).returns value
+ end
+ end
+ Puppet::Node::Inventory::Yaml.new.search(request).should =~ matching.values.map {|facts| facts.name}
+ end
+
+ it "should return node names that match the search query options" do
+ assert_search_matches({
+ '/path/to/matching.yaml' => Puppet::Node::Facts.new("matchingnode", "architecture" => "i386", 'processor_count' => '4'),
+ '/path/to/matching1.yaml' => Puppet::Node::Facts.new("matchingnode1", "architecture" => "i386", 'processor_count' => '4', 'randomfact' => 'foo')
+ },
+ {
+ "/path/to/nonmatching.yaml" => Puppet::Node::Facts.new("nonmatchingnode", "architecture" => "powerpc", 'processor_count' => '4'),
+ "/path/to/nonmatching1.yaml" => Puppet::Node::Facts.new("nonmatchingnode1", "architecture" => "powerpc", 'processor_count' => '5'),
+ "/path/to/nonmatching2.yaml" => Puppet::Node::Facts.new("nonmatchingnode2", "architecture" => "i386", 'processor_count' => '5'),
+ "/path/to/nonmatching3.yaml" => Puppet::Node::Facts.new("nonmatchingnode3", 'processor_count' => '4'),
+ },
+ {'facts.architecture' => 'i386', 'facts.processor_count' => '4'}
+ )
+ end
+
+ it "should return empty array when no nodes match the search query options" do
+ assert_search_matches({}, {
+ "/path/to/nonmatching.yaml" => Puppet::Node::Facts.new("nonmatchingnode", "architecture" => "powerpc", 'processor_count' => '10'),
+ "/path/to/nonmatching1.yaml" => Puppet::Node::Facts.new("nonmatchingnode1", "architecture" => "powerpc", 'processor_count' => '5'),
+ "/path/to/nonmatching2.yaml" => Puppet::Node::Facts.new("nonmatchingnode2", "architecture" => "i386", 'processor_count' => '5'),
+ "/path/to/nonmatching3.yaml" => Puppet::Node::Facts.new("nonmatchingnode3", 'processor_count' => '4'),
+ },
+ {'facts.processor_count.lt' => '4', 'facts.processor_count.gt' => '4'}
+ )
+ end
+
+
+ it "should return node names that match the search query options with the greater than operator" do
+ assert_search_matches({
+ '/path/to/matching.yaml' => Puppet::Node::Facts.new("matchingnode", "architecture" => "i386", 'processor_count' => '5'),
+ '/path/to/matching1.yaml' => Puppet::Node::Facts.new("matchingnode1", "architecture" => "powerpc", 'processor_count' => '10', 'randomfact' => 'foo')
+ },
+ {
+ "/path/to/nonmatching.yaml" => Puppet::Node::Facts.new("nonmatchingnode", "architecture" => "powerpc", 'processor_count' => '4'),
+ "/path/to/nonmatching2.yaml" => Puppet::Node::Facts.new("nonmatchingnode2", "architecture" => "i386", 'processor_count' => '3'),
+ "/path/to/nonmatching3.yaml" => Puppet::Node::Facts.new("nonmatchingnode3" ),
+ },
+ {'facts.processor_count.gt' => '4'}
+ )
+ end
+
+ it "should return node names that match the search query options with the less than operator" do
+ assert_search_matches({
+ '/path/to/matching.yaml' => Puppet::Node::Facts.new("matchingnode", "architecture" => "i386", 'processor_count' => '5'),
+ '/path/to/matching1.yaml' => Puppet::Node::Facts.new("matchingnode1", "architecture" => "powerpc", 'processor_count' => '30', 'randomfact' => 'foo')
+ },
+ {
+ "/path/to/nonmatching.yaml" => Puppet::Node::Facts.new("nonmatchingnode", "architecture" => "powerpc", 'processor_count' => '50' ),
+ "/path/to/nonmatching2.yaml" => Puppet::Node::Facts.new("nonmatchingnode2", "architecture" => "i386", 'processor_count' => '100'),
+ "/path/to/nonmatching3.yaml" => Puppet::Node::Facts.new("nonmatchingnode3" ),
+ },
+ {'facts.processor_count.lt' => '50'}
+ )
+ end
+
+ it "should return node names that match the search query options with the less than or equal to operator" do
+ assert_search_matches({
+ '/path/to/matching.yaml' => Puppet::Node::Facts.new("matchingnode", "architecture" => "i386", 'processor_count' => '5'),
+ '/path/to/matching1.yaml' => Puppet::Node::Facts.new("matchingnode1", "architecture" => "powerpc", 'processor_count' => '50', 'randomfact' => 'foo')
+ },
+ {
+ "/path/to/nonmatching.yaml" => Puppet::Node::Facts.new("nonmatchingnode", "architecture" => "powerpc", 'processor_count' => '100' ),
+ "/path/to/nonmatching2.yaml" => Puppet::Node::Facts.new("nonmatchingnode2", "architecture" => "i386", 'processor_count' => '5000'),
+ "/path/to/nonmatching3.yaml" => Puppet::Node::Facts.new("nonmatchingnode3" ),
+ },
+ {'facts.processor_count.le' => '50'}
+ )
+ end
+
+ it "should return node names that match the search query options with the greater than or equal to operator" do
+ assert_search_matches({
+ '/path/to/matching.yaml' => Puppet::Node::Facts.new("matchingnode", "architecture" => "i386", 'processor_count' => '100'),
+ '/path/to/matching1.yaml' => Puppet::Node::Facts.new("matchingnode1", "architecture" => "powerpc", 'processor_count' => '50', 'randomfact' => 'foo')
+ },
+ {
+ "/path/to/nonmatching.yaml" => Puppet::Node::Facts.new("nonmatchingnode", "architecture" => "powerpc", 'processor_count' => '40'),
+ "/path/to/nonmatching2.yaml" => Puppet::Node::Facts.new("nonmatchingnode2", "architecture" => "i386", 'processor_count' => '9' ),
+ "/path/to/nonmatching3.yaml" => Puppet::Node::Facts.new("nonmatchingnode3" ),
+ },
+ {'facts.processor_count.ge' => '50'}
+ )
+ end
+
+ it "should return node names that match the search query options with the not equal operator" do
+ assert_search_matches({
+ '/path/to/matching.yaml' => Puppet::Node::Facts.new("matchingnode", "architecture" => 'arm' ),
+ '/path/to/matching1.yaml' => Puppet::Node::Facts.new("matchingnode1", "architecture" => 'powerpc', 'randomfact' => 'foo')
+ },
+ {
+ "/path/to/nonmatching.yaml" => Puppet::Node::Facts.new("nonmatchingnode", "architecture" => "i386" ),
+ "/path/to/nonmatching2.yaml" => Puppet::Node::Facts.new("nonmatchingnode2", "architecture" => "i386", 'processor_count' => '9' ),
+ "/path/to/nonmatching3.yaml" => Puppet::Node::Facts.new("nonmatchingnode3" ),
+ },
+ {'facts.architecture.ne' => 'i386'}
+ )
+ end
+
+ def apply_timestamp(facts, timestamp)
+ facts.timestamp = timestamp
+ facts
+ end
+
+ it "should be able to query based on meta.timestamp.gt" do
+ assert_search_matches({
+ '/path/to/2010-11-01.yaml' => apply_timestamp(Puppet::Node::Facts.new("2010-11-01", {}), Time.parse("2010-11-01")),
+ '/path/to/2010-11-10.yaml' => apply_timestamp(Puppet::Node::Facts.new("2010-11-10", {}), Time.parse("2010-11-10")),
+ },
+ {
+ '/path/to/2010-10-01.yaml' => apply_timestamp(Puppet::Node::Facts.new("2010-10-01", {}), Time.parse("2010-10-01")),
+ '/path/to/2010-10-10.yaml' => apply_timestamp(Puppet::Node::Facts.new("2010-10-10", {}), Time.parse("2010-10-10")),
+ '/path/to/2010-10-15.yaml' => apply_timestamp(Puppet::Node::Facts.new("2010-10-15", {}), Time.parse("2010-10-15")),
+ },
+ {'meta.timestamp.gt' => '2010-10-15'}
+ )
+ end
+
+ it "should be able to query based on meta.timestamp.le" do
+ assert_search_matches({
+ '/path/to/2010-10-01.yaml' => apply_timestamp(Puppet::Node::Facts.new("2010-10-01", {}), Time.parse("2010-10-01")),
+ '/path/to/2010-10-10.yaml' => apply_timestamp(Puppet::Node::Facts.new("2010-10-10", {}), Time.parse("2010-10-10")),
+ '/path/to/2010-10-15.yaml' => apply_timestamp(Puppet::Node::Facts.new("2010-10-15", {}), Time.parse("2010-10-15")),
+ },
+ {
+ '/path/to/2010-11-01.yaml' => apply_timestamp(Puppet::Node::Facts.new("2010-11-01", {}), Time.parse("2010-11-01")),
+ '/path/to/2010-11-10.yaml' => apply_timestamp(Puppet::Node::Facts.new("2010-11-10", {}), Time.parse("2010-11-10")),
+ },
+ {'meta.timestamp.le' => '2010-10-15'}
+ )
+ end
+
+ it "should be able to query based on meta.timestamp.lt" do
+ assert_search_matches({
+ '/path/to/2010-10-01.yaml' => apply_timestamp(Puppet::Node::Facts.new("2010-10-01", {}), Time.parse("2010-10-01")),
+ '/path/to/2010-10-10.yaml' => apply_timestamp(Puppet::Node::Facts.new("2010-10-10", {}), Time.parse("2010-10-10")),
+ },
+ {
+ '/path/to/2010-11-01.yaml' => apply_timestamp(Puppet::Node::Facts.new("2010-11-01", {}), Time.parse("2010-11-01")),
+ '/path/to/2010-11-10.yaml' => apply_timestamp(Puppet::Node::Facts.new("2010-11-10", {}), Time.parse("2010-11-10")),
+ '/path/to/2010-10-15.yaml' => apply_timestamp(Puppet::Node::Facts.new("2010-10-15", {}), Time.parse("2010-10-15")),
+ },
+ {'meta.timestamp.lt' => '2010-10-15'}
+ )
+ end
+
+ it "should be able to query based on meta.timestamp.ge" do
+ assert_search_matches({
+ '/path/to/2010-11-01.yaml' => apply_timestamp(Puppet::Node::Facts.new("2010-11-01", {}), Time.parse("2010-11-01")),
+ '/path/to/2010-11-10.yaml' => apply_timestamp(Puppet::Node::Facts.new("2010-11-10", {}), Time.parse("2010-11-10")),
+ '/path/to/2010-10-15.yaml' => apply_timestamp(Puppet::Node::Facts.new("2010-10-15", {}), Time.parse("2010-10-15")),
+ },
+ {
+ '/path/to/2010-10-01.yaml' => apply_timestamp(Puppet::Node::Facts.new("2010-10-01", {}), Time.parse("2010-10-01")),
+ '/path/to/2010-10-10.yaml' => apply_timestamp(Puppet::Node::Facts.new("2010-10-10", {}), Time.parse("2010-10-10")),
+ },
+ {'meta.timestamp.ge' => '2010-10-15'}
+ )
+ end
+
+ it "should be able to query based on meta.timestamp.eq" do
+ assert_search_matches({
+ '/path/to/2010-10-15.yaml' => apply_timestamp(Puppet::Node::Facts.new("2010-10-15", {}), Time.parse("2010-10-15")),
+ },
+ {
+ '/path/to/2010-11-01.yaml' => apply_timestamp(Puppet::Node::Facts.new("2010-11-01", {}), Time.parse("2010-11-01")),
+ '/path/to/2010-11-10.yaml' => apply_timestamp(Puppet::Node::Facts.new("2010-11-10", {}), Time.parse("2010-11-10")),
+ '/path/to/2010-10-01.yaml' => apply_timestamp(Puppet::Node::Facts.new("2010-10-01", {}), Time.parse("2010-10-01")),
+ '/path/to/2010-10-10.yaml' => apply_timestamp(Puppet::Node::Facts.new("2010-10-10", {}), Time.parse("2010-10-10")),
+ },
+ {'meta.timestamp.eq' => '2010-10-15'}
+ )
+ end
+
+ it "should be able to query based on meta.timestamp" do
+ assert_search_matches({
+ '/path/to/2010-10-15.yaml' => apply_timestamp(Puppet::Node::Facts.new("2010-10-15", {}), Time.parse("2010-10-15")),
+ },
+ {
+ '/path/to/2010-11-01.yaml' => apply_timestamp(Puppet::Node::Facts.new("2010-11-01", {}), Time.parse("2010-11-01")),
+ '/path/to/2010-11-10.yaml' => apply_timestamp(Puppet::Node::Facts.new("2010-11-10", {}), Time.parse("2010-11-10")),
+ '/path/to/2010-10-01.yaml' => apply_timestamp(Puppet::Node::Facts.new("2010-10-01", {}), Time.parse("2010-10-01")),
+ '/path/to/2010-10-10.yaml' => apply_timestamp(Puppet::Node::Facts.new("2010-10-10", {}), Time.parse("2010-10-10")),
+ },
+ {'meta.timestamp' => '2010-10-15'}
+ )
+ end
+
+ it "should be able to query based on meta.timestamp.ne" do
+ assert_search_matches({
+ '/path/to/2010-11-01.yaml' => apply_timestamp(Puppet::Node::Facts.new("2010-11-01", {}), Time.parse("2010-11-01")),
+ '/path/to/2010-11-10.yaml' => apply_timestamp(Puppet::Node::Facts.new("2010-11-10", {}), Time.parse("2010-11-10")),
+ '/path/to/2010-10-01.yaml' => apply_timestamp(Puppet::Node::Facts.new("2010-10-01", {}), Time.parse("2010-10-01")),
+ '/path/to/2010-10-10.yaml' => apply_timestamp(Puppet::Node::Facts.new("2010-10-10", {}), Time.parse("2010-10-10")),
+ },
+ {
+ '/path/to/2010-10-15.yaml' => apply_timestamp(Puppet::Node::Facts.new("2010-10-15", {}), Time.parse("2010-10-15")),
+ },
+ {'meta.timestamp.ne' => '2010-10-15'}
+ )
+ end
+end
diff --git a/spec/unit/indirector/node/active_record_spec.rb b/spec/unit/indirector/node/active_record_spec.rb
index 6cc3f5132..3540ef738 100755
--- a/spec/unit/indirector/node/active_record_spec.rb
+++ b/spec/unit/indirector/node/active_record_spec.rb
@@ -3,7 +3,6 @@
require File.dirname(__FILE__) + '/../../../spec_helper'
require 'puppet/node'
-require 'spec/lib/puppet_spec/files.rb'
describe "Puppet::Node::ActiveRecord" do
include PuppetSpec::Files
diff --git a/spec/unit/indirector/node/ldap_spec.rb b/spec/unit/indirector/node/ldap_spec.rb
index f9c5efa07..042e7bd54 100755
--- a/spec/unit/indirector/node/ldap_spec.rb
+++ b/spec/unit/indirector/node/ldap_spec.rb
@@ -5,10 +5,6 @@ require File.dirname(__FILE__) + '/../../../spec_helper'
require 'puppet/indirector/node/ldap'
describe Puppet::Node::Ldap do
- before do
- Puppet::Node::Facts.stubs(:terminus_class).returns :yaml
- end
-
describe "when searching for a single node" do
before :each do
@searcher = Puppet::Node::Ldap.new
@@ -23,17 +19,17 @@ describe Puppet::Node::Ldap do
end
it "should convert the hostname into a search filter" do
- entry = stub 'entry', :dn => 'cn=mynode.domain.com,ou=hosts,dc=madstop,dc=com', :vals => %w{}, :to_hash => {"environment" => 'production'}
+ entry = stub 'entry', :dn => 'cn=mynode.domain.com,ou=hosts,dc=madstop,dc=com', :vals => %w{}, :to_hash => {}
@searcher.expects(:ldapsearch).with("(&(objectclass=puppetClient)(cn=#{@name}))").yields entry
- @searcher.name2hash(@name, 'production', 'parent')
+ @searcher.name2hash(@name)
end
it "should convert any found entry into a hash" do
- entry = stub 'entry', :dn => 'cn=mynode.domain.com,ou=hosts,dc=madstop,dc=com', :vals => %w{}, :to_hash => {"environment" => 'production'}
+ entry = stub 'entry', :dn => 'cn=mynode.domain.com,ou=hosts,dc=madstop,dc=com', :vals => %w{}, :to_hash => {}
@searcher.expects(:ldapsearch).with("(&(objectclass=puppetClient)(cn=#{@name}))").yields entry
- myhash = {"myhash" => true, :environment => 'production'}
+ myhash = {"myhash" => true}
@searcher.expects(:entry2hash).with(entry).returns myhash
- @searcher.name2hash(@name, 'production', 'parent').should == myhash
+ @searcher.name2hash(@name).should == myhash
end
# This heavily tests our entry2hash method, so we don't have to stub out the stupid entry information any more.
@@ -128,20 +124,20 @@ describe Puppet::Node::Ldap do
end
it "should search first for the provided key" do
- @searcher.expects(:name2hash).with("mynode.domain.com", 'production', 'child').returns({})
+ @searcher.expects(:name2hash).with("mynode.domain.com").returns({})
@searcher.find(@request)
end
it "should search for the short version of the provided key if the key looks like a hostname and no results are found for the key itself" do
- @searcher.expects(:name2hash).with("mynode.domain.com", 'production', 'child').returns(nil)
- @searcher.expects(:name2hash).with("mynode", 'production', 'child').returns({})
+ @searcher.expects(:name2hash).with("mynode.domain.com").returns(nil)
+ @searcher.expects(:name2hash).with("mynode").returns({})
@searcher.find(@request)
end
it "should search for default information if no information can be found for the key" do
- @searcher.expects(:name2hash).with("mynode.domain.com", 'production', 'child').returns(nil)
- @searcher.expects(:name2hash).with("mynode", 'production', 'child').returns(nil)
- @searcher.expects(:name2hash).with("default", 'production', 'child').returns({})
+ @searcher.expects(:name2hash).with("mynode.domain.com").returns(nil)
+ @searcher.expects(:name2hash).with("mynode").returns(nil)
+ @searcher.expects(:name2hash).with("default").returns({})
@searcher.find(@request)
end
@@ -162,8 +158,8 @@ describe Puppet::Node::Ldap do
end
it "should create the node with the correct name, even if it was found by a different name" do
- @searcher.expects(:name2hash).with("mynode.domain.com", 'production', 'child').returns nil
- @searcher.expects(:name2hash).with("mynode", 'production', 'child').returns @result
+ @searcher.expects(:name2hash).with("mynode.domain.com").returns nil
+ @searcher.expects(:name2hash).with("mynode").returns @result
Puppet::Node.expects(:new).with("mynode.domain.com").returns @node
@searcher.find(@request)
@@ -213,15 +209,17 @@ describe Puppet::Node::Ldap do
@parent = {:classes => [], :parameters => {}}
@parent_parent = {:classes => [], :parameters => {}}
- @searcher.stubs(:name2hash).with{|name, env, mode| name == @name}.returns(@entry)
- @searcher.stubs(:name2hash).with{|name, env, mode| name == 'parent'}.returns(@parent)
- @searcher.stubs(:name2hash).with{|name, env, mode| name == 'parent_parent'}.returns(@parent_parent)
+ @searcher.stubs(:name2hash).with(@name).returns(@entry)
+ @searcher.stubs(:name2hash).with('parent').returns(@parent)
+ @searcher.stubs(:name2hash).with('parent_parent').returns(@parent_parent)
@searcher.stubs(:parent_attribute).returns(:parent)
end
it "should search for the parent node" do
@entry[:parent] = "parent"
+ @searcher.expects(:name2hash).with(@name).returns @entry
+ @searcher.expects(:name2hash).with('parent').returns @parent
@searcher.find(@request)
end
@@ -229,7 +227,7 @@ describe Puppet::Node::Ldap do
it "should fail if the parent cannot be found" do
@entry[:parent] = "parent"
- @searcher.expects(:name2hash).with('parent', 'production', 'parent').returns nil
+ @searcher.expects(:name2hash).with('parent').returns nil
proc { @searcher.find(@request) }.should raise_error(Puppet::Error)
end
diff --git a/spec/unit/indirector/report/yaml_spec.rb b/spec/unit/indirector/report/yaml_spec.rb
new file mode 100644
index 000000000..610c9ae43
--- /dev/null
+++ b/spec/unit/indirector/report/yaml_spec.rb
@@ -0,0 +1,38 @@
+#!/usr/bin/env ruby
+
+require File.dirname(__FILE__) + '/../../../spec_helper'
+
+require 'puppet/transaction/report'
+require 'puppet/indirector/report/yaml'
+
+describe Puppet::Transaction::Report::Yaml do
+ it "should be a subclass of the Yaml terminus" do
+ Puppet::Transaction::Report::Yaml.superclass.should equal(Puppet::Indirector::Yaml)
+ end
+
+ it "should have documentation" do
+ Puppet::Transaction::Report::Yaml.doc.should_not be_nil
+ end
+
+ it "should be registered with the report indirection" do
+ indirection = Puppet::Indirector::Indirection.instance(:report)
+ Puppet::Transaction::Report::Yaml.indirection.should equal(indirection)
+ end
+
+ it "should have its name set to :yaml" do
+ Puppet::Transaction::Report::Yaml.name.should == :yaml
+ end
+
+ it "should inconditionnally save/load from the --lastrunreport setting" do
+ indirection = stub 'indirection', :name => :my_yaml, :register_terminus_type => nil
+ Puppet::Indirector::Indirection.stubs(:instance).with(:my_yaml).returns(indirection)
+ store_class = Class.new(Puppet::Transaction::Report::Yaml) do
+ def self.to_s
+ "MyYaml::MyType"
+ end
+ end
+ store = store_class.new
+
+ store.path(:me).should == Puppet[:lastrunreport]
+ end
+end
diff --git a/spec/unit/indirector/yaml_spec.rb b/spec/unit/indirector/yaml_spec.rb
index 134d476ba..86c13c5a0 100755
--- a/spec/unit/indirector/yaml_spec.rb
+++ b/spec/unit/indirector/yaml_spec.rb
@@ -40,6 +40,18 @@ describe Puppet::Indirector::Yaml, " when choosing file location" do
@store.path(:me).should =~ %r{^/client/yaml/dir}
end
+ it "should use the extension if one is specified" do
+ Puppet.run_mode.expects(:master?).returns true
+ Puppet.settings.expects(:value).with(:yamldir).returns "/server/yaml/dir"
+ @store.path(:me,'.farfignewton').should =~ %r{\.farfignewton$}
+ end
+
+ it "should assume an extension of .yaml if none is specified" do
+ Puppet.run_mode.expects(:master?).returns true
+ Puppet.settings.expects(:value).with(:yamldir).returns "/server/yaml/dir"
+ @store.path(:me).should =~ %r{\.yaml$}
+ end
+
it "should store all files in a single file root set in the Puppet defaults" do
@store.path(:me).should =~ %r{^#{@dir}}
end
@@ -120,8 +132,8 @@ describe Puppet::Indirector::Yaml, " when choosing file location" do
@request = stub 'request', :key => "*", :instance => @subject
@one = mock 'one'
@two = mock 'two'
- @store.expects(:base).returns "/my/yaml/dir"
- Dir.expects(:glob).with(File.join("/my/yaml/dir", @store.class.indirection_name.to_s, @request.key)).returns(%w{one.yaml two.yaml})
+ @store.expects(:path).with(@request.key,'').returns :glob
+ Dir.expects(:glob).with(:glob).returns(%w{one.yaml two.yaml})
YAML.expects(:load_file).with("one.yaml").returns @one;
YAML.expects(:load_file).with("two.yaml").returns @two;
@store.search(@request).should == [@one, @two]
@@ -130,16 +142,16 @@ describe Puppet::Indirector::Yaml, " when choosing file location" do
it "should return an array containing a single instance of fact when globbing 'one*'" do
@request = stub 'request', :key => "one*", :instance => @subject
@one = mock 'one'
- @store.expects(:base).returns "/my/yaml/dir"
- Dir.expects(:glob).with(File.join("/my/yaml/dir", @store.class.indirection_name.to_s, @request.key)).returns(%w{one.yaml})
+ @store.expects(:path).with(@request.key,'').returns :glob
+ Dir.expects(:glob).with(:glob).returns(%w{one.yaml})
YAML.expects(:load_file).with("one.yaml").returns @one;
@store.search(@request).should == [@one]
end
it "should return an empty array when the glob doesn't match anything" do
@request = stub 'request', :key => "f*ilglobcanfail*", :instance => @subject
- @store.expects(:base).returns "/my/yaml/dir"
- Dir.expects(:glob).with(File.join("/my/yaml/dir", @store.class.indirection_name.to_s, @request.key)).returns([])
+ @store.expects(:path).with(@request.key,'').returns :glob
+ Dir.expects(:glob).with(:glob).returns []
@store.search(@request).should == []
end
end
diff --git a/spec/unit/network/handler/fileserver_spec.rb b/spec/unit/network/handler/fileserver_spec.rb
index 40d1e57cd..b37d4f551 100644
--- a/spec/unit/network/handler/fileserver_spec.rb
+++ b/spec/unit/network/handler/fileserver_spec.rb
@@ -4,9 +4,8 @@ require File.dirname(__FILE__) + '/../../../spec_helper'
require 'puppet/network/handler/fileserver'
-
describe Puppet::Network::Handler::FileServer do
- require 'tmpdir'
+ include PuppetSpec::Files
def create_file(filename)
File.open(filename, "w") { |f| f.puts filename}
@@ -20,8 +19,7 @@ describe Puppet::Network::Handler::FileServer do
end
before do
- @basedir = File.join(Dir.tmpdir, "test_network_handler")
- Dir.mkdir(@basedir)
+ @basedir = tmpdir("test_network_handler")
@file = File.join(@basedir, "aFile")
@link = File.join(@basedir, "aLink")
create_file(@file)
diff --git a/spec/unit/network/http/api/v1_spec.rb b/spec/unit/network/http/api/v1_spec.rb
index c593242c0..84b98ddaf 100644
--- a/spec/unit/network/http/api/v1_spec.rb
+++ b/spec/unit/network/http/api/v1_spec.rb
@@ -32,7 +32,7 @@ describe Puppet::Network::HTTP::API::V1 do
end
it "should use the first field of the URI as the environment" do
- @tester.uri2indirection("GET", "/env/foo/bar", {}).environment.should == Puppet::Node::Environment.new("env")
+ @tester.uri2indirection("GET", "/env/foo/bar", {})[3][:environment].should == "env"
end
it "should fail if the environment is not alphanumeric" do
@@ -40,11 +40,11 @@ describe Puppet::Network::HTTP::API::V1 do
end
it "should use the environment from the URI even if one is specified in the parameters" do
- @tester.uri2indirection("GET", "/env/foo/bar", {:environment => "otherenv"}).environment.should == Puppet::Node::Environment.new("env")
+ @tester.uri2indirection("GET", "/env/foo/bar", {:environment => "otherenv"})[3][:environment].should == "env"
end
it "should use the second field of the URI as the indirection name" do
- @tester.uri2indirection("GET", "/env/foo/bar", {}).indirection_name.should == :foo
+ @tester.uri2indirection("GET", "/env/foo/bar", {})[0].should == "foo"
end
it "should fail if the indirection name is not alphanumeric" do
@@ -52,11 +52,11 @@ describe Puppet::Network::HTTP::API::V1 do
end
it "should use the remainder of the URI as the indirection key" do
- @tester.uri2indirection("GET", "/env/foo/bar", {}).key.should == "bar"
+ @tester.uri2indirection("GET", "/env/foo/bar", {})[2].should == "bar"
end
it "should support the indirection key being a /-separated file path" do
- @tester.uri2indirection("GET", "/env/foo/bee/baz/bomb", {}).key.should == "bee/baz/bomb"
+ @tester.uri2indirection("GET", "/env/foo/bee/baz/bomb", {})[2].should == "bee/baz/bomb"
end
it "should fail if no indirection key is specified" do
@@ -65,19 +65,31 @@ describe Puppet::Network::HTTP::API::V1 do
end
it "should choose 'find' as the indirection method if the http method is a GET and the indirection name is singular" do
- @tester.uri2indirection("GET", "/env/foo/bar", {}).method.should == :find
+ @tester.uri2indirection("GET", "/env/foo/bar", {})[1].should == :find
end
it "should choose 'search' as the indirection method if the http method is a GET and the indirection name is plural" do
- @tester.uri2indirection("GET", "/env/foos/bar", {}).method.should == :search
+ @tester.uri2indirection("GET", "/env/foos/bar", {})[1].should == :search
+ end
+
+ it "should choose 'find' as the indirection method if the http method is a GET and the indirection name is facts" do
+ @tester.uri2indirection("GET", "/env/facts/bar", {})[1].should == :find
+ end
+
+ it "should choose 'save' as the indirection method if the http method is a PUT and the indirection name is facts" do
+ @tester.uri2indirection("PUT", "/env/facts/bar", {})[1].should == :save
+ end
+
+ it "should choose 'search' as the indirection method if the http method is a GET and the indirection name is inventory" do
+ @tester.uri2indirection("GET", "/env/inventory/search", {})[1].should == :search
end
it "should choose 'delete' as the indirection method if the http method is a DELETE and the indirection name is singular" do
- @tester.uri2indirection("DELETE", "/env/foo/bar", {}).method.should == :destroy
+ @tester.uri2indirection("DELETE", "/env/foo/bar", {})[1].should == :destroy
end
it "should choose 'save' as the indirection method if the http method is a PUT and the indirection name is singular" do
- @tester.uri2indirection("PUT", "/env/foo/bar", {}).method.should == :save
+ @tester.uri2indirection("PUT", "/env/foo/bar", {})[1].should == :save
end
it "should fail if an indirection method cannot be picked" do
@@ -86,7 +98,8 @@ describe Puppet::Network::HTTP::API::V1 do
it "should URI unescape the indirection key" do
escaped = URI.escape("foo bar")
- @tester.uri2indirection("GET", "/env/foo/#{escaped}", {}).key.should == "foo bar"
+ indirection_name, method, key, params = @tester.uri2indirection("GET", "/env/foo/#{escaped}", {})
+ key.should == "foo bar"
end
end
diff --git a/spec/unit/network/http/handler_spec.rb b/spec/unit/network/http/handler_spec.rb
index 76a9c5530..16f1b5349 100755
--- a/spec/unit/network/http/handler_spec.rb
+++ b/spec/unit/network/http/handler_spec.rb
@@ -79,37 +79,22 @@ describe Puppet::Network::HTTP::Handler do
@handler.process(@request, @response)
end
- it "should call the 'do' method associated with the indirection method" do
- request = stub 'request'
- @handler.expects(:uri2indirection).returns request
+ it "should call the 'do' method and delegate authorization to the RestAuthorization layer" do
+ @handler.expects(:uri2indirection).returns(["facts", :mymethod, "key", {:node => "name"}])
- request.expects(:method).returns "mymethod"
+ @handler.expects(:do_mymethod).with("facts", "key", {:node => "name"}, @request, @response)
- @handler.expects(:do_mymethod).with(request, @request, @response)
-
- @handler.process(@request, @response)
- end
-
- it "should delegate authorization to the RestAuthorization layer" do
- request = stub 'request'
- @handler.expects(:uri2indirection).returns request
-
- request.expects(:method).returns "mymethod"
-
- @handler.expects(:do_mymethod).with(request, @request, @response)
-
- @handler.expects(:check_authorization).with(request)
+ @handler.expects(:check_authorization).with("facts", :mymethod, "key", {:node => "name"})
@handler.process(@request, @response)
end
it "should return 403 if the request is not authorized" do
- request = stub 'request'
- @handler.expects(:uri2indirection).returns request
+ @handler.expects(:uri2indirection).returns(["facts", :mymethod, "key", {:node => "name"}])
@handler.expects(:do_mymethod).never
- @handler.expects(:check_authorization).with(request).raises(Puppet::Network::AuthorizationError.new("forbindden"))
+ @handler.expects(:check_authorization).with("facts", :mymethod, "key", {:node => "name"}).raises(Puppet::Network::AuthorizationError.new("forbidden"))
@handler.expects(:set_response).with { |response, body, status| status == 403 }
@@ -117,7 +102,7 @@ describe Puppet::Network::HTTP::Handler do
end
it "should serialize a controller exception when an exception is thrown while finding the model instance" do
- @handler.expects(:uri2indirection).returns stub("request", :method => :find)
+ @handler.expects(:uri2indirection).returns(["facts", :find, "key", {:node => "name"}])
@handler.expects(:do_find).raises(ArgumentError, "The exception")
@handler.expects(:set_response).with { |response, body, status| body == "The exception" and status == 400 }
@@ -141,9 +126,8 @@ describe Puppet::Network::HTTP::Handler do
describe "when finding a model instance" do
before do
- @irequest = stub 'indirection_request', :method => :find, :indirection_name => "my_handler", :to_hash => {}, :key => "my_result", :model => @model_class
-
@model_class.stubs(:find).returns @result
+ Puppet::Indirector::Indirection.expects(:instance).with(:my_handler).returns( stub "indirection", :model => @model_class )
@format = stub 'format', :suitable? => true, :mime => "text/format", :name => "format"
Puppet::Network::FormatHandler.stubs(:format).returns @format
@@ -153,40 +137,37 @@ describe Puppet::Network::HTTP::Handler do
end
it "should use the indirection request to find the model class" do
- @irequest.expects(:model).returns @model_class
-
- @handler.do_find(@irequest, @request, @response)
+ @handler.do_find("my_handler", "my_result", {}, @request, @response)
end
it "should use the escaped request key" do
@model_class.expects(:find).with do |key, args|
key == "my_result"
end.returns @result
- @handler.do_find(@irequest, @request, @response)
+ @handler.do_find("my_handler", "my_result", {}, @request, @response)
end
it "should use a common method for determining the request parameters" do
- @irequest.stubs(:to_hash).returns(:foo => :baz, :bar => :xyzzy)
@model_class.expects(:find).with do |key, args|
args[:foo] == :baz and args[:bar] == :xyzzy
end.returns @result
- @handler.do_find(@irequest, @request, @response)
+ @handler.do_find("my_handler", "my_result", {:foo => :baz, :bar => :xyzzy}, @request, @response)
end
it "should set the content type to the first format specified in the accept header" do
@handler.expects(:accept_header).with(@request).returns "one,two"
@handler.expects(:set_content_type).with(@response, @oneformat)
- @handler.do_find(@irequest, @request, @response)
+ @handler.do_find("my_handler", "my_result", {}, @request, @response)
end
it "should fail if no accept header is provided" do
@handler.expects(:accept_header).with(@request).returns nil
- lambda { @handler.do_find(@irequest, @request, @response) }.should raise_error(ArgumentError)
+ lambda { @handler.do_find("my_handler", "my_result", {}, @request, @response) }.should raise_error(ArgumentError)
end
it "should fail if the accept header does not contain a valid format" do
@handler.expects(:accept_header).with(@request).returns ""
- lambda { @handler.do_find(@irequest, @request, @response) }.should raise_error(RuntimeError)
+ lambda { @handler.do_find("my_handler", "my_result", {}, @request, @response) }.should raise_error(RuntimeError)
end
it "should not use an unsuitable format" do
@@ -198,7 +179,7 @@ describe Puppet::Network::HTTP::Handler do
@handler.expects(:set_content_type).with(@response, bar) # the suitable one
- @handler.do_find(@irequest, @request, @response)
+ @handler.do_find("my_handler", "my_result", {}, @request, @response)
end
it "should render the result using the first format specified in the accept header" do
@@ -206,12 +187,12 @@ describe Puppet::Network::HTTP::Handler do
@handler.expects(:accept_header).with(@request).returns "one,two"
@result.expects(:render).with(@oneformat)
- @handler.do_find(@irequest, @request, @response)
+ @handler.do_find("my_handler", "my_result", {}, @request, @response)
end
it "should use the default status when a model find call succeeds" do
@handler.expects(:set_response).with { |response, body, status| status.nil? }
- @handler.do_find(@irequest, @request, @response)
+ @handler.do_find("my_handler", "my_result", {}, @request, @response)
end
it "should return a serialized object when a model find call succeeds" do
@@ -220,14 +201,14 @@ describe Puppet::Network::HTTP::Handler do
@handler.expects(:set_response).with { |response, body, status| body == "my_rendered_object" }
@model_class.stubs(:find).returns(@model_instance)
- @handler.do_find(@irequest, @request, @response)
+ @handler.do_find("my_handler", "my_result", {}, @request, @response)
end
it "should return a 404 when no model instance can be found" do
@model_class.stubs(:name).returns "my name"
@handler.expects(:set_response).with { |response, body, status| status == 404 }
@model_class.stubs(:find).returns(nil)
- @handler.do_find(@irequest, @request, @response)
+ @handler.do_find("my_handler", "my_result", {}, @request, @response)
end
it "should write a log message when no model instance can be found" do
@@ -236,7 +217,7 @@ describe Puppet::Network::HTTP::Handler do
Puppet.expects(:info).with("Could not find my_handler for 'my_result'")
- @handler.do_find(@irequest, @request, @response)
+ @handler.do_find("my_handler", "my_result", {}, @request, @response)
end
@@ -246,13 +227,13 @@ describe Puppet::Network::HTTP::Handler do
@handler.expects(:format_to_use).returns(@oneformat)
@model_instance.expects(:render).with(@oneformat).returns "my_rendered_object"
@model_class.stubs(:find).returns(@model_instance)
- @handler.do_find(@irequest, @request, @response)
+ @handler.do_find("my_handler", "my_result", {}, @request, @response)
end
end
describe "when searching for model instances" do
before do
- @irequest = stub 'indirection_request', :method => :find, :indirection_name => "my_handler", :to_hash => {}, :key => "key", :model => @model_class
+ Puppet::Indirector::Indirection.expects(:instance).with(:my_handler).returns( stub "indirection", :model => @model_class )
@result1 = mock 'result1'
@result2 = mock 'results'
@@ -269,29 +250,26 @@ describe Puppet::Network::HTTP::Handler do
end
it "should use the indirection request to find the model" do
- @irequest.expects(:model).returns @model_class
-
- @handler.do_search(@irequest, @request, @response)
+ @handler.do_search("my_handler", "my_result", {}, @request, @response)
end
it "should use a common method for determining the request parameters" do
- @irequest.stubs(:to_hash).returns(:foo => :baz, :bar => :xyzzy)
@model_class.expects(:search).with do |key, args|
args[:foo] == :baz and args[:bar] == :xyzzy
end.returns @result
- @handler.do_search(@irequest, @request, @response)
+ @handler.do_search("my_handler", "my_result", {:foo => :baz, :bar => :xyzzy}, @request, @response)
end
it "should use the default status when a model search call succeeds" do
@model_class.stubs(:search).returns(@result)
- @handler.do_search(@irequest, @request, @response)
+ @handler.do_search("my_handler", "my_result", {}, @request, @response)
end
it "should set the content type to the first format returned by the accept header" do
@handler.expects(:accept_header).with(@request).returns "one,two"
@handler.expects(:set_content_type).with(@response, @oneformat)
- @handler.do_search(@irequest, @request, @response)
+ @handler.do_search("my_handler", "my_result", {}, @request, @response)
end
it "should return a list of serialized objects when a model search call succeeds" do
@@ -302,57 +280,56 @@ describe Puppet::Network::HTTP::Handler do
@model_class.expects(:render_multiple).with(@oneformat, @result).returns "my rendered instances"
@handler.expects(:set_response).with { |response, data| data == "my rendered instances" }
- @handler.do_search(@irequest, @request, @response)
+ @handler.do_search("my_handler", "my_result", {}, @request, @response)
end
- it "should return a 404 when searching returns an empty array" do
- @model_class.stubs(:name).returns "my name"
- @handler.expects(:set_response).with { |response, body, status| status == 404 }
+ it "should return [] when searching returns an empty array" do
+ @handler.expects(:accept_header).with(@request).returns "one,two"
@model_class.stubs(:search).returns([])
- @handler.do_search(@irequest, @request, @response)
+ @model_class.expects(:render_multiple).with(@oneformat, []).returns "[]"
+
+
+ @handler.expects(:set_response).with { |response, data| data == "[]" }
+ @handler.do_search("my_handler", "my_result", {}, @request, @response)
end
it "should return a 404 when searching returns nil" do
@model_class.stubs(:name).returns "my name"
@handler.expects(:set_response).with { |response, body, status| status == 404 }
- @model_class.stubs(:search).returns([])
- @handler.do_search(@irequest, @request, @response)
+ @model_class.stubs(:search).returns(nil)
+ @handler.do_search("my_handler", "my_result", {}, @request, @response)
end
end
describe "when destroying a model instance" do
before do
- @irequest = stub 'indirection_request', :method => :destroy, :indirection_name => "my_handler", :to_hash => {}, :key => "key", :model => @model_class
+ Puppet::Indirector::Indirection.expects(:instance).with(:my_handler).returns( stub "indirection", :model => @model_class )
@result = stub 'result', :render => "the result"
@model_class.stubs(:destroy).returns @result
end
it "should use the indirection request to find the model" do
- @irequest.expects(:model).returns @model_class
-
- @handler.do_destroy(@irequest, @request, @response)
+ @handler.do_destroy("my_handler", "my_result", {}, @request, @response)
end
it "should use the escaped request key to destroy the instance in the model" do
- @irequest.expects(:key).returns "foo bar"
@model_class.expects(:destroy).with do |key, args|
key == "foo bar"
end
- @handler.do_destroy(@irequest, @request, @response)
+ @handler.do_destroy("my_handler", "foo bar", {}, @request, @response)
end
it "should use a common method for determining the request parameters" do
- @irequest.stubs(:to_hash).returns(:foo => :baz, :bar => :xyzzy)
@model_class.expects(:destroy).with do |key, args|
args[:foo] == :baz and args[:bar] == :xyzzy
end
- @handler.do_destroy(@irequest, @request, @response)
+ @handler.do_destroy("my_handler", "my_result", {:foo => :baz, :bar => :xyzzy}, @request, @response)
end
it "should use the default status code a model destroy call succeeds" do
@handler.expects(:set_response).with { |response, body, status| status.nil? }
- @handler.do_destroy(@irequest, @request, @response)
+ @handler.do_destroy("my_handler", "my_result", {}, @request, @response)
end
it "should return a yaml-encoded result when a model destroy call succeeds" do
@@ -361,13 +338,13 @@ describe Puppet::Network::HTTP::Handler do
@handler.expects(:set_response).with { |response, body, status| body == "the result" }
- @handler.do_destroy(@irequest, @request, @response)
+ @handler.do_destroy("my_handler", "my_result", {}, @request, @response)
end
end
describe "when saving a model instance" do
before do
- @irequest = stub 'indirection_request', :method => :save, :indirection_name => "my_handler", :to_hash => {}, :key => "key", :model => @model_class
+ Puppet::Indirector::Indirection.stubs(:instance).with(:my_handler).returns( stub "indirection", :model => @model_class )
@handler.stubs(:body).returns('my stuff')
@handler.stubs(:content_type_header).returns("text/yaml")
@@ -383,43 +360,41 @@ describe Puppet::Network::HTTP::Handler do
end
it "should use the indirection request to find the model" do
- @irequest.expects(:model).returns @model_class
-
- @handler.do_save(@irequest, @request, @response)
+ @handler.do_save("my_handler", "my_result", {}, @request, @response)
end
it "should use the 'body' hook to retrieve the body of the request" do
@handler.expects(:body).returns "my body"
@model_class.expects(:convert_from).with { |format, body| body == "my body" }.returns @model_instance
- @handler.do_save(@irequest, @request, @response)
+ @handler.do_save("my_handler", "my_result", {}, @request, @response)
end
it "should fail to save model if data is not specified" do
@handler.stubs(:body).returns('')
- lambda { @handler.do_save(@irequest, @request, @response) }.should raise_error(ArgumentError)
+ lambda { @handler.do_save("my_handler", "my_result", {}, @request, @response) }.should raise_error(ArgumentError)
end
it "should use a common method for determining the request parameters" do
@model_instance.expects(:save).with('key').once
- @handler.do_save(@irequest, @request, @response)
+ @handler.do_save("my_handler", "key", {}, @request, @response)
end
it "should use the default status when a model save call succeeds" do
@handler.expects(:set_response).with { |response, body, status| status.nil? }
- @handler.do_save(@irequest, @request, @response)
+ @handler.do_save("my_handler", "my_result", {}, @request, @response)
end
it "should return the yaml-serialized result when a model save call succeeds" do
@model_instance.stubs(:save).returns(@model_instance)
@model_instance.expects(:to_yaml).returns('foo')
- @handler.do_save(@irequest, @request, @response)
+ @handler.do_save("my_handler", "my_result", {}, @request, @response)
end
it "should set the content to yaml" do
@handler.expects(:set_content_type).with(@response, @yamlformat)
- @handler.do_save(@irequest, @request, @response)
+ @handler.do_save("my_handler", "my_result", {}, @request, @response)
end
it "should use the content-type header to know the body format" do
@@ -428,7 +403,7 @@ describe Puppet::Network::HTTP::Handler do
@model_class.expects(:convert_from).with { |format, body| format == "format" }.returns @model_instance
- @handler.do_save(@irequest, @request, @response)
+ @handler.do_save("my_handler", "my_result", {}, @request, @response)
end
end
end
diff --git a/spec/unit/network/http/rack/rest_spec.rb b/spec/unit/network/http/rack/rest_spec.rb
index 9b3e1e59f..96cf84c37 100755
--- a/spec/unit/network/http/rack/rest_spec.rb
+++ b/spec/unit/network/http/rack/rest_spec.rb
@@ -82,8 +82,8 @@ describe "Puppet::Network::HTTP::RackREST" do
@file.stubs(:is_a?).with(File).returns(true)
end
- it "should set the Content-Length header" do
- @response.expects(:[]=).with("Content-Length", 100)
+ it "should set the Content-Length header as a string" do
+ @response.expects(:[]=).with("Content-Length", '100')
@handler.set_response(@response, @file, 200)
end
@@ -246,4 +246,4 @@ describe Puppet::Network::HTTP::RackREST::RackFile do
@file.expects(:close)
@rackfile.close
end
-end \ No newline at end of file
+end
diff --git a/spec/unit/network/http/rack/xmlrpc_spec.rb b/spec/unit/network/http/rack/xmlrpc_spec.rb
index 63ba28bf2..870438f2c 100755
--- a/spec/unit/network/http/rack/xmlrpc_spec.rb
+++ b/spec/unit/network/http/rack/xmlrpc_spec.rb
@@ -1,6 +1,7 @@
#!/usr/bin/env ruby
require File.dirname(__FILE__) + '/../../../../spec_helper'
+require 'puppet/network/handler'
require 'puppet/network/http/rack' if Puppet.features.rack?
require 'puppet/network/http/rack/xmlrpc' if Puppet.features.rack?
diff --git a/spec/unit/network/http/rack_spec.rb b/spec/unit/network/http/rack_spec.rb
index df42a1ffa..8be9ccb50 100755
--- a/spec/unit/network/http/rack_spec.rb
+++ b/spec/unit/network/http/rack_spec.rb
@@ -1,6 +1,7 @@
#!/usr/bin/env ruby
require File.dirname(__FILE__) + '/../../../spec_helper'
+require 'puppet/network/handler'
require 'puppet/network/http/rack' if Puppet.features.rack?
describe "Puppet::Network::HTTP::Rack" do
diff --git a/spec/unit/network/http/webrick/rest_spec.rb b/spec/unit/network/http/webrick/rest_spec.rb
index aa2b93176..b00c62dc4 100755
--- a/spec/unit/network/http/webrick/rest_spec.rb
+++ b/spec/unit/network/http/webrick/rest_spec.rb
@@ -2,6 +2,7 @@
require File.dirname(__FILE__) + '/../../../../spec_helper'
require 'puppet/network/http'
+require 'webrick'
require 'puppet/network/http/webrick/rest'
describe Puppet::Network::HTTP::WEBrickREST do
diff --git a/spec/unit/network/http/webrick_spec.rb b/spec/unit/network/http/webrick_spec.rb
index 2a6ef2268..8e7c92b71 100755
--- a/spec/unit/network/http/webrick_spec.rb
+++ b/spec/unit/network/http/webrick_spec.rb
@@ -4,6 +4,7 @@
# Copyright (c) 2007. All rights reserved.
require File.dirname(__FILE__) + '/../../../spec_helper'
+require 'puppet/network/handler'
require 'puppet/network/http'
require 'puppet/network/http/webrick'
diff --git a/spec/unit/network/rest_authconfig_spec.rb b/spec/unit/network/rest_authconfig_spec.rb
index 351f3f040..e81eb41ed 100755
--- a/spec/unit/network/rest_authconfig_spec.rb
+++ b/spec/unit/network/rest_authconfig_spec.rb
@@ -30,9 +30,6 @@ describe Puppet::Network::RestAuthConfig do
@acl = stub_everything 'rights'
@authconfig.rights = @acl
-
- @request = stub 'request', :indirection_name => "path", :key => "to/resource", :ip => "127.0.0.1",
- :node => "me", :method => :save, :environment => :env, :authenticated => true
end
it "should use the puppet default rest authorization file" do
@@ -41,16 +38,10 @@ describe Puppet::Network::RestAuthConfig do
Puppet::Network::RestAuthConfig.new(nil, false)
end
- it "should read the config file when needed" do
- @authconfig.expects(:read)
-
- @authconfig.allowed?(@request)
- end
-
it "should ask for authorization to the ACL subsystem" do
@acl.expects(:fail_on_deny).with("/path/to/resource", :node => "me", :ip => "127.0.0.1", :method => :save, :environment => :env, :authenticated => true)
- @authconfig.allowed?(@request)
+ @authconfig.allowed?("path", :save, "to/resource", :ip => "127.0.0.1", :node => "me", :environment => :env, :authenticated => true)
end
describe "when defining an acl with mk_acl" do
diff --git a/spec/unit/network/rest_authorization_spec.rb b/spec/unit/network/rest_authorization_spec.rb
deleted file mode 100755
index 0cb0bcee9..000000000
--- a/spec/unit/network/rest_authorization_spec.rb
+++ /dev/null
@@ -1,43 +0,0 @@
-#!/usr/bin/env ruby
-
-require File.dirname(__FILE__) + '/../../spec_helper'
-
-require 'puppet/network/rest_authorization'
-
-class RestAuthorized
- include Puppet::Network::RestAuthorization
-end
-
-
-describe Puppet::Network::RestAuthorization do
- before :each do
- @auth = RestAuthorized.new
- @authconig = stub 'authconfig'
- @auth.stubs(:authconfig).returns(@authconfig)
-
- @request = stub_everything 'request'
- @request.stubs(:method).returns(:find)
- @request.stubs(:node).returns("node")
- @request.stubs(:ip).returns("ip")
- end
-
- describe "when testing request authorization" do
- it "should delegate to the current rest authconfig" do
- @authconfig.expects(:allowed?).with(@request).returns(true)
-
- @auth.check_authorization(@request)
- end
-
- it "should raise an AuthorizationError if authconfig raises an AuthorizationError" do
- @authconfig.expects(:allowed?).with(@request).raises(Puppet::Network::AuthorizationError.new("forbidden"))
-
- lambda { @auth.check_authorization(@request) }.should raise_error(Puppet::Network::AuthorizationError)
- end
-
- it "should not raise an AuthorizationError if request is allowed" do
- @authconfig.expects(:allowed?).with(@request).returns(true)
-
- lambda { @auth.check_authorization(@request) }.should_not raise_error(Puppet::Network::AuthorizationError)
- end
- end
-end
diff --git a/spec/unit/network/server_spec.rb b/spec/unit/network/server_spec.rb
index ccd9c082e..c2496dcca 100755
--- a/spec/unit/network/server_spec.rb
+++ b/spec/unit/network/server_spec.rb
@@ -5,6 +5,7 @@
require File.dirname(__FILE__) + '/../../spec_helper'
require 'puppet/network/server'
+require 'puppet/network/handler'
describe Puppet::Network::Server do
before do
@@ -161,11 +162,7 @@ describe Puppet::Network::Server do
describe "when creating its pidfile" do
it "should use an exclusive mutex" do
Puppet.settings.expects(:value).with(:name).returns "me"
-
- sync = mock 'sync'
- Puppet::Util.expects(:sync).with("me").returns sync
-
- sync.expects(:synchronize).with(Sync::EX)
+ Puppet::Util.expects(:synchronize_on).with("me",Sync::EX)
@server.create_pidfile
end
@@ -198,11 +195,7 @@ describe Puppet::Network::Server do
describe "when removing its pidfile" do
it "should use an exclusive mutex" do
Puppet.settings.expects(:value).with(:name).returns "me"
-
- sync = mock 'sync'
- Puppet::Util.expects(:sync).with("me").returns sync
-
- sync.expects(:synchronize).with(Sync::EX)
+ Puppet::Util.expects(:synchronize_on).with("me",Sync::EX)
@server.remove_pidfile
end
diff --git a/spec/unit/network/xmlrpc/client_spec.rb b/spec/unit/network/xmlrpc/client_spec.rb
index 0b9b2b095..8440d39fa 100755
--- a/spec/unit/network/xmlrpc/client_spec.rb
+++ b/spec/unit/network/xmlrpc/client_spec.rb
@@ -1,4 +1,5 @@
#!/usr/bin/env ruby
+require 'puppet/network/client'
Dir.chdir(File.dirname(__FILE__)) { (s = lambda { |f| File.exist?(f) ? require(f) : Dir.chdir("..") { s.call(f) } }).call("spec/spec_helper.rb") }
diff --git a/spec/unit/node/environment_spec.rb b/spec/unit/node/environment_spec.rb
index b400865a2..be2980879 100755
--- a/spec/unit/node/environment_spec.rb
+++ b/spec/unit/node/environment_spec.rb
@@ -52,7 +52,8 @@ describe Puppet::Node::Environment do
before do
@env = Puppet::Node::Environment.new("dev")
@collection = Puppet::Resource::TypeCollection.new(@env)
- @collection.stubs(:perform_initial_import)
+ @env.stubs(:perform_initial_import).returns(Puppet::Parser::AST::Hostclass.new(''))
+ Thread.current[:known_resource_types] = nil
end
it "should create a resource type collection if none exists" do
@@ -65,19 +66,46 @@ describe Puppet::Node::Environment do
end
it "should perform the initial import when creating a new collection" do
- @collection.expects(:perform_initial_import)
- Puppet::Resource::TypeCollection.expects(:new).returns @collection
+ @env = Puppet::Node::Environment.new("dev")
+ @env.expects(:perform_initial_import).returns(Puppet::Parser::AST::Hostclass.new(''))
+ @env.known_resource_types
+ end
+
+ it "should return the same collection even if stale if it's the same thread" do
+ Puppet::Resource::TypeCollection.stubs(:new).returns @collection
+ @env.known_resource_types.stubs(:stale?).returns true
+
+ @env.known_resource_types.should equal(@collection)
+ end
+
+ it "should return the current thread associated collection if there is one" do
+ Thread.current[:known_resource_types] = @collection
+ @env.known_resource_types.should equal(@collection)
+ end
+
+ it "should give to all threads the same collection if it didn't change" do
+ Puppet::Resource::TypeCollection.expects(:new).with(@env).returns @collection
@env.known_resource_types
+
+ t = Thread.new {
+ @env.known_resource_types.should equal(@collection)
+ }
+ t.join
end
- it "should create and return a new collection rather than returning a stale collection" do
- @env.known_resource_types.expects(:stale?).returns true
+ it "should give to new threads a new collection if it isn't stale" do
+ Puppet::Resource::TypeCollection.expects(:new).with(@env).returns @collection
+ @env.known_resource_types.expects(:stale?).returns(true)
Puppet::Resource::TypeCollection.expects(:new).returns @collection
- @env.known_resource_types.should equal(@collection)
+ t = Thread.new {
+ @env.known_resource_types.should equal(@collection)
+ }
+ t.join
end
+
end
[:modulepath, :manifestdir].each do |setting|
@@ -245,4 +273,56 @@ describe Puppet::Node::Environment do
@helper.environment.name.should == :foo
end
end
+
+ describe "when performing initial import" do
+ before do
+ @parser = stub 'parser', :file= => nil, :string => nil, :parse => nil
+ Puppet::Parser::Parser.stubs(:new).returns @parser
+ @env = Puppet::Node::Environment.new("env")
+ end
+
+ it "should create a new parser instance" do
+ Puppet::Parser::Parser.expects(:new).returns @parser
+ @env.instance_eval { perform_initial_import }
+ end
+
+ it "should set the parser's string to the 'code' setting and parse if code is available" do
+ Puppet.settings[:code] = "my code"
+ @parser.expects(:string=).with "my code"
+ @parser.expects(:parse)
+ @env.instance_eval { perform_initial_import }
+ end
+
+ it "should set the parser's file to the 'manifest' setting and parse if no code is available and the manifest is available" do
+ File.stubs(:expand_path).with("/my/file").returns "/my/file"
+ File.expects(:exist?).with("/my/file").returns true
+ Puppet.settings[:manifest] = "/my/file"
+ @parser.expects(:file=).with "/my/file"
+ @parser.expects(:parse)
+ @env.instance_eval { perform_initial_import }
+ end
+
+ it "should not attempt to load a manifest if none is present" do
+ File.stubs(:expand_path).with("/my/file").returns "/my/file"
+ File.expects(:exist?).with("/my/file").returns false
+ Puppet.settings[:manifest] = "/my/file"
+ @parser.expects(:file=).never
+ @parser.expects(:parse).never
+ @env.instance_eval { perform_initial_import }
+ end
+
+ it "should fail helpfully if there is an error importing" do
+ File.stubs(:exist?).returns true
+ @parser.expects(:parse).raises ArgumentError
+ lambda { @env.instance_eval { perform_initial_import } }.should raise_error(Puppet::Error)
+ end
+
+ it "should not do anything if the ignore_import settings is set" do
+ Puppet.settings[:ignoreimport] = true
+ @parser.expects(:string=).never
+ @parser.expects(:file=).never
+ @parser.expects(:parse).never
+ @env.instance_eval { perform_initial_import }
+ end
+ end
end
diff --git a/spec/unit/node/facts_spec.rb b/spec/unit/node/facts_spec.rb
index a2f4ab9f0..cb2aa3dc7 100755
--- a/spec/unit/node/facts_spec.rb
+++ b/spec/unit/node/facts_spec.rb
@@ -88,9 +88,20 @@ describe Puppet::Node::Facts, "when indirecting" do
@facts.save
end
- it "should default to the 'facter' terminus" do
- Puppet::Node::Facts.indirection.terminus_class.should == :facter
+ describe "when the Puppet application is 'master'" do
+ it "should default to the 'yaml' terminus" do
+ pending "Cannot test the behavior of defaults in defaults.rb"
+ # Puppet::Node::Facts.indirection.terminus_class.should == :yaml
+ end
end
+
+ describe "when the Puppet application is not 'master'" do
+ it "should default to the 'facter' terminus" do
+ pending "Cannot test the behavior of defaults in defaults.rb"
+ # Puppet::Node::Facts.indirection.terminus_class.should == :facter
+ end
+ end
+
end
describe "when storing and retrieving" do
@@ -98,5 +109,29 @@ describe Puppet::Node::Facts, "when indirecting" do
facts = Puppet::Node::Facts.new("me", "one" => "two", "three" => "four")
facts.values[:_timestamp].should be_instance_of(Time)
end
+
+ describe "using pson" do
+ before :each do
+ @timestamp = Time.parse("Thu Oct 28 11:16:31 -0700 2010")
+ @expiration = Time.parse("Thu Oct 28 11:21:31 -0700 2010")
+ end
+
+ it "should accept properly formatted pson" do
+ pson = %Q({"name": "foo", "expiration": "#{@expiration}", "timestamp": "#{@timestamp}", "values": {"a": "1", "b": "2", "c": "3"}})
+ format = Puppet::Network::FormatHandler.format('pson')
+ facts = format.intern(Puppet::Node::Facts,pson)
+ facts.name.should == 'foo'
+ facts.expiration.should == @expiration
+ facts.values.should == {'a' => '1', 'b' => '2', 'c' => '3', :_timestamp => @timestamp}
+ end
+
+ it "should generate properly formatted pson" do
+ Time.stubs(:now).returns(@timestamp)
+ facts = Puppet::Node::Facts.new("foo", {'a' => 1, 'b' => 2, 'c' => 3})
+ facts.expiration = @expiration
+ pson = PSON.parse(facts.to_pson)
+ pson.should == {"name"=>"foo", "timestamp"=>@timestamp.to_s, "expiration"=>@expiration.to_s, "values"=>{"a"=>1, "b"=>2, "c"=>3}}
+ end
+ end
end
end
diff --git a/spec/unit/parameter/value_collection_spec.rb b/spec/unit/parameter/value_collection_spec.rb
index 78c2c5263..cb82d1517 100755
--- a/spec/unit/parameter/value_collection_spec.rb
+++ b/spec/unit/parameter/value_collection_spec.rb
@@ -68,12 +68,12 @@ describe Puppet::Parameter::ValueCollection do
it "should correctly generate documentation for values" do
@collection.newvalues :foo
- @collection.doc.should be_include("Valid values are ``foo``")
+ @collection.doc.should be_include("Valid values are `foo`")
end
it "should correctly generate documentation for regexes" do
@collection.newvalues %r{\w+}
- @collection.doc.should be_include("Values can match ``/\\w+/``")
+ @collection.doc.should be_include("Values can match `/\\w+/`")
end
it "should be able to find the first matching value" do
diff --git a/spec/unit/parser/ast/astarray_spec.rb b/spec/unit/parser/ast/astarray_spec.rb
index f79d6c533..8794848b6 100755
--- a/spec/unit/parser/ast/astarray_spec.rb
+++ b/spec/unit/parser/ast/astarray_spec.rb
@@ -23,43 +23,26 @@ describe Puppet::Parser::AST::ASTArray do
operator.evaluate(@scope)
end
- it "should evaluate childrens of type ASTArray" do
- item1 = stub "item1", :is_a? => true
- item2 = stub "item2"
- item2.stubs(:is_a?).with(Puppet::Parser::AST).returns(true)
- item2.stubs(:instance_of?).with(Puppet::Parser::AST::ASTArray).returns(true)
- item2.stubs(:each).yields(item1)
-
- item1.expects(:safeevaluate).with(@scope).returns(123)
-
- operator = Puppet::Parser::AST::ASTArray.new :children => [item2]
- operator.evaluate(@scope).should == [123]
- end
-
- it "should flatten children coming from children ASTArray" do
- item1 = stub "item1", :is_a? => true
- item2 = stub "item2"
- item2.stubs(:is_a?).with(Puppet::Parser::AST).returns(true)
- item2.stubs(:instance_of?).with(Puppet::Parser::AST::ASTArray).returns(true)
- item2.stubs(:each).yields([item1])
-
- item1.expects(:safeevaluate).with(@scope).returns(123)
-
- operator = Puppet::Parser::AST::ASTArray.new :children => [item2]
- operator.evaluate(@scope).should == [123]
+ it "should not flatten children coming from children ASTArray" do
+ item = Puppet::Parser::AST::String.new :value => 'foo'
+ inner_array = Puppet::Parser::AST::ASTArray.new :children => [item, item]
+ operator = Puppet::Parser::AST::ASTArray.new :children => [inner_array, inner_array]
+ operator.evaluate(@scope).should == [['foo', 'foo'], ['foo', 'foo']]
end
it "should not flatten the results of children evaluation" do
- item1 = stub "item1", :is_a? => true
- item2 = stub "item2"
- item2.stubs(:is_a?).with(Puppet::Parser::AST).returns(true)
- item2.stubs(:instance_of?).with(Puppet::Parser::AST::ASTArray).returns(true)
- item2.stubs(:each).yields([item1])
-
- item1.expects(:safeevaluate).with(@scope).returns([123])
+ item = Puppet::Parser::AST::String.new :value => 'foo'
+ item.stubs(:evaluate).returns(['foo'])
+ operator = Puppet::Parser::AST::ASTArray.new :children => [item, item]
+ operator.evaluate(@scope).should == [['foo'], ['foo']]
+ end
- operator = Puppet::Parser::AST::ASTArray.new :children => [item2]
- operator.evaluate(@scope).should == [[123]]
+ it "should discard nil results from children evaluation" do
+ item1 = Puppet::Parser::AST::String.new :value => 'foo'
+ item2 = Puppet::Parser::AST::String.new :value => 'foo'
+ item2.stubs(:evaluate).returns(nil)
+ operator = Puppet::Parser::AST::ASTArray.new :children => [item1, item2]
+ operator.evaluate(@scope).should == ['foo']
end
it "should return a valid string with to_s" do
diff --git a/spec/unit/parser/ast/collection_spec.rb b/spec/unit/parser/ast/collection_spec.rb
index 3f7878a99..392a2c0f0 100755
--- a/spec/unit/parser/ast/collection_spec.rb
+++ b/spec/unit/parser/ast/collection_spec.rb
@@ -5,6 +5,8 @@ require File.dirname(__FILE__) + '/../../../spec_helper'
describe Puppet::Parser::AST::Collection do
before :each do
@scope = stub_everything 'scope'
+ @mytype = stub_everything('mytype')
+ @scope.stubs(:find_resource_type).returns @mytype
@compiler = stub_everything 'compile'
@scope.stubs(:compiler).returns(@compiler)
@@ -24,6 +26,8 @@ describe Puppet::Parser::AST::Collection do
it "should instantiate a Collector for this type" do
collection = Puppet::Parser::AST::Collection.new :form => :virtual, :type => "test"
+ @test_type = stub 'type', :name => 'test'
+ @scope.expects(:find_resource_type).with('test').returns @test_type
Puppet::Parser::Collector.expects(:new).with(@scope, "test", nil, nil, :virtual)
diff --git a/spec/unit/parser/ast/definition_spec.rb b/spec/unit/parser/ast/definition_spec.rb
new file mode 100644
index 000000000..b7b2c851c
--- /dev/null
+++ b/spec/unit/parser/ast/definition_spec.rb
@@ -0,0 +1,22 @@
+#!/usr/bin/env ruby
+
+require File.dirname(__FILE__) + '/../../../spec_helper'
+
+describe Puppet::Parser::AST::Definition do
+ it "should make its context available through an accessor" do
+ definition = Puppet::Parser::AST::Definition.new('foo', :line => 5)
+ definition.context.should == {:line => 5}
+ end
+
+ describe "when instantiated" do
+ it "should create a definition with the proper type, name, context, and module name" do
+ definition = Puppet::Parser::AST::Definition.new('foo', :line => 5)
+ instantiated_definitions = definition.instantiate('modname')
+ instantiated_definitions.length.should == 1
+ instantiated_definitions[0].type.should == :definition
+ instantiated_definitions[0].name.should == 'foo'
+ instantiated_definitions[0].line.should == 5
+ instantiated_definitions[0].module_name.should == 'modname'
+ end
+ end
+end
diff --git a/spec/unit/parser/ast/function_spec.rb b/spec/unit/parser/ast/function_spec.rb
index c57c7f098..38e344157 100644
--- a/spec/unit/parser/ast/function_spec.rb
+++ b/spec/unit/parser/ast/function_spec.rb
@@ -61,20 +61,30 @@ describe Puppet::Parser::AST::Function do
end
it "should call the underlying ruby function" do
- argument = stub 'arg', :safeevaluate => "nothing"
+ argument = stub 'arg', :safeevaluate => ["nothing"]
Puppet::Parser::Functions.stubs(:function).with("exist").returns(true)
func = Puppet::Parser::AST::Function.new :name => "exist", :ftype => :statement, :arguments => argument
- @scope.expects(:function_exist).with("nothing")
+ @scope.expects(:function_exist).with(["nothing"])
+
+ func.evaluate(@scope)
+ end
+
+ it "should convert :undef to '' in arguments" do
+ argument = stub 'arg', :safeevaluate => ["foo", :undef, "bar"]
+ Puppet::Parser::Functions.stubs(:function).with("exist").returns(true)
+ func = Puppet::Parser::AST::Function.new :name => "exist", :ftype => :statement, :arguments => argument
+
+ @scope.expects(:function_exist).with(["foo", "", "bar"])
func.evaluate(@scope)
end
it "should return the ruby function return for rvalue functions" do
- argument = stub 'arg', :safeevaluate => "nothing"
+ argument = stub 'arg', :safeevaluate => ["nothing"]
Puppet::Parser::Functions.stubs(:function).with("exist").returns(true)
func = Puppet::Parser::AST::Function.new :name => "exist", :ftype => :statement, :arguments => argument
- @scope.stubs(:function_exist).with("nothing").returns("returning")
+ @scope.stubs(:function_exist).with(["nothing"]).returns("returning")
func.evaluate(@scope).should == "returning"
end
diff --git a/spec/unit/parser/ast/hostclass_spec.rb b/spec/unit/parser/ast/hostclass_spec.rb
new file mode 100644
index 000000000..b22eba98b
--- /dev/null
+++ b/spec/unit/parser/ast/hostclass_spec.rb
@@ -0,0 +1,73 @@
+#!/usr/bin/env ruby
+
+require File.dirname(__FILE__) + '/../../../spec_helper'
+
+describe Puppet::Parser::AST::Hostclass do
+ def ast
+ Puppet::Parser::AST
+ end
+
+ def newarray(*elems)
+ ast::ASTArray.new({}).push(*elems)
+ end
+
+ it "should make its name and context available through accessors" do
+ hostclass = ast::Hostclass.new('foo', :line => 5)
+ hostclass.name.should == 'foo'
+ hostclass.context.should == {:line => 5}
+ end
+
+ it "should make its code available through an accessor" do
+ code = newarray
+ hostclass = ast::Hostclass.new('foo', :code => code)
+ hostclass.code.should be_equal(code)
+ end
+
+ describe "when instantiated" do
+ it "should create a class with the proper type, code, name, context, and module name" do
+ code = newarray
+ hostclass = ast::Hostclass.new('foo', :code => code, :line => 5)
+ instantiated_class = hostclass.instantiate('modname')[0]
+ instantiated_class.type.should == :hostclass
+ instantiated_class.name.should == 'foo'
+ instantiated_class.code.should be_equal(code)
+ instantiated_class.line.should == 5
+ instantiated_class.module_name.should == 'modname'
+ end
+
+ it "should instantiate all nested classes, defines, and nodes with the same module name." do
+ nested_objects = newarray(ast::Hostclass.new('foo::child1'),
+ ast::Definition.new('foo::child2'),
+ ast::Definition.new('child3'))
+ hostclass = ast::Hostclass.new('foo', :code => nested_objects)
+ instantiated_classes = hostclass.instantiate('modname')
+ instantiated_classes.length.should == 4
+ instantiated_classes[0].name.should == 'foo'
+ instantiated_classes[1].name.should == 'foo::child1'
+ instantiated_classes[2].name.should == 'foo::child2'
+ instantiated_classes[3].name.should == 'child3'
+ instantiated_classes.each { |cls| cls.module_name.should == 'modname' }
+ end
+
+ it "should handle a nested class that contains its own nested classes." do
+ foo_bar_baz = ast::Hostclass.new('foo::bar::baz')
+ foo_bar = ast::Hostclass.new('foo::bar', :code => newarray(foo_bar_baz))
+ foo = ast::Hostclass.new('foo', :code => newarray(foo_bar))
+ instantiated_classes = foo.instantiate('')
+ instantiated_classes.length.should == 3
+ instantiated_classes[0].name.should == 'foo'
+ instantiated_classes[1].name.should == 'foo::bar'
+ instantiated_classes[2].name.should == 'foo::bar::baz'
+ end
+
+ it "should skip nested elements that are not classes, definitions, or nodes." do
+ func = ast::Function.new(:name => 'biz', :arguments => newarray(ast::Name.new(:value => 'baz')))
+ foo = ast::Hostclass.new('foo', :code => newarray(func))
+ instantiated_classes = foo.instantiate('')
+ instantiated_classes.length.should == 1
+ instantiated_classes[0].should be_a(Puppet::Resource::Type)
+ instantiated_classes[0].name.should == 'foo'
+ end
+ end
+end
+
diff --git a/spec/unit/parser/ast/leaf_spec.rb b/spec/unit/parser/ast/leaf_spec.rb
index 5bdca67fa..a19c24115 100755
--- a/spec/unit/parser/ast/leaf_spec.rb
+++ b/spec/unit/parser/ast/leaf_spec.rb
@@ -47,6 +47,10 @@ describe Puppet::Parser::AST::String do
value = stub 'value', :is_a? => true, :to_s => "ab"
Puppet::Parser::AST::String.new( :value => value ).to_s.should == "\"ab\""
end
+ it "should return a dup of its value" do
+ value = ""
+ Puppet::Parser::AST::String.new( :value => value ).evaluate(stub('scope')).should_not be_equal(value)
+ end
end
end
@@ -132,6 +136,22 @@ describe Puppet::Parser::AST::HashOrArrayAccess do
access.evaluate(@scope).should == "val2"
end
+ it "should be able to return an array member when index is a stringified number" do
+ @scope.stubs(:lookupvar).with("a").returns(["val1", "val2", "val3"])
+
+ access = Puppet::Parser::AST::HashOrArrayAccess.new(:variable => "a", :key => "1" )
+
+ access.evaluate(@scope).should == "val2"
+ end
+
+ it "should raise an error when accessing an array with a key" do
+ @scope.stubs(:lookupvar).with("a").returns(["val1", "val2", "val3"])
+
+ access = Puppet::Parser::AST::HashOrArrayAccess.new(:variable => "a", :key => "get_me_the_second_element_please" )
+
+ lambda { access.evaluate(@scope) }.should raise_error
+ end
+
it "should be able to return an hash value" do
@scope.stubs(:lookupvar).with("a").returns({ "key1" => "val1", "key2" => "val2", "key3" => "val3" })
@@ -140,6 +160,14 @@ describe Puppet::Parser::AST::HashOrArrayAccess do
access.evaluate(@scope).should == "val2"
end
+ it "should be able to return an hash value with a numerical key" do
+ @scope.stubs(:lookupvar).with("a").returns({ "key1" => "val1", "key2" => "val2", "45" => "45", "key3" => "val3" })
+
+ access = Puppet::Parser::AST::HashOrArrayAccess.new(:variable => "a", :key => "45" )
+
+ access.evaluate(@scope).should == "45"
+ end
+
it "should raise an error if the variable lookup didn't return an hash or an array" do
@scope.stubs(:lookupvar).with("a").returns("I'm a string")
@@ -191,6 +219,24 @@ describe Puppet::Parser::AST::HashOrArrayAccess do
scope.lookupvar("a").should be_include("b")
end
+ it "should raise an error when assigning an array element with a key" do
+ @scope.stubs(:lookupvar).with("a").returns([])
+
+ access = Puppet::Parser::AST::HashOrArrayAccess.new(:variable => "a", :key => "get_me_the_second_element_please" )
+
+ lambda { access.assign(@scope, "test") }.should raise_error
+ end
+
+ it "should be able to return an array member when index is a stringified number" do
+ scope = Puppet::Parser::Scope.new
+ scope.setvar("a", [])
+
+ access = Puppet::Parser::AST::HashOrArrayAccess.new(:variable => "a", :key => "0" )
+
+ access.assign(scope, "val2")
+ scope.lookupvar("a").should == ["val2"]
+ end
+
it "should raise an error when trying to overwrite an hash value" do
@scope.stubs(:lookupvar).with("a").returns({ "key" => [ "a" , "b" ]})
access = Puppet::Parser::AST::HashOrArrayAccess.new(:variable => "a", :key => "key")
diff --git a/spec/unit/parser/ast/node_spec.rb b/spec/unit/parser/ast/node_spec.rb
new file mode 100644
index 000000000..3e8017de0
--- /dev/null
+++ b/spec/unit/parser/ast/node_spec.rb
@@ -0,0 +1,31 @@
+#!/usr/bin/env ruby
+
+require File.dirname(__FILE__) + '/../../../spec_helper'
+
+describe Puppet::Parser::AST::Node do
+ describe "when instantiated" do
+ it "should make its names and context available through accessors" do
+ node = Puppet::Parser::AST::Node.new(['foo', 'bar'], :line => 5)
+ node.names.should == ['foo', 'bar']
+ node.context.should == {:line => 5}
+ end
+
+ it "should create a node with the proper type, name, context, and module name" do
+ node = Puppet::Parser::AST::Node.new(['foo'], :line => 5)
+ instantiated_nodes = node.instantiate('modname')
+ instantiated_nodes.length.should == 1
+ instantiated_nodes[0].type.should == :node
+ instantiated_nodes[0].name.should == 'foo'
+ instantiated_nodes[0].line.should == 5
+ instantiated_nodes[0].module_name.should == 'modname'
+ end
+
+ it "should handle multiple names" do
+ node = Puppet::Parser::AST::Node.new(['foo', 'bar'])
+ instantiated_nodes = node.instantiate('modname')
+ instantiated_nodes.length.should == 2
+ instantiated_nodes[0].name.should == 'foo'
+ instantiated_nodes[1].name.should == 'bar'
+ end
+ end
+end
diff --git a/spec/unit/parser/ast/resource_reference_spec.rb b/spec/unit/parser/ast/resource_reference_spec.rb
index 7b48119f4..93419d963 100755
--- a/spec/unit/parser/ast/resource_reference_spec.rb
+++ b/spec/unit/parser/ast/resource_reference_spec.rb
@@ -32,11 +32,6 @@ describe Puppet::Parser::AST::ResourceReference do
]
end
- it "should pass its scope's namespaces to all created resource references" do
- @scope.add_namespace "foo"
- newref("File", "/tmp/yay").evaluate(@scope).namespaces.should == ["foo"]
- end
-
it "should return a correct representation when converting to string" do
type = stub 'type', :is_a? => true, :to_s => "file"
title = stub 'title', :is_a? => true, :to_s => "[/tmp/a, /tmp/b]"
diff --git a/spec/unit/parser/ast/resource_spec.rb b/spec/unit/parser/ast/resource_spec.rb
index 58ffae925..3f7fa229a 100755
--- a/spec/unit/parser/ast/resource_spec.rb
+++ b/spec/unit/parser/ast/resource_spec.rb
@@ -5,116 +5,180 @@ require File.dirname(__FILE__) + '/../../../spec_helper'
describe Puppet::Parser::AST::Resource do
ast = Puppet::Parser::AST
- before :each do
- @title = Puppet::Parser::AST::String.new(:value => "mytitle")
- @compiler = Puppet::Parser::Compiler.new(Puppet::Node.new("mynode"))
- @scope = Puppet::Parser::Scope.new(:compiler => @compiler)
- @scope.stubs(:resource).returns(stub_everything)
- @resource = ast::Resource.new(:title => @title, :type => "file", :parameters => ast::ASTArray.new(:children => []) )
- @resource.stubs(:qualified_type).returns("Resource")
- end
+ describe "for builtin types" do
+ before :each do
+ @title = Puppet::Parser::AST::String.new(:value => "mytitle")
+ @compiler = Puppet::Parser::Compiler.new(Puppet::Node.new("mynode"))
+ @scope = Puppet::Parser::Scope.new(:compiler => @compiler)
+ @scope.stubs(:resource).returns(stub_everything)
+ @instance = ast::ResourceInstance.new(:title => @title, :parameters => ast::ASTArray.new(:children => []))
+ @resource = ast::Resource.new(:type => "file", :instances => ast::ASTArray.new(:children => [@instance]))
+ @resource.stubs(:qualified_type).returns("Resource")
+ end
- it "should evaluate all its parameters" do
- param = stub 'param'
- param.expects(:safeevaluate).with(@scope).returns Puppet::Parser::Resource::Param.new(:name => "myparam", :value => "myvalue", :source => stub("source"))
- @resource.stubs(:parameters).returns [param]
+ it "should evaluate all its parameters" do
+ param = stub 'param'
+ param.expects(:safeevaluate).with(@scope).returns Puppet::Parser::Resource::Param.new(:name => "myparam", :value => "myvalue", :source => stub("source"))
+ @instance.stubs(:parameters).returns [param]
- @resource.evaluate(@scope)
- end
-
- it "should evaluate its title" do
- @resource.evaluate(@scope)[0].title.should == "mytitle"
- end
+ @resource.evaluate(@scope)
+ end
- it "should flatten the titles array" do
- titles = []
- %w{one two}.each do |title|
- titles << Puppet::Parser::AST::String.new(:value => title)
+ it "should evaluate its title" do
+ @resource.evaluate(@scope)[0].title.should == "mytitle"
end
- array = Puppet::Parser::AST::ASTArray.new(:children => titles)
+ it "should flatten the titles array" do
+ titles = []
+ %w{one two}.each do |title|
+ titles << Puppet::Parser::AST::String.new(:value => title)
+ end
- @resource.title = array
- result = @resource.evaluate(@scope).collect { |r| r.title }
- result.should be_include("one")
- result.should be_include("two")
- end
+ array = Puppet::Parser::AST::ASTArray.new(:children => titles)
- it "should create and return one resource objects per title" do
- titles = []
- %w{one two}.each do |title|
- titles << Puppet::Parser::AST::String.new(:value => title)
+ @instance.title = array
+ result = @resource.evaluate(@scope).collect { |r| r.title }
+ result.should be_include("one")
+ result.should be_include("two")
end
- array = Puppet::Parser::AST::ASTArray.new(:children => titles)
+ it "should create and return one resource objects per title" do
+ titles = []
+ %w{one two}.each do |title|
+ titles << Puppet::Parser::AST::String.new(:value => title)
+ end
- @resource.title = array
- result = @resource.evaluate(@scope).collect { |r| r.title }
- result.should be_include("one")
- result.should be_include("two")
- end
+ array = Puppet::Parser::AST::ASTArray.new(:children => titles)
- it "should handover resources to the compiler" do
- titles = []
- %w{one two}.each do |title|
- titles << Puppet::Parser::AST::String.new(:value => title)
+ @instance.title = array
+ result = @resource.evaluate(@scope).collect { |r| r.title }
+ result.should be_include("one")
+ result.should be_include("two")
end
- array = Puppet::Parser::AST::ASTArray.new(:children => titles)
+ it "should implicitly iterate over instances" do
+ new_title = Puppet::Parser::AST::String.new(:value => "other_title")
+ new_instance = ast::ResourceInstance.new(:title => new_title, :parameters => ast::ASTArray.new(:children => []))
+ @resource.instances.push(new_instance)
+ @resource.evaluate(@scope).collect { |r| r.title }.should == ["mytitle", "other_title"]
+ end
- @resource.title = array
- result = @resource.evaluate(@scope)
+ it "should handover resources to the compiler" do
+ titles = []
+ %w{one two}.each do |title|
+ titles << Puppet::Parser::AST::String.new(:value => title)
+ end
- result.each do |res|
- @compiler.catalog.resource(res.ref).should be_instance_of(Puppet::Parser::Resource)
- end
- end
- it "should generate virtual resources if it is virtual" do
- @resource.virtual = true
+ array = Puppet::Parser::AST::ASTArray.new(:children => titles)
- result = @resource.evaluate(@scope)
- result[0].should be_virtual
- end
+ @instance.title = array
+ result = @resource.evaluate(@scope)
- it "should generate virtual and exported resources if it is exported" do
- @resource.exported = true
+ result.each do |res|
+ @compiler.catalog.resource(res.ref).should be_instance_of(Puppet::Parser::Resource)
+ end
+ end
- result = @resource.evaluate(@scope)
- result[0].should be_virtual
- result[0].should be_exported
- end
+ it "should generate virtual resources if it is virtual" do
+ @resource.virtual = true
- # Related to #806, make sure resources always look up the full path to the resource.
- describe "when generating qualified resources" do
- before do
- @scope = Puppet::Parser::Scope.new :compiler => Puppet::Parser::Compiler.new(Puppet::Node.new("mynode"))
- @parser = Puppet::Parser::Parser.new(Puppet::Node::Environment.new)
- @parser.newdefine "one"
- @parser.newdefine "one::two"
- @parser.newdefine "three"
- @twoscope = @scope.newscope(:namespace => "one")
- @twoscope.resource = @scope.resource
+ result = @resource.evaluate(@scope)
+ result[0].should be_virtual
end
- def resource(type, params = nil)
- params ||= Puppet::Parser::AST::ASTArray.new(:children => [])
- Puppet::Parser::AST::Resource.new(:type => type, :title => Puppet::Parser::AST::String.new(:value => "myresource"), :parameters => params)
+ it "should generate virtual and exported resources if it is exported" do
+ @resource.exported = true
+
+ result = @resource.evaluate(@scope)
+ result[0].should be_virtual
+ result[0].should be_exported
end
- it "should be able to generate resources with fully qualified type information" do
- resource("two").evaluate(@twoscope)[0].type.should == "One::Two"
+ # Related to #806, make sure resources always look up the full path to the resource.
+ describe "when generating qualified resources" do
+ before do
+ @scope = Puppet::Parser::Scope.new :compiler => Puppet::Parser::Compiler.new(Puppet::Node.new("mynode"))
+ @parser = Puppet::Parser::Parser.new(Puppet::Node::Environment.new)
+ ["one", "one::two", "three"].each do |name|
+ @parser.environment.known_resource_types.add(Puppet::Resource::Type.new(:definition, name, {}))
+ end
+ @twoscope = @scope.newscope(:namespace => "one")
+ @twoscope.resource = @scope.resource
+ end
+
+ def resource(type, params = nil)
+ params ||= Puppet::Parser::AST::ASTArray.new(:children => [])
+ instance = Puppet::Parser::AST::ResourceInstance.new(
+ :title => Puppet::Parser::AST::String.new(:value => "myresource"), :parameters => params)
+ Puppet::Parser::AST::Resource.new(:type => type,
+ :instances => Puppet::Parser::AST::ASTArray.new(:children => [instance]))
+ end
+
+ it "should be able to generate resources with fully qualified type information" do
+ resource("two").evaluate(@twoscope)[0].type.should == "One::Two"
+ end
+
+ it "should be able to generate resources with unqualified type information" do
+ resource("one").evaluate(@twoscope)[0].type.should == "One"
+ end
+
+ it "should correctly generate resources that can look up builtin types" do
+ resource("file").evaluate(@twoscope)[0].type.should == "File"
+ end
+
+ it "should correctly generate resources that can look up defined classes by title" do
+ @scope.known_resource_types.add_hostclass Puppet::Resource::Type.new(:hostclass, "Myresource", {})
+ @scope.compiler.stubs(:evaluate_classes)
+ res = resource("class").evaluate(@twoscope)[0]
+ res.type.should == "Class"
+ res.title.should == "Myresource"
+ end
+
+ it "should evaluate parameterized classes when they are instantiated" do
+ @scope.known_resource_types.add_hostclass Puppet::Resource::Type.new(:hostclass, "Myresource", {})
+ @scope.compiler.expects(:evaluate_classes).with(['myresource'],@twoscope,false)
+ resource("class").evaluate(@twoscope)[0]
+ end
+
+ it "should fail for resource types that do not exist" do
+ lambda { resource("nosuchtype").evaluate(@twoscope) }.should raise_error(Puppet::ParseError)
+ end
end
+ end
- it "should be able to generate resources with unqualified type information" do
- resource("one").evaluate(@twoscope)[0].type.should == "One"
+ describe "for class resources" do
+ before do
+ @title = Puppet::Parser::AST::String.new(:value => "classname")
+ @compiler = Puppet::Parser::Compiler.new(Puppet::Node.new("mynode"))
+ @scope = Puppet::Parser::Scope.new(:compiler => @compiler)
+ @scope.stubs(:resource).returns(stub_everything)
+ @instance = ast::ResourceInstance.new(:title => @title, :parameters => ast::ASTArray.new(:children => []))
+ @resource = ast::Resource.new(:type => "Class", :instances => ast::ASTArray.new(:children => [@instance]))
+ @resource.stubs(:qualified_type).returns("Resource")
+ @type = Puppet::Resource::Type.new(:hostclass, "classname")
+ @compiler.known_resource_types.add(@type)
end
- it "should correctly generate resources that can look up builtin types" do
- resource("file").evaluate(@twoscope)[0].type.should == "File"
+ it "should instantiate the class" do
+ @compiler.stubs(:evaluate_classes)
+ result = @resource.evaluate(@scope)
+ result.length.should == 1
+ result.first.ref.should == "Class[Classname]"
+ @compiler.catalog.resource("Class[Classname]").should equal(result.first)
end
- it "should fail for resource types that do not exist" do
- lambda { resource("nosuchtype").evaluate(@twoscope) }.should raise_error(Puppet::ParseError)
+ it "should cause its parent to be evaluated" do
+ parent_type = Puppet::Resource::Type.new(:hostclass, "parentname")
+ @compiler.stubs(:evaluate_classes)
+ @compiler.known_resource_types.add(parent_type)
+ @type.parent = "parentname"
+ result = @resource.evaluate(@scope)
+ result.length.should == 1
+ result.first.ref.should == "Class[Classname]"
+ @compiler.catalog.resource("Class[Classname]").should equal(result.first)
+ @compiler.catalog.resource("Class[Parentname]").should be_instance_of(Puppet::Parser::Resource)
end
+
end
+
end
diff --git a/spec/unit/parser/collector_spec.rb b/spec/unit/parser/collector_spec.rb
index 15808d6ff..908cda63a 100755
--- a/spec/unit/parser/collector_spec.rb
+++ b/spec/unit/parser/collector_spec.rb
@@ -2,6 +2,7 @@
require File.dirname(__FILE__) + '/../../spec_helper'
+require 'puppet/rails'
require 'puppet/parser/collector'
describe Puppet::Parser::Collector, "when initializing" do
diff --git a/spec/unit/parser/compiler_spec.rb b/spec/unit/parser/compiler_spec.rb
index e8c06dd0b..95f3853e2 100755
--- a/spec/unit/parser/compiler_spec.rb
+++ b/spec/unit/parser/compiler_spec.rb
@@ -430,7 +430,18 @@ describe Puppet::Parser::Compiler do
lambda { @compiler.add_resource(@scope, resource) }.should raise_error(ArgumentError)
end
- it "should add edges from the class resources to the main stage if no stage is specified" do
+ it "should add edges from the class resources to the parent's stage if no stage is specified" do
+ main = @compiler.catalog.resource(:stage, :main)
+ foo_stage = resource(:stage, :foo_stage)
+ @compiler.add_resource(@scope, foo_stage)
+ resource = resource(:class, "foo")
+ @scope.stubs(:resource).returns(:stage => :foo_stage)
+ @compiler.add_resource(@scope, resource)
+
+ @compiler.catalog.should be_edge(foo_stage, resource)
+ end
+
+ it "should add edges from top-level class resources to the main stage if no stage is specified" do
main = @compiler.catalog.resource(:stage, :main)
resource = resource(:class, "foo")
@compiler.add_resource(@scope, resource)
@@ -569,7 +580,7 @@ describe Puppet::Parser::Compiler do
it "should evaluate each class" do
@compiler.catalog.stubs(:tag)
- @class.expects(:mk_plain_resource).with(@scope)
+ @class.expects(:ensure_in_catalog).with(@scope)
@scope.stubs(:class_scope).with(@class)
@compiler.evaluate_classes(%w{myclass}, @scope)
@@ -580,7 +591,7 @@ describe Puppet::Parser::Compiler do
@resource.expects(:evaluate).never
- @class.expects(:mk_plain_resource).returns(@resource)
+ @class.expects(:ensure_in_catalog).returns(@resource)
@scope.stubs(:class_scope).with(@class)
@compiler.evaluate_classes(%w{myclass}, @scope)
@@ -590,7 +601,7 @@ describe Puppet::Parser::Compiler do
@compiler.catalog.stubs(:tag)
@resource.expects(:evaluate)
- @class.expects(:mk_plain_resource).returns(@resource)
+ @class.expects(:ensure_in_catalog).returns(@resource)
@scope.stubs(:class_scope).with(@class)
@compiler.evaluate_classes(%w{myclass}, @scope, false)
@@ -627,7 +638,7 @@ describe Puppet::Parser::Compiler do
@scope.stubs(:class_scope).with(@class)
Puppet::Parser::Resource.stubs(:new).returns(@resource)
- @class.stubs :mk_plain_resource
+ @class.stubs :ensure_in_catalog
@compiler.evaluate_classes(%w{myclass notfound}, @scope).should == %w{myclass}
end
end
@@ -667,7 +678,7 @@ describe Puppet::Parser::Compiler do
@compiler.known_resource_types.stubs(:node).with("c").returns(node_class)
node_resource = stub 'node resource', :ref => "Node[c]", :evaluate => nil, :type => "node"
- node_class.expects(:mk_plain_resource).returns(node_resource)
+ node_class.expects(:ensure_in_catalog).returns(node_resource)
@compiler.compile
end
@@ -677,7 +688,7 @@ describe Puppet::Parser::Compiler do
@compiler.known_resource_types.stubs(:node).with("default").returns(node_class)
node_resource = stub 'node resource', :ref => "Node[default]", :evaluate => nil, :type => "node"
- node_class.expects(:mk_plain_resource).returns(node_resource)
+ node_class.expects(:ensure_in_catalog).returns(node_resource)
@compiler.compile
end
@@ -687,7 +698,7 @@ describe Puppet::Parser::Compiler do
@compiler.known_resource_types.stubs(:node).with("c").returns(node_class)
node_resource = stub 'node resource', :ref => "Node[c]", :type => "node"
- node_class.expects(:mk_plain_resource).returns(node_resource)
+ node_class.expects(:ensure_in_catalog).returns(node_resource)
node_resource.expects(:evaluate)
@@ -696,7 +707,7 @@ describe Puppet::Parser::Compiler do
it "should set the node's scope as the top scope" do
node_resource = stub 'node resource', :ref => "Node[c]", :evaluate => nil, :type => "node"
- node_class = stub 'node', :name => "c", :mk_plain_resource => node_resource
+ node_class = stub 'node', :name => "c", :ensure_in_catalog => node_resource
@compiler.known_resource_types.stubs(:node).with("c").returns(node_class)
diff --git a/spec/unit/parser/files_spec.rb b/spec/unit/parser/files_spec.rb
index fcfbfa613..3eb0db07e 100644
--- a/spec/unit/parser/files_spec.rb
+++ b/spec/unit/parser/files_spec.rb
@@ -154,7 +154,7 @@ describe Puppet::Parser::Files do
it "should match against provided fully qualified patterns" do
pattern = @basepath + "/fully/qualified/pattern/*"
- Dir.expects(:glob).with(pattern+'{,.pp,.rb}').returns(%w{my file list})
+ Dir.expects(:glob).with(pattern+'{.pp,.rb}').returns(%w{my file list})
Puppet::Parser::Files.find_manifests(pattern)[1].should == %w{my file list}
end
@@ -168,7 +168,7 @@ describe Puppet::Parser::Files do
pattern = @basepath + "/fully/qualified/pattern/*"
file = @basepath + "/my/file"
dir = @basepath + "/my/directory"
- Dir.expects(:glob).with(pattern+'{,.pp,.rb}').returns([file, dir])
+ Dir.expects(:glob).with(pattern+'{.pp,.rb}').returns([file, dir])
FileTest.expects(:directory?).with(file).returns(false)
FileTest.expects(:directory?).with(dir).returns(true)
Puppet::Parser::Files.find_manifests(pattern)[1].should == [file]
@@ -176,7 +176,7 @@ describe Puppet::Parser::Files do
it "should return files once only" do
pattern = @basepath + "/fully/qualified/pattern/*"
- Dir.expects(:glob).with(pattern+'{,.pp,.rb}').returns(%w{one two one})
+ Dir.expects(:glob).with(pattern+'{.pp,.rb}').returns(%w{one two one})
Puppet::Parser::Files.find_manifests(pattern)[1].should == %w{one two}
end
end
diff --git a/spec/unit/parser/functions/extlookup_spec.rb b/spec/unit/parser/functions/extlookup_spec.rb
new file mode 100755
index 000000000..a3dcaa742
--- /dev/null
+++ b/spec/unit/parser/functions/extlookup_spec.rb
@@ -0,0 +1,95 @@
+#! /usr/bin/env ruby
+
+require File.dirname(__FILE__) + '/../../../spec_helper'
+require 'tempfile'
+
+describe "the extlookup function" do
+
+ before :each do
+ @scope = Puppet::Parser::Scope.new
+
+ @scope.stubs(:environment).returns(Puppet::Node::Environment.new('production'))
+ Puppet::Parser::Functions.function("extlookup")
+ end
+
+ it "should exist" do
+ Puppet::Parser::Functions.function("extlookup").should == "function_extlookup"
+ end
+
+ it "should raise a ParseError if there is less than 1 arguments" do
+ lambda { @scope.function_extlookup([]) }.should( raise_error(Puppet::ParseError))
+ end
+
+ it "should raise a ParseError if there is more than 3 arguments" do
+ lambda { @scope.function_extlookup(["foo", "bar", "baz", "gazonk"]) }.should( raise_error(Puppet::ParseError))
+ end
+
+ it "should return the default" do
+ result = @scope.function_extlookup([ "key", "default"])
+ result.should == "default"
+ end
+
+ it "should lookup the key in a supplied datafile" do
+ t = Tempfile.new('extlookup.csv') do
+ t.puts 'key,value'
+ t.puts 'nonkey,nonvalue'
+ t.close
+
+ result = @scope.function_extlookup([ "key", "default", t.path])
+ result.should == "value"
+ end
+ end
+
+ it "should return an array if the datafile contains more than two columns" do
+ t = Tempfile.new('extlookup.csv') do
+ t.puts 'key,value1,value2'
+ t.puts 'nonkey,nonvalue,nonvalue'
+ t.close
+
+ result = @scope.function_extlookup([ "key", "default", t.path])
+ result.should == ["value1", "value2"]
+ end
+ end
+
+ it "should raise an error if there's no matching key and no default" do
+ t = Tempfile.new('extlookup.csv') do
+ t.puts 'key,value'
+ t.puts 'nonkey,nonvalue'
+ t.close
+
+ result = @scope.function_extlookup([ "key", nil, t.path])
+ result.should == "value"
+ end
+ end
+
+ describe "should look in $extlookup_datadir for data files listed by $extlookup_precedence" do
+ before do
+ @scope.stubs(:lookupvar).with('extlookup_datadir').returns("/tmp")
+ File.open("/tmp/one.csv","w"){|one| one.puts "key,value1" }
+ File.open("/tmp/two.csv","w") do |two|
+ two.puts "key,value2"
+ two.puts "key2,value_two"
+ end
+ end
+
+ it "when the key is in the first file" do
+ @scope.stubs(:lookupvar).with('extlookup_precedence').returns(["one","two"])
+ result = @scope.function_extlookup([ "key" ])
+ result.should == "value1"
+ end
+
+ it "when the key is in the second file" do
+ @scope.stubs(:lookupvar).with('extlookup_precedence').returns(["one","two"])
+ result = @scope.function_extlookup([ "key2" ])
+ result.should == "value_two"
+ end
+
+ it "should not modify extlookup_precedence data" do
+ variable = '%{fqdn}'
+ @scope.stubs(:lookupvar).with('extlookup_precedence').returns([variable,"one"])
+ @scope.stubs(:lookupvar).with('fqdn').returns('myfqdn')
+ result = @scope.function_extlookup([ "key" ])
+ variable.should == '%{fqdn}'
+ end
+ end
+end
diff --git a/spec/unit/parser/functions/include_spec.rb b/spec/unit/parser/functions/include_spec.rb
new file mode 100644
index 000000000..4f609b055
--- /dev/null
+++ b/spec/unit/parser/functions/include_spec.rb
@@ -0,0 +1,33 @@
+#!/usr/bin/env ruby
+
+require File.dirname(__FILE__) + '/../../../spec_helper'
+
+describe "the 'include' function" do
+
+ before :each do
+ Puppet::Node::Environment.stubs(:current).returns(nil)
+ @compiler = Puppet::Parser::Compiler.new(Puppet::Node.new("foo"))
+ @scope = Puppet::Parser::Scope.new(:compiler => @compiler)
+ end
+
+ it "should exist" do
+ Puppet::Parser::Functions.function("include").should == "function_include"
+ end
+
+ it "should include a single class" do
+ inc = "foo"
+ @compiler.expects(:evaluate_classes).with {|klasses,parser,lazy| klasses == [inc]}.returns([inc])
+ @scope.function_include("foo")
+ end
+
+ it "should include multiple classes" do
+ inc = ["foo","bar"]
+ @compiler.expects(:evaluate_classes).with {|klasses,parser,lazy| klasses == inc}.returns(inc)
+ @scope.function_include(["foo","bar"])
+ end
+
+ it "should not lazily evaluate the included class" do
+ @compiler.expects(:evaluate_classes).with {|klasses,parser,lazy| lazy == false}.returns("foo")
+ @scope.function_include("foo")
+ end
+end
diff --git a/spec/unit/parser/functions/require_spec.rb b/spec/unit/parser/functions/require_spec.rb
index bd42fa579..49c4bbf74 100755
--- a/spec/unit/parser/functions/require_spec.rb
+++ b/spec/unit/parser/functions/require_spec.rb
@@ -6,7 +6,7 @@ describe "the require function" do
before :each do
@catalog = stub 'catalog'
- @compiler = stub 'compiler', :catalog => @catalog
+ @compiler = stub 'compiler', :catalog => @catalog, :environment => nil
@scope = Puppet::Parser::Scope.new
@scope.stubs(:findresource)
diff --git a/spec/unit/parser/functions/tag_spec.rb b/spec/unit/parser/functions/tag_spec.rb
index ff37badbb..dac134134 100755
--- a/spec/unit/parser/functions/tag_spec.rb
+++ b/spec/unit/parser/functions/tag_spec.rb
@@ -6,6 +6,7 @@ describe "the 'tag' function" do
before :each do
@scope = Puppet::Parser::Scope.new
+ @scope.stubs(:environment).returns(nil)
end
it "should exist" do
diff --git a/spec/unit/parser/lexer_spec.rb b/spec/unit/parser/lexer_spec.rb
index d3d2a0a31..d52add399 100755
--- a/spec/unit/parser/lexer_spec.rb
+++ b/spec/unit/parser/lexer_spec.rb
@@ -30,6 +30,14 @@ describe Puppet::Parser::Lexer do
@lexer.line.should == 10
end
+
+ it "should not think the terminator is escaped, when preceeded by an even number of backslashes" do
+ @lexer.line = 10
+ @lexer.string = "here\nis\nthe\nstring\\\\'with\nextra\njunk"
+ @lexer.slurpstring("'")
+
+ @lexer.line.should == 13
+ end
end
end
@@ -410,8 +418,13 @@ describe Puppet::Parser::Lexer,"when lexing strings" do
%q{'single quoted string')} => [[:STRING,'single quoted string']],
%q{"double quoted string"} => [[:STRING,'double quoted string']],
%q{'single quoted string with an escaped "\\'"'} => [[:STRING,'single quoted string with an escaped "\'"']],
+ %q{'single quoted string with an escaped "\$"'} => [[:STRING,'single quoted string with an escaped "\$"']],
+ %q{'single quoted string with an escaped "\."'} => [[:STRING,'single quoted string with an escaped "\."']],
+ %q{'single quoted string with an escaped "\n"'} => [[:STRING,'single quoted string with an escaped "\n"']],
+ %q{'single quoted string with an escaped "\\\\"'} => [[:STRING,'single quoted string with an escaped "\\\\"']],
%q{"string with an escaped '\\"'"} => [[:STRING,"string with an escaped '\"'"]],
%q{"string with an escaped '\\$'"} => [[:STRING,"string with an escaped '$'"]],
+ %Q{"string with a line ending with a backslash: \\\nfoo"} => [[:STRING,"string with a line ending with a backslash: foo"]],
%q{"string with $v (but no braces)"} => [[:DQPRE,"string with "],[:VARIABLE,'v'],[:DQPOST,' (but no braces)']],
%q["string with ${v} in braces"] => [[:DQPRE,"string with "],[:VARIABLE,'v'],[:DQPOST,' in braces']],
%q["string with ${qualified::var} in braces"] => [[:DQPRE,"string with "],[:VARIABLE,'qualified::var'],[:DQPOST,' in braces']],
@@ -616,6 +629,12 @@ describe "Puppet::Parser::Lexer in the old tests" do
@lexer.namespace.should == "base::sub"
end
+ it "should not put class instantiation on the namespace" do
+ @lexer.string = "class base { class sub { class { mode"
+ @lexer.fullscan
+ @lexer.namespace.should == "base::sub"
+ end
+
it "should correctly handle fully qualified names" do
@lexer.string = "class base { class sub::more {"
@lexer.fullscan
@@ -634,7 +653,6 @@ end
require 'puppettest/support/utils'
describe "Puppet::Parser::Lexer in the old tests when lexing example files" do
- extend PuppetTest
extend PuppetTest::Support::Utils
textfiles do |file|
it "should correctly lex #{file}" do
diff --git a/spec/unit/parser/parser_spec.rb b/spec/unit/parser/parser_spec.rb
index 0657ab37a..ab43194e9 100755
--- a/spec/unit/parser/parser_spec.rb
+++ b/spec/unit/parser/parser_spec.rb
@@ -4,7 +4,7 @@ require File.dirname(__FILE__) + '/../../spec_helper'
describe Puppet::Parser do
- ast = Puppet::Parser::AST
+ Puppet::Parser::AST
before :each do
@known_resource_types = Puppet::Resource::TypeCollection.new("development")
@@ -52,15 +52,6 @@ describe Puppet::Parser do
@parser.file = "/my/file.rb"
@parser.parse
end
-
- describe "in ruby" do
- it "should use the ruby interpreter to load the file" do
- @parser.file = "/my/file.rb"
- @parser.expects(:require).with "/my/file.rb"
-
- @parser.parse_ruby_file
- end
- end
end
describe "when parsing append operator" do
@@ -73,35 +64,37 @@ describe Puppet::Parser do
lambda { @parser.parse("$var += ") }.should raise_error
end
- it "should call ast::VarDef with append=true" do
- ast::VarDef.expects(:new).with { |h| h[:append] == true }
- @parser.parse("$var += 2")
+ it "should create ast::VarDef with append=true" do
+ vardef = @parser.parse("$var += 2").code[0]
+ vardef.should be_a(Puppet::Parser::AST::VarDef)
+ vardef.append.should == true
end
it "should work with arrays too" do
- ast::VarDef.expects(:new).with { |h| h[:append] == true }
- @parser.parse("$var += ['test']")
+ vardef = @parser.parse("$var += ['test']").code[0]
+ vardef.should be_a(Puppet::Parser::AST::VarDef)
+ vardef.append.should == true
end
end
describe "when parsing 'if'" do
it "not, it should create the correct ast objects" do
- ast::Not.expects(:new).with { |h| h[:value].is_a?(ast::Boolean) }
+ Puppet::Parser::AST::Not.expects(:new).with { |h| h[:value].is_a?(Puppet::Parser::AST::Boolean) }
@parser.parse("if ! true { $var = 1 }")
end
it "boolean operation, it should create the correct ast objects" do
- ast::BooleanOperator.expects(:new).with {
- |h| h[:rval].is_a?(ast::Boolean) and h[:lval].is_a?(ast::Boolean) and h[:operator]=="or"
+ Puppet::Parser::AST::BooleanOperator.expects(:new).with {
+ |h| h[:rval].is_a?(Puppet::Parser::AST::Boolean) and h[:lval].is_a?(Puppet::Parser::AST::Boolean) and h[:operator]=="or"
}
@parser.parse("if true or true { $var = 1 }")
end
it "comparison operation, it should create the correct ast objects" do
- ast::ComparisonOperator.expects(:new).with {
- |h| h[:lval].is_a?(ast::Name) and h[:rval].is_a?(ast::Name) and h[:operator]=="<"
+ Puppet::Parser::AST::ComparisonOperator.expects(:new).with {
+ |h| h[:lval].is_a?(Puppet::Parser::AST::Name) and h[:rval].is_a?(Puppet::Parser::AST::Name) and h[:operator]=="<"
}
@parser.parse("if 1 < 2 { $var = 1 }")
@@ -112,13 +105,13 @@ describe Puppet::Parser do
describe "when parsing if complex expressions" do
it "should create a correct ast tree" do
aststub = stub_everything 'ast'
- ast::ComparisonOperator.expects(:new).with {
- |h| h[:rval].is_a?(ast::Name) and h[:lval].is_a?(ast::Name) and h[:operator]==">"
+ Puppet::Parser::AST::ComparisonOperator.expects(:new).with {
+ |h| h[:rval].is_a?(Puppet::Parser::AST::Name) and h[:lval].is_a?(Puppet::Parser::AST::Name) and h[:operator]==">"
}.returns(aststub)
- ast::ComparisonOperator.expects(:new).with {
- |h| h[:rval].is_a?(ast::Name) and h[:lval].is_a?(ast::Name) and h[:operator]=="=="
+ Puppet::Parser::AST::ComparisonOperator.expects(:new).with {
+ |h| h[:rval].is_a?(Puppet::Parser::AST::Name) and h[:lval].is_a?(Puppet::Parser::AST::Name) and h[:operator]=="=="
}.returns(aststub)
- ast::BooleanOperator.expects(:new).with {
+ Puppet::Parser::AST::BooleanOperator.expects(:new).with {
|h| h[:rval]==aststub and h[:lval]==aststub and h[:operator]=="and"
}
@parser.parse("if (1 > 2) and (1 == 2) { $var = 1 }")
@@ -141,9 +134,8 @@ describe Puppet::Parser do
end
it "should create an ast::ResourceReference" do
- ast::Resource.stubs(:new)
- ast::ResourceReference.expects(:new).with { |arg|
- arg[:line]==1 and arg[:type]=="File" and arg[:title].is_a?(ast::ASTArray)
+ Puppet::Parser::AST::ResourceReference.expects(:new).with { |arg|
+ arg[:line]==1 and arg[:type]=="File" and arg[:title].is_a?(Puppet::Parser::AST::ASTArray)
}
@parser.parse('exec { test: command => File["a","b"] }')
end
@@ -160,10 +152,14 @@ describe Puppet::Parser do
end
it "should create an ast::ResourceOverride" do
- ast::ResourceOverride.expects(:new).with { |arg|
- arg[:line]==1 and arg[:object].is_a?(ast::ResourceReference) and arg[:parameters].is_a?(ast::ResourceParam)
- }
- @parser.parse('Resource["title1","title2"] { param => value }')
+ #Puppet::Parser::AST::ResourceOverride.expects(:new).with { |arg|
+ # arg[:line]==1 and arg[:object].is_a?(Puppet::Parser::AST::ResourceReference) and arg[:parameters].is_a?(Puppet::Parser::AST::ResourceParam)
+ #}
+ ro = @parser.parse('Resource["title1","title2"] { param => value }').code[0]
+ ro.should be_a(Puppet::Parser::AST::ResourceOverride)
+ ro.line.should == 1
+ ro.object.should be_a(Puppet::Parser::AST::ResourceReference)
+ ro.parameters[0].should be_a(Puppet::Parser::AST::ResourceParam)
end
end
@@ -183,17 +179,17 @@ describe Puppet::Parser do
end
it "should create a nop node for empty branch" do
- ast::Nop.expects(:new)
+ Puppet::Parser::AST::Nop.expects(:new)
@parser.parse("if true { }")
end
it "should create a nop node for empty else branch" do
- ast::Nop.expects(:new)
+ Puppet::Parser::AST::Nop.expects(:new)
@parser.parse("if true { notice('test') } else { }")
end
it "should build a chain of 'ifs' if there's an 'elsif'" do
- ast = @parser.parse(<<-PP)
+ lambda { @parser.parse(<<-PP) }.should_not raise_error
if true { notice('test') } elsif true {} else { }
PP
end
@@ -278,33 +274,22 @@ describe Puppet::Parser do
it "should prefer provided options over AST context" do
@class.expects(:new).with { |opts| opts[:file] == "/bar" }
- @parser.expects(:ast_context).returns :file => "/foo"
+ @lexer.expects(:file).returns "/foo"
@parser.ast(@class, :file => "/bar")
end
it "should include docs when the AST class uses them" do
@class.expects(:use_docs).returns true
@class.stubs(:new)
- @parser.expects(:ast_context).with(true).returns({})
+ @parser.expects(:ast_context).with{ |a| a[0] == true }.returns({})
@parser.ast(@class, :file => "/bar")
end
- end
-
- describe "when creating a node" do
- before :each do
- @lexer = stub 'lexer'
- @lexer.stubs(:getcomment)
- @parser.stubs(:lexer).returns(@lexer)
- @node = stub_everything 'node'
- @parser.stubs(:ast_context).returns({})
- @parser.stubs(:node).returns(nil)
-
- @nodename = stub 'nodename', :is_a? => false, :value => "foo"
- @nodename.stubs(:is_a?).with(Puppet::Parser::AST::HostName).returns(true)
- end
- it "should return an array of nodes" do
- @parser.newnode(@nodename).should be_instance_of(Array)
+ it "should get docs from lexer using the correct AST line number" do
+ @class.expects(:use_docs).returns true
+ @class.stubs(:new).with{ |a| a[:doc] == "doc" }
+ @lexer.expects(:getcomment).with(12).returns "doc"
+ @parser.ast(@class, :file => "/bar", :line => 12)
end
end
@@ -360,30 +345,28 @@ describe Puppet::Parser do
@parser.stubs(:known_resource_types).returns @krt
end
- it "should create new classes" do
- @parser.parse("class foobar {}")
- @krt.hostclass("foobar").should be_instance_of(Puppet::Resource::Type)
+ it "should not create new classes" do
+ @parser.parse("class foobar {}").code[0].should be_a(Puppet::Parser::AST::Hostclass)
+ @krt.hostclass("foobar").should be_nil
end
it "should correctly set the parent class when one is provided" do
- @parser.parse("class foobar inherits yayness {}")
- @krt.hostclass("foobar").parent.should == "yayness"
+ @parser.parse("class foobar inherits yayness {}").code[0].instantiate('')[0].parent.should == "yayness"
end
it "should correctly set the parent class for multiple classes at a time" do
- @parser.parse("class foobar inherits yayness {}\nclass boo inherits bar {}")
- @krt.hostclass("foobar").parent.should == "yayness"
- @krt.hostclass("boo").parent.should == "bar"
+ statements = @parser.parse("class foobar inherits yayness {}\nclass boo inherits bar {}").code
+ statements[0].instantiate('')[0].parent.should == "yayness"
+ statements[1].instantiate('')[0].parent.should == "bar"
end
it "should define the code when some is provided" do
- @parser.parse("class foobar { $var = val }")
- @krt.hostclass("foobar").code.should_not be_nil
+ @parser.parse("class foobar { $var = val }").code[0].code.should_not be_nil
end
it "should define parameters when provided" do
- @parser.parse("class foobar($biz,$baz) {}")
- @krt.hostclass("foobar").arguments.should == {"biz" => nil, "baz" => nil}
+ foobar = @parser.parse("class foobar($biz,$baz) {}").code[0].instantiate('')[0]
+ foobar.arguments.should == {"biz" => nil, "baz" => nil}
end
end
@@ -400,13 +383,37 @@ describe Puppet::Parser do
end
it "should correctly mark exported resources as exported" do
- @parser.parse("@@file { '/file': }")
- @krt.hostclass("").code[0].exported.should be_true
+ @parser.parse("@@file { '/file': }").code[0].exported.should be_true
end
it "should correctly mark virtual resources as virtual" do
- @parser.parse("@file { '/file': }")
- @krt.hostclass("").code[0].virtual.should be_true
+ @parser.parse("@file { '/file': }").code[0].virtual.should be_true
+ end
+ end
+
+ describe "when parsing nodes" do
+ it "should be able to parse a node with a single name" do
+ node = @parser.parse("node foo { }").code[0]
+ node.should be_a Puppet::Parser::AST::Node
+ node.names.length.should == 1
+ node.names[0].value.should == "foo"
+ end
+
+ it "should be able to parse a node with two names" do
+ node = @parser.parse("node foo, bar { }").code[0]
+ node.should be_a Puppet::Parser::AST::Node
+ node.names.length.should == 2
+ node.names[0].value.should == "foo"
+ node.names[1].value.should == "bar"
+ end
+
+ it "should be able to parse a node with three names" do
+ node = @parser.parse("node foo, bar, baz { }").code[0]
+ node.should be_a Puppet::Parser::AST::Node
+ node.names.length.should == 3
+ node.names[0].value.should == "foo"
+ node.names[1].value.should == "bar"
+ node.names[2].value.should == "baz"
end
end
end
diff --git a/spec/unit/parser/resource_spec.rb b/spec/unit/parser/resource_spec.rb
index da49940b0..dae22fcaa 100755
--- a/spec/unit/parser/resource_spec.rb
+++ b/spec/unit/parser/resource_spec.rb
@@ -58,23 +58,17 @@ describe Puppet::Parser::Resource do
end
it "should get its environment from its scope" do
- scope = stub 'scope', :source => stub("source")
- scope.expects(:environment).returns "foo"
+ scope = stub 'scope', :source => stub("source"), :namespaces => nil
+ scope.expects(:environment).returns("foo").at_least_once
Puppet::Parser::Resource.new("file", "whatever", :scope => scope).environment.should == "foo"
end
- it "should get its namespaces from its scope" do
- scope = stub 'scope', :source => stub("source")
- scope.expects(:namespaces).returns %w{one two}
- Puppet::Parser::Resource.new("file", "whatever", :scope => scope).namespaces.should == %w{one two}
- end
-
it "should use the resource type collection helper module" do
Puppet::Parser::Resource.ancestors.should be_include(Puppet::Resource::TypeCollectionHelper)
end
it "should use the scope's environment as its environment" do
- @scope.expects(:environment).returns "myenv"
+ @scope.expects(:environment).returns("myenv").at_least_once
Puppet::Parser::Resource.new("file", "whatever", :scope => @scope).environment.should == "myenv"
end
diff --git a/spec/unit/parser/scope_spec.rb b/spec/unit/parser/scope_spec.rb
index 9895f446b..2e390a53b 100755
--- a/spec/unit/parser/scope_spec.rb
+++ b/spec/unit/parser/scope_spec.rb
@@ -29,8 +29,7 @@ describe Puppet::Parser::Scope do
end
it "should be able to retrieve its parent module name from the source of its parent type" do
- @topscope.source = Puppet::Resource::Type.new(:hostclass, :foo)
- @topscope.source.module_name = "foo"
+ @topscope.source = Puppet::Resource::Type.new(:hostclass, :foo, :module_name => "foo")
@scope.parent_module_name.should == "foo"
end
diff --git a/spec/unit/parser/templatewrapper_spec.rb b/spec/unit/parser/templatewrapper_spec.rb
index d4d1d1b8e..68d90a1cc 100755
--- a/spec/unit/parser/templatewrapper_spec.rb
+++ b/spec/unit/parser/templatewrapper_spec.rb
@@ -1,6 +1,7 @@
#!/usr/bin/env ruby
require File.dirname(__FILE__) + '/../../spec_helper'
+require 'puppet/parser/templatewrapper'
describe Puppet::Parser::TemplateWrapper do
before(:each) do
diff --git a/spec/unit/parser/type_loader_spec.rb b/spec/unit/parser/type_loader_spec.rb
index 8f005d551..cfa68871d 100644
--- a/spec/unit/parser/type_loader_spec.rb
+++ b/spec/unit/parser/type_loader_spec.rb
@@ -28,92 +28,21 @@ describe Puppet::Parser::TypeLoader do
describe "when loading names from namespaces" do
it "should do nothing if the name to import is an empty string" do
@loader.expects(:name2files).never
- @loader.load_until(["foo"], "") { |f| false }.should be_nil
- end
-
- it "should turn the provided namespaces and name into a list of files" do
- @loader.expects(:name2files).with(["foo"], "bar").returns []
- @loader.load_until(["foo"], "bar") { |f| false }
+ @loader.try_load_fqname(:hostclass, "") { |filename, modname| raise :should_not_occur }.should be_nil
end
it "should attempt to import each generated name" do
- @loader.expects(:name2files).returns %w{foo bar}
- @loader.expects(:import).with("foo",nil)
- @loader.expects(:import).with("bar",nil)
- @loader.load_until(["foo"], "bar") { |f| false }
- end
-
- it "should yield after each import" do
- yielded = []
- @loader.expects(:name2files).returns %w{foo bar}
- @loader.expects(:import).with("foo",nil)
- @loader.expects(:import).with("bar",nil)
- @loader.load_until(["foo"], "bar") { |f| yielded << f; false }
- yielded.should == %w{foo bar}
- end
-
- it "should stop importing when the yielded block returns true" do
- yielded = []
- @loader.expects(:name2files).returns %w{foo bar baz}
- @loader.expects(:import).with("foo",nil)
- @loader.expects(:import).with("bar",nil)
- @loader.expects(:import).with("baz",nil).never
- @loader.load_until(["foo"], "bar") { |f| true if f == "bar" }
- end
-
- it "should return the result of the block" do
- yielded = []
- @loader.expects(:name2files).returns %w{foo bar baz}
- @loader.expects(:import).with("foo",nil)
- @loader.expects(:import).with("bar",nil)
- @loader.expects(:import).with("baz",nil).never
- @loader.load_until(["foo"], "bar") { |f| 10 if f == "bar" }.should == 10
- end
-
- it "should return nil if the block never returns true" do
- @loader.expects(:name2files).returns %w{foo bar}
- @loader.expects(:import).with("foo",nil)
- @loader.expects(:import).with("bar",nil)
- @loader.load_until(["foo"], "bar") { |f| false }.should be_nil
- end
-
- it "should know when a given name has been loaded" do
- @loader.expects(:name2files).returns %w{file}
- @loader.expects(:import).with("file",nil)
- @loader.load_until(["foo"], "bar") { |f| true }
- @loader.should be_loaded("file")
- end
-
- it "should set the module name on any created resource types" do
- type = Puppet::Resource::Type.new(:hostclass, "mytype")
-
- Puppet::Parser::Files.expects(:find_manifests).returns ["modname", %w{one}]
- @loader.stubs(:parse_file)
- @loader.load_until(["foo"], "one") { |f| type }
-
- type.module_name.should == "modname"
- end
- end
-
- describe "when mapping names to files" do
- {
- [["foo"], "::bar::baz"] => %w{bar/baz},
- [[""], "foo::bar"] => %w{foo foo/bar},
- [%w{foo}, "bar"] => %w{foo foo/bar bar},
- [%w{a b}, "bar"] => %w{a a/bar b b/bar bar},
- [%w{a::b::c}, "bar"] => %w{a a/b/c/bar bar},
- [%w{a::b}, "foo::bar"] => %w{a a/b/foo/bar foo/bar}
- }.each do |inputs, outputs|
- it "should produce #{outputs.inspect} from the #{inputs[0].inspect} namespace and #{inputs[1]} name" do
- @loader.name2files(*inputs).should == outputs
- end
+ @loader.expects(:import).with("foo/bar",nil).returns([])
+ @loader.expects(:import).with("foo",nil).returns([])
+ @loader.try_load_fqname(:hostclass, "foo::bar") { |f| false }
end
end
describe "when importing" do
before do
Puppet::Parser::Files.stubs(:find_manifests).returns ["modname", %w{file}]
- @loader.stubs(:parse_file)
+ Puppet::Parser::Parser.any_instance.stubs(:parse).returns(Puppet::Parser::AST::Hostclass.new(''))
+ Puppet::Parser::Parser.any_instance.stubs(:file=)
end
it "should return immediately when imports are being ignored" do
@@ -144,26 +73,19 @@ describe Puppet::Parser::TypeLoader do
it "should parse each found file" do
Puppet::Parser::Files.expects(:find_manifests).returns ["modname", %w{/one}]
- @loader.expects(:parse_file).with("/one")
+ @loader.expects(:parse_file).with("/one").returns(Puppet::Parser::AST::Hostclass.new(''))
@loader.import("myfile")
end
it "should make each file qualified before attempting to parse it" do
Puppet::Parser::Files.expects(:find_manifests).returns ["modname", %w{one}]
- @loader.expects(:parse_file).with("/current/one")
+ @loader.expects(:parse_file).with("/current/one").returns(Puppet::Parser::AST::Hostclass.new(''))
@loader.import("myfile", "/current/file")
end
- it "should know when a given file has been imported" do
- Puppet::Parser::Files.expects(:find_manifests).returns ["modname", %w{/one}]
- @loader.import("myfile")
-
- @loader.should be_imported("/one")
- end
-
it "should not attempt to import files that have already been imported" do
Puppet::Parser::Files.expects(:find_manifests).returns ["modname", %w{/one}]
- @loader.expects(:parse_file).once
+ Puppet::Parser::Parser.any_instance.expects(:parse).once.returns(Puppet::Parser::AST::Hostclass.new(''))
@loader.import("myfile")
# This will fail if it tries to reimport the file.
@@ -174,7 +96,7 @@ describe Puppet::Parser::TypeLoader do
describe "when parsing a file" do
before do
@parser = Puppet::Parser::Parser.new(@loader.environment)
- @parser.stubs(:parse)
+ @parser.stubs(:parse).returns(Puppet::Parser::AST::Hostclass.new(''))
@parser.stubs(:file=)
Puppet::Parser::Parser.stubs(:new).with(@loader.environment).returns @parser
end
@@ -186,16 +108,27 @@ describe Puppet::Parser::TypeLoader do
it "should assign the parser its file and parse" do
@parser.expects(:file=).with("/my/file")
- @parser.expects(:parse)
+ @parser.expects(:parse).returns(Puppet::Parser::AST::Hostclass.new(''))
@loader.parse_file("/my/file")
end
end
it "should be able to add classes to the current resource type collection" do
- file = tmpfile("simple_file")
+ file = tmpfile("simple_file.pp")
File.open(file, "w") { |f| f.puts "class foo {}" }
@loader.import(file)
@loader.known_resource_types.hostclass("foo").should be_instance_of(Puppet::Resource::Type)
end
+
+ describe "when deciding where to look for files" do
+ { 'foo' => ['foo'],
+ 'foo::bar' => ['foo/bar', 'foo'],
+ 'foo::bar::baz' => ['foo/bar/baz', 'foo/bar', 'foo']
+ }.each do |fqname, expected_paths|
+ it "should look for #{fqname.inspect} in #{expected_paths.inspect}" do
+ @loader.instance_eval { name2files(fqname) }.should == expected_paths
+ end
+ end
+ end
end
diff --git a/spec/unit/provider/confine/exists_spec.rb b/spec/unit/provider/confine/exists_spec.rb
index c3958e317..f039208b8 100755
--- a/spec/unit/provider/confine/exists_spec.rb
+++ b/spec/unit/provider/confine/exists_spec.rb
@@ -39,25 +39,18 @@ describe Puppet::Provider::Confine::Exists do
describe "and the confine is for binaries" do
before { @confine.stubs(:for_binary).returns true }
- it "should use its 'binary' method to look up the full path of the file" do
- @confine.expects(:binary).returns nil
+ it "should use its 'which' method to look up the full path of the file" do
+ @confine.expects(:which).returns nil
@confine.pass?("/my/file")
end
- it "should return false if no binary can be found" do
- @confine.expects(:binary).with("/my/file").returns nil
+ it "should return false if no executable can be found" do
+ @confine.expects(:which).with("/my/file").returns nil
@confine.pass?("/my/file").should be_false
end
- it "should return true if the binary can be found and the file exists" do
- @confine.expects(:binary).with("/my/file").returns "/my/file"
- FileTest.expects(:exist?).with("/my/file").returns true
- @confine.pass?("/my/file").should be_true
- end
-
- it "should return false if the binary can be found but the file does not exist" do
- @confine.expects(:binary).with("/my/file").returns "/my/file"
- FileTest.expects(:exist?).with("/my/file").returns true
+ it "should return true if the executable can be found" do
+ @confine.expects(:which).with("/my/file").returns "/my/file"
@confine.pass?("/my/file").should be_true
end
end
diff --git a/spec/unit/provider/host/parsed_spec.rb b/spec/unit/provider/host/parsed_spec.rb
new file mode 100644
index 000000000..239e3bd86
--- /dev/null
+++ b/spec/unit/provider/host/parsed_spec.rb
@@ -0,0 +1,196 @@
+#!/usr/bin/env ruby
+
+require File.dirname(__FILE__) + '/../../../spec_helper'
+
+require 'puppet_spec/files'
+require 'puppettest/support/utils'
+require 'puppettest/fileparsing'
+
+provider_class = Puppet::Type.type(:host).provider(:parsed)
+
+describe provider_class do
+ include PuppetSpec::Files
+ extend PuppetTest::Support::Utils
+ include PuppetTest::FileParsing
+
+ before do
+ @host_class = Puppet::Type.type(:host)
+ @provider = @host_class.provider(:parsed)
+ @hostfile = tmpfile('hosts')
+ @provider.any_instance.stubs(:target).returns @hostfile
+ end
+
+ after :each do
+ @provider.initvars
+ end
+
+ def mkhost(args)
+ hostresource = Puppet::Type::Host.new(:name => args[:name])
+ hostresource.stubs(:should).with(:target).returns @hostfile
+
+ # Using setters of provider
+ host = @provider.new(hostresource)
+ args.each do |property,value|
+ host.send("#{property}=", value)
+ end
+ host
+ end
+
+ def genhost(host)
+ @provider.stubs(:filetype).returns(Puppet::Util::FileType::FileTypeRam)
+ File.stubs(:chown)
+ File.stubs(:chmod)
+ Puppet::Util::SUIDManager.stubs(:asuser).yields
+ host.flush
+ @provider.target_object(@hostfile).read
+ end
+
+ describe "when parsing a line with ip and hostname" do
+
+ it "should parse an ipv4 from the first field" do
+ @provider.parse_line("127.0.0.1 localhost")[:ip].should == "127.0.0.1"
+ end
+
+ it "should parse an ipv6 from the first field" do
+ @provider.parse_line("::1 localhost")[:ip].should == "::1"
+ end
+
+ it "should parse the name from the second field" do
+ @provider.parse_line("::1 localhost")[:name].should == "localhost"
+ end
+
+ it "should set an empty comment" do
+ @provider.parse_line("::1 localhost")[:comment].should == ""
+ end
+
+ end
+
+ describe "when parsing a line with ip, hostname and comment" do
+ before do
+ @testline = "127.0.0.1 localhost # A comment with a #-char"
+ end
+
+ it "should parse the ip from the first field" do
+ @provider.parse_line(@testline)[:ip].should == "127.0.0.1"
+ end
+
+ it "should parse the hostname from the second field" do
+ @provider.parse_line(@testline)[:name].should == "localhost"
+ end
+
+ it "should parse the comment after the first '#' character" do
+ @provider.parse_line(@testline)[:comment].should == 'A comment with a #-char'
+ end
+
+ end
+
+ describe "when parsing a line with ip, hostname and aliases" do
+
+ it "should parse alias from the third field" do
+ @provider.parse_line("127.0.0.1 localhost localhost.localdomain")[:host_aliases].should == ["localhost.localdomain"]
+ end
+
+ it "should parse multiple aliases" do
+ @provider.parse_line("127.0.0.1 host alias1 alias2")[:host_aliases].should == ['alias1', 'alias2']
+ @provider.parse_line("127.0.0.1 host alias1\talias2")[:host_aliases].should == ['alias1', 'alias2']
+ @provider.parse_line("127.0.0.1 host alias1\talias2 alias3")[:host_aliases].should == ['alias1', 'alias2', 'alias3']
+ end
+
+ end
+
+ describe "when parsing a line with ip, hostname, aliases and comment" do
+
+ before do
+ # Just playing with a few different delimiters
+ @testline = "127.0.0.1\t host alias1\talias2 alias3 # A comment with a #-char"
+ end
+
+ it "should parse the ip from the first field" do
+ @provider.parse_line(@testline)[:ip].should == "127.0.0.1"
+ end
+
+ it "should parse the hostname from the second field" do
+ @provider.parse_line(@testline)[:name].should == "host"
+ end
+
+ it "should parse all host_aliases from the third field" do
+ @provider.parse_line(@testline)[:host_aliases].should == ['alias1' ,'alias2', 'alias3']
+ end
+
+ it "should parse the comment after the first '#' character" do
+ @provider.parse_line(@testline)[:comment].should == 'A comment with a #-char'
+ end
+
+ end
+
+ describe "when operating on /etc/hosts like files" do
+ fakedata("data/providers/host/parsed","valid*").each do |file|
+ it "should be able to parse #{file}" do
+ fakedataparse(file)
+ end
+ end
+
+ it "should be able to generate a simple hostfile entry" do
+ host = mkhost(
+ :name => 'localhost',
+ :ip => '127.0.0.1',
+ :ensure => :present
+ )
+ genhost(host).should == "127.0.0.1\tlocalhost\n"
+ end
+
+ it "should be able to generate an entry with one alias" do
+ host = mkhost(
+ :name => 'localhost.localdomain',
+ :ip => '127.0.0.1',
+ :host_aliases => ['localhost'],
+ :ensure => :present
+ )
+ genhost(host).should == "127.0.0.1\tlocalhost.localdomain\tlocalhost\n"
+ end
+
+ it "should be able to generate an entry with more than one alias" do
+ host = mkhost(
+ :name => 'host',
+ :ip => '192.0.0.1',
+ :host_aliases => [ 'a1','a2','a3','a4' ],
+ :ensure => :present
+ )
+ genhost(host).should == "192.0.0.1\thost\ta1\ta2\ta3\ta4\n"
+ end
+
+ it "should be able to generate a simple hostfile entry with comments" do
+ host = mkhost(
+ :name => 'localhost',
+ :ip => '127.0.0.1',
+ :comment => 'Bazinga!',
+ :ensure => :present
+ )
+ genhost(host).should == "127.0.0.1\tlocalhost\t# Bazinga!\n"
+ end
+
+ it "should be able to generate an entry with one alias and a comment" do
+ host = mkhost(
+ :name => 'localhost.localdomain',
+ :ip => '127.0.0.1',
+ :host_aliases => ['localhost'],
+ :comment => 'Bazinga!',
+ :ensure => :present
+ )
+ genhost(host).should == "127.0.0.1\tlocalhost.localdomain\tlocalhost\t# Bazinga!\n"
+ end
+
+ it "should be able to generate an entry with more than one alias and a comment" do
+ host = mkhost(
+ :name => 'host',
+ :ip => '192.0.0.1',
+ :host_aliases => [ 'a1','a2','a3','a4' ],
+ :comment => 'Bazinga!',
+ :ensure => :present
+ )
+ genhost(host).should == "192.0.0.1\thost\ta1\ta2\ta3\ta4\t# Bazinga!\n"
+ end
+
+ end
+
+end
diff --git a/spec/unit/provider/mount_spec.rb b/spec/unit/provider/mount_spec.rb
index 55a52b44a..b034214ee 100755
--- a/spec/unit/provider/mount_spec.rb
+++ b/spec/unit/provider/mount_spec.rb
@@ -113,7 +113,14 @@ describe Puppet::Provider::Mount do
@mounter.should be_mounted
end
- it "should match ' on <name>' if the operating system is not Darwin or Solaris" do
+ it "should match '^<name> on' if the operating system is HP-UX" do
+ Facter.stubs(:value).with("operatingsystem").returns("HP-UX")
+ @mounter.expects(:mountcmd).returns("/ on /dev/dsk/whatever\n/var on /dev/dsk/other")
+
+ @mounter.should be_mounted
+ end
+
+ it "should match ' on <name>' if the operating system is not Darwin, Solaris, or HP-UX" do
Facter.stubs(:value).with("operatingsystem").returns("Debian")
@mounter.expects(:mountcmd).returns("/dev/dsk/whatever on / and stuff\n/dev/other/disk on /var and stuff")
diff --git a/spec/unit/provider/package/yum_spec.rb b/spec/unit/provider/package/yum_spec.rb
new file mode 100644
index 000000000..f6a99aa78
--- /dev/null
+++ b/spec/unit/provider/package/yum_spec.rb
@@ -0,0 +1,67 @@
+#!/usr/bin/env ruby
+
+require File.dirname(__FILE__) + '/../../../spec_helper'
+
+provider = Puppet::Type.type(:package).provider(:yum)
+
+describe provider do
+ before do
+ # Create a mock resource
+ @resource = stub 'resource'
+ @resource.stubs(:[]).with(:name).returns 'mypackage'
+ @provider = provider.new(@resource)
+ @provider.stubs(:resource).returns @resource
+ @provider.stubs(:yum).returns 'yum'
+ @provider.stubs(:rpm).returns 'rpm'
+ @provider.stubs(:get).with(:name).returns 'mypackage'
+ @provider.stubs(:get).with(:version).returns '1'
+ @provider.stubs(:get).with(:release).returns '1'
+ @provider.stubs(:get).with(:arch).returns 'i386'
+ end
+ # provider should repond to the following methods
+ [:install, :latest, :update, :purge].each do |method|
+ it "should have a(n) #{method}" do
+ @provider.should respond_to(method)
+ end
+ end
+
+ describe 'when installing' do
+ it 'should call yum install for :installed' do
+ @resource.stubs(:should).with(:ensure).returns :installed
+ @provider.expects(:yum).with('-d', '0', '-e', '0', '-y', :install, 'mypackage')
+ @provider.install
+ end
+ it 'should use :install to update' do
+ @provider.expects(:install)
+ @provider.update
+ end
+ it 'should be able to set version' do
+ @resource.stubs(:should).with(:ensure).returns '1.2'
+ @provider.expects(:yum).with('-d', '0', '-e', '0', '-y', :install, 'mypackage-1.2')
+ @provider.stubs(:query).returns :ensure => '1.2'
+ @provider.install
+ end
+ it 'should be able to downgrade' do
+ @resource.stubs(:should).with(:ensure).returns '1.0'
+ @provider.expects(:yum).with('-d', '0', '-e', '0', '-y', :downgrade, 'mypackage-1.0')
+ @provider.stubs(:query).returns(:ensure => '1.2').then.returns(:ensure => '1.0')
+ @provider.install
+ end
+ end
+
+ describe 'when uninstalling' do
+ it 'should use erase to purge' do
+ @provider.expects(:yum).with('-y', :erase, 'mypackage')
+ @provider.purge
+ end
+ it 'should use rpm to uninstall' do
+ @provider.expects(:rpm).with('-e', 'mypackage-1-1.i386')
+ @provider.uninstall
+ end
+ end
+
+ it 'should be versionable' do
+ provider.should be_versionable
+ end
+end
+
diff --git a/spec/unit/provider/service/freebsd_spec.rb b/spec/unit/provider/service/freebsd_spec.rb
new file mode 100644
index 000000000..0330adbed
--- /dev/null
+++ b/spec/unit/provider/service/freebsd_spec.rb
@@ -0,0 +1,50 @@
+#!/usr/bin/env ruby
+
+require File.dirname(__FILE__) + '/../../../spec_helper'
+
+provider_class = Puppet::Type.type(:service).provider(:freebsd)
+
+describe provider_class do
+ before :each do
+ @provider = provider_class.new
+ @provider.stubs(:initscript)
+ end
+
+ it "should correctly parse rcvar for FreeBSD < 7" do
+ @provider.stubs(:execute).returns <<OUTPUT
+# ntpd
+$ntpd_enable=YES
+OUTPUT
+ @provider.rcvar.should == ['# ntpd', 'ntpd_enable=YES']
+ end
+
+ it "should correctly parse rcvar for FreeBSD 7 to 8" do
+ @provider.stubs(:execute).returns <<OUTPUT
+# ntpd
+ntpd_enable=YES
+OUTPUT
+ @provider.rcvar.should == ['# ntpd', 'ntpd_enable=YES']
+ end
+
+ it "should correctly parse rcvar for FreeBSD >= 8.1" do
+ @provider.stubs(:execute).returns <<OUTPUT
+# ntpd
+#
+ntpd_enable="YES"
+# (default: "")
+OUTPUT
+ @provider.rcvar.should == ['# ntpd', 'ntpd_enable="YES"', '# (default: "")']
+ end
+
+ it "should find the right rcvar_value for FreeBSD < 7" do
+ @provider.stubs(:rcvar).returns(['# ntpd', 'ntpd_enable=YES'])
+
+ @provider.rcvar_value.should == "YES"
+ end
+
+ it "should find the right rcvar_value for FreeBSD >= 7" do
+ @provider.stubs(:rcvar).returns(['# ntpd', 'ntpd_enable="YES"', '# (default: "")'])
+
+ @provider.rcvar_value.should == "YES"
+ end
+end
diff --git a/spec/unit/provider/service/launchd_spec.rb b/spec/unit/provider/service/launchd_spec.rb
index 320ee3ace..43e4cba8e 100755
--- a/spec/unit/provider/service/launchd_spec.rb
+++ b/spec/unit/provider/service/launchd_spec.rb
@@ -98,19 +98,22 @@ describe provider_class do
it "should return true if the job plist says disabled is true and the global overrides says disabled is false" do
provider_class.stubs(:get_macosx_version_major).returns("10.6")
@provider.stubs(:plist_from_label).returns(["foo", {"Disabled" => true}])
- Plist.stubs(:parse_xml).returns({@resource[:name] => {"Disabled" => false}})
+ @provider.class.stubs(:read_plist).returns({@resource[:name] => {"Disabled" => false}})
+ FileTest.expects(:file?).with(Launchd_Overrides).returns(true)
@provider.enabled?.should == :true
end
it "should return false if the job plist says disabled is false and the global overrides says disabled is true" do
provider_class.stubs(:get_macosx_version_major).returns("10.6")
@provider.stubs(:plist_from_label).returns(["foo", {"Disabled" => false}])
- Plist.stubs(:parse_xml).returns({@resource[:name] => {"Disabled" => true}})
+ @provider.class.stubs(:read_plist).returns({@resource[:name] => {"Disabled" => true}})
+ FileTest.expects(:file?).with(Launchd_Overrides).returns(true)
@provider.enabled?.should == :false
end
it "should return true if the job plist and the global overrides have no disabled keys" do
provider_class.stubs(:get_macosx_version_major).returns("10.6")
@provider.stubs(:plist_from_label).returns(["foo", {}])
- Plist.stubs(:parse_xml).returns({})
+ @provider.class.stubs(:read_plist).returns({})
+ FileTest.expects(:file?).with(Launchd_Overrides).returns(true)
@provider.enabled?.should == :true
end
end
@@ -182,7 +185,7 @@ describe provider_class do
describe "when enabling the service on OS X 10.6" do
it "should write to the global launchd overrides file once" do
provider_class.stubs(:get_macosx_version_major).returns("10.6")
- Plist.stubs(:parse_xml).returns({})
+ @provider.class.stubs(:read_plist).returns({})
Plist::Emit.expects(:save_plist).once
@provider.enable
end
@@ -191,7 +194,7 @@ describe provider_class do
describe "when disabling the service on OS X 10.6" do
it "should write to the global launchd overrides file once" do
provider_class.stubs(:get_macosx_version_major).returns("10.6")
- Plist.stubs(:parse_xml).returns({})
+ @provider.class.stubs(:read_plist).returns({})
Plist::Emit.expects(:save_plist).once
@provider.enable
end
diff --git a/spec/unit/provider/service/upstart.rb b/spec/unit/provider/service/upstart.rb
new file mode 100644
index 000000000..9fde9e67f
--- /dev/null
+++ b/spec/unit/provider/service/upstart.rb
@@ -0,0 +1,49 @@
+#!/usr/bin/env ruby
+
+require File.dirname(__FILE__) + '/../../../spec_helper'
+
+provider_class = Puppet::Type.type(:service).provider(:upstart)
+
+describe provider_class do
+ describe "#instances" do
+ it "should be able to find all instances" do
+ processes = ["rc stop/waiting", "ssh start/running, process 712"]
+ provider_class.stubs(:execpipe).yields(processes)
+ provider_class.instances.map {|provider| provider.name}.should =~ ["rc","ssh"]
+ end
+
+ it "should attach the interface name for network interfaces" do
+ processes = ["network-interface (eth0)"]
+ provider_class.stubs(:execpipe).yields(processes)
+ provider_class.instances.first.name.should == "network-interface INTERFACE=eth0"
+ end
+ end
+
+ describe "#status" do
+ it "should allow the user to override the status command" do
+ resource = Puppet::Type.type(:service).new(:name => "foo", :provider => :upstart, :status => "/bin/foo")
+ provider = provider_class.new(resource)
+
+ provider.expects(:ucommand).with { `true`; true }
+ provider.status.should == :running
+ end
+
+ it "should use the default status command if none is specified" do
+ resource = Puppet::Type.type(:service).new(:name => "foo", :provider => :upstart)
+ provider = provider_class.new(resource)
+
+ provider.expects(:status_exec).with(["foo"]).returns("foo start/running, process 1000")
+ Process::Status.any_instance.stubs(:exitstatus).returns(0)
+ provider.status.should == :running
+ end
+
+ it "should properly handle services with 'start' in their name" do
+ resource = Puppet::Type.type(:service).new(:name => "foostartbar", :provider => :upstart)
+ provider = provider_class.new(resource)
+
+ provider.expects(:status_exec).with(["foostartbar"]).returns("foostartbar stop/waiting")
+ Process::Status.any_instance.stubs(:exitstatus).returns(0)
+ provider.status.should == :stopped
+ end
+ end
+end
diff --git a/spec/unit/provider/ssh_authorized_key/parsed_spec.rb b/spec/unit/provider/ssh_authorized_key/parsed_spec.rb
index 059d010bb..11e9233e0 100755
--- a/spec/unit/provider/ssh_authorized_key/parsed_spec.rb
+++ b/spec/unit/provider/ssh_authorized_key/parsed_spec.rb
@@ -3,21 +3,22 @@
require File.dirname(__FILE__) + '/../../../spec_helper'
require 'puppet_spec/files'
-require 'puppettest'
require 'puppettest/support/utils'
require 'puppettest/fileparsing'
+require 'puppettest/fakes'
provider_class = Puppet::Type.type(:ssh_authorized_key).provider(:parsed)
describe provider_class do
include PuppetSpec::Files
+ extend PuppetTest::Support::Utils
include PuppetTest
include PuppetTest::FileParsing
before :each do
@sshauthkey_class = Puppet::Type.type(:ssh_authorized_key)
@provider = @sshauthkey_class.provider(:parsed)
- @keyfile = File.join(Dir.tmpdir, 'authorized_keys')
+ @keyfile = tmpfile('authorized_keys')
@provider.any_instance.stubs(:target).returns @keyfile
@user = 'random_bob'
Puppet::Util.stubs(:uid).with(@user).returns 12345
@@ -49,7 +50,7 @@ describe provider_class do
@provider.target_object(@keyfile).read
end
- PuppetTest.fakedata("data/providers/ssh_authorized_key/parsed").each { |file|
+ fakedata("data/providers/ssh_authorized_key/parsed").each { |file|
it "should be able to parse example data in #{file}" do
fakedataparse(file)
end
diff --git a/spec/unit/provider/user/user_role_add_spec.rb b/spec/unit/provider/user/user_role_add_spec.rb
index 211f4260a..9cf649267 100644
--- a/spec/unit/provider/user/user_role_add_spec.rb
+++ b/spec/unit/provider/user/user_role_add_spec.rb
@@ -56,7 +56,7 @@ describe provider_class do
it "should use the add command when the user is not a role" do
@provider.stubs(:is_role?).returns(false)
@provider.expects(:addcmd).returns("useradd")
- @provider.expects(:run)
+ @provider.expects(:run).at_least_once
@provider.create
end
@@ -66,6 +66,15 @@ describe provider_class do
@provider.expects(:run)
@provider.create
end
+
+ it "should set password age rules" do
+ @resource = Puppet::Type.type(:user).new :name => "myuser", :password_min_age => 5, :password_max_age => 10, :provider => :user_role_add
+ @provider = provider_class.new(@resource)
+ @provider.stubs(:user_attributes)
+ @provider.stubs(:execute)
+ @provider.expects(:execute).with { |cmd, *args| args == ["-n", 5, "-x", 10, "myuser"] }
+ @provider.create
+ end
end
describe "when calling destroy" do
@@ -107,6 +116,7 @@ describe provider_class do
before do
@resource.expects(:allowdupe?).returns true
@provider.stubs(:is_role?).returns(false)
+ @provider.stubs(:execute)
@provider.expects(:execute).with { |args| args.include?("-o") }
end
@@ -246,4 +256,11 @@ describe provider_class do
@provider.password=("hashedpassword")
end
end
+
+ describe "#shadow_entry" do
+ it "should return the line for the right user" do
+ File.stubs(:readlines).returns(["someuser:!:10:5:20:7:1::\n", "fakeval:*:20:10:30:7:2::\n", "testuser:*:30:15:40:7:3::\n"])
+ @provider.shadow_entry.should == ["fakeval", "*", "20", "10", "30", "7", "2"]
+ end
+ end
end
diff --git a/spec/unit/provider/user/useradd_spec.rb b/spec/unit/provider/user/useradd_spec.rb
index 6eb9717b8..9ebba596c 100755
--- a/spec/unit/provider/user/useradd_spec.rb
+++ b/spec/unit/provider/user/useradd_spec.rb
@@ -15,6 +15,7 @@ describe provider_class do
# #1360
it "should add -o when allowdupe is enabled and the user is being created" do
@resource.expects(:allowdupe?).returns true
+ @provider.stubs(:execute)
@provider.expects(:execute).with { |args| args.include?("-o") }
@provider.create
end
@@ -26,6 +27,15 @@ describe provider_class do
@provider.uid = 150
end
+ it "should set password age rules" do
+ provider_class.has_feature :manages_password_age
+ @resource = Puppet::Type.type(:user).new :name => "myuser", :password_min_age => 5, :password_max_age => 10, :provider => :useradd
+ @provider = provider_class.new(@resource)
+ @provider.stubs(:execute)
+ @provider.expects(:execute).with { |cmd, *args| args == ["-m", 5, "-M", 10, "myuser"] }
+ @provider.create
+ end
+
describe "when checking to add allow dup" do
it "should check allow dup" do
@resource.expects(:allowdupe?)
@@ -109,7 +119,58 @@ describe provider_class do
@provider.stubs(:command).with(:add).returns("useradd")
@provider.stubs(:add_properties).returns(["-G", "somegroup"])
@resource.stubs(:[]).with(:name).returns("someuser")
+ @resource.stubs(:[]).with(:expiry).returns("somedate")
+ @provider.addcmd.must == ["useradd", "-G", "somegroup", "-o", "-m", '-e somedate', "someuser"]
+ end
+
+ it "should return an array without -e if expery is undefined full command" do
+ @provider.stubs(:command).with(:add).returns("useradd")
+ @provider.stubs(:add_properties).returns(["-G", "somegroup"])
+ @resource.stubs(:[]).with(:name).returns("someuser")
+ @resource.stubs(:[]).with(:expiry).returns nil
@provider.addcmd.must == ["useradd", "-G", "somegroup", "-o", "-m", "someuser"]
end
end
+
+ describe "when calling passcmd" do
+ before do
+ @resource.stubs(:allowdupe?).returns true
+ @resource.stubs(:managehome?).returns true
+ end
+
+ it "should call command with :pass" do
+ @provider.expects(:command).with(:password)
+ @provider.passcmd
+ end
+
+ it "should return nil if neither min nor max is set" do
+ @resource.stubs(:should).with(:password_min_age).returns nil
+ @resource.stubs(:should).with(:password_max_age).returns nil
+ @provider.passcmd.must == nil
+ end
+
+ it "should return a chage command array with -m <value> and the user name if password_min_age is set" do
+ @provider.stubs(:command).with(:password).returns("chage")
+ @resource.stubs(:[]).with(:name).returns("someuser")
+ @resource.stubs(:should).with(:password_min_age).returns 123
+ @resource.stubs(:should).with(:password_max_age).returns nil
+ @provider.passcmd.must == ['chage','-m',123,'someuser']
+ end
+
+ it "should return a chage command array with -M <value> if password_max_age is set" do
+ @provider.stubs(:command).with(:password).returns("chage")
+ @resource.stubs(:[]).with(:name).returns("someuser")
+ @resource.stubs(:should).with(:password_min_age).returns nil
+ @resource.stubs(:should).with(:password_max_age).returns 999
+ @provider.passcmd.must == ['chage','-M',999,'someuser']
+ end
+
+ it "should return a chage command array with -M <value> -m <value> if both password_min_age and password_max_age are set" do
+ @provider.stubs(:command).with(:password).returns("chage")
+ @resource.stubs(:[]).with(:name).returns("someuser")
+ @resource.stubs(:should).with(:password_min_age).returns 123
+ @resource.stubs(:should).with(:password_max_age).returns 999
+ @provider.passcmd.must == ['chage','-m',123,'-M',999,'someuser']
+ end
+ end
end
diff --git a/spec/unit/rails/param_value_spec.rb b/spec/unit/rails/param_value_spec.rb
index d6dc7d57b..243456e89 100755
--- a/spec/unit/rails/param_value_spec.rb
+++ b/spec/unit/rails/param_value_spec.rb
@@ -1,6 +1,7 @@
#!/usr/bin/env ruby
require File.dirname(__FILE__) + '/../../spec_helper'
+require 'puppet/rails'
describe "Puppet::Rails::ParamValue" do
confine "Cannot test without ActiveRecord" => Puppet.features.rails?
diff --git a/spec/unit/rails/resource_spec.rb b/spec/unit/rails/resource_spec.rb
index 08deda65e..6e23d2020 100755
--- a/spec/unit/rails/resource_spec.rb
+++ b/spec/unit/rails/resource_spec.rb
@@ -1,6 +1,7 @@
#!/usr/bin/env ruby
require File.dirname(__FILE__) + '/../../spec_helper'
+require 'puppet/rails'
describe "Puppet::Rails::Resource" do
confine "Cannot test without ActiveRecord" => Puppet.features.rails?
@@ -107,7 +108,7 @@ describe "Puppet::Rails::Resource" do
describe "#to_resource" do
it "should instantiate a Puppet::Parser::Resource" do
- scope = stub "scope", :source => nil
+ scope = stub "scope", :source => nil, :environment => nil, :namespaces => nil
@resource = Puppet::Rails::Resource.new
@resource.stubs(:attributes).returns({
diff --git a/spec/unit/rails_spec.rb b/spec/unit/rails_spec.rb
index eaa968099..24248e622 100755
--- a/spec/unit/rails_spec.rb
+++ b/spec/unit/rails_spec.rb
@@ -47,14 +47,20 @@ describe Puppet::Rails, "when initializing any connection" do
Puppet::Rails.connect
end
- describe "on ActiveRecord 2.1.x" do
- confine("ActiveRecord 2.1.x") { ::ActiveRecord::VERSION::MAJOR == 2 and ::ActiveRecord::VERSION::MINOR <= 1 }
-
- it "should set ActiveRecord::Base.allow_concurrency" do
+ describe "ActiveRecord Version" do
+ it "should set ActiveRecord::Base.allow_concurrency if ActiveRecord is 2.1" do
+ Puppet::Util.stubs(:activerecord_version).returns(2.1)
ActiveRecord::Base.expects(:allow_concurrency=).with(true)
Puppet::Rails.connect
end
+
+ it "should not set ActiveRecord::Base.allow_concurrency if ActiveRecord is >= 2.2" do
+ Puppet::Util.stubs(:activerecord_version).returns(2.2)
+ ActiveRecord::Base.expects(:allow_concurrency=).never
+
+ Puppet::Rails.connect
+ end
end
it "should call ActiveRecord::Base.verify_active_connections!" do
@@ -97,9 +103,9 @@ describe Puppet::Rails, "when initializing a mysql connection" do
Puppet.settings.stubs(:value).with(:dbport).returns("")
Puppet.settings.stubs(:value).with(:dbuser).returns("testuser")
Puppet.settings.stubs(:value).with(:dbpassword).returns("testpassword")
+ Puppet.settings.stubs(:value).with(:dbconnections).returns((pool_size = 45).to_s)
Puppet.settings.stubs(:value).with(:dbname).returns("testname")
Puppet.settings.stubs(:value).with(:dbsocket).returns("")
- Puppet.settings.stubs(:value).with(:dbconnections).returns(1)
Puppet::Rails.database_arguments.should == {
:adapter => "mysql",
@@ -107,9 +113,9 @@ describe Puppet::Rails, "when initializing a mysql connection" do
:host => "testserver",
:username => "testuser",
:password => "testpassword",
+ :pool => pool_size,
:database => "testname",
- :reconnect => true,
- :pool => 1
+ :reconnect => true
}
end
@@ -120,9 +126,9 @@ describe Puppet::Rails, "when initializing a mysql connection" do
Puppet.settings.stubs(:value).with(:dbport).returns("9999")
Puppet.settings.stubs(:value).with(:dbuser).returns("testuser")
Puppet.settings.stubs(:value).with(:dbpassword).returns("testpassword")
+ Puppet.settings.stubs(:value).with(:dbconnections).returns((pool_size = 12).to_s)
Puppet.settings.stubs(:value).with(:dbname).returns("testname")
Puppet.settings.stubs(:value).with(:dbsocket).returns("testsocket")
- Puppet.settings.stubs(:value).with(:dbconnections).returns(1)
Puppet::Rails.database_arguments.should == {
:adapter => "mysql",
@@ -131,10 +137,10 @@ describe Puppet::Rails, "when initializing a mysql connection" do
:port => "9999",
:username => "testuser",
:password => "testpassword",
+ :pool => pool_size,
:database => "testname",
:socket => "testsocket",
- :reconnect => true,
- :pool => 1
+ :reconnect => true
}
end
@@ -145,9 +151,9 @@ describe Puppet::Rails, "when initializing a mysql connection" do
Puppet.settings.stubs(:value).with(:dbport).returns("9999")
Puppet.settings.stubs(:value).with(:dbuser).returns("testuser")
Puppet.settings.stubs(:value).with(:dbpassword).returns("testpassword")
+ Puppet.settings.stubs(:value).with(:dbconnections).returns((pool_size = 23).to_s)
Puppet.settings.stubs(:value).with(:dbname).returns("testname")
Puppet.settings.stubs(:value).with(:dbsocket).returns("testsocket")
- Puppet.settings.stubs(:value).with(:dbconnections).returns(1)
Puppet::Rails.database_arguments.should == {
:adapter => "mysql",
@@ -156,12 +162,32 @@ describe Puppet::Rails, "when initializing a mysql connection" do
:port => "9999",
:username => "testuser",
:password => "testpassword",
+ :pool => pool_size,
:database => "testname",
:socket => "testsocket",
- :reconnect => true,
- :pool => 1
+ :reconnect => true
}
end
+
+ it "should not provide the pool if dbconnections is 0, '0', or ''" do
+ Puppet.settings.stubs(:value).with(:dbadapter).returns("mysql")
+ Puppet.settings.stubs(:value).with(:rails_loglevel).returns("testlevel")
+ Puppet.settings.stubs(:value).with(:dbserver).returns("testserver")
+ Puppet.settings.stubs(:value).with(:dbport).returns("9999")
+ Puppet.settings.stubs(:value).with(:dbuser).returns("testuser")
+ Puppet.settings.stubs(:value).with(:dbpassword).returns("testpassword")
+ Puppet.settings.stubs(:value).with(:dbname).returns("testname")
+ Puppet.settings.stubs(:value).with(:dbsocket).returns("testsocket")
+
+ Puppet.settings.stubs(:value).with(:dbconnections).returns(0)
+ Puppet::Rails.database_arguments.should_not be_include(:pool)
+
+ Puppet.settings.stubs(:value).with(:dbconnections).returns('0')
+ Puppet::Rails.database_arguments.should_not be_include(:pool)
+
+ Puppet.settings.stubs(:value).with(:dbconnections).returns('')
+ Puppet::Rails.database_arguments.should_not be_include(:pool)
+ end
end
describe Puppet::Rails, "when initializing a postgresql connection" do
@@ -174,9 +200,9 @@ describe Puppet::Rails, "when initializing a postgresql connection" do
Puppet.settings.stubs(:value).with(:dbport).returns("9999")
Puppet.settings.stubs(:value).with(:dbuser).returns("testuser")
Puppet.settings.stubs(:value).with(:dbpassword).returns("testpassword")
+ Puppet.settings.stubs(:value).with(:dbconnections).returns((pool_size = 200).to_s)
Puppet.settings.stubs(:value).with(:dbname).returns("testname")
Puppet.settings.stubs(:value).with(:dbsocket).returns("")
- Puppet.settings.stubs(:value).with(:dbconnections).returns(1)
Puppet::Rails.database_arguments.should == {
:adapter => "postgresql",
@@ -185,9 +211,9 @@ describe Puppet::Rails, "when initializing a postgresql connection" do
:port => "9999",
:username => "testuser",
:password => "testpassword",
+ :pool => pool_size,
:database => "testname",
- :reconnect => true,
- :pool => 1
+ :reconnect => true
}
end
@@ -198,9 +224,9 @@ describe Puppet::Rails, "when initializing a postgresql connection" do
Puppet.settings.stubs(:value).with(:dbport).returns("9999")
Puppet.settings.stubs(:value).with(:dbuser).returns("testuser")
Puppet.settings.stubs(:value).with(:dbpassword).returns("testpassword")
+ Puppet.settings.stubs(:value).with(:dbconnections).returns((pool_size = 122).to_s)
Puppet.settings.stubs(:value).with(:dbname).returns("testname")
Puppet.settings.stubs(:value).with(:dbsocket).returns("testsocket")
- Puppet.settings.stubs(:value).with(:dbconnections).returns(1)
Puppet::Rails.database_arguments.should == {
:adapter => "postgresql",
@@ -209,50 +235,90 @@ describe Puppet::Rails, "when initializing a postgresql connection" do
:port => "9999",
:username => "testuser",
:password => "testpassword",
+ :pool => pool_size,
:database => "testname",
:socket => "testsocket",
- :pool => 1,
:reconnect => true
}
end
+
+ it "should not provide the pool if dbconnections is 0, '0', or ''" do
+ Puppet.settings.stubs(:value).with(:dbadapter).returns("mysql")
+ Puppet.settings.stubs(:value).with(:rails_loglevel).returns("testlevel")
+ Puppet.settings.stubs(:value).with(:dbserver).returns("testserver")
+ Puppet.settings.stubs(:value).with(:dbport).returns("9999")
+ Puppet.settings.stubs(:value).with(:dbuser).returns("testuser")
+ Puppet.settings.stubs(:value).with(:dbpassword).returns("testpassword")
+ Puppet.settings.stubs(:value).with(:dbname).returns("testname")
+ Puppet.settings.stubs(:value).with(:dbsocket).returns("testsocket")
+
+ Puppet.settings.stubs(:value).with(:dbconnections).returns(0)
+ Puppet::Rails.database_arguments.should_not be_include(:pool)
+
+ Puppet.settings.stubs(:value).with(:dbconnections).returns('0')
+ Puppet::Rails.database_arguments.should_not be_include(:pool)
+
+ Puppet.settings.stubs(:value).with(:dbconnections).returns('')
+ Puppet::Rails.database_arguments.should_not be_include(:pool)
+ end
end
describe Puppet::Rails, "when initializing an Oracle connection" do
confine "Cannot test without ActiveRecord" => Puppet.features.rails?
- it "should provide the adapter, log_level, and username, password, dbconnections, and database arguments" do
+ it "should provide the adapter, log_level, and username, password, and database arguments" do
Puppet.settings.stubs(:value).with(:dbadapter).returns("oracle_enhanced")
Puppet.settings.stubs(:value).with(:rails_loglevel).returns("testlevel")
Puppet.settings.stubs(:value).with(:dbuser).returns("testuser")
Puppet.settings.stubs(:value).with(:dbpassword).returns("testpassword")
+ Puppet.settings.stubs(:value).with(:dbconnections).returns((pool_size = 123).to_s)
Puppet.settings.stubs(:value).with(:dbname).returns("testname")
- Puppet.settings.stubs(:value).with(:dbconnections).returns(1)
Puppet::Rails.database_arguments.should == {
:adapter => "oracle_enhanced",
:log_level => "testlevel",
:username => "testuser",
:password => "testpassword",
- :database => "testname",
- :pool => 1
+ :pool => pool_size,
+ :database => "testname"
}
end
- it "should provide the adapter, log_level, and host, username, password, database, pool, and socket arguments" do
+ it "should provide the adapter, log_level, and host, username, password, database and socket arguments" do
Puppet.settings.stubs(:value).with(:dbadapter).returns("oracle_enhanced")
Puppet.settings.stubs(:value).with(:rails_loglevel).returns("testlevel")
Puppet.settings.stubs(:value).with(:dbuser).returns("testuser")
Puppet.settings.stubs(:value).with(:dbpassword).returns("testpassword")
+ Puppet.settings.stubs(:value).with(:dbconnections).returns((pool_size = 124).to_s)
Puppet.settings.stubs(:value).with(:dbname).returns("testname")
- Puppet.settings.stubs(:value).with(:dbconnections).returns(1)
Puppet::Rails.database_arguments.should == {
:adapter => "oracle_enhanced",
:log_level => "testlevel",
:username => "testuser",
:password => "testpassword",
- :database => "testname",
- :pool => 1
+ :pool => pool_size,
+ :database => "testname"
}
end
+
+ it "should not provide the pool if dbconnections is 0, '0', or ''" do
+ Puppet.settings.stubs(:value).with(:dbadapter).returns("mysql")
+ Puppet.settings.stubs(:value).with(:rails_loglevel).returns("testlevel")
+ Puppet.settings.stubs(:value).with(:dbserver).returns("testserver")
+ Puppet.settings.stubs(:value).with(:dbport).returns("9999")
+ Puppet.settings.stubs(:value).with(:dbuser).returns("testuser")
+ Puppet.settings.stubs(:value).with(:dbpassword).returns("testpassword")
+ Puppet.settings.stubs(:value).with(:dbname).returns("testname")
+ Puppet.settings.stubs(:value).with(:dbsocket).returns("testsocket")
+
+ Puppet.settings.stubs(:value).with(:dbconnections).returns(0)
+ Puppet::Rails.database_arguments.should_not be_include(:pool)
+
+ Puppet.settings.stubs(:value).with(:dbconnections).returns('0')
+ Puppet::Rails.database_arguments.should_not be_include(:pool)
+
+ Puppet.settings.stubs(:value).with(:dbconnections).returns('')
+ Puppet::Rails.database_arguments.should_not be_include(:pool)
+ end
end
diff --git a/spec/unit/reports/rrdgraph_spec.rb b/spec/unit/reports/rrdgraph_spec.rb
new file mode 100644
index 000000000..ce2cf7905
--- /dev/null
+++ b/spec/unit/reports/rrdgraph_spec.rb
@@ -0,0 +1,31 @@
+#!/usr/bin/env ruby
+
+Dir.chdir(File.dirname(__FILE__)) { (s = lambda { |f| File.exist?(f) ? require(f) : Dir.chdir("..") { s.call(f) } }).call("spec/spec_helper.rb") }
+
+require 'puppet/reports'
+
+processor = Puppet::Reports.report(:rrdgraph)
+
+describe processor do
+ include PuppetSpec::Files
+ before do
+ Puppet[:rrddir] = tmpdir('rrdgraph')
+ Puppet.settings.use :master
+ end
+
+ after do
+ FileUtils.rm_rf(Puppet[:rrddir])
+ end
+
+ it "should not error on 0.25.x report format" do
+ report = YAML.load_file(File.join(PuppetSpec::FIXTURE_DIR, 'yaml/report0.25.x.yaml')).extend processor
+ report.expects(:mkhtml)
+ lambda{ report.process }.should_not raise_error
+ end
+
+ it "should not error on 2.6.x report format" do
+ report = YAML.load_file(File.join(PuppetSpec::FIXTURE_DIR, 'yaml/report2.6.x.yaml')).extend processor
+ report.expects(:mkhtml)
+ lambda{ report.process }.should_not raise_error
+ end
+end
diff --git a/spec/unit/reports/tagmail_spec.rb b/spec/unit/reports/tagmail_spec.rb
index 4349e999d..bdb16600e 100755
--- a/spec/unit/reports/tagmail_spec.rb
+++ b/spec/unit/reports/tagmail_spec.rb
@@ -3,12 +3,12 @@
Dir.chdir(File.dirname(__FILE__)) { (s = lambda { |f| File.exist?(f) ? require(f) : Dir.chdir("..") { s.call(f) } }).call("spec/spec_helper.rb") }
require 'puppet/reports'
-require 'puppettest'
+require 'puppettest/support/utils'
tagmail = Puppet::Reports.report(:tagmail)
describe tagmail do
- extend PuppetTest
+ extend PuppetTest::Support::Utils
before do
@processor = Puppet::Transaction::Report.new
@@ -31,6 +31,7 @@ describe tagmail do
{
"tag: abuse@domain.com" => [%w{abuse@domain.com}, %w{tag}, []],
+ "tag.localhost: abuse@domain.com" => [%w{abuse@domain.com}, %w{tag.localhost}, []],
"tag, other: abuse@domain.com" => [%w{abuse@domain.com}, %w{tag other}, []],
"tag-other: abuse@domain.com" => [%w{abuse@domain.com}, %w{tag-other}, []],
"tag, !other: abuse@domain.com" => [%w{abuse@domain.com}, %w{tag}, %w{other}],
diff --git a/spec/unit/resource/catalog_spec.rb b/spec/unit/resource/catalog_spec.rb
index 10cff91a3..fbfe29ff3 100755
--- a/spec/unit/resource/catalog_spec.rb
+++ b/spec/unit/resource/catalog_spec.rb
@@ -224,7 +224,7 @@ describe Puppet::Resource::Catalog, "when compiling" do
end
it "should convert parser resources to plain resources" do
- resource = Puppet::Parser::Resource.new(:file, "foo", :scope => stub("scope"), :source => stub("source"))
+ resource = Puppet::Parser::Resource.new(:file, "foo", :scope => stub("scope", :environment => nil, :namespaces => nil), :source => stub("source"))
catalog = Puppet::Resource::Catalog.new("whev")
catalog.add_resource(resource)
new = catalog.to_resource
@@ -374,7 +374,7 @@ describe Puppet::Resource::Catalog, "when compiling" do
@original.add_edge(@r1,@r2)
@original.filter do |r|
r == @r1
- end.edge(@r1,@r2).should be_empty
+ end.edge?(@r1,@r2).should_not be
end
end
@@ -933,8 +933,8 @@ describe Puppet::Resource::Catalog, "when converting to pson" do
@catalog.add_edge(one, two)
@catalog.add_edge(two, three)
- @catalog.edge(one, two ).expects(:to_pson_data_hash).returns "one_two_pson"
- @catalog.edge(two, three).expects(:to_pson_data_hash).returns "two_three_pson"
+ @catalog.edges_between(one, two )[0].expects(:to_pson_data_hash).returns "one_two_pson"
+ @catalog.edges_between(two, three)[0].expects(:to_pson_data_hash).returns "two_three_pson"
PSON.parse(@catalog.to_pson,:create_additions => false)['data']['edges'].sort.should == %w{one_two_pson two_three_pson}.sort
end
diff --git a/spec/unit/resource/type_collection_spec.rb b/spec/unit/resource/type_collection_spec.rb
index 09643cd24..b8da3cf58 100644
--- a/spec/unit/resource/type_collection_spec.rb
+++ b/spec/unit/resource/type_collection_spec.rb
@@ -89,6 +89,34 @@ describe Puppet::Resource::TypeCollection do
loader.node("node").should be_nil
end
+ describe "when resolving namespaces" do
+ [ ['', '::foo', ['foo']],
+ ['a', '::foo', ['foo']],
+ ['a::b', '::foo', ['foo']],
+ [['a::b'], '::foo', ['foo']],
+ [['a::b', 'c'], '::foo', ['foo']],
+ [['A::B', 'C'], '::Foo', ['foo']],
+ ['', '', ['']],
+ ['a', '', ['']],
+ ['a::b', '', ['']],
+ [['a::b'], '', ['']],
+ [['a::b', 'c'], '', ['']],
+ [['A::B', 'C'], '', ['']],
+ ['', 'foo', ['foo']],
+ ['a', 'foo', ['a::foo', 'foo']],
+ ['a::b', 'foo', ['a::b::foo', 'a::foo', 'foo']],
+ ['A::B', 'Foo', ['a::b::foo', 'a::foo', 'foo']],
+ [['a::b'], 'foo', ['a::b::foo', 'a::foo', 'foo']],
+ [['a', 'b'], 'foo', ['a::foo', 'foo', 'b::foo']],
+ [['a::b', 'c::d'], 'foo', ['a::b::foo', 'a::foo', 'foo', 'c::d::foo', 'c::foo']],
+ [['a::b', 'a::c'], 'foo', ['a::b::foo', 'a::foo', 'foo', 'a::c::foo']],
+ ].each do |namespaces, name, expected_result|
+ it "should resolve #{name.inspect} in namespaces #{namespaces.inspect} correctly" do
+ @code.instance_eval { resolve_namespaces(namespaces, name) }.should == expected_result
+ end
+ end
+ end
+
describe "when looking up names" do
before do
@type = Puppet::Resource::Type.new(:hostclass, "ns::klass")
@@ -107,29 +135,32 @@ describe Puppet::Resource::TypeCollection do
describe "that need to be loaded" do
it "should use the loader to load the files" do
- @code.loader.expects(:load_until).with(["ns"], "klass")
- @code.find_or_load(["ns"], "klass", :hostclass)
+ @code.loader.expects(:try_load_fqname).with(:hostclass, "ns::klass")
+ @code.loader.expects(:try_load_fqname).with(:hostclass, "klass")
+ @code.find_hostclass(["ns"], "klass")
end
it "should downcase the name and downcase and array-fy the namespaces before passing to the loader" do
- @code.loader.expects(:load_until).with(["ns"], "klass")
- @code.find_or_load("Ns", "Klass", :hostclass)
+ @code.loader.expects(:try_load_fqname).with(:hostclass, "ns::klass")
+ @code.loader.expects(:try_load_fqname).with(:hostclass, "klass")
+ @code.find_hostclass("Ns", "Klass")
end
- it "should attempt to find the type when the loader yields" do
- @code.loader.expects(:load_until).yields
- @code.expects(:find).with(["ns"], "klass", :hostclass).times(2).returns(false).then.returns(true)
- @code.find_or_load("ns", "klass", :hostclass)
+ it "should use the class returned by the loader" do
+ @code.loader.expects(:try_load_fqname).returns(:klass)
+ @code.expects(:hostclass).with("ns::klass").returns(false)
+ @code.find_hostclass("ns", "klass").should == :klass
end
- it "should return the result of 'load_until'" do
- @code.loader.expects(:load_until).returns "foo"
- @code.find_or_load("Ns", "Klass", :hostclass).should == "foo"
+ it "should return nil if the name isn't found" do
+ @code.stubs(:try_load_fqname).returns(nil)
+ @code.find_hostclass("Ns", "Klass").should be_nil
end
- it "should return nil if the name isn't found" do
- @code.stubs(:load_until).returns(nil)
- @code.find_or_load("Ns", "Klass", :hostclass).should be_nil
+ it "already-loaded names at broader scopes should not shadow autoloaded names" do
+ @code.add Puppet::Resource::Type.new(:hostclass, "bar")
+ @code.loader.expects(:try_load_fqname).with(:hostclass, "foo::bar").returns(:foobar)
+ @code.find_hostclass("foo", "bar").should == :foobar
end
end
end
@@ -195,75 +226,102 @@ describe Puppet::Resource::TypeCollection do
loader = Puppet::Resource::TypeCollection.new("env")
instance = Puppet::Resource::Type.new(:hostclass, "foo::bar")
loader.add instance
- loader.find("namespace", "::foo::bar", :hostclass).should equal(instance)
+ loader.find_hostclass("namespace", "::foo::bar").should equal(instance)
end
it "should return nil if the instance name is fully qualified and no such instance exists" do
loader = Puppet::Resource::TypeCollection.new("env")
- loader.find("namespace", "::foo::bar", :hostclass).should be_nil
+ loader.find_hostclass("namespace", "::foo::bar").should be_nil
end
it "should be able to find classes in the base namespace" do
loader = Puppet::Resource::TypeCollection.new("env")
instance = Puppet::Resource::Type.new(:hostclass, "foo")
loader.add instance
- loader.find("", "foo", :hostclass).should equal(instance)
+ loader.find_hostclass("", "foo").should equal(instance)
end
it "should return the partially qualified object if it exists in a provided namespace" do
loader = Puppet::Resource::TypeCollection.new("env")
instance = Puppet::Resource::Type.new(:hostclass, "foo::bar::baz")
loader.add instance
- loader.find("foo", "bar::baz", :hostclass).should equal(instance)
+ loader.find_hostclass("foo", "bar::baz").should equal(instance)
end
it "should be able to find partially qualified objects in any of the provided namespaces" do
loader = Puppet::Resource::TypeCollection.new("env")
instance = Puppet::Resource::Type.new(:hostclass, "foo::bar::baz")
loader.add instance
- loader.find(["nons", "foo", "otherns"], "bar::baz", :hostclass).should equal(instance)
+ loader.find_hostclass(["nons", "foo", "otherns"], "bar::baz").should equal(instance)
end
it "should return the unqualified object if it exists in a provided namespace" do
loader = Puppet::Resource::TypeCollection.new("env")
instance = Puppet::Resource::Type.new(:hostclass, "foo::bar")
loader.add instance
- loader.find("foo", "bar", :hostclass).should equal(instance)
+ loader.find_hostclass("foo", "bar").should equal(instance)
end
it "should return the unqualified object if it exists in the parent namespace" do
loader = Puppet::Resource::TypeCollection.new("env")
instance = Puppet::Resource::Type.new(:hostclass, "foo::bar")
loader.add instance
- loader.find("foo::bar::baz", "bar", :hostclass).should equal(instance)
+ loader.find_hostclass("foo::bar::baz", "bar").should equal(instance)
end
it "should should return the partially qualified object if it exists in the parent namespace" do
loader = Puppet::Resource::TypeCollection.new("env")
instance = Puppet::Resource::Type.new(:hostclass, "foo::bar::baz")
loader.add instance
- loader.find("foo::bar", "bar::baz", :hostclass).should equal(instance)
+ loader.find_hostclass("foo::bar", "bar::baz").should equal(instance)
end
it "should return the qualified object if it exists in the root namespace" do
loader = Puppet::Resource::TypeCollection.new("env")
instance = Puppet::Resource::Type.new(:hostclass, "foo::bar::baz")
loader.add instance
- loader.find("foo::bar", "foo::bar::baz", :hostclass).should equal(instance)
+ loader.find_hostclass("foo::bar", "foo::bar::baz").should equal(instance)
end
it "should return nil if the object cannot be found" do
loader = Puppet::Resource::TypeCollection.new("env")
instance = Puppet::Resource::Type.new(:hostclass, "foo::bar::baz")
loader.add instance
- loader.find("foo::bar", "eh", :hostclass).should be_nil
+ loader.find_hostclass("foo::bar", "eh").should be_nil
end
+
+ describe "when topscope has a class that has the same name as a local class" do
+ before do
+ @loader = Puppet::Resource::TypeCollection.new("env")
+ [ "foo::bar", "bar" ].each do |name|
+ @loader.add Puppet::Resource::Type.new(:hostclass, name)
+ end
+ end
+
+ it "should favor the local class, if the name is unqualified" do
+ @loader.find_hostclass("foo", "bar").name.should == 'foo::bar'
+ end
+
+ it "should only look in the topclass, if the name is qualified" do
+ @loader.find_hostclass("foo", "::bar").name.should == 'bar'
+ end
+
+ end
+
+ it "should not look in the local scope for classes when the name is qualified" do
+ @loader = Puppet::Resource::TypeCollection.new("env")
+ @loader.add Puppet::Resource::Type.new(:hostclass, "foo::bar")
+
+ @loader.find_hostclass("foo", "::bar").should == nil
+ end
+
end
- it "should use the generic 'find' method with an empty namespace to find nodes" do
+ it "should be able to find nodes" do
+ node = Puppet::Resource::Type.new(:node, "bar")
loader = Puppet::Resource::TypeCollection.new("env")
- loader.expects(:find).with("", "bar", :node)
- loader.find_node(stub("ignored"), "bar")
+ loader.add(node)
+ loader.find_node(stub("ignored"), "bar").should == node
end
it "should use the 'find_or_load' method to find hostclasses" do
@@ -358,50 +416,6 @@ describe Puppet::Resource::TypeCollection do
end
end
- describe "when performing initial import" do
- before do
- @parser = stub 'parser', :file= => nil, :string => nil, :parse => nil
- Puppet::Parser::Parser.stubs(:new).returns @parser
- @code = Puppet::Resource::TypeCollection.new("env")
- end
-
- it "should create a new parser instance" do
- Puppet::Parser::Parser.expects(:new).returns @parser
- @code.perform_initial_import
- end
-
- it "should set the parser's string to the 'code' setting and parse if code is available" do
- Puppet.settings[:code] = "my code"
- @parser.expects(:string=).with "my code"
- @parser.expects(:parse)
- @code.perform_initial_import
- end
-
- it "should set the parser's file to the 'manifest' setting and parse if no code is available and the manifest is available" do
- File.stubs(:expand_path).with("/my/file").returns "/my/file"
- File.expects(:exist?).with("/my/file").returns true
- Puppet.settings[:manifest] = "/my/file"
- @parser.expects(:file=).with "/my/file"
- @parser.expects(:parse)
- @code.perform_initial_import
- end
-
- it "should not attempt to load a manifest if none is present" do
- File.stubs(:expand_path).with("/my/file").returns "/my/file"
- File.expects(:exist?).with("/my/file").returns false
- Puppet.settings[:manifest] = "/my/file"
- @parser.expects(:file=).never
- @parser.expects(:parse).never
- @code.perform_initial_import
- end
-
- it "should fail helpfully if there is an error importing" do
- File.stubs(:exist?).returns true
- @parser.expects(:parse).raises ArgumentError
- lambda { @code.perform_initial_import }.should raise_error(Puppet::Error)
- end
- end
-
describe "when determining the configuration version" do
before do
@code = Puppet::Resource::TypeCollection.new("env")
@@ -429,4 +443,5 @@ describe Puppet::Resource::TypeCollection do
end
end
+
end
diff --git a/spec/unit/resource/type_spec.rb b/spec/unit/resource/type_spec.rb
index 0ef4a5166..ef45712e6 100755
--- a/spec/unit/resource/type_spec.rb
+++ b/spec/unit/resource/type_spec.rb
@@ -322,7 +322,7 @@ describe Puppet::Resource::Type do
end
it "should set its module name in the scope if available" do
- @type.module_name = "mymod"
+ @type.instance_eval { @module_name = "mymod" }
@type.set_resource_parameters(@resource, @scope)
@@ -369,7 +369,8 @@ describe Puppet::Resource::Type do
end
it "should cache a reference to the parent type" do
- @code.expects(:hostclass).once.with("bar").returns @parent
+ @code.stubs(:hostclass).with("foo::bar").returns nil
+ @code.expects(:hostclass).with("bar").once.returns @parent
@child.parent_type(@scope)
@child.parent_type
end
@@ -411,6 +412,23 @@ describe Puppet::Resource::Type do
@type = Puppet::Resource::Type.new(:hostclass, "foo")
end
+ it "should add hostclass names to the classes list" do
+ @type.evaluate_code(@resource)
+ @compiler.catalog.classes.should be_include("foo")
+ end
+
+ it "should add node names to the classes list" do
+ @type = Puppet::Resource::Type.new(:node, "foo")
+ @type.evaluate_code(@resource)
+ @compiler.catalog.classes.should be_include("foo")
+ end
+
+ it "should not add defined resource names to the classes list" do
+ @type = Puppet::Resource::Type.new(:definition, "foo")
+ @type.evaluate_code(@resource)
+ @compiler.catalog.classes.should_not be_include("foo")
+ end
+
it "should set all of its parameters in a subscope" do
subscope = stub 'subscope', :compiler => @compiler
@type.expects(:subscope).with(@scope, @resource).returns subscope
@@ -513,8 +531,7 @@ describe Puppet::Resource::Type do
@compiler.add_resource @scope, @parent_resource
@type.resource_type_collection = @scope.known_resource_types
- @type.resource_type_collection.stubs(:node).with("parent").returns(@parent_type)
- @type.resource_type_collection.stubs(:node).with("Parent").returns(@parent_type)
+ @type.resource_type_collection.add(@parent_type)
end
it "should evaluate the parent's resource" do
@@ -562,29 +579,29 @@ describe Puppet::Resource::Type do
end
it "should create a resource instance" do
- @top.mk_plain_resource(@scope).should be_instance_of(Puppet::Parser::Resource)
+ @top.ensure_in_catalog(@scope).should be_instance_of(Puppet::Parser::Resource)
end
it "should set its resource type to 'class' when it is a hostclass" do
- Puppet::Resource::Type.new(:hostclass, "top").mk_plain_resource(@scope).type.should == "Class"
+ Puppet::Resource::Type.new(:hostclass, "top").ensure_in_catalog(@scope).type.should == "Class"
end
it "should set its resource type to 'node' when it is a node" do
- Puppet::Resource::Type.new(:node, "top").mk_plain_resource(@scope).type.should == "Node"
+ Puppet::Resource::Type.new(:node, "top").ensure_in_catalog(@scope).type.should == "Node"
end
it "should fail when it is a definition" do
- lambda { Puppet::Resource::Type.new(:definition, "top").mk_plain_resource(@scope) }.should raise_error(ArgumentError)
+ lambda { Puppet::Resource::Type.new(:definition, "top").ensure_in_catalog(@scope) }.should raise_error(ArgumentError)
end
it "should add the created resource to the scope's catalog" do
- @top.mk_plain_resource(@scope)
+ @top.ensure_in_catalog(@scope)
@compiler.catalog.resource(:class, "top").should be_instance_of(Puppet::Parser::Resource)
end
it "should evaluate the parent class if one exists" do
- @middle.mk_plain_resource(@scope)
+ @middle.ensure_in_catalog(@scope)
@compiler.catalog.resource(:class, "top").should be_instance_of(Puppet::Parser::Resource)
end
@@ -592,40 +609,40 @@ describe Puppet::Resource::Type do
it "should fail to evaluate if a parent class is defined but cannot be found" do
othertop = Puppet::Resource::Type.new :hostclass, "something", :parent => "yay"
@code.add othertop
- lambda { othertop.mk_plain_resource(@scope) }.should raise_error(Puppet::ParseError)
+ lambda { othertop.ensure_in_catalog(@scope) }.should raise_error(Puppet::ParseError)
end
it "should not create a new resource if one already exists" do
@compiler.catalog.expects(:resource).with(:class, "top").returns("something")
@compiler.catalog.expects(:add_resource).never
- @top.mk_plain_resource(@scope)
+ @top.ensure_in_catalog(@scope)
end
it "should return the existing resource when not creating a new one" do
@compiler.catalog.expects(:resource).with(:class, "top").returns("something")
@compiler.catalog.expects(:add_resource).never
- @top.mk_plain_resource(@scope).should == "something"
+ @top.ensure_in_catalog(@scope).should == "something"
end
it "should not create a new parent resource if one already exists and it has a parent class" do
- @top.mk_plain_resource(@scope)
+ @top.ensure_in_catalog(@scope)
top_resource = @compiler.catalog.resource(:class, "top")
- @middle.mk_plain_resource(@scope)
+ @middle.ensure_in_catalog(@scope)
@compiler.catalog.resource(:class, "top").should equal(top_resource)
end
# #795 - tag before evaluation.
it "should tag the catalog with the resource tags when it is evaluated" do
- @middle.mk_plain_resource(@scope)
+ @middle.ensure_in_catalog(@scope)
@compiler.catalog.should be_tagged("middle")
end
it "should tag the catalog with the parent class tags when it is evaluated" do
- @middle.mk_plain_resource(@scope)
+ @middle.ensure_in_catalog(@scope)
@compiler.catalog.should be_tagged("top")
end
diff --git a/spec/unit/resource_spec.rb b/spec/unit/resource_spec.rb
index 204a2b02e..e65e8a13a 100755
--- a/spec/unit/resource_spec.rb
+++ b/spec/unit/resource_spec.rb
@@ -123,18 +123,6 @@ describe Puppet::Resource do
Puppet::Resource.new("file", "/my/file", :environment => :foo).environment.name.should == :foo
end
- it "should support specifying namespaces" do
- Puppet::Resource.new("file", "/my/file", :namespaces => ["foo"]).namespaces.should == ["foo"]
- end
-
- it "should convert namespaces to an array if not specified as one" do
- Puppet::Resource.new("file", "/my/file", :namespaces => "foo").namespaces.should == ["foo"]
- end
-
- it "should default to a single amespace of an empty string" do
- Puppet::Resource.new("file", "/my/file").namespaces.should == [""]
- end
-
describe "and munging its type and title" do
describe "when modeling a builtin resource" do
it "should be able to find the resource type" do
@@ -164,16 +152,6 @@ describe Puppet::Resource do
it "should set its title to the provided title" do
Puppet::Resource.new("foo::bar", "/my/file").title.should == "/my/file"
end
-
- describe "and the resource is unqualified and models a qualified resource type" do
- it "should set its type to the fully qualified resource type" do
- Puppet::Resource.new("bar", "/my/file", :namespaces => %w{foo}).type.should == "Foo::Bar"
- end
-
- it "should be able to find the resource type" do
- Puppet::Resource.new("bar", "/my/file", :namespaces => %w{foo}).resource_type.should equal(@type)
- end
- end
end
describe "that does not exist" do
@@ -210,20 +188,6 @@ describe Puppet::Resource do
it "should be able to find the resource type" do
Puppet::Resource.new("class", "foo::bar").resource_type.should equal(@type)
end
-
- describe "and the resource is unqualified and models a qualified class" do
- it "should set its title to the fully qualified resource type" do
- Puppet::Resource.new("class", "bar", :namespaces => %w{foo}).title.should == "Foo::Bar"
- end
-
- it "should be able to find the resource type" do
- Puppet::Resource.new("class", "bar", :namespaces => %w{foo}).resource_type.should equal(@type)
- end
-
- it "should set its type to 'Class'" do
- Puppet::Resource.new("class", "bar", :namespaces => %w{foo}).type.should == "Class"
- end
- end
end
describe "that does not exist" do
diff --git a/spec/unit/simple_graph_spec.rb b/spec/unit/simple_graph_spec.rb
index 83e674139..fa0bcb06a 100755
--- a/spec/unit/simple_graph_spec.rb
+++ b/spec/unit/simple_graph_spec.rb
@@ -31,12 +31,6 @@ describe Puppet::SimpleGraph do
proc { @graph.to_dot_graph }.should_not raise_error
end
- it "should always put its edges first when printing yaml" do
- @graph = Puppet::SimpleGraph.new
- @graph.add_edge(:one, :two)
- @graph.to_yaml_properties[0].should == "@edges"
- end
-
describe "when managing vertices" do
before do
@graph = Puppet::SimpleGraph.new
@@ -117,16 +111,31 @@ describe Puppet::SimpleGraph do
@graph.edge?(:one, :two).should be_true
end
- it "should provide a method for retrieving an edge label" do
- edge = Puppet::Relationship.new(:one, :two, :callback => :awesome)
- @graph.add_edge(edge)
- @graph.edge_label(:one, :two).should == {:callback => :awesome}
- end
+ describe "when retrieving edges between two nodes" do
+ it "should handle the case of nodes not in the graph" do
+ @graph.edges_between(:one, :two).should == []
+ end
- it "should provide a method for retrieving an edge" do
- edge = Puppet::Relationship.new(:one, :two)
- @graph.add_edge(edge)
- @graph.edge(:one, :two).should equal(edge)
+ it "should handle the case of nodes with no edges between them" do
+ @graph.add_vertex(:one)
+ @graph.add_vertex(:two)
+ @graph.edges_between(:one, :two).should == []
+ end
+
+ it "should handle the case of nodes connected by a single edge" do
+ edge = Puppet::Relationship.new(:one, :two)
+ @graph.add_edge(edge)
+ @graph.edges_between(:one, :two).length.should == 1
+ @graph.edges_between(:one, :two)[0].should equal(edge)
+ end
+
+ it "should handle the case of nodes connected by multiple edges" do
+ edge1 = Puppet::Relationship.new(:one, :two, :callback => :foo)
+ edge2 = Puppet::Relationship.new(:one, :two, :callback => :bar)
+ @graph.add_edge(edge1)
+ @graph.add_edge(edge2)
+ Set.new(@graph.edges_between(:one, :two)).should == Set.new([edge1, edge2])
+ end
end
it "should add the edge source as a vertex if it is not already" do
@@ -253,7 +262,7 @@ describe Puppet::SimpleGraph do
it "should retain labels on edges" do
@graph.add_edge(:one, :two, :callback => :awesome)
- edge = @graph.reversal.edge(:two, :one)
+ edge = @graph.reversal.edges_between(:two, :one)[0]
edge.label.should == {:callback => :awesome}
end
end
@@ -439,7 +448,8 @@ describe Puppet::SimpleGraph do
@middle = Container.new("middle", ["e", "f", @two])
@top = Container.new("top", ["g", "h", @middle, @one, @three])
@empty = Container.new("empty", [])
-
+
+ @whit = Puppet::Type.type(:whit)
@stage = Puppet::Type.type(:stage).new(:name => "foo")
@contgraph = @top.to_graph
@@ -499,8 +509,17 @@ describe Puppet::SimpleGraph do
end
end
+ it "should contain a whit-resource to mark the place held by the empty container" do
+ @depgraph.vertices.find_all { |v| v.is_a?(@whit) }.length.should == 1
+ end
+
+ it "should replace edges to empty containers with edges to their residual whit" do
+ emptys_whit = @depgraph.vertices.find_all { |v| v.is_a?(@whit) }.first
+ @depgraph.should be_edge("c", emptys_whit)
+ end
+
it "should no longer contain anything but the non-container objects" do
- @depgraph.vertices.find_all { |v| ! v.is_a?(String) }.should be_empty
+ @depgraph.vertices.find_all { |v| ! v.is_a?(String) and ! v.is_a?(@whit)}.should be_empty
end
it "should copy labels" do
@@ -512,14 +531,14 @@ describe Puppet::SimpleGraph do
it "should not add labels to edges that have none" do
@depgraph.add_edge(@two, @three)
splice
- @depgraph.edge_label("c", "i").should == {}
+ @depgraph.edges_between("c", "i")[0].label.should == {}
end
it "should copy labels over edges that have none" do
@depgraph.add_edge("c", @three, {:callback => :refresh})
splice
# And make sure the label got copied.
- @depgraph.edge_label("c", "i").should == {:callback => :refresh}
+ @depgraph.edges_between("c", "i")[0].label.should == {:callback => :refresh}
end
it "should not replace a label with a nil label" do
@@ -527,7 +546,7 @@ describe Puppet::SimpleGraph do
@depgraph.add_edge(@middle, @three)
@depgraph.add_edge("c", @three, {:callback => :refresh})
splice
- @depgraph.edge_label("c", "i").should == {:callback => :refresh}
+ @depgraph.edges_between("c", "i")[0].label.should == {:callback => :refresh}
end
it "should copy labels to all created edges" do
@@ -537,8 +556,207 @@ describe Puppet::SimpleGraph do
@three.each do |child|
edge = Puppet::Relationship.new("c", child)
@depgraph.should be_edge(edge.source, edge.target)
- @depgraph.edge_label(edge.source, edge.target).should == {:callback => :refresh}
+ @depgraph.edges_between(edge.source, edge.target)[0].label.should == {:callback => :refresh}
+ end
+ end
+ end
+
+ it "should serialize to YAML using the old format by default" do
+ Puppet::SimpleGraph.use_new_yaml_format.should == false
+ end
+
+ describe "(yaml tests)" do
+ def empty_graph(graph)
+ end
+
+ def one_vertex_graph(graph)
+ graph.add_vertex(:a)
+ end
+
+ def graph_without_edges(graph)
+ [:a, :b, :c].each { |x| graph.add_vertex(x) }
+ end
+
+ def one_edge_graph(graph)
+ graph.add_edge(:a, :b)
+ end
+
+ def many_edge_graph(graph)
+ graph.add_edge(:a, :b)
+ graph.add_edge(:a, :c)
+ graph.add_edge(:b, :d)
+ graph.add_edge(:c, :d)
+ end
+
+ def labeled_edge_graph(graph)
+ graph.add_edge(:a, :b, :callback => :foo, :event => :bar)
+ end
+
+ def overlapping_edge_graph(graph)
+ graph.add_edge(:a, :b, :callback => :foo, :event => :bar)
+ graph.add_edge(:a, :b, :callback => :biz, :event => :baz)
+ end
+
+ def self.all_test_graphs
+ [:empty_graph, :one_vertex_graph, :graph_without_edges, :one_edge_graph, :many_edge_graph, :labeled_edge_graph,
+ :overlapping_edge_graph]
+ end
+
+ def object_ids(enumerable)
+ # Return a sorted list of the object id's of the elements of an
+ # enumerable.
+ enumerable.collect { |x| x.object_id }.sort
+ end
+
+ def graph_to_yaml(graph, which_format)
+ previous_use_new_yaml_format = Puppet::SimpleGraph.use_new_yaml_format
+ Puppet::SimpleGraph.use_new_yaml_format = (which_format == :new)
+ ZAML.dump(graph)
+ ensure
+ Puppet::SimpleGraph.use_new_yaml_format = previous_use_new_yaml_format
+ end
+
+ # Test serialization of graph to YAML.
+ [:old, :new].each do |which_format|
+ all_test_graphs.each do |graph_to_test|
+ it "should be able to serialize #{graph_to_test} to YAML (#{which_format} format)" do
+ graph = Puppet::SimpleGraph.new
+ send(graph_to_test, graph)
+ yaml_form = graph_to_yaml(graph, which_format)
+
+ # Hack the YAML so that objects in the Puppet namespace get
+ # changed to YAML::DomainType objects. This lets us inspect
+ # the serialized objects easily without invoking any
+ # yaml_initialize hooks.
+ yaml_form.gsub!('!ruby/object:Puppet::', '!hack/object:Puppet::')
+ serialized_object = YAML.load(yaml_form)
+
+ # Check that the object contains instance variables @edges and
+ # @vertices only. @reversal is also permitted, but we don't
+ # check it, because it is going to be phased out.
+ serialized_object.type_id.should == 'object:Puppet::SimpleGraph'
+ serialized_object.value.keys.reject { |x| x == 'reversal' }.sort.should == ['edges', 'vertices']
+
+ # Check edges by forming a set of tuples (source, target,
+ # callback, event) based on the graph and the YAML and make sure
+ # they match.
+ edges = serialized_object.value['edges']
+ edges.should be_a(Array)
+ expected_edge_tuples = graph.edges.collect { |edge| [edge.source, edge.target, edge.callback, edge.event] }
+ actual_edge_tuples = edges.collect do |edge|
+ edge.type_id.should == 'object:Puppet::Relationship'
+ %w{source target}.each { |x| edge.value.keys.should include(x) }
+ edge.value.keys.each { |x| ['source', 'target', 'callback', 'event'].should include(x) }
+ %w{source target callback event}.collect { |x| edge.value[x] }
+ end
+ Set.new(actual_edge_tuples).should == Set.new(expected_edge_tuples)
+ actual_edge_tuples.length.should == expected_edge_tuples.length
+
+ # Check vertices one by one.
+ vertices = serialized_object.value['vertices']
+ if which_format == :old
+ vertices.should be_a(Hash)
+ Set.new(vertices.keys).should == Set.new(graph.vertices)
+ vertices.each do |key, value|
+ value.type_id.should == 'object:Puppet::SimpleGraph::VertexWrapper'
+ value.value.keys.sort.should == %w{adjacencies vertex}
+ value.value['vertex'].should equal(key)
+ adjacencies = value.value['adjacencies']
+ adjacencies.should be_a(Hash)
+ Set.new(adjacencies.keys).should == Set.new([:in, :out])
+ [:in, :out].each do |direction|
+ adjacencies[direction].should be_a(Hash)
+ expected_adjacent_vertices = Set.new(graph.adjacent(key, :direction => direction, :type => :vertices))
+ Set.new(adjacencies[direction].keys).should == expected_adjacent_vertices
+ adjacencies[direction].each do |adj_key, adj_value|
+ # Since we already checked edges, just check consistency
+ # with edges.
+ desired_source = direction == :in ? adj_key : key
+ desired_target = direction == :in ? key : adj_key
+ expected_edges = edges.select do |edge|
+ edge.value['source'] == desired_source && edge.value['target'] == desired_target
+ end
+ adj_value.should be_a(Set)
+ if object_ids(adj_value) != object_ids(expected_edges)
+ raise "For vertex #{key.inspect}, direction #{direction.inspect}: expected adjacencies #{expected_edges.inspect} but got #{adj_value.inspect}"
+ end
+ end
+ end
+ end
+ else
+ vertices.should be_a(Array)
+ Set.new(vertices).should == Set.new(graph.vertices)
+ vertices.length.should == graph.vertices.length
+ end
+ end
+ end
+
+ # Test deserialization of graph from YAML. This presumes the
+ # correctness of serialization to YAML, which has already been
+ # tested.
+ all_test_graphs.each do |graph_to_test|
+ it "should be able to deserialize #{graph_to_test} from YAML (#{which_format} format)" do
+ reference_graph = Puppet::SimpleGraph.new
+ send(graph_to_test, reference_graph)
+ yaml_form = graph_to_yaml(reference_graph, which_format)
+ recovered_graph = YAML.load(yaml_form)
+
+ # Test that the recovered vertices match the vertices in the
+ # reference graph.
+ expected_vertices = reference_graph.vertices.to_a
+ recovered_vertices = recovered_graph.vertices.to_a
+ Set.new(recovered_vertices).should == Set.new(expected_vertices)
+ recovered_vertices.length.should == expected_vertices.length
+
+ # Test that the recovered edges match the edges in the
+ # reference graph.
+ expected_edge_tuples = reference_graph.edges.collect do |edge|
+ [edge.source, edge.target, edge.callback, edge.event]
+ end
+ recovered_edge_tuples = recovered_graph.edges.collect do |edge|
+ [edge.source, edge.target, edge.callback, edge.event]
+ end
+ Set.new(recovered_edge_tuples).should == Set.new(expected_edge_tuples)
+ recovered_edge_tuples.length.should == expected_edge_tuples.length
+
+ # We ought to test that the recovered graph is self-consistent
+ # too. But we're not going to bother with that yet because
+ # the internal representation of the graph is about to change.
+ end
+ end
+
+ it "should be able to serialize a graph where the vertices contain backreferences to the graph (#{which_format} format)" do
+ reference_graph = Puppet::SimpleGraph.new
+ vertex = Object.new
+ vertex.instance_eval { @graph = reference_graph }
+ reference_graph.add_edge(vertex, :other_vertex)
+ yaml_form = graph_to_yaml(reference_graph, which_format)
+ recovered_graph = YAML.load(yaml_form)
+
+ recovered_graph.vertices.length.should == 2
+ recovered_vertex = recovered_graph.vertices.reject { |x| x.is_a?(Symbol) }[0]
+ recovered_vertex.instance_eval { @graph }.should equal(recovered_graph)
+ recovered_graph.edges.length.should == 1
+ recovered_edge = recovered_graph.edges[0]
+ recovered_edge.source.should equal(recovered_vertex)
+ recovered_edge.target.should == :other_vertex
+ end
+ end
+
+ it "should serialize properly when used as a base class" do
+ class Puppet::TestDerivedClass < Puppet::SimpleGraph
+ attr_accessor :foo
end
+ derived = Puppet::TestDerivedClass.new
+ derived.add_edge(:a, :b)
+ derived.foo = 1234
+ recovered_derived = YAML.load(YAML.dump(derived))
+ recovered_derived.class.should equal(Puppet::TestDerivedClass)
+ recovered_derived.edges.length.should == 1
+ recovered_derived.edges[0].source.should == :a
+ recovered_derived.edges[0].target.should == :b
+ recovered_derived.vertices.length.should == 2
+ recovered_derived.foo.should == 1234
end
end
end
diff --git a/spec/unit/sslcertificates/ca_spec.rb b/spec/unit/sslcertificates/ca_spec.rb
new file mode 100644
index 000000000..b1393b25d
--- /dev/null
+++ b/spec/unit/sslcertificates/ca_spec.rb
@@ -0,0 +1,110 @@
+#!/usr/bin/env ruby
+require File.dirname(__FILE__) + '/../../spec_helper'
+
+require 'puppet'
+require 'puppet/sslcertificates'
+require 'puppet/sslcertificates/ca'
+
+describe Puppet::SSLCertificates::CA do
+ before :all do
+ @hosts = %w{host.domain.com Other.Testing.Com}
+ end
+
+ before :each do
+ Puppet::Util::SUIDManager.stubs(:asuser).yields
+ file = Tempfile.new("ca_testing")
+ @dir = file.path
+ file.delete
+
+ Puppet.settings[:confdir] = @dir
+ Puppet.settings[:vardir] = @dir
+
+ @ca = Puppet::SSLCertificates::CA.new
+ end
+
+ after :each do
+ system("rm -rf #{@dir}")
+ end
+
+ describe 'when cleaning' do
+ it 'should remove associated files' do
+ dirs = [:csrdir, :signeddir, :publickeydir, :privatekeydir, :certdir]
+
+ @hosts.each do |host|
+ files = []
+ dirs.each do |dir|
+ dir = Puppet[dir]
+
+ # Case insensitivity is handled through downcasing
+ file = File.join(dir, host.downcase + '.pem')
+
+ File.open(file, "w") do |f|
+ f.puts "testing"
+ end
+
+ files << file
+ end
+
+ lambda { @ca.clean(host) }.should_not raise_error
+
+ files.reject {|f| ! File.exists?(f)}.should be_empty
+ end
+ end
+ end
+
+ describe 'when mapping hosts to files' do
+ it 'should correctly return the certfile' do
+ @hosts.each do |host|
+ value = nil
+ lambda { value = @ca.host2certfile host }.should_not raise_error
+
+ File.join(Puppet[:signeddir], host.downcase + '.pem').should == value
+ end
+ end
+
+ it 'should correctly return the csrfile' do
+ @hosts.each do |host|
+ value = nil
+ lambda { value = @ca.host2csrfile host }.should_not raise_error
+
+ File.join(Puppet[:csrdir], host.downcase + '.pem').should == value
+ end
+ end
+ end
+
+ describe 'when listing' do
+ it 'should find all csr' do
+ list = []
+
+ # Make some fake CSRs
+ @hosts.each do |host|
+ file = File.join(Puppet[:csrdir], host.downcase + '.pem')
+ File.open(file, 'w') { |f| f.puts "yay" }
+ list << host.downcase
+ end
+
+ @ca.list.sort.should == list.sort
+ end
+ end
+
+ describe 'when creating a root certificate' do
+ before :each do
+ lambda { @ca.mkrootcert }.should_not raise_exception
+ end
+
+ it 'should store the public key' do
+ File.exists?(Puppet[:capub]).should be_true
+ end
+
+ it 'should prepend "Puppet CA: " to the fqdn as the ca_name by default' do
+ host_mock_fact = mock()
+ host_mock_fact.expects(:value).returns('myhost')
+ domain_mock_fact = mock()
+ domain_mock_fact.expects(:value).returns('puppetlabs.lan')
+ Facter.stubs(:[]).with('hostname').returns(host_mock_fact)
+ Facter.stubs(:[]).with('domain').returns(domain_mock_fact)
+
+ @ca.mkrootcert.name.should == 'Puppet CA: myhost.puppetlabs.lan'
+ end
+ end
+end
diff --git a/spec/unit/transaction/report_spec.rb b/spec/unit/transaction/report_spec.rb
index 7e0b0554b..b310713d2 100755
--- a/spec/unit/transaction/report_spec.rb
+++ b/spec/unit/transaction/report_spec.rb
@@ -225,8 +225,19 @@ describe Puppet::Transaction::Report do
@report.calculate_metrics
end
- %w{Changes Total Resources}.each do |main|
- it "should include information on #{main} in the summary" do
+ %w{changes time resources events}.each do |main|
+ it "should include the key #{main} in the raw summary hash" do
+ @report.raw_summary.should be_key main
+ end
+ end
+
+ it "should include the last run time in the raw summary hash" do
+ Time.stubs(:now).returns(Time.utc(2010,11,10,12,0,24))
+ @report.raw_summary["time"]["last_run"].should == 1289390424
+ end
+
+ %w{Changes Total Resources Time Events}.each do |main|
+ it "should include information on #{main} in the textual summary" do
@report.summary.should be_include(main)
end
end
diff --git a/spec/unit/transaction/resource_harness_spec.rb b/spec/unit/transaction/resource_harness_spec.rb
index 31965c92c..255481ae4 100755
--- a/spec/unit/transaction/resource_harness_spec.rb
+++ b/spec/unit/transaction/resource_harness_spec.rb
@@ -50,7 +50,7 @@ describe Puppet::Transaction::ResourceHarness do
end
it "should cache and log the current value if no cached values are present" do
- @resource.expects(:info)
+ @resource.expects(:debug)
@harness.copy_audited_parameters(@resource, {:mode => "755"}).should == []
@harness.cached(@resource, :mode).should == "755"
diff --git a/spec/unit/type/file/content_spec.rb b/spec/unit/type/file/content_spec.rb
index e4b9f9bc6..cde643fc8 100755
--- a/spec/unit/type/file/content_spec.rb
+++ b/spec/unit/type/file/content_spec.rb
@@ -6,6 +6,7 @@ content = Puppet::Type.type(:file).attrclass(:content)
describe content do
before do
@resource = Puppet::Type.type(:file).new :path => "/foo/bar"
+ content.stubs(:standalone?).returns(false)
end
it "should be a subclass of Property" do
@@ -362,7 +363,7 @@ describe content do
end
it "should send the correct indirection uri" do
- @conn.expects(:request_get).with { |uri,headers| uri == "/production/file_content//path/to/source" }.yields(@response)
+ @conn.expects(:request_get).with { |uri,headers| uri == "/production/file_content/path/to/source" }.yields(@response)
@content.write(@fh)
end
diff --git a/spec/unit/type/host_spec.rb b/spec/unit/type/host_spec.rb
new file mode 100755
index 000000000..12ae2af08
--- /dev/null
+++ b/spec/unit/type/host_spec.rb
@@ -0,0 +1,83 @@
+#!/usr/bin/env ruby
+
+require File.dirname(__FILE__) + '/../../spec_helper'
+
+ssh_authorized_key = Puppet::Type.type(:ssh_authorized_key)
+
+describe Puppet::Type.type(:host) do
+ before do
+ @class = Puppet::Type.type(:host)
+ @catalog = Puppet::Resource::Catalog.new
+ end
+
+ it "should have :name be its namevar" do
+ @class.key_attributes.should == [:name]
+ end
+
+ describe "when validating attributes" do
+ [:name, :provider ].each do |param|
+ it "should have a #{param} parameter" do
+ @class.attrtype(param).should == :param
+ end
+ end
+
+ [:ip, :target, :host_aliases, :comment, :ensure].each do |property|
+ it "should have a #{property} property" do
+ @class.attrtype(property).should == :property
+ end
+ end
+ end
+
+ describe "when validating values" do
+ it "should support present as a value for ensure" do
+ proc { @class.new(:name => "foo", :ensure => :present) }.should_not raise_error
+ end
+
+ it "should support absent as a value for ensure" do
+ proc { @class.new(:name => "foo", :ensure => :absent) }.should_not raise_error
+ end
+
+ it "should accept IPv4 addresses" do
+ proc { @class.new(:name => "foo", :ip => '10.96.0.1') }.should_not raise_error
+ end
+
+ it "should accept long IPv6 addresses" do
+ # Taken from wikipedia article about ipv6
+ proc { @class.new(:name => "foo", :ip => '2001:0db8:85a3:08d3:1319:8a2e:0370:7344') }.should_not raise_error
+ end
+
+ it "should accept one host_alias" do
+ proc { @class.new(:name => "foo", :host_aliases => 'alias1') }.should_not raise_error
+ end
+
+ it "should accept multiple host_aliases" do
+ proc { @class.new(:name => "foo", :host_aliases => [ 'alias1', 'alias2' ]) }.should_not raise_error
+ end
+
+ it "should accept shortened IPv6 addresses" do
+ proc { @class.new(:name => "foo", :ip => '2001:db8:0:8d3:0:8a2e:70:7344') }.should_not raise_error
+ proc { @class.new(:name => "foo", :ip => '::ffff:192.0.2.128') }.should_not raise_error
+ proc { @class.new(:name => "foo", :ip => '::1') }.should_not raise_error
+ end
+
+ it "should not accept malformed IPv4 addresses like 192.168.0.300" do
+ proc { @class.new(:name => "foo", :ip => '192.168.0.300') }.should raise_error
+ end
+
+ it "should not accept malformed IP addresses like 2001:0dg8:85a3:08d3:1319:8a2e:0370:7344" do
+ proc { @class.new(:name => "foo", :ip => '2001:0dg8:85a3:08d3:1319:8a2e:0370:7344') }.should raise_error
+ end
+
+ it "should not accept spaces in resourcename" do
+ proc { @class.new(:name => "foo bar") }.should raise_error
+ end
+
+ it "should not accept host_aliases with spaces" do
+ proc { @class.new(:name => "foo", :host_aliases => [ 'well_formed', 'not wellformed' ]) }.should raise_error
+ end
+
+ it "should not accept empty host_aliases" do
+ proc { @class.new(:name => "foo", :host_aliases => ['alias1','']) }.should raise_error
+ end
+ end
+end
diff --git a/spec/unit/type/mount_spec.rb b/spec/unit/type/mount_spec.rb
index ce82cb516..4aa9baf70 100755
--- a/spec/unit/type/mount_spec.rb
+++ b/spec/unit/type/mount_spec.rb
@@ -203,23 +203,45 @@ describe Puppet::Type.type(:mount)::Ensure do
end
end
- describe Puppet::Type.type(:mount), "when responding to events" do
+ describe Puppet::Type.type(:mount), "when responding to refresh" do
- it "should remount if it is currently mounted" do
- @provider.expects(:mounted?).returns(true)
+ it "should remount if it is supposed to be mounted" do
+ @mount[:ensure] = "mounted"
@provider.expects(:remount)
@mount.refresh
end
- it "should not remount if it is not currently mounted" do
- @provider.expects(:mounted?).returns(false)
+ it "should not remount if it is supposed to be present" do
+ @mount[:ensure] = "present"
+ @provider.expects(:remount).never
+
+ @mount.refresh
+ end
+
+ it "should not remount if it is supposed to be absent" do
+ @mount[:ensure] = "absent"
+ @provider.expects(:remount).never
+
+ @mount.refresh
+ end
+
+ it "should not remount if it is supposed to be defined" do
+ @mount[:ensure] = "defined"
+ @provider.expects(:remount).never
+
+ @mount.refresh
+ end
+
+ it "should not remount if it is supposed to be unmounted" do
+ @mount[:ensure] = "unmounted"
@provider.expects(:remount).never
@mount.refresh
end
it "should not remount swap filesystems" do
+ @mount[:ensure] = "mounted"
@mount[:fstype] = "swap"
@provider.expects(:remount).never
diff --git a/spec/unit/type/schedule_spec.rb b/spec/unit/type/schedule_spec.rb
index 6975529b2..8305431a6 100755
--- a/spec/unit/type/schedule_spec.rb
+++ b/spec/unit/type/schedule_spec.rb
@@ -13,14 +13,6 @@ module ScheduleTesting
Time.at(diff)
end
- def month(method, count)
- diff(:hour, 3600 * 24 * 30, method, count)
- end
-
- def week(method, count)
- diff(:hour, 3600 * 24 * 7, method, count)
- end
-
def day(method, count)
diff(:hour, 3600 * 24, method, count)
end
@@ -33,15 +25,11 @@ module ScheduleTesting
diff(:min, 60, method, count)
end
- def sec(method, count)
- diff(:sec, 1, method, count)
- end
-
end
describe Puppet::Type.type(:schedule) do
before :each do
- Puppet.settings.stubs(:value).with(:ignoreschedules).returns(false)
+ Puppet[:ignoreschedules] = false
@schedule = Puppet::Type.type(:schedule).new(:name => "testing")
end
@@ -194,26 +182,18 @@ describe Puppet::Type.type(:schedule) do
end
it "should match if the times are one minute apart and the current minute is 0" do
- current = Time.now
+ current = Time.utc(2008, 1, 1, 0, 0, 0)
+ previous = Time.utc(2007, 12, 31, 23, 59, 0)
- # Subtract an hour, reset the minute to zero, then add 59 minutes, so we're the previous hour plus 59 minutes.
- previous = (current - 3600 - (current.min * 60) + (59 * 60))
-
- # Now set the "current" time to the zero minute of the current hour.
- now = (current - (current.min * 60))
- Time.stubs(:now).returns(now)
+ Time.stubs(:now).returns(current)
@schedule.match?(previous).should be_true
end
- it "should not match if the times are 58 minutes apart and the current minute is 59" do
- current = Time.now
+ it "should not match if the times are 59 minutes apart and the current minute is 59" do
+ current = Time.utc(2009, 2, 1, 12, 59, 0)
+ previous = Time.utc(2009, 2, 1, 12, 0, 0)
- # reset the minute to zero
- previous = current - (current.min * 60)
-
- # Now set the "current" time to the 59th minute of the current hour.
- now = (current - (current.min * 60) + (59 * 60))
- Time.stubs(:now).returns(now)
+ Time.stubs(:now).returns(current)
@schedule.match?(previous).should be_false
end
end
@@ -227,10 +207,7 @@ describe Puppet::Type.type(:schedule) do
end
it "should match if the times are one minute apart and the current minute and hour are 0" do
- zero = Time.now
-
- # Reset the current time to X:00:00
- current = zero - (zero.hour * 3600) - (zero.min * 60) - zero.sec
+ current = Time.utc(2010, "nov", 7, 0, 0, 0)
# Now set the previous time to one minute before that
previous = current - 60
@@ -240,10 +217,9 @@ describe Puppet::Type.type(:schedule) do
end
it "should not match if the times are 23 hours and 58 minutes apart and the current hour is 23 and the current minute is 59" do
- zero = Time.now
# Reset the previous time to 00:00:00
- previous = zero - (zero.hour * 3600) - (zero.min * 60) - zero.sec
+ previous = Time.utc(2010, "nov", 7, 0, 0, 0)
# Set the current time to 23:59
now = previous + (23 * 3600) + (59 * 60)
@@ -262,19 +238,17 @@ describe Puppet::Type.type(:schedule) do
end
it "should match if the previous time is prior to the most recent Sunday" do
- now = Time.now
-
- # Subtract the number days we've progressed into the week, plus one because we're zero-indexed.
- previous = now - (3600 * 24 * (now.wday + 1))
+ now = Time.utc(2010, "nov", 11, 0, 0, 0) # Thursday
+ Time.stubs(:now).returns(now)
+ previous = Time.utc(2010, "nov", 6, 23, 59, 59) # Sat
@schedule.match?(previous).should be_true
end
it "should not match if the previous time is after the most recent Saturday" do
- now = Time.now
-
- # Subtract the number days we've progressed into the week
- previous = now - (3600 * 24 * now.wday)
+ now = Time.utc(2010, "nov", 11, 0, 0, 0) # Thursday
+ Time.stubs(:now).returns(now)
+ previous = Time.utc(2010, "nov", 7, 0, 0, 0) # Sunday
@schedule.match?(previous).should be_false
end
@@ -289,19 +263,17 @@ describe Puppet::Type.type(:schedule) do
end
it "should match when the previous time is prior to the first day of this month" do
- now = Time.now
-
- # Subtract the number days we've progressed into the month
- previous = now - (3600 * 24 * now.day)
+ now = Time.utc(2010, "nov", 8, 00, 59, 59)
+ Time.stubs(:now).returns(now)
+ previous = Time.utc(2010, "oct", 31, 23, 59, 59)
@schedule.match?(previous).should be_true
end
it "should not match when the previous time is after the last day of last month" do
- now = Time.now
-
- # Subtract the number days we've progressed into the month, minus one
- previous = now - (3600 * 24 * (now.day - 1))
+ now = Time.utc(2010, "nov", 8, 00, 59, 59)
+ Time.stubs(:now).returns(now)
+ previous = Time.utc(2010, "nov", 1, 0, 0, 0)
@schedule.match?(previous).should be_false
end
diff --git a/spec/unit/type/service_spec.rb b/spec/unit/type/service_spec.rb
index 0f4a50750..77628670a 100755
--- a/spec/unit/type/service_spec.rb
+++ b/spec/unit/type/service_spec.rb
@@ -66,6 +66,10 @@ describe Puppet::Type.type(:service), "when validating attribute values" do
Puppet::Type.type(:service).new(:name => "yay", :hasstatus => :false)
end
+ it "should specify :true as the default value of hasstatus" do
+ Puppet::Type.type(:service).new(:name => "yay")[:hasstatus].should == :true
+ end
+
it "should support :true as a value to :hasrestart" do
Puppet::Type.type(:service).new(:name => "yay", :hasrestart => :true)
end
@@ -76,10 +80,18 @@ describe Puppet::Type.type(:service), "when validating attribute values" do
it "should allow setting the :enable parameter if the provider has the :enableable feature" do
Puppet::Type.type(:service).defaultprovider.stubs(:supports_parameter?).returns(true)
+ Puppet::Type.type(:service).defaultprovider.expects(:supports_parameter?).with(Puppet::Type.type(:service).attrclass(:enable)).returns(true)
svc = Puppet::Type.type(:service).new(:name => "yay", :enable => true)
svc.should(:enable).should == :true
end
+ it "should not allow setting the :enable parameter if the provider is missing the :enableable feature" do
+ Puppet::Type.type(:service).defaultprovider.stubs(:supports_parameter?).returns(true)
+ Puppet::Type.type(:service).defaultprovider.expects(:supports_parameter?).with(Puppet::Type.type(:service).attrclass(:enable)).returns(false)
+ svc = Puppet::Type.type(:service).new(:name => "yay", :enable => true)
+ svc.should(:enable).should be_nil
+ end
+
it "should split paths on ':'" do
FileTest.stubs(:exist?).returns(true)
FileTest.stubs(:directory?).returns(true)
diff --git a/spec/unit/type/tidy_spec.rb b/spec/unit/type/tidy_spec.rb
index 11edbfbf3..1573ead1b 100755
--- a/spec/unit/type/tidy_spec.rb
+++ b/spec/unit/type/tidy_spec.rb
@@ -110,7 +110,8 @@ describe tidy do
:b => 0,
:kb => 1,
:mb => 2,
- :gb => 3
+ :gb => 3,
+ :tb => 4
}
convertors.each do |unit, multiple|
diff --git a/spec/unit/type/user_spec.rb b/spec/unit/type/user_spec.rb
index abe18933f..ccea9ee4c 100755
--- a/spec/unit/type/user_spec.rb
+++ b/spec/unit/type/user_spec.rb
@@ -35,6 +35,14 @@ describe user do
user.provider_feature(:manages_solaris_rbac).should_not be_nil
end
+ it "should have a manages_expiry feature" do
+ user.provider_feature(:manages_expiry).should_not be_nil
+ end
+
+ it "should have a manages_password_age feature" do
+ user.provider_feature(:manages_password_age).should_not be_nil
+ end
+
describe "instances" do
it "should have a valid provider" do
user.new(:name => "foo").provider.class.ancestors.should be_include(Puppet::Provider)
@@ -47,7 +55,7 @@ describe user do
end
end
- properties = [:ensure, :uid, :gid, :home, :comment, :shell, :password, :groups, :roles, :auths, :profiles, :project, :keys]
+ properties = [:ensure, :uid, :gid, :home, :comment, :shell, :password, :password_min_age, :password_max_age, :groups, :roles, :auths, :profiles, :project, :keys, :expiry]
properties.each do |property|
it "should have a #{property} property" do
@@ -227,6 +235,16 @@ describe user do
end
end
+ describe "when managing expiry" do
+ before do
+ @expiry = user.attrclass(:expiry).new(:resource => @resource)
+ end
+
+ it "should fail if given an invalid date" do
+ lambda { @expiry.should = "200-20-20" }.should raise_error(Puppet::Error)
+ end
+ end
+
describe "when managing passwords" do
before do
@password = user.attrclass(:password).new(:resource => @resource, :should => "mypass")
@@ -262,6 +280,11 @@ describe user do
end
describe "when user has roles" do
+ before do
+ # To test this feature, we have to support it.
+ user.new(:name => "foo").provider.class.stubs(:feature?).returns(true)
+ end
+
it "should autorequire roles" do
testuser = Puppet::Type.type(:user).new(:name => "testuser")
testuser[:roles] = "testrole"
diff --git a/spec/unit/type/whit_spec.rb b/spec/unit/type/whit_spec.rb
new file mode 100644
index 000000000..998d9df30
--- /dev/null
+++ b/spec/unit/type/whit_spec.rb
@@ -0,0 +1,11 @@
+#!/usr/bin/env ruby
+
+require File.dirname(__FILE__) + '/../../spec_helper'
+
+whit = Puppet::Type.type(:whit).new(:name => "Foo::Bar")
+
+describe whit do
+ it "should stringify as though it were the class it represents" do
+ whit.to_s.should == "Class[Foo::Bar]"
+ end
+end
diff --git a/spec/unit/type_spec.rb b/spec/unit/type_spec.rb
index 487750e52..48b00ec4a 100755
--- a/spec/unit/type_spec.rb
+++ b/spec/unit/type_spec.rb
@@ -545,6 +545,13 @@ describe Puppet::Type.metaparamclass(:audit) do
@resource[:audit].should == list
end
+ it "should accept the string 'all' to specify auditing all possible properties" do
+ @resource[:audit] = 'all'
+
+ list = @resource.class.properties.collect { |p| p.name }
+ @resource[:audit].should == list
+ end
+
it "should fail if asked to audit an invalid property" do
lambda { @resource[:audit] = :foobar }.should raise_error(Puppet::Error)
end
diff --git a/spec/unit/util/backups_spec.rb b/spec/unit/util/backups_spec.rb
index 5c10d4c3c..259b18652 100755
--- a/spec/unit/util/backups_spec.rb
+++ b/spec/unit/util/backups_spec.rb
@@ -3,7 +3,6 @@
require File.dirname(__FILE__) + '/../../spec_helper'
require 'puppet/util/backups'
-include PuppetTest
describe Puppet::Util::Backups do
before do
diff --git a/spec/unit/util/command_line_spec.rb b/spec/unit/util/command_line_spec.rb
index a83ad968d..7ba965249 100644
--- a/spec/unit/util/command_line_spec.rb
+++ b/spec/unit/util/command_line_spec.rb
@@ -86,7 +86,7 @@ describe Puppet::Util::CommandLine do
describe "when the subcommand is not implemented" do
it "should find and invoke an executable with a hyphenated name" do
commandline = Puppet::Util::CommandLine.new("puppet", ['whatever', 'argument'], @tty)
- Puppet::Util.expects(:binary).with('puppet-whatever').returns('/dev/null/puppet-whatever')
+ Puppet::Util.expects(:which).with('puppet-whatever').returns('/dev/null/puppet-whatever')
commandline.expects(:system).with('/dev/null/puppet-whatever', 'argument')
commandline.execute
@@ -95,7 +95,7 @@ describe Puppet::Util::CommandLine do
describe "and an external implementation cannot be found" do
it "should abort and show the usage message" do
commandline = Puppet::Util::CommandLine.new("puppet", ['whatever', 'argument'], @tty)
- Puppet::Util.expects(:binary).with('puppet-whatever').returns(nil)
+ Puppet::Util.expects(:which).with('puppet-whatever').returns(nil)
commandline.expects(:system).never
commandline.expects(:usage_message).returns("the usage message")
diff --git a/spec/unit/util/file_locking_spec.rb b/spec/unit/util/file_locking_spec.rb
index 10051060c..8fafb1d52 100755
--- a/spec/unit/util/file_locking_spec.rb
+++ b/spec/unit/util/file_locking_spec.rb
@@ -32,17 +32,12 @@ describe Puppet::Util::FileLocking do
end
it "should use a global shared mutex" do
- @sync = mock 'sync'
- @sync.expects(:synchronize).with(Sync::SH).once
- Puppet::Util.expects(:sync).with('/file').returns @sync
-
+ Puppet::Util.expects(:synchronize_on).with('/file',Sync::SH).once
Puppet::Util::FileLocking.readlock '/file'
end
it "should use a shared lock on the file" do
- @sync = mock 'sync'
- @sync.stubs(:synchronize).yields
- Puppet::Util.expects(:sync).with('/file').returns @sync
+ Puppet::Util.expects(:synchronize_on).with('/file',Sync::SH).yields
fh = mock 'filehandle'
File.expects(:open).with("/file").yields fh
@@ -59,9 +54,7 @@ describe Puppet::Util::FileLocking do
end
it "should create missing files" do
- @sync = mock 'sync'
- @sync.stubs(:synchronize).yields
- Puppet::Util.expects(:sync).with('/file').returns @sync
+ Puppet::Util.expects(:synchronize_on).with('/file',Sync::SH).yields
File.expects(:exists?).with('/file').returns false
File.expects(:open).with('/file').once
@@ -72,9 +65,7 @@ describe Puppet::Util::FileLocking do
describe "when acquiring a write lock" do
before do
- @sync = mock 'sync'
- Puppet::Util.stubs(:sync).returns @sync
- @sync.stubs(:synchronize).yields
+ Puppet::Util.stubs(:synchronize_on).yields
File.stubs(:file?).with('/file').returns true
File.stubs(:exists?).with('/file').returns true
end
@@ -88,29 +79,26 @@ describe Puppet::Util::FileLocking do
end
it "should use a global exclusive mutex" do
- sync = mock 'sync'
- sync.expects(:synchronize).with(Sync::EX)
- Puppet::Util.expects(:sync).with("/file").returns sync
-
+ Puppet::Util.expects(:synchronize_on).with("/file",Sync::EX)
Puppet::Util::FileLocking.writelock '/file'
end
it "should use any specified mode when opening the file" do
- File.expects(:open).with("/file", "w", :mymode)
+ File.expects(:open).with("/file", File::Constants::CREAT | File::Constants::WRONLY , :mymode)
Puppet::Util::FileLocking.writelock('/file', :mymode)
end
it "should use the mode of the existing file if no mode is specified" do
File.expects(:stat).with("/file").returns(mock("stat", :mode => 0755))
- File.expects(:open).with("/file", "w", 0755)
+ File.expects(:open).with("/file", File::Constants::CREAT | File::Constants::WRONLY, 0755)
Puppet::Util::FileLocking.writelock('/file')
end
it "should use 0600 as the mode if no mode is specified and the file does not exist" do
File.expects(:stat).raises(Errno::ENOENT)
- File.expects(:open).with("/file", "w", 0600)
+ File.expects(:open).with("/file", File::Constants::CREAT | File::Constants::WRONLY, 0600)
Puppet::Util::FileLocking.writelock('/file')
end
@@ -130,6 +118,8 @@ describe Puppet::Util::FileLocking do
lfh = mock 'locked_filehandle'
fh.expects(:lock_exclusive).yields(lfh)
+ lfh.stubs(:seek)
+ lfh.stubs(:truncate)
lfh.expects(:print).with "foo"
Puppet::Util::FileLocking.writelock('/file') do |f|
@@ -137,18 +127,32 @@ describe Puppet::Util::FileLocking do
end
end
+ it "should truncate the file under an exclusive lock" do
+ fh = mock 'fh'
+ File.expects(:open).yields fh
+
+ lfh = mock 'locked_filehandle'
+ fh.expects(:lock_exclusive).yields(lfh)
+
+ lfh.expects(:seek).with(0, IO::SEEK_SET)
+ lfh.expects(:truncate).with(0)
+ lfh.stubs(:print)
+
+ Puppet::Util::FileLocking.writelock('/file') do |f|
+ f.print "foo"
+ end
+ end
+
it "should only work on regular files" do
File.expects(:file?).with('/file').returns false
proc { Puppet::Util::FileLocking.writelock('/file') }.should raise_error(ArgumentError)
end
it "should create missing files" do
- @sync = mock 'sync'
- @sync.stubs(:synchronize).yields
- Puppet::Util.expects(:sync).with('/file').returns @sync
+ Puppet::Util.expects(:synchronize_on).with('/file',Sync::EX).yields
File.expects(:exists?).with('/file').returns false
- File.expects(:open).with('/file', 'w', 0600).once
+ File.expects(:open).with('/file', File::Constants::CREAT | File::Constants::WRONLY, 0600).once
Puppet::Util::FileLocking.writelock('/file')
end
diff --git a/spec/unit/util/json_spec.rb b/spec/unit/util/json_spec.rb
deleted file mode 100755
index 4f6cea997..000000000
--- a/spec/unit/util/json_spec.rb
+++ /dev/null
@@ -1,21 +0,0 @@
-#!/usr/bin/env ruby
-
-Dir.chdir(File.dirname(__FILE__)) { (s = lambda { |f| File.exist?(f) ? require(f) : Dir.chdir("..") { s.call(f) } }).call("spec/spec_helper.rb") }
-
-require 'puppet/util/pson'
-
-class PsonUtil
- include Puppet::Util::Pson
-end
-
-describe Puppet::Util::Pson do
- it "should fail if no data is provided" do
- lambda { PsonUtil.new.pson_create("type" => "foo") }.should raise_error(ArgumentError)
- end
-
- it "should call 'from_pson' with the provided data" do
- pson = PsonUtil.new
- pson.expects(:from_pson).with("mydata")
- pson.pson_create("type" => "foo", "data" => "mydata")
- end
-end
diff --git a/spec/unit/util/log_spec.rb b/spec/unit/util/log_spec.rb
index 7d96fe190..ea5d59859 100755
--- a/spec/unit/util/log_spec.rb
+++ b/spec/unit/util/log_spec.rb
@@ -7,7 +7,7 @@ require 'puppet/util/log'
describe Puppet::Util::Log do
it "should write a given message to the specified destination" do
arraydest = []
- Puppet::Util::Log.newdestination(arraydest)
+ Puppet::Util::Log.newdestination(Puppet::Test::LogCollector.new(arraydest))
Puppet::Util::Log.new(:level => :notice, :message => "foo")
message = arraydest.last.message
message.should == "foo"
@@ -87,7 +87,7 @@ describe Puppet::Util::Log do
it "should flush the log queue when the first destination is specified" do
Puppet::Util::Log.close_all
Puppet::Util::Log.expects(:flushqueue)
- Puppet::Util::Log.newdestination([])
+ Puppet::Util::Log.newdestination(:console)
end
it "should convert the level to a symbol if it's passed in as a string" do
diff --git a/spec/unit/util/monkey_patches_spec.rb b/spec/unit/util/monkey_patches_spec.rb
index b0f61c808..049ed1044 100644
--- a/spec/unit/util/monkey_patches_spec.rb
+++ b/spec/unit/util/monkey_patches_spec.rb
@@ -5,3 +5,29 @@ Dir.chdir(File.dirname(__FILE__)) { (s = lambda { |f| File.exist?(f) ? require(f
require 'puppet/util/monkey_patches'
+
+describe "yaml deserialization" do
+ it "should call yaml_initialize when deserializing objects that have that method defined" do
+ class Puppet::TestYamlInitializeClass
+ attr_reader :foo
+
+ def yaml_initialize(tag, var)
+ var.should == {'foo' => 100}
+ instance_variables.should == []
+ @foo = 200
+ end
+ end
+
+ obj = YAML.load("--- !ruby/object:Puppet::TestYamlInitializeClass\n foo: 100")
+ obj.foo.should == 200
+ end
+
+ it "should not call yaml_initialize if not defined" do
+ class Puppet::TestYamlNonInitializeClass
+ attr_reader :foo
+ end
+
+ obj = YAML.load("--- !ruby/object:Puppet::TestYamlNonInitializeClass\n foo: 100")
+ obj.foo.should == 100
+ end
+end
diff --git a/spec/unit/util/pson_spec.rb b/spec/unit/util/pson_spec.rb
new file mode 100755
index 000000000..474ddafa4
--- /dev/null
+++ b/spec/unit/util/pson_spec.rb
@@ -0,0 +1,53 @@
+#!/usr/bin/env ruby
+
+Dir.chdir(File.dirname(__FILE__)) { (s = lambda { |f| File.exist?(f) ? require(f) : Dir.chdir("..") { s.call(f) } }).call("spec/spec_helper.rb") }
+
+require 'puppet/util/pson'
+
+class PsonUtil
+ include Puppet::Util::Pson
+end
+
+describe Puppet::Util::Pson do
+ it "should fail if no data is provided" do
+ lambda { PsonUtil.new.pson_create("type" => "foo") }.should raise_error(ArgumentError)
+ end
+
+ it "should call 'from_pson' with the provided data" do
+ pson = PsonUtil.new
+ pson.expects(:from_pson).with("mydata")
+ pson.pson_create("type" => "foo", "data" => "mydata")
+ end
+
+
+ {
+ 'foo' => '"foo"',
+ 1 => '1',
+ "\x80" => "\"\x80\"",
+ [] => '[]'
+ }.each { |str,pson|
+ it "should be able to encode #{str.inspect}" do
+ str.to_pson.should == pson
+ end
+ }
+
+ it "should be able to handle arbitrary binary data" do
+ bin_string = (1..20000).collect { |i| ((17*i+13*i*i) % 255).chr }.join
+ PSON.parse(%Q{{ "type": "foo", "data": #{bin_string.to_pson} }})["data"].should == bin_string
+ end
+
+ it "should be able to handle UTF8 that isn't a real unicode character" do
+ s = ["\355\274\267"]
+ PSON.parse( [s].to_pson ).should == [s]
+ end
+
+ it "should be able to handle UTF8 for \\xFF" do
+ s = ["\xc3\xbf"]
+ PSON.parse( [s].to_pson ).should == [s]
+ end
+
+ it "should be able to handle invalid UTF8 bytes" do
+ s = ["\xc3\xc3"]
+ PSON.parse( [s].to_pson ).should == [s]
+ end
+end
diff --git a/spec/unit/util/rdoc/parser_spec.rb b/spec/unit/util/rdoc/parser_spec.rb
index a9c8190a6..04713f293 100755
--- a/spec/unit/util/rdoc/parser_spec.rb
+++ b/spec/unit/util/rdoc/parser_spec.rb
@@ -19,8 +19,8 @@ describe RDoc::Parser do
it "should parse puppet files with the puppet parser" do
@parser.stubs(:scan_top_level)
parser = stub 'parser'
- Puppet::Parser::Parser.expects(:new).returns(parser)
- parser.expects(:parse)
+ Puppet::Parser::Parser.stubs(:new).returns(parser)
+ parser.expects(:parse).returns(Puppet::Parser::AST::Hostclass.new(''))
parser.expects(:file=).with("module/manifests/init.pp")
@parser.scan
@@ -29,6 +29,7 @@ describe RDoc::Parser do
it "should scan the ast for Puppet files" do
parser = stub_everything 'parser'
Puppet::Parser::Parser.stubs(:new).returns(parser)
+ parser.expects(:parse).returns(Puppet::Parser::AST::Hostclass.new(''))
@parser.expects(:scan_top_level)
@@ -38,6 +39,7 @@ describe RDoc::Parser do
it "should return a PuppetTopLevel to RDoc" do
parser = stub_everything 'parser'
Puppet::Parser::Parser.stubs(:new).returns(parser)
+ parser.expects(:parse).returns(Puppet::Parser::AST::Hostclass.new(''))
@parser.expects(:scan_top_level)
@@ -47,8 +49,8 @@ describe RDoc::Parser do
describe "when scanning top level entities" do
before :each do
- @resource_type_collection = stub_everything 'resource_type_collection'
- @parser.ast = @resource_type_collection
+ @resource_type_collection = resource_type_collection = stub_everything('resource_type_collection')
+ @parser.instance_eval { @known_resource_types = resource_type_collection }
@parser.stubs(:split_module).returns("module")
@topcontainer = stub_everything 'topcontainer'
@@ -85,8 +87,8 @@ describe RDoc::Parser do
@parser.scan_top_level(@topcontainer)
end
- it "should set the module as global if we parse the global manifests (ie <site> module)" do
- @parser.stubs(:split_module).returns("<site>")
+ it "should set the module as global if we parse the global manifests (ie __site__ module)" do
+ @parser.stubs(:split_module).returns(RDoc::Parser::SITE)
@parser.stubs(:parse_elements)
@topcontainer.expects(:global=).with(true)
@@ -131,7 +133,7 @@ describe RDoc::Parser do
it "should return <site> for manifests not under module path" do
File.stubs(:expand_path).returns("/path/to/manifests/init.pp")
File.stubs(:identical?).returns(false)
- @parser.split_module("/path/to/manifests/init.pp").should == "<site>"
+ @parser.split_module("/path/to/manifests/init.pp").should == RDoc::Parser::SITE
end
end
@@ -141,8 +143,8 @@ describe RDoc::Parser do
@definition = stub_everything 'definition', :file => "module/manifests/init.pp", :type => :definition, :name => "mydef"
@node = stub_everything 'node', :file => "module/manifests/init.pp", :type => :node, :name => "mynode"
- @resource_type_collection = Puppet::Resource::TypeCollection.new("env")
- @parser.ast = @resource_type_collection
+ @resource_type_collection = resource_type_collection = Puppet::Resource::TypeCollection.new("env")
+ @parser.instance_eval { @known_resource_types = resource_type_collection }
@container = stub_everything 'container'
end
@@ -340,10 +342,12 @@ describe RDoc::Parser do
def create_stmt(name)
stmt_value = stub "#{name}_value", :value => "myclass"
- stmt = stub_everything 'stmt', :name => name, :arguments => [stmt_value], :doc => "mydoc"
- stmt.stubs(:is_a?).with(Puppet::Parser::AST::ASTArray).returns(false)
- stmt.stubs(:is_a?).with(Puppet::Parser::AST::Function).returns(true)
- stmt
+
+ Puppet::Parser::AST::Function.new(
+ :name => name,
+ :arguments => [stmt_value],
+ :doc => 'mydoc'
+ )
end
before(:each) do
@@ -377,10 +381,11 @@ describe RDoc::Parser do
def create_stmt
stmt_value = stub "resource_ref", :to_s => "File[\"/tmp/a\"]"
- stmt = stub_everything 'stmt', :name => "realize", :arguments => [stmt_value], :doc => "mydoc"
- stmt.stubs(:is_a?).with(Puppet::Parser::AST::ASTArray).returns(false)
- stmt.stubs(:is_a?).with(Puppet::Parser::AST::Function).returns(true)
- stmt
+ Puppet::Parser::AST::Function.new(
+ :name => 'realize',
+ :arguments => [stmt_value],
+ :doc => 'mydoc'
+ )
end
before(:each) do
@@ -432,11 +437,16 @@ describe RDoc::Parser do
describe "when scanning for resources" do
before :each do
@class = stub_everything 'class'
-
- param = stub 'params', :children => []
- @stmt = stub_everything 'stmt', :type => "File", :title => "myfile", :doc => "mydoc", :params => param
- @stmt.stubs(:is_a?).with(Puppet::Parser::AST::ASTArray).returns(false)
- @stmt.stubs(:is_a?).with(Puppet::Parser::AST::Resource).returns(true)
+ @stmt = Puppet::Parser::AST::Resource.new(
+ :type => "File",
+ :instances => Puppet::Parser::AST::ASTArray.new(:children => [
+ Puppet::Parser::AST::ResourceInstance.new(
+ :title => Puppet::Parser::AST::Name.new(:value => "myfile"),
+ :parameters => Puppet::Parser::AST::ASTArray.new(:children => [])
+ )
+ ]),
+ :doc => 'mydoc'
+ )
@code = stub_everything 'code'
@code.stubs(:is_a?).with(Puppet::Parser::AST::ASTArray).returns(true)
diff --git a/spec/unit/util/rdoc_spec.rb b/spec/unit/util/rdoc_spec.rb
index 65df26156..41d4b9cd0 100755
--- a/spec/unit/util/rdoc_spec.rb
+++ b/spec/unit/util/rdoc_spec.rb
@@ -43,12 +43,20 @@ describe Puppet::Util::RDoc do
Puppet::Util::RDoc.rdoc("output", [], "utf-8")
end
- it "should tell RDoc to force updates of indices" do
+ it "should tell RDoc to force updates of indices when RDoc supports it" do
+ Options::OptionList.stubs(:options).returns([["--force-update", "-U", 0 ]])
@rdoc.expects(:document).with { |args| args.include?("--force-update") }
Puppet::Util::RDoc.rdoc("output", [])
end
+ it "should not tell RDoc to force updates of indices when RDoc doesn't support it" do
+ Options::OptionList.stubs(:options).returns([])
+ @rdoc.expects(:document).never.with { |args| args.include?("--force-update") }
+
+ Puppet::Util::RDoc.rdoc("output", [])
+ end
+
it "should tell RDoc to use the given outputdir" do
@rdoc.expects(:document).with { |args| args.include?("--op") and args.include?("myoutputdir") }
@@ -75,6 +83,19 @@ describe Puppet::Util::RDoc do
Puppet::Util::RDoc.manifestdoc([])
end
+ it "should use a parser with the correct environment" do
+ FileTest.stubs(:file?).returns(true)
+ Puppet::Util::RDoc.stubs(:output)
+
+ parser = stub_everything
+ Puppet::Parser::Parser.stubs(:new).with{ |env| env.is_a?(Puppet::Node::Environment) }.returns(parser)
+
+ parser.expects(:file=).with("file")
+ parser.expects(:parse)
+
+ Puppet::Util::RDoc.manifestdoc(["file"])
+ end
+
it "should puppet parse all given files" do
FileTest.stubs(:file?).returns(true)
Puppet::Util::RDoc.stubs(:output)
diff --git a/spec/unit/util/storage_spec.rb b/spec/unit/util/storage_spec.rb
index 6c8baba1f..ae3cbc2ae 100755
--- a/spec/unit/util/storage_spec.rb
+++ b/spec/unit/util/storage_spec.rb
@@ -3,15 +3,14 @@
require File.dirname(__FILE__) + '/../../spec_helper'
require 'yaml'
-require 'tempfile'
-
require 'puppet/util/storage'
describe Puppet::Util::Storage do
+ include PuppetSpec::Files
before(:all) do
@basepath = Puppet.features.posix? ? "/somepath" : "C:/somepath"
- Puppet[:statedir] = Dir.tmpdir
+ Puppet[:statedir] = tmpdir("statedir")
end
after(:all) do
diff --git a/spec/unit/util/zaml_spec.rb b/spec/unit/util/zaml_spec.rb
index 4de57e6d3..358c6aa11 100644..100755
--- a/spec/unit/util/zaml_spec.rb
+++ b/spec/unit/util/zaml_spec.rb
@@ -11,7 +11,8 @@ describe "Pure ruby yaml implementation" do
'test' => "--- test",
[] => "--- []",
:symbol => "--- !ruby/sym symbol",
- {:a => "A"} => "--- \n !ruby/sym a: A"
+ {:a => "A"} => "--- \n !ruby/sym a: A",
+ {:a => "x\ny"} => "--- \n !ruby/sym a: |-\n x\n y"
}.each { |o,y|
it "should convert the #{o.class} #{o.inspect} to yaml" do
o.to_yaml.should == y
@@ -34,5 +35,29 @@ describe "Pure ruby yaml implementation" do
lambda { YAML.load(o.to_yaml) }.should_not raise_error
end
}
-end
+ it "should emit proper labels and backreferences for common objects" do
+ # Note: this test makes assumptions about the names ZAML chooses
+ # for labels.
+ x = [1, 2]
+ y = [3, 4]
+ z = [x, y, x, y]
+ z.to_yaml.should == "--- \n - &id001\n - 1\n - 2\n - &id002\n - 3\n - 4\n - *id001\n - *id002"
+ z2 = YAML.load(z.to_yaml)
+ z2.should == z
+ z2[0].should equal(z2[2])
+ z2[1].should equal(z2[3])
+ end
+
+ it "should emit proper labels and backreferences for recursive objects" do
+ x = [1, 2]
+ x << x
+ x.to_yaml.should == "--- &id001\n \n - 1\n - 2\n - *id001"
+ x2 = YAML.load(x.to_yaml)
+ x2.should be_a(Array)
+ x2.length.should == 3
+ x2[0].should == 1
+ x2[1].should == 2
+ x2[2].should equal(x2)
+ end
+end
diff --git a/tasks/rake/git_workflow.rake b/tasks/rake/git_workflow.rake
index b2f96c603..4c39f98de 100644
--- a/tasks/rake/git_workflow.rake
+++ b/tasks/rake/git_workflow.rake
@@ -103,10 +103,21 @@ task :mail_patches do
# Create all of the patches
sh "git format-patch -C -M -s -n --subject-prefix='PATCH/puppet' #{parent}..HEAD"
+ # Add info to the patches
+ additional_info = "Local-branch: #{branch}\n"
+ files = Dir.glob("00*.patch")
+ files.each do |file|
+ contents = File.read(file)
+ contents.sub!(/^---\n/, "---\n#{additional_info}")
+ File.open(file, 'w') do |file_handle|
+ file_handle.print contents
+ end
+ end
+
# And then mail them out.
# If we've got more than one patch, add --compose
- if Dir.glob("00*.patch").length > 1
+ if files.length > 1
compose = "--compose"
else
compose = ""
diff --git a/tasks/rake/tracdocs.rake b/tasks/rake/tracdocs.rake
deleted file mode 100644
index d26d8fc17..000000000
--- a/tasks/rake/tracdocs.rake
+++ /dev/null
@@ -1,8 +0,0 @@
-task :tracdocs do
- require 'puppet'
- require 'puppet/util/reference'
- Puppet::Util::Reference.references.each do |ref|
- sh "puppetdoc -m trac -r #{ref.to_s}"
- end
-end
-
diff --git a/test/certmgr/ca.rb b/test/certmgr/ca.rb
deleted file mode 100755
index 7e0498dfb..000000000
--- a/test/certmgr/ca.rb
+++ /dev/null
@@ -1,87 +0,0 @@
-#!/usr/bin/env ruby
-
-require File.dirname(__FILE__) + '/../lib/puppettest'
-
-require 'puppet'
-require 'puppet/sslcertificates/ca.rb'
-require 'puppettest'
-require 'puppettest/certificates'
-require 'mocha'
-
-class TestCA < Test::Unit::TestCase
- include PuppetTest
-
- def setup
- super
- Puppet::Util::SUIDManager.stubs(:asuser).yields
- end
-
- def hosts
- %w{host.domain.com Other.Testing.Com}
- end
- def mkca
- Puppet::SSLCertificates::CA.new
- end
-
- def test_clean
- dirs = [:csrdir, :signeddir, :publickeydir, :privatekeydir, :certdir]
- ca = mkca
-
- hosts.each do |host|
- files = []
- dirs.each do |dir|
- dir = Puppet[dir]
- # We handle case insensitivity through downcasing
- file = File.join(dir, host.downcase + ".pem")
- File.open(file, "w") do |f|
- f.puts "testing"
- end
- files << file
- end
- assert_nothing_raised do
- ca.clean(host)
- end
- files.each do |f|
- assert(! FileTest.exists?(f), "File #{f} was not deleted")
- end
- end
- end
-
- def test_host2Xfile
- ca = mkca
- hosts.each do |host|
- {:signeddir => :host2certfile, :csrdir => :host2csrfile}.each do |dir, method|
- val = nil
- assert_nothing_raised do
- val = ca.send(method, host)
- end
- assert_equal(File.join(Puppet[dir], host.downcase + ".pem"), val,
- "incorrect response from #{method}")
- end
- end
- end
-
- def test_list
- ca = mkca
- # Make a fake csr
- dir = Puppet[:csrdir]
- list = []
- hosts.each do |host|
- file = File.join(dir, host.downcase + ".pem")
- File.open(file, "w") { |f| f.puts "yay" }
- list << host.downcase
- end
-
- assert_equal(list.sort, ca.list.sort, "list was not correct")
- end
-
- # #142 - test storing the public key
- def test_store_public_key
- ca = mkca
- assert_nothing_raised do
- ca.mkrootcert
- end
- assert(FileTest.exists?(Puppet[:capub]), "did not store public key")
- end
-end
-
diff --git a/test/certmgr/support.rb b/test/certmgr/support.rb
index 3138c94d7..060c458d8 100755
--- a/test/certmgr/support.rb
+++ b/test/certmgr/support.rb
@@ -89,8 +89,9 @@ class TestCertSupport < Test::Unit::TestCase
should_path = Puppet[:hostprivkey]
dir, file = File.split(should_path)
- newfile = file.sub(/^([a-z.]+)\./) { $1.upcase + "."}
+ newfile = file.sub(/^([-a-z.0-9]+)\./) { $1.upcase + "."}
upper_path = File.join(dir, newfile)
+p upper_path
File.open(upper_path, "w") { |f| f.print key.to_s }
user = CertUser.new
diff --git a/test/data/providers/host/parsed/valid_hosts b/test/data/providers/host/parsed/valid_hosts
new file mode 100644
index 000000000..24636295d
--- /dev/null
+++ b/test/data/providers/host/parsed/valid_hosts
@@ -0,0 +1,19 @@
+# Some leading comment, that should be ignored
+# The next line is empty so it should be ignored
+
+::1 localhost
+
+# We now try another delimiter: Several tabs
+127.0.0.1 localhost
+
+# No test trailing spaces
+10.0.0.1 host1
+
+# Ok its time to test aliases
+2001:252:0:1::2008:8 ipv6host alias1
+192.168.0.1 ipv4host alias2 alias3
+
+# Testing inlinecomments now
+192.168.0.2 host3 # This is host3
+192.168.0.3 host4 alias10 # This is host4
+192.168.0.4 host5 alias11 alias12 # This is host5
diff --git a/test/language/functions.rb b/test/language/functions.rb
index 1d4ed8241..081063e2b 100755
--- a/test/language/functions.rb
+++ b/test/language/functions.rb
@@ -451,7 +451,7 @@ class TestLangFunctions < Test::Unit::TestCase
scope.function_include("nosuchclass")
end
- parser.newclass("myclass")
+ scope.known_resource_types.add Puppet::Resource::Type.new(:hostclass, "myclass", {})
scope.compiler.expects(:evaluate_classes).with(%w{myclass otherclass}, scope, false).returns(%w{myclass otherclass})
diff --git a/test/language/parser.rb b/test/language/parser.rb
index 5a433c724..6f3d751c2 100755
--- a/test/language/parser.rb
+++ b/test/language/parser.rb
@@ -39,9 +39,8 @@ class TestParser < Test::Unit::TestCase
failers { |file|
parser = mkparser
Puppet.debug("parsing failer #{file}") if __FILE__ == $0
- assert_raise(Puppet::ParseError, "Did not fail while parsing #{file}") {
- parser.file = file
- ast = parser.parse
+ assert_raise(Puppet::ParseError, Puppet::Error, "Did not fail while parsing #{file}") {
+ Puppet[:manifest] = file
config = mkcompiler(parser)
config.compile
#ast.hostclass("").evaluate config.topscope
@@ -97,7 +96,7 @@ class TestParser < Test::Unit::TestCase
}
4.times { |i|
- path = File.join(basedir, subdir, "subfile#{i}")
+ path = File.join(basedir, subdir, "subfile#{i}.pp")
mkmanifest(path)
}
@@ -137,8 +136,8 @@ class TestParser < Test::Unit::TestCase
end
def test_importedclasses
- imported = tempfile
- importer = tempfile
+ imported = tempfile '.pp'
+ importer = tempfile '.pp'
made = tempfile
@@ -288,7 +287,7 @@ class TestParser < Test::Unit::TestCase
ret = parser.parse
}
- ret.hostclass("").code.each do |obj|
+ ret.code.each do |obj|
assert_instance_of(AST::Collection, obj)
end
end
@@ -362,12 +361,12 @@ file { "/tmp/yayness":
assert_raise(Puppet::ParseError) {
- parser.parse %{define mydef($schedule) {}}
+ parser.known_resource_types.import_ast(parser.parse(%{define mydef($schedule) {}}), '')
}
assert_nothing_raised {
- parser.parse %{define adef($schedule = false) {}}
- parser.parse %{define mydef($schedule = daily) {}}
+ parser.known_resource_types.import_ast(parser.parse(%{define adef($schedule = false) {}}), '')
+ parser.known_resource_types.import_ast(parser.parse(%{define mydef($schedule = daily) {}}), '')
}
end
@@ -379,12 +378,12 @@ file { "/tmp/yayness":
str1 = %{if true { #{exec.call("true")} }}
ret = nil
assert_nothing_raised {
- ret = parser.parse(str1).hostclass("").code[0]
+ ret = parser.parse(str1).code[0]
}
assert_instance_of(Puppet::Parser::AST::IfStatement, ret)
parser = mkparser
str2 = %{if true { #{exec.call("true")} } else { #{exec.call("false")} }}
- ret = parser.parse(str2).hostclass("").code[0]
+ ret = parser.parse(str2).code[0]
assert_instance_of(Puppet::Parser::AST::IfStatement, ret)
assert_instance_of(Puppet::Parser::AST::Else, ret.else)
end
@@ -393,23 +392,23 @@ file { "/tmp/yayness":
parser = mkparser
assert_nothing_raised {
- parser.parse %{class myclass { class other {} }}
+ parser.known_resource_types.import_ast(parser.parse(%{class myclass { class other {} }}), '')
}
assert(parser.hostclass("myclass"), "Could not find myclass")
assert(parser.hostclass("myclass::other"), "Could not find myclass::other")
assert_nothing_raised {
- parser.parse "class base {}
+ parser.known_resource_types.import_ast(parser.parse("class base {}
class container {
class deep::sub inherits base {}
- }"
+ }"), '')
}
sub = parser.hostclass("container::deep::sub")
assert(sub, "Could not find sub")
# Now try it with a parent class being a fq class
assert_nothing_raised {
- parser.parse "class container::one inherits container::deep::sub {}"
+ parser.known_resource_types.import_ast(parser.parse("class container::one inherits container::deep::sub {}"), '')
}
sub = parser.hostclass("container::one")
assert(sub, "Could not find one")
@@ -417,7 +416,7 @@ file { "/tmp/yayness":
# Finally, try including a qualified class
assert_nothing_raised("Could not include fully qualified class") {
- parser.parse "include container::deep::sub"
+ parser.known_resource_types.import_ast(parser.parse("include container::deep::sub"), '')
}
end
@@ -426,20 +425,11 @@ file { "/tmp/yayness":
# Make sure we put the top-level code into a class called "" in
# the "" namespace
- assert_nothing_raised do
- out = parser.parse ""
-
- assert_instance_of(Puppet::Resource::TypeCollection, out)
- assert_nil(parser.hostclass(""), "Got a 'main' class when we had no code")
- end
-
- # Now try something a touch more complicated
parser.initvars
assert_nothing_raised do
- out = parser.parse "Exec { path => '/usr/bin:/usr/sbin' }"
- assert_instance_of(Puppet::Resource::TypeCollection, out)
- assert_equal("", parser.hostclass("").name)
- assert_equal("", parser.hostclass("").namespace)
+ parser.known_resource_types.import_ast(parser.parse("Exec { path => '/usr/bin:/usr/sbin' }"), '')
+ assert_equal("", parser.known_resource_types.hostclass("").name)
+ assert_equal("", parser.known_resource_types.hostclass("").namespace)
end
end
@@ -482,22 +472,26 @@ file { "/tmp/yayness":
ret = nil
assert_nothing_raised do
- ret = parser.parse("#{at}file { '/tmp/testing': owner => root }")
+ parser.known_resource_types.import_ast(parser.parse("#{at}file { '/tmp/testing': owner => root }"), '')
+ ret = parser.known_resource_types
end
assert_instance_of(AST::ASTArray, ret.hostclass("").code)
resdef = ret.hostclass("").code[0]
assert_instance_of(AST::Resource, resdef)
- assert_equal("/tmp/testing", resdef.title.value)
+ assert_instance_of(AST::ASTArray, resdef.instances)
+ assert_equal(1, resdef.instances.children.length)
+ assert_equal("/tmp/testing", resdef.instances[0].title.value)
# We always get an astarray back, so...
check.call(resdef, "simple resource")
# Now let's try it with multiple resources in the same spec
assert_nothing_raised do
- ret = parser.parse("#{at}file { ['/tmp/1', '/tmp/2']: owner => root }")
+ parser.known_resource_types.import_ast(parser.parse("#{at}file { ['/tmp/1', '/tmp/2']: owner => root }"), '')
+ ret = parser.known_resource_types
end
- ret.hostclass("").code.each do |res|
+ ret.hostclass("").code[0].each do |res|
assert_instance_of(AST::Resource, res)
check.call(res, "multiresource")
end
@@ -537,7 +531,7 @@ file { "/tmp/yayness":
ret = parser.parse("File #{arrow}")
end
- coll = ret.hostclass("").code[0]
+ coll = ret.code[0]
assert_instance_of(AST::Collection, coll)
assert_equal(form, coll.form)
end
@@ -560,7 +554,7 @@ file { "/tmp/yayness":
res = nil
assert_nothing_raised do
- res = parser.parse(str).hostclass("").code[0]
+ res = parser.parse(str).code[0]
end
assert_instance_of(AST::Collection, res)
@@ -583,7 +577,7 @@ file { "/tmp/yayness":
res = nil
assert_nothing_raised do
- res = parser.parse(str).hostclass("").code[0]
+ res = parser.parse(str).code[0]
end
assert_instance_of(AST::Collection, res)
@@ -607,7 +601,7 @@ file { "/tmp/yayness":
res = nil
assert_nothing_raised("Could not parse '#{test}'") do
- res = parser.parse(str).hostclass("").code[0]
+ res = parser.parse(str).code[0]
end
assert_instance_of(AST::Collection, res)
@@ -624,15 +618,11 @@ file { "/tmp/yayness":
def test_fully_qualified_definitions
parser = mkparser
+ types = parser.known_resource_types
assert_nothing_raised("Could not parse fully-qualified definition") {
- parser.parse %{define one::two { }}
+ types.import_ast(parser.parse(%{define one::two { }}), '')
}
assert(parser.definition("one::two"), "Could not find one::two with no namespace")
-
- # Now try using the definition
- assert_nothing_raised("Could not parse fully-qualified definition usage") {
- parser.parse %{one::two { yayness: }}
- }
end
# #524
@@ -655,9 +645,9 @@ file { "/tmp/yayness":
end
def test_multiple_imports_on_one_line
- one = tempfile
- two = tempfile
- base = tempfile
+ one = tempfile '.pp'
+ two = tempfile '.pp'
+ base = tempfile '.pp'
File.open(one, "w") { |f| f.puts "$var = value" }
File.open(two, "w") { |f| f.puts "$var = value" }
File.open(base, "w") { |f| f.puts "import '#{one}', '#{two}'" }
@@ -691,7 +681,7 @@ file { "/tmp/yayness":
result = parser.parse %{$variable = undef}
}
- main = result.hostclass("").code
+ main = result.code
children = main.children
assert_instance_of(AST::VarDef, main.children[0])
assert_instance_of(AST::Undef, main.children[0].value)
@@ -704,7 +694,8 @@ file { "/tmp/yayness":
str = "file { '/tmp/yay': ensure => file }\nclass yay {}\nnode foo {}\ndefine bar {}\n"
result = nil
assert_nothing_raised("Could not parse") do
- result = parser.parse(str)
+ parser.known_resource_types.import_ast(parser.parse(str), '')
+ result = parser.known_resource_types
end
assert_instance_of(Puppet::Resource::TypeCollection, result, "Did not get a ASTSet back from parsing")
@@ -734,12 +725,14 @@ file { "/tmp/yayness":
result = nil
assert_nothing_raised do
- result = parser.newclass "Yayness"
+ parser.known_resource_types.import_ast(parser.parse("class yayness { }"), '')
+ result = parser.known_resource_types.hostclass('yayness')
end
assert_equal(result, parser.find_hostclass("", "yayNess"))
assert_nothing_raised do
- result = parser.newdefine "FunTest"
+ parser.known_resource_types.import_ast(parser.parse("define funtest { }"), '')
+ result = parser.known_resource_types.definition('funtest')
end
assert_equal(result, parser.find_definition("", "fUntEst"), "#{"fUntEst"} was not matched")
end
diff --git a/test/language/scope.rb b/test/language/scope.rb
index cb5558aec..d9c122a92 100755
--- a/test/language/scope.rb
+++ b/test/language/scope.rb
@@ -163,7 +163,7 @@ class TestScope < Test::Unit::TestCase
config = mkcompiler
# Create a default source
- parser.newclass("")
+ parser.known_resource_types.add Puppet::Resource::Type.new(:hostclass, "")
config.topscope.source = parser.known_resource_types.hostclass("")
# And a scope resource
@@ -175,12 +175,12 @@ class TestScope < Test::Unit::TestCase
)
# Create a top-level define
- parser.newdefine "one", :arguments => [%w{arg}],
+ parser.known_resource_types.add Puppet::Resource::Type.new(:definition, "one", :arguments => [%w{arg}],
:code => AST::ASTArray.new(
:children => [
resourcedef("file", "/tmp", {"owner" => varref("arg")})
]
- )
+ ))
# create a resource that calls our third define
obj = resourcedef("one", "boo", {"arg" => "parentfoo"})
diff --git a/test/lib/mocha_standalone.rb b/test/lib/mocha_standalone.rb
deleted file mode 100644
index ce605811a..000000000
--- a/test/lib/mocha_standalone.rb
+++ /dev/null
@@ -1,2 +0,0 @@
-require 'mocha/standalone'
-require 'mocha/object'
diff --git a/test/lib/puppettest.rb b/test/lib/puppettest.rb
index e31a31902..a60092cf7 100755
--- a/test/lib/puppettest.rb
+++ b/test/lib/puppettest.rb
@@ -6,17 +6,6 @@ mainlib = File.expand_path(File.join(File.dirname(__FILE__), '../../lib'))
$LOAD_PATH.unshift(mainlib) unless $LOAD_PATH.include?(mainlib)
require 'puppet'
-
-# include any gems in vendor/gems
-Dir["#{mainlib}/../vendor/gems/**"].each do |path|
- libpath = File.join(path, "lib")
- if File.directory?(libpath)
- $LOAD_PATH.unshift(libpath)
- else
- $LOAD_PATH.unshift(path)
- end
-end
-
require 'mocha'
# Only load the test/unit class if we're not in the spec directory.
@@ -31,16 +20,7 @@ if ARGV.include?("-d")
$console = true
end
-# Some monkey-patching to allow us to test private methods.
-class Class
- def publicize_methods(*methods)
- saved_private_instance_methods = methods.empty? ? self.private_instance_methods : methods
-
- self.class_eval { public(*saved_private_instance_methods) }
- yield
- self.class_eval { private(*saved_private_instance_methods) }
- end
-end
+require File.expand_path(File.join(File.dirname(__FILE__), '../../spec/monkey_patches/publicize_methods'))
module PuppetTest
# These need to be here for when rspec tests use these
@@ -205,7 +185,7 @@ module PuppetTest
#if rake? or ! Puppet[:debug]
#if defined?($puppet_debug) or ! rake?
Puppet[:color] = false if textmate?
- Puppet::Util::Log.newdestination(@logs)
+ Puppet::Util::Log.newdestination(Puppet::Test::LogCollector.new(@logs))
if defined? $console
Puppet.info @method_name
Puppet::Util::Log.newdestination(:console)
@@ -227,14 +207,14 @@ module PuppetTest
#Facter.stubs(:to_hash).returns({})
end
- def tempfile
+ def tempfile(suffix = '')
if defined?(@@tmpfilenum)
@@tmpfilenum += 1
else
@@tmpfilenum = 1
end
- f = File.join(self.tmpdir, "tempfile_" + @@tmpfilenum.to_s)
+ f = File.join(self.tmpdir, "tempfile_" + @@tmpfilenum.to_s + suffix)
@@tmpfiles ||= []
@@tmpfiles << f
f
@@ -325,7 +305,7 @@ module PuppetTest
def logstore
@logs = []
- Puppet::Util::Log.newdestination(@logs)
+ Puppet::Util::Log.newdestination(Puppet::Test::LogCollector.new(@logs))
end
end
diff --git a/test/lib/puppettest/fakes.rb b/test/lib/puppettest/fakes.rb
index aaa711004..712332b74 100644
--- a/test/lib/puppettest/fakes.rb
+++ b/test/lib/puppettest/fakes.rb
@@ -1,4 +1,4 @@
-require 'puppettest'
+require File.expand_path(File.join(File.dirname(__FILE__), '../../../lib/puppet/util'))
module PuppetTest
# A baseclass for the faketypes.
diff --git a/test/lib/puppettest/parsertesting.rb b/test/lib/puppettest/parsertesting.rb
index bd04c1ec5..411bad37a 100644
--- a/test/lib/puppettest/parsertesting.rb
+++ b/test/lib/puppettest/parsertesting.rb
@@ -94,16 +94,15 @@ module PuppetTest::ParserTesting
def resourcedef(type, title, params)
title = stringobj(title) unless title.is_a?(AST)
+ instance = AST::ResourceInstance.new(:title => title, :parameters => resourceparams(params))
assert_nothing_raised("Could not create #{type} #{title}") {
return AST::Resource.new(
:file => __FILE__,
:line => __LINE__,
- :title => title,
:type => type,
-
- :parameters => resourceinst(params)
+ :instances => AST::ASTArray.new(:children => [instance])
)
}
end
@@ -122,9 +121,7 @@ module PuppetTest::ParserTesting
:file => __FILE__,
:line => __LINE__,
:object => resourceref(type, title),
-
- :type => type,
- :parameters => resourceinst(params)
+ :parameters => resourceparams(params)
)
}
end
@@ -197,13 +194,13 @@ module PuppetTest::ParserTesting
}
end
- def resourceinst(hash)
+ def resourceparams(hash)
assert_nothing_raised("Could not create resource instance") {
params = hash.collect { |param, value|
resourceparam(param, value)
}
- return AST::ResourceInstance.new(
+ return AST::ASTArray.new(
:file => tempfile,
diff --git a/test/lib/puppettest/support/assertions.rb b/test/lib/puppettest/support/assertions.rb
index 7f326b119..31fa3f1da 100644
--- a/test/lib/puppettest/support/assertions.rb
+++ b/test/lib/puppettest/support/assertions.rb
@@ -1,8 +1,6 @@
-require 'puppettest'
require 'puppettest/support/utils'
require 'fileutils'
-
module PuppetTest
include PuppetTest::Support::Utils
def assert_logged(level, regex, msg = nil)
diff --git a/test/lib/puppettest/support/utils.rb b/test/lib/puppettest/support/utils.rb
index edc81d3d6..e022f123c 100644
--- a/test/lib/puppettest/support/utils.rb
+++ b/test/lib/puppettest/support/utils.rb
@@ -1,5 +1,3 @@
-require 'puppettest'
-
module PuppetTest::Support
end
module PuppetTest::Support::Utils
@@ -7,6 +5,30 @@ module PuppetTest::Support::Utils
Puppet.warning "#{type}: #{ObjectSpace.each_object(type) { |o| }}"
end
+ def basedir(*list)
+ unless defined? @@basedir
+ Dir.chdir(File.dirname(__FILE__)) do
+ @@basedir = File.dirname(File.dirname(File.dirname(File.dirname(Dir.getwd))))
+ end
+ end
+ if list.empty?
+ @@basedir
+ else
+ File.join(@@basedir, *list)
+ end
+ end
+
+ def fakedata(dir,pat='*')
+ glob = "#{basedir}/test/#{dir}/#{pat}"
+ files = Dir.glob(glob,File::FNM_PATHNAME)
+ raise Puppet::DevError, "No fakedata matching #{glob}" if files.empty?
+ files
+ end
+
+ def datadir(*list)
+ File.join(basedir, "test", "data", *list)
+ end
+
#
# TODO: I think this method needs to be renamed to something a little more
# explanatory.
@@ -38,10 +60,6 @@ module PuppetTest::Support::Utils
config
end
- # stop any services that might be hanging around
- def stopservices
- end
-
# TODO: rewrite this to use the 'etc' module.
# Define a variable that contains the name of my user.
@@ -84,7 +102,7 @@ module PuppetTest::Support::Utils
end
def fakefile(name)
- ary = [PuppetTest.basedir, "test"]
+ ary = [basedir, "test"]
ary += name.split("/")
file = File.join(ary)
raise Puppet::DevError, "No fakedata file #{file}" unless FileTest.exists?(file)
@@ -140,16 +158,3 @@ module PuppetTest::Support::Utils
config
end
end
-
-module PuppetTest
- include PuppetTest::Support::Utils
-
- def fakedata(dir,pat='*')
- glob = "#{basedir}/test/#{dir}/#{pat}"
- files = Dir.glob(glob,File::FNM_PATHNAME)
- raise Puppet::DevError, "No fakedata matching #{glob}" if files.empty?
- files
- end
- module_function :fakedata
-
-end
diff --git a/test/other/provider.rb b/test/other/provider.rb
index 052d7a0d0..a539ee5a7 100755
--- a/test/other/provider.rb
+++ b/test/other/provider.rb
@@ -70,24 +70,13 @@ class TestImpl < Test::Unit::TestCase
child = @type.provide("child", :parent => parent.name) {}
}
- assert_nothing_raised {
- child.commands :which => "which"
- }
-
- assert(child.command(:which), "Did not find 'which' command")
-
- assert(child.command(:which) =~ /^\//,
- "Command did not become fully qualified")
- assert(FileTest.exists?(child.command(:which)),
- "Did not find actual 'which' binary")
-
assert_raise(Puppet::DevError) do
child.command(:nosuchcommand)
end
# Now create a parent command
assert_nothing_raised {
- parent.commands :sh => Puppet::Util.binary('sh')
+ parent.commands :sh => Puppet::Util.which('sh')
}
assert(parent.command(:sh), "Did not find 'sh' command")
diff --git a/test/other/report.rb b/test/other/report.rb
index b3b41da19..8a909b41c 100755
--- a/test/other/report.rb
+++ b/test/other/report.rb
@@ -35,10 +35,7 @@ class TestReports < Test::Unit::TestCase
config.retrieval_duration = 0.001
trans = config.apply
- report = Puppet::Transaction::Report.new
- trans.add_metrics_to_report(report)
-
- report
+ trans.generate_report
end
# Make sure we can use reports as log destinations.
@@ -95,7 +92,7 @@ class TestReports < Test::Unit::TestCase
assert_equal(yaml, File.read(file), "File did not get written")
end
- if Puppet.features.rrd?
+ if Puppet.features.rrd? || Puppet.features.rrd_legacy?
def test_rrdgraph_report
Puppet.settings.use(:main, :metrics)
report = mkreport
diff --git a/test/puppet/tc_suidmanager.rb b/test/puppet/tc_suidmanager.rb
index 449f2aef5..eeb56f2c9 100755
--- a/test/puppet/tc_suidmanager.rb
+++ b/test/puppet/tc_suidmanager.rb
@@ -80,20 +80,11 @@ class TestSUIDManager < Test::Unit::TestCase
warn "Cannot run this test on ruby < 1.8.4"
else
set_exit_status!
-
-
- Puppet::Util.expects(:execute).with(
- 'yay',
- { :failonfail => false,
- :uid => @user.uid,
-
- :gid => @user.gid }
- ).returns('output')
-
-
- output = Puppet::Util::SUIDManager.run_and_capture 'yay',
- @user.uid,
- @user.gid
+ Puppet::Util.
+ expects(:execute).
+ with('yay',:combine => true, :failonfail => false, :uid => @user.uid, :gid => @user.gid).
+ returns('output')
+ output = Puppet::Util::SUIDManager.run_and_capture 'yay', @user.uid, @user.gid
assert_equal 'output', output.first
assert_kind_of Process::Status, output.last
diff --git a/test/rails/railsparameter.rb b/test/rails/railsparameter.rb
index 9f6fc1c1e..77ce33912 100755
--- a/test/rails/railsparameter.rb
+++ b/test/rails/railsparameter.rb
@@ -22,7 +22,7 @@ class TestRailsParameter < Test::Unit::TestCase
# Now create a source
parser = mkparser
- source = parser.newclass "myclass"
+ source = parser.known_resource_types.add Puppet::Resource::Type.new(:hostclass, "myclass")
host = Puppet::Rails::Host.new(:name => "myhost")
diff --git a/test/ral/manager/attributes.rb b/test/ral/manager/attributes.rb
index 74a4d0708..6d0284d9e 100755
--- a/test/ral/manager/attributes.rb
+++ b/test/ral/manager/attributes.rb
@@ -229,7 +229,10 @@ class TestTypeAttributes < Test::Unit::TestCase
end
yes.each { |a| assert(resource.should(a), "Did not get value for #{a} in #{prov.name}") }
no.each do |a|
- # These may or may not get passed to the provider. We shouldn't care.
+ assert_nil(resource.should(a), "Got value for unsupported %s in %s" % [a, prov.name])
+ if Puppet::Util::Log.sendlevel?(:info)
+ assert(@logs.find { |l| l.message =~ /not managing attribute #{a}/ and l.level == :info }, "No warning about failed %s" % a)
+ end
end
@logs.clear
diff --git a/test/ral/manager/type.rb b/test/ral/manager/type.rb
index 7df643005..145877722 100755
--- a/test/ral/manager/type.rb
+++ b/test/ral/manager/type.rb
@@ -276,7 +276,7 @@ class TestType < Test::Unit::TestCase
def test_isomorphic_names
catalog = mk_catalog
# First do execs, since they're not isomorphic.
- echo = Puppet::Util.binary "echo"
+ echo = Puppet::Util.which "echo"
exec1 = exec2 = nil
assert_nothing_raised do
diff --git a/test/ral/providers/cron/crontab.rb b/test/ral/providers/cron/crontab.rb
index 0c87a5bba..be2af1e16 100755
--- a/test/ral/providers/cron/crontab.rb
+++ b/test/ral/providers/cron/crontab.rb
@@ -97,7 +97,10 @@ class TestCronParsedProvider < Test::Unit::TestCase
# Then do them all at once.
records = []
text = ""
- sample_records.each do |name, options|
+ # Sort sample_records so that the :empty entry does not come last
+ # (if it does, the test will fail because the empty last line will
+ # be ignored)
+ sample_records.sort { |a, b| a.first.to_s <=> b.first.to_s }.each do |name, options|
records << options[:record]
text += options[:text] + "\n"
end
diff --git a/test/ral/providers/host/parsed.rb b/test/ral/providers/host/parsed.rb
index c2367d566..955edd5d3 100755
--- a/test/ral/providers/host/parsed.rb
+++ b/test/ral/providers/host/parsed.rb
@@ -67,7 +67,8 @@ class TestParsedHostProvider < Test::Unit::TestCase
# Make sure we convert both directlys correctly using a simple host.
def test_basic_isomorphism
- hash = {:record_type => :parsed, :name => "myhost", :ip => "192.168.43.56", :host_aliases => %w{another host}}
+ hash = {:record_type => :parsed, :name => "myhost", :ip => "192.168.43.56", :host_aliases => %w{another host},
+ :comment => ''}
str = nil
assert_nothing_raised do
@@ -105,11 +106,13 @@ class TestParsedHostProvider < Test::Unit::TestCase
[
{:record_type => :comment, :line => "# comment one"},
{:record_type => :blank, :line => ""},
- {:record_type => :parsed, :name => "myhost", :ip => "192.168.43.56", :host_aliases => %w{another host}},
+ {:record_type => :parsed, :name => "myhost", :ip => "192.168.43.56", :host_aliases => %w{another host},
+ :comment => ''},
{:record_type => :blank, :line => " "},
{:record_type => :comment, :line => "# another comment"},
- {:record_type => :parsed, :name => "anotherhost", :ip => "192.168.43.57", :host_aliases => []}
+ {:record_type => :parsed, :name => "anotherhost", :ip => "192.168.43.57", :host_aliases => [],
+ :comment => ''}
], instances)
newtext = nil
diff --git a/test/ral/providers/provider.rb b/test/ral/providers/provider.rb
index cb0b2a19e..f46e03f82 100755
--- a/test/ral/providers/provider.rb
+++ b/test/ral/providers/provider.rb
@@ -9,7 +9,7 @@ class TestProvider < Test::Unit::TestCase
include PuppetTest
def echo
- echo = Puppet::Util.binary("echo")
+ echo = Puppet::Util.which("echo")
raise "Could not find 'echo' binary; cannot complete test" unless echo
@@ -95,7 +95,7 @@ class TestProvider < Test::Unit::TestCase
provider.commands :testing => "/no/such/path"
- provider.stubs(:binary).returns "/no/such/path"
+ provider.stubs(:which).returns "/no/such/path"
provider.command(:testing)
assert_equal("/no/such/path", provider.command(:testing), "Did not return correct binary path")
@@ -187,7 +187,7 @@ class TestProvider < Test::Unit::TestCase
dir = tstdir
file = File.join(dir, "mycmd")
- sh = Puppet::Util.binary("sh")
+ sh = Puppet::Util.which("sh")
File.open(file, "w") { |f|
f.puts %{#!#{sh}
echo A Failure >&2
diff --git a/test/util/metrics.rb b/test/util/metrics.rb
index 1fd57f2f1..82e792d0b 100755
--- a/test/util/metrics.rb
+++ b/test/util/metrics.rb
@@ -8,7 +8,7 @@ require 'puppettest'
require 'puppet/type'
class TestMetric < PuppetTest::TestCase
- confine "Missing RRDtool library" => Puppet.features.rrd?
+ confine "Missing RRDtool library" => (Puppet.features.rrd? || Puppet.features.rrd_legacy?)
include PuppetTest
def gendata
@@ -43,7 +43,7 @@ class TestMetric < PuppetTest::TestCase
def rundata(report, time)
assert_nothing_raised {
gendata.each do |name, data|
- report.newmetric(name, data)
+ report.add_metric(name, data)
end
report.metrics.each { |n, m| m.store(time) }
}