text:
.. _example_algs:

###############################################################################
Auxiliary Algorithms
###############################################################################

This pages links to various algorithms that have been written for OpenPNM but for some reason are not included in the main package.  This usually happens the algorithm was written for an older version, and was not maintained or updated to a newer version.

.. toctree::
   :maxdepth: 1

   IP_timed.rst


text:
package versions_test

import (
	. "github.com/onsi/ginkgo/v2"
	. "github.com/onsi/gomega"

	"testing"
)

func TestVersions(t *testing.T) {
	RegisterFailHandler(Fail)
	RunSpecs(t, "Versions Suite")
}

redpajama_set_name: RedPajamaGithub


text:
module Alchemy
  module Admin
    class EssenceVideosController < Alchemy::Admin::BaseController

      def update
        @essence_video = EssenceVideo.find(params[:id])
        @essence_video.update_attributes(params[:essence_video])
      end

    end
  end
end


text:
And(/^I start a new refund$/) do
  visit '/apply/refund'
end

When(/^I start a new refund for a sole party who paid the tribunal fees directly and has not been reimbursed$/) do
  visit '/apply/refund'
  refund_profile_selection_page.select_profile.set('I was an individual claimant who made the payments set out in this application and have not been reimbursed by anyone pursuant to an order of the Tribunal')
  step("I take a screenshot named \"Page 1 - Applicant Type Selector\"")
  refund_profile_selection_page.save_and_continue.click
end

When(/^I start a new refund for an individual claimant whos representative paid the fees and the indivual reimbursed them$/) do
  visit '/apply/refund'
  refund_profile_selection_page.select_profile.set('I was an individual claimant whose representative paid the fee and I then reimbursed them')
  step("I take a screenshot named \"Page 1 - Applicant Type Selector\"")
  refund_profile_selection_page.save_and_continue.click
end


text:
CLASS({
  package: 'foam.documentation',
  name: 'DocOptionalView',
  extends: 'foam.documentation.DocView',
  documentation: 'A view wrapper for hiding content if a DAO is empty.',

  properties: [
    {
      name: 'data',
      hidden: false,
      postSet: function() {
        this.childData = this.data;
        if (this.data && this.data.select) {
          this.dao = this.data;
        } else {
          this.dao = [];
        }
      }
    },
    {
      name:  'dao',
      model_: 'foam.core.types.DAOProperty',
      factory: function() { return []; },
      onDAOUpdate: function() {
        var self = this;
        this.dao.select(COUNT())(function(c) {
          self.hasContent = c.count > 0;
        });
      }
    },
    {
      name: 'hasContent',
      defaultValue: false,
      postSet: function() {
        this.updateHTML();
      }
    }
  ]

});


text:
template '/etc/consul/conf.d/swarm.json' do
  source 'swarm.json.erb'
  variables swarm: node['docker-simple']['swarm']
  action :create
  mode '0644'
end


text:
from __future__ import absolute_import
from __future__ import unicode_literals

import mock

from pre_commit.languages import docker
from pre_commit.util import CalledProcessError

def test_docker_is_running_process_error():
    with mock.patch(
        'pre_commit.languages.docker.cmd_output',
        side_effect=CalledProcessError(*(None,) * 4)
    ):
        assert docker.docker_is_running() is False


text:
<?php
/**
 * Read from STDIN without blocking or waiting for input
 * @param filehandle pointer to php://stdin'
 * @return string the input from the stream if ready, otherwise empty string
 */
function fgets_u($fh) {

	// the stream_select function will indicate if there is anything to read
    $read = array($fh);
	$write  = NULL;
	$except = NULL;
	$num_changed_streams = stream_select($read, $write, $except, 0);

    if (false === $num_changed_streams) {
        throw new Exception("Unable to watch STDIN");
    }

	if ($num_changed_streams > 0) {
        return trim(fgets($fh));
    }
}


text:
id: 5900f5141000cf542c510027
challengeType: 5
title: 'Problem 423: Consecutive die throws'
videoUrl: ''
localeTitle: ''
---

## Description
undefined

## Instructions
undefined

## Tests

```yml
tests:
  - text: ''
    testString: 'assert.strictEqual(euler423(), 653972374, "<code>euler423()</code> should return 653972374.");'

```

## Challenge Seed

```js
function euler423() {
  // Good luck!
  return true;
}

euler423();

```

## Solution

```js
// solution required
```


text:
/* global inject, describe, availity, it, expect, beforeEach, module */

describe('avHasPermission', function() {

  'use strict';

  var $el;

  beforeEach(function() {
    module('availity', 'availity.ui');
  });

  availity.mock.directiveSpecHelper();

  var FIXTURES = {
    MARKUP: {
      VALID: '<div ng-cloak data-av-has-permission="1000"></button>',
      INVALID: '<div ng-cloak data-av-has-permission="2000"></button>'
    },
    REQUESTS: {
      VALID: '/api/internal/v1/axi-user-permissions?permissionId=1000',
      INVALID: '/api/internal/v1/axi-user-permissions?permissionId=2000'
    },
    RESPONSE: {
      'axiUserPermissions': [
        {
        'id': '1000',
        'description': 'Eligibility and Benefits Inquiry',
        'organizations':
          [{
            'id': '2000',
            'customerId': '1001',
            'name': 'sample org name',
            'resources': [{'id': '3000', 'payerId': 'PAYER1', 'payerName': 'Payer One'}]
          }]
      }]
    }
  };

  beforeEach(inject(function(_$httpBackend_, _avUserAuthorizations_, avUserPermissionsResource) {
    availity.mock.$scope.demo = {};
    availity.mock.$scope.demo.permissions = ['1000'];
    avUserPermissionsResource.sessionDate = null; // clear session date for tests
  }));

  it('should show content with VALID permission ', function() {
    availity.mock.$httpBackend.expectGET(FIXTURES.REQUESTS.VALID).respond(200, FIXTURES.RESPONSE);
    $el = availity.mock.compileDirective(FIXTURES.MARKUP.VALID);
    availity.mock.$scope.$digest();
    availity.mock.$httpBackend.flush();
    expect($el.is(':visible')).toBe(true);
  });

  it('should NOT show content with INVALID permission ', function() {
    availity.mock.$httpBackend.expectGET(FIXTURES.REQUESTS.INVALID).respond(200, FIXTURES.RESPONSE);
    $el = availity.mock.compileDirective(FIXTURES.MARKUP.INVALID);
    availity.mock.$scope.$digest();
    availity.mock.$httpBackend.flush();
    expect($el.is(':visible')).toBe(false);
  });

});


text:
package org.basex.query.func.fn;

import org.basex.query.*;
import org.basex.query.iter.*;
import org.basex.query.value.*;

/**
 * Function implementation.
 *
 * @author BaseX Team 2005-15, BSD License
 * @author Christian Gruen
 */
public final class FnUnparsedTextLines extends Parse {
  @Override
  public Iter iter(final QueryContext qc) throws QueryException {
    return textIter(unparsedText(qc, false, true).string(info));
  }

  @Override
  public Value value(final QueryContext qc) throws QueryException {
    return iter(qc).value();
  }

  @Override
  public boolean iterable() {
    // collections will never yield duplicates
    return true;
  }
}


text:
<!--
	Copyright 2016 Black Pepper Software

	Licensed under the Apache License, Version 2.0 (the "License");
	you may not use this file except in compliance with the License.
	You may obtain a copy of the License at

	    http://www.apache.org/licenses/LICENSE-2.0

	Unless required by applicable law or agreed to in writing, software
	distributed under the License is distributed on an "AS IS" BASIS,
	WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
	See the License for the specific language governing permissions and
	limitations under the License.
-->
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">

	<!--
		Deploy module - workaround for https://issues.sonatype.org/browse/NEXUS-9138
	-->

	<modelVersion>4.0.0</modelVersion>

	<parent>
		<groupId>me.hdpe.bowman</groupId>
		<artifactId>bowman-parent</artifactId>
		<version>0.9.1-SNAPSHOT</version>
	</parent>

	<artifactId>bowman-deploy</artifactId>
	<packaging>pom</packaging>

	<dependencies>
		<dependency>
			<groupId>${project.groupId}</groupId>
			<artifactId>bowman-test-it</artifactId>
			<version>${project.version}</version>
		</dependency>
	</dependencies>

</project>


text:
process.env.NODE_ENV = 'test';

const chai = require('chai');

const { expect } = chai;
const chaiAsPromised = require('chai-as-promised');
const config = require('../../app/models/config-model').server;

config['account lib'] = undefined;
const model = require('../../app/models/account-model');

chai.use(chaiAsPromised);

describe('Account Model', () => {
    describe('get: when attempting to obtain an account', () => {
        it('returns an error when the account does not exist', () =>
            expect(model.get('nonexisting')).to.eventually.be.rejected);

        [
            // config               // request serverUrl
            ['http://example.com', 'http://example.com'],
            ['http://example.com', 'https://example.com'],
            ['http://example.com', 'http://example.com/johndoe'],
            ['http://example.com', 'https://example.com/johndoe'],
            ['https://example.com', 'http://example.com'],
            ['https://example.com', 'http://example.com/johndoe'],
            ['https://example.com', 'https://example.com/johndoe'],
            ['example.com', 'http://example.com'],
            ['example.com', 'https://example.com'],
            ['example.com', 'http://example.com/johndoe'],
        ].forEach((test) => {
            const accountServerUrl = test[0];
            const requestServerUrl = test[1];
            it(`returns the hardcoded account object with linked server ${accountServerUrl} and request server ${requestServerUrl}`, () => {
                let getAccountPromise;
                const accountKey = '123abc';
                const survey = {
                    openRosaServer: requestServerUrl,
                };

                config['linked form and data server']['server url'] =
                    accountServerUrl;
                config['linked form and data server']['api key'] = accountKey;
                config['account manager api key'] = '';

                getAccountPromise = model.get(survey);

                return Promise.all([
                    expect(getAccountPromise)
                        .to.eventually.have.property('key')
                        .and.to.equal(accountKey),
                    expect(getAccountPromise)
                        .to.eventually.have.property('linkedServer')
                        .and.to.equal(accountServerUrl),
                ]);
            });
        });

        [
            ['http://example.com', 'http://example.org', 403],
            ['http://examplecom', 'http://example.org', 403],
            ['http://example.com/johndoe', 'http://example.com', 403],
        ].forEach((test) => {
            const accountServerUrl = test[0];
            const requestServerUrl = test[1];
            const errorCode = test[2];
            it(`returns ${errorCode} for ${accountServerUrl} and request server ${requestServerUrl}`, () => {
                const survey = {
                    openRosaServer: requestServerUrl,
                };

                config['linked form and data server']['server url'] =
                    accountServerUrl;

                const getAccountPromise = model.get(survey);

                return expect(getAccountPromise).to.eventually.be.rejected;
            });
        });
    });
});


text:
/* Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.camunda.bpm.engine.rest.sub.runtime;

import org.camunda.bpm.engine.rest.dto.runtime.CaseExecutionTriggerDto;
import org.camunda.bpm.engine.rest.dto.runtime.CaseInstanceDto;
import org.camunda.bpm.engine.rest.sub.VariableResource;

import javax.ws.rs.*;
import javax.ws.rs.core.MediaType;

/**
 *
 * @author Roman Smirnov
 *
 */
public interface CaseInstanceResource {

  @GET
  @Produces(MediaType.APPLICATION_JSON)
  CaseInstanceDto getCaseInstance();

  @POST
  @Path("/complete")
  @Consumes(MediaType.APPLICATION_JSON)
  void complete(CaseExecutionTriggerDto triggerDto);

  @POST
  @Path("/close")
  @Consumes(MediaType.APPLICATION_JSON)
  void close(CaseExecutionTriggerDto triggerDto);

  @POST
  @Path("/terminate")
  @Consumes(MediaType.APPLICATION_JSON)
  void terminate(CaseExecutionTriggerDto triggerDto);

  @Path("/variables")
  VariableResource getVariablesResource();

}


text:
import { EventEmitter, OnInit } from '@angular/core';
export declare class StringControlComponent implements OnInit {
    data: any;
    collapsed: boolean;
    fields: Array<string>;
    formats: Array<string>;
    keyChanged: EventEmitter<any>;
    constructor();
    ngOnInit(): void;
    onKeyChanged(newKey: string): void;
    addField(field: string): void;
}


text:
package calendar.user.dto;

/**
 * Class RegistrationDTO
 *
 * @author Axel Nilsson (axnion)
 */
public class RegistrationDTO {
    private String email;
    private String password;
    private String passwordConfirmation;
    private String organization;
    private String gRecaptchaResponse;

    public String getEmail() {
        return email;
    }

    public String getPassword() {
        return password;
    }

    public String getPasswordConfirmation() {
        return passwordConfirmation;
    }

    public String getOrganization() {
        return organization;
    }

    public String getRecaptcha() {
        return gRecaptchaResponse;
    }

    public void setEmail(String email) {
        this.email = email;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public void setPasswordConfirmation(String passwordConfirmation) {
        this.passwordConfirmation = passwordConfirmation;
    }

    public void setOrganization(String organization) {
        this.organization = organization;
    }

    public void setgRecaptchaResponse(String recaptcha) {
        this.gRecaptchaResponse = recaptcha;
    }
}


text:
/**
 * Contains the central plugin handler {@link io.reactivex.rxjava3.plugins.RxJavaPlugins}
 * class to hook into the lifecycle of the base reactive types and schedulers.
 */
package io.reactivex.rxjava3.plugins;


text:
"""HydraTK default event class

.. module:: core.event
   :platform: Unix
   :synopsis: HydraTK default event class
.. moduleauthor:: Petr Czaderna <pc@hydratk.org>

"""

import pprint

class Event(object):
    """ Class Event
    """

    _id = None
    _args = ()
    _data = {}
    _propagate = True
    _run_default = True
    _skip_before_hook = False
    _skip_after_hook = False

    def __init__(self, event_id, *args, **kwargs):
        """Class constructor

        Called when the object is initialized

        Args:
           event_id (str): event
           args (args): arguments
           kwargs (kwargs): key value arguments

        Raises:
           error: ValueError

        """

        self._args = ()
        self._data = {}
        self._propagate = True
        self._run_default = True
        self._skip_before_hook = False
        self._skip_after_hook = False
        if isinstance(event_id, str) and event_id != '':
            self._id = event_id
            self._data['target_event'] = None
            self._data['source_event'] = None
        else:
            raise ValueError(
                "Invalid event id specified, nonempty string is required")

        if isinstance(args, tuple):
            self._args = ()
        self._args = args
        if len(kwargs) > 0:
            for k, v in kwargs.items():

                self._data[k] = v

    @property
    def id(self):
        """Method gets id attribute

        Args:
           none

        Returns:
           str

        """

        return self._id

    def argc(self):
        """Method gets count of arguments

        Args:
           none

        Returns:
           int: count of arguments

        """

        return len(self._args)

    def args(self):
        """Method gets args attribute

        Args:
           none

        Returns:
           tuple

        """

        return self._args

    def get_all_data(self):
        """Method gets event data

        Args:
           none

        Returns:
           dict: data

        """

        return self._data

    def get_data(self, key):
        """Method gets requested event data

        Args:
           key (str): data key

        Returns:
           obj: data value

        """

        return self._data[key] if (key in self._data) else None

    def set_data(self, key, value):
        """Method sets requested event data

        Args:
           key (str): data key
           value (obj): data value

        Returns:
           void

        Raises:
           error: ValueError

        """

        if isinstance(key, str) and key != '':
            self._data[key] = value
        else:
            raise ValueError(
                "Invalid key specified, nonempty string is required")

    def argv(self, num):
        """Method gets request event argument

        Args:
           num (int): argument index

        Returns:
           obj: argument value

        """

        return self._args[num] if (num < len(self._args)) else None

    def set_argv(self, num, val=None):
        """Method sets requested event argument

        Args:
           num (int): argument index
           val (obj): argument value

        Returns:
           void

        """

        if isinstance(num, int) and num < len(self._args):
            args = list(self._args)
            args[num] = val
            self._args = tuple(args)

    def stop_propagation(self):
        """Method stops event propagation

        Args:
           none

        Returns:
           void

        """

        self._propagate = False

    @property
    def skip_before_hook(self):
        """ skip_before_hook property getter """

        return self._skip_before_hook

    @property
    def skip_after_hook(self):
        """ skip_after_hook property getter """

        return self._skip_after_hook

    def prevent_default(self):
        """Method prevents default event processing

        Args:
           none

        Returns:
           void

        """

        self._run_default = False

    def run_default(self):
        """Method enables default event processing

        Args:
           none

        Returns:
           void

        """

        self._run_default = True

    def will_run_default(self):
        """Method gets default event processing

        Args:
           none

        Returns:
           bool: run_default

        """

        return self._run_default

    def propagate(self):
        """Method gets propagate attribute

        Args:
           none

        Returns:
           bool

        """

        return self._propagate


text:
/*
 *  $Date: 2000/10/28 17:39:31 $
 *  $Author: hafner $
 *  $Revision: 5.5 $
 *  $State: Exp $
 */

#define _BSD_SOURCE 1   /* Make sure strdup() is in string.h */
#define _XOPEN_SOURCE 500  /* Make sure strdup() is in string.h */

#include "config.h"

#include <string.h>
#if STDC_HEADERS
#	include <stdlib.h>
#endif /* not STDC_HEADERS */

#include <stdio.h>

#include "types.h"
#include "macros.h"
#include "error.h"

#include "wfa.h"
#include "misc.h"
#include "bit-io.h"
#include "fiasco.h"
#include "options.h"

fiasco_c_options_t *
fiasco_c_options_new (void)
/*
 *  FIASCO options constructor.
 *  Allocate memory for the FIASCO coder options structure and
 *  fill in default values.
 *
 *  Return value:
 *	pointer to the new option structure
 */
{
   c_options_t 	      *options = calloc (1, sizeof (c_options_t));
   fiasco_c_options_t *public  = calloc (1, sizeof (fiasco_c_options_t));

   if (!options || !public)
   {
      set_error (_("Out of memory."));
      return NULL;
   }
   public->private 	      = options;
   public->delete 	      = fiasco_c_options_delete;
   public->set_tiling 	      = fiasco_c_options_set_tiling;
   public->set_frame_pattern  = fiasco_c_options_set_frame_pattern;
   public->set_basisfile      = fiasco_c_options_set_basisfile;
   public->set_chroma_quality = fiasco_c_options_set_chroma_quality;
   public->set_optimizations  = fiasco_c_options_set_optimizations;
   public->set_video_param    = fiasco_c_options_set_video_param;
   public->set_quantization   = fiasco_c_options_set_quantization;
   public->set_progress_meter = fiasco_c_options_set_progress_meter;
   public->set_smoothing      = fiasco_c_options_set_smoothing;
   public->set_title   	      = fiasco_c_options_set_title;
   public->set_comment        = fiasco_c_options_set_comment;

   strcpy (options->id, "COFIASCO");

   /*
    *  Set default value of fiasco options
    */
   options->basis_name 		  = strdup ("small.fco");
   options->lc_min_level 	  = 4;
   options->lc_max_level 	  = 12;
   options->p_min_level 	  = 8;
   options->p_max_level 	  = 10;
   options->images_level 	  = 5;
   options->max_states 		  = MAXSTATES;
   options->chroma_max_states 	  = 40;
   options->max_elements 	  = MAXEDGES;
   options->tiling_exponent 	  = 4;
   options->tiling_method 	  = FIASCO_TILING_VARIANCE_DSC;
   options->id_domain_pool 	  = strdup ("rle");
   options->id_d_domain_pool 	  = strdup ("rle");
   options->id_rpf_model 	  = strdup ("adaptive");
   options->id_d_rpf_model 	  = strdup ("adaptive");
   options->rpf_mantissa 	  = 3;
   options->rpf_range 		  = FIASCO_RPF_RANGE_1_50;
   options->dc_rpf_mantissa 	  = 5;
   options->dc_rpf_range 	  = FIASCO_RPF_RANGE_1_00;
   options->d_rpf_mantissa 	  = 3;
   options->d_rpf_range 	  = FIASCO_RPF_RANGE_1_50;
   options->d_dc_rpf_mantissa 	  = 5;
   options->d_dc_rpf_range 	  = FIASCO_RPF_RANGE_1_00;
   options->chroma_decrease 	  = 2.0;
   options->prediction 		  = NO;
   options->delta_domains 	  = YES;
   options->normal_domains 	  = YES;
   options->search_range 	  = 16;
   options->fps 		  = 25;
   options->pattern 		  = strdup ("IPPPPPPPPP");
   options->reference_filename 	  = NULL;
   options->half_pixel_prediction = NO;
   options->cross_B_search 	  = YES;
   options->B_as_past_ref 	  = YES;
   options->check_for_underflow   = NO;
   options->check_for_overflow 	  = NO;
   options->second_domain_block   = NO;
   options->full_search 	  = NO;
   options->progress_meter 	  = FIASCO_PROGRESS_NONE;
   options->smoothing 	 	  = 70;
   options->comment 		  = strdup ("");
   options->title 		  = strdup ("");

   return public;
}

void
fiasco_c_options_delete (fiasco_c_options_t *options)
/*
 *  FIASCO options destructor.
 *  Free memory of FIASCO options struct.
 *
 *  No return value.
 *
 *  Side effects:
 *	structure 'options' is discarded.
 */
{
   c_options_t *this = cast_c_options (options);

   if (!this)
      return;

   Free (this->id_domain_pool);
   Free (this->id_d_domain_pool);
   Free (this->id_rpf_model);
   Free (this->id_d_rpf_model);
   Free (this->pattern);
   Free (this->comment);
   Free (this->title);

   Free (this);

   return;
}

int
fiasco_c_options_set_tiling (fiasco_c_options_t *options,
			     fiasco_tiling_e method, unsigned exponent)
/*
 *  Set tiling `method' and `exponent'.
 *  See type `fiasco_tiling_e' for a list of valid  tiling `methods'.
 *  The image is subdivied into 2^`exponent' tiles
 *
 *  Return value:
 *	1 on success
 *	0 otherwise
 */
{
   c_options_t *this = (c_options_t *) cast_c_options (options);

   if (!this)
   {
      return 0;
   }
   switch (method)
   {
      case FIASCO_TILING_SPIRAL_ASC:
      case FIASCO_TILING_SPIRAL_DSC:
      case FIASCO_TILING_VARIANCE_ASC:
      case FIASCO_TILING_VARIANCE_DSC:
	 this->tiling_method = method;
	 break;
      default:
	 set_error (_("Invalid tiling method `%d' specified "
		      "(valid methods are 0, 1, 2, or 3)."), method);
	 return 0;
   }
   this->tiling_exponent = exponent;

   return 1;
}

int
fiasco_c_options_set_frame_pattern (fiasco_c_options_t *options,
				    const char *pattern)
/*
 *  Set `pattern' of input frames.
 *  `pattern' has to be a sequence of the following
 *  characters (case insensitive):
 *  'i' intra frame
 *  'p' predicted frame
 *  'b' bidirectional predicted frame
 *  E.g. pattern = 'IBBPBBPBB'
 *
 *  When coding video frames the prediction type of input frame N is determined
 *  by reading `pattern' [N] (`pattern' is periodically extended).
 *
 *  Return value:
 *	1 on success
 *	0 otherwise
 */
{
   c_options_t *this = (c_options_t *) cast_c_options (options);

   if (!this)
   {
      return 0;
   }
   else if (!pattern)
   {
      set_error (_("Parameter `%s' not defined (NULL)."), "pattern");
      return 0;
   }
   else if (strlen (pattern) < 1)
   {
      set_error (_("Frame type pattern doesn't contain any character."));
      return 0;
   }
   else
   {
      const char *str;
      bool_t 	  parse_error = NO;
      int	  c 	      = 0;

      for (str = pattern; *str && !parse_error; str++)
	 switch (*str)
	 {
	    case 'i':
	    case 'I':
	    case 'b':
	    case 'B':
	    case 'p':
	    case 'P':
	       break;
	    default:
	       c = *str;
	       parse_error = YES;
	 }

      if (parse_error)
      {
	 set_error (_("Frame type pattern contains invalid character `%c' "
		      "(choose I, B or P)."), c);
	 return 0;
      }
      else
      {
	 Free (this->pattern);
	 this->pattern = strdup (pattern);

	 return 1;
      }
   }
}

int
fiasco_c_options_set_basisfile (fiasco_c_options_t *options,
				const char *filename)
/*
 *  Set `filename' of FIASCO initial basis.
 *
 *  Return value:
 *	1 on success (if the file is readable)
 *	0 otherwise
 */
{
   c_options_t *this = (c_options_t *) cast_c_options (options);

   if (!this)
   {
      return 0;
   }
   else if (!filename)
   {
      set_error (_("Parameter `%s' not defined (NULL)."), "filename");
      return 0;
   }
   else
   {
       /* Skip this because basis file may be linked with program, not
          in a separate file.  See get_linked_basis().  NETPBM
      FILE *file = open_file (filename, "FIASCO_DATA", READ_ACCESS);
      if (file)
      {
	 fclose (file);
	 return 1;
      }
      else
      {
	 set_error (_("Can't read basis file `%s'.\n%s."), filename,
		    get_system_error ());
	 return 0;
      }
      */ return 1;
   }
}

int
fiasco_c_options_set_chroma_quality (fiasco_c_options_t *options,
				     float quality_factor,
				     unsigned dictionary_size)
/*
 *  Set color compression parameters.
 *  When coding chroma channels (Cb and Cr)
 *  - approximation quality is given by `quality_factor' * `Y quality' and
 *  - `dictionary_size' gives the number of dictionary elements.
 *
 *  If 'quality' <= 0 then the luminancy coding quality is also during
 *  chroma channel coding.
 *
 *  Return value:
 *	1 on success
 *	0 otherwise
 */
{
   c_options_t *this = (c_options_t *) cast_c_options (options);

   if (!this)
   {
      return 0;
   }
   else if (!dictionary_size)
   {
      set_error (_("Size of chroma compression dictionary has to be "
		   "a positive number."));
      return 0;
   }
   else if (quality_factor <= 0)
   {
      set_error (_("Quality of chroma channel compression has to be "
		   "positive value."));
      return 0;
   }
   else
   {
      this->chroma_decrease   = quality_factor;
      this->chroma_max_states = dictionary_size;

      return 1;
   }
}

int
fiasco_c_options_set_optimizations (fiasco_c_options_t *options,
				    unsigned min_block_level,
				    unsigned max_block_level,
				    unsigned max_elements,
				    unsigned dictionary_size,
				    unsigned optimization_level)
/*
 *  Set various optimization parameters.
 *  - During compression only image blocks of size
 *    {`min_block_level', ... ,`max_block_level'} are considered.
 *    The smaller this set of blocks is the faster the coder runs
 *    and the worse the image quality will be.
 *  - An individual approximation may use at most `max_elements'
 *    elements of the dictionary which itself contains at most
 *    `dictionary_size' elements. The smaller these values are
 *    the faster the coder runs and the worse the image quality will be.
 *  - `optimization_level' enables some additional low level optimizations.
 *    0: standard approximation method
 *    1: significantly increases the approximation quality,
 *       running time is twice as high as with the standard method
 *    2: hardly increases the approximation quality of method 1,
 *       running time is twice as high as with method 1
 *       (this method just remains for completeness)
 *
 *  Return value:
 *	1 on success
 *	0 otherwise
 */
{
   c_options_t *this = (c_options_t *) cast_c_options (options);

   if (!this)
   {
      return 0;
   }
   else if (!dictionary_size)
   {
      set_error (_("Size of dictionary has to be a positive number."));
      return 0;
   }
   else if (!max_elements)
   {
      set_error (_("At least one dictionary element has to be used "
		   "in an approximation."));
      return 0;
   }
   else if (max_block_level < 4)
   {
      set_error (_("Maximum image block size has to be at least level 4."));
      return 0;
   }
   else if (min_block_level < 4)
   {
      set_error (_("Minimum image block size has to be at least level 4."));
      return 0;
   }
   else if (max_block_level < min_block_level)
   {
      set_error (_("Maximum block size has to be larger or "
		   "equal minimum block size."));
      return 0;
   }
   else
   {
      this->lc_min_level 	= min_block_level;
      this->lc_max_level 	= max_block_level;
      this->max_states 	 	= dictionary_size;
      this->max_elements 	= max_elements;
      this->second_domain_block = optimization_level > 0 ? YES : NO;
      this->check_for_overflow  = optimization_level > 1 ? YES : NO;
      this->check_for_underflow = optimization_level > 1 ? YES : NO;
      this->full_search 	= optimization_level > 1 ? YES : NO;

      return 1;
   }
}

int
fiasco_c_options_set_prediction (fiasco_c_options_t *options,
				 int intra_prediction,
				 unsigned min_block_level,
				 unsigned max_block_level)
/*
 *  Set minimum and maximum size of image block prediction to
 *  `min_block_level' and `max_block_level'.
 *  (For either motion compensated prediction of inter frames
 *   or DC based prediction of intra frames)
 *  Prediction of intra frames is only used if `intra_prediction' != 0.
 *
 *  Return value:
 *	1 on success
 *	0 otherwise
 */
{
   c_options_t *this = (c_options_t *) cast_c_options (options);

   if (!this)
   {
      return 0;
   }
   else if (max_block_level < 6)
   {
      set_error (_("Maximum prediction block size has to be "
		   "at least level 6"));
      return 0;
   }
   else if (min_block_level < 6)
   {
      set_error (_("Minimum prediction block size has to be "
		   "at least level 6"));
      return 0;
   }
   else if (max_block_level < min_block_level)
   {
      set_error (_("Maximum prediction block size has to be larger or "
		   "equal minimum block size."));
      return 0;
   }
   else
   {
      this->p_min_level = min_block_level;
      this->p_max_level = max_block_level;
      this->prediction  = intra_prediction;

      return 1;
   }
}

int
fiasco_c_options_set_video_param (fiasco_c_options_t *options,
				  unsigned frames_per_second,
				  int half_pixel_prediction,
				  int cross_B_search,
				  int B_as_past_ref)
/*
 *  Set various parameters used for video compensation.
 *  'frames_per_second' defines the frame rate which should be
 *  used when the video is decoded. This value has no effect during coding,
 *  it is just passed to the FIASCO output file.
 *  If 'half_pixel_prediction' is not 0 then half pixel precise
 *  motion compensated prediction is used.
 *  If 'cross_B_search' is not 0 then the fast Cross-B-Search algorithm is
 *  used to determine the motion vectors of interpolated prediction. Otherwise
 *  exhaustive search (in the given search range) is used.
 *  If 'B_as_past_ref' is not 0 then B frames are allowed to be used
 *  for B frame predicion.
 *
 *  Return value:
 *	1 on success
 *	0 otherwise
 */
{
   c_options_t *this = (c_options_t *) cast_c_options (options);

   if (!this)
   {
      return 0;
   }
   else
   {
      this->fps 	  	  = frames_per_second;
      this->half_pixel_prediction = half_pixel_prediction;
      this->cross_B_search 	  = cross_B_search;
      this->B_as_past_ref 	  = B_as_past_ref;

      return 1;
   }
}

int
fiasco_c_options_set_quantization (fiasco_c_options_t *options,
				   unsigned mantissa,
				   fiasco_rpf_range_e range,
				   unsigned dc_mantissa,
				   fiasco_rpf_range_e dc_range)
/*
 *  Set accuracy of coefficients quantization.
 *  DC coefficients (of the constant dictionary vector f(x,y) = 1)
 *  are quantized to values of the interval [-`dc_range', `dc_range'] using
 *  #`dc_mantissa' bits. All other quantized coefficients are quantized in
 *  an analogous way using the parameters `range' and `mantissa'.
 *
 *  Return value:
 *	1 on success
 *	0 otherwise
 */
{
   c_options_t *this = (c_options_t *) cast_c_options (options);

   if (!this)
   {
      return 0;
   }
   else if (mantissa < 2 || mantissa > 8 || dc_mantissa < 2 || dc_mantissa > 8)
   {
      set_error (_("Number of RPF mantissa bits `%d', `%d' have to be in "
		   "the interval [2,8]."), mantissa, dc_mantissa);
      return 0;
   }
   else
   {
      if ((range == FIASCO_RPF_RANGE_0_75
	  || range == FIASCO_RPF_RANGE_1_00
	  || range == FIASCO_RPF_RANGE_1_50
	   || range == FIASCO_RPF_RANGE_2_00)
	  &&
	  (dc_range == FIASCO_RPF_RANGE_0_75
	   || dc_range == FIASCO_RPF_RANGE_1_00
	   || dc_range == FIASCO_RPF_RANGE_1_50
	   || dc_range == FIASCO_RPF_RANGE_2_00))
      {
	 this->rpf_range       = range;
	 this->dc_rpf_range    = dc_range;
	 this->rpf_mantissa    = mantissa;
	 this->dc_rpf_mantissa = dc_mantissa;

	 return 1;
      }
      else
      {
	 set_error (_("Invalid RPF ranges `%d', `%d' specified."),
		    range, dc_range);
	 return 0;
      }
   }
}

int
fiasco_c_options_set_progress_meter (fiasco_c_options_t *options,
				     fiasco_progress_e type)
/*
 *  Set type of progress meter.
 *
 *  Return value:
 *	1 on success
 *	0 otherwise
 */
{
   c_options_t *this = (c_options_t *) cast_c_options (options);

   if (!this)
   {
      return 0;
   }
   switch (type)
   {
      case FIASCO_PROGRESS_BAR:
      case FIASCO_PROGRESS_PERCENT:
      case FIASCO_PROGRESS_NONE:
	 this->progress_meter = type;
	 break;
      default:
	 set_error (_("Invalid progress meter `%d' specified "
		      "(valid values are 0, 1, or 2)."), type);
	 return 0;
   }
   return 1;
}

int
fiasco_c_options_set_smoothing (fiasco_c_options_t *options, int smoothing)
/*
 *  Define `smoothing'-percentage along partitioning borders.
 *
 *  Return value:
 *	1 on success
 *	0 otherwise
 */
{
   c_options_t *this = (c_options_t *) cast_c_options (options);

   if (!this)
   {
      return 0;
   }
   else if (smoothing < -1 || smoothing > 100)
   {
      set_error (_("Smoothing percentage must be in the range [-1, 100]."));
      return 0;
   }
   else
   {
      this->smoothing = smoothing;
      return 1;
   }
}

int
fiasco_c_options_set_comment (fiasco_c_options_t *options, const char *comment)
/*
 *  Define `comment' of FIASCO stream.
 *
 *  Return value:
 *	1 on success
 *	0 otherwise
 */
{
   c_options_t *this = (c_options_t *) cast_c_options (options);

   if (!this)
   {
      return 0;
   }
   else if (!comment)
   {
      set_error (_("Parameter `%s' not defined (NULL)."), "title");
      return 0;
   }
   else
   {
      this->comment = strdup (comment);
      return 1;
   }
}

int
fiasco_c_options_set_title (fiasco_c_options_t *options, const char *title)
/*
 *  Define `title' of FIASCO stream.
 *
 *  Return value:
 *	1 on success
 *	0 otherwise
 */
{
   c_options_t *this = (c_options_t *) cast_c_options (options);

   if (!this)
   {
      return 0;
   }
   else if (!title)
   {
      set_error (_("Parameter `%s' not defined (NULL)."), "title");
      return 0;
   }
   else
   {
      this->title = strdup (title);
      return 1;
   }
}

c_options_t *
cast_c_options (fiasco_c_options_t *options)
/*
 *  Cast generic pointer `options' to type c_options_t.
 *  Check whether `options' is a valid object of type c_options_t.
 *
 *  Return value:
 *	pointer to options struct on success
 *      NULL otherwise
 */
{
   c_options_t *this = (c_options_t *) options->private;
   if (this)
   {
      if (!streq (this->id, "COFIASCO"))
      {
	 set_error (_("Parameter `options' doesn't match required type."));
	 return NULL;
      }
   }
   else
   {
      set_error (_("Parameter `%s' not defined (NULL)."), "options");
   }

   return this;
}

/**************************************************************************
***************************************************************************
			       DECODER
***************************************************************************
**************************************************************************/

fiasco_d_options_t *
fiasco_d_options_new (void)
/*
 *  FIASCO options constructor.
 *  Allocate memory for the FIASCO coder options structure and
 *  fill in default values.
 *
 *  Return value:
 *	pointer to the new option structure
 */
{
   d_options_t 	      *options = calloc (1, sizeof (d_options_t));
   fiasco_d_options_t *public  = calloc (1, sizeof (fiasco_d_options_t));

   if (!options || !public)
   {
      set_error (_("Out of memory."));
      return NULL;
   }
   public->private 	      = options;
   public->delete 	      = fiasco_d_options_delete;
   public->set_smoothing      = fiasco_d_options_set_smoothing;
   public->set_magnification  = fiasco_d_options_set_magnification;
   public->set_4_2_0_format   = fiasco_d_options_set_4_2_0_format;

   strcpy (options->id, "DOFIASCO");

   /*
    *  Set default value of fiasco decoder options
    */
   options->smoothing 	  = 70;
   options->magnification = 0;
   options->image_format  = FORMAT_4_4_4;

   return public;
}

void
fiasco_d_options_delete (fiasco_d_options_t *options)
/*
 *  FIASCO options destructor.
 *  Free memory of FIASCO options struct.
 *
 *  No return value.
 *
 *  Side effects:
 *	structure 'options' is discarded.
 */
{
   d_options_t *this = cast_d_options (options);

   if (!this)
      return;

   Free (this);

   return;
}

int
fiasco_d_options_set_smoothing (fiasco_d_options_t *options, int smoothing)
/*
 *  Define `smoothing'-percentage along partitioning borders.
 *
 *  Return value:
 *	1 on success
 *	0 otherwise
 */
{
   d_options_t *this = (d_options_t *) cast_d_options (options);

   if (!this)
   {
      return 0;
   }
   else if (smoothing < -1 || smoothing > 100)
   {
      set_error (_("Smoothing percentage must be in the range [-1, 100]."));
      return 0;
   }
   else
   {
      this->smoothing = smoothing;
      return 1;
   }
}

int
fiasco_d_options_set_magnification (fiasco_d_options_t *options, int level)
/*
 *  Set magnification-'level' of decoded image.
 *  0: width x height of original image
 *  1: (2 * width) x (2 * height) of original image
 *  -1: (width / 2 ) x (height / 2) of original image
 *  etc.
 *
 *  Return value:
 *	1 on success
 *	0 otherwise
 */
{
   d_options_t *this = (d_options_t *) cast_d_options (options);

   if (!this)
   {
      return 0;
   }
   else
   {
      this->magnification = level;
      return 1;
   }
}

int
fiasco_d_options_set_4_2_0_format (fiasco_d_options_t *options, int format)
/*
 *  Set image format to 4:2:0 or 4:4:4.
 *
 *  Return value:
 *	1 on success
 *	0 otherwise
 */
{
   d_options_t *this = (d_options_t *) cast_d_options (options);

   if (!this)
   {
      return 0;
   }
   else
   {
      this->image_format = format ? FORMAT_4_2_0 : FORMAT_4_4_4;
      return 1;
   }
}

d_options_t *
cast_d_options (fiasco_d_options_t *options)
/*
 *  Cast generic pointer `options' to type d_options_t.
 *  Check whether `options' is a valid object of type d_options_t.
 *
 *  Return value:
 *	pointer to options struct on success
 *      NULL otherwise
 */
{
   d_options_t *this = (d_options_t *) options->private;

   if (this)
   {
      if (!streq (this->id, "DOFIASCO"))
      {
	 set_error (_("Parameter `options' doesn't match required type."));
	 return NULL;
      }
   }
   else
   {
      set_error (_("Parameter `%s' not defined (NULL)."), "options");
   }

   return this;
}


text:
<?php

namespace Dgafka\AuthorizationSecurity\UI\Annotation\Type;

use Doctrine\Common\Annotations\Annotation;

/**
 * Class AuthorizationSecurity
 *
 * @package Dgafka\AuthorizationSecurity\UI\Annotation\Type
 * @author Dariusz Gafka <dgafka.mail@gmail.com>
 * @Annotation
 * @Target({"METHOD"})
 */
class AuthorizationSecurity
{

    /** @var  string */
    private $securityTypeName;

    /** @var  string */
    private $userFactoryName;

    public function __construct(array $values)
    {

        if(!isset($values['type'])) {
            throw new \RuntimeException("Pass 'type' of security to AuthorizationSecurity annotation. Example usage: @AuthorizationSecurity(type=\"standard\", userFactory=\"roleUserFactory\") ");
        }

        if(!isset($values['userFactory'])) {
            throw new \RuntimeException("Pass 'userFactory' to AuthrizationSecurity annotation. Example usage: @AuthorizationSecurity(type=\"standard\", userFactory=\"roleUserFactory\") ");
        }

        $this->securityTypeName = trim($values['type']);
        $this->userFactoryName  = trim($values['userFactory']);
    }

    /**
     * @return string
     */
    public function securityTypeName()
    {
        return $this->securityTypeName;
    }

    /**
     * @return string
     */
    public function userFactoryName()
    {
        return $this->userFactoryName;
    }

}


text:
package org.apache.sqoop.mapreduce.netezza;

import java.io.IOException;

import org.apache.commons.lang.StringEscapeUtils;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.io.LongWritable;
import org.apache.hadoop.io.NullWritable;
import org.apache.hadoop.mapreduce.Job;
import org.apache.hadoop.mapreduce.Mapper;
import org.apache.hadoop.mapreduce.OutputFormat;
import org.apache.sqoop.config.ConfigurationHelper;
import org.apache.sqoop.lib.DelimiterSet;
import org.apache.sqoop.manager.DirectNetezzaManager;
import org.apache.sqoop.mapreduce.DBWritable;
import org.apache.sqoop.mapreduce.ImportJobBase;
import org.apache.sqoop.mapreduce.RawKeyTextOutputFormat;
import
  org.apache.sqoop.mapreduce.db.netezza.NetezzaExternalTableHCatImportMapper;
import
  org.apache.sqoop.mapreduce.db.netezza.NetezzaExternalTableTextImportMapper;
import org.apache.sqoop.mapreduce.hcat.SqoopHCatUtilities;

import com.cloudera.sqoop.SqoopOptions;
import com.cloudera.sqoop.manager.ConnManager;
import com.cloudera.sqoop.manager.ImportJobContext;
import com.cloudera.sqoop.mapreduce.db.DBConfiguration;
import com.cloudera.sqoop.mapreduce.db.DataDrivenDBInputFormat;

/**
 * Class that runs an import job using netezza external tables in the mapper.
 */
public class NetezzaExternalTableImportJob extends ImportJobBase {

  public NetezzaExternalTableImportJob(final SqoopOptions opts,
      ImportJobContext context) {
    super(opts, NetezzaExternalTableTextImportMapper.class,
        NetezzaExternalTableInputFormat.class, RawKeyTextOutputFormat.class,
        context);
  }

  @Override
  protected void propagateOptionsToJob(Job job) {
    Configuration conf = job.getConfiguration();
    String nullValue = options.getNullStringValue();
    if (nullValue != null) {
      conf.set(DirectNetezzaManager.NETEZZA_NULL_VALUE,
          StringEscapeUtils.unescapeJava(nullValue));
    }
    conf.setInt(DelimiterSet.OUTPUT_FIELD_DELIM_KEY,
        options.getOutputFieldDelim());
    conf.setInt(DelimiterSet.OUTPUT_RECORD_DELIM_KEY,
        options.getOutputRecordDelim());
    conf.setInt(DelimiterSet.OUTPUT_ENCLOSED_BY_KEY,
        options.getOutputEnclosedBy());
    // Netezza uses \ as the escape character. Force the use of it
    int escapeChar = options.getOutputEscapedBy();
    if (escapeChar > 0) {
      if (escapeChar != '\\') {
        LOG.info(
            "Setting escaped char to \\ for Netezza external table import");
      }
      conf.setInt(DelimiterSet.OUTPUT_ESCAPED_BY_KEY, '\\');
    }
    conf.setBoolean(DelimiterSet.OUTPUT_ENCLOSE_REQUIRED_KEY,
        options.isOutputEncloseRequired());

  }
  /**
   * Configure the inputformat to use for the job.
   */
  @Override
  protected void configureInputFormat(Job job, String tableName,
      String tableClassName, String splitByCol) throws ClassNotFoundException,
      IOException {

    ConnManager mgr = getContext().getConnManager();
    String username = options.getUsername();
    if (null == username || username.length() == 0) {
      DBConfiguration.configureDB(job.getConfiguration(), mgr.getDriverClass(),
          options.getConnectString());
    } else {
      DBConfiguration.configureDB(job.getConfiguration(), mgr.getDriverClass(),
          options.getConnectString(), username, options.getPassword());
    }

    String[] colNames = options.getColumns();
    if (null == colNames) {
      colNames = mgr.getColumnNames(tableName);
    }

    String[] sqlColNames = null;
    if (null != colNames) {
      sqlColNames = new String[colNames.length];
      for (int i = 0; i < colNames.length; i++) {
        sqlColNames[i] = mgr.escapeColName(colNames[i]);
      }
    }

    // It's ok if the where clause is null in DBInputFormat.setInput.
    String whereClause = options.getWhereClause();

    // We can't set the class properly in here, because we may not have the
    // jar loaded in this JVM. So we start by calling setInput() with
    // DBWritable and then overriding the string manually.

    // Note that mysqldump also does *not* want a quoted table name.
    DataDrivenDBInputFormat.setInput(job, DBWritable.class, tableName,
        whereClause, mgr.escapeColName(splitByCol), sqlColNames);

    LOG.debug("Using InputFormat: " + inputFormatClass);
    job.setInputFormatClass(getInputFormatClass());

    if (isHCatJob) {
      LOG.debug("Using table class: " + tableClassName);
      job.getConfiguration().set(ConfigurationHelper.getDbInputClassProperty(),
        tableClassName);
    }
  }

  /**
   * Set the mapper class implementation to use in the job, as well as any
   * related configuration (e.g., map output types).
   */
  protected void configureMapper(Job job, String tableName,
      String tableClassName) throws ClassNotFoundException, IOException {
    super.configureMapper(job, tableName, tableClassName);
    job.setMapperClass(getMapperClass());
    if (isHCatJob) {
      LOG.info("Configuring mapper for HCatalog import job");
      job.setOutputKeyClass(LongWritable.class);
      job.setOutputValueClass(SqoopHCatUtilities.getImportValueClass());
      return;
    }
    job.setOutputKeyClass(String.class);
    job.setOutputValueClass(NullWritable.class);
  }

  @Override
  protected Class<? extends OutputFormat> getOutputFormatClass()
      throws ClassNotFoundException {
    if (isHCatJob) {
      return SqoopHCatUtilities.getOutputFormatClass();
    } else {
      return RawKeyTextOutputFormat.class;
    }
  }

  @Override
  protected Class<? extends Mapper> getMapperClass() {
    if (isHCatJob) {
      return NetezzaExternalTableHCatImportMapper.class;
    } else {
      return NetezzaExternalTableTextImportMapper.class;
    }
  }
}


text:
/* Created On: Sep 7, 2005 */
package edu.unl.act.rma.firm.core;

import java.io.Serializable;

/**
 * @author Ian Cottingham
 *
 */
public class InvalidStateException extends Exception implements Serializable {

	private static final long serialVersionUID = 1L;

	public InvalidStateException(String str) { super(str); }
}


text:
namespace Server.Interface
{
    using System.ServiceModel;

    [ServiceContract(
        Namespace = "http://Server.Interface.INotification",
        SessionMode = SessionMode.Required,
        CallbackContract = typeof(INotificationDuplexCallback))]
    public interface INotificationService
    {
        [OperationContract(IsOneWay = true)]
        void Submit(int recordId);
    }
}


text:
<?php

namespace Eureka\Package\Money\DataMapper\Mapper\Money;

/**
 * DataMapper Mapper class for table "bank"
 *
 * @author  Romain Cottard
 * @version 1.0.0
 */
class BankMapper extends Abstracts\BankMapperAbstract
{
}


text:
title: "Summary"
version: 1.0
weight: 7
next:
  url: "getting-started"
  text: "Getting Started Guide"
---

# Installation Guide Summary

Congratulations - you have successfully installed and configured the Sensu
services, one or more Sensu clients, and a Sensu dashboard! With this basic
implementation in place, you have the core Sensu framework available for
development, testing and evaluation purposes. What's next?

## Next steps

The installation guide provided manual, step-by-step instructions to help the
user (that's you) learn how Sensu is installed and configured. It would not be
practical to manually install Sensu on every machine you wish to monitor. It was
for this reason that Sensu was designed to be deployed by a configuration
management tool, such as [Puppet][1] or [Chef][2]; see the official [Puppet
module][3] and [Chef cookbook][4] for more information about how to automate
your Sensu deployment.

Depending on your business requirements you may be interested in [learning more
about how Sensu Works][5], or in preparing Sensu for production.

### Build a Comprehensive Telemetry Solution

Conceptually, building out a monitoring solution using Sensu requires one or
more [Sensu servers][6], and automating the installation of Sensu
clients on all of your machines. With this core framework in place, you'll also
need to define [monitoring checks][7] for all of the services in your
application stack (e.g. proxy services, web services, database services, etc).
Additionally, it may be prudent to collect and analyze metrics for the same
services, by creating [metric collection][8] and [metric analysis][9] checks.
Finally, no comprehensive telemetry solution would be complete without
configuring notification routing groups (i.e. who gets notified for what?) and
defining alerting and escalation policies via [Sensu Handlers][10].

### Deploying Sensu into Production Environments

Coming soon. If you have questions about deploying Sensu into production
environments, please contact [Sensu Support][11].

### Hardening Sensu

Coming soon. If you have questions about hardening Sensu, please contact [Sensu
Support][11].

### Scaling Sensu

Coming soon. If you have questions about scaling Sensu, please contact [Sensu
Support][11].

[1]:  http://puppet.com
[2]:  http://www.chef.io
[3]:  https://github.com/sensu/sensu-puppet
[4]:  https://github.com/sensu/sensu-chef
[5]:  ../guides/getting-started/overview.html
[6]:  #scaling-sensu
[7]:  ../guides/getting-started/intro-to-checks.html
[8]:  ../guides/getting-started/intro-to-checks.html#create-a-metric-collection-check
[9]:  ../guides/getting-started/intro-to-checks.html#create-a-metric-analysis-check
[10]: ../guides/getting-started/intro-to-handlers.html
[11]: https://helpdesk.sensuapp.com


text:
<bill session="110" type="h" number="895" updated="2009-01-08T18:41:07-05:00">
	<status><introduced date="1170824400" datetime="2007-02-07"/></status>

	<introduced date="1170824400" datetime="2007-02-07"/>
	<titles>
		<title type="official" as="introduced">To take certain steps toward recognition by the United States of Jerusalem as the capital of Israel.</title>
	</titles>
	<sponsor id="400338"/>
	<cosponsors>
		<cosponsor id="400222" joined="2007-02-07"/>
		<cosponsor id="400367" joined="2007-02-07"/>
		<cosponsor id="400060" joined="2007-02-07"/>
		<cosponsor id="400257" joined="2007-07-10"/>
		<cosponsor id="400242" joined="2007-02-15"/>
		<cosponsor id="400385" joined="2007-02-07"/>
		<cosponsor id="400342" joined="2008-04-22"/>
		<cosponsor id="400268" joined="2007-02-07"/>
		<cosponsor id="400370" joined="2007-02-07"/>
		<cosponsor id="412250" joined="2007-02-07"/>
		<cosponsor id="400055" joined="2007-02-07"/>
		<cosponsor id="400225" joined="2008-05-01"/>
		<cosponsor id="400417" joined="2007-02-15"/>
		<cosponsor id="400147" joined="2007-07-17"/>
		<cosponsor id="400296" joined="2007-02-07"/>
		<cosponsor id="400220" joined="2007-02-07"/>
		<cosponsor id="412216" joined="2007-06-25"/>
		<cosponsor id="400400" joined="2007-02-07"/>
		<cosponsor id="400139" joined="2007-02-15"/>
		<cosponsor id="400047" joined="2007-03-07"/>
		<cosponsor id="400024" joined="2007-02-07"/>
		<cosponsor id="412191" joined="2007-02-07"/>
	</cosponsors>
	<actions>
		<action date="1170824400" datetime="2007-02-07"><text>Referred to the House Committee on Foreign Affairs.</text></action>
	</actions>
	<committees>

	</committees>
	<relatedbills>

	</relatedbills>
	<subjects>

	</subjects>
	<amendments>

	</amendments>

	2/7/2007--Introduced.
Prohibits the United States from operating a U.S. consulate or diplomatic facility in Jerusalem unless it is under the supervision of the U.S. Ambassador to Israel. Requires any official U.S. government document which lists countries and their capital cities to identify Jerusalem as Israel's capital. Declares that, for purposes of registration of birth, certification of nationality, or issuance of a passport of a U.S. citizen born in Jerusalem, the Secretary of State shall, upon the citizen's (or the citizen's legal guardian's) request, record the place of birth as Israel.

</bill>


text:
; (tentative of) multi-subsystem PE
; would display Hello World no matter what the subsystem.

; not working, need work on imports loading

%include '..\..\standard_hdr.asm'

SUBSYSTEM equ IMAGE_SUBSYSTEM_WINDOWS_CUI
;CARACTERISTICS EQU IMAGE_FILE_EXECUTABLE_IMAGE | IMAGE_FILE_32BIT_MACHINE

STD_OUTPUT_HANDLE equ -11

EntryPoint:
    pushad
    push cs
    pop eax
    cmp ax, 01bh            ; XP user mode ?
    jz not_driver
    cmp ax, 023h            ; Win7 user mode
    jz not_driver

    jmp driver

nop
not_driver:
    popad
    mov eax, [OPTIONAL_HEADER.Subsystem]
    cmp eax, 3
    jz console
    cmp eax, 2
    jz gui
    jmp end_

nop
console:
    push STD_OUTPUT_HANDLE  ; DWORD nStdHandle
    call GetStdHandle
    mov [hConsoleOutput], eax

    push 0                          ; LPVOID lpReserved
    push lpNumbersOfCharsWritten    ; LPWORD lpNumbersOfCharsWritten
    push HELLOWORLD_LEN             ; DWORD nNumbersOfCharsToWrite
    push helloworld                 ; VOID *lpBuffer
    push dword [hConsoleOutput]     ; HANDLE hConsoleOutput
    call WriteConsoleA
jmp end_

align 16, int3

nop
driver:
;%reloc 1
    push helloworld     ; PCHAR  Format
;    call DbgPrint
    add esp, 4

    popad
    mov eax, STATUS_DEVICE_CONFIGURATION_ERROR
    retn 8

align 16, int3

;%reloc 2
;IMPORT ntoskrnl.exe!DbgPrint

align 16, int3

;%reloc 2
;%IMPORT kernel32.dll!GetStdHandle
;%reloc 2
;%IMPORT kernel32.dll!WriteConsoleA

align 16, int3

gui:
    push MB_ICONINFORMATION ; UINT uType
    push tada               ; LPCTSTR lpCaption
    push helloworld         ; LPCTSTR lpText
    push 0                  ; HWND hWnd
    call MessageBoxA
jmp end_
align 16, int3

;%reloc 2
;%IMPORT user32.dll!MessageBoxA

align 16, int3

end_:
    push 0                  ; UINT uExitCode
    call ExitProcess
    retn

align 16, int3

;%reloc 2
;%IMPORT kernel32.dll!ExitProcess

align 16, int3

lpNumbersOfCharsWritten dd 0
hConsoleOutput dd 0

align 16, db 0

tada db "Tada!", 0
helloworld db "Hello World!"
    HELLOWORLD_LEN equ $ - helloworld
db 0

align 16, db 0

;%IMPORTS
align 16, db 0
;%relocs

%include '..\..\standard_ftr.asm'

; Ange Albertini, BSD Licence 2011


text:
        {{'msg.space.set.member' | translate}}

        {{'msg.comm.btn.cancl' | translate}}
        {{'msg.comm.btn.done' | translate}}

              {{'msg.space.ui.shared.member' | translate}} {{totalUsers}}

              {{'msg.space.ui.shared.group' | translate}} {{totalGroups}}

                <input #inputSearch type="text"
                       placeholder="{{ isShowUserTab ? ( 'msg.comm.search.usr' | translate ) : 'msg.comm.search.grp' | translate}}"
                       [ngModel]="searchText"
                       (keypress)="searchDataPressKey($event)"
                       (keyup.esc)="resetSearchText(false)"
                       (clickOutside)="resetSearchText(false)">

                    <input type="checkbox" [checked]="isCheckAllUser" (click)="clickCheckAll()" >

                    {{ 'msg.comm.btn.data.all' | translate }}

                    <input type="checkbox"  [checked]="checkIsSharedTarget(user)" (click)="setSharedTarget(user)">

                    {{user.fullName}} ({{user.id}})

                    <input type="checkbox" [checked]="isCheckAllGroup" (click)="clickCheckAll()" >

                    {{ 'msg.comm.btn.data.all' | translate }}

                    <input type="checkbox" [checked]="checkIsSharedTarget(group)" (click)="setSharedTarget(group)">

                    {{getPredefinedName(group.name)}}

              {{'msg.comm.ui.more' | translate}}

              {{'msg.comm.ui.more' | translate}}

              {{workspaceUsers.length}} {{ 'msg.storage.ui.sel.count' | translate }}

                  {{ 'msg.spaces.permission.schema.userroles' | translate }}

Dashboard data information

                  <app-permission-schema [roleSet]="roleSet" [editMode]="false"></app-permission-schema>

                    <colgroup>
                      <col width="*">
                      <col width="30%">
                      <col width="35%">
                      <col width="30px">
                    </colgroup>

                       {{'msg.comm.th.usr.name' | translate}}
                       {{'msg.comm.th.full.name' | translate}}
                       {{'msg.comm.th.role' | translate}}

                    <colgroup>
                      <col width="*">
                      <col width="30%">
                      <col width="35%">
                      <col width="30px">
                    </colgroup>

                           {{userItem.member.username}}

                       {{userItem.member.fullName}}

                            {{userItem.role}}

                                {{roleItem.name}}

                {{'msg.comm.ui.more' | translate}}

              {{workspaceGroups.length}} {{ 'msg.storage.ui.sel.count' | translate }}

                  {{ 'msg.spaces.permission.schema.userroles' | translate }}

Dashboard data information

                  <app-permission-schema [roleSet]="roleSet" [editMode]="false"></app-permission-schema>

                    <colgroup>
                      <col width="*">
                      <col width="45%">
                      <col width="30px">
                    </colgroup>

                        {{'msg.comm.th.grp.name' | translate}}
                        {{'msg.comm.th.role' | translate}}

                    <colgroup>
                      <col width="*">
                      <col width="45%">
                      <col width="30px">
                    </colgroup>

                           {{getPredefinedName(groupItem.member.name)}}

                              {{groupItem.role}}

                                  {{roleItem.name}}

                {{'msg.comm.ui.more' | translate}}


text:
define([
], function () {

    // @ngInject
    function demoCtrl ($rootScope, $state, $injector) {
        this.primary = function () {
            alert('Primary Action!');
        };

        this.cancel = function () {
            alert('Cancel Action!');
        };
    }

    return demoCtrl;
});


text:
		<select ng-model="scanTrendType" ng-options="m as m for m in scan.scanTrendTypes"
			class="form-control" required="true">
		</select>

		<select ng-model="scanTrendType" ng-options="m as m for m in scan.scanTrendTypes"
			class="form-control" required="true">
		</select>

		<select ng-model="scanTrendType" ng-options="m as m for m in scan.scanTrendTypes"
			class="form-control" required="true">
		</select>

		<button class="btn-default">Create Charts</button>


text:
from PyQt4 import QtCore, QtGui

try:
    _fromUtf8 = QtCore.QString.fromUtf8
except AttributeError:
    def _fromUtf8(s):
        return s

try:
    _encoding = QtGui.QApplication.UnicodeUTF8
    def _translate(context, text, disambig):
        return QtGui.QApplication.translate(context, text, disambig, _encoding)
except AttributeError:
    def _translate(context, text, disambig):
        return QtGui.QApplication.translate(context, text, disambig)

class Ui_Form(object):
    def setupUi(self, Form):
        Form.setObjectName(_fromUtf8("Form"))
        Form.resize(840, 514)
        self.gridLayout = QtGui.QGridLayout(Form)
        self.gridLayout.setObjectName(_fromUtf8("gridLayout"))
        self.graphicsView_3d = GLViewWidget(Form)
        self.graphicsView_3d.setObjectName(_fromUtf8("graphicsView_3d"))
        self.gridLayout.addWidget(self.graphicsView_3d, 0, 0, 2, 1)
        self.addPlotButton = QtGui.QPushButton(Form)
        self.addPlotButton.setMaximumSize(QtCore.QSize(200, 56))
        font = QtGui.QFont()
        font.setPointSize(30)
        self.addPlotButton.setFont(font)
        self.addPlotButton.setStyleSheet(_fromUtf8(""))
        self.addPlotButton.setObjectName(_fromUtf8("addPlotButton"))
        self.gridLayout.addWidget(self.addPlotButton, 0, 1, 1, 1)
        self.listWidget = QtGui.QListWidget(Form)
        self.listWidget.setMaximumSize(QtCore.QSize(200, 16777215))
        self.listWidget.setLineWidth(10)
        self.listWidget.setObjectName(_fromUtf8("listWidget"))
        self.gridLayout.addWidget(self.listWidget, 1, 1, 1, 1)

        self.retranslateUi(Form)
        QtCore.QMetaObject.connectSlotsByName(Form)

    def retranslateUi(self, Form):
        Form.setWindowTitle(_translate("Form", "Form", None))
        self.addPlotButton.setText(_translate("Form", "+", None))

from pyqtgraph.opengl import GLViewWidget


text:
<!DOCTYPE html>

  <meta charset="utf-8" name="viewport"
        content="width=device-width, initial-scale=1, maximum-scale=1, minimum-scale=1">

  <link rel="stylesheet" href="http://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css">

  <title>Forms Text Demo</title>


text:
using NUnit.Framework;
using Stylet;
using System;

namespace StyletUnitTests
{
    [TestFixture]
    public class PropertyChangedExtensionsTests
    {
        class NotifyingClass : PropertyChangedBase
        {
            private string _foo;
            public string Foo
            {
                get { return this._foo; }
                set { SetAndNotify(ref this._foo, value); }
            }

            private string _bar;
            public string Bar
            {
                get { return this._bar; }
                set { SetAndNotify(ref this._bar, value);  }
            }

            public void NotifyAll()
            {
                this.NotifyOfPropertyChange(String.Empty);
            }
        }

        class BindingClass
        {
            public string LastFoo;

            public IEventBinding BindStrong(NotifyingClass notifying)
            {
                // Must make sure the compiler doesn't generate an inner class for this, otherwise we're not testing the right thing
                return notifying.Bind(x => x.Foo, (o, e) => this.LastFoo = e.NewValue);
            }
        }

        [Test]
        public void StrongBindingBinds()
        {
            string newVal = null;
            var c1 = new NotifyingClass();
            c1.Bind(x => x.Foo, (o, e) => newVal = e.NewValue);
            c1.Foo = "bar";

            Assert.AreEqual("bar", newVal);
        }

        [Test]
        public void StrongBindingIgnoresOtherProperties()
        {
            string newVal = null;
            var c1 = new NotifyingClass();
            c1.Bind(x => x.Bar, (o, e) => newVal = e.NewValue);
            c1.Foo = "bar";

            Assert.AreEqual(null, newVal);
        }

        [Test]
        public void StrongBindingListensToEmptyString()
        {
            string newVal = null;
            var c1 = new NotifyingClass
            {
                Bar = "bar"
            };
            c1.Bind(x => x.Bar, (o, e) => newVal = e.NewValue);
            c1.NotifyAll();

            Assert.AreEqual("bar", newVal);
        }

        [Test]
        public void StrongBindingDoesNotRetainNotifier()
        {
            WeakReference Test(out IEventBinding binder)
            {
                var binding = new BindingClass();
                var notifying = new NotifyingClass();
                // Retain the IPropertyChangedBinding, in case that causes NotifyingClass to be retained
                binder = binding.BindStrong(notifying);
                return new WeakReference(notifying);
            }

            var weakNotifying = Test(out var retained);

            GC.Collect();

            Assert.IsFalse(weakNotifying.IsAlive);
            GC.KeepAlive(retained);
        }

        [Test]
        public void StrongBindingPassesTarget()
        {
            var c1 = new NotifyingClass();
            object sender = null;
            c1.Bind(x => x.Foo, (o, e) => sender = o);
            c1.Foo = "foo";
            Assert.AreEqual(c1, sender);
        }

        [Test]
        public void StrongBindingUnbinds()
        {
            string newVal = null;
            var c1 = new NotifyingClass();
            var binding = c1.Bind(x => x.Bar, (o, e) => newVal = e.NewValue);
            binding.Unbind();
            c1.Bar = "bar";

            Assert.AreEqual(null, newVal);
        }

        [Test]
        public void BindAndInvokeInvokes()
        {
            var c1 = new NotifyingClass()
            {
                Foo = "FooVal",
            };
            PropertyChangedExtendedEventArgs<string> ea = null;
            c1.BindAndInvoke(s => s.Foo, (o, e) => ea = e);

            Assert.NotNull(ea);
            Assert.AreEqual("Foo", ea.PropertyName);
            Assert.AreEqual("FooVal", ea.NewValue);
        }
    }
}


text:
title: "Container Runtime Meetup #1でNOTIFY\_SOCKETについて話してきました"
date: 2019-09-25 02:37 JST
tags:
- programming
- runc
- docker
- golang
- diary

---

![git grep NOTIFY_SOCKET](2019/container-runtime-meetup-1-git-grep.png)

[Container Runtime Meetup #1 - connpass](https://runtime.connpass.com/event/145088/) に参加して `NOTIFY_SOCKET` について調べたことを話してきました。

この記事ではその内容の書き起こしと、その場で行われた会話についてのメモについて書きます。

## 参加するきっかけ
@udzuraさんにそそのかされたことがきっかけです。

@yu_suke1994 情報です https://t.co/U5zsvUlz30
— Uchio KONDO 🔫 (@udzura) August 27, 2019

あまりよくないExecuteをすると、普段はRails APIを運用していてRubyしか書いておらず、Goも数年前にCLI toolを作った程度で、GoやLinuxのコンテナ回りに詳しいという訳ではありません。

## 読む対象について
connpassのイベント概要に

> 少人数の輪読形式です。「参加枠1」の方々にはあらかじめ「runc run」周辺のコードをざっと読んできてもらい、当日、それに関連するトピックをそれぞれ発表して頂きます。「聴講のみ」の方々は、発表の必要はありません。

とあったので、その時点での最新リリースである v1.0.0-rc8 を対象に読むことにしました。

<https://github.com/opencontainers/runc/releases/tag/v1.0.0-rc8>

`runc run` が実行されたとき、呼び出される実体は run.go だろうとアタリをつけ、周辺を読んでいきます。

```go
		status, err := startContainer(context, spec, CT_ACT_RUN, nil)
		if err == nil {
			// exit with the container's exit status so any external supervisor is
			// notified of the exit with the correct exit status.
			os.Exit(status)
		}
```

<https://github.com/opencontainers/runc/blob/v1.0.0-rc8/run.go#L76>

まずここで `startContainer` によりContainerがstartするものと思われます。中を見ていきます。

```go
func startContainer(context *cli.Context, spec *specs.Spec, action CtAct, criuOpts *libcontainer.CriuOpts) (int, error) {
	id := context.Args().First()
	if id == "" {
		return -1, errEmptyID
	}

	notifySocket := newNotifySocket(context, os.Getenv("NOTIFY_SOCKET"), id)
	if notifySocket != nil {
		notifySocket.setupSpec(context, spec)
	}
```
<https://github.com/opencontainers/runc/blob/v1.0.0-rc8/utils_linux.go#L405-L414>

`startContainer` 内部、 411行目にて `os.Getenv("NOTIFY_SOCKET")` としている部分があります。この環境変数は何でしょう?気になったので、ここを掘っていきました。

この時点で僕の `NOTIFY_SOCKET` に対する認識は、

> 「環境変数がある状態で起動させると色々な通知が飛んでくるのだろうか?」

くらいのものでした。

## Dive into code
では、 `newNotifySocket` で何が行われているかを見ていきます。

```go
func newNotifySocket(context *cli.Context, notifySocketHost string, id string) *notifySocket {
	if notifySocketHost == "" {
		return nil
	}

	root := filepath.Join(context.GlobalString("root"), id)
	path := filepath.Join(root, "notify.sock")

	notifySocket := &notifySocket{
		socket:     nil,
		host:       notifySocketHost,
		socketPath: path,
	}

	return notifySocket
}
```

<https://github.com/opencontainers/runc/blob/v1.0.0-rc8/notify_socket.go#L23-L38>

この関数の返り値として、 `notifySocket` 構造体のインスタンス(のポインタ?)が得られます。

ちなみに `notifySocket` 構造体はこのように定義されています。

```go
type notifySocket struct {
	socket     *net.UnixConn
	host       string
	socketPath string
}
```
<https://github.com/opencontainers/runc/blob/v1.0.0-rc8/notify_socket.go#L17-L21>

ところで `newNotifySocket` 関数の引数として渡される `context *cli.Context` は何でしょうか。

これはruncが採用しているCLIツール用パッケージ <https://github.com/urfave/cli> で定義されている Context 構造体を指しています

<https://godoc.org/github.com/urfave/cli#Context>

`startContainer` では、 `newNotifySocket` を呼んだ直後に、返ってきた `notifySocket` に対して `setupSpec` を呼んでいます。これも見ていきます。

```go
// If systemd is supporting sd_notify protocol, this function will add support
// for sd_notify protocol from within the container.
func (s *notifySocket) setupSpec(context *cli.Context, spec *specs.Spec) {
	mount := specs.Mount{Destination: s.host, Source: s.socketPath, Options: []string{"bind"}}
	spec.Mounts = append(spec.Mounts, mount)
	spec.Process.Env = append(spec.Process.Env, fmt.Sprintf("NOTIFY_SOCKET=%s", s.host))
}
```
<https://github.com/opencontainers/runc/blob/v1.0.0-rc8/notify_socket.go#L44-L50>

この関数のコメントにもあるように、systemdが何か関係していそうだということがわかりました。

ここでの処理は runtime-spec を読むとわかりそうです。とりあえず、`Process.Env` に対して `NOTIFY_SOCKET` 環境変数を追加しているようです。

`startContainer` に戻ると、 `createContainer` を呼んだあとに `notifySocket.setupSocket()` を呼んでいます。これを見ていきます。

```go
func (s *notifySocket) setupSocket() error {
	addr := net.UnixAddr{
		Name: s.socketPath,
		Net:  "unixgram",
	}

	socket, err := net.ListenUnixgram("unixgram", &addr)
	if err != nil {
		return err
	}

	s.socket = socket
	return nil
}
```
<https://github.com/opencontainers/runc/blob/v1.0.0-rc8/notify_socket.go#L52-L65>

`net.UnixAddr` とは何でしょうか。これの実体は <https://golang.org/pkg/net/#UnixAddr> にあります。

```go
type UnixAddr struct {
    Name string
    Net  string
}
```

ここでの `unixgram` は datagram socketを指すようで、UDPのような送りっぱなしのプロトコルのようです。
( <https://github.com/golang/go/blob/master/src/net/unixsock_posix.go#L16-L27> の `syscall.SOCK_DGRAM` を参照 )

`net.ListenUnixgram` によってconnectionを張り、それを `notifySocket.socket` に格納したものを、 `runner` 構造体の `notifySocket` フィールドに入れています。

```go
type runner struct {
	init            bool
	enableSubreaper bool
	shouldDestroy   bool
	detach          bool
	listenFDs       []*os.File
	preserveFDs     int
	pidFile         string
	consoleSocket   string
	container       libcontainer.Container
	action          CtAct
	notifySocket    *notifySocket
	criuOpts        *libcontainer.CriuOpts
}
```
<https://github.com/opencontainers/runc/blob/v1.0.0-rc8/utils_linux.go#L254-L267>

この後に、 `notifySocket` に対して行われている操作は、`runner.run` 内部で以下のコードを呼んでいる部分があります。

```go
// Setting up IO is a two stage process. We need to modify process to deal
// with detaching containers, and then we get a tty after the container has
// started.
handler := newSignalHandler(r.enableSubreaper, r.notifySocket)
```
<https://github.com/opencontainers/runc/blob/v1.0.0-rc8/utils_linux.go#L305-L308>

### 一旦まとめ
一旦ここまでをまとめると、

- `NOTIFY_SOCKET` という環境変数をもとにsoket通信をしている?
- これは `unixgram` によって通信するもの
- systemd が何か関係しているようだ

といったところでしょうか。

## NOTIFY_SOCKET を調べる
何やらsystemdが関係していそうなことはわかっているので、単純に `NOTIFY_SOCKET` でググってみると、いくつか記事が見付かりました。

- <https://www.freedesktop.org/software/systemd/man/sd_notify.html#Notes>
- [sd_notifyの通信方法 - Qiita](https://qiita.com/ozaki-r/items/ced43d5e32af67c7ae04)
- [systemd(1) — Arch Linux マニュアルページ](https://man.kusakata.com/man/systemd.1.html)

freedesktop.orgでは

> These functions send a single datagram with the state string as payload to the AF_UNIX socket referenced in the \$NOTIFY_SOCKET environment variable. If the first character of \$NOTIFY_SOCKET is "@", the string is understood as Linux abstract namespace socket.

<https://www.freedesktop.org/software/systemd/man/sd_notify.html#Notes>

「sd_notifyの通信方法 - Qiita」では

> systemdのマネージャ(デーモンプロセス)は、起動プロセスの最後の方でsd_notifyという関数を用いて、起動が完了したことをsystemd本体(PID=1)に通知する。(注:sd_notifyは実際にはもっと汎用的なステータス通知に使える。)

<https://qiita.com/ozaki-r/items/ced43d5e32af67c7ae04>

ざっくりとした理解でいくと、プロセスが起動した、などのステータスの通知に使用されているんだろうということがわかりました。

## Dockerの場合
ここで、「ではDockerの場合はどうなのだろう」と思い、 <https://github.com/docker/cli> 内をgrepしましたが、見当りません。いや、Dockerはmobyに移行したのでした。 案の定、 <https://github.com/moby/moby> 内をgrepすると見付かりました。

```shell
$ git grep NOTIFY_SOCKET
libcontainerd/supervisor/remote_daemon.go:200:  // clear the NOTIFY_SOCKET from the env when starting containerd
libcontainerd/supervisor/remote_daemon.go:203:          if !strings.HasPrefix(e, "NOTIFY_SOCKET") {
vendor/github.com/coreos/go-systemd/daemon/sdnotify.go:49:// If `unsetEnvironment` is true, the environment variable `NOTIFY_SOCKET`
vendor/github.com/coreos/go-systemd/daemon/sdnotify.go:53:// (false, nil) - notification not supported (i.e. NOTIFY_SOCKET is unset)
vendor/github.com/coreos/go-systemd/daemon/sdnotify.go:54:// (false, err) - notification supported, but failure happened (e.g. error connecting to NOTIFY_SOCKET or while sending data)
vendor/github.com/coreos/go-systemd/daemon/sdnotify.go:58:              Name: os.Getenv("NOTIFY_SOCKET"),
vendor/github.com/coreos/go-systemd/daemon/sdnotify.go:62:      // NOTIFY_SOCKET not set
vendor/github.com/coreos/go-systemd/daemon/sdnotify.go:68:              if err := os.Unsetenv("NOTIFY_SOCKET"); err != nil {
vendor/github.com/coreos/go-systemd/daemon/sdnotify.go:74:      // Error connecting to NOTIFY_SOCKET
```
<https://github.com/moby/moby/search?q=NOTIFY_SOCKET&unscoped_q=NOTIFY_SOCKET>

ということは、Dockerを使っているだけでそのようなsocketが作成されているのではないでしょうか。調べてみましょう。

Docker daemonが動作しているマシン上で、systemdが関係していそうなunixドメインソケットの数を出してみました。

```shell
$ ss --family=unix | grep systemd | wc -l
110
```

けっこうな数ありますね。grepする単語を変えてみます。

```shell
$ ss --family=unix | grep container
u_str    ESTAB   0  0     /var/snap/microk8s/common/run/containerd.sock 21833469  * 21836828
u_str    ESTAB   0  0     /var/snap/microk8s/common/run/containerd.sock 21836830  * 21836829
u_str    ESTAB   0  0        /var/run/docker/containerd/containerd.sock 23108     * 23106
u_str    ESTAB   0  0        /var/run/docker/containerd/containerd.sock 23114     * 23113
u_str    ESTAB   0  0        /var/run/docker/containerd/containerd.sock 23110     * 25748
```

それらしきものが存在しています。

もっと見ていきましょう。dockerdのpidを調べます。

```shell
$ ps aux --forest # 抜粋
root  601  /usr/bin/dockerd -H fd://
root  769   \_ containerd --config /var/run/docker/containerd/containerd.toml --log-level info
root 1213       \_ containerd-shim -namespace moby -workdir /var/lib/docker/containerd/daemon/io.containerd.runtime.v1.linux/moby/61f9489e17355a4f00594feb5c
root 1230           \_ bash
```

pid `601` の環境変数を見てみます。

```shell
$ sudo cat /proc/601/environ # 改行を入れています
LANG=ja_JP.UTF-8
PATH=/usr/local/sbin:/usr/local/bin:/usr/bin:/var/lib/snapd/snap/bin
NOTIFY_SOCKET=/run/systemd/notify
LISTEN_PID=601
LISTEN_FDS=1
LISTEN_FDNAMES=docker.socket
INVOCATION_ID=e65738cc4b8f461e968d23c6740a557e
JOURNAL_STREAM=9:22835
```

確かに `NOTIFY_SOCKET` がありますね。

## ここまでのまとめと今後の目標
- `NOTIFY_SOCKET` でsystemdとやりとりしているようだ
- `dockerd` には `NOTIFY_SOCKET` が与えられていることが確認できた
- `runc run` を実行したときにもこれは与えられるのか?
- 実際にどのようなデータがどのようなタイミングで送られるのか?
  - dockerでは? runcでは?他では?

ここまでがMeetupでの発表内容になります。

## 当日の議論
ここからは、当日の発表のあと、その場で行われた議論の簡単な書き起しになります。

- `NOTIFY_SOCKET` が与えられるのは、systemd経由で起動した場合だけで、bashなどから直接 `$ runc run` など実行してもこの環境変数が自動的に作成されるということはない。
    - そもそもこの環境変数はDockerやruncに特有なものではなくどのようなプロセスにおいても汎用的に使用できるもの。
- systemd に対して自身の状態がどうなったのか、を通知するために使われる
- もし `NOTIFY_SOCKET` を活用できるのであれば、docker-composeにおける `pg_isready` などのhackが不要になるんじゃないか?
    - docker-composeはcontainerの起動までは面倒みてくれるけどprocessがreadyになったかどうかまでは見てくれない
    - <https://github.com/containers/libpod/issues/746#issuecomment-388959969> が何か関係している?
    - 現時点でもただ `return` しているだけなので改善の余地はありそう
        - <https://github.com/opencontainers/runc/blob/v1.0.0-rc8/notify_socket.go#L69-L109>
    - <https://github.com/containers/podman-compose> なんてあったのか
    - 活用するためにはミドルウェアが `sd_notify` を使用して自身の状態を通知しないといけないからそれもハードルになるのではないか
        - <https://www.freedesktop.org/software/systemd/man/systemd.service.html#Options>
            - この `Type=notify` がそれらしい
        - MariaDB (MySQLも?)はできていそう
            - [Ubuntuでmysql-serverをmariadb-serverで置き換えるとsystemd経由でmariadbが起動できない - NaruseJunのメモ帳](https://narusejun.com/archives/24/)