Found 605 repositories(showing 30)
Sfedfcv
Skip to content github / docs Code Issues 80 Pull requests 35 Discussions Actions Projects 2 Security Insights Merge branch 'main' into 1862-Add-Travis-CI-migration-table 1862-Add-Travis-CI-migration-table (#1869, Iixixi/ZachryTylerWood#102, THEBOLCK79/docs#1, sbnbhk/docs#1) @martin389 martin389 committed on Dec 9, 2020 2 parents 2f9ec0c + 1588f50 commit 1a56ed136914e522f3a23ecc2be1c49f479a1a6a Showing 501 changed files with 5,397 additions and 1,362 deletions. 2 .github/allowed-actions.js @@ -30,7 +30,7 @@ module.exports = [ 'rachmari/labeler@832d42ec5523f3c6d46e8168de71cd54363e3e2e', 'repo-sync/github-sync@3832fe8e2be32372e1b3970bbae8e7079edeec88', 'repo-sync/pull-request@33777245b1aace1a58c87a29c90321aa7a74bd7d', 'rtCamp/action-slack-notify@e17352feaf9aee300bf0ebc1dfbf467d80438815', 'someimportantcompany/github-actions-slack-message@0b470c14b39da4260ed9e3f9a4f1298a74ccdefd', 'tjenkinson/gh-action-auto-merge-dependency-updates@cee2ac0', 'EndBug/add-and-commit@9358097a71ad9fb9e2f9624c6098c89193d83575' ] 72 .github/workflows/confirm-internal-staff-work-in-docs.yml @@ -0,0 +1,72 @@ name: Confirm internal staff meant to post in public on: issues: types: - opened - reopened - transferred pull_request_target: types: - opened - reopened jobs: check-team-membership: runs-on: ubuntu-latest continue-on-error: true if: github.repository == 'github/docs' steps: - uses: actions/github-script@626af12fe9a53dc2972b48385e7fe7dec79145c9 with: github-token: ${{ secrets.DOCUBOT_FR_PROJECT_BOARD_WORKFLOWS_REPO_ORG_READ_SCOPES }} script: | // Only perform this action with GitHub employees try { await github.teams.getMembershipForUserInOrg({ org: 'github', team_slug: 'employees', username: context.payload.sender.login, }); } catch(err) { // An error will be thrown if the user is not a GitHub employee // If a user is not a GitHub employee, we should stop here and // Not send a notification return } // Don't perform this action with Docs team members try { await github.teams.getMembershipForUserInOrg({ org: 'github', team_slug: 'docs', username: context.payload.sender.login, }); // If the user is a Docs team member, we should stop here and not send // a notification return } catch(err) { // An error will be thrown if the user is not a Docs team member // If a user is not a Docs team member we should continue and send // the notification } const issueNo = context.number || context.issue.number // Create an issue in our private repo await github.issues.create({ owner: 'github', repo: 'docs-internal', title: `@${context.payload.sender.login} confirm that \#${issueNo} should be in the public github/docs repo`, body: `@${context.payload.sender.login} opened https://github.com/github/docs/issues/${issueNo} publicly in the github/docs repo, instead of the private github/docs-internal repo.\n\n@${context.payload.sender.login}, please confirm that this belongs in the public repo and that no sensitive information was disclosed by commenting below and closing the issue.\n\nIf this was not intentional and sensitive information was shared, please delete https://github.com/github/docs/issues/${issueNo} and notify us in the \#docs-open-source channel.\n\nThanks! \n\n/cc @github/docs @github/docs-engineering` }); throw new Error('A Hubber opened an issue on the public github/docs repo'); - name: Send Slack notification if a GitHub employee who isn't on the docs team opens an issue in public if: ${{ failure() && github.repository == 'github/docs' }} uses: someimportantcompany/github-actions-slack-message@0b470c14b39da4260ed9e3f9a4f1298a74ccdefd with: channel: ${{ secrets.DOCS_OPEN_SOURCE_SLACK_CHANNEL_ID }} bot-token: ${{ secrets.SLACK_DOCS_BOT_TOKEN }} text: <@${{github.actor}}> opened https://github.com/github/docs/issues/${{ github.event.number || github.event.issue.number }} publicly on the github/docs repo instead of the private github/docs-internal repo. They have been notified via a new issue in the github/docs-internal repo to confirm this was intentional. 15 .github/workflows/js-lint.yml @@ -10,23 +10,8 @@ on: - translations jobs: see_if_should_skip: runs-on: ubuntu-latest outputs: should_skip: ${{ steps.skip_check.outputs.should_skip }} steps: - id: skip_check uses: fkirc/skip-duplicate-actions@36feb0d8d062137530c2e00bd278d138fe191289 with: cancel_others: 'false' github_token: ${{ github.token }} paths: '["**/*.js", "package*.json", ".github/workflows/js-lint.yml", ".eslint*"]' lint: runs-on: ubuntu-latest needs: see_if_should_skip if: ${{ needs.see_if_should_skip.outputs.should_skip != 'true' }} steps: - name: Check out repo uses: actions/checkout@5a4ac9002d0be2fb38bd78e4b4dbde5606d7042f 13 .github/workflows/repo-freeze-reminders.yml @@ -14,11 +14,10 @@ jobs: if: github.repository == 'github/docs-internal' steps: - name: Send Slack notification if repo is frozen uses: someimportantcompany/github-actions-slack-message@0b470c14b39da4260ed9e3f9a4f1298a74ccdefd if: ${{ env.FREEZE == 'true' }} uses: rtCamp/action-slack-notify@e17352feaf9aee300bf0ebc1dfbf467d80438815 env: SLACK_WEBHOOK: ${{ secrets.DOCS_ALERTS_SLACK_WEBHOOK }} SLACK_USERNAME: docs-repo-sync SLACK_ICON_EMOJI: ':freezing_face:' SLACK_COLOR: '#51A0D5' # Carolina Blue SLACK_MESSAGE: All repo-sync runs will fail for ${{ github.repository }} because the repo is currently frozen! with: channel: ${{ secrets.DOCS_ALERTS_SLACK_CHANNEL_ID }} bot-token: ${{ secrets.SLACK_DOCS_BOT_TOKEN }} color: info text: All repo-sync runs will fail for ${{ github.repository }} because the repo is currently frozen! 54 .github/workflows/repo-sync-stalls.yml @@ -0,0 +1,54 @@ name: Repo Sync Stalls on: workflow_dispatch: schedule: - cron: '*/30 * * * *' jobs: check-freezer: name: Check for deployment freezes runs-on: ubuntu-latest steps: - name: Exit if repo is frozen if: ${{ env.FREEZE == 'true' }} run: | echo 'The repo is currently frozen! Exiting this workflow.' exit 1 # prevents further steps from running repo-sync-stalls: runs-on: ubuntu-latest steps: - name: Check if repo sync is stalled uses: actions/github-script@626af12fe9a53dc2972b48385e7fe7dec79145c9 with: github-token: ${{ secrets.DOCUBOT_FR_PROJECT_BOARD_WORKFLOWS_REPO_ORG_READ_SCOPES }} script: | let pulls; const owner = context.repo.owner const repo = context.repo.repo try { pulls = await github.pulls.list({ owner: owner, repo: repo, head: `${owner}:repo-sync`, state: 'open' }); } catch(err) { throw err return } pulls.data.forEach(pr => { const timeDelta = Date.now() - Date.parse(pr.created_at); const minutesOpen = timeDelta / 1000 / 60; if (minutesOpen > 30) { core.setFailed('Repo sync appears to be stalled') } }) - name: Send Slack notification if workflow fails uses: someimportantcompany/github-actions-slack-message@0b470c14b39da4260ed9e3f9a4f1298a74ccdefd if: failure() with: channel: ${{ secrets.DOCS_ALERTS_SLACK_CHANNEL_ID }} bot-token: ${{ secrets.SLACK_DOCS_BOT_TOKEN }} color: failure text: Repo sync appears to be stalled for ${{github.repository}}. See https://github.com/${{github.repository}}/pulls?q=is%3Apr+is%3Aopen+repo+sync 16 .github/workflows/repo-sync.yml @@ -7,6 +7,7 @@ name: Repo Sync on: workflow_dispatch: schedule: - cron: '*/15 * * * *' # every 15 minutes @@ -70,11 +71,10 @@ jobs: number: ${{ steps.find-pull-request.outputs.number }} - name: Send Slack notification if workflow fails uses: rtCamp/action-slack-notify@e17352feaf9aee300bf0ebc1dfbf467d80438815 if: ${{ failure() }} env: SLACK_WEBHOOK: ${{ secrets.DOCS_ALERTS_SLACK_WEBHOOK }} SLACK_USERNAME: docs-repo-sync SLACK_ICON_EMOJI: ':ohno:' SLACK_COLOR: '#B90E0A' # Crimson SLACK_MESSAGE: The last repo-sync run for ${{github.repository}} failed. See https://github.com/${{github.repository}}/actions?query=workflow%3A%22Repo+Sync%22 uses: someimportantcompany/github-actions-slack-message@0b470c14b39da4260ed9e3f9a4f1298a74ccdefd if: failure() with: channel: ${{ secrets.DOCS_ALERTS_SLACK_CHANNEL_ID }} bot-token: ${{ secrets.SLACK_DOCS_BOT_TOKEN }} color: failure text: The last repo-sync run for ${{github.repository}} failed. See https://github.com/${{github.repository}}/actions?query=workflow%3A%22Repo+Sync%22 10 .github/workflows/sync-algolia-search-indices.yml @@ -33,8 +33,10 @@ jobs: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} run: npm run sync-search - name: Send slack notification if workflow run fails uses: rtCamp/action-slack-notify@e17352feaf9aee300bf0ebc1dfbf467d80438815 uses: someimportantcompany/github-actions-slack-message@0b470c14b39da4260ed9e3f9a4f1298a74ccdefd if: failure() env: SLACK_WEBHOOK: ${{ secrets.DOCS_ALERTS_SLACK_WEBHOOK }} SLACK_MESSAGE: The last Algolia workflow run for ${{github.repository}} failed. Search actions for `workflow:Algolia` with: channel: ${{ secrets.DOCS_ALERTS_SLACK_CHANNEL_ID }} bot-token: ${{ secrets.SLACK_DOCS_BOT_TOKEN }} color: failure text: The last Algolia workflow run for ${{github.repository}} failed. Search actions for `workflow:Algolia` 15 .github/workflows/yml-lint.yml @@ -10,23 +10,8 @@ on: - translations jobs: see_if_should_skip: runs-on: ubuntu-latest outputs: should_skip: ${{ steps.skip_check.outputs.should_skip }} steps: - id: skip_check uses: fkirc/skip-duplicate-actions@36feb0d8d062137530c2e00bd278d138fe191289 with: cancel_others: 'false' github_token: ${{ github.token }} paths: '["**/*.yml", "**/*.yaml", "package*.json", ".github/workflows/yml-lint.yml"]' lint: runs-on: ubuntu-latest needs: see_if_should_skip if: ${{ needs.see_if_should_skip.outputs.should_skip != 'true' }} steps: - name: Check out repo uses: actions/checkout@5a4ac9002d0be2fb38bd78e4b4dbde5606d7042f 4 README.md @@ -28,7 +28,7 @@ If you've found a problem, you can open an issue using a [template](https://gith #### Solve an issue If you have a solution to one of the open issues, you will need to fork the repository and submit a PR using the [template](https://github.com/github/docs/blob/main/CONTRIBUTING.md#pull-request-template) that is visible automatically in the pull request body. For more details about this process, please check out [Getting Started with Contributing](/CONTRIBUTING.md). If you have a solution to one of the open issues, you will need to fork the repository and submit a pull request using the [template](https://github.com/github/docs/blob/main/CONTRIBUTING.md#pull-request-template) that is visible automatically in the pull request body. For more details about this process, please check out [Getting Started with Contributing](/CONTRIBUTING.md). #### Join us in discussions @@ -50,6 +50,8 @@ There are a few more things to know when you're getting started with this repo: In addition to the README you're reading right now, this repo includes other READMEs that describe the purpose of each subdirectory in more detail: - [content/README.md](content/README.md) - [content/graphql/README.md](content/graphql/README.md) - [content/rest/README.md](content/rest/README.md) - [contributing/README.md](contributing/README.md) - [data/README.md](data/README.md) - [data/reusables/README.md](data/reusables/README.md) BIN +164 KB assets/images/help/classroom/assignment-group-hero.png Binary file not shown. BIN +75.5 KB assets/images/help/classroom/assignment-ide-go-grant-access-button.png Binary file not shown. BIN +175 KB assets/images/help/classroom/assignment-individual-hero.png Binary file not shown. BIN +27.6 KB assets/images/help/classroom/assignment-repository-ide-button-in-readme.png Binary file not shown. BIN +83.4 KB assets/images/help/classroom/assignments-assign-deadline.png Binary file not shown. BIN +32.4 KB assets/images/help/classroom/assignments-assignment-title.png Binary file not shown. BIN +27.7 KB assets/images/help/classroom/assignments-autograding-click-pencil-or-trash.png Binary file not shown. BIN +72 KB assets/images/help/classroom/assignments-choose-repository-visibility.png Binary file not shown. BIN +20.1 KB assets/images/help/classroom/assignments-click-continue-button.png Binary file not shown. BIN +23.7 KB assets/images/help/classroom/assignments-click-create-assignment-button.png Binary file not shown. BIN +76.4 KB assets/images/help/classroom/assignments-click-grading-and-feedback.png Binary file not shown. BIN +53.1 KB assets/images/help/classroom/assignments-click-new-assignment-button.png Binary file not shown. BIN +134 KB assets/images/help/classroom/assignments-click-online-ide.png Binary file not shown. BIN +77.8 KB assets/images/help/classroom/assignments-click-pencil.png Binary file not shown. BIN +18.8 KB assets/images/help/classroom/assignments-click-review-button.png Binary file not shown. BIN +20.6 KB assets/images/help/classroom/assignments-click-save-test-case-button.png Binary file not shown. BIN +121 KB assets/images/help/classroom/assignments-click-template-repository-in-list.png Binary file not shown. BIN +21.1 KB assets/images/help/classroom/assignments-click-update-assignment.png Binary file not shown. BIN +76.9 KB assets/images/help/classroom/assignments-click-view-ide.png Binary file not shown. BIN +96.5 KB assets/images/help/classroom/assignments-click-view-test.png Binary file not shown. BIN +71.3 KB assets/images/help/classroom/assignments-define-teams.png Binary file not shown. BIN +39.4 KB assets/images/help/classroom/assignments-enable-feedback-pull-requests.png Binary file not shown. BIN +40.4 KB assets/images/help/classroom/assignments-type-protected-file-paths.png Binary file not shown. BIN +330 KB assets/images/help/classroom/autograding-actions-logs.png Binary file not shown. BIN +187 KB assets/images/help/classroom/autograding-actions-tab.png Binary file not shown. BIN +94.9 KB assets/images/help/classroom/autograding-click-grading-method.png Diff not rendered. BIN +57.5 KB assets/images/help/classroom/autograding-click-pencil.png Diff not rendered. BIN +57.7 KB assets/images/help/classroom/autograding-click-trash.png Diff not rendered. BIN +168 KB assets/images/help/classroom/autograding-hero.png Diff not rendered. BIN +154 KB assets/images/help/classroom/classroom-add-students-to-your-roster.png Diff not rendered. BIN +166 KB assets/images/help/classroom/classroom-copy-credentials.png Diff not rendered. BIN +181 KB assets/images/help/classroom/classroom-hero.png Diff not rendered. BIN +48.3 KB assets/images/help/classroom/classroom-settings-click-connection-settings.png Diff not rendered. BIN +94 KB ...ges/help/classroom/classroom-settings-click-disconnect-from-your-lms-button.png Diff not rendered. BIN +148 KB assets/images/help/classroom/classroom-settings-click-lms.png Diff not rendered. BIN +149 KB assets/images/help/classroom/click-assignment-in-list.png Diff not rendered. BIN +52.3 KB assets/images/help/classroom/click-classroom-in-list.png Diff not rendered. BIN +49.5 KB assets/images/help/classroom/click-create-classroom-button.png Diff not rendered. BIN +30 KB assets/images/help/classroom/click-create-roster-button.png Diff not rendered. BIN +78.2 KB assets/images/help/classroom/click-delete-classroom-button.png Diff not rendered. BIN +60.8 KB ...images/help/classroom/click-import-from-a-learning-management-system-button.png Diff not rendered. BIN +51.9 KB assets/images/help/classroom/click-new-classroom-button.png Diff not rendered. BIN +83.4 KB assets/images/help/classroom/click-organization.png Diff not rendered. BIN +28.4 KB assets/images/help/classroom/click-settings.png Diff not rendered. BIN +29.7 KB assets/images/help/classroom/click-students.png Diff not rendered. BIN +60 KB assets/images/help/classroom/click-update-students-button.png Diff not rendered. BIN +127 KB assets/images/help/classroom/delete-classroom-click-delete-classroom-button.png Diff not rendered. BIN +104 KB assets/images/help/classroom/delete-classroom-modal-with-warning.png Diff not rendered. BIN +264 KB assets/images/help/classroom/ide-makecode-arcade-version-control-button.png Diff not rendered. BIN +69.4 KB assets/images/help/classroom/ide-replit-version-control-button.png Diff not rendered. BIN +234 KB assets/images/help/classroom/lms-github-classroom-credentials.png Diff not rendered. BIN +955 KB assets/images/help/classroom/probot-settings.gif Diff not rendered. BIN +113 KB assets/images/help/classroom/roster-hero.png Diff not rendered. BIN +40.4 KB assets/images/help/classroom/settings-click-rename-classroom-button.png Diff not rendered. BIN +41 KB assets/images/help/classroom/settings-type-classroom-name.png Diff not rendered. BIN +140 KB assets/images/help/classroom/setup-click-authorize-github-classroom.png Diff not rendered. BIN +102 KB assets/images/help/classroom/setup-click-authorize-github.png Diff not rendered. BIN +163 KB assets/images/help/classroom/setup-click-grant.png Diff not rendered. BIN +324 KB assets/images/help/classroom/students-click-delete-roster-button-in-modal.png Diff not rendered. BIN +91.1 KB assets/images/help/classroom/students-click-delete-roster-button.png Diff not rendered. BIN +48.2 KB assets/images/help/classroom/type-classroom-name.png Diff not rendered. BIN +174 KB assets/images/help/classroom/type-or-upload-student-identifiers.png Diff not rendered. BIN +83.3 KB assets/images/help/classroom/use-drop-down-then-click-archive.png Diff not rendered. BIN +45.2 KB assets/images/help/classroom/use-drop-down-then-click-unarchive.png Diff not rendered. BIN +55.4 KB assets/images/help/discussions/choose-new-category.png Diff not rendered. BIN +56.8 KB assets/images/help/discussions/click-delete-and-move-button.png Diff not rendered. BIN +59.7 KB assets/images/help/discussions/click-delete-discussion.png Diff not rendered. BIN +65.3 KB assets/images/help/discussions/click-delete-for-category.png Diff not rendered. BIN +68.9 KB assets/images/help/discussions/click-delete-this-discussion-button.png Diff not rendered. BIN +353 KB assets/images/help/discussions/click-discussion-in-list.png Diff not rendered. BIN +41 KB assets/images/help/discussions/click-edit-categories.png Diff not rendered. BIN +64.3 KB assets/images/help/discussions/click-edit-for-category.png Diff not rendered. BIN +60.2 KB assets/images/help/discussions/click-edit-pinned-discussion.png Diff not rendered. BIN +104 KB assets/images/help/discussions/click-new-category-button.png Diff not rendered. BIN +98.2 KB assets/images/help/discussions/click-pin-discussion-button.png Diff not rendered. BIN +55.7 KB assets/images/help/discussions/click-pin-discussion.png Diff not rendered. BIN +104 KB assets/images/help/discussions/click-save.png Diff not rendered. BIN +59.9 KB assets/images/help/discussions/click-transfer-discussion-button.png Diff not rendered. BIN +60.2 KB assets/images/help/discussions/click-transfer-discussion.png Diff not rendered. BIN +63.3 KB assets/images/help/discussions/click-unpin-discussion-button.png Diff not rendered. BIN +59.8 KB assets/images/help/discussions/click-unpin-discussion.png Diff not rendered. BIN +140 KB assets/images/help/discussions/comment-mark-as-answer-button.png Diff not rendered. BIN +136 KB assets/images/help/discussions/comment-marked-as-answer.png Diff not rendered. BIN +234 KB assets/images/help/discussions/customize-pinned-discussion.png Diff not rendered. BIN +1.21 MB assets/images/help/discussions/discussons-hero.png Diff not rendered. BIN +139 KB assets/images/help/discussions/edit-category-details.png Diff not rendered. BIN +136 KB assets/images/help/discussions/edit-existing-category-details.png Diff not rendered. BIN +55.5 KB assets/images/help/discussions/existing-category-click-save-changes-button.png Diff not rendered. BIN +680 KB assets/images/help/discussions/hero.png Diff not rendered. BIN +307 KB assets/images/help/discussions/most-helpful.png Diff not rendered. BIN +52.9 KB assets/images/help/discussions/new-category-click-create-button.png Diff not rendered. BIN +132 KB assets/images/help/discussions/new-discussion-button.png Diff not rendered. BIN +140 KB assets/images/help/discussions/new-discussion-select-category-dropdown-menu.png Diff not rendered. BIN +46.7 KB assets/images/help/discussions/new-discussion-start-discussion-button.png Diff not rendered. BIN +108 KB assets/images/help/discussions/new-discussion-title-and-body-fields.png Diff not rendered. BIN +23.1 KB assets/images/help/discussions/public-repo-settings.png Diff not rendered. BIN +49.5 KB assets/images/help/discussions/repository-discussions-tab.png Diff not rendered. BIN +51.8 KB assets/images/help/discussions/search-and-filter-controls.png Diff not rendered. BIN +44.4 KB assets/images/help/discussions/search-result.png Diff not rendered. BIN +35.4 KB assets/images/help/discussions/select-discussions-checkbox.png Diff not rendered. BIN +44.8 KB assets/images/help/discussions/setup-discussions-button.png Diff not rendered. BIN +95.9 KB assets/images/help/discussions/toggle-allow-users-with-read-access-checkbox.png Diff not rendered. BIN +73 KB assets/images/help/discussions/unanswered-discussion.png Diff not rendered. BIN +81.3 KB assets/images/help/discussions/use-choose-a-repository-drop-down.png Diff not rendered. BIN +30.3 KB assets/images/help/discussions/your-discussions.png Diff not rendered. BIN +563 KB assets/images/help/education/click-get-teacher-benefits.png Diff not rendered. BIN +116 KB assets/images/help/images/overview-actions-result-navigate.png Diff not rendered. BIN +150 KB assets/images/help/images/overview-actions-result-updated-2.png Diff not rendered. BIN +128 KB assets/images/help/images/workflow-graph-job.png Diff not rendered. BIN +135 KB assets/images/help/images/workflow-graph.png Diff not rendered. BIN +5.46 KB assets/images/help/organizations/update-profile-button.png Diff not rendered. BIN +44.6 KB assets/images/help/pull_requests/dependency-review-rich-diff.png Diff not rendered. BIN +24.6 KB assets/images/help/pull_requests/dependency-review-source-diff.png Diff not rendered. BIN +214 KB assets/images/help/pull_requests/dependency-review-vulnerability.png Diff not rendered. BIN +105 KB assets/images/help/pull_requests/file-filter-menu-json.png Diff not rendered. BIN +22.5 KB (510%) assets/images/help/pull_requests/pull-request-tabs-changed-files.png Diff not rendered. BIN +45.2 KB assets/images/help/repository/actions-delete-artifact-updated.png Diff not rendered. BIN +122 KB assets/images/help/repository/actions-failed-pester-test-updated.png Diff not rendered. BIN +45.4 KB assets/images/help/repository/artifact-drop-down-updated.png Diff not rendered. BIN +54.5 KB assets/images/help/repository/cancel-check-suite-updated.png Diff not rendered. BIN +120 KB assets/images/help/repository/copy-link-button-updated-2.png Diff not rendered. BIN +77.6 KB assets/images/help/repository/delete-all-logs-updated-2.png Diff not rendered. BIN +326 KB assets/images/help/repository/docker-action-workflow-run-updated.png Diff not rendered. BIN +84.6 KB assets/images/help/repository/download-logs-drop-down-updated-2.png Diff not rendered. BIN +170 KB assets/images/help/repository/in-progress-run.png Diff not rendered. BIN +124 KB assets/images/help/repository/javascript-action-workflow-run-updated-2.png Diff not rendered. BIN +116 KB assets/images/help/repository/passing-data-between-jobs-in-a-workflow-updated.png Diff not rendered. BIN +80.8 KB assets/images/help/repository/rerun-checks-drop-down-updated.png Diff not rendered. BIN +41.2 KB assets/images/help/repository/search-log-box-updated-2.png Diff not rendered. BIN +133 KB assets/images/help/repository/super-linter-workflow-results-updated-2.png Diff not rendered. BIN +97.5 KB assets/images/help/repository/superlinter-lint-code-base-job-updated.png Diff not rendered. BIN -128 KB assets/images/help/repository/upload-build-test-artifact.png Diff not rendered. BIN +27.5 KB (170%) assets/images/help/repository/view-run-billable-time.png Diff not rendered. BIN +54.8 KB assets/images/help/repository/workflow-run-kebab-horizontal-icon-updated-2.png Diff not rendered. BIN +7.54 KB assets/images/help/settings/appearance-tab.png Diff not rendered. BIN +39.7 KB assets/images/help/settings/theme-settings-radio-buttons.png Diff not rendered. BIN +11.1 KB assets/images/help/settings/update-theme-preference-button.png Diff not rendered. BIN +22.5 KB assets/images/help/sponsors/billing-account-switcher.png Diff not rendered. BIN +6.37 KB (150%) assets/images/help/sponsors/edit-sponsorship-payment-button.png Diff not rendered. BIN +34.8 KB assets/images/help/sponsors/link-account-button.png Diff not rendered. BIN +12.8 KB (170%) assets/images/help/sponsors/manage-your-sponsorship-button.png Diff not rendered. BIN +20.6 KB assets/images/help/sponsors/organization-update-email-textbox.png Diff not rendered. BIN +13.5 KB assets/images/help/sponsors/pay-prorated-amount-link.png Diff not rendered. BIN +34.7 KB assets/images/help/sponsors/select-an-account-drop-down.png Diff not rendered. BIN +17 KB assets/images/help/sponsors/sponsor-as-drop-down-menu.png Diff not rendered. BIN +15.8 KB assets/images/help/sponsors/sponsoring-as-drop-down-menu.png Diff not rendered. BIN +16.1 KB assets/images/help/sponsors/sponsoring-settings-button.png Diff not rendered. BIN +29.5 KB assets/images/help/sponsors/sponsoring-tab.png Diff not rendered. BIN +7.91 KB assets/images/help/sponsors/update-checkbox-manage.png Diff not rendered. BIN +43 KB (160%) assets/images/marketplace/marketplace-request-button.png Diff not rendered. BIN +53.6 KB assets/images/marketplace/marketplace_verified_creator_badges_apps.png Diff not rendered. 6 content/actions/creating-actions/creating-a-docker-container-action.md @@ -226,6 +226,10 @@ jobs: ``` {% endraw %} From your repository, click the **Actions** tab, and select the latest workflow run. You should see "Hello Mona the Octocat" or the name you used for the `who-to-greet` input and the timestamp printed in the log. From your repository, click the **Actions** tab, and select the latest workflow run. {% if currentVersion == "free-pro-team@latest" or currentVersion ver_gt "enterprise-server@3.0" %}Under **Jobs** or in the visualization graph, click **A job to say hello**. {% endif %}You should see "Hello Mona the Octocat" or the name you used for the `who-to-greet` input and the timestamp printed in the log. {% if currentVersion == "free-pro-team@latest" or currentVersion ver_gt "enterprise-server@3.0" %}  {% else %}  {% endif %} 6 content/actions/creating-actions/creating-a-javascript-action.md @@ -261,9 +261,11 @@ jobs: ``` {% endraw %} From your repository, click the **Actions** tab, and select the latest workflow run. You should see "Hello Mona the Octocat" or the name you used for the `who-to-greet` input and the timestamp printed in the log. From your repository, click the **Actions** tab, and select the latest workflow run. {% if currentVersion == "free-pro-team@latest" or currentVersion ver_gt "enterprise-server@3.0" %}Under **Jobs** or in the visualization graph, click **A job to say hello**. {% endif %}You should see "Hello Mona the Octocat" or the name you used for the `who-to-greet` input and the timestamp printed in the log. {% if currentVersion == "free-pro-team@latest" or currentVersion ver_gt "enterprise-server@2.22" %} {% if currentVersion == "free-pro-team@latest" or currentVersion ver_gt "enterprise-server@3.0" %}  {% elsif currentVersion ver_gt "enterprise-server@2.22" %}  {% else %}  4 content/actions/guides/about-packaging-with-github-actions.md @@ -25,7 +25,11 @@ Creating a package at the end of a continuous integration workflow can help duri Now, when reviewing a pull request, you'll be able to look at the workflow run and download the artifact that was produced. {% if currentVersion == "free-pro-team@latest" or currentVersion ver_gt "enterprise-server@3.0" %}  {% else %}  {% endif %} This will let you run the code in the pull request on your machine, which can help with debugging or testing the pull request. 4 content/actions/guides/building-and-testing-powershell.md @@ -60,7 +60,11 @@ jobs: * `run: Test-Path resultsfile.log` - Check whether a file called `resultsfile.log` is present in the repository's root directory. * `Should -Be $true` - Uses Pester to define an expected result. If the result is unexpected, then {% data variables.product.prodname_actions %} flags this as a failed test. For example: {% if currentVersion == "free-pro-team@latest" or currentVersion ver_gt "enterprise-server@3.0" %}  {% else %}  {% endif %} * `Invoke-Pester Unit.Tests.ps1 -Passthru` - Uses Pester to execute tests defined in a file called `Unit.Tests.ps1`. For example, to perform the same test described above, the `Unit.Tests.ps1` will contain the following: ``` 7 content/actions/guides/storing-workflow-data-as-artifacts.md @@ -108,8 +108,6 @@ jobs: path: output/test/code-coverage.html ```  {% if currentVersion == "free-pro-team@latest" or currentVersion ver_gt "enterprise-server@2.22" %} ### Configuring a custom artifact retention period @@ -238,7 +236,12 @@ jobs: echo The result is $value ``` The workflow run will archive any artifacts that it generated. For more information on downloading archived artifacts, see "[Downloading workflow artifacts](/actions/managing-workflow-runs/downloading-workflow-artifacts)." {% if currentVersion == "free-pro-team@latest" or currentVersion ver_gt "enterprise-server@3.0" %}  {% else %}  {% endif %} {% if currentVersion == "free-pro-team@latest" %} 8 content/actions/index.md @@ -68,18 +68,18 @@ versions: <h2 class="mb-2 font-mktg h1">Code examples</h2> <div class="pr-lg-3 mb-5 mt-3"> <input class="js-code-example-filter input-lg py-2 px-3 col-12 col-lg-8 form-control" placeholder="Search code examples" type="search" autocomplete="off" aria-label="Search code examples"/> <input class="js-filter-card-filter input-lg py-2 px-3 col-12 col-lg-8 form-control" placeholder="Search code examples" type="search" autocomplete="off" aria-label="Search code examples"/> </div> <div class="d-flex flex-wrap gutter"> {% render 'code-example-card' for actionsCodeExamples as example %} </div> <button class="js-code-example-show-more btn btn-outline float-right">Show more {% octicon "arrow-right" %}</button> <button class="js-filter-card-show-more btn btn-outline float-right">Show more {% octicon "arrow-right" %}</button> <div class="js-code-example-no-results d-none py-4 text-center text-gray font-mktg"> <div class="js-filter-card-no-results d-none py-4 text-center text-gray font-mktg"> <div class="mb-3">{% octicon "search" width="24" %}</div> <h3 class="text-normal">Sorry, there is no result for <strong class="js-code-example-filter-value"></strong></h3> <h3 class="text-normal">Sorry, there is no result for <strong class="js-filter-card-value"></strong></h3> <p class="my-3 f4">It looks like we don't have an example that fits your filter.<br>Try another filter or add your code example</p> <a href="https://github.com/github/docs/blob/main/data/variables/action_code_examples.yml">Learn how to add a code example {% octicon "arrow-right" %}</a> </div> 11 content/actions/learn-github-actions/introduction-to-github-actions.md @@ -204,7 +204,7 @@ In this diagram, you can see the workflow file you just created and how the {% d ### Viewing the job's activity Once your job has started running, you can view each step's activity on {% data variables.product.prodname_dotcom %}. Once your job has started running, you can {% if currentVersion == "free-pro-team@latest" or currentVersion ver_gt "enterprise-server@3.0" %}see a visualization graph of the run's progress and {% endif %}view each step's activity on {% data variables.product.prodname_dotcom %}. {% data reusables.repositories.navigate-to-repo %} 1. Under your repository name, click **Actions**. @@ -213,7 +213,14 @@ Once your job has started running, you can view each step's activity on {% data  1. Under "Workflow runs", click the name of the run you want to see.  {% if currentVersion == "free-pro-team@latest" or currentVersion ver_gt "enterprise-server@2.22" %} {% if currentVersion == "free-pro-team@latest" or currentVersion ver_gt "enterprise-server@3.0" %} 1. Under **Jobs** or in the visualization graph, click the job you want to see.  {% endif %} {% if currentVersion == "free-pro-team@latest" or currentVersion ver_gt "enterprise-server@3.0" %} 1. View the results of each step.  {% elsif currentVersion ver_gt "enterprise-server@2.22" %} 1. Click on the job name to see the results of each step.  {% else %} 7 content/actions/managing-workflow-runs/canceling-a-workflow.md @@ -17,9 +17,14 @@ versions: {% data reusables.repositories.navigate-to-repo %} {% data reusables.repositories.actions-tab %} {% data reusables.repositories.navigate-to-workflow %} {% data reusables.repositories.view-run %} 1. From the list of workflow runs, click the name of the `queued` or `in progress` run that you want to cancel.  1. In the upper-right corner of the workflow, click **Cancel workflow**. {% if currentVersion == "free-pro-team@latest" or currentVersion ver_gt "enterprise-server@3.0" %}  {% else %}  {% endif %} ### Steps {% data variables.product.prodname_dotcom %} takes to cancel a workflow run 4 content/actions/managing-workflow-runs/downloading-workflow-artifacts.md @@ -20,4 +20,8 @@ versions: {% data reusables.repositories.navigate-to-workflow %} {% data reusables.repositories.view-run %} 1. Under **Artifacts**, click the artifact you want to download. {% if currentVersion == "free-pro-team@latest" or currentVersion ver_gt "enterprise-server@3.0" %}  {% else %}  {% endif %} 1 content/actions/managing-workflow-runs/index.md @@ -18,6 +18,7 @@ versions: {% data reusables.actions.enterprise-beta %} {% data reusables.actions.enterprise-github-hosted-runners %} {% if currentVersion == "free-pro-team@latest" or currentVersion ver_gt "enterprise-server@3.0" %}{% link_in_list /using-the-visualization-graph %}{% endif %} {% link_in_list /viewing-workflow-run-history %} {% link_in_list /using-workflow-run-logs %} {% link_in_list /manually-running-a-workflow %} 3 content/actions/managing-workflow-runs/re-running-a-workflow.md @@ -16,5 +16,4 @@ versions: {% data reusables.repositories.actions-tab %} {% data reusables.repositories.navigate-to-workflow %} {% data reusables.repositories.view-run %} 1. In the upper-right corner of the workflow, use the **Re-run jobs** drop-down menu, and select **Re-run all jobs**.  1. In the upper-right corner of the workflow, use the **Re-run jobs** drop-down menu, and select **Re-run all jobs**.{% if currentVersion == "free-pro-team@latest" or currentVersion ver_gt "enterprise-server@3.0" %}{% else %}{% endif %} 4 content/actions/managing-workflow-runs/removing-workflow-artifacts.md @@ -27,7 +27,11 @@ versions: {% data reusables.repositories.navigate-to-workflow %} {% data reusables.repositories.view-run %} 1. Under **Artifacts**, click {% octicon "trashcan" aria-label="The trashcan icon" %} next to the artifact you want to remove. {% if currentVersion == "free-pro-team@latest" or currentVersion ver_gt "enterprise-server@3.0" %}  {% else %}  {% endif %} {% if currentVersion == "free-pro-team@latest" or currentVersion ver_gt "enterprise-server@2.22" %} ### Setting the retention period for an artifact 23 content/actions/managing-workflow-runs/using-the-visualization-graph.md @@ -0,0 +1,23 @@ --- title: Using the visualization graph intro: Every workflow run generates a real-time graph that illustrates the run progress. You can use this graph to monitor and debug workflows. product: '{% data reusables.gated-features.actions %}' versions: free-pro-team: '*' enterprise-server: '>=3.1' --- {% data reusables.actions.enterprise-beta %} {% data reusables.actions.visualization-beta %} {% data reusables.actions.enterprise-github-hosted-runners %} {% data reusables.repositories.navigate-to-repo %} {% data reusables.repositories.actions-tab %} {% data reusables.repositories.navigate-to-workflow %} {% data reusables.repositories.view-run %} 1. The graph displays each job in the workflow. An icon to the left of the job name indicates the status of the job. Lines between jobs indicate dependencies.  2. Click on a job to view the job log.  18 content/actions/managing-workflow-runs/using-workflow-run-logs.md @@ -45,7 +45,11 @@ You can search the build logs for a particular step. When you search logs, only {% data reusables.repositories.navigate-to-job-superlinter %} {% if currentVersion == "free-pro-team@latest" or currentVersion ver_gt "enterprise-server@2.22" %} 1. In the upper-right corner of the log output, in the **Search logs** search box, type a search query. {% if currentVersion == "free-pro-team@latest" or currentVersion ver_gt "enterprise-server@3.0" %}  {% else %}  {% endif %} {% else %} 1. To expand each step you want to include in your search, click the step.  @@ -63,8 +67,12 @@ You can download the log files from your workflow run. You can also download a w {% data reusables.repositories.view-run-superlinter %} {% data reusables.repositories.navigate-to-job-superlinter %} {% if currentVersion == "free-pro-team@latest" or currentVersion ver_gt "enterprise-server@2.22" %} 1. In the upper right corner, click {% octicon "kebab-horizontal" aria-label="The horizontal kebab icon" %} and select **Download log archive**. 1. In the upper right corner, click {% if currentVersion == "free-pro-team@latest" or currentVersion ver_gt "enterprise-server@3.0" %}{% octicon "gear" aria-label="The gear icon" %}{% else %}{% octicon "kebab-horizontal" aria-label="The horizontal kebab icon" %}{% endif %} and select **Download log archive**. {% if currentVersion == "free-pro-team@latest" or currentVersion ver_gt "enterprise-server@3.0" %}  {% else %}  {% endif %} {% else %} 1. In the upper right corner, click {% octicon "kebab-horizontal" aria-label="The horizontal kebab icon" %} and select **Download log archive**.  @@ -80,9 +88,17 @@ You can delete the log files from your workflow run. {% data reusables.repositor {% data reusables.repositories.view-run-superlinter %} {% if currentVersion == "free-pro-team@latest" or currentVersion ver_gt "enterprise-server@2.22" %} 1. In the upper right corner, click {% octicon "kebab-horizontal" aria-label="The horizontal kebab icon" %}. {% if currentVersion == "free-pro-team@latest" or currentVersion ver_gt "enterprise-server@3.0" %}  {% else %}  {% endif %} 2. To delete the log files, click the **Delete all logs** button and review the confirmation prompt. {% if currentVersion == "free-pro-team@latest" or currentVersion ver_gt "enterprise-server@3.0" %}  {% else %}  {% endif %} After deleting logs, the **Delete all logs** button is removed to indicate that no log files remain in the workflow run. {% else %} 1. In the upper right corner, click {% octicon "kebab-horizontal" aria-label="The horizontal kebab icon" %}. 2 content/actions/managing-workflow-runs/viewing-job-execution-time.md @@ -15,7 +15,7 @@ Billable job execution minutes are only shown for jobs run on private repositori {% data reusables.repositories.actions-tab %} {% data reusables.repositories.navigate-to-workflow %} {% data reusables.repositories.view-run %} 1. Under the job summary, you can view the job's execution time. To view the billable job execution time, click **Run and billable time details**. 1. Under the job summary, you can view the job's execution time. To view details about the billable job execution time, click the time under **Billable time**.  {% note %} 5 content/actions/quickstart.md @@ -60,8 +60,13 @@ Committing the workflow file in your repository triggers the `push` event and ru {% data reusables.repositories.actions-tab %} {% data reusables.repositories.navigate-to-workflow-superlinter %} {% data reusables.repositories.view-run-superlinter %} {% if currentVersion == "free-pro-team@latest" or currentVersion ver_gt "enterprise-server@3.0" %} 1. Under **Jobs** or in the visualization graph, click the **Lint code base** job.  {% else %} 1. In the left sidebar, click the **Lint code base** job.  {% endif %} {% data reusables.repositories.view-failed-job-results-superlinter %} ### More starter workflows 49 content/developers/github-marketplace/about-github-marketplace.md @@ -1,6 +1,6 @@ --- title: About GitHub Marketplace intro: 'Learn the basics to prepare your app for review before joining {% data variables.product.prodname_marketplace %}.' intro: 'Learn about {% data variables.product.prodname_marketplace %} where you can share your apps and actions publicly with all {% data variables.product.product_name %} users.' redirect_from: - /apps/marketplace/getting-started/ - /marketplace/getting-started @@ -14,52 +14,41 @@ versions: {% data reusables.actions.actions-not-verified %} To learn about publishing {% data variables.product.prodname_actions %} in the {% data variables.product.prodname_marketplace %}, see "[Publishing actions in GitHub Marketplace](/actions/creating-actions/publishing-actions-in-github-marketplace)." To learn about publishing {% data variables.product.prodname_actions %} in {% data variables.product.prodname_marketplace %}, see "[Publishing actions in GitHub Marketplace](/actions/creating-actions/publishing-actions-in-github-marketplace)." ### Apps You can list verified and unverified apps in {% data variables.product.prodname_marketplace %}. Unverified apps do not go through the security, testing, and verification cycle {% data variables.product.prodname_dotcom %} requires for verified apps. Anyone can share their apps with other users on {% data variables.product.prodname_marketplace %} but only listings that are verified by {% data variables.product.company_short %} can include paid plans. For more information, see "[About verified creators](/developers/github-marketplace/about-verified-creators)." Verified apps have a green badge in {% data variables.product.prodname_marketplace %}. Unverified apps have a grey badge next to their listing and are only available as free apps. If you're interested in creating an app for {% data variables.product.prodname_marketplace %}, but you're new to {% data variables.product.prodname_github_apps %} or {% data variables.product.prodname_oauth_app %}s, see "[Building {% data variables.product.prodname_github_apps %}](/developers/apps/building-github-apps)" or "[Building {% data variables.product.prodname_oauth_app %}s](/developers/apps/building-oauth-apps)."  If you're interested in creating an app for {% data variables.product.prodname_marketplace %}, but you're new to {% data variables.product.prodname_github_apps %} and {% data variables.product.prodname_oauth_app %}s, see "[Building apps](/apps/)." {% data reusables.marketplace.github_apps_preferred %}, although you can list both OAuth and {% data variables.product.prodname_github_app %}s in {% data variables.product.prodname_marketplace %}. See "[Differences between GitHub and OAuth apps](/apps/differences-between-apps/)" for more details. To learn more about switching from OAuth to {% data variables.product.prodname_github_apps %}, see [Migrating OAuth Apps to {% data variables.product.prodname_github_app %}s](/apps/migrating-oauth-apps-to-github-apps/). {% data reusables.marketplace.github_apps_preferred %}, although you can list both OAuth and {% data variables.product.prodname_github_app %}s in {% data variables.product.prodname_marketplace %}. For more information, see "[Differences between {% data variables.product.prodname_github_apps %} and {% data variables.product.prodname_oauth_app %}s](/apps/differences-between-apps/)" and "[Migrating {% data variables.product.prodname_oauth_app %}s to {% data variables.product.prodname_github_apps %}](/apps/migrating-oauth-apps-to-github-apps/)." If you have questions about {% data variables.product.prodname_marketplace %}, please contact {% data variables.contact.contact_support %} directly. #### Unverified Apps Unverified apps do not need to meet the "[Requirements for listing an app on {% data variables.product.prodname_marketplace %}](/marketplace/getting-started/requirements-for-listing-an-app-on-github-marketplace/)" or go through the "[Security review process](/marketplace/getting-started/security-review-process/)". {% data reusables.marketplace.unverified-apps %} Having a published paid plan will prevent you from being able to submit an unverified app. You must remove paid plans or keep them in draft mode before publishing an unverified app. To list your unverified app in {% data variables.product.prodname_marketplace %}, you only need to create a "[Listing on {% data variables.product.prodname_marketplace %}](/marketplace/listing-on-github-marketplace/)" and submit it as an unverified listing. {% data reusables.marketplace.launch-with-free %} ### Publishing an app to {% data variables.product.prodname_marketplace %} #### Verified Apps When you have finished creating your app, you can share it with other users by publishing it to {% data variables.product.prodname_marketplace %}. In summary, the process is: If you've already built an app and you're interested in submitting a verified listing in {% data variables.product.prodname_marketplace %}, start here: 1. Review your app carefully to ensure that it will behave as expected in other repositories and that it follows best practice guidelines. For more information, see "[Security best practices for apps](/developers/github-marketplace/security-best-practices-for-apps)" and "[Requirements for listing an app](/developers/github-marketplace/requirements-for-listing-an-app#best-practice-for-customer-experience)." 1. [Getting started with {% data variables.product.prodname_marketplace %}](/marketplace/getting-started/)<br/>Learn about requirements, guidelines, and the app submission process. 1. Add webhook events to the app to track user billing requests. For more information about the {% data variables.product.prodname_marketplace %} API, webhook events, and billing requests, see "[Using the {% data variables.product.prodname_marketplace %} API in your app](/developers/github-marketplace/using-the-github-marketplace-api-in-your-app)." 1. [Integrating with the {% data variables.product.prodname_marketplace %} API](/marketplace/integrating-with-the-github-marketplace-api/)<br/>Before you can list your app on {% data variables.product.prodname_marketplace %}, you'll need to integrate billing flows using the {% data variables.product.prodname_marketplace %} API and webhook events. 1. Create a draft {% data variables.product.prodname_marketplace %} listing. For more information, see "[Drafting a listing for your app](/developers/github-marketplace/drafting-a-listing-for-your-app)." 1. [Listing on {% data variables.product.prodname_marketplace %}](/marketplace/listing-on-github-marketplace/) <br/>Create a draft {% data variables.product.prodname_marketplace %} listing, configure webhook settings, and set up pricing plans. 1. Add a pricing plan. For more information, see "[Setting pricing plans for your listing](/developers/github-marketplace/setting-pricing-plans-for-your-listing)." 1. [Selling your app](/marketplace/selling-your-app/)<br/>Learn about pricing plans, billing cycles, and how to receive payment from {% data variables.product.prodname_dotcom %} for your app. 1. Check whether your app meets the requirements for listing on {% data variables.product.prodname_marketplace %} as a free or a paid app. For more information, see "[Requirements for listing an app](/developers/github-marketplace/requirements-for-listing-an-app)." 1. [{% data variables.product.prodname_marketplace %} Insights](/marketplace/github-marketplace-insights/)<br/>See how your app is performing in {% data variables.product.prodname_marketplace %}. You can use metrics collected by {% data variables.product.prodname_dotcom %} to guide your marketing campaign and be successful in {% data variables.product.prodname_marketplace %}. 1. Read and accept the terms of the "[{% data variables.product.prodname_marketplace %} Developer Agreement](/articles/github-marketplace-developer-agreement/)." 1. [{% data variables.product.prodname_marketplace %} transactions](/marketplace/github-marketplace-transactions/)<br/>Download and view transaction data for your {% data variables.product.prodname_marketplace %} listing. 1. Submit your listing for publication in {% data variables.product.prodname_marketplace %}, requesting verification if you want to sell the app. For more information, see "[Submitting your listing for publication](/developers/github-marketplace/submitting-your-listing-for-publication)." ### Reviewing your app An onboarding expert will contact you with any questions or further steps. For example, if you have added a paid plan, you will need to complete the verification process and complete financial onboarding. As soon as your listing is approved the app is published to {% data variables.product.prodname_marketplace %}. We want to make sure that the apps offered on {% data variables.product.prodname_marketplace %} are safe, secure, and well tested. The {% data variables.product.prodname_marketplace %} onboarding specialists will review your app to ensure that it meets all requirements. Follow the guidelines in these articles before submitting your app: ### Seeing how your app is performing You can access metrics and transactions for your listing. For more information, see: * [Requirements for listing an app on {% data variables.product.prodname_marketplace %}](/marketplace/getting-started/requirements-for-listing-an-app-on-github-marketplace/) * [Security review process](/marketplace/getting-started/security-review-process/) - "[Viewing metrics for your listing](/developers/github-marketplace/viewing-metrics-for-your-listing)" - "[Viewing transactions for your listing](/developers/github-marketplace/viewing-transactions-for-your-listing)" 43 content/developers/github-marketplace/about-verified-creators.md @@ -0,0 +1,43 @@ --- title: About verified creators intro: 'Each organization that wants to sell apps on {% data variables.product.prodname_marketplace %} must follow a verification process. Their identity is checked and their billing process reviewed.' versions: free-pro-team: '*' --- ### About verified creators A verified creator is an organization that {% data variables.product.company_short %} has checked. Anyone can share their apps with other users on {% data variables.product.prodname_marketplace %} but only organizations that are verified by {% data variables.product.company_short %} can sell apps. For more information about organizations, see "[About organizations](/github/setting-up-and-managing-organizations-and-teams/about-organizations)." The verification process aims to protect users. For example, it verifies the seller's identity, checks that their {% data variables.product.product_name %} organization is set up securely, and that they can be contacted for support. After passing the verification checks, any apps that the organization lists on {% data variables.product.prodname_marketplace %} are shown with a verified creator badge {% octicon "verified" aria-label="Verified creator badge" %}. The organization can now add paid plans to any of their apps. Each app with a paid plan also goes through a financial onboarding process to check that it's set up to handle billing correctly.  In addition to the verified creator badge, you'll also see badges for unverified and verified apps. These apps were published using the old method for verifying individual apps.  For information on finding apps to use, see "[Searching {% data variables.product.prodname_marketplace %}](/github/searching-for-information-on-github/searching-github-marketplace)." ### About the verification process The first time you request verification for a listing of one of your apps, you will enter the verification process. An onboarding expert will guide you through the process. This includes checking: - Profile information - The basic profile information is populated accurately and appropriately. - Security - The organization has enabled two-factor authentication. - Verified domain - The organization has verified the domain of the site URL. - Purchase webhook event - The event is handled correctly by the app. When your organization is verified, all your apps are shown with a verified creator badge. You are now able to offer paid plans for any of your apps. For more information about the requirements for listing an app on {% data variables.product.prodname_marketplace %}, see "[Requirements for listing an app on {% data variables.product.prodname_marketplace %}](/marketplace/getting-started/requirements-for-listing-an-app-on-github-marketplace/)." {% data reusables.marketplace.app-transfer-to-org-for-verification %} For information on how to do this, see: "[Submitting your listing for publication](/developers/github-marketplace/submitting-your-listing-for-publication#transferring-an-app-to-an-organization-before-you-submit)." {% note %} **Note:** This verification process for apps replaces the previous process where individual apps were verified. The current process is similar to the verification process for actions. If you have apps that were verified under the old process, these will not be affected by the changes. The {% data variables.product.prodname_marketplace %} team will contact you with details of how to migrate to organization-based verification. {% endnote %} 12 content/developers/github-marketplace/billing-customers.md @@ -13,17 +13,17 @@ versions: ### Understanding the billing cycle Customers can choose a monthly or yearly billing cycle when they purchase your app. All changes customers make to the billing cycle and plan selection will trigger a `marketplace_purchase` event. You can refer to the `marketplace_purchase` webhook payload to see which billing cycle a customer selects and when the next billing date begins (`effective_date`). For more information about webhook payloads, see "[{% data variables.product.prodname_marketplace %} webhook events](/marketplace/integrating-with-the-github-marketplace-api/github-marketplace-webhook-events/)." Customers can choose a monthly or yearly billing cycle when they purchase your app. All changes customers make to the billing cycle and plan selection will trigger a `marketplace_purchase` event. You can refer to the `marketplace_purchase` webhook payload to see which billing cycle a customer selects and when the next billing date begins (`effective_date`). For more information about webhook payloads, see "[Webhook events for the {% data variables.product.prodname_marketplace %} API](/developers/github-marketplace/webhook-events-for-the-github-marketplace-api)." ### Providing billing services in your app's UI Customers must be able to perform the following actions from your app's website: - Customers must be able to modify or cancel their {% data variables.product.prodname_marketplace %} plans for personal and organizational accounts separately. Customers should be able to perform the following actions from your app's website: - Customers should be able to modify or cancel their {% data variables.product.prodname_marketplace %} plans for personal and organizational accounts separately. {% data reusables.marketplace.marketplace-billing-ui-requirements %} ### Billing services for upgrades, downgrades, and cancellations Follow these guidelines for upgrades, downgrades, and cancellations to maintain a clear and consistent billing process. For more detailed instructions about the {% data variables.product.prodname_marketplace %} purchase events, see "[Billing flows](/marketplace/integrating-with-the-github-marketplace-api/#billing-flows)." Follow these guidelines for upgrades, downgrades, and cancellations to maintain a clear and consistent billing process. For more detailed instructions about the {% data variables.product.prodname_marketplace %} purchase events, see "[Using the {% data variables.product.prodname_marketplace %} API in your app](/developers/github-marketplace/using-the-github-marketplace-api-in-your-app)." You can use the `marketplace_purchase` webhook's `effective_date` key to determine when a plan change will occur and periodically synchronize the [List accounts for a plan](/rest/reference/apps#list-accounts-for-a-plan). @@ -33,7 +33,7 @@ When a customer upgrades their pricing plan or changes their billing cycle from {% data reusables.marketplace.marketplace-failed-purchase-event %} For information about building upgrade and downgrade workflows into your app, see "[Upgrading and downgrading plans](/marketplace/integrating-with-the-github-marketplace-api/upgrading-and-downgrading-plans/)." For information about building upgrade and downgrade workflows into your app, see "[Handling plan changes](/developers/github-marketplace/handling-plan-changes)." #### Downgrades and cancellations @@ -45,4 +45,4 @@ When a customer cancels a plan, you must: {% data reusables.marketplace.cancellation-clarification %} - Enable them to upgrade the plan through GitHub if they would like to continue the plan at a later time. For information about building cancellation workflows into your app, see "[Cancelling plans](/marketplace/integrating-with-the-github-marketplace-api/cancelling-plans/)." For information about building cancellation workflows into your app, see "[Handling plan cancellations](/developers/github-marketplace/handling-plan-cancellations)." 20 ...nt/developers/github-marketplace/customer-experience-best-practices-for-apps.md @@ -0,0 +1,20 @@ --- title: Customer experience best practices for apps intro: 'Guidelines for creating an app that will be easy to use and understand.' shortTitle: Customer experience best practice versions: free-pro-team: '*' --- If you follow these best practices it will help you to provide a good customer experience. ### Customer communication - Marketing materials for the app should accurately represent the app's behavior. - Apps should include links to user-facing documentation that describe how to set up and use the app. - Customers should be able to see what type of plan they have in the billing, profile, or account settings section of the app. - Customers should be able to install and use your app on both a personal account and an organization account. They should be able to view and manage the app on those accounts separately. ### Plan management {% data reusables.marketplace.marketplace-billing-ui-requirements %} 4 content/developers/github-marketplace/drafting-a-listing-for-your-app.md @@ -59,8 +59,8 @@ Once you've created a {% data variables.product.prodname_marketplace %} draft li ### Submitting your app Once you've completed your {% data variables.product.prodname_marketplace %} listing, you can submit your listing for review from the **Overview** page. You'll need to read and accept the "[{% data variables.product.prodname_marketplace %} Developer Agreement](/articles/github-marketplace-developer-agreement/)," and then you can click **Submit for review**. After you submit your app for review, the {% data variables.product.prodname_marketplace %} onboarding team will contact you with additional information about the onboarding process. You can learn more about the onboarding and security review process in "[Getting started with {% data variables.product.prodname_marketplace %}](/marketplace/getting-started/)." Once you've completed your {% data variables.product.prodname_marketplace %} listing, you can submit your listing for review from the **Overview** page. You'll need to read and accept the "[{% data variables.product.prodname_marketplace %} Developer Agreement](/articles/github-marketplace-developer-agreement/)," and then you can click **Submit for review**. After you submit your app for review, an onboarding expert will contact you with additional information about the onboarding process. You can learn more about the onboarding and security review process in "[Getting started with {% data variables.product.prodname_marketplace %}](/marketplace/getting-started/)." ### Removing a {% data variables.product.prodname_marketplace %} listing If you no longer want to list your app in {% data variables.product.prodname_marketplace %}, contact [marketplace@github.com](mailto:marketplace@github.com) to remove your listing. If you no longer want to list your app in {% data variables.product.prodname_marketplace %}, contact {% data variables.contact.contact_support %} to remove your listing. 2 content/developers/github-marketplace/handling-new-purchases-and-free-trials.md @@ -28,7 +28,7 @@ GitHub then sends the [`marketplace_purchase`](/webhooks/event-payloads/#marketp Read the `effective_date` and `marketplace_purchase` object from the `marketplace_purchase` webhook to determine which plan the customer purchased, when the billing cycle starts, and when the next billing cycle begins. If your app offers a free trial, read the `marketplace_purchase[on_free_trial]` attribute from the webhook. If the value is `true`, your app will need to track the free trial start date (`effective_date`) and the date the free trial ends (`free_trial_ends_on`). Use the `free_trial_ends_on` date to display the remaining days left in a free trial in your app's UI. You can do this in either a banner or in your [billing UI](/marketplace/selling-your-app/billing-customers-in-github-marketplace/#providing-billing-services-in-your-apps-ui). To learn how to handle cancellations before a free trial ends, see "[Cancelling plans](/marketplace/integrating-with-the-github-marketplace-api/cancelling-plans/)." See "[Upgrading and downgrading plans](/marketplace/integrating-with-the-github-marketplace-api/upgrading-and-downgrading-plans/)" to find out how to transition a free trial to a paid plan when a free trial expires. If your app offers a free trial, read the `marketplace_purchase[on_free_trial]` attribute from the webhook. If the value is `true`, your app will need to track the free trial start date (`effective_date`) and the date the free trial ends (`free_trial_ends_on`). Use the `free_trial_ends_on` date to display the remaining days left in a free trial in your app's UI. You can do this in either a banner or in your [billing UI](/marketplace/selling-your-app/billing-customers-in-github-marketplace/#providing-billing-services-in-your-apps-ui). To learn how to handle cancellations before a free trial ends, see "[Handling plan cancellations](/developers/github-marketplace/handling-plan-cancellations)." See "[Handling plan changes](/developers/github-marketplace/handling-plan-changes)" to find out how to transition a free trial to a paid plan when a free trial expires. See "[{% data variables.product.prodname_marketplace %} webhook events](/marketplace/integrating-with-the-github-marketplace-api/github-marketplace-webhook-events/)" for an example of the `marketplace_purchase` event payload. 6 content/developers/github-marketplace/index.md @@ -11,8 +11,10 @@ versions: {% topic_link_in_list /creating-apps-for-github-marketplace %} {% link_in_list /about-github-marketplace %} {% link_in_list /about-verified-creators %} {% link_in_list /requirements-for-listing-an-app %} {% link_in_list /security-review-process-for-submitted-apps %} {% link_in_list /security-best-practices-for-apps %} {% link_in_list /customer-experience-best-practices-for-apps %} {% link_in_list /viewing-metrics-for-your-listing %} {% link_in_list /viewing-transactions-for-your-listing %} {% topic_link_in_list /using-the-github-marketplace-api-in-your-app %} @@ -27,7 +29,7 @@ versions: {% link_in_list /writing-a-listing-description-for-your-app %} {% link_in_list /setting-pricing-plans-for-your-listing %} {% link_in_list /configuring-a-webhook-to-notify-you-of-plan-changes %} {% link_in_list /submitting-your-listing-for-review %} {% link_in_list /submitting-your-listing-for-publication %} {% topic_link_in_list /selling-your-app-on-github-marketplace %} {% link_in_list /pricing-plans-for-github-marketplace-apps %} {% link_in_list /billing-customers %} 32 content/developers/github-marketplace/pricing-plans-for-github-marketplace-apps.md @@ -10,35 +10,45 @@ versions: {% data variables.product.prodname_marketplace %} pricing plans can be free, flat rate, or per-unit, and GitHub lists the price in US dollars. Customers purchase your app using a payment method attached to their {% data variables.product.product_name %} account, without having to leave GitHub.com. You don't have to write code to perform billing transactions, but you will have to handle [billing flows](/marketplace/integrating-with-the-github-marketplace-api/#billing-flows) for purchase events. {% data variables.product.prodname_marketplace %} pricing plans can be free, flat rate, or per-unit. Prices are set, displayed, and processed in US dollars. Paid plans are restricted to verified listings. Customers purchase your app using a payment method attached to their {% data variables.product.product_name %} account, without having to leave {% data variables.product.prodname_dotcom_the_website %}. You don't have to write code to perform billing transactions, but you will have to handle events from the {% data variables.product.prodname_marketplace %} API. For more information, see "[Using the {% data variables.product.prodname_marketplace %} API in your app](/developers/github-marketplace/using-the-github-marketplace-api-in-your-app)." If the app you're listing on {% data variables.product.prodname_marketplace %} has multiple plan options, you can set up corresponding pricing plans. For example, if your app has two plan options, an open source plan and a pro plan, you can set up a free pricing plan for your open source plan and a flat pricing plan for your pro plan. Each {% data variables.product.prodname_marketplace %} listing must have an annual and a monthly price for every plan that's listed. For more information on how to create a pricing plan, see "[Setting a {% data variables.product.prodname_marketplace %} listing's pricing plan](/marketplace/listing-on-github-marketplace/setting-a-github-marketplace-listing-s-pricing-plan/)." {% note %} {% data reusables.marketplace.free-plan-note %} **Note:** If you're listing an app on {% data variables.product.prodname_marketplace %}, you can't list your app with a free pricing plan if you offer a paid service outside of {% data variables.product.prodname_marketplace %}. ### Types of pricing plans {% endnote %} #### Free pricing plans ### Types of pricing plans {% data reusables.marketplace.free-apps-encouraged %} Free plans are completely free for users. If you set up a free pricing plan, you cannot charge users that choose the free pricing plan for the use of your app. You can create both free and paid plans for your listing. All apps need to handle events for new purchases and cancellations. Apps that only have free plans do not need to handle events for free trials, upgrades, and downgrades. For more information, see: "[Using the {% data variables.product.prodname_marketplace %} API in your app](/developers/github-marketplace/using-the-github-marketplace-api-in-your-app)." If you add a paid plan to an app that you've already listed in {% data variables.product.prodname_marketplace %} as a free service, you'll need to request verification for the app and go through financial onboarding. #### Paid pricing plans **Free pricing plans** are completely free for users. If you set up a free pricing plan, you cannot charge users that choose the free pricing plan for the use of your app. You can create both free and paid plans for your listing. Unverified free apps do not need to implement any billing flows. Free apps that are verified by Github need to implement billing flows for new purchases and cancellations, but do not need to implement billing flows for free trials, upgrades, and downgrades. If you add a paid plan to an app that you've already listed in {% data variables.product.prodname_marketplace %} as a free service, you'll need to resubmit the app for review. There are two types of paid pricing plan: **Flat rate pricing plans** charge a set fee on a monthly and yearly basis. - Flat rate pricing plans charge a set fee on a monthly and yearly basis. **Per-unit pricing plans** charge a set fee on either a monthly or yearly basis for a unit that you specify. A "unit" can be anything you'd like (for example, a user, seat, or person). - Per-unit pricing plans charge a set fee on either a monthly or yearly basis for a unit that you specify. A "unit" can be anything you'd like (for example, a user, seat, or person). **Marketplace free trials** provide 14-day free trials of OAuth or GitHub Apps to customers. When you [set up a Marketplace pricing plan](/marketplace/listing-on-github-marketplace/setting-a-github-marketplace-listing-s-pricing-plan/), you can select the option to provide a free trial for flat-rate or per-unit pricing plans. You may also want to offer free trials. These provide free, 14-day trials of OAuth or GitHub Apps to customers. When you set up a Marketplace pricing plan, you can select the option to provide a free trial for flat-rate or per-unit pricing plans. ### Free trials Customers can start a free trial for any available paid plan on a Marketplace listing, but will not be able to create more than one free trial for a Marketplace product. Customers can start a free trial for any paid plan on a Marketplace listing that includes free trials. However, customers cannot create more than one free trial per marketplace product. Free trials have a fixed length of 14 days. Customers are notified 4 days before the end of their trial period (on day 11 of the free trial) that their plan will be upgraded. At the end of a free trial, customers will be auto-enrolled into the plan they are trialing if they do not cancel. See "[New purchases and free trials](/marketplace/integrating-with-the-github-marketplace-api/handling-new-purchases-and-free-trials/)" for details on how to handle free trials in your app. For more information, see: "[Handling new purchases and free trials](/developers/github-marketplace/integrating-with-the-github-marketplace-api/handling-new-purchases-and-free-trials/)." {% note %} 61 content/developers/github-marketplace/requirements-for-listing-an-app.md @@ -1,6 +1,6 @@ --- title: Requirements for listing an app intro: 'Apps on {% data variables.product.prodname_marketplace %} must meet the requirements outlined on this page before our {% data variables.product.prodname_marketplace %} onboarding specialists will approve the listing.' intro: 'Apps on {% data variables.product.prodname_marketplace %} must meet the requirements outlined on this page before the listing can be published.' redirect_from: - /apps/adding-integrations/listing-apps-on-github-marketplace/requirements-for-listing-an-app-on-github-marketplace/ - /apps/marketplace/listing-apps-on-github-marketplace/requirements-for-listing-an-app-on-github-marketplace/ @@ -12,49 +12,62 @@ versions: free-pro-team: '*' --- <!--UI-LINK: Displayed as a link on the https://github.com/marketplace/new page.--> The requirements for listing an app on {% data variables.product.prodname_marketplace %} vary according to whether you want to offer a free or a paid app. Before you submit your app for review, you must read and accept the terms of the "[{% data variables.product.prodname_marketplace %} Developer Agreement](/articles/github-marketplace-developer-agreement/)." You'll accept the terms within your [draft listing](/marketplace/listing-on-github-marketplace/creating-a-draft-github-marketplace-listing/) on {% data variables.product.product_name %}. Once you've submitted your app, one of the {% data variables.product.prodname_marketplace %} onboarding specialists will reach out to you with more information about the onboarding process, and review your app to ensure it meets these requirements: ### Requirements for all {% data variables.product.prodname_marketplace %} listings ### User experience All listings on {% data variables.product.prodname_marketplace %} should be for tools that provide value to the {% data variables.product.product_name %} community. When you submit your listing for publication, you must read and accept the terms of the "[{% data variables.product.prodname_marketplace %} Developer Agreement](/articles/github-marketplace-developer-agreement/)." - {% data variables.product.prodname_github_app %}s should have a minimum of 100 installations. - {% data variables.product.prodname_oauth_app %}s should have a minimum of 200 users. #### User experience requirements for all apps All listings should meet the following requirements, regardless of whether they are for a free or paid app. - Listings must not actively persuade users away from {% data variables.product.product_name %}. - Listings must include valid contact information for the publisher. - Listings must have a relevant description of the application. - Listings must specify a pricing plan. - Apps must provide value to customers and integrate with the platform in some way beyond authentication. - Apps must be publicly available in {% data variables.product.prodname_marketplace %} and cannot be in beta or available by invite only. - Apps cannot actively persuade users away from {% data variables.product.product_name %}. - Marketing materials for the app must accurately represent the app's behavior. - Apps must include links to user-facing documentation that describe how to set up and use the app. - When a customer purchases an app and GitHub redirects them to the app's installation URL, the app must begin the OAuth flow immediately. For details, see "[Handling new purchases and free trials](/marketplace/integrating-with-the-github-marketplace-api/handling-new-purchases-and-free-trials/#step-3-authorization)." - Apps must have webhook events set up to notify the publisher of any plan changes or cancellations using the {% data variables.product.prodname_marketplace %} API. For more information, see "[Using the {% data variables.product.prodname_marketplace %} API in your app](/developers/github-marketplace/using-the-github-marketplace-api-in-your-app)." - Customers must be able to install your app and select repositories on both a personal and organization account. They should be able to view and manage those accounts separately. For more information on providing a good customer experience, see "[Customer experience best practices for apps](/developers/github-marketplace/customer-experience-best-practices-for-apps)." ### Brand and listing #### Brand and listing requirements for all apps - Apps that use GitHub logos must follow the "[{% data variables.product.product_name %} Logos and Usage](https://github.com/logos)" guidelines. - Apps that use GitHub logos must follow the {% data variables.product.company_short %} guidelines. For more information, see "[{% data variables.product.company_short %} Logos and Usage](https://github.com/logos)." - Apps must have a logo, feature card, and screenshots images that meet the recommendations provided in "[Writing {% data variables.product.prodname_marketplace %} listing descriptions](/marketplace/listing-on-github-marketplace/writing-github-marketplace-listing-descriptions/)." - Listings must include descriptions that are well written and free of grammatical errors. For guidance in writing your listing, see "[Writing {% data variables.product.prodname_marketplace %} listing descriptions](/marketplace/listing-on-github-marketplace/writing-github-marketplace-listing-descriptions/)." ### Security To protect your customers, we recommend that you also follow security best practices. For more information, see "[Security best practices for apps](/developers/github-marketplace/security-best-practices-for-apps)." ### Considerations for free apps Apps will go through a security review before being listed on {% data variables.product.prodname_marketplace %}. A successful review will meet the requirements and follow the security best practices listed in "[Security review process](/marketplace/getting-started/security-review-process/)." For information on the review process, contact [marketplace@github.com](mailto:marketplace@github.com). {% data reusables.marketplace.free-apps-encouraged %} ### Requirements for paid apps In addition to the requirements for all apps above, each app that you offer as a paid service on {% data variables.product.prodname_marketplace %} must also meet the following requirements: - {% data variables.product.prodname_github_app %}s should have a minimum of 100 installations. - {% data variables.product.prodname_oauth_app %}s should have a minimum of 200 users. - All paid apps must handle {% data variables.product.prodname_marketplace %} purchase events for new purchases, upgrades, downgrades, cancellations, and free trials. For more information, see "[Billing requirements for paid apps](#billing-requirements-for-paid-apps)" below. - Publishing organizations must have a verified domain and must enable two-factor authentication. For more information, see "[Requiring two-factor authentication in your organization](/github/setting-up-and-managing-organizations-and-teams/requiring-two-factor-authentication-in-your-organization.") ### Billing flows When you are ready to publish the app on {% data variables.product.prodname_marketplace %} you must request verification for the listing. Your app must integrate [billing flows](/marketplace/integrating-with-the-github-marketplace-api/#billing-flows) using the [{% data variables.product.prodname_marketplace %} webhook event](/marketplace/integrating-with-the-github-marketplace-api/github-marketplace-webhook-events/). {% note %} #### Free apps The verification process is open to organizations. {% data reusables.marketplace.app-transfer-to-org-for-verification %} For information on how to do this, see: "[Submitting your listing for publication](/developers/github-marketplace/submitting-your-listing-for-publication#transferring-an-app-to-an-organization-before-you-submit)." {% data reusables.marketplace.free-apps-encouraged %} If you are listing a free app, you'll need to meet these requirements: {% endnote %} - Customers must be able to see that they have a free plan in the billing, profile, or account settings section of the app. - When a customer cancels your app, you must follow the flow for [cancelling plans](/marketplace/integrating-with-the-github-marketplace-api/cancelling-plans/). ### Billing requirements for paid apps #### Paid apps Your app does not need to handle payments but does need to use {% data variables.product.prodname_marketplace %} purchase events to manage new purchases, upgrades, downgrades, cancellations, and free trials. For information about how integrate these events into your app, see "[Using the {% data variables.product.prodname_marketplace %} API in your app](/developers/github-marketplace/using-the-github-marketplace-api-in-your-app)." To offer your app as a paid service, you'll need to meet these requirements to list your app on {% data variables.product.prodname_marketplace %}: Using GitHub's billing API allows customers to purchase an app without leaving GitHub and to pay for the service with the payment method already attached to their {% data variables.product.product_name %} account. - To sell your app in {% data variables.product.prodname_marketplace %}, it must use GitHub's billing system. Your app does not need to handle payments but does need to use "[{% data variables.product.prodname_marketplace %} purchase events](/marketplace/integrating-with-the-github-marketplace-api/github-marketplace-webhook-events/)" to manage new purchases, upgrades, downgrades, cancellations, and free trials. See "[Billing flows](/marketplace/integrating-with-the-github-marketplace-api/#billing-flows)" to learn about how to integrate these events into your app. Using GitHub's billing system allows customers to purchase an app without leaving GitHub and pay for the service with the payment method already attached to their {% data variables.product.product_name %} account. - Apps must support both monthly and annual billing for paid subscriptions purchases. - Listings may offer any combination of free and paid plans. Free plans are optional but encouraged. For more information, see "[Setting a {% data variables.product.prodname_marketplace %} listing's pricing plan](/marketplace/listing-on-github-marketplace/setting-a-github-marketplace-listing-s-pricing-plan/)." {% data reusables.marketplace.marketplace-billing-ui-requirements %} 60 content/developers/github-marketplace/security-best-practices-for-apps.md @@ -0,0 +1,60 @@ --- title: Security best practices for apps intro: 'Guidelines for preparing a secure app to share on {% data variables.product.prodname_marketplace %}.' redirect_from: - /apps/marketplace/getting-started/security-review-process/ - /marketplace/getting-started/security-review-process - /developers/github-marketplace/security-review-process-for-submitted-apps shortTitle: Security best practice versions: free-pro-team: '*' --- If you follow these best practices it will help you to provide a secure user experience. ### Authorization, authentication, and access control We recommend creating a GitHub App rather than an OAuth App. {% data reusables.marketplace.github_apps_preferred %}. See "[Differences between GitHub Apps and OAuth Apps](/apps/differences-between-apps/)" for more details. - Apps should use the principle of least privilege and should only request the OAuth scopes and GitHub App permissions that the app needs to perform its intended functionality. For more information, see [Principle of least privilege](https://en.wikipedia.org/wiki/Principle_of_least_privilege) in Wikipedia. - Apps should provide customers with a way to delete their account, without having to email or call a support person. - Apps should not share tokens between different implementations of the app. For example, a desktop app should have a separate token from a web-based app. Individual tokens allow each app to request the access needed for GitHub resources separately. - Design your app with different user roles, depending on the functionality needed by each type of user. For example, a standard user should not have access to admin functionality, and billing managers might not need push access to repository code. - Apps should not share service accounts such as email or database services to manage your SaaS service. - All services used in your app should have unique login and password credentials. - Admin privilege access to the production hosting infrastructure should only be given to engineers and employees with administrative duties. - Apps should not use personal access tokens to authenticate and should authenticate as an [OAuth App](/apps/about-apps/#about-oauth-apps) or a [GitHub App](/apps/about-apps/#about-github-apps): - OAuth Apps should authenticate using an [OAuth token](/apps/building-oauth-apps/authorizing-oauth-apps/). - GitHub Apps should authenticate using either a [JSON Web Token (JWT)](/apps/building-github-apps/authenticating-with-github-apps/#authenticating-as-a-github-app), [OAuth token](/apps/building-github-apps/identifying-and-authorizing-users-for-github-apps/), or [installation access token](/apps/building-github-apps/authenticating-with-github-apps/#authenticating-as-an-installation). ### Data protection - Apps should encrypt data transferred over the public internet using HTTPS, with a valid TLS certificate, or SSH for Git. - Apps should store client ID and client secret keys securely. We recommend storing them as [environmental variables](http://en.wikipedia.org/wiki/Environment_variable#Getting_and_setting_environment_variables). - Apps should delete all GitHub user data within 30 days of receiving a request from the user, or within 30 days of the end of the user's legal relationship with GitHub. - Apps should not require the user to provide their GitHub password. - Apps should encrypt tokens, client IDs, and client secrets. ### Logging and monitoring Apps should have logging and monitoring capabilities. App logs should be retained for at least 30 days and archived for at least one year. A security log should include: - Authentication and authorization events - Service configuration changes - Object reads and writes - All user and group permission changes - Elevation of role to admin - Consistent timestamping for each event - Source users, IP addresses, and/or hostnames for all logged actions ### Incident response workflow To provide a secure experience for users, you should have a clear incident response plan in place before listing your app. We recommend having a security and operations incident response team in your company rather than using a third-party vendor. You should have the capability to notify {% data variables.product.product_name %} within 24 hours of a confirmed incident. For an example of an incident response workflow, see the "Data Breach Response Policy" on the [SANS Institute website](https://www.sans.org/information-security-policy/). A short document with clear steps to take in the event of an incident is more valuable than a lengthy policy template. ### Vulnerability management and patching workflow You should conduct regular vulnerability scans of production infrastructure. You should triage the results of vulnerability scans and define a period of time in which you agree to remediate the vulnerability. If you are not ready to set up a full vulnerability management program, it's useful to start by creating a patching process. For guidance in creating a patch management policy, see this TechRepublic article "[Establish a patch management policy](https://www.techrepublic.com/blog/it-security/establish-a-patch-management-policy-87756/)." 94 ...ent/developers/github-marketplace/security-review-process-for-submitted-apps.md This file was deleted. 53 content/developers/github-marketplace/setting-pricing-plans-for-your-listing.md @@ -1,6 +1,6 @@ --- title: Setting pricing plans for your listing intro: 'When [listing your app on {% data variables.product.prodname_marketplace %}](/marketplace/listing-on-github-marketplace/), you can choose to provide your app as a free service or sell your app. If you plan to sell your app, you can create different pricing plans for different feature tiers.' intro: 'When you list your app on {% data variables.product.prodname_marketplace %}, you can choose to provide your app as a free service or sell your app. If you plan to sell your app, you can create different pricing plans for different feature tiers.' redirect_from: - /apps/adding-integrations/managing-pricing-and-payments-for-a-github-marketplace-listing/setting-a-github-marketplace-listing-s-pricing-plan/ - /apps/marketplace/managing-pricing-and-payments-for-a-github-marketplace-listing/setting-a-github-marketplace-listing-s-pricing-plan/ @@ -17,57 +17,52 @@ versions: free-pro-team: '*' --- ### About setting pricing plans If you want to sell an app on {% data variables.product.prodname_marketplace %}, you need to request verification when you publish the listing for your app. During the verification process, an onboarding expert checks the organization's identity and security settings. The onboarding expert will also take the organization through financial onboarding. For more information, see: "[Requirements for listing an app on {% data variables.product.prodname_marketplace %}](/marketplace/getting-started/requirements-for-listing-an-app-on-github-marketplace/)." ### Creating pricing plans To learn about the types of pricing plans that {% data variables.product.prodname_marketplace %} offers, see "[{% data variables.product.prodname_marketplace %} Pricing Plans](/marketplace/selling-your-app/github-marketplace-pricing-plans/)." You'll also find helpful billing guidelines in "[Selling your app](/marketplace/selling-your-app/)." Pricing plans can be in the draft or published state. If you haven't submitted your {% data variables.product.prodname_marketplace %} listing for approval, a published listing will function the same way as draft listings until your app is approved and listed on {% data variables.product.prodname_marketplace %}. Draft listings allow you to create and save new pricing plans without making them available on your {% data variables.product.prodname_marketplace %} listing page. Once you publish the pricing plan, it's available for customers to purchase immediately. You can publish up to 10 pricing plans. {% data reusables.marketplace.app-transfer-to-org-for-verification %} For information on how to do this, see: "[Submitting your listing for publication](/developers/github-marketplace/submitting-your-listing-for-publication#transferring-an-app-to-an-organization-before-you-submit)." To create a pricing plan for your {% data variables.product.prodname_marketplace %} listing, click **Plans and pricing** in the left sidebar of your [{% data variables.product.prodname_marketplace %} listing page](https://github.com/marketplace/manage). If you haven't created a {% data variables.product.prodname_marketplace %} listing yet, read "[Creating a draft {% data variables.product.prodname_marketplace %} listing](/marketplace/listing-on-github-marketplace/creating-a-draft-github-marketplace-listing/)" to learn how. When you click **New draft plan**, you'll see a form that allows you to customize your pricing plan. You'll need to configure the following fields to create a pricing plan: {% data variables.product.prodname_marketplace %} offers several different types of pricing plan. For detailed information, see "[Pricing plans for {% data variables.product.prodname_marketplace %}](/developers/github-marketplace/pricing-plans-for-github-marketplace-apps)." #### Plan name ### About saving pricing plans Your pricing plan's name will appear on your {% data variables.product.prodname_marketplace %} app's landing page. You can customize the name of your pricing plan to align to the plan's resources, the size of the company that will use the plan, or anything you'd like. You can save pricing plans in a draft or published state. If you haven't submitted your {% data variables.product.prodname_marketplace %} listing for approval, a published plan will function in the same way as a draft plan until your listing is approved and shown on {% data variables.product.prodname_marketplace %}. Draft plans allow you to create and save new pricing plans without making them available on your {% data variables.product.prodname_marketplace %} listing page. Once you publish a pricing plan on a published listing, it's available for customers to purchase immediately. You can publish up to 10 pricing plans. #### Pricing models For guidelines on billing customers, see "[Billing customers](/developers/github-marketplace/billing-customers)." ##### Free plans {% data reusables.marketplace.free-apps-encouraged %} A free plan still requires you to handle [new purchase](/marketplace/integrating-with-the-github-marketplace-api/handling-new-purchases-and-free-trials/) and [cancellation](/marketplace/integrating-with-the-github-marketplace-api/cancelling-plans/) billing flows. See "[Billing flows](/marketplace/integrating-with-the-github-marketplace-api/#billing-flows)" for more details. ##### Flat-rate plans ### Creating pricing plans Flat-rate pricing plans allow you to offer your service to customers for a flat-rate fee. {% data reusables.marketplace.marketplace-pricing-free-trials %} To create a pricing plan for your {% data variables.product.prodname_marketplace %} listing, click **Plans and pricing** in the left sidebar of your [{% data variables.product.prodname_marketplace %} listing page](https://github.com/marketplace/manage). For more information, see "[Creating a draft {% data variables.product.prodname_marketplace %} listing](/marketplace/listing-on-github-marketplace/creating-a-draft-github-marketplace-listing/)." You must set a price for both monthly and yearly subscriptions in U.S. Dollars for flat-rate plans. When you click **New draft plan**, you'll see a form that allows you to customize your pricing plan. You'll need to configure the following fields to create a pricing plan: ##### Per-unit plans - **Plan name** - Your pricing plan's name will appear on your {% data variables.product.prodname_marketplace %} app's landing page. You can customize the name of your pricing plan to align with the plan's resources, the size of the company that will use the plan, or anything you'd like. Per-unit pricing allows you to offer your app in units. For example, a unit can be a person, seat, or user. You'll need to provide a name for the unit and set a price for both monthly and yearly subscriptions, in U.S. Dollars. - **Pricing models** - There are three types of pricing plan: free, flat-rate, and per-unit. All plans require you to process new purchase and cancellation events from the marketplace API. In addition, for paid plans: #### Available for - You must set a price for both monthly and yearly subscriptions in US dollars. - Your app must process plan change events. - You must request verification to publish a listing with a paid plan. - {% data reusables.marketplace.marketplace-pricing-free-trials %} {% data variables.product.prodname_marketplace %} pricing plans can apply to **Personal and organization accounts**, **Personal accounts only**, or **Organization accounts only**. For example, if your pricing plan is per-unit and provides multiple seats, you would select **Organization accounts only** because there is no way to assign seats to people in an organization from a personal account. For detailed information, see "[Pricing plans for {% data variables.product.prodname_marketplace %} apps](/developers/github-marketplace/pricing-plans-for-github-marketplace-apps)" and "[Using the {% data variables.product.prodname_marketplace %} API in your app](/developers/github-marketplace/using-the-github-marketplace-api-in-your-app)." #### Short description - **Available for** - {% data variables.product.prodname_marketplace %} pricing plans can apply to **Personal and organization accounts**, **Personal accounts only**, or **Organization accounts only**. For example, if your pricing plan is per-unit and provides multiple seats, you would select **Organization accounts only** because there is no way to assign seats to people in an organization from a personal account. Write a brief summary of the details of the pricing plan. The description might include the type of customer the plan is intended for or the resources the plan includes. - **Short description** - Write a brief summary of the details of the pricing plan. The description might include the type of customer the plan is intended for or the resources the plan includes. #### Bullets - **Bullets** - You can write up to four bullets that include more details about your pricing plan. The bullets might include the use cases of your app or list more detailed information about the resources or features included in the plan. You can write up to four bullets that include more details about your pricing plan. The bullets might include the use cases of your app or list more detailed information about the resources or features included in the plan. {% data reusables.marketplace.free-plan-note %} ### Changing a {% data variables.product.prodname_marketplace %} listing's pricing plan If a pricing plan for your {% data variables.product.prodname_marketplace %} plan is no longer needed or if you need to adjust pricing details, you can remove it. If a pricing plan for your {% data variables.product.prodname_marketplace %} listing is no longer needed, or if you need to adjust pricing details, you can remove it.  Once you publish a pricing plan for an app already listed in the {% data variables.product.prodname_marketplace %}, you can't make changes to the plan. Instead, you'll need to remove the pricing plan. Customers who already purchased the removed pricing plan will continue to use it until they opt out and move onto a new pricing plan. For more on pricing plans, see "[{% data variables.product.prodname_marketplace %} pricing plans](/marketplace/selling-your-app/github-marketplace-pricing-plans/)." Once you publish a pricing plan for an app that is already listed in {% data variables.product.prodname_marketplace %}, you can't make changes to the plan. Instead, you'll need to remove the pricing plan and create a new plan. Customers who already purchased the removed pricing plan will continue to use it until they opt out and move onto a new pricing plan. For more on pricing plans, see "[{% data variables.product.prodname_marketplace %} pricing plans](/marketplace/selling-your-app/github-marketplace-pricing-plans/)." Once you remove a pricing plan, users won't be able to purchase your app using that plan. Existing users on the removed pricing plan will continue to stay on the plan until they cancel their plan subscription. 37 content/developers/github-marketplace/submitting-your-listing-for-publication.md @@ -0,0 +1,37 @@ --- title: Submitting your listing for publication intro: 'You can submit your listing for the {% data variables.product.prodname_dotcom %} community to use.' redirect_from: - /marketplace/listing-on-github-marketplace/submitting-your-listing-for-review - /developers/github-marketplace/submitting-your-listing-for-review versions: free-pro-team: '*' --- Once you've completed the listing for your app, you'll see two buttons that allow you to request publication of the listing with or without verification. The **Request** button for "Publish without verification" is disabled if you have published any paid pricing plans in the listing.  {% data reusables.marketplace.launch-with-free %} After you submit your listing for review, an onboarding expert will reach out to you with additional information. For an overview of the process for creating and submitting a listing, see "[About {% data variables.product.prodname_marketplace %}](/developers/github-marketplace/about-github-marketplace#publishing-an-app-to-github-marketplace)." ### Prerequisites for publishing with verification Before you request verification of your listing, you'll need to integrate the {% data variables.product.prodname_marketplace %} billing flows and webhook into your app. For more information, see "[Using the {% data variables.product.prodname_marketplace %} API in your app](/developers/github-marketplace/using-the-github-marketplace-api-in-your-app)." If you've met the requirements for listing and you've integrated with the {% data variables.product.prodname_marketplace %} API, go ahead and submit your listing. For more information, see "[Requirements for listing an app](/developers/github-marketplace/requirements-for-listing-an-app)." {% data reusables.marketplace.app-transfer-to-org-for-verification %} For information on how to do this, see: "[Transferring an app to an organization before you submit](#transferring-an-app-to-an-organization-before-you-submit)" below. ### Transferring an app to an organization before you submit You cannot sell an app that's owned by a user account. You need to transfer the app to an organization that is already a verified creator, or that can request verification for a listing for the app. For details, see: 1. "[Creating an organization from scratch](/github/setting-up-and-managing-organizations-and-teams/creating-a-new-organization-from-scratch)" 1. "[Transferring ownership of a GitHub App](/developers/apps/transferring-ownership-of-a-github-app)" or "[Transferring ownership of an OAuth App](/developers/apps/transferring-ownership-of-an-oauth-app)" 22 content/developers/github-marketplace/submitting-your-listing-for-review.md This file was deleted. 4 content/developers/github-marketplace/testing-your-app.md @@ -1,6 +1,6 @@ --- title: Testing your app intro: 'GitHub recommends testing your app with APIs and webhooks before submitting your listing to {% data variables.product.prodname_marketplace %} so you can provide an ideal experience for customers. Before the {% data variables.product.prodname_marketplace %} onboarding team approves your app, it must adequately handle the [billing flows](/marketplace/integrating-with-the-github-marketplace-api/#billing-flows).' intro: 'GitHub recommends testing your app with APIs and webhooks before submitting your listing to {% data variables.product.prodname_marketplace %} so you can provide an ideal experience for customers. Before an onboarding expert approves your app, it must adequately handle the billing flows.' redirect_from: - /apps/marketplace/testing-apps-apis-and-webhooks/ - /apps/marketplace/integrating-with-the-github-marketplace-api/testing-github-marketplace-apps/ @@ -13,7 +13,7 @@ versions: ### Testing apps You can use a [draft {% data variables.product.prodname_marketplace %} listing](/marketplace/listing-on-github-marketplace/creating-a-draft-github-marketplace-listing/) to simulate each of the [billing flows](/marketplace/integrating-with-the-github-marketplace-api/#billing-flows). A listing in the draft state means that it has not been submitted for approval. Any purchases you make using a draft {% data variables.product.prodname_marketplace %} listing will _not_ create real transactions, and GitHub will not charge your credit card. You can use a draft {% data variables.product.prodname_marketplace %} listing to simulate each of the billing flows. A listing in the draft state means that it has not been submitted for approval. Any purchases you make using a draft {% data variables.product.prodname_marketplace %} listing will _not_ create real transactions, and GitHub will not charge your credit card. For more information, see "[Drafting a listing for your app](/developers/github-marketplace/drafting-a-listing-for-your-app)" and "[Using the {% data variables.product.prodname_marketplace %} API in your app](/developers/github-marketplace/using-the-github-marketplace-api-in-your-app)." #### Using a development app with a draft listing to test changes 2 .../developers/github-marketplace/webhook-events-for-the-github-marketplace-api.md @@ -1,6 +1,6 @@ --- title: Webhook events for the GitHub Marketplace API intro: 'A {% data variables.product.prodname_marketplace %} app receives information about changes to a user''s plan from the Marketplace purchase event webhook. A Marketplace purchase event is triggered when a user purchases, cancels, or changes their payment plan. For details on how to respond to each of these types of events, see "[Billing flows](/marketplace/integrating-with-the-github-marketplace-api/#billing-flows)."' intro: 'A {% data variables.product.prodname_marketplace %} app receives information about changes to a user''s plan from the Marketplace purchase event webhook. A Marketplace purchase event is triggered when a user purchases, cancels, or changes their payment plan.' redirect_from: - /apps/marketplace/setting-up-github-marketplace-webhooks/about-webhook-payloads-for-a-github-marketplace-listing/ - /apps/marketplace/integrating-with-the-github-marketplace-api/github-marketplace-webhook-events/ 4 content/developers/webhooks-and-events/webhook-events-and-payloads.md @@ -445,7 +445,7 @@ Key | Type | Description #### Webhook payload object {% data reusables.webhooks.installation_properties %} {% data reusables.webhooks.app_desc %} {% data reusables.webhooks.app_always_desc %} {% data reusables.webhooks.sender_desc %} #### Webhook payload example @@ -469,7 +469,7 @@ Key | Type | Description #### Webhook payload object {% data reusables.webhooks.installation_repositories_properties %} {% data reusables.webhooks.app_desc %} {% data reusables.webhooks.app_always_desc %} {% data reusables.webhooks.sender_desc %} #### Webhook payload example 54 ...ssions/collaborating-with-your-community-using-discussions/about-discussions.md @@ -0,0 +1,54 @@ --- title: About discussions intro: Use discussions to ask and answer questions, share information, make announcements, and conduct or participate in a conversation about a project on {% data variables.product.product_name %}. versions: free-pro-team: '*' --- {% data reusables.discussions.beta %} ### About discussions With {% data variables.product.prodname_discussions %}, the community for your project can create and participate in conversations within the project's repository. Discussions empower a project's maintainers, contributors, and visitors to gather and accomplish the following goals in a central location, without third-party tools. - Share announcements and information, gather feedback, plan, and make decisions - Ask questions, discuss and answer the questions, and mark the discussions as answered - Foster an inviting atmosphere for visitors and contributors to discuss goals, development, administration, and workflows  You don't need to close a discussion like you close an issue or a pull request. If a repository administrator or project maintainer enables discussions for a repository, anyone who visits the repository can create and participate in discussions for the repository. Repository administrators and project maintainers can manage discussions and discussion categories in a repository, and pin discussions to increase the visibility of the discussion. Moderators and collaborators can mark comments as answers, lock discussions, and convert issues to discussions. For more information, see "[Repository permission levels for an organization](/github/setting-up-and-managing-organizations-and-teams/repository-permission-levels-for-an-organization)." For more information about management of discussions for your repository, see "[Managing discussions in your repository](/discussions/managing-discussions-for-your-community/managing-discussions-in-your-repository)." ### About categories and formats for discussions {% data reusables.discussions.you-can-categorize-discussions %} {% data reusables.discussions.about-categories-and-formats %} {% data reusables.discussions.repository-category-limit %} For discussions with a question/answer format, an individual comment within the discussion can be marked as the discussion's answer. {% data reusables.discussions.github-recognizes-members %} For more information, see "[Managing categories for discussions in your repository](/discussions/managing-discussions-for-your-community/managing-categories-for-discussions-in-your-repository)." ### Best practices for discussions As a community member or maintainer, start a discussion to ask a question or discuss information that affects the community. For more information, see "[Collaborating with maintainers using discussions](/discussions/collaborating-with-your-community-using-discussions/collaborating-with-maintainers-using-discussions)." Participate in a discussion to ask and answer questions, provide feedback, and engage with the project's community. For more information, see "[Participating in a discussion](/discussions/collaborating-with-your-community-using-discussions/participating-in-a-discussion)." You can spotlight discussions that contain important, useful, or exemplary conversations among members in the community. For more information, see "[Managing discussions in your repository](/discussions/managing-discussions-for-your-community/managing-discussions-in-your-repository#pinning-a-discussion)." {% data reusables.discussions.you-can-convert-an-issue %} For more information, see "[Moderating discussions in your repository](/discussions/managing-discussions-for-your-community/moderating-discussions#converting-an-issue-to-a-discussion)." ### Sharing feedback You can share your feedback about {% data variables.product.prodname_discussions %} with {% data variables.product.company_short %}. To join the conversation, see [`github/feedback`](https://github.com/github/feedback/discussions?discussions_q=category%3A%22Discussions+Feedback%22). ### Further reading - "[About writing and formatting on {% data variables.product.prodname_dotcom %}](/github/writing-on-github/about-writing-and-formatting-on-github)" - "[Searching discussions](/github/searching-for-information-on-github/searching-discussions)" - "[About notifications](/github/managing-subscriptions-and-notifications-on-github/about-notifications)" - "[Moderating comments and conversations](/github/building-a-strong-community/moderating-comments-and-conversations)" - "[Maintaining your safety on {% data variables.product.prodname_dotcom %}](/github/building-a-strong-community/maintaining-your-safety-on-github)" 50 ...community-using-discussions/collaborating-with-maintainers-using-discussions.md @@ -0,0 +1,50 @@ --- title: Collaborating with maintainers using discussions shortTitle: Collaborating with maintainers intro: You can contribute to the goals, plans, health, and community for a project on {% data variables.product.product_name %} by communicating with the maintainers of the project in a discussion. permissions: People with read permissions to a repository can start and participate in discussions in the repository. versions: free-pro-team: '*' --- {% data reusables.discussions.beta %} ### About collaboration with maintainers using discussions {% data reusables.discussions.about-discussions %} If you use or contribute to a project, you can start a discussion to make suggestions and engage with maintainers and community members about your plans, questions, ideas, and feedback. For more information, see "[About discussions](/discussions/collaborating-with-your-community-using-discussions/about-discussions)." {% data reusables.discussions.about-categories-and-formats %} Repository administrators and project maintainers can delete a discussion. For more information, see "[Managing discussions in your repository](/discussions/managing-discussions-for-your-community/managing-discussions-in-your-repository#deleting-a-discussion)." {% data reusables.discussions.github-recognizes-members %} These members appear in a list of the most helpful contributors to the project's discussions. As your project grows, you can grant higher access permissions to active members of your community. For more information, see "[Granting higher permissions to top contributors](/discussions/guides/granting-higher-permissions-to-top-contributors)"  For more information about participation in discussions, see "[Participating in a discussion](/discussions/collaborating-with-your-community-using-discussions/participating-in-a-discussion)." ### Prerequisites To collaborate with maintainers using discussions, a repository administrator or project maintainer must enable discussions for the repository. For more information, see "[Enabling or disabling discussions for a repository](/github/administering-a-repository/enabling-or-disabling-github-discussions-for-a-repository)." ### Starting a discussion {% data reusables.discussions.starting-a-discussion %} ### Filtering the list of discussions You can search for discussions and filter the list of discussions in a repository. For more information, see "[Searching discussions](/github/searching-for-information-on-github/searching-discussions)." {% data reusables.repositories.navigate-to-repo %} {% data reusables.discussions.discussions-tab %} 1. In the **Search all discussions** field, type a search query. Optionally, to the right of the search field, click a button to further filter the results.  1. In the list of discussions, click the discussion you want to view.  ### Converting an issue to a discussion {% data reusables.discussions.you-can-convert-an-issue %} For more information, see "[Moderating discussions in your repository](/discussions/managing-discussions-for-your-community/moderating-discussions#converting-an-issue-to-a-discussion#converting-an-issue-to-a-discussion)." ### Further reading - "[About writing and formatting on {% data variables.product.prodname_dotcom %}](/github/writing-on-github/about-writing-and-formatting-on-github)" - "[Maintaining your safety on {% data variables.product.prodname_dotcom %}](/github/building-a-strong-community/maintaining-your-safety-on-github)" 14 content/discussions/collaborating-with-your-community-using-discussions/index.md @@ -0,0 +1,14 @@ --- title: Collaborating with your community using discussions shortTitle: Collaborating using discussions intro: Gather and discuss your project with community members and other maintainers. versions: free-pro-team: '*' --- {% data reusables.discussions.beta %} {% link_in_list /about-discussions %} {% link_in_list /participating-in-a-discussion %} {% link_in_list /collaborating-with-maintainers-using-discussions %} 31 ...borating-with-your-community-using-discussions/participating-in-a-discussion.md @@ -0,0 +1,31 @@ --- title: Participating in a discussion intro: You can converse with the community and maintainers in a forum within the repository for a project on {% data variables.product.product_name %}. permissions: People with read permissions to a repository can participate in discussions in the repository. versions: free-pro-team: '*' --- {% data reusables.discussions.beta %} ### About participation in a discussion {% data reusables.discussions.about-discussions %} For more information, see "[About discussions](/discussions/collaborating-with-your-community-using-discussions/about-discussions)." In addition to starting or viewing a discussion, you can comment in response to the original comment from the author of the discussion. You can also create a comment thread by replying to an individual comment that another community member made within the discussion, and react to comments with emoji. For more information about reactions, see "[About conversations on {% data variables.product.prodname_dotcom %}](/github/collaborating-with-issues-and-pull-requests/about-conversations-on-github#reacting-to-ideas-in-comments)." You can block users and report disruptive content to maintain a safe and pleasant environment for yourself on {% data variables.product.product_name %}. For more information, see "[Maintaining your safety on {% data variables.product.prodname_dotcom %}](/github/building-a-strong-community/maintaining-your-safety-on-github)." ### Prerequisites Discussions must be enabled for the repository for you to participate in a discussion in the repository. For more information, see "[Enabling or disabling discussions for a repository](/github/administering-a-repository/enabling-or-disabling-github-discussions-for-a-repository)." ### Creating a discussion {% data reusables.discussions.starting-a-discussion %} ### Marking a comment as an answer Discussion authors and users with the triage role or greater for a repository can mark a comment as the answer to a discussion in the repository. {% data reusables.discussions.marking-a-comment-as-an-answer %} 49 content/discussions/guides/best-practices-for-community-conversations-on-github.md @@ -0,0 +1,49 @@ --- title: Best practices for community conversations on GitHub shortTitle: Best practices for community conversations intro: 'You can use discussions to brainstorm with your team, and eventually move the conversation to a discussion when you are ready to scope out the work.' versions: free-pro-team: '*' --- {% data reusables.discussions.beta %} ### Community conversations in {% data variables.product.prodname_discussions %} Since {% data variables.product.prodname_discussions %} is an open forum, there is an opportunity to bring non-code collaboration into a project's repository and gather diverse feedback and ideas more quickly. You can help drive a productive conversation by: - Asking pointed questions and follow-up questions to garner specific feedback - Capture a diverse experience and distill it down to main points - Open an issue to take action based on the conversation, where applicable For more information about opening an issue and cross-referencing a discussion, see "[Opening an issue from a comment](/github/managing-your-work-on-github/opening-an-issue-from-a-comment)." ### Learning about conversations on GitHub You can create and participate in discussions, issues, and pull requests, depending on the type of conversation you'd like to have. You can use {% data variables.product.prodname_discussions %} to discuss big picture ideas, brainstorm, and spike out a project's specific details before committing it to an issue, which can then be scoped. Discussions are useful for teams if: - You are in the discovery phase of a project and are still learning which director your team wants to go in - You want to collect feedback from a wider community about a project - You want to keep bug fixes, feature requests, and general conversations separate Issues are useful for discussing specific details of a project such as bug reports and planned improvements. For more information, see "[About issues](/articles/about-issues)." Pull requests allow you to comment directly on proposed changes. For more information, see "[About pull requests](/articles/about-pull-requests)" and "[Commenting on a pull request](/articles/commenting-on-a-pull-request)." {% data reusables.organizations.team-discussions-purpose %} For more information, see "[About team discussions](/articles/about-team-discussions)." ### Following contributing guidelines Before you open a discussion, check to see if the repository has contributing guidelines. The CONTRIBUTING file includes information about how the repository maintainer would like you to contribute ideas to the project. For more information, see "[Setting up your project for healthy contributions](/github/building-a-strong-community/setting-up-your-project-for-healthy-contributions)." ### Next steps To continue learning about {% data variables.product.prodname_discussions %} and quickly create a discussion for your community, see "[Quickstart for {% data variables.product.prodname_discussions %}](/discussions/quickstart)." ### Further reading - "[Setting up your project for healthy contributions](/articles/setting-up-your-project-for-healthy-contributions)" - "[Using templates to encourage useful issues and pull requests](/github/building-a-strong-community/using-templates-to-encourage-useful-issues-and-pull-requests)" - "[Moderating comments and conversations](/articles/moderating-comments-and-conversations)" - "[Writing on {% data variables.product.prodname_dotcom %}](/articles/writing-on-github)" 21 content/discussions/guides/finding-discussions-across-multiple-repositories.md @@ -0,0 +1,21 @@ --- title: Finding discussions across multiple repositories intro: 'You can easily access every discussion you''ve created or participated in across multiple repositories.' versions: free-pro-team: '*' --- {% data reusables.discussions.beta %} ### Finding discussions 1. Navigate to {% data variables.product.prodname_dotcom_the_website %}. 1. In the top-right corner of {% data variables.product.prodname_dotcom_the_website %}, click your profile photo, then click **Your enterprises**.  1. Toggle between **Created** and **Commented** to see the discussions you've created or participated in. ### Further reading - "[Searching discussions](/github/searching-for-information-on-github/searching-discussions)" - "[About discussions](/discussions/collaborating-with-your-community-using-discussions/about-discussions)" - "[Managing discussions for your community](/discussions/managing-discussions-for-your-community)" 32 content/discussions/guides/granting-higher-permissions-to-top-contributors.md @@ -0,0 +1,32 @@ --- title: Granting higher permissions to top contributors intro: 'Repository administrators can promote any community member to a moderator and maintainer.' versions: free-pro-team: '*' --- {% data reusables.discussions.beta %} ### Introduction The most helpful contributors for the past 30 days are highlighted on the {% data variables.product.prodname_discussions %} dashboard, based on how many comments were marked as answers by other community members. Helpful contributors can help drive a healthy community and moderate and guide the community space in addition to maintainers. ### Step 1: Audit your discussions top contributors {% data reusables.repositories.navigate-to-repo %} {% data reusables.discussions.discussions-tab %} 1. Compare the list of contributors with their access permissions to see who qualifies to moderate the discussion. ### Step 2: Review permission levels for discussions People with triage permissions for a repository can help moderate a project's discussions by marking comments as answers, locking discussions that are not longer useful or are damaging to the community, and converting issues to discussions when an idea is still in the early stages of development. For more information, see "[Moderating discussions](/discussions/managing-discussions-for-your-community/moderating-discussions)." For more information about repository permission levels and {% data variables.product.prodname_discussions %}, see "[Repository permissions levels for an organization](/github/setting-up-and-managing-organizations-and-teams/repository-permission-levels-for-an-organization)." ### Step 3: Change permissions levels for top contributors You can change a contributor's permission levels to give them more access to the tooling they need to moderate GitHub Discussions. To change a person's or team's permission levels, see "[Managing teams and people with access to your repository](/github/administering-a-repository/managing-teams-and-people-with-access-to-your-repository)." ### Step 4: Notify community members of elevated access When you change a collaborators permission level, they will receive a notification for the change. 29 content/discussions/guides/index.md @@ -0,0 +1,29 @@ --- title: Discussions guides shortTitle: Guides intro: 'Discover pathways to get started or learn best practices for participating or monitoring your community''s discussions.' versions: free-pro-team: '*' --- {% data reusables.discussions.beta %} ### Getting started with discussions {% link_in_list /about-discussions %} {% link_in_list /best-practices-for-community-conversations-on-github %} {% link_in_list /finding-discussions-across-multiple-repositories %} <!-- {% link_in_list /managing-notifications-for-discussions %} --> ### Administering discussions {% link_in_list /granting-higher-permissions-to-top-contributors %} <!--<!-- Commenting out what is only nice to have for discussions release {% link_in_list /updating-your-contributing-guidelines-with-discussions %} --> <!-- ### Discussions and open source projects {% link_in_list /collaborating-on-open-source-projects-in-discussions %} {% link_in_list /welcoming-contributions-to-your-communitys-discussions %} --> 55 content/discussions/index.md @@ -0,0 +1,55 @@ --- title: GitHub Discussions Documentation beta_product: true shortTitle: GitHub Discussions intro: '{% data variables.product.prodname_discussions %} is a collaborative communication forum for the community around an open source project. Community members can ask and answer questions, share updates, have open-ended conversations, and follow along on decisions affecting the community''s way of working.' introLinks: quickstart: /discussions/quickstart featuredLinks: guides: - /discussions/collaborating-with-your-community-using-discussions/about-discussions - /discussions/collaborating-with-your-community-using-discussions/participating-in-a-discussion - /discussions/managing-discussions-for-your-community/moderating-discussions gettingStarted: - /discussions/quickstart guideCards: - /discussions/collaborating-with-your-community-using-discussions/about-discussions - /discussions/collaborating-with-your-community-using-discussions/participating-in-a-discussion - /discussions/managing-discussions-for-your-community/moderating-discussions popular: - /discussions/guides/granting-higher-permissions-to-top-contributors - /discussions/guides/best-practices-for-community-conversations-on-github - /discussions/guides/finding-discussions-across-multiple-repositories - /discussions/collaborating-with-your-community-using-discussions/collaborating-with-maintainers-using-discussions - /discussions/managing-discussions-for-your-community/managing-categories-for-discussions-in-your-repository product_video: https://www.youtube-nocookie.com/embed/DbTWBP3_RbM layout: product-landing versions: free-pro-team: '*' --- <!-- {% link_with_intro /quickstart %} --> <!-- {% link_with_intro /discussions-guides %} --> <!-- {% link_with_intro /collaborating-with-your-community-using-discussions %} --> <!-- {% link_with_intro /managing-discussions-for-your-community %} --> <!-- Community examples --> {% assign discussionsCommunityExamples = site.data.variables.discussions_community_examples %} {% if discussionsCommunityExamples %} <div class="my-6 pt-6"> <h2 class="mb-2 font-mktg h1">Communities using discussions</h2> <div class="d-flex flex-wrap gutter"> {% render 'discussions-community-card' for discussionsCommunityExamples as example %} </div> {% if discussionsCommunityExamples.length > 6 %} <button class="js-filter-card-show-more btn btn-outline float-right">Show more {% octicon "arrow-right" %}</button> {% endif %} <div class="js-filter-card-no-results d-none py-4 text-center text-gray font-mktg"> <div class="mb-3">{% octicon "search" width="24" %}</div> <h3 class="text-normal">Sorry, there is no result for <strong class="js-filter-card-value"></strong></h3> <p class="my-3 f4">It looks like we don't have an example that fits your filter.<br>Try another filter or add your code example</p> <a href="https://github.com/github/docs/blob/main/data/variables/discussions_community_examples.yml">Add your community {% octicon "arrow-right" %}</a> </div> </div> {% endif %} 13 content/discussions/managing-discussions-for-your-community/index.md @@ -0,0 +1,13 @@ --- title: Managing discussions for your community shortTitle: Managing discussions intro: 'You can enable and configure discussions for your repository, and you can use tools on {% data variables.product.product_name %} to moderate conversations among community members.' versions: free-pro-team: '*' --- {% data reusables.discussions.beta %} {% link_in_list /managing-discussions-in-your-repository %} {% link_in_list /managing-categories-for-discussions-in-your-repository %} {% link_in_list /moderating-discussions %} 64 ...ns-for-your-community/managing-categories-for-discussions-in-your-repository.md @@ -0,0 +1,64 @@ --- title: Managing categories for discussions in your repository intro: You can categorize the discussions in your repository to organize conversations for your community members, and you can choose a format for each category. permissions: Repository administrators and people with write or greater access to a repository can enable discussions in the repository. versions: free-pro-team: '*' --- {% data reusables.discussions.beta %} ### About categories for discussions {% data reusables.discussions.about-discussions %} {% data reusables.discussions.about-categories-and-formats %} Each category must have a unique name and emoji pairing, and can be accompanied by a detailed description stating its purpose. Categories help maintainers organize how conversations are filed and are customizable to help distinguish categories that are Q&A or more open-ended conversations.{% data reusables.discussions.repository-category-limit %} For more information, see "[About discussions](/discussions/collaborating-with-your-community-using-discussions/about-discussions#about-categories-and-formats-for-discussions)." ### Default categories | Category | Purpose | Type | | :- | :- | :- | | #️⃣ General | Anything and everything relevant to the project | Open-ended discussion | |💡Ideas | Ideas to change or improve the project | Open-ended discussion | | 🙏 Q&A | Questions for the community to answer, with a question/answer format | Question and Answer | | 🙌 Show and tell | Creations, experiments, or tests relevant to the project | Open-ended discussion | ### Creating a category {% data reusables.repositories.navigate-to-repo %} {% data reusables.discussions.discussions-tab %} {% data reusables.discussions.edit-categories %} 1. Click **New category**.  1. Edit the emoji, title, description, and discussion format for the category. For more information about discussion formats, see "[About discussions](/discussions/collaborating-with-your-community-using-discussions/about-discussions#about-categories-and-formats-for-discussions)."  1. Click **Create**.  ### Editing a category You can edit a category to change the category's emoji, title, description, and discussion format. {% data reusables.repositories.navigate-to-repo %} {% data reusables.discussions.discussions-tab %} 1. To the right of a category in the list, click {% octicon "pencil" aria-label="The pencil icon" %}.  1. {% data reusables.discussions.edit-category-details %}  1. Click **Save changes**.  ### Deleting a category When you delete a category, {% data variables.product.product_name %} will move all discussions in the deleted category to an existing category that you choose. {% data reusables.repositories.navigate-to-repo %} {% data reusables.discussions.discussions-tab %} 1. To the right of a category in the list, click {% octicon "trash" aria-label="The trash icon" %}.  1. Use the drop-down menu, and choose a new category for any discussions in the category you're deleting.  1. Click **Delete & Move**.  108 ...aging-discussions-for-your-community/managing-discussions-in-your-repository.md @@ -0,0 +1,108 @@ --- title: Managing discussions in your repository intro: You can categorize, spotlight, transfer, or delete the discussions in a repository. permissions: Repository administrators and people with write or greater access to a repository can manage discussions in the repository. versions: free-pro-team: '*' --- {% data reusables.discussions.beta %} ### About management of discussions {% data reusables.discussions.about-discussions %} For more information about discussions, see "[About discussions](/discussions/collaborating-with-your-community-using-discussions/about-discussions)." Organization owners can choose the permissions required to create a discussion for repositories owned by the organization. For more information, see "[Managing discussion creation for repositories in your organization](/github/setting-up-and-managing-organizations-and-teams/managing-discussion-creation-for-repositories-in-your-organization)." As a discussions maintainer, you can create community resources to encourage discussions that are aligned with the overall project goal and maintain a friendly open forum for collaborators. Creating a code of conduct or contribution guidelines for collaborators to follow will help facilitate a collaborative and productive forum. For more information on creating community resources, see "[Adding a code of conduct to your project](/github/building-a-strong-community/adding-a-code-of-conduct-to-your-project)," and "[Setting guidelines for repository contributors](/github/building-a-strong-community/setting-guidelines-for-repository-contributors)." For more information on facilitating a healthy discussion, see "[Moderating comments and conversations](/github/building-a-strong-community/moderating-comments-and-conversations)." ### Prerequisites To manage discussions in a repository, discussions must be enabled for the repository. For more information, see "[Enabling or disabling discussions for a repository](/github/administering-a-repository/enabling-or-disabling-github-discussions-for-a-repository)." ### Changing the category for a discussion You can categorize discussions to help community members find related discussions. For more information, see "[Managing categories for discussions in your repository](/discussions/managing-discussions-for-your-community/managing-categories-for-discussions-in-your-repository)" article. You can also move a discussion to a different category. {% data reusables.repositories.navigate-to-repo %} {% data reusables.discussions.discussions-tab %} {% data reusables.discussions.click-discussion-in-list %} 1. In the right sidebar, click {% octicon "pencil" aria-label="The pencil icon" %} **Edit pinned discussion**.  ### Pinning a discussion You can pin up to four important discussions above the list of discussions for the repository. {% data reusables.repositories.navigate-to-repo %} {% data reusables.discussions.discussions-tab %} {% data reusables.discussions.click-discussion-in-list %} 1. In the right sidebar, click {% octicon "pin" aria-label="The pin icon" %} **Pin discussion**.  1. Optionally, customize the look of the pinned discussion.  1. Click **Pin discussion**.  ### Editing a pinned discussion Editing a pinned discussion will not change the discussion's category. For more information, see "[Managing categories for discussions in your repository](/discussions/managing-discussions-for-your-community/managing-categories-for-discussions-in-your-repository)." {% data reusables.repositories.navigate-to-repo %} {% data reusables.discussions.discussions-tab %} {% data reusables.discussions.click-discussion-in-list %} 1. In the right sidebar, click {% octicon "pencil" aria-label="The pencil icon" %} **Edit pinned discussion**.  1. Customize the look of the pinned discussion.  1. Click **Pin discussion**.  ### Unpinning a discussion {% data reusables.repositories.navigate-to-repo %} {% data reusables.discussions.discussions-tab %} {% data reusables.discussions.click-discussion-in-list %} 1. In the right sidebar, click {% octicon "pin" aria-label="The pin icon" %} **Unpin discussion**.  1. Read the warning, then click **Unpin discussion**.  ### Transferring a discussion To transfer a discussion, you must have permissions to create discussions in the repository where you want to transfer the discussion. {% data reusables.repositories.navigate-to-repo %} {% data reusables.discussions.discussions-tab %} {% data reusables.discussions.click-discussion-in-list %} 1. In the right sidebar, click {% octicon "arrow-right" aria-label="The right arrow icon" %} **Transfer discussion**.  1. Select the **Choose a repository** drop-down, and click the repository you want to transfer the discussion to.  1. Click **Transfer discussion**.  ### Deleting a discussion {% data reusables.repositories.navigate-to-repo %} {% data reusables.discussions.discussions-tab %} {% data reusables.discussions.click-discussion-in-list %} 1. In the right sidebar, click {% octicon "trash" aria-label="The trash arrow icon" %} **Delete discussion**.  1. Read the warning, then click **Delete this discussion**.  ### Converting issues based on labels You can convert all issues with the same label to discussions in bulk. Future issues with this label will also automatically convert to the discussion and category you configure. {% data reusables.repositories.navigate-to-repo %} {% data reusables.repositories.sidebar-issues %} {% data reusables.project-management.labels %} 1. Next to the label you want to convert to issues, click **Convert issues**. 1. Select the **Choose a category** drop-down menu, and click a category for your discussion. 1. Click **I understand, convert this issue to a discussion**. 40 ...t/discussions/managing-discussions-for-your-community/moderating-discussions.md @@ -0,0 +1,40 @@ --- title: Moderating discussions intro: 'You can promote healthy collaboration by marking comments as answers, locking or unlocking discussions, and converting issues to discussions. and editing or deleting comments, discussions, and categories that don''t align with your community''s code of conduct to discussions.' permissions: People with triage access to a repository can moderate discussions in the repository. versions: free-pro-team: '*' --- {% data reusables.discussions.beta %} ### About moderating discussions {% data reusables.discussions.about-discussions %} If you have triage permissions for a repository, you can help moderate a project's discussions by marking comments as answers, locking discussions that are not longer useful or are damaging to the community, and converting issues to discussions when an idea is still in the early stages of development. ### Marking a comment as an answer {% data reusables.discussions.marking-a-comment-as-an-answer %} ### Locking discussions It's appropriate to lock a conversation when the entire conversation is not constructive or violates your community's code of conduct or {% data variables.product.prodname_dotcom %}'s [Community Guidelines](/github/site-policy/github-community-guidelines). You can also lock a conversation to prevent comments on a discussion you want to use as an announcement to the community. When you lock a conversation, people with write access to the repository will still be able to comment on the discussion. {% data reusables.repositories.navigate-to-repo %} {% data reusables.discussions.discussions-tab %} 1. In the list of discussions, click the discussion you want to lock.  1. In the right margin of a discussion, click **Lock conversation**. 1. Read the information about locking conversations and click **Lock conversation on this discussion**. 1. When you're ready to unlock the conversation, click **Unlock conversation**, then click **Unlock conversation on this discussion**. ### Converting an issue to a discussion When you convert an issue to a discussion, the discussion is automatically created using the content from the issue. People with write access to a repository can bulk convert issues based on labels. For more information, see "[Managing discussions in your repository](/discussions/managing-discussions-for-your-community/managing-discussions-in-your-repository)." {% data reusables.repositories.navigate-to-repo %} {% data reusables.repositories.sidebar-issues %} 1. In the list of issues, click the issue you'd like to convert. 1. In the right margin of an issue, click **Convert to discussion**. 1. Select the **Choose a category** drop-down menu, and click a category for your discussion. 1. Click **I understand, convert this issue to a discussion**. 62 content/discussions/quickstart.md @@ -0,0 +1,62 @@ --- title: Quickstart for GitHub Discussions intro: 'Enable {% data variables.product.prodname_discussions %} on an existing repository and start conversations with your community.' allowTitleToDifferFromFilename: true versions: free-pro-team: '*' --- {% data reusables.discussions.beta %} ### Introduction {% data variables.product.prodname_discussions %} is a collaborative communication forum for the community around an open source project. Discussions are for conversations that need to be transparent and accessible but do not need to be tracked on a project board and are not related to code, unlike issues. Discussions enable fluid, open conversation in a public forum. Discussions give a space for more collaborative conversations by connecting and giving a more centralized area to connect and find information. ### Enabling {% data variables.product.prodname_discussions %} on your repository Repository owners and people with write access can enable {% data variables.product.prodname_discussions %} for a community on their public repositories. When you first enable a {% data variables.product.prodname_discussions %}, you will be invited to configure a welcome post. {% data reusables.repositories.navigate-to-repo %} 1. Under your repository name, click {% octicon "gear" aria-label="The gear icon" %} **Settings**.  1. Under "Features", click **Set up discussions**.  1. Under "Start a new discussion," edit the template to align with the resources and tone you want to set for your community. 1. Click **Start discussion**.  ### Welcoming contributions to your discussions You can welcome your community and introduce a new way to communicate in a repository by creating a welcome post and pin the post to your {% data variables.product.prodname_discussions %} page. Pinning and locking discussions helps people know that a post is meant as an announcement. You can use announcements as a way to link people to more resources and offer guidance for opening discussions in your community. For more information about pinning a discussion, see "[Managing discussions in your repository](/discussions/managing-discussions-for-your-community/managing-discussions-in-your-repository#pinning-a-discussion)." ### Setting up community guidelines for contributors You can set contributing guidelines to encourage collaborators to have meaningful, useful conversations that are relevant to the repository. You can also update the repository's README to communicate expectations on when collaborators should open an issue or discussion. For more information about providing guidelines for your project, see "[Adding a code of conduct to your project](/github/building-a-strong-community/adding-a-code-of-conduct-to-your-project)" and "[Setting up your project for healthy contributions](/github/building-a-strong-community/setting-up-your-project-for-healthy-contributions)." ### Creating a new discussion Anyone with access to a repository can create a discussion. {% data reusables.discussions.starting-a-discussion %} ### Organizing discussions into relevant categories Repository owners and people with write access can create new categories to keep discussions organized. Collaborators participating and creating new discussions can group discussions into the most relevant existing categories. Discussions can also be recategorized after they are created. For more information, see "[Managing categories for discussions in your repository](/discussions/managing-discussions-for-your-community/managing-categories-for-discussions-in-your-repository)" ### Promoting healthy conversations People with write permissions for a repository can help surface important conversations by pinning discussions, deleting discussions that are no longer useful or are damaging to the community, and transferring discussions to more relevant repositories owned by the organization. For more information, see "[Managing discussions in your repository](/discussions/managing-discussions-for-your-community/managing-discussions-in-your-repository)." People with triage permissions for a repository can help moderate a project's discussions by marking comments as answers, locking discussions that are not longer useful or are damaging to the community, and converting issues to discussions when an idea is still in the early stages of development. For more information, see "[Moderating discussions](/discussions/managing-discussions-for-your-community/moderating-discussions)." ### Next steps Once there is a clear path to scope work out and move an idea from concept to reality, you can create an issue and start tracking your progress. For more information on creating an issue from a discussion, see "[Moderating discussions](/discussions/managing-discussions-for-your-community/moderating-discussions)." 45 content/education/guides.md @@ -0,0 +1,45 @@ --- title: Guides for GitHub Education intro: 'These guides for {% data variables.product.prodname_education %} help you teach and learn both {% data variables.product.product_name %} and software development.' allowTitleToDifferFromFilename: true versions: free-pro-team: '*' --- ### Get started with {% data variables.product.product_name %} Teachers, students, and researchers can use tools from {% data variables.product.product_name %} to enrich a software development curriculum and develop real-world collaboration skills. - [Sign up for a new {% data variables.product.prodname_dotcom %} account](/github/getting-started-with-github/signing-up-for-a-new-github-account) - [Git and {% data variables.product.prodname_dotcom %} quickstart ](/github/getting-started-with-github/quickstart) - [Apply for an educator or researcher discount](/education/teach-and-learn-with-github-education/apply-for-an-educator-or-researcher-discount) - [Apply for a student developer pack](/education/teach-and-learn-with-github-education/apply-for-a-student-developer-pack) ### Run a software development course with {% data variables.product.company_short %} Administer a classroom, assign and review work from your students, and teach the new generation of software developers with {% data variables.product.prodname_classroom %}. - [Basics of setting up {% data variables.product.prodname_classroom %} ](/education/manage-coursework-with-github-classroom/basics-of-setting-up-github-classroom) - [Manage classrooms](/education/manage-coursework-with-github-classroom/manage-classrooms) - [Create an individual assignment](/education/manage-coursework-with-github-classroom/create-an-individual-assignment) - [Create a group assignment](/education/manage-coursework-with-github-classroom/create-a-group-assignment) - [Create an assignment from a template repository](/education/manage-coursework-with-github-classroom/create-an-assignment-from-a-template-repository) - [Leave feedback with pull requests](/education/manage-coursework-with-github-classroom/leave-feedback-with-pull-requests) - [Use autograding](/education/manage-coursework-with-github-classroom/use-autograding) ### Learn to develop software Incorporate {% data variables.product.prodname_dotcom %} into your education, and use the same tools as the professionals. - [Git and {% data variables.product.prodname_dotcom %} learning resources](/github/getting-started-with-github/git-and-github-learning-resources) - [Use {% data variables.product.prodname_dotcom %} for your schoolwork](/education/teach-and-learn-with-github-education/use-github-for-your-schoolwork) - [Try {% data variables.product.prodname_desktop %}](/desktop) - [Try {% data variables.product.prodname_cli %}](/github/getting-started-with-github/github-cli) ### Contribute to the community Participate in the community, get training from {% data variables.product.company_short %}, and learn or teach new skills. - [{% data variables.product.prodname_education_community %}](https://education.github.community) - [About Campus Experts](/education/teach-and-learn-with-github-education/about-campus-experts) - [About Campus Advisors](/education/teach-and-learn-with-github-education/about-campus-advisors) 43 content/education/index.md @@ -0,0 +1,43 @@ --- title: GitHub Education Documentation shortTitle: Education intro: "{% data variables.product.prodname_education %} helps you teach or learn software development with the tools and support of {% data variables.product.company_short %}'s platform and community." introLinks: quickstart: /education/quickstart featuredLinks: guides: - /education/teach-and-learn-with-github-education/apply-for-a-student-developer-pack - /education/teach-and-learn-with-github-education/apply-for-an-educator-or-researcher-discount - /education/teach-and-learn-with-github-education/use-github-at-your-educational-institution guideCards: - /github/getting-started-with-github/signing-up-for-a-new-github-account - /github/getting-started-with-github/git-and-github-learning-resources - /education/manage-coursework-with-github-classroom/basics-of-setting-up-github-classroom popular: - /education/teach-and-learn-with-github-education/use-github-for-your-schoolwork - /education/teach-and-learn-with-github-education/use-github-in-your-classroom-and-research - /desktop - /github/getting-started-with-github/github-cli - /education/manage-coursework-with-github-classroom/teach-with-github-classroom changelog: - title: 'Try something new at Local Hack Day: Learn' date: '2020-10-15' href: https://github.blog/2020-10-15-try-something-new-at-local-hack-day-learn/ - title: 'Remote Education: Creating community through shared experiences' date: '2020-09-24' href: https://github.blog/2020-09-24-remote-education-creating-community-through-shared-experiences/ - title: 'Remote Education: A series of best practices for online campus communities' date: '2020-09-10' href: https://github.blog/2020-09-10-remote-education-a-series-of-best-practices-for-online-campus-communities/ - title: Welcome to the inaugural class of MLH Fellows date: '2020-06-24' href: https://github.blog/2020-06-24-welcome-to-the-inaugural-class-of-mlh-fellows/ layout: product-landing versions: free-pro-team: '*' --- <!-- {% link_with_intro /teach-and-learn-with-github-education %} --> <!-- {% link_with_intro /manage-coursework-with-github-classroom %} --> 31 ...work-with-github-classroom/about-using-makecode-arcade-with-github-classroom.md @@ -0,0 +1,31 @@ --- title: About using MakeCode Arcade with GitHub Classroom shortTitle: About using MakeCode Arcade intro: You can configure MakeCode Arcade as the online IDE for assignments in {% data variables.product.prodname_classroom %}. versions: free-pro-team: '*' redirect_from: - /education/manage-coursework-with-github-classroom/student-experience-makecode --- ### About MakeCode Arcade MakeCode Arcade is an online integrated development environment (IDE) for developing retro arcade games using drag-and-drop block programming and JavaScript. Students can write, edit, run, test, and debug code in a browser with MakeCode Arcade. For more information about online IDEs and {% data variables.product.prodname_classroom %}, see "[Integrate {% data variables.product.prodname_classroom %} with an online IDE](/education/manage-coursework-with-github-classroom/integrate-github-classroom-with-an-online-ide)." {% data reusables.classroom.readme-contains-button-for-online-ide %} The first time the student clicks the button to visit MakeCode Arcade, the student must sign into MakeCode Arcade with {% data variables.product.product_name %} credentials. After signing in, the student will have access to a development environment containing the code from the assignment repository, fully configured on MakeCode Arcade. For more information about working on MakeCode Arcade, see the [MakeCode Arcade Tour](https://arcade.makecode.com/ide-tour) and [documentation](https://arcade.makecode.com/docs) on the MakeCode Arcade website. MakeCode Arcade does not support multiplayer-editing for group assignments. Instead, students can collaborate with Git and {% data variables.product.product_name %} features like branches and pull requests. ### About submission of assignments with MakeCode Arcade By default, MakeCode Arcade is configured to push to the assignment repository on {% data variables.product.product_location %}. After making progress on an assignment with MakeCode Arcade, students should push changes to {% data variables.product.product_location %} using the {% octicon "mark-github" aria-label="The GitHub mark" %}{% octicon "arrow-up" aria-label="The up arrow icon" %} button at the bottom of the screen.  ### Further reading - "[About READMEs](/github/creating-cloning-and-archiving-repositories/about-readmes)" 33 ...ge-coursework-with-github-classroom/about-using-replit-with-github-classroom.md @@ -0,0 +1,33 @@ --- title: About using Repl.it with GitHub Classroom shortTitle: About using Repl.it intro: You can configure Repl.it as the online integrated development environment (IDE) for assignments in {% data variables.product.prodname_classroom %}. versions: free-pro-team: '*' redirect_from: - /education/manage-coursework-with-github-classroom/student-experience-replit --- ### About Repl.it Repl.it is an online integrated development environment (IDE) that supports multiple programming languages. Students can write, edit, run, test, and debug code in a browser with Repl.it. For more information about online IDEs and {% data variables.product.prodname_classroom %}, see "[Integrate {% data variables.product.prodname_classroom %} with an online IDE](/education/manage-coursework-with-github-classroom/integrate-github-classroom-with-an-online-ide)." {% data reusables.classroom.readme-contains-button-for-online-ide %} The first time the student clicks the button to visit Repl.it, the student must sign into Repl.it with {% data variables.product.product_name %} credentials. After signing in, the student will have access to a development environment containing the code from the assignment repository, fully configured on Repl.it. For more information about working on Repl.it, see the [Repl.it Quickstart Guide](https://docs.repl.it/misc/quick-start#the-repl-environment). For group assignments, students can use Repl.it Multiplayer to work collaboratively. For more information, see the [Repl.it Multiplayer](https://repl.it/site/multiplayer) website. ### About submission of assignments with Repl.it By default, Repl.it is configured to push to the assignment repository on {% data variables.product.product_location %}. After making progress on an assignment with Repl.it, students should push changes to {% data variables.product.product_location %} using the version control functionality in the left sidebar.  For more information about using Git on Repl.it, see the [Repl.it + Git Tutorial](https://repl.it/talk/learn/Replit-Git-Tutorial/23331) on the Repl.it website. ### Further reading - "[About READMEs](/github/creating-cloning-and-archiving-repositories/about-readmes)" 33 ...anage-coursework-with-github-classroom/basics-of-setting-up-github-classroom.md @@ -0,0 +1,33 @@ --- title: Basics of setting up GitHub Classroom shortTitle: '{% data variables.product.prodname_classroom %} basics' intro: Learn how to set up your classroom, manage assignments, and configure time-saving automation. versions: free-pro-team: '*' --- ### Videos about {% data variables.product.prodname_classroom %} You can watch a series of short video tutorials about the configuration and use of {% data variables.product.prodname_classroom %}. To watch all videos as part of a continuous playlist, see the [{% data variables.product.prodname_classroom %} Getting Started Guide](https://www.youtube.com/playlist?list=PLIRjfNq867bewk3ZGV6Z7a16YDNRCpK3u) on YouTube. For more information about terminology for {% data variables.product.prodname_classroom %}, see "[Glossary](/education/manage-coursework-with-github-classroom/glossary)". 1. <a href="https://youtu.be/xVVeqIDgCvM" target="_blank">Getting started</a> {% octicon "link-external" aria-label="The external link icon" %} 2. <a href="https://youtu.be/DTzrKduaHj8" target="_blank">Adding your student roster</a> {% octicon "link-external" aria-label="The external link icon" %} 3. Creating assignments - <a href="https://youtu.be/6QzKZ63KLss" target="_blank">Creating an assignment using a {% data variables.product.prodname_dotcom %} repository</a> {% octicon "link-external" aria-label="The external link icon" %} - <a href="https://youtu.be/Qmwh6ijsQJU" target="_blank">Creating an assignment using Microsoft MakeCode as your online IDE</a> {% octicon "link-external" aria-label="The external link icon" %} - <a href="https://youtu.be/p_g5sQ7hUis" target="_blank">Creating an assignment using Repl.it as your online IDE</a> {% octicon "link-external" aria-label="The external link icon" %} 4. <a href="https://youtu.be/ObaFRGp_Eko" target="_blank">How students complete assignments</a> {% octicon "link-external" aria-label="The external link icon" %} 5. <a href="https://youtu.be/g45OJn3UyCU" target="_blank">How teachers review assignments</a> {% octicon "link-external" aria-label="The external link icon" %} 6. <a href="https://youtu.be/QxrA3taZdNM" target="_blank">Creating group assignments</a> {% octicon "link-external" aria-label="The external link icon" %} 7. <a href="https://youtu.be/tJK2cmoh1KM" target="_blank">Next steps to get started</a> {% octicon "link-external" aria-label="The external link icon" %} 8. <a href="https://youtu.be/X87v3SFQxLU" target="_blank">{% data variables.product.prodname_dotcom %} Teacher Toolbox</a> {% octicon "link-external" aria-label="The external link icon" %} ### Next steps For more information about teaching with {% data variables.product.prodname_classroom %}, see "[Teach with {% data variables.product.prodname_classroom %}](/education/manage-coursework-with-github-classroom/teach-with-github-classroom)." ### Further reading - "[Teach and learn with {% data variables.product.prodname_education %}](/education/teach-and-learn-with-github-education)" 51 ...with-github-classroom/configure-default-settings-for-assignment-repositories.md @@ -0,0 +1,51 @@ --- title: Configure default settings for assignment repositories shortTitle: Configure defaults for assignment repositories intro: You can use the Probot Settings app to configure the default settings for repositories that {% data variables.product.prodname_classroom %} creates for an assignment. permissions: Organization owners can configure default settings for assignment repositories by installing a {% data variables.product.prodname_github_app %} for the organization. versions: free-pro-team: '*' redirect_from: - /education/manage-coursework-with-github-classroom/probot-settings --- ### About configuration of defaults for assignment repositories {% data variables.product.prodname_classroom %} creates a repository that belongs for each student or team that accepts an assignment. The repository belongs to the organization that you use for {% data variables.product.prodname_classroom %}. Assignment repositories can be empty, or you can use a template repository. For more information, see "[Create an assignment from a template repository](/education/manage-coursework-with-github-classroom/create-an-assignment-from-a-template-repository)." {% data reusables.classroom.you-may-want-to-predefine-repository-settings %} With the Probot Settings app, you can create a file named _.github/settings.yml_ in a repository that contains a list of settings for the repository, and then install a {% data variables.product.prodname_github_app %} for your organization that automatically applies the settings to the repository. You can include _.github/settings.yml_ in a template repository that you use for an assignment in {% data variables.product.prodname_classroom %}. When an individual or team accepts the assignment, {% data variables.product.prodname_classroom %} creates the assignment repository, and the Settings app automatically applies the settings from _.github/settings.yml_. Probot is a a project, framework, and collection of free apps to automate {% data variables.product.product_name %}. A Probot app can listen to repository events, like the creation of new commits, comments, and issues, and automatically respond to the event. For more information, see the [Probot website](https://probot.github.io) and the [Settings app website](https://probot.github.io/apps/settings/). For more information about {% data variables.product.prodname_github_apps %}, see "[About apps](/developers/apps/about-apps)." ### Adding the Settings app to your organization After you install the Probot Settings app for your organization, the app will apply the settings that you define in _.github/settings.yml_ for any repository in your organization, including new assignment repositories that {% data variables.product.prodname_classroom %} creates. 1. Navigate to the [Settings app page](https://github.com/apps/settings). 1. Click **Install**, then click the organization that you use for {% data variables.product.prodname_classroom %}. Provide the app full access to all repositories owned by the organization.  ### Configuring default settings for an assignment repository 1. Create a template repository that contains a _.github/settings.yml_ file. For a complete list of settings, see the [README](https://github.com/probot/settings#github-settings) for the `probot/settings` repository. For more information about using a template repository for starter code in {% data variables.product.prodname_classroom %}, see "[Create an assignment from a template repository](/education/manage-coursework-with-github-classroom/create-an-assignment-from-a-template-repository)." {% warning %} **Warning:** Do not define `collaborators` in the _.github/settings.yml_ file for your template repository. {% data variables.product.prodname_classroom %} automatically grants teachers and teaching assistants access to assignment repositories. {% endwarning %} 1. Create an assignment using the template repository containing _.github/settings.yml_ as the starter code. {% data reusables.classroom.for-more-information-about-assignment-creation %} The Probot Settings app for your organization will now apply the settings you define in _.github/settings.yml_ within the template repository to every assignment repository that {% data reusables.classroom.you-may-want-to-predefine-repository-settings %} creates for a student or team. ### Further reading - [Probot apps](https://probot.github.io/apps/) - [Probot documentation](https://probot.github.io/docs/) 142 ...th-github-classroom/connect-a-learning-management-system-to-github-classroom.md @@ -0,0 +1,142 @@ --- title: Connect a learning management system to GitHub Classroom intro: You can configure an LTI-compliant learning management system (LMS) to connect to {% data variables.product.prodname_classroom %} so that you can import a roster for your classroom. versions: free-pro-team: '*' redirect_from: - /education/manage-coursework-with-github-classroom/configuring-a-learning-management-system-for-github-classroom - /education/manage-coursework-with-github-classroom/connect-to-lms - /education/manage-coursework-with-github-classroom/generate-lms-credentials - /education/manage-coursework-with-github-classroom/setup-canvas - /education/manage-coursework-with-github-classroom/setup-generic-lms - /education/manage-coursework-with-github-classroom/setup-moodle --- ### About configuration of your LMS You can connect a learning management system (LMS) to {% data variables.product.prodname_classroom %}, and {% data variables.product.prodname_classroom %} can import a roster of student identifiers from the LMS. To connect your LMS to {% data variables.product.prodname_classroom %}, you must enter configuration credentials for {% data variables.product.prodname_classroom %} in your LMS. ### Prerequisites To configure an LMS to connect to {% data variables.product.prodname_classroom %}, you must first create a classroom. For more information, see "[Manage classrooms](/education/manage-coursework-with-github-classroom/manage-classrooms#creating-a-classroom)." ### Supported LMSes {% data variables.product.prodname_classroom %} supports import of roster data from LMSes that implement Learning Tools Interoperability (LTI) standards. - LTI version 1.0 and/or 1.1 - LTI Names and Roles Provisioning 1.X Using LTI helps keep your information safe and secure. LTI is an industry-standard protocol and GitHub Classroom's use of LTI is certified by the Instructional Management System (IMS) Global Learning Consortium. For more information, see [Learning Tools Interoperability](https://www.imsglobal.org/activity/learning-tools-interoperability) and [About IMS Global Learning Consortium](http://www.imsglobal.org/aboutims.html) on the IMS Global Learning Consortium website. {% data variables.product.company_short %} has tested import of roster data from the following LMSes into {% data variables.product.prodname_classroom %}. - Canvas - Google Classroom - Moodle - Sakai Currently, {% data variables.product.prodname_classroom %} doesn't support import of roster data from Blackboard or Brightspace ### Generating configuration credentials for your classroom {% data reusables.classroom.sign-into-github-classroom %} {% data reusables.classroom.click-classroom-in-list %} {% data reusables.classroom.click-students %} 1. If your classroom already has a roster, you can either update the roster or delete the roster and create a new roster. - For more information about deleting and creating a roster, see "[Deleting a roster for a classroom](/education/manage-coursework-with-github-classroom/manage-classrooms#deleting-a-roster-for-a-classroom)" and "[Creating a roster for your classroom](/education/manage-coursework-with-github-classroom/manage-classrooms#creating-a-roster-for-your-classroom)." - For more information about updating a roster, see "[Adding students to the roster for your classroom](/education/manage-coursework-with-github-classroom/manage-classrooms#adding-students-to-the-roster-for-your-classroom)." 1. In the list of LMSes, click your LMS. If your LMS is not supported, click **Other LMS**.  1. Read about connecting your LMS, then click **Connect to _LMS_**. 1. Copy the "Consumer Key", "Shared Secret", and "Launch URL" for the connection to the classroom.  ### Configuring a generic LMS You must configure the privacy settings for your LMS to allow external tools to receive roster information. 1. Navigate to your LMS. 1. Configure an external tool. 1. Provide the configuration credentials you generated in {% data variables.product.prodname_classroom %}. - Consumer key - Shared secret - Launch URL (sometimes called "tool URL" or similar) ### Configuring Canvas You can configure {% data variables.product.prodname_classroom %} as an external app for Canvas to import roster data into your classroom. For more information about Canvas, see the [Canvas website](https://www.instructure.com/canvas/). 1. Sign into [Canvas](https://www.instructure.com/canvas/#login). 1. Select the Canvas course to integrate with {% data variables.product.prodname_classroom %}. 1. In the left sidebar, click **Settings**. 1. Click the **Apps** tab. 1. Click **View app configurations**. 1. Click **+App**. 1. Select the **Configuration Type** drop-down menu, and click **By URL**. 1. Paste the configuration credentials from {% data variables.product.prodname_classroom %}. For more information, see "[Generating configuration credentials for your classroom](#generating-configuration-credentials-for-your-classroom)." | Field in Canvas app configuration | Value or setting | | :- | :- | | **Consumer Key** | Consumer key from {% data variables.product.prodname_classroom %} | | **Shared Secret** | Shared secret from {% data variables.product.prodname_classroom %} | | **Allow this tool to access the IMS Names and Role Provisioning Service** | Enabled | | **Configuration URL** | Launch URL from {% data variables.product.prodname_classroom %} | {% note %} **Note**: If you don't see a checkbox in Canvas labeled "Allow this tool to access the IMS Names and Role Provisioning Service", then your Canvas administrator must contact Canvas support to enable membership service configuration for your Canvas account. Without enabling this feature, you won't be able to sync the roster from Canvas. For more information, see [How do I contact Canvas Support?](https://community.canvaslms.com/t5/Canvas-Basics-Guide/How-do-I-contact-Canvas-Support/ta-p/389767) on the Canvas website. {% endnote %} 1. Click **Submit**. 1. In the left sidebar, click **Home**. 1. To prompt Canvas to send a confirmation email, in the left sidebar, click **GitHub Classroom**. Follow the instructions in the email to finish linking {% data variables.product.prodname_classroom %}. ### Configuring Moodle You can configure {% data variables.product.prodname_classroom %} as an activity for Moodle to import roster data into your classroom. For more information about Moodle, see the [Moodle website](https://moodle.org). You must be using Moodle version 3.0 or greater. 1. Sign into [Moodle](https://moodle.org/login/index.php). 1. Select the Moodle course to integrate with {% data variables.product.prodname_classroom %}. 1. Click **Turn editing on**. 1. Wherever you'd like {% data variables.product.prodname_classroom %} to be available in Moodle, click **Add an activity or resource**. 1. Choose **External tool** and click **Add**. 1. In the "Activity name" field, type "GitHub Classroom". 1. In the **Preconfigured tool** field, to the right of the drop-down menu, click **+**. 1. Under "External tool configuration", paste the configuration credentials from {% data variables.product.prodname_classroom %}. For more information, see "[Generating configuration credentials for your classroom](#generating-configuration-credentials-for-your-classroom)." | Field in Moodle app configuration | Value or setting | | :- | :- | | **Tool name** | {% data variables.product.prodname_classroom %} - _YOUR CLASSROOM NAME_<br/><br/>**Note**: You can use any name, but we suggest this value for clarity. | | **Tool URL** | Launch URL from {% data variables.product.prodname_classroom %} | | **LTI version** | LTI 1.0/1.1 | | **Default launch container** | New window | | **Consumer key** | Consumer key from {% data variables.product.prodname_classroom %} | | **Shared secret** | Shared secret from {% data variables.product.prodname_classroom %} | 1. Scroll to and click **Services**. 1. To the right of "IMS LTI Names and Role Provisioning", select the drop-down menu and click **Use this service to retrieve members' information as per privacy settings**. 1. Scroll to and click **Privacy**. 1. To the right of **Share launcher's name with tool** and **Share launcher's email with tool**, select the drop-down menus to click **Always**. 1. At the bottom of the page, click **Save changes**. 1. In the **Preconfigure tool** menu, click **GitHub Classroom - _YOUR CLASSROOM NAME_**. 1. Under "Common module settings", to the right of "Availability", select the drop-down menu and click **Hide from students**. 1. At the bottom of the page, click **Save and return to course**. 1. Navigate to anywhere you chose to display {% data variables.product.prodname_classroom %}, and click the {% data variables.product.prodname_classroom %} activity. ### Importing a roster from your LMS For more information about importing the roster from your LMS into {% data variables.product.prodname_classroom %}, see "[Manage classrooms](/education/manage-coursework-with-github-classroom/manage-classrooms#creating-a-roster-for-your-classroom)." ### Disconnecting your LMS {% data reusables.classroom.sign-into-github-classroom %} {% data reusables.classroom.click-classroom-in-list %} {% data reusables.classroom.click-settings %} 1. Under "Connect to a learning management system (LMS)", click **Connection Settings**.  1. Under "Delete Connection to your learning management system", click **Disconnect from your learning management system**.  145 .../education/manage-coursework-with-github-classroom/create-a-group-assignment.md @@ -0,0 +1,145 @@ --- title: Create a group assignment intro: 'You can create a collaborative assignment for teams of students who participate in your course.' versions: free-pro-team: '*' redirect_from: - /education/manage-coursework-with-github-classroom/create-group-assignments --- ### About group assignments {% data reusables.classroom.assignments-group-definition %} Students can work together on a group assignment in a shared repository, like a team of professional developers. When a student accepts a group assignment, the student can create a new team or join an existing team. {% data variables.product.prodname_classroom %} saves the teams for an assignment as a set. You can name the set of teams for a specific assignment when you create the assignment, and you can reuse that set of teams for a later assignment. {% data reusables.classroom.classroom-creates-group-repositories %} {% data reusables.classroom.about-assignments %} You can decide how many teams one assignment can have, and how many members each team can have. Each team that a student creates for an assignment is a team within your organization on {% data variables.product.product_name %}. The visibility of the team is secret. Teams that you create on {% data variables.product.product_name %} will not appear in {% data variables.product.prodname_classroom %}. For more information, see "[About teams](/github/setting-up-and-managing-organizations-and-teams/about-teams)." For a video demonstration of the creation of a group assignment, see "[Basics of setting up {% data variables.product.prodname_classroom %}](/education/manage-coursework-with-github-classroom/basics-of-setting-up-github-classroom)." ### Prerequisites {% data reusables.classroom.assignments-classroom-prerequisite %} ### Creating an assignment {% data reusables.classroom.assignments-guide-create-the-assignment %} ### Setting up the basics for an assignment Name your assignment, decide whether to assign a deadline, define teams, and choose the visibility of assignment repositories. - [Naming an assignment](#naming-an-assignment) - [Assigning a deadline for an assignment](#assigning-a-deadline-for-an-assignment) - [Choosing an assignment type](#choosing-an-assignment-type) - [Defining teams for an assignment](#defining-teams-for-an-assignment) - [Choosing a visibility for assignment repositories](#choosing-a-visibility-for-assignment-repositories) #### Naming an assignment For a group assignment, {% data variables.product.prodname_classroom %} names repositories by the repository prefix and the name of the team. By default, the repository prefix is the assignment title. For example, if you name an assignment "assignment-1" and the team's name on {% data variables.product.product_name %} is "student-team", the name of the assignment repository for members of the team will be `assignment-1-student-team`. {% data reusables.classroom.assignments-type-a-title %} #### Assigning a deadline for an assignment {% data reusables.classroom.assignments-guide-assign-a-deadline %} #### Choosing an assignment type Under "Individual or group assignment", select the drop-down menu, then click **Group assignment**. You can't change the assignment type after you create the assignment. If you'd rather create a individual assignment, see "[Create an individual assignment](/education/manage-coursework-with-github-classroom/create-an-individual-assignment)." #### Defining teams for an assignment If you've already created a group assignment for the classroom, you can reuse a set of teams for the new assignment. To create a new set with the teams that your students create for the assignment, type the name for the set. Optionally, type the maximum number of team members and total teams. {% tip %} **Tips**: - We recommend including details about the set of teams in the name for the set. For example, if you want to use the set of teams for one assignment, name the set after the assignment. If you want to reuse the set throughout a semester or course, name the set after the semester or course. - If you'd like to assign students to a specific team, give your students a name for the team and provide a list of members. {% endtip %}  #### Choosing a visibility for assignment repositories {% data reusables.classroom.assignments-guide-choose-visibility %} {% data reusables.classroom.assignments-guide-click-continue-after-basics %} ### Adding starter code and configuring a development environment {% data reusables.classroom.assignments-guide-intro-for-environment %} - [Choosing a template repository](#choosing-a-template-repository) - [Choosing an online integrated development environment (IDE)](#choosing-an-online-integrated-development-environment-ide) #### Choosing a template repository By default, a new assignment will create an empty repository for each team that a student creates. {% data reusables.classroom.you-can-choose-a-template-repository %} For more information about template repositories, see "[Creating a template repository](/github/creating-cloning-and-archiving-repositories/creating-a-template-repository)." {% data reusables.classroom.assignments-guide-choose-template-repository %} #### Choosing an online integrated development environment (IDE) {% data reusables.classroom.about-online-ides %} For more information, see "[Integrate {% data variables.product.prodname_classroom %} with an IDE](/education/manage-coursework-with-github-classroom/integrate-github-classroom-with-an-ide)." {% data reusables.classroom.assignments-guide-choose-an-online-ide %} {% data reusables.classroom.assignments-guide-click-continue-after-starter-code-and-feedback %} ### Providing feedback Optionally, you can automatically grade assignments and create a space for discussing each submission with the team. - [Testing assignments automatically](#testing-assignments-automatically) - [Preventing changes to important files](#preventing-changes-to-important-files) - [Creating a pull request for feedback](#creating-a-pull-request-for-feedback) #### Testing assignments automatically {% data reusables.classroom.assignments-guide-using-autograding %} #### Preventing changes to important files {% data reusables.classroom.assignments-guide-prevent-changes %} #### Creating a pull request for feedback {% data reusables.classroom.you-can-create-a-pull-request-for-feedback %} {% data reusables.classroom.assignments-guide-create-review-pull-request %} {% data reusables.classroom.assignments-guide-click-create-assignment-button %} ### Inviting students to an assignment {% data reusables.classroom.assignments-guide-invite-students-to-assignment %} You can see the teams that are working on or have submitted an assignment in the **Teams** tab for the assignment. {% data reusables.classroom.assignments-to-prevent-submission %} <div class="procedural-image-wrapper"> <img alt="Group assignment" class="procedural-image-wrapper" src="/assets/images/help/classroom/assignment-group-hero.png"> </div> ### Next steps - After you create the assignment and your students form teams, team members can start work on the assignment using Git and {% data variables.product.product_name %}'s features. Students can clone the repository, push commits, manage branches, create and review pull requests, address merge conflicts, and discuss changes with issues. Both you and the team can review the commit history for the repository. For more information, see "[Getting started with {% data variables.product.prodname_dotcom %}](/github/getting-started-with-github)," "[Creating, cloning, and archiving repositories](/github/creating-cloning-and-archiving-repositories)," "[Using Git](/github/using-git)," and "[Collaborating with issues and pull requests](/github/collaborating-with-issues-and-pull-requests)," and the free course on [managing merge conflicts](https://lab.github.com/githubtraining/managing-merge-conflicts) from {% data variables.product.prodname_learning %}. - When a team finishes an assignment, you can review the files in the repository, or you can review the history and visualizations for the repository to better understand how the team collaborated. For more information, see "[Visualizing repository data with graphs](/github/visualizing-repository-data-with-graphs)." - You can provide feedback for an assignment by commenting on individual commits or lines in a pull request. For more information, see "[Commenting on a pull request](/github/collaborating-with-issues-and-pull-requests/commenting-on-a-pull-request)" and "[Opening an issue from code](/github/managing-your-work-on-github/opening-an-issue-from-code)." For more information about creating saved replies to provide feedback for common errors, see "[About saved replies](/github/writing-on-github/about-saved-replies)." ### Further reading - "[Use {% data variables.product.prodname_dotcom %} in your classroom and research](/education/teach-and-learn-with-github-education/use-github-in-your-classroom-and-research)" - "[Connect a learning management system to {% data variables.product.prodname_classroom %}](/education/manage-coursework-with-github-classroom/connect-a-learning-management-system-to-github-classroom)" - [Using Existing Teams in Group Assignments?](https://education.github.community/t/using-existing-teams-in-group-assignments/6999) in the {% data variables.product.prodname_education %} Community 19 ...sework-with-github-classroom/create-an-assignment-from-a-template-repository.md @@ -0,0 +1,19 @@ --- title: Create an assignment from a template repository intro: You can create an assignment from a template repository to provide starter code, documentation, and other resources to your students. versions: free-pro-team: '*' redirect_from: - /education/manage-coursework-with-github-classroom/using-template-repos-for-assignments --- You can use a template repository on {% data variables.product.product_name %} as starter code for an assignment on {% data variables.product.prodname_classroom %}. Your template repository can contain boilerplate code, documentation, and other resources for your students. For more information, see "[Creating a template repository](/github/creating-cloning-and-archiving-repositories/creating-a-template-repository)." To use the template repository for your assignment, the template repository must be owned by your organization, or the visibility of the template repository must be public. {% data reusables.classroom.you-may-want-to-predefine-repository-settings %} For more information, see "[Configure default settings for assignment repositories](/education/manage-coursework-with-github-classroom/configure-default-settings-for-assignment-repositories)." ### Further reading - "[Create an individual assignment](/education/manage-coursework-with-github-classroom/create-an-individual-assignment)" - "[Create a group assignment](/education/manage-coursework-with-github-classroom/create-a-group-assignment)" 124 ...tion/manage-coursework-with-github-classroom/create-an-individual-assignment.md @@ -0,0 +1,124 @@ --- title: Create an individual assignment intro: You can create an assignment for students in your course to complete individually. versions: free-pro-team: '*' redirect_from: - /education/manage-coursework-with-github-classroom/creating-an-individual-assignment - /education/manage-coursework-with-github-classroom/create-an-individual-assignment --- ### About individual assignments {% data reusables.classroom.assignments-individual-definition %} {% data reusables.classroom.classroom-creates-individual-repositories %} {% data reusables.classroom.about-assignments %} For a video demonstration of the creation of an individual assignment, see "[Basics of setting up {% data variables.product.prodname_classroom %}](/education/manage-coursework-with-github-classroom/basics-of-setting-up-github-classroom)." ### Prerequisites {% data reusables.classroom.assignments-classroom-prerequisite %} ### Creating an assignment {% data reusables.classroom.assignments-guide-create-the-assignment %} ### Setting up the basics for an assignment Name your assignment, decide whether to assign a deadline, and choose the visibility of assignment repositories. - [Naming an assignment](#naming-an-assignment) - [Assigning a deadline for an assignment](#assigning-a-deadline-for-an-assignment) - [Choosing an assignment type](#choosing-an-assignment-type) - [Choosing a visibility for assignment repositories](#choosing-a-visibility-for-assignment-repositories) #### Naming an assignment For an individual assignment, {% data variables.product.prodname_classroom %} names repositories by the repository prefix and the student's {% data variables.product.product_name %} username. By default, the repository prefix is the assignment title. For example, if you name an assignment "assignment-1" and the student's username on {% data variables.product.product_name %} is @octocat, the name of the assignment repository for @octocat will be `assignment-1-octocat`. {% data reusables.classroom.assignments-type-a-title %} #### Assigning a deadline for an assignment {% data reusables.classroom.assignments-guide-assign-a-deadline %} #### Choosing an assignment type Under "Individual or group assignment", select the drop-down menu, and click **Individual assignment**. You can't change the assignment type after you create the assignment. If you'd rather create a group assignment, see "[Create a group assignment](/education/manage-coursework-with-github-classroom/create-a-group-assignment)." #### Choosing a visibility for assignment repositories {% data reusables.classroom.assignments-guide-choose-visibility %} {% data reusables.classroom.assignments-guide-click-continue-after-basics %} ### Adding starter code and configuring a development environment {% data reusables.classroom.assignments-guide-intro-for-environment %} - [Choosing a template repository](#choosing-a-template-repository) - [Choosing an online integrated development environment (IDE)](#choosing-an-online-integrated-development-environment-ide) #### Choosing a template repository By default, a new assignment will create an empty repository for each student on the roster for the classroom. {% data reusables.classroom.you-can-choose-a-template-repository %} For more information about template repositories, see "[Creating a template repository](/github/creating-cloning-and-archiving-repositories/creating-a-template-repository)." {% data reusables.classroom.assignments-guide-choose-template-repository %} {% data reusables.classroom.assignments-guide-click-continue-after-starter-code-and-feedback %} #### Choosing an online integrated development environment (IDE) {% data reusables.classroom.about-online-ides %} For more information, see "[Integrate {% data variables.product.prodname_classroom %} with an IDE](/education/manage-coursework-with-github-classroom/integrate-github-classroom-with-an-ide)." {% data reusables.classroom.assignments-guide-choose-an-online-ide %} ### Providing feedback for an assignment Optionally, you can automatically grade assignments and create a space for discussing each submission with the student. - [Testing assignments automatically](#testing-assignments-automatically) - [Preventing changes to important files](#preventing-changes-to-important-files) - [Creating a pull request for feedback](#creating-a-pull-request-for-feedback) #### Testing assignments automatically {% data reusables.classroom.assignments-guide-using-autograding %} #### Preventing changes to important files {% data reusables.classroom.assignments-guide-prevent-changes %} #### Creating a pull request for feedback {% data reusables.classroom.you-can-create-a-pull-request-for-feedback %} {% data reusables.classroom.assignments-guide-create-review-pull-request %} {% data reusables.classroom.assignments-guide-click-create-assignment-button %} ### Inviting students to an assignment {% data reusables.classroom.assignments-guide-invite-students-to-assignment %} You can see whether a student has joined the classroom and accepted or submitted an assignment in the **All students** tab for the assignment. {% data reusables.classroom.assignments-to-prevent-submission %} <div class="procedural-image-wrapper"> <img alt="Individual assignment" class="procedural-image-wrapper" src="/assets/images/help/classroom/assignment-individual-hero.png"> </div> ### Next steps - Once you create the assignment, students can start work on the assignment using Git and {% data variables.product.product_name %}'s features. Students can clone the repository, push commits, manage branches, create and review pull requests, address merge conflicts, and discuss changes with issues. Both you and student can review the commit history for the repository. For more information, see "[Getting started with {% data variables.product.prodname_dotcom %}](/github/getting-started-with-github)," "[Creating, cloning, and archiving repositories](/github/creating-cloning-and-archiving-repositories)," "[Using Git](/github/using-git)," and "[Collaborating with issues and pull requests](/github/collaborating-with-issues-and-pull-requests)." - When a student finishes an assignment, you can review the files in the repository, or you can review the history and visualizations for the repository to better understand the student's work. For more information, see "[Visualizing repository data with graphs](/github/visualizing-repository-data-with-graphs)." - You can provide feedback for an assignment by commenting on individual commits or lines in a pull request. For more information, see "[Commenting on a pull request](/github/collaborating-with-issues-and-pull-requests/commenting-on-a-pull-request)" and "[Opening an issue from code](/github/managing-your-work-on-github/opening-an-issue-from-code)." For more information about creating saved replies to provide feedback for common errors, see "[About saved replies](/github/writing-on-github/about-saved-replies)." ### Further reading - "[Use {% data variables.product.prodname_dotcom %} in your classroom and research](/education/teach-and-learn-with-github-education/use-github-in-your-classroom-and-research)" - "[Connect a learning management system to {% data variables.product.prodname_classroom %}](/education/manage-coursework-with-github-classroom/connect-a-learning-management-system-to-github-classroom)" 9 ...on/manage-coursework-with-github-classroom/get-started-with-github-classroom.md @@ -0,0 +1,9 @@ --- title: Get started with GitHub Classroom shortTitle: Get started intro: Learn how to configure and use {% data variables.product.prodname_classroom %} to administer your course. mapTopic: true versions: free-pro-team: '*' --- 52 content/education/manage-coursework-with-github-classroom/glossary.md @@ -0,0 +1,52 @@ --- title: Glossary intro: You can review explanations of terminology for {% data variables.product.prodname_classroom %}. versions: free-pro-team: '*' --- ### assignment An assignment is coursework in {% data variables.product.prodname_classroom %}. A teacher can assign an assignment to an individual student or a group of students. Teachers can import starter code for the assignment, assign students, and create a deadline for each assignment. For more information, see the definitions for "[individual assignment](#individual-assignment)" and "[group assignment](#group-assignment)." --- ### classroom A classroom is the basic unit of {% data variables.product.prodname_classroom %}. Teachers can use a classroom to organize and manage students, teaching assistants, and assignments for a single course. A classroom belongs to an organization on {% data variables.product.prodname_dotcom_the_website %}. To administer a classroom, you must be an organization owner for the organization on {% data variables.product.prodname_dotcom %}. For more information, see "[Manage classrooms](/education/manage-coursework-with-github-classroom/manage-classrooms)." --- ### {% data variables.product.prodname_classroom %} {% data variables.product.prodname_classroom %} is a web application for educators that provides course administration tools integrated with {% data variables.product.prodname_dotcom %}. For more information, see the [{% data variables.product.prodname_classroom %}](https://classroom.github.com/) website. --- ### group assignment {% data reusables.classroom.assignments-group-definition %} For more information, see "[Create a group assignment](/education/manage-coursework-with-github-classroom/create-a-group-assignment)." --- ### identifier An identifier in {% data variables.product.prodname_classroom %} is a unique ID for a student participating in a course. For example, an identifier can be a student name, alphanumeric ID, or email address. --- ### individual assignment {% data reusables.classroom.assignments-individual-definition %} For more information, see "[Create an individual assignment](/education/manage-coursework-with-github-classroom/create-an-individual-assignment)." --- ### roster A roster allows a teacher to manage students and assignment submissions in a classroom on {% data variables.product.prodname_classroom %}. Teachers can create a roster by entering a list of student identifiers, or by connecting {% data variables.product.prodname_classroom %} to a learning management system (LMS). For more information about identifiers, see the definition of "[identifier](#identifier)." For more information about connecting {% data variables.product.prodname_classroom %} to an LMS, see "[Connect a learning management system to {% data variables.product.prodname_classroom %}](/education/manage-coursework-with-github-classroom/connect-a-learning-management-system-to-github-classroom)." --- ### Further reading - "[{% data variables.product.prodname_dotcom %} glossary](/github/getting-started-with-github/github-glossary)" 32 content/education/manage-coursework-with-github-classroom/index.md @@ -0,0 +1,32 @@ --- title: Manage coursework with GitHub Classroom shortTitle: '{% data variables.product.prodname_classroom %}' intro: With {% data variables.product.prodname_classroom %}, you can use {% data variables.product.product_name %} to administer or participate in a course about software development. versions: free-pro-team: '*' --- ### Table of Contents {% topic_link_in_list /get-started-with-github-classroom %} {% link_in_list /basics-of-setting-up-github-classroom %} {% link_in_list /glossary %} {% topic_link_in_list /teach-with-github-classroom %} {% link_in_list /manage-classrooms %} {% link_in_list /create-an-individual-assignment %} {% link_in_list /create-a-group-assignment %} {% link_in_list /create-an-assignment-from-a-template-repository %} {% link_in_list /leave-feedback-with-pull-requests %} {% link_in_list /use-autograding %} {% link_in_list /configure-default-settings-for-assignment-repositories %} {% link_in_list /connect-a-learning-management-system-to-github-classroom %} {% topic_link_in_list /integrate-github-classroom-with-an-ide %} {% link_in_list /integrate-github-classroom-with-an-online-ide %} {% link_in_list /about-using-makecode-arcade-with-github-classroom %} {% link_in_list /about-using-replit-with-github-classroom %} {% link_in_list /run-student-code-in-an-online-ide %} {% topic_link_in_list /learn-with-github-classroom %} {% link_in_list /view-autograding-results %} 8 ...nage-coursework-with-github-classroom/integrate-github-classroom-with-an-ide.md @@ -0,0 +1,8 @@ --- title: Integrate GitHub Classroom with an IDE shortTitle: Integrate with an IDE intro: You can help your students write, test, and debug code by preconfiguring a development environment for assignment repositories on {% data variables.product.prodname_classroom %}. mapTopic: true versions: free-pro-team: '*' --- 42 ...ursework-with-github-classroom/integrate-github-classroom-with-an-online-ide.md @@ -0,0 +1,42 @@ --- title: Integrate GitHub Classroom with an online IDE shortTitle: Integrate with an online IDE intro: You can preconfigure a supported online integrated development environment (IDE) for assignments you create in {% data variables.product.prodname_classroom %}. versions: free-pro-team: '*' redirect_from: - /education/manage-coursework-with-github-classroom/online-ide-integrations --- ### About integration with an online IDE {% data reusables.classroom.about-online-ides %} After a student accepts an assignment with an online IDE, the README file in the student's assignment repository will contain a button to open the assignment in the IDE. The student can begin working immediately, and no additional configuration is necessary.  ### Supported online IDEs {% data variables.product.prodname_classroom %} supports the following online IDEs. You can learn more about the student experience for each IDE. | IDE | More information | | :- | :- | | Microsoft MakeCode Arcade | "[About using MakeCode Arcade with {% data variables.product.prodname_classroom %}](/education/manage-coursework-with-github-classroom/about-using-makecode-arcade-with-github-classroom)" | | Repl.it | "[About using Repl.it with GitHub Classroom](/education/manage-coursework-with-github-classroom/about-using-replit-with-github-classroom)" | ### Configuring an online IDE for an assignment You can choose the online IDE you'd like to use for an assignment when you create an assignment. To learn how to create a new assignment that uses an online IDE, see "[Create an individual assignment](/education/manage-coursework-with-github-classroom/create-an-individual-assignment)" or "[Create a group assignment](/education/manage-coursework-with-github-classroom/create-a-group-assignment)." ### Authorizing the OAuth app for an online IDE The first time you configure an assignment with an online IDE, you must authorize the OAuth app for the online IDE for your organization.  For all repositories, grant the app **read** access to metadata, administration, and code, and **write** access to administration and code. For more information, see "[Authorizing OAuth Apps](/github/authenticating-to-github/authorizing-oauth-apps)." ### Further reading - "[About READMEs](/github/creating-cloning-and-archiving-repositories/about-readmes)" 7 ...ducation/manage-coursework-with-github-classroom/learn-with-github-classroom.md @@ -0,0 +1,7 @@ --- title: Learn with GitHub Classroom intro: You can participate in coursework in {% data variables.product.prodname_classroom %} and see results from your teacher. mapTopic: true versions: free-pro-team: '*' --- 33 ...on/manage-coursework-with-github-classroom/leave-feedback-with-pull-requests.md @@ -0,0 +1,33 @@ --- title: Leave feedback with pull requests intro: You can leave feedback for your students in a special pull request within the repository for each assignment. permissions: People with read permissions to a repository can leave feedback in a pull request for the repository. versions: free-pro-team: '*' redirect_from: - /education/manage-coursework-with-github-classroom/leaving-feedback-in-github --- ### About feedback pull requests for assignments {% data reusables.classroom.you-can-create-a-pull-request-for-feedback %} When you enable the pull request for feedback for an assignment, {% data variables.product.prodname_classroom %} will create a special pull request titled **Feedback** in the assignment repository for each student or team. The pull request automatically shows every commit that a student pushed to the assignment repository's default branch. ### Prerequisites To create and access the feedback pull request, you must enable the feedback pull request when you create the assignment. {% data reusables.classroom.for-more-information-about-assignment-creation %} ### Leaving feedback in a pull request for an assignment {% data reusables.classroom.sign-into-github-classroom %} 1. In the list of classrooms, click the classroom with the assignment you want to review.  {% data reusables.classroom.click-assignment-in-list %} 1. To the right of the submission, click **Review**.  1. Review the pull request. For more information, see "[Commenting on a pull request](/github/collaborating-with-issues-and-pull-requests/commenting-on-a-pull-request)." ### Further reading - "[Integrate {% data variables.product.prodname_classroom %} with an IDE](http://localhost:4000/en/free-pro-team@latest/education/manage-coursework-with-github-classroom/integrate-github-classroom-with-an-ide)" 121 content/education/manage-coursework-with-github-classroom/manage-classrooms.md @@ -0,0 +1,121 @@ --- title: Manage classrooms intro: You can create and manage a classroom for each course that you teach using {% data variables.product.prodname_classroom %}. permissions: Organization owners can manage a classroom for an organization. versions: free-pro-team: '*' redirect_from: - /education/manage-coursework-with-github-classroom/archive-a-classroom --- ### About classrooms {% data reusables.classroom.about-classrooms %}  ### About management of classrooms {% data variables.product.prodname_classroom %} uses organization accounts on {% data variables.product.product_name %} to manage permissions, administration, and security for each classroom that you create. Each organization can have multiple classrooms. After you create a classroom, {% data variables.product.prodname_classroom %} will prompt you to invite teaching assistants (TAs) and admins to the classroom. Each classroom can have one or more admins. Admins can be teachers, TAs, or any other course administrator who you'd like to have control over your classrooms on {% data variables.product.prodname_classroom %}. Invite TAs and admins to your classroom by inviting the user accounts on {% data variables.product.product_name %} to your organization as organization owners and sharing the URL for your classrom. Organization owners can administer any classroom for the organization. For more information, see "[Permission levels for an organization](/github/setting-up-and-managing-organizations-and-teams/permission-levels-for-an-organization)" and "[Inviting users to join your organization](/github/setting-up-and-managing-organizations-and-teams/inviting-users-to-join-your-organization)." When you're done using a classroom, you can archive the classroom and refer to the classroom, roster, and assignments later, or you can delete the classroom if you no longer need the classroom. ### About classroom rosters Each classroom has a roster. A roster is a list of identifiers for the students who participate in your course. When you first share the URL for an assignment with a student, the student must sign into {% data variables.product.product_name %} with a user account to link the user account to an identifier for the classroom. After the student links a user account, you can see the associated user account in the roster. You can also see when the student accepts or submits an assignment.  ### Prerequisites You must have an organization account on {% data variables.product.product_name %} to manage classrooms on {% data variables.product.prodname_classroom %}. For more information, see "[Types of {% data variables.product.company_short %} accounts](/github/getting-started-with-github/types-of-github-accounts#organization-accounts)" and "[Creating a new organization from scratch](/github/setting-up-and-managing-organizations-and-teams/creating-a-new-organization-from-scratch)." You must authorize the OAuth app for {% data variables.product.prodname_classroom %} for your organization to manage classrooms for your organization account. For more information, see "[Authorizing OAuth Apps](/github/authenticating-to-github/authorizing-oauth-apps)." ### Creating a classroom {% data reusables.classroom.sign-into-github-classroom %} 1. Click **New classroom**.  {% data reusables.classroom.guide-create-new-classroom %} After you create a classroom, you can begin creating assignments for students. For more information, see "[Create an individual assignment](/education/manage-coursework-with-github-classroom/create-an-individual-assignment)" or "[Create a group assignment](/education/manage-coursework-with-github-classroom/create-a-group-assignment)." ### Creating a roster for your classroom You can create a roster of the students who participate in your course. If your course already has a roster, you can update the students on the roster or delete the roster. For more information, see "[Adding a student to the roster for your classroom](#adding-students-to-the-roster-for-your-classroom)" or "[Deleting a roster for a classroom](#deleting-a-roster-for-a-classroom)." {% data reusables.classroom.sign-into-github-classroom %} {% data reusables.classroom.click-classroom-in-list %} {% data reusables.classroom.click-students %} 1. To connect {% data variables.product.prodname_classroom %} to your LMS and import a roster, click {% octicon "mortar-board" aria-label="The mortar board icon" %} **Import from a learning management system** and follow the instructions. For more information, see "[Connect a learning management system to {% data variables.product.prodname_classroom %}](/education/manage-coursework-with-github-classroom/connect-a-learning-management-system-to-github-classroom)."  1. To create a roster manually, type your student identifiers. Optionally, click **Upload a CSV or text file** to upload a file containing the identifiers.  1. Click **Create roster**.  ### Adding students to the roster for your classroom Your classroom must have an existing roster to add students to the roster. For more information about creating a roster, see "[Creating a roster for your classrom](#creating-a-roster-for-your-classroom)." {% data reusables.classroom.sign-into-github-classroom %} {% data reusables.classroom.click-classroom-in-list %} {% data reusables.classroom.click-students %} 1. To the right of "Classroom roster", click **Update students**.  1. Follow the instructions to add students to the roster. - To import students from an LMS, click **Sync from a learning management system**. For more information about importing a roster from an LMS, see "[Connect a learning management system to {% data variables.product.prodname_classroom %}](/education/manage-coursework-with-github-classroom/connect-a-learning-management-system-to-github-classroom)." - To manually add students, under "Manually add students", click **Upload a CSV or text file** or type the identifiers for the students, then click **Add roster entries**.  ### Renaming a classroom {% data reusables.classroom.sign-into-github-classroom %} {% data reusables.classroom.click-classroom-in-list %} {% data reusables.classroom.click-settings %} 1. Under "Classroom name", type a new name for the classroom.  1. Click **Rename classroom**.  ### Archiving or unarchiving a classroom You can archive a classroom that you no longer use on {% data variables.product.prodname_classroom %}. When you archive a classroom, you can't create new assignments or edit existing assignments for the classroom. Students can't accept invitations to assignments in archived classrooms. {% data reusables.classroom.sign-into-github-classroom %} 1. To the right of a classroom's name, select the {% octicon "kebab-horizontal" aria-label="The horizontal kebab icon" %} drop-down menu, then click **Archive**.  1. To unarchive a classroom, to the right of a classroom's name, select the {% octicon "kebab-horizontal" aria-label="The horizontal kebab icon" %} drop-down menu, then click **Unarchive**.  ### Deleting a roster for a classroom {% data reusables.classroom.sign-into-github-classroom %} {% data reusables.classroom.click-classroom-in-list %} {% data reusables.classroom.click-students %} 1. Under "Delete this roster", click **Delete roster**.  1. Read the warnings, then click **Delete roster**.  ### Deleting a classroom {% data reusables.classroom.sign-into-github-classroom %} {% data reusables.classroom.click-classroom-in-list %} {% data reusables.classroom.click-settings %} 1. To the right of "Delete this classroom", click **Delete classroom**.  1. **Read the warnings**. 1. To verify that you're deleting the correct classroom, type the name of the classroom you want to delete.  1. Click **Delete classroom**.  22 ...on/manage-coursework-with-github-classroom/run-student-code-in-an-online-ide.md @@ -0,0 +1,22 @@ --- title: Run student code in an online IDE intro: You can run the code from a student assignment within the online integrated development environment (IDE) that you configured for the assignment. versions: free-pro-team: '*' redirect_from: - /education/manage-coursework-with-github-classroom/running-student-code --- ### About student code and online IDEs If you configure an online integrated development environment (IDE) for an assignment, you can run the code within the online IDE. You don't need to clone the assignment repository to your computer. For more information about online IDEs, see "[Integrate {% data variables.product.prodname_classroom %} with an online IDE](/education/manage-coursework-with-github-classroom/integrate-github-classroom-with-an-online-ide)." ### Running student code in the online IDE {% data reusables.classroom.sign-into-github-classroom %} {% data reusables.classroom.click-classroom-in-list %} {% data reusables.classroom.click-assignment-in-list %} 1. To the right of the submission, click **View IDE**.  8 ...ducation/manage-coursework-with-github-classroom/teach-with-github-classroom.md @@ -0,0 +1,8 @@ --- title: Teach with GitHub Classroom intro: Learn how to set up your classroom and assignments. mapTopic: true versions: free-pro-team: '*' --- 93 content/education/manage-coursework-with-github-classroom/use-autograding.md 30 ...t/education/manage-coursework-with-github-classroom/view-autograding-results.md 90 content/education/quickstart.md 1 ...github-education/about-campus-advisors.md → ...github-education/about-campus-advisors.md 1 ...-github-education/about-campus-experts.md → ...-github-education/about-campus-experts.md 1 ...ducation-for-educators-and-researchers.md → ...ducation-for-educators-and-researchers.md 5 ...on/about-github-education-for-students.md → ...on/about-github-education-for-students.md 9 ...ithub-education/about-github-education.md → ...ithub-education/about-github-education.md 5 .../applying-for-a-student-developer-pack.md → ...ion/apply-for-a-student-developer-pack.md 14 ...for-an-educator-or-researcher-discount.md → ...for-an-educator-or-researcher-discount.md 26 content/education/teach-and-learn-with-github-education/index.md 3 ...github-at-your-educational-institution.md → ...github-at-your-educational-institution.md 3 ...ation/using-github-for-your-schoolwork.md → ...ucation/use-github-for-your-schoolwork.md 3 ...-github-in-your-classroom-and-research.md → ...-github-in-your-classroom-and-research.md 5 ...-for-a-student-developer-pack-approved.md → ...-for-a-student-developer-pack-approved.md 3 ...ucator-or-researcher-discount-approved.md → ...ucator-or-researcher-discount-approved.md 20 ...ering-a-repository/enabling-or-disabling-github-discussions-for-a-repository.md 5 content/github/administering-a-repository/index.md 2 content/github/authenticating-to-github/reviewing-your-security-log.md 1 content/github/collaborating-with-issues-and-pull-requests/index.md 74 ...with-issues-and-pull-requests/reviewing-dependency-changes-in-a-pull-request.md 19 ...g-with-issues-and-pull-requests/reviewing-proposed-changes-in-a-pull-request.md 10 content/github/creating-cloning-and-archiving-repositories/about-repositories.md 15 content/github/customizing-your-github-workflow/about-github-marketplace.md 2 content/github/getting-started-with-github/git-and-github-learning-resources.md 4 content/github/getting-started-with-github/github-glossary.md 6 content/github/getting-started-with-github/signing-up-for-a-new-github-account.md 1 content/github/index.md 2 ...b/managing-security-vulnerabilities/about-alerts-for-vulnerable-dependencies.md 25 ...hub/managing-security-vulnerabilities/about-managing-vulnerable-dependencies.md 1 content/github/managing-security-vulnerabilities/index.md 4 ...nerabilities/viewing-and-updating-vulnerable-dependencies-in-your-repository.md 3 ...criptions-and-notifications-on-github/managing-notifications-from-your-inbox.md 6 content/github/managing-your-work-on-github/about-issues.md 3 content/github/searching-for-information-on-github/about-searching-on-github.md 5 content/github/searching-for-information-on-github/index.md 114 content/github/searching-for-information-on-github/searching-discussions.md 2 ...ithub/searching-for-information-on-github/searching-issues-and-pull-requests.md 2 ...nd-managing-billing-and-payments-on-github/about-billing-for-github-sponsors.md 4 ...-billing-and-payments-on-github/discounted-subscriptions-for-github-accounts.md 19 ...ing-up-and-managing-billing-and-payments-on-github/downgrading-a-sponsorship.md 16 ...tting-up-and-managing-billing-and-payments-on-github/upgrading-a-sponsorship.md 4 content/github/setting-up-and-managing-organizations-and-teams/index.md 27 ...and-teams/managing-discussion-creation-for-repositories-in-your-organization.md 25 ...izations-and-teams/managing-updates-from-accounts-your-organization-sponsors.md 3 ...p-and-managing-organizations-and-teams/permission-levels-for-an-organization.md 14 ...ing-organizations-and-teams/repository-permission-levels-for-an-organization.md 86 ...naging-organizations-and-teams/reviewing-the-audit-log-for-your-organization.md 1 content/github/setting-up-and-managing-your-github-user-account/index.md 24 ...etting-up-and-managing-your-github-user-account/managing-your-theme-settings.md 12 content/github/site-policy/github-additional-product-terms.md 8 ...porting-the-open-source-community-with-github-sponsors/about-github-sponsors.md 17 ...community-with-github-sponsors/attributing-sponsorships-to-your-organization.md 28 ...e-open-source-community-with-github-sponsors/changing-your-sponsorship-tiers.md 22 ...th-github-sponsors/configuring-webhooks-for-events-in-your-sponsored-account.md 17 ...ting-the-open-source-community-with-github-sponsors/contacting-your-sponsors.md 25 ...munity-with-github-sponsors/editing-your-profile-details-for-github-sponsors.md 1 content/github/supporting-the-open-source-community-with-github-sponsors/index.md 12 ...ce-community-with-github-sponsors/managing-your-payouts-from-github-sponsors.md 18 ...he-open-source-community-with-github-sponsors/managing-your-sponsorship-goal.md 39 ...ing-the-open-source-community-with-github-sponsors/managing-your-sponsorship.md 10 ...munity-with-github-sponsors/setting-up-github-sponsors-for-your-organization.md 10 ...munity-with-github-sponsors/setting-up-github-sponsors-for-your-user-account.md 62 ...-source-community-with-github-sponsors/sponsoring-an-open-source-contributor.md 27 ...source-community-with-github-sponsors/viewing-your-sponsors-and-sponsorships.md 23 content/github/teaching-and-learning-with-github-education/index.md This file was deleted. 7 ...nt/github/visualizing-repository-data-with-graphs/about-the-dependency-graph.md 1 content/github/working-with-github-support/index.md 10 content/graphql/README.md 58 ...tting-started-with-github-container-registry/about-github-container-registry.md This file was deleted. 15 content/packages/getting-started-with-github-container-registry/index.md This file was deleted. 95 content/packages/guides/about-github-container-registry.md 2 ...ol-and-visibility-for-container-images.md → ...ol-and-visibility-for-container-images.md 5 ...che-maven-for-use-with-github-packages.md → ...che-maven-for-use-with-github-packages.md 1 ...ng-docker-for-use-with-github-packages.md → ...ng-docker-for-use-with-github-packages.md 1 ...otnet-cli-for-use-with-github-packages.md → ...otnet-cli-for-use-with-github-packages.md 1 ...ng-gradle-for-use-with-github-packages.md → ...ng-gradle-for-use-with-github-packages.md 1 ...uring-npm-for-use-with-github-packages.md → ...uring-npm-for-use-with-github-packages.md 1 ...-rubygems-for-use-with-github-packages.md → ...-rubygems-for-use-with-github-packages.md 2 ...ting-a-repository-to-a-container-image.md → ...ting-a-repository-to-a-container-image.md 10 content/packages/guides/container-guides-for-github-packages.md 2 ...er-registry/deleting-a-container-image.md → ...ages/guides/deleting-a-container-image.md 2 ...ry/enabling-improved-container-support.md → ...es/enabling-improved-container-support.md 33 content/packages/guides/index.md 2 ...b-container-registry-for-docker-images.md → ...b-container-registry-for-docker-images.md 10 content/packages/guides/package-client-guides-for-github-packages.md 2 ...stry/pushing-and-pulling-docker-images.md → ...ides/pushing-and-pulling-docker-images.md 1 ...ng-github-packages-with-github-actions.md → ...ng-github-packages-with-github-actions.md 46 content/packages/index.md 60 ...anaging-packages/about-github-packages.md → ...-github-packages/about-github-packages.md 13 ...concepts-for-github-container-registry.md → ...ages/core-concepts-for-github-packages.md 16 content/packages/learn-github-packages/index.md 1 ...managing-packages/publishing-a-package.md → ...n-github-packages/publishing-a-package.md 3 ...d-managing-packages/deleting-a-package.md → ...ges/manage-packages/deleting-a-package.md 8 ...publishing-and-managing-packages/index.md → content/packages/manage-packages/index.md 1 ...managing-packages/installing-a-package.md → ...s/manage-packages/installing-a-package.md 1 ...and-managing-packages/viewing-packages.md → ...kages/manage-packages/viewing-packages.md 11 content/packages/managing-container-images-with-github-container-registry/index.md This file was deleted. 109 content/packages/quickstart.md 20 content/packages/using-github-packages-with-your-projects-ecosystem/index.md This file was deleted. 10 content/rest/README.md 18 content/rest/overview/resources-in-the-rest-api.md 2 content/rest/overview/troubleshooting.md 10 content/rest/reference/enterprise-admin.md 2 data/products.yml 2 data/reusables/accounts/create-account.md 2 data/reusables/actions/actions-not-verified.md 7 data/reusables/actions/visualization-beta.md 5 data/reusables/audit_log/audit-log-api-info.md 1 data/reusables/audit_log/audit-log-git-events-retention.md 1 data/reusables/classroom/about-assignments.md 1 data/reusables/classroom/about-autograding.md 1 data/reusables/classroom/about-classrooms.md 1 data/reusables/classroom/about-online-ides.md 1 data/reusables/classroom/assignments-classroom-prerequisite.md 2 data/reusables/classroom/assignments-click-pencil.md 1 data/reusables/classroom/assignments-group-definition.md 5 data/reusables/classroom/assignments-guide-assign-a-deadline.md 5 data/reusables/classroom/assignments-guide-choose-an-online-ide.md 5 data/reusables/classroom/assignments-guide-choose-template-repository.md 9 data/reusables/classroom/assignments-guide-choose-visibility.md 7 data/reusables/classroom/assignments-guide-click-continue-after-basics.md 7 ...s/classroom/assignments-guide-click-continue-after-starter-code-and-feedback.md 5 data/reusables/classroom/assignments-guide-click-create-assignment-button.md 5 data/reusables/classroom/assignments-guide-create-review-pull-request.md 5 data/reusables/classroom/assignments-guide-create-the-assignment.md 1 data/reusables/classroom/assignments-guide-intro-for-environment.md 3 data/reusables/classroom/assignments-guide-invite-students-to-assignment.md 7 data/reusables/classroom/assignments-guide-prevent-changes.md 23 data/reusables/classroom/assignments-guide-using-autograding.md 1 data/reusables/classroom/assignments-individual-definition.md 1 data/reusables/classroom/assignments-to-prevent-submission.md 5 data/reusables/classroom/assignments-type-a-title.md 1 data/reusables/classroom/classroom-creates-group-repositories.md 1 data/reusables/classroom/classroom-creates-individual-repositories.md 1 data/reusables/classroom/classroom-enables-invitation-urls.md 2 data/reusables/classroom/click-assignment-in-list.md 2 data/reusables/classroom/click-classroom-in-list.md 2 data/reusables/classroom/click-settings.md 2 data/reusables/classroom/click-students.md 1 data/reusables/classroom/for-more-information-about-assignment-creation.md 6 data/reusables/classroom/guide-create-new-classroom.md 5 data/reusables/classroom/invitation-url-warning.md 1 data/reusables/classroom/readme-contains-button-for-online-ide.md 1 data/reusables/classroom/sign-into-github-classroom.md 1 data/reusables/classroom/use-add-test-drop-down-to-click-grading-method.md 1 data/reusables/classroom/you-can-choose-a-template-repository.md 1 data/reusables/classroom/you-can-create-a-pull-request-for-feedback.md 1 data/reusables/classroom/you-may-want-to-predefine-repository-settings.md 1 data/reusables/discussions/about-categories-and-formats.md 1 data/reusables/discussions/about-discussions.md 5 data/reusables/discussions/beta.md 2 data/reusables/discussions/click-discussion-in-list.md 2 data/reusables/discussions/discussions-tab.md 2 data/reusables/discussions/edit-categories.md 1 data/reusables/discussions/edit-category-details.md 8 ...les/discussions/enabling-or-disabling-github-discussions-for-your-repository.md 1 data/reusables/discussions/github-recognizes-members.md 16 data/reusables/discussions/marking-a-comment-as-an-answer.md 1 data/reusables/discussions/repository-category-limit.md 10 data/reusables/discussions/starting-a-discussion.md 1 data/reusables/discussions/you-can-categorize-discussions.md 1 data/reusables/discussions/you-can-convert-an-issue.md 1 data/reusables/discussions/you-can-use-discussions.md 1 data/reusables/discussions/you-cannot-convert-a-discussion.md 2 data/reusables/education/about-github-education-link.md 2 data/reusables/education/apply-for-team.md 2 data/reusables/education/click-get-teacher-benefits.md 6 data/reusables/education/educator-requirements.md 1 data/reusables/gated-features/discussions.md 1 data/reusables/marketplace/app-transfer-to-org-for-verification.md 5 data/reusables/marketplace/free-plan-note.md 2 data/reusables/marketplace/launch-with-free.md 8 data/reusables/marketplace/marketplace-billing-ui-requirements.md 2 data/reusables/package_registry/billing-for-container-registry.md 2 data/reusables/package_registry/container-registry-beta-billing-note.md 2 data/reusables/package_registry/container-registry-beta.md 2 data/reusables/package_registry/docker_registry_deprecation_status.md 2 data/reusables/package_registry/feature-preview-for-container-registry.md 2 data/reusables/package_registry/required-scopes.md 2 data/reusables/package_registry/viewing-packages.md 3 data/reusables/repositories/dependency-review.md 7 data/reusables/repositories/navigate-to-job-superlinter.md 4 data/reusables/repositories/view-failed-job-results-superlinter.md 4 data/reusables/repositories/view-specific-line-superlinter.md 2 data/reusables/search/date_gt_lt.md 2 data/reusables/sponsors/billing-switcher.md 2 data/reusables/sponsors/change-tier.md 2 data/reusables/sponsors/choose-updates.md 2 data/reusables/sponsors/developer-sponsored-choose-updates.md This file was deleted. 4 data/reusables/sponsors/manage-developer-sponsorship.md This file was deleted. 4 data/reusables/sponsors/manage-org-sponsorship.md This file was deleted. 2 data/reusables/sponsors/manage-sponsorship.md 1 data/reusables/sponsors/manage-updates-for-orgs.md 2 data/reusables/sponsors/maximum-tier.md 4 data/reusables/sponsors/navigate-to-org-sponsors-dashboard.md This file was deleted. 2 ...onsors/navigate-to-sponsored-developer.md → ...sponsors/navigate-to-sponsored-account.md 1 data/reusables/sponsors/navigate-to-sponsored-org.md This file was deleted. 2 ...ors/navigate-to-dev-sponsors-dashboard.md → ...ponsors/navigate-to-sponsors-dashboard.md 2 data/reusables/sponsors/no-fees.md 5 data/reusables/sponsors/org-sponsors-release-phase.md 2 data/reusables/sponsors/pay-prorated-amount.md 2 data/reusables/sponsors/prorated-sponsorship.md 2 data/reusables/sponsors/sponsor-account.md 7 data/reusables/sponsors/sponsorship-dashboard.md 2 data/reusables/sponsors/sponsorship-details.md 1 data/reusables/webhooks/app_always_desc.md 3 data/ui.yml 7 data/variables/action_code_examples.yml 37 data/variables/discussions_community_examples.yml 6 data/variables/product.yml 21 includes/all-articles.html 4 includes/breadcrumbs.html 2 includes/code-example-card.html 14 includes/discussions-community-card.html 2 includes/header-notification.html 90 javascripts/filter-cards.js 92 javascripts/filter-code-examples.js This file was deleted. 4 javascripts/index.js 64 layouts/product-landing.html 68 lib/data-directory.js 28 lib/filename-to-key.js 7 lib/frontmatter.js 2 lib/liquid-tags/data.js 25 lib/page.js 54 lib/pages.js 21 lib/redirects/get-docs-path-from-developer-path.js 41 lib/redirects/precompile.js 231 lib/rest/static/decorated/api.github.com.json 495 lib/rest/static/dereferenced/api.github.com.deref.json 17 lib/rewrite-local-links.js 10 lib/site-data.js 24 lib/warm-server.js 5 middleware/breadcrumbs.js 38 middleware/categories-for-support-team.js 6 middleware/contextualizers/early-access-links.js 103 middleware/csp.js 69 middleware/early-access-breadcrumbs.js 1 middleware/index.js 45 package-lock.json 3 package.json 4 script/check-s3-images.js 4 script/early-access/clone-locally 41 script/early-access/create-branch 7 server.js 2 stylesheets/article.scss 4 tests/browser/browser.js 10 tests/content/category-pages.js 2 tests/content/crowdin-config.js 3 tests/content/featured-links.js 5 tests/content/glossary.js 42 tests/content/remove-liquid-statements.js 39 tests/content/site-data-references.js 4 tests/content/site-data.js 22 tests/fixtures/rest-redirects.json 10 tests/graphql/build-changelog-test.js 9 tests/helpers/conditional-runs.js 20 tests/meta/orphan-tests.js 23 tests/rendering/breadcrumbs.js 4 tests/rendering/rest.js 3 tests/rendering/server.js 47 tests/routing/developer-site-redirects.js 10 tests/routing/redirects.js 15 tests/unit/data-directory/filename-to-key.js 1 tests/unit/data-directory/fixtures/README.md 1 tests/unit/data-directory/fixtures/bar.yaml 1 tests/unit/data-directory/fixtures/foo.json 1 tests/unit/data-directory/fixtures/nested/baz.md 40 tests/unit/data-directory/index.js 19 tests/unit/early-access.js 4 tests/unit/find-page.js 57 tests/unit/liquid-helpers.js 140 tests/unit/page.js 2 tests/unit/pages.js 0 comments on commit 1a56ed1 Leave a comment You’re not receiving notifications from this thread. © 2021 GitHub, Inc. Terms Privacy Security Status Docs Contact GitHub Pricing API Training Blog About
The aim of this assignment is to have you do UDP socket client / server programming with a focus on two broad aspects : Setting up the exchange between the client and server in a secure way despite the lack of a formal connection (as in TCP) between the two, so that ‘outsider’ UDP datagrams (broadcast, multicast, unicast - fortuitously or maliciously) cannot intrude on the communication. Introducing application-layer protocol data-transmission reliability, flow control and congestion control in the client and server using TCP-like ARQ sliding window mechanisms. The second item above is much more of a challenge to implement than the first, though neither is particularly trivial. But they are not tightly interdependent; each can be worked on separately at first and then integrated together at a later stage. Apart from the material in Chapters 8, 14 & 22 (especially Sections 22.5 - 22.7), and the experience you gained from the preceding assignment, you will also need to refer to the following : ioctl function (Chapter 17). get_ifi_info function (Section 17.6, Chapter 17). This function will be used by the server code to discover its node’s network interfaces so that it can bind all its interface IP addresses (see Section 22.6). ‘Race’ conditions (Section 20.5, Chapter 20) You also need a thorough understanding of how the TCP protocol implements reliable data transfer, flow control and congestion control. Chapters 17- 24 of TCP/IP Illustrated, Volume 1 by W. Richard Stevens gives a good overview of TCP. Though somewhat dated for some things (it was published in 1994), it remains, overall, a good basic reference. Overview This assignment asks you to implement a primitive file transfer protocol for Unix platforms, based on UDP, and with TCP-like reliability added to the transfer operation using timeouts and sliding-window mechanisms, and implementing flow and congestion control. The server is a concurrent server which can handle multiple clients simultaneously. A client gives the server the name of a file. The server forks off a child which reads directly from the file and transfers the contents over to the client using UDP datagrams. The client prints out the file contents as they come in, in order, with nothing missing and with no duplication of content, directly on to stdout (via the receiver sliding window, of course, but with no other intermediate buffering). The file to be transferred can be of arbitrary length, but its contents are always straightforward ascii text. As an aside let me mention that assuming the file contents ascii is not as restrictive as it sounds. We can always pretend, for example, that binary files are base64 encoded (“ASCII armor”). A real file transfer protocol would, of course, have to worry about transferring files between heterogeneous platforms with different file structure conventions and semantics. The sender would first have to transform the file into a platform-independent, protocol-defined, format (using, say, ASN.1, or some such standard), and the receiver would have to transform the received file into its platform’s native file format. This kind of thing can be fairly time consuming, and is certainly very tedious, to implement, with little educational value - it is not part of this assignment. Arguments for the server You should provide the server with an input file server.in from which it reads the following information, in the order shown, one item per line : Well-known port number for server. Maximum sending sliding-window size (in datagram units). You will not be handing in your server.in file. We shall create our own when we come to test your code. So it is important that you stick strictly to the file name and content conventions specified above. The same applies to the client.in input file below. Arguments for the client The client is to be provided with an input file client.in from which it reads the following information, in the order shown, one item per line : IP address of server (not the hostname). Well-known port number of server. filename to be transferred. Receiving sliding-window size (in datagram units). Random generator seed value. Probability p of datagram loss. This should be a real number in the range [ 0.0 , 1.0 ] (value 0.0 means no loss occurs; value 1.0 means all datagrams all lost). The mean µ, in milliseconds, for an exponential distribution controlling the rate at which the client reads received datagram payloads from its receive buffer. Operation Server starts up and reads its arguments from file server.in. As we shall see, when a client communicates with the server, the server will want to know what IP address that client is using to identify the server (i.e. , the destination IP address in the incoming datagram). Normally, this can be done relatively straightforwardly using the IP_RECVDESTADDR socket option, and picking up the information using the ancillary data (‘control information’) capability of the recvmsg function. Unfortunately, Solaris 2.10 does not support the IP_RECVDESTADDR option (nor, incidentally, does it support the msg_flags option in msghdr - see p.390). This considerably complicates things. In the absence of IP_RECVDESTADDR, what the server has to do as part of its initialization phase is to bind each IP address it has (and, simultaneously, its well-known port number, which it has read in from server.in) to a separate UDP socket. The code in Section 22.6, which uses the get_ifi_info function, shows you how to do that. However, there are important differences between that code and the version you want to implement. The code of Section 22.6 binds the IP addresses and forks off a child for each address that is bound to. We do not want to do that. Instead you should have an array of socket descriptors. For each IP address, create a new socket and bind the address (and well-known port number) to the socket without forking off child processes. Creating child processes comes later, when clients arrive. The code of Section 22.6 also attempts to bind broadcast addresses. We do not want to do this. It binds a wildcard IP address, which we certainly do not want to do either. We should bind strictly only unicast addresses (including the loopback address). The get_ifi_info function (which the code in Section 22.6 uses) has to be modified so that it also gets the network masks for the IP addresses of the node, and adds these to the information stored in the linked list of ifi_info structures (see Figure 17.5, p.471) it produces. As you go binding each IP address to a distinct socket, it will be useful for later processing to build your own array of structures, where a structure element records the following information for each socket : sockfd IP address bound to the socket network mask for the IP address subnet address (obtained by doing a bit-wise and between the IP address and its network mask) Report, in a ReadMe file which you hand in with your code, on the modifications you had to introduce to ensure that only unicast addresses are bound, and on your implementation of the array of structures described above. You should print out on stdout, with an appropriate message and appropriately formatted in dotted decimal notation, the IP address, network mask, and subnet address for each socket in your array of structures (you do not need to print the sockfd). The server now uses select to monitor the sockets it has created for incoming datagrams. When it returns from select, it must use recvfrom or recvmsg to read the incoming datagram (see 6. below). When a client starts, it first reads its arguments from the file client.in. The client checks if the server host is ‘local’ to its (extended) Ethernet. If so, all its communication to the server is to occur as MSG_DONTROUTE (or SO_DONTROUTE socket option). It determines if the server host is ‘local’ as follows. The first thing the client should do is to use the modified get_ifi_info function to obtain all of its IP addresses and associated network masks. Print out on stdout, in dotted decimal notation and with an appropriate message, the IP addresses and network masks obtained. In the following, IPserver designates the IP address the client will use to identify the server, and IPclient designates the IP address the client will choose to identify itself. The client checks whether the server is on the same host. If so, it should use the loopback address 127.0.0.1 for the server (i.e. , IPserver = 127.0.0.1). IPclient should also be set to the loopback address. Otherwise it proceeds as follows: IPserver is set to the IP address for the server in the client.in file. Given IPserver and the (unicast) IP addresses and network masks for the client returned by get_ifi_info in the linked list of ifi_info structures, you should be able to figure out if the server node is ‘local’ or not. This will be discussed in class; but let me just remind you here that you should use ‘longest prefix matching’ where applicable. If there are multiple client addresses, and the server host is ‘local’, the client chooses an IP address for itself, IPclient, which matches up as ‘local’ according to your examination above. If the server host is not ‘local’, then IPclient can be chosen arbitrarily. Print out on stdout the results of your examination, as to whether the server host is ‘local’ or not, as well as the IPclient and IPserver addresses selected. Note that this manner of determining whether the server is local or not is somewhat clumsy and ‘over-engineered’, and, as such, should be viewed more in the nature of a pedagogical exercise. Ideally, we would like to look up the server IP address(es) in the routing table (see Section 18.3). This requires that a routing socket be created, for which we need superuser privilege. Alternatively, we might want to dump out the routing table, using the sysctl function for example (see Section 18.4), and examine it directly. Unfortunately, Solaris 2.10 does not support sysctl. Furthermore, note that there is a slight problem with the address 130.245.1.123/24 assigned to compserv3 (see rightmost column of file hosts, and note that this particular compserv3 address “overlaps” with the 130.245.1.x/28 addresses in that same column assigned to compserv1, compserv2 & comserv4). In particular, if the client is running on compserv3 and the server on any of the other three compservs, and if that server node is also being identified to the client by its /28 (rather than its /24) address, then the client will get a “false positive” when it tests as to whether the server node is local or not. In other words, the client will deem the server node to be local, whereas in fact it should not be considered local. Because of this, it is perhaps best simply not to use compserv3 to run the client (but it is o.k. to use it to run the server). Finally, using MSG_DONTROUTE where possible would seem to gain us efficiency, in as much as the kernel does not need to consult the routing table for every datagram sent. But, in fact, that is not so. Recall that one effect of connect with UDP sockets is that routing information is obtained by the kernel at the time the connect is issued. That information is cached and used for subsequent sends from the connected socket (see p.255). The client now creates a UDP socket and calls bind on IPclient, with 0 as the port number. This will cause the kernel to bind an ephemeral port to the socket. After the bind, use the getsockname function (Section 4.10) to obtain IPclient and the ephemeral port number that has been assigned to the socket, and print that information out on stdout, with an appropriate message and appropriately formatted. The client connects its socket to IPserver and the well-known port number of the server. After the connect, use the getpeername function (Section 4.10) to obtain IPserver and the well-known port number of the server, and print that information out on stdout, with an appropriate message and appropriately formatted. The client sends a datagram to the server giving the filename for the transfer. This send needs to be backed up by a timeout in case the datagram is lost. Note that the incoming datagram from the client will be delivered to the server at the socket to which the destination IP address that the datagram is carrying has been bound. Thus, the server can obtain that address (it is, of course, IPserver) and thereby achieve what IP_RECVDESTADDR would have given us had it been available. Furthermore, the server process can obtain the IP address (this will, of course, be IPclient) and ephemeral port number of the client through the recvfrom or recvmsg functions. The server forks off a child process to handle the client. The server parent process goes back to the select to listen for new clients. Hereafter, and unless otherwise stated, whenever we refer to the ‘server’, we mean the server child process handling the client’s file transfer, not the server parent process. Typically, the first thing the server child would be expected to do is to close all sockets it ‘inherits’ from its parent. However, this is not the case with us. The server child does indeed close the sockets it inherited, but not the socket on which the client request arrived. It leaves that socket open for now. Call this socket the ‘listening’ socket. The server (child) then checks if the client host is local to its (extended) Ethernet. If so, all its communication to the client is to occur as MSG_DONTROUTE (or SO_DONTROUTE socket option). If IPserver (obtained in 5. above) is the loopback address, then we are done. Otherwise, the server has to proceed with the following step. Use the array of structures you built in 1. above, together with the addresses IPserver and IPclient to determine if the client is ‘local’. Print out on stdout the results of your examination, as to whether the client host is ‘local’ or not. The server (child) creates a UDP socket to handle file transfer to the client. Call this socket the ‘connection’ socket. It binds the socket to IPserver, with port number 0 so that its kernel assigns an ephemeral port. After the bind, use the getsockname function (Section 4.10) to obtain IPserver and the ephemeral port number that has been assigned to the socket, and print that information out on stdout, with an appropriate message and appropriately formatted. The server then connects this ‘connection’ socket to the client’s IPclient and ephemeral port number. The server now sends the client a datagram, in which it passes it the ephemeral port number of its ‘connection’ socket as the data payload of the datagram. This datagram is sent using the ‘listening’ socket inherited from its parent, otherwise the client (whose socket is connected to the server’s ‘listening’ socket at the latter’s well-known port number) will reject it. This datagram must be backed up by the ARQ mechanism, and retransmitted in the event of loss. Note that if this datagram is indeed lost, the client might well time out and retransmit its original request message (the one carrying the file name). In this event, you must somehow ensure that the parent server does not mistake this retransmitted request for a new client coming in, and spawn off yet another child to handle it. How do you do that? It is potentially more involved than it might seem. I will be discussing this in class, as well as ‘race’ conditions that could potentially arise, depending on how you code the mechanisms I present. When the client receives the datagram carrying the ephemeral port number of the server’s ‘connection’ socket, it reconnects its socket to the server’s ‘connection’ socket, using IPserver and the ephemeral port number received in the datagram (see p.254). It now uses this reconnected socket to send the server an acknowledgment. Note that this implies that, in the event of the server timing out, it should retransmit two copies of its ‘ephemeral port number’ message, one on its ‘listening’ socket and the other on its ‘connection’ socket (why?). When the server receives the acknowledgment, it closes the ‘listening’ socket it inherited from its parent. The server can now commence the file transfer through its ‘connection’ socket. The net effect of all these binds and connects at server and client is that no ‘outsider’ UDP datagram (broadcast, multicast, unicast - fortuitously or maliciously) can now intrude on the communication between server and client. Starting with the first datagram sent out, the client behaves as follows. Whenever a datagram arrives, or an ACK is about to be sent out (or, indeed, the initial datagram to the server giving the filename for the transfer), the client uses some random number generator function random() (initialized by the client.in argument value seed) to decide with probability p (another client.in argument value) if the datagram or ACK should be discarded by way of simulating transmission loss across the network. (I will briefly discuss in class how you do this.) Adding reliability to UDP The mechanisms you are to implement are based on TCP Reno. These include : Reliable data transmission using ARQ sliding-windows, with Fast Retransmit. Flow control via receiver window advertisements. Congestion control that implements : SlowStart Congestion Avoidance (‘Additive-Increase/Multiplicative Decrease’ – AIMD) Fast Recovery (but without the window-inflation aspect of Fast Recovery) Only some, and by no means all, of the details for these are covered below. The rest will be presented in class, especially those concerning flow control and TCP Reno’s congestion control mechanisms in general : Slow Start, Congestion Avoidance, Fast Retransmit and Fast Recovery. Implement a timeout mechanism on the sender (server) side. This is available to you from Stevens, Section 22.5 . Note, however, that you will need to modify the basic driving mechanism of Figure 22.7 appropriately since the situation at the sender side is not a repetitive cycle of send-receive, but rather a straightforward progression of send-send-send-send- . . . . . . . . . . . Also, modify the RTT and RTO mechanisms of Section 22.5 as specified below. I will be discussing the details of these modifications and the reasons for them in class. Modify function rtt_stop (Fig. 22.13) so that it uses integer arithmetic rather than floating point. This will entail your also having to modify some of the variable and function parameter declarations throughout Section 22.5 from float to int, as appropriate. In the unprrt.h header file (Fig. 22.10) set : RTT_RXTMIN to 1000 msec. (1 sec. instead of the current value 3 sec.) RTT_RXTMAX to 3000 msec. (3 sec. instead of the current value 60 sec.) RTT_MAXNREXMT to 12 (instead of the current value 3) In function rtt_timeout (Fig. 22.14), after doubling the RTO in line 86, pass its value through the function rtt_minmax of Fig. 22.11 (somewhat along the lines of what is done in line 77 of rtt_stop, Fig. 22.13). Finally, note that with the modification to integer calculation of the smoothed RTT and its variation, and given the small RTT values you will experience on the cs / sbpub network, these calculations should probably now be done on a millisecond or even microsecond scale (rather than in seconds, as is the case with Stevens’ code). Otherwise, small measured RTTs could show up as 0 on a scale of seconds, yielding a negative result when we subtract the smoothed RTT from the measured RTT (line 72 of rtt_stop, Fig. 22.13). Report the details of your modifications to the code of Section 22.5 in the ReadMe file which you hand in with your code. We need to have a sender sliding window mechanism for the retransmission of lost datagrams; and a receiver sliding window in order to ensure correct sequencing of received file contents, and some measure of flow control. You should implement something based on TCP Reno’s mechanisms, with cumulative acknowledgments, receiver window advertisements, and a congestion control mechanism I will explain in detail in class. For a reference on TCP’s mechanisms generally, see W. Richard Stevens, TCP/IP Illustrated, Volume 1 , especially Sections 20.2 - 20.4 of Chapter 20 , and Sections 21.1 - 21.8 of Chapter 21 . Bear in mind that our sequence numbers should count datagrams, not bytes as in TCP. Remember that the sender and receiver window sizes have to be set according to the argument values in client.in and server.in, respectively. Whenever the sender window becomes full and so ‘locks’, the server should print out a message to that effect on stdout. Similarly, whenever the receiver window ‘locks’, the client should print out a message on stdout. Be aware of the potential for deadlock when the receiver window ‘locks’. This situation is handled by having the receiver process send a duplicate ACK which acts as a window update when its window opens again (see Figure 20.3 and the discussion about it in TCP/IP Illustrated). However, this is not enough, because ACKs are not backed up by a timeout mechanism in the event they are lost. So we will also need to implement a persist timer driving window probes in the sender process (see Sections 22.1 & 22.2 in Chapter 22 of TCP/IP Illustrated). Note that you do not have to worry about the Silly Window Syndrome discussed in Section 22.3 of TCP/IP Illustrated since the receiver process consumes ‘full sized’ 512-byte messages from the receiver buffer (see 3. below). Report on the details of the ARQ mechanism you implemented in the ReadMe file you hand in. Indeed, you should report on all the TCP mechanisms you implemented in the ReadMe file, both the ones discussed here, and the ones I will be discussing in class. Make your datagram payload a fixed 512 bytes, inclusive of the file transfer protocol header (which must, at the very least, carry: the sequence number of the datagram; ACKs; and advertised window notifications). The client reads the file contents in its receive buffer and prints them out on stdout using a separate thread. This thread sits in a repetitive loop till all the file contents have been printed out, doing the following. It samples from an exponential distribution with mean µ milliseconds (read from the client.in file), sleeps for that number of milliseconds; wakes up to read and print all in-order file contents available in the receive buffer at that point; samples again from the exponential distribution; sleeps; and so on. The formula -1 × µ × ln( random( ) ) , where ln is the natural logarithm, yields variates from an exponential distribution with mean µ, based on the uniformly-distributed variates over ( 0 , 1 ) returned by random(). Note that you will need to implement some sort of mutual exclusion/semaphore mechanism on the client side so that the thread that sleeps and wakes up to consume from the receive buffer is not updating the state variables of the buffer at the same time as the main thread reading from the socket and depositing into the buffer is doing the same. Furthermore, we need to ensure that the main thread does not effectively monopolize the semaphore (and thus lock out for prolonged periods of time) the sleeping thread when the latter wakes up. See the textbook, Section 26.7, ‘Mutexes: Mutual Exclusion’, pp.697-701. You might also find Section 26.8, ‘Condition Variables’, pp.701-705, useful. You will need to devise some way by which the sender can notify the receiver when it has sent the last datagram of the file transfer, without the receiver mistaking that EOF marker as part of the file contents. (Also, note that the last data segment could be a “short” segment of less than 512 bytes – your client needs to be able to handle this correctly somehow.) When the sender receives an ACK for the last datagram of the transfer, the (child) server terminates. The parent server has to take care of cleaning up zombie children. Note that if we want a clean closing, the client process cannot simply terminate when the receiver ACKs the last datagram. This ACK could be lost, which would leave the (child) server process ‘hanging’, timing out, and retransmitting the last datagram. TCP attempts to deal with this problem by means of the TIME_WAIT state. You should have your receiver process behave similarly, sticking around in something akin to a TIME_WAIT state in case in case it needs to retransmit the ACK. In the ReadMe file you hand in, report on how you dealt with the issues raised here: sender notifying receiver of the last datagram, clean closing, and so on. Output Some of the output required from your program has been described in the section Operation above. I expect you to provide further output – clear, well-structured, well-laid-out, concise but sufficient and helpful – in the client and server windows by means of which we can trace the correct evolution of your TCP’s behaviour in all its intricacies : information (e.g., sequence number) on datagrams and acks sent and dropped, window advertisements, datagram retransmissions (and why : dup acks or RTO); entering/exiting Slow Start and Congestion Avoidance, ssthresh and cwnd values; sender and receiver windows locking/unlocking; etc., etc. . . . . The onus is on you to convince us that the TCP mechanisms you implemented are working correctly. Too many students do not put sufficient thought, creative imagination, time or effort into this. It is not the TA’s nor my responsibility to sit staring at an essentially blank screen, trying to summon up our paranormal psychology skills to figure out if your TCP implementation is really working correctly in all its very intricate aspects, simply because the transferred file seems to be printing o.k. in the client window. Nor is it our responsibility to strain our eyes and our patience wading through a mountain of obscure, ill-structured, hyper-messy, debugging-style output because, for example, your effort-conserving concept of what is ‘suitable’ is to dump your debugging output on us, relevant, irrelevant, and everything in between.
Rastaman4e
NICEHASH PLATFORM TERMS OF USE AND NICEHASH MINING TERMS OF SERVICE PLEASE READ THESE NICEHASH PLATFORM TERMS OF USE AND NICEHASH MINING TERMS OF SERVICE (“Terms”) CAREFULLY BEFORE USING THE THE PLATFORM OR SERVICES DESCRIBED HEREIN. BY SELECTING “I AGREE”, ACCESSING THE PLATFORM, USING NICEHASH MINING SERVICES OR DOWNLOADING OR USING NICEHASH MINING SOFTWARE, YOU ARE ACKNOWLEDGING THAT YOU HAVE READ THESE TERMS, AS AMENDED FROM TIME TO TIME, AND YOU ARE AGREEING TO BE BOUND BY THEM. IF YOU DO NOT AGREE TO THESE TERMS, OR ANY SUBSEQUENT AMENDMENTS, CHANGES OR UPDATES, DO NOT ACCESS THE PLATFORM, USE NICEHASH MINING SERVICES OR USE THE NICEHASH MINING SOFTWARE. GENERAL These Terms apply to users of the NiceHash Platform (“Platform” and NiceHash Mining Services (“Services”) which are provided to you by NICEHASH Ltd, company organized and existing under the laws of the British Virgin Islands, with registered address at Intershore Chambers, Road Town, Tortola, British Virgin Islands, registration number: 2048669, hereinafter referred to as “NiceHash, as well as “we” or “us”. ELIGIBILITY By using the NiceHash platform and NiceHash Mining Services, you represent and warrant that you: are at least Minimum Age and have capacity to form a binding contract; have not previously been suspended or removed from the NiceHash Platform; have full power and authority to enter into this agreement and in doing so will not violate any other agreement to which you are a party; are not not furthering, performing, undertaking, engaging in, aiding, or abetting any unlawful activity through your relationship with us, through your use of NiceHash Platform or use of NiceHash Mining Services; will not use NiceHash Platform or NiceHash Mining Services if any applicable laws in your country prohibit you from doing so in accordance with these Terms. We reserve the right to terminate your access to the NiceHash Platform and Mining Services for any reason and in our sole and absolute discretion. Use of NiceHash Platform and Mining Services is void where prohibited by applicable law. Depending on your country of residence or incorporation or registered office, you may not be able to use all the functions of the NiceHash Platform or services provided therein. It is your responsibility to follow the rules and laws in your country of residence and/or country from which you access the NiceHash Platform. DEFINITIONS NiceHash Platform means a website located on the following web address: www.nicehash.com. NiceHash Mining Services mean all services provided by NiceHash, namely the provision of the NiceHash Platform, NiceHash Hashing power marketplace, NiceHash API, NiceHash OS, NiceHash Mining Software including licence for NiceHash Miner, NiceHash Private Endpoint, NiceHash Account, NiceHash mobile apps, and all other software products, applications and services associated with these products, except for the provision of NiceHash Exchange Services. NiceHash Exchange Service means a service which allows trading of digital assets in the form of digital tokens or cryptographic currency for our users by offering them a trading venue, helping them find a trading counterparty and providing the means for transaction execution. NiceHash Exchange Services are provided by NICEX Ltd and accessible at the NiceHash Platform under NiceHash Exchange Terms of Service. Hashing power marketplace means an infrastructure provided by the NiceHash which enables the Hashing power providers to point their rigs towards NiceHash stratum servers where Hashing power provided by different Hashing power providers is gathered and sold as generic Hashing power to the Hashing power buyers. Hashing power buyer means a legal entity or individual who buys the gathered and generic hashing power on the Hashing power marketplace from undefined Hashing power providers. Hashing power provider means a legal entity or individual who sells his hashing power on the Hashing power marketplace to undefined Hashing power buyers. NiceHash Mining Software means NiceHash Miner and any other software available via the NiceHash Platform. NiceHash Miner means a comprehensive software with graphical user interface and web interface, owned by NiceHash. NiceHash Miner is a process manager software which enables the Hashing power providers to point their rigs towards NiceHash stratum servers and sell their hashing power to the Hashing power buyers. NiceHash Miner also means any and all of its code, compilations, updates, upgrades, modifications, error corrections, patches and bug fixes and similar. NiceHash Miner does not mean third party software compatible with NiceHash Miner (Third Party Plugins and Miners). NiceHash QuickMiner means a software accessible at https://www.nicehash.com/quick-miner which enables Hashing power providers to point their PCs or rigs towards NiceHash stratum servers and sell their hashing power to the Hashing power buyers. NiceHash QuickMiner is intended as a tryout tool. Hashing power rig means all hardware which produces hashing power that represents computation power which is required to calculate the hash function of different type of cryptocurrency. Secondary account is an account managed by third party from which the Account holder deposits funds to his NiceHash Wallet or/and to which the Account holder withdraws funds from his NiceHash Wallet. Stratum is a lightweight mining protocol: https://slushpool.com/help/manual/stratum-protocol. NiceHash Account means an online account available on the NiceHash Platform and created by completing the registration procedure on the NiceHash Platform. Account holder means an individual or legal entity who completes the registration procedure and successfully creates the NiceHash Account. Minimum Age means 18 years old or older, if in order for NiceHash to lawfully provide the Services to you without parental consent (including using your personal data). NiceHash Wallet means a wallet created automatically for the Account holder and provided by the NiceHash Wallet provider. NiceHash does not hold funds on behalf of the Account holder but only transfers Account holder’s requests regarding the NiceHash Wallet transaction to the NiceHash Wallet provider who executes the requested transactions. In this respect NiceHash only processes and performs administrative services related to the payments regarding the NiceHash Mining Services and NiceHash Exchange Services, if applicable. NiceHash Wallet provider is a third party which on the behalf of the Account holder provides and manages the NiceHash Wallet, holds, stores and transfers funds and hosts NiceHash Wallet. For more information about the NiceHash Wallet provider, see the following website: https://www.bitgo.com/. Blockchain network is a distributed database that is used to maintain a continuously growing list of records, called blocks. Force Majeure Event means any governmental or relevant regulatory regulations, acts of God, war, riot, civil commotion, fire, flood, or any disaster or an industrial dispute of workers unrelated to you or NiceHash. Any act, event, omission, happening or non-happening will only be considered Force Majeure if it is not attributable to the wilful act, neglect or failure to take reasonable precautions of the affected party, its agents, employees, consultants, contractors and sub-contractors. SALE AND PURCHASE OF HASHING POWER Hashing power providers agree to sell and NiceHash agrees to proceed Hashing power buyers’ payments for the provided hashing power on the Hashing power marketplace, on the Terms set forth herein. According to the applicable principle get-paid-per-valid-share (pay as you go principle) Hashing power providers will be paid only for validated and accepted hashing power to their NiceHash Wallet or other wallet, as indicated in Account holder’s profile settings or in stratum connection username. In some cases, no Hashing power is sent to Hashing power buyers or is accepted by NiceHash Services, even if Hashing power is generated on the Hashing power rigs. These cases include usage of slower hardware as well as software, hardware or network errors. In these cases, Hashing power providers are not paid for such Hashing power. Hashing power buyers agree to purchase and NiceHash agrees to process the order and forward the purchased hashing power on the Hashing power marketplace, on the Terms set forth herein. According to the applicable principle pay-per-valid-share (pay as you go principle) Hashing power buyers will pay from their NiceHash Wallet only for the hashing power that was validated by our engine. When connection to the mining pool which is selected on the Hashing power order is lost or when an order is cancelled during its lifetime, Hashing power buyer pays for additional 10 seconds worth of hashing power. Hashing power order is charged for extra hashing power when mining pool which is selected on the Hashing power order, generates rapid mining work changes and/or rapid mining job switching. All payments including any fees will be processed in crypto currency and NiceHash does not provide an option to sale and purchase of the hashing power in fiat currency. RISK DISCLOSURE If you choose to use NiceHash Platform, Services and NiceHash Wallet, it is important that you remain aware of the risks involved, that you have adequate technical resources and knowledge to bear such risks and that you monitor your transactions carefully. General risk You understand that NiceHash Platform and Services, blockchain technology, Bitcoin, all other cryptocurrencies and cryptotokens, proof of work concept and other associated and related technologies are new and untested and outside of NiceHash’s control. You acknowledge that there are major risks associated with these technologies. In addition to the risks disclosed below, there are risks that NiceHash cannot foresee and it is unreasonable to believe that such risk could have been foreseeable. The performance of NiceHash’s obligation under these Terms will terminate if market or technology circumstances change to such an extent that (i) these Terms clearly no longer comply with NiceHash’s expectations, (ii) it would be unjust to enforce NiceHash’s obligations in the general opinion or (iii) NiceHash’s obligation becomes impossible. NiceHash Account abuse You acknowledge that there is risk associated with the NiceHash Account abuse and that you have been fully informed and warned about it. The funds stored in the NiceHash Wallet may be disposed by third party in case the third party obtains the Account holder’s login credentials. The Account holder shall protect his login credentials and his electronic devices where the login credentials are stored against unauthorized access. Regulatory risks You acknowledge that there is risk associated with future legislation which may restrict, limit or prohibit certain aspects of blockchain technology which may also result in restriction, limitation or prohibition of NiceHash Services and that you have been fully informed and warned about it. Risk of hacking You acknowledge that there is risk associated with hacking NiceHash Services and NiceHash Wallet and that you have been fully informed and warned about it. Hacker or other groups or organizations may attempt to interfere with NiceHash Services or NiceHash Wallet in any way, including without limitation denial of services attacks, Sybil attacks, spoofing, smurfing, malware attacks, mining attacks or consensus-based attacks. Cryptocurrency risk You acknowledge that there is risk associated with the cryptocurrencies which are used as payment method and that you have been fully informed and warned about it. Cryptocurrencies are prone to, but not limited to, value volatility, transaction costs and times uncertainty, lack of liquidity, availability, regulatory restrictions, policy changes and security risks. NiceHash Wallet risk You acknowledge that there is risk associated with funds held on the NiceHash Wallet and that you have been fully informed and warned about it. You acknowledge that NiceHash Wallet is provided by NiceHash Wallet provider and not NiceHash. You acknowledge and agree that NiceHash shall not be responsible for any NiceHash Wallet provider’s services, including their accuracy, completeness, timeliness, validity, copyright compliance, legality, decency, quality or any other aspect thereof. NiceHash does not assume and shall not have any liability or responsibility to you or any other person or entity for any Hash Wallet provider’s services. Hash Wallet provider’s services and links thereto are provided solely as a convenience to you and you access and use them entirely at your own risk and subject to NiceHash Wallet provider’s terms and conditions. Since the NiceHash Wallet is a cryptocurrency wallet all funds held on it are entirely uninsured in contrast to the funds held on the bank account or other financial institutions which are insured. Connection risk You acknowledge that there are risks associated with usage of NiceHash Services which are provided through the internet including, but not limited to, the failure of hardware, software, configuration and internet connections and that you have been fully informed and warned about it. You acknowledge that NiceHash will not be responsible for any configuration, connection or communication failures, disruptions, errors, distortions or delays you may experience when using NiceHash Services, however caused. Hashing power provision risk You acknowledge that there are risks associated with the provisions of the hashing power which is provided by the Hashing power providers through the Hashing power marketplace and that you have been fully informed and warned about it. You acknowledge that NiceHash does not provide the hashing power but only provides the Hashing power marketplace as a service. Hashing power providers’ Hashing power rigs are new and untested and outside of NiceHash’s control. There is a major risk that the Hashing power rigs (i) will stop providing hashing power, (ii) will provide hashing power in an unstable way, (iii) will be wrongly configured or (iv) provide insufficient speed of the hashing power. Hashing power rigs as hardware could be subject of damage, errors, electricity outage, misconfiguration, connection or communication failures and other malfunctions. NiceHash will not be responsible for operation of Hashing power rigs and its provision of hashing power. By submitting a Hashing power order you agree to Hashing power no-refund policy – all shares forwarded to mining pool, selected on the Hashing power order are final and non-refundable. Hashing power profitability risk You acknowledge that there is risk associated with the profitability of the hashing power provision and that you have been fully informed and warned about it. You acknowledge that all Hashing power rig’s earning estimates and profitability calculations on NiceHash Platform are only for informational purposes and were made based on the Hashing power rigs set up in the test environments. NiceHash does not warrant that your Hashing power rigs would achieve the same profitability or earnings as calculated on NiceHash Platform. There is risk that your Hashing power rig would not produce desired hashing power quantity and quality and that your produced hashing power would differentiate from the hashing power produced by our Hashing power rigs set up in the test environments. There is risk that your Hashing power rigs would not be as profitable as our Hashing power rigs set up in the test environments or would not be profitable at all. WARRANTIES NiceHash Platform and Mining Services are provided on the “AS IS” and “AS AVAILABLE” basis, including all faults and defects. To the maximum extent permitted by applicable law, NiceHash makes no representations and warranties and you waive all warranties of any kind. Particularly, without limiting the generality of the foregoing, the NiceHash makes no representations and warranties, whether express, implied, statutory or otherwise regarding NiceHash Platform and Mining Services or other services related to NiceHash Platform and provided by third parties, including any warranty that such services will be uninterrupted, harmless, secure or not corrupt or damaged, meet your requirements, achieve any intended results, be compatible or work with any other software, applications, systems or services, meet any performance or error free or that any errors or defects can or will be corrected. Additionally NiceHash makes no representations and warranties, whether express, implied, statutory or otherwise of merchantability, suitability, reliability, availability, timeliness, accuracy, satisfactory quality, fitness for a particular purpose or quality, title and non-infringement with respect to any of the Mining Services or other services related to NiceHash Platform and provided by third parties, or quiet enjoyment and any warranties arising out of any course of dealing, course of performance, trade practice or usage of NiceHash Platform and Mining Services including information, content and material contained therein. Especially NiceHash makes no representations and warranties, whether express, implied, statutory or otherwise regarding any payment services and systems, NiceHash Wallet which is provided by third party or any other financial services which might be related to the NiceHash Platform and Mining Services. You acknowledge that you do not rely on and have not been induced to accept the NiceHash Platform and Mining Services according to these Terms on the basis of any warranties, representations, covenants, undertakings or any other statement whatsoever, other than expressly set out in these Terms that neither the NiceHash nor any of its respective agents, officers, employees or advisers have given any such warranties, representations, covenants, undertakings or other statements. LIABILITY NiceHash and their respective officers, employees or agents will not be liable to you or anyone else, to the maximum extent permitted by applicable law, for any damages of any kind, including, but not limited to, direct, consequential, incidental, special or indirect damages (including but not limited to lost profits, trading losses or damages that result from use or loss of use of NiceHash Services or NiceHash Wallet), even if NiceHash has been advised of the possibility of such damages or losses, including, without limitation, from the use or attempted use of NiceHash Platform and Mining Services, NiceHash Wallet or other related websites or services. NiceHash does not assume any obligations to users in connection with the unlawful alienation of Bitcoins, which occurred on 6. 12. 2017 with NICEHASH, d. o. o., and has been fully reimbursed with the completion of the NiceHash Repayment Program. NiceHash will not be responsible for any compensation, reimbursement, or damages arising in connection with: (i) your inability to use the NiceHash Platform and Mining Services, including without limitation as a result of any termination or suspension of the NiceHash Platform or these Terms, power outages, maintenance, defects, system failures, mistakes, omissions, errors, defects, viruses, delays in operation or transmission or any failure of performance, (ii) the cost of procurement of substitute goods or services, (iii) any your investments, expenditures, or commitments in connection with these Terms or your use of or access to the NiceHash Platform and Mining Services, (iv) your reliance on any information obtained from NiceHash, (v) Force Majeure Event, communications failure, theft or other interruptions or (vi) any unauthorized access, alteration, deletion, destruction, damage, loss or failure to store any data, including records, private key or other credentials, associated with NiceHash Platform and Mining Services or NiceHash Wallet. Our aggregate liability (including our directors, members, employees and agents), whether in contract, warranty, tort (including negligence, whether active, passive or imputed), product liability, strict liability or other theory, arising out of or relating to the use of NiceHash Platform and Mining Services, or inability to use the Platform and Services under these Terms or under any other document or agreement executed and delivered in connection herewith or contemplated hereby, shall in any event not exceed 100 EUR per user. You will defend, indemnify, and hold NiceHash harmless and all respective employees, officers, directors, and representatives from and against any claims, demand, action, damages, loss, liabilities, costs and expenses (including reasonable attorney fees) arising out of or relating to (i) any third-party claim concerning these Terms, (ii) your use of, or conduct in connection with, NiceHash Platform and Mining Services, (iii) any feedback you provide, (iv) your violation of these Terms, (v) or your violation of any rights of any other person or entity. If you are obligated to indemnify us, we will have the right, in our sole discretion, to control any action or proceeding (at our expense) and determine whether we wish to settle it. If we are obligated to respond to a third-party subpoena or other compulsory legal order or process described above, you will also reimburse us for reasonable attorney fees, as well as our employees’ and contractors’ time and materials spent responding to the third-party subpoena or other compulsory legal order or process at reasonable hourly rates. The Services and the information, products, and services included in or available through the NiceHash Platform may include inaccuracies or typographical errors. Changes are periodically added to the information herein. Improvements or changes on the NiceHash Platform can be made at any time. NICEHASH ACCOUNT The registration of the NiceHash Account is made through the NiceHash Platform, where you are required to enter your email address and password in the registration form. After successful completion of registration, the confirmation email is sent to you. After you confirm your registration by clicking on the link in the confirmation email the NiceHash Account is created. NiceHash will send you proof of completed registration once the process is completed. When you create NiceHash Account, you agree to (i) create a strong password that you change frequently and do not use for any other website, (ii) implement reasonable and appropriate measures designed to secure access to any device which has access to your email address associated with your NiceHash Account and your username and password for your NiceHash Account, (iii) maintain the security of your NiceHash Account by protecting your password and by restricting access to your NiceHash Account; (iv) promptly notify us if you discover or otherwise suspect any security breaches related to your NiceHash Account so we can take all required and possible measures to secure your NiceHash Account and (v) take responsibility for all activities that occur under your NiceHash Account and accept all risks of any authorized or unauthorized access to your NiceHash Account, to the maximum extent permitted by law. Losing access to your email, registered at NiceHash Platform, may also mean losing access to your NiceHash Account. You may not be able to use the NiceHash Platform or Mining Services, execute withdrawals and other security sensitive operations until you regain access to your email address, registered at NiceHash Platform. If you wish to change the email address linked to your NiceHash Account, we may ask you to complete a KYC procedure for security purposes. This step serves solely for the purpose of identification in the process of regaining access to your NiceHash Account. Once the NiceHash Account is created a NiceHash Wallet is automatically created for the NiceHash Account when the request for the first deposit to the NiceHash Wallet is made by the user. Account holder’s NiceHash Wallet is generated by NiceHash Wallet provider. Account holder is strongly suggested to enhance the security of his NiceHash Account by adding an additional security step of Two-factor authentication (hereinafter “2FA”) when logging into his account, withdrawing funds from his NiceHash Wallet or placing a new order. Account holder can enable this security feature in the settings of his NiceHash Account. In the event of losing or changing 2FA code, we may ask the Account holder to complete a KYC procedure for security reasons. This step serves solely for the purpose of identification in the process of reactivating Account holders 2FA and it may be subject to an a In order to use certain functionalities of the NiceHash Platform, such as paying for the acquired hashing power, users must deposit funds to the NiceHash Wallet, as the payments for the hashing power could be made only through NiceHash Wallet. Hashing power providers have two options to get paid for the provided hashing power: (i) by using NiceHash Wallet to receive the payments or (ii) by providing other Bitcoin address where the payments shall be received to. Hashing power providers provide their Bitcoin address to NiceHash by providing such details via Account holder’s profile settings or in a form of a stratum username while connecting to NiceHash stratum servers. Account holder may load funds on his NiceHash Wallet from his Secondary account. Account holder may be charged fees by the Secondary account provider or by the blockchain network for such transaction. NiceHash is not responsible for any fees charged by Secondary account providers or by the blockchain network or for the management and security of the Secondary accounts. Account holder is solely responsible for his use of Secondary accounts and Account holder agrees to comply with all terms and conditions applicable to any Secondary accounts. The timing associated with a load transaction will depend in part upon the performance of Secondary accounts providers, the performance of blockchain network and performance of the NiceHash Wallet provider. NiceHash makes no guarantee regarding the amount of time it may take to load funds on to NiceHash Wallet. NiceHash Wallet shall not be used by Account holders to keep, save and hold funds for longer period and also not for executing other transactions which are not related to the transactions regarding the NiceHash Platform. The NiceHash Wallet shall be used exclusively and only for current and ongoing transactions regarding the NiceHash Platform. Account holders shall promptly withdraw any funds kept on the NiceHash Wallet that will not be used and are not intended for the reasons described earlier. Commission fees may be charged by the NiceHash Wallet provider, by the blockchain network or by NiceHash for any NiceHash Wallet transactions. Please refer to the NiceHash Platform, for more information about the commission fees for NiceHash Wallet transactions which are applicable at the time of the transaction. NiceHash reserves the right to change these commission fees according to the provisions to change these Terms at any time for any reason. You have the right to use the NiceHash Account only in compliance with these Terms and other commercial terms and principles published on the NiceHash Platform. In particular, you must observe all regulations aimed at ensuring the security of funds and financial transactions. Provided that the balance of funds in your NiceHash Wallet is greater than any minimum balance requirements needed to satisfy any of your open orders, you may withdraw from your NiceHash Wallet any amount of funds, up to the total amount of funds in your NiceHash Wallet in excess of such minimum balance requirements, to Secondary Account, less any applicable withdrawal fees charged by NiceHash or by the blockchain network for such transaction. Withdrawals are not processed instantly and may be grouped with other withdrawal requests. Some withdrawals may require additional verification information which you will have to provide in order to process the withdrawal. It may take up to 24 hours before withdrawal is fully processed and distributed to the Blockchain network. Please refer to the NiceHash Platform for more information about the withdrawal fees and withdrawal processing. NiceHash reserves the right to change these fees according to the provisions to change these Terms at any time for any reason. You have the right to close the NiceHash Account. In case you have funds on your NiceHash Wallet you should withdraw funds from your account prior to requesting NiceHash Account closure. After we receive your NiceHash Account closure request we will deactivate your NiceHash Account. You can read more about closing the NiceHash Account in our Privacy Policy. Your NiceHash Account may be deactivated due to your inactivity. Your NiceHash account may be locked and a mandatory KYC procedure is applied for security reasons, if it has been more than 6 month since your last login. NiceHash or any of its partners or affiliates are not responsible for the loss of the funds, stored on or transferred from the NiceHash Wallet, as well as for the erroneous implementation of the transactions made via NiceHash Wallet, where such loss or faulty implementation of the transaction are the result of a malfunction of the NiceHash Wallet and the malfunction was caused by you or the NiceHash Wallet provider. You are obliged to inform NiceHash in case of loss or theft, as well as in the case of any possible misuse of the access data to your NiceHash Account, without any delay, and demand change of access data or closure of your existing NiceHash Account and submit a request for new access data. NiceHash will execute the change of access data or closure of the NiceHash Account and the opening of new NiceHash Account as soon as technically possible and without any undue delay. All information pertaining to registration, including a registration form, generation of NiceHash Wallet and detailed instructions on the use of the NiceHash Account and NiceHash Wallet are available at NiceHash Platform. The registration form as well as the entire system is properly protected from unwanted interference by third parties. KYC PROCEDURE NiceHash is appropriately implementing AML/CTF and security measures to diligently detect and prevent any malicious or unlawful use of NiceHash Services or use, which is strictly prohibited by these Terms, which are deemed as your agreement to provide required personal information for identity verification. Security measures include a KYC procedure, which is aimed at determining the identity of an individual user or an organisation. We may ask you to complete this procedure before enabling some or all functionalities of the NiceHash platform and provide its services. A KYC procedure might be applied as a security measure when: changing the email address linked to your NiceHash Account, losing or changing your 2FA code; logging in to your NiceHash Account for the first time after the launch of the new NiceHash Platform in August 2019, gaining access to all or a portion of NiceHash Services, NiceHash Wallet and its related services or any portion thereof if they were disabled due to and activating your NiceHash Account if it has been deactivated due to its inactivity and/or security or other reasons. HASHING POWER TRANSACTIONS General NiceHash may, at any time and in our sole discretion, (i) refuse any order submitted or provided hashing power, (ii) cancel an order or part of the order before it is executed, (iii) impose limits on the order amount permitted or on provided hashing power or (iv) impose any other conditions or restrictions upon your use of the NiceHash Platform and Mining Services without prior notice. For example, but not limited to, NiceHash may limit the number of open orders that you may establish or limit the type of supported Hashing power rigs and mining algorithms or NiceHash may restrict submitting orders or providing hashing power from certain locations. Please refer to the NiceHash Platform, for more information about terminology, hashing power transactions’ definitions and descriptions, order types, order submission, order procedure, order rules and other restrictions and limitations of the hashing power transactions. NiceHash reserves the right to change any transaction, definitions, description, order types, procedure, rules, restrictions and limitations at any time for any reason. Orders, provision of hashing power, payments, deposits, withdrawals and other transactions are accepted only through the interface of the NiceHash Platform, NiceHash API and NiceHash Account and are fixed by the software and hardware tools of the NiceHash Platform. If you do not understand the meaning of any transaction option, NiceHash strongly encourages you not to utilize any of those options. Hashing Power Order In order to submit an Hashing Power Order via the NiceHash Account, the Hashing power buyer must have available funds in his NiceHash Wallet. Hashing power buyer submits a new order to buy hashing power via the NiceHash Platform or via the NiceHash API by setting the following parameters in the order form: NiceHash service server location, third-party mining pool, algorithm to use, order type, set amount he is willing to spend on this order, set price per hash he is willing to pay, optionally approximate limit maximum hashing power for his order and other parameters as requested and by confirming his order. Hashing power buyer may submit an order in maximum amount of funds available on his NiceHash Wallet at the time of order submission. Order run time is only approximate since order’s lifetime is based on the number of hashes that it delivers. Particularly during periods of high volume, illiquidity, fast movement or volatility in the marketplace for any digital assets or hashing power, the actual price per hash at which some of the orders are executed may be different from the prevailing price indicated on NiceHash Platform at the time of your order. You understand that NiceHash is not liable for any such price fluctuations. In the event of market disruption, NiceHash Services disruption, NiceHash Hashing Power Marketplace disruption or manipulation or Force Majeure Event, NiceHash may do one or more of the following: (i) suspend access to the NiceHash Account or NiceHash Platform, or (ii) prevent you from completing any actions in the NiceHash Account, including closing any open orders. Following any such event, when trading resumes, you acknowledge that prevailing market prices may differ significantly from the prices available prior to such event. When Hashing power buyer submits an order for purchasing of the Hashing power via NiceHash Platform or via the NiceHash API he authorizes NiceHash to execute the order on his behalf and for his account in accordance with such order. Hashing power buyer acknowledges and agrees that NiceHash is not acting as his broker, intermediary, agent or advisor or in any fiduciary capacity. NiceHash executes the order in set order amount minus NiceHash’s processing fee. Once the order is successfully submitted the order amount starts to decrease in real time according to the payments for the provided hashing power. Hashing power buyer agrees to pay applicable processing fee to NiceHash for provided services. The NiceHash’s fees are deducted from Hashing power buyer’s NiceHash Wallet once the whole order is exhausted and completed. Please refer to the NiceHash Platform, for more information about the fees which are applicable at the time of provision of services. NiceHash reserves the right to change these fees according to the provisions to change these Terms at any time for any reason. The changed fees will apply only for the NiceHash Services provided after the change of the fees. All orders submitted prior the fee change but not necessary completed prior the fee change will be charged according to the fees applicable at the time of the submission of the order. NiceHash will attempt, on a commercially reasonable basis, to execute the Hashing power buyer’s purchase of the hashing power on the Hashing power marketplace under these Terms according to the best-effort delivery approach. In this respect NiceHash does not guarantee that the hashing power will actually be delivered or verified and does not guarantee any quality of the NiceHash Services. Hashing power buyer may cancel a submitted order during order’s lifetime. If an order has been partially executed, Hashing power buyer may cancel the unexecuted remainder of the order. In this case the NiceHash’s processing fee will apply only for the partially executed order. NiceHash reserves the right to refuse any order cancellation request once the order has been submitted. Selling Hashing Power and the Provision of Hashing Power In order to submit the hashing power to the NiceHash stratum server the Hashing power provider must first point its Hashing power rig to the NiceHash stratum server. Hashing power provider is solely responsible for configuration of his Hashing power rig. The Hashing power provider gets paid by Hashing power buyers for all validated and accepted work that his Hashing power rig has produced. The provided hashing power is validated by NiceHash’s stratum engine and validator. Once the hashing power is validated the Hashing power provider is entitled to receive the payment for his work. NiceHash logs all validated hashing power which was submitted by the Hashing power provider. The Hashing power provider receives the payments of current globally weighted average price on to his NiceHash Wallet or his selected personal Bitcoin address. The payments are made periodically depending on the height of payments. NiceHash reserves the right to hold the payments any time and for any reason by indicating the reason, especially if the payments represent smaller values. Please refer to the NiceHash Platform, for more information about the height of payments for provided hashing power, how the current globally weighted average price is calculated, payment periods, payment conditions and conditions for detention of payments. NiceHash reserves the right to change this payment policy according to the provisions to change these Terms at any time for any reason. All Hashing power rig’s earnings and profitability calculations on NiceHash Platform are only for informational purposes. NiceHash does not warrant that your Hashing power rigs would achieve the same profitability or earnings as calculated on NiceHash Platform. You hereby acknowledge that it is possible that your Hashing power rigs would not be as profitable as indicated in our informational calculations or would not be profitable at all. Hashing power provider agrees to pay applicable processing fee to NiceHash for provided Services. The NiceHash’s fees are deducted from all the payments made to the Hashing power provider for his provided work. Please refer to the NiceHash Platform, for more information about the fees which are applicable at the time of provision of services. Hashing power provider which has not submitted any hashing power to the NiceHash stratum server for a period of 90 days agrees that a processing fee of 0.00001000 BTC or less, depending on the unpaid mining balance, will be deducted from his unpaid mining balance. NiceHash reserves the right to change these fees according to the provisions to change these Terms at any time for any reason. The changed fees will apply only for the NiceHash Services provided after the change of the fees. NiceHash will attempt, on a commercially reasonable basis, to execute the provision of Hashing power providers’ hashing power on the Hashing power marketplace under these Terms according to the best-effort delivery approach. In this respect NiceHash does not guarantee that the hashing power will actually be delivered or verified and does not guarantee any quality of the NiceHash Services. Hashing power provider may disconnect the Hashing power rig from the NiceHash stratum server any time. NiceHash reserves the right to refuse any Hashing power rig once the Hashing power rig has been pointed towards NiceHash stratum server. RESTRICTIONS When accessing the NiceHash Platform or using the Mining Services or NiceHash Wallet, you warrant and agree that you: will not use the Services for any purpose that is unlawful or prohibited by these Terms, will not violate any law, contract, intellectual property or other third-party right or commit a tort, are solely responsible for your conduct while accessing the NiceHash Platform or using the Mining Services or NiceHash Wallet, will not access the NiceHash Platform or use the Mining Services in any manner that could damage, disable, overburden, or impair the provision of the Services or interfere with any other party's use and enjoyment of the Services, will not misuse and/or maliciously use Hashing power rigs, you will particularly refrain from using network botnets or using NiceHash Platform or Mining Services with Hashing power rigs without the knowledge or awareness of Hashing power rig owner(s), will not perform or attempt to perform any kind of malicious attacks on blockchains with the use of the NiceHash Platform or Mining Services, intended to maliciously gain control of more than 50% of the network's mining hash rate, will not use the NiceHash Platform or Mining Services for any kind of market manipulation or disruption, such as but not limited to NiceHash Mining Services disruption and NiceHash Hashing Power Marketplace manipulation. In case of any of the above mentioned events, NiceHash reserves the right to immediately suspend your NiceHash Account, freeze or block the funds in the NiceHash Wallet, and suspend your access to NiceHash Platform, particularly if NiceHash believes that such NiceHash Account are in violation of these Terms or Privacy Policy, or any applicable laws and regulation. RIGHTS AND OBLIGATIONS In the event of disputes with you, NiceHash is obliged to prove that the NiceHash service which is the subject of the dispute was not influenced by technical or other failure. You will have possibility to check at any time, subject to technical availability, the transactions details, statistics and available balance of the funds held on the NiceHash Wallet, through access to the NiceHash Account. You may not obtain or attempt to obtain any materials or information through any means not intentionally made available or provided to you or public through the NiceHash Platform or Mining Services. We may, in our sole discretion, at any time, for any or no reason and without liability to you, with prior notice (i) terminate all rights and obligations between you and NiceHash derived from these Terms, (ii) suspend your access to all or a portion of NiceHash Services, NiceHash Wallet and its related services or any portion thereof and delete or deactivate your NiceHash Account and all related information and files in such account (iii) modify, suspend or discontinue, temporarily or permanently, any portion of NiceHash Platform or (iv) provide enhancements or improvements to the features and functionality of the NiceHash Platform, which may include patches, bug fixes, updates, upgrades and other modifications. Any such change may modify or delete certain portion, features or functionalities of the NiceHash Services. You agree that NiceHash has no obligation to (i) provide any updates, or (ii) continue to provide or enable any particular portion, features or functionalities of the NiceHash Services to you. You further agree that all changes will be (i) deemed to constitute an integral part of the NiceHash Platform, and (ii) subject to these Terms. In the event of your breach of these Terms, including but not limited to, for instance, in the event that you breach any term of these Terms, due to legal grounds originating in anti-money laundering and know your client regulation and procedures, or any other relevant applicable regulation, all right and obligations between you and NiceHash derived from these Terms terminate automatically if you fail to comply with these Terms within the notice period of 8 days after you have been warned by NiceHash about the breach and given 8 days period to cure the breaches. NiceHash reserves the right to keep these rights and obligations in force despite your breach of these Terms. In the event of termination, NiceHash will attempt to return you any funds stored on your NiceHash Wallet not otherwise owed to NiceHash, unless NiceHash believes you have committed fraud, negligence or other misconduct. You acknowledge that the NiceHash Services and NiceHash Wallet may be suspended for maintenance. Technical information about the hashing power transactions, including information about chosen server locations, algorithms used, selected mining pools, your business or activities, including all financial and technical information, specifications, technology together with all details of prices, current transaction performance and future business strategy represent confidential information and trade secrets. NiceHash shall, preserve the confidentiality of all before mentioned information and shall not disclose or cause or permit to be disclosed without your permission any of these information to any person save to the extent that such disclosure is strictly to enable you to perform or comply with any of your obligations under these Terms, or to the extent that there is an irresistible legal requirement on you or NiceHash to do so; or where the information has come into the public domain otherwise than through a breach of any of the terms of these Terms. NiceHash shall not be entitled to make use of any of these confidential information and trade secrets other than during the continuance of and pursuant to these Terms and then only for the purpose of carrying out its obligations pursuant to these Terms. NICEHASH MINER LICENSE (NICEHASH MINING SOFTWARE LICENSE) NiceHash Mining Software whether on disk, in read only memory, or any other media or in any other form is licensed, not sold, to you by NiceHash for use only under these Terms. NiceHash retains ownership of the NiceHash Mining Software itself and reserves all rights not expressly granted to you. Subject to these Terms, you are granted a limited, non-transferable, non-exclusive and a revocable license to download, install and use the NiceHash Mining Software. You may not distribute or make the NiceHash Mining Software available over a network where it could be used by multiple devices at the same time. You may not rent, lease, lend, sell, redistribute, assign, sublicense host, outsource, disclose or otherwise commercially exploit the NiceHash Mining Software or make it available to any third party. There is no license fee for the NiceHash Mining Software. NiceHash reserves the right to change the license fee policy according to the provisions to change these Terms any time and for any reason, including to decide to start charging the license fee for the NiceHash Mining Software. You are responsible for any and all applicable taxes. You may not, and you agree not to or enable others to, copy, decompile, reverse engineer, reverse compile, disassemble, attempt to derive the source code of, decrypt, modify, or create derivative works of the NiceHash Mining Software or any services provided by the NiceHash Mining Software, or any part thereof (except as and only to the extent any foregoing restriction is prohibited by applicable law or to the extent as may be permitted by the licensing terms governing use of open-sourced components included with the NiceHash Mining Software). If you choose to allow automatic updates, your device will periodically check with NiceHash for updates and upgrades to the NiceHash Mining Software and, if an update or upgrade is available, the update or upgrade will automatically download and install onto your device and, if applicable, your peripheral devices. You can turn off the automatic updates altogether at any time by changing the automatic updates settings found within the NiceHash Mining Software. You agree that NiceHash may collect and use technical and related information, including but not limited to technical information about your computer, system and application software, and peripherals, that is gathered periodically to facilitate the provision of software updates, product support and other services to you (if any) related to the NiceHash Mining Software and to verify compliance with these Terms. NiceHash may use this information, as long as it is in a form that does not personally identify you, to improve our NiceHash Services. NiceHash Mining Software contains features that rely upon information about your selected mining pools. You agree to our transmission, collection, maintenance, processing, and use of all information obtained from you about your selected mining pools. You can opt out at any time by going to settings in the NiceHash Mining Software. NiceHash may provide interest-based advertising to you. If you do not want to receive relevant ads in the NiceHash Mining Software, you can opt out at any time by going to settings in the NiceHash Mining Software. If you opt out, you will continue to receive the same number of ads, but they may be less relevant because they will not be based on your interest. NiceHash Mining Software license is effective until terminated. All provisions of these Terms regarding the termination apply also for the NiceHash Mining Software license. Upon the termination of NiceHash Mining Software license, you shall cease all use of the NiceHash Mining Software and destroy or delete all copies, full or partial, of the NiceHash Mining Software. THIRD PARTY MINERS AND PLUGINS Third Party Miners and Plugins are a third party software which enables the best and most efficient mining operations. NiceHash Miner integrates third party mining software using a third party miner plugin system. Third Party Mining Software is a closed source software which supports mining algorithms for cryptocurrencies and can be integrated into NiceHash Mining Software. Third Party Miner Plugin enables the connection between NiceHash Mining Software and Third Party Mining Software and it can be closed, as well as open sourced. NiceHash Mining Software user interface enables the user to manually select which available Third Party Miners and Plugins will be downloaded and integrated. Users can select or deselect Third Party Miners and Plugins found in the Plugin Manager window. Some of the available Third Party Miners and Plugins which are most common are preselected by NiceHash, but can be deselected, depending on users' needs. The details of the Third Party Miners and Plugins available for NiceHash Mining Software are accessible within the NiceHash Mining Software user interface. The details include, but not limited to, the author of the software and applicable license information, if applicable information about developer fee for Third Party Miners, software version etc. Developer fees may apply to the use of Third Party Miners and Plugins. NiceHash will not be liable, to the maximum extent permitted by applicable law, for any damages of any kind, including, but not limited to, direct, consequential, incidental, special or indirect damages, arising out of using Third Party Miners and Plugins. The latter includes, but is not limited to: i) any power outages, maintenance, defects, system failures, mistakes, omissions, errors, defects, viruses, delays in operation or transmission or any failure of performance; ii) any unauthorized access, alteration, deletion, destruction, damage, loss or failure to store any data, including records, private key or other credentials, associated with usage of Third Party Miners and Plugins and ii) Force Majeure Event, communications failure, theft or other interruptions. If you choose to allow automatic updates, your device will periodically check with NiceHash for updates and upgrades to the installed Third Party Miners and Plugins, if an update or upgrade is available, the update or upgrade will automatically download and install onto your device and, if applicable, your peripheral devices. You can turn off the automatic updates altogether at any time by changing the automatic updates settings found within the NiceHash Mining Software. NICEHASH QUICKMINER NiceHash QuickMiner is a software application that allows the visitors of the NiceHash Quick Miner web page, accessible athttps://www.nicehash.com/quick-miner, to connect their PC or a mining rig to the NiceHash Hashing Power Marketplace. Visitors of the NiceHash Quick Miner web page can try out and experience crypto currency mining without having to register on the NiceHash Platform and create a NiceHash Account. Users are encouraged to do so as soon as possible in order to collect the funds earned using NiceHash Quick Miner. Users can download NiceHash QuickMiner free of charge. In order to operate NiceHash QuickMiner software needs to automatically detect technical information about users' computer hardware. You agree that NiceHash may collect and use technical and related information. For more information please refer to NiceHash Privacy Policy. Funds arising from the usage of NiceHash QuickMiner are transferred to a dedicated cryptocurrency wallet owned and managed by NiceHash. NiceHash QuickMiner Users expressly agree and acknowledge that completing the registration process and creating a NiceHash Account is necessary in order to collect the funds arising from the usage of NiceHash QuickMiner. Users of NiceHash QuickMiner who do not successfully register a NiceHash Account will lose their right to claim funds arising from their usage of NiceHash QuickMiner. Those funds, in addition to the condition that the user has not been active on the NiceHash QuickMiner web page for consecutive 7 days, will be donated to the charity of choice. NICEHASH PRIVATE ENDPOINT NiceHash Private Endpoint is a network interface that connects users privately and securely to NiceHash Stratum servers. Private Endpoint uses a private IP address and avoids additional latency caused by DDOS protection. All NiceHash Private Mining Proxy servers are managed by NiceHash and kept up-to-date. Users can request a dedicated private access endpoint by filling in the form for NiceHash Private Endpoint Solution available at the NiceHash Platform. In the form the user specifies the email address, country, number of connections and locations and algorithms used. Based on the request NiceHash prepares an individualized offer based on the pricing stipulated on the NiceHash Platform, available at https://www.nicehash.com/private-endpoint-solution. NiceHash may request additional information from the users of the Private Endpoint Solution in order to determine whether we are obligated to collect VAT from you, including your VAT identification number. INTELLECTUAL PROPERTY NiceHash retains all copyright and other intellectual property rights, including inventions, discoveries, knowhow, processes, marks, methods, compositions, formulae, techniques, information and data, whether or not patentable, copyrightable or protectable in trademark, and any trademarks, copyrights or patents based thereon over all content and other materials contained on NiceHash Platform or provided in connection with the Services, including, without limitation, the NiceHash logo and all designs, text, graphics, pictures, information, data, software, source code, as well as the compilation thereof, sound files, other files and the selection and arrangement thereof. This material is protected by international copyright laws and other intellectual property right laws, namely trademark. These Terms shall not be understood and interpreted in a way that they would mean assignment of copyright or other intellectual property rights, unless it is explicitly defined so in these Terms. NiceHash hereby grants you a limited, nonexclusive and non-sublicensable license to access and use NiceHash’s copyrighted work and other intellectual property for your personal or internal business use. Such license is subject to these Terms and does not permit any resale, the distribution, public performance or public display, modifying or otherwise making any derivative uses, use, publishing, transmission, reverse engineering, participation in the transfer or sale, or any way exploit any of the copyrighted work and other intellectual property other than for their intended purposes. This granted license will automatically terminate if NiceHash suspends or terminates your access to the Services, NiceHash Wallet or closes your NiceHash Account. NiceHash will own exclusive rights, including all intellectual property rights, to any feedback including, but not limited to, suggestions, ideas or other information or materials regarding NiceHash Services or related products that you provide, whether by email, posting through our NiceHash Platform, NiceHash Account or otherwise and you irrevocably assign any and all intellectual property rights on such feedback unlimited in time, scope and territory. Any Feedback you submit is non-confidential and shall become the sole property of NiceHash. NiceHash will be entitled to the unrestricted use, modification or dissemination of such feedback for any purpose, commercial or otherwise, without acknowledgment or compensation to you. You waive any rights you may have to the feedback. We have the right to remove any posting you make on NiceHash Platform if, in our opinion, your post does not comply with the content standards defined by these Terms. PRIVACY POLICY Please refer to our NiceHash Platform and Mining Services Privacy Policy published on the NiceHash Platform for information about how we collect, use and share your information, as well as what options do you have with regards to your personal information. COMMUNICATION AND SUPPORT You agree and consent to receive electronically all communications, agreements, documents, receipts, notices and disclosures that NiceHash provides in connection with your NiceHash Account or use of the NiceHash Platform and Services. You agree that NiceHash may provide these communications to you by posting them via the NiceHash Account or by emailing them to you at the email address you provide. You should maintain copies of electronic communications by printing a paper copy or saving an electronic copy. It is your responsibility to keep your email address updated in the NiceHash Account so that NiceHash can communicate with you electronically. You understand and agree that if NiceHash sends you an electronic communication but you do not receive it because your email address is incorrect, out of date, blocked by your service provider, or you are otherwise unable to receive electronic communications, it will be deemed that you have been provided with the communication. You can update your NiceHash Account preferences at any time by logging into your NiceHash Account. If your email address becomes invalid such that electronic communications sent to you by NiceHash are returned, NiceHash may deem your account to be inactive and close it. You may give NiceHash a notice under these Terms by sending an email to support@nicehash.com or contact NiceHash through support located on the NiceHash Platform. All communication and notices pursuant to these Terms must be given in English language. FEES Please refer to the NiceHash Platform for more information about the fees or administrative costs which are applicable at the time of provision of services. NiceHash reserves the right to change these fees according to the provisions to change these Terms at any time for any reason. The changed fees will apply only for the Services provided after the change of the fees. You authorize us, or our designated payment processor, to charge or deduct your NiceHash Account for any applicable fees in connection with the transactions completed via the Services. TAX It is your responsibility to determine what, if any, taxes apply to the transactions you complete or services you provide via the NiceHash Platform, Mining Services and NiceHash Wallet, it is your responsibility to report and remit the correct tax to the appropriate tax authority and all your factual and potential tax obligations are your concern. You agree that NiceHash is not in any case and under no conditions responsible for determining whether taxes apply to your transactions or services or for collecting, reporting, withholding or remitting any taxes arising from any transactions or services. You also agree that NiceHash is not in any case and under no conditions bound to compensate for your tax obligation or give you any advice related to tax issues. All fees and charges payable by you to NiceHash are exclusive of any taxes, and shall certain taxes be applicable, they shall be added on top of the payable amounts. Upon our request, you will provide to us any information that we reasonably request to determine whether we are obligated to collect VAT from you, including your VAT identification number. If any deduction or withholding is required by law, you will notify NiceHash and will pay NiceHash any additional amounts necessary to ensure that the net amount received by NiceHash, after any deduction and withholding, equals the amount NiceHash would have received if no deduction or withholding had been required. Additionally, you will provide NiceHash with documentation showing that the withheld and deducted amounts have been paid to the relevant taxing authority. FINAL PROVISIONS Natural persons and legal entities that are not capable of holding legal rights and obligations are not allowed to create NiceHash Account and use NiceHash Platform or other related services. If NiceHash becomes aware that such natural person or legal entity has created the NiceHash Account or has used NiceHash Services, NiceHash will delete such NiceHash Account and disable any Services and block access to NiceHash Account and NiceHash Services to such natural person or legal entity. If you register to use the NiceHash Services on behalf of a legal entity, you represent and warrant that (i) such legal entity is duly organized and validly existing under the applicable laws of the jurisdiction of its organization; and (ii) you are duly authorized by such legal entity to act on its behalf. These Terms do not create any third-party beneficiary rights in any individual or entity. These Terms forms the entire agreement and understanding relating to the subject matter hereof and supersede any previous and contemporaneous agreements, arrangements or understandings relating to the subject matter hereof to the exclusion of any terms implied by law that may be excluded by contract. If at any time any provision of these Terms is or becomes illegal, invalid or unenforceable, the legality, validity and enforceability of every other provisions will not in any way be impaired. Such illegal, invalid or unenforceable provision of these Terms shall be deemed to be modified and replaced by such legal, valid and enforceable provision or arrangement, which corresponds as closely as possible to our and your will and business purpose pursued and reflected in these Terms. Headings of sections are for convenience only and shall not be used to limit or construe such sections. No failure to enforce nor delay in enforcing, on our side to the Terms, any right or legal remedy shall function as a waiver thereof, nor shall any individual or partial exercise of any right or legal remedy prevent any further or other enforcement of these rights or legal remedies or the enforcement of any other rights or legal remedies. NiceHash reserves the right to make changes, amendments, supplementations or modifications from time to time to these Terms including but not limited to changes of licence agreement for NiceHash Mining Software and of any fees and compensations policies, in its sole discretion and for any reason. We suggest that you review these Terms periodically for changes. If we make changes to these Terms, we will provide you with notice of such changes, such as by sending an email, providing notice on the NiceHash Platform, placing a popup window after login to the NiceHash Account or by posting the amended Terms on the NiceHash Platform and updating the date at the top of these Terms. The amended Terms will be deemed effective immediately upon posting for any new users of the NiceHash Services. In all other cases, the amended Terms will become effective for preexisting users upon the earlier of either: (i) the date users click or press a button to accept such changes in their NiceHash Account, or (ii) continued use of NiceHash Services 30 days after NiceHash provides notice of such changes. Any amended Terms will apply prospectively to use of the NiceHash Services after such changes become effective. The notice of change of these Terms is considered as notice of termination of all rights and obligations between you and NiceHash derived from these Terms with notice period of 30 days, if you do not accept the amended Terms. If you do not agree to any amended Terms, (i) the agreement between you and NiceHash is terminated by expiry of 30 days period which starts after NiceHash provides you a notice of change of these Terms, (ii) you must discontinue using NiceHash Services and (iii) you must inform us regarding your disagreement with the changes and request closure of your NiceHash Account. If you do not inform us regarding your disagreement and do not request closure of you NiceHash Account, we will deem that you agree with the changed Terms. You may not assign or transfer your rights or obligations under these Terms without the prior written consent of NiceHash. NiceHash may assign or transfer any or all of its rights under these Terms, in whole or in part, without obtaining your consent or approval. These Terms shall be governed by and construed and enforced in accordance with the Laws of the British Virgin Islands, and shall be interpreted in all respects as a British Virgin Islands contract. Any transaction, dispute, controversy, claim or action arising from or related to your access or use of the NiceHash Platform or these Terms of Service likewise shall be governed by the Laws of the British Virgin Islands, exclusive of choice-of-law principles. The rights and remedies conferred on NiceHash by, or pursuant to, these Terms are cumulative and are in addition, and without prejudice, to all other rights and remedies otherwise available to NiceHash at law. NiceHash may transfer its rights and obligations under these Terms to other entities which include, but are not limited to H-BIT, d.o.o. and NICEX Ltd, or any other firm or business entity that directly or indirectly acquires all or substantially all of the assets or business of NICEHASH Ltd. If you do not consent to any transfer, you may terminate this agreement and close your NiceHash Account. These Terms are not boilerplate. If you disagree with any of them, believe that any should not apply to you, or wish to negotiate these Terms, please contact NiceHash and immediately navigate away from the NiceHash Platform. Do not use the NiceHash Mining Services, NiceHash Wallet or other related services until you and NiceHash have agreed upon new terms of service. Last updated: March 1, 2021
SOYJUN
The aim of this assignment is to have you do TCP socket client / server programming using I/O multiplexing, child processes and threads. It also aims at getting you to familiarize yourselves with the inetd superserver daemon, the ‘exec’ family of functions, various socket error scenarios, some socket options, and some basic domain name / IP address conversion functions. Apart from the material in Chapters 1 to 6 covered in class, you will also need to refer to the following : the exec family of functions (Section 4.7 of Chapter 4) using pipes for interprocess communication (IPC) in Unix error scenarios induced by process terminations & host crashes (Sections 5.11 to 5.16, Chapter 5) setsockopt function & SO_REUSEADDR socket option (Section 7.2 & pp.210-213, Chapter 7) gethostbyname & gethostbyaddr functions (Sections 11.3 & 11.4, Chapter 11) the basic structure of inetd (Section 13.5, Chapter 13) programming with threads (Sections 26.1 to 26.5, Chapter 26) Overview I shall present an overview of this assignment and discuss some of the specification details given below in class on Wednesday, September 17 & Monday, September 22. Client The client is evoked with a command line argument giving either the server IP address in dotted decimal notation, or the server domain name. The client has to be able to handle either mode and figure out which of the two is being passed to it. If it is given the IP address, it calls the gethostbyaddr function to get the domain name, which it then prints out to the user in the form of an appropriate message (e.g., ‘The server host is compserv1.cs.stonybrook.edu’). The function gethostbyname, on the other hand, returns the IP address that corresponds to a given domain name. The client then enters an infinite loop in which it queries the user which service is being requested. There are two options : echo and time (note that time is a slightly modified version of the daytime service – see below). The client then forks off a child. After the child is forked off, the parent process enters a second loop in which it continually reads and prints out status messages received from the child via a half-duplex pipe (see below). The parent exits the second loop when the child closes the pipe (how does the parent detect this?), and/or the SIGCHLD signal is generated when the child terminates. The parent then repeats the outer loop, querying the user again for the (next) service s/he desires. This cycle continues till the user responds to a query with quit rather than echo or time. The child process is the one which handles the actual service for the user. It execs (see Section 4.7, Chapter 4) an xterm to generate a separate window through which all interactions with server and user take place. For example, the following exec function call evokes an xterm, and gets the xterm to execute echocli, located in the current directory, passing the string 127.0.0.1 (assumed to be the IP address of the server) as the command line argument argv[1] to echocli (click on the url for further details) : execlp("xterm", "xterm", "-e", "./echocli", "127.0.0.1", (char *) 0) xterm executes one of two client programs (echocli or timecli, say) depending on the service requested. A client program establishes a TCP connection to the server at the ‘well-known port’ for the service (in reality, this port will, of course, be some ephemeral port of your choosing, the value of which is known to both server and client code). All interaction with the user, on the one hand, and with the server, on the other, takes place through the child’s xterm window, not the parent’s window. On the other hand, the child will use a half-duplex pipe to relay status information to the parent which the parent prints out in its window (see below).To terminate the echo client, the user can type in ^D (CTRL D, the EOF character). To terminate the time client, the only option is for the user to type in ^C (CTRL C). (This can also be used as an alternative means of terminating the echo client.) Note that using ^C in the context of the time service will give the server process the impression that the client process has ‘crashed’. It is your responsibility to ensure that the server process handles this correctly and closes cleanly. I shall address this further when discussing the server process. It is also part of your responsibility in this assignment to ensure that the client code is robust with respect to the server process crashing (see Sections 5.12 & 5.13, Chapter 5). Amongst other implications, this means that it would probably be a good idea for you to implement your echo client code along the lines of either : Figure 6.9, p.168 (or even Figure 6.13, p.174) which uses I/O multiplexing with the select function; or of Figure 26.2, p.680, which uses threads; rather than along the lines of Figure 5.5, p.125. When the child terminates, either normally or abnormally, its xterm window disappears instantaneously. Consequently, any status information that the child might want to communicate to the user should not be printed out on the child’s xterm window, since the user will not have time to see the final such message before the window disappears. Instead, as the parent forks off the child at the beginning, a half-duplex pipe should be established from child to parent. The child uses the pipe to send status reports to the parent, which the parent prints out in its window. I leave it up to you to decide what status information exactly should be relayed to the parent but, at a minimum, the parent should certainly be notified, in as precise terms as possible, of any abnormal termination conditions of the service provided by the child. In general, you should try to make your code as robust as possible with respect to handling errors, including confused behaviour by the user (e.g., passing an invalid command line argument; responding to a query incorrectly; trying to interact with the service through the parent process window, not the child process xterm; etc.). Amongst other things, you have to worry about EINTR errors occurring during slow system calls (such as the parent reading from the pipe, or, possibly, printing to stdout, for example) due to a SIGCHLD signal. What about other kinds of errors? Which ones can occur? How should you handle them? Server The server has to be able to handle multiple clients using threads (specifically, detached threads), not child processes (see Sections 26.1 to 26.4, Chapter 26). Furthermore, it has to be able to handle multiple types of service; in our case, two : echo and time. echo is just the standard echo service we have seen in class. time is a slightly modified version of the daytime service (see Figure 1.9, p.14) : instead of sending the client the ‘daytime’ just once and closing, the service sits in an infinite loop, sending the ‘daytime’, sleeping for 5 seconds, and repeating, ad infinitum. The server is loosely based on the way the inetd daemon works : see Figure 13.7, p.374. However, note that the differences between inetd and our server are probably more significant than the similarities: inetd forks off children, whereas our server uses threads; inetd child processes issue exec commands, which our server threads do not; etc. So you should treat Figure 13.7 (and Section 13.5, Chapter 13, generally) as a source of ideas, not as a set of specifications which you must slavishly adhere to and copy. Note, by the way, that there are some similarities between our client and inetd (primarily, forking off children which issue execs), which could be a useful source of ideas. The server creates a listening socket for each type of service that it handles, bound to the ‘well-known port’ for that service. It then uses select to await clients (Chapter 6; or, if you prefer, poll; note that pselect is not supported in Solaris 2.10). The socket on which a client connects identifies the service the client is seeking. The server accepts the connection and creates a thread which provides the service. The thread detaches itself. Meanwhile, the main thread goes back to the select to await further clients. A major concern when using threads is to make sure that operations are thread safe (see p.685 and on into Section 26.5). In this respect, Stevens’ readline function (in Stevens’ file unpv13e/lib/readline.c, see Figure 3.18, pp.91-92) poses a particular problem. On p.686, the authors give three options for dealing with this. The third option is too inefficient and should be discarded. You can implement the second option if you wish. Easiest of all would be the first option, since it involves using a thread-safe version of readline (see Figures 26.11 & 26.12) provided in file unpv13e/threads/readline.c. Whatever you do, remember that Stevens’ library, libunp.a, contains the non-thread-safe version of Figure 3.18, and that is the version that will be link-loaded to your code unless you undertake explicit steps to ensure this does not happen (libunp.a also contains the ‘wrapper’ function Readline, whose code is also in file unpv13e/lib/readline.c). Remaking your copy of libunp.a with the ‘correct’ version of readline is not a viable option because when you hand in your code, it will be compiled and link-loaded with respect to the version of libunp.a in the course account, ~cse533/Stevens/unpv13e_solaris2.10 (I do not intend to change that version since it risks creating confusion later on in the course). Also, you will probably want to use the original version of readline in the client code anyway. I am providing you with a sample Makefile which picks up the thread-safe version of readline from directory ~cse533/Stevens/unpv13e_solaris2.10/threads and uses it when making the executable for the server, but leaves the other executables it makes to link-load the non-thread-safe version from libunp.a. Again, it is part of your responsibility to make sure that your server code is as robust as possible with respect to errors, and that the server threads terminate cleanly under all circumstances. Recall, first of all, that the client user will often use ^C (CTRL C) in the xterm to terminate the service. This will appear to the server thread as if the client process has crashed. You need to think about the error conditions that will be induced (see Sections 5.11 to 5.13, Chapter 5), and how the echo and time server code is to detect and handle these conditions. For example, the time server will almost certainly experience an EPIPE error (see Section 5.13). How should the associated SIGPIPE signal be handled? Be aware that when we return out of the Stevens’ writen function with -1 (indicating an error) and check errno, errno is sometimes equal to 0, not EPIPE (value 32). This can happen under Solaris 2.10, but I am not sure under precisely what conditions nor why. Nor am I sure if it also happens under other Unix versions, or if it also happens when using write rather than writen. The point is, you cannot depend on errno to find out what has happened to the write or writen functions. My suggestion, therefore, is that the time server should use the select function. On the one hand, select’s timeout mechanism can be used to make the server sleep for the 5 seconds. On the other hand, select should also monitor the connection socket read event because, when the client xterm is ^C’ed, a FIN will be sent to the server TCP, which will prime the socket for reading; a read on the socket will then return with value 0 (see Figure 14.3, p. 385 as an example). But what about errors other than EPIPE? Which ones can occur? How should you handle them? Recall, as well, that if a thread terminates without explicitly closing the connection socket it has been using, the connection socket will remain existent until the server process itself dies (why?). Since the server process is supposed, in principle, to run for ever, you risk ending up with an ever increasing number of unused, ‘orphaned’ sockets unless you are careful. Whenever a server thread detects the termination of its client, it should print out a message giving appropriate details: e.g., “Client termination: EPIPE error detected”, “Client termination: socket read returned with value 0”, “Client termination: socket read returned with value -1, errno = . . .”, and so on. When debugging your server code, you will probably find that restarting the server very shortly after it was last running will give you trouble when it comes to bind to its ‘well-known ports’. This is because, when the server side initiates connection termination (which is what will happen if the server process crashes; or if you kill it first, before killing the client) TCP keeps the connections open in the TIME_WAIT state for 2MSLs (Sections 2.6 & 2.7, Chapter 2). This could very quickly become a major irritant. I suggest you explore the possibility of using the SO_REUSEADDR socket option (pp.210-213, Chapter 7; note that the SO_REUSEPORT socket option is not supported in Solaris 2.10), which should help keep the stress level down. You will need to use the setsockopt function (Section 7.2) to enable this option. Figure 8.24, p.263, shows an instance of server code that sets the SO_REUSEADDR socket option. Finally, you should be aware of the sort of problem, described in Section 16.6, pp.461-463, that might occur when (blocking) listening sockets are monitored using select. Such sockets should be made nonblocking, which requires use of the fcntl function after socket creates the socket, but before listen turns the socket into a listening socket.
Overview For this assignment you will be developing an application that uses raw IP sockets to ‘walk’ around an ordered list of nodes (given as a command line argument at the ‘source’ node, which is the node at which the tour was initiated), in a manner similar to the IP SSRR (Strict Source and Record Route) option. At each node, the application pings the preceding node in the tour. However, unlike the ping code in Stevens, you will be sending the ping ICMP echo request messages through a SOCK_RAW-type PF_PACKET socket and implementing ARP functionality to find the Ethernet address of the target node. Finally, when the ‘walk’ is completed, the group of nodes visited on the tour will exchange multicast messages. Your code will consist of two process modules, a ‘Tour’ application module (which will implement all the functionality outlined above, except for ARP activity) and an ARP module. The following should prove to be useful reference material for the assignment: Sections 21.2, 21.3, 21.6 and 21.10, Chapter 21, on Multicasting. Sections 27.1 to 27.3, Chapter 27, on the IP SSRR option. Sections 28.1 to 28.5, Chapter 28, on raw sockets, the IP_HDRINCL socket option, and ping. Sections 15.5, Chapter 15, on Unix domain SOCK_STREAM sockets. Figure 29.14, p. 807, and the corresponding explanation on p. 806, on filling in an IP header when the IP_HDRINCL socket option is in effect. The Lecture Slides on ARP & RARP (especially Section 4.4, ARP Packet Format, and the Figure 4.3 it includes). The link http://www.pdbuchan.com/rawsock/rawsock.html contains useful code samples that use IP raw sockets and PF_PACKET sockets. Note, in partcular, the code “icmp4_ll.c” in Table 2 for building an echo request sent through a PF_PACKET SOCK_RAW socket. The VMware environment You will be using the same vm1 , . . . . . , vm10 nodes you used for Assignment 3. However, unlike Assignment 3, you should use only interfaces eth0 and their associated IP addresses and ignore the other Ethernet interfaces that nodes have (interfaces eth0 make vm1 , . . . . . , vm10 look as if they belong to the same Ethernet LAN segment IP network 130.245.156.0/24). Note that, apart from the primary IP addresses associated with interfaces eth0, some nodes might also have one or more alias IP addresses associated with their interface eth0. Tour application module specifications The application will create a total of four sockets: two IP raw sockets, a PF_PACKET socket and a UDP socket for multicasting. We shall call the two IP raw sockets the ‘rt ’ (‘route traversal’) and ‘pg ’ (‘ping’) sockets, respectively. The rt socket should have the IP_HDRINCL option set. You will only be receiving ICMP echo reply messages through the pg socket (and not sending echo requests), so it does not matter whether it has the IP_HDRINCL option set or not. The pg socket should have protocol value (i.e., protocol demultiplexing key in the IP header) IPPROTO_ICMP. The rt socket should have a protocol value that identifies the application - i.e., some value other than the IPPROTO_XXXX values in /usr/include/netinet/in.h. However, remember that you will all be running your code using the same root account on the vm1 , . . . . . , vm10 nodes. So if two of you happen to choose the same protocol value and happen to be running on the same vm node at the same time, your applications will receive each other’s IP packets. For that reason, try to choose a protocol value for your rt socket that is likely to be unique to yourself. The PF_PACKET socket should be of type SOCK_RAW (not SOCK_DGRAM). This socket should have a protocol value of ETH_P_IP = 0x0800 (IPv4). The UDP socket for multicasting will be discussed below. Note that, depending on how you choose to bind that socket, you might actually need to have two UDP sockets for multicast communication – see bottom of p. 576, Section 21.10. Your application will, of course, have to be running on every vm node that is included in the tour. When evoking the application on the source node, the user supplies a sequence of vm node names (not IP addresses) to be visited in order. This command line sequence starts with the next node to be visited from the source node (i.e., it does not start with the source node itself). The sequence can include any number of repeated visits to the same node. For example, suppose that the source node is vm3 and the executable is called badr_tour : [root@vm3/root]# badr_tour vm2 vm10 vm4 vm7 vm5 vm2 vm6 vm2 vm9 vm4 vm7 vm2 vm6 vm5 vm1 vm10 vm8 (but note that the tour does not necessarily have to visit every vm node; and the same node should not appear consequentively in the tour list – i.e., the next node on the tour cannot be the current node itself). The application turns the sequence into a list of IP addresses for source routing. It also adds the IP address of the source node itself to the beginning of the list. The list thus produced will be carried as the payload of an IP packet, not as a SSRR option in the packet header. It is our application which will ensure that every node in the sequence is visited in order, not the IP SSRR capability. The source node should also add to the list an IP multicast address and a port number of its choice. It should also join the multicast group at that address and port number on its UDP socket. The TTL for outgoing multicasts should be set to 1. The application then fills in the header of an IP packet, designating itself as the IP source, and the next node to be visited as the IP destination. The packet is sent out on the rt socket. Note that on Linux, all the fields of the packet header must be in network byte order (Stevens, Section 28.3, p. 737, the fourth bullet point). When filling in the packet header, you should explicitly fill in the identification field (recall that, with the IP_HDRINCL socket option, if the identification field is given value 0, then the kernel will set its value). Try to make sure that the value you choose is likely to be unique to yourself (for reasons similar to those explained with respect to the IPPROTO_XXXX in 1. above). When a node receives an IP packet on its rt socket, it should first check that the identification field carries the right value (this implies that you will hard code your choice of identification field value determined in item 2 above in your code). If the identification field value does not check out, the packet is ignored. For a valid packet : Print out a message along the lines of: <time> received source routing packet from <hostname> <time> is the current time in human-readable format (see lines 19 & 20 in Figure 1.9, p. 14, and the corresponding explanation on p. 14f.), and <hostname> is the host name corresponding to the source IP address in the header of the received packet. If this is the first time the node is visited, the application should use the multicast address and port number in the packet received to join the multicast group on its UDP socket. The TTL for outgoing multicasts should be set to 1. The application updates the list in the payload, so that the next node in the tour can easily identify what the next hop from itself will be when it receives the packet. How you do this I leave up to you. You could, for example, include as part of the payload a pointer field into the list of nodes to be visited. This pointer would then be updated to the next entry in the list as the packet progresses hop by hop (see Figure 27.1 and the associated explanation on pp. 711-712). Other solutions are, of course, possible. The application then fills in a new IP header, designating itself as the IP source, and the next node to be visited as the IP destination. The identification field should be set to the same value as in the received packet. The packet is sent out on the rt socket. The node should also initiate pinging to the preceding node in the tour (the IP address of which it should pick up from the header of the received packet). However, unlike the Stevens ping code, it will be using the SOCK_RAW-type PF_PACKET socket of item 1 above to send the ICMP echo request messages. Before it can send echo request messages, the application has to call on the ARP module you will implement to get the Ethernet address of this preceding / ‘target’ node; this call is made using the API function areq which you will also implement (see sections ARP module specifications & API specifications below). Note that ARP has to be evoked every time the application wants to send out an echo request message, and not just the first time. An echo request message has to be encapsulated in a properly-formulated IP packet, which is in turn encapsulated in a properly-formulated Ethernet frame transmitted out through the PF_PACKET socket ; otherwise, ICMP at the source node will not receive it. You will have to modify Stevens’ ping code accordingly, specifically, the send_v4 function. In particular, the Ethernet frame must have a value of ETH_P_IP = 0x0800 (IPv4 – see <linux/if_ether.h>) in the frame type / ‘length’ field ; and the encapsulated IP packet must have a value of IPPROTO_ICMP = 0x01 (ICMPv4 – see <netinet_in.h>) in its protocol field. You should also simplify the ping code in its entirety by stripping all the ‘indirection’ IPv4 / IPv6 dual-operability paraphernalia and making the code work just for IPv4. Also note that the functions host_serv and freeaddrinfo, together with the associated structure addrinfo (see Sections 11.6, 11.8 & 11.11), in Figures 27.3, 27.6 & 28.5 ( pp. 713, 716 & 744f., respectively) can be replaced by the function gethostbyname and associated structure hostent (see Section 11.3) where needed. Also, there is no ‘-v’ verbose option, so this too should be stripped from Stevens’ code. When a node is ready to start pinging, it first prints out a ‘PING’ message similar to lines 32-33 of Figure 28.5, p. 744. It then builds up ICMP echo request messages and sends them to the source node every 1 second through the PF_PACKET socket. It also reads incoming echo response messages off the pg socket, in response to which it prints out the same kind of output as the code of Figure 28.8, p. 748. If this node and its preceding node have been previously visited in that order during the tour, then pinging would have already been initiated from the one to the other in response to the first visit, and nothing further should nor need be done during second and subsequent visits. In light of the above, note that once a node initiates pinging, it needs to read from both its rt and pg sockets, necessitating the use of the select function. As will be clear from what follows below, the application will anyway be needing also to simultaneously monitor its UDP socket for incoming multicast datagrams. When the last node on the tour is reached, and if this is the first time it is visited, it joins the multicast group and starts pinging the preceding node (if it is not already doing so). After a few echo replies are received (five, say), it sends out the multicast message below on its UDP socket (i.e., the node should wait about five seconds before sending the multicast message) : <<<<< This is node vmi . Tour has ended . Group members please identify yourselves. >>>>> where vmi is the name (not IP address) of the node. The node should also print this message out on stdout preceded, on the same line, by the phrase: Node vmi . Sending: <then print out the message sent>. Each node vmj receiving this message should print out the message received preceded, on the same line, by the phrase: Node vmj . Received <then print out the message received>. Each such node in step a above should then immediately stop its pinging activity. The node should then send out the following multicast message: <<<<< Node vmj . I am a member of the group. >>>>> and print out this message preceded, on the same line, by the phrase: Node vmj . Sending: <then print out the message sent>. Each node receiving these second multicast messages (i.e., the messages that nodes – including itself – sent out in step c above) should print each such message out preceded, on the same line, by the phrase: Node vmk . Received: <then print out the message received>. Reading from the socket in step d above should be implemented with a 5-second timeout. When the timeout expires, the node should print out another message to the effect that it is terminating the Tour application, and gracefully exit its Tour process. Note that under Multicast specifications, the last node in the tour, which sends out the End of Tour message, should itself receive a copy of that message and, when it does, it should behave exactly as do the other nodes in steps a. – e. above. ARP module specifications Your executable is evoked with no command line arguments. Like the Tour module, it will be running on every vm node. It uses the get_hw_addrs function of Assignment 3 to explore its node’s interfaces and build a set of <IP address , HW address> matching pairs for all eth0 interface IP addresses (including alias IP addresses, if any). Write out to stdout in some appropriately clear format the address pairs found. The module creates two sockets: a PF_PACKET socket and a Unix domain socket. The PF_PACKET should be of type SOCK_RAW (not type SOCK_DGRAM) with a protocol value of your choice (but not one of the standard values defined in <linux/if_ether.h>) which is, hopefully, unique to yourself. This value effectively becomes the protocol value for your implementation of ARP. Because this protocol value will be carried in the frame type / ‘length’ field of the Ethernet frame header (see Figure 4.3 of the ARP & RARP handout), the value chosen should be not less than 1536 (0x600) so that it is not misinterpreted as the length of an Ethernet 802.3 frame. The Unix domain socket should be of type SOCK_STREAM (not SOCK_DGRAM). It is a listening socket bound to a ‘well-known’ sun_path file. This socket will be used to communicate with the function areq that is implemented in the Tour module (see the section API specifications below). In this context, areq will act as the client and the ARP module as the server. The ARP module then sits in an infinite loop, monitoring these two sockets. As ARP request messages arrive on the PF_PACKET socket, the module processes them, and responds with ARP reply messages as appropriate. The protocol builds a ‘cache’ of matching <IP address , HW address> pairs from the replies (and requests – see below) it receives. For simplicity, and unlike the real ARP, we shall not implement timing out mechanisms for these cache entries. A cache entry has five parts: (i) IP address ; (ii) HW address ; (iii) sll_ifindex (the interface to be used for reaching the matching pair <(i) , (ii)>) ; (iv) sll_hatype ; and (v) a Unix-domain connection-socket descriptor for a connected client (see the section API specifications below for the latter three). When an ARP reply is being entered in the cache, the ARP module uses the socket descriptor in (v) to send a reply to the client, closes the connection socket, and deletes the socket descriptor from the cache entry. Note that, like the real ARP, when an ARP request is received by a node, and if the request pertains to that receiving node, the sender’s (see Figure 4.3 of the ARP & RARP handout) <IP address, HW address> matching pair should be entered into the cache if it is not already there (together, of course, with (iii) sll_ifindex & (iv) sll_hatype), or updated if need be if such an entry already exists in the cache. If the ARP request received does not pertain to the node receiving it, but there is already an entry in that receiving node's cache for the sender’s <IP address, HW address> matching pair, that entry should be checked and updated if need be. If there is no such entry, no action is taken (in particular, and unlike the case above, no new entry should be made in the receiving node's cache of the sender’s <IP address, HW address> matching pair if such an entry does not already exist). ARP request and reply messages have the same format as Figure 4.3 of the ARP & RARP handout, but with an extra 2-byte identification field added at the beginning which you fill with a value chosen so that it has a high probability of being unique to yourself. This value is to be echoed in the reply message, and helps to act as a further filter in case some other student happens to have fortuitously chosen the same value as yourself for the protocol parameter of the ARP PF_PACKET. Values in the fields of our ARP messages must be in network byte order. You might find the system header file <linux/if_arp.h> useful for manipulating ARP request and reply messages, but remember that our version of these messages have an extra two-byte field as mentioned above. Your code should print out on stdout, in some appropriately clear format, the contents of the Ethernet frame header and ARP request message you send. As described in Section 4.4 of the ARP & RARP handout, the node that responds to the request should, in its reply message, swap the two sender addresses with the two target addresses, as well as, of course, echo back the extra identification field sent with the request. The protocol at this responding node should print out, in an appropriately clear format, both the request frame (header and ARP message) it receives and the reply frame it sends. Similarly, the node that sent the request should print out the reply frame it receives. Finally, recall that the node issuing the request sends out a broadcast Ethernet frame, but the responding node replies with a unicast frame. API specifications The API is for communication between the Tour process and the ARP process. It consists of a single function, areq, implemented in the Tour module. areq is called by send_v4 function of the application every time the latter want to send out an ICMP echo request message: int areq (struct sockaddr *IPaddr, socklen_t sockaddrlen, struct hwaddr *HWaddr); IPaddr contains the primary or alias IPaddress of a ‘target’ node on the LAN for which the corresponding hardware address is being requested. hwaddr is a new structure (and not a pre-existing type) modeled on the sockaddr_ll of PF_PACKET; you will have to declare it in your code. It is used to return the requested hardware address to the caller of areq : structure hwaddr { int sll_ifindex; /* Interface number */ unsigned short sll_hatype; /* Hardware type */ unsigned char sll_halen; /* Length of address */ unsigned char sll_addr[8]; /* Physical layer address */ }; areq creates a Unix domain socket of type SOCK_STREAM and connects to the ‘well-known’ sun_path file of the ARP listening socket. It sends the IP address from parameter IPaddr and the information in the three fields of parameter HWaddr to ARP. It then blocks on a read awaiting a reply from ARP. This read should be backed up by a timeout since it is possible that no reply is received for the request. If a timeout occurs, areq should close the socket and return to its caller indicating failure (through its int return value). Your application code should print out on stdout, in some appropriately clear format, a notification every time areq is called, giving the IP address for which a HW address is being sought. It should similarly print out the result when the call to areq returns (HW address returned, or failure). When the ARP module receives a request for a HW address from areq through its Unix domain listening socket, it first checks if the required HW address is already in the cache. If so, it can respond immediately to the areq and close the Unix domain connection socket. Else : it makes an ‘incomplete’ entry in the cache, consisting of parts (i), (iii), (iv) and (v) ; puts out an ARP request message on the network on its PF_PACKET socket; and starts monitoring the areq connection socket for readability – if the areq client closes the connection socket (this would occur in response to a timeout in areq), ARP deletes the corresponding incomplete entry from the cache (and ignores any subsequent ARP reply from the network if such is received). On the other hand, if ARP receives a reply from the network, it updates the incomplete cache entry, responds to areq, and closes the connection socket.
SOYJUN
Overview For this assignment you will be developing and implementing : An On-Demand shortest-hop Routing (ODR) protocol for networks of fixed but arbitrary and unknown connectivity, using PF_PACKET sockets. The implementation is based on (a simplified version of) the AODV algorithm. Time client and server applications that send requests and replies to each other across the network using ODR. An API you will implement using Unix domain datagram sockets enables applications to communicate with the ODR mechanism running locally at their nodes. I shall be discussing the assignment in class on Wednesday, October 29, and Monday, November 3. The following should prove useful reference material for the assignment : Sections 15.1, 15.2, 15.4 & 15.6, Chapter 15, on Unix domain datagram sockets. PF_PACKET(7) from the Linux manual pages. You might find these notes made by a past CSE 533 student useful. Also, the following link http://www.pdbuchan.com/rawsock/rawsock.html contains useful code samples that use PF_PACKET sockets (as well as other code samples that use raw IP sockets which you do not need for this assignment, though you will be using these types of sockets for Assignment 4). Charles E. Perkins & Elizabeth M. Royer. “Ad-hoc On-Demand Distance Vector Routing.” Proceedings of the 2nd IEEE Workshop on Mobile Computing Systems and Applications, New Orleans, Louisiana, February 1999, pp. 90 - 100. The VMware environment minix.cs.stonybrook.edu is a Linux box running VMware. A cluster of ten Linux virtual machines, called vm1 through vm10, on which you can gain access as root and run your code have been created on minix. See VMware Environment Hosts for further details. VMware instructions takes you to a page that explains how to use the system. The ten virtual machines have been configured into a small virtual intranet of Ethernet LANs whose topology is (in principle) unknown to you. There is a course account cse533 on node minix, with home directory /users/cse533. In there, you will find a subdirectory Stevens/unpv13e , exactly as you are used to having on the cs system. You should develop your source code and makefiles for handing in accordingly. You will be handing in your source code on the minix node. Note that you do not need to link against the socket library (-lsocket) in Linux. The same is true for -lnsl and -lresolv. For example, take a look at how the LIBS variable is defined for Solaris, in /home/courses/cse533/Stevens/unpv13e_solaris2.10/Make.defines (on compserv1, say) : LIBS = ../libunp.a -lresolv -lsocket -lnsl -lpthread But if you take a look at Make.defines on minix (/users/cse533/Stevens/unpv13e/Make.defines) you will find only: LIBS = ../libunp.a -lpthread The nodes vm1 , . . . . . , vm10 are all multihomed : each has two (or more) interfaces. The interface ‘eth0 ’ should be completely ignored and is not to be used for this assignment (because it shows all ten nodes as if belonging to the same single Ethernet 192.168.1.0/24, rather than to an intranet composed of several Ethernets). Note that vm1 , . . . . . , vm10 are virtual machines, not real ones. One implication of this is that you will not be able to find out what their (virtual) IP addresses are by using nslookup and such. To find out these IP addresses, you need to look at the file /etc/hosts on minix. More to the point, invoking gethostbyname for a given vm will return to you only the (primary) IP address associated with the interface eth0 of that vm (which is the interface you will not be using). It will not return to you any other IP address for the node. Similarly, gethostbyaddr will return the vm node name only if you give it the (primary) IP address associated with the interface eth0 for the node. It will return nothing if you give it any other IP address for the node, even though the address is perfectly valid. Because of this, and because it will ease your task to be able to use gethostbyname and gethostbyaddr in a straightforward way, we shall adopt the (primary) IP addresses associated with interfaces eth0 as the ‘canonical’ IP addresses for the nodes (more on this below). Time client and server A time server runs on each of the ten vm machines. The client code should also be available on each vm so that it can be evoked at any of them. Normally, time clients/servers exchange request/reply messages using the TCP/UDP socket API that, effectively, enables them to receive service (indirectly, via the transport layer) from the local IP mechanism running at their nodes. You are to implement an API using Unix domain sockets to access the local ODR service directly (somewhat similar, in effect, to the way that raw sockets permit an application to access IP directly). Use Unix domain SOCK_DGRAM, rather than SOCK_STREAM, sockets (see Figures 15.5 & 15.6, pp. 418 - 419). API You need to implement a msg_send function that will be called by clients/servers to send requests/replies. The parameters of the function consist of : int giving the socket descriptor for write char* giving the ‘canonical’ IP address for the destination node, in presentation format int giving the destination ‘port’ number char* giving message to be sent int flag if set, force a route rediscovery to the destination node even if a non-‘stale’ route already exists (see below) msg_send will format these parameters into a single char sequence which is written to the Unix domain socket that a client/server process creates. The sequence will be read by the local ODR from a Unix domain socket that the ODR process creates for itself. Recall that the ‘canonical’ IP address for a vm node is the (primary) IP address associated with the eth0 interface for the node. It is what will be returned to you by a call to gethostbyname. Similarly, we need a msg_recv function which will do a (blocking) read on the application domain socket and return with : int giving socket descriptor for read char* giving message received char* giving ‘canonical’ IP address for the source node of message, in presentation format int* giving source ‘port’ number This information is written as a single char sequence by the ODR process to the domain socket that it creates for itself. It is read by msg_recv from the domain socket the client/server process creates, decomposed into the three components above, and returned to the caller of msg_recv. Also see the section below entitled ODR and the API. Client When a client is evoked at a node, it creates a domain datagram socket. The client should bind its socket to a ‘temporary’ (i.e., not ‘well-known’) sun_path name obtained from a call to tmpnam() (cf. line 10, Figure 15.6, p. 419) so that multiple clients may run at the same node. Note that tmpnam() is actually highly deprecated. You should use the mkstemp() function instead - look up the online man pages on minix (‘man mkstemp’) for details. As you run client code again and again during the development stage, the temporary files created by the calls to tmpnam / mkstemp start to proliferate since these files are not automatically removed when the client code terminates. You need to explicitly remove the file created by the client evocation by issuing a call to unlink() or to remove() in your client code just before the client code exits. See the online man pages on minix (‘man unlink’, ‘man remove’) for details. The client then enters an infinite loop repeating the steps below. The client prompts the user to choose one of vm1 , . . . . . , vm10 as a server node. Client msg_sends a 1 or 2 byte message to server and prints out on stdout the message client at node vm i1 sending request to server at vm i2 (In general, throughout this assignment, “trace” messages such as the one above should give the vm names and not IP addresses of the nodes.) Client then blocks in msg_recv awaiting response. This attempt to read from the domain socket should be backed up by a timeout in case no response ever comes. I leave it up to you whether you ‘wrap’ the call to msg_recv in a timeout, or you implement the timeout inside msg_recv itself. When the client receives a response it prints out on stdout the message client at node vm i1 : received from vm i2 <timestamp> If, on the other hand, the client times out, it should print out the message client at node vm i1 : timeout on response from vm i2 The client then retransmits the message out, setting the flag parameter in msg_send to force a route rediscovery, and prints out an appropriate message on stdout. This is done only once, when a timeout for a given message to the server occurs for the first time. Client repeats steps 1. - 3. Server The server creates a domain datagram socket. The server socket is assumed to have a (node-local) ‘well-known’ sun_path name which it binds to. This ‘well-known’ sun_path name is designated by a (network-wide) ‘well-known’ ‘port’ value. The time client uses this ‘port’ value to communicate with the server. The server enters an infinite sequence of calls to msg_recv followed by msg_send, awaiting client requests and responding to them. When it responds to a client request, it prints out on stdout the message server at node vm i1 responding to request from vm i2 ODR The ODR process runs on each of the ten vm machines. It is evoked with a single command line argument which gives a “staleness” time parameter, in seconds. It uses get_hw_addrs (available to you on minix in ~cse533/Asgn3_code) to obtain the index, and associated (unicast) IP and Ethernet addresses for each of the node’s interfaces, except for the eth0 and lo (loopback) interfaces, which should be ignored. In the subdirectory ~cse533/Asgn3_code (/users/cse533/Asgn3_code) on minix I am providing you with two functions, get_hw_addrs and prhwaddrs. These are analogous to the get_ifi_info_plus and prifinfo_plus of Assignment 2. Like get_ifi_info_plus, get_hw_addrs uses ioctl. get_hw_addrs gets the (primary) IP address, alias IP addresses (if any), HW address, and interface name and index value for each of the node's interfaces (including the loopback interface lo). prhwaddrs prints that information out. You should modify and use these functions as needed. Note that if an interface has no HW address associated with it (this is, typically, the case for the loopback interface lo for example), then ioctl returns get_hw_addrs a HW address which is the equivalent of 00:00:00:00:00:00 . get_hw_addrs stores this in the appropriate field of its data structures as it would with any HW address returned by ioctl, but when prhwaddrs comes across such an address, it prints a blank line instead of its usual ‘HWaddr = xx:xx:xx:xx:xx:xx’. The ODR process creates one or more PF_PACKET sockets. You will need to try out PF_PACKET sockets for yourselves and familiarize yourselves with how they behave. If, when you read from the socket and provide a sockaddr_ll structure, the kernel returns to you the index of the interface on which the incoming frame was received, then one socket will be enough. Otherwise, somewhat in the manner of Assignment 2, you shall have to create a PF_PACKET socket for every interface of interest (which are all the interfaces of the node, excluding interfaces lo and eth0 ), and bind a socket to each interface. Furthermore, if the kernel also returns to you the source Ethernet address of the frame in the sockaddr_ll structure, then you can make do with SOCK_DGRAM type PF_PACKET sockets; otherwise you shall have to use SOCK_RAW type sockets (although I would prefer you to use SOCK_RAW type sockets anyway, even if it turns out you can make do with SOCK_DGRAM type). The socket(s) should have a protocol value (no larger than 0xffff so that it fits in two bytes; this value is given as a network-byte-order parameter in the call(s) to function socket) that identifies your ODR protocol. The <linux/if_ether.h> include file (i.e., the file /usr/include/linux/if_ether.h) contains protocol values defined for the standard protocols typically found on an Ethernet LAN, as well as other values such as ETH_P_ALL. You should set protocol to a value of your choice which is not a <linux/if_ether.h> value, but which is, hopefully, unique to yourself. Remember that you will all be running your code using the same root account on the vm1 , . . . . . , vm10 nodes. So if two of you happen to choose the same protocol value and happen to be running on the same vm node at the same time, your applications will receive each other’s frames. For that reason, try to choose a protocol value for the socket(s) that is likely to be unique to yourself (something based on your Stony Brook student ID number, for example). This value effectively becomes the protocol value for your implementation of ODR, as opposed to some other cse 533 student's implementation. Because your value of protocol is to be carried in the frame type field of the Ethernet frame header, the value chosen should be not less than 1536 (0x600) so that it is not misinterpreted as the length of an Ethernet 802.3 frame. Note from the man pages for packet(7) that frames are passed to and from the socket without any processing in the frame content by the device driver on the other side of the socket, except for calculating and tagging on the 4-byte CRC trailer for outgoing frames, and stripping that trailer before delivering incoming frames to the socket. Nevertheless, if you write a frame that is less than 60 bytes, the necessary padding is automatically added by the device driver so that the frame that is actually transmitted out is the minimum Ethernet size of 64 bytes. When reading from the socket, however, any such padding that was introduced into a short frame at the sending node to bring it up to the minimum frame size is not stripped off - it is included in what you receive from the socket (thus, the minimum number of bytes you receive should never be less than 60). Also, you will have to build the frame header for outgoing frames yourselves (assuming you use SOCK_RAW type sockets). Bear in mind that the field values in that header have to be in network order. The ODR process also creates a domain datagram socket for communication with application processes at the node, and binds the socket to a ‘well known’ sun_path name for the ODR service. Because it is dealing with fixed topologies, ODR is, by and large, considerably simpler than AODV. In particular, discovered routes are relatively stable and there is no need for all the paraphernalia that goes with the possibility of routes changing (such as maintenance of active nodes in the routing tables and timeout mechanisms; timeouts on reverse links; lifetime field in the RREP messages; etc.) Nor will we be implementing source_sequence_#s (in the RREQ messages), and dest_sequence_# (in RREQ and RREP messages). In reality, we should (though we will not, for the sake of simplicity, be doing so) implement some sort of sequence number mechanism, or some alternative mechanism such as split-horizon for example, if we are to avoid possible scenarios of routing loops in a “count to infinity” context (I shall explain this point in class). However, we want ODR to discover shortest-hop paths, and we want it to do so in a reasonably efficient manner. This necessitates having one or two aspects of its operations work in a different, possibly slightly more complicated, way than AODV does. ODR has several basic responsibilities : Build and maintain a routing table. For each destination in the table, the routing table structure should include, at a minimum, the next-hop node (in the form of the Ethernet address for that node) and outgoing interface index, the number of hops to the destination, and a timestamp of when the the routing table entry was made or last “reconfirmed” / updated. Note that a destination node in the table is to be identified only by its ‘canonical’ IP address, and not by any other IP addresses the node has. Generate a RREQ in response to a time client calling msg_send for a destination for which ODR has no route (or for which a route exists, but msg_send has the flag parameter set or the route has gone ‘stale’ – see below), and ‘flood’ the RREQ out on all the node’s interfaces (except for the interface it came in on and, of course, the interfaces eth0 and lo). Flooding is done using an Ethernet broadcast destination address (0xff:ff:ff:ff:ff:ff) in the outgoing frame header. Note that a copy of the broadcast packet is supposed to / might be looped back to the node that sends it (see p. 535 in the Stevens textbook). ODR will have to take care not to treat these copies as new incoming RREQs. Also note that ODR at the client node increments the broadcast_id every time it issues a new RREQ for any destination node. When a RREQ is received, ODR has to generate a RREP if it is at the destination node, or if it is at an intermediate node that happens to have a route (which is not ‘stale’ – see below) to the destination. Otherwise, it must propagate the RREQ by flooding it out on all the node’s interfaces (except the interface the RREQ arrived on). Note that as it processes received RREQs, ODR should enter the ‘reverse’ route back to the source node into its routing table, or update an existing entry back to the source node if the RREQ received shows a shorter-hop route, or a route with the same number of hops but going through a different neighbour. The timestamp associated with the table entry should be updated whenever an existing route is either “reconfirmed” or updated. Obviously, if the node is going to generate a RREP, updating an existing entry back to the source node with a more efficient route, or a same-hops route using a different neighbour, should be done before the RREP is generated. Unlike AODV, when an intermediate node receives a RREQ for which it generates a RREP, it should nevertheless continue to flood the RREQ it received if the RREQ pertains to a source node whose existence it has heretofore been unaware of, or the RREQ gives it a more efficient route than it knew of back to the source node (the reason for continuing to flood the RREQ is so that other nodes in the intranet also become aware of the existence of the source node or of the potentially more optimal reverse route to it, and update their tables accordingly). However, since an RREP for this RREQ is being sent by our node, we do not want other nodes who receive the RREQ propagated by our node, and who might be in a position to do so, to also send RREPs. So we need to introduce a field in the RREQ message, not present in the AODV specifications, which acts like a “RREP already sent” field. Our node sets this field before further propagating the RREQ and nodes receiving an RREQ with this field set do not send RREPs in response, even if they are in a position to do so. ODR may, of course, receive multiple, distinct instances of the same RREQ (the combination of source_addr and broadcast_id uniquely identifies the RREQ). Such RREQs should not be flooded out unless they have a lower hop count than instances of that RREQ that had previously been received. By the same token, if ODR is in a position to send out a RREP, and has already done so for this, now repeating, RREQ , it should not send out another RREP unless the RREQ shows a more efficient, previously unknown, reverse route back to the source node. In other words, ODR should not generate essentially duplicative RREPs, nor generate RREPs to instances of RREQs that reflect reverse routes to the source that are not more efficient than what we already have. Relay RREPs received back to the source node (this is done using the ‘reverse’ route entered into the routing table when the corresponding RREQ was processed). At the same time, a ‘forward’ path to the destination is entered into the routing table. ODR could receive multiple, distinct RREPs for the same RREQ. The ‘forward’ route entered in the routing table should be updated to reflect the shortest-hop route to the destination, and RREPs reflecting suboptimal routes should not be relayed back to the source. In general, maintaining a route and its associated timestamp in the table in response to RREPs received is done in the same manner described above for RREQs. Forward time client/server messages along the next hop. (The following is important – you will lose points if you do not implement it.) Note that such application payload messages (especially if they are the initial request from the client to the server, rather than the server response back to the client) can be like “free” RREPs, enabling nodes along the path from source (client) to destination (server) node to build a reverse path back to the client node whose existence they were heretofore unaware of (or, possibly, to update an existing route with a more optimal one). Before it forwards an application payload message along the next hop, ODR at an intermediate node (and also at the final destination node) should use the message to update its routing table in this way. Thus, calls to msg_send by time servers should never cause ODR at the server node to initiate RREQs, since the receipt of a time client request implies that a route back to the client node should now exist in the routing table. The only exception to this is if the server node has a staleness parameter of zero (see below). A routing table entry has associated with it a timestamp that gives the time the entry was made into the table. When a client at a node calls msg_send, and if an entry for the destination node already exists in the routing table, ODR first checks that the routing information is not ‘stale’. A stale routing table entry is one that is older than the value defined by the staleness parameter given as a command line argument to the ODR process when it is executed. ODR deletes stale entries (as well as non-stale entries when the flag parameter in msg_send is set) and initiates a route rediscovery by issuing a RREQ for the destination node. This will force periodic updating of the routing tables to take care of failed nodes along the current path, Ethernet addresses that might have changed, and so on. Similarly, as RREQs propagate through the intranet, existing stale table entries at intermediate nodes are deleted and new route discoveries propagated. As noted above when discussing the processing of RREQs and RREPs, the associated timestamp for an existing table entry is updated in response to having the route either “reconfirmed” or updated (this applies to both reverse routes, by virtue of RREQs received, and to forward routes, by virtue of RREPs). Finally, note that a staleness parameter of 0 essentially indicates that the discovered route will be used only once, when first discovered, and then discarded. Effectively, an ODR with staleness parameter 0 maintains no real routing table at all ; instead, it forces route discoveries at every step of its operation. As a practical matter, ODR should be run with staleness parameter values that are considerably larger than the longest RTT on the intranet, otherwise performance will degrade considerably (and collapse entirely as the parameter values approach 0). Nevertheless, for robustness, we need to implement a mechanism by which an intermediate node that receives a RREP or application payload message for forwarding and finds that its relevant routing table entry has since gone stale, can intiate a RREQ to rediscover the route it needs. RREQ, RREP, and time client/server request/response messages will all have to be carried as encapsulated ODR protocol messages that form the data payload of Ethernet frames. So we need to design the structure of ODR protocol messages. The format should contain a type field (0 for RREQ, 1 for RREP, 2 for application payload ). The remaining fields in an ODR message will depend on what type it is. The fields needed for (our simplified versions of AODV’s) RREQ and RREP should be fairly clear to you, but keep in mind that you need to introduce two extra fields: The “RREP already sent” bit or field in RREQ messages, as mentioned above. A “forced discovery” bit or field in both RREQ and RREP messages: When a client application forces route rediscovery, this bit should be set in the RREQ issued by the client node ODR. Intermediate nodes that are not the destination node but which do have a route to the destination node should not respond with RREPs to an RREQ which has the forced discovery field set. Instead, they should continue to flood the RREQ so that it eventually reaches the destination node which will then respond with an RREP. The intermediate nodes relaying such an RREQ must update their ‘reverse’ route back to the source node accordingly, even if the new route is less efficient (i.e., has more hops) than the one they currently have in their routing table. The destination node responds to the RREQ with an RREP in which this field is also set. Intermediate nodes that receive such a forced discovery RREP must update their ‘forward’ route to the destination node accordingly, even if the new route is less efficient (i.e., has more hops) than the one they currently have in their routing table. This behaviour will cause a forced discovery RREQ to be responded to only by the destination node itself and not any other node, and will cause intermediate nodes to update their routing tables to both source and destination nodes in accordance with the latest routing information received, to cover the possibility that older routes are no longer valid because nodes and/or links along their paths have gone down. A type 2, application payload, message needs to contain the following type of information : type = 2 ‘canonical’ IP address of source node ‘port’ number of source application process (This, of course, is not a real port number in the TCP/UDP sense, but simply a value that ODR at the source node uses to designate the sun_path name for the source application’s domain socket.) ‘canonical’ IP address of destination node ‘port’ number of destination application process (This is passed to ODR by the application process at the source node when it calls msg_send. Its designates the sun_path name for an application’s domain socket at the destination node.) hop count (This starts at 0 and is incremented by 1 at each hop so that ODR can make use of the message to update its routing table, as discussed above.) number of bytes in application message The fields above essentially constitute a ‘header’ for the ODR message. Note that fields which you choose to have carry numeric values (rather than ascii characters, for example) must be in network byte order. ODR-defined numeric-valued fields in type 0, RREQ, and type 1, RREP, messages must, of course, also be in network byte order. Also note that only the ‘canonical’ IP addresses are used for the source and destination nodes in the ODR header. The same has to be true in the headers for type 0, RREQ, and type 1, RREP, messages. The general rule is that ODR messages only carry ‘canonical’ IP node addresses. The last field in the type 2 ODR message is essentially the data payload of the message. application message given in the call to msg_send An ODR protocol message is encapsulated as the data payload of an Ethernet frame whose header it fills in as follows : source address = Ethernet address of outgoing interface of the current node where ODR is processing the message. destination address = Ethernet broadcast address for type 0 messages; Ethernet address of next hop node for type 1 & 2 messages. protocol field = protocol value for the ODR PF_PACKET socket(s). Last but not least, whenever ODR writes an Ethernet frame out through its socket, it prints out on stdout the message ODR at node vm i1 : sending frame hdr src vm i1 dest addr ODR msg type n src vm i2 dest vm i3 where addr is in presentation format (i.e., hexadecimal xx:xx:xx:xx:xx:xx) and gives the destination Ethernet address in the outgoing frame header. Other nodes in the message should be identified by their vm name. A message should be printed out for each packet sent out on a distinct interface. ODR and the API When the ODR process first starts, it must construct a table in which it enters all well-known ‘port’ numbers and their corresponding sun_path names. These will constitute permanent entries in the table. Thereafter, whenever it reads a message off its domain socket, it must obtain the sun_path name for the peer process socket and check whether that name is entered in the table. If not, it must select an ‘ephemeral’ ‘port’ value by which to designate the peer sun_path name and enter the pair < port value , sun_path name > into the table. Such entries cannot be permanent otherwise the table will grow unboundedly in time, with entries surviving for ever, beyond the peer processes’ demise. We must associate a time_to_live field with a non-permanent table entry, and purge the entry if nothing is heard from the peer for that amount of time. Every time a peer process for which a non-permanent table entry exists communicates with ODR, its time_to_live value should be reinitialized. Note that when ODR writes to a peer, it is possible for the write to fail because the peer does not exist : it could be a ‘well-known’ service that is not running, or we could be in the interval between a process with a non-permanent table entry terminating and the expiration of its time_to_live value. Notes A proper implementation of ODR would probably require that RREQ and RREP messages be backed up by some kind of timeout and retransmission mechanism since the network transmission environment is not reliable. This would considerably complicate the implementation (because at any given moment, a node could have multiple RREQs that it has flooded out, but for which it has still not received RREPs; the situation is further complicated by the fact that not all intermediate nodes receiving and relaying RREQs necessarily lie on a path to the destination, and therefore should expect to receive RREPs), and, learning-wise, would not add much to the experience you should have gained from Assignment 2.
w32zhong
CSC 541 Assignment 4 B-Trees Introduction The goals of this assignment are two-fold: To introduce you to searching data on disk using B-trees. To investigate how changing the order of a B-tree affects its performance. Index File During this assignment you will create, search, and manage a binary index file of integer key values. The values stored in the file will be specified by the user. You will structure the file as a B-tree. Program Execution Your program will be named assn_4 and it will run from the command line. Two command line arguments will be specified: the name of the index file, and a B-tree order. assn_4 index-file order For example, executing your program as follows assn_4 index.bin 4 would open an index file called index.bin that holds integer keys stored in an order-4 B-tree. You can assume order will always be ≥ 3. For convenience, we refer to the index file as index.bin throughout the remainder of the assignment. Note. If you are asked open an existing index file, you can assume the B-tree order specified on the command line matches the order that was used when the index file was first created. B-Tree Nodes Your program is allowed to hold individual B-tree nodes in memory—but not the entire tree—at any given time. Your B-tree node should have a structure and usage similar to the following. #include <stdlib.h> int order = 4; /* B-tree order */ typedef struct { /* B-tree node */ int n; /* Number of keys in node */ int *key; /* Node's keys */ long *child; /* Node's child subtree offsets */ } btree_node; btree_node node; /* Single B-tree node */ node.n = 0; node.key = (int *) calloc( order - 1, sizeof( int ) ); node.child = (long *) calloc( order, sizeof( long ) ); Note. Be careful when you're reading and writing data structures with dynamically allocated memory. For example, trying to write node like this fwrite( &node, sizeof( btree_node ), 1, fp ); will write node's key count, the pointer value for its key array, and the pointer value for its child offset array, but it will not write the contents of the key and child offset arrays. The arrays' contents and not pointers to their contents need to be written explicitly instead. fwrite( &node.n, sizeof( int ), 1, fp ); fwrite( node.key, sizeof( int ), order - 1, fp ); fwrite( node.child, sizeof( long ), order, fp ); Reading node structures from disk would use a similar strategy. Root Node Offset In order to manage any tree, you need to locate its root node. Initially the root node will be stored near the front of index.bin. If the root node splits, however, a new root will be appended to the end of index.bin. The root node's offset will be maintained persistently by storing it at the front of index.bin when the file is closed, and reading it when the file is opened. #include <stdio.h> FILE *fp; /* Input file stream */ long root; /* Offset of B-tree root node */ fp = fopen( "index.bin", "r+b" ); /* If file doesn't exist, set root offset to unknown and create * file, otherwise read the root offset at the front of the file */ if ( fp == NULL ) { root = -1; fp = fopen( "index.bin", "w+b" ); fwrite( &root, sizeof( long ), 1, fp ); } else { fread( &root, sizeof( long ), 1, fp ); } User Interface The user will communicate with your program through a set of commands typed at the keyboard. Your program must support four simple commands: add k Add a new integer key with value k to index.bin. find k Find an entry with a key value of k in index.bin, if it exists. print Print the contents and the structure of the B-tree on-screen. end Update the root node's offset at the front of the index.bin, and close the index file, and end the program. Add Use a standard B-tree algorithm to add a new key k to the index file. Search the B-tree for the leaf node L responsible for k. If k is stored in L's key list, print Entry with key=k already exists on-screen and stop, since duplicate keys are not allowed. Create a new key list K that contains L's keys, plus k, sorted in ascending order. If L's key list is not full, replace it with K, update L's child offsets, write L back to disk, and stop. Otherwise, split K about its median key value km into left and right key lists KL = (k0, ... , km-1) and KR = (km+1, ... , kn-1). Use ceiling to calculate m = ⌈(n-1)/2⌉. For example, if n = 3, m = 1. If n = 4, m = 2. Save KL and its associated child offsets in L, then write L back to disk. Save KR and its associated child offsets in a new node R, then append R to the end of the index file. Promote km , L's offset, and R's offset and insert them in L's parent node. If the parent's key list is full, recursively split its list and promote the median to its parent. If a promotion is made to a root node with a full key list, split and create a new root node holding km and offsets to L and R. Find To find key value k in the index file, search the root node for k. If k is found, the search succeeds. Otherwise, determine the child subtree S that is responsible for k, then recursively search S. If k is found during the recursive search, print Entry with key=k exists on-screen. If at any point in the recursion S does not exist, print Entry with key=k does not exist on-screen. Print This command prints the contents of the B-tree on-screen, level by level. Begin by considering a single B-tree node. To print the contents of the node on-screen, print its key values separated by commas. int i; /* Loop counter */ btree_node node; /* Node to print */ long off; /* Node's offset */ for( i = 0; i < node.n - 1; i++ ) { printf( "%d,", node.key[ i ] ); } printf( "%d", node.key[ node.n - 1 ] ); To print the entire tree, start by printing the root node. Next, print the root node's children on a new line, separating each child node's output by a space character. Then, print their children on a new line, and so on until all the nodes in the tree are printed. This approach prints the nodes on each level of the B-tree left-to-right on a common line. For example, inserting the integers 1 through 13 inclusive into an order-4 B-tree would produce the following output. 1: 9 2: 3,6 12 3: 1,2 4,5 7,8 10,11 13 To support trees with more than 9 levels, we leave space for two characters to print the level at the beginning of each line, that is, using printf( "%2d: ", lvl )" or something similar. Hint. To process nodes left-to-right level-by-level, do not use recursion. Instead, create a queue containing the root node's offset. Remove the offset at the front of the queue (initially the root's offset) and read the corresponding node from disk. Append the node's non-empty subtree offsets to the end of the queue, then print the node's key values. Continue until the queue is empty. End This command ends the program by writing the root node's offset to the front of index.bin, then closing the index file. Programming Environment All programs must be written in C, and compiled to run on the remote.eos.ncsu.edu Linux server. Any ssh client can be used to access your Unity account and AFS storage space on this machine. Your assignment will be run automatically, and the output it produces will be compared to known, correct output using diff. Because of this, your output must conform to the print command's description. If it doesn't, diff will report your output as incorrect, and it will be marked accordingly. Supplemental Material In order to help you test your program, we provide example input and output files. input-01.txt, an input file of commands applied to an initially empty index file saved as an order-4 B-tree, and input-02.txt, an input file of commands applied to the index file produced by input-01.txt. The output files show what your program should print after each input file is processed. output-01.txt, the output your program should produce after it processes input-01.txt. output-02.txt, the output your program should produce after it processes input-02.txt. To test your program, you would issue the following commands: % rm index.bin % assn_4 index.bin 4 < input-01.txt > my-output-01.txt % assn_4 index.bin 4 < input-02.txt > my-output-02.txt You can use diff to compare output from your program to our output files. If your program is running properly and your output is formatted correctly, your program should produce output identical to what is in these files. Please remember, the files we're providing here are meant to serve as examples only. Apart from holding valid commands, you cannot make any assumptions about the size or the content of the input files we will use to test your program. Test Files The following files were used to test your program. Order 3 Test Case. input-03.txt output-03-first.txt Order 4 Test Case. input-04.txt output-04-first.txt Order 10 Test Case. input-10-01.txt, input-10-02.txt output-10-01.txt, output-10-02.txt Order 20 Test Case. input-20.txt output-20-first.txt Your program was run on all test cases using order-3, order-4, and order-20 B-trees. % rm index.bin % assn_4 index.bin 3 < input-03.txt > my-output-03.txt % rm index.bin % assn_4 index.bin 4 < input-04.txt > my-output-04.txt % rm index.bin % assn_4 index.bin 20 < input-20.txt > my-output-20.txt Your program was also run twice using an order-10 B-tree, to test its ability to re-use an existing index file. % rm index.bin % assn_4 index.bin 10 < input-10-01.txt > my-output-10-01.txt % assn_4 index.bin 10 < input-10-02.txt > my-output-10-02.txt Hand-In Requirements Use Moodle (the online assignment submission software) to submit the following files: assn_4, a Linux executable of your finished assignment, and all associated source code files (these can be called anything you want). There are four important requirements that your assignment must satisfy. Your executable file must be named exactly as shown above. The program will be run and marked electronically using a script file, so using a different name means the executable will not be found, and subsequently will not be marked. Your program must be compiled to run on remote.eos.ncsu.edu. If we cannot run your program, we will not be able to mark it, and we will be forced to assign you a grade of 0. Your program must produce output that exactly matches the format described in the print command section of this assignment. If it doesn't, it will not pass our automatic comparison to known, correct output. You must submit your source code with your executable prior to the submission deadline. If you do not submit your source code, we cannot MOSS it to check for code similarity. Because of this, any assignment that does not include source code will be assigned a grade of 0. Updated 20-Dec-14
flybunctious
Introduction In this project, you will develop a simulator and multiple strategies for the dice game Hog. You will need to use control statements and higher-order functions together, as described in Sections 1.2 through 1.6 of Composing Programs. In Hog, two players alternate turns trying to be the first to end a turn with at least 100 total points. On each turn, the current player chooses some number of dice to roll, up to 10. That player's score for the turn is the sum of the dice outcomes. To spice up the game, we will play with some special rules: Pig Out. If any of the dice outcomes is a 1, the current player's score for the turn is 1. Example 1: The current player rolls 7 dice, 5 of which are 1's. They score 1 point for the turn. Example 2: The current player rolls 4 dice, all of which are 3's. Since Pig Out did not occur, they score 12 points for the turn. Free Bacon. A player who chooses to roll zero dice scores one more than the largest digit in the opponent's total score. Example 1: If the opponent has 42 points, the current player gains 1 + max(4, 2) = 5 points by rolling zero dice. Example 2: If the opponent has 48 points, the current player gains 1 + max(4, 8) = 9 points by rolling zero dice. Example 3: If the opponent has 7 points, the current player gains 1 + max(0, 7) = 8 points by rolling zero dice. Swine Swap. After points for the turn are added to the current player's score, if both scores are larger than 1 and either one of the scores is a positive integer multiple of the other, then the two scores are swapped. Example 1: The current player has a total score of 37 and the opponent has 92. The current player rolls two dice that total 9. The opponent's score (92) is exactly twice the player's new total score (46). These scores are swapped! The current player now has 92 points and the opponent has 46. The turn ends. Example 2: The current player has 91 and the opponent has 37. The current player rolls five dice that total 20. The current player has 111, which is 3 times 37, so the scores are swapped. The opponent ends the turn with 111 and wins the game. Download starter files To get started, download all of the project code as a zip archive. You only have to make changes to hog.py. hog.py: A starter implementation of Hog dice.py: Functions for rolling dice hog_gui.py: A graphical user interface for Hog ucb.py: Utility functions for CS 61A ok: CS 61A autograder tests: A directory of tests used by ok images: A directory of images used by hog_gui.py Logistics This is a 2-week project. This is a solo project, so you will complete this project without a partner. You should not share your code with any other students, or copy from anyone else's solutions. Remember that you can earn an additional bonus point by submitting the project at least 24 hours before the deadline. The project is worth 20 points. 18 points are assigned for correctness, and 2 points for the overall composition of your program. You will turn in the following files: hog.py You do not need to modify or turn in any other files to complete the project. To submit the project, run the following command: python3 ok --submit You will be able to view your submissions on the Ok dashboard. For the functions that we ask you to complete, there may be some initial code that we provide. If you would rather not use that code, feel free to delete it and start from scratch. You may also add new function definitions as you see fit. However, please do not modify any other functions. Doing so may result in your code failing our autograder tests. Also, please do not change any function signatures (names, argument order, or number of arguments). Testing Throughout this project, you should be testing the correctness of your code. It is good practice to test often, so that it is easy to isolate any problems. However, you should not be testing too often, to allow yourself time to think through problems. We have provided an autograder called ok to help you with testing your code and tracking your progress. The first time you run the autograder, you will be asked to log in with your Ok account using your web browser. Please do so. Each time you run ok, it will back up your work and progress on our servers. The primary purpose of ok is to test your implementations, but there are two things you should be aware of. First, some of the test cases are locked. To unlock tests, run the following command from your terminal: python3 ok -u This command will start an interactive prompt that looks like: ===================================================================== Assignment: The Game of Hog Ok, version ... ===================================================================== ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Unlocking tests At each "? ", type what you would expect the output to be. Type exit() to quit --------------------------------------------------------------------- Question 0 > Suite 1 > Case 1 (cases remaining: 1) >>> Code here ? At the ?, you can type what you expect the output to be. If you are correct, then this test case will be available the next time you run the autograder. The idea is to understand conceptually what your program should do first, before you start writing any code. Once you have unlocked some tests and written some code, you can check the correctness of your program using the tests that you have unlocked: python3 ok Most of the time, you will want to focus on a particular question. Use the -q option as directed in the problems below. We recommend that you submit after you finish each problem. Only your last submission will be graded. It is also useful for us to have more backups of your code in case you run into a submission issue. The tests folder is used to store autograder tests, so do not modify it. You may lose all your unlocking progress if you do. If you need to get a fresh copy, you can download the zip archive and copy it over, but you will need to start unlocking from scratch. If you do not want us to record a backup of your work or information about your progress, use the --local option when invoking ok. With this option, no information will be sent to our course servers. Graphical User Interface A graphical user interface (GUI, for short) is provided for you. At the moment, it doesn't work because you haven't implemented the game logic. Once you complete the play function, you will be able to play a fully interactive version of Hog! In order to render the graphics, make sure you have Tkinter, Python's main graphics library, installed on your computer. Once you've done that, you can run the GUI from your terminal: python3 hog_gui.py Once you complete the project, you can play against the final strategy that you've created! python3 hog_gui.py -f Phase 1: Simulator In the first phase, you will develop a simulator for the game of Hog. Problem 0 (0 pt) The dice.py file represents dice using non-pure zero-argument functions. These functions are non-pure because they may have different return values each time they are called. The documentation of dice.py describes the two different types of dice used in the project: Dice can be fair, meaning that they produce each possible outcome with equal probability. Example: six_sided. For testing functions that use dice, deterministic test dice always cycle through a fixed sequence of values that are passed as arguments to the make_test_dice function. Before we start writing any code, let's understand the make_test_dice function by unlocking its tests. python3 ok -q 00 -u This should display a prompt that looks like this: ===================================================================== Assignment: Project 1: Hog Ok, version v1.5.2 ===================================================================== ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Unlocking tests At each "? ", type what you would expect the output to be. Type exit() to quit --------------------------------------------------------------------- Question 0 > Suite 1 > Case 1 (cases remaining: 1) >>> test_dice = make_test_dice(4, 1, 2) >>> test_dice() ? You should type in what you expect the output to be. To do so, you need to first figure out what test_dice will do, based on the description above. You can exit the unlocker by typing exit() (without quotes). Typing Ctrl-C on Windows to exit out of the unlocker has been known to cause problems, so avoid doing so. Problem 1 (2 pt) Implement the roll_dice function in hog.py. It takes two arguments: a positive integer called num_rolls giving the number of dice to roll and a dice function. It returns the number of points scored by rolling the dice that number of times in a turn: either the sum of the outcomes or 1 (Pig Out). To obtain a single outcome of a dice roll, call dice(). You should call dice() exactly num_rolls times in the body of roll_dice. Remember to call dice() exactly num_rolls times even if Pig Out happens in the middle of rolling. In this way, we correctly simulate rolling all the dice together. Checking Your Work: Before writing any code, unlock the tests to verify your understanding of the question. python3 ok -q 01 -u Once you are done unlocking, begin implementing your solution. You can check your correctness with: python3 ok -q 01 If the tests don't pass, it's time to debug. You can observe the behavior of your function using Python directly. First, start the Python interpreter and load the hog.py file. python3 -i hog.py Then, you can call your roll_dice function on any number of dice you want, such as 4. >>> roll_dice(4) In most systems, you can evaluate the same expression again by pressing the up arrow or Control-P, then pressing enter or return. You should find that evaluating this call expression gives a different answer each time, since dice rolls are random. The roll_dice function has a default argument value for dice that is a random six-sided dice function. You can also use test dice that fix the outcomes of the dice in advance. For example, rolling twice when you know that the dice will come up 3 and 4 should give a total outcome of 7. >>> fixed_dice = make_test_dice(3, 4) >>> roll_dice(2, fixed_dice) 7 If you find a problem, you need to change your hog.py file, save it, quit Python, start it again, and then start evaluating expressions. Pressing the up arrow should give you access to your previous expressions, even after restarting Python. Once you think that your roll_dice function is correct, run the ok tests again. Tests like these don't prove that your program is exactly correct, but they help you build confidence that this part of your program does what you expect, so that you can trust the abstraction it defines as you proceed. Problem 2 (1 pt) Implement the free_bacon helper function that returns the number of points scored by rolling 0 dice, based on the opponent's current score. You can assume that score is less than 100. For a score less than 10, assume that the first of the two digits is 0. Before writing any code, unlock the tests to verify your understanding of the question. python3 ok -q 02 -u Once you are done unlocking, begin implementing your solution. You can check your correctness with: python3 ok -q 02 You can also test free_bacon interactively by entering python3 -i hog.py in the terminal and then calling free_bacon with various inputs. Problem 3 (1 pt) Implement the take_turn function, which returns the number of points scored for a turn by the current player. Your implementation should call roll_dice when possible. You will need to implement the Free Bacon rule. You can assume that opponent_score is less than 100. Call free_bacon in your implementation of take_turn. Before writing any code, unlock the tests to verify your understanding of the question. python3 ok -q 03 -u Once you are done unlocking, begin implementing your solution. You can check your correctness with: python3 ok -q 03 Problem 4 (1 pt) Implement is_swap, which returns whether or not the scores should be swapped because one is an integer multiple of the other. The is_swap function takes two arguments: the player scores. It returns a boolean value to indicate whether the Swine Swap condition is met. Before writing any code, unlock the tests to verify your understanding of the question. python3 ok -q 04 -u Once you are done unlocking, begin implementing your solution. You can check your correctness with: python3 ok -q 04 Problem 5 (3 pt) Implement the play function, which simulates a full game of Hog. Players alternate turns, each using their respective strategy function (Player 0 uses strategy0, etc.), until one of the players reaches the goal score. When the game ends, play returns the final total scores of both players, with Player 0's score first, and Player 1's score second. Here are some hints: You should use the functions you have already written! You will need to call take_turn with all three arguments. Only call take_turn once per turn. Enforce all the special rules. You can get the number of the other player (either 0 or 1) by calling the provided function other. You can ignore the say argument to the play function for now. You will use it in Phase 2 of the project. A strategy is a function that, given a player's score and their opponent's score, returns how many dice the player wants to roll. A strategy function (such as strategy0 and strategy1) takes two arguments: scores for the current player and opposing player, which both must be non-negative integers. A strategy function returns the number of dice that the current player wants to roll in the turn. Each strategy function should be called only once per turn. Don't worry about the details of implementing strategies yet. You will develop them in Phase 3. Before writing any code, unlock the tests to verify your understanding of the question. python3 ok -q 05 -u Once you are done unlocking, begin implementing your solution. You can check your correctness with: python3 ok -q 05 The last test for Question 5 is a fuzz test, which checks that your play function works for a large number of different inputs. Failing this test means something is wrong, but you should look at other tests to see where the problem might be. Once you are finished, you will be able to play a graphical version of the game. We have provided a file called hog_gui.py that you can run from the terminal: python3 hog_gui.py If you don't already have Tkinter (Python's graphics library) installed, you'll need to install it first before you can run the GUI. The GUI relies on your implementation, so if you have any bugs in your code, they will be reflected in the GUI. This means you can also use the GUI as a debugging tool; however, it's better to run the tests first. Congratulations! You have finished Phase 1 of this project! Phase 2: Commentary In the second phase, you will implement commentary functions that print remarks about the game, such as, "22 points! That's the biggest gain yet for Player 1." A commentary function takes two arguments, the current score for Player 0 and the current score for Player 1. It returns another commentary function to be called on the next turn. It may also print some output as a side effect of being called. The function say_scores in hog.py is an example of a commentary function. The function announce_lead_changes is an example of a higher-order function that returns a commentary function. def say_scores(score0, score1): """A commentary function that announces the score for each player.""" print("Player 0 now has", score0, "and Player 1 now has", score1) return say_scores def announce_lead_changes(previous_leader=None): """Return a commentary function that announces lead changes. >>> f0 = announce_lead_changes() >>> f1 = f0(5, 0) Player 0 takes the lead by 5 >>> f2 = f1(5, 12) Player 1 takes the lead by 7 >>> f3 = f2(8, 12) >>> f4 = f3(8, 13) >>> f5 = f4(15, 13) Player 0 takes the lead by 2 """ def say(score0, score1): if score0 > score1: leader = 0 elif score1 > score0: leader = 1 else: leader = None if leader != None and leader != previous_leader: print('Player', leader, 'takes the lead by', abs(score0 - score1)) return announce_lead_changes(leader) return say Problem 6 (2 pt) Update your play function so that a commentary function is called at the end of each turn. say(score0, score1) should be called at the end of the first turn. Its return value (another commentary function) should be called at the end of the second turn. Each turn, a new commentary function should be called that is the return value of the previous call to a commentary function. Also implement both, a function that takes two commentary functions (f and g) and returns a new commentary function. This new commentary function returns another commentary function which calls the functions returned by calling f and g, in that order. Before writing any code, unlock the tests to verify your understanding of the question. python3 ok -q 06 -u Once you are done unlocking, begin implementing your solution. You can check your correctness with: python3 ok -q 06 Problem 7 (2 pt) Implement the announce_highest function, which is a higher-order function that returns a commentary function. This commentary function announces whenever a particular player gains more points in a turn than ever before. To compute the gain, it must compare the score from last turn to the score from this turn for the player of interest, which is designated by the who argument. This function must also keep track of the highest gain for the player so far. The way in which announce_highest announces is very specific, and your implementation should match the doctests provided. Notice in particular that if the gain is only 1 point, then the message includes "point" in singular form. If the gain is larger, then the message includes "points" in plural form. Use Ok to test your code: python3 ok -q 07 Hint. The announce_lead_changes function provided to you is an example of how to keep track of information using commentary functions. If you are stuck, first make sure you understand how announce_lead_changes works. When you are done, if play the game again, you will see the commentary. python3 hog_gui.py The commentary in the GUI is generated by passing the following function as the say argument to play. both(announce_highest(0), both(announce_highest(1), announce_lead_changes())) Great work! You just finished Phase 2 of the project! Phase 3: Strategies In the third phase, you will experiment with ways to improve upon the basic strategy of always rolling a fixed number of dice. First, you need to develop some tools to evaluate strategies. Problem 8 (2 pt) Implement the make_averaged function, which is a higher-order function that takes a function fn as an argument. It returns another function that takes the same number of arguments as fn (the function originally passed into make_averaged). This returned function differs from the input function in that it returns the average value of repeatedly calling fn on the same arguments. This function should call fn a total of num_samples times and return the average of the results. To implement this function, you need a new piece of Python syntax! You must write a function that accepts an arbitrary number of arguments, then calls another function using exactly those arguments. Here's how it works. Instead of listing formal parameters for a function, we write *args. To call another function using exactly those arguments, we call it again with *args. For example, >>> def printed(fn): ... def print_and_return(*args): ... result = fn(*args) ... print('Result:', result) ... return result ... return print_and_return >>> printed_pow = printed(pow) >>> printed_pow(2, 8) Result: 256 256 >>> printed_abs = printed(abs) >>> printed_abs(-10) Result: 10 10 Read the docstring for make_averaged carefully to understand how it is meant to work. Before writing any code, unlock the tests to verify your understanding of the question. python3 ok -q 08 -u Once you are done unlocking, begin implementing your solution. You can check your correctness with: python3 ok -q 08 Problem 9 (1 pt) Implement the max_scoring_num_rolls function, which runs an experiment to determine the number of rolls (from 1 to 10) that gives the maximum average score for a turn. Your implementation should use make_averaged and roll_dice. If two numbers of rolls are tied for the maximum average score, return the lower number. For example, if both 3 and 6 achieve a maximum average score, return 3. Before writing any code, unlock the tests to verify your understanding of the question. python3 ok -q 09 -u Once you are done unlocking, begin implementing your solution. You can check your correctness with: python3 ok -q 09 To run this experiment on randomized dice, call run_experiments using the -r option: python3 hog.py -r Running experiments For the remainder of this project, you can change the implementation of run_experiments as you wish. By calling average_win_rate, you can evaluate various Hog strategies. For example, change the first if False: to if True: in order to evaluate always_roll(8) against the baseline strategy of always_roll(4). You should find that it wins slightly more often than it loses, giving a win rate around 0.5. Some of the experiments may take up to a minute to run. You can always reduce the number of samples in make_averaged to speed up experiments. Problem 10 (1 pt) A strategy can take advantage of the Free Bacon rule by rolling 0 when it is most beneficial to do so. Implement bacon_strategy, which returns 0 whenever rolling 0 would give at least margin points and returns num_rolls otherwise. Before writing any code, unlock the tests to verify your understanding of the question. python3 ok -q 10 -u Once you are done unlocking, begin implementing your solution. You can check your correctness with: python3 ok -q 10 Once you have implemented this strategy, change run_experiments to evaluate your new strategy against the baseline. You should find that it wins more than half of the time. Problem 11 (2 pt) A strategy can also take advantage of the Swine Swap rule. The swap_strategy rolls 0 if it would cause a beneficial swap. It also returns 0 if rolling 0 would give at least margin points and would not cause a swap. Otherwise, the strategy rolls num_rolls. Before writing any code, unlock the tests to verify your understanding of the question. python3 ok -q 11 -u Once you are done unlocking, begin implementing your solution. You can check your correctness with: python3 ok -q 11 Once you have implemented this strategy, update run_experiments to evaluate your new strategy against the baseline. You should find that it gives a significant edge over always_roll(4). Optional: Problem 12 (0 pt) Implement final_strategy, which combines these ideas and any other ideas you have to achieve a high win rate against the always_roll(4) strategy. Some suggestions: swap_strategy is a good default strategy to start with. There's no point in scoring more than 100. Check whether you can win by rolling 0, 1 or 2 dice. If you are in the lead, you might take fewer risks. Try to force a beneficial swap. Choose the num_rolls and margin arguments carefully. You can check that your final strategy is valid by running Ok. python3 ok -q 12 You can also check your exact final winrate by running python3 calc.py At this point, run the entire autograder to see if there are any tests that don't pass. python3 ok Once you are satisfied, submit to Ok to complete the project. python3 ok --submit You can also play against your final strategy with the graphical user interface: python3 hog_gui.py -f The GUI will alternate which player is controlled by you. Congratulations, you have reached the end of your first CS 61A project! If you haven't already, relax and enjoy a few games of Hog with a friend.
thehuy2000
In this assignment you will write smallsh your own shell in C. smallsh will implement a subset of features of well-known shells, such as bash. Your program will Provide a prompt for running commands Handle blank lines and comments, which are lines beginning with the # character Provide expansion for the variable $$ Execute 3 commands exit, cd, and status via code built into the shell Execute other commands by creating new processes using a function from the exec family of functions Support input and output redirection Support running commands in foreground and background processes Implement custom handlers for 2 signals, SIGINT and SIGTSTP Learning Outcomes After successful completion of this assignment, you should be able to do the following Describe the Unix process API (Module 4, MLO 2) Write programs using the Unix process API (Module 4, MLO 3) Explain the concept of signals and their uses (Module 5, MLO 2) Write programs using the Unix API for signal handling (Module 5, MLO 3) Explain I/O redirection and write programs that can employ I/O redirection (Module 5, MLO 4) Program Functionality 1. The Command Prompt Use the colon : symbol as a prompt for each command line. The general syntax of a command line is: command [arg1 arg2 ...] [< input_file] [> output_file] [&] …where items in square brackets are optional. You can assume that a command is made up of words separated by spaces. The special symbols <, > and & are recognized, but they must be surrounded by spaces like other words. If the command is to be executed in the background, the last word must be &. If the & character appears anywhere else, just treat it as normal text. If standard input or output is to be redirected, the > or < words followed by a filename word must appear after all the arguments. Input redirection can appear before or after output redirection. Your shell does not need to support any quoting; so arguments with spaces inside them are not possible. We are also not implementing the pipe "|" operator. Your shell must support command lines with a maximum length of 2048 characters, and a maximum of 512 arguments. You do not need to do any error checking on the syntax of the command line. 2. Comments & Blank Lines Your shell should allow blank lines and comments. Any line that begins with the # character is a comment line and should be ignored. Mid-line comments, such as the C-style //, will not be supported. A blank line (one without any commands) should also do nothing. Your shell should just re-prompt for another command when it receives either a blank line or a comment line. 3. Expansion of Variable $$ Your program must expand any instance of "$$" in a command into the process ID of the smallsh itself. Your shell does not otherwise perform variable expansion. 4. Built-in Commands Your shell will support three built-in commands: exit, cd, and status. These three built-in commands are the only ones that your shell will handle itself - all others are simply passed on to a member of the exec() family of functions. You do not have to support input/output redirection for these built in commands These commands do not have to set any exit status. If the user tries to run one of these built-in commands in the background with the & option, ignore that option and run the command in the foreground anyway (i.e. don't display an error, just run the command in the foreground). exit The exit command exits your shell. It takes no arguments. When this command is run, your shell must kill any other processes or jobs that your shell has started before it terminates itself. cd The cd command changes the working directory of smallsh. By itself - with no arguments - it changes to the directory specified in the HOME environment variable This is typically not the location where smallsh was executed from, unless your shell executable is located in the HOME directory, in which case these are the same. This command can also take one argument: the path of a directory to change to. Your cd command should support both absolute and relative paths. status The status command prints out either the exit status or the terminating signal of the last foreground process ran by your shell. If this command is run before any foreground command is run, then it should simply return the exit status 0. The three built-in shell commands do not count as foreground processes for the purposes of this built-in command - i.e., status should ignore built-in commands. 5. Executing Other Commands Your shell will execute any commands other than the 3 built-in command by using fork(), exec() and waitpid() Whenever a non-built in command is received, the parent (i.e., smallsh) will fork off a child. The child will use a function from the exec() family of functions to run the command. Your shell should use the PATH variable to look for non-built in commands, and it should allow shell scripts to be executed If a command fails because the shell could not find the command to run, then the shell will print an error message and set the exit status to 1 A child process must terminate after running a command (whether the command is successful or it fails). 6. Input & Output Redirection You must do any input and/or output redirection using dup2(). The redirection must be done before using exec() to run the command. An input file redirected via stdin should be opened for reading only; if your shell cannot open the file for reading, it should print an error message and set the exit status to 1 (but don't exit the shell). Similarly, an output file redirected via stdout should be opened for writing only; it should be truncated if it already exists or created if it does not exist. If your shell cannot open the output file it should print an error message and set the exit status to 1 (but don't exit the shell). Both stdin and stdout for a command can be redirected at the same time (see example below). 7. Executing Commands in Foreground & Background Foreground Commands Any command without an & at the end must be run as a foreground command and the shell must wait for the completion of the command before prompting for the next command. For such commands, the parent shell does NOT return command line access and control to the user until the child terminates. Background Commands Any non built-in command with an & at the end must be run as a background command and the shell must not wait for such a command to complete. For such commands, the parent must return command line access and control to the user immediately after forking off the child. The shell will print the process id of a background process when it begins. When a background process terminates, a message showing the process id and exit status will be printed. This message must be printed just before the prompt for a new command is displayed. If the user doesn't redirect the standard input for a background command, then standard input should be redirected to /dev/null If the user doesn't redirect the standard output for a background command, then standard output should be redirected to /dev/null 8. Signals SIGINT & SIGTSTP SIGINT A CTRL-C command from the keyboard sends a SIGINT signal to the parent process and all children at the same time (this is a built-in part of Linux). Your shell, i.e., the parent process, must ignore SIGINT Any children running as background processes must ignore SIGINT A child running as a foreground process must terminate itself when it receives SIGINT The parent must not attempt to terminate the foreground child process; instead the foreground child (if any) must terminate itself on receipt of this signal. If a child foreground process is killed by a signal, the parent must immediately print out the number of the signal that killed it's foreground child process (see the example) before prompting the user for the next command. SIGTSTP A CTRL-Z command from the keyboard sends a SIGTSTP signal to your parent shell process and all children at the same time (this is a built-in part of Linux). A child, if any, running as a foreground process must ignore SIGTSTP. Any children running as background process must ignore SIGTSTP. When the parent process running the shell receives SIGTSTP The shell must display an informative message (see below) immediately if it's sitting at the prompt, or immediately after any currently running foreground process has terminated The shell then enters a state where subsequent commands can no longer be run in the background. In this state, the & operator should simply be ignored, i.e., all such commands are run as if they were foreground processes. If the user sends SIGTSTP again, then your shell will Display another informative message (see below) immediately after any currently running foreground process terminates The shell then returns back to the normal condition where the & operator is once again honored for subsequent commands, allowing them to be executed in the background. See the example below for usage and the exact syntax which you must use for these two informative messages. Sample Program Execution Here is an example run using smallsh. Note that CTRL-C has no effect towards the bottom of the example, when it's used while sitting at the command prompt: $ smallsh : ls junk smallsh smallsh.c : ls > junk : status exit value 0 : cat junk junk smallsh smallsh.c : wc < junk > junk2 : wc < junk 3 3 23 : test -f badfile : status exit value 1 : wc < badfile cannot open badfile for input : status exit value 1 : badfile badfile: no such file or directory : sleep 5 ^Cterminated by signal 2 : status & terminated by signal 2 : sleep 15 & background pid is 4923 : ps PID TTY TIME CMD 4923 pts/0 00:00:00 sleep 4564 pts/0 00:00:03 bash 4867 pts/0 00:01:32 smallsh 4927 pts/0 00:00:00 ps : : # that was a blank command line, this is a comment line : background pid 4923 is done: exit value 0 : # the background sleep finally finished : sleep 30 & background pid is 4941 : kill -15 4941 background pid 4941 is done: terminated by signal 15 : pwd /nfs/stak/users/chaudhrn/CS344/prog3 : cd : pwd /nfs/stak/users/chaudhrn : cd CS344 : pwd /nfs/stak/users/chaudhrn/CS344 : echo 4867 4867 : echo $$ 4867 : ^C^Z Entering foreground-only mode (& is now ignored) : date Mon Jan 2 11:24:33 PST 2017 : sleep 5 & : date Mon Jan 2 11:24:38 PST 2017 : ^Z Exiting foreground-only mode : date Mon Jan 2 11:24:39 PST 2017 : sleep 5 & background pid is 4963 : date Mon Jan 2 11:24:39 PST 2017 : exit $ Hints & Resources 1. The Command Prompt Be sure you flush out the output buffers each time you print, as the text that you're outputting may not reach the screen until you do in this kind of interactive program. To do this, call fflush() immediately after each and every time you output text. Consider defining a struct in which you can store all the different elements included in a command. Then as you parse a command, you can set the value of members of a variable of this struct type. 2. Comments & Blank Lines This should be simple. 3. Expansion of Variable $$ Here are examples to illustrate the required behavior. Suppose the process ID of smallsh is 179. Then The string foo$$$$ in the command is converted to foo179179 The string foo$$$ in the command is converted to foo179$ 4. Built-in Commands It is recommended that you program the built-in commands first, before tackling the commands that require fork(), exec() and waitpid(). The built-in commands don't set the value of status. This means that however you are keeping track of the status, don't change it after the execution of a built-in command. A process can use chdir() (Links to an external site.) to change its directory. To test the implementation of the cd command in smallsh, don't use getenv("PWD") because it will not give you the correct result. Instead, you can use the function getcwd() (Links to an external site.). Here is why getenv("PWD") doesn't give you the correct result: PWD is an environment variable. As discussed in Module 4, Exploration: Environment "When a parent process forks a child process, the child process inherits the environment of its parent process." When you run smallsh from a bash shell, smallsh inherits the environment of this bash shell The value of PWD in the bash shell is set to the directory in which you are when you run the command to start smallsh smallsh inherits this value of PWD. When you change the directory in smallsh, it doesn't update the value of the environment variable PWD 5. Executing Other Commands Note that if exec() is told to execute something that it cannot do, like run a program that doesn't exist, it will fail, and return the reason why. In this case, your shell should indicate to the user that a command could not be executed (which you know because exec() returned an error), and set the value retrieved by the built-in status command to 1. Make sure that the child process that has had an exec() call fail terminates itself, or else it often loops back up to the top and tries to become a parent shell. This is easy to spot: if the output of the grading script seems to be repeating itself, then you've likely got a child process that didn't terminate after a failed exec(). You can choose any function in the exec() family. However, we suggest that using either execlp() or execvp() will be simplest because of the following reasons smallsh doesn't need to pass a new environment to the program. So the additional functionality provided by the exec() functions with names ending in e is not required. One example of a command that smallsh needs to run is ls (the graders will try this command at the start of the testing). Running this command will be a lot easier using the exec() functions that search the PATH environment variable. 6. Input & Output Redirection We recommend that the needed input/output redirection should be done in the child process. Note that after using dup2() to set up the redirection, the redirection symbol and redirection destination/source are NOT passed into the exec command For example, if the command given is ls > junk, then you handle the redirection to "junk" with dup2() and then simply pass ls into exec(). 7. Executing Commands in Foreground & Background Foreground Commands For a foreground command, it is recommend to have the parent simply call waitpid() on the child, while it waits. Background Commands The shell should respect the input and output redirection operators for a command regardless of whether the command is to be run in the foreground or the background. This means that a background command should use /dev/null for input only when input redirection is not specified in the command. Similarly a background command should use /dev/null for output only when output redirection is not specified in the command. Your parent shell will need to periodically check for the background child processes to complete, so that they can be cleaned up, as the shell continues to run and process commands. Consider storing the PIDs of non-completed background processes in an array. Then every time BEFORE returning access to the command line to the user, you can check the status of these processes using waitpid(...NOHANG...). Alternatively, you may use a signal handler to immediately wait() for child processes that terminate, as opposed to periodically checking a list of started background processes The time to print out when these background processes have completed is just BEFORE command line access and control are returned to the user, every time that happens. 8. Signals SIGINT & SIGTSTP Reentrancy is important when we consider that signal handlers cause jumps in execution that cause problems with certain functions. Note that the printf() family of functions is NOT reentrant. In your signal handlers, when outputting text, you must use other output functions! What to turn in? You can only use C for coding this assignment and you must use the gcc compiler. You can use C99 or GNU99 standard or the default standard used by the gcc installation on os1. Your assignment will be graded on os1. Submit a single zip file with all your code, which can be in as many different files as you want. This zip file must be named youronid_program3.zip where youronid should be replaced by your own ONID. E.g., if chaudhrn was submitting the assignment, the file must be named chaudhrn_program3.zip. In the zip file, you must include a text file called README.txt that contains instructions on how to compile your code using gcc to create an executable file that must be named smallsh. Your zip file should not contain any extraneous files. In particular, make sure not to zip up the __MACOSX directories. When you resubmit a file in Canvas, Canvas can attach a suffix to the file, e.g., the file name may become chaudhrn_program3-1.zip. Don't worry about this name change as no points will be deducted because of this. Caution During the development of this program, take extra care to only do your work on os1, our class server, as your software will likely negatively impact whatever machine it runs on, especially before it is finished. If you cause trouble on one of the non-class, public servers, it could hurt your grade! If you are having trouble logging in to any of our EECS servers because of runaway processes, please use this page to kill off any programs running on your account that might be blocking your access: T.E.A.C.H. - The Engineering Accounts and Classes HomepageLinks to an external site. Grading Criteria This assignment is worth 20% of your grade and there are 180 points available for it. 170 points are available in the test script, while the final 10 points will be based on your style, readability, and commenting. Comment well, often, and verbosely: we want to see that you are telling us WHY you are doing things, in addition to telling us WHAT you are doing. Once the program is compiled, according to your specifications given in README.txt, your shell will be executed to run a few sample commands against (ls, status, exit, in that order). If the program does not successfully work on those commands, it will receive a zero. If it works, then the grading script will be run against it (as detailed below) for final grading. Points will be assigned according to the grading script running on our class server only. Grading Method Here is the grading script p3testscript. It is a bash script that starts the smallsh program and runs commands on smallsh's command line. Most of the commands run by the grading script are very similar to the commands shown in the section Sample Program Execution. You can open the script in a text editor. The comments in the script will show you the points for individual items. Use the script to prepare for your grade, as this is how it's being earned. To run the script, place it in the same directory as your compiled shell, chmod it (chmod +x ./p3testscript) and run this command from a bash prompt: $ ./p3testscript 2>&1 or $ ./p3testscript 2>&1 | more or $ ./p3testscript > mytestresults 2>&1 Do not worry if the spacing, indentation, or look of the output of the script is different than when you run it interactively: that won’t affect your grade. The script may add extra colons at the beginning of lines or do other weird things, like put output about terminating processes further down the script than you intended. If your program does not work with the grading script, and you instead request that we grade your script by hand, we will apply a 15% reduction to your final score. So from the very beginning, make sure that you work with the grading script on our class server!
rrbrink
Friend Finder - Node and Express Servers Overview In this activity, you'll build a compatibility-based "FriendFinder" application -- basically a dating app. This full-stack site will take in results from your users' surveys, then compare their answers with those from other users. The app will then display the name and picture of the user with the best overall match. You will use Express to handle routing. Make sure you deploy your app to Heroku so other users can fill it out. Before You Begin Check out this demo version of the site. Use this as a model for how we expect your assignment look and operate. Create a folder called FriendFinder. Inside the folder, organize your directories so it matches the following: FriendFinder - app - data - friends.js - public - home.html - survey.html - routing - apiRoutes.js - htmlRoutes.js - node_modules - package.json - server.js Instructions Your survey should have 10 questions of your choosing. Each answer should be on a scale of 1 to 5 based on how much the user agrees or disagrees with a question. Your server.js file should require the basic npm packages we've used in class: express, body-parser and path. Your htmlRoutes.js file should include two routes: A GET Route to /survey which should display the survey page. A default, catch-all route that leads to home.html which displays the home page. Your apiRoutes.js file should contain two routes: A GET route with the url /api/friends. This will be used to display a JSON of all possible friends. A POST routes /api/friends. This will be used to handle incoming survey results. This route will also be used to handle the compatibility logic. You should save your application's data inside of app/data/friends.js as an array of objects. Each of these objects should roughly follow the format below. { "name":"Ahmed", "photo":"https://media.licdn.com/mpr/mpr/shrinknp_400_400/p/6/005/064/1bd/3435aa3.jpg", "scores":[ 5, 1, 4, 4, 5, 1, 2, 5, 4, 1 ] } Determine the user's most compatible friend using the following as a guide: Convert each user's results into a simple array of numbers (ex: [5, 1, 4, 4, 5, 1, 2, 5, 4, 1]). With that done, compare the difference between current user's scores against those from other users, question by question. Add up the differences to calculate the totalDifference. Example: User 1: [5, 1, 4, 4, 5, 1, 2, 5, 4, 1] User 2: [3, 2, 6, 4, 5, 1, 2, 5, 4, 1] Total Difference: 2 + 1 + 2 = 5 Remember to use the absolute value of the differences. Put another way: no negative solutions! Your app should calculate both 5-3 and 3-5 as 2, and so on. The closest match will be the user with the least amount of difference. Once you've found the current user's most compatible friend, display the result as a modal pop-up. The modal should display both the name and picture of the closest match. Minimum Requirements Attempt to complete homework assignment as described in instructions. If unable to complete certain portions, please pseudocode these portions to describe what remains to be completed. Hosting on Heroku Now that we have a backend to our applications, we use Heroku for hosting. Please note that while Heroku is free, it will request credit card information if you have more than 5 applications at a time or are adding a database. Please see Heroku’s Account Verification Information for more details. One More Thing If you have any questions about this project or the material we have covered, please post them in the community channels in slack so that your fellow developers can help you! If you're still having trouble, you can come to office hours for assistance from your instructor and TAs. Good Luck! Copyright Coding Boot Camp (C) 2016. All Rights Reserved.
dakotale-zz
CSE4/589: PA1 Description CSE 489/589 Programming Assignment 1 Text Chat Application 1. Objectives Develop the client and server components of a text chat application, consisting of one chat server and multiple chat clients over TCP connections. 2. Getting Started 2.1 Socket Programming Beej Socket Guide: http://beej.us/guide/bgnet 2.2 Install the PA1 template Read the document at https://goo.gl/L2kgb5 in full and install the template. You should complete this step before reading further. It is mandatory to use this template. 3. Implementation 3.1 Programming environment You will write C (or C++) code that compiles under the GCC (GNU Compiler Collection) environment. Furthermore, you should ensure that your code compiles and operates correctly on 5 dedicated hosts/machines, which will be provided to you by the instructor. Your code should successfully compile using the version of gcc (for C code) or g++ (for C++ code) found on the 5 dedicated hosts and should function correctly when executed. NOTE: You are NOT allowed to use any external (not present by default on the dedicated hosts) libraries for the socket programming part. Bundling of code (or part of it) from external libraries with your source will not be accepted either. You can however use external modules for other parts of the assignment (like maintaining a linked list). If you are not sure whether you are allowed to use an external library or not, consult with the course staff. Further, your implementation should NOT invoke any external binaries (e.g., ifconfig, nslookup, etc.) and should NOT involve any disk I/O unless explicitly mentioned in the PA description. 3.2 Sockets Use TCP Sockets only for your implementation. Use the select() system call only for handling multiple socket connections. Do not use multi-threading or fork-exec. 3.3 Running your program Your program will take 2 command line parameters: The first parameter (s/c) indicates whether your program instance should run as a server or a client. The second parameter (number) is the port number on which your process will listen for incoming connections. In the rest of the document, this port is referred to as the listening port. E.g., if your executable is named chat_app: To run as a server listening on port 4322 ./chat_app s 4322 To run as a client listening on port 4322 ./chat_app c 4322 3.4 Dedicated Hosts For the purpose of this assignment, you should only use (for development and/or testing) the directory created for you on each of the 5 dedicated hosts. Change the access permission to this directory so that only you are allowed to access the contents of the directory. This is to prevent others from getting access to your code. 4. Output Format We will use automated tests to grade this assignment. The grader, among other things, will also look at the output generated by your program. Towards this end, ALL the required output (as described in section 5) generated by your program needs to be written to BOTH stdout and to a specific logfile. Later sections provide the exact format strings to be used for output, which need to be strictly followed. 4.1 Print and LOG We have already provided a convenience function for this purpose in the template (see src/logger.c and include/logger.h), which writes both to stdout and to the logfile. You should use ONLY this function, for all output described in this assignment. On the other hand, if you want to output something more to stdout (for debugging etc.) than what is described, do NOT use this function and rather use native C/C++ function calls. Any extra output in the log file will cause the test cases to fail. To use the function, you will need to have the following statement at the top of your .c/.cpp source file(s) where you want to use this function: #include “../include/logger.h” The function is designed to behave almost exactly as printf. You can use the function as: cse4589_print_and_log(char* format, ...) Read the comments above the function definition contained in the src/logger.c file, for more information on the arguments and return value. 5. Detailed Description The chat application follows a typical client-server model, whereby we will have one server instance and two or more client instances. Given that we will be testing on the five dedicated hosts listed before, you can assume that at most four clients will be online at any given time. The clients, when launched, log in to the server, identify themselves, and obtain the list of other clients that are connected to the server. Clients can either send a unicast message to any one of the other clients or a broadcast a message to all the other clients. Note that the clients maintain an active connection only with the server and not with any other clients. Consequently, all messages exchanged between the clients must flow through the server. Clients never exchange messages directly with each other. The server exists to facilitate the exchange of messages between the clients. The server can exchange control messages with the clients. Among other things, it maintains a list of all clients that are connected to it, and their related information (IP address, port number, etc.). Further, the server stores/buffers any messages destined to clients that are not logged-in at the time of the receipt of the message at the server from the sender, to be delivered at a later time when the client logs in to the server. You do NOT need to buffer messages for EXITed clients or from BLOCKed clients (see section 5.6). You can assume that the total number of buffered messages will not exceed 100. Your code, when compiled, will produce a single executable file. Depending on what arguments are passed to this executable (see section 3.3), a client or a server instance should be started. 5.1 Network and SHELL Dual Functionality When launched (either as server or client), your application should work like a UNIX shell accepting specific commands (described below), in addition to performing network operations required for the chat application to work. You will need to use the select() system call which will allow you to provide a user interface and perform network functions at the same time (simultaneously). 5.2 SHELL Commands Your application should accept commands only when they are inputted: In UPPER CASE. Having exactly the same syntax as described below. 5.3. SHELL Command Output [IMPORTANT] The first line of output of all the commands should declare whether it was successfully executed or it failed. If the command was successful, use the following format string: (“[%s:SUCCESS]\n”, command_str) //where command_str is the command inputted without its arguments If the command failed with error, use the following format string: (“[%s:ERROR]\n”, command_str) //where command_str is the command inputted without its arguments For all such required output, you should only use the special print/log function described in section 4. See section 5.4 (IP command) for an example code snippet. If the command is successful, it should immediately be followed by its real output (if any) as described in the sections below. Extra output lines in the log file between the success message and output will cause test cases to fail. The last line of the output of all the commands (whether success or failure) should use the following format string: (“[%s:END]\n”, command_str) //where command_str is the command inputted without its arguments For events, printing format/requirements will be the same as for commands. Each of the event’s description tells the value of the command_str you should use for it. 5.4 Server/Client SHELL Command Description This set of commands should work irrespective of whether the application is started as a server or a client. AUTHOR Print a statement using the following format string: (“I, %s, have read and understood the course academic integrity policy.\n”, your_ubit_name) Your submission will not be graded if the AUTHOR command fails to work. IP Print the IP address of this process. Note that this should not be the localhost address (127.0.0.1), but the external IP address. Use the following format string: (“IP:%s\n”, ip_addr) //where ip_addr is a null-terminated char array storing IP Example Code Snippet To generate the required output for this command, you would need the following lines in your code: //Successful cse4589_print_and_log(“[%s:SUCCESS]\n”, command_str); cse4589_print_and_log(“IP:%s\n”, ip_addr); cse4589_print_and_log(“[%s:END]\n”, command_str); //Error cse4589_print_and_log(“[%s:ERROR]\n”, command_str); cse4589_print_and_log(“[%s:END]\n”, command_str); Here, command_str and ip_str are char arrays containing “IP” and some valid IP address like “xxx.xx.xx.xx”, respectively. Any extra output in between the SUCCESS/ERROR and END output will cause the test cases to fail. PORT Print the port number this process is listening on. Use the following format string: (“PORT:%d\n”, port) LIST Display a numbered list of all the currently logged-in clients. The output should display the hostname, IP address, and the listening port numbers, sorted by their listening port numbers, in increasing order. E.g., 1 stones.cse.buffalo.edu 128.205.36.46 4545 2 embankment.cse.buffalo.edu 128.205.36.35 5000 3 highgate.cse.buffalo.edu 128.205.36.33 5499 4 euston.cse.buffalo.edu 128.205.36.34 5701 Use the following format string: /*The following printf will print out one host. Repeat this printf statement to * print all hosts * list_id: integer item number * hostname: null-terminated char array containing fully qualified hostname * ip_addr: null-terminated char array storing IP * port_num: integer storing listening port num */ ("%-5d%-35s%-20s%-8d\n", list_id, hostname, ip_addr, port_num) Notes: LIST output should contain all the currently logged-in clients, including the client that executed the command. The server should NOT be included in the output. If you do not implement the LIST command correctly, most automated tests for other commands will fail. 5.5 Server SHELL Command/Event Description This set of commands should work only when the application is started as a server. STATISTICS Display a numbered list of all the clients that have ever logged-in to the server (but have never executed the EXIT command) and statistics about each one. The output should display the hostname, #messages-sent, #messages-received, and the current status: logged-in/logged-out depending on whether the client is currently logged-in or not, sorted by their listening port numbers, in increasing order. E.g., 1 stones.cse.buffalo.edu 4 0 logged-in 2 embankment.cse.buffalo.edu 3 67 logged-out 3 highgate.cse.buffalo.edu 7 14 logged-in 4 euston.cse.buffalo.edu 11 23 logged-in Use the following format string: /*The following printf will print out one host. Repeat this printf statement to * print all hosts * list_id: integer item number * hostname: null-terminated char array containing fully qualified hostname * num_msg_sent: integer number of messages sent by the client * num_msg_rcv: integer number of messages received by the client */ * status: null-terminated char array containing logged-in or logged-out ("%-5d%-35s%-8d%-8d%-8s\n", list_id, hostname, num_msg_sent, num_msg_rcv, status) BLOCKED <client-ip> Display a numbered list of all the clients (see BLOCK command in section 5.6) blocked by the client with ip address: <client-ip>. The output should display the hostname, IP address, and the listening port numbers, sorted by their listening port numbers, in increasing order. The output format should be identical to that of the LIST command. Exceptions to be handled Invalid IP address Valid but incorrect/non-existent IP address [EVENT]: Message Relayed All messages exchanged between clients pass through (are relayed by) the server. In the event of relay of a message <msg> from a client with ip address: <from-client-ip> addressed to another client with ip address: <to-client-ip>, print/log the message using the following format string: ("msg from:%s, to:%s\n[msg]:%s\n", from-client-ip, to-client-ip, msg) In case of a broadcast message, <to-client-ip> will be 255.255.255.255 For the purposes of printing/logging, use command_str: RELAYED 5.6 Client SHELL Command/Event Description This set of commands should work only when the application is started as a client. LOGIN <server-ip> <server-port> This command is used by a client to login to the server located at ip address: <server-ip> listening on port: <server-port>. The LOGIN command takes 2 arguments. The first argument is the IP address of the server and the second argument is the listening port of the server. On successful registration, the server responds with: 1. List of all currently logged-in clients. The client should store this list for later display and use. 2. All the stored/buffered messages for this client in the order they were received at the server. Each of these messages will trigger an [EVENT]: Message Received, described at the end of this section. A client should not accept any other command, except LOGIN, EXIT, IP, PORT, and AUTHOR, or receive packets, unless it is successfully logged-in to the server. Notes You should NOT print the list of clients received as part of the output of the LOGIN command. The LOGIN SUCCESS/ERROR message should be printed after all the event related output (triggered by the buffered messages). Exceptions to be handled Invalid IP address/port number (e.g., 127.abc is an invalid IP; 43f is an invalid port). You can assume that a valid IP/port will always be the actual IP/listening port of the server. REFRESH Get an updated list of currently logged-in clients from the server. SEND <client-ip> <msg> Send message: <msg> to client with ip address: <client-ip>. <msg> can have a maximum length of 256 bytes and will consist of valid ASCII characters. Exceptions to be handled Invalid IP address. Valid IP address which does not exist in the local copy of the list of logged-in clients (This list may be outdated. Do not update it as a result of this check). BROADCAST <msg> Send message: <msg> to all logged-in clients. <msg> can have a maximum length of 256 bytes and will consist of valid ASCII characters. This should be a server-assisted broadcast. The sending client should send only one message to the server, indicating it is a broadcast. The server then forwards/relays this message to all the currently logged-in clients and stores/buffers the message for the others. Notes The client that executes BROADCAST should not receive the same message back. BLOCK <client-ip> Block all incoming messages (unicast and broadcast) from the client with IP address: <client-ip>. The client implementation should notify the server about this blocking. The server should not relay or store/buffer any messages from a blocked sender destined for the blocking client. The blocked sender, however, will be unaware about this blocking and should execute the SEND command without any error. Exceptions to be handled Invalid IP address. Valid IP address which does not exist in the local copy of the list of logged-in clients (This list may be outdated. Do not update it as a result of this check). Client with IP address: <client-ip> is already blocked. UNBLOCK <client-ip> Unblock a previously blocked client with IP address: <client-ip>. The client implementation should notify the server about the unblocking. Exceptions to be handled Invalid IP address. Valid IP address which does not exist in the local copy of the list of logged-in clients (This list may be outdated. Do not update it as a result of this check). Client with IP address: <client-ip> is not blocked. LOGOUT Logout from the server. However, your application should not exit and continue to accept LOGIN, EXIT, IP, PORT, and AUTHOR commands. In general, on LOGOUT all state related to this client is maintained on both the client and the server. Notes LOGOUT does NOT reset the statistic counters (see STATISTICS command in section 5.5). LOGOUT does NOT unblock any clients blocked by this client. LOGOUT does NOT change the blocked/unblocked status of this client on the server. EXIT Logout from the server (if logged-in) and terminate the application with exit code 0. This should delete all the state for this client on the server. You can assume that an EXITed client will never start again. [EVENT]: Message Received In the event of receipt of a message <msg> from a client with ip address: <client-ip>, print/log the message using the following format string: ("msg from:%s\n[msg]:%s\n", client-ip, msg) Note that <client-ip> here is the IP address of the original sender, not of the relaying server. For the purposes of printing/logging, use command_str: RECEIVED 5.7 BONUS: Peer-to-peer (P2P) file transfer Implement additional functionality to allow clients to send/receive files. Here, however, the transfer will take place directly between two clients and will not involve the server. For this, your implementation should establish a TCP connection between the two clients involved in a file transfer. The implementation does not need to handle any broadcast file transfers. All transfers will take place between a pair of clients. To send a file <file> residing in the same folder as the executable to a client with ip address: <client-ip>, a client would execute the following command: SENDFILE <client-ip> <file> The receiving client should store the file in the same folder as the executable, with the same name. Your implementation should be able to transfer both text and binary files. You can assume the maximum file size to be 10 MB. 6. Grading and Submission The grading will be done using automated tests. Any deviation from the output format/syntax described in previous sections will cause the tests to fail. For a detailed breakup of points associated with each command/functions, see https://goo.gl/UAVWgY For packaging and submission, see the section Packaging and Submission in https://goo.gl/L2kgb5 Published by Google Drive–Report Abuse–Updated automatically every 5 minutes
FOR MVC DEVLEOPERS THE FEAUTURES OF ASP.NET CORE ASP.NET Core 1.0 gives a patched up Web development system adapted towards the prerequisites of present day Web applications. The new structure, as of now in RC1, obliges you to learn numerous new ideas not found in ASP.NET MVC 5. To that end, this article identifies a couple of essential components that ASP.NET MVC 5 designers ought to know as they get ready to take in this new structure. 1. ASP.NET Core on Numerous Runways ASP.NET Core is a piece of .NET Core—another measured structure that backings numerous stages.ASP.NET and the .NET framework are focused on towards the Windows stage. Then again, ASP.NET Core is created to bolster various stages including Windows, Mac, and Linux. This additionally implies, dissimilar to ASP.NET web applications, basically, keep running under IIS, the ASP.NET Core applications can keep running under non-IIS Web servers. Figure 1 demonstrates the part of the .NET Core and ASP.NET Core. The part of the .NET Core and ASP.NET Core - A Web application worked with ASP.NET Core can target ASP.NET Framework 4.6 or the ASP.NET Core. The Web applications focusing on ASP.NET Framework 4.6 run just on the Windows stage. The Web applications focusing on the ASP.NET Core can keep running on Windows and non-Windows stages. Obviously, as on this composition, ASP.NET Core doesn't offer the same rich usefulness offered by ASP.NET Framework 4.6. 2. Part of Project.json ASP.NET Core utilizes an exceptional document—Project.json for putting away all the undertaking level configuration data. Project.config can store numerous design settings, for example, references to NuGet bundles utilized as a part of the task and target structures. "dependencies": { "Microsoft.AspNet.IISPlatformHandler": "1.0.0-rc1-final", "Microsoft.AspNet.Server.Kestrel": "1.0.0-rc1-final", "Microsoft.AspNet.Mvc": "6.0.0-rc1-final", "Microsoft.AspNet.Mvc.TagHelpers": "6.0.0-rc1-final", "Microsoft.AspNet.StaticFiles": "1.0.0-rc1-final", "Microsoft.AspNet.Tooling.Razor": "1.0.0-rc1-final", "Microsoft.Extensions.Configuration.Abstractions": "1.0.0-rc1-final", "Microsoft.Extensions.Configuration.Json": "1.0.0-rc1-final", "EntityFramework.MicrosoftSqlServer": "7.0.0-rc1-final", "EntityFramework.Commands": "7.0.0-rc1-final", "Microsoft.AspNet.Session": "1.0.0-rc1-final", "Newtonsoft.Json": "8.0.3" The Project.json record stores configuration data in JSON position. The above markup demonstrates a conditions segment that contains a rundown of NuGet bundles required by the application. For instance, the Web application under thought requires the 6.0.0-rc1-last form of Microsoft.AspNet.Mvc get together, etc 3. Part of AppSettings.json ASP.NET stores application configuration settings in Web.config. For instance, engineers utilize the <appSettings> area to store custom application settings, the <connectionStrings> segment to store database association strings, etc. ASP.NET Core utilizes AppSettings.json to store such bits of data. Consider the accompanying configuration: { "AppSettings": { "Title": "My ASP.NET Core Application" }, "Data": { "DefaultConnection": { "ConnectionString": "data source=.; initial catalog=Northwind;integrated security=true" } } } The previous JSON markup comprises of two properties or keys, to be specific AppSettings and Data. The AppSettings property holds a sub-key named Title. The Title sub-key has a string estimation of "My ASP.NET Core Application". Also, the Data key has a DefaultConnection sub-key. The DefaultConnection thusly has a ConnectionString sub-key. 4. Application set-up In ASP.NET, Global.asax goes about as the passage point for your application. You can wire different events handlers for occasions, for example, Application_Start and Session_Start, in the Global.asax record. In ASP.NET Core, the application startup happens in an unexpected way—it happens through a Startup class. one such Startup class - public class Startup { public Startup(IHostingEnvironment env, IApplicationEnvironment app) { ConfigurationBuilder builder = new ConfigurationBuilder(); builder.SetBasePath(app.ApplicationBasePath); builder.AddJsonFile("appsettings.json"); IConfigurationRoot config = builder.Build(); string str = config.Get<string> ("Data:DefaultConnection:ConnectionString"); // do something with str } public void ConfigureServices(IServiceCollection services) { services.AddMvc(); services.AddEntityFramework() .AddSqlServer(); } public void Configure(IApplicationBuilder app) { app.UseStaticFiles(); app.UseMvc(routes => { routes.MapRoute( name: "default", template: "{controller=Home}/ {action=Index}/{id?}"); }); } public static void Main(string[] args) => WebApplication.Run<Startup>(args); } The Startup class appeared above starts with a constructor. The constructor stacks the AppSettings.json record utilizing ConfigurationBuilder class. The Get() strategy then is utilized to peruse the database association string put away in the AppSettings.json document. The ConfigureServices() technique includes the administrations required by the application. For instance, here you add MVC and Entity Framework to the administrations gathering. The Configure() technique determines and arranges the administrations included before for application's utilization. For instance, the MVC directing is designed in the code appeared previously. 5. Tag Helpers In ASP.NET MVC 5, you utilized HTML assistants, for example, BeginForm(), LabelFor(), and TextBoxFor() to render structures and frame fields. You can keep on using HTML partners in ASP.NET Core, too. However, there is a superior option: Tag Helpers. Label aides take the type of standard HTML labels with certain extraordinary asp-* credits added to them. Consider the accompanying markup that renders a structure: <form asp-controller="Home" asp-action="Save" method="post"> <table border="1" cellpadding="10"> <tr> <td><label asp-for="FirstName">First Name :</label></td> <td><input type="text" asp-for="FirstName" /></td> </tr> <tr> <td><label asp-for="LastName">Last Name :</label></td> <td><input type="text" asp-for="LastName" /></td> </tr> <tr> <td><label asp-for="Email">Email :</label></td> <td><input type="text" asp-for="Email" /></td> </tr> <tr> <td><label asp-for="Phone">Phone :</label></td> <td><input type="text" asp-for="Phone" /></td> </tr> <tr> <td colspan="2"> <input type="submit" value="Submit" /> </td> </tr> </table> </form> Observe clearly, the properties that start with asp-. They are characterized by the label aides. For instance, the structure label aide utilizes asp-controller ascribe to indicate the objective controller name and asp-activity credit to determine the objective activity technique name. Correspondingly, asp-for traits utilized with name and info label partners tie a name or a text box to a model property. Label partners are more advantageous to use than HTML assistants in light of the fact that their linguistic structure nearly takes after the HTML markup. 6. View Components In MVC 5, you utilized halfway perspectives as a way to reuse markup and code. ASP.NET Core presents View Components, the more intense and adaptable option. A perspective part comprises of a class normally acquired from ViewComponent base class and a perspective record containing the required markup. This programming model is entirely like the one utilized by controllers and perspectives. It permits you to separate code and markup from each other—code in the perspective segment class and markup in a perspective. Once made, you can utilize a perspective segment on a perspective by utilizing the @Component.Invoke() technique. 7. Dependency Injection ASP.NET Core gives an inbuilt reliance infusion system. The DI system of ASP.NET Core offers four-lifetime modes for a sort being infused: Singleton: An object of an administration (the sort to be infused) is made and supplied to all the requests to that administration. Along these lines, fundamentally all requests get the same article to work with. Scoped: An object of an administration is made for every single request. In this way, every request gets another event of an administration to work with. Transient: An object of an administration is made each time an article is asked. Instance: For this situation, you are in charge of making an object of an administration. The DI system then uses that case in singleton mode said prior public void ConfigureServices(IServiceCollection services) { services.AddMvc(); services.AddSingleton<IMyService,MyService>(); } Here, MyService is the sort to be enlisted with the DI structure and actualizes IMyService. The AddSingleton() technique enlists this type for Singleton mode portrayed previously. Once a sort is enrolled with the DI system, you can infuse it in a controller like this: public class HomeController : Controller { private IMyService obj; public HomeController(IMyService obj) { this.obj = obj; } .... .... } 8. Gulp, Grunt, and Bower Support Gulp and Grunt are JavaScript assignment runners. They help you computerize generally required undertakings, for example, packaging JavaScript and CSS records, minifying JavaScript and CSS documents, and arranging Less and Sass records (and some more). They are introduced utilizing npm (Node Package Manager). The ASP.NET Core venture made utilizing Visual Studio 2015 permits you to include Grunt and Gulp arrangement documents furthermore gives Task Runner Explorer to screen the errands. Bower is a bundle administrator basically for front-end bundles. Front-end bundles are the bundles that you use in your Web pages, for example, JavaScript libraries/systems and CSS records. For instance, you may introduce jQuery in your ASP.NET Core venture by utilizing Bower. An ASP.NET Core venture made utilizing Visual Studio 2015 permits you to include a Bower setup document. You likewise can work with the bundles utilizing the Manage Bower Packages menu choice. 9. Single Programming for Web API Model for and MVC In MVC 5, controllers acquire from the System.Web.Mvc.Controller base class. What's more, Web API 2 controllers acquire from System.Web.Http.ApiController. In ASP.NET Core, both of these structures are converged into a solitary system. Therefore, under ASP.NET Core, an MVC controller and Web API controller both acquire from Microsoft.AspNet.Mvc.Controller base class. You then can design viewpoints, for example, HTTP verb mapping and the directing of the controllers as coveted. 10. Static Files and the wwwroot Folder In ASP.NET, there is no settled area for putting away static documents, for example, picture records, JavaScript documents, and CSS records (engineers regularly utilized a Content envelope to store such documents). In ASP.NET Core, all the static records are kept under the wwwroot envelope (default). You likewise can change the name of this envelope by utilizing the Project.json document. Refer the figure following down - After arrangement, the wwwroot turns into the Web application's root. Every one of the URLs to static records are determined as for this envelope. Along these lines,/pictures/logo.png anticipates that logo.png will be available under the wwwroot/pictures envelope. Conclusion - ASP.NET Core 1.0 is a redone system outfitted towards present day cloud based, measured Web applications. Despite the fact that the new structure safeguards the key ideas of MVC 5, ASP.NET engineers will discover numerous contrasts between MVC 5 and ASP.NET Core 1.0. This article specified the imperative new components/ideas that you have to comprehend to start your voyage with ASP.NET Core 1.0.
JoshBell302
In this assignment you will write smallsh your own shell in C. smallsh will implement a subset of features of well-known shells, such as bash. Your program will Provide a prompt for running commands Handle blank lines and comments, which are lines beginning with the # character Provide expansion for the variable $$ Execute 3 commands exit, cd, and status via code built into the shell Execute other commands by creating new processes using a function from the exec family of functions Support input and output redirection Support running commands in foreground and background processes Implement custom handlers for 2 signals, SIGINT and SIGTSTP Learning Outcomes After successful completion of this assignment, you should be able to do the following Describe the Unix process API (Module 4, MLO 2) Write programs using the Unix process API (Module 4, MLO 3) Explain the concept of signals and their uses (Module 5, MLO 2) Write programs using the Unix API for signal handling (Module 5, MLO 3) Explain I/O redirection and write programs that can employ I/O redirection (Module 5, MLO 4) Program Functionality 1. The Command Prompt Use the colon : symbol as a prompt for each command line. The general syntax of a command line is: command [arg1 arg2 ...] [< input_file] [> output_file] [&] …where items in square brackets are optional. You can assume that a command is made up of words separated by spaces. The special symbols <, > and & are recognized, but they must be surrounded by spaces like other words. If the command is to be executed in the background, the last word must be &. If the & character appears anywhere else, just treat it as normal text. If standard input or output is to be redirected, the > or < words followed by a filename word must appear after all the arguments. Input redirection can appear before or after output redirection. Your shell does not need to support any quoting; so arguments with spaces inside them are not possible. We are also not implementing the pipe "|" operator. Your shell must support command lines with a maximum length of 2048 characters, and a maximum of 512 arguments. You do not need to do any error checking on the syntax of the command line. 2. Comments & Blank Lines Your shell should allow blank lines and comments. Any line that begins with the # character is a comment line and should be ignored. Mid-line comments, such as the C-style //, will not be supported. A blank line (one without any commands) should also do nothing. Your shell should just re-prompt for another command when it receives either a blank line or a comment line. 3. Expansion of Variable $$ Your program must expand any instance of "$$" in a command into the process ID of the smallsh itself. Your shell does not otherwise perform variable expansion. 4. Built-in Commands Your shell will support three built-in commands: exit, cd, and status. These three built-in commands are the only ones that your shell will handle itself - all others are simply passed on to a member of the exec() family of functions. You do not have to support input/output redirection for these built in commands These commands do not have to set any exit status. If the user tries to run one of these built-in commands in the background with the & option, ignore that option and run the command in the foreground anyway (i.e. don't display an error, just run the command in the foreground). exit The exit command exits your shell. It takes no arguments. When this command is run, your shell must kill any other processes or jobs that your shell has started before it terminates itself. cd The cd command changes the working directory of smallsh. By itself - with no arguments - it changes to the directory specified in the HOME environment variable This is typically not the location where smallsh was executed from, unless your shell executable is located in the HOME directory, in which case these are the same. This command can also take one argument: the path of a directory to change to. Your cd command should support both absolute and relative paths. status The status command prints out either the exit status or the terminating signal of the last foreground process ran by your shell. If this command is run before any foreground command is run, then it should simply return the exit status 0. The three built-in shell commands do not count as foreground processes for the purposes of this built-in command - i.e., status should ignore built-in commands. 5. Executing Other Commands Your shell will execute any commands other than the 3 built-in command by using fork(), exec() and waitpid() Whenever a non-built in command is received, the parent (i.e., smallsh) will fork off a child. The child will use a function from the exec() family of functions to run the command. Your shell should use the PATH variable to look for non-built in commands, and it should allow shell scripts to be executed If a command fails because the shell could not find the command to run, then the shell will print an error message and set the exit status to 1 A child process must terminate after running a command (whether the command is successful or it fails). 6. Input & Output Redirection You must do any input and/or output redirection using dup2(). The redirection must be done before using exec() to run the command. An input file redirected via stdin should be opened for reading only; if your shell cannot open the file for reading, it should print an error message and set the exit status to 1 (but don't exit the shell). Similarly, an output file redirected via stdout should be opened for writing only; it should be truncated if it already exists or created if it does not exist. If your shell cannot open the output file it should print an error message and set the exit status to 1 (but don't exit the shell). Both stdin and stdout for a command can be redirected at the same time (see example below). 7. Executing Commands in Foreground & Background Foreground Commands Any command without an & at the end must be run as a foreground command and the shell must wait for the completion of the command before prompting for the next command. For such commands, the parent shell does NOT return command line access and control to the user until the child terminates. Background Commands Any non built-in command with an & at the end must be run as a background command and the shell must not wait for such a command to complete. For such commands, the parent must return command line access and control to the user immediately after forking off the child. The shell will print the process id of a background process when it begins. When a background process terminates, a message showing the process id and exit status will be printed. This message must be printed just before the prompt for a new command is displayed. If the user doesn't redirect the standard input for a background command, then standard input should be redirected to /dev/null If the user doesn't redirect the standard output for a background command, then standard output should be redirected to /dev/null 8. Signals SIGINT & SIGTSTP SIGINT A CTRL-C command from the keyboard sends a SIGINT signal to the parent process and all children at the same time (this is a built-in part of Linux). Your shell, i.e., the parent process, must ignore SIGINT Any children running as background processes must ignore SIGINT A child running as a foreground process must terminate itself when it receives SIGINT The parent must not attempt to terminate the foreground child process; instead the foreground child (if any) must terminate itself on receipt of this signal. If a child foreground process is killed by a signal, the parent must immediately print out the number of the signal that killed it's foreground child process (see the example) before prompting the user for the next command. SIGTSTP A CTRL-Z command from the keyboard sends a SIGTSTP signal to your parent shell process and all children at the same time (this is a built-in part of Linux). A child, if any, running as a foreground process must ignore SIGTSTP. Any children running as background process must ignore SIGTSTP. When the parent process running the shell receives SIGTSTP The shell must display an informative message (see below) immediately if it's sitting at the prompt, or immediately after any currently running foreground process has terminated The shell then enters a state where subsequent commands can no longer be run in the background. In this state, the & operator should simply be ignored, i.e., all such commands are run as if they were foreground processes. If the user sends SIGTSTP again, then your shell will Display another informative message (see below) immediately after any currently running foreground process terminates The shell then returns back to the normal condition where the & operator is once again honored for subsequent commands, allowing them to be executed in the background. See the example below for usage and the exact syntax which you must use for these two informative messages. Sample Program Execution Here is an example run using smallsh. Note that CTRL-C has no effect towards the bottom of the example, when it's used while sitting at the command prompt: $ smallsh : ls junk smallsh smallsh.c : ls > junk : status exit value 0 : cat junk junk smallsh smallsh.c : wc < junk > junk2 : wc < junk 3 3 23 : test -f badfile : status exit value 1 : wc < badfile cannot open badfile for input : status exit value 1 : badfile badfile: no such file or directory : sleep 5 ^Cterminated by signal 2 : status & terminated by signal 2 : sleep 15 & background pid is 4923 : ps PID TTY TIME CMD 4923 pts/0 00:00:00 sleep 4564 pts/0 00:00:03 bash 4867 pts/0 00:01:32 smallsh 4927 pts/0 00:00:00 ps : : # that was a blank command line, this is a comment line : background pid 4923 is done: exit value 0 : # the background sleep finally finished : sleep 30 & background pid is 4941 : kill -15 4941 background pid 4941 is done: terminated by signal 15 : pwd /nfs/stak/users/chaudhrn/CS344/prog3 : cd : pwd /nfs/stak/users/chaudhrn : cd CS344 : pwd /nfs/stak/users/chaudhrn/CS344 : echo 4867 4867 : echo $$ 4867 : ^C^Z Entering foreground-only mode (& is now ignored) : date Mon Jan 2 11:24:33 PST 2017 : sleep 5 & : date Mon Jan 2 11:24:38 PST 2017 : ^Z Exiting foreground-only mode : date Mon Jan 2 11:24:39 PST 2017 : sleep 5 & background pid is 4963 : date Mon Jan 2 11:24:39 PST 2017 : exit $ Hints & Resources 1. The Command Prompt Be sure you flush out the output buffers each time you print, as the text that you're outputting may not reach the screen until you do in this kind of interactive program. To do this, call fflush() immediately after each and every time you output text. Consider defining a struct in which you can store all the different elements included in a command. Then as you parse a command, you can set the value of members of a variable of this struct type. 2. Comments & Blank Lines This should be simple. 3. Expansion of Variable $$ Here are examples to illustrate the required behavior. Suppose the process ID of smallsh is 179. Then The string foo$$$$ in the command is converted to foo179179 The string foo$$$ in the command is converted to foo179$ 4. Built-in Commands It is recommended that you program the built-in commands first, before tackling the commands that require fork(), exec() and waitpid(). The built-in commands don't set the value of status. This means that however you are keeping track of the status, don't change it after the execution of a built-in command. A process can use chdir() (Links to an external site.) to change its directory. To test the implementation of the cd command in smallsh, don't use getenv("PWD") because it will not give you the correct result. Instead, you can use the function getcwd() (Links to an external site.). Here is why getenv("PWD") doesn't give you the correct result: PWD is an environment variable. As discussed in Module 4, Exploration: Environment "When a parent process forks a child process, the child process inherits the environment of its parent process." When you run smallsh from a bash shell, smallsh inherits the environment of this bash shell The value of PWD in the bash shell is set to the directory in which you are when you run the command to start smallsh smallsh inherits this value of PWD. When you change the directory in smallsh, it doesn't update the value of the environment variable PWD 5. Executing Other Commands Note that if exec() is told to execute something that it cannot do, like run a program that doesn't exist, it will fail, and return the reason why. In this case, your shell should indicate to the user that a command could not be executed (which you know because exec() returned an error), and set the value retrieved by the built-in status command to 1. Make sure that the child process that has had an exec() call fail terminates itself, or else it often loops back up to the top and tries to become a parent shell. This is easy to spot: if the output of the grading script seems to be repeating itself, then you've likely got a child process that didn't terminate after a failed exec(). You can choose any function in the exec() family. However, we suggest that using either execlp() or execvp() will be simplest because of the following reasons smallsh doesn't need to pass a new environment to the program. So the additional functionality provided by the exec() functions with names ending in e is not required. One example of a command that smallsh needs to run is ls (the graders will try this command at the start of the testing). Running this command will be a lot easier using the exec() functions that search the PATH environment variable. 6. Input & Output Redirection We recommend that the needed input/output redirection should be done in the child process. Note that after using dup2() to set up the redirection, the redirection symbol and redirection destination/source are NOT passed into the exec command For example, if the command given is ls > junk, then you handle the redirection to "junk" with dup2() and then simply pass ls into exec(). 7. Executing Commands in Foreground & Background Foreground Commands For a foreground command, it is recommend to have the parent simply call waitpid() on the child, while it waits. Background Commands The shell should respect the input and output redirection operators for a command regardless of whether the command is to be run in the foreground or the background. This means that a background command should use /dev/null for input only when input redirection is not specified in the command. Similarly a background command should use /dev/null for output only when output redirection is not specified in the command. Your parent shell will need to periodically check for the background child processes to complete, so that they can be cleaned up, as the shell continues to run and process commands. Consider storing the PIDs of non-completed background processes in an array. Then every time BEFORE returning access to the command line to the user, you can check the status of these processes using waitpid(...NOHANG...). Alternatively, you may use a signal handler to immediately wait() for child processes that terminate, as opposed to periodically checking a list of started background processes The time to print out when these background processes have completed is just BEFORE command line access and control are returned to the user, every time that happens. 8. Signals SIGINT & SIGTSTP Reentrancy is important when we consider that signal handlers cause jumps in execution that cause problems with certain functions. Note that the printf() family of functions is NOT reentrant. In your signal handlers, when outputting text, you must use other output functions! What to turn in? You can only use C for coding this assignment and you must use the gcc compiler. You can use C99 or GNU99 standard or the default standard used by the gcc installation on os1. Your assignment will be graded on os1. Submit a single zip file with all your code, which can be in as many different files as you want. This zip file must be named youronid_program3.zip where youronid should be replaced by your own ONID. E.g., if chaudhrn was submitting the assignment, the file must be named chaudhrn_program3.zip. In the zip file, you must include a text file called README.txt that contains instructions on how to compile your code using gcc to create an executable file that must be named smallsh. Your zip file should not contain any extraneous files. In particular, make sure not to zip up the __MACOSX directories. When you resubmit a file in Canvas, Canvas can attach a suffix to the file, e.g., the file name may become chaudhrn_program3-1.zip. Don't worry about this name change as no points will be deducted because of this. Caution During the development of this program, take extra care to only do your work on os1, our class server, as your software will likely negatively impact whatever machine it runs on, especially before it is finished. If you cause trouble on one of the non-class, public servers, it could hurt your grade! If you are having trouble logging in to any of our EECS servers because of runaway processes, please use this page to kill off any programs running on your account that might be blocking your access: T.E.A.C.H. - The Engineering Accounts and Classes HomepageLinks to an external site. Grading Criteria This assignment is worth 20% of your grade and there are 180 points available for it. 170 points are available in the test script, while the final 10 points will be based on your style, readability, and commenting. Comment well, often, and verbosely: we want to see that you are telling us WHY you are doing things, in addition to telling us WHAT you are doing. Once the program is compiled, according to your specifications given in README.txt, your shell will be executed to run a few sample commands against (ls, status, exit, in that order). If the program does not successfully work on those commands, it will receive a zero. If it works, then the grading script will be run against it (as detailed below) for final grading. Points will be assigned according to the grading script running on our class server only. Grading Method Here is the grading script p3testscript. It is a bash script that starts the smallsh program and runs commands on smallsh's command line. Most of the commands run by the grading script are very similar to the commands shown in the section Sample Program Execution. You can open the script in a text editor. The comments in the script will show you the points for individual items. Use the script to prepare for your grade, as this is how it's being earned. To run the script, place it in the same directory as your compiled shell, chmod it (chmod +x ./p3testscript) and run this command from a bash prompt: $ ./p3testscript 2>&1 or $ ./p3testscript 2>&1 | more or $ ./p3testscript > mytestresults 2>&1 Do not worry if the spacing, indentation, or look of the output of the script is different than when you run it interactively: that won’t affect your grade. The script may add extra colons at the beginning of lines or do other weird things, like put output about terminating processes further down the script than you intended. If your program does not work with the grading script, and you instead request that we grade your script by hand, we will apply a 15% reduction to your final score. So from the very beginning, make sure that you work with the grading script on our class server!
karanheart96
In this programming assignment, you will write a client ping program in Python. Your client will send a simple ping message to a server, receive a corresponding pong message back from the server, and determine the delay between when the client sent the ping message and received the pong message. This delay is called the Round Trip Time (RTT). The functionality provided by the client and server is similar to the functionality provided by standard ping program available in modern operating systems. However, standard ping programs use the Internet Control Message Protocol (ICMP) (which we will study in Chapter 5). Here we will create a nonstandard (but simple!) UDP-based ping program. Your ping program is to send 10 ping messages to the target server over UDP. For each message, your client is to determine and print the RTT when the corresponding pong message is returned. Because UDP is an unreliable protocol, a packet sent by the client or server may be lost. For this reason, the client cannot wait indefinitely for a reply to a ping message. You should have the client wait up to one second for a reply from the server; if no reply is received, the client should assume that the packet was lost and print a message accordingly. In this assignment, you will be given the complete code for the server (available in the Companion Website). Your job is to write the client code, which will be very similar to the server code. It is recommended that you first study carefully the server code. You can then write your client code, liberally cutting and pasting lines from the server code.
General Description: In this assignment you will implement a text-based game server and client. The communication between the server and the client(s) will be performed using a simple text based protocol (TBGP), which can potentially support different games; However, your server will only support a single game - Bluffer. The implementation of the server will be based on the Reactor and Thread-Per-Client servers taught in class. You will have to adjust them to support more complex protocols, implement the TBGP, and finally, add support for the Bluffer game in your server, and implement a client. The rest of this document is organized as follows: section 2 presents the TBGP and its specifications, section 3 presents the Bluffer game and its implementation using TBGP, section 4 describes implementation details. 2 Text-based Game Server Protocol (TBGP) Specification 2.1 Establishing a client/server connection Upon connection, the client must specify a nickname using the NICK command. The nickname must be unique and cannot be changed after it is set. The server will respond with a SYSMSG specifying whether the nickname was successfully acquired. 2.2 Game Rooms Games are held in rooms, which can also be used for chat. A user can create and join a room using the JOIN command. A user can only be in one room at any given time. A game can be started using the STARTGAME command. Once started, the room will not accept new users until the game is over. 2.3 Supported Commands The TBGP supports various commands needed in order to create chat rooms and start games in them. There are two types of commands, Server-to-Client and Client-to-Server. The commands are all formatted as follows: <Command> <Optional : Parameters>\n 2.4 Server To Client Commands • Command: ASKTXT Parameter: text - question to ask. 1 Used to ask the client the specified question, expecting a TXTRESP. • Command: ASKCHOICES Parameter: text - question to ask. Used to ask the client the specified question, expecting a SELECTRESP. • Command: SYSMSG Parameter: text. Response to every command the user sends. The format is: SYSMSG <Original Command> <Result> <Optional : Custom Message>\n Where < Result > is one of: ACCEPTED, REJECTED or UNIDENTIFIED. • Command GAMEMSG Parameter: text. Custom messages that are a part of the game being played. • Command: USRMSG Parameter: text. Used to deliver a message sent by another user, in the context of a game-room. 2.5 Client To Server Commands • Command: NICK Parameter: nickname. Requests the specified nickname. • Command: JOIN Parameter: room name. Joins the specified room, creating it if it doesn’t exist. This also causes the user to leave the current room, therefore is impossible while a game is in progress. • Command: MSG Parameter: text to be sent. Sends the specified message to the users current room. • Command: LISTGAMES Lists the games supported by the server. • Command: STARTGAME Parameter: game name. Starts the specified game in the current room. Game is specified using a unique string identifier. • Command: TXTRESP Parameter: text to be sent. Used as a response to ASKTXT command, providing a textual response. • Command: SELECTRESP Parameter: integer - selected response. Used as a response to ASKCHOICES command, providing a numeric selection. 2 • Command: QUIT Closes the connection. 3 The Bluffer Game The Bluffer game is a type of trivia game, with a twist - the players try to fool each other into choosing absurd answers. The game host asks a series of questions, for which the players try to provide answers that seem real. The players are then presented with both the real answer, and the fake answers provided by other players, and have to choose the real one. Players are awarded 10 points for choosing the correct answer, and 5 for each player that chose one of their fake answers. 3.1 Bluffer using TBGP The Bluffer is uniquely identified in the TBGP using the string ”BLUFFER”. Once started, the server will load 3 random question from its database (3.2), and for each question (sequentially): 1. Use ASKTXT to present the question to the user. 2. Once all the users reply (using TXTRESP), their responses must be turned to lowercase and shuffled with the real answer, and then presented with ASKCHOICES. 3. Users reply with SELECTRESP. Once all the users reply, score is awarded (as described in the game description), and is announced along with the correct answer. 4. Move on to the next question. After 3 questions, the scores summary is sent to the users using SYSMSG, and the game is over. 3.2 Questions Database The questions for the Bluffer game are given to you in a JSON file. In it is an array of question objects. question contains two fields: • questionText - String of the question. • realAnswer - String of the real answer. The file must be loaded each time questions are needed, so server restart is not required for editing the database. 4 4.1 • • • Implementation Details General Guidelines The server should be written in Java. The client should be written in C++ with BOOST. Both should be tested on Linux installed at CS computer labs. You must use maven as your build tool. The same coding standards expected in the course and previous assignments are expected here. 3 4.2 Server You will have to implement a single protocol, supporting both the Thread-Per-Client and Reactor servers pre- sented in class. The ServerProtocol interface, as presented in class, is limited to protocols where each user message is responded by a single message, sent to the same user. In order to implement TBGP, and other more complex protocols, the server needs to provide the protocol with means to send messages to any user, at any point in time. In order to achieve this, the ServerProtocol and AsyncServerProtocol presented in class have been refactored to send a ProtocolCallback along with each message. This interface, given in 6.1.1 must be implemented by each server, and a unique instance must be created for each TCP connection. Left to you, are the following 3 tasks: 1. Refactor the Thread-Per-Client server to support the new ServerProtocol. This will require changing the server to use a Tokenizer, and implementing the new ProtocolCallback. 2. Refactor the Reactor server to support the new AsyncServerProtocol. 3. Implement the new AsyncServerProtocol, and support the Bluffer game. Keep in mind, while you’re only required to implement one game, your implementation should support easily adding more games. 4.3 Client The client is multithreaded with one thread for handling the socket and another thread to handle stdin. An echo client is provided, but its a single threaded client. While it is blocking on stdin it does not get messages from the socket. The client should receive the server’s IP and PORT as arguments. You may assume a network disconnection does not happen (like disconnecting the network cable).
nchapelle
# Friend Finder - Node and Express Servers ### Overview In this activity, you'll build a compatibility-based "FriendFinder" application -- basically a dating app. This full-stack site will take in results from your users' surveys, then compare their answers with those from other users. The app will then display the name and picture of the user with the best overall match. You will use Express to handle routing. Make sure you deploy your app to Heroku so other users can fill it out. ### Before You Begin * Check out [this demo version of the site](https://friend-finder-fsf.herokuapp.com/). Use this as a model for how we expect your assignment look and operate. * Create a folder called `FriendFinder`. Inside the folder, organize your directories so it matches the following: ``` FriendFinder - .gitignore - app - data - friends.js - public - home.html - survey.html - routing - apiRoutes.js - htmlRoutes.js - node_modules - package.json - server.js ``` ### Commits Having an active and healthy commit history on GitHub is important for your future job search. It is also extremely important for making sure your work is saved in your repository. If something breaks, committing often ensures you are able to go back to a working version of your code. * Committing often is a signal to employers that you are actively working on your code and learning. * We use the mantra “commit early and often.” This means that when you write code that works, add it and commit it! * Numerous commits allow you to see how your app is progressing and give you a point to revert to if anything goes wrong. * Be clear and descriptive in your commit messaging. * When writing a commit message, avoid vague messages like "fixed." Be descriptive so that you and anyone else looking at your repository knows what happened with each commit. * We would like you to have well over 200 commits by graduation, so commit early and often! ### Submission on BCS * Please submit both the deployed Heroku link to your homework AND the link to the Github Repository! ### Instructions 1. Your survey should have 10 questions of your choosing. Each answer should be on a scale of 1 to 5 based on how much the user agrees or disagrees with a question. 2. Your `server.js` file should require the basic npm packages we've used in class: `express` and `path`. 3. Your `htmlRoutes.js` file should include two routes: * A GET Route to `/survey` which should display the survey page. * A default, catch-all route that leads to `home.html` which displays the home page. 4. Your `apiRoutes.js` file should contain two routes: * A GET route with the url `/api/friends`. This will be used to display a JSON of all possible friends. * A POST routes `/api/friends`. This will be used to handle incoming survey results. This route will also be used to handle the compatibility logic. 5. You should save your application's data inside of `app/data/friends.js` as an array of objects. Each of these objects should roughly follow the format below. ```json { "name":"Ahmed", "photo":"https://media.licdn.com/mpr/mpr/shrinknp_400_400/p/6/005/064/1bd/3435aa3.jpg", "scores":[ 5, 1, 4, 4, 5, 1, 2, 5, 4, 1 ] } ``` 6. Determine the user's most compatible friend using the following as a guide: * Convert each user's results into a simple array of numbers (ex: `[5, 1, 4, 4, 5, 1, 2, 5, 4, 1]`). * With that done, compare the difference between current user's scores against those from other users, question by question. Add up the differences to calculate the `totalDifference`. * Example: * User 1: `[5, 1, 4, 4, 5, 1, 2, 5, 4, 1]` * User 2: `[3, 2, 6, 4, 5, 1, 2, 5, 4, 1]` * Total Difference: **2 + 1 + 2 =** **_5_** * Remember to use the absolute value of the differences. Put another way: no negative solutions! Your app should calculate both `5-3` and `3-5` as `2`, and so on. * The closest match will be the user with the least amount of difference. 7. Once you've found the current user's most compatible friend, display the result as a modal pop-up. * The modal should display both the name and picture of the closest match. ### Reminder: Submission on BCS * Please submit both the deployed Heroku link to your homework AND the link to the Github Repository! - - - ### Minimum Requirements Attempt to complete homework assignment as described in instructions. If unable to complete certain portions, please pseudocode these portions to describe what remains to be completed. Adding a README.md as well as adding this homework to your portfolio are required as well and more information can be found below. **This assignment must be deployed.** - - - ### Hosting on Heroku Now that we have a backend to our applications, we use Heroku for hosting. Please note that while **Heroku is free**, it will request credit card information if you have more than 5 applications at a time or are adding a database. Please see [Heroku’s Account Verification Information](https://devcenter.heroku.com/articles/account-verification) for more details. See the [Supplemental Heroku Deployment Guide](../../03-Supplemental/HerokuGuide.md) for in-detail deployment instructions. - - - ### Create a README.md Add a `README.md` to your repository describing the project. Here are some resources for creating your `README.md`. Here are some resources to help you along the way: * [About READMEs](https://help.github.com/articles/about-readmes/) * [Mastering Markdown](https://guides.github.com/features/mastering-markdown/) - - - ### Add To Your Portfolio After completing the homework please add the piece to your portfolio. Make sure to add a link to your updated portfolio in the comments section of your homework so the TAs can easily ensure you completed this step when they are grading the assignment. - - - ### **Good Luck!**
SadatRiyad
No description available
dev-habibhossain
No description available
OMI786I
No description available
Abdur-Nur-Tushar-Irfan
No description available
Electronick79
Syllabus – COMP 596 Web Application Development Class Meeting Time & Location: Wednesday 4-6:40 Website: https://github.com/ http://blackboard.bridgew.edu/ Instructor: Dr. Jung (sjung@bridgew.edu) DMF339 Office Hours: 10-11 Tuesdays and Thursdays, 2-3:30 Wednesdays, or by appointment ___________________________________________________________________________________________ BSU Catalog Course Description: (http://catalog.bridgew.edu ) COMP 596 - Topics in Computer Science Prerequisite: Admission to the MS program in Computer Science or consent of instructor 3 credits, this course is elective in the category 3 Software Development https://www.bridgew.edu/graduate/computer-science-ms In this course, topics are chosen from program verification, formal semantics, formal language theory, concurrent programming, complexity or algorithms, programming language theory, graphics and other computer science topics. Repeatable for different topics. Offered as topics arise. This course covers web technologies for modern web application development; designing, developing, publishing websites on the World Wide Web; databases, client and server-side scripting, security and privacy issues. Course Outcomes (Learning objectives) At the end of the course, students should be able to • Describe the fundamentals of web development • Design and implement a web application with a variety of programming techniques • Demonstrate the ability to run and mange a web application Major Topics Covered in the Course • Client-side development • Server-side development • Working with Databases • Web Server Administration Instructional Methodologies This course will combine traditional lecturing with hands-on assignments that reinforce the lecture material. In particular, lectures will focus on concepts and ideas while the assignments will provide concrete experience and skills. Students will also have a term project, which allows them to apply what they learned from the lectures to interesting questions. Learning requires work. Research indicates that we learn through practice, teaching others, and discussion that corrects misconceptions. Assignments: • Further instructions will be given in each assignment. • Must be submitted on the due date. Assignments submitted late will be given a grade of 0. • Extensions will be handled on an individual basis, but typically reserved for special cases. The earlier you talk to me, the better your chances of receiving one. Do not expect to get an extension by requesting on the assignment due day. No extensions will be allowed after due. • All of the assignment scores will be entered into the grading formula. • No make-up assignments, no extra assignments for this class Exams: Make-ups for exams will be given ONLY to those students who (1) contact me BEFORE the exam with a reasonable excuse (documented by a note from a physician, court summons, etc.). All of these exam scores will be entered into the grading formula. You will fail the course (Letter grade F) if you miss any exam. Syllabus – COMP 596 Web Application Development Attendance Policy: Show up on time. Participate regularly. Attendance is not part of your grading. However, if you miss a lecture, it is your responsibility to learn what you missed. Excessive unexcused absences (more than 5 times) will result in failure for the course (letter grade F). If you arrive late to class, it is your responsibility to correct me on your attendance at the end of the class. Grade Components and Weights (TENTATIVE): Assignments 25% Exams 40% Group project & presentation 35% (Prototyping, Progress presentation, Final presentation & code) Accommodations https://studentbridgew.sharepoint.com/sites/SAS Based on legal requirements outlined in the Americans with Disabilities Act (ADA) and Section 504 of the Rehabilitation Act of 1973, all student-requests for reasonable accommodation must be processed through Student Accessibility Services (SAS). Instructor should NOT accommodate a student without official SAS paperwork. Mask up policy: Effective August 23, BSU mandates that all members of our campus community (including vaccinated students, employees, and visitors) wear a mask in indoor public places, including faculty offices. If a student fails to mask up even after instructor has requested, the faculty member may dismiss the student from class, and upon refusal of the student to leave, the faculty may dismiss the class and report the student to the student conduct officer. Faculty will also receive prior notice of students in their classes who may have a mask exemption which will be issued through the disability resource office. Academic Dishonesty: http://catalog.bridgew.edu/content.php?catoid=7&navoid=486 (BSU academic policy) All assignments in this course are considered take-home programming tests. You must do your own work, entirely. • You are permitted to discuss the meaning of assignments, general approaches and strategies. • You may not share code, pseudo-code, or documentation of any kind. • You may not use code from any other source, including the Internet. • Penalty (generally) o 1st strike: zero score (including the student who helped the other students) o 2nd strike: F in the class In-Class Conduct: Any sort of disruptive behavior in class will not be tolerated and dealt with according to the university policy. https://catalog.bridgew.edu/content.php?catoid=11&navoid=996#Academic_Integrity_and_Classroom_Conduct If disruptive behavior occurs, whether in the classroom or another academic environment, a faculty member has the right to remove the student from the classroom setting. Privacy Policy BSU privacy policy includes that you MUST use BSU account. It is students’ responsibilities to check BSU account. I will not respond any emails from outside BSU account
spt3gntlmn
Friend Finder - Node and Express Servers Overview In this activity, you'll build a compatibility-based "FriendFinder" application -- basically a dating app. This full-stack site will take in results from your users' surveys, then compare their answers with those from other users. The app will then display the name and picture of the user with the best overall match. You will use Express to handle routing. Make sure you deploy your app to Heroku so other users can fill it out. Before You Begin Check out this demo version of the site. Use this as a model for how we expect your assignment look and operate. Create a folder called FriendFinder. Inside the folder, organize your directories so it matches the following: FriendFinder - app - data - friends.js - public - home.html - survey.html - routing - apiRoutes.js - htmlRoutes.js - node_modules - package.json - server.js Instructions Your survey should have 10 questions of your choosing. Each answer should be on a scale of 1 to 5 based on how much the user agrees or disagrees with a question. Your server.js file should require the basic npm packages we've used in class: express, body-parser and path. Your htmlRoutes.js file should include two routes: A GET Route to /survey which should display the survey page. A default, catch-all route that leads to home.html which displays the home page. Your apiRoutes.js file should contain two routes: A GET route with the url /api/friends. This will be used to display a JSON of all possible friends. A POST routes /api/friends. This will be used to handle incoming survey results. This route will also be used to handle the compatibility logic. You should save your application's data inside of app/data/friends.js as an array of objects. Each of these objects should roughly follow the format below. { "name":"Ahmed", "photo":"https://media.licdn.com/mpr/mpr/shrinknp_400_400/p/6/005/064/1bd/3435aa3.jpg", "scores":[ 5, 1, 4, 4, 5, 1, 2, 5, 4, 1 ] } Determine the user's most compatible friend using the following as a guide: Convert each user's results into a simple array of numbers (ex: [5, 1, 4, 4, 5, 1, 2, 5, 4, 1]). With that done, compare the difference between current user's scores against those from other users, question by question. Add up the differences to calculate the totalDifference. Example: User 1: [5, 1, 4, 4, 5, 1, 2, 5, 4, 1] User 2: [3, 2, 6, 4, 5, 1, 2, 5, 4, 1] Total Difference: 2 + 1 + 2 = 5 Remember to use the absolute value of the differences. Put another way: no negative solutions! Your app should calculate both 5-3 and 3-5 as 2, and so on. The closest match will be the user with the least amount of difference. Once you've found the current user's most compatible friend, display the result as a modal pop-up. The modal should display both the name and picture of the closest match. Minimum Requirements Attempt to complete homework assignment as described in instructions. If unable to complete certain portions, please pseudocode these portions to describe what remains to be completed. Hosting on Heroku Now that we have a backend to our applications, we use Heroku for hosting. Please note that while Heroku is free, it will request credit card information if you have more than 5 applications at a time or are adding a database. Please see Heroku’s Account Verification Information for more details. Create a README.md Add a README.md to your repository describing the project. Here are some resources for creating your README.md. Here are some resources to help you along the way: About READMEs Mastering Markdown Add To Your Portfolio After completing the homework please add the piece to your portfolio. Make sure to add a link to your updated portfolio in the comments section of your homework so the TAs can easily ensure you completed this step when they are grading the assignment. To receive an 'A' on any assignment, you must link to it from your portfolio. One More Thing If you have any questions about this project or the material we have covered, please post them in the community channels in slack so that your fellow developers can help you! If you're still having trouble, you can come to office hours for assistance from your instructor and TAs. Good Luck!
Lspringer24
# Tableau Homework - Citi Bike Analytics ### Before You Begin * This assignment will be saved to your tableau public account rather than github. * If you haven't already, be sure to create a tableau public account [here](https://public.tableau.com/s/). * The free tier of tableau only lets you save to their public server. This means that each time you save your file it will be uploaded to your tableau public profile. * You are able to load and continue working on the same workbook. * When you are finished with your assignment, you will turn in the URL to your tableau public workbook along with any additional files used for your analysis. ## Background  Congratulations on your new job! As the new lead analyst for the [New York Citi Bike](https://en.wikipedia.org/wiki/Citi_Bike) Program, you are now responsible for overseeing the largest bike sharing program in the United States. In your new role, you will be expected to generate regular reports for city officials looking to publicize and improve the city program. Since 2013, the Citi Bike Program has implemented a robust infrastructure for collecting data on the program's utilization. Through the team's efforts, each month bike data is collected, organized, and made public on the [Citi Bike Data](https://www.citibikenyc.com/system-data) webpage. However, while the data has been regularly updated, the team has yet to implement a dashboard or sophisticated reporting process. City officials have a number of questions on the program, so your first task on the job is to build a set of data reports to provide the answers. ## Task **Your task in this assignment is to aggregate the data found in the Citi Bike Trip History Logs and find two unexpected phenomena.** **Design 2-5 visualizations for each discovered phenomena (4-10 total). You may work with a timespan of your choosing. Optionally, you may merge multiple datasets from different periods.** **The following are some questions you may wish to tackle. Do not limit yourself to these questions; they are suggestions for a starting point. Be creative!** * How many trips have been recorded total during the chosen period? * By what percentage has total ridership grown? * How has the proportion of short-term customers and annual subscribers changed? * What are the peak hours in which bikes are used during summer months? * What are the peak hours in which bikes are used during winter months? * Today, what are the top 10 stations in the city for starting a journey? (Based on data, why do you hypothesize these are the top locations?) * Today, what are the top 10 stations in the city for ending a journey? (Based on data, why?) * Today, what are the bottom 10 stations in the city for starting a journey? (Based on data, why?) * Today, what are the bottom 10 stations in the city for ending a journey (Based on data, why?) * Today, what is the gender breakdown of active participants (Male v. Female)? * How effective has gender outreach been in increasing female ridership over the timespan? * How does the average trip duration change by age? * What is the average distance in miles that a bike is ridden? * Which bikes (by ID) are most likely due for repair or inspection in the timespan? * How variable is the utilization by bike ID? **Next, as a chronic over-achiever:** * Use your visualizations (does not have to be all of them) to design a dashboard for each phenomena. * The dashboards should be accompanied with an analysis explaining why the phenomena may be occuring. **City officials would also like to see one of the following visualizations:** * **Basic:** A static map that plots all bike stations with a visual indication of the most popular locations to start and end a journey with zip code data overlaid on top. * **Advanced:** A dynamic map that shows how each station's popularity changes over time (by month and year). Again, with zip code data overlaid on the map. * The map you choose should also be accompanied by a write-up unveiling any trends that were noticed during your analysis. **Finally, create your final presentation** * Create a Tableau story that brings together the visualizations, requested maps, and dashboards. * This is what will be presented to the officials, so be sure to make it professional, logical, and visually appealing. ## Considerations Remember, the people reading your analysis will **NOT** be data analysts. Your audience will be city officials, public administrators, and heads of New York City departments. Your data and analysis needs to be presented in a way that is focused, concise, easy-to-understand, and visually compelling. Your visualizations should be colorful enough to be included in press releases, and your analysis should be thoughtful enough for dictating programmatic changes. ## Submission Your final submission should include: * A link to your Tableau Public workbook that includes: * 4-10 Total "Phenomenon" Visualizations * 2 Dashboards * 1 City Official Map * 1 Story * A text or markdown file with your analysis on the phenomenons you uncovered from the data. ## Assessment Your final product will be assessed on the following metrics: * Analytic Rigor * Readability * Visual Attraction ## Hints * You may need to get creative in how you combine each of the CSV files. Don't just assume Tableau is the right tool for the job. At this point, you have a wealth of technical skills and research abilities. Dig for an approach that works and just go with it. * Don't just assume the CSV format hasn't changed since 2013. Subtle changes to the formats in any of your columns can blockade your analysis. Ensure your data is consistent and clean throughout your analysis. (Hint: Start and End Time change at some point in the history logs). * Consider building your visualizations with small extracts of the data (i.e. single files) before attempting to import the whole thing. What you will find is that importing all 20+ million records of data will create performance issues quickly. Welcome to "Big Data." * While utilizing all of the data may seem like a nice power play, consider the time-course in making your analysis. Is data from 2013 the most relevant for making bike replacement decisions today? Probably not. Don't let overwhelming data fool you. Ground your analysis in common sense. * Remember, data alone doesn't "answer" anything. You will need to accompany your data visualizations with clear and directed answers and analysis. * As is often the case, your clients are asking for a LOT of answers. Be considerate about their need-to-know and the importance of not "cramming in everything". Of course, answer each question, but do so in a way that is organized and presentable. * Since this is a project for the city, spend the appropriate time thinking through decisions on color schemes, fonts, and visual story-telling. The Citi Bike program has a clear visual footprint. As a suggestion, look for ways to have your data visualizations match their aesthetic tones. * Pay attention to labels. What exactly is "time duration"? What's the value of "age of birth"? You will almost certainly need calculated fields to get what you need. * Keep a close eye for obvious outliers or false data. Not everyone who signs up for the program is answering honestly. * In answering the question of "why" a phenomenon is occurring, consider adding other pieces of information on socioeconomic or other geographic data. Tableau has a map "layer" feature that you may find handy. * Don't be afraid to manipulate your data and play with settings in Tableau. Tableau is meant to be explored. We haven't covered all that you need -- so you will need to keep an eye out for new tricks. * Treat this as a serious endeavor! This is an opportunity to show future employers that you have what it takes to be a top-notch analyst. * Good luck! ### Copyright Data Boot Camp (C) 2019. All Rights Reserved.
Assignment Introduction You work in a small business named Dublin Computer School (DCS) who are a small college specializing in IT training that were established 15 years ago. You work as the IT intern and you report into the Infrastructure Manager. The company has a total of twenty full-time staff members. The business is home grown in Dublin and the organization is expanding rapidly both in Dublin and in many sites around Ireland (due to open a training site in Galway, Limerick, Athlone, Cork and Sligo with another ten staff to be recruited shortly). There is a small on premises data centre in the Dublin office (currently it is a small room in the basement but doesn’t have any specialist equipment such as UPS or additional links). It mainly composed of a flat network with just the bare minimum to support the current users. The infrastructure manager predicts that by December 2019, they will have on average 500 users on the Dublin network at any given time during the day. DCS now require a new Moodle system for all training resources and a CRM system for the Marketing department to help advertise and attract students to the college. The infrastructure manager wishes to have all servers to be placed in the data centre on site in the Dublin headquarters. The managing director has given a modest budget for a new data centre to house the new servers and it will need to be built for reliability and availability. They would like to achieve five nines availability across their infrastructure and servers. The infrastructure manager has asked you to evaluate data centres in areas such as security, availability along with other key factors. Part 1: Conduct an individual research report: You will need to create a 1500 word (+/- 10%) research report illustrating the importance of on-premises small data centres today and the potential of housing the businesses critical data for these departments and students to access. Your report should include sections on the following: a) Design and plan for high availability of data for DCS in a new on–premises small data centre in the Dublin office. b) Make recommendations on how security of data (both physical and virtual) can be enforced to best practices in the new on-premises data centre. Make recommendations on how to meet mission critical standards such as five nines for DCS. c) Recommend strategies to migrate existing networks to a fault tolerant infrastructure. As the college is now increasing year on year they need to have a network that can scale and is resilient. IMPORTANT NOTE: Use references (both text and images) in each of the above to help backup the points you make. Note the Harvard referencing system should be used. For each of the above, ensure to keep cognisant the importance of data to the college and why each of the above are required for sending/storing critical data for DCS in today’s digital world. (Part 1: 40 marks) Part 2: Append in your submission in part 1, an individual contribution report (max 300 words): Answer these questions after completing parts 3 & 4 below: i. What parts did you participate in for Parts 3 and 4 below. ii. What did you learn from working within a team? iii. What would you do differently if you had to build it again? iv. What did you find most difficult to implement or understand. v. What do you wish you could have implemented if you had more time? Any other thoughts? (Part 2: 5 marks) Part 3: Group - Design and implement a network using Packet Tracer to Model the following network: Include TWO networks – the Dublin HQ and the Galway office. In the main Dublin office implement the following: a) Create different VLANs (at least 4 VLANs – name these with relevant departments e.g. SALES, MARKETING etc) b) Implement inter-VLAN communication between all of these VLANs. c) Implement rapid spanning tree between switches. d) Show evidence of Etherchannel being implemented (add links to implement this)-ensure the root bridge is in a suitable position in the network. e) Configure a highly available secure wireless access for a GUEST wifi network in the main Dublin office. Show evidence of these PC’s connecting to the network (ensure that PC’s connect using DHCP). On the WAN: f) The organization requires you to create a WAN network bridging across their different sites. Each site has a WAN connection and all other sites will need to be connected e.g. Cork, Limerick, Athlone. The IT infrastructure manager has specified your main concern is the interconnection of Dublin and Galway sites but you are required to route through other sites to connect Dublin to Galway. Create a WAN network using private addresses from the 10.0.0.0 network which must provide connectivity to the Galway office. This WAN network will include a redundant path from the Dublin office through the Sligo office to Galway. However, this redundant path is known to have a slow connection. g) Utilizing a routing protocol of your choice to ensure all Dublin HQ PC’s can communicate with the Galway branch. (note more points will be awarded for ability to demonstrate control of traffic through the network). Ensure that the main gateway router can be managed remotely from the Dublin site using a secure protocol (SSH protocol). In the Galway office: h) Create a small LAN in the Galway office showing at least 2 switches and multiple PC’s. i) Implement HSRP and provide redundant default gateways for end-user devices within the network if one of the routers fails. j) Ensure all PCs in the Galway office can communicate with PC’s / servers in the Dublin’s office. (Part 3: 40 marks) Part 4: Group Justification Report Justify the design choices you made in Part 3. Use screen shots to provide key samples of why you did things for your implemented parts a) – j) (in part 3 above). Note: Five additional marks can be scored if other best practice configuration and security is completed in part 3 and documented in part 4. (Part 4: 15 marks) Your submission must be your own work and once completed, must be uploaded to Moodle within the time frame above. Any student found breaking College regulations will receive zero marks. Copying and pasting large sections of text directly from web sites is NOT permitted and will result in zero marks awarded. Read the assignment carefully and answer the questions that have been asked. Specific Requirements • For report sections: create using MS Word OR similar software and upload as a PDF document. Each member to upload group Packet Tracer file. • You will need to supply the following: • Individual report – Part A • Individual contribution / reflection – Part B • Group Packet Tracer file – Part C • Group Justification report – Part D
EhsanEIK
Assignment 10 (Server Side)
kazifahim7
No description available
ronisarkarexe
No description available
Das203web-dev
No description available
Dipta04
No description available
Mahmud256
No description available