d8e1ce5f481a140c56f6ea6f086fd2c073c4245c
Ruby-and-Rails-questions.md
... | ... | @@ -0,0 +1,78 @@ |
1 | +1. What does this print, and why? |
|
2 | + |
|
3 | + name = nil |
|
4 | + puts "#{name}" |
|
5 | + |
|
6 | +2. What will this do? |
|
7 | + |
|
8 | + class Parent |
|
9 | + |
|
10 | + def message |
|
11 | + "Something in a private method" |
|
12 | + end |
|
13 | + private :message |
|
14 | + |
|
15 | + end |
|
16 | + |
|
17 | + class Child < Parent |
|
18 | + def use_message |
|
19 | + puts message |
|
20 | + end |
|
21 | + end |
|
22 | + |
|
23 | + child = Child.new |
|
24 | + child.use_message |
|
25 | + |
|
26 | + parent = Parent.new |
|
27 | + puts parent.message |
|
28 | + |
|
29 | +3. Here's what you know about the relationships between clinics and doctors. |
|
30 | + |
|
31 | + A clinic has many doctors. |
|
32 | + A doctor has many patients. |
|
33 | + |
|
34 | + To make this more concrete, let's say that there's a clinic with name "Chicago." There are two doctors with names "Smith" and "Snow." Both belong to the "Chicago" clinic. |
|
35 | + |
|
36 | + What Rails commands would you type to generate these models? What, if anything, would have to edit in the models so that you could type the following into the rails console: |
|
37 | + |
|
38 | + chicago = Clinic.create!(name: 'Chicago') |
|
39 | + chicago.doctors.create!(name: 'Smith') |
|
40 | + chicago.doctors.create!(name: 'Snow') |
|
41 | + chicago.doctors |
|
42 | + |
|
43 | + and get output something like this: |
|
44 | + |
|
45 | + => #<ActiveRecord::Associations::CollectionProxy [#<Doctor id: 1, name: "Smith", clinic_id: 1, created_at: "2015-11-02 21:18:48", updated_at: "2015-11-02 21:18:48">, #<Doctor id: 2, name: "Snow", clinic_id: 1, created_at: "2015-11-02 21:19:49", updated_at: "2015-11-02 21:19:49">]> |
|
46 | + |
|
47 | + Typical answer: |
|
48 | + |
|
49 | + rails generate model clinic name:string |
|
50 | + rails generate model doctor name:string clinic:references |
|
51 | + rails generate model patient name:string doctor:references |
|
52 | + # You would also have to add `has_many :doctors` to the `Clinic` class. |
|
53 | + |
|
54 | +4. There's a change in the business. Now, a doctor can belong to many clinics. How would you change your code? |
|
55 | + |
|
56 | +5. Let's discuss this: |
|
57 | + |
|
58 | + double_anything_but_10_a = lambda { |x| return if x == 10; x * 2 } |
|
59 | + double_anything_but_10_b = Proc.new { |x| return if x == 10; x * 2 } |
|
60 | + |
|
61 | + puts double_anything_but_10_a[3] |
|
62 | + puts double_anything_but_10_b[5] |
|
63 | + |
|
64 | + puts double_anything_but_10_a[10] |
|
65 | + puts double_anything_but_10_b[10] |
|
66 | + |
|
67 | +6. Here are some methods on the `Enumerable` module. They all take a block so that you can iterate through the collection. |
|
68 | + |
|
69 | + each |
|
70 | + cycle |
|
71 | + inject |
|
72 | + map |
|
73 | + partition |
|
74 | + reduce |
|
75 | + |
|
76 | + Which one would you use to create a new collection where you do something to each item in the original collection? |
|
77 | + |
|
78 | + Which one would you use to sum up all of the values in a collection of integers? |
ansible.md
... | ... | @@ -0,0 +1,28 @@ |
1 | +#### Installation |
|
2 | + |
|
3 | +* `brew install python` |
|
4 | +* then `pip install ansible` |
|
5 | + |
|
6 | +### Basics |
|
7 | + |
|
8 | +#### Need an `inventory` file that looks like this |
|
9 | + |
|
10 | +``` |
|
11 | +[example] |
|
12 | +localhost |
|
13 | +``` |
|
14 | + |
|
15 | +#### Commands |
|
16 | + |
|
17 | +* `ansible -i whatever` -- specify the inventory host path |
|
18 | + |
|
19 | + ``` |
|
20 | + $ ansible -i inventory example -m ping |
|
21 | + jgn.local | SUCCESS => { |
|
22 | + "changed": false, |
|
23 | + "ping": "pong" |
|
24 | + } |
|
25 | + ``` |
|
26 | + |
|
27 | +* `ansible -m modulename` -- e.g., `modulename` might be `ping` |
|
28 | +* `ansible -a "df -kh"` -- e.g., `-a` is module args, but gets passed directly (?) |
aws-windows.md
... | ... | @@ -0,0 +1,17 @@ |
1 | +### To create a Windows instance in a specific VPC |
|
2 | + |
|
3 | +1. Pick an AMI. This will be a dedicated instance in a VPC, so the "free tier" won't work. Try the one that is `Microsoft Windows Server 2012 R2 with SQL Server Express - ami-a330b3b4`. |
|
4 | +1. Size: `m3.medium` |
|
5 | +1. Network: Pick the VPC (e.g., for Iora: `vpc-... production`) |
|
6 | +1. Pick the subnet - it should be `subnet-9c801fc5...public subnet` |
|
7 | +1. For Auto-assign Public IP: `Enable` |
|
8 | +1. Tag: Key = "Name" Value = "hipaa-risk-tool" |
|
9 | +1. Security group: Use the existing group `rdp from nest` |
|
10 | +1. Use the `iora-production` keypair - make sure you have the `.pem` file for whatever keeper you pick |
|
11 | +1. Launch |
|
12 | + |
|
13 | +### To get a password |
|
14 | + |
|
15 | +1. After launch, select Actions / Retrieve password |
|
16 | +2. Paste in the text of the `.pem` file associated with the keeper |
|
17 | + |
aws.md
... | ... | @@ -0,0 +1,22 @@ |
1 | +### Logging in to IAM |
|
2 | + |
|
3 | +https://7fff.signin.aws.amazon.com/console |
|
4 | + |
|
5 | +### |
|
6 | + |
|
7 | +Authorizations needed to do IAM |
|
8 | + |
|
9 | +* iam:GetAccountSummary |
|
10 | +* iam:ListAccountAliases |
|
11 | + |
|
12 | +### Make sure to enable IAM for Billing |
|
13 | + |
|
14 | +See <https://blogs.aws.amazon.com/security/post/Tx2255RUMJGC96Y/Don-t-Forget-to-Enable-Access-to-the-Billing-Console> |
|
15 | + |
|
16 | +Go here: <https://console.aws.amazon.com/billing/home#/account> |
|
17 | + |
|
18 | +Then click Edit for "IAM User Access to Billing Information" |
|
19 | + |
|
20 | +Then Check "Activate IAM Billing access" and click Update |
|
21 | + |
|
22 | + |
awscli.md
... | ... | @@ -0,0 +1,22 @@ |
1 | +1. Install with |
|
2 | + |
|
3 | + pip install awscli |
|
4 | + |
|
5 | +2. Configure like so |
|
6 | + |
|
7 | + ``` |
|
8 | + $ aws configure |
|
9 | + AWS Access Key ID [None]: 0JCM42F53N9EAXVANT82 |
|
10 | + AWS Secret Access Key [None]: [removed] |
|
11 | + Default region name [None]: |
|
12 | + Default output format [None]: |
|
13 | + ``` |
|
14 | + |
|
15 | +3. Example commands |
|
16 | + |
|
17 | + ``` |
|
18 | + aws s3 ls |
|
19 | + aws s3 mb s3://mybucket |
|
20 | + aws s3 ls mybucket |
|
21 | + aws s3 rm s3://mybucket --include "*" --recursive |
|
22 | + ``` |
bash.md
... | ... | @@ -0,0 +1,32 @@ |
1 | +### |
|
2 | + |
|
3 | +Webserver |
|
4 | + |
|
5 | +``` |
|
6 | +#!/bin/bash |
|
7 | +# web.sh -- http://localhost:9000/hello?world |
|
8 | + |
|
9 | +RESP=/tmp/webresp |
|
10 | +[ -p $RESP ] || mkfifo $RESP |
|
11 | + |
|
12 | +while true ; do |
|
13 | +( cat $RESP ) | nc -l -p 9000 | ( |
|
14 | +REQ=`while read L && [ " " "<" "$L" ] ; do echo "$L" ; done` |
|
15 | +echo "[`date '+%Y-%m-%d %H:%M:%S'`] $REQ" | head -1 |
|
16 | +cat >$RESP <<EOF |
|
17 | +HTTP/1.0 200 OK |
|
18 | +Cache-Control: private |
|
19 | +Content-Type: text/plain |
|
20 | +Server: bash/2.0 |
|
21 | +Connection: Close |
|
22 | +Content-Length: ${#REQ} |
|
23 | + |
|
24 | +$REQ |
|
25 | +EOF |
|
26 | +) |
|
27 | +done |
|
28 | +``` |
|
29 | + |
|
30 | +Remove -p on nc for it to work on OS/X. |
|
31 | + |
|
32 | +<http://paulbuchheit.blogspot.ca/2007/04/webserver-in-bash.html> |
blocks-open-closed.md
... | ... | @@ -0,0 +1,11 @@ |
1 | +1. Show diagram of modules, a big one (A) that does the main deploy, and a small one (x) that an individual developer writes |
|
2 | +2. CEO asks that a deploy message be changed. |
|
3 | +3. Dev has to change A. Very costly, has to go through QA, etc. |
|
4 | +4. CEO asks for another change. Same thing. |
|
5 | +5. CEO asks for another change. This time the dev alters A so that a little behavior can be injected. That goes through QA. Now the dev makes his change in x. |
|
6 | +6. CEO asks for another change. No problem; change made in x. |
|
7 | +7. Show with Ruby blocks. |
|
8 | +8. Show with Java interfaces. |
|
9 | +9. Talk about Matz's good taste. |
|
10 | +10. Open/closed Principle: <http://en.wikipedia.org/wiki/Open/closed_principle> and <http://www.objectmentor.com/resources/articles/ocp.pdf> |
|
11 | + |
bootstrap.md
... | ... | @@ -0,0 +1,128 @@ |
1 | +Bootstrap requires jQuery for its JavaScript components to work. Go to jquery.com20 and download jQuery version 1.11.0. Bootstrap supports Internet Explorer 8 and above. If you download jQuery version 2, IE8+ will fail to function properly because |
|
2 | +20 http://jquery.com/ |
|
3 | +12 Jump Start Bootstrap |
|
4 | +jQuery has officially opted out of support for IE8 in versions 2 and above. Hence, jQuery 1.11.0 is needed, the latest version of jQuery 1. |
|
5 | + |
|
6 | +#### Template document |
|
7 | + |
|
8 | +* `<meta charset="utf-8">` because: Force unicode |
|
9 | +* `<meta http-equiv="X-UA-Compatible" content="IE=edge">` because: Keeps IE from running in compat mode |
|
10 | +* `<meta name="viewport" content="width=device-width, initial-scale=1">` because: consume all space in browser window |
|
11 | +* Comments for IE: Support for HTML5 and CSS3 |
|
12 | + |
|
13 | +``` |
|
14 | +<!DOCTYPE html> |
|
15 | +<html lang="en"> |
|
16 | + <head> |
|
17 | + <meta charset="utf-8"> |
|
18 | + <meta http-equiv="X-UA-Compatible" content="IE=edge"> |
|
19 | + <meta name="viewport" content="width=device-width, initial-scale=1"> |
|
20 | + <title>Bootstrap Grid System</title> |
|
21 | + <link rel="stylesheet" type="text/css" href="css/bootstrap.css"> |
|
22 | + <link rel="stylesheet" type="text/css" href="css/styles.css"> |
|
23 | + <!--[if lt IE 9]> |
|
24 | + <script src="https://oss.maxcdn.com/libs/html5shiv/3.7.0/html5shiv.js"></script> |
|
25 | + <script src="https://oss.maxcdn.com/libs/respond.js/1.4.2/respond.min.js"></script> <![endif]--> |
|
26 | + </head> |
|
27 | + <body> |
|
28 | + <div class="container"> |
|
29 | + <!-- Content here --> |
|
30 | + </div> |
|
31 | + <script src="js/jquery-1.11.2.min.js"></script> |
|
32 | + <script src="js/bootstrap.js"></script> |
|
33 | + </body> |
|
34 | +</html> |
|
35 | +``` |
|
36 | + |
|
37 | +#### Grid system |
|
38 | + |
|
39 | +* up to 12 columns |
|
40 | +* Put everything in a container. `container` is fixed-width and appears at the center of the screen, `container-fluid` is fluid width. |
|
41 | +* Have a singer container with all rows |
|
42 | +* E.g., inside container, multiple `<div class="row"> <!-- content --> </div>` |
|
43 | + |
|
44 | +#### Column classes |
|
45 | + |
|
46 | +* `col-xs-6` means: span 6 columns. **NOTE:** The idea of **span** is important, since the span can be offset. I.e., the item is not "taking up six columns" where it starts, but is going to span 6 columns, which can be offset (offset class example: `col-xs-6 col-xs-offset-3 col1`). |
|
47 | +* `xs` is a class prefix. Options |
|
48 | + 1. col-xs for extra small displays (screen width < 768px) |
|
49 | + 2. col-sm for smaller displays (screen width >= 768px) |
|
50 | + 3. col-md for medium displays (screen width >= 992px) |
|
51 | + 4. col-lg for larger displays (screen width >= 1200px) |
|
52 | +* You can also target different sizes at the same time. E.g., `col-xs-12 col-sm-6` means: "each column in an extra small-sized display will occupy all the 12 available Bootstrap columns, which will appear as a stack of columns. Yet on a smaller display, they will occupy only six Bootstrap columns each to achieve a two-column layout." Another example: `col-md-4 col-sm-6` means that for medium and larger, each item uses 4 of the columns (so 3 items per line), while on a small display, it uses 6 (2 items per line). |
|
53 | +* For desktop, use `col-md-` unless you need to target something really big |
|
54 | +* Note that if the number of columns in a row goes greater than 12, then the next columns flow to the next "line" (so you don't have to create a new row). **This is important** because we will want to change the number of columns used per line based on the size of the target display. If we introduced a new row every "3" columns, then we would be forcing the row change for larger or smaller displays. We would rather this happen automatically. |
|
55 | +* Once inside of an item in a row, you can create a new row which itself gets items that can span up to 12 columns. For example: |
|
56 | + |
|
57 | + <div class="container"> |
|
58 | + <div class="row"> |
|
59 | + <div class="col-md-6 col1"> |
|
60 | + <h3>Column 1</h3> |
|
61 | + <!-- Nesting Starts --> |
|
62 | + |
|
63 | + <div class="row"> |
|
64 | + <div class="col-md-6 col3"> |
|
65 | + <h3>Column 4</h3> |
|
66 | + </div> |
|
67 | + <div class="col-md-6 col4"> |
|
68 | + <h3>Column 5</h3> |
|
69 | + </div> |
|
70 | + </div> |
|
71 | + </div> |
|
72 | + <div class="col-md-6 col2"> |
|
73 | + <h3>Column 2</h3> |
|
74 | + </div> |
|
75 | + </div> |
|
76 | + </div> |
|
77 | + |
|
78 | +#### Offsets |
|
79 | + |
|
80 | +You can offset a span with, say, `col-xs-offset-3` meaning "offset 3 columns to the right." This is usually used to increase the left margin. With a class setting such as `col-xs-6 col-xs-offset-3` you are effectively centering. |
|
81 | + |
|
82 | +#### Push and Pull |
|
83 | + |
|
84 | +Items can be pushed (to the right) and pulled (to the left). Example: |
|
85 | + |
|
86 | +``` |
|
87 | +<div class="container"> |
|
88 | + <div class="col-xs-9 col-xs-push-3"> |
|
89 | + <h1>Pushed Column</h1> |
|
90 | + </div> |
|
91 | + <div class="col-xs-3 col-xs-pull-9"> |
|
92 | + <h1>Pulled Column</h1> |
|
93 | + </div> |
|
94 | +</div> |
|
95 | +``` |
|
96 | + |
|
97 | +#### Page header |
|
98 | + |
|
99 | +``` |
|
100 | +<div class="container"> |
|
101 | + <div class="page-header"> |
|
102 | + <h1>Chapter 3</h1> |
|
103 | + </div> |
|
104 | +</div> |
|
105 | +``` |
|
106 | + |
|
107 | +#### Panel |
|
108 | + |
|
109 | +Goes inside a container. The `panel-default` can be replaced with `panel-<style>` where style is `primary`, `success`, `info`, `warning`, `danger`. |
|
110 | + |
|
111 | +``` |
|
112 | +<div class="panel panel-default"> |
|
113 | + <div class="panel-heading"> |
|
114 | + ATTENTION |
|
115 | + </div> |
|
116 | + <div class="panel-body"> |
|
117 | + Lorem ipsum dolor sit ametnim ... |
|
118 | + </div> |
|
119 | + <div class="panel-footer"> |
|
120 | + <a href="#" class="btn btn-danger btn-sm">Agree</a> |
|
121 | + <a href="#" class="btn btn-default btn-sm">Decline</a> </div> |
|
122 | + </div> |
|
123 | +</div> |
|
124 | +``` |
|
125 | + |
|
126 | +#### Bootstrap helpers |
|
127 | + |
|
128 | +* `text-center` (on a `div`, e.g., `<div class="col-md-12 text-center">`) |
|
... | ... | \ No newline at end of file |
box.md
... | ... | @@ -0,0 +1,32 @@ |
1 | +### How to put Box onto external drive |
|
2 | + |
|
3 | +1. Quit out of Box sync; in Activity Monitor, kill Box Sync, Box Sync Monitor, and Box Edit |
|
4 | + |
|
5 | +1. Remove Box sync |
|
6 | + |
|
7 | + sudo rm -fR /Applications/Box\ Sync.app/ |
|
8 | + |
|
9 | +2. For all users, move old ~/Box Sync out of the way (or remove it altogether if you're confident) |
|
10 | + |
|
11 | + mv $HOME/Box\ Sync/ $HOME/Box\ Sync_old |
|
12 | + |
|
13 | +3. For all users, remove the Application Support and logs for Box Sync |
|
14 | + |
|
15 | + rm -fR $HOME/Library/Application\ Support/Box/Box\ Sync/ |
|
16 | + rm -fR $HOME/Library/Logs/Box/Box\ Sync/ |
|
17 | + |
|
18 | +4. Empty trash |
|
19 | + |
|
20 | +5. `sudo vim /Library/Preferences/com.box.sync.plist` and enter, where `/Volumes/Iora/BoxSync/` is the external location. |
|
21 | + |
|
22 | + <!--?xml version="1.0" encoding="UTF-8"?--> |
|
23 | + <plist version="1.0"> |
|
24 | + <dict> |
|
25 | + <key>SyncRootFolder</key> |
|
26 | + <string>/Volumes/Iora/BoxSync/</string> |
|
27 | + </dict> |
|
28 | + </plist> |
|
29 | + |
|
30 | +6. Reboot! |
|
31 | + |
|
32 | +7. Re-install Box |
boxen-creating-branch.md
... | ... | @@ -0,0 +1,14 @@ |
1 | +1. fork |
|
2 | +2. clone |
|
3 | + |
|
4 | + git clone git@github.com:IoraHealth/puppet-postgresql.git ih-puppet-postgresql |
|
5 | + git remote add upstream https://github.com/boxen/puppet-postgresql.git |
|
6 | + |
|
7 | +3. Before commencing work |
|
8 | + |
|
9 | + git fetch upstream |
|
10 | + git rebase upstream/master |
|
11 | + |
|
12 | +4. Make changes |
|
13 | + |
|
14 | + |
boxen-remove-service.md
... | ... | @@ -0,0 +1,6 @@ |
1 | +Something like |
|
2 | + |
|
3 | + sudo launchctl remove dev.redis |
|
4 | + rm -fR /opt/boxen/homebrew/Cellar/redis |
|
5 | + rm -fR /opt/boxen/repo/.tmp/librarian/cache/source/puppet/githubtarball/*/redis* |
|
6 | + rm /opt/boxen/repo/vendor/puppet/cache/*redis*.tar.gz |
boxen-remove.md
... | ... | @@ -0,0 +1,8 @@ |
1 | +### Removing Boxen completely |
|
2 | + |
|
3 | +``` |
|
4 | +/opt/boxen/repo |
|
5 | +script/nuke --all |
|
6 | +rm -fR /Library/Caches/Homebrew* |
|
7 | +sudo rm -fR /opt/boxen |
|
8 | +``` |
|
... | ... | \ No newline at end of file |
boxen-stop-nginx.md
... | ... | @@ -0,0 +1 @@ |
1 | + sudo launchctl remove dev.nginx |
brew.md
... | ... | @@ -0,0 +1,10 @@ |
1 | +#### Get up-to-date |
|
2 | + |
|
3 | +`brew update` |
|
4 | + |
|
5 | +#### Upgrade a single package |
|
6 | + |
|
7 | +`brew upgrade wget` |
|
8 | + |
|
9 | + |
|
10 | + |
business.md
... | ... | @@ -0,0 +1,4 @@ |
1 | +* comp - <http://designerfund.com/bridge/how-to-understand-and-negotiate-your-startup-compensation/> |
|
2 | +* stock and options |
|
3 | + * http://blog.samaltman.com/employee-equity |
|
4 | + * http://jvns.ca/blog/2015/12/30/do-the-math-on-your-stock-options/ |
canopy-docs.md
... | ... | @@ -0,0 +1,126 @@ |
1 | +### How to log in with a username/password combination, bypassing Okta/SAML |
|
2 | + |
|
3 | +Browse to https://canopy.iorahealth.com/login.action |
|
4 | + |
|
5 | +### Finding key system data |
|
6 | + |
|
7 | +Browse to <https://canopy.iorahealth.com/admin/systeminfo.action> |
|
8 | + |
|
9 | +You can see the `Confluence Home` under `Confluence Information`: For Canopy, the `Confluence Home` is |
|
10 | +`/home/deployer/confluence-data` |
|
11 | + |
|
12 | +Other key definitions here: |
|
13 | + |
|
14 | +* Server ID |
|
15 | +* Support Entitlement Number (SEN) |
|
16 | + |
|
17 | +### The "Confluence Home" |
|
18 | + |
|
19 | +The Confluence Home may be found at <https://canopy.iorahealth.com/admin/systeminfo.action> |
|
20 | + |
|
21 | +On our Canopy, it is: `/home/deployer/confluence-data` |
|
22 | + |
|
23 | +### Key configuration files |
|
24 | + |
|
25 | +| File | What | |
|
26 | +|------------------------------------------------------------------------------------------------|------------------------------------------------------| |
|
27 | +| `/etc/nginx/sites-enabled/canopy.conf` | | |
|
28 | +| `/home/deployer/apps/atlassian/confluence-5.10.3/conf/server.xml` | Defines the Connector for requests on 8090 to Tomcat | |
|
29 | +| `/home/deployer/apps/atlassian/confluence-5.10.3/conf/web.xml` | Defines the value for `session-timeout` | |
|
30 | +| `/home/deployer/apps/atlassian/confluence-5.10.3/confluence/WEB-INF/classes/seraph-config.xml` | `authenticator-class` element defines Okta authenticator | |
|
31 | +| `/opt/okta/okta-config-confluence.xml` | Provides cert for Okta | |
|
32 | + |
|
33 | +### Key log files |
|
34 | + |
|
35 | +| File | What | |
|
36 | +|------------------------------------------------------------------------------------------------|------------------------------------------------------| |
|
37 | +| `/home/deployer/confluence-data/logs/atlassian-confluence.log` | Confluence status | |
|
38 | +| `/home/deployer/apps/atlassian/confluence-5.10.3/logs/catalina.out` | Tomcat startup / shutdown | |
|
39 | +| `/home/deployer/apps/atlassian/confluence-5.10.3/logs/catalina.YYYY-MM-DD.log` | Daily rotated Tomcat log | |
|
40 | + |
|
41 | +### Confluence doesn't start |
|
42 | + |
|
43 | +As root, `/etc/init.d/confluence status` |
|
44 | + |
|
45 | +If you are old that Confluence is dead but there is a pidfile, trying deleting |
|
46 | +all of the pidfiles and locks and try again: |
|
47 | + |
|
48 | + sudo rm -f /var/run/confluence.pid |
|
49 | + sudo rm -f /home/deployer/apps/atlassian/confluence-5.10.3/work/catalina.pid |
|
50 | + sudo rm -f /var/lock/subsys/confluence |
|
51 | + |
|
52 | +### Some problems can be caused by cruft in the plugin caches |
|
53 | + |
|
54 | +To remove the plugin caches, |
|
55 | + |
|
56 | + # See https://confluence.atlassian.com/confkb/how-to-clear-confluence-plugins-cache-297664846.html |
|
57 | + CONFLUENCE_HOME=/home/deployer/confluence-data |
|
58 | + sudo rm -fR $CONFLUENCE_HOME/bundled-plugins |
|
59 | + sudo rm -fR $CONFLUENCE_HOME/plugins-cache |
|
60 | + sudo rm -fR $CONFLUENCE_HOME/plugins-osgi-cache |
|
61 | + sudo rm -fR $CONFLUENCE_HOME/plugins-temp |
|
62 | + sudo rm -fR $CONFLUENCE_HOME/bundled-plugins_language |
|
63 | + |
|
64 | +### Additional settings |
|
65 | + |
|
66 | +At <https://canopy-staging.iorahealth.com/admin/viewgeneralconfig.action>, set Site |
|
67 | +Title and Server Base URL. |
|
68 | + |
|
69 | +Change /home/deployer/apps/atlassian/confluence-5.10.3/conf/server.xml to be |
|
70 | + |
|
71 | + <Server port="8000" shutdown="SHUTDOWN"> |
|
72 | + <Service name="Tomcat-Standalone"> |
|
73 | + <Connector |
|
74 | + port="8090" |
|
75 | + connectionTimeout="20000" |
|
76 | + redirectPort="8443" |
|
77 | + maxThreads="48" |
|
78 | + minSpareThreads="10" |
|
79 | + enableLookups="false" |
|
80 | + acceptCount="10" |
|
81 | + URIEncoding="UTF-8" |
|
82 | + protocol="org.apache.coyote.http11.Http11NioProtocol" |
|
83 | + proxyName="canopy.iorahealth.com" |
|
84 | + proxyPort="443" |
|
85 | + scheme="https" |
|
86 | + secure="true" |
|
87 | + /> |
|
88 | + |
|
89 | + <Engine name="Standalone" defaultHost="localhost"> |
|
90 | + <Host name="localhost" appBase="webapps" unpackWARs="true" autoDeploy="false"> |
|
91 | + <Context path="" docBase="../confluence" reloadable="false" useHttpOnly="true"> |
|
92 | + <Manager pathname="" /> |
|
93 | + <Valve className="org.apache.catalina.valves.StuckThreadDetectionValve" threshold="60" /> |
|
94 | + </Context> |
|
95 | + </Host> |
|
96 | + </Engine> |
|
97 | + </Service> |
|
98 | + </Server> |
|
99 | + |
|
100 | +Set up SAML |
|
101 | + |
|
102 | +1. Add the app in Okta: Go to <https://iora-admin.okta.com/admin/apps/active> and click |
|
103 | +Add Application. Search for "Confluence On-Premise SAML" and click Add. |
|
104 | + |
|
105 | +2. Change the Application label to: Canopy Staging |
|
106 | + |
|
107 | +3. The Confluence URL should be: https://canopy-staging.iorahealth.com -- do not |
|
108 | +check anything for Application Visibility. Click Next. |
|
109 | + |
|
110 | +4. Do not click "Enable provisioning features" and click Next. |
|
111 | + |
|
112 | +5. Add someone. |
|
113 | + |
|
114 | +6. Now go to the "Sign On" tab. |
|
115 | + |
|
116 | +7. Click View Setup Instructions |
|
117 | + |
|
118 | +8. `sudo mkdir -p /opt/okta` |
|
119 | + |
|
120 | +9. Create /opt/okta/okta-config-confluence.xml with the XML from the setup instructions. |
|
121 | + |
|
122 | +10. Modify `/home/deployer/apps/atlassian/confluence-5.10.3/confluence/WEB-INF/classes/seraph-config.xml` per the Okta instructions. |
|
123 | + |
|
124 | +11. Get the Okta auth jar in place. |
|
125 | + |
|
126 | +12. Restart Confluence. |
capistrano.md
... | ... | @@ -0,0 +1,40 @@ |
1 | +0. Pre-requesities |
|
2 | + |
|
3 | + sudo apt-get install git-core |
|
4 | + sudo gem install bundler |
|
5 | + |
|
6 | +1. To Gemfile, add `gem 'capistrano', '~> 2.11.2'` to the main gem block. Then: |
|
7 | + |
|
8 | + bundle install |
|
9 | + |
|
10 | +2. Create config/deploy.rb |
|
11 | + |
|
12 | +3. Create the deploy directory with the stages, e.g., |
|
13 | + |
|
14 | + mkdir -p config/deploy |
|
15 | + touch config/deploy/vagrant.rb |
|
16 | + |
|
17 | +4. Do |
|
18 | + |
|
19 | + cap deploy:setup |
|
20 | + |
|
21 | + Whatever your `deploy_to` directory value is, `deploy:setup` creates the deploy_to dir; subdirectories: releases/ shared/ shared/system/ shared/log/ shared/pids/ |
|
22 | + |
|
23 | + Then it chmod's these to g+w |
|
24 | + |
|
25 | + [This means that the group name should be picked correctly] |
|
26 | + |
|
27 | +5. Make sure the database is created |
|
28 | + |
|
29 | + sudo -u postgres psql -d postgres -c "create user icis_querytool_vagrant with password 'POOQwQkDtFtMBaqR';" |
|
30 | + sudo -u postgres psql -d postgres -c "create database icis_querytool_vagrant;" |
|
31 | + sudo -u postgres psql -d postgres -c "grant all privileges on database icis_querytool_vagrant to icis_querytool_vagrant;" |
|
32 | + |
|
33 | +6. Manual |
|
34 | + |
|
35 | + Copy the database.yml to: |
|
36 | + |
|
37 | +7. And set the schema -- |
|
38 | + |
|
39 | + cap vagrant shell |
|
40 | + cd apps/icis-querytool/vagrant/current; RAILS_ENV=vagrant bundle exec rake db:schema:load |
coffeescript-notes.md
... | ... | @@ -0,0 +1,77 @@ |
1 | +### Notes |
|
2 | + |
|
3 | +* avoid terminating statements with `;` -- it can still be used to separate statements on the same line. |
|
4 | +* don't use `var`: CoffeeScript automatically declares variables at the top of the closest scope. Be careful to not use the variable name of something "higher"; since there is no `var` keyword, it is impossible to "shadow" a variable in an outer scope. |
|
5 | +* Instead of curly braces, use indentation. |
|
6 | +* When calling a function with parameters, you can omit the parentheses (unless there are no parameters, in which case use `()`). |
|
7 | +* use if predicate |
|
8 | +* functions |
|
9 | + * declaring |
|
10 | + |
|
11 | + square = (x) -> x * x |
|
12 | + |
|
13 | + The parameter name is x. |
|
14 | + |
|
15 | + * can define default values for function parameters. |
|
16 | +* Ternary: Instead of `date = friday ? sue : jill;` use `date = if friday then sue else jill` |
|
17 | +* As a shortcut for `this.property`, you can use `@property` |
|
18 | +* CoffeeScript's existential operator `?` returns true unless a variable is **null** or **undefined**, which makes it analogous to Ruby's `nil?` |
|
19 | + * using `?` |
|
20 | + |
|
21 | + speed ?= 15 |
|
22 | + footprints = yeti ? "bear" |
|
23 | +* soaking up nulls: `zip = lottery.drawWinner?().address?.zipcode`: discussion: "The accessor variant of the existential operator ?. can be used to soak up null references in a chain of properties. Use it instead of the dot accessor . in cases where the base value may be null or undefined. If all of the properties exist then you'll get the expected result, if the chain is broken, undefined is returned instead of the TypeError that would be raised otherwise." |
|
24 | +* When to use `=>`: If you are declaring a function X that must in turn pass a function where, inside the function, variables referenced @foo should be the foo on X (not on the new function), then use the `=>`. See <http://coffeescript.org/#fat_arrow>. The typical cases are (a) when you want to enumerate and declare an anonymous function. If the anonymous function needs access to methods on the caller, then use `=>`; or (b) when you want to bind a function to something with jQuery, but inside that bound function, you want `@` to refer to the caller's attributes. |
|
25 | +* |
|
26 | +* |
|
27 | + |
|
28 | +### Add method to prototype (existing class) |
|
29 | + |
|
30 | +``` |
|
31 | +Array::size = -> @length |
|
32 | +``` |
|
33 | + |
|
34 | +### Questions |
|
35 | + |
|
36 | +* What is the difference between the CoffeeScript `constructor` and the use of `initialize` in our code? |
|
37 | +* |
|
38 | + |
|
39 | + |
|
40 | + |
|
41 | + |
|
42 | +Usefulness of `do` |
|
43 | + |
|
44 | +```coffeescript |
|
45 | +((Pi) -> |
|
46 | + (diameter) -> |
|
47 | + diameter * Pi |
|
48 | +)(3.14159265)(2) |
|
49 | +``` |
|
50 | + |
|
51 | +vs. |
|
52 | + |
|
53 | +```coffeescript |
|
54 | +do (Pi = 3.14159265) -> |
|
55 | + (diameter) -> |
|
56 | + diameter * Pi |
|
57 | +``` |
|
58 | + |
|
59 | + |
|
60 | +*** |
|
61 | + |
|
62 | +From _Async JavaScript_: |
|
63 | + |
|
64 | +var: Scopes variable to closest function |
|
65 | + |
|
66 | +E.g., |
|
67 | + |
|
68 | +```javascript |
|
69 | +for (var i = 1; i <= 3; i++) { |
|
70 | + setTimeout(function(){ console.log(i); }, 0); |
|
71 | +}; |
|
72 | +``` |
|
73 | + |
|
74 | +i is not scoped to the loop. |
|
75 | + |
|
76 | + |
|
77 | +*** |
confluence-on-a-mac.md
... | ... | @@ -0,0 +1,39 @@ |
1 | +1. Ensure that you have Java 8 installed with Brew: |
|
2 | + |
|
3 | + brew update |
|
4 | + brew cask install java |
|
5 | + |
|
6 | +2. Download from <https://www.atlassian.com/software/confluence/download> |
|
7 | +3. Set up the Confluence software |
|
8 | + |
|
9 | + cd $HOME/src |
|
10 | + tar xf $HOME/Downloads/atlassian-confluence-5.10.4.tar.gz |
|
11 | + # Note: If you download with Safari, the tar will already be ungzipped, so just |
|
12 | + # tar xf $HOME/Downloads/atlassian-confluence-5.10.4.tar |
|
13 | + |
|
14 | +4. In the file `atlassian-confluence-5.10.4/confluence/WEB-INF/classes/confluence-init.properties`, set the value for `confluence.home`, e.g., `confluence.home=/Users/jgn/src/atlassian-confluence-5.10.4` |
|
15 | + |
|
16 | +5. Make a database called `confluence` |
|
17 | + |
|
18 | + created confluence |
|
19 | + |
|
20 | +6. Start up the server |
|
21 | + |
|
22 | + cd atlassian-confluence-5.10.4/bin |
|
23 | + JAVA_HOME=/opt/boxen ./catalina.sh start |
|
24 | + |
|
25 | +7. Browse to <http://localhost:8090> |
|
26 | + |
|
27 | +8. Pick Production Install |
|
28 | + |
|
29 | +9. Don't check Answers or Calendars |
|
30 | + |
|
31 | +10. Right-click to get a license. After some clicking around, it should put the license into the server. Click Submit. |
|
32 | + |
|
33 | +11. Select PostgreSQL and click External Database |
|
34 | + |
|
35 | +12. Click Direct JDBC |
|
36 | + |
|
37 | +13. At Iora, we run PG on port 15432, so make the JDBC URL `jdbc:postgresql://localhost:15432/confluence` - the username should be your Mac username (for example, mine is `jgn`). Leave the password field blank. |
|
38 | + |
|
39 | +14. Now wait while Confluence configures the database. |
dad.md
... | ... | @@ -0,0 +1,33 @@ |
1 | +Wifi |
|
2 | + |
|
3 | +* SSID: Home-3992 |
|
4 | +* Password: 508arct1 |
|
5 | + |
|
6 | +Access to the router: |
|
7 | + |
|
8 | +* Browse to http://10.0.0.1 |
|
9 | +* Username: admin |
|
10 | +* Password: password |
|
11 | + |
|
12 | + |
|
13 | +---- |
|
14 | + |
|
15 | +Phone |
|
16 | + |
|
17 | +* first car: olds |
|
18 | +* name of first pet: dopey |
|
19 | +* Favorite sports team: Twins |
|
20 | +* 5305 |
|
21 | +* 508... |
|
22 | + |
|
23 | +ATT Customer support 1-800-331-0500 |
|
24 | + |
|
25 | +---- |
|
26 | + |
|
27 | +Port this phone number |
|
28 | + |
|
29 | +Old phone |
|
30 | +* Provider: Consumer Cellular |
|
31 | +* Contract: 5846205 |
|
32 | +* Phone number: 651-214-6236 |
|
33 | +* Last four digital of social: 6320 |
elasticsearch.md
... | ... | @@ -0,0 +1,41 @@ |
1 | +### ElasticSearch Fundamentals |
|
2 | + |
|
3 | +Download the latest version for OS/X from <http://www.elasticsearch.org/download/>. After unzipping, it will work right out of the box; that is, running `bin/elasticsearch` will start up the service on <http://localhost:9200> which you can browse to for a status message. |
|
4 | + |
|
5 | +If you look at ElasticSearch from the point of view of its URLs, they look like this: |
|
6 | + |
|
7 | + /{index}/{type}/{id} |
|
8 | + |
|
9 | +`index` might be the token `website`, the `type` might be `blog`, and `id` would be the entry number in the blog. |
|
10 | + |
|
11 | +Here's how the [ElasticSearch docs](http://www.elasticsearch.org/guide/en/elasticsearch/guide/current/_document_metadata.html) describe index, type, and id: |
|
12 | + |
|
13 | +entity | definition |
|
14 | +------------- | ------------- |
|
15 | +_index | Where the document lives (think of this as a database) |
|
16 | +_type | The class of object that the document represents (think of the as a type of document) |
|
17 | +_id | The unique identifier for the document (the combination of index, type, and id uniquely defines the doc) |
|
18 | + |
|
19 | +### Create index |
|
20 | + |
|
21 | + curl -XPUT 'http://localhost:9200/claims/' |
|
22 | + |
|
23 | +### Index a document |
|
24 | + |
|
25 | + curl -XPUT 'http://localhost:9200/claims/claim/1' -d '{ |
|
26 | + "user" : "jgn", |
|
27 | + "post_date" : "2009-11-15T14:12:12", |
|
28 | + "message" : "trying out Elasticsearch" |
|
29 | + }' |
|
30 | + |
|
31 | +### Index a document with automatic id generation |
|
32 | + |
|
33 | + curl -XPOST 'http://localhost:9200/claims/claim/' -d '{ |
|
34 | + "user" : "jgn", |
|
35 | + "post_date" : "2009-11-15T14:12:12", |
|
36 | + "message" : "trying out Elasticsearch" |
|
37 | + }' |
|
38 | + |
|
39 | +#### Notes |
|
40 | + |
|
41 | +* [Indexing GMail with ElasticSearch](https://github.com/oliver006/elasticsearch-gmail) |
|
... | ... | \ No newline at end of file |
ember-testing.md
... | ... | @@ -0,0 +1,42 @@ |
1 | +### Setup |
|
2 | + |
|
3 | +``` |
|
4 | +ember new ember-testing |
|
5 | +cd ember-testing |
|
6 | +ember generate acceptance-test root |
|
7 | +a tests/acceptance/root-test.js |
|
8 | +``` |
|
9 | + |
|
10 | +### Start testing |
|
11 | + |
|
12 | +``` |
|
13 | +ember test --server |
|
14 | +``` |
|
15 | + |
|
16 | +### Change page to make pass |
|
17 | + |
|
18 | +``` |
|
19 | +@@ -3,10 +3,10 @@ import moduleForAcceptance from 'ember-testing/tests/helpers/module-for-acceptan |
|
20 | + |
|
21 | + moduleForAcceptance('Acceptance | root'); |
|
22 | + |
|
23 | +-test('visiting /root', function(assert) { |
|
24 | +- visit('/root'); |
|
25 | ++test('visiting /', function(assert) { |
|
26 | ++ visit('/'); |
|
27 | + |
|
28 | + andThen(function() { |
|
29 | +- assert.equal(currentURL(), '/root'); |
|
30 | ++ assert.equal(currentURL(), '/'); |
|
31 | + }); |
|
32 | + }); |
|
33 | +``` |
|
34 | + |
|
35 | +### Switch test framework from QUinit to Mocha |
|
36 | + |
|
37 | +``` |
|
38 | +ember install ember-cli-mocha |
|
39 | +# regenerate acceptance test, or generate a different one and merge in |
|
40 | +ember generate acceptance-test root |
|
41 | +# Then edit the route |
|
42 | +``` |
ember.md
... | ... | @@ -0,0 +1,206 @@ |
1 | +## Install |
|
2 | + |
|
3 | +See https://docs.npmjs.com/getting-started/installing-node |
|
4 | + |
|
5 | +* Install the latest stable node from <https://nodejs.org/en/> |
|
6 | +* Ember: `sudo npm install -g ember-cli@2.4` |
|
7 | + |
|
8 | +## Ember Data |
|
9 | + |
|
10 | +### Components |
|
11 | + |
|
12 | +#### Standard |
|
13 | + |
|
14 | +* broccoli - asset pipeline for applications that run in the browser <https://github.com/broccolijs/broccoli> |
|
15 | + |
|
16 | +#### Others |
|
17 | + |
|
18 | +* ember-cli-mocha - to replace QUnit |
|
19 | + |
|
20 | +### Terminology |
|
21 | + |
|
22 | +* Adapter - your code to hit an endpoint |
|
23 | +* Serializer - turn that data into something Ember expects |
|
24 | + |
|
25 | +### typeKey - the type in a String |
|
26 | + |
|
27 | +``` |
|
28 | +routeName: -> @typeKey.camelize() |
|
29 | +routePath: -> @typeKey.dasherize() |
|
30 | +templateName: -> @typeKey.underscore() |
|
31 | +cssClass: -> @typeKey.dasherize() |
|
32 | +dynamicSegmentName: -> "#{@typeKey.underscore()}_id" |
|
33 | +``` |
|
34 | + |
|
35 | +### Convention |
|
36 | + |
|
37 | +``` |
|
38 | +{{link-to model.name model.routeName model}} |
|
39 | +``` |
|
40 | + |
|
41 | +### Articles |
|
42 | + |
|
43 | +* [Ember Concepts](http://emberigniter.com/5-essential-ember-2.0-concepts/) |
|
44 | +* [Ember CLI for status sites](http://blog.current.sh/using-ember-cli-as-a-single-page-static-site-generator/) |
|
45 | + |
|
46 | +### Screencasts |
|
47 | + |
|
48 | +* http://ember.codeschool.com/levels/1/challenges/1 |
|
49 | +* https://www.youtube.com/watch?v=XlWcj41D-So |
|
50 | +* https://www.youtube.com/watch?v=4ixw_5keMTc |
|
51 | +* http://vimeo.com/86715370 |
|
52 | +* http://vimeo.com/84385535 |
|
53 | +* [How to do an integration test](http://eviltrout.com/2014/06/27/integration-testing.html) |
|
54 | + |
|
55 | +### Starting Out |
|
56 | + |
|
57 | +Get starter kit and Ember data: <http://emberjs.com> and <https://github.com/emberjs/data> |
|
58 | + |
|
59 | +Twitter Bootstrap: <http://getbootstrap.com> |
|
60 | + |
|
61 | +#### View structure |
|
62 | + |
|
63 | +`templates/application.hbs` - main layout. Pages passed through `outlet` |
|
64 | + |
|
65 | +### What is a "route object"? |
|
66 | + |
|
67 | +See <https://www.youtube.com/watch?v=Hm8XsgKT0Qw> |
|
68 | + |
|
69 | +Is responsible for mapping URL to model data, and for telling app what to do when the URL changes. |
|
70 | + |
|
71 | +#### The "run loop" |
|
72 | + |
|
73 | +* <http://ember.zone/a-50000-foot-overview-of-the-ember-js-run-loop/> |
|
74 | + |
|
75 | +## Topics to learn about! |
|
76 | + |
|
77 | +* Errors: <http://emberjs.com/api/data/classes/DS.Errors.html> |
|
78 | + |
|
79 | +## Generators |
|
80 | + |
|
81 | +``` |
|
82 | + |
|
83 | +ember generate route signup |
|
84 | +``` |
|
85 | + |
|
86 | +produces in `app/router.js` |
|
87 | + |
|
88 | +``` |
|
89 | +Router.map(function() { |
|
90 | + this.route('signup'); |
|
91 | +}); |
|
92 | +``` |
|
93 | + |
|
94 | +in `app/router.js`, along with |
|
95 | + |
|
96 | +* `app/routes/signup.js` |
|
97 | +* `app/templates/signup.hbs` |
|
98 | +* `tests/unit/routes/signup-test.js` |
|
99 | + |
|
100 | +Note that the default test passes only because of the existence of `app/routes/signup.js`: If you comment-out the route in `app/router.js` it will still pass. Why? |
|
101 | + |
|
102 | +In |
|
103 | + |
|
104 | +``` |
|
105 | +var Router = Ember.Router.extend({ |
|
106 | + location: config.locationType |
|
107 | +}); |
|
108 | +``` |
|
109 | + |
|
110 | +The `config.locationType` seems to point to `config/environment.js` where we see `locationType: 'auto'` in `ENV`. The possible values for `locationType` are `history` `hash` or `none` |
|
111 | + |
|
112 | +## What is the resolver? |
|
113 | + |
|
114 | +The resolver is the part of our dependency injection system that is responsible for determining naming conventions. For example, imagine a user visits your Ember application at `/posts`. By default, Ember will look for a template called `posts`, ask the `App.PostsRoute` for a model, and hook it all up to the `App.PostsController`. But these globals are not hardcoded into the framework—instead, there's a default resolver that encapsulates all of these naming conventions. (see <http://emberjs.com/blog/2013/12/17/whats-coming-in-ember-in-2014.html>) |
|
115 | + |
|
116 | +This means: "Notice we don’t have to make something like `App.User` like you would in a traditional Ember App. Instead, thanks to Ember CLI, the model is resolved by its filename, and exported correctly." (<https://medium.com/@ulisesrmzroche/lets-build-jwt-backed-authentication-with-ember-and-express-5425a1977d23>) |
|
117 | + |
|
118 | +## Ember - architectural issues |
|
119 | + |
|
120 | +* setters and getters / dirty checking (see <https://www.youtube.com/watch?v=DqMFX91ToLw#t=150>) |
|
121 | + |
|
122 | +As opposed to Angular, which does diffs on models to detect differences |
|
123 | + |
|
124 | +### Testing - Use of Pretender |
|
125 | + |
|
126 | +* <https://gist.github.com/stefanpenner/1a3b3467059fc9b2f7be#file-asdf-test-js-L40-L72> |
|
127 | + |
|
128 | +#### Script (1) |
|
129 | + |
|
130 | +``` |
|
131 | +nom cache clean -f |
|
132 | +npm install -g n |
|
133 | +npm install -g bower |
|
134 | +npm install -g phantomjs |
|
135 | +npm install -g ember-cli |
|
136 | +nodenv rehash |
|
137 | +cd src |
|
138 | +ember new ember-note |
|
139 | +``` |
|
140 | + |
|
141 | +#### Script (2) |
|
142 | + |
|
143 | +``` |
|
144 | +npm install # doesn't change `git status`; so why? |
|
145 | +bower install # doesn't change `git status`; so why? |
|
146 | +``` |
|
147 | + |
|
148 | +#### Script (3) |
|
149 | + |
|
150 | +``` |
|
151 | +bower install bootstrap --save # only modifies `bower.json` |
|
152 | +``` |
|
153 | + |
|
154 | +Add this to `ember-cli-build.js`: |
|
155 | + |
|
156 | +``` |
|
157 | +app.import('bower_components/bootstrap/dist/css/bootstrap.css'); |
|
158 | +// app.import('/bower_components/bootstrap/dist/css/bootstrap-theme.css'); // if you want the theme |
|
159 | +app.import('bower_components/bootstrap/dist/css/bootstrap.css.map', { |
|
160 | + destDir: 'assets' |
|
161 | +}); |
|
162 | +``` |
|
163 | + |
|
164 | +Note that `ember install ember-bootstrap` does essentially the same thing, but you don't have to add the `app.import` lines to `ember-cli-build.js` |
|
165 | + |
|
166 | +#### Adding a new route |
|
167 | + |
|
168 | +`ember generate route register --pod` |
|
169 | + |
|
170 | +1. Modifies `app/router.js` (adding the route) |
|
171 | +2. adds `app/register/` and two files: `app/register/route.js` and `app/register/template.hbs` |
|
172 | +3. Adds `tests/unit/register/route-test.js` |
|
173 | + |
|
174 | +### What is bower? |
|
175 | + |
|
176 | +`ember new whatever` creates the `bower.json` file, which also creates and sets up `bower_components` - these are the components that will be packaged up to be delivered in the browser. |
|
177 | + |
|
178 | +#### build? |
|
179 | + |
|
180 | +"`ember-cli-build.js` contains the build configuration of your project. It is responsible for recompiling all assets when a project file changes, and then outputs one bundle that contains all JavaScript code and one |
|
181 | +for the CSS. It runs all preprocessors, copies files from one place to another, and concatenates 3rd-party libraries. This processing is called the asset pipeline" (RAR). |
|
182 | + |
|
183 | +#### npm packages |
|
184 | + |
|
185 | +`package.json` defines the npm packages, which end up in `node_modules` |
|
186 | + |
|
187 | +#### Declaring a new class |
|
188 | + |
|
189 | +``` |
|
190 | +var Person = Ember.Object.extend({ |
|
191 | + // attributes and methods |
|
192 | +}); |
|
193 | +``` |
|
194 | + |
|
195 | +#### Creating an instance of a class |
|
196 | + |
|
197 | +``` |
|
198 | +var noname = Person.create(); |
|
199 | +``` |
|
200 | + |
|
201 | +Also |
|
202 | + |
|
203 | +``` |
|
204 | +var amy = Person.create({ name: "Amy" }); |
|
205 | +``` |
|
206 | + |
foobar.md
... | ... | @@ -1 +0,0 @@ |
1 | -zzzz |
|
... | ... | \ No newline at end of file |
foop.md
... | ... | @@ -0,0 +1 @@ |
1 | +foop xx yy |
|
... | ... | \ No newline at end of file |
git-notes.md
... | ... | @@ -0,0 +1,275 @@ |
1 | +## End-to-End Git / GitHub Notes |
|
2 | + |
|
3 | +### What is git? |
|
4 | + |
|
5 | +Git is a distributed revision and source code management (SCM) system. With it, you can edit a |
|
6 | +file and see its entire revision history including the author of the change, the date, and the |
|
7 | +details of the edits. The "distributed" part is important. Unlike other SCM's like Subversion |
|
8 | +and CVS that require a central hub with all of the histories, in git, each user has an entire |
|
9 | +copy of the repository data, and each and every user can provide updates to others: There is |
|
10 | +no requirement for a central hub (though in practice, almost everyone has one or more repositories |
|
11 | +that are authoritative in some way). Among other benefits of this distribution is that a fairly |
|
12 | +up-to-date backup is represented by each copy; and each user can make updates with users via a network; |
|
13 | +copies are "pushed" as needed. Because you have a copy of the whole repo, you can manipulate your |
|
14 | +code edits on plane, and push your updates later. |
|
15 | + |
|
16 | +The most significant benefit of Git, though, is that it supports the efficient and fast |
|
17 | +manipulation of branches. Each branch might represent a separate feature; these branches can |
|
18 | +very easily be merged with other branches, and marked for various stages of release. |
|
19 | + |
|
20 | +For more regarding git's design, see <https://en.wikipedia.org/wiki/Git_(software)#Design>. |
|
21 | + |
|
22 | +### Installation and Setup |
|
23 | + |
|
24 | +#### Git and ssh |
|
25 | + |
|
26 | +I recommend installing both command-line git as well as a visual tool. Note that you will also |
|
27 | +need a version of the `ssh` (secure shell) command. |
|
28 | + |
|
29 | +Command-line: First check if it's there by typing `git`; most versions will work. If not, |
|
30 | + |
|
31 | +* OS/X: The best way is to install the OS/X Xcode "command-line tools." You can install Xcode |
|
32 | +via the OS/X App Store, or the command-line tools alone following these instructions: <http://osxdaily.com/2014/02/12/install-command-line-tools-mac-os-x/>. `ssh` is on the Mac by default. |
|
33 | + |
|
34 | +* Windows: For a Windows user who is not a programmer, I recommend that you use the Rails |
|
35 | +Installer at <http://railsinstaller.org/en>. This is a quick way to get `git` and `ssh`. You won't be using Ruby or Rails, |
|
36 | +and that's fine, but this is quick and easy. |
|
37 | + |
|
38 | +* Linux: Both should be there; if not, use your package manager. |
|
39 | + |
|
40 | +##### Set your `git` name and email |
|
41 | + |
|
42 | +Make sure that you have defined your git name and email; these values will be attached to all of |
|
43 | +your commits. |
|
44 | + |
|
45 | + git config --global user.name "YOUR NAME" |
|
46 | + git config --global user.email "YOUR EMAIL ADDRESS" |
|
47 | + |
|
48 | +#### Setting up ssh |
|
49 | + |
|
50 | +You must have a public key. Type `ls -l ~/.ssh`. If you see a pair of files called `id_rsa` (your public key) and |
|
51 | +`id_rsa.pub`, that's good. If not, generate them with `ssh-keygen -t rsa -b 4096`. Accept the default file locations. |
|
52 | +When you are asked for a passphrase, enter something that is easy to remember and to type, but is at least 10 characters. |
|
53 | + |
|
54 | +> Iora Note: At Iora, you are required to use a passphrase. When you use ssh for the first time after your |
|
55 | +computer is booted up, you will be asked for your password, and you will see checkbox asking if you would like to |
|
56 | +save the passphrase in your OS/X keychain. Never check this. You always want the prompt for the passphrase, so that |
|
57 | +if your computer is compromised, evildoers won't be able to use your key. |
|
58 | + |
|
59 | +#### A quick note about keys |
|
60 | + |
|
61 | +You may use the very same key for everything. Sometimes you will see articles that suggest creating a separate key |
|
62 | +for everything. There is little reason to do this, because you never share your private key. Since you want to |
|
63 | +be able to unlock all the resources permitted to you, you should just use the same key. Thus this key becomes |
|
64 | +pretty important. You might want to save a copy into a _secure_ backup in the cloud, or burn it to CD and keep |
|
65 | +the disc in a safe-deposit box. |
|
66 | + |
|
67 | +#### GitHub |
|
68 | + |
|
69 | +Make sure you are signed up at <https://github.com/>. Once signed up, go to <https://github.com/settings/ssh> and |
|
70 | +click "Add SSH key". What you want to do now is take the contents of `id_rsa.pub` and paste it into the text |
|
71 | +area entitled "key" - you might set the "Title" to "Personal Key." |
|
72 | + |
|
73 | +Once you have your public key installed at GitHub, go to the command line and type: `ssh git@github.com`. You should |
|
74 | +see something like `Hi username! You've successfully authenticated` - the display of `username` proves that GitHub |
|
75 | +has used your public key to associate your account with your key. |
|
76 | + |
|
77 | +> U of MN Note: The U's GitHub site is <https://github.umn.edu>. Log in with your U of MN credentials: A user |
|
78 | +will created for you automatically. Follow the above instructions, but note that the ssh management is |
|
79 | +here -- <https://github.umn.edu/settings/ssh> -- and you must `ssh git@github.umn.edu` instead of `sshgit@github.com`. |
|
80 | +It is entirely OK to have accounts at both systems, but there is no way to link projects on the two systems. |
|
81 | + |
|
82 | +### Getting a copy of the repository by "cloning" |
|
83 | + |
|
84 | +You are going to need a directory for all of your copies of repositories. I create a directory in my home |
|
85 | +directory called `src` for anything I'm working on. I also create a directory called `refrepos` for things |
|
86 | +I want to clone in order to keep around for local viewing on my computer. To make a directory like `src`, open |
|
87 | +a new terminal window and type `mkdir src`. Now you can get in there with `cd src`. I'm going to assume |
|
88 | +in the following that you have a directory in your home called `src`. |
|
89 | + |
|
90 | +To get your initial copy of a repo, clone it. For example, browse to <https://github.com/jgn/sample>. You will see |
|
91 | +this: |
|
92 | + |
|
93 | + |
|
94 | + |
|
95 | +Copy the URL from the red-boxed area; that URL is `https://github.com/jgn/sample.git`. Now type |
|
96 | + |
|
97 | +``` |
|
98 | +cd src |
|
99 | +git clone https://github.com/jgn/sample.git |
|
100 | +cd sample |
|
101 | +``` |
|
102 | + |
|
103 | +### The simplest methodology that could possibly work |
|
104 | + |
|
105 | +Now that you've cloned from GitHub, let's assume that there are others who also consider the GitHub repo to |
|
106 | +be the "master" for this project. The GitHub repo is a shared repo. If you push data up there, you need to be |
|
107 | +careful that you are not obliterating what others have earlier pushed. |
|
108 | + |
|
109 | +Here is the simplest thing that could possibly work. |
|
110 | +Sometimes this is called the "Centralized Workflow." |
|
111 | +For a nice walk-through and second opinion, see <https://www.atlassian.com/git/tutorials/comparing-workflows>. |
|
112 | + |
|
113 | +I'm going to put aside for a bit the meaning of |
|
114 | +various terms like "commit" "push" and the like. |
|
115 | + |
|
116 | +1. Make some edits |
|
117 | +2. `git add -A` |
|
118 | +3. Optional: `git status` to review the new files, which may help you write a better commit message (next step). |
|
119 | +4. `git commit -m "A short message describing your commit"` (less than 50 characters, please.) |
|
120 | +5. `git push origin master` |
|
121 | +6. No errors? Done. |
|
122 | +7. You got the message "Updates were rejected because the remote contains work that you do |
|
123 | +hint: not have locally"? |
|
124 | + * (Why are you getting this error? Because someone pushed some commits and beat you to it! You're |
|
125 | +out of sync with origin.) |
|
126 | + * `git fetch origin && git rebase origin/master` |
|
127 | + * No errors? Go to Step 5. |
|
128 | + * You have a message saying there is a "CONFLICT" |
|
129 | + * (Why are you getting this error? Because git can't automatically figure out what's "new" in |
|
130 | +your commits; for instance, there might be changes on the same line, and git can't figure out which edits |
|
131 | +should have priority. So you are going to have to pick the difference manually.) |
|
132 | + * `git mergetool`; accept the default (opendiff) |
|
133 | + * Go through each conflict, and from the "Actions" menu, select which version you like: left, right, |
|
134 | +both (selecting which one comes first) or neither. |
|
135 | + * Then from the menu, select Find / Go To Next / Difference, and pick left, right, etc., again. |
|
136 | + * Once you've gone through all of the differences: File / Save Merge; and then FileMerge / Quit FileMerge. |
|
137 | + * One file down . . . now type into the console, `git rebase --continue`. If there is another conflict, |
|
138 | +do `git mergetool` again and resolve all the conflicts. |
|
139 | + * When you're done with all the conflicts, you will see "Applying: " and the name of your commit. |
|
140 | + * Go to Step 5. |
|
141 | + |
|
142 | +**Some terminology** |
|
143 | + |
|
144 | +`git add` means add files to the "index," also known as the "staging area." In this case, `-A` means add new |
|
145 | +files as well as any already known files that have been changed locally. |
|
146 | + |
|
147 | +`git status` means: Give me a list of everything in the staging area and anything that is changed. |
|
148 | + |
|
149 | +`git commit`: Saves what's in the index (staging area) in your current local branch. |
|
150 | + |
|
151 | +`git push <remote> <branch>`: That `origin` thing? That's the name that is given for the place from which |
|
152 | +you cloned. When you cloned, you by default are using the `master` branch. So this command is "pushing" |
|
153 | +your version of the `master` branch to the `origin` remote. |
|
154 | + |
|
155 | +Key point: Git tries to be as efficient as possible. Is it pushing an entire copy of everything in your |
|
156 | +local version of the master branch? Of course not. It's trying to be minimalist, and is going to verify |
|
157 | +that your branch is based on the latest version at the remote. Once this has been verified, then all |
|
158 | +of your changes can be added "on to the top" of what's at the remote master with no conflicts. But what |
|
159 | +if another person has pushed their version of master? Well now we have a problem. Your additions can be |
|
160 | +blinded added on, because the origin copy may have other stuff your local hasn't taken into account. |
|
161 | +That means that we should update our local copy of the remote master, and re-apply our changes on top. |
|
162 | +(So read the next item.) |
|
163 | + |
|
164 | +`git fetch origin && git rebase origin/master`. This is two commands. First get a copy of the `origin` |
|
165 | +repo; now `rebase` our commits "on top" of the state of the `master` branch from the `origin` remote. |
|
166 | +Now we are up-to-date, and we can re-push. (It we get another fail, it just means we should rebase again.) |
|
167 | + |
|
168 | +**Commentary** |
|
169 | + |
|
170 | +This is pretty weak. All this methodology does is provide for shared storage, with some controls |
|
171 | +to prevent overwriting the additions (commits) of collaborators. |
|
172 | + |
|
173 | +We can do better. What we want is a mechanism where you additions are saved in a separate branch, |
|
174 | +which may be reviewed by colleagues. Then you can make changes, and once your branch is solid, it |
|
175 | +can be merged into the master branch. |
|
176 | + |
|
177 | +### "Feature Branch Workflow" |
|
178 | + |
|
179 | +"Feature Branch Workflow" is th most popular git pattern nowadays. Once again, Atlassian has a nice |
|
180 | +writeup; see <https://www.atlassian.com/git/tutorials/comparing-workflows/feature-branch-workflow>. |
|
181 | + |
|
182 | +There are two core ideas: |
|
183 | + |
|
184 | +* Your new code is going to be in a separate branch. The branch's name is going to represent your |
|
185 | +work, and its content is going to be pretty lumpy: something big, like a feature in a new application, or perhaps |
|
186 | +a new dimension in a multidimensional warehouse. |
|
187 | + |
|
188 | +* You are only going to merge your new stuff into the master branch |
|
189 | +after your stuff has been reviewed by a colleague. |
|
190 | + |
|
191 | +Here's how it works: |
|
192 | + |
|
193 | +1. First switch to the master branch, and ensure that your copy of the repo is up-to-date. |
|
194 | + |
|
195 | + git checkout master |
|
196 | + git pull --rebase |
|
197 | + |
|
198 | +2. Then create a new branch. For the name of your new |
|
199 | +branch, use your initials, followed by a dash, and then the name of your "feature" or new development. |
|
200 | +Separate the words of your features with underscores. The way you create a new branch is to "check out" |
|
201 | +your new branch, but you use the `git checkout` command with the `-b` option to indicate that you are |
|
202 | +creation the new branch at the same time: |
|
203 | + |
|
204 | + git checkout -b jn-adding_pharma_registry |
|
205 | + |
|
206 | +3. Now make edits and add new files. When you're done . . . `git add` all the new files, and then: |
|
207 | + |
|
208 | + git commit -a -m "Pharma registry - see https://trello.com/c/yo7tld0m" |
|
209 | + |
|
210 | +4. The crucial step. Get your own branch up-to-date with "master" -- this means: refresh your |
|
211 | +local copy, and then "rebase" by putting your commits "after" the current state of master. |
|
212 | + |
|
213 | + |
|
214 | + git fetch |
|
215 | + git rebase origin/master |
|
216 | + git push origin jn-adding_pharma_registry --force |
|
217 | + |
|
218 | + This little sequence -- `git fetch` followed by `git rebase origin/master` -- is the essense of getting |
|
219 | +your local branch up-to-date with the master branch. In effect, these commands are saying; "I don't know |
|
220 | +what else has happened to the master branch, but I'm going to ensure that my local freature branch |
|
221 | +is based on whatever is now at master. Do this command a lot. By rebasing frequently against master, you |
|
222 | +are ensuring that your own branch doesn't drift away from master. If there are changes to be made, they |
|
223 | +will be minimized. Most developers rebase off master the first thing in the morning, and then frequently |
|
224 | +through out the day. |
|
225 | + |
|
226 | +5. Now your branch is ready for review. |
|
227 | + |
|
228 | + Browse to <https://github.com>. You will find that GitHub has noticed your |
|
229 | +new branch, and will provide you with the opportunity to create a "pull request": |
|
230 | + |
|
231 | +  |
|
232 | + |
|
233 | + After clicking, copy the URL for the "pull" and let your colleagues see it. Now they can click it, |
|
234 | +and review it. |
|
235 | + |
|
236 | + How to review? When you click on the pull request link, you will see a tabbed panel with tabs |
|
237 | +for Discussion, Commits, and Files. Typically I start with the files. You can click on individual |
|
238 | +lines and add comments wherever you want; these comments will be emailed to the developer. |
|
239 | + |
|
240 | + As the feature author, response to their questions at GitHub, or change your code locally, and re-push (steps |
|
241 | +3 and 4). The newly-pushed code will be available for furthe rcomments. |
|
242 | + |
|
243 | + Eventually, your |
|
244 | +colleague will sign off on what you've done, providing a comment such as "ship it" or ":octocat:". |
|
245 | + |
|
246 | +### Tailor your git config |
|
247 | + |
|
248 | +TODO: `git up`; `git glog` |
|
249 | + |
|
250 | +### About commits and branches |
|
251 | + |
|
252 | +TODO: Use Gitx to show branches, branches off of branches, commits, "train tracks," etc. |
|
253 | + |
|
254 | +### From beginner to habitual user |
|
255 | + |
|
256 | +* Usage of `git log` |
|
257 | +* Creating a local repo for yourself |
|
258 | +* Adding a remote from the command line |
|
259 | +* `.gitignore` |
|
260 | +* `get reset` |
|
261 | +* Squashing commits |
|
262 | +* Reordering commits |
|
263 | +* Reverting |
|
264 | +* `git bisect` |
|
265 | +* `git grep` |
|
266 | + |
|
267 | +### References |
|
268 | + |
|
269 | +* Try Git (interactive teaching tool): <https://try.github.io/levels/1/challenges/1> |
|
270 | +* GitHub's explanation for their "flow": <https://guides.github.com/introduction/flow/index.html> |
|
271 | +* Atlassian documentation on Git: <https://www.atlassian.com/git/tutorials> |
|
272 | +* Pro Git: <http://git-scm.com/book> |
|
273 | +* GitHub git cheatsheet: <https://training.github.com/kit/downloads/github-git-cheat-sheet.pdf> |
|
274 | + |
|
275 | + |
git.md
... | ... | @@ -0,0 +1,97 @@ |
1 | +### Terminology |
|
2 | + |
|
3 | +* The "staging" area, aka "index," aka the "cache," aka "changes to be committed" (which is what `git status` |
|
4 | +says) - where you put files that can be committed into the repo. |
|
5 | + |
|
6 | +### Interactive rebasing |
|
7 | + |
|
8 | +The display order in `git rebase -i` is the opposite of `git log`. That is, in `git log` you see |
|
9 | +stuff starting with newest. In `git rebase -i` you see stuff starting with oldest at the top. |
|
10 | + |
|
11 | +Change a commit from `pick` to `squash` (or just `s`) means: "apply both that change and the |
|
12 | +change directly before it and makes you merge the commit messages together." By "before it" is |
|
13 | +meant: above, i.e., the prior commit in time. |
|
14 | + |
|
15 | +### Delete a branch locally and in remote |
|
16 | + |
|
17 | + git branch -D local-branch |
|
18 | + git push origin :local-branch |
|
19 | + |
|
20 | +### Rename local branch |
|
21 | + |
|
22 | + git branch -m <oldname> <newname> |
|
23 | + |
|
24 | +### Specify merge strategy |
|
25 | + |
|
26 | + git merge master -s <strategy> |
|
27 | + |
|
28 | +E.g., `git merge master -s ours` means: "give me master, but my final state should match my current branch"; use when your long-running branch will supersede master. By merging this way, you preserve changes in master. `git merge master -s recursive -X patience`: means: Say you have |
|
29 | + |
|
30 | +``` |
|
31 | +{ |
|
32 | + a: 1 |
|
33 | +} |
|
34 | +``` |
|
35 | + |
|
36 | +and change it to |
|
37 | + |
|
38 | +``` |
|
39 | +{ |
|
40 | + a: 1 |
|
41 | +} |
|
42 | +{ |
|
43 | + b: 2 |
|
44 | +} |
|
45 | +``` |
|
46 | + |
|
47 | +you want the change to be the addition of the `{ b: 2 }` not `} { b: 2`. |
|
48 | + |
|
49 | +### Making a gzip tar archive |
|
50 | + |
|
51 | + git archive --format=tar --prefix=IoraHealth/ HEAD | tee IoraHealth.tar | gzip > IoraHealth.tar.gz |
|
52 | + |
|
53 | +### ZIP |
|
54 | + |
|
55 | + git archive --output=IoraHealth.zip --prefix=IoraHealth/ -9 HEAD |
|
56 | + |
|
57 | +### Managing a fork |
|
58 | + |
|
59 | +(See <http://robots.thoughtbot.com/post/5133345960/keeping-a-github-fork-updated>) |
|
60 | + |
|
61 | +### Track |
|
62 | + |
|
63 | + git clone git@github.com:croaky/dotfiles.git |
|
64 | + cd dotfiles |
|
65 | + git remote add upstream git@github.com:thoughtbot/dotfiles.git |
|
66 | + |
|
67 | +### Update |
|
68 | + |
|
69 | + git fetch upstream |
|
70 | + git rebase upstream/master |
|
71 | + |
|
72 | +### Removing tags locally and at remote |
|
73 | + |
|
74 | +1. Delete the v0.4 tag locally: `git tag -d v0.4` |
|
75 | +2. Delete the v0.4 tag on GitHub (which removes its download link): `git push origin :v0.4` |
|
76 | +3. Add a new tag for the newest stable release: `git tag -a v0.5 -m "Version 0.5 Stable"` |
|
77 | +4. Push the latest tag to GitHub (two dashes): `git push --tags` |
|
78 | + |
|
79 | +### Find first commit |
|
80 | + |
|
81 | + git rev-list --parents HEAD | egrep "^[a-f0-9]{40}$" |
|
82 | + |
|
83 | +### What happens when you `git add`? |
|
84 | + |
|
85 | +1. **First:** Hash the contents of the "operation" representing this `git add`. Say the hash is `2e65efe2a145dda7ee51d1741299f848e5bf752e ` -- A new file is |
|
86 | +created in `.git/objects/` in a directory for the first two characters of the hash (`2e/`) |
|
87 | +and then the file name is the rest (`65efe2a145dda7ee51d1741299f848e5bf752e`). The contents |
|
88 | +is the compressed version of the operation. |
|
89 | + |
|
90 | + To see the contents, you can do `alias deflate="perl -MCompress::Zlib -e 'undef $/; print uncompress(<>)'"`; then |
|
91 | +`deflate .git/objects/2e/65efe2a145dda7ee51d1741299f848e5bf752e` will show `blob 1a`. |
|
92 | + |
|
93 | + This is saving the "content" of the change in the `objects` directory. Notice that if |
|
94 | +you now delete the file that is added, it will rename in the `objects` directory. |
|
95 | + |
|
96 | + **Second:** Add the file to the "index," in `.git/index` which is a list of every |
|
97 | +file Git is keeping track of. You can see a list of things in the index with `git ls-files -s`. |
github-page.jpg
... | ... | Binary files /dev/null and b/github-page.jpg differ |
hipaa-wikis.md
... | ... | @@ -0,0 +1,49 @@ |
1 | +1. Clone the software and the repo |
|
2 | + |
|
3 | + cd src |
|
4 | + git clone git@github.com:jgn/stoor.git stoor_hipaa_draft |
|
5 | + git clone https://github.com/IoraHealth/HIPAA.wiki.git HIPAA-draft.wiki |
|
6 | + |
|
7 | +2. Go into DNS, and create the A record for hipaa-draft.iorahealth.com |
|
8 | + |
|
9 | +3. Now go into Github settings for IoraHealth, and add the app: Settings / Applications, then Register New Application |
|
10 | + |
|
11 | +4. Fill out the form |
|
12 | + * Application name: HIPAA - draft |
|
13 | + * Homepage URL: https://hipaa-draft.iorahealth.com |
|
14 | + * Application description: (blank) |
|
15 | + * Authorization callback URL: https://hipaa-draft.iorahealth.com/auth/github/callback |
|
16 | + |
|
17 | +5. Click "Register application" |
|
18 | + |
|
19 | +6. Now copy the client id (example: `981dfe2120a639bc990f`) and client secret (example: `018ae56231f6667015efb9568f4bfe2f51412448`) |
|
20 | + |
|
21 | +7. Start OS/X Server. Select Websites. |
|
22 | + |
|
23 | +8. Click "+" and fill out the form |
|
24 | + * Domain Name: hipaa-draft.iorahealth.com |
|
25 | + * IP Address: Any |
|
26 | + * Port: 443 |
|
27 | + * SSL Certificate: Select Iora's |
|
28 | + * Store Site Files In: (browse to the right stoor and use public/) |
|
29 | + * Who Can Access: Anyone |
|
30 | + |
|
31 | +9. Click "Create" |
|
32 | + |
|
33 | +10. Now edit `/Library/Server/Web/Config/apache2/sites/0000_any_443_hipaa-draft.iorahealth.com.conf` |
|
34 | + |
|
35 | +11. After `</IfModule>` add |
|
36 | + |
|
37 | + SetEnv STOOR_HIPAA_DRAFT_GITHUB_CLIENT_ID 981dfe2120a639bc990f |
|
38 | + SetEnv STOOR_HIPAA_DRAFT_GITHUB_CLIENT_SECRET 018ae56231f6667015efb9568f4bfe2f51412448 |
|
39 | + SetEnv STOOR_HIPAA_DRAFT_TEAM_ID 493798 |
|
40 | + SetEnv STOOR_HIPAA_DRAFT_GITHUB_EMAIL_DOMAIN iorahealth.com |
|
41 | + SetEnv STOOR_HIPAA_DRAFT_DOMAIN iorahealth.com |
|
42 | + SetEnv STOOR_HIPAA_DRAFT_EXPIRE_AFTER 60 |
|
43 | + SetEnv STOOR_HIPAA_DRAFT_WIKI_PATH /Users/jgn/src/HIPAA-draft.wiki |
|
44 | + SetEnv STOOR_HIPAA_DRAFT_WIKI_WIDE y |
|
45 | + SetEnv STOOR_HIPAA_DRAFT_READONLY y |
|
46 | + |
|
47 | + (making sure to update `STOOR_HIPAA_DRAFT_GITHUB_CLIENT_ID`, `STOOR_HIPAA_DRAFT_GITHUB_CLIENT_SECRET`, `STOOR_HIPAA_DRAFT_TEAM_ID`, and `STOOR_HIPAA_DRAFT_WIKI_PATH`) |
|
48 | + |
|
49 | +12. Stop and start the web server |
home.md
... | ... | @@ -0,0 +1,92 @@ |
1 | +* [How to edit](howto) |
|
2 | +* [This Wiki](wiki) |
|
3 | +* [Iora](iora) |
|
4 | +* [Mirth](mirth) |
|
5 | +* [Dad's System and Phone](dad) |
|
6 | +* [Pi](pi) |
|
7 | +* [Blog](blog) |
|
8 | + |
|
9 | +--- |
|
10 | + |
|
11 | +* [Amazon](amazon) |
|
12 | +* [ansible](ansible) |
|
13 | +* [APIs](apis) |
|
14 | +* [Architecture](architecture) |
|
15 | +* [AWS](aws) |
|
16 | +* [AWS CLI](awscli) |
|
17 | +* [AWS Windows](aws-windows) |
|
18 | +* [bash](bash) |
|
19 | +* [bootstrap](bootstrap) |
|
20 | +* [Boxen - creating branch](boxen-creating-branch) |
|
21 | +* [Boxen - remove service](boxen-remove-service) |
|
22 | +* [Boxen - stop nginx](boxen-stop-nginx) |
|
23 | +* [Boxen - remove completely](boxen-remove) |
|
24 | +* [Box](box) |
|
25 | +* [Brew](brew) |
|
26 | +* [Capistrano](capistrano) |
|
27 | +* [Chrome](chrome) |
|
28 | +* [CoffeeScript](coffeescript notes) |
|
29 | +* [Confluence on a Mac](confluence-on-a-mac) |
|
30 | +* [curl](curl) |
|
31 | +* [Data Warehousing](data-warehousing) |
|
32 | +* [Elastic Search](elasticsearch) |
|
33 | +* [Ember](ember) |
|
34 | +* [Ember - front end masters](ember-fem) |
|
35 | +* [Ember testing](ember-testing) |
|
36 | +* [Encryption](encryption) |
|
37 | +* [Full stack developers](full-stack) |
|
38 | +* [Git and GitHub](git) |
|
39 | +* [Git notes](git-notes) |
|
40 | +* [HIPAA wikis](hipaa-wikis) |
|
41 | +* [http](http) |
|
42 | +* [JavaScript](javascript) |
|
43 | +* [JavaScript - History](javascript-history) |
|
44 | +* [JavaScript - Language](javascript-language) |
|
45 | +* [JSON API](json-api) |
|
46 | +* [Linux](linux) |
|
47 | +* [List](list) |
|
48 | +* [Management](management) |
|
49 | +* [Mechanize](mechanize) |
|
50 | +* [Medical Data](medical-data) |
|
51 | +* [Music](music) |
|
52 | +* [MySQL](mysql) |
|
53 | +* [Nginx](nginx) |
|
54 | +* [Node](node) |
|
55 | +* [npm](npm) |
|
56 | +* [One-page app](one-page-app) |
|
57 | +* [OS/X](osx) |
|
58 | +* [PKI](public-key-encryption) |
|
59 | +* [Port forwarding with pf](port-forwarding-with-pf) |
|
60 | +* [PostgreSQL](postgresql) |
|
61 | +* [PostgreSQL - Running two instances on OS/X](postgresql-two-on-osx) |
|
62 | +* [Product Management](product-management) |
|
63 | +* [proxy](proxy) |
|
64 | +* [Puppet](puppet) |
|
65 | +* [Rails - Spring](rails-spring) |
|
66 | +* [Rails new app](rails-new-app) |
|
67 | +* [React](react) |
|
68 | +* [Redhat](redhat) |
|
69 | +* [Redis](redis) |
|
70 | +* [Reference Repositories - List](refrepos) |
|
71 | +* [Regular Expressions](regexps) |
|
72 | +* [REST backends - throttling, auth, etc.](rest) |
|
73 | +* [RSpec](rspec) |
|
74 | +* [Ruby Course](ruby-course) |
|
75 | +* [Ruby](ruby) |
|
76 | +* [Ruby and Rails Questions](ruby-and-rails-questions) |
|
77 | +* [SendGrid](sendgrid) |
|
78 | +* [Sinatra](sinatra) |
|
79 | +* [ssh](ssh) |
|
80 | +* [SSL Notes - esp. web servers](ssl-notes) |
|
81 | +* [Startups / Business](business) |
|
82 | +* [Stunnel](stunnel) |
|
83 | +* [Syncany](syncany) |
|
84 | +* [Telephony](telephony) |
|
85 | +* [Testing - doubles](test-doubles) |
|
86 | +* [Testing - General](testing-general) |
|
87 | +* [Testing - mocha](testing-mocha) |
|
88 | +* [Travel](travel) |
|
89 | +* [Ubuntu-DigitalOcean](ubuntu-digital-ocean) |
|
90 | +* [UMN (hacker hours, other stuff)](umn) |
|
91 | +* [Vim](vim) |
|
92 | +* [WebSockets - Javascript](websockets-javascript) |
|
... | ... | \ No newline at end of file |
howto.md
... | ... | @@ -0,0 +1,40 @@ |
1 | +The pages in this wiki are written in Markdown, which provides for creating headings, rendering text in italics, bolding, and so forth. Additionally, this version of Markdown allows you to include/reference files. |
|
2 | + |
|
3 | +In a wiki, pages are accessible via links. What this means is that you typically edit a page, add a link **for a new page**, and then save the page. Then you click on the newly-created link (for the **new** page), and put in your new content. |
|
4 | + |
|
5 | +#### Links |
|
6 | + |
|
7 | +Links look like this: |
|
8 | + |
|
9 | + [[Display Text|name-of-page]] |
|
10 | + |
|
11 | +The double brackets delimit the link. The part of the link in front of the vertical bar (|) is the display text for the link. The portion after the | is the name of the file for the page. The display text should be mixed case and may have spaces. For the file name, please use all lowercase, and uses dashes to separate words. |
|
12 | + |
|
13 | +#### Page inclusion |
|
14 | + |
|
15 | +Sometimes you will create a separate page and want to include it in another page. To include a page, you use the double brackets, but use the keyword "include," followed by a colon, followed by the file name. Example: |
|
16 | + |
|
17 | + [[include:forms]] |
|
18 | + |
|
19 | +#### Headings |
|
20 | + |
|
21 | +Once editing the page, you can indicate headings with one or more pound signs (`#`). For example: |
|
22 | + |
|
23 | + # Biggest heading |
|
24 | + ## Big heading |
|
25 | + ### Heading |
|
26 | + #### Smaller heading |
|
27 | + |
|
28 | +----- |
|
29 | + |
|
30 | +# Biggest heading |
|
31 | +## Big heading |
|
32 | +### Heading |
|
33 | +#### Smaller heading |
|
34 | + |
|
35 | +----- |
|
36 | + |
|
37 | +#### Text decoration |
|
38 | + |
|
39 | +For something you **want in bold** use two asterisks: `**want in bold**`. Underlining: _use underscores_ (`_use underscores_`). Italics: *single asterisks* (`*single asterisks*`). |
|
40 | + |
http.md
... | ... | @@ -0,0 +1,13 @@ |
1 | +### POST |
|
2 | + |
|
3 | +For a POST, the `Content-type` header should define the type of what's in the body. E.g., `application/x-www-form-urlencoded` |
|
4 | + |
|
5 | +### Would be nice to see |
|
6 | + |
|
7 | +See what a server really does for TRACE, OPTIONS, CONNECT |
|
8 | + |
|
9 | +### 301 vs 302 |
|
10 | + |
|
11 | +301 = permanent |
|
12 | + |
|
13 | +302 = temp - will come back |
images/link-to.png
... | ... | Binary files /dev/null and b/images/link-to.png differ |
iora-faye.md
... | ... | @@ -0,0 +1,38 @@ |
1 | +### Notes |
|
2 | + |
|
3 | +1. Thin timeout (?) is exceeded, therefore Faye flushes and closes because Rack is telling Faye that the connection is no longer there? |
|
4 | +2. When laptop is opened back up, Chrome never reconnects? Or is it that Safari DOES reconnect? (Tap into events? Log events to browser console?) |
|
5 | + |
|
6 | +### Starting |
|
7 | + |
|
8 | +`bundle exec thin start -t 6000 -R config.ru` |
|
9 | + |
|
10 | +### Bundling |
|
11 | + |
|
12 | +Commit changes and then: `bundle install --gemfile ./Gemfile --path /home/deployer/apps/icis/vagrant/shared/bundle-faye --deployment --quiet --without development test` |
|
13 | + |
|
14 | +### config.ru |
|
15 | + |
|
16 | +``` |
|
17 | + |
|
18 | +$LOAD_PATH.unshift File.expand_path(File.join(File.dirname(__FILE__), "lib")) |
|
19 | +require 'faye' |
|
20 | +require 'extensions/server_auth' |
|
21 | + |
|
22 | +Faye::Logging.log_level = :debug |
|
23 | + |
|
24 | +bayeux = Faye::RackAdapter.new( |
|
25 | + :mount => '/faye', |
|
26 | + :timeout => 60 * 10, |
|
27 | + :ping => 1, |
|
28 | + :engine => { :timeout => 60 * 10 } ) |
|
29 | + |
|
30 | +bayeux.add_extension(ServerAuth.new) |
|
31 | + |
|
32 | +bayeux.listen( |
|
33 | + 8443, |
|
34 | + :key => '/etc/ssl/certs/STAR_icisapp_com.key', |
|
35 | + :cert => '/etc/ssl/certs/STAR_icisapp_com.crt' |
|
36 | +) |
|
37 | + |
|
38 | +``` |
|
... | ... | \ No newline at end of file |
iora.md
... | ... | @@ -0,0 +1,3 @@ |
1 | +wifi password: tran$form222 |
|
2 | + |
|
3 | +[Faye](iora-faye) |
|
... | ... | \ No newline at end of file |
javascript-history.md
... | ... | @@ -0,0 +1,10 @@ |
1 | +From Crockford |
|
2 | + |
|
3 | +* HyperCard (Apple, Bill Atkinson) |
|
4 | +* Mosaic (U of IL), commercialized as Netscape |
|
5 | +* Looking at HyperCard, Netscape wanted to bring programmability to the browser. Gave Brendan Eich 10 days. |
|
6 | + * First cut was called LiveScript |
|
7 | + * Syntax from Java |
|
8 | + * Scheme - Lisp dialect to show actor ideas; functions as first-class objects with lexical scoping |
|
9 | + * Self - dialect of SmallTalk, but more expressive, faster to implement: Removed classes from SmallTalk. Objects would inherit directly from other objects |
|
10 | + |
javascript-language.md
... | ... | @@ -0,0 +1,13 @@ |
1 | +### Objects |
|
2 | + |
|
3 | +get, `object.name` or `object[expression]` |
|
4 | + |
|
5 | +set, `object.name = value` or `object[expression] = value` |
|
6 | + |
|
7 | +delete, `delete object.name` or `delete object[expression]` |
|
8 | + |
|
9 | +### Object literals |
|
10 | + |
|
11 | +`var my_object = { foo: bar };` |
|
12 | + |
|
13 | +### |
|
... | ... | \ No newline at end of file |
javascript.md
... | ... | @@ -0,0 +1,106 @@ |
1 | +* [Details of the object model](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Details_of_the_Object_Model) |
|
2 | +* [Transitioning to JavaScript From Ruby: Prototypes](http://karimbutt.github.io/blog/2014/11/15/the-notion-of-flow/) |
|
3 | +* [JavaScript's Pseudo Classical Inheritance diagram](http://kenneth-kin-lum.blogspot.com/2012/10/javascripts-pseudo-classical.html) |
|
4 | + |
|
5 | +* [Scope](js-scope) |
|
6 | + |
|
7 | +-- |
|
8 | + |
|
9 | +### Compatibility with various versions / browsers |
|
10 | + |
|
11 | +* https://kangax.github.io/compat-table/es6/ |
|
12 | + |
|
13 | +### How to declare a global variable |
|
14 | + |
|
15 | +``` |
|
16 | +// outside of a function |
|
17 | +var foo; |
|
18 | +``` |
|
19 | + |
|
20 | +Or, in a browser: `window.foo = "bar";` |
|
21 | + |
|
22 | +### Test for null |
|
23 | + |
|
24 | +`typeof null` returns `'object'`. Must use `thing === null` |
|
25 | + |
|
26 | +### Test for objectness |
|
27 | + |
|
28 | +Typeof cannot distinguish between null and objects. but Crockford says you can because null is falsy and all objects are truthy: |
|
29 | + |
|
30 | +``` |
|
31 | +if (my_value && typeof my_value === 'object') { |
|
32 | + // my_value is an object or an array! |
|
33 | +} |
|
34 | +``` |
|
35 | + |
|
36 | +### Immediately Invocable Function Expressions |
|
37 | + |
|
38 | +Why doesn't this work? |
|
39 | + |
|
40 | +``` |
|
41 | +function () { |
|
42 | +} (); |
|
43 | +``` |
|
44 | + |
|
45 | +Because `function` is in the "statement position." If we do this, it will work: |
|
46 | + |
|
47 | +``` |
|
48 | +(function () { |
|
49 | +})(); |
|
50 | +``` |
|
51 | + |
|
52 | +Crockford says, though, that it should look like this: |
|
53 | + |
|
54 | +``` |
|
55 | +(function () { |
|
56 | +}()); |
|
57 | +``` |
|
58 | + |
|
59 | +So that the whole thing is inside the starting paren. |
|
60 | + |
|
61 | +### Rockford things |
|
62 | + |
|
63 | +1. Don't use `with` |
|
64 | +2. Always use `===` never `==` |
|
65 | +3. Avoid `if (a = b) { }` |
|
66 | + |
|
67 | +### Block scope vs function scope |
|
68 | + |
|
69 | +Most languages since Algol have had block scope. |
|
70 | + |
|
71 | +JavaScript doesn't. It has syntax that is similar, but it doesn't work. |
|
72 | + |
|
73 | +It's about the way the `var` statement works. |
|
74 | + |
|
75 | +It gets split into two parts. |
|
76 | + |
|
77 | +The declaration part gets hoisted. |
|
78 | + |
|
79 | +So . . . |
|
80 | + |
|
81 | +``` |
|
82 | +function foo() { |
|
83 | + ... |
|
84 | + var myVar = 0, myOtherVar; |
|
85 | +``` |
|
86 | + |
|
87 | +expands to |
|
88 | + |
|
89 | +``` |
|
90 | +function foo() { |
|
91 | + var myVar = undefined, |
|
92 | + myOtherVar = undefined; |
|
93 | + ... |
|
94 | + myVar = 0; |
|
95 | +``` |
|
96 | + |
|
97 | +Therefore: Declare vars at the top. Declare functions before you use them. |
|
98 | + |
|
99 | +Also: `for (var i ...) { ... }`. Variable `i` is not scoped to the loop. It's scoped to the function and will get hoisted. |
|
100 | + |
|
101 | +Put the `var i` at the top of the function. |
|
102 | + |
|
103 | +### Let there be `let` |
|
104 | + |
|
105 | +Just like the `var` statement, but it doesn't hoist. It will provide for block scope. Once we have that, Crockford will say: Always use `let` not `var`. |
|
106 | + |
js-scope.md
... | ... | @@ -0,0 +1,12 @@ |
1 | +* LHS scoping (for a): `var a`; `a = 5`. |
|
2 | +* RHS scoping (for a): `b = a`; `f(a)`. |
|
3 | +* `var a` declares a variable in the current scope, whatever it is. |
|
4 | +* Both LHS and RHS will work up the scope tree until fulfilled or not. |
|
5 | + * unfulfilled RHS results in a `ReferenceError` being thrown. |
|
6 | + * unfulfilled LHS results in an automatic, implicitly-created global of that name (if not in "Strict Mode"), or a `ReferenceError` (if in "Strict Mode"). |
|
7 | + |
|
8 | + |
|
9 | + |
|
10 | +#### Strict mode in the console |
|
11 | + |
|
12 | +`(function f() { 'use strict'; bar = 5; })();` vs `(function f() { bar = 5; })();` |
|
... | ... | \ No newline at end of file |
linux-grab-bag-2.md
... | ... | @@ -0,0 +1,517 @@ |
1 | +<https://github.com/WilliamHackmore/linuxgems/blob/master/cheat_sheet.org.sh> |
|
2 | + |
|
3 | +``` |
|
4 | +# cheat_sheet.org |
|
5 | +# (C) William Hackmore, 2010 |
|
6 | +# The contents of this file are released under the GNU General Public License. Feel free to reuse the contents of this work, as long as the resultant works give proper attribution and are made publicly available under the GNU General Public License. |
|
7 | +# Last updated 8/14/2012 |
|
8 | +# Best viewed in emacs org-mode. |
|
9 | + |
|
10 | +* Command Reference: |
|
11 | +** Basics: |
|
12 | +*** Getting help: |
|
13 | + |
|
14 | +# View the manual for target command |
|
15 | +man [command] |
|
16 | + |
|
17 | +# Get help with a target command (probably the same as above, but not always): |
|
18 | +[command] -h |
|
19 | + |
|
20 | +# In case you forget the name of a command, print possible commands relating to [guess]: |
|
21 | +apropos [guess] |
|
22 | + |
|
23 | +# View index of help pages: |
|
24 | +info |
|
25 | + |
|
26 | +*** Command Line Utilities: |
|
27 | +**** Basic File and Directory Operations: |
|
28 | +# Print current working directory: |
|
29 | +pwd |
|
30 | + |
|
31 | +# Show files in current directory: |
|
32 | +ls |
|
33 | + |
|
34 | +# Show maximum information about all files, including hidden: |
|
35 | +ls -a |
|
36 | + |
|
37 | +# Recurse into subdirectories and list those as well: |
|
38 | +ls -r |
|
39 | + |
|
40 | +# Move/rename a file or directory (be careful that you don't move the source over a destination with the same name): |
|
41 | +mv [source] [destination] |
|
42 | + |
|
43 | +# Delete target forever (be very careful), use -r recursive flag for directories: |
|
44 | +rm [target] |
|
45 | + |
|
46 | +# Copy file or directory: |
|
47 | +cp [source] [destination] |
|
48 | + |
|
49 | +# Mount filesytem: |
|
50 | +mount /dev/[device name] /media/[device name] |
|
51 | + |
|
52 | +# Unmount: |
|
53 | +umount /media/[device name] |
|
54 | + |
|
55 | +# Forensically clone filesystems and do other low-level operations on files. Very dangerous: |
|
56 | +dd |
|
57 | + |
|
58 | +# Work with filesystems and partitions. (Easier, still quite dangerous): |
|
59 | +fdisk |
|
60 | + |
|
61 | +**** System Administration: |
|
62 | + |
|
63 | +# Execute command as an administrator (dangerous, but necessary for system administration tasks): |
|
64 | +sudo [command] |
|
65 | + |
|
66 | +# Become system administrator: |
|
67 | +sudo -s |
|
68 | + |
|
69 | +# Quit system administration: |
|
70 | +exit |
|
71 | + |
|
72 | +# Check distro repositories for software updates: |
|
73 | +sudo apt-get update |
|
74 | + |
|
75 | +# Download and install updates (update first): |
|
76 | +sudo apt-get upgrade |
|
77 | + |
|
78 | +# Search for package in the repositories: |
|
79 | +apt-cache search [keyword] |
|
80 | + |
|
81 | +# Get more detail on one specific package: |
|
82 | +apt-cache show [package name] |
|
83 | + |
|
84 | +# Download and install a package: |
|
85 | +sudo apt-get install [package name] |
|
86 | + |
|
87 | +# View the output of a command in a more convenient format: |
|
88 | +[command] | less |
|
89 | + |
|
90 | +**** Working With Files: |
|
91 | + |
|
92 | +# Print a file in terminal: |
|
93 | +cat [file] |
|
94 | + |
|
95 | +# Find files matching [filename]: |
|
96 | +locate [filename] |
|
97 | + |
|
98 | +# Search through [filename] for matches to [phrase]: |
|
99 | +grep [phrase] [filename] |
|
100 | + |
|
101 | +# Search through output of a command for [phrase]: |
|
102 | +[command] | grep [phrase] |
|
103 | + |
|
104 | +**** Working With Processes: |
|
105 | + |
|
106 | +# List all running processes: |
|
107 | +ps -e |
|
108 | + |
|
109 | +# Standard system monitor showing a more extensive view of all processes and system resources: |
|
110 | +top |
|
111 | + |
|
112 | +# Like top, but with a better, cleaner interface: |
|
113 | +htop |
|
114 | + |
|
115 | +# Stop a process from using all system resources and lagging computer: |
|
116 | +nice [process name] |
|
117 | + |
|
118 | +# Kill misbehaving process (use sparingly, last resort, try 'nice' command first): |
|
119 | +pkill [process name] |
|
120 | + |
|
121 | +**** Compression and Encryption: |
|
122 | + |
|
123 | +# Make a simple compressed backup of a file or directory: |
|
124 | +tar -cvzf [backup output.tgz] [target file or directory] |
|
125 | + |
|
126 | +# Open a compressed .tgz or .tar.gz file: |
|
127 | +tar -xvf [target.tgz] |
|
128 | + |
|
129 | +# Encrypt a file: |
|
130 | +gpg -o [outputfilename.gpg] -c [target file] |
|
131 | + |
|
132 | +# Decrypt a file: |
|
133 | +gpg -o [outputfilename] -d [target.gpg] |
|
134 | + |
|
135 | +# Zip and encrypt a directory simultaneously: |
|
136 | +gpg-zip -o encrypted-filename.tgz.gpg -c -s file-to-be-encrypted |
|
137 | + |
|
138 | +*** The Bash shell: |
|
139 | +**** File Name expansions: |
|
140 | +# Current user's home directory: |
|
141 | +~/ |
|
142 | + |
|
143 | +# Current directory: |
|
144 | +./ |
|
145 | + |
|
146 | +# Parent directory: |
|
147 | +../ |
|
148 | + |
|
149 | +# Or even (Two parent directories down): |
|
150 | +../../ |
|
151 | + |
|
152 | +# All files in target directory. (Be very careful.): |
|
153 | +/* |
|
154 | + |
|
155 | +**** Output Redirects: |
|
156 | + |
|
157 | +# Redirect output of one command into the input of another with a pipe: |
|
158 | +[command 1] | [command 2] |
|
159 | + |
|
160 | +# Or even: |
|
161 | + |
|
162 | +[command 1] | [command 2] | [command 3] |
|
163 | + |
|
164 | +# Redirect output to a file: |
|
165 | +[command] > file |
|
166 | + |
|
167 | +# Or: |
|
168 | + |
|
169 | +[file] > [file] |
|
170 | + |
|
171 | +# Or even, to redirect in a different direction: |
|
172 | +[file] < [file] |
|
173 | + |
|
174 | +# Append output rather than writing over the target file: |
|
175 | + |
|
176 | +[file/command] >> [file] |
|
177 | + |
|
178 | +# Works like |, but it writes output to both target and terminal: |
|
179 | +tee [target] |
|
180 | + |
|
181 | +**** Controlling Execution: |
|
182 | +# Wait until [command 1] is finished to execute [command 2] |
|
183 | +[command 1] ; [command 2] |
|
184 | + |
|
185 | +# Or even: |
|
186 | +[command 1] ; [command 2] ; [command 3] |
|
187 | + |
|
188 | +**** Wildcards: |
|
189 | +# Zero or more characters: |
|
190 | +* |
|
191 | + |
|
192 | +# Matches "phrase" and any number of trailing characters: |
|
193 | +phrase* |
|
194 | + |
|
195 | +# Matches any incidences of "phrase" with any trailing or leading chars: |
|
196 | +*phrase* |
|
197 | + |
|
198 | +# Matches any one char: |
|
199 | +? |
|
200 | + |
|
201 | +# Matches any of the characters listed inside brackets: |
|
202 | +[chars] |
|
203 | + |
|
204 | +# Matches a range of chars between a-z: |
|
205 | +[a-z] |
|
206 | + |
|
207 | +** Advanced: |
|
208 | +*** Command Line Utilities, Continued: |
|
209 | +**** Networking: |
|
210 | + |
|
211 | +# Configure network interfaces: |
|
212 | +ifconfig |
|
213 | + |
|
214 | +# Configure wireless network interfaces: |
|
215 | +iwconfig |
|
216 | + |
|
217 | +# Connect to a remote server. |
|
218 | +ssh [username]@[ipaddress] |
|
219 | + |
|
220 | +# Forward x from target to current machine (Get a remote desktop. Very obscure and very useful): |
|
221 | +ssh -x [username]@[ipaddress] |
|
222 | + |
|
223 | +# Copy files over the network from one machine to another: |
|
224 | +scp [source filename]:[username]@[ipaddress] [target filename]:[target username]@[target ipaddress] |
|
225 | + |
|
226 | +# Copy only changes between files or directories (super efficient way to sync directories, works either locally or with remote servers using username@ipaddress:optionalport, just like ssh): |
|
227 | +rsync [source] [target] |
|
228 | + |
|
229 | +# Check to see if target is online and responding |
|
230 | +ping [ip address] |
|
231 | + |
|
232 | +# View network route to target: |
|
233 | +traceroute6 [ip address] |
|
234 | + |
|
235 | +# Network Monitor |
|
236 | +netstat |
|
237 | + |
|
238 | +# Manage standard linux firewall (advanced users only) |
|
239 | +iptables |
|
240 | + |
|
241 | +# Scan this machine to check for open ports: |
|
242 | +nmap 127.0.0.1 |
|
243 | + |
|
244 | +***** netcat: |
|
245 | + |
|
246 | +# Listen for input from network on [recieving port], dump it to a file (possibly insecure): |
|
247 | +netcat -l [recieving port] > file_copied |
|
248 | + |
|
249 | +# Pipe the output of a command to a target ip and port over the network: |
|
250 | +[command] | netcat -w [number of seconds before timeout] [target ip] [target port] |
|
251 | + |
|
252 | +# Use tar to compress and output a file as a stream, pipe it to a target ip and port over the network: |
|
253 | +sudo tar -czf - [filename] | netcat -w [number of seconds before timeout] [target ip] [target port] |
|
254 | + |
|
255 | +**** Users and Groups: |
|
256 | +# Change owner of a file or directory: |
|
257 | +chown |
|
258 | + |
|
259 | +# Change privileges over file or directory: |
|
260 | +chmod |
|
261 | + |
|
262 | +# Create a new user: |
|
263 | +adduser |
|
264 | + |
|
265 | +# Change user privileges (be very careful with this one): |
|
266 | +usermod |
|
267 | + |
|
268 | +# Delete user" |
|
269 | +deluser |
|
270 | + |
|
271 | +# Print groups: |
|
272 | +groups |
|
273 | + |
|
274 | +# Create a new group: |
|
275 | +groupadd |
|
276 | + |
|
277 | +# Change group privileges: |
|
278 | +groupmod |
|
279 | + |
|
280 | +# Delete group: |
|
281 | +delgroup |
|
282 | + |
|
283 | +# Temporarily become a different user: |
|
284 | +su [username] |
|
285 | + |
|
286 | + |
|
287 | +# Print usernames of logged in users: |
|
288 | +users |
|
289 | + |
|
290 | +# Write one line to another user from your terminal: |
|
291 | +talk |
|
292 | + |
|
293 | +# Interactive talk program to talk to other users from terminal: |
|
294 | +ytalk |
|
295 | + |
|
296 | +**** Working With Files, Continued: |
|
297 | +# View what processes are using what files: |
|
298 | +lsof |
|
299 | + |
|
300 | +# View the differences between two files: |
|
301 | +diff [file 1] [file 2] |
|
302 | + |
|
303 | +# Output the top -n lines of [file]: |
|
304 | +head -n [number of lines] [file] |
|
305 | + |
|
306 | +# Like head, but it outputs the last -n lines: |
|
307 | +tail |
|
308 | + |
|
309 | +# Checksum a file: |
|
310 | +md5sum [file] |
|
311 | + |
|
312 | +# Checksum every file in a directory: |
|
313 | +md5deep [directory] |
|
314 | + |
|
315 | +# Checksum a file (safer algorithm with no hash collisions): |
|
316 | +sha1sum |
|
317 | + |
|
318 | +# Same operation as md5deep, but using sha1: |
|
319 | +sha1deep |
|
320 | + |
|
321 | +# Call [command] every -n seconds, and display output: |
|
322 | +watch -n [number of seconds] [command] |
|
323 | + |
|
324 | +# Execute [command], print how long it took: |
|
325 | +time [command] |
|
326 | + |
|
327 | +# View files in home from largest to smallest: |
|
328 | +du -a ~/ | sort -n -r | less |
|
329 | + |
|
330 | +# remove spaces from filenames in current directory |
|
331 | +rename -n 's/[\s]/''/g' * |
|
332 | + |
|
333 | +# change capitals to lowercase in filenames in current directory |
|
334 | +rename 'y/A-Z/a-z/' * |
|
335 | + |
|
336 | +***** Environment and Hardware: |
|
337 | +# Print full date and time: |
|
338 | +date |
|
339 | + |
|
340 | +# Print the hostname of this machine: |
|
341 | +echo $HOSTNAME |
|
342 | + |
|
343 | +# Print information about current linux distro: |
|
344 | +lsb_release -a |
|
345 | + |
|
346 | +# Print linux kernel version: |
|
347 | +uname -a |
|
348 | + |
|
349 | +# Print information about kernel modules: |
|
350 | +lsmod |
|
351 | + |
|
352 | +# Configure kernel modules (never do this): |
|
353 | +modprobe |
|
354 | + |
|
355 | +# View Installed packages: |
|
356 | +dpkg --get-selections |
|
357 | + |
|
358 | +# Print environment variables: |
|
359 | +printenv |
|
360 | + |
|
361 | +# List hardware connected via PCI ports: |
|
362 | +lspci |
|
363 | + |
|
364 | +# List hardware connected via USB ports: |
|
365 | +lsusb |
|
366 | + |
|
367 | +# Print hardware info stored in BIOS: |
|
368 | +sudo dmidecode |
|
369 | + |
|
370 | +# Dump captured data off of wireless card: |
|
371 | +dumpcap |
|
372 | + |
|
373 | +# Dump info about keyboard drivers: |
|
374 | +dumpkeys |
|
375 | + |
|
376 | +***** System Administration (Continued): |
|
377 | + |
|
378 | +# Add a Personal Package Archive from Ubuntu Launchpad: |
|
379 | + |
|
380 | +add-apt-repository |
|
381 | + |
|
382 | +# Install a .deb file from command line: |
|
383 | +sudo dpkg -i package.deb |
|
384 | +**** Python: |
|
385 | + |
|
386 | +# update pip (Python package manager): |
|
387 | +pip install -U pip |
|
388 | + |
|
389 | +# search pip repos |
|
390 | +pip |
|
391 | + |
|
392 | +# create a virtual python environment |
|
393 | +virtualenv [dirname] --no-site-packages |
|
394 | + |
|
395 | +# connect to a virtual python environment |
|
396 | +source [dirname]/bin/activate |
|
397 | + |
|
398 | +# disconnect from a python environment: |
|
399 | +deactivate |
|
400 | + |
|
401 | +# install package into virtual python environment from outsie: |
|
402 | +pip install [packagename]==[version_number] -E [dirname] |
|
403 | + |
|
404 | +# export python virtual environment into a shareable format: |
|
405 | +pip freeze -E [dirname] > requirements.txt |
|
406 | + |
|
407 | +# import python virtual environment from a requirements.txt file: |
|
408 | +pip install -E [dirname] -r requirements.txt |
|
409 | + |
|
410 | +**** git (all commands must be performed in the same directory as .git folder): |
|
411 | + |
|
412 | +# Start a new git project: |
|
413 | +git init |
|
414 | + |
|
415 | +# Clone a git (target can be specified either locally or remotely, via any number of protocols): |
|
416 | +git clone [target] |
|
417 | + |
|
418 | +# Commit changes to a git: |
|
419 | +git commit -m "[message]" |
|
420 | + |
|
421 | +# Get info on current repository: |
|
422 | +git status |
|
423 | + |
|
424 | +# Show change log for current repository: |
|
425 | +git log |
|
426 | + |
|
427 | +# Update git directory from another repository: |
|
428 | +git pull [target] |
|
429 | + |
|
430 | +# Push branch to other repository: |
|
431 | +git push [target] |
|
432 | + |
|
433 | +# Create a new branch: |
|
434 | +git branch [branchname] |
|
435 | + |
|
436 | +# Switch to target branch: |
|
437 | +git checkout [branchname] |
|
438 | + |
|
439 | +# Delete a branch: |
|
440 | +git branch -d [branchname] |
|
441 | + |
|
442 | +# Merge two branches: |
|
443 | +git merge [branchname] [branchname] |
|
444 | + |
|
445 | +*** Virtualization: |
|
446 | + |
|
447 | +#clone a virtual machine (this works, it's been tested): |
|
448 | +vboxmanage clonehd [virtual machine name].vdi --format VDI ~/[target virtual machine name].vdi |
|
449 | + |
|
450 | +#mount a shared virtual folder: |
|
451 | +#you need to make sure you have the right kernel modules. You can do this with modprobe, but this package works instead in a ubuntu-specific way. |
|
452 | + |
|
453 | +sudo apt-get install virtualbox-ose-guest-utils |
|
454 | + |
|
455 | +sudo mount -t vboxsf [name of Shared folder specified in Virtualbox] [path of mountpoint] |
|
456 | + |
|
457 | +*** mysql: |
|
458 | + |
|
459 | +# Get help: |
|
460 | +help |
|
461 | + |
|
462 | +# Show databases: |
|
463 | +show databases; |
|
464 | + |
|
465 | +# Choose a database to use: |
|
466 | +use [database name here]; |
|
467 | + |
|
468 | +# Show database schema: |
|
469 | +show tables; |
|
470 | + |
|
471 | +# Delete database: |
|
472 | +DROP DATABASE [databasename]; |
|
473 | + |
|
474 | +# New database: |
|
475 | +CREATE DATABASE [databasename]; |
|
476 | + |
|
477 | +# Create a new user: |
|
478 | +CREATE USER [username@localhost] IDENTIFIED BY '[password]' ; |
|
479 | + |
|
480 | +# Show users: |
|
481 | +select * from mysql.user; |
|
482 | + |
|
483 | +# Delete a user: |
|
484 | +delete from mysql.user WHERE User='[user_name]'; |
|
485 | + |
|
486 | +# Give user access to all tables (make them root). the "%" means that they can sign in remotely, from any machine, not just localhost.: |
|
487 | +grant all privileges on *.* to someusr@"%" identified by '[password]'; |
|
488 | + |
|
489 | +# give certain privileges to a user on a certain database: |
|
490 | +grant select,insert,update,delete,create,drop on [somedb].* to [someusr]@["%"] identified by '[password]'; |
|
491 | + |
|
492 | +# Tell mysql to use new user priv policies: |
|
493 | +flush privileges; |
|
494 | + |
|
495 | +# change user password: |
|
496 | +use mysql; |
|
497 | + |
|
498 | +update user set password='[password]'('[newpassword]') where User='[user_name]' ; |
|
499 | + |
|
500 | +# mysql command line args: |
|
501 | + |
|
502 | +# export text file with commands to rebuild all mysql tables: |
|
503 | + |
|
504 | +mysqldump [databasename] > [dumpfilename.txt] |
|
505 | + |
|
506 | +# restore from a dump: |
|
507 | + |
|
508 | +mysql -u [username] -p < [dumpfilename.txt] |
|
509 | + |
|
510 | +# dump entire database: |
|
511 | + |
|
512 | +mysqldump -u [username] -p --opt [databasename] > [dumpfile.sql] |
|
513 | + |
|
514 | +# restore from entire database dump: |
|
515 | + |
|
516 | +mysql -u [username] -p --database=[databasename] < [dumpfile.sql] |
|
517 | +``` |
|
... | ... | \ No newline at end of file |
linux-grab-bag.md
... | ... | @@ -0,0 +1,99 @@ |
1 | +http://mmb.pcb.ub.es/~carlesfe/unix/tricks.txt |
|
2 | + |
|
3 | +``` |
|
4 | +I have marked with a * those which I think are absolutely essential |
|
5 | +Items for each section are sorted by oldest to newest. Come back soon for more! |
|
6 | + |
|
7 | +BASH |
|
8 | +* In bash, 'ctrl-r' searches your command history as you type |
|
9 | +- Add "set -o vi" in your ~/.bashrc to make use the vi keybindings instead |
|
10 | + of the Emacs ones. Takes some time to get used to, but it's fantastic! |
|
11 | +- Input from the commandline as if it were a file by replacing |
|
12 | + 'command < file.in' with 'command <<< "some input text"' |
|
13 | +- '^' is a sed-like operator to replace chars from last command |
|
14 | + 'ls docs; ^docs^web^' is equal to 'ls web'. The second argument can be empty. |
|
15 | +* '!!:n' selects the nth argument of the last command, and '!$' the last arg |
|
16 | + 'ls file1 file2 file3; cat !!:1-2' shows all files and cats only 1 and 2 |
|
17 | +- More in-line substitutions: http://tiny.cc/ecv0cw http://tiny.cc/8zbltw |
|
18 | +- 'nohup ./long_script &' to leave stuff in background even if you logout |
|
19 | +- 'cd -' change to the previous directory you were working on |
|
20 | +- 'ctrl-x ctrl-e' opens an editor to work with long or complex command lines |
|
21 | +* Use traps for cleaning up bash scripts on exit http://tiny.cc/traps |
|
22 | +* 'shopt -s cdspell' automatically fixes your 'cd folder' spelling mistakes |
|
23 | + |
|
24 | + |
|
25 | +PSEUDO ALIASES FOR COMMONLY USED LONG COMMANDS |
|
26 | +- function lt() { ls -ltrsa "$@" | tail; } |
|
27 | +- function psgrep() { ps axuf | grep -v grep | grep "$@" -i --color=auto; } |
|
28 | +- function fname() { find . -iname "*$@*"; } |
|
29 | + |
|
30 | + |
|
31 | +VIM |
|
32 | +- ':set spell' activates vim spellchecker. Use ']s' and '[s' to move between |
|
33 | + mistakes, 'zg' adds to the dictionary, 'z=' suggests correctly spelled words |
|
34 | +- check my .vimrc http://tiny.cc/qxzktw and here http://tiny.cc/kzzktw for more |
|
35 | + |
|
36 | + |
|
37 | +TOOLS |
|
38 | +* 'htop' instead of 'top' |
|
39 | +- 'ranger' is a nice console file manager for vi fans |
|
40 | +- Use 'apt-file' to see which package provides that file you're missing |
|
41 | +- 'dict' is a commandline dictionary |
|
42 | +- Learn to use 'find' and 'locate' to look for files |
|
43 | +- Compile your own version of 'screen' from the git sources. Most versions |
|
44 | + have a slow scrolling on a vertical split or even no vertical split at all |
|
45 | +* 'trash-cli' sends files to the trash instead of deleting them forever. |
|
46 | + Be very careful with 'rm' or maybe make a wrapper to avoid deleting '*' by |
|
47 | + accident (e.g. you want to type 'rm tmp*' but type 'rm tmp *') |
|
48 | +- 'file' gives information about a file, as image dimensions or text encoding |
|
49 | +- 'sort | uniq' to check for duplicate lines |
|
50 | +- 'echo start_backup.sh | at midnight' starts a command at the specified time |
|
51 | +- Pipe any command over 'column -t' to nicely align the columns |
|
52 | +* Google 'magic sysrq' and learn how to bring you machine back from the dead |
|
53 | +- 'diff --side-by-side fileA.txt fileB.txt | pager' to see a nice diff |
|
54 | +* 'j.py' http://tiny.cc/62qjow remembers your most used folders and is an |
|
55 | + incredible substitute to browse directories by name instead of 'cd' |
|
56 | +- 'dropbox_uploader.sh' http://tiny.cc/o2qjow is a fantastic solution to |
|
57 | + upload by commandline via Dropbox's API if you can't use the official client |
|
58 | +- learn to use 'pushd' to save time navigating folders (j.py is better though) |
|
59 | +- if you liked the 'psgrep' alias, check 'pgrep' as it is far more powerful |
|
60 | +* never run 'chmod o+x * -R', capitalize the X to avoid executable files. If |
|
61 | + you want _only_ executable folders: 'find . -type d -exec chmod g+x {} \;' |
|
62 | +- 'xargs' gets its input from a pipe and runs some command for each argument |
|
63 | + |
|
64 | + |
|
65 | +NETWORKING |
|
66 | +- Don't know where to start? SMB is usually better than NFS for most cases. |
|
67 | + 'sshfs_mount' is not really stable, any network failure will be troublesome |
|
68 | +- 'python -m SimpleHTTPServer 8080' shares all the files in the current |
|
69 | + folder over HTTP, port 8080 |
|
70 | +- 'ssh -R 12345:localhost:22 server.com "sleep 1000; exit"' forwards |
|
71 | + server.com's port 12345 to your local ssh port, even if you machine |
|
72 | + is not externally visible on the net. |
|
73 | + Now you can 'ssh localhost -p 12345' from server.com and you will |
|
74 | + log into your machine. |
|
75 | + 'sleep' avoids getting kicked out from server.com for inactivity |
|
76 | +* Read on 'ssh-keygen' to avoid typing passwords every time you ssh |
|
77 | +- 'socat TCP4-LISTEN:1234,fork TCP4:192.168.1.1:22' forwards your port |
|
78 | + 1234 to another machine's port 22. Very useful for quick NAT redirection. |
|
79 | +* Configure postfix to use your personal Gmail account as SMTP: |
|
80 | + http://tiny.cc/n5k0cw. Now you can send emails from the command line. |
|
81 | + 'echo "Hello, User!" | mail user@domain.com' |
|
82 | +- Some tools to monitor network connections and bandwith: |
|
83 | + 'lsof -i' monitors network connections in real time |
|
84 | + 'iftop' shows bandwith usage per *connection* |
|
85 | + 'nethogs' shows the bandwith usage per *process* |
|
86 | +* Use this trick on .ssh/config to directly access 'host2' which is on a private |
|
87 | + network, and must be accessed by ssh-ing into 'host1' first |
|
88 | + Host host2 |
|
89 | + ProxyCommand ssh -T host1 'nc %h %p' |
|
90 | + HostName host2 |
|
91 | +* Pipe a compressed file over ssh to avoid creating large temporary .tgz files |
|
92 | + 'tar cz folder/ | ssh server "tar xz"' or even better, use 'rsync' |
|
93 | + |
|
94 | + -~- |
|
95 | + |
|
96 | +(CC) by-nc, Carles Fenollosa <carles.fenollosa@bsc.es> |
|
97 | +Retrieved from http://mmb.pcb.ub.es/~carlesfe/unix/tricks.txt |
|
98 | +Last modified: vie 08 mar 2013 12:42:06 CET |
|
99 | +``` |
linux.md
... | ... | @@ -0,0 +1,159 @@ |
1 | +## Other tips |
|
2 | + |
|
3 | +[Grab bag](linux-grab-bag) |
|
4 | + |
|
5 | +[Grab bag 2](linux-grab-bag-2) |
|
6 | + |
|
7 | +## Permissions |
|
8 | + |
|
9 | +Utility: <http://permissions-calculator.org/> |
|
10 | + |
|
11 | +## Monit |
|
12 | + |
|
13 | +Version (14-Nov-2012): 5.1.1 |
|
14 | +Documentation: <http://mmonit.com/monit/documentation/monit.html> |
|
15 | + |
|
16 | +Monit is a service and can be stopped / started / restarted / reloaded with (for instance, as root) |
|
17 | + |
|
18 | + service monit restart |
|
19 | + |
|
20 | +But typically one uses the `monit` command directly (in fact, `service monit reload` delegates to monit itself). For help on monit: |
|
21 | + |
|
22 | + monit -h |
|
23 | + |
|
24 | +The monit config file lives at `/etc/monit.conf`. On our Puppetized system, monit configuration is exceedingly short, on the theory that starting with a small configuration and growing it is better than using a fancy config and getting confused by it. So our entire config file is: |
|
25 | + |
|
26 | + set daemon 15 |
|
27 | + set statefile /tmp/monit.state |
|
28 | + set mailserver localhost |
|
29 | + set httpd port 2812 and |
|
30 | + use address localhost |
|
31 | + allow localhost |
|
32 | + include /etc/monit.d/* |
|
33 | + |
|
34 | +The daemon setting defines how frequently monit runs (every 15 seconds - this is faster than the stock setting). |
|
35 | + |
|
36 | +The statefile is actually quite important. If a server crashes, the statefile is consulted so that any services that were manually started can be restarted automatically. We actually don't want this. We want a post-crash server to come up with only predefined automated monitoring. Therefore, we put the statefile in /tmp so that it won't be found after a crash. For this practice, see the end of the "Monitoring Mode" discussion: <http://mmonit.com/monit/documentation/monit.html#monitoring_mode> |
|
37 | + |
|
38 | +Here our mailserver setting means that we use Postfix on localhost, which is not what we will want as we grow. |
|
39 | + |
|
40 | +The httpd port is crucial, because when you consult monit's status through the monit command, it probes this port for details of the current state. We only allow the state to be reviewed from localhost, though there is also a web interface. |
|
41 | + |
|
42 | +Finally, the include directive pulls in configuration files for each individual service. |
|
43 | + |
|
44 | +### Service configuration |
|
45 | + |
|
46 | +Here's the config file for DrFirst: |
|
47 | + |
|
48 | + check process vagrant_dr_first |
|
49 | + with pidfile "/home/deployer/apps/icis/vagrant/shared/pids/vagrant_dr_first.pid" |
|
50 | + start program = "/bin/sh -l -c 'cd /home/deployer/apps/icis/vagrant/current; RAILS_ENV=vagrant APPLICATION="" ANS_SYSTEM=cert ENDPOINTS_USERNAME=drf ENDPOINTS_PASSWORD=RAV5Cu0L4G5cJom5 QUEUE_NAME=dr_firs |
|
51 | + t REDIS=redis://db.vagrant.icisapp.com/0 RESQUE_NAMESPACE=resque:ICIS:vagrant WORKER_LOGGER_PATH=log/vagrant_dr_first.log WORKER_LOGGER_LEVEL=debug PIDFILE=/home/deployer/apps/icis/vagrant/shared/pids/vag |
|
52 | + rant_dr_first.pid BACKGROUND=t nohup bundle exec dr_first_worker >> log/vagrant_dr_first.log 2>&1'" as uid deployer and gid deployer with timeout 240 seconds |
|
53 | + stop program = "/bin/bash -c 'cd /home/deployer/apps/icis/vagrant/current && kill -s QUIT `cat /home/deployer/apps/icis/vagrant/shared/pids/vagrant_dr_first.pid` && rm -f /home/deployer/apps/icis/vagran |
|
54 | + t/shared/pids/vagrant_dr_first.pid; exit 0;'" as uid deployer and gid deployer |
|
55 | + mode active |
|
56 | + |
|
57 | +A few things: |
|
58 | + |
|
59 | +* Notice the "with pidfile": That is the means by which monit detects that a process has crashed and restarted, or has been restarted behind the back of monit (we get these when the deploy process restarts faye). |
|
60 | +* The moral of the pidfile monitoring is that monit should "own" the things it monitors. Generally, once something is being managed in monit, you stop starting and stopping them through the "service" command or the files in `/etc/init.d`. (In our case, we should be stopping/starting via monit not via the cap and rake faye targets.) |
|
61 | +* The relative complexity of the "start program" and "stop program" directives is much simpler than it was, because rvm added another level of configuration. Arguably, the stop/start logic should be encapsulated by scripts; but the reason it is exposed here is because if you ever want to tinker with this, you probably don't want to consult another file. |
|
62 | +* As a best practice, process startup should be as fast as possible for monit to manage it well. For the "box" worker, we run a rake task within the ICIS process, because the box process has full-blown ActiveRecord model instances passed in. To speed up startup, we should stop booting up Rails to work off of a queue. The way to do this would be to serialize the data required for the box process as a hash or some other kind of lightweight object. |
|
63 | + |
|
64 | +## What processes are running? |
|
65 | + |
|
66 | +To find out what processes are running, do |
|
67 | + |
|
68 | + ps -ef |
|
69 | + |
|
70 | +`-e` means every process (same as `-A`), and `-f` means that you want the "full" listing. If you want to know if a specific program is running, try `ps -ef | grep -i PROGNAME`, e.g., `ps -ef | grep -i postgres` (`-i` means: case insensitive). |
|
71 | + |
|
72 | +A very useful command is `pgrep`: Read the man page yourself; but it becomes even more useful when you want to kill processes with its companion `pkill`: |
|
73 | + |
|
74 | + sudo pkill -SIGTERM -f -u postgres iora_health_development |
|
75 | + |
|
76 | +You can also use `top`. |
|
77 | + |
|
78 | +## How much physical memory is available? Am I using virtual memory? |
|
79 | + |
|
80 | + [ops@vagrant ~]$ free -m -t |
|
81 | + total used free shared buffers cached |
|
82 | + Mem: 490 (a) 383 (b) 106 0 22 (f) 267 (e) |
|
83 | + -/+ buffers/cache: 94 (g) 396 |
|
84 | + Swap: 991 (c) 0 991 |
|
85 | + Total: 1482 (d) 384 1098 |
|
86 | + |
|
87 | +The `-m` means: report in MB. Otherwise you will get the quantity of "blocks." |
|
88 | + |
|
89 | +490MB of physical memory are available (a). The total in use is 383MB (b). The kernel may decided that some memory is not being accessed very frequently. When it notices this, it may save it to disk (a "swap out") thus freeing RAM for other purposes. If a process needs that RAM, it will swap it back in. When a hunk of memory (a "page") is asked for but not in RAM, that is called a "page fault." This is what is called virtual memory. This technology goes back to the 60s on systems such Multics and the IBM 360. |
|
90 | + |
|
91 | +The total amount of disk space provided for swapping out is 991MB (c). Thus the total available memory is 1481MB (or 1482MB (d): That final line of totals is provided by the `-t` option). What happens if all of the 1481MB is used? Then you will get "out of memory" failures, which are logged in `/var/log/messages`. It is not uncommon to configure your system so that there is 0 swap space because you don't want the kernel to go to disk for anything. A rule of thumb is to devote 2x the RAM for swap, for no particularly good reason. Typically a special partition is set aside for swap. You can see this with `swapon -s`: |
|
92 | + |
|
93 | + [ops@vagrant ~]$ swapon -s |
|
94 | + Filename Type Size Used Priority |
|
95 | + /dev/dm-1 partition 1015800 936 -1 |
|
96 | + |
|
97 | +(Those are bytes. 936 bytes is so small it is considered 0MB (e) in free.) |
|
98 | + |
|
99 | +Now, the kernel will allocate some of that memory for disk access, i.e., it will keep frequently used parts of the disk in RAM to speed things up. Here it's 267MB (e). The kernel will also allocate short-lived in-memory I/O buffers: here, 22MB (f). |
|
100 | + |
|
101 | +Notice that the kernel is using 22 + 267 MB (289MB) for its nefarious purposes. Now subtract that from the total RAM used (383MB), giving 94MB, which you will see in the "-/+" row (g). This is an important number. It is the amount of memory not being used by the kernel, i.e., the amount being used by ordinary programs such as Rails and PostgreSQL. |
|
102 | + |
|
103 | +### But, doctor, is all this swapping normal? |
|
104 | + |
|
105 | +Swap utilization doesn't really matter. So what if the kernel has parked a lot of unused memory on the disk? If no one wants it frequently, we don't care. What we *do* care about is moving stuff from RAM to disk and back frequently. How can we observe this? |
|
106 | + |
|
107 | +The best way is to use the `vmstat` command, which takes two parameters, the length of a probe in seconds (i.e., for this number of seconds, how much is being swapped in and out) and the number of times to check (you can leave off the last param to run forever). For example: |
|
108 | + |
|
109 | + [ops@vagrant ~]$ vmstat 5 4 |
|
110 | + procs -----------memory---------- ---swap-- -----io---- --system-- -----cpu----- |
|
111 | + r b swpd free buff cache si so bi bo in cs us sy id wa st |
|
112 | + 0 0 19228 290024 15664 129692 3 7 175 249 220 293 5 1 93 0 0 |
|
113 | + 0 0 19228 290016 15664 129680 0 0 0 0 134 248 0 0 100 0 0 |
|
114 | + 1 0 19228 290016 15672 129680 0 0 0 2 131 249 0 0 100 0 0 |
|
115 | + 0 0 19228 290016 15672 129680 0 0 0 0 130 246 0 0 99 0 0 |
|
116 | + |
|
117 | +The first row is the data since the last reboot. |
|
118 | + |
|
119 | +`si` is the amount of memory swapped in from disk per second (kernel says: uh oh, someone wants this memory I parked on the disk!). `so` is the amount of memory swapped to disk per second (kernel says: No urgency for this memory: park it on the disk). If these numbers are both big, then you are "thrashing" (a bad thing). For example: |
|
120 | + |
|
121 | + [ops@vagrant ~]$ vmstat 5 |
|
122 | + procs -----------memory---------- ---swap-- -----io---- --system-- -----cpu----- |
|
123 | + r b swpd free buff cache si so bi bo in cs us sy id wa st |
|
124 | + 3 0 0 12044 17648 59088 0 0 4315 56 1047 30823 21 35 39 6 0 |
|
125 | + 5 1 6424 33104 10768 15892 0 1277 2692 1458 1312 73165 50 50 0 0 0 |
|
126 | + 4 0 7900 4136 8308 18656 0 292 1884 332 1230 1364 63 38 0 0 0 |
|
127 | + 3 1 8760 5536 11460 26808 74 176 3282 209 1101 1239 74 26 0 0 0 |
|
128 | + 2 1 17000 3244 6068 13644 99 1659 1046 1704 960 1015 78 22 0 0 0 |
|
129 | + 2 2 28960 3772 3800 9512 14 2393 5616 2394 1172 1390 73 27 0 1 0 |
|
130 | + 2 2 42760 4020 3124 6856 6 2758 4250 2780 1122 1373 79 20 0 1 0 |
|
131 | + 3 0 52312 89864 1476 7232 1482 3240 9490 3261 1233 1587 74 24 0 1 0 |
|
132 | + 0 0 47072 79888 1624 14412 1179 0 2629 14 331 759 7 4 88 0 0 |
|
133 | + 1 0 45256 81704 13312 70772 198 0 8942 1498 1853 2659 52 27 13 8 0 |
|
134 | + |
|
135 | +This is ICIS being deployed on a Vagrant - but it is a very special Vagrant, running with only 256MB RAM. |
|
136 | + |
|
137 | +Typically, ICIS rarely swaps. |
|
138 | + |
|
139 | +### Can I identify which program is causing swapping? |
|
140 | + |
|
141 | +No. That's not how it works. A "swap in" can be triggered by any program, small or large. What it's about is demand on RAM. If you are seeing a lot of swapping, you need more RAM. Having said that, it is possible to figure out which program has the most allocated memory sitting on the disk. See <http://www.quora.com/How-can-I-determine-which-process-is-contributing-to-paging-on-Linux> |
|
142 | + |
|
143 | +## Disk usage |
|
144 | + |
|
145 | +### How much storage is being used on each disk? |
|
146 | + |
|
147 | + df -kh |
|
148 | + |
|
149 | +### Which directories are holding the most data? |
|
150 | + |
|
151 | + sudo du -sh /* |
|
152 | + |
|
153 | + (Probe carefully: this is traverse your entire tree.) |
|
154 | + |
|
155 | +## Log rotation |
|
156 | + |
|
157 | +Log rotation is simply close out the currently-used logs and starting up new ones. |
|
158 | + |
|
159 | +We actually shouldn't be rotating logs. What we should be doing is logging to a centralized log server with software such as syslog-ng: <http://www.bluebox.net/about/blog/2009/06/unified_rails_logging_with_syslog-ng/>). |
list.md
... | ... | @@ -0,0 +1 @@ |
1 | +mm: recovery key: |
mac-osx-rebuilding.md
... | ... | @@ -0,0 +1,3 @@ |
1 | +1. Put in USB drive |
|
2 | +2. Restart |
|
3 | +3. PC keyboard: Hold down ALT |
management.md
... | ... | @@ -0,0 +1,18 @@ |
1 | +### One-on-One's |
|
2 | + |
|
3 | +* <https://popforms.com/30-minutes-one-on-one/> and <https://popforms.com/ones/> |
|
4 | +* <http://randsinrepose.com/archives/the-update-the-vent-and-the-disaster/> |
|
5 | + |
|
6 | +### Scaling |
|
7 | + |
|
8 | +* How to Scale a Development Team - <http://adam.herokuapp.com/past/2011/4/28/scaling_a_development_team/> |
|
9 | + |
|
10 | +### Product management |
|
11 | + |
|
12 | +* <https://medium.com/hubspot-product/4-mistakes-new-product-managers-make-359ca767fdef> |
|
13 | +* <http://dev.hubspot.com/blog/what-does-a-product-manager-do-at-hubspot> |
|
14 | + |
|
15 | +### Work day |
|
16 | + |
|
17 | +* <http://www.theguardian.com/world/2015/sep/17/efficiency-up-turnover-down-sweden-experiments-with-six-hour-working-day> |
|
18 | + |
mechanize.md
... | ... | @@ -0,0 +1,25 @@ |
1 | +Quick example |
|
2 | + |
|
3 | +```ruby |
|
4 | + |
|
5 | +require 'mechanize' |
|
6 | +require 'csv' |
|
7 | + |
|
8 | +headers = nil |
|
9 | + |
|
10 | +agent = Mechanize.new |
|
11 | +page = agent.get('http://en.wikipedia.org/wiki/List_of_The_Office_(U.S._TV_series)_characters') |
|
12 | +table_rows = page.search('table.wikitable tr') |
|
13 | +CSV do |csv| |
|
14 | + table_rows.each_with_index do |row, i| |
|
15 | + if i == 0 |
|
16 | + headers = row.search('th').map(&:text) |
|
17 | + csv << headers |
|
18 | + else |
|
19 | + values = row.search('td') |
|
20 | + next if values.size < headers.size |
|
21 | + csv << values.map(&:text) |
|
22 | + end |
|
23 | + end |
|
24 | +end |
|
25 | +``` |
mirth.md
... | ... | @@ -0,0 +1,341 @@ |
1 | +### Download and install |
|
2 | + |
|
3 | +Download an install Java 7 first; Java 6 on the most recent Lion seems broken. For the download: <http://www.oracle.com/technetwork/java/javase/downloads/index.html> |
|
4 | + |
|
5 | +Mirth downloads: <http://www.mirthcorp.com/community/downloads> |
|
6 | + |
|
7 | +Use 2.2.1.x |
|
8 | + |
|
9 | +For OS/X, use the Installer; select all components. For ports: To not collide with ICIS port redirection to Vagrant, prefix all ports with 1, e.g., 18080, 18443, 11099. Do ask for the Server Manager to run post-install. When the Server Manager starts up, select the "Database" config, and change the type to postgresql. In a separate window, `createdb mirthdb`. No username and password should be needed. You should then be able to browse to <http://localhost:18080> |
|
10 | + |
|
11 | +### Install details |
|
12 | + |
|
13 | +OS/X: Mirth is installed at `/Applications/Mirth Connect`. Application data is in `/Applications/Mirth Connect/appdata` and log data is in `/Applications/Mirth Connect/logs`. Install service? Yes |
|
14 | + |
|
15 | +Linux: Mirth is installed at `/usr/local/mirthconnect` |
|
16 | + |
|
17 | +* Config files are in `conf/`. The main config file is: `conf/mirth.properties` |
|
18 | +* This file has been updated to use a postgres database called mirthdb, username postgres, no pw for now |
|
19 | +* To start service: `./mcservice start` |
|
20 | +* To stop service: `./mcservice stop` |
|
21 | + |
|
22 | + |
|
23 | +# Mirth |
|
24 | + |
|
25 | +Mirth is a tool for processing incoming messages, with special emphasis on HL7. |
|
26 | +I want to note up front, though, that Mirth is quite generic; it can be used |
|
27 | +for almost any kind of file processing. |
|
28 | + |
|
29 | +## Installation |
|
30 | + |
|
31 | +My recommendation is that you install Mirth onto your Mac. Then browse to |
|
32 | +<http://localhost:8080> and download the `.jnlp` file, which provides access |
|
33 | +to the Mirth Connect Administrator. You can move this `.jnlp` to your |
|
34 | +`/Applications` folder for later access. |
|
35 | + |
|
36 | +After the install, you will find in `/Applications/Mirth Connect` an app |
|
37 | +called `mcmanager.app`: This is the "Mirth Connect Server Manager." Open |
|
38 | +this to change your database configuration. My suggestion is that you create |
|
39 | +a database in PostgreSQL (`createdb mirthdb`) and then set your Database |
|
40 | +connector accordingly. |
|
41 | + |
|
42 | +## Reinstallation |
|
43 | + |
|
44 | +You can drop the mirthdb, re-create it, and start over. For example: |
|
45 | + |
|
46 | +``` |
|
47 | +sudo launchctl stop com.mirth.connect |
|
48 | +dropdb mirthdb |
|
49 | +createdb mirthdb |
|
50 | +sudo launchctl start com.mirth.connect |
|
51 | +``` |
|
52 | + |
|
53 | +## User Interface |
|
54 | + |
|
55 | +**TL;DR** Notice that the left sidebar nav changes depending on what you |
|
56 | +are doing! Much of the good stuff is here! |
|
57 | + |
|
58 | +Let me tell you one thing that is obvious in Mirth but took me awhile to get |
|
59 | +used to: Whenever you pick a channel to do something with it, the menu in the |
|
60 | +left sidebar changes; i.e., it's contextual: It's the same menu you get when |
|
61 | +you right-click on something. |
|
62 | + |
|
63 | +You will find that the contextual menu changes quite a bit. For example, |
|
64 | +select a channel, right-click to edit it, and look under "Channel Tasks": See |
|
65 | +"Export Channel." Now click the "Source" tab, and look again: You will see |
|
66 | +a number of new options. All of the good stuff is in these contextual |
|
67 | +sidebar navs. |
|
68 | + |
|
69 | +When you want to save something, click out of it (e.g., if editing a |
|
70 | +specific channel, click "Channels" in the main menu, and you will be |
|
71 | +prompted to save). |
|
72 | + |
|
73 | +Notice as well that if you touch a channel in an "editing" way, a "Save Changes" |
|
74 | +item will be added under "Channel Tasks." |
|
75 | + |
|
76 | +Double-click frequently does what you expect: For example, if you're looking |
|
77 | +at a channel, you can double-click it to edit it. |
|
78 | + |
|
79 | +## Terminology |
|
80 | + |
|
81 | +### Channel |
|
82 | + |
|
83 | +Think of a "channel" as a processor. The processor defines sources, |
|
84 | +destinations, filters, and transformers. |
|
85 | + |
|
86 | +### Source |
|
87 | + |
|
88 | +A source has a Connector Type. Examples: File Reader, LLP Reader (wire protocol |
|
89 | +for HL7). |
|
90 | + |
|
91 | +### Destination |
|
92 | + |
|
93 | +Where a message goes. Also has Connector Types: Channel Writer (write BACK into |
|
94 | +a Channel), File Writer, Database Writer). |
|
95 | + |
|
96 | +### Filter |
|
97 | + |
|
98 | +When a Channel is being edited, you can add filters to either the Source or the |
|
99 | +Destinations. This allows you to pick and choose from the "messages" being passed |
|
100 | +through the Channel. [? Difference between filters on Source and Destinations? |
|
101 | +Why would you want to filter in one place as opposed to the other?] |
|
102 | + |
|
103 | +### Transformer |
|
104 | + |
|
105 | +This gives you a chance to cherry-pick from the incoming elements of the |
|
106 | +HL7 message (e.g., msg['PID']['PID.8']['PID.8.1']) and set them to a variable |
|
107 | +name (e.g., 'gender') and then add that to the "Channel Map." |
|
108 | + |
|
109 | +If the Data Type is Delimited Text, you can also reference the columns of a CSV file. |
|
110 | + |
|
111 | + |
|
112 | + |
|
113 | +## Recipes |
|
114 | + |
|
115 | +### Process some files - noop |
|
116 | + |
|
117 | +1. Create directories `input/`, `output/`, `error/`, and `backup/`. Put the example files |
|
118 | +in `backup/` and then `cp -R backup/* input/`. |
|
119 | + |
|
120 | +2. Select Channels; "New Channel" |
|
121 | + |
|
122 | +3. Channel Name: "Process" |
|
123 | + |
|
124 | +4. In Source tab: For Connector Type, choose: "File Reader." For Directory: |
|
125 | +`/Users/jgn/Desktop/mirth/data/input`; For "Move-to Directory": `/Users/jgn/Desktop/mirth/data/output`; |
|
126 | +For "Error Move-to Directory": `/Users/jgn/Desktop/mirth/data/error`. |
|
127 | + |
|
128 | +5. In Destination tab: For Connector Type, choose: "Channel Writer," and then in the |
|
129 | +"Channel Writer" pane, for Channel Name, pick: None (should already be selected). |
|
130 | + |
|
131 | +6. Now click: Channels, and click Yes for "Save?" |
|
132 | + |
|
133 | +7. Notice that the status for this Channel is "Enabled." Right-click and select: "Deploy Channel." |
|
134 | + |
|
135 | +8. Watch. You should see that 19 messages are received and sent. If you right-click and |
|
136 | +select "View Messages," you can inspect the state of the data as it passed from source to desination. |
|
137 | +Also, inspect the `output/` and `error/` directories. You should see processed files in `output/` |
|
138 | +and nothing in `error/`. |
|
139 | + |
|
140 | +9. Go back to the Dashboard, right-click the Channel, and select Pause. Select again, and: Remove |
|
141 | +All Messages (and clear stats). Now `cp -R backup/* input/` to put the files back, and remove |
|
142 | +everything in `output/`. |
|
143 | + |
|
144 | +### Process some csv files |
|
145 | + |
|
146 | +1. Create channel; Data Types: Set Data Types . . . Switch all Data Type from HL7 v2.x to Delimited Text. |
|
147 | + |
|
148 | +2. Now click in Properties for "Source Connector Inbound": For "Record Delimiter": \r\n |
|
149 | +UNCHECK "Ignore Carriage Returns"; Set "Number of Header Records" to: 1 |
|
150 | + |
|
151 | +3. Change Source Connector Type to: File Reader. For Directory: /Users/jgn/Desktop/mirth/csv/input |
|
152 | +Make sure that "Process Batch Files" is: Yes |
|
153 | + |
|
154 | +4. Change the Destination Connector Type to: Channel Writer with Channel Name: None |
|
155 | + |
|
156 | +5. Save Changes and enanble the channel; Then deploy it. At this point you can start it, and then |
|
157 | +with "View Messages" look at the incoming. You should see one CSV row per message. If multiple |
|
158 | +CSV lines have been combined, then you set the delimiters and/or Batch mode wrong. |
|
159 | + |
|
160 | +----- |
|
161 | + |
|
162 | +6. Now let's add a filter. Edit the channel. Click the source tab, and then in the left nav, Edit Filter. |
|
163 | +Add New Rule. Into the Message Template tab (right pan) paste in a row of the CSV. The most convenient |
|
164 | +is to paste in the header row. |
|
165 | + |
|
166 | +7. Now click the "Message Trees" tab. Drag the value ("Performed Test Name") INSIDE of "column12" |
|
167 | +into the field. For "Condition," select "Equals." For Valuei, click New, and enter: 'LDL Chol. (Direct)' (with quotes). |
|
168 | +You probably have a bogus default rule at the top of your filter list: Delete it. Back to Channel. Save |
|
169 | +Changes. From your Channel List, deploy channel. Now remove all messages, and inspect the incoming. |
|
170 | + |
|
171 | +----- |
|
172 | + |
|
173 | +8. Now let's shoot those values into the database. From the shell, `createdb labdata`, `psql labdata` and |
|
174 | +`create table labs (result varchar(20))`. |
|
175 | + |
|
176 | +9. Now edit the channel and go to Destinations. New Destination. Connector type: Database Writer. Driver: PG. |
|
177 | +Insert URL template. Edit for our db. Now Insert, and take "result." |
|
178 | + |
|
179 | +10. Switch over to Edit Transformer for the source. Paste the header row from the CSV into Message Templates. Drag the |
|
180 | +"value" for Column 15 (result). Make the variable name: result |
|
181 | + |
|
182 | +11. Now go back to the destination, and notice that "result" is appearing in the "Destination mappings." |
|
183 | +Drag it into the SQL. The field reference must be enclosed in single quotation marks to make the query work. |
|
184 | +[Todo: Trim the value of leading/trailing spaces.] |
|
185 | + |
|
186 | + |
|
187 | +### Process HL7 from a file or from LLP |
|
188 | + |
|
189 | +1. (Trigger LLP from Hl7 Inspector). |
|
190 | + |
|
191 | + |
|
192 | + |
|
193 | + |
|
194 | +## Useful bits of Mirth Connect information |
|
195 | + |
|
196 | +### |
|
197 | + |
|
198 | +* <http://www.mirthcorp.com/community/forums/showthread.php?t=6902&highlight=csv> |
|
199 | +* <http://codingheadache.com/?p=165> |
|
200 | +* <http://arrow.dit.ie/cgi/viewcontent.cgi?article=1001&context=teapotrep> |
|
201 | +* <http://sourceforge.net/projects/hl7inspector/> |
|
202 | +* <http://nule.org/?page_id=62> |
|
203 | +* <http://blog.nrgup.net/2012/12/parsing-continuity-of-care-ccd-using-mirth-and-mdht/> |
|
204 | +* [Example of a JavaScript transformer leverage Java classes](http://www.youtube.com/watch?v=rbyA5Ni8L-c) |
|
205 | +* [End-to-end, HL7 to PG](http://www.youtube.com/watch?v=ncHMgxbuUks&list=UUhoJ-ZJA4Lk69MBAYGDMOJA&index=23) |
|
206 | + |
|
207 | + |
|
208 | + |
|
209 | + |
|
210 | + |
|
211 | + |
|
212 | + |
|
213 | +## Oddities |
|
214 | + |
|
215 | +### Mirth can be quite slow sometimes |
|
216 | + |
|
217 | +For example, if you try to remove more than 1,000,000 messages, Mirth will |
|
218 | +devote all of its processing to that task and will seem to freeze. Be |
|
219 | +patient. |
|
220 | + |
|
221 | + |
|
222 | +## HL7 Notes |
|
223 | + |
|
224 | +An order is made to a lab with an HL7 "ORM^O01" message. |
|
225 | + |
|
226 | +The lab responds with a "ORU^R01" message (<http://www.interfaceware.com/hl7-standard/hl7-message-ORUR01.html> and <https://www.corepointhealth.com/resource-center/hl7-resources/hl7-oru-message>). |
|
227 | + |
|
228 | +Each line has a different meaning. |
|
229 | + |
|
230 | +OBR: "Observation Request" |
|
231 | + |
|
232 | +OBX: "Observation Result" (<http://www.interfaceware.com/hl7-standard/hl7-segment-OBX.html>); there can be more than one of these per incoming HL7 message. |
|
233 | + |
|
234 | +The OBX is the data that might go into Markers. |
|
235 | + |
|
236 | +HL7 messages may contain other types of data. For instance, it is possible to shove a UU-encoded PDF right into a message. |
|
237 | + |
|
238 | + |
|
239 | + |
|
240 | +## Mirth Questions |
|
241 | + |
|
242 | +1. Does one allocate one incoming LLP port per partner? |
|
243 | + |
|
244 | + |
|
245 | +## Consequences for ICIS |
|
246 | + |
|
247 | +1. Each Marker measurements that comes in from Mirth/HL7 will need an origin tag so that we can trace the measure |
|
248 | +back to its source. |
|
249 | + |
|
250 | +2. Notice that in an HL7 message, there can be MULTIPLE OBX (result values) for one message. Also notice that they |
|
251 | +have sequence numbers. Does Markers need to account |
|
252 | +for this? It may imply that certain kinds of values are themselves "arrays." |
|
253 | + |
|
254 | +3. Similarly: NTE (notes): They come after OBX's. Do we need to save them? |
|
255 | + |
|
256 | + |
|
257 | + |
|
258 | + |
|
259 | +### Using mirth.icisapp.com |
|
260 | + |
|
261 | +If you are an admin, use the latest ssh config (<https://github.com/IoraHealth/IoraHealth/wiki/Bluebox-security-and-access>) and verify your connectivity with: |
|
262 | + |
|
263 | + ssh deploy@mirth.icisapp.com |
|
264 | + |
|
265 | +Browse to http://mirth.icisapp.com - you will be asked to download a JNLP component. After it is downloaded, run it, and enter your Mirth credentials. |
|
266 | + |
|
267 | +### crontab (ops user) |
|
268 | + |
|
269 | + SHELL=/bin/bash |
|
270 | + HOME=/var/lib/pgsql |
|
271 | + PATH=/usr/local/bin:/usr/bin:/bin:/opt/ruby/bin |
|
272 | + MAILTO="" |
|
273 | + 30 4 * * * /var/lib/ops/bin/dump_mirth production daily use_box |
|
274 | + |
|
275 | +### ~ops/bin/dump_mirth |
|
276 | + |
|
277 | + #!/bin/bash |
|
278 | + source $HOME/.bash_profile |
|
279 | + source $HOME/bin/dump $1 $2 |
|
280 | + source $HOME/bin/dump_to_box $1 $BOX_PATH $LABEL |
|
281 | + |
|
282 | +### ~ops/bin/dump |
|
283 | + |
|
284 | + #!/bin/bash |
|
285 | + |
|
286 | + MIRTH_ENVIRONMENT=$1 |
|
287 | + if [ -z "$MIRTH_ENVIRONMENT" ] |
|
288 | + then |
|
289 | + MIRTH_ENVIRONMENT="vagrant" |
|
290 | + fi |
|
291 | + |
|
292 | + LABEL=$2 |
|
293 | + if [ -z "$LABEL" ] |
|
294 | + then |
|
295 | + LABEL="periodic" |
|
296 | + fi |
|
297 | + |
|
298 | + MIRTH_ENVIRONMENT=production |
|
299 | + source $HOME/.bash_profile |
|
300 | + DUMP_DIRECTORY=$HOME/dumps/$LABEL |
|
301 | + mkdir -p $DUMP_DIRECTORY |
|
302 | + DUMP_FILENAME=mirth-$MIRTH_ENVIRONMENT-`/bin/date "+%Y-%m-%d---%H-%M"`.dmp.enc |
|
303 | + /usr/bin/pg_dump -U postgres -Fc mirthdb \ |
|
304 | + | /usr/bin/openssl enc \ |
|
305 | + -aes-256-cbc \ |
|
306 | + -salt \ |
|
307 | + -out $DUMP_DIRECTORY/$DUMP_FILENAME \ |
|
308 | + -pass file:$HOME/.encode-passphrase |
|
309 | + |
|
310 | + export BOX_PATH=$DUMP_DIRECTORY/$DUMP_FILENAME |
|
311 | + export LABEL |
|
312 | + |
|
313 | +### ~ops/bin/dump_to_box |
|
314 | + |
|
315 | + #!/bin/bash |
|
316 | + |
|
317 | + # $1 - The Mirth environment (e.g., vagrant or staging or production) |
|
318 | + # $2 - Full path to file that should be uploaded to Box; if absent, no push to box |
|
319 | + # $3 - An optional label; if specified, adds "-label" to the target folder name |
|
320 | + |
|
321 | + MIRTH_ENVIRONMENT=$1 |
|
322 | + if [ -z "$MIRTH_ENVIRONMENT" ] |
|
323 | + then |
|
324 | + MIRTH_ENVIRONMENT="vagrant" |
|
325 | + fi |
|
326 | + |
|
327 | + BOX_PATH=$2 |
|
328 | + |
|
329 | + LABEL=$3 |
|
330 | + |
|
331 | + if [ ! -z "$BOX_PATH" ] |
|
332 | + then |
|
333 | + BOX_TARGET=MIRTH-Dumps-$MIRTH_ENVIRONMENT |
|
334 | + if [ ! -z "$LABEL" ] |
|
335 | + then |
|
336 | + BOX_TARGET=$BOX_TARGET-$LABEL |
|
337 | + fi |
|
338 | + BOX_COMMAND="box -kAPI_KEY -uicis-archives@iorahealth.com -pdummy" |
|
339 | + $BOX_COMMAND create_folder $BOX_TARGET |
|
340 | + $BOX_COMMAND upload $BOX_PATH $BOX_TARGET |
|
341 | + fi |
|
... | ... | \ No newline at end of file |
node.md
... | ... | @@ -0,0 +1,12 @@ |
1 | +#### Best way to install??? |
|
2 | + |
|
3 | +`brew install nodenv` |
|
4 | + |
|
5 | +Then |
|
6 | + |
|
7 | +`nodenv install -l` |
|
8 | + |
|
9 | +Then |
|
10 | + |
|
11 | +`nodenv install 5.7.1` |
|
12 | + |
notes/apis.md
... | ... | @@ -0,0 +1,69 @@ |
1 | +### REST |
|
2 | + |
|
3 | +"Representational State Transfer" |
|
4 | + |
|
5 | +### APIs |
|
6 | + |
|
7 | +Let's assume that our app is at the host umntodos-dev.com |
|
8 | + |
|
9 | +We can set this up by editing /etc/hosts and adding an entry like |
|
10 | + |
|
11 | +127.0.0.1 www.umntodos-dev.com api.umntodos-dev.com |
|
12 | + |
|
13 | +### Routes |
|
14 | + |
|
15 | +Review routes for, say, todos |
|
16 | + |
|
17 | + |
|
18 | + |
|
19 | +resources :todos, except: :destroy # or an Array |
|
20 | +resources :todos, only: :index |
|
21 | + |
|
22 | + |
|
23 | +Put resources on a subdomain - now traffic can be managed by our load-balance |
|
24 | + |
|
25 | +resources :todos, constraints: { subdomain: 'api' } |
|
26 | + |
|
27 | +constraints subdomain: 'api' do |
|
28 | + resources :todos |
|
29 | +end |
|
30 | + |
|
31 | +constraints subdomain: 'api' do |
|
32 | + namespace :api do |
|
33 | + resources :todos |
|
34 | + end |
|
35 | +end |
|
36 | + |
|
37 | +Now: |
|
38 | + |
|
39 | +module Api |
|
40 | + class TodosController < ApplicationController |
|
41 | + end |
|
42 | +end |
|
43 | + |
|
44 | +Makes to http://api.umntodos-dev.com/api/todos |
|
45 | + |
|
46 | +Remove /api |
|
47 | + |
|
48 | +constraints subdomain: 'api' do |
|
49 | + namespace :api, path: '/' do |
|
50 | + resources :todos |
|
51 | + end |
|
52 | +end |
|
53 | + |
|
54 | +OR |
|
55 | + |
|
56 | +namespace :api, path: '/', constraints: { subdomain: 'api' } do |
|
57 | + resources :todos |
|
58 | +end |
|
59 | + |
|
60 | +Notice module name Api - kind of gross |
|
61 | + |
|
62 | +We can force it to API |
|
63 | + |
|
64 | +In config/initializes/inflections.rb |
|
65 | + |
|
66 | +ActiveSupport::Inflector.inflections(:en) do |inflect| |
|
67 | + inflect.acronym 'API' |
|
68 | +end |
|
69 | + |
one-page-app.md
... | ... | @@ -0,0 +1,14 @@ |
1 | +### Upgrade npm |
|
2 | + |
|
3 | + npm install npm -g |
|
4 | + |
|
5 | +### Get node up to date (not clear why needs sudo) |
|
6 | + |
|
7 | + npm cache clean -f |
|
8 | + npm install -g n |
|
9 | + # sudo n stable # not sure if this does anything |
|
10 | + |
|
11 | +### ember-cli |
|
12 | + |
|
13 | + npm install -g ember-cli |
|
14 | + |
osx-encrypted-image.md
... | ... | @@ -0,0 +1,11 @@ |
1 | +1. Open Disk Utility (located in /Applications/Utilities/). |
|
2 | +2. Click the New Image button, or choose File > New > Blank Disk Image. |
|
3 | +3. Type a name in the Save As field. This name will be used for the disk image (.dmg) file. |
|
4 | +4. Change the save destination if you wish. |
|
5 | +5. Select a size for the disk image file from the Size pop-up menu. |
|
6 | +6. Choose a different volume format if you don't want to use the default Mac OS X Extended (Journaled). |
|
7 | +7. Choose an image format. You can use "sparse disk image" for a disk image that only uses as much space as it needs, rather than a set amount of space. If you're not sure, use "read/write disk image" choice. |
|
8 | +8. Choose 128-bit AES encryption (and/or 256-bit AES in Mac OS X v10.5 or later) from the Encryption pop-up menu to encrypt the image's contents with a password. If you don't choose an encryption, your new image won't be encrypted. |
|
9 | +9. Click the Create button. |
|
10 | +10. Enter and verify a good password in the dialog window that appears. This password will be saved in your keychain by default, or you can deselect "Remember password (add to keychain)" if you don't want it saved. You can store the password in the keychain for convenience. |
|
11 | +11. Click OK. |
osx-flush-dns.md
... | ... | @@ -0,0 +1,11 @@ |
1 | +### Lion, Mountain Lion |
|
2 | + |
|
3 | +``` |
|
4 | +sudo killall -HUP mDNSResponder |
|
5 | +``` |
|
6 | + |
|
7 | +### 10.6 and earlier |
|
8 | + |
|
9 | +``` |
|
10 | +sudo dscacheutil -flushcache |
|
11 | +``` |
osx-port-redirection-on-startup.md
... | ... | @@ -0,0 +1,99 @@ |
1 | +### Preliminary |
|
2 | + |
|
3 | +``` |
|
4 | +sudo mkdir -p /usr/local/bin |
|
5 | +sudo mkdir -p /var/log/ipfw # (?) |
|
6 | +``` |
|
7 | + |
|
8 | +### In ` /usr/local/bin/ipfw-setup` |
|
9 | + |
|
10 | +``` |
|
11 | +#!/bin/sh |
|
12 | + |
|
13 | +export REDIS_PORT=6379 |
|
14 | +export POSTGRESQL_PORT=5432 |
|
15 | +export MEMCACHED_PORT=11211 |
|
16 | + |
|
17 | +export BOXEN_REDIS_PORT=16379 |
|
18 | +export BOXEN_POSTGRESQL_PORT=15432 |
|
19 | +export BOXEN_MEMCACHED_PORT=11211 |
|
20 | + |
|
21 | +# Flush existing rules |
|
22 | +/sbin/ipfw -f -q flush |
|
23 | + |
|
24 | +# Silently drop unsolicited connections |
|
25 | +/usr/sbin/sysctl -w net.inet.tcp.blackhole=2 |
|
26 | +/usr/sbin/sysctl -w net.inet.udp.blackhole=1 |
|
27 | + |
|
28 | +# Load the firewall ruleset |
|
29 | +/sbin/ipfw -q -p /usr/bin/m4 /etc/ipfw.conf |
|
30 | + |
|
31 | +ln -fs /tmp/.s.PGSQL.$BOXEN_POSTGRESQL_PORT /tmp/.s.PGSQL.$POSTGRESQL_PORT``` |
|
32 | +``` |
|
33 | + |
|
34 | +### In `/etc/ipfw.conf` |
|
35 | + |
|
36 | +``` |
|
37 | +define(BOXEN_REDIS_PORT, `syscmd(`printf $BOXEN_REDIS_PORT')') |
|
38 | +define(BOXEN_POSTGRESQL_PORT, `syscmd(`printf $BOXEN_POSTGRESQL_PORT')') |
|
39 | +define(BOXEN_MEMCACHED_PORT, `syscmd(`printf $BOXEN_MEMCACHED_PORT')') |
|
40 | +define(REDIS_PORT, `syscmd(`printf $REDIS_PORT')') |
|
41 | +define(POSTGRESQL_PORT, `syscmd(`printf $POSTGRESQL_PORT')') |
|
42 | +define( MEMCACHED_PORT, `syscmd(`printf $MEMCACHED_PORT')') |
|
43 | +add 100 fwd 127.0.0.1,BOXEN_REDIS_PORT tcp from any to any REDIS_PORT in |
|
44 | +add 100 fwd 127.0.0.1,BOXEN_POSTGRESQL_PORT tcp from any to any POSTGRESQL_PORT in |
|
45 | +add 100 fwd 127.0.0.1,BOXEN_MEMCACHED_PORT tcp from any to any MEMCACHED_PORT in |
|
46 | +``` |
|
47 | + |
|
48 | +### In `/Library/LaunchDaemons/dev.ipfw.plist` |
|
49 | + |
|
50 | +``` |
|
51 | +<?xml version="1.0" encoding="UTF-8"?> |
|
52 | +<plist version="1.0"> |
|
53 | + <dict> |
|
54 | + <key>Label</key> |
|
55 | + <string>dev.ipfw</string> |
|
56 | + <key>ServiceDescription</key> |
|
57 | + <string>ipfw rules</string> |
|
58 | + <key>ProgramArguments</key> |
|
59 | + <array> |
|
60 | + <string>/usr/local/bin/ipfw-setup</string> |
|
61 | + </array> |
|
62 | + <key>RunAtLoad</key> |
|
63 | + <true /> |
|
64 | + <key>KeepAlive</key> |
|
65 | + <true /> |
|
66 | + <key>StandardErrorPath</key> |
|
67 | + <string>/var/log/ipfw/ipfw.log</string> |
|
68 | + <key>StandardOutPath</key> |
|
69 | + <string>/var/log/ipfw/ipfw.log</string> |
|
70 | + </dict> |
|
71 | +</plist> |
|
72 | +``` |
|
73 | + |
|
74 | +### Using pf |
|
75 | + |
|
76 | +According to <http://mitmproxy.org/doc/transparent/osx.html> |
|
77 | + |
|
78 | +``` |
|
79 | +sudo sysctl -w net.inet.ip.forwarding=1 |
|
80 | +``` |
|
81 | + |
|
82 | +Then (in a file such as pf.conf) |
|
83 | + |
|
84 | +``` |
|
85 | +rdr on en2 inet proto tcp to any port 80 -> 127.0.0.1 port 8080 |
|
86 | +rdr on en2 inet proto tcp to any port 443 -> 127.0.0.1 port 8080 |
|
87 | +``` |
|
88 | + |
|
89 | +Configure |
|
90 | + |
|
91 | +``` |
|
92 | +sudo pfctl -f pf.conf |
|
93 | +``` |
|
94 | + |
|
95 | +Enable |
|
96 | + |
|
97 | +``` |
|
98 | +sudo pfctl -e |
|
99 | +``` |
osx-suppress-user-icons.md
... | ... | @@ -0,0 +1,5 @@ |
1 | +### Suppress use login icons |
|
2 | + |
|
3 | +``` |
|
4 | +sudo defaults write /Library/Preferences/com.apple.loginwindow HiddenUsersList -array-add admin iora.user |
|
5 | +``` |
osx-usb-format.md
... | ... | @@ -0,0 +1,7 @@ |
1 | +1. Open Disk Utility |
|
2 | +2. Select Volume and pick Get Info |
|
3 | +3. Determine the disk identifier (e.g., disk2). If it says disk2s2 it's disk2 |
|
4 | +4. From the command line |
|
5 | + |
|
6 | + diskutil partitiondisk disk2 JHFS+ newdisk 100% |
|
7 | + |
osx.md
... | ... | @@ -0,0 +1,9 @@ |
1 | +### OS/X |
|
2 | + |
|
3 | +* [Rebuilding](mac-osx-rebuilding) |
|
4 | +* [Port redirection on startup](osx-port-redirection-on-startup) |
|
5 | +* [How to format an encrypted USB](osx-usb-format) |
|
6 | +* [Suppress user login icons](osx-suppress-user-icons) |
|
7 | +* [OS/X encrypted image](osx-encrypted-image) |
|
8 | +* [Flush DNS](osx-flush-dns) |
|
9 | + |
pi.md
... | ... | @@ -0,0 +1,19 @@ |
1 | +* user: pi/raspberryzzz |
|
2 | +* user: jgn/fizzbinzzz |
|
3 | + |
|
4 | + |
|
5 | +``` |
|
6 | +Google Authenticator |
|
7 | + |
|
8 | +https://www.google.com/chart?chs=200x200&chld=M|0&cht=qr&chl=otpauth://totp/root@raspberrypi%3Fsecret%3DONXYH75J3MRTVFTZ |
|
9 | +Your new secret key is: ONXYH75J3MRTVFTZ |
|
10 | +Your verification code is 895686 |
|
11 | +Your emergency scratch codes are: |
|
12 | + 83007250 |
|
13 | + 41806191 |
|
14 | + 58419871 |
|
15 | + 80898174 |
|
16 | + 11437504 |
|
17 | + |
|
18 | + |
|
19 | +``` |
port-forwarding-with-pf.md
... | ... | @@ -0,0 +1,11 @@ |
1 | +1. Become root |
|
2 | +2. `vim /etc/pf.anchors/redis.forwarding` and add rules |
|
3 | + |
|
4 | + rdr pass on lo0 inet proto tcp from any to 127.0.0.1 port 6379 -> 127.0.0.1 port 16379 |
|
5 | + |
|
6 | +3. `vim /etc/pf-redis.conf` and . . . |
|
7 | + |
|
8 | + rdr-anchor "forwarding" |
|
9 | + load anchor "forwarding" from "/etc/pf.anchors/redis.forwarding" |
|
10 | + |
|
11 | +4. `pfctl -ef /etc/pf-redis.conf` |
postgresql-two-on-osx.md
... | ... | @@ -0,0 +1,73 @@ |
1 | +## To keep things clean and organized, completely remove any PGs you have running via Boxen or straight Brew. |
|
2 | + |
|
3 | +### Under Boxen |
|
4 | + |
|
5 | +``` |
|
6 | +sudo /bin/launchctl unload -w /Library/LaunchDaemons/dev.postgresql.plist |
|
7 | +brew remove postgres |
|
8 | +rm -fR $BOXEN_DATA_DIR/postgresql-* |
|
9 | +sudo rm -fR /Library/LaunchDaemons/dev.postgresql.plist |
|
10 | +rm -fR BOXEN_HOME/repo/shared/postgresql |
|
11 | +``` |
|
12 | + |
|
13 | +### Brew (without Boxen) |
|
14 | + |
|
15 | +``` |
|
16 | +brew services stop postgresql # probably |
|
17 | +brew remove postgres |
|
18 | +``` |
|
19 | + |
|
20 | +## Now we are going to re-install Postgres with straight Brew |
|
21 | + |
|
22 | +``` |
|
23 | +brew install postgres |
|
24 | +``` |
|
25 | + |
|
26 | +## Now we're going to make a copy which will be your stable dev Boxen that runs all the time on port 15432 |
|
27 | + |
|
28 | +``` |
|
29 | +MYPG=$HOME/mypostgres |
|
30 | +mkdir -p $MYPG |
|
31 | +sudo cp /opt/boxen/homebrew/Cellar/postgresql/9.5.3/homebrew.mxcl.postgresql.plist /Library/LaunchDaemons/my.postgresql.plist |
|
32 | +cp -R /opt/boxen/homebrew/var/postgres $MYPG |
|
33 | +``` |
|
34 | + |
|
35 | +Edit `/Library/LaunchDaemons/my.postgresql.plist` so it looks like this: |
|
36 | + |
|
37 | +``` |
|
38 | +<?xml version="1.0" encoding="UTF-8"?> |
|
39 | +<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> |
|
40 | +<plist version="1.0"> |
|
41 | +<dict> |
|
42 | + <key>KeepAlive</key> |
|
43 | + <true/> |
|
44 | + <key>Label</key> |
|
45 | + <string>my.postgresql</string> |
|
46 | + <key>ProgramArguments</key> |
|
47 | + <array> |
|
48 | + <string>/opt/boxen/homebrew/opt/postgresql/bin/postgres</string> |
|
49 | + <string>-D</string> |
|
50 | + <string>/Users/jgn/mypostgres</string> |
|
51 | + <string>-r</string> |
|
52 | + <string>/Users/jgn/mypostgres/server.log</string> |
|
53 | + </array> |
|
54 | + <key>RunAtLoad</key> |
|
55 | + <true/> |
|
56 | + |
|
57 | + <key>UserName</key> |
|
58 | + <string>jgn</string> |
|
59 | + |
|
60 | + <key>WorkingDirectory</key> |
|
61 | + <string>/Users/jgn/mypostgres</string> |
|
62 | + <key>StandardErrorPath</key> |
|
63 | + <string>/Users/jgn/mypostgres/server.log</string> |
|
64 | +</dict> |
|
65 | +</plist> |
|
66 | +``` |
|
67 | + |
|
68 | +In `$MYPG/postgresql.conf`, change `#port = 5432` to `port = 15432` |
|
69 | + |
|
70 | +Have brew start up your "fun" PG at login: `brew services start postgresql` |
|
71 | + |
|
72 | +And have your long-running PG (running on 15432) run all the time: `sudo /bin/launchctl load -w /Library/LaunchDaemons/my.postgresql.plist` |
|
73 | + |
postgresql.md
... | ... | @@ -0,0 +1,120 @@ |
1 | +### Resources |
|
2 | + |
|
3 | +* Searching: <http://blog.lostpropertyhq.com/postgres-full-text-search-is-good-enough> |
|
4 | +* Point-in-time recovery: <http://blog.endpoint.com/2016/01/postgresql-point-in-time-recovery.html> |
|
5 | + |
|
6 | +### Change password for username |
|
7 | + |
|
8 | +```sql |
|
9 | +alter user icis_vagrant password 'foobar' |
|
10 | +``` |
|
11 | + |
|
12 | +### About tablespaces |
|
13 | + |
|
14 | +A `tablespace` defines a location in the filesystem where objects (e.g., tables) will be stored. Note that when you restore a database, directories (not just the tablespace names) must exist in the filesystem with appropriate file permissions for any tablespaces that are defined in the database being restored. Similarly, if in a master/slave environment, the path should exist on both master and slave. |
|
15 | + |
|
16 | +To create a tablespace: `create tablespace mytablespace location '/some/location';` |
|
17 | + |
|
18 | +`/some/location` must be owned by the `postgres` user. |
|
19 | + |
|
20 | +### Default tablespaces |
|
21 | + |
|
22 | +When a cluster is created, `pg_default` and `pg_global` are created. `pg_global` contains system tables shared by all databases in the cluster. `pg_default` will be used for all table creation unless another tablespace is specified. `pg_default` is located as the base directory under `PGDATA`. |
|
23 | + |
|
24 | +### What happens when a tablespace is created? |
|
25 | + |
|
26 | +When a tablespace is created, a link is made in `PGDATA/pg_tblspc` to the specified location. The name of the link in `pg_tblspc` is the OID. |
|
27 | + |
|
28 | +You can get a list of all OIDs for all tables in a database with the system command `oid2name -d <database-name>`. |
|
29 | + |
|
30 | +### Per-used default tablespace |
|
31 | + |
|
32 | +```sql |
|
33 | +alter user set default_tablespace = 'whatever'; |
|
34 | +``` |
|
35 | + |
|
36 | +### List all tablespaces for databases |
|
37 | + |
|
38 | +```text |
|
39 | +\l+ |
|
40 | +``` |
|
41 | + |
|
42 | +### List tablespaces (including locations on disk) |
|
43 | + |
|
44 | +```text |
|
45 | +\db+ |
|
46 | +``` |
|
47 | + |
|
48 | +### List users |
|
49 | + |
|
50 | +```text |
|
51 | +\du+ |
|
52 | +``` |
|
53 | + |
|
54 | +### What is the default tablespace for a particular database? |
|
55 | + |
|
56 | +### In what tablespace does a table live? |
|
57 | + |
|
58 | +``` |
|
59 | +select tablename, tablespace from pg_tables; |
|
60 | +``` |
|
61 | + |
|
62 | +### Atomic query / update |
|
63 | + |
|
64 | +``` |
|
65 | +drop table if exists messages; |
|
66 | +create table messages ( |
|
67 | + id serial primary key, |
|
68 | + text varchar(255), |
|
69 | + status varchar(255), |
|
70 | + created_at timestamp default now() |
|
71 | +); |
|
72 | +insert into messages (text, status) values ('hi', 'queued'); |
|
73 | +insert into messages (text, status) values ('hello', 'queued'); |
|
74 | +insert into messages (text, status) values ('whatever', 'queued'); |
|
75 | + |
|
76 | +update messages m |
|
77 | +set status = 'accepted' |
|
78 | +from (select id from messages where status = 'queued' order by created_at asc limit 1 for update of messages) sub |
|
79 | +where m.id = sub.id |
|
80 | +returning *; |
|
81 | + |
|
82 | +-- select * from messages; |
|
83 | +``` |
|
84 | + |
|
85 | +### JSON |
|
86 | + |
|
87 | +* [Example with populating, querying, indexing in PG 9.3](http://jmorano.moretrix.com/2013/12/postgresql-9-3-creating-index-json-attribute/) |
|
88 | +* [Summary of differences between 9.2, 9.3, 9.4](http://www.pgcon.org/2014/schedule/attachments/328_9.4json.pdf) |
|
89 | + |
|
90 | +### Materialized View |
|
91 | + |
|
92 | +``` |
|
93 | +drop materialized view authors_and_titles; |
|
94 | + |
|
95 | +drop table if exists books cascade; |
|
96 | +drop table if exists authors cascade; |
|
97 | + |
|
98 | +create table authors (id int, name varchar); |
|
99 | +create table books (id int, title varchar, author_id int); |
|
100 | + |
|
101 | +insert into authors (id, name) values (1, 'Shakespeare'); |
|
102 | +insert into authors (id, name) values (2, 'Dickens'); |
|
103 | + |
|
104 | +insert into books (id, title, author_id) values (1, 'The Tempest', 1); |
|
105 | +insert into books (id, title, author_id) values (2, 'Hamlet', 1); |
|
106 | +insert into books (id, title, author_id) values (3, 'David Copperfield', 2); |
|
107 | + |
|
108 | +create materialized view authors_and_titles as |
|
109 | +select name, title |
|
110 | +from books left join authors on books.author_id = authors.id; |
|
111 | + |
|
112 | +insert into books (id, title, author_id) values (4, 'Bleak House', 2); |
|
113 | + |
|
114 | +select * from authors_and_titles; |
|
115 | + |
|
116 | +refresh materialized view authors_and_titles; |
|
117 | +-- NOTE: Takes time! |
|
118 | + |
|
119 | +-- select * from authors_and_titles; |
|
120 | +``` |
|
... | ... | \ No newline at end of file |
product-management.md
... | ... | @@ -0,0 +1,2 @@ |
1 | +* From Slack - <http://firstround.com/review/slacks-first-product-manager-on-how-to-make-a-firehose-of-feedback-useful/> |
|
2 | +* Early introduction of waterfall model - <http://www.cs.umd.edu/class/spring2003/cmsc838p/Process/waterfall.pdf> |
public-key-encryption.md
... | ... | @@ -0,0 +1,34 @@ |
1 | +NOTE: This only works for files that are shorter than your public key. For a strategy that uses RSA for the password, and symmetric encryption for the file, see <http://unix.stackexchange.com/questions/27005/encrypting-file-only-with-ssh-priv-key>. |
|
2 | + |
|
3 | +1. Extract public key from `id_rsa` file and make a `.pem` file with only the public key |
|
4 | + |
|
5 | + openssl rsa -in id_rsa -pubout -out id_rsa.pub.pem |
|
6 | + |
|
7 | + **This will give you a `.pem` file that does not require entering the passphrase.** |
|
8 | + |
|
9 | +2. Encrypt using the public key portion of your `id_rsa` file (will ask for passphrase): |
|
10 | + |
|
11 | + openssl rsautl -encrypt -inkey ~/.ssh/id_rsa -in file.txt -out file.ssl |
|
12 | + |
|
13 | +3. Encrypt using your new `id_rsa.pub.pem` file (**will not** ask for passphrase): |
|
14 | + |
|
15 | + openssl rsautl -encrypt -pubin -inkey ~/.ssh/id_rsa.pub.pem -in file.txt -out file.ssl |
|
16 | + |
|
17 | +4. Decrypt using your regular private key (prompts for passphrase): |
|
18 | + |
|
19 | + openssl rsautl -decrypt -inkey ~/.ssh/id_rsa -in file.ssl |
|
20 | + |
|
21 | +### How to get a fingerprint |
|
22 | + |
|
23 | + $ ssh-keygen -l -f ~/.ssh/id_rsa.pub |
|
24 | + |
|
25 | +### How to determine the number of bits in a key |
|
26 | + |
|
27 | + $ ssh-keygen -l -f ~/.ssh/id_rsa.pub |
|
28 | + 2048 8f:ad:b8:89:06:40:94:85:fd:df:24:55:b1:41:89:11 jgn@jgn.local (RSA) |
|
29 | + |
|
30 | +### How to determine if a key has a passphrase |
|
31 | + |
|
32 | + $ ssh-keygen -p -f ~/.ssh/id_rsa.pub |
|
33 | + |
|
34 | +(If it says "Enter old passphrase" then it has a passphrase.) |
pull-request.jpg
... | ... | Binary files /dev/null and b/pull-request.jpg differ |
puppet-old-notes.md
... | ... | @@ -0,0 +1,64 @@ |
1 | +## Chef vs Puppet |
|
2 | + |
|
3 | +* My blink is that in 2012 Puppet is safer and more productive. |
|
4 | +* Puppet is declarative, Chef procedural. |
|
5 | +* Puppet brings system into compliance (state), Chef "does" things (recipes). |
|
6 | +* Puppet has strong security practices; Chef has a toleration for loose security in Chef itself. |
|
7 | +* Puppet makes it very hard to get "outside the lines" or violate its strong opinions; in Chef |
|
8 | +this is routine. |
|
9 | + |
|
10 | +## Puppet standalone becoming a "best practice"? |
|
11 | + |
|
12 | +Not used very much, but . . . |
|
13 | + |
|
14 | +* Doesn't depend on a puppet master (client/server bottleneck) |
|
15 | +* [Puppet docs at "Massively scalable deployments"](http://puppetlabs.com/blog/deploying-puppet-in-client-server-standalone-and-massively-scaled-environments/) |
|
16 | +* [See strategy at Loggly](http://semicomplete.com/presentations/puppet-presentation/puppet-at-loggly.html#42) |
|
17 | + |
|
18 | +## Best things about Puppet |
|
19 | + |
|
20 | +* Declarative, not procedural. |
|
21 | +* Feels Ruby-ish. But *never* think that it is Ruby. |
|
22 | +* The fact, though, that it isn't Ruby is arguably good: One seeks for the best "Puppet"-style solution. |
|
23 | + |
|
24 | +## Worst thing about Puppet |
|
25 | + |
|
26 | +* Not Ruby. It has its own syntax. Lots of opportunities for screwups. |
|
27 | +* Difficult to understand differences between fundamental resources and what goes where (e.g., classes, modules, nodes). |
|
28 | +* Very hard to understand scopes. |
|
29 | +* Hard to inject. |
|
30 | + |
|
31 | +## Something apparently not used much: The Ruby DSL |
|
32 | + |
|
33 | +* Every puppet example I've read has been written in Puppet. |
|
34 | +* But there is a full-blown Ruby DSL: http://puppetlabs.com/blog/ruby-dsl/ and http://projects.puppetlabs.com/projects/1/wiki/Ruby_Dsl |
|
35 | + |
|
36 | +## Language oddities: "class" |
|
37 | + |
|
38 | +* A Puppet class is really something like a class, but everything inside |
|
39 | +of it "runs" as class-level behavior. There seem to be no "instances" of classes. |
|
40 | +* This is a big deal. When you import (include?) a class, its behavior runs. |
|
41 | + |
|
42 | +## Language oddities: "module" |
|
43 | + |
|
44 | +* Gotcha: There is really no such thing as a module |
|
45 | +* It just happens that a module is a directory with a conventional pattern |
|
46 | + |
|
47 | +## Not clear if puppet user is really required |
|
48 | + |
|
49 | +* Our config has a puppet user with a local Ruby 1.8.7 and its own gems. |
|
50 | +* The puppet user has a ~/.puppet directory; not clear if in play. |
|
51 | + |
|
52 | +## Definitely want default puppet file hierarchy |
|
53 | + |
|
54 | + etc/ |
|
55 | + puppet/ |
|
56 | + puppet.conf |
|
57 | + manifests/ |
|
58 | + site.pp # manifest for site |
|
59 | + modules/ |
|
60 | + # your modules here |
|
61 | + |
|
62 | +## Where do environment params go? Not clear |
|
63 | + |
|
64 | +I put them in a module called icis::params |
|
... | ... | \ No newline at end of file |
puppet.md
... | ... | @@ -0,0 +1 @@ |
1 | +[Old notes](puppet_old_notes) |
|
... | ... | \ No newline at end of file |
rails-new-app.md
... | ... | @@ -0,0 +1,19 @@ |
1 | +1. Create a new Rails app, and initialize it in git: |
|
2 | + |
|
3 | + rails new skel -d postgresql -T |
|
4 | + cd skel |
|
5 | + git init |
|
6 | + git add . |
|
7 | + |
|
8 | +2. To the Gemfile, add |
|
9 | + |
|
10 | + group :development, :test do |
|
11 | + gem 'rspec-rails', '~> 2.12.0' |
|
12 | + end |
|
13 | + |
|
14 | +3. Generate rspec: |
|
15 | + |
|
16 | + bundle exec rails generate rspec:install |
|
17 | + |
|
18 | +4. Remove username and password from `config/database.yml`; then `bundle exec rake db:create db:migrate` |
|
19 | + |
react.md
... | ... | @@ -0,0 +1,9 @@ |
1 | +### Blog posts |
|
2 | + |
|
3 | +* https://discord.engineering/using-react-native-one-year-later-91fd5e949933#.og7ojy85i |
|
4 | + |
|
5 | +### Resources |
|
6 | + |
|
7 | +* [#react-native](https://discordapp.com/invite/0ZcbPKXt5bWVQmld) on Reactiflux. |
|
8 | +* [js.coach](https://js.coach/react-native) — a catalog of open source component of React Native. |
|
9 | +* [awesome-react-native](https://github.com/jondot/awesome-react-native) — a list of React Native articles, tutorials and examples. |
|
... | ... | \ No newline at end of file |
redhat.md
... | ... | @@ -0,0 +1,21 @@ |
1 | +### List all installed packages |
|
2 | + |
|
3 | + [deploy@test01 ~]$ yum list installed |
|
4 | + |
|
5 | +### What version of Linux am I on? |
|
6 | + |
|
7 | + [deploy@test01 ~]$ uname -r |
|
8 | + 2.6.18-274.3.1.el5.028stab094.3 |
|
9 | + |
|
10 | +### What distro am I on? |
|
11 | + |
|
12 | + [deploy@test01 ~]$ ls /etc/*-release |
|
13 | + /etc/blueboxgrp-release /etc/redhat-release /etc/system-release |
|
14 | + [deploy@test01 ~]$ more /etc/system-release |
|
15 | + Scientific Linux release 6.1 (Carbon) |
|
16 | + |
|
17 | +### What is the architecture? |
|
18 | + |
|
19 | + [deploy@test01 ~]$ uname -m |
|
20 | + x86_64 |
|
21 | + |
redis.md
... | ... | @@ -0,0 +1,5 @@ |
1 | +Delete all key/value pairs |
|
2 | + |
|
3 | +```bash |
|
4 | +redis-cli KEYS "*" | xargs redis-cli DEL |
|
5 | +``` |
refrepos.md
... | ... | @@ -0,0 +1,43 @@ |
1 | +``` |
|
2 | +ls -1 | xargs -I % sh -c 'cd %; git config --get remote.origin.url;' |
|
3 | +https://gist.github.com/1595572.git |
|
4 | +https://github.com/JamieMason/All-iTerm-Colors.git |
|
5 | +git://github.com/zoocasa/activerecord-postgresql-extensions.git |
|
6 | +https://github.com/cucumber/aruba.git |
|
7 | +git://github.com/knowtheory/backbone-slides.git |
|
8 | +https://github.com/thoughtbot/bourne.git |
|
9 | +https://github.com/box/box-ruby-sdk.git |
|
10 | +git://github.com/camptocamp/puppet-postgresql.git |
|
11 | +git://github.com/capistrano/capistrano.git |
|
12 | +https://github.com/visionmedia/commander.git |
|
13 | +https://github.com/wicketstuff/core.wiki.git |
|
14 | +https://github.com/cucumber/cucumber.git |
|
15 | +git@github.com:IoraHealth/data_import_service.git |
|
16 | +https://github.com/aetrion/dnsimple-ruby.git |
|
17 | +git://github.com/faye/faye.git |
|
18 | +git://github.com/github/gollum.git |
|
19 | +https://github.com/JEG2/highline.git |
|
20 | +https://github.com/jwagener/httmultiparty |
|
21 | +git://github.com/jnunemaker/httparty.git |
|
22 | +https://github.com/gnachman/iTerm2 |
|
23 | +git://github.com/flori/json.git |
|
24 | +https://github.com/adamzap/landslide.git |
|
25 | +https://github.com/freerange/mocha.git |
|
26 | +git://github.com/imathis/octopress.git |
|
27 | +git://github.com/PagerDuty/pd-cap-recipes.git |
|
28 | +https://github.com/play/play.git |
|
29 | +git://github.com/skmetz/poodr.git |
|
30 | +git://github.com/dockyard/postgres_ext.git |
|
31 | +git://github.com/Lokaltog/powerline-fonts.git |
|
32 | +git://github.com/fredj/puppet-postgresql.git |
|
33 | +https://github.com/puppetlabs/puppet-postgresql |
|
34 | +git://github.com/rack/rack.git |
|
35 | +git://github.com/rack/rack-contrib.git |
|
36 | +git@github.com:nov/rack-oauth2-sample.git |
|
37 | +git://github.com/defunkt/resque.git |
|
38 | +https://github.com/sinatra/sinatra.git |
|
39 | +git://github.com/grobie/soundcloud2000.git |
|
40 | +git://github.com/taf2/speech2text.git |
|
41 | +https://github.com/mattsears/taco.git |
|
42 | +git://github.com/mitchellh/vagrant.git |
|
43 | +``` |
|
... | ... | \ No newline at end of file |
rest.md
... | ... | @@ -0,0 +1,11 @@ |
1 | +#### Throttling |
|
2 | + |
|
3 | +* <http://sdqali.in/blog/2013/10/12/implementing-rate-limiting-in-rails-part-1/> |
|
4 | +* <http://blog.joshsoftware.com/2014/06/26/api-throttling-on-requests-per-minute/> |
|
5 | + |
|
6 | +#### Auth |
|
7 | + |
|
8 | +* <http://tools.ietf.org/html/draft-ietf-oauth-jwt-bearer-04> |
|
9 | +* <http://blog.yanted.com/2014/02/13/jwt-based-authentication-with-ember-js-and-rails/> |
|
10 | + |
|
11 | + |
ruby-course.md
... | ... | @@ -0,0 +1,21 @@ |
1 | +* [Ruby vs Other Languages](ruby-vs-others) |
|
2 | +* [Blocks and open/close](blocks-open-closed) |
|
3 | + |
|
4 | +#### Next version |
|
5 | + |
|
6 | +Tutorials |
|
7 | + |
|
8 | +* More on git |
|
9 | +* use git/github to manage assignments |
|
10 | +* <https://medium.com/@mackenziechild/how-i-finally-learned-rails-95e9b832675b> |
|
11 | +* lynda.com |
|
12 | +* [Assignment 2 changes](a2changes) |
|
13 | + |
|
14 | +#### Resources |
|
15 | + |
|
16 | +* Rails app with API - <https://github.com/iridakos/lofocats_api> |
|
17 | + |
|
18 | +#### Other courses |
|
19 | + |
|
20 | +* Pito Salas, Brandeis, COSI 236B: <http://cosi236b.courses.salas.com.s3-website-us-west-2.amazonaws.com> |
|
21 | +* U of MN, CSCI 4131: <http://www-users.cselabs.umn.edu/classes/Fall-2014/csci4131/index.php?page=syllabus> |
ruby-vs-others.md
... | ... | @@ -0,0 +1,2 @@ |
1 | +1. Torvalds on C vs C++: <http://harmful.cat-v.org/software/c++/linus> |
|
2 | +2. Metasploit on why they use Ruby: <http://mail.metasploit.com/pipermail/framework/2006-October/001325.html> |
ruby.md
... | ... | @@ -0,0 +1,86 @@ |
1 | +### Quick web server |
|
2 | + |
|
3 | +``` |
|
4 | +ruby -run -e httpd . -p5000 |
|
5 | +``` |
|
6 | + |
|
7 | +### Quick web server using Rack |
|
8 | + |
|
9 | +``` |
|
10 | +rackup -p 8090 -b "run Proc.new { |env| ['200', {'Content-Type' => 'text/html'}, [ env.map { |e| '%s: %s' % e }.join('<br/>') ]] }" |
|
11 | +``` |
|
12 | + |
|
13 | +### Closure |
|
14 | + |
|
15 | +```ruby |
|
16 | +lambda { |x| |
|
17 | + lambda { |y| x } |
|
18 | +}[1][2] |
|
19 | +``` |
|
20 | + |
|
21 | +### Stabby lambda |
|
22 | + |
|
23 | +```ruby |
|
24 | +a = -> x { puts x } |
|
25 | +a.call("john") # ok |
|
26 | +a["john"] # ok |
|
27 | +a.("john") # gross |
|
28 | + |
|
29 | +b = -> { puts "hi" } |
|
30 | +b[] |
|
31 | +``` |
|
32 | + |
|
33 | +### Use of protected |
|
34 | + |
|
35 | +```ruby |
|
36 | +class A |
|
37 | + attr_reader :value |
|
38 | + protected :value |
|
39 | + def initialize(value) |
|
40 | + @value = value |
|
41 | + end |
|
42 | + |
|
43 | + def ==(other) |
|
44 | + self.value == other.value |
|
45 | + end |
|
46 | + |
|
47 | + # protected |
|
48 | + # |
|
49 | + # def value |
|
50 | + # @value |
|
51 | + # end |
|
52 | +end |
|
53 | + |
|
54 | +class B < A; end |
|
55 | + |
|
56 | +a = A.new(5) |
|
57 | +b = A.new(6) |
|
58 | +c = A.new(5) |
|
59 | +d = B.new(6) |
|
60 | +e = B.new(5) |
|
61 | + |
|
62 | +p a == b |
|
63 | +p a == c |
|
64 | +p a == d |
|
65 | +p a == e |
|
66 | +``` |
|
67 | + |
|
68 | +### Want access to instance variables via a passed-in block during initialization |
|
69 | + |
|
70 | +``` |
|
71 | +class Building |
|
72 | + def initialize(&block) |
|
73 | + instance_eval(&block) if block_given? |
|
74 | + end |
|
75 | + |
|
76 | + def to_s |
|
77 | + "#{@rooms}" |
|
78 | + end |
|
79 | +end |
|
80 | + |
|
81 | +b1 = Building.new { @rooms = 5 } |
|
82 | +puts b1 |
|
83 | + |
|
84 | +b2 = Building.new |
|
85 | +puts b2 |
|
86 | +``` |
|
... | ... | \ No newline at end of file |
sinatra.md
... | ... | @@ -0,0 +1,2 @@ |
1 | +* `Rack::Builder` |
|
2 | +* use / map / run |
ssh.md
... | ... | @@ -0,0 +1,27 @@ |
1 | +### OS/X Add extra port for ssh |
|
2 | + |
|
3 | +In `/etc/services`, add a new service, `ssh2` defined as `22999/tcp` |
|
4 | + |
|
5 | +Then `sudo cp /System/Library/LaunchDaemons/ssh.plist /Library/LaunchDaemons/ssh2.plist` |
|
6 | +(Notice that we are copying from the system launchdaemons to your own.) |
|
7 | + |
|
8 | +Change `sshd` to `sshd2` and `ssh` to `ssh2`: |
|
9 | + |
|
10 | +``` |
|
11 | +<key>Label</key> |
|
12 | +<string>com.openssh.sshd2</string> |
|
13 | +... |
|
14 | +<key>SockServiceName</key> |
|
15 | +<string>ssh2</string> |
|
16 | +``` |
|
17 | + |
|
18 | +Launch: `launchctl load -w /Library/LaunchDaemons/ssh2.plist` |
|
19 | + |
|
20 | +Then another user might have this in the `~.ssh/config` |
|
21 | + |
|
22 | +``` |
|
23 | +Host pair.7fff.com |
|
24 | + Port 22999 |
|
25 | +``` |
|
26 | + |
|
27 | +See <http://marcel.zurreck.com/os-x-yosemite-change-ssh-port> |
|
... | ... | \ No newline at end of file |
ssl-notes.md
... | ... | @@ -0,0 +1,8 @@ |
1 | +For Apache |
|
2 | + |
|
3 | +``` |
|
4 | +SSLEngine on |
|
5 | +SSLCertificateKeyFile /etc/ssl/ssl.key/server.key |
|
6 | +SSLCertificateFile /etc/ssl/ssl.crt/yourDomainName.crt |
|
7 | +SSLCertificateChainFile /etc/ssl/ssl.crt/yourDomainName.ca-bundle |
|
8 | +``` |
syncany.md
... | ... | @@ -0,0 +1,59 @@ |
1 | +1. Install with |
|
2 | + |
|
3 | + brew install https://get.syncany.org/homebrew/syncany.rb |
|
4 | + |
|
5 | +2. Install the S3 plugin |
|
6 | + |
|
7 | + sy plugin install s3 |
|
8 | + |
|
9 | + For more recent version: `sy plugin remove s3; sy plugin install s3 --snapshot` |
|
10 | + |
|
11 | +3. Create a bucket in AWS S3 with |
|
12 | + |
|
13 | + aws s3 mb s3://jgnsync |
|
14 | + |
|
15 | +3. Go the the directory you want to sync and type |
|
16 | + |
|
17 | + sy init |
|
18 | + |
|
19 | + You will need to enter the plugin name (s3). Have your S3 access key |
|
20 | +and secret key at the ready. It should look something like this: |
|
21 | + |
|
22 | + ``` |
|
23 | + Connection details for s3 connection: |
|
24 | + - Access Key: 0JCM42F53N9EAXVANT82 |
|
25 | + - Secret Key (not displayed): |
|
26 | + - Bucket: jgnsync |
|
27 | + - Endpoint (non-standard S3-compatible backends only) (optional, default is none): |
|
28 | + - Amazon S3 Region/Location (ignored for if endpoint is set) (us-west-1): |
|
29 | + |
|
30 | + The password is used to encrypt data on the remote storage. |
|
31 | + Choose wisely! |
|
32 | + |
|
33 | + Password (min. 10 chars): |
|
34 | + Confirm: |
|
35 | + |
|
36 | + Creating master key from password (this might take a while) ... |
|
37 | + |
|
38 | + Repository created, and local folder initialized. To share the same repository |
|
39 | + with others, you can share this link: |
|
40 | + syncany://2/[deleted] |
|
41 | + |
|
42 | + This link is encrypted with the given password, so you can safely share it. |
|
43 | + using unsecure communication (chat, e-mail, etc.) |
|
44 | + |
|
45 | + Note: The link contains the details of your repo connection which typically |
|
46 | + consist of usernames/password of the connection (e.g. FTP user/pass). |
|
47 | + ``` |
|
48 | + |
|
49 | +4. `sy up` |
|
50 | + |
|
51 | +5. Then on the other system |
|
52 | + |
|
53 | + ``` |
|
54 | + sy connect syncany://2/4uteydtBt3c88p1KmXaBYHekDmjiHSmF8TcHk7FPA5rbwrEVL3w1h7x3duVVqdSw6KMGkoZMKnY7cFgJwArf9CA4/5u1DApUs1V6Dqu9DUjP1WRxpELbmc2t... |
|
55 | + ``` |
|
56 | + |
|
57 | + If you get the error `Error: Unable to extract connection settings: java.lang.IllegalArgumentException: No enum constant org.syncany.plugins.s3.Location.us-west-1` do `sy connect` and enter the details manually. |
|
58 | + |
|
59 | +6. Once the connection is established, `sy down` to get a copy. |
telephony.md
... | ... | @@ -0,0 +1,2 @@ |
1 | +* [How Patrick McKenzie (patio11) Builds Twilio Apps](https://www.twilio.com/blog/2015/01/how-patrick-mckenzie-builds-twilio-apps.html) |
|
2 | +* [Twimlets](https://www.twilio.com/labs/twimlets) |
|
... | ... | \ No newline at end of file |
test-doubles.md
... | ... | @@ -0,0 +1,10 @@ |
1 | +Page references to xUnit Test Patterns |
|
2 | + |
|
3 | +* SUT - System under test |
|
4 | +* DOC - Depended-on component |
|
5 | +* "indirect input" - This is data that gets into the SUT from a DOC. I.e., we're not calling a method with parameters; inputs are getting into the SUT via some DOC. (126) |
|
6 | +* "indirect output" - We want to verify at an "observation point" that calls to the DOC are happening correctly (127). |
|
7 | +* "Stubbing" for Indirect Input - When the SUT makes calls to the DOC, it may take data from the DOC. This data would be an "indirect input." We want to simulate these indirect inputs. Why? Because the DOC may be unpredictable or unavailable. A thing that stands in for the DOC so as to provide indirect inputs to the SUT is called a stub. The stub receives the calls and returns pre-configured responses. We want to "install a Test Stub in place of the DOC" (129). Want to provide indirect inputs? We say that install the Test Stub to act as a "control point" (135). We call it a "control point" because we are trying to force the SUT down some path (524). |
|
8 | +* "Test Spies" or "Mocking" for Indirect Output - By "indirect output," we mean the calls the SUT makes to DOCs. Example: the SUT makes calls to a logger. We want to ensure that the DOC is getting called properly. |
|
9 | + * Procedural Behavior Verification. We want to capture the calls to the DOC during SUT execution and see what happens. This means installing a Test Spy. It receives the calls and records them; then afterwards we make assertions on what is recorded in the Spy. What to check indirect outputs? We say that that happens at an "observation point" (e.g., 137). |
|
10 | + * Expected Behavior. We install a Mock Object, and say in advance what we expect. If the Mock doesn't get what we expect, it fails the test. |
|
... | ... | \ No newline at end of file |
test.md
... | ... | @@ -0,0 +1,3 @@ |
1 | +This is a test. |
|
2 | + |
|
3 | +Hmm. |
test2.md
... | ... | @@ -0,0 +1 @@ |
1 | +test2ffffccccddddccc |
|
... | ... | \ No newline at end of file |
testing-general.md
... | ... | @@ -0,0 +1,8 @@ |
1 | +* Unit test - verification - "Are we writing the code right?" |
|
2 | +* Customer test (acceptance test) - validation - "Are we writing the right software?" |
|
3 | +* Four phase |
|
4 | + 1. Setup |
|
5 | + 2. Exercise |
|
6 | + 3. Verify (assertion) |
|
7 | + 4. Teardown |
|
8 | + |
testing-mocha.md
... | ... | @@ -0,0 +1,14 @@ |
1 | +Why Mocha over RR, etc.? |
|
2 | + |
|
3 | +In RSpec mocks: |
|
4 | + |
|
5 | + stub_car = mock(Car) |
|
6 | + stub_car.stub!(:speed).and_return(100) |
|
7 | + Car.stub!(:new).and_return(stub_car) |
|
8 | + |
|
9 | +In Mocha, can stub `any_instance`: |
|
10 | + |
|
11 | + Car.any_instance.stubs(:speed).returns(100) |
|
12 | + |
|
13 | +(See <http://stackoverflow.com/questions/1406692/what-are-the-advantages-of-mocha-over-rspecs-built-in-mocking-framework>) |
|
14 | + |
time-machine.md
... | ... | @@ -0,0 +1,9 @@ |
1 | +### Restoring hidden files (dot files) |
|
2 | + |
|
3 | + $ defaults write com.apple.finder AppleShowAllFiles TRUE |
|
4 | + $ killall Finder |
|
5 | + |
|
6 | + # Get what you need via Time Machine |
|
7 | + |
|
8 | + $ defaults write com.apple.finder AppleShowAllFiles FALSE |
|
9 | + $ killall Finder |
tips.md
... | ... | @@ -0,0 +1,5 @@ |
1 | +* [capistrano](capistrano) |
|
2 | +* [Puppet](puppet) |
|
3 | +* [Redhat](redhat) |
|
4 | +* [Redis](redis) |
|
5 | +* [tmux](tmux) |
tmux.md
... | ... | @@ -0,0 +1,58 @@ |
1 | +Standard bindings |
|
2 | + |
|
3 | +``` |
|
4 | + C-b Send the prefix key (C-b) through to the application. |
|
5 | + C-o Rotate the panes in the current window forwards. |
|
6 | + C-z Suspend the tmux client. |
|
7 | + ! Break the current pane out of the window. |
|
8 | + " Split the current pane into two, top and bottom. |
|
9 | + # List all paste buffers. |
|
10 | + $ Rename the current session. |
|
11 | + % Split the current pane into two, left and right. |
|
12 | + & Kill the current window. |
|
13 | + ' Prompt for a window index to select. |
|
14 | + , Rename the current window. |
|
15 | + - Delete the most recently copied buffer of text. |
|
16 | + . Prompt for an index to move the current window. |
|
17 | + 0 to 9 Select windows 0 to 9. |
|
18 | + : Enter the tmux command prompt. |
|
19 | + ; Move to the previously active pane. |
|
20 | + = Choose which buffer to paste interactively from a list. |
|
21 | + ? List all key bindings. |
|
22 | + D Choose a client to detach. |
|
23 | + [ Enter copy mode to copy text or view the history. |
|
24 | + ] Paste the most recently copied buffer of text. |
|
25 | + c Create a new window. |
|
26 | + d Detach the current client. |
|
27 | + f Prompt to search for text in open windows. |
|
28 | + i Display some information about the current window. |
|
29 | + l Move to the previously selected window. |
|
30 | + n Change to the next window. |
|
31 | + o Select the next pane in the current window. |
|
32 | + p Change to the previous window. |
|
33 | + q Briefly display pane indexes. |
|
34 | + r Force redraw of the attached client. |
|
35 | + s Select a new session for the attached client interactively. |
|
36 | + L Switch the attached client back to the last session. |
|
37 | + t Show the time. |
|
38 | + w Choose the current window interactively. |
|
39 | + x Kill the current pane. |
|
40 | + { Swap the current pane with the previous pane. |
|
41 | + } Swap the current pane with the next pane. |
|
42 | + ~ Show previous messages from tmux, if any. |
|
43 | + Page Up Enter copy mode and scroll one page up. |
|
44 | + Up, Down |
|
45 | + Left, Right |
|
46 | + Change to the pane above, below, to the left, or to the right of the current pane. |
|
47 | + M-1 to M-5 Arrange panes in one of the five preset layouts: even-horizontal, even-vertical, main-horizontal, main-vertical, or |
|
48 | + tiled. |
|
49 | + M-n Move to the next window with a bell or activity marker. |
|
50 | + M-o Rotate the panes in the current window backwards. |
|
51 | + M-p Move to the previous window with a bell or activity marker. |
|
52 | + C-Up, C-Down |
|
53 | + C-Left, C-Right |
|
54 | + Resize the current pane in steps of one cell. |
|
55 | + M-Up, M-Down |
|
56 | + M-Left, M-Right |
|
57 | + Resize the current pane in steps of five cells. |
|
58 | +``` |
vim.md
... | ... | @@ -0,0 +1,15 @@ |
1 | +### Show current color scheme |
|
2 | + |
|
3 | + :echo g:colors_name |
|
4 | + |
|
5 | +See <http://vimdoc.sourceforge.net/htmldoc/syntax.html#:colorscheme> |
|
6 | + |
|
7 | +### Show current font |
|
8 | + |
|
9 | + :set guifont=* |
|
10 | + |
|
11 | +### Inserting from clipboard |
|
12 | + |
|
13 | + :set paste |
|
14 | + :set nopaste |
|
15 | + |
websockets-javascript.md
... | ... | @@ -0,0 +1,3 @@ |
1 | +1. `` |
|
2 | + |
|
3 | +zzz |
|
... | ... | \ No newline at end of file |
wiki.md
... | ... | @@ -0,0 +1,32 @@ |
1 | +#### For OS/X Server |
|
2 | + |
|
3 | +1. The right Ruby must be installed |
|
4 | +2. Bundler must be installed |
|
5 | +3. gem install passenger # right version |
|
6 | +4. passenger-install-apache2-module |
|
7 | +5. Watch the console. You will get instructions for the Passenger setup in Apache. It should look |
|
8 | +like this: |
|
9 | + |
|
10 | + ``` |
|
11 | + LoadModule passenger_module /opt/boxen/rbenv/versions/2.1.4/lib/ruby/gems/2.1.0/gems/passenger-5.0.6/buildout/apache2/mod_passenger.so |
|
12 | + <IfModule mod_passenger.c> |
|
13 | + PassengerRoot /opt/boxen/rbenv/versions/2.1.4/lib/ruby/gems/2.1.0/gems/passenger-5.0.6 |
|
14 | + PassengerDefaultRuby /opt/boxen/rbenv/versions/2.1.4/bin/ruby |
|
15 | + </IfModule> |
|
16 | + ``` |
|
17 | + |
|
18 | +6. Put that in a file in `/Library/Server/Web/Config/apache2/other` |
|
19 | +7. Create the site through the OS/X server interface |
|
20 | +8. Edit the config file for the site created by OS/X server, e.g., `/Library/Server/Web/Config/apache2/sites/0000_any_443_wiki.7fff.com.conf` |
|
21 | +9. You will need to add `SetEnv` directives inside the `<VirtualHost>` block. It should look something like the following (the values for the client id and client secret may be found here: <https://github.com/settings/applications/35517>): |
|
22 | + |
|
23 | + ``` |
|
24 | + SetEnv STOOR_WIKI_GITHUB_CLIENT_ID 780ec06a331b4f61a344 |
|
25 | + SetEnv STOOR_WIKI_GITHUB_CLIENT_SECRET f1e5439aff166c34f707747120acbf66ef233fc1 |
|
26 | + SetEnv STOOR_WIKI_GITHUB_EMAIL_DOMAIN 7fff.com |
|
27 | + SetEnv STOOR_WIKI_DOMAIN 7fff.com |
|
28 | + SetEnv STOOR_WIKI_EXPIRE_AFTER 60 |
|
29 | + SetEnv STOOR_WIKI_WIKI_PATH /Users/jgn/Dropbox/wiki |
|
30 | + SetEnv STOOR_WIKI_WIDE y |
|
31 | + SetEnvIf X-Forwarded-Proto https HTTPS=on |
|
32 | + ``` |
|
... | ... | \ No newline at end of file |