text:
<?xml version="1.0" encoding="utf-8"?>
<CrawlItem xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <Text>Izvrsna pizza. Nažalost dostava prespora. Čekali smo 1:10 min umjesto 50 min prema obavijesti.Poraditi na dostavi!!!</Text>
  <Rating>4.5</Rating>
  <Source>http://pauza.hr/menu/pizza-slavonija</Source>
</CrawlItem>


text:
import { instanceOf } from '@boost/common';
import { Blueprint, Schemas } from '@boost/common/optimal';
import { Context } from './Context';
import { createWorkUnit } from './createWorkUnit';
import { Pipeline } from './Pipeline';
import { Action, AggregatedResult } from './types';
import { WorkUnit } from './WorkUnit';

export abstract class ParallelPipeline<
	Options extends object,
	Ctx extends Context,
	Input = unknown,
	Output = Input,
> extends Pipeline<Options, Ctx, Input, Output> {
	// Empty blueprint so that sub-classes may type correctly
	blueprint(schemas: Schemas): Blueprint<object> {
		return {};
	}

	/**
	 * Add a work unit to the list of items to process.
	 */
	add(title: string, action: Action<Ctx, Input, Output>, scope?: unknown): this;
	add(workUnit: WorkUnit<{}, Input, Output>): this;
	add(
		titleOrWorkUnit: WorkUnit<{}, Input, Output> | string,
		action?: Action<Ctx, Input, Output>,
		scope?: unknown,
	): this {
		const workUnit = createWorkUnit(titleOrWorkUnit, action, scope);

		workUnit.depth = this.depth;
		workUnit.index = this.work.length;

		this.work.push(workUnit);

		return this;
	}

	/**
	 * Aggregate and partition errors and results into separate collections.
	 */
	protected aggregateResult(responses: (Error | Output)[]): AggregatedResult<Output> {
		const errors: Error[] = [];
		const results: Output[] = [];

		responses.forEach((response) => {
			if (instanceOf(response, Error)) {
				errors.push(response);
			} else {
				results.push(response);
			}
		});

		return { errors, results };
	}

	/**
	 * Run and process the work unit's asynchronously.
	 */
	abstract run(): Promise<unknown>;
}

redpajama_set_name: RedPajamaGithub


text:
<?php

require_once('utils/BaseController.php');
require_once('utils/photos.php');
require_once('utils/b2_util.php');
require_once('utils/KeysUtil.php');
require_once('libs/flickr.simple.php');

class ImportTasksController extends BaseController
{
	public function __construct( $config )
	{
		parent::__construct( true, $config );
	}

	public function urlStub()
	{
		return 'importtasks';
	}

	public function getTitle()
	{
		return 'Import Tasks';
	}

	public function getBody( $request, $todaysPhoto, $xtpl )
	{
		$xtpl->assign_file('BODY_FILE', 'templates/import_tasks.html');

		$db = getDb();

		if( count( $request->args ) == 0 )
		{
			$importTasks = $db->photo_import()->select('*')->order('id');
			while ($task = $importTasks->fetch()) {
				$xtpl->assign('TASK_ID', $task['id']);
				$xtpl->assign('ALBUM_ID', $task['flickr_album_id']);
				$xtpl->assign('FLICKR_ID', $task['flickr_id']);
				$xtpl->assign('STATUS', $task['import_state']);

				$xtpl->parse('main.body.import_task');
			}

			$xtpl->parse('main.body');
		}
		else if( count( $request->args ) == 1 )
		{
			session_write_close();
			set_time_limit( 2400 );

			if( $request->args[0] == 'all' )
			{
				$importTasks = $db->photo_import()->select('id')->order('id');
				while ($task = $importTasks->fetch())
				{
					processImportTask($task['id']);
				}
			}
			else if( is_numeric($request->args[0]) )
			{
				$importTaskId = $request->args[0];
				processImportTask( $importTaskId );
			}

			header('Location:/' . $this->urlStub());
		}
		else
		{
			header('Location:/' . $this->urlStub());
		}
	}

	public function post( $request )
	{
		/*
		if( !empty($request->post['import_task_id']) && is_numeric($request->post['import_task_id']) )
		{
			processImportTask( $request->post['import_task_id'] );
		}
		*/
	}
}

?>


text:
using UnityEngine;
using System;
using System.IO;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using ForieroEngine.MIDIUnified;
using ForieroEngine.MIDIUnified.Midi;
using System.Text.RegularExpressions;

public partial class MidiSeqKaraokeScript : MonoBehaviour, IMidiEvents
{
	void Update ()
	{
		if (state == State.Playing) {
			cancelUpdate = false;

			midiFinished = true;
			musicFinished = true;
			vocalsFinished = true;

			deltaTime = Time.deltaTime * speed;

			if (musicClip && music) {
				deltaTime = audioMusic.time - lastTime;
				musicFinished = !audioMusic.isPlaying;
			} else if (vocalsClip && vocals) {
				deltaTime = audioVocals.time - lastTime;
				vocalsFinished = !audioVocals.isPlaying;
			}

			deltaTimeNumerator = deltaTime + deltaTimeRest;

			deltaTimeIterator = Mathf.FloorToInt (deltaTimeNumerator / deltaTimeResolution);

			for (int k = 0; k < deltaTimeIterator; k++) {

				if (cancelUpdate) {
					break;
				}

				midiFinished = false;

				if (CallEvents ()) {
					UpdateTime ();
				}

				if (midiFinished) {
					break;
				}
			}

			if (midiFinished && musicFinished && vocalsFinished) {
				state = State.Finished;
				return;
			}

			deltaTimeRest = deltaTimeNumerator % deltaTimeResolution;

		}
	}

	void UpdateTime ()
	{
		deltaTime = deltaTimeResolution;

		periodResolution = PPQN * 1000f * deltaTime * MicrosecondsPerMillisecond;
		//ticksPerClock = PPQN / PPQNMinValue;
		deltaTicks = (fractionalTicks + periodResolution) / tempoTicks;
		fractionalTicks += periodResolution - deltaTicks * tempoTicks;

		if (repeatBarSelection) {
			barTmp = bar;

			if (beatCount != (int)((ticks + deltaTicks) / PPQN / (4f / timeSignatureDenominator)) + 1)
			if (beatCount % (int)timeSignatureNumerator + 1 == 1) {
				barTmp++;
			}

			if (barTmp > endBar + 1) {

				if (OnRepeat != null) {
					OnRepeat (startBar);
				}

				cancelUpdate = true;
				SetBar (startBar, true, pickUpBarOnRepeat);
				return;
			}
		}

		if (beatCount != (int)(ticks / PPQN / (4f / timeSignatureDenominator)) + 1) {
			beat = beatCount % (int)timeSignatureNumerator + 1;

			if (beat == 1) {
				bar++;
			}

			beatCount = (int)(ticks / PPQN / (4f / timeSignatureDenominator)) + 1;

			if (metronome) {
				TimeKeeper.BeatEvent (beat, timeSignatureNumerator, timeSignatureDenominator);
			}
		}

		ticks += deltaTicks;
		time += deltaTime;

		lastTime = time;
		lastDeltaTime = deltaTime;
		lastDeltaTicks = deltaTicks;
	}

	int GetTrackEventPosFromAbsoluteTicks (int aTrackIndex, float aAbsoluteTicks)
	{
		for (int i = 0; i < tracks [aTrackIndex].Count; i++) {
			if (tracks [aTrackIndex] [i].AbsoluteTime > aAbsoluteTicks)
				return i - 1;
		}
		return tracks [aTrackIndex].Count - 1;
	}

	public float TimeToTicks (float aTime)
	{
		return PPQN * 1000f * aTime * (float)MicrosecondsPerMillisecond / tempoTicks;
	}

	public float TicksToTime (float ticks)
	{
		return ticks / PPQN / 1000f / (float)MicrosecondsPerMillisecond * tempoTicks;
	}
}


text:
using namespace std;

int main() {
	cout << "Size of char : " << sizeof(char) << endl;
	cout << "Size of int : " << sizeof(int) << endl;
	cout << "Size of float : " << sizeof(float) << endl;
	cout << "Size of double : " << sizeof(double) << endl;
	return 0;
}


text:
namespace windows {
  namespace
  {
    std::vector<char> vecstring(std::string const & str)
    {
      std::vector<char> result{str.begin(), str.end()};
      result.push_back('\0');
      return result;
    }
  }

  template <typename T_handler>
  class t_service_runner final
  {
  private:
    SERVICE_STATUS_HANDLE m_status_handle{nullptr};
    SERVICE_STATUS m_status{};
    boost::mutex m_lock{};
    std::string m_name;
    T_handler m_handler;

    static std::unique_ptr<t_service_runner<T_handler>> sp_instance;
  public:
    t_service_runner(
        std::string name
      , T_handler handler
      )
      : m_name{std::move(name)}
      , m_handler{std::move(handler)}
    {
      m_status.dwServiceType = SERVICE_WIN32;
      m_status.dwCurrentState = SERVICE_STOPPED;
      m_status.dwControlsAccepted = 0;
      m_status.dwWin32ExitCode = NO_ERROR;
      m_status.dwServiceSpecificExitCode = NO_ERROR;
      m_status.dwCheckPoint = 0;
      m_status.dwWaitHint = 0;
    }

    t_service_runner & operator=(t_service_runner && other)
    {
      if (this != &other)
      {
        m_status_handle = std::move(other.m_status_handle);
        m_status = std::move(other.m_status);
        m_name = std::move(other.m_name);
        m_handler = std::move(other.m_handler);
      }
      return *this;
    }

    static void run(
        std::string name
      , T_handler handler
      )
    {
      sp_instance.reset(new t_service_runner<T_handler>{
        std::move(name)
      , std::move(handler)
      });

      sp_instance->run_();
    }

  private:
    void run_()
    {
      SERVICE_TABLE_ENTRY table[] =
      {
        { vecstring(m_name).data(), &service_main }
      , { 0, 0 }
      };

      StartServiceCtrlDispatcher(table);
    }

    void report_status(DWORD status)
    {
      m_status.dwCurrentState = status;
      if (status == SERVICE_RUNNING)
      {
        m_status.dwControlsAccepted = SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_SHUTDOWN;
      }
      else if(status == SERVICE_STOP_PENDING)
      {
        m_status.dwControlsAccepted = 0;
      }
      SetServiceStatus(m_status_handle, &m_status);
    }

    static void WINAPI service_main(DWORD argc, LPSTR * argv)
    {
      sp_instance->service_main_(argc, argv);
    }

    void service_main_(DWORD argc, LPSTR * argv)
    {
      m_status_handle = RegisterServiceCtrlHandler(m_name.c_str(), &on_state_change_request);
      if (m_status_handle == nullptr) return;

      report_status(SERVICE_START_PENDING);

      report_status(SERVICE_RUNNING);

      m_handler.run();

      on_state_change_request_(SERVICE_CONTROL_STOP);

      // Ensure that the service is uninstalled
      uninstall_service(m_name);
    }

    static void WINAPI on_state_change_request(DWORD control_code)
    {
      sp_instance->on_state_change_request_(control_code);
    }

    void on_state_change_request_(DWORD control_code)
    {
      switch (control_code)
      {
        case SERVICE_CONTROL_INTERROGATE:
          break;
        case SERVICE_CONTROL_SHUTDOWN:
        case SERVICE_CONTROL_STOP:
          report_status(SERVICE_STOP_PENDING);
          m_handler.stop();
          report_status(SERVICE_STOPPED);
          break;
        case SERVICE_CONTROL_PAUSE:
          break;
        case SERVICE_CONTROL_CONTINUE:
          break;
        default:
          break;
      }
    }
  };

  template <typename T_handler>
  std::unique_ptr<t_service_runner<T_handler>> t_service_runner<T_handler>::sp_instance;
}

#endif


text:
<?xml version="1.0" encoding="UTF-8"?>
<metadata>
  <groupId>fi.mml</groupId>
  <artifactId>wms</artifactId>
  <versioning>
    <release>1.1.1</release>
    <versions>
      <version>1.1.1</version>
    </versions>
    <lastUpdated>20140404082509</lastUpdated>
  </versioning>
</metadata>


text:
package testflight_test

import (
	. "github.com/onsi/ginkgo"
	. "github.com/onsi/gomega"
	"github.com/onsi/gomega/gbytes"
)

var _ = Describe("A job with a task that produces outputs", func() {
	Context("with outputs and single worker", func() {
		BeforeEach(func() {
			setAndUnpausePipeline("fixtures/task-outputs.yml")
		})

		It("propagates the outputs from one task to another", func() {
			watch := fly("trigger-job", "-j", inPipeline("some-job"), "-w")
			Expect(watch).To(gbytes.Say("initializing"))

			Expect(watch.Out.Contents()).To(ContainSubstring("./output-1/file-1"))
			Expect(watch.Out.Contents()).To(ContainSubstring("./output-2/file-2"))
		})
	})
})


text:
#include <aws/workmail/model/ListResourcesRequest.h>
#include <aws/core/utils/json/JsonSerializer.h>

#include <utility>

using namespace Aws::WorkMail::Model;
using namespace Aws::Utils::Json;
using namespace Aws::Utils;

ListResourcesRequest::ListResourcesRequest() :
    m_organizationIdHasBeenSet(false),
    m_nextTokenHasBeenSet(false),
    m_maxResults(0),
    m_maxResultsHasBeenSet(false)
{
}

Aws::String ListResourcesRequest::SerializePayload() const
{
  JsonValue payload;

  if(m_organizationIdHasBeenSet)
  {
   payload.WithString("OrganizationId", m_organizationId);

  }

  if(m_nextTokenHasBeenSet)
  {
   payload.WithString("NextToken", m_nextToken);

  }

  if(m_maxResultsHasBeenSet)
  {
   payload.WithInteger("MaxResults", m_maxResults);

  }

  return payload.View().WriteReadable();
}

Aws::Http::HeaderValueCollection ListResourcesRequest::GetRequestSpecificHeaders() const
{
  Aws::Http::HeaderValueCollection headers;
  headers.insert(Aws::Http::HeaderValuePair("X-Amz-Target", "WorkMailService.ListResources"));
  return headers;

}


text:
package com.hazelcast.internal.util;

import java.util.ArrayList;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

import static java.util.Collections.sort;

/**
 * Non Thread-Safe Counter of things. It allows to count items without worrying about nulls.
 *
 * @param <T>
 */
public final class ItemCounter<T> {

    private final Map<T, MutableLong> map = new HashMap<T, MutableLong>();
    private long total;

    /**
     * Returns the total counts.
     *
     * Complexity is O(1).
     *
     * @return total count.
     */
    public long total() {
        return total;
    }

    /**
     * Returns an iterator over all keys.
     *
     * @return the key iterator.
     */
    public Set<T> keySet() {
        return map.keySet();
    }

    /**
     * Returns a List of keys in descending value order.
     *
     * @return the list of keys
     */
    public List<T> descendingKeys() {
        List<T> list = new ArrayList<T>(map.keySet());

        sort(list, new Comparator<T>() {
            @Override
            public int compare(T o1, T o2) {
                MutableLong l1 = map.get(o1);
                MutableLong l2 = map.get(o2);
                return compare(l2.value, l1.value);
            }

            private int compare(long x, long y) {
                return (x < y) ? -1 : ((x == y) ? 0 : 1);
            }
        });

        return list;
    }

    /**
     * Get current counter for an item item
     *
     * @param item
     * @return current state of a counter for item
     */
    public long get(T item) {
        MutableLong count = map.get(item);
        return count == null ? 0 : count.value;
    }

    /**
     * Set counter of item to value
     *
     * @param item  to set set the value for
     * @param value a new value
     */
    public void set(T item, long value) {
        MutableLong entry = map.get(item);
        if (entry == null) {
            entry = MutableLong.valueOf(value);
            map.put(item, entry);
            total += value;
        } else {
            total -= entry.value;
            total += value;
            entry.value = value;
        }
    }

    /**
     * Increases the count by on for the given item.
     *
     * @param item
     */
    public void inc(T item) {
        add(item, 1);
    }

    /**
     * Add delta to the item
     *
     * @param item
     * @param delta
     */
    public void add(T item, long delta) {
        MutableLong entry = map.get(item);
        if (entry == null) {
            entry = MutableLong.valueOf(delta);
            map.put(item, entry);
        } else {
            entry.value += delta;
        }
        total += delta;
    }

    /**
     * Reset state of the counter to 0.
     * It will <b>NOT</b> necessary remove all data referenced.
     *
     * Time complexity of this operation is O(n) where n is number of items.
     */
    public void reset() {
        for (MutableLong entry : map.values()) {
            entry.value = 0;
        }
        total = 0;
    }

    /**
     * Clears the counter.
     */
    public void clear() {
        map.clear();
        total = 0;
    }

    /**
     * Set counter for item and return previous value
     *
     * @param item
     * @param value
     * @return
     */
    public long getAndSet(T item, long value) {
        MutableLong entry = map.get(item);

        if (entry == null) {
            entry = MutableLong.valueOf(value);
            map.put(item, entry);
            total += value;
            return 0;
        }

        long oldValue = entry.value;
        total = total - oldValue + value;
        entry.value = value;
        return oldValue;
    }

    public void remove(T item) {
        MutableLong entry = map.remove(item);
        total -= entry == null ? 0 : entry.value;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) {
            return true;
        }
        if (o == null || getClass() != o.getClass()) {
            return false;
        }

        ItemCounter that = (ItemCounter) o;
        if (!map.equals(that.map)) {
            return false;
        }
        return true;
    }

    @Override
    public int hashCode() {
        return map.hashCode();
    }

    @Override
    public String toString() {
        return map.toString();
    }
}


text:
<?php
namespace cs;
include __DIR__.'/../../bootstrap.php';
$Event = Event::instance();
$User  = User::instance();

var_dump('Registration confirmation');
$result = $User->registration('mrcc1@test.com', true, false);
var_dump('Find unconfirmed user');
var_dump($User->search_users('mrcc1@test.com'));
var_dump($result, $User->get('password_hash', $result['id']));
var_dump($User->registration_confirmation($result['reg_key']));
var_dump((int)$User->get('id', $result['id']) ?: false, $User->get('password_hash', $result['id']));
var_dump('Find confirmed user');
var_dump($User->search_users('mrcc1@test.com'));

var_dump('Wrong confirmation key');
var_dump($User->registration_confirmation('abc'));

var_dump('Cancel registration in System/User/registration/confirmation/before event');
$Event->once(
	'System/User/registration/confirmation/before',
	function () {
		return false;
	}
);
$result = $User->registration('mrcc2@test.com', true, false);
var_dump($result, $User->get('password_hash', $result['id']));
var_dump($User->registration_confirmation($result['reg_key']));
var_dump((int)$User->get('id', $result['id']) ?: false, $User->get('password_hash', $result['id']));

var_dump('Cancel registration in System/User/registration/confirmation/after event');
$Event->once(
	'System/User/registration/confirmation/after',
	function () {
		return false;
	}
);
$result = $User->registration('mrcc3@test.com', true, false);
var_dump($result, $User->get('password_hash', $result['id']));
var_dump($User->registration_confirmation($result['reg_key']));
var_dump((int)$User->get('id', $result['id']) ?: false, $User->get('password_hash', $result['id']));

var_dump('Generate password during confirmation');
$result = $User->registration('mrcc4@test.com', true, false);
var_dump($result, $User->get('password_hash', $result['id']));
var_dump($User->registration_confirmation($result['reg_key']));
var_dump((int)$User->get('id', $result['id']) ?: false, $User->get('password_hash', $result['id']));

var_dump('Confirm with non-existing key');
var_dump($User->registration_confirmation(md5(random_bytes(1000))));

var_dump('Delete non-existing users');
$Event->on(
	'System/User/del/before',
	function ($data) {
		var_dump('System/User/del/before with', $data);
	}
);
$User->del_user(0);
$User->del_user(PHP_INT_MAX);

var_dump('Try to delete guest');
$User->del_user(User::GUEST_ID);

var_dump('Try to delete root administrator');
$User->del_user(User::ROOT_ID);
?>
--EXPECTF--
string(25) "Registration confirmation"
string(21) "Find unconfirmed user"
bool(false)
array(3) {
  ["reg_key"]=>
  string(32) "%s"
  ["password"]=>
  string(0) ""
  ["id"]=>
  int(%d)
}
string(0) ""
array(3) {
  ["id"]=>
  int(%d)
  ["email"]=>
  string(14) "mrcc1@test.com"
  ["password"]=>
  string(4) "%s"
}
int(%d)
string(60) "%s"
string(19) "Find confirmed user"
array(1) {
  [0]=>
  int(%d)
}
string(22) "Wrong confirmation key"
bool(false)
string(73) "Cancel registration in System/User/registration/confirmation/before event"
array(3) {
  ["reg_key"]=>
  string(32) "%s"
  ["password"]=>
  string(0) ""
  ["id"]=>
  int(%d)
}
string(0) ""
bool(false)
bool(false)
bool(false)
string(72) "Cancel registration in System/User/registration/confirmation/after event"
array(3) {
  ["reg_key"]=>
  string(32) "%s"
  ["password"]=>
  string(0) ""
  ["id"]=>
  int(%d)
}
string(0) ""
bool(false)
bool(false)
bool(false)
string(37) "Generate password during confirmation"
array(3) {
  ["reg_key"]=>
  string(32) "%s"
  ["password"]=>
  string(0) ""
  ["id"]=>
  int(%d)
}
string(0) ""
array(3) {
  ["id"]=>
  int(%d)
  ["email"]=>
  string(14) "mrcc4@test.com"
  ["password"]=>
  string(4) "%s"
}
int(%d)
string(60) "%s"
string(29) "Confirm with non-existing key"
bool(false)
string(25) "Delete non-existing users"
string(19) "Try to delete guest"
string(32) "Try to delete root administrator"


text:
import {Directive, ElementRef, Host, LifecycleEvent} from 'angular2/angular2';
import {Dropdown} from './dropdown';

@Directive({
  selector: '[dropdown-menu], .dropdown-menu',
  host: {
    '[attr.templateUrl]': 'templateUrl'
  },
  lifecycle: [LifecycleEvent.onInit]
})
export class DropdownMenu {
  public templateUrl:string;

  constructor(@Host() public dropdown:Dropdown, public el:ElementRef) {
  }

  onInit() {
    this.dropdown.dropDownMenu = this;
  }
}


text:
package main

import "testing"

func TestIsTagExcemptedFromDeletion(t *testing.T) {
	CheckAndGetConfigs()
	_, err := IsTagExcemptedFromDeletion([]string{"tagName1"}, "tagName1")
	FailOnError(err, "Step: Test - Excemption From Deletion")
}

func TestLatestTag(t *testing.T) {
	CheckAndGetConfigs()
	isExcempt, err := IsTagExcemptedFromDeletion([]string{"j7t7"}, "latest")
	if !isExcempt || err != nil {
		t.Fail()
	}
}


text:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Xemio.GameLibrary.Content.Metadata
{
    public interface IMetadata
    {
        /// <summary>
        /// Gets the unique identifier.
        /// </summary>
        Guid Guid { get; }
        /// <summary>
        /// Gets the type.
        /// </summary>
        Type Type { get; }
    }
}


text:
package storagemetrics_test

import (
	"testing"

	"github.com/pkg/errors"
	"github.com/stretchr/testify/require"

	"github.com/kopia/kopia/internal/blobtesting"
	"github.com/kopia/kopia/internal/gather"
	"github.com/kopia/kopia/internal/metrics"
	"github.com/kopia/kopia/internal/testlogging"
	"github.com/kopia/kopia/repo/blob"
	"github.com/kopia/kopia/repo/blob/storagemetrics"
)

func TestStorageMetrics_PutBlob(t *testing.T) {
	ctx := testlogging.Context(t)
	someError := errors.Errorf("foo")
	st := blobtesting.NewMapStorage(blobtesting.DataMap{}, nil, nil)

	fs := blobtesting.NewFaultyStorage(st)
	fs.AddFault(blobtesting.MethodPutBlob).ErrorInstead(someError)

	mr := metrics.NewRegistry()
	ms := storagemetrics.NewWrapper(fs, mr)
	snap := mr.Snapshot(false)

	requireCounterValue(t, snap, "blob_upload_bytes", 0)
	requireCounterValue(t, snap, "blob_errors[method:PutBlob]", 0)

	require.ErrorIs(t, ms.PutBlob(ctx, "someBlob1", gather.FromSlice([]byte{1, 2, 3, 4}), blob.PutOptions{}), someError)
	require.NoError(t, ms.PutBlob(ctx, "someBlob", gather.FromSlice([]byte{1, 2, 3}), blob.PutOptions{}))

	snap = mr.Snapshot(false)
	requireCounterValue(t, snap, "blob_errors[method:PutBlob]", 1)
	requireCounterValue(t, snap, "blob_upload_bytes", 3)

	d := snap.DurationDistributions["blob_storage_latency[method:PutBlob]"]
	require.EqualValues(t, 2, d.Count)
}

func TestStorageMetrics_GetBlob(t *testing.T) {
	ctx := testlogging.Context(t)
	someError := errors.Errorf("foo")
	st := blobtesting.NewMapStorage(blobtesting.DataMap{}, nil, nil)

	require.NoError(t, st.PutBlob(ctx, "someBlob", gather.FromSlice([]byte{1, 2, 3, 4, 5}), blob.PutOptions{}))

	fs := blobtesting.NewFaultyStorage(st)
	fs.AddFault(blobtesting.MethodGetBlob).ErrorInstead(someError)

	mr := metrics.NewRegistry()
	ms := storagemetrics.NewWrapper(fs, mr)
	snap := mr.Snapshot(false)

	requireCounterValue(t, snap, "blob_download_full_blob_bytes", 0)
	requireCounterValue(t, snap, "blob_download_partial_blob_bytes", 0)
	requireCounterValue(t, snap, "blob_errors[method:GetBlob]", 0)

	var tmp gather.WriteBuffer
	defer tmp.Close()

	require.ErrorIs(t, ms.GetBlob(ctx, "someBlob", 0, -1, &tmp), someError)
	require.NoError(t, ms.GetBlob(ctx, "someBlob", 0, -1, &tmp))

	snap = mr.Snapshot(false)
	requireCounterValue(t, snap, "blob_errors[method:GetBlob]", 1)
	requireCounterValue(t, snap, "blob_download_full_blob_bytes", 5)

	d := snap.DurationDistributions["blob_storage_latency[method:GetBlob-full]"]
	require.EqualValues(t, 2, d.Count)

	require.NoError(t, ms.GetBlob(ctx, "someBlob", 2, 2, &tmp))

	snap = mr.Snapshot(false)
	requireCounterValue(t, snap, "blob_errors[method:GetBlob]", 1)
	requireCounterValue(t, snap, "blob_download_full_blob_bytes", 5)
	require.Equal(t, 2, tmp.Length())

	d = snap.DurationDistributions["blob_storage_latency[method:GetBlob-partial]"]
	require.EqualValues(t, 1, d.Count)
}

func TestStorageMetrics_GetMetadata(t *testing.T) {
	ctx := testlogging.Context(t)
	someError := errors.Errorf("foo")
	st := blobtesting.NewMapStorage(blobtesting.DataMap{}, nil, nil)

	require.NoError(t, st.PutBlob(ctx, "someBlob", gather.FromSlice([]byte{1, 2, 3, 4, 5}), blob.PutOptions{}))

	fs := blobtesting.NewFaultyStorage(st)
	fs.AddFault(blobtesting.MethodGetMetadata).ErrorInstead(someError)

	mr := metrics.NewRegistry()
	ms := storagemetrics.NewWrapper(fs, mr)
	snap := mr.Snapshot(false)

	requireCounterValue(t, snap, "blob_errors[method:GetMetadata]", 0)

	var tmp gather.WriteBuffer
	defer tmp.Close()

	_, err := ms.GetMetadata(ctx, "someBlob")
	require.ErrorIs(t, err, someError)

	_, err = ms.GetMetadata(ctx, "someBlob")
	require.NoError(t, err)

	snap = mr.Snapshot(false)
	requireCounterValue(t, snap, "blob_errors[method:GetMetadata]", 1)

	d := snap.DurationDistributions["blob_storage_latency[method:GetMetadata]"]
	require.EqualValues(t, 2, d.Count)
}

func TestStorageMetrics_GetCapacity(t *testing.T) {
	ctx := testlogging.Context(t)
	someError := errors.Errorf("foo")
	st := blobtesting.NewMapStorage(blobtesting.DataMap{}, nil, nil)

	fs := blobtesting.NewFaultyStorage(st)
	fs.AddFault(blobtesting.MethodGetCapacity).ErrorInstead(someError)

	mr := metrics.NewRegistry()
	ms := storagemetrics.NewWrapper(fs, mr)
	snap := mr.Snapshot(false)

	requireCounterValue(t, snap, "blob_errors[method:GetCapacity]", 0)

	var tmp gather.WriteBuffer
	defer tmp.Close()

	_, err := ms.GetCapacity(ctx)
	require.ErrorIs(t, err, someError)

	_, err = ms.GetCapacity(ctx)
	require.ErrorIs(t, err, blob.ErrNotAVolume)

	snap = mr.Snapshot(false)
	requireCounterValue(t, snap, "blob_errors[method:GetCapacity]", 2)

	d := snap.DurationDistributions["blob_storage_latency[method:GetCapacity]"]
	require.EqualValues(t, 2, d.Count)
}

func TestStorageMetrics_DeleteBlob(t *testing.T) {
	ctx := testlogging.Context(t)
	someError := errors.Errorf("foo")
	st := blobtesting.NewMapStorage(blobtesting.DataMap{}, nil, nil)

	require.NoError(t, st.PutBlob(ctx, "someBlob", gather.FromSlice([]byte{1, 2, 3, 4, 5}), blob.PutOptions{}))

	fs := blobtesting.NewFaultyStorage(st)
	fs.AddFault(blobtesting.MethodDeleteBlob).ErrorInstead(someError)

	mr := metrics.NewRegistry()
	ms := storagemetrics.NewWrapper(fs, mr)
	snap := mr.Snapshot(false)

	requireCounterValue(t, snap, "blob_errors[method:DeleteBlob]", 0)

	var tmp gather.WriteBuffer
	defer tmp.Close()

	err := ms.DeleteBlob(ctx, "someBlob")
	require.ErrorIs(t, err, someError)

	err = ms.DeleteBlob(ctx, "someBlob")
	require.NoError(t, err)

	snap = mr.Snapshot(false)
	requireCounterValue(t, snap, "blob_errors[method:DeleteBlob]", 1)

	d := snap.DurationDistributions["blob_storage_latency[method:DeleteBlob]"]
	require.EqualValues(t, 2, d.Count)
}

func TestStorageMetrics_Close(t *testing.T) {
	ctx := testlogging.Context(t)
	someError := errors.Errorf("foo")
	st := blobtesting.NewMapStorage(blobtesting.DataMap{}, nil, nil)

	fs := blobtesting.NewFaultyStorage(st)
	fs.AddFault(blobtesting.MethodClose).ErrorInstead(someError)

	mr := metrics.NewRegistry()
	ms := storagemetrics.NewWrapper(fs, mr)
	snap := mr.Snapshot(false)

	requireCounterValue(t, snap, "blob_errors[method:Close]", 0)

	var tmp gather.WriteBuffer
	defer tmp.Close()

	err := ms.Close(ctx)
	require.ErrorIs(t, err, someError)

	err = ms.Close(ctx)
	require.NoError(t, err)

	snap = mr.Snapshot(false)
	requireCounterValue(t, snap, "blob_errors[method:Close]", 1)

	d := snap.DurationDistributions["blob_storage_latency[method:Close]"]
	require.EqualValues(t, 2, d.Count)
}

func TestStorageMetrics_FlushCaches(t *testing.T) {
	ctx := testlogging.Context(t)
	someError := errors.Errorf("foo")
	st := blobtesting.NewMapStorage(blobtesting.DataMap{}, nil, nil)

	fs := blobtesting.NewFaultyStorage(st)
	fs.AddFault(blobtesting.MethodFlushCaches).ErrorInstead(someError)

	mr := metrics.NewRegistry()
	ms := storagemetrics.NewWrapper(fs, mr)
	snap := mr.Snapshot(false)

	requireCounterValue(t, snap, "blob_errors[method:FlushCaches]", 0)

	var tmp gather.WriteBuffer
	defer tmp.Close()

	err := ms.FlushCaches(ctx)
	require.ErrorIs(t, err, someError)

	err = ms.FlushCaches(ctx)
	require.NoError(t, err)

	snap = mr.Snapshot(false)
	requireCounterValue(t, snap, "blob_errors[method:FlushCaches]", 1)

	d := snap.DurationDistributions["blob_storage_latency[method:FlushCaches]"]
	require.EqualValues(t, 2, d.Count)
}

func TestStorageMetrics_ListBlobs(t *testing.T) {
	ctx := testlogging.Context(t)
	someError := errors.Errorf("foo")
	st := blobtesting.NewMapStorage(blobtesting.DataMap{}, nil, nil)
	require.NoError(t, st.PutBlob(ctx, "someBlob1", gather.FromSlice([]byte{1, 2, 3, 4, 5}), blob.PutOptions{}))
	require.NoError(t, st.PutBlob(ctx, "someBlob2", gather.FromSlice([]byte{1, 2, 3, 4, 5}), blob.PutOptions{}))
	require.NoError(t, st.PutBlob(ctx, "someBlob3", gather.FromSlice([]byte{1, 2, 3, 4, 5}), blob.PutOptions{}))

	fs := blobtesting.NewFaultyStorage(st)
	fs.AddFault(blobtesting.MethodListBlobs).ErrorInstead(someError)

	mr := metrics.NewRegistry()
	ms := storagemetrics.NewWrapper(fs, mr)
	snap := mr.Snapshot(false)

	requireCounterValue(t, snap, "blob_errors[method:ListBlobs]", 0)
	requireCounterValue(t, snap, "blob_list_items", 0)

	var tmp gather.WriteBuffer
	defer tmp.Close()

	err := ms.ListBlobs(ctx, "", func(bm blob.Metadata) error { return nil })
	require.ErrorIs(t, err, someError)

	err = ms.ListBlobs(ctx, "", func(bm blob.Metadata) error { return nil })
	require.NoError(t, err)

	snap = mr.Snapshot(false)
	requireCounterValue(t, snap, "blob_errors[method:ListBlobs]", 1)

	d := snap.DurationDistributions["blob_storage_latency[method:ListBlobs]"]
	require.EqualValues(t, 2, d.Count)
	requireCounterValue(t, snap, "blob_list_items", 3)
}

func TestStorageMetrics_Misc(t *testing.T) {
	st := blobtesting.NewMapStorage(blobtesting.DataMap{}, nil, nil)
	mr := metrics.NewRegistry()
	ms := storagemetrics.NewWrapper(st, mr)
	require.Equal(t, st.ConnectionInfo(), ms.ConnectionInfo())
	require.Equal(t, st.DisplayName(), ms.DisplayName())
}

func requireCounterValue(t *testing.T, snap metrics.Snapshot, key string, want int64) {
	t.Helper()

	v, ok := snap.Counters[key]
	require.True(t, ok)
	require.EqualValues(t, want, v)
}


text:
Virtlet uses custom flexvolume driver to handle raw block devices and
Ceph volumes right now. This makes VM pods less consistent with
"plain" Kubernetes pods. Another problem is that we may want to support
persistent rootfs in future. As there's now Local Persistent Volume
support (beta as of 1.10) and Block Volume support (alpha as of 1.10)
in Kubernetes, we may use these features in Virtlet to avoid the
flexvolume hacks and gain persistent rootfs support.

This document contains the results of the research and will be turned
into a more detailed proposal later if we decide to make use of
the block PVs.

The research is based on
[this Kubernetes blog post](https://kubernetes.io/blog/2018/04/13/local-persistent-volumes-beta/#enabling-smarter-scheduling-and-volume-binding)
and
[the raw block volume description](https://kubernetes.io/docs/concepts/storage/persistent-volumes/#raw-block-volume-support)
from Kubernetes documentation.

First, I'll describe how the block PVs can be used in Virtlet, and
then I'll give a detailed description of how the experiments were
conducted.

## Using block PVs in Virtlet

As it turns out, the non-local block PVs aren't different from local
block PVs from the CRI point of view. They're configured using
`volumeDevices` section of the container spec in the pod and `volumes`
section of the pod spec, and passed as `devices` section in the
container config to `CreateContainer()` CRI call:

```yaml
  devices:
  - container_path: /dev/testpvc
    host_path: /var/lib/kubelet/pods/65b0c985-6e81-11e8-be27-769e6e14e66a/volumeDevices/kubernetes.io~local-volume/local-block-pv
    permissions: mrw
```

Virtlet can use `host_path` to attach the device to the VM using a
`DomainDisk`, and `container_path` to mount it inside the VM using
cloud-init. The handling of local and non-local PVs doesn't differ
on the CRI level.

Supporting non-local PVs will automatically give Virtlet support for
all the Kubernetes volume types that support the block mode, which
include Ceph, FibreChannel, and the persistent disks on AWS, GCP and
Azure, with the list probably growing larger in the future. It will
also give automatic support for CSI plugins that support the block
mode.  The caveat is that the block mode is Alpha as of Kubernetes
1.10 and it wasn't checked for earlier Kubernetes versions.

The use of block PVs will eliminate the need for custom flexvolumes at
some point (after block volumes become GA and we stop supporting
earlier Kubernetes versions). There's one caveat, with block PVs the
Ceph RBDs will be mapped on the nodes by `kubelet`, instead of being
consumed by qemu by the means of `librbd`. It's not clear though if
this will be good or bad from the performance standpoint. If we'll
still need custom volume types, flexvolumes may be replaced with
[CSI](https://kubernetes.io/blog/2018/04/10/container-storage-interface-beta/).

More advantages of using block PVs instead of custom flexvolumes
include having VM pods differ even less from "plain" pods, and a
possibility to make use automatic PV provisioning in future.

There's also a possibility of using the block PVs (local or non-local)
for the persistent rootfs. It's possible to copy the image onto PV
upon the first use, and then have another pod reuse the PV after the
original one is destroyed. For local PVs, the scheduler will always
place the pod on the node where the local PV resides (this constitutes
so called "gravity"). There's a problem with this approach, namely,
there's no reliable way for a CRI implementation to find a PV that
corresponds to a block device, so Virtlet will have to examine the
contents of the PV to see if it's used for the first time. This also
means that Virtlet will have hard time establishing the correspondence
between PVs and the images that are applied to them (e.g. imagine a PV
being used by a pod with different image later). It's possible to
overcome these problems by either storing the metadata on the block
device itself somehow, or using CRDs and PV metadata to keep track of
"pet" VMs and their root filesystems. The use of local PVs will take
much of the burden from the corresponding controller, though.

## Experimenting with the Local Persistent Volumes

First, we need to define a storage class that specifies
`volumeBindingMode: WaitForFirstConsumer` that's
[needed](https://kubernetes.io/blog/2018/04/13/local-persistent-volumes-beta/#enabling-smarter-scheduling-and-volume-binding)
for propoper pod scheduling:
```yaml
---
kind: StorageClass
apiVersion: storage.k8s.io/v1
metadata:
  name: local-storage
provisioner: kubernetes.io/no-provisioner
volumeBindingMode: WaitForFirstConsumer
```

Below is a definition of a Local Persistent Volume:
```yaml
apiVersion: v1
kind: PersistentVolume
metadata:
  name: local-block-pv
spec:
  capacity:
    storage: 100Mi
  accessModes:
  - ReadWriteOnce
  persistentVolumeReclaimPolicy: Retain
  storageClassName: local-storage
  volumeMode: Block
  local:
    path: /dev/loop3
  claimRef:
    name: local-block-pvc
    namespace: default
  nodeAffinity:
    required:
      nodeSelectorTerms:
      - matchExpressions:
        - key: kubernetes.io/hostname
          operator: In
          values:
          - kube-node-1
```

The important parts here are the following: `volumeMode: Block`
setting the block volume mode, local volume source specification
that makes the PV use `/dev/loop3`
```yaml
  local:
    path: /dev/loop3
```
and a `nodeAffinity` spec that pins the local PV to `kube-node-1`:
```
  nodeAffinity:
    required:
      nodeSelectorTerms:
      - matchExpressions:
        - key: kubernetes.io/hostname
          operator: In
          values:
          - kube-node-1
```

The following PVC makes use of that PV (it's referenced explicitly via
`claimRef` above but we could allow Kubernetes to associate the PV
with PVC instead), also including `volumeMode: Block` in it:
```yaml
kind: PersistentVolumeClaim
apiVersion: v1
metadata:
  name: local-block-pvc
spec:
  accessModes:
  - ReadWriteOnce
  volumeMode: Block
  storageClassName: local-storage
  resources:
    requests:
      storage: 100Mi
```

And, finally, a pod that makes use of the PVC:
```
---
kind: Pod
apiVersion: v1
metadata:
  name: test-block-pod
spec:
  containers:
  - name: ubuntu
    image: ubuntu:16.04
    command:
    - /bin/sh
    - -c
    - sleep 30000
    volumeDevices:
    - devicePath: /dev/testpvc
      name: testpvc
  volumes:
  - name: testpvc
    persistentVolumeClaim:
      claimName: local-block-pvc
```

In the pod definition, we're using `volumeDevices` with `devicePath`
instead of `volumeMounts` with `mountPath`. This will make the node's
`/dev/loop3` appear as `/dev/testpvc` inside the pod's container:

```
$ kubectl exec test-block-pod -- ls -l /dev/testpvc
brw-rw---- 1 root disk 7, 3 Jun 12 20:44 /dev/testpvc
$ kubectl exec test-block-pod -- mkfs.ext4 /dev/testpvc
Discarding device blocks: done
Creating filesystem with 102400 1k blocks and 25688 inodes
Filesystem UUID: a02f7560-23a6-45c1-b10a-6e0a1b1eee72
Superblock backups stored on blocks:
        8193, 24577, 40961, 57345, 73729

Allocating group tables: done
Writing inode tables: done
Creating journal (4096 blocks): mke2fs 1.42.13 (17-May-2015)
done
Writing superblocks and filesystem accounting information: done
```

The important part is that the pod gets automatically scheduled on the
node where the local PV used by the PVC resides:
```
$ kubectl get pods test-block-pod -o wide
NAME             READY     STATUS    RESTARTS   AGE       IP           NODE
test-block-pod   1/1       Running   0          21m       10.244.2.9   kube-node-1
```

From CRI point of view, the following container config is passed to
the `CreateContainer()` call, as seen in CRI Proxy logs (pod sandbox
config omitted for brevity as it doesn't contain the mount or device
related information):
```yaml
I0612 20:44:29.869566    1038 proxy.go:126] ENTER: /runtime.v1alpha2.RuntimeService/CreateContainer():
config:
  annotations:
    io.kubernetes.container.hash: ff82c6d3
    io.kubernetes.container.restartCount: "0"
    io.kubernetes.container.terminationMessagePath: /dev/termination-log
    io.kubernetes.container.terminationMessagePolicy: File
    io.kubernetes.pod.terminationGracePeriod: "30"
  command:
  - /bin/sh
  - -c
  - sleep 30000
  devices:
  - container_path: /dev/testpvc
    host_path: /var/lib/kubelet/pods/65b0c985-6e81-11e8-be27-769e6e14e66a/volumeDevices/kubernetes.io~local-volume/local-block-pv
    permissions: mrw
  envs:
  - key: KUBERNETES_SERVICE_PORT_HTTPS
    value: "443"
  - key: KUBERNETES_PORT
    value: tcp://10.96.0.1:443
  - key: KUBERNETES_PORT_443_TCP
    value: tcp://10.96.0.1:443
  - key: KUBERNETES_PORT_443_TCP_PROTO
    value: tcp
  - key: KUBERNETES_PORT_443_TCP_PORT
    value: "443"
  - key: KUBERNETES_PORT_443_TCP_ADDR
    value: 10.96.0.1
  - key: KUBERNETES_SERVICE_HOST
    value: 10.96.0.1
  - key: KUBERNETES_SERVICE_PORT
    value: "443"
  image:
    image: sha256:5e8b97a2a0820b10338bd91674249a94679e4568fd1183ea46acff63b9883e9c
  labels:
    io.kubernetes.container.name: ubuntu
    io.kubernetes.pod.name: test-block-pod
    io.kubernetes.pod.namespace: default
    io.kubernetes.pod.uid: 65b0c985-6e81-11e8-be27-769e6e14e66a
  linux:
    resources:
      cpu_shares: 2
      oom_score_adj: 1000
    security_context:
      namespace_options:
        pid: 1
      run_as_user: {}
  log_path: ubuntu/0.log
  metadata:
    name: ubuntu
  mounts:
  - container_path: /var/run/secrets/kubernetes.io/serviceaccount
    host_path: /var/lib/kubelet/pods/65b0c985-6e81-11e8-be27-769e6e14e66a/volumes/kubernetes.io~secret/default-token-7zwlh
    readonly: true
  - container_path: /etc/hosts
    host_path: /var/lib/kubelet/pods/65b0c985-6e81-11e8-be27-769e6e14e66a/etc-hosts
  - container_path: /dev/termination-log
    host_path: /var/lib/kubelet/pods/65b0c985-6e81-11e8-be27-769e6e14e66a/containers/ubuntu/2be42601
```

The important part is this:
```yaml
  devices:
  - container_path: /dev/testpvc
    host_path: /var/lib/kubelet/pods/65b0c985-6e81-11e8-be27-769e6e14e66a/volumeDevices/kubernetes.io~local-volume/local-block-pv
    permissions: mrw
```

If we look at the node, we'll see that `host_path` points to a symlink to `/dev/loop3` which
is specified in the local block PV:
```
root@kube-node-1:/# ls -l /var/lib/kubelet/pods/65b0c985-6e81-11e8-be27-769e6e14e66a/volumeDevices/kubernetes.io~local-volume/local-block-pv
lrwxrwxrwx 1 root root 10 Jun 13 08:31 /var/lib/kubelet/pods/65b0c985-6e81-11e8-be27-769e6e14e66a/volumeDevices/kubernetes.io~local-volume/local-block-pv -> /dev/loop3
```

`container_path` denotes the path to the device inside the container.

The `permissions` is described in CRI spec as follows:
```
    // Cgroups permissions of the device, candidates are one or more of
    // * r - allows container to read from the specified device.
    // * w - allows container to write to the specified device.
    // * m - allows container to create device files that do not yet exist.
```

Also note that the device is not listed in `mounts`.

There's a
[tool](https://github.com/kubernetes-incubator/external-storage/tree/master/local-volume)
for automatic provisioning of Local Persistent Volumes that's part of
[external-storage](https://github.com/kubernetes-incubator/external-storage)
project. Right now it may not be very useful for Virtlet, but it may
gain some important features later, like support for automatic
partitioning and fs formatting.

## Experimenting with non-local ("plain") Persistent Volumes

Let's check "plain" PVs now. We'll be using Ceph block volumes.

Below are some tricks that make kubeadm-dind-cluster compatible with
Ceph. Some of them may be useful for running
[Rook](https://github.com/rook/rook) on k-d-c, too.

For Ceph RBDs to work with Kubernetes Ceph PVs (not just Virtlet's
flexvolume-based ones), I had to make `rbd` work on the DIND nodes, so
the following change had to be made to the kubeadm-dind-cluster's main
script (observed in [Rook's](https://github.com/rook/rook) DIND
setup):
```
diff --git a/dind-cluster.sh b/dind-cluster.sh
index e9118e2..24a0a78 100755
--- a/dind-cluster.sh
+++ b/dind-cluster.sh
@@ -645,6 +645,9 @@ function dind::run {
          --hostname "${container_name}" \
          -l mirantis.kubeadm_dind_cluster \
          -v ${volume_name}:/dind \
+         -v /dev:/dev \
+         -v /sys/bus:/sys/bus \
+         -v /var/run/docker.sock:/opt/outer-docker.sock \
          ${opts[@]+"${opts[@]}"} \
          "${DIND_IMAGE}" \
          ${args[@]+"${args[@]}"}
```

The following file had to be added as a fake `rbd` command to each DIND node
(borrowed from [Rook scripts](https://github.com/rook/rook/blob/cd2b69915958e7453b3fc5031f59179058163dcd/tests/scripts/dind-cluster-rbd)):
```
#!/bin/bash
DOCKER_HOST=unix:///opt/outer-docker.sock /usr/bin/docker run --rm -v /sys:/sys --net=host --privileged=true ceph/base rbd "$@"
```
It basically executes rbd command using `ceph/base` images using the
host docker in the host network namespace.

So let's bring up the cluster:
```bash
./dind-cluster.sh up
```

Disable rate limiting so journald doesn't choke on CRI proxy logs on the node 1:
```bash
docker exec kube-node-1 /bin/bash -c 'echo "RateLimitInterval=0" >>/etc/systemd/journald.conf && systemctl restart systemd-journald'
```

Enable `BlockVolume` mode for kubelet on the node 1
(`MountPropagation` is enabled by default in 1.10, so let's just
replace it):
```bash
docker exec kube-node-1 /bin/bash -c 'sed -i "s/MountPropagation/BlockVolume/" /lib/systemd/system/kubelet.service && systemctl daemon-reload && systemctl restart kubelet'
```

Install CRI Proxy so we can grab the logs:
```bash
CRIPROXY_DEB_URL="${CRIPROXY_DEB_URL:-https://github.com/Mirantis/criproxy/releases/download/v0.14.0/criproxy-nodeps_0.14.0_amd64.deb}"
docker exec kube-node-1 /bin/bash -c "curl -sSL '${CRIPROXY_DEB_URL}' >/criproxy.deb && dpkg -i /criproxy.deb && rm /criproxy.deb"
```

Taint node 2 so we get everything scheduled on node 1:
```bash
kubectl taint nodes kube-node-2 dedicated=foobar:NoSchedule
```

Now we need to add `rbd` command to the 'hypokube' image that's used
by the control plane (we need it for `kube-controller-manager`). The
proper way would be using the node's `rbd` command with mounting host
docker socket into the container, but as the controller manager
doesn't need `rbd map` command which needs host access, we can just
install `rbd` package here, just make sure it's new enough to support
commands like `rbd status` that are invoked by the controller manager:

```bash
docker exec kube-master /bin/bash -c 'docker rm -f tmp; docker run --name tmp mirantis/hypokube:final /bin/bash -c "echo deb http://ftp.debian.org/debian jessie-backports main >>/etc/apt/sources.list && apt-get update && DEBIAN_FRONTEND=noninteractive apt-get install -y ceph-common=10.2.5-6~bpo8+1 libradosstriper1 ntp librados2=10.2.5-6~bpo8+1 librbd1=10.2.5-6~bpo8+1 python-cephfs=10.2.5-6~bpo8+1 libcephfs1=10.2.5-6~bpo8+1" && docker commit tmp mirantis/hypokube:final && docker rm -f tmp'
```

At this point, we must edit the following files on `kube-master` node, adding
`--feature-gates=BlockVolume=true` to the end of `command:` in each pod's only container:

* `/etc/kubernetes/manifests/kube-apiserver.yaml`
* `/etc/kubernetes/manifests/kube-scheduler.yaml`
* `/etc/kubernetes/manifests/kube-controller-manager.yaml`

Likely, updating just the controller manager may suffice, but I didn't
check.  This will cause the pods to restart and use the updated
`mirantis/hypokube:final` image.

Now let's start the Ceph demo container:
```bash
MON_IP=$(docker exec kube-master route | grep default | awk '{print $2}')
CEPH_PUBLIC_NETWORK=${MON_IP}/16
docker run -d --net=host -e MON_IP=${MON_IP} \
       -e CEPH_PUBLIC_NETWORK=${CEPH_PUBLIC_NETWORK} \
       -e CEPH_DEMO_UID=foo \
       -e CEPH_DEMO_ACCESS_KEY=foo \
       -e CEPH_DEMO_SECRET_KEY=foo \
       -e CEPH_DEMO_BUCKET=foo \
       -e DEMO_DAEMONS="osd mds" \
       --name ceph_cluster docker.io/ceph/daemon demo
```

Create a pool there:
```bash
docker exec ceph_cluster ceph osd pool create kube 8 8
```

Create an image for testing (it's important to use `rbd create` with
`layering` feature here so as not to get a feature mismatch error
later when creating a pod):
```bash
docker exec ceph_cluster rbd create tstimg \
       --size 11M --pool kube --image-feature layering
```

Set up a Kubernetes secret for use with Ceph:
```bash
admin_secret="$(docker exec ceph_cluster ceph auth get-key client.admin)"
kubectl create secret generic ceph-admin \
        --type="kubernetes.io/rbd" \
        --from-literal=key="${admin_secret}" \
        --namespace=kube-system
```

Copy the `rbd` replacement script presented earlier above to each node:
```bash
for n in kube-{master,node-{1,2}}; do
  docker cp dind-cluster-rbd ${n}:/usr/bin/rbd
done
```

Now we can create a test PV, PVC and a pod.

Let's define a storage class:
```yaml
kind: StorageClass
apiVersion: storage.k8s.io/v1
metadata:
  name: ceph-testnew
provisioner: kubernetes.io/rbd
parameters:
  monitors: 10.192.0.1:6789
  adminId: admin
  adminSecretName: ceph-admin
  adminSecretNamespace: kube-system
  pool: kube
  userId: admin
  userSecretName: ceph-admin
  userSecretNamespace: kube-system
  fsType: ext4
  imageFormat: "1"
  # the following was disabled while testing non-block PVs
  imageFeatures: "layering"
```
Actually, the automatic provisioning didn't work for me because it
was setting `volumeMode: Filesystem` in the PVs, but this was probably
due to my mistake, or otherwise from looking at Kubernetes source
it should be fixable.

Let's define a block PV:
```yaml
---
apiVersion: v1
kind: PersistentVolume
metadata:
  name: test-block-pv
spec:
  accessModes:
  - ReadWriteOnce
  capacity:
    storage: 10Mi
  claimRef:
    name: ceph-block-pvc
    namespace: default
  persistentVolumeReclaimPolicy: Delete
  rbd:
    image: tstimg
    keyring: /etc/ceph/keyring
    monitors:
    - 10.192.0.1:6789
    pool: kube
    secretRef:
      name: ceph-admin
      namespace: kube-system
    user: admin
  storageClassName: ceph-testnew
  volumeMode: Block
```

The difference from the "usual" RBD PV is `volumeMode: Block` here,
and the same goes for the PVC:
```yaml
---
kind: PersistentVolumeClaim
apiVersion: v1
metadata:
  name: ceph-block-pvc
spec:
  accessModes:
  - ReadWriteOnce
  volumeMode: Block
  storageClassName: ceph-testnew
  resources:
    requests:
      storage: 10Mi
```

Now, the pod itself, with `volumeDevices` instead of `volumeMounts`:
```yaml
kind: Pod
apiVersion: v1
metadata:
  name: ceph-block-pod
spec:
  containers:
  - name: ubuntu
    image: ubuntu:16.04
    command:
    - /bin/sh
    - -c
    - sleep 30000
    volumeDevices:
    - name: data
      devicePath: /dev/cephdev
  volumes:
  - name: data
    persistentVolumeClaim:
      claimName: ceph-block-pvc
```

Let's do `kubectl apply -f ceph-test.yaml` (`ceph-test.yaml`
containing all of the yaml documents above), and try it out:

```
$ kubectl exec ceph-block-pod -- ls -l /dev/cephdev
brw-rw---- 1 root disk 252, 0 Jun 12 20:19 /dev/cephdev
$ kubectl exec ceph-block-pod -- mkfs.ext4 /dev/cephdev
mke2fs 1.42.13 (17-May-2015)
Discarding device blocks: done
Creating filesystem with 11264 1k blocks and 2816 inodes
Filesystem UUID: 81ce32e8-bf37-4bc8-88bf-674bf6f79d14
Superblock backups stored on blocks:
        8193

Allocating group tables: done
Writing inode tables: done
Creating journal (1024 blocks): done
Writing superblocks and filesystem accounting information: done
```

Let's capture CRI Proxy logs:
```
docker exec kube-node-1 journalctl -xe -n 20000 -u criproxy|egrep --line-buffered -v '/run/virtlet.sock|\]: \{\}|/var/run/dockershim.sock|ImageFsInfo' >/tmp/log.txt
```

The following is the important part of the log which is slightly
cleaned up:
```
I0612 20:19:38.681852    1038 proxy.go:126] ENTER: /runtime.v1alpha2.RuntimeService/CreateContainer():
config:
  annotations:
    io.kubernetes.container.hash: d0c4a380
    io.kubernetes.container.restartCount: "0"
    io.kubernetes.container.terminationMessagePath: /dev/termination-log
    io.kubernetes.container.terminationMessagePolicy: File
    io.kubernetes.pod.terminationGracePeriod: "30"
  command:
  - /bin/sh
  - -c
  - sleep 30000
  devices:
  - container_path: /dev/cephdev
    host_path: /var/lib/kubelet/pods/ebb11dcb-6e7d-11e8-be27-769e6e14e66a/volumeDevices/kubernetes.io~rbd/test-block-pv
    permissions: mrw
  envs:
  - key: KUBERNETES_PORT
    value: tcp://10.96.0.1:443
  - key: KUBERNETES_PORT_443_TCP
    value: tcp://10.96.0.1:443
  - key: KUBERNETES_PORT_443_TCP_PROTO
    value: tcp
  - key: KUBERNETES_PORT_443_TCP_PORT
    value: "443"
  - key: KUBERNETES_PORT_443_TCP_ADDR
    value: 10.96.0.1
  - key: KUBERNETES_SERVICE_HOST
    value: 10.96.0.1
  - key: KUBERNETES_SERVICE_PORT
    value: "443"
  - key: KUBERNETES_SERVICE_PORT_HTTPS
    value: "443"
  image:
    image: sha256:5e8b97a2a0820b10338bd91674249a94679e4568fd1183ea46acff63b9883e9c
  labels:
    io.kubernetes.container.name: ubuntu
    io.kubernetes.pod.name: ceph-block-pod
    io.kubernetes.pod.namespace: default
    io.kubernetes.pod.uid: ebb11dcb-6e7d-11e8-be27-769e6e14e66a
  linux:
    resources:
      cpu_shares: 2
      oom_score_adj: 1000
    security_context:
      namespace_options:
        pid: 1
      run_as_user: {}
  log_path: ubuntu/0.log
  metadata:
    name: ubuntu
  mounts:
  - container_path: /var/run/secrets/kubernetes.io/serviceaccount
    host_path: /var/lib/kubelet/pods/ebb11dcb-6e7d-11e8-be27-769e6e14e66a/volumes/kubernetes.io~secret/default-token-7zwlh
    readonly: true
  - container_path: /etc/hosts
    host_path: /var/lib/kubelet/pods/ebb11dcb-6e7d-11e8-be27-769e6e14e66a/etc-hosts
  - container_path: /dev/termination-log
    host_path: /var/lib/kubelet/pods/ebb11dcb-6e7d-11e8-be27-769e6e14e66a/containers/ubuntu/577593a5
```

Again, we have this here:
```yaml
  devices:
  - container_path: /dev/cephdev
    host_path: /var/lib/kubelet/pods/ebb11dcb-6e7d-11e8-be27-769e6e14e66a/volumeDevices/kubernetes.io~rbd/test-block-pv
    permissions: mrw
```

The `host_path` points to a mapped RBD:
```yaml
root@kube-node-1:/# ls -l /var/lib/kubelet/pods/ebb11dcb-6e7d-11e8-be27-769e6e14e66a/volumeDevices/kubernetes.io~rbd/test-block-pv
lrwxrwxrwx 1 root root 9 Jun 12 20:19 /var/lib/kubelet/pods/ebb11dcb-6e7d-11e8-be27-769e6e14e66a/volumeDevices/kubernetes.io~rbd/test-block-pv -> /dev/rbd0
```

An unpleasant part about RBDs+DIND is that the machine may hang on
some commands / refuse to reboot if RBDs aren't unmapped. If kdc
cluster is already teared down (but `ceph_cluster` container is still
alive), the following commands can be used to list and unmap RBDs on
the Linux host:

```
# rbd showmapped
id pool image                                 snap device
0  kube tstimg                                -    /dev/rbd0
# rbd unmap -o force kube/tstimg
```


text:
/**
 * Tooltip to select a tag
 *
 * Inputs
 * - tagList
 * - position
 * - visible
 *
 * Outputs
 * - onTag()
 */
import React from 'react'
import PropTypes from 'prop-types'
import styled from 'styled-components'

const UnstyledContainer = ({ className, children, style }) => (
  <div
    className={`tooltip tooltip-bottom ${className}`}
    style={style}
  >
    {children}

)

const Container = styled(UnstyledContainer)`
  opacity: 1;
  position: fixed;
  transform: translateX(-50%);
`

const List = styled.ul`
  padding: 0;
  margin: 0;
  list-style: none;
`

const ListItem = styled.li`
  padding: 5px;
`

const Button = styled.button`
  color: #FFF;
  font-family: sans-serif;
  font-weight: bold;
  padding: 5px;
  background: none;
  border: 0;
  cursor: pointer;
  outline: none;
  text-align: left;
  width: 100%;
`

const Tooltip = ({ list, onSelect, position }) => (
  <Container
    style={{
      top: (position.top + position.height) + 'px',
      left: (position.left + position.width / 2) + 'px'
    }}
  >

      <List>
        {
          list.map(({ref, title}) => (
            <ListItem key={ref}>
              <Button onClick={() => onSelect(ref)}>
                {title}
              </Button>
            </ListItem>
          ))
        }
      </List>

  </Container>
)

Tooltip.propTypes = {
  list: PropTypes.arrayOf(
    PropTypes.shape({
      ref: PropTypes.oneOfType([
        PropTypes.string,
        PropTypes.number
      ]).isRequired,
      title: PropTypes.string.isRequired
    })
  ),
  onSelect: PropTypes.func.isRequired
}

export default Tooltip


text:
class AddColumnDeckImg < ActiveRecord::Migration
  def change
  	add_column :decks, :deck_img, :string
  end
end


text:
module DiffParser
  def parse_diff(diff)
    raise "parse_diff(diff) must be overridden"
  end
end


text:
Python Client for Google Cloud DNS
==================================

    Python idiomatic client for `Google Cloud DNS`_

.. _Google Cloud DNS: https://cloud.google.com/dns/

|pypi| |versions|

-  `Documentation`_

.. _Documentation: https://googlecloudplatform.github.io/google-cloud-python/stable/dns/usage.html

Quick Start
-----------

.. code-block:: console

    $ pip install --upgrade google-cloud-dns

Authentication
--------------

With ``google-cloud-python`` we try to make authentication as painless as
possible. Check out the `Authentication section`_ in our documentation to
learn more. You may also find the `authentication document`_ shared by all
the ``google-cloud-*`` libraries to be helpful.

.. _Authentication section: https://google-cloud-python.readthedocs.io/en/latest/core/auth.html
.. _authentication document: https://github.com/GoogleCloudPlatform/gcloud-common/tree/master/authentication

Using the API
-------------

The Cloud `DNS`_ API (`DNS API docs`_) provides methods that you can use to
manage DNS for your applications.

.. _DNS: https://cloud.google.com/dns/
.. _DNS API docs: https://cloud.google.com/dns/docs/apis

See the ``google-cloud-python`` API DNS `Documentation`_ to learn
how to manage DNS records using this Client Library.

.. |pypi| image:: https://img.shields.io/pypi/v/google-cloud-dns.svg
   :target: https://pypi.org/project/google-cloud-dns/
.. |versions| image:: https://img.shields.io/pypi/pyversions/google-cloud-dns.svg
   :target: https://pypi.org/project/google-cloud-dns/


text:
package me.dilek.cezmi.dlna;

import org.fourthline.cling.support.model.container.Container;
import org.fourthline.cling.support.model.item.Item;
import org.fourthline.cling.support.model.item.VideoItem;

/**
 * Observes only video files
 * Created by Hakan Dilek on 26.04.15.
 */
public abstract class VideoObserver implements ContentObserver {
    @Override
    public void itemFound(ContentPath path, Item item) {
        if (item instanceof VideoItem) {
            videoFound(path, (VideoItem) item);
        }
    }

    protected abstract void videoFound(ContentPath path, VideoItem item);

    @Override
    public void containerFound(ContentPath path, Container container) {
        // just ignore
    }
}


text:
"use strict";

var fs = require('fs'),
    path = require('path'),
    touch = require('touch'),
    expect = require('chai').expect,
    temp = require('temp').track(),
    cases = require('cases'),
    paths = require('../src/paths'),
    _ = require('lodash');

describe('paths', function() {

    describe('expand', function() {

        var basePath, relative, absolute;

        before(function() {

            basePath = temp.mkdirSync();

            touch.sync(path.join(basePath, 'a.xml'));
            touch.sync(path.join(basePath, 'b.xml'));
            fs.mkdirSync(path.join(basePath, 'dir'));
            touch.sync(path.join(basePath, 'dir', 'a.xml'));
            touch.sync(path.join(basePath, 'dir', 'b.xml'));

            relative = function(file) {
                return path.relative(basePath, file.path);
            };

            absolute = function() {
                return path.join.apply(null, [ basePath ].concat(_.toArray(arguments)));
            };
        });

        after(function() {
            temp.cleanupSync();
        });

        it('should resolve files', function() {

             cases([
                [[ absolute('a.*'), absolute('dir', 'b.*') ]],
                [[ [ absolute('a.*'), absolute('dir', 'b.*') ] ]],
                [[ [ absolute('a.*')], [ absolute('dir', 'b.*') ] ]],
                [[ { path: absolute('a.*') }, { path: absolute('dir', 'b.*') } ]],
                [[ [ { path: absolute('a.*') }, { path: absolute('dir', 'b.*') } ] ]],
                [[ [ { path: absolute('a.*') }], [{ path: absolute('dir', 'b.*') } ] ]],
                [[ absolute('a.*'), { path: absolute('dir', 'b.*') } ]],
                [[ absolute('a.*'), { customPath: absolute('dir', 'b.*') }, function(x) { return x.customPath; } ]]
            ], function (params) {

                var files = paths.expand.apply(null, params);

                expect(files).to.have.length(2);

                expect(relative(files[0])).to.equal('a.xml');
                expect(files[0].context).to.exist();

                expect(relative(files[1])).to.equal('dir/b.xml');
                expect(files[1].context).to.exist();
            })();

        });

        it('should not resolve directories', function() {
            var files = paths.expand(absolute('**', '*'));

            expect(files).to.have.length(4);

            expect(relative(files[0])).to.equal('a.xml');
            expect(relative(files[1])).to.equal('b.xml');
            expect(relative(files[2])).to.equal('dir/a.xml');
            expect(relative(files[3])).to.equal('dir/b.xml');

        });

        it('should return unique string results', function() {
            var files = paths.expand(absolute('**', 'a.*'), absolute('**', 'a.*'));

            expect(files).to.have.length(2);

            expect(relative(files[0])).to.equal('a.xml');
            expect(relative(files[1])).to.equal('dir/a.xml');

        });

        it('should not return unique object results', function() {
            var files = paths.expand({ path: absolute('**', 'a.*') }, { path: absolute('**', 'a.*') });

            expect(files).to.have.length(4);

            expect(relative(files[0])).to.equal('a.xml');
            expect(relative(files[1])).to.equal('dir/a.xml');
            expect(relative(files[2])).to.equal('a.xml');
            expect(relative(files[3])).to.equal('dir/a.xml');

        });

        it('should pass context with objects', function() {
            var context = { path: absolute('a.*') };
            var files = paths.expand(context);

            expect(relative(files[0])).to.equal('a.xml');
            expect(files[0].context).to.equal(context);

        });

        it('should pass empty context with strings', function() {
            var files = paths.expand(absolute('a.*'));

            expect(relative(files[0])).to.equal('a.xml');
            expect(files[0].context).to.deep.equal({});

        });

        it('should fail if no files', cases([
          [[ ]],
          [[ function(x) { return x.customPath; } ]]
        ], function (params) {
            expect(function() { paths.expand.apply(null, params); }).to.throw(Error);
        }));

    });
});


text:
using namespace Gautier::SFMLApp;

void WindowEventController::CollectNextEvent(SFMLWindow& programWindow)
{
	_EventCollectionIsActive = programWindow.isOpen();

	if(_EventCollectionIsActive)
	{
		SFMLEvent InteractionEvent;

		bool EventPollSuccessful = programWindow.pollEvent(InteractionEvent);

		if(EventPollSuccessful)
		{
			_EventCollectionIsActive = (InteractionEvent.type != SFMLEvent::Closed);

			if(_EventCollectionIsActive)
			{
				_EventModel.InterpretInteractionEvent(InteractionEvent);
			}
		}
	}
}

const bool WindowEventController::GetEventCollectionIsActive()
{
	return _EventCollectionIsActive;
}

const WindowEventModel& WindowEventController::GetEventModel()
{
	return _EventModel;
}


text:
jpersistence
============

Persistence engine using plain text docs.

###Usage Example

####Extending from Entity

```java
import jpersistence.Entity;

public class Person extends Entity {

    private String name;
    private Integer age;

    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public int getAge() {
        return age;
    }
    public void setAge(int age) {
        this.age = age;
    }
}
```

####Testing it

```java
import static org.junit.Assert.*;

import jpersistence.EntityDao;
import jpersistence.EntityList;

import org.junit.Test;

public class Main {

    @Test
    public void testSaveAndFind() {

        Person person = new Person();

        person.setName("Juan");
        person.setAge(25);

        person.save();

        EntityList<Person> testPersons = new EntityDao<Person>().findAll(Person.class);
        Person testPerson = testPersons.get(0);

        assertEquals("Juan", testPerson.getName());
        assertEquals(25, testPerson.getAge());
        assertEquals(Integer.valueOf(1), testPerson.getId());
    }

}
```


text:
layout: page
weight: 0
title: Exchange 2010
navigation:
  show: true
---

If your organization is using Microsoft's Exchange 2010 for email services, this document outlines the basics required in order to use SendGrid for SMTP. This requires the configuration of a send connector in the Exchange Management Console.

{% warning %}
This documentation assumes that you already have a working installation of Exchange 2010 that is configured for client access and is able to send messages to the public internet. **If you do not configure this connector correctly it may result in the unintended delivery of messages through your SendGrid account, resulting in the consumption of account emails.**
{% endwarning %}

{% info %}
[For more information regarding Send Connectors, check out this swank TechNet documentation on the subject](http://technet.microsoft.com/en-us/library/aa998662.aspx).
{% endinfo %}

The configuration of a new send connector is straight forward. It is the associated configurations that you may require in order to properly control access to the connector that may be complicated. Let's start with just sending email through SendGrid:

1. Login to your Exchange server or a server that has the Exchange Management Console installed for administrative purposes.
2. Go to **Start \> All Programs \> Microsoft Exchange Server 2010** and click on the **Exchange Management Console** item.
3. Roll open the **Organization Configuration** list and select **Hub Transport**.
4. Click on **New Send Connector** in the Actions sidebar.
5. Name the Send Connector whatever you like and select Internet for the Intended Use pull-down. This allows for the integration with an authenticated SmartHost and adds the default send permissions required by Exchange 2010 to route messages through an external host that is not a part of the domain forest.
6. Click **Next**.
7. Click Add and specify the allowed address space to which the connector can send messages. If you want to send to anyone on the internet, then you would insert an "\*" in the Address field. If you want to send only to a specific domain, enter that domain. If you want to allow all sub-domains you can check the box, but I prefer to notate that literally like so: \*.SAMPLEDOMAIN.COM. Insert a high cost (100 is the top, so choose wisely) so that the connector is not used inadvertently.
8. Click **Next**.
9. On the Network Settings page, select the **Route mail through the following smart hosts** item.
10. Click **Add**.
11. Select the **Fully qualified domain name (FQDN)** item, and enter: *smtp.sendgrid.net*
12. Click **Next**.
13. In the **Configure smart host authentication settings** page, select the **Basic Authentication** option and check the **Basic Authentication over TLS** checkbox, then ***enter your SendGrid username and password***.
14. Click **Next**.
15. If you only have one Exchange server, it should automatically appear. If you want to use another server(s) in your domain click Add to locate the servers you want to allocate to this connector.
16. Click **Next**.
17. Verify your settings and, when satisfied, click **New**.
18. If the configuration completes correctly, you will receive positive notification. You can then click on **Finish**.

Once you have completed installation of the connector, you will need to configure your server(s) to allow limited access to the new send connector. You can read more about [Send Connector permissions][send-connector-permissions].

[send-connector-permissions]: http://technet.microsoft.com/en-us/library/aa998662(v=exchg.141).aspx


text:
// Copyright (c) 2011 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "gpu/tools/compositor_model_bench/shaders.h"

#include <stdint.h>

#include <algorithm>

#include "gpu/tools/compositor_model_bench/render_model_utils.h"
#include "gpu/tools/compositor_model_bench/render_tree.h"

using std::min;

static const int kPositionLocation = 0;
static const int kTexCoordLocation = 1;

static unsigned g_quad_vertices_vbo;
static unsigned g_quad_elements_vbo;

// Store a pointer to the transform matrix of the active layer (the complete
// transform isn't build until we draw the quad; then we can apply
// translation/scaling/projection)
static float* g_current_layer_transform;

// In addition to the transform, store other useful information about tiled
// layers that we'll need to render each tile's quad
static float g_current_tile_layer_width;
static float g_current_tile_layer_height;
static float g_current_tile_width;
static float g_current_tile_height;

static const float yuv2RGB[9] = {
  1.164f, 1.164f, 1.164f,
  0.f, -.391f, 2.018f,
  1.596f, -.813f, 0.f
};

// Store shader programs in a sparse array so that they can be addressed easily.
static int g_program_objects[SHADER_ID_MAX*SHADER_ID_MAX];
static int g_active_index = -1;

///////////////////////////////////////////////////////////////////////////////
//              L        R           B          T   N  F
//      glOrtho(0, WINDOW_WIDTH, WINDOW_HEIGHT, 0, -1, 1);   // column major

static float g_projection_matrix[] = {
  2.0 / WINDOW_WIDTH, 0.0, 0.0, 0.0,
  0.0, 2.0 / -WINDOW_HEIGHT, 0.0, 0.0,
  0.0, 0.0, -1.0, 0.0,
  -1.0, 1.0, 0.0, 1.0
};

#define ADDR(i, j) (i*4 + j) /* column major */
static void Project(const float* v, float* p) {
  for (int i = 0; i < 4; ++i) {
    for (int j = 0; j < 4; ++j) {
      p[ADDR(i, j)] = 0;
      for (int k = 0; k < 4; ++k) {
        p[ADDR(i, j)] += g_projection_matrix[ADDR(k, i)] * v[ADDR(j, k)];
      }
    }
  }
}

static void Scale(const float* in, float* out, float sx, float sy, float sz) {
  for (int i = 0; i < 4; ++i)
    out[i] = in[i] * sx;
  for (int j = 4; j < 8; ++j)
    out[j] = in[j] * sy;
  for (int k = 8; k < 12; ++k)
    out[k] = in[k] * sz;
  for (int l = 12; l < 16; ++l)
    out[l] = in[l];
}

static void TranslateInPlace(float* m, float tx, float ty, float tz) {
  m[12] += tx;
  m[13] += ty;
  m[14] += tz;
}

///////////////////////////////////////////////////////////////////////////////

ShaderID ShaderIDFromString(const std::string& name) {
  if (name == "VertexShaderPosTexYUVStretch")
    return VERTEX_SHADER_POS_TEX_YUV_STRETCH;
  if (name == "VertexShaderPosTex")
    return VERTEX_SHADER_POS_TEX;
  if (name == "VertexShaderPosTexTransform")
    return VERTEX_SHADER_POS_TEX_TRANSFORM;
  if (name == "FragmentShaderYUVVideo")
    return FRAGMENT_SHADER_YUV_VIDEO;
  if (name == "FragmentShaderRGBATexFlipAlpha")
    return FRAGMENT_SHADER_RGBA_TEX_FLIP_ALPHA;
  if (name == "FragmentShaderRGBATexAlpha")
    return FRAGMENT_SHADER_RGBA_TEX_ALPHA;
  return SHADER_UNRECOGNIZED;
}

std::string ShaderNameFromID(ShaderID id) {
  switch (id) {
    case VERTEX_SHADER_POS_TEX_YUV_STRETCH:
      return "VertexShaderPosTexYUVStretch";
    case VERTEX_SHADER_POS_TEX:
      return "VertexShaderPosTex";
    case VERTEX_SHADER_POS_TEX_TRANSFORM:
      return "VertexShaderPosTexTransform";
    case FRAGMENT_SHADER_YUV_VIDEO:
      return "FragmentShaderYUVVideo";
    case FRAGMENT_SHADER_RGBA_TEX_FLIP_ALPHA:
      return "FragmentShaderRGBATexFlipAlpha";
    case FRAGMENT_SHADER_RGBA_TEX_ALPHA:
      return "FragmentShaderRGBATexAlpha";
    default:
      return "(unknown shader)";
  }
}

#define SHADER0(Src) #Src
#define SHADER(Src) SHADER0(Src)

const char* GetShaderSource(ShaderID shader) {
  switch (shader) {
    case VERTEX_SHADER_POS_TEX_YUV_STRETCH:
      return SHADER(
        #ifdef GL_ES
        precision mediump float;
        #endif
        attribute vec4 a_position;
        attribute vec2 a_texCoord;
        uniform mat4 matrix;
        varying vec2 y_texCoord;
        varying vec2 uv_texCoord;
        uniform float y_widthScaleFactor;
        uniform float uv_widthScaleFactor;
        void main() {
          gl_Position = matrix * a_position;
          y_texCoord = vec2(y_widthScaleFactor * a_texCoord.x,
            a_texCoord.y);
          uv_texCoord = vec2(uv_widthScaleFactor * a_texCoord.x,
            a_texCoord.y);
        });
      break;
    case VERTEX_SHADER_POS_TEX:
      return SHADER(
        attribute vec4 a_position;
        attribute vec2 a_texCoord;
        uniform mat4 matrix;
        varying vec2 v_texCoord;
        void main() {
          gl_Position = matrix * a_position;
          v_texCoord = a_texCoord;
        });
      break;
    case VERTEX_SHADER_POS_TEX_TRANSFORM:
      return SHADER(
        attribute vec4 a_position;
        attribute vec2 a_texCoord;
        uniform mat4 matrix;
        uniform vec4 texTransform;
        varying vec2 v_texCoord;
        void main() {
          gl_Position = matrix * a_position;
          v_texCoord = a_texCoord*texTransform.zw + texTransform.xy;
        });
      break;
    case FRAGMENT_SHADER_YUV_VIDEO:
      return SHADER(
        #ifdef GL_ES
        precision mediump float;
        precision mediump int;
        #endif
        varying vec2 y_texCoord;
        varying vec2 uv_texCoord;
        uniform sampler2D y_texture;
        uniform sampler2D u_texture;
        uniform sampler2D v_texture;
        uniform float alpha;
        uniform vec3 yuv_adj;
        uniform mat3 cc_matrix;
        void main() {
          float y_raw = texture2D(y_texture, y_texCoord).x;
          float u_unsigned = texture2D(u_texture, uv_texCoord).x;
          float v_unsigned = texture2D(v_texture, uv_texCoord).x;
          vec3 yuv = vec3(y_raw, u_unsigned, v_unsigned) + yuv_adj;
          vec3 rgb = cc_matrix * yuv;
          gl_FragColor = vec4(rgb, 1.0) * alpha;
        });
      break;
    case FRAGMENT_SHADER_RGBA_TEX_FLIP_ALPHA:
      return SHADER(
        #ifdef GL_ES
        precision mediump float;
        #endif
        varying vec2 v_texCoord;
        uniform sampler2D s_texture;
        uniform float alpha;
        void main() {
          vec4 texColor = texture2D(s_texture,
            vec2(v_texCoord.x, 1.0 - v_texCoord.y));
          gl_FragColor = vec4(texColor.x,
            texColor.y,
            texColor.z,
            texColor.w) * alpha;
        });
      break;
    case FRAGMENT_SHADER_RGBA_TEX_ALPHA:
      return SHADER(
        #ifdef GL_ES
        precision mediump float;
        #endif
        varying vec2 v_texCoord;
        uniform sampler2D s_texture;
        uniform float alpha;
        void main() {
          vec4 texColor = texture2D(s_texture, v_texCoord);
          gl_FragColor = texColor * alpha;
        });
      break;
    default:
      printf("Shader source requested for unknown shader\n");
      return "";
  }
}

int GetProgramIdx(ShaderID v, ShaderID f) {
  return v * SHADER_ID_MAX + f;
}

static void ReportAnyShaderCompilationErrors(GLuint shader, ShaderID id) {
  GLint status;
  glGetShaderiv(shader, GL_COMPILE_STATUS, &status);
  if (status)
    return;
  // Get the length of the log string
  GLsizei length;
  glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &length);
  scoped_ptr<GLchar[]> log(new GLchar[length+1]);
  glGetShaderInfoLog(shader, length, NULL, log.get());
  LOG(ERROR) << log.get() << " in shader " << ShaderNameFromID(id);
}

static int ActivateShader(ShaderID v, ShaderID f, float* layer_transform) {
  int program_index = GetProgramIdx(v, f);
  if (!g_program_objects[program_index]) {
    g_program_objects[program_index] = glCreateProgramObjectARB();
    GLenum vs = glCreateShaderObjectARB(GL_VERTEX_SHADER);
    GLenum fs = glCreateShaderObjectARB(GL_FRAGMENT_SHADER);
    const char* vs_source = GetShaderSource(v);
    const char* fs_source = GetShaderSource(f);
    glShaderSourceARB(vs, 1, &vs_source, 0);
    glShaderSourceARB(fs, 1, &fs_source, 0);
    glCompileShaderARB(vs);
    ReportAnyShaderCompilationErrors(vs, v);
    glCompileShaderARB(fs);
    ReportAnyShaderCompilationErrors(fs, f);
    glAttachObjectARB(g_program_objects[program_index], vs);
    glAttachObjectARB(g_program_objects[program_index], fs);
    glBindAttribLocationARB(g_program_objects[program_index],
                            kPositionLocation,
                            "a_position");
    glBindAttribLocationARB(g_program_objects[program_index],
                            kTexCoordLocation,
                            "a_texCoord");
    glLinkProgramARB(g_program_objects[program_index]);
  }
  if (g_active_index != program_index)
    glUseProgramObjectARB(g_program_objects[program_index]);
  g_active_index = program_index;

  g_current_layer_transform = layer_transform;

  return g_program_objects[program_index];
}

void ConfigAndActivateShaderForNode(CCNode* n) {
  ShaderID vs = n->vertex_shader();
  ShaderID fs = n->fragment_shader();
  float* transform = n->transform();
  int program = ActivateShader(vs, fs, transform);
  if (vs == VERTEX_SHADER_POS_TEX_YUV_STRETCH) {
    GLint y_scale = glGetUniformLocationARB(program, "y_widthScaleFactor");
    GLint uv_scale = glGetUniformLocationARB(program, "uv_widthScaleFactor");
    glUniform1fARB(y_scale, 1.0);
    glUniform1fARB(uv_scale, 1.0);
  }
  if (vs == VERTEX_SHADER_POS_TEX_TRANSFORM) {
    GLint texTrans = glGetUniformLocationARB(program, "texTransform");
    glUniform4fARB(texTrans, 0.0, 0.0, 0.0, 0.0);
  }
  if (fs == FRAGMENT_SHADER_RGBA_TEX_FLIP_ALPHA) {
    DCHECK_EQ(n->num_textures(), 1u);
    DCHECK_NE(n->texture(0)->texID, -1);
    glActiveTexture(GL_TEXTURE0);
    glBindTexture(GL_TEXTURE_2D, n->texture(0)->texID);
    int sTexLoc = glGetUniformLocationARB(program, "s_texture");
    glUniform1iARB(sTexLoc, 0);
  }
  if (fs == FRAGMENT_SHADER_YUV_VIDEO) {
    DCHECK_EQ(n->num_textures(), 3u);
    DCHECK_NE(n->texture(0)->texID, -1);
    DCHECK_NE(n->texture(1)->texID, -1);
    DCHECK_NE(n->texture(2)->texID, -1);
    // Bind Y tex.
    glActiveTexture(GL_TEXTURE0);
    glBindTexture(GL_TEXTURE_2D, n->texture(0)->texID);
    int yTexLoc = glGetUniformLocationARB(program, "y_texture");
    glUniform1iARB(yTexLoc, 0);
    // Bind U tex.
    glActiveTexture(GL_TEXTURE0 + 1);
    glBindTexture(GL_TEXTURE_2D, n->texture(1)->texID);
    int uTexLoc = glGetUniformLocationARB(program, "u_texture");
    glUniform1iARB(uTexLoc, 1);
    // Bind V tex.
    glActiveTexture(GL_TEXTURE0 + 2);
    glBindTexture(GL_TEXTURE_2D, n->texture(2)->texID);
    int vTexLoc = glGetUniformLocationARB(program, "v_texture");
    glUniform1iARB(vTexLoc, 2);
    // Set YUV offset.
    int yuvAdjLoc = glGetUniformLocationARB(program, "yuv_adj");
    glUniform3fARB(yuvAdjLoc, -0.0625f, -0.5f, -0.5f);
    // Set YUV matrix.
    int ccMatLoc = glGetUniformLocationARB(program, "cc_matrix");
    glUniformMatrix3fvARB(ccMatLoc, 1, false, yuv2RGB);
  }
  GLint alpha = glGetUniformLocationARB(program, "alpha");
  glUniform1fARB(alpha, 0.9);
}

void ConfigAndActivateShaderForTiling(ContentLayerNode* n) {
  int program = ActivateShader(VERTEX_SHADER_POS_TEX_TRANSFORM,
                               FRAGMENT_SHADER_RGBA_TEX_ALPHA,
                               n->transform());
  GLint texTrans = glGetUniformLocationARB(program, "texTransform");
  glUniform4fARB(texTrans, 0.0, 0.0, 1.0, 1.0);
  GLint alpha = glGetUniformLocationARB(program, "alpha");
  glUniform1fARB(alpha, 0.9);

  g_current_tile_layer_width = n->width();
  g_current_tile_layer_height = n->height();
  g_current_tile_width = n->tile_width();
  g_current_tile_height = n->tile_height();
}

void DeleteShaders() {
  g_active_index = -1;
  glUseProgramObjectARB(0);
  for (int i = 0; i < SHADER_ID_MAX*SHADER_ID_MAX; ++i) {
    if (g_program_objects[i]) {
      glDeleteObjectARB(g_program_objects[i]);
    }
    g_program_objects[i] = 0;
  }
}

void InitBuffers() {
  // Vertex positions and texture coordinates for the 4 corners of a 1x1 quad.
  float vertices[] = { -0.5f,  0.5f, 0.0f, 0.0f,  1.0f,
                       -0.5f, -0.5f, 0.0f, 0.0f,  0.0f,
                       0.5f,  -0.5f, 0.0f, 1.0f,  0.0f,
                       0.5f,   0.5f, 0.0f, 1.0f,  1.0f };
  uint16_t indices[] = { 0, 1, 2, 0, 2, 3};

  glGenBuffers(1, &g_quad_vertices_vbo);
  glGenBuffers(1, &g_quad_elements_vbo);
  glBindBuffer(GL_ARRAY_BUFFER, g_quad_vertices_vbo);
  glBufferData(GL_ARRAY_BUFFER,
               sizeof(vertices),
               vertices,
               GL_STATIC_DRAW);
  glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, g_quad_elements_vbo);
  glBufferData(GL_ELEMENT_ARRAY_BUFFER,
               sizeof(indices),
               indices,
               GL_STATIC_DRAW);
}

void BeginFrame() {
  glBindBuffer(GL_ARRAY_BUFFER, g_quad_vertices_vbo);
  glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, g_quad_elements_vbo);
  unsigned offset = 0;
  glVertexAttribPointer(kPositionLocation,
                        3,
                        GL_FLOAT,
                        false,
                        5 * sizeof(float),
                        reinterpret_cast<void*>(offset));
  offset += 3 * sizeof(float);
  glVertexAttribPointer(kTexCoordLocation,
                        2,
                        GL_FLOAT,
                        false,
                        5 * sizeof(float),
                        reinterpret_cast<void*>(offset));
  glEnableVertexAttribArray(kPositionLocation);
  glEnableVertexAttribArray(kTexCoordLocation);
}

void DrawQuad(float width, float height) {
  float mv_transform[16];
  float proj_transform[16];
  Scale(g_current_layer_transform, mv_transform, width, height, 1.0);
  Project(mv_transform, proj_transform);
  GLint mat = glGetUniformLocationARB(g_program_objects[g_active_index],
                                      "matrix");
  glUniformMatrix4fvARB(mat, 1, GL_TRUE, proj_transform);

  glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, 0);
}

void DrawTileQuad(GLuint texID, int x, int y) {
  float left = g_current_tile_width*x;
  float top = g_current_tile_height*y;
  if (left > g_current_tile_layer_width || top > g_current_tile_layer_height)
    return;

  float right = min(left+g_current_tile_width, g_current_tile_layer_width);
  float bottom = min(top+g_current_tile_height, g_current_tile_layer_height);
  float width = right-left;
  float height = bottom-top;

  int prog = g_program_objects[g_active_index];

  // Scale the texture if the full tile rectangle doesn't get drawn.
  float u_scale = width / g_current_tile_width;
  float v_scale = height / g_current_tile_height;
  GLint texTrans = glGetUniformLocationARB(prog, "texTransform");
  glUniform4fARB(texTrans, 0.0, 0.0, u_scale, v_scale);

  glActiveTexture(GL_TEXTURE0);
  glBindTexture(GL_TEXTURE_2D, texID);
  int texLoc = glGetUniformLocationARB(prog, "s_texture");
  glUniform1iARB(texLoc, 0);

  float mv_transform[16];
  float proj_transform[16];
  Scale(g_current_layer_transform, mv_transform, width, height, 1.0);

  // We have to position the tile by its center.
  float center_x = (left+right)/2 - g_current_tile_layer_width/2;
  float center_y = (top+bottom)/2 - g_current_tile_layer_height/2;
  TranslateInPlace(mv_transform, center_x, center_y, 0.0);

  Project(mv_transform, proj_transform);
  GLint mat = glGetUniformLocationARB(prog, "matrix");
  glUniformMatrix4fvARB(mat, 1, GL_TRUE, proj_transform);

  glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, 0);
}


text:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">

<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>ELException (EL 3.0 API Documentation - Apache Tomcat 9.0.0.M11)</title>
<link rel="stylesheet" type="text/css" href="../../stylesheet.css" title="Style">

JavaScript is disabled on your browser.

Skip navigation links

Package

Class

Tree

Deprecated

Index

Help

EL 3.0 - Apache Tomcat 9.0.0.M11

Prev Class

Next Class

Frames

No Frames

All Classes

Summary:

Nested |

Field |

Constr |

Method

Detail:

Field |

Constr |

Method

javax.el

Class ELException

java.lang.Object

java.lang.Throwable

java.lang.Exception

java.lang.RuntimeException

javax.el.ELException

All Implemented Interfaces:

java.io.Serializable

Direct Known Subclasses:

MethodNotFoundException, PropertyNotFoundException, PropertyNotWritableException

public class ELException
extends java.lang.RuntimeException

Represents any of the exception conditions that can arise during expression
 evaluation.

Since:

2.1

See Also:

Serialized Form

Constructor Summary

Constructors

Constructor and Description

ELException()

Creates an ELException with no detail message

ELException(java.lang.String message)

Creates an ELException with the provided detail message.

ELException(java.lang.String message,
           java.lang.Throwable cause)

Creates an ELException with the given detail message and root cause.

ELException(java.lang.Throwable cause)

Creates an ELException with the given cause

Method Summary

Methods inherited from class java.lang.Throwable

addSuppressed, fillInStackTrace, getCause, getLocalizedMessage, getMessage, getStackTrace, getSuppressed, initCause, printStackTrace, printStackTrace, printStackTrace, setStackTrace, toString

Methods inherited from class java.lang.Object

clone, equals, finalize, getClass, hashCode, notify, notifyAll, wait, wait, wait

Constructor Detail

ELException

public ELException()

Creates an ELException with no detail message

ELException

public ELException(java.lang.String message)

Creates an ELException with the provided detail message.

Parameters:

message - the detail message

ELException

public ELException(java.lang.Throwable cause)

Creates an ELException with the given cause

Parameters:

cause - the originating cause of this exception

ELException

public ELException(java.lang.String message,
                   java.lang.Throwable cause)

Creates an ELException with the given detail message and root cause.

Parameters:

message - the detail message

cause - the originating cause of this exception

Skip navigation links

Package

Class

Tree

Deprecated

Index

Help

EL 3.0 - Apache Tomcat 9.0.0.M11

Prev Class

Next Class

Frames

No Frames

All Classes

Summary:

Nested |

Field |

Constr |

Method

Detail:

Field |

Constr |

Method

Copyright © 2000-2016 Apache Software Foundation. All Rights Reserved.


text:
import tornado.web
import tornado.escape
from handlers.base_handler import BaseHandler
from models.user import User
from forms.forms import UserForm

class LoginHandler(BaseHandler):

    def get(self):
        self.render('auth/login.html', error_message='')

    def post(self):
        email = self.get_argument('email', '')
        password = self.get_argument('password', '')
        user = User.authenticate(email=email, password=password)
        if user is not None:
            self.set_current_user(user)
            self.redirect(self.reverse_url(name='index'))
        else:
            error_message = 'ユーザ名かパスワードが間違っています。'
            self.render('auth/login.html', error_message=error_message)

class LogoutHandler(BaseHandler):

    @tornado.web.authenticated
    def get(self):
        self.clear_cookie('user')
        self.redirect(self.reverse_url(name='index'))

class SignupHandler(BaseHandler):

    def get(self):
        self.render('auth/signup.html', error_message='', form=UserForm())

    def post(self):
        email = self.get_argument('email', '')
        form = UserForm(self.request.arguments)
        if not form.validate():
            self.render('auth/signup.html', error_message='', form=form)
        elif User.exists_email(email):
            error_message = '既に存在するメールアドレスです。'
            self.render('auth/signup.html', error_message=error_message, form=form)
        else:
            user = User(**form.data)
            user.save()
            self.redirect(self.reverse_url('login'))


text:
<?php
namespace oasis\names\specification\ubl\schema\xsd\CommonBasicComponents_2;

/**
 * @xmlNamespace urn:oasis:names:specification:ubl:schema:xsd:CommonBasicComponents-2
 * @xmlType TariffDescriptionType
 * @xmlName TariffDescription
 * @var oasis\names\specification\ubl\schema\xsd\CommonBasicComponents_2\TariffDescription
 */
class TariffDescription extends TariffDescriptionType
{
} // end class TariffDescription


text:
using System.Collections;
using System.Collections.Generic;
using Jsonics;
using NUnit.Framework;

namespace JsonicsTests.FromJsonTests.DictionaryTests
{
    [TestFixture]
    public class BoolFloatTests : DictionaryTestsBase<bool, float>
    {

        public static IEnumerable TestCases
        {
            get
            {
                yield return new TestCaseData("{}", new Dictionary<bool, float>{});
                yield return new TestCaseData("{\"true\":1.1}", new Dictionary<bool, float>{{true, 1.1f}});
                yield return new TestCaseData("{\"false\":0.05,\"true\":\"42.42\"}", new Dictionary<bool, float>{{false, 0.05f},{true, 42.42f}});
                yield return new TestCaseData("null", null);
                yield return new TestCaseData(" null", null);
            }
        }
    }
}