├── .dockerignore ├── .eslintignore ├── .eslintrc.js ├── .gitattributes ├── .github └── workflows │ └── ci.yml ├── .gitignore ├── .husky ├── .gitignore └── pre-commit ├── .lintstagedrc.mjs ├── .prettierignore ├── .prettierrc.json ├── .transpire.py ├── .vscode ├── extensions.json ├── settings.json └── tasks.json ├── .yarn └── sdks │ ├── eslint │ ├── bin │ │ └── eslint.js │ ├── lib │ │ └── api.js │ └── package.json │ ├── integrations.yml │ ├── prettier │ ├── index.js │ └── package.json │ └── typescript │ ├── bin │ ├── tsc │ └── tsserver │ ├── lib │ ├── tsc.js │ ├── tsserver.js │ ├── tsserverlibrary.js │ └── typescript.js │ └── package.json ├── .yarnrc.yml ├── Dockerfile ├── Jenkinsfile ├── Makefile ├── README.md ├── docs ├── faq.md ├── internal │ ├── about.md │ ├── about │ │ └── formerstaff.md │ ├── contact.md │ ├── contact │ │ ├── irc.md │ │ └── slack.md │ ├── docs.md │ ├── docs │ │ ├── archive.md │ │ ├── archive │ │ │ └── constitution.md │ │ ├── charter.md │ │ ├── operatingrules.md │ │ ├── operatingrules │ │ │ ├── bylaws.md │ │ │ └── constitution.md │ │ └── policies.md │ ├── membership.md │ └── membership │ │ ├── banning.md │ │ └── eligibility.md ├── services │ ├── account.md │ ├── account │ │ ├── account-policies.md │ │ └── content-removal.md │ ├── hpc.md │ ├── hpc │ │ └── slurm.md │ ├── lab.md │ ├── lab │ │ ├── lab-reservation-policy.md │ │ └── printing.md │ ├── mail.md │ ├── mastodon.md │ ├── mirrors.md │ ├── mysql.md │ ├── shell.md │ ├── shell │ │ └── commands.md │ ├── vhost.md │ ├── vhost │ │ ├── mail.md │ │ └── mail │ │ │ └── gmail.md │ ├── web.md │ ├── web │ │ ├── backups.md │ │ ├── django.md │ │ ├── flask.md │ │ ├── jekyll.md │ │ ├── php.md │ │ ├── rails.md │ │ └── wordpress.md │ ├── webapps.md │ ├── webapps │ │ ├── nodejs.md │ │ ├── python.md │ │ └── rails.md │ ├── webhostingsolutions.md │ └── xmpp.md └── staff │ ├── backend.md │ ├── backend │ ├── backups.md │ ├── firewall.md │ ├── git.md │ ├── internal-firewalls.md │ ├── jenkins.md │ ├── kerberos.md │ ├── kubernetes.md │ ├── ldap.md │ ├── libvirt.md │ ├── mail.md │ ├── mail │ │ └── vhost.md │ ├── munin.md │ ├── printhost.md │ ├── prometheus.md │ ├── puppet.md │ ├── rt.md │ └── switch.md │ ├── getinvolved.md │ ├── i3wm.md │ ├── mailing-lists.md │ ├── policies.md │ ├── policies │ ├── keycard.md │ ├── lab-reservation-policy.md │ └── staff-policy.md │ ├── powers.md │ ├── private.md │ ├── procedures.md │ ├── procedures │ ├── accounts.md │ ├── accounts │ │ ├── alumni-reset.md │ │ ├── association.md │ │ └── renaming.md │ ├── backporting-packages.md │ ├── dmca.md │ ├── editing-docs.md │ ├── gapps.md │ ├── granting-privileges.md │ ├── hpc.md │ ├── installing-updates.md │ ├── new-host.md │ ├── printing.md │ ├── process-accounting.md │ ├── restarting-services.md │ ├── setting-up-lacp.md │ ├── setting-up-mdraid.md │ ├── ssh-supernova.md │ ├── ssl.md │ ├── user-quotas.md │ ├── vhost.md │ └── xmpp.md │ ├── rebuild.md │ ├── rebuild │ └── rt.md │ ├── scripts.md │ ├── scripts │ ├── approve.md │ ├── check.md │ ├── checkacct.md │ ├── chpass.md │ ├── economode.md │ ├── how.md │ ├── lab-wakeup.md │ ├── migrate-vm.md │ ├── note.md │ ├── ocf-tv.md │ ├── paper.md │ ├── pdf-open.md │ ├── signat.md │ ├── sorry.md │ ├── ssh-list.md │ └── unsorry.md │ ├── startertasks.md │ ├── startertasks │ └── completed.md │ ├── techtalks.md │ ├── tips.md │ └── tips │ ├── desktoprc.md │ ├── shorturls.md │ ├── staffvm.md │ ├── staffvm │ ├── ocfweb.md │ └── znc.md │ ├── templates.md │ └── testaccts.md ├── gatsby-browser.tsx ├── gatsby-config.ts ├── gatsby-env.d.ts ├── gatsby-node.ts ├── gatsby-ssr.tsx ├── kubernetes └── ocfstatic-previews.yml.erb ├── nginx.conf ├── package.json ├── src ├── @chakra-ui │ └── gatsby-plugin │ │ └── theme.ts ├── components │ ├── Footer.tsx │ ├── FullWidthBox.tsx │ ├── InternalLink.tsx │ ├── Layout.tsx │ ├── Logo.css │ ├── Logo.tsx │ ├── Navbar.tsx │ ├── NavbarButton.tsx │ ├── NavbarDropdown.tsx │ ├── NavbarDropdownLink.tsx │ └── SEO.tsx ├── definitions │ └── ocfapi.ts ├── hooks │ ├── useCalNetAuth.ts │ └── useKeycloakAuth.ts ├── images │ ├── logo.svg │ └── penguin.svg ├── pages │ ├── 404.tsx │ ├── about │ │ ├── lab.tsx │ │ └── staff.tsx │ ├── account │ │ ├── index.tsx │ │ ├── password.tsx │ │ └── register.tsx │ ├── auth │ │ └── calnet │ │ │ ├── callback.tsx │ │ │ └── index.tsx │ ├── index.tsx │ ├── staff-hours.tsx │ └── stats.tsx ├── styles │ └── inter.css └── utils │ ├── api.ts │ ├── cookie.ts │ └── keycloak.ts ├── static ├── assets │ ├── Inter-italic.var.woff2 │ ├── Inter-roman.var.woff2 │ └── img │ │ ├── actions │ │ ├── event.jpg │ │ └── webdev.jpg │ │ ├── cloud.jpg │ │ ├── computer-lab-clipart.jpg │ │ ├── favicon │ │ ├── favicon-16.png │ │ └── favicon-32.png │ │ ├── hero.jpg │ │ ├── lab_and_printing.png │ │ ├── nikitpenguin.png │ │ ├── penguin-sticker.png │ │ ├── printer.jpg │ │ ├── techsupport.png │ │ └── unix-shell.jpg ├── docs │ ├── .nojekyll │ ├── 404.html │ ├── assets │ │ ├── css │ │ │ └── styles.3979abba.css │ │ └── js │ │ │ ├── 00b48360.c79fb133.js │ │ │ ├── 0223ccf0.9cb6fc13.js │ │ │ ├── 0480b142.4c228694.js │ │ │ ├── 04ad60f6.12da1aa2.js │ │ │ ├── 05773811.9f1ece4e.js │ │ │ ├── 07f86827.bcbb4157.js │ │ │ ├── 08326d2d.4ececd3e.js │ │ │ ├── 0afb01d8.836500ba.js │ │ │ ├── 0e27b87d.e3d2a177.js │ │ │ ├── 1073d45f.aff51894.js │ │ │ ├── 13cda1bc.78ec80c0.js │ │ │ ├── 15e932ec.8e1af936.js │ │ │ ├── 17896441.b1c3ce96.js │ │ │ ├── 1a0f1658.d66849a7.js │ │ │ ├── 1be78505.c022dbcf.js │ │ │ ├── 1f509571.de906def.js │ │ │ ├── 21dcafa7.ea35e04a.js │ │ │ ├── 21e10260.e39bb6d9.js │ │ │ ├── 233336e3.f5d38960.js │ │ │ ├── 2379cec2.78e133b8.js │ │ │ ├── 280c38e1.f9772c27.js │ │ │ ├── 2960be92.48da3cd4.js │ │ │ ├── 2c89a27c.a67c8a20.js │ │ │ ├── 2cfed8c3.b164ef1b.js │ │ │ ├── 3095c0b6.6bf709eb.js │ │ │ ├── 37a2d882.0901b1f8.js │ │ │ ├── 37a8fa91.3b2b9335.js │ │ │ ├── 38be7b0a.26d496f1.js │ │ │ ├── 3bcf540a.2bdb8b67.js │ │ │ ├── 3ebee732.dde2ffbe.js │ │ │ ├── 40223539.f939981c.js │ │ │ ├── 4843cc06.c2420667.js │ │ │ ├── 4972.6526eff4.js │ │ │ ├── 4a42023c.7ace6006.js │ │ │ ├── 4ab29704.61205cfa.js │ │ │ ├── 4d648bd1.5222741b.js │ │ │ ├── 4f4239c0.32bec070.js │ │ │ ├── 5028fe3f.d0a0ee60.js │ │ │ ├── 55884ad7.280bbe65.js │ │ │ ├── 56760a6e.914c07b3.js │ │ │ ├── 59d1205d.6b0491d5.js │ │ │ ├── 5ab06d0f.326f1486.js │ │ │ ├── 5f537c1c.878757f4.js │ │ │ ├── 6020ec86.34bb777a.js │ │ │ ├── 66185a68.c0ff03ca.js │ │ │ ├── 6be4e37b.7ccfa5d0.js │ │ │ ├── 6d71ae9c.1cce7dcb.js │ │ │ ├── 6db9db05.7132c7ba.js │ │ │ ├── 6f653e1f.75dc67dd.js │ │ │ ├── 71dd125d.6bb73fd5.js │ │ │ ├── 732ee796.606690cf.js │ │ │ ├── 772af447.301991cd.js │ │ │ ├── 780fe06f.5ae38403.js │ │ │ ├── 78791b94.47c76237.js │ │ │ ├── 78c45307.43998b8c.js │ │ │ ├── 7a45209b.1676cf4f.js │ │ │ ├── 7a8e4636.0de80dde.js │ │ │ ├── 7ae2771f.7235eaa7.js │ │ │ ├── 7dad9d97.df99c328.js │ │ │ ├── 7dba809f.82d913db.js │ │ │ ├── 80415fc5.abdd06bd.js │ │ │ ├── 808596c7.44aa46df.js │ │ │ ├── 832ffc4e.df7dcaa8.js │ │ │ ├── 85254dd1.07378e65.js │ │ │ ├── 864f5fc7.8d8a7556.js │ │ │ ├── 874a19b5.38ae3450.js │ │ │ ├── 8b0cd1a4.b25dc251.js │ │ │ ├── 8c18e6b4.c9f87d0d.js │ │ │ ├── 8c56da71.c29dfc9e.js │ │ │ ├── 8c66e887.544f43b6.js │ │ │ ├── 8ef94bd6.ef7e639a.js │ │ │ ├── 90c90b6e.64f67eb4.js │ │ │ ├── 90d94352.1e0b40ef.js │ │ │ ├── 913335ed.cf77681e.js │ │ │ ├── 914a2a57.2f8454cc.js │ │ │ ├── 935f2afb.932a14bc.js │ │ │ ├── 94e46be2.684a1c6f.js │ │ │ ├── 95a59ba2.13acf68d.js │ │ │ ├── 963007ad.3ae93dce.js │ │ │ ├── 96d8bcdc.726e2663.js │ │ │ ├── 96e7c74e.a05b5a76.js │ │ │ ├── 97c24920.ab164544.js │ │ │ ├── 97faafa8.5290a8c6.js │ │ │ ├── 9a40843e.56bef745.js │ │ │ ├── 9abd5fe3.a1f121ec.js │ │ │ ├── 9ae15cb2.af7863ed.js │ │ │ ├── 9da52549.24ee1aab.js │ │ │ ├── 9dfa47c2.da49f7f9.js │ │ │ ├── a4f66507.75e298c7.js │ │ │ ├── a6610474.751a5e6a.js │ │ │ ├── a6921aec.0642be3d.js │ │ │ ├── aadf4e14.17609b93.js │ │ │ ├── ac3925b9.b36f49f3.js │ │ │ ├── acb3372d.8b6e9aa5.js │ │ │ ├── b18dc229.43117661.js │ │ │ ├── b4089854.2a2c54db.js │ │ │ ├── bdf3548b.58853a19.js │ │ │ ├── c15482d2.af7538ce.js │ │ │ ├── c377a04b.b88b65a5.js │ │ │ ├── c430766f.58c61274.js │ │ │ ├── c45b943a.cab858e0.js │ │ │ ├── c470593d.03dcc3ce.js │ │ │ ├── c64ee159.1f6ea70d.js │ │ │ ├── c6753cdd.7be870e2.js │ │ │ ├── c7ef5120.a843e22b.js │ │ │ ├── cde1920f.227015ee.js │ │ │ ├── cee5fe5a.b6fb987a.js │ │ │ ├── cf43f79b.6799b182.js │ │ │ ├── d1318b96.843690e9.js │ │ │ ├── d88d60b7.edf26af4.js │ │ │ ├── d91d4969.9658fed2.js │ │ │ ├── d95c3a1c.412c8011.js │ │ │ ├── d9917b14.27f90846.js │ │ │ ├── dbc1d846.e1bbd8b6.js │ │ │ ├── dc33c9d7.362c510b.js │ │ │ ├── e00964b2.03114c80.js │ │ │ ├── e1d3b8a1.04903f97.js │ │ │ ├── e44ae13b.7e5a7533.js │ │ │ ├── e7140ad7.91528e9f.js │ │ │ ├── e84d9ede.9df9a2b0.js │ │ │ ├── e9143bbc.52ce7fda.js │ │ │ ├── ec7ec896.4193d212.js │ │ │ ├── ed649418.54c21edb.js │ │ │ ├── f1a9a140.197a47cd.js │ │ │ ├── f2f30711.b597da7e.js │ │ │ ├── f379b670.10357042.js │ │ │ ├── f6d6aca8.2d6847eb.js │ │ │ ├── f6fa8add.31d15850.js │ │ │ ├── f94208ce.9ffa969c.js │ │ │ ├── f963742c.ea881d73.js │ │ │ ├── fddeb8c4.d639d7bf.js │ │ │ ├── fe1e5cdb.644ce7d0.js │ │ │ ├── fea75759.26b5fd7f.js │ │ │ ├── fffb4572.10bfd03b.js │ │ │ ├── main.4f9c1481.js │ │ │ ├── main.4f9c1481.js.LICENSE.txt │ │ │ └── runtime~main.a314d0f9.js │ ├── faq │ │ └── index.html │ ├── img │ │ ├── docusaurus.png │ │ ├── favicon.ico │ │ ├── logo.svg │ │ ├── undraw_docusaurus_mountain.svg │ │ ├── undraw_docusaurus_react.svg │ │ └── undraw_docusaurus_tree.svg │ ├── index.html │ ├── internal │ │ ├── about │ │ │ ├── formerstaff │ │ │ │ └── index.html │ │ │ └── index.html │ │ ├── contact │ │ │ ├── index.html │ │ │ ├── irc │ │ │ │ └── index.html │ │ │ └── slack │ │ │ │ └── index.html │ │ ├── docs │ │ │ ├── archive │ │ │ │ ├── constitution │ │ │ │ │ └── index.html │ │ │ │ └── index.html │ │ │ ├── charter │ │ │ │ └── index.html │ │ │ ├── index.html │ │ │ ├── operatingrules │ │ │ │ ├── bylaws │ │ │ │ │ └── index.html │ │ │ │ ├── constitution │ │ │ │ │ └── index.html │ │ │ │ └── index.html │ │ │ └── policies │ │ │ │ └── index.html │ │ └── membership │ │ │ ├── banning │ │ │ └── index.html │ │ │ ├── eligibility │ │ │ └── index.html │ │ │ └── index.html │ ├── search-index-docs-default-current.json │ ├── services │ │ ├── account │ │ │ ├── account-policies │ │ │ │ └── index.html │ │ │ ├── content-removal │ │ │ │ └── index.html │ │ │ └── index.html │ │ ├── hpc │ │ │ ├── index.html │ │ │ └── slurm │ │ │ │ └── index.html │ │ ├── lab │ │ │ ├── index.html │ │ │ ├── lab-reservation-policy │ │ │ │ └── index.html │ │ │ └── printing │ │ │ │ └── index.html │ │ ├── mail │ │ │ └── index.html │ │ ├── mastodon │ │ │ └── index.html │ │ ├── mirrors │ │ │ └── index.html │ │ ├── mysql │ │ │ └── index.html │ │ ├── shell │ │ │ ├── commands │ │ │ │ └── index.html │ │ │ └── index.html │ │ ├── vhost │ │ │ ├── index.html │ │ │ └── mail │ │ │ │ ├── gmail │ │ │ │ └── index.html │ │ │ │ └── index.html │ │ ├── web │ │ │ ├── backups │ │ │ │ └── index.html │ │ │ ├── django │ │ │ │ └── index.html │ │ │ ├── flask │ │ │ │ └── index.html │ │ │ ├── index.html │ │ │ ├── jekyll │ │ │ │ └── index.html │ │ │ ├── php │ │ │ │ └── index.html │ │ │ ├── rails │ │ │ │ └── index.html │ │ │ └── wordpress │ │ │ │ └── index.html │ │ ├── webapps │ │ │ ├── index.html │ │ │ ├── nodejs │ │ │ │ └── index.html │ │ │ ├── python │ │ │ │ └── index.html │ │ │ └── rails │ │ │ │ └── index.html │ │ ├── webhostingsolutions │ │ │ └── index.html │ │ └── xmpp │ │ │ └── index.html │ ├── sitemap.xml │ └── staff │ │ ├── backend │ │ ├── backups │ │ │ └── index.html │ │ ├── firewall │ │ │ └── index.html │ │ ├── git │ │ │ └── index.html │ │ ├── index.html │ │ ├── internal-firewalls │ │ │ └── index.html │ │ ├── jenkins │ │ │ └── index.html │ │ ├── kerberos │ │ │ └── index.html │ │ ├── kubernetes │ │ │ └── index.html │ │ ├── ldap │ │ │ └── index.html │ │ ├── libvirt │ │ │ └── index.html │ │ ├── mail │ │ │ ├── index.html │ │ │ └── vhost │ │ │ │ └── index.html │ │ ├── munin │ │ │ └── index.html │ │ ├── printhost │ │ │ └── index.html │ │ ├── prometheus │ │ │ └── index.html │ │ ├── puppet │ │ │ └── index.html │ │ ├── rt │ │ │ └── index.html │ │ └── switch │ │ │ └── index.html │ │ ├── getinvolved │ │ └── index.html │ │ ├── i3wm │ │ └── index.html │ │ ├── mailing-lists │ │ └── index.html │ │ ├── policies │ │ ├── index.html │ │ ├── keycard │ │ │ └── index.html │ │ ├── lab-reservation-policy │ │ │ └── index.html │ │ └── staff-policy │ │ │ └── index.html │ │ ├── powers │ │ └── index.html │ │ ├── private │ │ └── index.html │ │ ├── procedures │ │ ├── accounts │ │ │ ├── alumni-reset │ │ │ │ └── index.html │ │ │ ├── association │ │ │ │ └── index.html │ │ │ ├── index.html │ │ │ └── renaming │ │ │ │ └── index.html │ │ ├── backporting-packages │ │ │ └── index.html │ │ ├── dmca │ │ │ └── index.html │ │ ├── editing-docs │ │ │ └── index.html │ │ ├── gapps │ │ │ └── index.html │ │ ├── granting-privileges │ │ │ └── index.html │ │ ├── hpc │ │ │ └── index.html │ │ ├── index.html │ │ ├── installing-updates │ │ │ └── index.html │ │ ├── new-host │ │ │ └── index.html │ │ ├── printing │ │ │ └── index.html │ │ ├── process-accounting │ │ │ └── index.html │ │ ├── restarting-services │ │ │ └── index.html │ │ ├── setting-up-lacp │ │ │ └── index.html │ │ ├── setting-up-mdraid │ │ │ └── index.html │ │ ├── ssh-supernova │ │ │ └── index.html │ │ ├── ssl │ │ │ └── index.html │ │ ├── user-quotas │ │ │ └── index.html │ │ ├── vhost │ │ │ └── index.html │ │ └── xmpp │ │ │ └── index.html │ │ ├── rebuild │ │ ├── index.html │ │ └── rt │ │ │ └── index.html │ │ ├── scripts │ │ ├── approve │ │ │ └── index.html │ │ ├── check │ │ │ └── index.html │ │ ├── checkacct │ │ │ └── index.html │ │ ├── chpass │ │ │ └── index.html │ │ ├── economode │ │ │ └── index.html │ │ ├── how │ │ │ └── index.html │ │ ├── index.html │ │ ├── lab-wakeup │ │ │ └── index.html │ │ ├── migrate-vm │ │ │ └── index.html │ │ ├── note │ │ │ └── index.html │ │ ├── ocf-tv │ │ │ └── index.html │ │ ├── paper │ │ │ └── index.html │ │ ├── pdf-open │ │ │ └── index.html │ │ ├── signat │ │ │ └── index.html │ │ ├── sorry │ │ │ └── index.html │ │ ├── ssh-list │ │ │ └── index.html │ │ └── unsorry │ │ │ └── index.html │ │ ├── startertasks │ │ ├── completed │ │ │ └── index.html │ │ └── index.html │ │ ├── techtalks │ │ └── index.html │ │ └── tips │ │ ├── desktoprc │ │ └── index.html │ │ ├── index.html │ │ ├── shorturls │ │ └── index.html │ │ ├── staffvm │ │ ├── index.html │ │ ├── ocfweb │ │ │ └── index.html │ │ └── znc │ │ │ └── index.html │ │ ├── templates │ │ └── index.html │ │ └── testaccts │ │ └── index.html ├── keycloak.json └── silent-check-sso.html ├── tsconfig.json └── yarn.lock /.dockerignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | dist 3 | .git 4 | .cache 5 | .dockerignore 6 | Dockerfile 7 | .DS_Store 8 | src/.temp 9 | .gitignore 10 | .env 11 | public 12 | -------------------------------------------------------------------------------- /.eslintignore: -------------------------------------------------------------------------------- 1 | public/ 2 | static/docs/ 3 | .cache/ 4 | node_modules/ 5 | .vscode/ 6 | .yarn/ 7 | .pnp.* 8 | 9 | !.eslintrc.* 10 | !.lintstagedrc.* 11 | -------------------------------------------------------------------------------- /.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | root: true, 3 | env: { 4 | browser: true, 5 | }, 6 | parser: "@typescript-eslint/parser", 7 | parserOptions: { 8 | tsconfigRootDir: __dirname, 9 | project: ["./tsconfig.json"], 10 | }, 11 | plugins: ["@typescript-eslint"], 12 | extends: [ 13 | "eslint:recommended", 14 | "plugin:import/recommended", 15 | "plugin:import/typescript", 16 | "plugin:@typescript-eslint/recommended", 17 | "plugin:react/recommended", 18 | "plugin:react/jsx-runtime", 19 | "plugin:react-hooks/recommended", 20 | "plugin:jsx-a11y/recommended", 21 | "plugin:prettier/recommended", 22 | ], 23 | rules: { 24 | "import/no-anonymous-default-export": "error", 25 | }, 26 | settings: { 27 | react: { 28 | version: "detect", 29 | }, 30 | "import/resolver": "typescript", 31 | }, 32 | overrides: [ 33 | { 34 | files: ["*.ts", "*.tsx"], 35 | extends: [ 36 | "plugin:@typescript-eslint/recommended-requiring-type-checking", 37 | ], 38 | }, 39 | { 40 | files: [".eslintrc.*js", ".lintstagedrc.*js"], 41 | parser: "espree", 42 | env: { 43 | node: true, 44 | es6: true, 45 | browser: false, 46 | }, 47 | rules: { 48 | "import/no-anonymous-default-export": "off", 49 | }, 50 | }, 51 | { 52 | files: ["src/definitions/ocfapi.ts"], 53 | rules: { 54 | "@typescript-eslint/no-empty-interface": "off", 55 | }, 56 | }, 57 | ], 58 | } 59 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | # Treat yarn artifacts as binary blobs (we don't use the `binary` macro 2 | # attribute since we still want git to treat the contents as text for the 3 | # purposes of line-ending converesion and the like) 4 | .yarn/releases/** -diff -merge 5 | .yarn/plugins/** -diff -merge 6 | .yarn/sdks/*/** -diff -merge 7 | 8 | # Suppress lockfile diffs by default 9 | yarn.lock -diff 10 | 11 | # Supress static compiled docs 12 | static/docs/** -diff -merge 13 | -------------------------------------------------------------------------------- /.github/workflows/ci.yml: -------------------------------------------------------------------------------- 1 | name: CI 2 | on: 3 | push: 4 | branches: [master] 5 | pull_request: 6 | 7 | jobs: 8 | lint: 9 | runs-on: ubuntu-22.04 10 | strategy: 11 | matrix: 12 | node: [18] 13 | steps: 14 | - uses: actions/checkout@v3 15 | 16 | - name: Set up Node ${{ matrix.node }} 17 | uses: actions/setup-node@v3 18 | with: 19 | node-version: ${{ matrix.node }} 20 | 21 | # https://github.com/actions/cache/blob/v3.0.11/examples.md#node---yarn-2 22 | - name: Get yarn cache directory path 23 | id: yarn-cache-dir-path 24 | run: echo "dir=$(yarn config get cacheFolder)" >> $GITHUB_OUTPUT 25 | - uses: actions/cache@v3 26 | id: yarn-cache # use this to check for `cache-hit` (`steps.yarn-cache.outputs.cache-hit != 'true'`) 27 | with: 28 | path: ${{ steps.yarn-cache-dir-path.outputs.dir }} 29 | key: ${{ runner.os }}-yarn-${{ hashFiles('**/yarn.lock') }} 30 | restore-keys: | 31 | ${{ runner.os }}-yarn- 32 | 33 | - name: Install dependencies 34 | run: | 35 | yarn install --immutable 36 | - name: Check formatting 37 | run: | 38 | yarn prettier --check . 39 | - name: Typecheck 40 | run: | 41 | yarn typecheck 42 | - name: Lint 43 | run: | 44 | yarn lint --max-warnings=0 45 | 46 | transpire-ci: 47 | uses: ocf/transpire-ci/.github/workflows/trigger.yml@master 48 | needs: lint 49 | with: 50 | module_name: ocfstatic 51 | secrets: 52 | TRANSPIRE_CI_PAT: ${{ secrets.TRANSPIRE_CI_PAT }} 53 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.log 2 | .cache 3 | .DS_Store 4 | src/.temp 5 | node_modules 6 | dist 7 | .env 8 | .env.* 9 | public 10 | .eslintcache 11 | 12 | # Yarn 2, non-zero-install 13 | .pnp.* 14 | .yarn/* 15 | !.yarn/patches 16 | !.yarn/plugins 17 | !.yarn/releases 18 | !.yarn/sdks 19 | !.yarn/versions 20 | -------------------------------------------------------------------------------- /.husky/.gitignore: -------------------------------------------------------------------------------- 1 | _ 2 | -------------------------------------------------------------------------------- /.husky/pre-commit: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | . "$(dirname "$0")/_/husky.sh" 3 | 4 | yarn lint-staged 5 | -------------------------------------------------------------------------------- /.lintstagedrc.mjs: -------------------------------------------------------------------------------- 1 | import { ESLint } from "eslint" 2 | 3 | const eslint = new ESLint() 4 | 5 | const asyncFilter = async (arr, pred) => { 6 | const kept = await Promise.all(arr.map(pred)) 7 | return arr.filter((_v, index) => kept[index]) 8 | } 9 | 10 | export default { 11 | "*.{m,c,}{j,t}s?(x)": async (files) => { 12 | const filtered = await asyncFilter( 13 | files, 14 | async (file) => !(await eslint.isPathIgnored(file)), 15 | ) 16 | if (filtered.length === 0) { 17 | return [] 18 | } 19 | return ["yarn eslint --cache --max-warnings=0 --fix " + filtered.join(" ")] 20 | }, 21 | "*.ts?(x)": () => "yarn tsc --noEmit", 22 | "*.({j,t}s?(x)|md?(x)|json|y?(a)ml)": "yarn prettier --write", 23 | } 24 | -------------------------------------------------------------------------------- /.prettierignore: -------------------------------------------------------------------------------- 1 | public/ 2 | .cache/ 3 | node_modules/ 4 | tsconfig.json 5 | .vscode/ 6 | .yarn/ 7 | .pnp.* 8 | static/docs/ 9 | -------------------------------------------------------------------------------- /.prettierrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "semi": false 3 | } 4 | -------------------------------------------------------------------------------- /.transpire.py: -------------------------------------------------------------------------------- 1 | from pathlib import Path 2 | 3 | from transpire.resources import Deployment, Ingress, Service 4 | from transpire.types import Image 5 | from transpire.utils import get_image_tag 6 | 7 | name = "ocfstatic" 8 | 9 | 10 | def objects(): 11 | dep = Deployment( 12 | name="ocfstatic", 13 | image=get_image_tag("ocfstatic"), 14 | ports=[80], 15 | ) 16 | 17 | svc = Service( 18 | name="ocfstatic", 19 | selector=dep.get_selector(), 20 | port_on_pod=80, 21 | port_on_svc=80, 22 | ) 23 | 24 | ing = Ingress.from_svc( 25 | svc=svc, 26 | host="new.ocf.berkeley.edu", 27 | path_prefix="/", 28 | ) 29 | 30 | yield dep.build() 31 | yield svc.build() 32 | yield ing.build() 33 | 34 | 35 | def images(): 36 | yield Image(name="ocfstatic", path=Path("/")) 37 | -------------------------------------------------------------------------------- /.vscode/extensions.json: -------------------------------------------------------------------------------- 1 | { 2 | "recommendations": [ 3 | "arcanis.vscode-zipfs", 4 | "dbaeumer.vscode-eslint", 5 | "esbenp.prettier-vscode" 6 | ] 7 | } 8 | -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "editor.defaultFormatter": "esbenp.prettier-vscode", 3 | "editor.formatOnSave": true, 4 | "npm.packageManager": "yarn", 5 | "search.exclude": { 6 | "**/.yarn": true, 7 | "**/.pnp.*": true 8 | }, 9 | "eslint.nodePath": ".yarn/sdks", 10 | "prettier.prettierPath": ".yarn/sdks/prettier/index.js", 11 | "typescript.tsdk": ".yarn/sdks/typescript/lib", 12 | "typescript.enablePromptUseWorkspaceTsdk": true, 13 | "typescript.preferences.quoteStyle": "double", 14 | "githubPullRequests.ignoredPullRequestBranches": [ 15 | "master" 16 | ] 17 | } 18 | -------------------------------------------------------------------------------- /.vscode/tasks.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "2.0.0", 3 | "tasks": [ 4 | { 5 | "type": "npm", 6 | "script": "develop", 7 | "problemMatcher": [], 8 | "label": "yarn: develop", 9 | "detail": "gatsby develop" 10 | } 11 | ] 12 | } 13 | -------------------------------------------------------------------------------- /.yarn/sdks/eslint/bin/eslint.js: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | 3 | const {existsSync} = require(`fs`); 4 | const {createRequire} = require(`module`); 5 | const {resolve} = require(`path`); 6 | 7 | const relPnpApiPath = "../../../../.pnp.cjs"; 8 | 9 | const absPnpApiPath = resolve(__dirname, relPnpApiPath); 10 | const absRequire = createRequire(absPnpApiPath); 11 | 12 | if (existsSync(absPnpApiPath)) { 13 | if (!process.versions.pnp) { 14 | // Setup the environment to be able to require eslint/bin/eslint.js 15 | require(absPnpApiPath).setup(); 16 | } 17 | } 18 | 19 | // Defer to the real eslint/bin/eslint.js your application uses 20 | module.exports = absRequire(`eslint/bin/eslint.js`); 21 | -------------------------------------------------------------------------------- /.yarn/sdks/eslint/lib/api.js: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | 3 | const {existsSync} = require(`fs`); 4 | const {createRequire} = require(`module`); 5 | const {resolve} = require(`path`); 6 | 7 | const relPnpApiPath = "../../../../.pnp.cjs"; 8 | 9 | const absPnpApiPath = resolve(__dirname, relPnpApiPath); 10 | const absRequire = createRequire(absPnpApiPath); 11 | 12 | if (existsSync(absPnpApiPath)) { 13 | if (!process.versions.pnp) { 14 | // Setup the environment to be able to require eslint 15 | require(absPnpApiPath).setup(); 16 | } 17 | } 18 | 19 | // Defer to the real eslint your application uses 20 | module.exports = absRequire(`eslint`); 21 | -------------------------------------------------------------------------------- /.yarn/sdks/eslint/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "eslint", 3 | "version": "8.50.0-sdk", 4 | "main": "./lib/api.js", 5 | "type": "commonjs" 6 | } 7 | -------------------------------------------------------------------------------- /.yarn/sdks/integrations.yml: -------------------------------------------------------------------------------- 1 | # This file is automatically generated by @yarnpkg/sdks. 2 | # Manual changes might be lost! 3 | 4 | integrations: 5 | - vscode 6 | -------------------------------------------------------------------------------- /.yarn/sdks/prettier/index.js: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | 3 | const {existsSync} = require(`fs`); 4 | const {createRequire} = require(`module`); 5 | const {resolve} = require(`path`); 6 | 7 | const relPnpApiPath = "../../../.pnp.cjs"; 8 | 9 | const absPnpApiPath = resolve(__dirname, relPnpApiPath); 10 | const absRequire = createRequire(absPnpApiPath); 11 | 12 | if (existsSync(absPnpApiPath)) { 13 | if (!process.versions.pnp) { 14 | // Setup the environment to be able to require prettier 15 | require(absPnpApiPath).setup(); 16 | } 17 | } 18 | 19 | // Defer to the real prettier your application uses 20 | module.exports = absRequire(`prettier`); 21 | -------------------------------------------------------------------------------- /.yarn/sdks/prettier/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "prettier", 3 | "version": "3.0.3-sdk", 4 | "main": "./index.js", 5 | "type": "commonjs" 6 | } 7 | -------------------------------------------------------------------------------- /.yarn/sdks/typescript/bin/tsc: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | 3 | const {existsSync} = require(`fs`); 4 | const {createRequire} = require(`module`); 5 | const {resolve} = require(`path`); 6 | 7 | const relPnpApiPath = "../../../../.pnp.cjs"; 8 | 9 | const absPnpApiPath = resolve(__dirname, relPnpApiPath); 10 | const absRequire = createRequire(absPnpApiPath); 11 | 12 | if (existsSync(absPnpApiPath)) { 13 | if (!process.versions.pnp) { 14 | // Setup the environment to be able to require typescript/bin/tsc 15 | require(absPnpApiPath).setup(); 16 | } 17 | } 18 | 19 | // Defer to the real typescript/bin/tsc your application uses 20 | module.exports = absRequire(`typescript/bin/tsc`); 21 | -------------------------------------------------------------------------------- /.yarn/sdks/typescript/bin/tsserver: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | 3 | const {existsSync} = require(`fs`); 4 | const {createRequire} = require(`module`); 5 | const {resolve} = require(`path`); 6 | 7 | const relPnpApiPath = "../../../../.pnp.cjs"; 8 | 9 | const absPnpApiPath = resolve(__dirname, relPnpApiPath); 10 | const absRequire = createRequire(absPnpApiPath); 11 | 12 | if (existsSync(absPnpApiPath)) { 13 | if (!process.versions.pnp) { 14 | // Setup the environment to be able to require typescript/bin/tsserver 15 | require(absPnpApiPath).setup(); 16 | } 17 | } 18 | 19 | // Defer to the real typescript/bin/tsserver your application uses 20 | module.exports = absRequire(`typescript/bin/tsserver`); 21 | -------------------------------------------------------------------------------- /.yarn/sdks/typescript/lib/tsc.js: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | 3 | const {existsSync} = require(`fs`); 4 | const {createRequire} = require(`module`); 5 | const {resolve} = require(`path`); 6 | 7 | const relPnpApiPath = "../../../../.pnp.cjs"; 8 | 9 | const absPnpApiPath = resolve(__dirname, relPnpApiPath); 10 | const absRequire = createRequire(absPnpApiPath); 11 | 12 | if (existsSync(absPnpApiPath)) { 13 | if (!process.versions.pnp) { 14 | // Setup the environment to be able to require typescript/lib/tsc.js 15 | require(absPnpApiPath).setup(); 16 | } 17 | } 18 | 19 | // Defer to the real typescript/lib/tsc.js your application uses 20 | module.exports = absRequire(`typescript/lib/tsc.js`); 21 | -------------------------------------------------------------------------------- /.yarn/sdks/typescript/lib/typescript.js: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | 3 | const {existsSync} = require(`fs`); 4 | const {createRequire} = require(`module`); 5 | const {resolve} = require(`path`); 6 | 7 | const relPnpApiPath = "../../../../.pnp.cjs"; 8 | 9 | const absPnpApiPath = resolve(__dirname, relPnpApiPath); 10 | const absRequire = createRequire(absPnpApiPath); 11 | 12 | if (existsSync(absPnpApiPath)) { 13 | if (!process.versions.pnp) { 14 | // Setup the environment to be able to require typescript/lib/typescript.js 15 | require(absPnpApiPath).setup(); 16 | } 17 | } 18 | 19 | // Defer to the real typescript/lib/typescript.js your application uses 20 | module.exports = absRequire(`typescript/lib/typescript.js`); 21 | -------------------------------------------------------------------------------- /.yarn/sdks/typescript/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "typescript", 3 | "version": "5.2.2-sdk", 4 | "main": "./lib/typescript.js", 5 | "type": "commonjs" 6 | } 7 | -------------------------------------------------------------------------------- /.yarnrc.yml: -------------------------------------------------------------------------------- 1 | packageExtensions: 2 | # Gatsby is missing this dependency, which causes TS resolution to fail 3 | gatsby@*: 4 | dependencies: 5 | "@types/reach__router": "^1.3.10" 6 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | # Build stage 2 | FROM node:18 AS build 3 | WORKDIR /build 4 | COPY package.json yarn.lock .yarnrc.yml ./ 5 | COPY .yarn .yarn 6 | RUN corepack enable 7 | RUN corepack yarn install --immutable 8 | COPY . . 9 | RUN corepack yarn run build 10 | 11 | FROM nginx:stable 12 | COPY --from=build /build/public /usr/share/nginx/html/ 13 | COPY nginx.conf /etc/nginx/conf.d/default.conf 14 | EXPOSE 80 15 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | DOCKER_REVISION ?= testing-$(USER) 2 | DOCKER_TAG = docker-push.ocf.berkeley.edu/ocfstatic:$(DOCKER_REVISION) 3 | KUBE_PREVIEW_DEPLOY_NAMESPACE ?= app-ocfstatic 4 | KUBE_PREVIEW_DEPLOY_APP ?= ocfstatic-previews 5 | 6 | .PHONY: cook-image 7 | cook-image: 8 | docker build --pull -t $(DOCKER_TAG) . 9 | 10 | .PHONY: push-image 11 | push-image: 12 | docker push $(DOCKER_TAG) 13 | 14 | .PHONY: preview-deploy 15 | preview-deploy: 16 | $(eval CONTAINER_ID=$(shell sh -c "docker create $(DOCKER_TAG)")) 17 | $(eval DEPLOY_ID=$(shell echo $(PREVIEW_DEPLOY_ID) | tr '[:upper:]' '[:lower:]')) 18 | docker cp $(CONTAINER_ID):/usr/share/nginx/html/ ./$(DEPLOY_ID) 19 | docker rm $(CONTAINER_ID) 20 | $(eval POD_NAME=$(shell sh -c "kubectl get pods --no-headers -o custom-columns=":metadata.name" -l=app=$(KUBE_PREVIEW_DEPLOY_APP) -n $(KUBE_PREVIEW_DEPLOY_NAMESPACE) | head -n 1")) 21 | kubectl exec $(POD_NAME) -n $(KUBE_PREVIEW_DEPLOY_NAMESPACE) -- sh -c "rm -rf /var/www/ocfstatic/$(DEPLOY_ID)" 22 | kubectl cp ./$(DEPLOY_ID) $(KUBE_PREVIEW_DEPLOY_NAMESPACE)/$(POD_NAME):/var/www/ocfstatic/ --no-preserve=true 23 | rm -rf ./$(DEPLOY_ID) 24 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # OCF Static 2 | 3 | A new website for the OCF. Written in React with [Gatsby](https://www.gatsbyjs.com/), uses [Chakra UI](https://chakra-ui.com/). 4 | 5 | ## Development 6 | 7 | ### Dependencies 8 | 9 | - Node.js 18+ (https://nodejs.org/en/) 10 | - If using an Apple Silicon Mac (M1, M2, etc.), `vips` is required (can be installed through [Homebrew](https://brew.sh/) `brew install libvips`) 11 | - If using Windows, WSL is required (https://learn.microsoft.com/en-us/windows/wsl/install) 12 | 13 | ### Getting set up 14 | 15 | ```bash 16 | # Clone the repository 17 | $ git clone https://github.com/ocf/ocfstatic.git && cd ocfstatic 18 | # Install all of our dependencies 19 | $ corepack enable 20 | $ yarn 21 | # Run dev server (visit http://localhost:8000 to view) 22 | $ yarn develop 23 | ``` 24 | 25 | ### Extras 26 | 27 | ```bash 28 | # Build 29 | $ yarn build 30 | # Lint 31 | $ yarn lint 32 | # Typecheck 33 | $ yarn typecheck 34 | # Autoformat 35 | $ yarn format 36 | ``` 37 | 38 | ### Developing with ocfapi locally 39 | 40 | Create a file named .env.development with the following contents: 41 | 42 | ``` 43 | GATSBY_API_URL=http://localhost:8001 # or whatever port the API is on 44 | ``` 45 | 46 | This will redirect all API requests to that URL, if you want to revert to the production API just delete the file or comment out the line. 47 | 48 | ## How to contribute 49 | 50 | Take a look at the issues, and take your pick! 51 | 52 | ## Possible pitfalls 53 | 54 | Remember, you are writing server side rendered code. Don't use browser APIs such as anything on `window` except in a `useEffect` hook (and chances are, if you find yourself reaching for those APIs there's a better way of doing it!) 55 | -------------------------------------------------------------------------------- /docs/faq.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Frequently asked questions" 3 | --- 4 | 5 | #### Why might I want an OCF account? What do I get? How do I use OCF services? 6 | 7 | Access to computing by the students for the students! 8 | 9 | More specifically, we have a [list of services](/services). 10 | 11 | #### Who are you? 12 | 13 | The largest(\*) student organization on campus (\*by membership count). OCF is 14 | completely administered and operated by student volunteers ("staff"). [About the OCF](/about). 15 | 16 | Interested in [joining staff](/docs/staff/getinvolved/)? Feel free to attend our meetings 17 | or [contact us](/docs/internal/contact) by email. 18 | 19 | #### Where is the lab? What are the hours? 20 | 21 | See [lab](/docs/services/lab). 22 | 23 | #### How do I join the OCF and get an OCF account? 24 | 25 | See [join the OCF](/docs/internal/membership). 26 | 27 | #### How do I join [OCF staff](/docs/staff)? 28 | 29 | Check out [our staff recruitment website](/docs/staff/getinvolved/)! 30 | 31 | #### It's been a week since I requested an account, what happened! 32 | 33 | Accounts are typically processed immediately. If your account requires 34 | additional approval by staff, it may take a few days (usually less) to be 35 | manually approved. If this was the case, you will have been informed during 36 | account creation. 37 | 38 | In most cases when people think their account has not been created, the email 39 | landed in their spam folder. Check that first, or try to [[reset your password|change_password]] to see if your account has been created. 40 | 41 | #### I think I left something in the lab, can you tell me if it's there? 42 | 43 | **Please do not email us about items lost in the lab.** The front desk is 44 | staffed by paid employees, not by OCF volunteers. If you email us, the front 45 | desk staff _will not see it_. If you've lost something, you should instead stop 46 | by in-person to ask for it. 47 | 48 | #### I have an account. Does it expire? Will it still work? 49 | 50 | It should still work. Our current policy is to leave accounts alone after 51 | graduation. See [account](/docs/services/account). 52 | 53 | #### My account is disabled. Or, I want to disable or delete my account. 54 | 55 | See [account](/docs/services/account). 56 | 57 | #### I forgot my username or password. 58 | 59 | See [account](/docs/services/account). 60 | 61 | #### [Web hosting](/docs/services/web): How do I get group.berkeley.edu ([virtual hosting](/docs/services/vhost))? 62 | 63 | First, you need to have a group [account](/docs/internal/membership) and a working 64 | [website](/docs/services/web). Then, request [virtual hosting](/docs/services/vhost). 65 | 66 | #### [Email hosting](/docs/services/mail): How do I get @group.berkeley.edu ([virtual hosting](/docs/services/vhost))? 67 | 68 | First, set up regular [virtual hosting](/docs/services/vhost). 69 | Then, request [email virtual hosting](/docs/services/vhost/mail). 70 | 71 | #### [Printing](/docs/services/lab/printing): I have a printing question/problem. 72 | 73 | See [Printing](/docs/services/lab/printing). 74 | 75 | #### There is some content on your website I want removed. 76 | 77 | See our [content removal policy](/docs/services/account/content-removal). 78 | 79 | #### I need to talk to a human. 80 | 81 | See [contact](/docs/internal/contact). 82 | -------------------------------------------------------------------------------- /docs/internal/docs.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Official documents" 3 | --- 4 | 5 | Here are official documents relating to the Open Computing Facility. 6 | -------------------------------------------------------------------------------- /docs/internal/docs/archive.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Archived documents" 3 | --- 4 | 5 | Here are older versions of official documents. Documents under this section are 6 | no longer in force. 7 | -------------------------------------------------------------------------------- /docs/internal/docs/charter.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Charter" 3 | --- 4 | 5 | The OCF is an ASUC Chartered Program; the authoritative text of its charter can 6 | be found at [section 7 | 3204](https://docs.google.com/document/d/1bZhThJoNRUFOAX_gntXd4fgUSZkmfvCbOCr8p5Am75s/) 8 | of the ASUC bylaws. 9 | -------------------------------------------------------------------------------- /docs/internal/docs/operatingrules.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Operating Rules" 3 | --- 4 | 5 | The Operating Rules of the OCF consist of the Constitution and the Bylaws. The 6 | Constitution's provisions hold precedence over the Bylaws. 7 | 8 | - [Constitution of the Open Computing Facility](/docs/docs/operatingrules/constitution) 9 | - [Bylaws of the Open Computing Facility](/docs/docs/operatingrules/bylaws) 10 | -------------------------------------------------------------------------------- /docs/internal/docs/policies.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Policies" 3 | --- 4 | 5 | OCF Policies are established by the [OCF Decision Making Process](/docs/docs/operatingrules/constitution#ocf_decision_making_process). 6 | 7 | These are the current policies of the Open Computing Facility: 8 | 9 | - [Account policy](/docs/services/account/account-policies) 10 | - [Eligibility policy](/docs/membership/eligibility) 11 | - [Banning policy](/docs/membership/banning) 12 | - [Content removal policy](/docs/services/account/content-removal) 13 | - [Lab reservation policy](/docs/services/lab/lab-reservation-policy) 14 | - The printing quotas as documented on the 15 | [Printing](/docs/services/lab/printing) page 16 | - [Database policy](/docs/services/mysql#policies) 17 | - [Disk quota policy](/docs/services/shell#disk_quotas) 18 | - [Unattended processes policy](/docs/services/shell#unattended_processes) 19 | - [Virtual hosting policy](/docs/services/vhost#policies) 20 | 21 | There are also OCF policies which apply only to staff. These policies can 22 | be found at the [Staff policies](/docs/staff/policies) page. 23 | 24 | University policies additionally apply to the OCF. A list of the University's 25 | IT policies can be found [here][university-policy]. Some policies of note 26 | include: 27 | 28 | - [Computer Use Policy](https://security.berkeley.edu/computer-use-policy) 29 | - [Campus Online Activities Policy](https://security.berkeley.edu/campus-online-activities-policy) 30 | - [Electronic Communications Policy](https://security.berkeley.edu/electronic-communications-policy) 31 | 32 | [university-policy]: https://security.berkeley.edu/policy/policy-catalog 33 | -------------------------------------------------------------------------------- /docs/internal/membership.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Joining the OCF" 3 | --- 4 | 5 | ## Before you begin 6 | 7 | - Check the [membership eligibility](/docs/membership/eligibility) page to make 8 | sure you are eligible for an OCF account. For example, all currently-enrolled 9 | students and active student groups registered with the LEAD Center are 10 | eligible. 11 | 12 | - OCF accounts do not expire, so make sure you have not made an account in the 13 | past. If you have forgotten your account name or password, please do not 14 | request a new account. Instead, reset your [password](/docs/services/account). 15 | 16 | - We recommend that you choose a professional OCF account name. It is unlikely 17 | you will be able to change your account name after your request has been 18 | processed. For group accounts, your account name must be based on your 19 | group's name. 20 | 21 | ## Individual accounts 22 | 23 | - Individual accounts are associated with a single person and may not be 24 | shared. 25 | - Individual accounts are **not** eligible for [virtual hosting](/docs/services/vhost) except for faculty and staff accounts. 26 | - Individual accounts are eligible for [printing](/docs/services/lab/printing). 27 | 28 | **[[Request an account online|register]]** 29 | 30 | You will be prompted to log in with CalNet. Then follow the instructions to 31 | make your request. 32 | 33 | Feel free to [contact us](/docs/contact) if you experience difficulties in the 34 | request or you have questions. 35 | 36 | Then, wait for your account to be created. (below) 37 | 38 | ## Group accounts 39 | 40 | - Group accounts are associated with a group and may be shared by members of 41 | the group. 42 | - Group accounts are eligible for [virtual hosting](/docs/services/vhost). 43 | - Group accounts are **not** eligible for [printing](/docs/services/lab/printing). 44 | 45 | Follow this procedure to get a group account: 46 | 47 | 1. **Prepare appropriate documents and identification.** See the [membership eligibility](/docs/membership/eligibility) page for information on the 48 | documents and identification you will be asked to present for verification 49 | at the time you submit your account form. 50 | 51 | 2. **Have the authorized person come to [staff hours](/staff-hours).** For 52 | groups registered with the LEAD Center, that means a signatory. Otherwise, 53 | it's the person named in the documentation letter (and yes, you must bring 54 | documentation!). The account will be created during your visit. 55 | 56 | ## Account life 57 | 58 | We don't actively close accounts. You don't need to re-apply for a new account 59 | every semester, and you can still use your account after you graduate. 60 | 61 | Because the OCF is funded by students for student use, we cater our services to 62 | students, but it doesn't mean that your OCF account stops working after you 63 | stop being a student. However, we will occasionally make changes to our 64 | services based on the needs of current students and the abilities of current 65 | OCF staff, so we can't promise all OCF account privileges and services into 66 | perpetuity. 67 | -------------------------------------------------------------------------------- /docs/internal/membership/banning.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Banning policy" 3 | --- 4 | 5 | _As amended by the Board of Directors, December 3, 2018._ 6 | 7 | Any member of the OCF staff may propose to ban a user from the OCF for willful 8 | violation of OCF policies. Banned users may not enter the OCF lab or use any 9 | OCF services. 10 | 11 | Once a user is proposed to be banned, all staff with any involvement with the 12 | user will be called to the next Board of Directors meeting, and those present 13 | shall testify. The Board of Directors may then decide to ban the user with a ⅔ 14 | majority vote. If the violation of OCF policies is additionally a violation of 15 | the UC Berkeley Student Code of Conduct, the GM will submit a report to the 16 | Center of Student Conduct. 17 | 18 | If the user is banned, they shall be promptly notified of the ban and given a 19 | chance to appeal the ban at one of the next three future Board of Directors 20 | meetings. At that meeting, they will be asked to explain their actions. The 21 | Board of Directors then may decide with a ⅔ majority vote by secret ballot to 22 | uphold the ban; if the ban is not upheld, it shall be rescinded. 23 | -------------------------------------------------------------------------------- /docs/services/account/content-removal.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Content removal policy" 3 | --- 4 | 5 | _As promulgated by the SMs on April 10, 2017._ 6 | 7 | ## Introduction 8 | 9 | Most of the content on [www.ocf.berkeley.edu](https://www.ocf.berkeley.edu) 10 | is created and owned by OCF members, not the OCF itself. This user-generated 11 | content is not endorsed or supported by the OCF nor is the OCF responsible 12 | for content posted by OCF members. 13 | 14 | The OCF maintains a strict policy not to remove or modify data 15 | hosted by members unless legally compelled to do so, or if such 16 | data is in violation of existing OCF 17 | [account policies](/docs/services/account/account-policies). 18 | 19 | This means the OCF will not change or remove any text, pictures, 20 | information, or other data hosted by an OCF member. We do however 21 | reserve the right to deactivate inactive accounts at our discretion. 22 | 23 | ## Suggestions 24 | 25 | If you take issue with the content hosted on the website of an OCF user, 26 | the responsibility falls on you to resolve any conflict. 27 | 28 | We expect you to make a serious attempt to contact the owner of 29 | the content in question and request that they address your concern 30 | directly. You may try to find their contact information on their 31 | website or in the [University directory](//directory.berkeley.edu). 32 | If this fails, you may try to contact the owner by the contact email 33 | associated with their OCF account. If the website in question is 34 | `https://www.ocf.berkeley.edu/~username`, the contact address will be 35 | @ocf.berkeley.edu. 36 | 37 | If repeated attempts to contact the owner of the account have failed, 38 | you may [contact us](/docs/contact) and request the website be 39 | disabled due to inactivity. If we attempt to contact the website owner 40 | and fail to get a response, we may disable their account as per our 41 | [account policies](/docs/services/account/account-policies). 42 | 43 | However, if the website owner responds and refuses your removal request, 44 | the OCF cannot take any further action on your behalf unless the website 45 | is in violation of our 46 | [account policies](/docs/services/account/account-policies). If you believe 47 | this is the case, you may notify us of the exact policy you believe to have 48 | been breached, and if we determine the complaint to be valid, we will take 49 | appropriate action on our end. 50 | 51 | Please note that, if the above steps fail, the website is likely being 52 | maintained in compliance with our policies. There is nothing the OCF can 53 | do to change this outcome. Please do not assume that we support or endorse 54 | information posted by our members. 55 | 56 | ### DMCA considerations 57 | 58 | If you require content to be taken down under the DMCA for copyright reasons, 59 | you may send a DMCA takedown notice to the University, which will forward 60 | the request to us. Do not send any notices to the OCF directly; we can only 61 | act on them if they are sent to our designated agent. You must certify under 62 | penalty of perjury that your request is valid, that you are the rightsholder 63 | for the content in question, and that the use of the content does not fall 64 | under fair use exemptions to the DMCA. If you believe you have a valid DMCA 65 | claim against an OCF member, we suggest that you seek legal advice prior to 66 | filing a takedown notice. 67 | -------------------------------------------------------------------------------- /docs/services/lab.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Lab" 3 | --- 4 | 5 | Interested in reserving the lab, view our [Lab reservation policy](lab-reservation-policy/) 6 | 7 | For details about printing in the lab, see [Printing](printing/). 8 | 9 | ### Need help from an OCF staffer? 10 | 11 | OCF staff are student volunteers who are usually not present in the lab. 12 | 13 | The front desk staff can help with basic troubleshooting, but for technical or organization-related questions, it would be better to either chat with an OCF volunteer staffer during [staff hours](/staff-hours) or contact us via [email](/docs/internal/contact). 14 | 15 | ### Location 16 | 17 | The OCF computer lab is located in 171 MLK Student Union. It can be accessed through the main MLK building or via the tunnel by the stairs between Upper and Lower Sproul. 18 | 19 | Having trouble finding the entrance? Follow the video [here](https://fat.gfycat.com/DefiniteEquatorialAtlanticblackgoby.webm) starting from Upper Sproul. 20 | 21 | To enter the lab, **bring a valid student identification card; you will be asked to show it.** 22 | 23 | 24 | 25 | ### Hours 26 | 27 | Please note that our hours are all Berkeley Time, as the front desk staff are student employees and may have classes before opening times. 28 | 29 | | Day | Time | 30 | | :-------: | :--------: | 31 | | Sunday | **Closed** | 32 | | Monday | 9am–6pm | 33 | | Tuesday | 9am–8pm | 34 | | Wednesday | 9am–6pm | 35 | | Thursday | 9am–8pm | 36 | | Friday | 9am–6pm | 37 | | Saturday | 11am–6pm | 38 | 39 | ### Holidays/Adjusted Hours 40 | 41 | Current and future holidays are listed below. Note that holiday hours may change, so you should check back closer to the holiday. 42 | 43 | To Be Added 44 | 45 | ### More Info about the Lab 46 | 47 | The OCF computer lab consists of 29 workstations running [Debian Linux](https://www.debian.org/). They are maintained by [OCF volunteer staff](/about/staff/) who operate the servers, workstations, and networking gear that helps the lab run. 48 | 49 | The computer lab contains 3 scanners, 3 standing desks, and a Blu-ray/DVD/CD reader/writer. 50 | 51 | OCF computers include free and open-source software such as [LibreOffice](https://www.libreoffice.org/) (similar to Microsoft Office), [GIMP](https://www.gimp.org/) (similar to Adobe Photoshop), and more. 52 | -------------------------------------------------------------------------------- /docs/services/lab/printing.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Printing" 3 | --- 4 | 5 | The OCF offers a certain amount of printing to individual members. You don't 6 | have to request a new account each semester - the quota is refreshed at the 7 | start of each semester. 8 | 9 | Printing is currently limited to: 10 | 11 | - 200 pages per semester 12 | - 20 pages per day 13 | 14 | Please note: 15 | 16 | - Each **printed side** of a sheet counts as a page. 17 | - Jobs take time to process proportional to the job size. If you submit a 18 | large job, please be patient while the print server processes it. 19 | 20 | ## Remaining quota 21 | 22 | To see how many pages you have left for the day and semester, run the `paper` 23 | command [over the web|commands]] or [in the shell](/docs/services/shell). Print 24 | quota is also displayed at the top of the screen when using a lab computer. 25 | Check your print balance regularly! 26 | 27 | ## Printing refunds 28 | 29 | Pages are **not** normally refunded, except in cases of technical issues. In 30 | this case, you should talk with the OCF Operations Staff at the front desk 31 | for a refund. 32 | -------------------------------------------------------------------------------- /docs/services/mail.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Email" 3 | --- 4 | 5 | Email sent to your username @ocf.berkeley.edu (e.g. 6 | `username@ocf.berkeley.edu`) will be forwarded to a contact email address of 7 | your choosing. 8 | 9 | To configure a forwarding address, log in via [SSH](/docs/services/shell) and 10 | enter the `update-email` command to view or update your contact email address. 11 | 12 | Note that you are required to keep your contact address up-to-date for as long 13 | as you continue to use your account. While we do not proactively disable 14 | accounts without emails, if we need to contact you for any reason and cannot, 15 | your account will be disabled. This is true for both individual and group 16 | accounts. 17 | 18 | ## Student groups 19 | 20 | We provide email virtual hosting for student groups who have a [virtual host](/docs/services/vhost) (e.g. mygroup.berkeley.edu). See [here](/docs/services/vhost/mail) for instructions on requesting email hosting and 21 | configuring email addresses. 22 | 23 | ## Individual accounts 24 | 25 | Mail service for individual accounts was discontinued over summer 2014, but we 26 | are still offering email forwarding for individual accounts indefinitely. 27 | 28 | Note that sending mail from your individual OCF account is no longer possible. 29 | -------------------------------------------------------------------------------- /docs/services/mastodon.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Mastodon" 3 | --- 4 | 5 | Mastodon is a federated microblogging platform and social network. See the 6 | [official project homepage](https://joinmastodon.org/) for more information. 7 | 8 | The OCF operates a Mastodon instance, open to all members. To create an account, 9 | go to https://mastodon.ocf.berkeley.edu. Use `@ocf.berkeley.edu` as 10 | your email address (emails sent will be [forwarded](/docs/services/mail) to your 11 | Berkeley email), and use the same username as your OCF account. Note that 12 | Mastodon passwords are separate from OCF account passwords! 13 | 14 | ## Alternate usernames 15 | 16 | If you would like to use a username different from your OCF account username, 17 | email [help@ocf.berkeley.edu](mailto:help@ocf.berkeley.edu) to request a custom 18 | username. 19 | 20 | ## Rules 21 | 22 | See our [server rules](https://mastodon.ocf.berkeley.edu/about/more). 23 | -------------------------------------------------------------------------------- /docs/services/mirrors.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Software Mirrors" 3 | --- 4 | 5 | The OCF provides public mirrors of free and open-source software projects for 6 | anyone to use. These mirrors are available using any of the following protocols: 7 | 8 | - http: [http://mirrors.ocf.berkeley.edu/](http://mirrors.ocf.berkeley.edu/) 9 | - https: [https://mirrors.ocf.berkeley.edu/](https://mirrors.ocf.berkeley.edu/) 10 | - rsync: [rsync://mirrors.ocf.berkeley.edu/](rsync://mirrors.ocf.berkeley.edu/) 11 | 12 | We are also available at `mirrors.berkeley.edu` (HTTP only), as an alias for 13 | `mirrors.ocf.berkeley.edu`. 14 | 15 | To request for another project to be mirrored or to report a problem with our 16 | mirroring service, please [contact us](/docs/contact). 17 | 18 | ## Currently mirrored projects 19 | 20 | - [AlmaLinux](https://almalinux.org/) 21 | - [Alpine Linux](https://www.alpinelinux.org/) 22 | - [Apache Projects](https://www.apache.org/) 23 | - [Arch Linux](https://www.archlinux.org/) 24 | - [Arch Linux ARM](http://www.archlinuxarm.org/) 25 | - [Arch Linux CN](https://www.archlinuxcn.org/archlinux-cn-repo-and-mirror/) 26 | - [Artix Linux](https://www.artixlinux.org/) 27 | - [Blender](https://www.blender.org) 28 | - [CentOS and CentOS Stream](https://www.centos.org/) 29 | - [The Comprehensive R Archive Network](https://cran.r-project.org/) 30 | - [Debian](https://www.debian.org/) 31 | - [Devuan](https://www.devuan.org/) 32 | - [GNU ELPA](https://elpa.gnu.org/) 33 | - [Fedora](https://getfedora.org/) 34 | - [Finnix](https://www.finnix.org/) 35 | - [FreeBSD](https://www.freebsd.org/) 36 | - [Gentoo](https://www.gentoo.org/) 37 | - [GNU](https://www.gnu.org/) 38 | - [GNOME](https://www.gnome.org/) 39 | - [GIMP](https://www.gimp.org/) 40 | - [IPFire](https://ipfire.org) 41 | - [Kali Linux](https://www.kali.org/) 42 | - [KDE](https://www.kde.org/) 43 | - [Linux Mint](https://linuxmint.com/) 44 | - [Manjaro](https://manjaro.org/) 45 | - [MELPA](https://melpa.org/) 46 | - [MX Linux](https://mxlinux.org/) 47 | - [OpenBSD](https://www.openbsd.org/) 48 | - [OpenSUSE](https://www.opensuse.org/) 49 | - [OpenWRT](https://openwrt.org/) 50 | - [Parabola](https://www.parabola.nu/) 51 | - [Parrot Project](https://www.parrotsec.org/) 52 | - [Puppet](https://puppet.com/) 53 | - [Qt](https://www.qt.io/) 54 | - [Qubes-OS](https://www.qubes-os.org/) 55 | - [Raspbian](https://www.raspbian.org/) 56 | - [RPMFusion](https://rpmfusion.org/) 57 | - [Rocky Linux](https://www.rockylinux.org/) 58 | - [SageMath](https://www.sagemath.org/) 59 | - [Slackware](http://www.slackware.com/) 60 | - [Tails](https://tails.boum.org/) 61 | - [The Document Foundation](https://www.documentfoundation.org/) 62 | - [Trisquel](https://trisquel.info/) 63 | - [Ubuntu and ubuntu-ports](https://www.ubuntu.com/) 64 | - [VideoLAN](https://www.videolan.org/) 65 | -------------------------------------------------------------------------------- /docs/services/shell/commands.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Command Reference" 3 | --- 4 | 5 | ## Shell Interface 6 | 7 | Welcome to the live command reference! Here you can securely access our login server via [SSH](/docs/services/shell/#ssh) and run commands to manage your account, edit a website, or work on our server. Below is a list of account management commands with a brief description of what they do and how to use them. Simply type in a command and hit enter to run it. To log out, run the command `exit`. 8 | 9 |
10 | 13 |
14 | 15 | ## OCF commands 16 | 17 | **Key**: `ARGUMENT` `[optioanal]` 18 | 19 | | **Command** | **Description** | 20 | | :--------------------------------------------------: | :-------------------------------------------------------------------------------------------: | 21 | | `how SCRIPT` | Shows the source code for a script | 22 | | [`makehttp`](/docs/services/web/#h3_via-ssh) | Puts a shortcut to your web directory in your home folder | 23 | | [`makemysql`](/docs/services/mysql/#h3_ssh-terminal) | Generates a new random password for your database, creating the database if it does not exist | 24 | | `paper` | Shows how many pages you can currently print | 25 | | `update-email` | Prompts you to set a contact email address for your OCF account | 26 | 27 | ## File commands 28 | 29 | For convenience, here is a very basic listing of commands to manage files. For a more complete listing, see for example [Wikipedia](https://en.wikipedia.org/wiki/List_of_Unix_commands). For more information on a specific command, run `man COMMAND`. 30 | 31 | **Key**: `ARGUMENT` `[optioanal]` 32 | 33 | | **Command** | **Description** | 34 | | :-------------------: | :------------------------------------------------------------------------: | 35 | | `cd DIRECTORY` | Changes the current directory to a new one | 36 | | `cp [-r] SOURCE DEST` | Copies a file. The `-r` option allows for copying directories. | 37 | | `less FILE` | Lets you view the contents of a text file | 38 | | `ls [FILE]` | Lists information about files and directories | 39 | | `mkdir DIRECTORY` | Creates a new directory | 40 | | `nano FILE` | Lets you edit a text file with a basic interface | 41 | | `mv SOURCE DEST` | Moves or renames a file or folder | 42 | | `rm [-r] FILE` | Deletes a file. The `-r` option allows for deleting non-empty directories. | 43 | | `rmdir DIRECTORY` | Deletes an empty directory. Safer than `rm -r`. | 44 | -------------------------------------------------------------------------------- /docs/services/vhost/mail.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Mail virtual hosting for student groups" 3 | --- 4 | 5 | Our regular virtual hosting gives your group a website at 6 | `mygroup.berkeley.edu`. By contrast, _mail virtual hosting_ lets you create as 7 | many email addresses as you'd like `@mygroup.berkeley.edu`. 8 | 9 | These addresses can be used both to receive mail (via mail forwarding), and 10 | send mail. The details of how to use these addresses are below. 11 | 12 | ## Getting set up with mail virtual hosting 13 | 14 | By default, groups only have regular web virtual hosting. 15 | 16 | If you'd like to get started using mail virtual hosting, send us an email at 17 | [hostmaster@ocf.berkeley.edu](mailto:hostmaster@ocf.berkeley.edu) letting us 18 | know you'd like to enable email virtual hosting. Be sure to include both the 19 | domain name, and your OCF account name. 20 | 21 | Once your domain is configured for mail, head over to our [[mail virtual hosting page|vhost_mail]] to add and remove addresses. 22 | 23 | ## How sending and receiving mail works 24 | 25 | The OCF does not provide "true" mail hosting -- we do not store mail on our 26 | servers, nor do we provide a new mailbox for you to monitor. Instead, we 27 | provide: 28 | 29 | - Mail forwarding: forward emails sent to `xxxx@yourgroup.berkeley.edu` to an 30 | email address you already own. 31 | - Mail sending: send an email as `xxxx@yourgroup.berkeley.edu`. 32 | - Lightweight user management: create different email addresses and configure 33 | who to forward them to. 34 | 35 | Our admin panel looks like this: 36 | ![](https://i.fluffy.cc/9cGLcQv29G6kmlgvnvgq8J7nxw9BlMrx.png) 37 | 38 | We provide instructions for setting this up with Gmail below, but other email 39 | providers and clients offer similar options. 40 | 41 | #### How can I use Gmail to send and receive email? 42 | 43 | [We have an entire page about that — click here!](/docs/services/vhost/mail/gmail) 44 | 45 | #### How can I use an email client besides Gmail to send and receive email? 46 | 47 | There are too many email clients for us to provide instructions for, so here 48 | are the settings you'll need: 49 | 50 | - **SMTP server:** `smtp.ocf.berkeley.edu` 51 | - **Port:** 587 52 | - **Security:** TLS, verify cert 53 | - **Username:** The full email address, including domain name 54 | - **Password:** The password you set 55 | 56 | Note that we _only provide email sending_, so you only need to configure SMTP 57 | and not POP/IMAP. 58 | 59 | Good luck! 60 | 61 | #### What if I only want to receive and not send email? 62 | 63 | You can totally do that! Just set up an address to forward to and don't bother 64 | configuring the sending address. You can even leave the password blank. 65 | -------------------------------------------------------------------------------- /docs/services/vhost/mail/gmail.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Using Gmail with mail virtual hosting" 3 | --- 4 | 5 | **Note:** Your berkeley.edu address is really just a branded Gmail account, so 6 | these steps also work using your Berkeley email. You can use either a personal 7 | or Berkeley email for these steps. 8 | 9 | 1. **Make sure you can receive mail.** This must be done before you can start 10 | sending mail. 11 | 12 | From the [[mail hosting configuration page|vhost_mail]], create a new 13 | mailing address for yourself. Make sure it forwards to your Gmail account: 14 | 15 | ![](https://i.fluffy.cc/zBz5DtjQbDpR7nGDrZXJnNDrtPDkxtmR.png) 16 | 17 | Once this is done, try sending yourself an email at your new address and 18 | make sure you receive it. 19 | 20 | 2. **Set a password for the email.** From the same page as before, make sure 21 | you've set a secure password for the email address. 22 | 23 | This is the password you'll use when configuring Gmail to send as your 24 | account. 25 | 26 | 3. **From Gmail, go to the settings page and start adding a new address.** 27 | 28 | From your Gmail account, click on the settings wheel in the top-right 29 | corner, then click "Settings". 30 | 31 | At the top of the Settings page, click the tab that says "Accounts". 32 | 33 | From this page, click "Add another email address you own". 34 | 35 | 4. **Fill out the name and email.** 36 | 37 | In the window that opened, fill out the first section with your name and the 38 | full email address. It's important to use the same email as in step 1. 39 | 40 | ![](https://i.fluffy.cc/pp80jlHtz7M7CVvN2qBTpjc8sVBXLx42.png) 41 | 42 | After filling this in, click "Next Step". 43 | 44 | 5. **Fill out the SMTP server details.** 45 | 46 | Use the following settings: 47 | 48 | - **SMTP Server:** `smtp.ocf.berkeley.edu` 49 | - **Username:** The _full email address_, including 50 | `@mygroup.berkeley.edu` at the end. 51 | - **Password:** The password you chose in step 2. 52 | - **Port:** 587 (the default) 53 | - **Secured connection:** Using TLS (the default) 54 | 55 | It should look roughly like this: 56 | 57 | ![](https://i.fluffy.cc/Zk7LNFs9Brh2vn1vLnlCH2JbHqWQ6mln.png) 58 | 59 | Click "Add Account" when done. 60 | 61 | 6. **Verify the address.** 62 | 63 | You'll now be sent an email with a link to click to verify the address. This 64 | should have arrived at the same Gmail account. 65 | 66 | Click the link in that email and you're good to go! 67 | 68 | From now on, when sending email via Gmail, you'll have a drop-down menu which 69 | lets you select the "From" address, like this: 70 | 71 | ![](https://i.fluffy.cc/NlrKSbQG16MM6H2K6ZZF4l26D1pGBgjx.png) 72 | 73 | If you use the Gmail app on your iPhone or Android device, you'll be able to 74 | select the From address there as well. 75 | 76 | **Having trouble with the above steps?** If you're stuck and can't figure out 77 | what's wrong, feel free to [drop by our staff hours](/staff-hours) for 78 | in-person help! 79 | 80 | As a last resort, you can also [email us](/docs/contact) for assistance. If you 81 | do this, please provide as much detail as possible, including screenshots, the 82 | email you're trying to use, and the steps you took. (But please _do not_ send 83 | us your password!) 84 | -------------------------------------------------------------------------------- /docs/services/web.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Web hosting (personal)" 3 | --- 4 | 5 | All accounts include hosting with a web address at: 6 | 7 | - **`https://www.ocf.berkeley.edu/~user`** (canonical version) 8 | - **`https://ocf.io/user`** (shorter version) 9 | 10 | where `user` is the account name. 11 | 12 | Groups, faculty, and staff may also request a [virtual host](/docs/services/vhost) for another domain (e.g., group.berkeley.edu). 13 | 14 | ## Uploading Files 15 | 16 | Upload files to your web space the same way you [upload files to your OCF account](/docs/services/shell) (typically SFTP if used remotely). The only 17 | difference is that files for your web space are placed in your `public_html` 18 | directory. 19 | 20 | ## Additional details 21 | 22 | The web server runs Apache 2.4 with FastCGI (mod_fcgid) and suEXEC. 23 | Access and error logs are accessible in `/opt/httpd` using [SSH](/docs/services/shell). 24 | 25 | The web server itself runs as a dedicated user. If your .htaccess file is not 26 | world-readable (e.g., `chmod 644`), the web server will return the error "401 27 | Forbidden". 28 | 29 | PHP/CGI/FastCGI scripts are executed as your user, so they do not need to be 30 | world-readable. If they contain sensitive information (such as database 31 | passwords), you should make them private (e.g., `chmod 600` or `chmod 700`). 32 | 33 | Both individual hosting and student group hosting are done entirely over HTTPS. 34 | 35 | ### Supported languages 36 | 37 | - PHP 7.0.33 38 | - Perl 5.24.1 39 | - Python 2.7.13, and 3.5.3; Django 1.10.7; Flask 0.12.1 40 | - Ruby 2.3.3; Rails 4.2.7.1 41 | - NodeJS 4.8.2 42 | 43 | Other flavors of the day may work but are not currently supported. We may be 44 | able to install additional packages on request, but will generally advise you 45 | to use alternatives instead (such as installing in a virtualenv or inside your 46 | home directory). 47 | 48 | ## FAQ 49 | 50 | ### My `public_html` directory is missing, how do I fix that? 51 | 52 | We automatically create the `public_html` symlink for all new accounts, but 53 | it's possible that it was accidentally removed (or that you have an older 54 | account from before we started the practice). 55 | 56 | Keep in mind that just recreating the directory is _not_ sufficient; it must be 57 | a symbolic link to your actual web space. If you simply make a directory named 58 | `public_html`, it won't be used for your website. 59 | 60 | Here are two easy ways to re-create the symlink: 61 | 62 | #### via the web interface 63 | 64 | 1. Open the [[web commands interface|commands]] in your web browser. 65 | 2. Select the "makehttp" option. Enter your OCF username and password, and 66 | choose "Run command". You should see something like this in the output, 67 | assuming you entered your username and password correctly: 68 | 69 | public_html folder has been created successfully. 70 | 71 | #### via SSH 72 | 73 | 1. Login to your account via [SSH](/docs/services/shell). 74 | 2. After you go past all system messages, you will see prompt: 75 | 76 | tsunami$ 77 | 78 | At this prompt, type `makehttp`. This command will create your web 79 | directory. Here's a sample screen output: 80 | 81 | tsunami$ makehttp 82 | public_html folder has been created successfully. 83 | -------------------------------------------------------------------------------- /docs/services/web/php.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "PHP" 3 | --- 4 | 5 | `death`, the OCF webserver, currently runs PHP 7.0 with the following 6 | non-standard packages installed: 7 | 8 | - [APCu](https://www.php.net/manual/en/book.apcu.php) (opcode caching) 9 | - [BC Math](https://www.php.net/manual/en/book.bc.php) (arbitrary precision math) 10 | - [Bzip2](https://www.php.net/manual/en/book.bzip2.php) (compression library) 11 | - [cURL](https://www.php.net/manual/en/book.curl.php) (networking library) 12 | - [DBA](https://www.php.net/manual/en/book.dba.php) (database connector) 13 | - [GD](https://www.php.net/manual/en/book.image.php) (graphics library) 14 | - [MB String](https://www.php.net/manual/en/book.mbstring.php) (string encoding) 15 | - [Mcrypt](https://www.php.net/manual/en/book.mcrypt.php) (cryptography library) 16 | - [MySQL](https://www.php.net/manual/en/book.mysqli.php) (database connector) 17 | - [SQLite](https://www.php.net/manual/en/book.sqlite.php) (database connector) 18 | - [SOAP](https://www.php.net/manual/en/book.soap.php) (messaging protocol library) 19 | - [XML](https://www.php.net/manual/en/book.xml.php) (markup parsing library) 20 | - [ZIP](https://www.php.net/manual/en/book.zip.php) (compression library) 21 | 22 | For a full list of available modules, run `phpinfo()` from a PHP script. 23 | Plase [contact us](/docs/contact) if you are missing a module that you need 24 | installed to get your application running. 25 | 26 | ## Custom PHP settings 27 | 28 | If the default PHP settings are problematic for your site (for example, if you 29 | require larger than normal file uploads), you can customize the PHP settings 30 | used by creating [a `.user.ini` file][.user.ini] inside your web root. 31 | 32 | In order to maintain compatibility with the OCF's PHP settings, we highly 33 | recommend _not_ copying an entire `php.ini`\* or `.user.ini` file from the web 34 | or from another server. Instead, we advise you to create an empty `.user.ini` 35 | and add only the settings you wish to change. 36 | 37 | Note that `.user.ini` filename should be used, as our webserver will not look 38 | for (per-user) `php.ini` files. 39 | 40 | ### Example `.user.ini` file 41 | 42 | The following file, located at `~/public_html/.user.ini`, is an example of a 43 | good `.user.ini` file. 44 | 45 | ; raise max upload and POST sizes 46 | upload_max_filesize = 32M 47 | post_max_size = 32M 48 | 49 | ; raise maximum number of input variables 50 | max_input_vars = 20000 51 | 52 | [.user.ini]: https://secure.php.net/manual/en/configuration.file.per-user.php 53 | -------------------------------------------------------------------------------- /docs/services/webapps/nodejs.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Node.js" 3 | --- 4 | 5 | **Note: This document only applies to student groups with virtual hosts who 6 | have applied for apphosting. For normal user accounts or for groups without 7 | apphosting, you'll want to host with FastCGI instead.** 8 | 9 | You will want to deploy your application using nvm so that you can easily 10 | install and manage dependencies and versions. 11 | 12 | ## Setting up nvm 13 | 14 | 1. Create a directory for your app to live in: 15 | 16 | mkdir -p ~/myapp 17 | cd ~/myapp 18 | 19 | 2. Install nvm in your home directory. Note that `nvm` is terrible and will 20 | modify your shell config files without asking. But maybe that's what you 21 | want? 22 | 23 | Go find the latest version from [the NVM GitHub][nvm-github], and copy the 24 | nasty one-liner straight into your shell to install it. At the time of 25 | writing, it looks like this: 26 | 27 | curl -o- https://raw.githubusercontent.com/creationix/nvm/v0.33.0/install.sh | bash 28 | 29 | Go ahead and run it, and close/re-open your terminal as it suggests. 30 | 31 | 3. Install whatever version of Node.js you want. 32 | 33 | nvm install 6 34 | nvm alias default 6 35 | 36 | 4. Copy your code to `~/myapp/src` or similar, and install any dependencies 37 | using `npm`. 38 | 39 | ## Preparing your app to be supervised 40 | 41 | Create a file at `~/myapp/run` with content like: 42 | 43 | #!/bin/bash -e 44 | USER="$(whoami)" 45 | [ -e "/srv/apps/$USER/$USER.sock" ] && rm "/srv/apps/$USER/$USER.sock" 46 | umask 0 47 | 48 | . ~/.nvm/nvm.sh 49 | NODE_ENV=production PORT="/srv/apps/$USER/$USER.sock" \ 50 | exec ~/myapp/src/bin/www 51 | 52 | Replace `~/myapp/src/bin/www` with the path to your app, then make `run` 53 | executable: 54 | 55 | chmod +x ~/myapp/run 56 | 57 | Test executing the run script. You should be able to access your website while 58 | running it (or see any errors in your terminal). 59 | 60 | ## Supervise your app with systemd 61 | 62 | Cool, your app works. [Set up systemd](/docs/services/webapps#supervise) to 63 | supervise your app (so that it starts and restarts automatically). 64 | 65 | ## Suggestions/improvements? 66 | 67 | If you have a better way to host Node.js-based apps on the app server (or a 68 | suggestion for how we could improve this documentation), [send us an email](/docs/contact)! 69 | 70 | [nvm-github]: https://github.com/creationix/nvm 71 | -------------------------------------------------------------------------------- /docs/services/webapps/python.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Python (Django, Flask, etc.)" 3 | --- 4 | 5 | **Note: This document only applies to student groups with virtual hosts who 6 | have applied for apphosting. For normal user accounts or for groups without 7 | apphosting, you'll want to host with FastCGI instead. See our instructions for 8 | [Django](/docs/services/web/django) or [Flask](/docs/services/web/flask).** 9 | 10 | You will want to deploy your application using a virtualenv so that you can 11 | easily install and manage dependencies and versions. 12 | 13 | ## Setting up a virtualenv 14 | 15 | 1. Create a directory for your app to live in: 16 | 17 | mkdir -p ~/myapp 18 | cd ~/myapp 19 | 20 | 2. Set up a virtualenv: 21 | 22 | virtualenv venv 23 | 24 | 3. Activate the virtualenv: 25 | 26 | . venv/bin/activate 27 | 28 | You should do this step every time before running your app or managing 29 | installed packages. 30 | 31 | 4. Copy your code to `~/myapp/src` or similar, and install any dependencies 32 | using `pip`. 33 | 34 | ## Installing gunicorn 35 | 36 | We recommend using gunicorn to serve your application. After activating your 37 | virtualenv, install it with `pip install gunicorn`. 38 | 39 | Note that you may see a warning about a syntax error. As long as the output 40 | ends in "Successfully installed gunicorn", [it's safe to ignore 41 | this][lol-syntax]. 42 | 43 | ## Preparing your app to be supervised 44 | 45 | Create a file at `~/myapp/run` with content like: 46 | 47 | #!/bin/bash -e 48 | . ~/myapp/venv/bin/activate 49 | PYTHONPATH=~/myapp/src:$PYTHONPATH \ 50 | exec gunicorn -w 2 -b unix:/srv/apps/$(whoami)/$(whoami).sock \ 51 | --log-file - main:app 52 | 53 | Replace `main:app` with the module containing the app, and name of your app, 54 | then make `run` executable: 55 | 56 | chmod +x ~/myapp/run 57 | 58 | Test executing the run script. You should be able to access your website while 59 | running it (or see any errors in your terminal). 60 | 61 | ## Supervise your app with systemd 62 | 63 | Cool, your app works. [Set up systemd](/docs/services/webapps#supervise) to 64 | supervise your app (so that it starts and restarts automatically). 65 | 66 | ### Bonus Gunicorn tip: reloading your app 67 | 68 | Gunicorn will reload your app if you send it SIGHUP. You can teach systemd that 69 | fact by adding the following line under `[Service]` in your systemd unit file: 70 | 71 | ExecReload=/bin/kill -HUP $MAINPID 72 | 73 | and then running `systemctl --user daemon-reload`. After that, you can use 74 | `systemctl` to reload your app: 75 | 76 | systemctl --user reload myapp 77 | 78 | ## Suggestions/improvements? 79 | 80 | If you have a better way to host Python-based apps on the app server (or a 81 | suggestion for how we could improve this documentation), [send us an email](/docs/contact)! 82 | 83 | [lol-syntax]: https://stackoverflow.com/a/25611194 84 | -------------------------------------------------------------------------------- /docs/services/webhostingsolutions.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "What type of web hosting do I need?" 3 | --- 4 | 5 | The OCF offers two main types of hosting, personal hosting and group hosting. If you have a personal account (which most people do unless you have specifically requested a group account), then your only option is personal hosting. If you have a group account for a Registered Student Organization, then you have a couple options for your hosting solutions, which are listed in the group hosting section. 6 | 7 | ## Hosting your personal site 8 | 9 | See [personal hosting documentation](/docs/services/web/) to get started! 10 | 11 | ## Hosting your group's site 12 | 13 | You should start with our [virtual hosting documentation](/docs/services/vhost/) if you are just getting started with group hosting at the OCF. If you have applied and been approved for application hosting, head over to the [app hosting documentation](/docs/services/webapps/). 14 | -------------------------------------------------------------------------------- /docs/services/xmpp.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "XMPP" 3 | --- 4 | 5 | XMPP (formerly Jabber) is a federated chat protocol. All OCF members can get an 6 | XMPP account with JID `username@ocf.berkeley.edu`. Our server supports most 7 | modern XEPs, including end-to-end encrypted chats with OMEMO. 8 | 9 | XMPP accounts are currently available upon request. If you are interested, email 10 | [help@ocf.berkeley.edu](mailto:help@ocf.berkeley.edu) with your OCF username. 11 | -------------------------------------------------------------------------------- /docs/staff/backend.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Infrastructure" 3 | --- 4 | 5 | Many parts of the OCF are not exposed to users. This section will shed light on 6 | some of those details. 7 | -------------------------------------------------------------------------------- /docs/staff/backend/firewall.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "External firewall" 3 | --- 4 | 5 | We use a Palo Alto Networks (PAN) firewall provided by IST. We have one network 6 | port in the server room which is activated and behind the firewall; we have 7 | another network port activated in the lab behind the television which is also 8 | behind the firewall. All the ports the desktops use are also behind the 9 | firewall since they are routed through the switch in the server room. 10 | 11 | ## Administering the firewall 12 | 13 | ### Accessing the interface 14 | 15 | Administration of the firewall is done through the [web interface][panorama], 16 | and must be done from an on-campus IP address (for instance through the 17 | [library VPN][library-vpn] or SOCKS proxying through an OCF host). **Remember 18 | to specify https when loading the firewall admin page**, as it does not have a 19 | redirect from http to https. If you are having connection issues with the 20 | firewall admin page loading indefinitely, it is likely because you are trying 21 | to use http or trying to access it from an off-campus IP. To quickly set up a 22 | SOCKS proxy, run `ssh -D 8000 -N supernova` from any off-campus host and then 23 | set up the SOCKS proxy (through your OS or through your browser's settings) to 24 | use the proxy on `localhost` and port `8000`. 25 | 26 | [panorama]: https://panorama.net.berkeley.edu 27 | [library-vpn]: https://www.lib.berkeley.edu/using-the-libraries/vpn 28 | 29 | To sign in to administer the firewall, make sure to use the single sign-on 30 | (SSO) option, and it will ask for CalNet authentication. 31 | 32 | ### Policies 33 | 34 | All our current policies are located in the "Pre Rules" section under 35 | "Security" in the policies tab. This option should be right at the top in the 36 | box on the left side of the page. It contains all our rules since we are only 37 | blocking traffic (either outgoing or incoming) before it goes through the 38 | firewall, so all we need are pre rules. 39 | 40 | In general the interface is pretty self-explanatory. Each rule has a custom 41 | name and a description that describes what kind of traffic it should be 42 | blocking or letting through, as well as the source and destination addresses 43 | (or groups of addresses), application (identified by the firewall), service 44 | (port), and whether it is allowed or blocked. Each rule has a dropdown next to 45 | the rule name if you hover over it that leads to the log viewer, where you can 46 | see what kind of traffic matched each rule and when the traffic was 47 | allowed/blocked. 48 | 49 | Any changes made to the firewall policies need to be committed and pushed to 50 | the firewall using the commit button and then the push button (or the commit 51 | and push button to do it in one step) located in the top right. 52 | 53 | ### Syslog 54 | 55 | When we switched over to the new PAN firewall, syslog was set up to send 56 | messages to `syslog.ocf.berkeley.edu`, however it is only configured to send 57 | logs there over TLS, so currently it is failing. 58 | -------------------------------------------------------------------------------- /docs/staff/backend/mail.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Mail" 3 | --- 4 | 5 | **anthrax** is our mail server. It is used for sending and receiving all OCF 6 | mail, excluding staff use of Google Apps. Mail sent by users, websites, virtual 7 | hosts, or basically anything else goes through here. 8 | 9 | Received mail to @ocf.berkeley.edu is forwarded to the address in the `mail` 10 | attribute of the LDAP account entry (or the [aliases table](https://github.com/ocf/puppet/blob/master/modules/ocf_mail/files/site_ocf/aliases)) 11 | or rejected; nothing is stored. 12 | 13 | Received virtual host mail is forwarded to the address stored in a MySQL 14 | table. Outgoing virtual host mail is also via anthrax, which uses SMTP 15 | authentication (passwords checked against `crypt(3)`'d passwords in a MySQL 16 | table). [There's a whole page with more details about vhost mail.](/docs/staff/backend/mail/vhost) 17 | 18 | Mail originating anywhere inside the OCF relays through anthrax. 19 | 20 | ## External relations 21 | 22 | We maintain relations with external groups for two reasons. 23 | 24 | 1. To monitor our mail server reputation and prevent outgoing mail from being 25 | blocked by external service providers. 26 | 2. To monitor abuse and disable compromised accounts. 27 | 28 | When our IP addresses change, we need to update our registrations. 29 | 30 | We have [feedback 31 | loops](https://en.wikipedia.org/wiki/Feedback_loop_%28email%29) with 32 | 33 | - AOL (out-of-date) 34 | - Comcast (out-of-date) 35 | - Cox (out-of-date) 36 | - FastMail (out-of-date) 37 | - Microsoft (Junk Email Reporting Agreement, 2013-03-06) (out-of-date) 38 | - Rackspace (out-of-date) 39 | - RoadRunner (out-of-date) 40 | - Yahoo (out-of-date) 41 | 42 | We are whitelisted by 43 | 44 | - AOL (out-of-date) 45 | - [DNSWL](https://www.dnswl.org/s/?s=berkeley.edu) (out-of-date) 46 | - Verizon (out-of-date) 47 | 48 | We are also registered with 49 | 50 | - [abuse.net](https://www.abuse.net/lookup.phtml?domain=ocf.berkeley.edu) 51 | - SpamCop (ISP account set to receive summary reports) 52 | -------------------------------------------------------------------------------- /docs/staff/backend/mail/vhost.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Virtual hosted mail" 3 | --- 4 | 5 | **Note: This page is designed for OCF staffers and is a technical description 6 | of the service. For information or help using it, see [our page about it](/docs/services/vhost/mail).** 7 | 8 | Virtual hosting mail allows groups to receive mail at `@group.b.e` addresses, 9 | and send from those same addresses. It complements our web hosting nicely. 10 | 11 | ## Features 12 | 13 | - Each user has mail forwarding. 14 | 15 | - Each virtual user can have its own password (not the same as the account 16 | password). If a user doesn't have a password set, then they can receive mail 17 | but not send it. 18 | 19 | - [[Simple admin panel|vhost_mail]] built into ocfweb for admins to set 20 | passwords for emails. It might also be cool if you could change your own 21 | password (without having the group password), but that's not currently 22 | possible. 23 | 24 | ## Technical implementation 25 | 26 | There is a database on our MySQL host for storing email vhost information. It 27 | has one table, `addresses`, with columns for the incoming address, password, 28 | and forwarding addresses (among others). 29 | 30 | It has one view, `domains`, which is generated from the `addresses` table. This 31 | is only used to make the queries Postfix makes simpler. In particular, you 32 | never need to update MySQL to add forwarding to a domain; it's entirely based 33 | on `~staff/vhost/vhost-mail.conf`. 34 | 35 | ocflib has simple functions for interacting with this database (see `pydoc3 ocflib.vhost.mail`). 36 | 37 | We use MySQL lookup tables on the mail host to dynamically look up the list of 38 | virtual domains (using the `domains` view), and the addresses (using the 39 | `addresses` table). 40 | 41 | For sending, we use pam-mysql to authenticate SMTP sessions before allowing 42 | clients to send as a vhost address. (See `/etc/pam.d/smtp` and 43 | `/etc/pam-mysql.conf` on anthrax). 44 | 45 | ## How do I add mail hosting to a group? 46 | 47 | See [here](/docs/staff/procedures/vhost#mail). 48 | -------------------------------------------------------------------------------- /docs/staff/backend/munin.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Munin" 3 | --- 4 | 5 | **NOTE:** We are currently in the process of migrating many of our monitoring services to Prometheus. For more information, visit the documentation page for Prometheus [here](/docs/staff/backend/prometheus). 6 | 7 | We use [Munin](https://munin.ocf.berkeley.edu) to provide real-time monitoring 8 | of our hardware. The master is [dementors](/docs/staff/backend/servers) which 9 | runs a cron job every five minutes to collect data from the node server running 10 | on each machine. A [custom script][gen-munin-nodes] periodically generates the 11 | list of available nodes from LDAP. 12 | 13 | We monitor servers, desktops, and staff VMs, but not the hozer boxes. 14 | Additionally, we don't receive email alerts for staff VMs. 15 | 16 | ## Automated alerts 17 | 18 | Munin sends mail to root whenever certain stats run out of bounds for a 19 | machine, e.g. if disk usage goes above 92%. Some plugins have configurable 20 | warning and critical levels for each field, which are usually set in the node 21 | config like so: 22 | 23 | ``` 24 | [pluginname] 25 | env.fieldname_warning min:max 26 | env.fieldname_critical min:max 27 | ``` 28 | 29 | The warning bounds for each node are generated from a Puppet template in the 30 | `ocf` module using machine specs from facter. While config files use 31 | underscores, the display name for a variable's warning levels takes the form 32 | `fieldname.warning` or `fieldname.critical`. 33 | 34 | When `munin-limits` finds a variable in warning or critical range, it pipes the 35 | alert text to [another script][mail-munin-alert] which filters out 36 | uninteresting or noisy messages and emails the rest to root. Munin itself isn't 37 | very flexible about disabling alerts from plugins, so, if there is a noisy 38 | variable you want to ignore alerts for, you can add it to the list of 39 | `IGNORED_WARNINGS`. 40 | 41 | ## Custom plugins 42 | 43 | We provide a Puppet class, `ocf::munin::plugin`, which installs a custom Munin 44 | plugin to a machine, for example, to monitor the number of players on our CS:GO 45 | server. Writing a plugin is very easy, should you need to do so. When called 46 | without arguments, it should print to standard output a list of variable names 47 | and values: 48 | 49 | ``` 50 | field1.value 51 | field2.value 52 | ... 53 | ``` 54 | 55 | When given the lone argument `config`, it should print display information for 56 | Munin graphs and variable warning levels: 57 | 58 | ``` 59 | graph_title Title 60 | graph_vlabel yaxis 61 | graph_scale no 62 | field1.label label 63 | field1.warning min:max 64 | ... 65 | ``` 66 | 67 | [gen-munin-nodes]: https://github.com/ocf/puppet/blob/master/modules/ocf_munin/files/gen-munin-nodes 68 | [mail-munin-alert]: https://github.com/ocf/puppet/blob/master/modules/ocf_munin/templates/mail-munin-alert.erb 69 | [ocf_munin_plugin]: https://github.com/ocf/puppet/blob/master/modules/ocf/manifests/munin/plugin.pp 70 | -------------------------------------------------------------------------------- /docs/staff/backend/puppet.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Puppet" 3 | --- 4 | 5 | The puppetmaster is [lightning](/docs/staff/backend/servers). Instructions on 6 | making, testing, and deploying changes to Puppet are located at the [Git 7 | repository](https://github.com/ocf/puppet) on GitHub. 8 | -------------------------------------------------------------------------------- /docs/staff/i3wm.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "i3wm" 3 | --- 4 | 5 | `i3wm` or `i3` is is a tiling window manager we use on `tornado`, which is the computer behind the ocf tv. 6 | To learn how to access the ocf tv, see [ocf-tv](/docs/staff/scripts/ocf-tv). A tiling window manager is 7 | a window manager that breaks the screen into different tiles, and places applications into these tiles, 8 | which are normally controlled by keyboard shortcuts instead of by dragging and dropping. 9 | -------------------------------------------------------------------------------- /docs/staff/mailing-lists.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Staff mailing lists" 3 | --- 4 | 5 | ## Mailing lists 6 | 7 | There are several mailing lists used internally by staff. Append 8 | `@ocf.berkeley.edu` to the end of each mailing list. 9 | 10 | All staffers are automatically added to the following two mailing lists: 11 | 12 | - `staff`: For staff announcements, such as meeting times and events. 13 | - `wheel`: For technical discussion among all staff 14 | 15 | Staffers can also choose to be further added to the following mailing lists. 16 | Technical Managers are required to join them: 17 | 18 | - `rt`: Emails sent to Request Tracker are copied to this mailing list. If 19 | you are on the `rt` mailing list, you can reply to RT tickets from your 20 | email. You are highly encouraged to join this mailing list even if you're 21 | not root staff. 22 | - `root`: Miscellaneous messages from system daemons are sent here: 23 | 24 | - Cron daemons send mail containing any stdout/stderr output from cronjobs 25 | - [Jenkins][jenkins] sends emails whenever a Jenkins build fails 26 | - ocflib sends emails whenever an uncaught exception is thrown in ocfweb, 27 | create, enforcer, and several other background tasks 28 | - Miscellaneous other emails are sent here 29 | 30 | This mailing list gets a median of ~10 messages every day, although on some 31 | days it can get a lot more. 32 | 33 | - `puppet`: Error messages from puppet runs go here. This list tends to be 34 | very noisy. 35 | - `mon`: Monitoring alerts are sent here: 36 | - [Rackspace Cloud Monitoring][rackspace] emails us alerts when our 37 | important services are inaccessible from outside the OCF network. 38 | - [Munin][munin] sends mail whenever some munin measurement (e.g. disk 39 | usage, RAM usage, etc.) is outside the normal range. 40 | - [Prometheus][prometheus] sends mail for alerts, similar to Munin. 41 | - `extcomm`: A compilation of technical mailing lists for upstream projects 42 | and projects we mirror. 43 | 44 | On the administrative side, the `officers` mailing list receives emails related 45 | to OCF administrivia. Cabinet members are expected to be on this mailing list, 46 | and any other staffer can audit it as well. 47 | 48 | Operations Staff are added to the `opstaff` mailing list. 49 | 50 | 51 | 52 | 53 | 54 | There are also some special purpose mailing lists: 55 | 56 | - `ocf@lists.berkeley.edu` ([ocf.io/announce][announce]): we add emails from 57 | Calapalooza tabling to this mailing list, and send out announcements about 58 | staff meetings here. We use a Berkeley mailing list here to let non-OCF 59 | members sign up for it. 60 | 61 | This mailing list should be cleared every fall. 62 | 63 | [announce]: https://ocf.io/announce 64 | [jenkins]: https://jenkins.ocf.berkeley.edu/ 65 | [rackspace]: https://intelligence.rackspace.com/login 66 | [munin]: https://munin.ocf.berkeley.edu/ 67 | [prometheus]: https://prometheus.ocf.berkeley.edu/ 68 | -------------------------------------------------------------------------------- /docs/staff/policies.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Staff policies" 3 | --- 4 | 5 | In this section are policies specially applying to staff. All staffers should 6 | read and be aware of these policies. 7 | 8 | - [Staff policy](/docs/staff/policies/staff-policy) 9 | - [Keycard policy](/docs/staff/policies/keycard) 10 | - The [restarting services procedure](/docs/staff/procedures/restarting-services) 11 | 12 | OCF staff should also familiarize themselves with the 13 | [University's IT Policies](https://security.berkeley.edu/policy/policy-catalog). 14 | The following policies are primarily applicable to staff: 15 | 16 | - [Campus Information Technology Security Policy](https://security.berkeley.edu/campus-information-technology-security-policy) 17 | - [Departmental Security Contact Policy](https://security.berkeley.edu/departmental-security-contact-policy) 18 | - [DNS Policy](https://security.berkeley.edu/domain-name-system-dns-service-policy) 19 | - [Minimum Security Standards for Networked Devices](https://security.berkeley.edu/minimum-security-standards-networked-devices) 20 | -------------------------------------------------------------------------------- /docs/staff/policies/keycard.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Keycard policy" 3 | --- 4 | 5 | _As promulgated by the GMs on August 18, 2017._ 6 | 7 | ## Keycard access 8 | 9 | Keycard access is given much like root, but requires approval from both GMs and 10 | SMs. 11 | 12 | To be eligible for keycard access, you must fulfill the following criteria: 13 | 14 | - A Site Manager/General Manager must be able to recognize you in person 15 | - You must have been a staffer for at least a year already, but this may be 16 | waived at the discretion of the GM/SM 17 | - You must demonstrate a concrete, actual need for keycard privileges and 18 | concrete examples of helpful activity in the OCF 19 | 20 | Keycard access, once given, can be revoked at the discretion of SMs or GMs. 21 | 22 | ## After hours policy 23 | 24 | Staffers with keycard access to the lab are free to enter and leave as they 25 | please. In contrast, staffers without keycard access may only be in the lab 26 | when there is someone with keycard access in the lab as well. More 27 | specifically, no staffer without keycard access is permitted within the lab if 28 | there is no one with keycard also within the lab as well. As circumstances may 29 | result in staffers with keycard having to step out of the lab for short periods 30 | of time, a general rule of thumb will be that if those with keycard will return 31 | in a 30 minute time frame, non-keycarded staffers are free to stay. 32 | 33 | OCF staffers are permitted to bring in as many guests after hours as is 34 | considered reasonable. Note that this is not a right, but a privilege and as 35 | such can be revoked if SMs/GMs feel that guests are being disruptive. Any 36 | non-staffer in the lab after hours must be logged in the OCF guest sign-in 37 | sheet, and failure to do so may be considered abuse of keycard privileges. 38 | 39 | ## Abuse of privileges 40 | 41 | Failure to abide with the policies described above will be defined as abuse of 42 | keycard privileges. Since there is no good way to formalize disciplinary 43 | actions as severity of infractions can range from simple forgetfulness to 44 | full-fledged theft, abuse may result in consequences including, but not limited 45 | to, loss of root privileges, being banned from the OCF, and/or being referred 46 | to the Office of Student Conduct or University Police. 47 | 48 | ## Amendments to this policy 49 | 50 | This policy can only be amended by Cabinet consensus (or by BoD). 51 | 52 | Staffers must promptly be made aware of any amendments to this policies. 53 | -------------------------------------------------------------------------------- /docs/staff/policies/lab-reservation-policy.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Lab reservation policy (staff expectations)" 3 | --- 4 | 5 | _As promulgated by the GMs on November 06, 2017_ 6 | 7 | Should the OCF lab be closed for the event requested, OCF staff (excluding 8 | those at the front desk) should remain outside the OCF lab during the time 9 | requested. Those at the front desk will continue to require that Cal ID’s be 10 | shown to gain access to the OCF. However, should Staff also agree to respond to 11 | all student group requests within one week and one day of their form submission 12 | as it will need to be approved by the OCF’s Board of Directors. 13 | 14 | It is likely that requests will be accepted that follow some base rules. 15 | Firstly, the person who registers for the group MUST be a signatory of the 16 | organization wishing to reserve the lab. In addition, the lab should not be 17 | reserved for more than two hours within our standard operating times. Groups 18 | are more likely to be approved if they demonstrate a specific need to use our 19 | computers instead of any other space -- the manner in which our technology is 20 | utilized should be mentioned in the reservation form. 21 | -------------------------------------------------------------------------------- /docs/staff/private.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Additional documentation" 3 | --- 4 | 5 | Additional documentation not published publicly can be found at 6 | `~staff/privdocs` on supernova. 7 | 8 | Generally, staff documentation should be placed on this website whenever 9 | possible. However, sometimes there are things which should be documented, but 10 | wouldn't be appropriate to document publicly. In only that case, it should be 11 | placed under the unpublished documentation. 12 | -------------------------------------------------------------------------------- /docs/staff/procedures.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Procedures" 3 | --- 4 | 5 | Create pages under this directory to document how to perform common procedures. 6 | 7 | ## Procedures map 8 | -------------------------------------------------------------------------------- /docs/staff/procedures/accounts.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Accounts" 3 | --- 4 | 5 | Create pages under this directory to document account procedures. 6 | 7 | ## Accounts map 8 | -------------------------------------------------------------------------------- /docs/staff/procedures/accounts/alumni-reset.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Alumni account reset" 3 | --- 4 | 5 | Occasionally former OCF members want to re-enable their accounts after 6 | they've been disabled for various reasons, including weak passwords, 7 | lack of CalNet UID, lack of Kerberos principal, etc. 8 | 9 | These are the relevant steps to take in various situations. 10 | 11 | #### Missing CalNet UID {calnet} 12 | 13 | If an alumni cannot use the online password reset function to reset the 14 | password on their account, but they do have a CalNet login, you can manually 15 | add the Calnet UID to their account in LDAP to let them perform a password 16 | reset. They may also need to have a Kerberos principal added for them. 17 | 18 | Please make sure to confirm the user's CalNet ID using the Berkeley Directory, 19 | or by searching the Cal Alumni Network. Alumni profile URLs are in the form 20 | `https://cal.berkeley.edu/profile.php?u=`. You may need an 21 | actual alumnus to perform the search for you, if you are so inclined but 22 | unable to access the page on account of your youth. 23 | 24 | To perform the association, simply follow the steps outlined in the 25 | [LDAP Association](/docs/staff/procedures/accounts/association) documentation 26 | with regards to adding the `calnetUid` record. However, don't delete it after 27 | you're done. 28 | 29 | #### Missing Kerberos principal {kerberos} 30 | 31 | In 2011, we transitioned our password database to Kerberos. Anyone who 32 | logged into their OCF account during the transition had their credentials 33 | migrated, but alumni who didn't log in may be missing a 34 | [Kerberos principal](/docs/staff/backend/kerberos). For them, it is necessary 35 | to manually add one. 36 | 37 | This error manifests itself as the following when a user attempts to reset 38 | their password: 39 | 40 | kadmin Error: kadmin: cpw : Principal does not exist 41 | 42 | To add the principal, run the following: 43 | 44 | $ kadmin add --use-defaults --random-password 45 | 46 | You will need an admin principal yourself to do this. `kadmin` will return the 47 | password and you can relay this to the alumni. 48 | 49 | #### Disabled Account {sorried} 50 | 51 | If the account is [sorried](/docs/staff/scripts/sorry), refer to the documentation 52 | for [unsorry](/docs/staff/scripts/unsorry) to re-enable the account. 53 | 54 | #### Manual Verification of Alumni Identity {verify} 55 | 56 | Before re-enabling access to an alumni's account, one should verify their identity. 57 | If they do not have a CalNet UID or are otherwise lacking a reasonable method of 58 | verifying their identity, it may be necessary to request manual verification of 59 | identity. Pursuant to the [instructions for alumni](/docs/services/account), if 60 | you receive a reactivation request from an alum and need to manually verify their 61 | identity, direct them to send you the required documentation at a private address 62 | and destroy the documentation as soon as possible. 63 | -------------------------------------------------------------------------------- /docs/staff/procedures/accounts/association.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "LDAP association" 3 | --- 4 | 5 | New individual accounts have a `calnetUid` attribute in 6 | [LDAP](/docs/staff/backend/ldap) which is used for 7 | [[changing passwords online|change_password]], querying CalNet when running 8 | [`check`](/docs/staff/scripts/check), and producing aggregate counts of 9 | the number of members by university affiliation. 10 | 11 | Similarly, group accounts have a `callinkOid` attribute. 12 | 13 | Old accounts, especially if previously disabled, may be missing the 14 | `calnetUID` or `callinkOid` attribute. Please add it when enabling accounts. 15 | If unknown or a group other than a registered student organization, set it 16 | to `0`. The `0` is still useful for distinguishing between individuals and 17 | groups based on the attribute name. 18 | 19 | Occasionally, it is useful to allow someone to reset a group account password 20 | online when they are not a signatory, namely when the account is not for a 21 | registered student organization. This is done by associating the user's CalNet 22 | ID with the account record in LDAP. 23 | 24 | Open the LDAP record for editing. 25 | 26 | $ kinit /admin ldapvi uid= 27 | 28 | After looking up the user's UID in the [University 29 | directory](https://www.berkeley.edu/directory), add it to the record with a line 30 | like this: 31 | 32 | calnetUid: 6081 33 | 34 | If the `mail` attribute is missing, but you know of a contact email address for 35 | the account, please add it as well. 36 | 37 | Save the file to update LDAP. Now, the user can 38 | [[change the account password online|change_password]]. 39 | 40 | CalNet association is only meant to be temporary and must be reverted once the 41 | password has been reset by removing this line. It can cause problems with 42 | individual/group acount detection in scripts if an account has both 43 | `callinkOid` and `calnetUid` fields. If an account is associated in an RT 44 | ticket, leave the ticket open until the password has been reset and the account 45 | disassociated. 46 | -------------------------------------------------------------------------------- /docs/staff/procedures/accounts/renaming.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Rename an account" 3 | --- 4 | 5 | We should sparingly rename a user account, and only do so when it is 6 | necessary (e.g. typo in the username). 7 | 8 | To rename an individual account, `sorry` the account with the old name and 9 | make a `note` of why you are changing the username. To run `sorry` you need 10 | to be a root user. Follow the prompts of the script. 11 | 12 | ```bash 13 | sudo sorry username_to_rename 14 | 15 | note -u username_to_rename 16 | ``` 17 | 18 | Then manually create an 19 | account using `approve`. [Associate](/docs/staff/procedures/accounts/association) 20 | the user's `calnetUID` manually, and delete `callinkOID` attribute. You will need 21 | to be a root user to do this. Be sure to `note` the reason and previous username 22 | in the new account note file. 23 | 24 | ```bash 25 | approve 26 | 27 | note -u new_username 28 | ``` 29 | 30 | #### Note 31 | 32 | When the user uses certain OCF webpage (e.g. password reset) that uses `calnetUid` 33 | to find associated OCF accounts, the user will see their old account in the 34 | list of accounts drop-down menu. However, as the old account has been sorried, 35 | the user cannot use the old account in any ways. 36 | -------------------------------------------------------------------------------- /docs/staff/procedures/editing-docs.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Editing docs" 3 | --- 4 | 5 | The OCF's documentation (formerly known as "the wiki") is a part of the OCF 6 | website built with [Markdown][markdown] where we provide technical support for 7 | users and documentation for fellow staff. 8 | 9 | ## Overview 10 | 11 | Docs is currently a part of the OCF's main website, known as [ocfweb][ocfweb]. 12 | Markdown syntax is parsed by [Mistune][mistune] with syntax highlighting done 13 | by [Pygments][pygments]. 14 | 15 | We use a wiki-like syntax for making links within documentation and the 16 | website, e.g. from [Virtual Hosting](/docs/services/vhost#h4_hosting-badge): 17 | 18 | All virtual hosts on the OCF must include an [OCF banner](/docs/services/vhost/badges) on the front page that links to the [OCF home page](/). 19 | 20 | ## Editing docs 21 | 22 | Edits to the documentation are made via the OCF website's Git repository on 23 | GitHub. The editing process is like our other Git workflows: 24 | 25 | 1. Fork [the repository on GitHub][ocfweb]. 26 | 27 | 2. Make changes on a new branch. 28 | 29 | 3. Push your changes. 30 | 31 | 4. Make a pull request. 32 | 33 | Once you make a pull request, it will automatically be tested by 34 | [Jenkins][jenkins], the build server. Jenkins will also deploy your changes 35 | once they have been merged. 36 | 37 | For simple changes, you can just click "Edit this Page" in the sidebar. This 38 | will open the file in GitHub, and walk you through the steps for either 39 | commiting on master or making a pull request. 40 | 41 | For more complicated ones, the repository's readme file has instructions for 42 | testing and building the website so you can preview your edits before making 43 | the commit. Also see [our page on Git](/docs/staff/backend/git) for further info 44 | on working with OCF repos. 45 | 46 | [markdown]: https://daringfireball.net/projects/markdown/syntax 47 | [ocfweb]: https://github.com/ocf/ocfweb 48 | [mistune]: https://github.com/lepture/mistune 49 | [pygments]: https://pygments.org/ 50 | [jenkins]: https://jenkins.ocf.berkeley.edu 51 | -------------------------------------------------------------------------------- /docs/staff/procedures/gapps.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Making OCF Google Apps accounts" 3 | --- 4 | 5 | The OCF has its own Google Apps deployment, which we mainly use for GDrive and 6 | GMail. While it's possible to use Calnet accounts for these (ocf.berkeley.edu 7 | emails redirect to Calnet by default), most active staffers choose to have a 8 | dedicated account because: 9 | 10 | - It allows for nicer integration with our Google Drive folders 11 | - It makes it easier to send emails from the ocf.berkeley.edu domain, which is 12 | good if you want to send an email while representing the OCF 13 | - It can be useful to have a separation between OCF and Calnet accounts. 14 | 15 | ## Making an account 16 | 17 | Google Apps accounts are available upon request for OCF staff members, and are 18 | granted at SM discretion. Upon getting one, staffers should be aware that OCF 19 | emails will be sent to the new account instead of the Calnet account that 20 | they're used to. 21 | 22 | Making a new account requires Google Admin privileges: 23 | 24 | 1. Go to admin.google.com, click on the "Users" section of the Admin panel, and 25 | press the '+' button. 26 | 2. Fill in the first and last name of the user, and make sure their email 27 | address matches their OCF username. 28 | 3. Update the user's `mail` attribute in LDAP to use Google Apps: `kinit you/admin uid=usernamehere`. Change it to `usernamehere@g.ocf.berkeley.edu`. 29 | **The `g.` in the domain is critical; omitting it can cause email delivery 30 | loops in our system!** 31 | -------------------------------------------------------------------------------- /docs/staff/procedures/granting-privileges.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Granting staff privileges" 3 | --- 4 | 5 | ## Adding people to groups 6 | 7 | ### `ocfstaff` 8 | 9 | If you have root privileges, you can add or remove people from `ocfstaff` by 10 | editing the group in LDAP: 11 | 12 | ``` 13 | $ kinit you/admin 14 | you/admin@OCF.BERKELEY.EDU's Password: 15 | $ ldapvi cn=ocfstaff 16 | ``` 17 | 18 | Then add or remove the appropriate `memberUid` attribute. 19 | 20 | ### `ocfroot` 21 | 22 | Before giving anyone root privileges, make sure to obtain authorization from 23 | the SM. 24 | 25 | Adding or removing people from `ocfroot` is similar to modifying 26 | `ocfstaff`. However, if you are adding someone to root staff, in addition to 27 | modifying LDAP, you will also have to create their `/root` and `/admin` 28 | principals (if those don't already exist). For example, to create the 29 | `/admin` principal, you would do: 30 | 31 | ``` 32 | $ kadmin 33 | kadmin> add otherstaffer/admin 34 | you/admin@OCF.BERKELEY.EDU's Password: 35 | Max ticket life [1 day]: 36 | Max renewable life [1 week]: 37 | Principal expiration time [never]: 38 | Password expiration time [never]: 39 | Attributes []: 40 | Policy [default]: 41 | otherstaffer/admin@OCF.BERKELEY.EDU's Password: 42 | Verify password - otherstaffer/admin@OCF.BERKELEY.EDU's Password: 43 | ``` 44 | 45 | At the very first prompt, you are prompted for your password. It's safe to 46 | accept the defaults for the next few prompts. The last two prompts should be 47 | filled in by the new root staffer; it will become the password for their 48 | `/root` or `/admin` principal. 49 | 50 | After you've created these principals, you'll need to grant them powers in the 51 | [Kerberos ACL file in Puppet](https://github.com/ocf/puppet/blob/master/modules/ocf_kerberos/files/kadmind.acl). 52 | 53 | Also add the new root staffer to the Admin team in our GitHub org and grant 54 | them RT admin privileges. 55 | 56 | ## Granting IRC chanop status 57 | 58 | TODO 59 | 60 | ## Granting firewall access 61 | 62 | In order to gain access to the firewall, it is necessary to email someone 63 | from the ASUC Student Union to ask them to fill out the Telecom Shopping 64 | Cart on your behalf. Send them an email with the CalNet IDs of the people 65 | you want to add to the firewall, and have an existing firewall administrator 66 | authorize the request. As of Fall 2017, the 67 | [Facilities Coordinator](https://studentunion.berkeley.edu/our-team/) has 68 | worked to get new people added to the firewall, although it is likely that 69 | this process will change in Spring/Fall 2018 when the firewall is changed as 70 | part of the [bSecure](https://bsecure.berkeley.edu) project. 71 | -------------------------------------------------------------------------------- /docs/staff/procedures/hpc.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Adding users to the HPC cluster" 3 | --- 4 | 5 | Access to the OCF's HPC [cluster](/docs/services/hpc) is controlled by means 6 | of an LDAP group named `ocfhpc`. If a user requests access to the cluster and 7 | meets the basic access criteria, namely that they have specified what they 8 | want to use the cluster for, simply run the following commands to add the user 9 | to the LDAP group: 10 | 11 | abizer@supernova $ kinit abizer/admin ldapvi cn=ocfhpc 12 | ... 13 | memberUid: guser 14 | ... 15 | 16 | Add another line to the list in the form of `memberUid: ` 17 | 18 | Save and quit from your `$EDITOR`, and then reply to the request email with [this][hpc] template. 19 | 20 | [hpc]: https://templates.ocf.berkeley.edu/#hpc-new-user 21 | -------------------------------------------------------------------------------- /docs/staff/procedures/installing-updates.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Installing updates with apt-dater" 3 | --- 4 | 5 | Installing updates requires root (`ocfroot` group). Besides that, anybody 6 | should feel free to install updates at any time. Generally it is quite safe, 7 | though you might want to keep an eye on important things to ensure they start 8 | again after being updated (MySQL, LDAP, and Kerberos are the common offenders). 9 | 10 | ## apt-dater 11 | 12 | We install updates using [apt-dater](https://www.ibh.de/apt-dater/). We wrap it 13 | in a script that builds a list of hosts from LDAP and sends a summary email to 14 | root. 15 | 16 | To install updates: 17 | 18 | 1. Make sure the desktops are not 19 | [suspended](https://github.com/ocf/puppet/blob/master/modules/ocf_desktop/files/suspend/ocf-suspend), 20 | and that you aren't trying to install updates near a 15-minute boundary when 21 | the desktops auto-suspend. See [lab-wakeup](/docs/staff/scripts/lab-wakeup) to 22 | wake up the desktops prior to updating. 23 | 24 | 2. From `supernova`, run: 25 | 26 | sudo apt-dater-ocf 27 | 28 | This will send an email to `root` with a list of packages to be updated. 29 | Glance over the list to make sure there are no obvious problems (for 30 | example, if it's trying to upgrade an entire system or install every 31 | available backport, which has actually happened before). 32 | 33 | Once apt-dater opens, proceed to the next step. 34 | 35 | 3. Select the "Updates pending" row at the top, and hit `u`. You'll be asked if 36 | you wish to upgrade the entire group. Press `y` to confirm. 37 | 38 | 4. All the hosts will now be in the "Sessions" category. Expand it (select then 39 | hit enter), then attach to each host one-by-one (hit `a` when you're over a 40 | host). You'll attach to a tmux session where the updates are being 41 | installed. 42 | 43 | In each session, wait for the updates to be installed, then press `C-b q`. 44 | If "errors" are found, you'll be asked to review them before proceeding. 45 | 46 | These are full tmux sessions, so you can, for example, use `Ctrl-B, D` to 47 | detach if your current session is taking a while. 48 | -------------------------------------------------------------------------------- /docs/staff/procedures/process-accounting.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Process accounting" 3 | --- 4 | 5 | Sometimes we want to figure out how resources on a server have been used 6 | recently. For example, we might want to find which user was using tons of CPU 7 | on the web server. 8 | 9 | Process accounting lets us look at limited historical data for that. In 10 | particular, process accounting logs what programs have been executed by what 11 | user at what time and for how long. Program arguments are _not_ logged, which 12 | is good for helping ensure privacy. 13 | 14 | ## Useful commands 15 | 16 | Some useful commands are below; see `man sa` for many more options. 17 | 18 | ### List recent commands by user 19 | 20 | List programs a user has run, along with timestamps and execution time. 21 | 22 | lastcomm $user 23 | 24 | ### Show sorted CPU usage of all users (past day) 25 | 26 | Shows how much processing time each user has used, sorted by the seventh column 27 | (percentage of CPU minutes). 28 | 29 | `re` is real minutes, `cp` is CPU minutes (i.e. the time actually spent 30 | working). 31 | 32 | sa -m -c | sort -n -k 7 33 | -------------------------------------------------------------------------------- /docs/staff/procedures/restarting-services.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Restarting services" 3 | --- 4 | 5 | ## Taking production services offline 6 | 7 | _As established by the SMs on August 30, 2017._ 8 | 9 | Staffers who wish to take any production service offline for longer than the 10 | length of a reboot, or who wish to reboot a hypervisor hosting production 11 | services must gain permission from the Site Managers or Deputy Site Managers 12 | whenever possible. 13 | 14 | Whenever a staffer restarts a production service, whether permission is 15 | required or not, or restarts a machine that other users have running processes 16 | on, they must give notice to other staffers of their actions as soon as 17 | possible and ideally receive acknowledgement. The staffer should preferably do 18 | this on IRC/Slack. 19 | 20 | Staffers scheduling downtime for public-facing services should make a blog post 21 | at [status.ocf.berkeley.edu][status] to give users sufficient advance notice. 22 | Planned restarts of hypervisors should also be announced on this blog, since 23 | restarting hypervisors can often take several minutes or more. 24 | 25 | _End of policy_ 26 | 27 | ## Rebooting hypervisors 28 | 29 | Rebooting hypervisors is a slightly risky business. Hypervisors aren't 30 | guaranteed to always reboot without problems. Therefore, you shouldn't reboot 31 | them unless you can physically access the lab in case problems arise. 32 | Additionally, this risk is the reason (D)SM permission is normally required to 33 | reboot hypervisors. 34 | 35 | So you've gotten the necessary permission and made a post on the 36 | [status blog][status]/updated the MOTD (if it's a scheduled restart). What now? 37 | 38 | If you are planning to shut down login servers (i.e. tsunami, vampires and 39 | corruption), run the `shutdown` command on these machines as soon as possible in 40 | order to schedule the shutdown and warn users in advance. You can do this with 41 | a command like 42 | 43 | sudo shutdown -h 22:00 "Rebooting for kernel upgrades" 44 | 45 | for a shutdown scheduled for 10:00pm. 46 | 47 | For other VMs, you can shut them each down via `sudo virsh shutdown`. 48 | 49 | Be careful to **always shut down firestorm last**. This is because once 50 | firestorm is shut down, LDAP/Kerberos logins go offline, and the hypervisors can 51 | thereafter only be logged into via the root account. Since you'll not be able to 52 | run new commands using sudo, you should always `sudo -i` before shutting down 53 | firestorm. 54 | 55 | Once all of the VMs have been shut down, you can then power off the hypervisors 56 | via `shutdown -h now`. 57 | 58 | [status]: https://status.ocf.berkeley.edu 59 | -------------------------------------------------------------------------------- /docs/staff/procedures/ssh-supernova.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "SSHing into Supernova" 3 | --- 4 | 5 | When contributing to the OCF codebase, you will need some way of running and 6 | testing your code. Most of our applications cannot be run on a personal 7 | machine--they need to be run on OCF infrastructure. For most projects we 8 | recommend doing all development from `supernova`, a server available to all 9 | staff. Our [Kubernetes server](/docs/staff/backend/kubernetes) is also 10 | accessible from `supernova`. 11 | 12 | ## Before you begin 13 | 14 | You need to be on staff to log into the server. If you're not sure whether or 15 | not you're on staff, try logging in. If this doesn't work, talk to a staff 16 | member and we can add you! All are welcome and encouraged to join. 17 | 18 | ## Logging in 19 | 20 | To log in, open a terminal window and type in: 21 | 22 | ```bash 23 | ssh username@supernova.ocf.berkeley.edu 24 | ``` 25 | 26 | For more instructions, see the [SSH docs](/docs/services/shell). You should 27 | replace `ssh.ocf.berkeley.edu` with `supernova.ocf.berkeley.edu`. 28 | 29 | ## Things you can do on `supernova` 30 | 31 | ### Administration scripts 32 | 33 | Some scripts, such as ones used to create group accounts and refund printing 34 | quotas, are available on `supernova`. Learn more about these in the scripts 35 | section of [staff documentation](/docs/staff). 36 | 37 | ### Development and Testing 38 | 39 | You can `git clone` OCF repositories and run them on `supernova`. An example 40 | for `ocfweb`: 41 | 42 | ```bash 43 | git clone https://github.com/ocf/ocfweb # clone the repository 44 | cd ocfweb # change directory into the repository 45 | 46 | ... make changes ... 47 | 48 | make test # run tests to make sure everything is working 49 | make dev # start a development server and see your changes live 50 | ``` 51 | 52 | ### Kubernetes 53 | 54 | To access Kubernetes, simply run `kubectl` commands. See the [Kubernetes 55 | documentation][kubernetes-basics] for more information. 56 | 57 | Note that staff only have viewing permissions for the cluster. Interested 58 | stafferse can request write access to a development namespace by talking to a 59 | root staffer. 60 | 61 | [kubernetes-basics]: https://kubernetes.io/docs/tutorials/kubernetes-basics/ 62 | -------------------------------------------------------------------------------- /docs/staff/procedures/user-quotas.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "User disk quotas" 3 | --- 4 | 5 | We use the standard Unix quota utilities to set disk quotas. 6 | 7 | ### Summary of useful commands 8 | 9 | All of these can be executed on `filehost`. Some of them also work on other 10 | servers which mount NFS. 11 | 12 | #### View your own quota 13 | 14 | quota 15 | 16 | #### View another user's quota 17 | 18 | quota -u daradib 19 | 20 | #### Print a summary of every user's disk quota 21 | 22 | repquota /dev/mapper/vg-homes 23 | 24 | #### Setting custom disk quotas 25 | 26 | Sometimes we want to set a custom disk quota for a staff member or other 27 | special snowflake (e.g. perhaps a user wants to host their research or 28 | something on OCF, which we encourage). 29 | 30 | To make an exception, just change their quota individually using `edquota -u {username}`. This will open a file in your editor showing their quota. Change 31 | the `soft` and `hard` columns to the number of kibibytes you wish to allocate, 32 | then save the file. 33 | 34 | You can disable the quota entirely by setting `0` for both the `soft` and 35 | `hard` limit, but this is **not recommended** because the next time somebody 36 | tries to raise disk quotas, it will "raise" your quota from "no quota" to the 37 | new quota. To mimic an infinite quota, just give the account a very large quota 38 | instead. 39 | 40 | ## Raising disk quotas for every user 41 | 42 | Are you trying to raise disk quotas for every user? Congratulations on finding 43 | this page! The SM who wrote this section spent a couple of hours trying to 44 | figure out _how in the hell_ our automatic disk quotas were working, despite 45 | all internet documentation claiming there is no way to set default disk quotas. 46 | 47 | Indeed, you cannot configure a default quota. You can, however, set quotas for 48 | non-existent users! We've set quotas for user IDs 1000 through 99999 in order 49 | to mimic default users. 50 | 51 | To raise disk quotas, you can use a command like: 52 | 53 | ```bash 54 | soft_limit="5242880" # 5 GiB in KiB 55 | hard_limit="5767168" # 5.5 GiB in KiB 56 | 57 | for i in $(seq 1000 99999); do 58 | quotatool -b -Rr -q "$soft_limit" -l "$hard_limit" -u ":$i" /dev/mapper/vg-homes 59 | done 60 | ``` 61 | 62 | The flags assure that we set a block limit (rather than an inode limit) and 63 | that we only raise quotas (so that we don't accidentally lower the quota of a 64 | special snowflake). 65 | 66 | The "soft limit" is like a warning limit; it can be configured to be enforced 67 | after a grace period, but we don't do this. In practice, we announce the limit 68 | to the public as "X GB", with a soft limit of "X GB" and a hard limit of "X+0.5 69 | GB". 70 | 71 | Since the soft limit is never enforced, the real limit is the hard limit. 72 | -------------------------------------------------------------------------------- /docs/staff/procedures/xmpp.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Manually creating XMPP accounts" 3 | --- 4 | 5 | Currently, users must request XMPP accounts since registration is disabled. To 6 | create an account for someone, you must have root privileges. 7 | 8 | 1. Ensure their email address matches the OCF username given 9 | 2. Generate a random password: `pwgen -s 16` 10 | 3. On `flood`, run the command 11 | `sudo prosodyctl register username ocf.berkeley.edu password` 12 | -------------------------------------------------------------------------------- /docs/staff/rebuild.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Rebuild" 3 | --- 4 | 5 | The Great OCF Rebuild 6 | 7 | ## Rebuild map 8 | -------------------------------------------------------------------------------- /docs/staff/scripts.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Scripts" 3 | --- 4 | 5 | Create subpages under this category to document scripts/programs that are 6 | commonly used in the OCF. 7 | -------------------------------------------------------------------------------- /docs/staff/scripts/approve.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "approve: record an OCF group account request" 3 | --- 4 | 5 | This page explains the OCF account approval procedure and the usage of the 6 | `approve` script. 7 | 8 | ## When to use approve 9 | 10 | OCF group accounts need to be manually approved by staff in the lab. All 11 | members requesting individual accounts should be directed to the online 12 | approval page. If a member requesting an individual account cannot use the 13 | online approval system (likely because of an invalid/unacceptable CalNet UID), 14 | direct them to an OCF officer. 15 | 16 | ## Approving a request 17 | 18 | **The approve program can only be run from supernova.** 19 | 20 | ### Before approve 21 | 22 | - SSH into supernova.ocf.berkeley.edu 23 | 24 | - For registered student groups, the OCF requires that a signatory authorize 25 | the approval of the account. If the account is not a registered student 26 | group, check with the [membership eligibility](/docs/membership/eligibility) 27 | to see what constitutes acceptable documentation. 28 | 29 | - If the group is a registered student group, you can look up the requester's 30 | signatory status by name with [signat](/docs/staff/scripts/signat). 31 | 32 | ``` 33 | $ signat name matthew mcallister 34 | Searching for people... Found 1 entry. 35 | Searching for signatories... 36 | 37 | MATTHEW JAMES Mcallister (1031366) 38 | ================================== 39 | Group Accounts OID 40 | ----------------------- --------------------------- ----- 41 | Open Computing Facility decal, linux, ggroup, group 46187 42 | ``` 43 | 44 | Copy the group's OID, as you will need it when running approve. 45 | 46 | - If the group is not a student group, the requester will need an official 47 | letterhead giving them authority to create the account. You will also need to 48 | check that the group doesn't already have an account using 49 | `checkacct`. 50 | 51 | ``` 52 | $ checkacct privacy 53 | Login: bipla Name: Berkeley Information Privacy Law Association 54 | ``` 55 | 56 | - Finally, check that the name on the requester's Cal ID matches who 57 | they say they are. 58 | 59 | ### Running approve 60 | 61 | When you run approve it will open a text editor; just fill out the form, 62 | save it, and let the requester enter a password when prompted. 63 | 64 | For reference, `user_name` will be the username used to log in to the 65 | newly-created account, `group_name` is the full name of the group, e.g. 66 | 'Open Computing Facility', and `email` should ideally point somewhere that 67 | will be read by whoever will be maintaining the account. `signatory` has been 68 | deprecated. 69 | 70 | Optionally, if you pass the OID as the only argument, the `group_name`, 71 | `callink_oid`, and `email` fields will get filled in automatically using the 72 | group's public information on CalLink. If the group is not a student group, 73 | (e.g. a research group), use 0 as the OID. 74 | 75 | ### Post approval 76 | 77 | Explain to the requesters that they will need to apply for [virtual hosting](/docs/services/vhost) after they have set up their site if they wish to 78 | do so. Point them to relevant wiki articles. 79 | -------------------------------------------------------------------------------- /docs/staff/scripts/check.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "check: get details about an OCF user" 3 | --- 4 | 5 | ## Introduction 6 | 7 | `check` allows staffers to get account details about users. Some information 8 | may only be accessible to privileged users or root, or depend on the server 9 | `check` is being run on, so output may differ accordingly. 10 | 11 | `check` is best run on `supernova`. 12 | 13 | `check` currently returns: 14 | 15 | - `getent` (i.e. LDAP) info 16 | - CalNet info 17 | - Remaining print quota 18 | - Virtual host, apphost, and/or virtual mail configuration if applicable 19 | - DNS records for any of the above 20 | - Signatory of / signatories for 21 | - [Notes](/docs/staff/scripts/note) about the user in `~staff/User_Info` 22 | - Processes running on the current machine owned by that user 23 | - Recent login history on the current machine by that user 24 | 25 | ## Usage/Example 26 | 27 | $ check sanjayk 28 | sanjayk:*:18298:20:Sanjay Krishnan:/home/s/sa/sanjayk:/bin/tcsh 29 | Member of group(s): ocf ocfstaff admin 30 | Mail forwarded to "|procmail #sanjayk" 31 | CalNet UID number: 646431 32 | CalNet affilations: AFFILIATE-TYPE-ADVCON-ALUMNUS AFFILIATE-TYPE-ADVCON-STUDENT EMPLOYEE-TYPE-ACADEMIC STUDENT-TYPE-REGISTERED 33 | 34 | Recent login history on local machine: 35 | ------------------------------------------------------------------------------- 36 | pts/5 Fri Mar 8 10:42 - 10:58 (00:16) avalanche.ocf.berkeley.edu 37 | pts/17 Fri Mar 8 10:16 - 10:28 (00:11) avalanche.ocf.berkeley.edu 38 | pts/5 Wed Mar 6 18:14 - 19:54 (01:39) reccev-wism-wlan-189-130.airbears.berkeley.edu 39 | pts/5 Wed Mar 6 18:05 - 18:05 (00:00) reccev-wism-wlan-189-130.airbears.berkeley.edu 40 | pts/5 Mon Mar 4 19:04 - 19:05 (00:01) destruction.ocf.berkeley.edu 41 | ------------------------------------------------------------------------------- 42 | -------------------------------------------------------------------------------- /docs/staff/scripts/checkacct.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "checkacct: find accounts by full name" 3 | --- 4 | 5 | ## Introduction 6 | 7 | If a member does not know their account name, you can use this script to look 8 | it up. 9 | 10 | Before recording an account request for a group with [approve](/docs/staff/scripts/approve), check to see if the group already has an account. Be 11 | sure to use different forms and abbreviations of the group's name to maximize 12 | the chance that a group will be found. 13 | 14 | This script will search [LDAP](/docs/staff/backend/ldap) for case-insensitive 15 | matches in any part of the full name or account name, including part of a word. 16 | For example, `checkacct wa fel andy` will search for any account that has "wa" 17 | (as in waf), "fel" (as in Felix), and "andy" (as in Andy) in the full name 18 | (LDAP cn) or account name (LDAP uid). 19 | 20 | ## Usage 21 | 22 | $ checkacct wa fel andy 23 | Login: waf Name: Felix Andy Wong 24 | 25 | $ checkacct dara 26 | Login: darac Name: Dara T. Chu 27 | Login: laktalk Name: Lakshmi Sridaran 28 | Login: sby Name: Sanji Bandara Yapa 29 | Login: angeloq Name: Cesar Angelo Quindara 30 | Login: jayasund Name: Jayasree Padma Sundaram 31 | Login: dpastor Name: Dara Elana Pastor 32 | Login: msiva Name: Matheepan Sivagnanasundaram 33 | Login: daraech Name: Diana Darae Choe 34 | Login: suchitha Name: Suchitha Sundaram 35 | Login: csavong Name: Christindaravy Savong 36 | Login: norac Name: Nora Chandara 37 | Login: salmabah Name: Salma Bahadarakhann 38 | Login: darabkin Name: David Andrew Rabkin 39 | Login: daradib Name: Dara Adib 40 | Login: akhilsun Name: Akhil Sundararajan 41 | Login: mdarabi Name: ZARA MARISA DARABIFARD 42 | Login: eeden Name: Elana Dara Eden 43 | -------------------------------------------------------------------------------- /docs/staff/scripts/chpass.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "chpass: reset a user's password" 3 | --- 4 | 5 | The preferred way of changing passwords is to [[do it online|change_password]]. 6 | This does not require a staffer to be present to change the user's password. 7 | Only use the command line chpass if this is not suitable. An example is, for 8 | group accounts or users that send notarized letters to the OCF. 9 | 10 | ## Technical Description 11 | 12 | Python script that changes a user's kerberos principal password using a specified 13 | staff/root principal. 14 | 15 | ## Usage 16 | 17 | ~$ chpass andromeda 18 | 19 | Changes user andromeda's password 20 | 21 | ## Sample Use Case 22 | 23 | You can run chpass on any server. 24 | 25 | raphtown@pileup:~$ chpass andromeda 26 | OCF Change Password Program 27 | 28 | WARNING: If you are resetting/changing a password for an OCF staff member, 29 | you acknowledge that you may potentially modify some of the privileges that the staff 30 | member may have. 31 | 32 | Changing password for: andromeda:*:1615:20:Andromeda Centauri,The OCF,,:/home/a/an/andromeda:/opt/share/utils/bin/sorried 33 | 34 | Let the user type in his new password (and verify it). Requirements are for 35 | passwords to be at least 8 characters long. It is helpful to indicate that 36 | nothing will show up when the user starts typing. 37 | 38 | Enter New Password: 39 | Verify password: 40 | Connecting to kerberos.ocf.berkeley.edu... 41 | 42 | Now type in your kerberos root principal password. If you don't have one you 43 | can't change passwords! 44 | 45 | Please enter the password for principal raphtown/root: 46 | andromeda@OCF.BERKELEY.EDU's Password: 47 | Verifying - andromeda@OCF.BERKELEY.EDU's Password: 48 | raphtown/root@OCF.BERKELEY.EDU's Password: 49 | Successfully changed heimdal kerberos principal 50 | -------------------------------------------------------------------------------- /docs/staff/scripts/economode.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "economode: turn economode on/off on the printers" 3 | --- 4 | 5 | By default our printers print with the Economode setting on, which saves toner 6 | and also means your printouts come out draft quality. If you need to print 7 | something and not have it in draft quality, you can use the `economode` script 8 | to turn Economode off. 9 | 10 | You'll need the printer password, whose location can be found in `/opt/passwords`. Only `rootstaff` has access to this file, you'll have to ask someone on `rootstaff` to give you the password. 11 | 12 | Remember to reset Economode to on using the same script once you're done. 13 | 14 | ## Usage 15 | 16 | ``` 17 | $ economode on 18 | Enter printer password: 19 | Setting economode to on for papercut... OK 20 | Setting economode to on for pagefault... OK 21 | 22 | $ economode off 23 | Enter printer password: 24 | Setting economode to off for papercut... OK 25 | Setting economode to off for pagefault... OK 26 | ``` 27 | -------------------------------------------------------------------------------- /docs/staff/scripts/how.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "how: view the source of a script" 3 | --- 4 | 5 | ## Introduction 6 | 7 | `how` displays the source of a script in the `PATH` in a pager (usually `less`) 8 | 9 | It's very simple. 10 | 11 | ## Usage/Example 12 | 13 | $ how sorry 14 | 15 | #!/bin/bash 16 | # Script for sorrying OCF user accounts 17 | .... 18 | -------------------------------------------------------------------------------- /docs/staff/scripts/lab-wakeup.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "lab-wakeup: wake up suspended desktops" 3 | --- 4 | 5 | ## Introduction 6 | 7 | ##### Usage: `lab-wakeup $HOST` 8 | 9 | Use `lab-wakeup $hostname` when you need to wake up a desktop that has 10 | suspended. For example, if you try to SSH into `volcano.ocf.berkeley.edu` 11 | and get an error similar to 12 | 13 | ssh: connect to host $host port 22: No route to host 14 | 15 | you can try `lab-wakeup volcano` on supernova or your staff VM to wake it, 16 | after which you should be able to log in without issue. You may need to 17 | install `wakeonlan` if it's not there already. 18 | 19 | ![](https://i.fluffy.cc/rLBlrNjrlnRN5tP9WjXjH8mkTss09fNH.png) 20 | 21 | See also: 22 | [ocf-suspend](https://github.com/ocf/puppet/blob/master/modules/ocf_desktop/file 23 | s/suspend/ocf-suspend), which suspends the desktops on 15-minute intervals. 24 | -------------------------------------------------------------------------------- /docs/staff/scripts/migrate-vm.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "migrate-vm: migrate VMs between hosts" 3 | --- 4 | 5 | ## Usage 6 | 7 | This script is used for migrating [KVM virtual machines][kvm] between physical 8 | hosts. The script should be run on the new host for the virtual machine using 9 | the following format. The first hostname specified in the command is what 10 | physical host to move the virtual machine from, and the second one is the name 11 | of the virtual machine to move. 12 | 13 | For example, the following command moves `supernova` from `jaws` to whatever 14 | KVM host the command is run on: 15 | 16 | sudo migrate-vm jaws:supernova 17 | 18 | [kvm]: https://wiki.debian.org/KVM 19 | 20 | ## Steps performed 21 | 22 | To move the virtual machine, `migrate-vm` performs the following steps: 23 | 24 | 1. Shuts down the virtual machine on the old host. 25 | 2. Creates a new [LVM][lvm] volume on the new host with the correct size. 26 | 3. Securely copies the virtual machine's disk from the old host to the new 27 | host. 28 | 4. Checksums both the old and the new disks on each machine to ensure they 29 | match. 30 | 5. Imports the KVM domain definition from the old host to the new host. 31 | 32 | [lvm]: https://wiki.debian.org/LVM 33 | 34 | ## Final steps 35 | 36 | After the virtual machine has been transferred between hosts, make sure the 37 | guest works on the new host. If moving from `hal`, you might need to delete the 38 | custom CPU definition section from the KVM XML to get the virtual machine to 39 | start. To edit the XML definition, run `sudo virsh edit ${hostname}`. The 40 | section to delete looks like this: 41 | 42 | ```xml 43 | 44 | Opteron_G3 45 | 46 | ``` 47 | 48 | Then, after everything works, you should remove the old KVM and LVM definitions 49 | on only the **old** host: 50 | 51 | sudo virsh undefine ${hostname} 52 | sudo lvremove /dev/vg/${hostname} 53 | 54 | ## Assumptions Made 55 | 56 | - The LVM volume group `/dev/vg` is used on both the old and new host. 57 | - Virtual machines are stored at `/dev/vg/${hostname}` on both hosts. 58 | -------------------------------------------------------------------------------- /docs/staff/scripts/note.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "note: add notes to a user account" 3 | --- 4 | 5 | ## Introduction 6 | 7 | `note` adds notes to the user's entry in `~staff/User_Info`. It is used to log 8 | important information about a user, for example, if they've been sorried 9 | (and why), if their password was reset, if some admistrative action has been 10 | performed on their account, e.g. renaming the account, or for myriad other 11 | reasons where some documentation should be made about an OCF account. 12 | 13 | `note` should be run on supernova. 14 | 15 | ## Usage/Example 16 | 17 | $ note -u username [note] 18 | 19 | `note` will append the note-taking user's username, the day's date, the noted 20 | user's username, and the note to `~staff/User_Info`, where it can later be retrieved by 21 | [`check`](/docs/staff/scripts/check). 22 | -------------------------------------------------------------------------------- /docs/staff/scripts/ocf-tv.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "ocf-tv: connect to the tv or modify the volume" 3 | --- 4 | 5 | The usage of `ocf-tv` looks like: 6 | 7 | ocf-tv [-h] [-H HOST] {connect,volume,mute,stop-tunnel,tunnel-audio} 8 | 9 | If you provide no arguments to `ocf-tv` the default behavior is that it will 10 | start a VNC session to the TV. If you do not specify the host it will use the 11 | TV by default. 12 | 13 | `ocf-tv connect` will open up a VNC window using `xvncviewer` to the host. 14 | The TV uses [i3wm](/docs/staff/i3wm), a tiling window manager, so if you are 15 | unsure of how to use it read the linked documentation. 16 | 17 | If you'd like to just change the volume on the host, you can use the 18 | `volume` or `mute` options to change the pulseaudio volume level. 19 | `ocf-tv volume 50` sets the remote volume to 50% (acceptable values in [0,150]) 20 | and `mute` does what you might expect. 21 | 22 | If you'd like to tunnel audio playing on your local desktop to the TV (for 23 | example, so you don't have to manipulate YouTube over VNC), you can start 24 | the tunnel via `ocf-tv tunnel-audio` from any desktop, and similarly, use 25 | `ocf-tv stop-tunnel` to close the tunnel and resume local-only playback. 26 | -------------------------------------------------------------------------------- /docs/staff/scripts/paper.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "paper: view and modify print quotas" 3 | --- 4 | 5 | ## Introduction 6 | 7 | The `paper` script is used to list and modify user print quotas. When users 8 | print documents, their print quota is updated in a central database on `mysql` 9 | that is also checked to make sure users have enough print quota before sending 10 | their document(s) to the printer. This database can be queried and modified by 11 | the `paper` script, which internally uses `ocflib` to access the database. 12 | 13 | The `paper` script can be used from anywhere to list pages remaining per day 14 | and per semester, but can currently only be used to change print quotas by 15 | issuing refunds from `supernova`. 16 | 17 | ## Usage Scenarios 18 | 19 | ### View help (shows possible commands and arguments) 20 | 21 | $ paper -h 22 | $ paper view -h 23 | $ paper refund -h 24 | 25 | ### View balances 26 | 27 | For yourself: 28 | 29 | $ paper 30 | 31 | For other users: 32 | 33 | $ paper view 34 | 35 | ### Issue refunds (change user balances) 36 | 37 | Refunds can be positive or negative, so you can add or subtract quotas using 38 | this method. By default they are positive, so you are refunding them for pages 39 | wrongly used. Make sure to surround the reason in quotes if it contains spaces, 40 | otherwise the command will not work. 41 | 42 | $ paper refund --pages --reason "" 43 | -------------------------------------------------------------------------------- /docs/staff/scripts/pdf-open.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "pdf-open: unf*&^ bad PDFs if they won't print right" 3 | --- 4 | 5 | ## Introduction 6 | 7 | The `pdf-open` script is used when lab users attempt to print PDFs that our 8 | printers don't like for myriad reasons. The easiest solution is to rasterize 9 | the PDF and send it for printing again, hoping the printer gods are merciful. 10 | Examples of PDFs that commonly fail include many Econ 136 and Bio 1B papers, 11 | PDFs with strange images or scanned components in them, and things people try 12 | to print straight from Gmail attachment viewer. 13 | 14 | If a user comes asking why their paper isn't printing right, first download the 15 | PDF, then run `pdf-open $pdf_file`. Don't forget the hyphen, and make sure the 16 | filename doesn't have any spaces or weird characters in it. After 17 | re-rasterizing the file, Evince will open, and you can start a new print job 18 | from there. Monitor the job's progress in 19 | [printhost.ocf.berkeley.edu](//printhost.ocf.berkeley.edu) to ensure the job 20 | survives. You may [refund](/docs/staff/scripts/paper) printing credits to 21 | the user in case they've gone over their daily capacity and you're feeling 22 | generous. 23 | -------------------------------------------------------------------------------- /docs/staff/scripts/sorry.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "sorry: disable an OCF account" 3 | --- 4 | 5 | ## Introduction 6 | 7 | `sorry` is the command used to disable OCF accounts. Accounts are disabled 8 | for various reasons, including but not limited to violating OCF/university 9 | policies, security issues, lack of contact information, etc. Alumni also 10 | sometimes request to have their accounts disabled to stop vhosts, take down 11 | information, or for myriad other reasons. 12 | 13 | ## Usage/Example 14 | 15 | Usage: sorry [user to be sorried] [sorry file] 16 | 17 | Sorrying a user changes their login shell to the sorryshell, 18 | (/opt/share/utils/bin/sorried), copies the sorry file (containing the reason 19 | they were sorried) to ~user/.sorry, `chmod 000`'s the user's httpdir, `chmod 500`'s the user's homedir, and adds the user to the "sorry" group, before 20 | emailing them with the reason they were sorried. If a sorried user attempts to 21 | log in, they will be rebuffed. 22 | 23 | You will need an admin and root principal (or, atleast, ocfroot membership) in 24 | order to run this command, which should preferably be run on supernova in order 25 | to find all the appropriate files. 26 | 27 | All sorry files are stored in [ocf/utils](//github.com/ocf/utils) under 28 | `staff/acct/sorry/`, which is where they should be edited if necessary. Puppet 29 | clones this repo to `/opt/share/utils/` on all the computers. 30 | 31 | After sorrying a user, make sure to run the `note` command to document the 32 | reasoning to ~staff/User_Info. This reason will be read to future users running 33 | `check` on the sorried user. 34 | 35 | [Unsorrying](/docs/staff/scripts/unsorry) a user is also possible. 36 | 37 | If a user is sending too much mail, it may be easier to `nomail` the user 38 | instead of sorrying their account. This involves adding the user to 39 | `/etc/postfix/ocf/nomail` on anthrax, at which point their ability to send 40 | mail will be removed. 41 | 42 | See `how sorry` for more information on the sorry command itself. 43 | -------------------------------------------------------------------------------- /docs/staff/scripts/ssh-list.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "ssh-list: run command via SSH on many hosts simultaneously" 3 | --- 4 | 5 | `ssh-list` is a small wrapper around `parallel-ssh` which reads lists of hosts 6 | from LDAP. 7 | 8 | The usage of `ssh-list` looks like: 9 | 10 | ssh-list [arguments to parallel-ssh] 11 | 12 | The argument `` is interpreted by `ssh-list`, and the arguments after are 13 | passed verbatim to `parallel-ssh`. 14 | 15 | In most cases, you want at least `-i` in the arguments to parallel-ssh. `-i` 16 | prints out the stdout and stderr for each host you are running the command on. 17 | For example: 18 | 19 | ssh-list all -i whoami 20 | 21 | In most cases, it's most useful to use a type like `desktop` rather than `all`. 22 | 23 | If you get a ton of authentication errors, don't provide your password, just do 24 | `kinit $USER` first (your Kerberos ticket probably expired, or you probably 25 | logged in with an SSH key). 26 | 27 | Some useful commands are below (please add more!): 28 | 29 | ### Run puppet once 30 | 31 | Anyone in `ocfroot` can call `sudo puppet-trigger` without providing a 32 | password. 33 | 34 | ssh-list desktop -i 'sudo puppet-trigger' 35 | 36 | ### Restart unused desktops 37 | 38 | Anyone in `ocfroot` can call `sudo shutdown` without providing a password. 39 | 40 | ssh-list desktop -i '[ $(who | wc -l) -eq 0 ] && sudo shutdown -r now' 41 | 42 | ### Run `apt-get update` to clear apt caches 43 | 44 | `ocfroot` can't run passwordless `apt-get`, so you need to use the `apt-dater` 45 | keytab. 46 | 47 | From supernova: 48 | 49 | sudo kinit -k -t /root/apt-dater.keytab 'apt-dater@OCF.BERKELEY.EDU' \ 50 | ssh-list desktop -l apt-dater -i 'sudo apt-get update' 51 | -------------------------------------------------------------------------------- /docs/staff/scripts/unsorry.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "unsorry: re-enable a sorried account" 3 | --- 4 | 5 | ## Introduction 6 | 7 | For various reasons, we've had to disable accounts. Some for weak passwords, 8 | some for security vulnerabilities, or myriad other reasons. If an account 9 | is [sorried](/docs/staff/scripts/sorry), once you've made sure the original problem 10 | has been resolved (you can check `User_Info` via [check](/docs/staff/scripts/check)) 11 | you can `unsorry` their account and let them log in again. 12 | 13 | `unsorry` will remove the user from the sorry group, re-enable a login shell, 14 | and generally allow them to use their account again. Occasionally more 15 | than simply `unsorry` may be necessary depending on changes in the 16 | infrastructure. 17 | 18 | `unsorry` should be run on supernova. 19 | 20 | ## Usage/Example 21 | 22 | $ sudo unsorry username 23 | 24 | It may also be necessary to run `nscd -i passwd` on **`tsunami`**. 25 | 26 | Make sure to document all `sorry`ing and `unsorry`ing using [note](/docs/staff/scripts/note) 27 | -------------------------------------------------------------------------------- /docs/staff/startertasks/completed.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "PR Completion Record" 3 | --- 4 | 5 | The following staffers have successfully made a pull request to 6 | [ocfweb](https://github.com/ocf/ocfweb): 7 | 8 | 9 | 10 | - [bngo](https://github.com/ocf/ocfweb/pull/578) 11 | - [cooperc](https://github.com/ocf/ocfweb/pull/569) 12 | -------------------------------------------------------------------------------- /docs/staff/techtalks.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Tech talks" 3 | --- 4 | 5 | The OCF regularly hosts tech talks where volunteer staff members share their knowledge, 6 | and try and teach others how the OCF works, and how to contribute to it. 7 | 8 | We will be recording these talks and make them available publicly, along with slides. 9 | 10 | | Date | Title | Staff Member | Video | Slides | 11 | | ------------------- | ----------------------------- | ------------ | ---------------------- | ------------------------ | 12 | | February 13th, 2017 | Contributing to the OCF | nickimp | [video][contrib-video] | [slides][contrib-slides] | 13 | | February 27th, 2017 | Free and Open Source Software | baisang | [video][foss-video] | [slides][foss-slides] | 14 | | March 13th, 2017 | Puppet (and the OCF) | jvperrin | [video][puppet-video] | [slides][puppet-slides] | 15 | | April 10th, 2017 | GNU Privacy Guard | kpengboy | [video][gpg-video] | [slides][gpg-slides] | 16 | 17 | [contrib-video]: https://www.youtube.com/watch?v=qLFSHZYj8Qw 18 | [contrib-slides]: https://drive.google.com/file/d/0B6qdeEJcBKpMVkpoQlItSzJJQzlUd3RtczQxZ0o5Y28xcGJj/view 19 | [foss-video]: https://www.youtube.com/watch?v=uXfosiVuB64 20 | [foss-slides]: https://docs.google.com/presentation/d/1ppPxTzhIVjqixdb40ft4YDx_gZXsN7sDhbF9SKAWXkM/view 21 | [puppet-video]: https://www.youtube.com/watch?v=QER7DQQNO48 22 | [puppet-slides]: https://docs.google.com/presentation/d/1QSkZ7zKe-ZHw_Gmq4JIRu4fNHUn7nQpyeg4JGgJTgj8/view 23 | [gpg-video]: https://www.youtube.com/watch?v=7kxrvNHxal8 24 | [gpg-slides]: https://www.ocf.berkeley.edu/~kpengboy/gpg-20170410.pdf 25 | -------------------------------------------------------------------------------- /docs/staff/tips.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Tips and tricks" 3 | --- 4 | 5 | This category includes bits of information that make the OCF easier and more 6 | fun to use. 7 | -------------------------------------------------------------------------------- /docs/staff/tips/desktoprc.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: ".desktoprc" 3 | --- 4 | 5 | The file `~/remote/.desktoprc` is automatically sourced when you log into any 6 | of the desktops. Since `~/remote` is actually `sshfs`'d to your home folder on 7 | NFS, this means you can put your common config or preferences in it and have 8 | them be shared across all desktops. 9 | 10 | ## Example uses 11 | 12 | If you want to get a feel for what you can do with your `.desktoprc`, try out 13 | some of these useful ideas. 14 | 15 | ### Sync your dotfiles 16 | 17 | If you want your application settings shared between the desktops and login 18 | servers, you can just copy them over with a line like this: 19 | 20 | cp ~/remote/{.bashrc, .bash_aliases, .vimrc, ...} ~/ 21 | 22 | Alternatively, if you have a [dotfile repo](https://dotfiles.github.io/), you 23 | can either clone it... 24 | 25 | git clone https://github.com/username/dotfiles.git ~/.dotfiles 26 | ~/.dotfiles/my-install-script 27 | 28 | ... or just link to it in your NFS homedir, if you have it there: 29 | 30 | ln -s ~/remote/.dotfiles ~/.dotfiles 31 | ~/.dotfiles/my-install-script 32 | 33 | ### Configure HexChat (IRC) 34 | 35 | We install HexChat as a desktop IRC client. You can automatically configure it 36 | to connect to your favorite networks on startup. For example, to automatically 37 | connect to the OCF's IRC server, try this snippet: 38 | 39 | mkdir -p ~/.config/hexchat 40 | echo " 41 | v=2.12.4 42 | 43 | N=ocf 44 | L=7 45 | E=UTF-8 (Unicode) 46 | F=30 47 | D=0 48 | S=irc.ocf.berkeley.edu/6697 49 | J=#rebuild 50 | " > ~/.config/hexchat/servlist.conf 51 | 52 | For more complex configs, you always have the option to edit your server list 53 | from the GUI, then copy and paste `servlist.conf` into your `.desktoprc`. 54 | 55 | ### Disable terminal shortcuts 56 | 57 | The XFCE4 terminal emulator installed on the desktops comes with keyboard 58 | shortcuts by default. If these bother you, you can disable them like this: 59 | 60 | echo " 61 | ShortcutsNoHelpkey=TRUE 62 | ShortcutsNoMenukey=TRUE 63 | ShortcutsNoMnemonics=TRUE 64 | " >> ~/.config/xfce4/terminal/terminalrc 65 | -------------------------------------------------------------------------------- /docs/staff/tips/shorturls.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Shorturls" 3 | --- 4 | 5 | We use `ocf.io` as a URL shortener. 6 | 7 | One of its functions is to shorten member website URLs: 8 | `https://ocf.io/username` is a shorturl for 9 | `https://www.ocf.berkeley.edu/~username`. 10 | 11 | We've additionally defined other shorturls. Here are some especially useful 12 | ones for staff: 13 | 14 | - **ocf.io/gh/__**, **ocf.io/github/__**: The repository __ 15 | on the OCF GitHub page.\ 16 | There are also abbreviations for the most commonly used repositories: 17 | - **ocf.io/gh/i**: ircbot 18 | - **ocf.io/gh/l**: ocflib 19 | - **ocf.io/gh/p**: puppet 20 | - **ocf.io/gh/u**: utils 21 | - **ocf.io/gh/w**: ocfweb 22 | - **ocf.io/rt**: RT 23 | - **ocf.io/rt/__**: The page for ticket __ in RT 24 | - **ocf.io/stats**: Lab stats 25 | - **ocf.io/guest**: If you bring a guest into the lab after hours, fill out 26 | this form 27 | - **ocf.io/servers**: The server chart 28 | - **ocf.io/bod**: BoD minutes 29 | 30 | We also often give out these shorturls in RT tickets: 31 | 32 | - **ocf.io/join**: Signup page for an OCF account 33 | - **ocf.io/vhost**: Info about virtual hosting 34 | - **ocf.io/vhost-mail**: Info about mail virtual hosting 35 | - **ocf.io/apphost**: Info about apphosting 36 | 37 | ## More shorturls 38 | 39 | You can find a list of `ocf.io` shorturls in our Apache configuration in 40 | Puppet at [ocf.io/shorturl](https://ocf.io/shorturl). 41 | 42 | You can add additional shorturls to this list. When doing so, make sure that: 43 | 44 | 1. The shorturl isn't already someone's username, so you don't accidentally 45 | break the `ocf.io/username` functionality for them. 46 | 2. You add your shorturl to 47 | [the list of reserved usernames][reserved-usernames]. This way, no one will 48 | subsequently register an account with the same name as your shorturl and 49 | find that `ocf.io/username` doesn't work for them. 50 | 51 | [reserved-usernames]: https://github.com/ocf/ocflib/blob/master/ocflib/account/validators.py 52 | -------------------------------------------------------------------------------- /docs/staff/tips/staffvm.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "On your staff VM" 3 | --- 4 | 5 | ## Essentials 6 | 7 | Your vm's environment is determined by the ldap entry for the machine. 8 | 9 | johnsnow@~$ kinit johnsnow/admin ldapvi cn=whitewalker 10 | ### ...LDIF 11 | #... 12 | # whitewalker, Hosts, OCF.Berkeley.EDU 13 | dn: cn=whitewalker,ou=Hosts,dc=OCF,dc=Berkeley,dc=EDU 14 | objectClass: device 15 | objectClass: ocfDevice 16 | cn: whitewalker 17 | ipHostNumber: 169.229.226.256 18 | type: server 19 | puppetVar: owner=johnsnow 20 | environment: johnsnow 21 | #... 22 | -------------------------------------------------------------------------------- /docs/staff/tips/staffvm/ocfweb.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Running ocfweb" 3 | --- 4 | 5 | If you want to work on [`ocfweb`][0] on your Staff VM, it isn't as 6 | simple as cloning the repo and running `make dev`, unfortunately. 7 | In order to do so, you will need to add the `ocfweb` dev config to 8 | your Staff VM's Puppet configuration, so Puppet can install 9 | `ocfweb`'s config files. To do this, clone the [puppet repo][1] or 10 | go to `/opt/puppet/env/` on `lightning`, and then in 11 | `hieradata/nodes/` add the following lines to your staff VM's Hiera 12 | configuration: 13 | 14 | classes: 15 | - ocf_ocfweb::dev_config 16 | 17 | Take a look at the configs for [`fireball`][2] or [`raptors`][3] for 18 | examples. 19 | 20 | If you are in `ocfroot` you can push this directly to puppet and 21 | trigger a puppet run on your staffvm (`sudo puppet-trigger -fe `) 22 | otherwise, push to your fork and submit a pull request and someone will 23 | merge it for you, after which you can trigger the puppet run on your VM. 24 | 25 | Furthermore, you will need to install the `libcrack2-dev` package so that 26 | the crypto libraries `ocfweb` depends on will successfully compile. 27 | 28 | [0]: https://github.com/ocf/ocfweb 29 | [1]: https://github.com/ocf/puppet 30 | [2]: https://github.com/ocf/puppet/blob/master/hieradata/nodes/fireball.yaml 31 | [3]: https://github.com/ocf/puppet/blob/master/hieradata/nodes/raptors.yaml 32 | -------------------------------------------------------------------------------- /docs/staff/tips/templates.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Email Templates" 3 | --- 4 | 5 | General email response templates can be found at 6 | [templates.ocf.berkeley.edu](https://templates.ocf.berkeley.edu) 7 | for purposes such as sending requests for DNS to the University hostmaster, 8 | responding to virtual host requests, and resetting alumni account passwords. 9 | Templates should be used when applicable because they are designed to provide 10 | all necessary information while remaining cordial to the recipient. 11 | 12 | Some templates have variables that should be filled out before copying the 13 | template. The template variables will be automatically filled out by entering 14 | text into the input boxes above the main text box. Variables can be located in 15 | the template by looking for `{}` before filling it out. 16 | 17 | ## Adding templates 18 | 19 | New templates can be added to the website by submitting a pull request to the 20 | [ocf/templates](https://ocf.io/gh/templates) repo. Template files are found in 21 | `templates/www/templates`. Variables can be added in a template as 22 | `{}`. 23 | -------------------------------------------------------------------------------- /docs/staff/tips/testaccts.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Test accounts" 3 | --- 4 | 5 | There are a couple official test accounts: 6 | 7 | - `guser`: Test user account. Name stands for "guest user". 8 | - `ggroup`: Test group account. Name stands for "guest group". 9 | - `testgroupacct`: Another test group account. Originally created to test 10 | usernames with length > 8 characters. 11 | - `gstaff`: Test staff account. Name stands for "guest staff". 12 | - `testopstaff`: Test opstaff account. 13 | - `ofc`: Test sorried account. 14 | -------------------------------------------------------------------------------- /gatsby-browser.tsx: -------------------------------------------------------------------------------- 1 | import { type GatsbyBrowser } from "gatsby" 2 | import { AuthProvider } from "react-oidc-context" 3 | import keycloakConfig from "~/utils/keycloak" 4 | import { SWRConfig, SWRConfiguration } from "swr" 5 | import "~/styles/inter.css" 6 | 7 | export const wrapRootElement: GatsbyBrowser["wrapRootElement"] = ({ 8 | element, 9 | }) => { 10 | const options: SWRConfiguration = { 11 | fetcher: (url: string) => { 12 | if (process.env.NODE_ENV === "production" && url.startsWith("/api")) { 13 | url = "https://api.ocf.berkeley.edu" + url.replace("/api", "") 14 | } 15 | return fetch(url).then((r) => r.json()) 16 | }, 17 | refreshInterval: 15 * 1000, // 15 seconds 18 | } 19 | 20 | const config = { 21 | ...keycloakConfig, 22 | redirect_uri: window.location.origin, 23 | } as typeof keycloakConfig 24 | 25 | return ( 26 | 27 | {element} 28 | 29 | ) 30 | } 31 | -------------------------------------------------------------------------------- /gatsby-config.ts: -------------------------------------------------------------------------------- 1 | import type { GatsbyConfig } from "gatsby" 2 | import { config as dotenv } from "dotenv" 3 | import { createProxyMiddleware } from "http-proxy-middleware" 4 | import type { Application as ExpressApp } from "express" 5 | import { API_HOST } from "./src/utils/api" 6 | 7 | dotenv({ 8 | path: `.env.${process.env.NODE_ENV ?? "development"}`, 9 | }) 10 | 11 | const config: GatsbyConfig = { 12 | siteMetadata: { 13 | title: `ocfstatic`, 14 | siteUrl: `https://new.ocf.berkeley.edu`, 15 | }, 16 | jsxRuntime: "automatic", 17 | plugins: [ 18 | { 19 | resolve: "@chakra-ui/gatsby-plugin", 20 | options: { 21 | /** 22 | * @property {boolean} [resetCSS=true] 23 | * if false, this plugin will not use ` 24 | */ 25 | resetCSS: true, 26 | }, 27 | }, 28 | ], 29 | developMiddleware: (app: ExpressApp) => { 30 | app.use( 31 | "/api", 32 | createProxyMiddleware({ 33 | target: API_HOST(), 34 | pathRewrite: { 35 | "^/api": "", 36 | }, 37 | changeOrigin: true, 38 | }), 39 | ) 40 | }, 41 | } 42 | 43 | export default config 44 | -------------------------------------------------------------------------------- /gatsby-env.d.ts: -------------------------------------------------------------------------------- 1 | declare module "*.svg" { 2 | declare const path: string 3 | export default path 4 | } 5 | -------------------------------------------------------------------------------- /gatsby-node.ts: -------------------------------------------------------------------------------- 1 | import type { GatsbyNode } from "gatsby" 2 | import path from "path" 3 | 4 | export const onCreateWebpackConfig: GatsbyNode["onCreateWebpackConfig"] = ({ 5 | actions, 6 | }) => { 7 | actions.setWebpackConfig({ 8 | resolve: { 9 | alias: { 10 | "~": path.resolve(__dirname, "/src"), 11 | }, 12 | fallback: { 13 | assert: false, 14 | crypto: false, 15 | http: false, 16 | https: false, 17 | os: false, 18 | path: false, 19 | querystring: false, 20 | stream: false, 21 | url: false, 22 | util: false, 23 | zlib: false, 24 | }, 25 | }, 26 | }) 27 | } 28 | -------------------------------------------------------------------------------- /gatsby-ssr.tsx: -------------------------------------------------------------------------------- 1 | import type { GatsbyBrowser } from "gatsby" 2 | import { AuthProvider } from "react-oidc-context" 3 | import keycloakConfig from "~/utils/keycloak" 4 | 5 | export const wrapRootElement: GatsbyBrowser["wrapRootElement"] = ({ 6 | element, 7 | }) => {element} 8 | -------------------------------------------------------------------------------- /kubernetes/ocfstatic-previews.yml.erb: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | name: ocfstatic-previews-service 5 | spec: 6 | selector: 7 | app: ocfstatic-previews 8 | ports: 9 | - port: 80 10 | targetPort: 80 11 | --- 12 | apiVersion: apps/v1 13 | kind: Deployment 14 | metadata: 15 | name: ocfstatic-previews-deployment 16 | labels: 17 | app: ocfstatic-previews 18 | spec: 19 | replicas: 1 20 | selector: 21 | matchLabels: 22 | app: ocfstatic-previews 23 | template: 24 | metadata: 25 | labels: 26 | app: ocfstatic-previews 27 | spec: 28 | containers: 29 | - name: ocfstatic-previews 30 | image: "docker.ocf.berkeley.edu/ocfstatic-previews:latest" 31 | resources: 32 | limits: 33 | memory: 256Mi 34 | cpu: 500m 35 | ports: 36 | - containerPort: 80 37 | volumeMounts: 38 | - mountPath: /var/www/ocfstatic 39 | name: ocfstatic-previews 40 | volumes: 41 | - name: ocfstatic-previews 42 | persistentVolumeClaim: 43 | claimName: ocfstatic-previews 44 | --- 45 | apiVersion: extensions/v1beta1 46 | kind: Ingress 47 | metadata: 48 | name: ocfstatic-previews-ingress 49 | spec: 50 | rules: 51 | - host: "*.new.ocf.berkeley.edu" 52 | http: 53 | paths: 54 | - backend: 55 | serviceName: ocfstatic-previews-service 56 | servicePort: 80 57 | --- 58 | apiVersion: v1 59 | kind: PersistentVolumeClaim 60 | metadata: 61 | name: ocfstatic-previews 62 | spec: 63 | accessModes: 64 | - ReadWriteMany 65 | resources: 66 | requests: 67 | storage: 4Gi 68 | storageClassName: managed-nfs-storage 69 | -------------------------------------------------------------------------------- /nginx.conf: -------------------------------------------------------------------------------- 1 | server { 2 | listen 80; 3 | listen [::]:80; 4 | server_name localhost; 5 | 6 | #access_log /var/log/nginx/host.access.log main; 7 | 8 | location / { 9 | root /usr/share/nginx/html; 10 | index index.html index.htm; 11 | } 12 | 13 | error_page 404 /404.html; 14 | 15 | # redirect server error pages to the static page /50x.html 16 | # 17 | error_page 500 502 503 504 /50x.html; 18 | location = /50x.html { 19 | root /usr/share/nginx/html; 20 | } 21 | 22 | # proxy the PHP scripts to Apache listening on 127.0.0.1:80 23 | # 24 | #location ~ \.php$ { 25 | # proxy_pass http://127.0.0.1; 26 | #} 27 | 28 | # pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000 29 | # 30 | #location ~ \.php$ { 31 | # root html; 32 | # fastcgi_pass 127.0.0.1:9000; 33 | # fastcgi_index index.php; 34 | # fastcgi_param SCRIPT_FILENAME /scripts$fastcgi_script_name; 35 | # include fastcgi_params; 36 | #} 37 | 38 | # deny access to .htaccess files, if Apache's document root 39 | # concurs with nginx's one 40 | # 41 | #location ~ /\.ht { 42 | # deny all; 43 | #} 44 | } -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "ocfstatic", 3 | "version": "0.1.0", 4 | "private": true, 5 | "description": "The main OCF website", 6 | "author": "The Open Computing Facility ", 7 | "keywords": [ 8 | "gatsby" 9 | ], 10 | "scripts": { 11 | "develop": "gatsby develop", 12 | "start": "gatsby develop", 13 | "build": "gatsby build", 14 | "serve": "gatsby serve", 15 | "clean": "gatsby clean", 16 | "lint": "eslint --cache .", 17 | "format": "prettier -w .", 18 | "typecheck": "tsc --noEmit", 19 | "postinstall": "husky install", 20 | "updateapi": "openapi-typescript https://api.ocf.berkeley.edu/openapi.json -o src/definitions/ocfapi.ts -c .prettierrc.json" 21 | }, 22 | "dependencies": { 23 | "@chakra-ui/gatsby-plugin": "^3.1.3", 24 | "@chakra-ui/icons": "^2.1.1", 25 | "@chakra-ui/react": "^2.8.1", 26 | "@chakra-ui/system": "^2.6.1", 27 | "@emotion/react": "^11.11.1", 28 | "@emotion/styled": "^11.11.0", 29 | "framer-motion": "^10.16.4", 30 | "gatsby": "^5.12.5", 31 | "gatsby-plugin-emotion": "^8.12.0", 32 | "gatsby-source-filesystem": "^5.12.0", 33 | "gatsby-transformer-remark": "^6.12.0", 34 | "keycloak-js": "^22.0.3", 35 | "oidc-client-ts": "^2.2.5", 36 | "react": "^18.2.0", 37 | "react-dom": "^18.2.0", 38 | "react-oidc-context": "^2.3.0", 39 | "swr": "^2.2.4", 40 | "type-fest": "^4.3.2" 41 | }, 42 | "devDependencies": { 43 | "@types/express": "^4.17.18", 44 | "@types/node": "^18.11.9", 45 | "@types/react": "^18.2.23", 46 | "@types/react-dom": "^18.2.8", 47 | "@typescript-eslint/eslint-plugin": "^6.7.3", 48 | "@typescript-eslint/parser": "^6.7.3", 49 | "dotenv": "^16.3.1", 50 | "eslint": "^8.50.0", 51 | "eslint-config-prettier": "^9.0.0", 52 | "eslint-import-resolver-typescript": "^3.6.1", 53 | "eslint-plugin-import": "^2.28.1", 54 | "eslint-plugin-jsx-a11y": "^6.7.1", 55 | "eslint-plugin-prettier": "^5.0.0", 56 | "eslint-plugin-react": "^7.33.2", 57 | "eslint-plugin-react-hooks": "^4.6.0", 58 | "http-proxy-middleware": "^2.0.6", 59 | "husky": "^8.0.3", 60 | "lint-staged": "^14.0.1", 61 | "openapi-typescript": "^6.7.0", 62 | "prettier": "3.0.3", 63 | "typescript": "5.2.2" 64 | }, 65 | "packageManager": "yarn@3.6.3" 66 | } 67 | -------------------------------------------------------------------------------- /src/@chakra-ui/gatsby-plugin/theme.ts: -------------------------------------------------------------------------------- 1 | import { extendTheme } from "@chakra-ui/react" 2 | 3 | const theme = { 4 | colors: { 5 | primary: "#68b4d3", 6 | gray: { 7 | 50: "#fafafa", 8 | 100: "#f5f5f5", 9 | 200: "#e5e5e5", 10 | 300: "#d4d4d4", 11 | 400: "#a3a3a3", 12 | 500: "#737373", 13 | 600: "#525252", 14 | 700: "#404040", 15 | 800: "#262626", 16 | 900: "#171717", 17 | }, 18 | }, 19 | components: { 20 | Link: { 21 | baseStyle: { 22 | textDecoration: "underline", 23 | _hover: { 24 | opacity: "75%", 25 | }, 26 | }, 27 | }, 28 | }, 29 | fonts: { 30 | heading: `'Inter var', sans-serif`, 31 | body: `'Inter var', sans-serif`, 32 | }, 33 | styles: { 34 | global: () => ({ 35 | body: { 36 | bg: "#fafafa", 37 | }, 38 | }), 39 | }, 40 | } 41 | 42 | export default extendTheme(theme) 43 | -------------------------------------------------------------------------------- /src/components/Footer.tsx: -------------------------------------------------------------------------------- 1 | import { Text, Flex } from "@chakra-ui/react" 2 | import FullWidthBox from "~/components/FullWidthBox" 3 | 4 | const Footer = () => { 5 | return ( 6 | 7 | 13 | 14 | Donate to the OCF 15 | 16 | Board Meeting Minutes 17 | 18 | Official Documents 19 | Privacy Policy 20 | 21 | 27 | 28 | The Open Computing Facility is run entirely by student volunteers. 29 | 30 | 31 | Copyright © 1989–2022 Board of Directors of the Open Computing 32 | Facility. 33 | 34 | 35 | The Open Computing Facility is a Chartered Program of the ASUC. 36 | 37 | 38 | 39 | 40 | ) 41 | } 42 | 43 | export default Footer 44 | -------------------------------------------------------------------------------- /src/components/FullWidthBox.tsx: -------------------------------------------------------------------------------- 1 | import { Box, forwardRef, type BoxProps } from "@chakra-ui/react" 2 | 3 | const FullWidthBox = forwardRef( 4 | ({ children, maxW = "7xl", ...rest }, ref) => { 5 | return ( 6 | 13 | 14 | {children} 15 | 16 | 17 | ) 18 | }, 19 | ) 20 | 21 | export default FullWidthBox 22 | -------------------------------------------------------------------------------- /src/components/InternalLink.tsx: -------------------------------------------------------------------------------- 1 | import { 2 | Link as ChakraLink, 3 | LinkProps as ChakraLinkProps, 4 | } from "@chakra-ui/react" 5 | import { GatsbyLinkProps, Link as GatsbyLink } from "gatsby" 6 | 7 | export type InternalLinkProps = GatsbyLinkProps & 8 | Omit 9 | 10 | const InternalLink = ({ to, ...props }: InternalLinkProps) => ( 11 | 12 | ) 13 | 14 | export default InternalLink 15 | -------------------------------------------------------------------------------- /src/components/Layout.tsx: -------------------------------------------------------------------------------- 1 | import { ReactNode } from "react" 2 | import { Box } from "@chakra-ui/react" 3 | 4 | const Layout = ({ 5 | children, 6 | maxW = "7xl", 7 | }: { 8 | children: ReactNode 9 | maxW?: string 10 | }) => { 11 | return ( 12 | 19 | 31 | {children} 32 | 33 | 34 | ) 35 | } 36 | 37 | export default Layout 38 | -------------------------------------------------------------------------------- /src/components/Logo.css: -------------------------------------------------------------------------------- 1 | .logo { 2 | max-width: 700px; 3 | } 4 | .o { 5 | fill-opacity: 0; 6 | stroke-dasharray: 1294 1296; 7 | stroke-dashoffset: 1295; 8 | animation: 9 | drawStroke 1000ms ease 0ms forwards, 10 | fadeStroke 250ms linear 1500ms forwards, 11 | fillPath 250ms linear 1500ms forwards; 12 | } 13 | .c { 14 | fill-opacity: 0; 15 | stroke-dasharray: 1053 1055; 16 | stroke-dashoffset: 1054; 17 | animation: 18 | drawStroke 1000ms ease 250ms forwards, 19 | fadeStroke 250ms linear 1500ms forwards, 20 | fillPath 250ms linear 1500ms forwards; 21 | } 22 | .f { 23 | fill-opacity: 0; 24 | stroke-dasharray: 949 951; 25 | stroke-dashoffset: 950; 26 | animation: 27 | drawStroke 1000ms ease 500ms forwards, 28 | fadeStroke 250ms linear 1500ms forwards, 29 | fillPath 250ms linear 1500ms forwards; 30 | } 31 | @keyframes drawStroke { 32 | 100% { 33 | stroke-dashoffset: 0; 34 | } 35 | } 36 | @keyframes fillPath { 37 | from { 38 | fill-opacity: 0; 39 | } 40 | to { 41 | fill-opacity: 1; 42 | } 43 | } 44 | @keyframes fadeStroke { 45 | to { 46 | stroke-opacity: 0; 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /src/components/Logo.tsx: -------------------------------------------------------------------------------- 1 | import { useId } from "react" 2 | 3 | import "~/components/Logo.css" 4 | 5 | export type LogoProps = { 6 | height?: number 7 | width?: number 8 | animated?: boolean 9 | } 10 | 11 | const Logo = ({ height, width, animated }: LogoProps) => { 12 | const id = useId() 13 | 14 | return ( 15 | 22 | 29 | 36 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | ) 51 | } 52 | 53 | export default Logo 54 | -------------------------------------------------------------------------------- /src/components/NavbarButton.tsx: -------------------------------------------------------------------------------- 1 | import { 2 | Button, 3 | ButtonProps, 4 | forwardRef, 5 | Link as ChakraLink, 6 | } from "@chakra-ui/react" 7 | import InternalLink from "./InternalLink" 8 | 9 | export type NavbarButtonProps = { 10 | href?: string 11 | } 12 | 13 | const NavbarButton = forwardRef( 14 | ({ href, ...rest }, ref) => { 15 | return ( 16 | 13 | 14 | 15 | 16 | ) 17 | } 18 | 19 | export default NotFoundPage 20 | 21 | export const Head = () => 22 | -------------------------------------------------------------------------------- /src/pages/about/lab.tsx: -------------------------------------------------------------------------------- 1 | import { Box } from "@chakra-ui/react" 2 | import { SEO } from "~/components/SEO" 3 | 4 | const AboutLabPage = () => { 5 | return page content 6 | } 7 | 8 | export default AboutLabPage 9 | 10 | export const Head = () => 11 | -------------------------------------------------------------------------------- /src/pages/about/staff.tsx: -------------------------------------------------------------------------------- 1 | import { Box } from "@chakra-ui/react" 2 | import { SEO } from "~/components/SEO" 3 | 4 | const AboutStaffPage = () => { 5 | return page content 6 | } 7 | 8 | export default AboutStaffPage 9 | 10 | export const Head = () => 11 | -------------------------------------------------------------------------------- /src/pages/account/index.tsx: -------------------------------------------------------------------------------- 1 | import { Box } from "@chakra-ui/react" 2 | import { SEO } from "~/components/SEO" 3 | 4 | const AccountDashboardPage = () => { 5 | return page content 6 | } 7 | 8 | export default AccountDashboardPage 9 | 10 | export const Head = () => 11 | -------------------------------------------------------------------------------- /src/pages/account/password.tsx: -------------------------------------------------------------------------------- 1 | import { Box } from "@chakra-ui/react" 2 | import { SEO } from "~/components/SEO" 3 | 4 | const AccountPasswordPage = () => { 5 | return page content 6 | } 7 | 8 | export default AccountPasswordPage 9 | 10 | export const Head = () => 11 | -------------------------------------------------------------------------------- /src/pages/account/register.tsx: -------------------------------------------------------------------------------- 1 | import { Box } from "@chakra-ui/react" 2 | import { SEO } from "~/components/SEO" 3 | 4 | const AccountRegisterPage = () => { 5 | return page content 6 | } 7 | 8 | export default AccountRegisterPage 9 | 10 | export const Head = () => 11 | -------------------------------------------------------------------------------- /src/pages/auth/calnet/callback.tsx: -------------------------------------------------------------------------------- 1 | import { Box } from "@chakra-ui/react" 2 | import { navigate, type PageProps } from "gatsby" 3 | import { useEffect } from "react" 4 | import { SEO } from "~/components/SEO" 5 | 6 | const CalNetAuthCallbackPage = ({ location }: PageProps) => { 7 | useEffect(() => { 8 | const params = new URLSearchParams(location.search) 9 | const next = params.get("next") || "/" 10 | navigate(next)?.catch(console.error) 11 | // we only want this to effect to run once on page load 12 | // eslint-disable-next-line react-hooks/exhaustive-deps 13 | }, []) 14 | 15 | return ( 16 | 17 | Authenticating with CalNet... 18 | 19 | ) 20 | } 21 | 22 | export default CalNetAuthCallbackPage 23 | 24 | export const Head = () => 25 | -------------------------------------------------------------------------------- /src/pages/auth/calnet/index.tsx: -------------------------------------------------------------------------------- 1 | import { Box } from "@chakra-ui/react" 2 | import { type PageProps } from "gatsby" 3 | import { useEffect } from "react" 4 | import { SEO } from "~/components/SEO" 5 | import { API_HOST } from "~/utils/api" 6 | 7 | interface LocationState { 8 | next: string 9 | } 10 | 11 | const CalNetAuthPage = ({ location }: PageProps) => { 12 | useEffect(() => { 13 | const next = location.state?.next || "/" 14 | window.location.href = `${API_HOST()}/auth/calnet?next=${encodeURIComponent( 15 | window.location.origin + 16 | "/auth/calnet/callback?next=" + 17 | encodeURIComponent(next), 18 | )}` 19 | // we only want this to effect to run once on page load 20 | // eslint-disable-next-line react-hooks/exhaustive-deps 21 | }, []) 22 | 23 | return ( 24 | 25 | Redirecting to CalNet... 26 | 27 | ) 28 | } 29 | 30 | export default CalNetAuthPage 31 | 32 | export const Head = () => 33 | -------------------------------------------------------------------------------- /src/pages/staff-hours.tsx: -------------------------------------------------------------------------------- 1 | import { Box } from "@chakra-ui/react" 2 | import { SEO } from "~/components/SEO" 3 | 4 | const StaffHoursPage = () => { 5 | return page content 6 | } 7 | 8 | export default StaffHoursPage 9 | 10 | export const Head = () => 11 | -------------------------------------------------------------------------------- /src/pages/stats.tsx: -------------------------------------------------------------------------------- 1 | import { Box } from "@chakra-ui/react" 2 | import { SEO } from "~/components/SEO" 3 | 4 | const StatsPage = () => { 5 | return page content 6 | } 7 | 8 | export default StatsPage 9 | 10 | export const Head = () => 11 | -------------------------------------------------------------------------------- /src/styles/inter.css: -------------------------------------------------------------------------------- 1 | @font-face { 2 | font-family: "Inter var"; 3 | font-weight: 100 900; 4 | font-display: swap; 5 | font-style: normal; 6 | font-named-instance: "Regular"; 7 | src: url("/assets/Inter-roman.var.woff2?v=3.19") format("woff2"); 8 | } 9 | @font-face { 10 | font-family: "Inter var"; 11 | font-weight: 100 900; 12 | font-display: swap; 13 | font-style: italic; 14 | font-named-instance: "Italic"; 15 | src: url("/assets/Inter-italic.var.woff2?v=3.19") format("woff2"); 16 | } 17 | -------------------------------------------------------------------------------- /src/utils/cookie.ts: -------------------------------------------------------------------------------- 1 | export const getCookie = (key: string): string => { 2 | if (typeof document === "undefined") return "" 3 | 4 | return document?.cookie.split("; ").reduce((total, currentCookie) => { 5 | const item = currentCookie.split("=") 6 | const storedKey = item[0] 7 | const storedValue = item[1] 8 | 9 | return key === storedKey ? decodeURIComponent(storedValue) : total 10 | }, "") 11 | } 12 | -------------------------------------------------------------------------------- /src/utils/keycloak.ts: -------------------------------------------------------------------------------- 1 | import { type KeycloakTokenParsed } from "keycloak-js" 2 | import { type AuthProviderProps } from "react-oidc-context" 3 | 4 | const keycloakConfig = { 5 | authority: "https://auth.ocf.berkeley.edu/auth/realms/ocf", 6 | client_id: "ocfstatic", 7 | } as AuthProviderProps 8 | 9 | export default keycloakConfig 10 | 11 | export interface OCFKeycloakToken extends KeycloakTokenParsed { 12 | auth_time: number 13 | scope: string 14 | email_verified: boolean 15 | name: string 16 | preferred_username: string 17 | given_name: string 18 | email: string 19 | } 20 | -------------------------------------------------------------------------------- /static/assets/Inter-italic.var.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ocf/ocfstatic/8b851f51b2614c669ffdc42df99ef0bfe48a5064/static/assets/Inter-italic.var.woff2 -------------------------------------------------------------------------------- /static/assets/Inter-roman.var.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ocf/ocfstatic/8b851f51b2614c669ffdc42df99ef0bfe48a5064/static/assets/Inter-roman.var.woff2 -------------------------------------------------------------------------------- /static/assets/img/actions/event.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ocf/ocfstatic/8b851f51b2614c669ffdc42df99ef0bfe48a5064/static/assets/img/actions/event.jpg -------------------------------------------------------------------------------- /static/assets/img/actions/webdev.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ocf/ocfstatic/8b851f51b2614c669ffdc42df99ef0bfe48a5064/static/assets/img/actions/webdev.jpg -------------------------------------------------------------------------------- /static/assets/img/cloud.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ocf/ocfstatic/8b851f51b2614c669ffdc42df99ef0bfe48a5064/static/assets/img/cloud.jpg -------------------------------------------------------------------------------- /static/assets/img/computer-lab-clipart.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ocf/ocfstatic/8b851f51b2614c669ffdc42df99ef0bfe48a5064/static/assets/img/computer-lab-clipart.jpg -------------------------------------------------------------------------------- /static/assets/img/favicon/favicon-16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ocf/ocfstatic/8b851f51b2614c669ffdc42df99ef0bfe48a5064/static/assets/img/favicon/favicon-16.png -------------------------------------------------------------------------------- /static/assets/img/favicon/favicon-32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ocf/ocfstatic/8b851f51b2614c669ffdc42df99ef0bfe48a5064/static/assets/img/favicon/favicon-32.png -------------------------------------------------------------------------------- /static/assets/img/hero.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ocf/ocfstatic/8b851f51b2614c669ffdc42df99ef0bfe48a5064/static/assets/img/hero.jpg -------------------------------------------------------------------------------- /static/assets/img/lab_and_printing.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ocf/ocfstatic/8b851f51b2614c669ffdc42df99ef0bfe48a5064/static/assets/img/lab_and_printing.png -------------------------------------------------------------------------------- /static/assets/img/nikitpenguin.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ocf/ocfstatic/8b851f51b2614c669ffdc42df99ef0bfe48a5064/static/assets/img/nikitpenguin.png -------------------------------------------------------------------------------- /static/assets/img/penguin-sticker.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ocf/ocfstatic/8b851f51b2614c669ffdc42df99ef0bfe48a5064/static/assets/img/penguin-sticker.png -------------------------------------------------------------------------------- /static/assets/img/printer.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ocf/ocfstatic/8b851f51b2614c669ffdc42df99ef0bfe48a5064/static/assets/img/printer.jpg -------------------------------------------------------------------------------- /static/assets/img/techsupport.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ocf/ocfstatic/8b851f51b2614c669ffdc42df99ef0bfe48a5064/static/assets/img/techsupport.png -------------------------------------------------------------------------------- /static/assets/img/unix-shell.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ocf/ocfstatic/8b851f51b2614c669ffdc42df99ef0bfe48a5064/static/assets/img/unix-shell.jpg -------------------------------------------------------------------------------- /static/docs/.nojekyll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ocf/ocfstatic/8b851f51b2614c669ffdc42df99ef0bfe48a5064/static/docs/.nojekyll -------------------------------------------------------------------------------- /static/docs/assets/js/0223ccf0.9cb6fc13.js: -------------------------------------------------------------------------------- 1 | "use strict";(self.webpackChunkdocusaurus=self.webpackChunkdocusaurus||[]).push([[9161],{3905:(e,t,r)=>{r.d(t,{Zo:()=>p,kt:()=>d});var n=r(7294);function c(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function o(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function a(e){for(var t=1;t=0||(c[r]=e[r]);return c}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(c[r]=e[r])}return c}var s=n.createContext({}),i=function(e){var t=n.useContext(s),r=t;return e&&(r="function"==typeof e?e(t):a(a({},t),e)),r},p=function(e){var t=i(e.components);return n.createElement(s.Provider,{value:t},e.children)},l={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},f=n.forwardRef((function(e,t){var r=e.components,c=e.mdxType,o=e.originalType,s=e.parentName,p=u(e,["components","mdxType","originalType","parentName"]),f=i(r),d=c,m=f["".concat(s,".").concat(d)]||f[d]||l[d]||o;return r?n.createElement(m,a(a({ref:t},p),{},{components:r})):n.createElement(m,a({ref:t},p))}));function d(e,t){var r=arguments,c=t&&t.mdxType;if("string"==typeof e||c){var o=r.length,a=new Array(o);a[0]=f;var u={};for(var s in t)hasOwnProperty.call(t,s)&&(u[s]=t[s]);u.originalType=e,u.mdxType="string"==typeof e?e:c,a[1]=u;for(var i=2;i{r.r(t),r.d(t,{assets:()=>s,contentTitle:()=>a,default:()=>l,frontMatter:()=>o,metadata:()=>u,toc:()=>i});var n=r(7462),c=(r(7294),r(3905));const o={title:"Accounts"},a=void 0,u={unversionedId:"staff/procedures/accounts/accounts",id:"staff/procedures/accounts/accounts",title:"Accounts",description:"Create pages under this directory to document account procedures.",source:"@site/docs/staff/procedures/accounts/accounts.md",sourceDirName:"staff/procedures/accounts",slug:"/staff/procedures/accounts/",permalink:"/docs/staff/procedures/accounts/",draft:!1,editUrl:"https://github.com/facebook/docusaurus/tree/main/packages/create-docusaurus/templates/shared/docs/staff/procedures/accounts/accounts.md",tags:[],version:"current",frontMatter:{title:"Accounts"},sidebar:"tutorialSidebar",previous:{title:"Procedures",permalink:"/docs/staff/procedures/"},next:{title:"Alumni account reset",permalink:"/docs/staff/procedures/accounts/alumni-reset"}},s={},i=[{value:"Accounts map",id:"accounts-map",level:2}],p={toc:i};function l(e){let{components:t,...r}=e;return(0,c.kt)("wrapper",(0,n.Z)({},p,r,{components:t,mdxType:"MDXLayout"}),(0,c.kt)("p",null,"Create pages under this directory to document account procedures."),(0,c.kt)("h2",{id:"accounts-map"},"Accounts map"))}l.isMDXComponent=!0}}]); -------------------------------------------------------------------------------- /static/docs/assets/js/08326d2d.4ececd3e.js: -------------------------------------------------------------------------------- 1 | "use strict";(self.webpackChunkdocusaurus=self.webpackChunkdocusaurus||[]).push([[9317],{3769:u=>{u.exports=JSON.parse('{"name":"docusaurus-plugin-content-docs","id":"default"}')}}]); -------------------------------------------------------------------------------- /static/docs/assets/js/3bcf540a.2bdb8b67.js: -------------------------------------------------------------------------------- 1 | "use strict";(self.webpackChunkdocusaurus=self.webpackChunkdocusaurus||[]).push([[5536],{3905:(e,t,r)=>{r.d(t,{Zo:()=>u,kt:()=>f});var n=r(7294);function o(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function a(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function c(e){for(var t=1;t=0||(o[r]=e[r]);return o}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(o[r]=e[r])}return o}var s=n.createContext({}),l=function(e){var t=n.useContext(s),r=t;return e&&(r="function"==typeof e?e(t):c(c({},t),e)),r},u=function(e){var t=l(e.components);return n.createElement(s.Provider,{value:t},e.children)},p={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},d=n.forwardRef((function(e,t){var r=e.components,o=e.mdxType,a=e.originalType,s=e.parentName,u=i(e,["components","mdxType","originalType","parentName"]),d=l(r),f=o,m=d["".concat(s,".").concat(f)]||d[f]||p[f]||a;return r?n.createElement(m,c(c({ref:t},u),{},{components:r})):n.createElement(m,c({ref:t},u))}));function f(e,t){var r=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var a=r.length,c=new Array(a);c[0]=d;var i={};for(var s in t)hasOwnProperty.call(t,s)&&(i[s]=t[s]);i.originalType=e,i.mdxType="string"==typeof e?e:o,c[1]=i;for(var l=2;l{r.r(t),r.d(t,{assets:()=>s,contentTitle:()=>c,default:()=>p,frontMatter:()=>a,metadata:()=>i,toc:()=>l});var n=r(7462),o=(r(7294),r(3905));const a={title:"Charter"},c=void 0,i={unversionedId:"internal/docs/charter",id:"internal/docs/charter",title:"Charter",description:"The OCF is an ASUC Chartered Program; the authoritative text of its charter can",source:"@site/docs/internal/docs/charter.md",sourceDirName:"internal/docs",slug:"/internal/docs/charter",permalink:"/docs/internal/docs/charter",draft:!1,editUrl:"https://github.com/facebook/docusaurus/tree/main/packages/create-docusaurus/templates/shared/docs/internal/docs/charter.md",tags:[],version:"current",frontMatter:{title:"Charter"},sidebar:"tutorialSidebar",previous:{title:"Old constitution (1989\u20132016)",permalink:"/docs/internal/docs/archive/constitution"},next:{title:"Operating Rules",permalink:"/docs/internal/docs/operatingrules/"}},s={},l=[],u={toc:l};function p(e){let{components:t,...r}=e;return(0,o.kt)("wrapper",(0,n.Z)({},u,r,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("p",null,"The OCF is an ASUC Chartered Program; the authoritative text of its charter can\nbe found at ",(0,o.kt)("a",{parentName:"p",href:"https://docs.google.com/document/d/1bZhThJoNRUFOAX_gntXd4fgUSZkmfvCbOCr8p5Am75s/"},"section\n3204"),"\nof the ASUC bylaws."))}p.isMDXComponent=!0}}]); -------------------------------------------------------------------------------- /static/docs/assets/js/40223539.f939981c.js: -------------------------------------------------------------------------------- 1 | "use strict";(self.webpackChunkdocusaurus=self.webpackChunkdocusaurus||[]).push([[3178],{3905:(e,t,r)=>{r.d(t,{Zo:()=>l,kt:()=>d});var n=r(7294);function a(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function o(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function c(e){for(var t=1;t=0||(a[r]=e[r]);return a}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(a[r]=e[r])}return a}var i=n.createContext({}),u=function(e){var t=n.useContext(i),r=t;return e&&(r="function"==typeof e?e(t):c(c({},t),e)),r},l=function(e){var t=u(e.components);return n.createElement(i.Provider,{value:t},e.children)},p={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},f=n.forwardRef((function(e,t){var r=e.components,a=e.mdxType,o=e.originalType,i=e.parentName,l=s(e,["components","mdxType","originalType","parentName"]),f=u(r),d=a,b=f["".concat(i,".").concat(d)]||f[d]||p[d]||o;return r?n.createElement(b,c(c({ref:t},l),{},{components:r})):n.createElement(b,c({ref:t},l))}));function d(e,t){var r=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var o=r.length,c=new Array(o);c[0]=f;var s={};for(var i in t)hasOwnProperty.call(t,i)&&(s[i]=t[i]);s.originalType=e,s.mdxType="string"==typeof e?e:a,c[1]=s;for(var u=2;u{r.r(t),r.d(t,{assets:()=>i,contentTitle:()=>c,default:()=>p,frontMatter:()=>o,metadata:()=>s,toc:()=>u});var n=r(7462),a=(r(7294),r(3905));const o={title:"Infrastructure"},c=void 0,s={unversionedId:"staff/backend/backend",id:"staff/backend/backend",title:"Infrastructure",description:"Many parts of the OCF are not exposed to users. This section will shed light on",source:"@site/docs/staff/backend/backend.md",sourceDirName:"staff/backend",slug:"/staff/backend/",permalink:"/docs/staff/backend/",draft:!1,editUrl:"https://github.com/facebook/docusaurus/tree/main/packages/create-docusaurus/templates/shared/docs/staff/backend/backend.md",tags:[],version:"current",frontMatter:{title:"Infrastructure"},sidebar:"tutorialSidebar",previous:{title:"XMPP",permalink:"/docs/services/xmpp"},next:{title:"Backups",permalink:"/docs/staff/backend/backups"}},i={},u=[],l={toc:u};function p(e){let{components:t,...r}=e;return(0,a.kt)("wrapper",(0,n.Z)({},l,r,{components:t,mdxType:"MDXLayout"}),(0,a.kt)("p",null,"Many parts of the OCF are not exposed to users. This section will shed light on\nsome of those details."))}p.isMDXComponent=!0}}]); -------------------------------------------------------------------------------- /static/docs/assets/js/4972.6526eff4.js: -------------------------------------------------------------------------------- 1 | "use strict";(self.webpackChunkdocusaurus=self.webpackChunkdocusaurus||[]).push([[4972],{4972:(e,t,a)=>{a.r(t),a.d(t,{default:()=>c});var n=a(7294),l=a(5999),o=a(1944),r=a(8499);function c(){return n.createElement(n.Fragment,null,n.createElement(o.d,{title:(0,l.I)({id:"theme.NotFound.title",message:"Page Not Found"})}),n.createElement(r.Z,null,n.createElement("main",{className:"container margin-vert--xl"},n.createElement("div",{className:"row"},n.createElement("div",{className:"col col--6 col--offset-3"},n.createElement("h1",{className:"hero__title"},n.createElement(l.Z,{id:"theme.NotFound.title",description:"The title of the 404 page"},"Page Not Found")),n.createElement("p",null,n.createElement(l.Z,{id:"theme.NotFound.p1",description:"The first paragraph of the 404 page"},"We could not find what you were looking for.")),n.createElement("p",null,n.createElement(l.Z,{id:"theme.NotFound.p2",description:"The 2nd paragraph of the 404 page"},"Please contact the owner of the site that linked you to the original URL and let them know their link is broken.")))))))}}}]); -------------------------------------------------------------------------------- /static/docs/assets/js/59d1205d.6b0491d5.js: -------------------------------------------------------------------------------- 1 | "use strict";(self.webpackChunkdocusaurus=self.webpackChunkdocusaurus||[]).push([[7954],{3905:(e,t,r)=>{r.d(t,{Zo:()=>s,kt:()=>f});var n=r(7294);function a(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function o(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function i(e){for(var t=1;t=0||(a[r]=e[r]);return a}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(a[r]=e[r])}return a}var l=n.createContext({}),c=function(e){var t=n.useContext(l),r=t;return e&&(r="function"==typeof e?e(t):i(i({},t),e)),r},s=function(e){var t=c(e.components);return n.createElement(l.Provider,{value:t},e.children)},p={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},d=n.forwardRef((function(e,t){var r=e.components,a=e.mdxType,o=e.originalType,l=e.parentName,s=u(e,["components","mdxType","originalType","parentName"]),d=c(r),f=a,b=d["".concat(l,".").concat(f)]||d[f]||p[f]||o;return r?n.createElement(b,i(i({ref:t},s),{},{components:r})):n.createElement(b,i({ref:t},s))}));function f(e,t){var r=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var o=r.length,i=new Array(o);i[0]=d;var u={};for(var l in t)hasOwnProperty.call(t,l)&&(u[l]=t[l]);u.originalType=e,u.mdxType="string"==typeof e?e:a,i[1]=u;for(var c=2;c{r.r(t),r.d(t,{assets:()=>l,contentTitle:()=>i,default:()=>p,frontMatter:()=>o,metadata:()=>u,toc:()=>c});var n=r(7462),a=(r(7294),r(3905));const o={title:"Rebuild"},i=void 0,u={unversionedId:"staff/rebuild/rebuild",id:"staff/rebuild/rebuild",title:"Rebuild",description:"The Great OCF Rebuild",source:"@site/docs/staff/rebuild/rebuild.md",sourceDirName:"staff/rebuild",slug:"/staff/rebuild/",permalink:"/docs/staff/rebuild/",draft:!1,editUrl:"https://github.com/facebook/docusaurus/tree/main/packages/create-docusaurus/templates/shared/docs/staff/rebuild/rebuild.md",tags:[],version:"current",frontMatter:{title:"Rebuild"},sidebar:"tutorialSidebar",previous:{title:"Manually creating XMPP accounts",permalink:"/docs/staff/procedures/xmpp"},next:{title:"Request Tracker",permalink:"/docs/staff/rebuild/rt"}},l={},c=[{value:"Rebuild map",id:"rebuild-map",level:2}],s={toc:c};function p(e){let{components:t,...r}=e;return(0,a.kt)("wrapper",(0,n.Z)({},s,r,{components:t,mdxType:"MDXLayout"}),(0,a.kt)("p",null,"The Great OCF Rebuild"),(0,a.kt)("h2",{id:"rebuild-map"},"Rebuild map"))}p.isMDXComponent=!0}}]); -------------------------------------------------------------------------------- /static/docs/assets/js/6d71ae9c.1cce7dcb.js: -------------------------------------------------------------------------------- 1 | "use strict";(self.webpackChunkdocusaurus=self.webpackChunkdocusaurus||[]).push([[3611],{3905:(e,r,t)=>{t.d(r,{Zo:()=>u,kt:()=>f});var n=t(7294);function o(e,r,t){return r in e?Object.defineProperty(e,r,{value:t,enumerable:!0,configurable:!0,writable:!0}):e[r]=t,e}function c(e,r){var t=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);r&&(n=n.filter((function(r){return Object.getOwnPropertyDescriptor(e,r).enumerable}))),t.push.apply(t,n)}return t}function a(e){for(var r=1;r=0||(o[t]=e[t]);return o}(e,r);if(Object.getOwnPropertySymbols){var c=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,t)&&(o[t]=e[t])}return o}var s=n.createContext({}),l=function(e){var r=n.useContext(s),t=r;return e&&(t="function"==typeof e?e(r):a(a({},r),e)),t},u=function(e){var r=l(e.components);return n.createElement(s.Provider,{value:r},e.children)},d={inlineCode:"code",wrapper:function(e){var r=e.children;return n.createElement(n.Fragment,{},r)}},p=n.forwardRef((function(e,r){var t=e.components,o=e.mdxType,c=e.originalType,s=e.parentName,u=i(e,["components","mdxType","originalType","parentName"]),p=l(t),f=o,m=p["".concat(s,".").concat(f)]||p[f]||d[f]||c;return t?n.createElement(m,a(a({ref:r},u),{},{components:t})):n.createElement(m,a({ref:r},u))}));function f(e,r){var t=arguments,o=r&&r.mdxType;if("string"==typeof e||o){var c=t.length,a=new Array(c);a[0]=p;var i={};for(var s in r)hasOwnProperty.call(r,s)&&(i[s]=r[s]);i.originalType=e,i.mdxType="string"==typeof e?e:o,a[1]=i;for(var l=2;l{t.r(r),t.d(r,{assets:()=>s,contentTitle:()=>a,default:()=>d,frontMatter:()=>c,metadata:()=>i,toc:()=>l});var n=t(7462),o=(t(7294),t(3905));const c={title:"Archived documents"},a=void 0,i={unversionedId:"internal/docs/archive/archive",id:"internal/docs/archive/archive",title:"Archived documents",description:"Here are older versions of official documents. Documents under this section are",source:"@site/docs/internal/docs/archive/archive.md",sourceDirName:"internal/docs/archive",slug:"/internal/docs/archive/",permalink:"/docs/internal/docs/archive/",draft:!1,editUrl:"https://github.com/facebook/docusaurus/tree/main/packages/create-docusaurus/templates/shared/docs/internal/docs/archive/archive.md",tags:[],version:"current",frontMatter:{title:"Archived documents"},sidebar:"tutorialSidebar",previous:{title:"Official documents",permalink:"/docs/internal/docs/"},next:{title:"Old constitution (1989\u20132016)",permalink:"/docs/internal/docs/archive/constitution"}},s={},l=[],u={toc:l};function d(e){let{components:r,...t}=e;return(0,o.kt)("wrapper",(0,n.Z)({},u,t,{components:r,mdxType:"MDXLayout"}),(0,o.kt)("p",null,"Here are older versions of official documents. Documents under this section are\nno longer in force."))}d.isMDXComponent=!0}}]); -------------------------------------------------------------------------------- /static/docs/assets/js/6f653e1f.75dc67dd.js: -------------------------------------------------------------------------------- 1 | "use strict";(self.webpackChunkdocusaurus=self.webpackChunkdocusaurus||[]).push([[588],{3905:(e,t,r)=>{r.d(t,{Zo:()=>u,kt:()=>d});var n=r(7294);function o(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function a(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function i(e){for(var t=1;t=0||(o[r]=e[r]);return o}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(o[r]=e[r])}return o}var c=n.createContext({}),p=function(e){var t=n.useContext(c),r=t;return e&&(r="function"==typeof e?e(t):i(i({},t),e)),r},u=function(e){var t=p(e.components);return n.createElement(c.Provider,{value:t},e.children)},f={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},l=n.forwardRef((function(e,t){var r=e.components,o=e.mdxType,a=e.originalType,c=e.parentName,u=s(e,["components","mdxType","originalType","parentName"]),l=p(r),d=o,m=l["".concat(c,".").concat(d)]||l[d]||f[d]||a;return r?n.createElement(m,i(i({ref:t},u),{},{components:r})):n.createElement(m,i({ref:t},u))}));function d(e,t){var r=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var a=r.length,i=new Array(a);i[0]=l;var s={};for(var c in t)hasOwnProperty.call(t,c)&&(s[c]=t[c]);s.originalType=e,s.mdxType="string"==typeof e?e:o,i[1]=s;for(var p=2;p{r.r(t),r.d(t,{assets:()=>c,contentTitle:()=>i,default:()=>f,frontMatter:()=>a,metadata:()=>s,toc:()=>p});var n=r(7462),o=(r(7294),r(3905));const a={title:"Tips and tricks"},i=void 0,s={unversionedId:"staff/tips/tips",id:"staff/tips/tips",title:"Tips and tricks",description:"This category includes bits of information that make the OCF easier and more",source:"@site/docs/staff/tips/tips.md",sourceDirName:"staff/tips",slug:"/staff/tips/",permalink:"/docs/staff/tips/",draft:!1,editUrl:"https://github.com/facebook/docusaurus/tree/main/packages/create-docusaurus/templates/shared/docs/staff/tips/tips.md",tags:[],version:"current",frontMatter:{title:"Tips and tricks"},sidebar:"tutorialSidebar",previous:{title:"Tech talks",permalink:"/docs/staff/techtalks"},next:{title:".desktoprc",permalink:"/docs/staff/tips/desktoprc"}},c={},p=[],u={toc:p};function f(e){let{components:t,...r}=e;return(0,o.kt)("wrapper",(0,n.Z)({},u,r,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("p",null,"This category includes bits of information that make the OCF easier and more\nfun to use."))}f.isMDXComponent=!0}}]); -------------------------------------------------------------------------------- /static/docs/assets/js/808596c7.44aa46df.js: -------------------------------------------------------------------------------- 1 | "use strict";(self.webpackChunkdocusaurus=self.webpackChunkdocusaurus||[]).push([[8832],{3905:(e,r,t)=>{t.d(r,{Zo:()=>i,kt:()=>f});var o=t(7294);function n(e,r,t){return r in e?Object.defineProperty(e,r,{value:t,enumerable:!0,configurable:!0,writable:!0}):e[r]=t,e}function c(e,r){var t=Object.keys(e);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);r&&(o=o.filter((function(r){return Object.getOwnPropertyDescriptor(e,r).enumerable}))),t.push.apply(t,o)}return t}function a(e){for(var r=1;r=0||(n[t]=e[t]);return n}(e,r);if(Object.getOwnPropertySymbols){var c=Object.getOwnPropertySymbols(e);for(o=0;o=0||Object.prototype.propertyIsEnumerable.call(e,t)&&(n[t]=e[t])}return n}var u=o.createContext({}),p=function(e){var r=o.useContext(u),t=r;return e&&(t="function"==typeof e?e(r):a(a({},r),e)),t},i=function(e){var r=p(e.components);return o.createElement(u.Provider,{value:r},e.children)},d={inlineCode:"code",wrapper:function(e){var r=e.children;return o.createElement(o.Fragment,{},r)}},l=o.forwardRef((function(e,r){var t=e.components,n=e.mdxType,c=e.originalType,u=e.parentName,i=s(e,["components","mdxType","originalType","parentName"]),l=p(t),f=n,m=l["".concat(u,".").concat(f)]||l[f]||d[f]||c;return t?o.createElement(m,a(a({ref:r},i),{},{components:t})):o.createElement(m,a({ref:r},i))}));function f(e,r){var t=arguments,n=r&&r.mdxType;if("string"==typeof e||n){var c=t.length,a=new Array(c);a[0]=l;var s={};for(var u in r)hasOwnProperty.call(r,u)&&(s[u]=r[u]);s.originalType=e,s.mdxType="string"==typeof e?e:n,a[1]=s;for(var p=2;p{t.r(r),t.d(r,{assets:()=>u,contentTitle:()=>a,default:()=>d,frontMatter:()=>c,metadata:()=>s,toc:()=>p});var o=t(7462),n=(t(7294),t(3905));const c={title:"Procedures"},a=void 0,s={unversionedId:"staff/procedures/procedures",id:"staff/procedures/procedures",title:"Procedures",description:"Create pages under this directory to document how to perform common procedures.",source:"@site/docs/staff/procedures/procedures.md",sourceDirName:"staff/procedures",slug:"/staff/procedures/",permalink:"/docs/staff/procedures/",draft:!1,editUrl:"https://github.com/facebook/docusaurus/tree/main/packages/create-docusaurus/templates/shared/docs/staff/procedures/procedures.md",tags:[],version:"current",frontMatter:{title:"Procedures"},sidebar:"tutorialSidebar",previous:{title:"Additional documentation",permalink:"/docs/staff/private"},next:{title:"Accounts",permalink:"/docs/staff/procedures/accounts/"}},u={},p=[{value:"Procedures map",id:"procedures-map",level:2}],i={toc:p};function d(e){let{components:r,...t}=e;return(0,n.kt)("wrapper",(0,o.Z)({},i,t,{components:r,mdxType:"MDXLayout"}),(0,n.kt)("p",null,"Create pages under this directory to document how to perform common procedures."),(0,n.kt)("h2",{id:"procedures-map"},"Procedures map"))}d.isMDXComponent=!0}}]); -------------------------------------------------------------------------------- /static/docs/assets/js/8c18e6b4.c9f87d0d.js: -------------------------------------------------------------------------------- 1 | "use strict";(self.webpackChunkdocusaurus=self.webpackChunkdocusaurus||[]).push([[4440],{3905:(e,t,r)=>{r.d(t,{Zo:()=>u,kt:()=>f});var n=r(7294);function o(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function c(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function a(e){for(var t=1;t=0||(o[r]=e[r]);return o}(e,t);if(Object.getOwnPropertySymbols){var c=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(o[r]=e[r])}return o}var l=n.createContext({}),s=function(e){var t=n.useContext(l),r=t;return e&&(r="function"==typeof e?e(t):a(a({},t),e)),r},u=function(e){var t=s(e.components);return n.createElement(l.Provider,{value:t},e.children)},p={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},d=n.forwardRef((function(e,t){var r=e.components,o=e.mdxType,c=e.originalType,l=e.parentName,u=i(e,["components","mdxType","originalType","parentName"]),d=s(r),f=o,m=d["".concat(l,".").concat(f)]||d[f]||p[f]||c;return r?n.createElement(m,a(a({ref:t},u),{},{components:r})):n.createElement(m,a({ref:t},u))}));function f(e,t){var r=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var c=r.length,a=new Array(c);a[0]=d;var i={};for(var l in t)hasOwnProperty.call(t,l)&&(i[l]=t[l]);i.originalType=e,i.mdxType="string"==typeof e?e:o,a[1]=i;for(var s=2;s{r.r(t),r.d(t,{assets:()=>l,contentTitle:()=>a,default:()=>p,frontMatter:()=>c,metadata:()=>i,toc:()=>s});var n=r(7462),o=(r(7294),r(3905));const c={title:"Official documents"},a=void 0,i={unversionedId:"internal/docs/docs",id:"internal/docs/docs",title:"Official documents",description:"Here are official documents relating to the Open Computing Facility.",source:"@site/docs/internal/docs/docs.md",sourceDirName:"internal/docs",slug:"/internal/docs/",permalink:"/docs/internal/docs/",draft:!1,editUrl:"https://github.com/facebook/docusaurus/tree/main/packages/create-docusaurus/templates/shared/docs/internal/docs/docs.md",tags:[],version:"current",frontMatter:{title:"Official documents"},sidebar:"tutorialSidebar",previous:{title:"Slack",permalink:"/docs/internal/contact/slack"},next:{title:"Archived documents",permalink:"/docs/internal/docs/archive/"}},l={},s=[],u={toc:s};function p(e){let{components:t,...r}=e;return(0,o.kt)("wrapper",(0,n.Z)({},u,r,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("p",null,"Here are official documents relating to the Open Computing Facility."))}p.isMDXComponent=!0}}]); -------------------------------------------------------------------------------- /static/docs/assets/js/c7ef5120.a843e22b.js: -------------------------------------------------------------------------------- 1 | "use strict";(self.webpackChunkdocusaurus=self.webpackChunkdocusaurus||[]).push([[9273],{3905:(e,t,r)=>{r.d(t,{Zo:()=>u,kt:()=>d});var n=r(7294);function o(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function a(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function s(e){for(var t=1;t=0||(o[r]=e[r]);return o}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(o[r]=e[r])}return o}var i=n.createContext({}),p=function(e){var t=n.useContext(i),r=t;return e&&(r="function"==typeof e?e(t):s(s({},t),e)),r},u=function(e){var t=p(e.components);return n.createElement(i.Provider,{value:t},e.children)},l={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},f=n.forwardRef((function(e,t){var r=e.components,o=e.mdxType,a=e.originalType,i=e.parentName,u=c(e,["components","mdxType","originalType","parentName"]),f=p(r),d=o,m=f["".concat(i,".").concat(d)]||f[d]||l[d]||a;return r?n.createElement(m,s(s({ref:t},u),{},{components:r})):n.createElement(m,s({ref:t},u))}));function d(e,t){var r=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var a=r.length,s=new Array(a);s[0]=f;var c={};for(var i in t)hasOwnProperty.call(t,i)&&(c[i]=t[i]);c.originalType=e,c.mdxType="string"==typeof e?e:o,s[1]=c;for(var p=2;p{r.r(t),r.d(t,{assets:()=>i,contentTitle:()=>s,default:()=>l,frontMatter:()=>a,metadata:()=>c,toc:()=>p});var n=r(7462),o=(r(7294),r(3905));const a={title:"Scripts"},s=void 0,c={unversionedId:"staff/scripts/scripts",id:"staff/scripts/scripts",title:"Scripts",description:"Create subpages under this category to document scripts/programs that are",source:"@site/docs/staff/scripts/scripts.md",sourceDirName:"staff/scripts",slug:"/staff/scripts/",permalink:"/docs/staff/scripts/",draft:!1,editUrl:"https://github.com/facebook/docusaurus/tree/main/packages/create-docusaurus/templates/shared/docs/staff/scripts/scripts.md",tags:[],version:"current",frontMatter:{title:"Scripts"},sidebar:"tutorialSidebar",previous:{title:"Request Tracker",permalink:"/docs/staff/rebuild/rt"},next:{title:"approve: record an OCF group account request",permalink:"/docs/staff/scripts/approve"}},i={},p=[],u={toc:p};function l(e){let{components:t,...r}=e;return(0,o.kt)("wrapper",(0,n.Z)({},u,r,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("p",null,"Create subpages under this category to document scripts/programs that are\ncommonly used in the OCF."))}l.isMDXComponent=!0}}]); -------------------------------------------------------------------------------- /static/docs/assets/js/d91d4969.9658fed2.js: -------------------------------------------------------------------------------- 1 | "use strict";(self.webpackChunkdocusaurus=self.webpackChunkdocusaurus||[]).push([[3829],{3905:(e,t,r)=>{r.d(t,{Zo:()=>u,kt:()=>d});var n=r(7294);function a(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function o(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function p(e){for(var t=1;t=0||(a[r]=e[r]);return a}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(a[r]=e[r])}return a}var s=n.createContext({}),i=function(e){var t=n.useContext(s),r=t;return e&&(r="function"==typeof e?e(t):p(p({},t),e)),r},u=function(e){var t=i(e.components);return n.createElement(s.Provider,{value:t},e.children)},f={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},l=n.forwardRef((function(e,t){var r=e.components,a=e.mdxType,o=e.originalType,s=e.parentName,u=c(e,["components","mdxType","originalType","parentName"]),l=i(r),d=a,m=l["".concat(s,".").concat(d)]||l[d]||f[d]||o;return r?n.createElement(m,p(p({ref:t},u),{},{components:r})):n.createElement(m,p({ref:t},u))}));function d(e,t){var r=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var o=r.length,p=new Array(o);p[0]=l;var c={};for(var s in t)hasOwnProperty.call(t,s)&&(c[s]=t[s]);c.originalType=e,c.mdxType="string"==typeof e?e:a,p[1]=c;for(var i=2;i{r.r(t),r.d(t,{assets:()=>s,contentTitle:()=>p,default:()=>f,frontMatter:()=>o,metadata:()=>c,toc:()=>i});var n=r(7462),a=(r(7294),r(3905));const o={title:"Puppet"},p=void 0,c={unversionedId:"staff/backend/puppet",id:"staff/backend/puppet",title:"Puppet",description:"The puppetmaster is lightning. Instructions on",source:"@site/docs/staff/backend/puppet.md",sourceDirName:"staff/backend",slug:"/staff/backend/puppet",permalink:"/docs/staff/backend/puppet",draft:!1,editUrl:"https://github.com/facebook/docusaurus/tree/main/packages/create-docusaurus/templates/shared/docs/staff/backend/puppet.md",tags:[],version:"current",frontMatter:{title:"Puppet"},sidebar:"tutorialSidebar",previous:{title:"Prometheus",permalink:"/docs/staff/backend/prometheus"},next:{title:"Request Tracker",permalink:"/docs/staff/backend/rt"}},s={},i=[],u={toc:i};function f(e){let{components:t,...r}=e;return(0,a.kt)("wrapper",(0,n.Z)({},u,r,{components:t,mdxType:"MDXLayout"}),(0,a.kt)("p",null,"The puppetmaster is ",(0,a.kt)("a",{parentName:"p",href:"/docs/staff/backend/servers"},"lightning"),". Instructions on\nmaking, testing, and deploying changes to Puppet are located at the ",(0,a.kt)("a",{parentName:"p",href:"https://github.com/ocf/puppet"},"Git\nrepository")," on GitHub."))}f.isMDXComponent=!0}}]); -------------------------------------------------------------------------------- /static/docs/assets/js/main.4f9c1481.js.LICENSE.txt: -------------------------------------------------------------------------------- 1 | /* 2 | object-assign 3 | (c) Sindre Sorhus 4 | @license MIT 5 | */ 6 | 7 | /* NProgress, (c) 2013, 2014 Rico Sta. Cruz - http://ricostacruz.com/nprogress 8 | * @license MIT */ 9 | 10 | /*! 11 | * lunr.Builder 12 | * Copyright (C) 2020 Oliver Nightingale 13 | */ 14 | 15 | /*! 16 | * lunr.Index 17 | * Copyright (C) 2020 Oliver Nightingale 18 | */ 19 | 20 | /*! 21 | * lunr.Pipeline 22 | * Copyright (C) 2020 Oliver Nightingale 23 | */ 24 | 25 | /*! 26 | * lunr.Set 27 | * Copyright (C) 2020 Oliver Nightingale 28 | */ 29 | 30 | /*! 31 | * lunr.TokenSet 32 | * Copyright (C) 2020 Oliver Nightingale 33 | */ 34 | 35 | /*! 36 | * lunr.Vector 37 | * Copyright (C) 2020 Oliver Nightingale 38 | */ 39 | 40 | /*! 41 | * lunr.stemmer 42 | * Copyright (C) 2020 Oliver Nightingale 43 | * Includes code from - http://tartarus.org/~martin/PorterStemmer/js.txt 44 | */ 45 | 46 | /*! 47 | * lunr.stopWordFilter 48 | * Copyright (C) 2020 Oliver Nightingale 49 | */ 50 | 51 | /*! 52 | * lunr.tokenizer 53 | * Copyright (C) 2020 Oliver Nightingale 54 | */ 55 | 56 | /*! 57 | * lunr.trimmer 58 | * Copyright (C) 2020 Oliver Nightingale 59 | */ 60 | 61 | /*! 62 | * lunr.utils 63 | * Copyright (C) 2020 Oliver Nightingale 64 | */ 65 | 66 | /*!*************************************************** 67 | * mark.js v8.11.1 68 | * https://markjs.io/ 69 | * Copyright (c) 2014–2018, Julian Kühnel 70 | * Released under the MIT license https://git.io/vwTVl 71 | *****************************************************/ 72 | 73 | /** 74 | * Prism: Lightweight, robust, elegant syntax highlighting 75 | * 76 | * @license MIT 77 | * @author Lea Verou 78 | * @namespace 79 | * @public 80 | */ 81 | 82 | /** 83 | * lunr - http://lunrjs.com - A bit like Solr, but much smaller and not as bright - 2.3.9 84 | * Copyright (C) 2020 Oliver Nightingale 85 | * @license MIT 86 | */ 87 | 88 | /** @license React v0.20.2 89 | * scheduler.production.min.js 90 | * 91 | * Copyright (c) Facebook, Inc. and its affiliates. 92 | * 93 | * This source code is licensed under the MIT license found in the 94 | * LICENSE file in the root directory of this source tree. 95 | */ 96 | 97 | /** @license React v16.13.1 98 | * react-is.production.min.js 99 | * 100 | * Copyright (c) Facebook, Inc. and its affiliates. 101 | * 102 | * This source code is licensed under the MIT license found in the 103 | * LICENSE file in the root directory of this source tree. 104 | */ 105 | 106 | /** @license React v17.0.2 107 | * react-dom.production.min.js 108 | * 109 | * Copyright (c) Facebook, Inc. and its affiliates. 110 | * 111 | * This source code is licensed under the MIT license found in the 112 | * LICENSE file in the root directory of this source tree. 113 | */ 114 | 115 | /** @license React v17.0.2 116 | * react.production.min.js 117 | * 118 | * Copyright (c) Facebook, Inc. and its affiliates. 119 | * 120 | * This source code is licensed under the MIT license found in the 121 | * LICENSE file in the root directory of this source tree. 122 | */ 123 | -------------------------------------------------------------------------------- /static/docs/img/docusaurus.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ocf/ocfstatic/8b851f51b2614c669ffdc42df99ef0bfe48a5064/static/docs/img/docusaurus.png -------------------------------------------------------------------------------- /static/docs/img/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ocf/ocfstatic/8b851f51b2614c669ffdc42df99ef0bfe48a5064/static/docs/img/favicon.ico -------------------------------------------------------------------------------- /static/keycloak.json: -------------------------------------------------------------------------------- 1 | { 2 | "realm": "ocf", 3 | "auth-server-url": "https://auth.ocf.berkeley.edu/auth/", 4 | "ssl-required": "external", 5 | "resource": "ocfstatic", 6 | "public-client": true, 7 | "verify-token-audience": true, 8 | "use-resource-role-mappings": true, 9 | "confidential-port": 0 10 | } 11 | -------------------------------------------------------------------------------- /static/silent-check-sso.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 6 | 7 | 8 | --------------------------------------------------------------------------------