A practical approach to chef (Using Vagrant)
Composed by Balaji Vajjala / @bvajjala
"What we have to learn to do, we learn by doing." - Aristotle, Greek philosopher
Today we are SURE that we made the right decision, choosing Tikal
Guy Ben-Porat, Development Manager “ExLibris”
http://prezi.com/8zwcr5df9eno/chef-intro-chef-server-workflow
Lets go through this prezi together
We know what !
are
Let's write a simple cookbook ...
*git bash is also used in order to ssh
into a vagrant image on windows
Write a cookbook
Omnibus
installer will "figure out" your OS and install it
In
addition to an embedded version of chef
On *nix / MacOSX
curl -L https://www.opscode.com/chef/install.sh | sudo bash
/opt/opscode/...
On Windows [Download link]
https://opscode-omnibus-packages.s3.amazonaws.com/windows/2008r2/x86_64/chef-client-11.8.0-1.windows.msi
c:\opscode
We don't really need knife (at this stage), so we will just provide it with the defaults
Execute & Accept all defaults:
knife configure
WARNING: No knife configuration file found
Where should I put the config file? [/home/hagzag/.chef/knife.rb] y
Please enter the chef server URL: [https://:443]
Please enter an existing username or clientname for the API: [hagzag]
Please enter the validation clientname: [chef-validator]
Please enter the location of the validation key: [/etc/chef-server/chef-validator.pem]
...
*****
Configuration file written to /home/hagzag/.chef/knife.rb
knife cookbook create ntp -o .
We get:
attributes/
definitions/
files/
libraries/
metadata.rb
providers/
README.rdoc
recipes/
resources/
templates/
Shortcut => Get from git:
git clone git@github.com:tikalk-cookbooks/ntp-intro.git
git checkout -b 0.1.0
vim cookbooks/ntp/recipes/default.rb
package "ntp" do
action [:install]
end
yum install ntp
template "/etc/ntp.conf" do
source "ntp.conf.erb"
variables( :ntp_server => "time.nist.gov" )
notifies :restart, "service[ntpd]"
end
vim cookbooks/ntp/templates/default/ntp.conf.erb
restrict default kod nomodify notrap nopeer noquery
restrict -6 default kod nomodify notrap nopeer noquery
restrict <IP_ADDRESS>
restrict -6 ::1
server <%= @ntp_server %>
server <IP_ADDRESS> # local clock
driftfile /var/lib/ntp/drift
keys /etc/ntp/keys
https://raw.github.com/tikalk-cookbooks/ntp-intro/0.1.0/templates/default/ntp.conf.erb
Similar to manually editing the /etc/ntp.conf
service "ntpd" do
action [:enable,:start]
end
chkconfig ntp on
What have we here ?
If yours differs - compare with:
https://github.com/tikalk-cookbooks/ntp-intro
use tag 0.1.0
Sharpen your knives => Improve the cookbook
vim ntp/attributes/default.rb
Use a case statement to differentiate between platforms
case x
when 1,2,3
puts "1, 2, or 3"
when 10
puts "10"
else
puts "Some other number"
end
Rubydoc case statement
case platform
when "redhat","centos","fedora","scientific"
default[:ntp][:service] = "ntpd"
when "ubuntu","debian"
default[:ntp][:service] = "ntp"
else
default[:ntp][:service] = "ntpd"
end
So now according to the
node['platform'] which chef "knows" during the chef run the service name will be
defined accordingly !
+ provide a default of
"ntpd" !
[1of3] on
github tag 0.1.1
In order to support more than 1 server
In this example add:
0.pool.ntp.org, 1.pool.ntp.org, 2.pool.ntp.org, 3.pool.ntp.org
We have 4 servers in out attributes file (but we might have 5 tomorrow ...)
0.pool.ntp.org, 1.pool.ntp.org, 2.pool.ntp.org, 3.pool.ntp.org
Our template file will is an erb file + loop over the servers array using the .each method
default[:ntp][:servers] = ["0.pool.ntp.org", "1.pool.ntp.org", "2.pool.ntp.org", "3.pool.ntp.org"]
# Generated by Chef for <%= node[:fqdn] %>
# node[:fqdn] = ohai data collected on node !
# Local modifications will be overwritten.
restrict -6 ::1
#server <%= @ntp_server %>
<% node[:ntp][:servers].each do |ntpsrv| -%>
server <%= ntpsrv %> iburst
restrict <%= ntpsrv %> nomodify notrap noquery
<% end -%>
# Generated by Chef for <%= node[:fqdn] %>
# node[:fqdn] = ohai data collected on node !
# Local modifications will be overwritten.
Re-arrange recipe
package "ntp" do
action [:install]
end
The package name is similar on all platforms
so there is no real change here ...
[3of3] on github tag 0.1.1
service node[:ntp][:service] do
service_name node[:ntp][:service]
action [:enable,:start,:restart]
end
Service declaration - the service name and it's implied location
/etc/init.d/ntp or /etc/init.d/ntpd
based on: service =>node[:ntp][:service]
[3of3] on
github tag 0.1.1
template "/etc/ntp.conf" do
source "ntp.conf.erb"
owner "root"
group "root"
mode 0644
notifies :restart, resources(:service => node[:ntp][:service])
end
This part is also the same as before just with a shift in it's location
[3of3] on
github tag 0.1.1
package "ntp" do
action [:install]
end
service node[:ntp][:service] do
service_name node[:ntp][:service]
action [:enable,:start,:restart]
end
template "/etc/ntp.conf" do
source "ntp.conf.erb"
owner "root"
group "root"
mode 0644
notifies :restart, resources(:service => node[:ntp][:service])
end
The service name comes
before the template which notifies
:service =>node[:ntp][:service]
[3of3] on
github tag 0.1.1
What have we here ?
If yours differs - compare with:
https://github.com/tikalk-cookbooks/ntp-intro
use tag 0.1.1
We want to test this cookbook & we need a server to test this on right ?
A good place to introduce
Use opscode's @ https://github.com/opscode-cookbooks/ntp
This one is just for play ;)
Vagrant provides easy to configure, reproducible, and portable work environments built on top of industry-standard technology and controlled by a single consistent work-flow to help maximize the productivity and flexibility of you and your team.
To achieve its magic, Vagrant stands on the shoulders of giants. Machines are provisioned on top of VirtualBox , VMware , AWS, or any other provider. Then, industry-standard provisioning tools such as shell scripts , Chef , or Puppet, can be used to automatically install and configure software on the machine.
Off-line copy is available with workshop materials
cd ~/My_Cool_Project
vagrant init My_Cool_Project http://shonky.info/centos64.box
So now you have a skeleton [ with good remarks ] of a Vagrantfile
Define a box & box url
config.vm.box = "CentOS 6.4 x86_64"
config.vm.box_url = "http://bit.ly/1aNaifu"
config.vm.network "private_network", ip: "<IP_ADDRESS>"
config.vm.network "public_network # will get DHCP from your LAN
NAME = "MyAwesomeVM"
config.vm.hostname = "#{NAME}"
Define your provisioner: shell/chef/puppet
shell example:
config.vm.provision :shell, :path => File.expand_path("../bootstrap.sh", __FILE__)
config.vm.provision :chef_solo do |chef|
chef.cookbooks_path = ["cookbooks", "site-cookbooks"]
chef.roles_path = ["roles"]
chef.log_level = ENV['CHEF_LOG'] ? ENV['CHEF_LOG'].to_sym : :info
chef.add_role "web"
# chef.add_recipe "nginx" => marked out but you can also add recipes ...
end
More about provisioner(s) here
Define your provider: virtualbox, aws, vmware fusion
Customize you virtualbox machine:
config.vm.provider :virtualbox do |vb|
# Don't boot with headless mode
# vb.gui = true
vb.customize [ "modifyvm", :id, "--memory", "512"]
vb.name = "#{NAME}"
end
Add some "juice" to your machine [if you need it]
More about providers here
First try virtual box unless --provider is specified
if --provider=aws ignore all vb customizations (or networking for that matter)
Look for a provisioner Chef / Shell / Salt / Other ..., more then one great !
config.vm.provision "shell",
inline: "[[ `which chef-solo` ]] || curl -L https://www.opscode.com/chef/install.sh | sudo bash"
config.vm.provision :chef_solo do |chef|
chef.cookbooks_path = ["cookbooks", "site-cookbooks"]
chef.roles_path = ["roles"]
chef.log_level = ENV['CHEF_LOG'] ? ENV['CHEF_LOG'].to_sym : :info
chef.add_role "web"
end
Work in the cloud - AWS example:
config.vm.provider :aws do |aws, override|
# Add aws tags
aws.tags = {
'vagrant' => 'true',
'environment' => 'devenv'
}
aws.access_key_id = ENV['AWS_ACCESS_KEY']
aws.secret_access_key = ENV['AWS_SECRET_KEY']
aws.keypair_name = "A_VAGRANT_KEYPAIR"
aws.security_groups = [ "MySecurotyGroupWithSSHOpen" ]
aws.region = "us-west-2"
aws.ami = "ami-myami"
end
In the example above set the AWS_ACCESS_KEY & AWS_SECRET_KEY
and executevagrant up --provider=aws
For example:
Easy as:
vagrant plugin install [plugin-name]
Use installer suitable for your platform from:
Virtualbox site
Offline copy is available with workshop materials
Offline copy is available with workshop materials
No extra configuration needed (at this point ...)
cd path/to/project
vagrant init
You should get a clean vagrant file
Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|
config.vm.box = "CentOS 6.5 x86_64"
config.vm.box_url = "http://bit.ly/1aNaifu"
In order to save time I have provided an offline copy of this box:
Add it by excuting the command Vagrant box add like so:
vagrant box add "CentOS 6.5 x86_64" file:///path/to/vbox/image-bundle.box
This command will add to your home folder ~/.vagrnat/boxes/CentOS 6.5 x86_64
vagrant box add "centos65-x86_65" /Volumes/TOSHIBADISK/Vagrant-Boxes/centos65-x86_64-20131205.box
Downloading box from URL: file:/Volumes/TOSHIBADISK/Vagrant-Boxes/centos65-x86_64-20131205.box
Extracting box...te: 245M/s, Estimated time remaining: --:--:--)
Successfully added box 'centos65-x86_65' with provider 'virtualbox'!
cd path/to/project
vagrant up
Bringing machine 'default' up with 'virtualbox' provider...
[default] Importing base box 'CentOS 6.5 x86_64'...
[default] Matching MAC address for NAT networking...
[default] Setting the name of the VM...
[default] Clearing any previously set forwarded ports...
[default] Clearing any previously set network interfaces...
[default] Preparing network interfaces based on configuration...
[default] Forwarding ports...
[default] -- 22 => 2222 (adapter 1)
[default] Booting VM...
[default] Waiting for machine to boot. This may take a few minutes...
DL is deprecated, please use Fiddle
[default] Machine booted and ready!
[default] Mounting shared folders...
[default] -- /vagrant
Open Virtual box Manager ans see you have a box there, Then desory it ...
vagrant destroy -f
-f used for force ...
config.vm.provider "virtualbox" do |vb|
vb.gui = true
vb.customize ["modifyvm", :id, "--memory", 512]
vb.customize ["modifyvm", :id, "--ioapic", "on", "--cpus", 1]
end
Note the vb.gui = true option here,
in this case I would like the Virtualbox GUI to startup !
Is now
We cloud choose a vagran box with chef client installed ..., but where is the fun in that ?
config.vm.provision "shell",
inline: "[[ `which chef-solo` ]] || curl -L https://www.opscode.com/chef/install.sh | sudo bash"
Use chef to install our ntp cookbook from ex02
config.vm.provision :chef_solo do |chef|
chef.cookbooks_path = ["cookbooks" ]
chef.add_recipe "ntp"
end
Copy the ntp cookbook in to a directory called cookbooks
mkdir ./cookbooks
cp -R ntp cookbooks
Execute the vagrant provision
$ vagrant provision
[default] Running provisioner: shell...
[default] Running: inline script
[default] Running provisioner: chef_solo...
Generating chef JSON and uploading...
Vagrant is trigerring chef-solo ...
Running chef-solo...
[] INFO: Forking chef instance to converge...
[] INFO: *** Chef 11.10.0 ***
[] INFO: Chef-client pid: 1655
[] INFO: Setting the run_list to ["recipe[ntp]"] from JSON
[] INFO: Run List is [recipe[ntp]]
[] INFO: Run List expands to [ntp]
[] INFO: Starting Chef Run for vagrant-centos65
[] INFO: Running start handlers
[] INFO: Start handlers complete.
end of "compliation - begining of converge (execution)"
[] INFO: package[ntp] installing ntp-4.2.6p5-1.el6.centos from base repository
[] INFO: service[ntpd] enabled
[] INFO: service[ntpd] started
[] INFO: service[ntpd] restarted
[] INFO: template[/etc/ntp.conf] backed up to /var/chef/backup/etc/ntp.conf.chef-20130913144203.354529
[] INFO: template[/etc/ntp.conf] updated file contents/etc/ntp.conf
[] INFO: template[/etc/ntp.conf] sending restart actionto service[ntpd] (delayed)
[] INFO: service[ntpd] restarted
[] INFO: Chef Run complete in 87.127895456 seconds
[] INFO: Running report handlers
[] INFO: Report handlers complete
Connect to the machine
vagrant ssh
Is the rpm installed ?
rpm -qa | grep ntp
[vagrant@vagrant-centos65 ~]$ rpm -qa | grep ntp
ntpdate-4.2.6p5-1.el6.centos.x86_64
ntp-4.2.6p5-1.el6.centos.x86_64
Examine /etc/ntp.conf
[vagrant@vagrant-centos65 ~]$ cat /etc/ntp.conf
# Generated by Chef for
# node[:fqdn] = ohai data collected on node !
# Local modifications will be overwritten.
restrict -6 ::1
#server
server 0.pool.ntp.org iburst
restrict 0.pool.ntp.org nomodify notrap noquery
server 1.pool.ntp.org iburst
restrict 1.pool.ntp.org nomodify notrap noquery
server 2.pool.ntp.org iburst
restrict 2.pool.ntp.org nomodify notrap noquery
server 3.pool.ntp.org iburst
restrict 3.pool.ntp.org nomodify notrap noquery
restrict default kod nomodify notrap nopeer noquery
restrict -6 default kod nomodify notrap nopeer noquery
restrict <IP_ADDRESS>
server <IP_ADDRESS> # local clock
driftfile /var/lib/ntp/drift
keys /etc/ntp/keys
Planned for next session
"What we have to learn to do, we learn by doing." - Aristotle, Greek philosopher
If you followed so far you should already have it all ...
knife cookbook create web
vim web/metadata.rb
depends 'nginx'
We will learn later on how this line
makes a difference ...
default['nginx']['port'] = '4000'
default['nginx']['listen_ports'] = %w[80, #{node['nginx']['port']}]
default['nginx']['vhost']['basedir'] = '/var/www/nginx'
default['nginx']['vhost']['demo'] = "#{node['nginx']['vhost']['basedir']}/demo"
use an attribute, for the directory name !
include_recipe "nginx"
#Create the runtime directory - using directory resource [ chef core resource provider ]
directory node[:nginx][:vhost][:demo] do
owner 'nginx'
group 'nginx'
recursive true
end
Use a template file ...
template "/etc/nginx/sites-available/demo-site" do # the "default" sites-available dir under nginx's run folder
source "demo-site.erb" # the template file to use
owner "root" # Owner of the file
group "root" # Group of the file
mode 0644 # Mode
notifies :restart, "service[nginx]" # Restart nginx upon configuration
end
Use a template file ...
# nginx virtual host template configured by chef on <%= node[:fqdn] %>
server {
listen <%= node[:nginx][:port] %> default;
server_name <%= node[:fqdn] %>;
root <%= node[:nginx][:vhost][:demo] %>;
}
Will evaluate to:
# nginx virtual host template configured by chef on chef-solo-demo
server {
listen 4000 default;
server_name chef-solo-demo;
root /var/www/nginx/demo;
}
# Create a website from template ...
template "#{node[:nginx][:vhost][:demo]}/index.html" do #index file location
source "index.html.erb" # now user
owner "nginx" # is nginx [ the user running the nginx server !]
group "nginx"
end

Demo site running on nginx <%= node[:fqdn] %>

And your'e a full stack developer !!!

nginx_site "demo-site" do # "nginx_ensite" see :: https://github.com/perusio/nginx_ensite
enable :true
notifies :restart, "service[nginx]"
end
# disable iptables ! => just for this demo :)
include_recipe "iptables::disabled"
name 'web'
maintainer 'Tikal Knowledge LTD'
maintainer_email<EMAIL_ADDRESS>license 'Apache 2.0'
description 'Installs/Configures web'
long_description IO.read(File.join(File.dirname(__FILE__), 'README.md'))
version '0.1.0'
depends 'nginx'
depends 'iptables' # opend nginx port(S)
depends 'nginx'
depends 'iptables' # opend nginx port(S)
And know how to get these cookbooks - right ?
echo "cookbook 'nginx'" >> /path/to/Cheffile
Or
echo "cookbook 'nginx'" >> /path/to/Berksfile
Usually will find Berkshelf with a chef server environment and librarian with chef-solo
gem install berkshelf
Define your dependencies
site :opscode
cookbook 'mysql'
cookbook 'nginx', '~> 0.101.5'
cookbook 'web', path: '~/cookbooks/web'
cookbook 'lvm', git: 'git://github.com/opscode-cookbooks/lvm.git'
gem install librarian-chef
Define your dependencies
site "http://community.opscode.com/api/v1"
cookbook "ntp"
cookbook "timezone", "0.0.1"
cookbook "rvm",
:git => "https://github.com/fnichol/chef-rvm",
:ref => "v0.7.1"
cookbook "cloudera",
:path => "vendor/cookbooks/cloudera-cookbook"
Test our `web` cookbook
In order to do that we need:
You can use the Vagrant-box from last exercise (to save time)
cd path/to/project
vagrant init
You should get a clean vagrant file
Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|
config.vm.box = "CentOS 6.5 x86_64"
config.vm.box_url = "http://bit.ly/1aNaifu"
In order to save time I have provided an offline copy of this box:
Add it by excuting the command Vagrant box add like so:
vagrant box add "CentOS 6.5 x86_64" file:///path/to/vbox/image-bundle.box
This command will add to your home folder ~/.vagrnat/boxes/CentOS 6.5 x86_64
vagrant box add "centos65-x86_65" /Volumes/TOSHIBADISK/Vagrant-Boxes/centos65-x86_64-20131205.box
Downloading box from URL: file:/Volumes/TOSHIBADISK/Vagrant-Boxes/centos65-x86_64-20131205.box
Extracting box...te: 245M/s, Estimated time remaining: --:--:--)
Successfully added box 'centos65-x86_65' with provider 'virtualbox'!
librarian-chef init
create Cheffile
Add your dependency
vim Cheffile
cookbook 'nginx'
cookbook 'iptables'
librarian-chef config path ./chef/cookbooks --local
this will create .librarian/chef/config
cat .librarian/chef/config
---
LIBRARIAN_CHEF_PATH: ./chef/cookbooks
3 options
config.vm.provision "shell",
inline: "[[ `which chef-solo` ]] || curl -L https://www.opscode.com/chef/install.sh | sudo bash"
$ vagrant plugin install vagrant-omnibus
Configure vagrant to do it ...
Vagrant.configure("2") do |config|
config.omnibus.chef_version = :latest # or version: "11.4.0"
...
end
config.vm.provision :chef_solo do |chef|
chef.cookbooks_path = ["chef/cookbooks", "chef/site-cookbooks"]
chef.log_level = ENV['CHEF_LOG'] ? ENV['CHEF_LOG'].to_sym : :info
chef.add_role "web"
# You may also specify custom JSON attributes:
chef.json = { some_key: "value" }
end
please note:
you can control anything you can control in solo.rb ...
proxy configuration, log level, roles, attributes etc .
#Proxy support for chef-solo, else i.e. remote_file externally will do worklibr
# chef.http_proxy = ""
# chef.https_proxy = ""
# chef.no_proxy = ""
# chef.log_level = ENV['CHEF_LOG'] ? ENV['CHEF_LOG'].to_sym : :debug
place the web cookbook into the ./chef/site-cookbooks directory
mkdir ./chef/site-cookbooks
cp -R path/to/cookbook/web ./chef/site-cookbooks/
├── .librarian
│ └── chef
├── Cheffile
├── Vagrantfile
├── chef
│ └── site-cookbooks
│ └── web
we also want to add chef/cookbooks and tmp to .gitignore
so we don't submit dependencies to source control
echo -e "chef/cookbooks\ntmp\n" > .gitignore
librarian-chef install
*if you are using vagrant-librarian-chef skip this step
librarian-chef output:
Installing apt (2.3.8)
Installing rsyslog (1.11.0)
Installing bluepill (2.3.1)
Installing build-essential (1.4.2)
Installing iptables (0.12.0)
Installing ohai (1.1.12)
Installing yum (3.1.0)
Installing yum-epel (0.3.4)
Installing runit (1.5.8)
Installing nginx (2.2.2)
ls ./chef/cookbooks/
apt bluepill build-essential nginx ohai rsyslog runit yum yum-epel
Where did all that come from ?
Take a look @: ./chef/coobkooks/nginx/metadata.rb
vagrant up
Vagrant output -> standard stuff ...
vagrant provision
[default] Installing Chef cookbooks with Librarian-Chef...
[default] The cookbook path '/Users/c5191707/Projects/tikal/chef_workshop/excersizes/ex05/roles' doesn't exist. Ignoring...
[default] Running provisioner: shell...
[default] Running: inline script
[default] Running provisioner: chef_solo...
Generating chef JSON and uploading...
Running chef-solo...
[] INFO: Forking chef instance to converge...
[] INFO: *** Chef 11.10.4 ***
[] INFO: Chef-client pid: 3042
[] INFO: Setting the run_list to ["recipe[web]"] from JSON
[] INFO: Run List is [recipe[web]]
[] INFO: Run List expands to [web]
[] INFO: Starting Chef Run for ex05
[] INFO: Running start handlers
[] INFO: Start handlers complete.
[] INFO: ohai plugins will be at: /etc/chef/ohai_plugins
[] INFO: ohai[custom_plugins] reloaded
when using the vagrant librarian-chef plugin you will see:
[default] Installing Chef cookbooks with Librarian-Chef...
Vagrant output -> chef converge
[] INFO: package[nginx] installing nginx-1.0.15-5.el6 from epel repository
[] INFO: package[nginx] sending reload action to ohai[reload_nginx] (immediate)
[] INFO: ohai[reload_nginx] reloaded
[] INFO: service[nginx] enabled
[] INFO: directory[/var/log/nginx] mode changed to 755
[] INFO: directory[/etc/nginx/sites-available] created directory /etc/nginx/sites-available
[] INFO: directory[/etc/nginx/sites-available] owner changed to 0
[] INFO: directory[/etc/nginx/sites-available] group changed to 0
[] INFO: directory[/etc/nginx/sites-available] mode changed to 755
[] INFO: directory[/etc/nginx/sites-enabled] created directory /etc/nginx/sites-enabled
[] INFO: directory[/etc/nginx/sites-enabled] owner changed to 0
[] INFO: directory[/etc/nginx/sites-enabled] group changed to 0
[] INFO: directory[/etc/nginx/sites-enabled] mode changed to 755
[] INFO: execute[nxensite default] ran successfully
[] INFO: execute[nxensite default] not queuing delayed action reload on service[nginx] (delayed), as it's already been queued
[] INFO: service[nginx] started
[] INFO: directory[/var/www/nginx/demo] created directory /var/www/nginx/demo
[] INFO: directory[/var/www/nginx/demo] owner changed to 497
[] INFO: directory[/var/www/nginx/demo] group changed to 497
Note the "(delayed)" in the service restart
Notify immediately / delayed:
By default, notifications are :delayed, that is they are queued up as they are triggered, and then executed at the very end of a chef-client run. To run an action immediately, use :immediately:
[] INFO: template[/etc/nginx/sites-available/demo-site] created file /etc/nginx/sites-available/demo-site
[] INFO: template[/etc/nginx/sites-available/demo-site] updated file contents /etc/nginx/sites-available/demo-site
[] INFO: template[/etc/nginx/sites-available/demo-site] owner changed to 0
[] INFO: template[/etc/nginx/sites-available/demo-site] group changed to 0
[] INFO: template[/etc/nginx/sites-available/demo-site] mode changed to 644
[] INFO: template[/var/www/nginx/demo/index.html] created file /var/www/nginx/demo/index.html
[] INFO: template[/var/www/nginx/demo/index.html] updated file contents /var/www/nginx/demo/index.html
[] INFO: template[/var/www/nginx/demo/index.html] owner changed to 497
[] INFO: template[/var/www/nginx/demo/index.html] group changed to 497
[] INFO: execute[nxensite demo-site] ran successfully
[] INFO: execute[nxensite demo-site] not queuing delayed action reload on service[nginx] (delayed), as it's already been queued
[] INFO: service[iptables] disabled
[] INFO: template[nginx.conf] sending reload action to service[nginx] (delayed)
[] INFO: service[nginx] reloaded
[] INFO: template[/etc/nginx/sites-available/demo-site] sending restart action to service[nginx] (delayed)
[] INFO: service[nginx] restarted
[] INFO: Chef Run complete in 28.387247187 seconds
[] INFO: Running report handlers
[] INFO: Report handlers complete
Disabled iptables (just in case ...)
Reload nginx service
The long answer is it depends ...
Worth noting
Think of chef solo as the entire "chef-server" in a repository
.
├── README.md
├── centos_node
│ ├── Vagrantfile
│ └── bootstrap.sh
├── chef-server
│ ├── Vagrantfile
│ ├── bootstrap.sh
│ └── knife-config.sh
└── ubutnu_node
├── Vagrantfile
└── bootstrap.sh
Available @ chef_workshop
on Github
[ see chef_server_rotute directory ]
We will have a chef server + 2 nodes - 1 centos, 1 ubuntu all on VirtualBox
git clone git://github.com/opscode/chef-repo.git
Provides a directory layout to be used in conjunction with knife to:
pull down / upload cookbooks
Create nodes / roles / environments etc
see example in this workshop:
install from master using chef-solo ...
cd chef_workshop/chef_server_route/chef_server
vagrant up
In 3-5 minuets you have a chef server installed and chef_repo cloned under the root users directory !
The "magic" is in the ./bootstrap.sh & ./knife-config.sh files
# create required bootstrap dirs/files
mkdir -p /var/chef/cache /var/chef/cookbooks/chef-server
# pull down this chef-server cookbook
wget -qO- https://github.com/opscode-cookbooks/chef-server/archive/master.tar.gz | tar xvzC /var/chef/cookbooks/chef-server --strip-components=1
# install chef server with chef solo
chef-solo -o 'recipe[chef-server::default]'
Download the master bundle in to chef's
default directories and invoke chef-solo ...
In this workshop the chef workstation will reside on our chef server
#!/bin/bash
[[ -z "$DEBUG" ]] && set -x || set -e
# we need git on the image to set the cookbook path in knife.rb
[[ `which git` ]] || apt-get -y install git
# clone the repo ... [myself :)]
test -d /root/chef_repo || git clone https://github.com/tikalk-cookbooks/chef-intro-repo.git /root/chef_repo
cd /etc/bash_completion.d/
test -f knife.sh || wget https://gist.github.com/raw/1050685/23624fff40694d5ed5f55089774d13b1937bb37f/knife.sh
install git, checkout the chef-repo for this example
Manual instructions how to configure knife ...*
knife configure --admin-client-name admin --admin-client-key \
/etc/chef-server/admin.pem -i -r /root/chef_repo/ \
--validation-client-name chef-validator --validation-key \
/etc/chef-server/chef-validator.pem
This is relevant to our example, in most cases you will
knife configure -i
In a "real life" situation you will need a copy of the pem files
root@chef-srv:~# knife configure --admin-client-name admin --admin-client-key /etc/chef-server/admin.pem -i -r /root/chef_repo/ --validation-client-name chef-validator --validation-key /etc/chef-server/chef-validator.pem
WARNING: No knife configuration file found
Where should I put the config file? [/root/.chef/knife.rb]
Please enter the chef server URL: [https://chef-srv:443] https://<IP_ADDRESS>:443
Please enter a name for the new user: [vagrant]
Creating initial API user...
Please enter a password for the new user:
Created user[vagrant]
Configuration file written to /root/.chef/knife.rb
please use your ip int the chef server url "https://ipaddress:443"
log_level :info
log_location STDOUT
node_name 'vagrant'
client_key '/root/.chef/vagrant.pem'
validation_client_name 'chef-validator'
validation_key '/etc/chef-server/chef-validator.pem'
chef_server_url 'https://<IP_ADDRESS>:443'
syntax_check_cache_path '/root/.chef/syntax_check_cache'
cookbook_path [ '/root/chef_repo//cookbooks' ]
Provision a centos / ubuntu node via Vagrant ...
cd chef_workshop/chef_server_route/centos_node
vagrant up
cd chef_workshop/chef_server_route/ubutnu_node
vagrant up
once they are up and running connect to your chef workstation
root@chef-srv:~/chef_repo$ cat roles/base.json
{
"name": "base",
"description": "",
"json_class": "Chef::Role",
"default_attributes": {
},
"override_attributes": {
"chef_client": {
"server_url": "http://<IP_ADDRESS>:443"
}
},
"chef_type": "role",
"run_list": [
"recipe[ntp]",
"recipe[chef-client]",
"recipe[chef-client::delete_validation]"
],
"env_run_lists": {
}
}
sudo -i
cd ~/chef_repo
Upload role to server:
root@chef-srv:~/chef_repo$ knife role from file roles/base.json
Updated Role base!
list exiting roles on the server
root@chef-srv:~/chef_repo$ knife role list
base
Connect back to chef-server / workstation and provision nodes
# Bootstrap nodes
centos node ::
knife bootstrap <IP_ADDRESS> -x opencm -P opencm -r 'role[base]' --sudo
ubtunu node ::
knife bootstrap <IP_ADDRESS> -x opencm -P opencm -r 'role[base]' --sudo
opencm is a user defined on the nodes ...
(during vagrant provision)
scroll to view output ...
root@chef-srv:~/chef_repo# knife bootstrap <IP_ADDRESS> -x opencm -P opencm -r 'role[base]' --sudo
Bootstrapping Chef on <IP_ADDRESS>
<IP_ADDRESS> Starting Chef Client, version 11.10.4
<IP_ADDRESS> resolving cookbooks for run list: ["ntp", "chef-client", "chef-client::delete_validation"]
<IP_ADDRESS> Synchronizing Cookbooks:
<IP_ADDRESS> - chef-client
<IP_ADDRESS> - ntp
<IP_ADDRESS> Compiling Cookbooks...
<IP_ADDRESS> [2014-02-22T21:32:59+00:00] WARN: Chef::Mixin::Language is deprecated. Use either (or both)
<IP_ADDRESS> Chef::DSL::PlatformIntrospection or Chef::DSL::DataQuery instead.
<IP_ADDRESS>
<IP_ADDRESS> [2014-02-22T21:32:59+00:00] WARN: Called from:
<IP_ADDRESS> /var/chef/cache/cookbooks/chef-client/libraries/helpers.rb:23:in `'
<IP_ADDRESS> /var/chef/cache/cookbooks/chef-client/libraries/helpers.rb:22:in `'
<IP_ADDRESS> /var/chef/cache/cookbooks/chef-client/libraries/helpers.rb:21:in `'
<IP_ADDRESS> Converging 12 resources
<IP_ADDRESS> Recipe: ntp::default
<IP_ADDRESS> * package[ntp] action install
<IP_ADDRESS> - install version 1:4.2.6.p3+dfsg-1ubuntu3.1 of package ntp
<IP_ADDRESS>
<IP_ADDRESS> * service[ntp] action enable (up to date)
<IP_ADDRESS> * service[ntp] action start (up to date)
<IP_ADDRESS> * service[ntp] action restart
<IP_ADDRESS> - restart service service[ntp]
<IP_ADDRESS>
<IP_ADDRESS> * template[/etc/ntp.conf] action create
<IP_ADDRESS> - update content in file /etc/ntp.conf from 4eb9a0 to a95b85
<IP_ADDRESS> --- /etc/ntp.conf 2012-06-05 20:12:18.000000000 +0000
<IP_ADDRESS> +++ /tmp/chef-rendered-template20140222-2637-u4910c 2014-02-22 21:33:04.957012896 +0000
<IP_ADDRESS> @@ -1,56 +1,24 @@
<IP_ADDRESS> -# /etc/ntp.conf, configuration for ntpd; see ntp.conf(5) for help
<IP_ADDRESS> +# Generated by Chef for node2
<IP_ADDRESS> +# node[:fqdn] = ohai data collected on node !
<IP_ADDRESS> +# Local modifications will be overwritten.
<IP_ADDRESS>
<IP_ADDRESS> -driftfile /var/lib/ntp/ntp.drift
<IP_ADDRESS> +restrict -6 ::1
<IP_ADDRESS> +#server
<IP_ADDRESS>
<IP_ADDRESS> + server 0.pool.ntp.org iburst
<IP_ADDRESS> + restrict 0.pool.ntp.org nomodify notrap noquery
<IP_ADDRESS> + server 1.pool.ntp.org iburst
<IP_ADDRESS> + restrict 1.pool.ntp.org nomodify notrap noquery
<IP_ADDRESS> + server 2.pool.ntp.org iburst
<IP_ADDRESS> + restrict 2.pool.ntp.org nomodify notrap noquery
<IP_ADDRESS> + server 3.pool.ntp.org iburst
<IP_ADDRESS> + restrict 3.pool.ntp.org nomodify notrap noquery
<IP_ADDRESS>
<IP_ADDRESS> -# Enable this if you want statistics to be logged.
<IP_ADDRESS> -#statsdir /var/log/ntpstats/
<IP_ADDRESS> -
<IP_ADDRESS> -statistics loopstats peerstats clockstats
<IP_ADDRESS> -filegen loopstats file loopstats type day enable
<IP_ADDRESS> -filegen peerstats file peerstats type day enable
<IP_ADDRESS> -filegen clockstats file clockstats type day enable
<IP_ADDRESS> -
<IP_ADDRESS> -# Specify one or more NTP servers.
<IP_ADDRESS> -
<IP_ADDRESS> -# Use servers from the NTP Pool Project. Approved by Ubuntu Technical Board
<IP_ADDRESS> -# on 2011-02-08 (LP: #104525). See http://www.pool.ntp.org/join.html for
<IP_ADDRESS> -# more information.
<IP_ADDRESS> -server 0.ubuntu.pool.ntp.org
<IP_ADDRESS> -server 1.ubuntu.pool.ntp.org
<IP_ADDRESS> -server 2.ubuntu.pool.ntp.org
<IP_ADDRESS> -server 3.ubuntu.pool.ntp.org
<IP_ADDRESS> -
<IP_ADDRESS> -# Use Ubuntu's ntp server as a fallback.
<IP_ADDRESS> -server ntp.ubuntu.com
<IP_ADDRESS> -
<IP_ADDRESS> -# Access control configuration; see /usr/share/doc/ntp-doc/html/accopt.html for
<IP_ADDRESS> -# details. The web page
<IP_ADDRESS> -# might also be helpful.
<IP_ADDRESS> -#
<IP_ADDRESS> -# Note that "restrict" applies to both servers and clients, so a configuration
<IP_ADDRESS> -# that might be intended to block requests from certain clients could also end
<IP_ADDRESS> -# up blocking replies from your own upstream servers.
<IP_ADDRESS> -
<IP_ADDRESS> -# By default, exchange time with everybody, but don't allow configuration.
<IP_ADDRESS> -restrict -4 default kod notrap nomodify nopeer noquery
<IP_ADDRESS> -restrict -6 default kod notrap nomodify nopeer noquery
<IP_ADDRESS> -
<IP_ADDRESS> -# Local users may interrogate the ntp server more closely.
<IP_ADDRESS> +restrict default kod nomodify notrap nopeer noquery
<IP_ADDRESS> +restrict -6 default kod nomodify notrap nopeer noquery
<IP_ADDRESS> restrict <IP_ADDRESS>
<IP_ADDRESS> -restrict ::1
<IP_ADDRESS>
<IP_ADDRESS> -# Clients from this (example!) subnet have unlimited access, but only if
<IP_ADDRESS> -# cryptographically authenticated.
<IP_ADDRESS> -#restrict <IP_ADDRESS> mask <IP_ADDRESS> notrust
<IP_ADDRESS> -
<IP_ADDRESS> -
<IP_ADDRESS> -# If you want to provide time to your local subnet, change the next line.
<IP_ADDRESS> -# (Again, the address is an example only.)
<IP_ADDRESS> -#broadcast <IP_ADDRESS>
<IP_ADDRESS> -
<IP_ADDRESS> -# If you want to listen to time broadcasts on your local subnet, de-comment the
<IP_ADDRESS> -# next lines. Please do this only if you trust everybody on the network!
<IP_ADDRESS> -#disable auth
<IP_ADDRESS> -#broadcastclient
<IP_ADDRESS> +server <IP_ADDRESS> # local clock
<IP_ADDRESS> +driftfile /var/lib/ntp/drift
<IP_ADDRESS> +keys /etc/ntp/keys
<IP_ADDRESS>
<IP_ADDRESS> Recipe: chef-client::service
<IP_ADDRESS> * directory[/var/run/chef] action create
<IP_ADDRESS> - create new directory /var/run/chef
<IP_ADDRESS> - change mode from '' to '0755'
<IP_ADDRESS> - change owner from '' to 'root'
<IP_ADDRESS> - change group from '' to 'root'
<IP_ADDRESS>
<IP_ADDRESS> * directory[/var/cache/chef] action create
<IP_ADDRESS> - create new directory /var/cache/chef
<IP_ADDRESS> - change mode from '' to '0755'
<IP_ADDRESS> - change owner from '' to 'root'
<IP_ADDRESS> - change group from '' to 'root'
<IP_ADDRESS>
<IP_ADDRESS> * directory[/var/lib/chef] action create
<IP_ADDRESS> - create new directory /var/lib/chef
<IP_ADDRESS> - change mode from '' to '0755'
<IP_ADDRESS> - change owner from '' to 'root'
<IP_ADDRESS> - change group from '' to 'root'
<IP_ADDRESS>
<IP_ADDRESS> * directory[/var/log/chef] action create
<IP_ADDRESS> - create new directory /var/log/chef
<IP_ADDRESS> - change mode from '' to '0750'
<IP_ADDRESS> - change owner from '' to 'root'
<IP_ADDRESS> - change group from '' to 'root'
<IP_ADDRESS>
<IP_ADDRESS> * directory[/etc/chef] action create (up to date)
<IP_ADDRESS> * template[/etc/init.d/chef-client] action create
<IP_ADDRESS> - create new file /etc/init.d/chef-client
<IP_ADDRESS> - update content in file /etc/init.d/chef-client from none to 120a45
<IP_ADDRESS> --- /etc/init.d/chef-client 2014-02-22 21:33:05.021019559 +0000
<IP_ADDRESS> +++ /tmp/chef-rendered-template20140222-2637-1nzg8iy 2014-02-22 21:33:05.021019559 +0000
<IP_ADDRESS> @@ -1 +1,186 @@
<IP_ADDRESS> +#! /bin/sh
<IP_ADDRESS> +### BEGIN INIT INFO
<IP_ADDRESS> +# Provides: chef-client
<IP_ADDRESS> +# Required-Start: $remote_fs $network
<IP_ADDRESS> +# Required-Stop: $remote_fs $network
<IP_ADDRESS> +# Default-Start: 2 3 4 5
<IP_ADDRESS> +# Default-Stop: 0 1 6
<IP_ADDRESS> +# Short-Description: Start a chef-client.
<IP_ADDRESS> +### END INIT INFO
<IP_ADDRESS> +#
<IP_ADDRESS> +# Copyright (c) 2009-2010 Opscode, Inc,
<IP_ADDRESS> +#
<IP_ADDRESS> +# chef-client Startup script for chef-client.
<IP_ADDRESS> +# chkconfig: - 99 02
<IP_ADDRESS> +# description: starts up chef-client in daemon mode.
<IP_ADDRESS> +
<IP_ADDRESS> +PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
<IP_ADDRESS> +DAEMON=/usr/bin/chef-client
<IP_ADDRESS> +NAME=chef-client
<IP_ADDRESS> +DESC=chef-client
<IP_ADDRESS> +PIDFILE=/var/run/chef/client.pid
<IP_ADDRESS> +
<IP_ADDRESS> +test -x $DAEMON || exit 1
<IP_ADDRESS> +
<IP_ADDRESS> +. /lib/lsb/init-functions
<IP_ADDRESS> +
<IP_ADDRESS> +[ -r /etc/default/$NAME ] && . /etc/default/$NAME
<IP_ADDRESS> +
<IP_ADDRESS> +if [ ! -d /var/run/chef ]; then
<IP_ADDRESS> + mkdir /var/run/chef
<IP_ADDRESS> +fi
<IP_ADDRESS> +
<IP_ADDRESS> +DAEMON_OPTS="-d -P $PIDFILE -L $LOGFILE -c $CONFIG -i $INTERVAL -s $SPLAY "
<IP_ADDRESS> +
<IP_ADDRESS> +running_pid() {
<IP_ADDRESS> + pid=$1
<IP_ADDRESS> + name=$2
<IP_ADDRESS> + [ -z "$pid" ] && return 1
<IP_ADDRESS> + [ ! -d /proc/$pid ] && return 1
<IP_ADDRESS> + cmd=`awk '/Name:/ {print $2}' /proc/$pid/status`
<IP_ADDRESS> + [ "$cmd" != "$name" ] && return 1
<IP_ADDRESS> + return 0
<IP_ADDRESS> +}
<IP_ADDRESS> +
<IP_ADDRESS> +running() {
<IP_ADDRESS> + [ ! -f "$PIDFILE" ] && return 1
<IP_ADDRESS> + pid=`cat $PIDFILE`
<IP_ADDRESS> + running_pid $pid $NAME || return 1
<IP_ADDRESS> + return 0
<IP_ADDRESS> +}
<IP_ADDRESS> +
<IP_ADDRESS> +start_server() {
<IP_ADDRESS> + if [ -z "$DAEMONUSER" ] ; then
<IP_ADDRESS> + start_daemon -p $PIDFILE $DAEMON $DAEMON_OPTS
<IP_ADDRESS> + errcode=$?
<IP_ADDRESS> + else
<IP_ADDRESS> + start-stop-daemon --start --quiet --pidfile $PIDFILE \
<IP_ADDRESS> + --chuid $DAEMONUSER \
<IP_ADDRESS> + --exec $DAEMON -- $DAEMON_OPTS
<IP_ADDRESS> + errcode=$?
<IP_ADDRESS> + fi
<IP_ADDRESS> + return $errcode
<IP_ADDRESS> +}
<IP_ADDRESS> +
<IP_ADDRESS> +stop_server() {
<IP_ADDRESS> + if [ -z "$DAEMONUSER" ] ; then
<IP_ADDRESS> + killproc -p $PIDFILE $DAEMON
<IP_ADDRESS> + errcode=$?
<IP_ADDRESS> + else
<IP_ADDRESS> + start-stop-daemon --stop --quiet --pidfile $PIDFILE \
<IP_ADDRESS> + --user $DAEMONUSER \
<IP_ADDRESS> + --exec $DAEMON
<IP_ADDRESS> + errcode=$?
<IP_ADDRESS> + fi
<IP_ADDRESS> + return $errcode
<IP_ADDRESS> +}
<IP_ADDRESS> +
<IP_ADDRESS> +reload_server() {
<IP_ADDRESS> + if [ -z "$DAEMONUSER" ] ; then
<IP_ADDRESS> + killproc -p $PIDFILE $DAEMON -HUP
<IP_ADDRESS> + errcode=$?
<IP_ADDRESS> + else
<IP_ADDRESS> + start-stop-daemon --stop --signal HUP --quiet --pidfile $PIDFILE \
<IP_ADDRESS> + --user $DAEMONUSER \
<IP_ADDRESS> + --exec $DAEMON
<IP_ADDRESS> + errcode=$?
<IP_ADDRESS> + fi
<IP_ADDRESS> + return $errcode
<IP_ADDRESS> +}
<IP_ADDRESS> +
<IP_ADDRESS> +force_stop() {
<IP_ADDRESS> + [ ! -e "$PIDFILE" ] && return
<IP_ADDRESS> + if running ; then
<IP_ADDRESS> + /bin/kill -15 $pid
<IP_ADDRESS> + sleep "$DIETIME"s
<IP_ADDRESS> + if running ; then
<IP_ADDRESS> + /bin/kill -9 $pid
<IP_ADDRESS> + sleep "$DIETIME"s
<IP_ADDRESS> + if running ; then
<IP_ADDRESS> + echo "Cannot kill $NAME (pid=$pid)!"
<IP_ADDRESS> + exit 1
<IP_ADDRESS> + fi
<IP_ADDRESS> + fi
<IP_ADDRESS> + fi
<IP_ADDRESS> + rm -f $PIDFILE
<IP_ADDRESS> +}
<IP_ADDRESS> +
<IP_ADDRESS> +case "$1" in
<IP_ADDRESS> + start)
<IP_ADDRESS> + log_daemon_msg "Starting $DESC " "$NAME"
<IP_ADDRESS> + if running ; then
<IP_ADDRESS> + log_progress_msg "apparently already running"
<IP_ADDRESS> + log_end_msg 0
<IP_ADDRESS> + exit 0
<IP_ADDRESS> + fi
<IP_ADDRESS> + if start_server ; then
<IP_ADDRESS> + [ -n "$STARTTIME" ] && sleep $STARTTIME # Wait some time
<IP_ADDRESS> + if running ; then
<IP_ADDRESS> + log_end_msg 0
<IP_ADDRESS> + else
<IP_ADDRESS> + log_end_msg 1
<IP_ADDRESS> + fi
<IP_ADDRESS> + else
<IP_ADDRESS> + log_end_msg 1
<IP_ADDRESS> + fi
<IP_ADDRESS> + ;;
<IP_ADDRESS> + stop)
<IP_ADDRESS> + log_daemon_msg "Stopping $DESC" "$NAME"
<IP_ADDRESS> + if running ; then
<IP_ADDRESS> + errcode=0
<IP_ADDRESS> + stop_server || errcode=$?
<IP_ADDRESS> + log_end_msg $errcode
<IP_ADDRESS> + else
<IP_ADDRESS> + log_progress_msg "apparently not running"
<IP_ADDRESS> + log_end_msg 0
<IP_ADDRESS> + exit 0
<IP_ADDRESS> + fi
<IP_ADDRESS> + ;;
<IP_ADDRESS> + force-stop)
<IP_ADDRESS> + $0 stop
<IP_ADDRESS> + if running; then
<IP_ADDRESS> + log_daemon_msg "Stopping (force) $DESC" "$NAME"
<IP_ADDRESS> + errcode=0
<IP_ADDRESS> + force_stop || errcode=$?
<IP_ADDRESS> + log_end_msg $errcode
<IP_ADDRESS> + fi
<IP_ADDRESS> + ;;
<IP_ADDRESS> + restart|force-reload)
<IP_ADDRESS> + log_daemon_msg "Restarting $DESC" "$NAME"
<IP_ADDRESS> + errcode=0
<IP_ADDRESS> + stop_server || errcode=$?
<IP_ADDRESS> + [ -n "$DIETIME" ] && sleep $DIETIME
<IP_ADDRESS> + start_server || errcode=$?
<IP_ADDRESS> + [ -n "$STARTTIME" ] && sleep $STARTTIME
<IP_ADDRESS> + running || errcode=$?
<IP_ADDRESS> + log_end_msg $errcode
<IP_ADDRESS> + ;;
<IP_ADDRESS> + status)
<IP_ADDRESS> + log_daemon_msg "Checking status of $DESC" "$NAME"
<IP_ADDRESS> + if running ; then
<IP_ADDRESS> + log_progress_msg "running"
<IP_ADDRESS> + log_end_msg 0
<IP_ADDRESS> + else
<IP_ADDRESS> + log_progress_msg "apparently not running"
<IP_ADDRESS> + log_end_msg 1
<IP_ADDRESS> + exit 3
<IP_ADDRESS> + fi
<IP_ADDRESS> + ;;
<IP_ADDRESS> + reload)
<IP_ADDRESS> + if running; then
<IP_ADDRESS> + log_daemon_msg "Reloading $DESC" "$NAME"
<IP_ADDRESS> + errcode=0
<IP_ADDRESS> + reload_server || errcode=$?
<IP_ADDRESS> + log_end_msg $errcode
<IP_ADDRESS> + fi
<IP_ADDRESS> + ;;
<IP_ADDRESS> + *)
<IP_ADDRESS> + N=/etc/init.d/$NAME
<IP_ADDRESS> + echo "Usage: $N {start|stop|force-stop|restart|force-reload|status}" >&2
<IP_ADDRESS> + exit 1
<IP_ADDRESS> + ;;
<IP_ADDRESS> +esac
<IP_ADDRESS> +
<IP_ADDRESS> +exit 0
<IP_ADDRESS> +
<IP_ADDRESS> - change mode from '' to '0755'
<IP_ADDRESS>
<IP_ADDRESS> * template[/etc/default/chef-client] action create
<IP_ADDRESS> - create new file /etc/default/chef-client
<IP_ADDRESS> - update content in file /etc/default/chef-client from none to 13b3d0
<IP_ADDRESS> --- /etc/default/chef-client 2014-02-22 21:33:05.073020993 +0000
<IP_ADDRESS> +++ /tmp/chef-rendered-template20140222-2637-tvy22g 2014-02-22 21:33:05.073020993 +0000
<IP_ADDRESS> @@ -1 +1,5 @@
<IP_ADDRESS> +LOGFILE=/var/log/chef/client.log
<IP_ADDRESS> +CONFIG=/etc/chef/client.rb
<IP_ADDRESS> +INTERVAL=1800
<IP_ADDRESS> +SPLAY=20
<IP_ADDRESS> - change mode from '' to '0644'
<IP_ADDRESS>
<IP_ADDRESS> * service[chef-client] action enable
<IP_ADDRESS> - enable service service[chef-client]
<IP_ADDRESS>
<IP_ADDRESS> Recipe: chef-client::delete_validation
<IP_ADDRESS> * file[/etc/chef/validation.pem] action delete
<IP_ADDRESS> - delete file /etc/chef/validation.pem
<IP_ADDRESS>
<IP_ADDRESS> Recipe: ntp::default
<IP_ADDRESS> * service[ntp] action restart
<IP_ADDRESS> - restart service service[ntp]
<IP_ADDRESS>
<IP_ADDRESS> Recipe: chef-client::service
<IP_ADDRESS> * service[chef-client] action restart
<IP_ADDRESS> - restart service service[chef-client]
<IP_ADDRESS>
<IP_ADDRESS>
<IP_ADDRESS> Running handlers:
<IP_ADDRESS> Running handlers complete
<IP_ADDRESS>
<IP_ADDRESS> Chef Client finished, 13/16 resources updated in 8.521233887 seconds
expect it to fail the first time see next slide ...
we didn't upload the cookbooks to our chef server
knife cookbook upload ntp
knife cookbook upload chef-client
output
root@chef-srv:~/chef_repo# knife cookbook upload ntp
Uploading ntp [0.1.1]
Uploaded 1 cookbook.
root@chef-srv:~/chef_repo# knife cookbook upload chef-client
Uploading chef-client [2.1.6]
Uploaded 1 cookbook.
Connect back to chef-server / workstation and provision nodes
# Bootstrap nodes
centos node ::
knife bootstrap <IP_ADDRESS> -x opencm -P opencm -r 'role[base]' --sudo
ubtunu node ::
knife bootstrap <IP_ADDRESS> -x opencm -P opencm -r 'role[base]' --sudo
opencm is a user defined on the nodes ...
(during vagrant provision)
.
├── README.md
├── centos_node
│ ├── Vagrantfile
│ └── bootstrap.sh
└── ubutnu_node
├── Vagrantfile
└── bootstrap.sh
Avialble @ chef_workshop
on Github
[ see chef_solo_route directory ]
Use anyone you like - ubuntu / cnetos
.
├── .chef/knife.rb
├── .git
├── .gitignore
├── Cheffile
├── Gemfile
├── README.md
├── nodes
├── roles
├── site-cookbooks
└── solo.rb
Provides a place for all chef objects [ nodes, roles, databags ]
base_dir = File.expand_path('../', __FILE__)
cookbook_path [File.join(base_dir, 'cookbooks'), File.join(base_dir, 'site-cookbooks')]
role_path File.join(base_dir, 'roles')
data_bag_path File.join(base_dir, 'data_bags')
file_cache_path file_cache_path File.join(base_dir, 'tmp')
# Default json
json_attribs File.join(base_dir, 'nodes', 'default.json')
Defines:
Looks familiar ?
Vagrant file creates the solo.rb configuration ...
config.vm.provision :chef_solo do |chef|
chef.cookbooks_path = ["cookbooks", "site-cookbooks"]
chef.roles_path = ["roles"]
chef.log_level = ENV['CHEF_LOG'] ? ENV['CHEF_LOG'].to_sym : :info
chef.add_role "web"
end
chef-solo -c <solo-config> -j node.json
Now in our case we used:
json_attribs File.join(base_dir, 'nodes', 'default.json')
So:
{
"run_list": [
"role[default]"
]
}
Will use:
name "default"
description "The basic stuff any server needs - rpm repos, users, etc etc ..."
run_list "recipe[yum::yum]", "recipe[base]"
override_attributes({
:yum => {
:repoforge_release => '0.5.3-1'
}
})
gem "knife-solo"
gem "librarian-chef"
gem "knife-solo_data_bag"
config.vm.provision "shell", inline: "[[ `which chef-solo` ]] || curl -L https://www.opscode.com/chef/install.sh | sudo bash"
config.vm.provision :chef_solo do |chef|
chef.cookbooks_path = ["cookbooks", "site-cookbooks"]
chef.roles_path = ["roles"]
chef.log_level = ENV['CHEF_LOG'] ? ENV['CHEF_LOG'].to_sym : :info
chef.add_role "web"
end
Two provisioners in this example:
Everything (including these slides) are on


The long tail serves as a lightning rod during electric attacks, so it is easy to find it on scorched footprints near its habitat. However, some Raichu are more timid and with the help of digging hide from people so that they are not afraid of him.


“I played football for a little bit, but I knew that wasn’t going to be it. I didn’t want to be outside all the time,” Hunter said.
Although Hunter’s dad taught him the ropes, the Manchester, Connecticut native fell in love with the game all on his own. Basketball was the only sport he played past the eighth grade. When a football coach told Hunter something wouldn’t fly in high school, he didn’t worry because he knew he wouldn’t return to the gridiron.
Hunter wanted to blaze his own path. He knew basketball was his key, but he didn’t know how yet.
In high school, Hunter played the Adidas Amateur Athletic Union circuit. He enjoyed traveling across the country and earning medals along the way. The summer his team got fourth in the championships is one of his favorite memories.
At that point in his career, Hunter dove into basketball head-first. He became a student of the game. Hunter watched practice and game footage with his father to grow as a player.
Hunter showcased his talent during high school, but his recruiting process was slow. He didn’t get offers to play at the collegiate level until his career was almost over.
“I didn’t get my first offer until the second semester of my senior year, and that was from Old Dominion, the school that I originally committed to,” Hunter said. “I only got four real offers but I got a lot of interest.”
Hunter arrived at Old Dominion during his freshman year and made an immediate impact as a bench player. He played more minutes his sophomore year and made three starts, but he wasn’t quite where he wanted to be.
Jesse Jarrold-Grapes | Photo Editor
Ohio guard Jaylin Hunter (12) gets a rebound during the second half of the victory over Central Michigan on Saturday, Jan. 21, 2022 at the Convo.
In Hunter’s junior year, he was a team captain, started all 32 games and led the team in free throw percentage. Hunter scored in double figures 16 times and ranked in the top 10 for several categories in Conference-USA, including assists, steals, assist-to-turnover ratio and minutes played.
But Hunter wanted a more holistic experience. He wanted the connections that come with basketball. That’s what brought him to Ohio.
“It was just a better opportunity (and) a more close-knit team,” Hunter said. “One thing I love about here is I just feel like we’re a circle, one big group instead of a hierarchy. I think that’s just a testament to coach Boals and the culture he created here.”
Hunter is a team-first guy. He doesn’t get upset when someone’s shots aren’t falling and loves seeing his teammates succeed. Most of the time, Hunter is the Bobcats’ assists leader.
“I know that’s kind of cliche to say, but I feel like as a point guard, I do love seeing my teammates be successful.”
Hunter has found his way to a successful career. He’s taken the Mid-American Conference by storm and still has more time. Basketball is Hunter’s past and present, and he hopes it will be his future.
He’s an NBA junkie and plans to pursue a career in management or coaching in the professional ranks. He doesn’t exactly want to follow in his father’s footsteps, though.
“I think I want to deviate a little bit. I think I can use his experiences to create my own path and see what I can do with it,” Hunter said.
Hunter has forged his own path since he picked up a basketball and now intends to stay on it.


The Limited Editions Club
The Limited Editions Club was started in 1929 by George Macy.
Members paid a subscription for the classic titles, which were illustrated by contemporary artists. They were published in relatively small quantities, and are now highly prized by collectors.


Main entry point to the tool. The function accepts multiple different kinds
of arguments as a convenience. In particular the function accepts either
- a string containing source code
The string is parsed with Recast
- a single AST node
- a single node path
- an array of nodes
- an array of node paths
Parameters:
| Name | Type | Description |
|---|---|---|
source |
Node | NodePath | Array | string | |
options |
Object | Options to pass to Recast when passing source code |
Returns:
- Type
- Collection
Members
(static) types :external:astTypes
Type:
Methods
(static) match(path)
Utility function to match a node against a pattern.
Parameters:
| Name | Type | Description |
|---|---|---|
path |
Node | NodePath | Object |
Returns:
boolean
(static) use(plugin)
Utility function for registering plugins.
Plugins are simple functions that are passed the core jscodeshift instance.
They should extend jscodeshift by calling `registerMethods`, etc.
This method guards against repeated registrations (the plugin callback will only be called once).
Parameters:
| Name | Type | Description |
|---|---|---|
plugin |
function |
(static) withParser()
Returns a version of the core jscodeshift function "bound" to a specific
parser.


As CSV
Activity Report
Project : {{controller.reportData.additional.project}}
Location : {{controller.reportData.additional.location}}
Start date : {{controller.reportData.additional.startDate|date:'dd MMM yyyy'}}
End date : {{controller.reportData.additional.endDate|date:'dd MMM yyyy'}}
Number of clients currently active : {{controller.reportData.additional.active}}
Number of assessments carried out : {{controller.reportData.additional.assessments}}
Number of clients that were discharged : {{controller.reportData.additional.discharged}}
Number of sessions that took place : {{controller.reportData.additional.sessions}}
Number of Did Not Attends : {{controller.reportData.additional.dna}}
Referrals From
{{from.where}} : {{from.count}}
Referrals To
{{to.where}} : {{to.count}}


Data visualisation of Referenda held in Ireland and Polling System for upcoming Referenda
This web application is a polling system used to gather information around the country of Ireland
to allow campaign parties that are taking part in these referenda to see concentrations
of votes along with a variety of other information about the public. This information is displayed
as a series of graphs, progress bars and heatmaps. The data that has been gathered in this poll
can be compared to the data of previous referenda held in Ireland.
Please click the link to take part in the upcoming repeal the 8th referendum poll and share with your family and friends with the links below!


|
The Cutting Edge
|
|
|
G'Day Developers!
Do you conduct Market Research via
the Web?
Why write code when you may not need
to write any at all? In every
industry Market Research is
conducted before a product is
developed. Why is IT any different?
Doing Market Research focuses the
product on the right set of people
so you can satisfy their needs. If
you can't connect the dots between
the work you do and how it helps the
customer, consider investing your
time elsewhere. Market Research
bridges the gap between the techies
and the users.
Read More on Do you conduct
Market Research via the Web?... and
don't forget to check out
more
of SSW rules to better projects...
|
|
Cheers until next time,
Adam
SSW Chief Architect and Microsoft Regional Director, Australia
Got a comment for Adam? 6164616d636f67616e407373772e636f6d2e6175
|
|
Sydney .NET User Group - The best
place to learn .NET for free in
Sydney
|
|
Paul Stovell & Adam Cogan will look at data binding
in Windows Forms: the classes involved, what's changed in .NET 2.0 and things to watch out for!
Edward Forgacs will demonstrate how to implement Full-text Indexing in SQL Server 2005. Full Text
Indexing is used to speed up keyword-based queries of text data stored in SQL Server. It is possible to build
and search indexes on standard SQL types such as char and varchar,
as well as PDF and Word documents stored
in your database. Edward will also show
you how to store full-text indexes in your database backups.
|
See You There!! |
Sorry I can't make it
|
|
|
OzFox Lite 2006 - 15 Rules to Successful
Projects
|
|
|
|
12 days to
go!
OzFox Lite 2006
Saturday 25th
&
Sunday 26th March 2006 Location: Microsoft, Sydney
|
15 Rules to Successful Projects
Managing a team of coders can be
a tricky experience, especially as
most coders like to do things their
own way. During this session we go
through a list of rules that help
make the development process as
smooth as possible. These rules
govern the creation of
specifications and schedules, best
methods for testing and fixing bugs
and even employees working
conditions. Then we will dive into
how you can make the most of
Exchange Server in your organisation.
Read more about OzFox Lite 2006...
|
|
Code Camp OZ - Favourite 3rd Party
Tools
|
|
41 days to go!
CodeCampOz 2006
Sunday 23rd & Monday 24th April 2006 Location:
Wagga Wagga
Adam Cogan's Favourite 3rd
Party Tools
Camp Code is an annual gathering of developers who work with Microsoft based technologies. In this session
Adam will look at
his favourite third party tools. "Microsoft tools are the most important tools I have. I spend most of
my time using Outlook, Visual Studio .NET, SQL
Server Enterprise Manager and Access."
Read more on 3rd party tools...
So join Adam Cogan and a host of other speakers at this year's Code Camp OZ.
|
Featured Product: SSW
Upsizing PRO!
|
|
Migrate from
Access to SQL Server
safely with SSW
Upsizing PRO!
Has your business
outgrown your home
made Access
database? Upsizing
is the process of
migrating some or
all database objects
(tables and queries)
from a Microsoft
Access database (.mdb)
to a new or existing
Microsoft SQL Server
database. If your
business is growing
and you demand a
scalable database
solution, upsize
from Access Jet to
the robust SQL
Server environment.
SSW Upsizing PRO! is
the tool that
prepares your Access
database so you can
convert effortlessly
to SQL Server.
Upsizing PRO! will
prevent known errors,
ensuring a smooth
migration.
More on SSW
Upsizing PRO!....
|


Iíve been using tramadol and codeine for a long time now. I take either drug once a day, always in the evening, several hours before bed time. I consider myself an addict to opiates and have had love affairs with other opiates such as hydrocodone and morphine. But due to prices and availability, I am usually confined to codeine and tramadol.
I donít take both drugs at the same time, or switch back and forth very often due to some reasons I will get to later on in this article. To summarize, I started taking codeine every night. I fell in love with this drug. The effects come on very fast, were incredible, and usually faded away rather quickly. My supply of codeine was dwindling, and I can across tramadol in my search for a substitute. I began using tramadol every night instead of codeine, because like codeine, it would take away my pain and also cause a very nice high. Tramadol's high was different from codeine. It came on slower, was less intense (though you can get very intense buzz off of the right dose), and lasted much longer.
I decided to submit this report because Iíve discovered some things about these two drugs. I love both drugs, and both are effective, though codeine does help with pain more than tramadol does.
Iíve noticed that switching from one drug over to the other causes some problems for me. However, I notice that when I switch from codeine to tramadol, my first few nights with tramadol are not very comfortable. Instead of feeling pain relief and a sense of well being, I tend to feel the effects of withdrawal from the codeine more severely. I donít really get anything out of tramadol. But, by the second or third night, tramadol begins to act normally in my body. By this time, I am well settled with tramadol and will stick with it until my supply runs out, or I build up too much tolerance to the drug.
My best time with tramadol is within the first few weeks. It doesnít take very much, maybe 100 or 150mg a night to soothe my pain. For the most part, I feel normal during the day. But once my tolerance builds up, and I start taking around 200 to 300mg a day or more, and the drug begins to take its toll on my life. My sleeping schedules become irregular. I become a zombie during the day. I am always tired and very grumpy. When I do finally sleep I have very vivid dreams that leave me feeling more exhausted then when I feel asleep.
Switching back to codeine is another story all together. I can take codeine the first night without a problem. I donít really feel much from taking the codeine, but at least I donít feel the withdrawals from tramadol. Every day before dosing, though, I feel the withdrawals from tramadol and these withdrawals usually last a few days. The withdrawals, for me, are very awkward. Aside from the physical discomfort, I get wide swings in my emotions. I can feel very sad at times, and also very happy, and I always find myself doing a lot of internal dialogue in which I work out a lot of problems in my life. This time is hard for me, but part of me likes it. Itís almost a sacred time. During this time, I feel emotions that I donít get the chance to feel very often, and they are usually very amplified. Especially the feeling I get when I hear a song on the radio and it reminds me of a very happy time in my life. I even find myself crying from time to time, which is very unusual for me.
But this state doesnít last very long. After 3 or 4 days itís gone, and I am taking codeine every night without a problem. During the first few weeks itís great. The side effects are minimal, and I find myself feeling very alive and many times very athletic during the day (I am athletic... or try to be). This is probably why I like codeine more than tramadol. Because I feel better during the day. I think it has to do with the quality of sleep I am getting after a dose of codeine as opposed to a dose of tramadol. But, as tolerance develops, codeine soon takes over my life. Codeine seems to be more habit forming and tolerance develops quicker. After several weeks, I find my body and mind needing the dose... and if I donít take my dose at the usual time I can become quite irritated. My fingers and joints become stiff.  Once my tolerance to codeine gets really bad, the side effects just outweigh the positives, and then I know itís time to switch again.
Whenever I am at a point where my tolerance has built up, my life begins to fall apart. Iím sure my family and friends are affected, and Iím sure they can tell something is wrong with me. The best times are always after a few days after I make the switch from one drug to the other, sometimes I almost feel normal, almost like Iím not a drug addict.
I just wish I had kept opiates and opioids as a recreational drug. They were much more fun back in those days. Now, they are simply just a way of life.
Experience Reports are the writings and opinions of the individual authors who submit them.
Some of the activities described are dangerous and/or illegal and none are recommended by Erowid.


6. Look for the best RNN parameters¶
You can execute a grid search to find the best parameters for the RNN. This script allow you to find a good learning rate for your RNN but you can also implement other test by changing the Model class in the ‘rnn/rnn.py’ file to get access to other parameters.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 | import json
import numpy as np
from keras.preprocessing import sequence
from keras.utils.np_utils import to_categorical
from rnn.rnn import prepare_data
with open('rnn/configurations/rnn_test.json') as c:
config = json.load(c)
tokens, all_smiles = prepare_data(config)
#%%
from rnn.rnn import convert_data_to_numbers
x_train, y_train = convert_data_to_numbers(tokens, all_smiles[:100000])
print("SMILES converted to numbers")
maxlen = 81
x = sequence.pad_sequences(x_train, maxlen=maxlen, dtype='int32',
padding='post', truncating='pre', value=0.)
y = sequence.pad_sequences(y_train, maxlen=maxlen, dtype='int32',
padding='post', truncating='pre', value=0.)
print("Loading y_train_one_hot")
y_train_one_hot = np.array([to_categorical(y_i, num_classes=len(tokens)) for y_i in y])
print(y_train_one_hot.shape)
n = x.shape[1]
#%%
from rnn.rnn import Model
from sklearn.model_selection import GridSearchCV
model = Model(tokens=tokens, n= x.shape[1])
grid = {'lr': [0.1, 0.01, 0.001, 0.0001, 0.00001, 0.000001]}
gridsearch = GridSearchCV(model, grid, cv=10)
gridsearch.fit(x, y_train_one_hot)
#%%
gridsearch.best_params_
|
Launching this script in a jupyter-notebook is maybe easier for analysing results.


Enter Details
Guest Photo
First Name *
Purpose of Visit *
Mobile *
No spaces or brackets e.g.<PHONE_NUMBER>
Your mobile number is valid
No of Guests Accompanying
Accompany Name
Company
Building
Padmanbham
Nila
Tesjaswini
Bhavani
Vehicle No
Photo Id Number
Voter Id
Aadhar
License
Other
Pass Valid for (hours)
Fields marked (*) are required
Preview Pass
No:
Name:
Purpose:
Mobile:
Company:
Building:
Vehicle No:
Issued On:
Time In:
Valid for (Hours):


Ethiopia,South Korea Business Forum Held In Addis Ababa
By Tesfa-Alem Tekle
(ADDIS ABABA) – Ethiopia and South Korea Business Forum was held in the Ethiopian capital, Addis Ababa according to the local, Fana broadcast news agency (FBC).
At the joint occasion, State Minister for Economic and Diaspora Affairs, Dr. Aklilu Hailemikael, said Ethiopia is paying special attention to attract foreign direct investment (FDI).
He underscored his country’s commitment to help Korean and all other foreign companies in succeeding up on engagement in investments in Ethiopia.
The minister called on the Korean companies to participate and work with Ethiopian investors in the fields of agriculture, agricultural processing, tourism, mining, and information technology.
South Korea’s ambassador to Ethiopia, Lim Hoon Min, on his part noted that Ethiopia and South Korea have a historic relationship further citing to Ethiopia’s contribution to the Korean War as “unforgettable”
The Ambassador also said Prime Minister Dr. Abiy Ahmed’s visit to Korea last August was a testament to the growing relations between the two countries.
Over 90 companies and investors from Ethiopia and South Korea participated in the current business Forum.
Expediting the implementation of the pending Investment Expansion and Protection agreement between the two countries would be indispensable in attracting foreign investors, the Ambassador added.
The Forum was organized by the Ethiopian Embassy in Seoul, Korea-Africa Foundation, Korea Federation of Textile Industries, Ethio-South Korea Business Association, the Ethiopian Chamber of Commerce and Sectoral Associations, Addis Ababa Chamber of Commerce and South Korean Embassy in Ethiopia.
(BORKENA)
Join the conversation. Like borkena on Facebook and get Ethiopian News updates regularly. As well, you may get Ethiopia News by following us on twitter @zborkena


Click the selected tab to toggle its content closed/open. To enable this functionality, set the 'collapsible' property of the Tabs Custom Element to true.
- Node.js
- JavaServer Pages
- Active Server Pages
- Python
- Perl
Node.js is an event-driven I/O server-side JavaScript environment based on V8. It
is intended for writing scalable network programs such as web servers. It was created
by Ryan Dahl in 2009, and its growth is sponsored by Joyent, which employs Dahl.
Similar environments written in other programming languages include Twisted for
Python, Perl Object Environment for Perl, libevent for C and EventMachine for Ruby.
Unlike most JavaScript, it is not executed in a web browser, but is instead a form
of server-side JavaScript. Node.js implements some CommonJS specifications. Node.js
includes a REPL environment for interactive testing.
JavaServer Pages (JSP) is a Java technology that helps software developers serve
dynamically generated web pages based on HTML, XML, or other document types. Released
in 1999 as Sun's answer to ASP and PHP,[citation needed] JSP was designed to address
the perception that the Java programming environment didn't provide developers with
enough support for the Web. To deploy and run, a compatible web server with servlet
container is required. The Java Servlet and the JavaServer Pages (JSP) specifications
from Sun Microsystems and the JCP (Java Community Process) must both be met by the
container.
ASP.NET is a web application framework developed and marketed by Microsoft to allow
programmers to build dynamic web sites, web applications and web services. It was
first released in January 2002 with version 1.0 of the .NET Framework, and is the
successor to Microsoft's Active Server Pages (ASP) technology. ASP.NET is built
on the Common Language Runtime (CLR), allowing programmers to write ASP.NET code
using any supported .NET language. The ASP.NET SOAP extension framework allows ASP.NET
components to process SOAP messages.
Python is a general-purpose, high-level programming language[5] whose design philosophy
emphasizes code readability. Python claims to "[combine] remarkable power with very
clear syntax",[7] and its standard library is large and comprehensive. Its use of
indentation for block delimiters is unique among popular programming languages.
Python supports multiple programming paradigms, primarily but not limited to object-oriented,
imperative and, to a lesser extent, functional programming styles. It features a
fully dynamic type system and automatic memory management, similar to that of Scheme,
Ruby, Perl, and Tcl. Like other dynamic languages, Python is often used as a scripting
language, but is also used in a wide range of non-scripting contexts. Using third-party
tools, Python code can be packaged into standalone executable programs. Python interpreters
are available for many operating systems.
Perl is a high-level, general-purpose, interpreted, dynamic programming language.
Perl was originally developed by Larry Wall in 1987 as a general-purpose Unix scripting
language to make report processing easier. Since then, it has undergone many changes
and revisions and become widely popular amongst programmers. Larry Wall continues
to oversee development of the core language, and its upcoming version, Perl 6. Perl
borrows features from other programming languages including C, shell scripting (sh),
AWK, and sed.[5] The language provides powerful text processing facilities without
the arbitrary data length limits of many contemporary Unix tools, facilitating easy
manipulation of text files. Perl gained widespread popularity in the late 1990s
as a CGI scripting language, in part due to its parsing abilities.


Hello,
I'm having problems accessing my Pi via my home network.
I've found its IP address in the Home Network on my router and it's named 'RaspberryPi'. I have tried pasting this IP address in to a number of browsers and also pasting the IP address http://<IP_ADDRESS>/emoncms but I keep getting a 'cannot connect' message each time.
The LEDs on the pi are flashing aside from the SD card one (ACT) which flashes green on boot up but not after that. I've checked the SD card on my computer and it looks fine.
I've tried re-booting the pi and tried different ports on the routers but succuess.
Any suggestions?
Re: Problems finding RaspberryPi on home network
The syntax
http://<IP_ADDRESS>/emoncms/input/post?json={power:200}&apikey=[MYAPIKEY]
works on my WAMP and Firefox browser. I don't have a RPi so sorry I can't help any more.
Re: Problems finding RaspberryPi on home network
Try just http://<IP_ADDRESS> first; you should get the Apache default index page that says 'It works'. If so then at least you know the pi server is working and the problem is with the emoncms setup.
On a Windows box the host name you see in the router probably wont work until you add a line in your host file.
Re: Problems finding RaspberryPi on home network
You could try to 'ping <IP_ADDRESS>' , that would tell you if you pi was up at that address. If it's not able to connect check the dhcp list on your home router again (sometimes things move). If you have no joy, the next step is probably to plug in a monitor to your pi and see what it's saying.
Re: Problems finding RaspberryPi on home network
It's weird, none of the above work despite the fact the pi is clearly visible on my router home network....
...probably as Matt suggests next stage is attach a screen and see what's actually going on with the pi.
Thanks for the suggestions guys!
Re: Problems finding RaspberryPi on home network
Ping will tell you if the pi is working or not. I use an app called Fing on my Android phone to scan the local network and view the IP's of attached devices. It's a bit quicker than loggin into the router. If you're using the pre-built emoncms SD card for the pi the host name is set so you should just be able to browse to http://emoncmspi instead of messing around with IP addresses.
Re: Problems finding RaspberryPi on home network
Thanks Glyn, I've been able to logon to the pi now via Fing and an SSH client on my Android so I can see what's going on with the pi.
The message on the pi when logging in says:
"NOTICE: the software on this Raspberry Pi has not been fully configured. Please run 'sudo raspi-config'
I am using an SD card with the image downloaded from the OpenEnergyMonitor website rather than a pre-built emoncms SD card.
How should I communicate with the pi to see whether the emoncms software is working and diagnose why I can't login to the local dashboard...
Jonathan
Re: Problems finding RaspberryPi on home network
It works! Basically on the recommendation of Matt, I downloaded the latest emoncms SD card image and installed it on to my SD card.
Thanks for all your help!


My RSS 2.0 feed exposes end-to-end support for the comments specifications I'm aware of:
Several other folks are working on producing and/or consuming the <wfw:commentRss> extension as well, including Joe, Sam, Scott, JamesS and Kevin. JamesD posted instructions on how to do it with MoveableType. Hopefully Dare, Luke and Nick will follow suit.


Ctx |
|
|---|---|
An S4 class for a TileDB context |
|
Creates a |
|
Sets default context tags |
|
Sets a string:string "tag" on the Ctx |
|
Query if a TileDB backend is supported |
|
Retrieve a TileDB context object from the package cache |
|
Store a TileDB context object in the package cache |
|
Retrieve the |
|
Config |
|
An S4 class for a TileDB configuration |
|
Creates a |
|
Load a saved |
|
Save a |
|
Unset a TileDB Config parameter to its default value |
|
Convert a |
|
Convert a |
|
Prints the config object to STDOUT |
|
Gets a config parameter value |
|
Sets a config parameter value |
|
Array |
|
Creates a new TileDB array given an input schema. |
|
An S4 class for a TileDB dense array |
|
Constructs a tiledb_dense object backed by a persisted tiledb array uri |
|
An S4 class for a TileDB sparse array |
|
Constructs a tiledb_sparse object backed by a persisted tiledb array uri |
|
Selects attributes for the given TileDB array |
|
Retrieve attributes from |
|
Returns a list of all |
|
Returns a |
|
Returns a |
|
Returns the cell layout string associated with the |
|
Set datetimes_as_int64 toggle |
|
Retrieve datetimes_as_int64 toggle |
|
Retrieve the dimension (domain extent) of the domain |
|
Returns a list of |
|
Returns the |
|
Set data.frame extended return columns toggle |
|
Retrieve data.frame extended returns columns toggle |
|
Returns the offsets and coordinate filter_lists associated with the |
|
Returns TRUE if the tiledb_array_schema is sparse, else FALSE |
|
Set query_layout return values for the array |
|
Retrieve query_layout values for the array |
|
Set data.frame return toggle |
|
Retrieve data.frame return toggle |
|
Set marix return toggle |
|
Retrieve matrix.frame return toggle |
|
Return a schema from a tiledb_array object |
|
Set selected_ranges return values for the array |
|
Retrieve selected_ranges values for the array |
|
Prints a tiledb_array object |
|
Prints an array schema object |
|
Returns a TileDB array, allowing for specific subset ranges. |
|
Sets a tiledb array value or value range |
|
Returns the tile layout string associated with the |
|
An S4 class for a TileDB Array |
|
Constructs a tiledb_array object backed by a persisted tiledb array uri |
|
Close a TileDB Array |
|
Get the non-empty domain from a TileDB Array by index |
|
Get the non-empty domain from a TileDB Array by name |
|
Check for Heterogeneous Domain |
|
Check for Homogeneous Domain |
|
Open a TileDB Array |
|
Open a TileDB Array at Timestamp |
|
An S4 class for the TileDB array schema |
|
Constructs a |
|
Check the schema for correctness |
|
Returns logical value whether the array schema allows duplicate values or not. This is only valid for sparse arrays. |
|
Retrieve schema capacity (for sparse fragments) |
|
Sets toggle whether the array schema allows duplicate values or not. This is only valid for sparse arrays. |
|
Sets the schema capacity (for sparse fragments) |
|
Set a Filter List for Coordinate of a TileDB Schema |
|
Set a Filter List for Variable-Sized Offsets of a TileDB Schema |
|
Return the number of dimensions associated with the |
|
Selects attributes for the given TileDB array |
|
Retrieve attributes from |
|
Returns true is if the array or array_schema is sparse |
|
Set data.frame return toggle |
|
Retrieve data.frame return toggle |
|
Returns the |
|
Prints a tiledb_dense array object |
|
Gets a dense array value |
|
Sets a dense array value |
|
Selects attributes for the given TileDB array |
|
Retrieve attributes from |
|
Check if object is sparse |
|
Set data.frame return toggle |
|
Retrieve data.frame return toggle |
|
Return a schema from a sparse array |
|
Prints a tiledb_sparse array object |
|
Gets a sparse array value |
|
Sets a sparse array value |
|
Query a array using a subarray vector |
|
ArraySchema |
|
An S4 class for the TileDB array schema |
|
Constructs a |
|
Check the schema for correctness |
|
Returns logical value whether the array schema allows duplicate values or not. This is only valid for sparse arrays. |
|
Retrieve schema capacity (for sparse fragments) |
|
Sets toggle whether the array schema allows duplicate values or not. This is only valid for sparse arrays. |
|
Sets the schema capacity (for sparse fragments) |
|
Set a Filter List for Coordinate of a TileDB Schema |
|
Set a Filter List for Variable-Sized Offsets of a TileDB Schema |
|
Look up TileDB type corresponding to the type of an R object |
|
Get all Dimension and Attribute Names |
|
Get all Dimension and Attribute Types |
|
Returns a |
|
Return a schema from a URI character value |
|
Attribute |
|
An S4 class for a TileDB attribute |
|
Contructs a |
|
Get the TileDB Attribute cell size |
|
Return the number of scalar values per attribute cell |
|
Get the fill value for a TileDB Attribute |
|
Get the TileDB Attribute Nullable flag value |
|
Check whether TileDB Attribute is variable-sized |
|
Set the number of scalar values per attribute cell |
|
Set the fill value for a TileDB Attribute |
|
Set the TileDB Attribute Nullable flags |
|
Selects attributes for the given TileDB array |
|
Selects attributes for the given TileDB array |
|
Selects attributes for the given TileDB array |
|
Retrieve attributes from |
|
Returns a list of all |
|
Returns a |
|
Returns a |
|
Retrieve attributes from |
|
Retrieve attributes from |
|
|
|
Generic Methods |
Return the |
|
Sets the TileDB Filter List for the TileDB Attribute object |
|
Returns the TileDB Filter List object associated with the given TileDB Attribute |
|
Return the |
|
Prints an attribute object |
|
Check a schema for a given attribute name |
|
Filter |
|
An S4 class for a TileDB filter |
|
Constructs a |
|
Returns the filter's option |
|
An S4 class for a TileDB filter list |
|
Constructs a |
|
Returns the filter_list's max_chunk_size |
|
|
|
Set the filter_list's max_chunk_size |
Set the filter's option |
|
Returns the type of the filter used |
|
Sets the TileDB Filter List for the TileDB Attribute object |
|
Sets the TileDB Filter List for the TileDB Dimension object |
|
Returns the offsets and coordinate filter_lists associated with the |
|
Returns the TileDB Filter List object associated with the given TileDB Attribute |
|
Returns the TileDB Filter List object associated with the given TileDB Dimension |
|
|
|
Generic Methods |
FilterList |
|
Returns the filter_list's number of filters |
|
Returns the filter at given index |
|
An S4 class for a TileDB filter list |
|
Constructs a |
|
Returns the filter_list's max_chunk_size |
|
|
|
Set the filter_list's max_chunk_size |
Sets the TileDB Filter List for the TileDB Attribute object |
|
Sets the TileDB Filter List for the TileDB Dimension object |
|
Returns the offsets and coordinate filter_lists associated with the |
|
Returns the TileDB Filter List object associated with the given TileDB Attribute |
|
Returns the TileDB Filter List object associated with the given TileDB Dimension |
|
|
|
Generic Methods |
Domain |
|
An S4 class for a TileDB domain |
|
Constructs a |
|
Returns a Dimension indicated by index for the given TileDB Domain |
|
Returns a Dimension indicated by name for the given TileDB Domain |
|
Check a domain for a given dimension name |
|
|
|
Generic Methods |
Return the number of dimensions associated with the |
|
Returns the number of dimensions for a tiledb domain object |
|
Returns the number of dimensions of the |
|
Returns the tiledb_domain TileDB type string |
|
Returns a list of the tiledb_domain dimension objects |
|
Returns TRUE is tiledb_domain is an integral (integer) domain |
|
Prints an domain object |
|
Dim |
|
An S4 class for a TileDB dimension object |
|
Contructs a |
|
Retrieve the dimension (domain extent) of the domain |
|
Retrieves the dimension of the tiledb_dim domain |
|
Retrieve the dimension (domain extent) of the domain |
|
Returns a list of |
|
Returns a list of the tiledb_domain dimension objects |
|
|
|
Generic Methods |
Return the |
|
Return the |
|
Sets the TileDB Filter List for the TileDB Dimension object |
|
Returns the TileDB Filter List object associated with the given TileDB Dimension |
|
Return the |
|
Return the |
|
Returns the number of dimensions for a tiledb domain object |
|
Returns TRUE if the tiledb_dim is anonymous |
|
Queryquery object functions |
|
An S4 class for a TileDB Query object |
|
Creates a 'tiledb_query' object |
|
Set a range for a given query |
|
Set a range for a given query |
|
Allocate a Query buffer for reading a character attribute |
|
Allocate a Query buffer for reading a character attribute using a subarray |
|
Allocate a Query buffer for a given type |
|
Allocate and populate a Query buffer for a given object of a given data type. |
|
Allocate and populate a Query buffer for writing the given char vector |
|
Export Query Buffer to Pair of Arrow IO Pointers |
|
Finalize TileDB Query |
|
Retrieve content from a Query character buffer |
|
Retrieve content from a Query buffer |
|
Retrieve the estimated result size for a query and attribute |
|
Retrieve the estimated result size for a query and variable-sized attribute |
|
Retrieve the Number of Fragments for Query |
|
Retrieve the timestamp range for a given Query Fragment |
|
Retrieve the URI for a given Query Fragment |
|
Get TileDB Query layout |
|
Retrieve the query range for a query dimension and range index |
|
Retrieve the number of ranges for a query dimension |
|
Import to Query Buffer from Pair of Arrow IO Pointers |
|
Get TileDB Query result buffer elements |
|
Set TileDB Query buffer |
|
Assigns to a Query buffer for a given attribute |
|
Assign a buffer to a Query attribute |
|
Set TileDB Query layout |
|
Set subarray for TileDB Query object |
|
Get TileDB Query status |
|
Submit TileDB Query |
|
Submit TileDB Query asynchronously without a callback returning immediately |
|
Return TileDB Query type |
|
Group |
|
Creates a TileDB group object at given uri path |
|
Objectobject management functions |
|
List TileDB resources at a given root URI path |
|
Move a TileDB resource to new uri path |
|
Removes a TileDB resource |
|
Return the TileDB object type string of a TileDB resource |
|
Recursively discover TileDB resources at a given root URI path |
|
Returns TRUE if the tiledb_dim is anonymous |
|
Returns TRUE if the tiledb_dim is anonymous |
|
Consolidate fragments of a TileDB Array |
|
After consolidation, remove consilidated fragments of a TileDB Array |
|
MetaDataarrray metadata functionality |
|
Print a TileDB Array Metadata object |
|
Delete a TileDB Array Metadata object given by key |
|
Return a TileDB Array Metadata object given by key |
|
Return a TileDB Array Metadata object given by key |
|
Test if TileDB Array has Metadata |
|
Return count of TileDB Array Metadata objects |
|
Store an object in TileDB Array Metadata under given key |
|
Statsperformance stat collection functions |
|
Disable internal TileDB statistics counters |
|
Dumps internal TileDB statistics to file |
|
Enable internal TileDB statistics counters |
|
Print internal TileDB statistics |
|
Dumps internal TileDB statistics as JSON to file |
|
Gets internal TileDB statistics as JSON string |
|
Print internal TileDB statistics as JSON |
|
Reset internal TileDB statistics counters |
|
VFSvirtual file system functions |
|
An S4 class for a TileDB VFS object |
|
Creates a |
|
Close a TileDB VFS Filehandle |
|
Create a VFS Bucket |
|
Create a VFS Directory |
|
Empty a VFS Bucket |
|
Return VFS File Size |
|
Check for VFS Bucket |
|
Test for VFS Directory |
|
Check for empty VFS Bucket |
|
Test for VFS File |
|
Move (or rename) a VFS Directory |
|
Move (or rename) a VFS File |
|
Open a TileDB VFS Filehandle for reading or writing |
|
Read from a TileDB VFS Filehandle |
|
Remove a VFS Bucket |
|
Remove a VFS Directory |
|
Remove a VFS File |
|
Sync a TileDB VFS Filehandle |
|
Touch a VFS URI Resource |
|
Write to a TileDB VFS Filehandle |
|
Retrieve a TileDB VFS object from the package environment and cache |
|
Store a TileDB VFS object in the package environment |
|
DataFramedata.frame functionality functions |
|
Construct a data.frame from query results |
|
Create a TileDB dense or sparse array from a given |
|
Set data.frame return toggle |
|
Set data.frame return toggle |
|
Set data.frame return toggle |
|
Retrieve data.frame return toggle |
|
Retrieve data.frame return toggle |
|
Retrieve data.frame return toggle |
|
Convert a |
|
SparseMatrixsparse matrices helper functions |
|
Create (or return) a TileDB sparse array |
|
Arrowinterface to Arrow in-memory representation |
|
|
|
Allocate (or Release) Arrow Array and Schema Pointers |
Packagepackage and version information |
|
The version of the libtiledb library |
|
tiledb - Interface to the TileDB Storage Manager API |
|
Limit TileDB core use to a given number of cores |


RenderSender
- Render URL to image/PDF document and send via email
Send in PDF Format
(default is PNG)


Gradually change the background property:
The background property is a shorthand property for all background properties.
Only background-color, background-position, and background-size are animatable in CSS.
Note: CSS Animations do not work in Internet Explorer 9 and earlier versions.


The switch statement is used to perform different actions based on different conditions.
Use the switch statement to select one of many blocks of code to be executed.
This is how it works:
The getDay() method returns the weekday as a number between 0 and 6. (Sunday=0, Monday=1, Tuesday=2 ..)
Use the weekday number to calculate weekday name:
The result of day will be:
When the JavaScript code interpreter reaches a break keyword, it breaks out of the switch block.
This will stop the execution of more code and case testing inside the block.
|
When a match is found, and the job is done, it's time for a break. There is no need for more testing. |
The default keyword specifies the code to run if there is no case match:
The getDay() method returns the weekday as a number between 0 and 6.
If today is neither Saturday (6) nor Sunday (0), write a default message:
The result of text will be:
Sometimes, in a switch block, you will want different cases to use the same code, or fall-through to a common default.
Note from the next example, that cases can share the same code block, and that the default case does not have to be the last case in a switch block:
| If default is not the last case in the switch block, remember to end it with a break. |


|
Table PIT_MESSAGE
central log message repository in various languages.
|
|
Name
|
Type
|
Optional
|
Default
|
Comments
|
|
PMS_NAME
|
VARCHAR2(128)
|
|
|
Unique message name. Used to reference the message as a constant in package MSG.
|
|
PMS_PMG_NAME
|
VARCHAR2(128)
|
Y
|
|
Unique message grup name. Reference to PIT_MESSAGE_GROUP.
|
|
PMS_PML_NAME
|
VARCHAR2(128)
|
|
|
Languae reference of the message. Taken from Oracle v$nls_valid_values
|
|
PMS_TEXT
|
CLOB
|
Y
|
|
Optional description to further describe the error or provide help on how to solve the issue
|
|
PMS_DESCRIPTION
|
CLOB
|
Y
|
|
|
|
PMS_PSE_ID
|
NUMBER(3)
|
Y
|
|
severity of the message. Reference to PIT_MESSAGE_SEVERITY
|
|
PMS_CUSTOM_ERROR
|
NUMBER
|
Y
|
|
Optional pointer to an oracle error number. If null, an exception will be generated. To define custom errors, use null.
|
|
PMS_ACTIVE_ERROR
|
NUMBER
|
Y
|
|
If a custom error number of -20000 is used, this field contains the actual error number as processed by PIT_ADMIN.CREATE_MESSAGE_PACKAGE.
|
|
PMS_ID
|
VARCHAR2(128)
|
Y
|
CASE "PMS_PML_NAME" WHEN 'GERMAN' THEN "PMS_NAME" ELSE NULL END
|
Virtual column as a surrogate primary key for references
|


Founded in 1967 as a non-profit corporation (#ES 6325) with mental health focus
Began as Paquette House, a 12 bed co-ed community based residential facility (24/7 staffing)
1982 name changed to Robert E. Berry House in memory of Robert Berry, Fond du Lac Department of Community Programs Mental Health Director who died in an accident.
1995 downsized to 8 beds
2000 - Established Ahern House - named for Patricia Ahern, long-time member of BH Board of Directors; located 100-102 Marquette St.; supported apartment concept - duplex with 3 bedrooms on each side; co-ed; preferably was a prior resident of Berry House
April 19, 2013 - Purchased 2 homes on 1 city parcel at 193 & 195 7th Street
May 1, 2013 first resident admitted to 195 7th St; 193 7th St. tenancy began Jan 2014; Each have capacity to house 4.
January 9, 2014 7th Street Houses named Heller Houses in honor of Melvin Heller, long-time member of BH Board of Directors


Here at Heavenly Pizza, we believe in quality ingredients for a good price. You won't find a better pizza anywhere in the mortal realm. It's pizza so good it makes the angels sing.
More than one meat will cost $2.00 extra per meat.
Lamb will cost $1.00 extra on its own, and $3.00 extra as a second meat.
More than two will cost $1.50 per extra topping.


Properties
camera
camera: any
cameraStart
cameraStart: any[] = []
canvas
canvas: any
clickSelections
isHorizontalPanEnabled
isHorizontalPanEnabled: boolean = true
isLassoEnabled
isLassoEnabled: boolean = true
isPanEnabled
isPanEnabled: boolean = true
lassoEndHandler
lassoEndHandler: any
lassoMoveHandler
lassoMoveHandler: any
lassoPoints
lassoPoints: any[] = []
lassoStartHandler
lassoStartHandler: any
lastIntersectedElements
lastIntersectedElements: any[] = []
lastIntersectedSelections
lastIntersectedSelections: any[] = []
mouse
mouse: any[] = []
mouseDown
mouseDown: boolean = false
mouseDownSelections
mouseMoveSelections
mouseOutSelections
mouseOverSelections
mouseStart
mouseStart: any[] = []
mouseUpSelections
panOffset
panOffset: any[] = []
raycaster
raycaster: any
scene
scene: any


Template Options
Wide
Boxed
Default header
Fixed dark
Static light
Static dark
Toggle navigation
Home
tour packages
Tour Packages Grid View
Packages Sidebar Left
Packages Sidebar Right
Packages 3 Columns
Tour Packages List View
Packages Sidebar Left
Packages Sidebar Right
Packages List
Single Package
Package Sidebar Left
Package Sidebar Right
Package Fullwidth
Booking Steps
Step 1 - Personal Info
Step 2 - Payment Info
Step 3 - Confirmation
Destinations
Destination Cities
Single Destination
PAGES
About Us
Contact Us
Gallery
Gallery Grid
Gallery Masonry
Photo Slider
404 Not Found
Coming Soon
Blog
Blog Grid View
Blog Grid 3 Col
Blog Grid 2 Col
Blog List View
Blog List Right Sidebar
blog-list-left-sidebar.html
Blog List Fullwidth
Single Blog Post
Right Sidebar
Left Sidebar
shortcodes
Accordions & Toggles
Tabs & Dropdowns
Pricing Tables
Search
Booking Step 1
1. personal info
2. payment info
3. Confirmation
personal info
First Name
Last Name
Address 1
Address 2
City
Zip Code
State/Region
Country
Requirements
I have read and accept the
terms and conditions
back
next


There is an specific style for titles slides

Your Institution

Your Title

Some subtitle
 <address class="author"> The author! </address>


Insurance Service Call Prediction
----- Insuranc-------------
Under what circumstances should we step off a path? When is it essential that we finish what we start?  If I ended a relationship with a woman who...
[Read More]


Bus Mall Focus Group
Click on the image you like best in the group of three you are shown.
Click to Show Analytics
If clicked prior to voting, please click again to refresh results.
Product Selection Based on Popularity
Analytics will be shown upon completion.
Total Amount of Times an Image was Shown
Analytics will be shown upon completion.
Comparison Between Votes and Offerings
Analytics will be shown upon completion.


Home Station Equipments LOG Photos/Videos
VU6P Station Equipments
| Main operational rig will be ICOM
IC7100 and additionally, IC-718, Kenwood TS-550S and a SDR based on Peaberry
(VUSDR by VU2ZAZ), capable of all band operation (QRP 5 Watts). We may use
digital modes on higher bands.
Balun 4:1 (Red toroid) for connecting antenna tuner to 300 Ohm homebrew ladder line (with 320 electrical wire) and TV ribbon cable Balun 1:1 (Ferrite FT-200-60) for usign at the feed point of W8010 or Fan dipole. IC-2200H for VHF - If ducting is good, we could reach lot of VHF operators through VU2TCD repeater having a reach radius of up to 300 miles. |
|
|
| Multiband (40M, 20M and 10M fan dipole with coaxial cable balun was used in last year Lighthouse weekend activities. Had good results with it. This year this antenna will be used as spare. |
Hygain tape doublet antenna lying around for several years in my junkbox. Had to open it up and clean up the contacts. It is definitely vintage, came from military junk. I will be trying this antenna in this lighthouse event. Will probably use the 1:1 balun with this.
| Try Morseit ringtone software for Android
Devices. Click Here for more details. Available in Google Play Store https://play.google.com/store/apps/details?id=com.vu3rgk.Morseit |
Home Station Equipments LOG Photos/Videos


See also Chapter 4.
See also Chapter 12.


JavaScript is disabled on your browser.
Skip navigation links
Overview
Package
Class
Use
Tree
Deprecated
Index
Help
Prev
Next
Frames
No Frames
All Classes
SEARCH:
JavaScript is disabled on your browser.
Hierarchy For Package crypt
Package Hierarchies:
All Packages
Class Hierarchy
java.lang.Object
crypt.
BenutzerSpielsprache
crypt.
Caesar_test
crypt.
Chiffre
crypt.
ADFGX
crypt.
Affine
crypt.
Bacon
crypt.
Caesar
crypt.
Gartenzaun
crypt.
Hill
crypt.
Multiplikativ
crypt.
OneTimePad
crypt.
Permutation
crypt.
Spaltentransposition
crypt.
Vigenere
crypt.
Doppelwuerfel
crypt.
Haeufigkeitsanalyse
crypt.
Hill_test
crypt.
MatrixTools
crypt.
Options
crypt.
Spielsprache
crypt.
Alpha_Bin
crypt.
AlphaIndex
crypt.
Anagramm
crypt.
ASCII_Bin
crypt.
ASCII_Hex
crypt.
BI_language
crypt.
Bobsprache
crypt.
Hex_Bin
crypt.
Loeffelsprache
crypt.
Morse
crypt.
NATO_Alphabet
crypt.
Pseudo_Text
crypt.
PseudoText
crypt.
Test
crypt.
Tools
crypt.
Tools_test
crypt.
Trans_Test
Skip navigation links
Overview
Package
Class
Use
Tree
Deprecated
Index
Help
Prev
Next
Frames
No Frames
All Classes
JavaScript is disabled on your browser.


Desilting of Adyar till estuary begins
CRA reviews eco-restoration work on rivers
by Special CorrespondentAfter getting CRZ clearance for the Adyar river eco-restoration project a month ago, the Water Resources Department has started work on desilting a portion of the Adyar river from the Maraimalai Nagar Bridge to the estuary.
On Saturday, Commissioner of Revenue Administration J. Radhakrishnan reviewed eco-restoration works taken up in the Adyar and Cooum rivers.
WRD has taken up the ₹94.76-crore project on the 25-km stretch between the Tiruneermalai Bridge and the Adyar estuary. While improvement works on the portion till the Maraimalai Nagar Bridge was being done since June, the Department recently started the desilting exercise on the stretch till the Adyar estuary.
Besides removing silt from the waterway, the Department will also be widening the river to its original width and building retaining walls on both sides of the river banks to prevent inundation in neighbouring areas.
Concrete retaining walls for a distance of 1,800 m has been proposed to be constructed in vulnerable areas. So far, nearly 800 m of retaining wall has been built.
Of the 11,400 encroachments identified along the Adyar river, nearly 4,515 encroached structures have been removed so far, said Mr. Radhakrishnan, in an official release.
WRD is also executing the Cooum river eco-restoration project at a cost of ₹93.57 crore through the Chennai Rivers Restoration Trust.
Nearly 80% of the work has been completed so far. Similar works , are being taken up, including forming of a baby canal, are being taken up at the Cooum river. Of the 16,598 encroachments identified, 11,890 structures have been removed so far, he said.
Officials of the Greater Chennai Corporation and WRD were present during his review.


JMAP Proxy
[% sessions %]Oauth to a Gmail or AOL account, or log in to an IMAP server below:
The JMAP proxy is a work in a progress. It is currently stable enough to test out and get a feel for JMAP in action. All the methods in the spec are implemented, though some atomic guarantees are not possible with other users accessing your servers at the same time
The eventual goal is to have a proxy you can stick in front of any IMAP server and get a usable JMAP out the other end. The proxy supports Gmail and modern IMAP implementations (it will be quite inefficient if they don't implement CONDSTORE). Source code is available on GitHub and is MIT licensed.
The web client hooked up for this demo is a simple example (no compose, contacts, calendars). It is also MIT licenced and available on GitHub. The code is unminified, so takes much longer to initially load than it would in a production setting, but can be viewed with standard web-dev tools. These can also show the data exchanges being made to load the data and get delta updates.
The service is not running with all of the security measures employed on a production site such as FastMail, so DO NOT USE THIS PROXY FOR ACCOUNTS WITH SENSITIVE DATA.
When you create your account, the most recent 50 emails will be downloaded in their entirety, so the first page should be snappy immediately. After that, you are redirected to the landing page. A background task will continue to pull in batches of messages and add them to your account, so you will see older messages appear while you are using the interface.


The inspiration for this page comes from this image I found on reddit many winters ago while I was in college. I spent ten forty-five minutes or so casually glancing intently staring at the letters, thinking I found the answer only to be foiled by the last letter (BONOBBO still counts doesn't it?). That's when I got to thinking, "There is NO way somebody made this one letter at a time." And I began thinking about creating one of these myself.
Creating the array of letters was easy enough: simply make rows and columns, and fill them with letters; you can use the entire alphabet, or (to make things more interesting) just use the letters from the word(s) in the list. That was the easy part, but things get a little tricky when you think about about making sure there was a solution to the puzzle (after all, who wants to spend two hours staring at a word search only to realize the answers weren't in there?)
In order to ensure that the puzzle would have at least one solution, the program (cheats a little bit, and) keeps track of all the instances the first letter of each word appeared in the crossword (so all the A's, M's and T's in this example). Later, the program looks at those letters (and the letters around them) to search for a solution. This idea was inspired by my own strategy when solving a crossword, except this happens 30,000 times faster. If no solution is found for a particular word, the program inserts a solution randomly somewhere in the puzzle (with a random direction as well), and then checks for all the solutions again (in case another solution got overwritten in the process).
There are still a few bugs in the code that powers this page, but once those are fixed I will release different word searches.